[PATCH] hvc_console: Separate hvc_console and vio code 2
Remove all the vio device driver code from hvc_console.c This will allow us to separate hvsi, hvc, and allow hvc_console to be used without the ppc64 vio layer. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
d5ee257c33
commit
acad9559f1
5 changed files with 145 additions and 74 deletions
|
@ -27,7 +27,6 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <asm/hvcall.h>
|
#include <asm/hvcall.h>
|
||||||
#include <asm/hvconsole.h>
|
#include <asm/hvconsole.h>
|
||||||
#include <asm/prom.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
|
* hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
|
||||||
|
@ -88,35 +87,3 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(hvc_put_chars);
|
EXPORT_SYMBOL(hvc_put_chars);
|
||||||
|
|
||||||
/*
|
|
||||||
* We hope/assume that the first vty found corresponds to the first console
|
|
||||||
* device.
|
|
||||||
*/
|
|
||||||
static int hvc_find_vtys(void)
|
|
||||||
{
|
|
||||||
struct device_node *vty;
|
|
||||||
int num_found = 0;
|
|
||||||
|
|
||||||
for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
|
|
||||||
vty = of_find_node_by_name(vty, "vty")) {
|
|
||||||
uint32_t *vtermno;
|
|
||||||
|
|
||||||
/* We have statically defined space for only a certain number of
|
|
||||||
* console adapters. */
|
|
||||||
if (num_found >= MAX_NR_HVC_CONSOLES)
|
|
||||||
break;
|
|
||||||
|
|
||||||
vtermno = (uint32_t *)get_property(vty, "reg", NULL);
|
|
||||||
if (!vtermno)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (device_is_compatible(vty, "hvterm1")) {
|
|
||||||
hvc_instantiate(*vtermno, num_found);
|
|
||||||
++num_found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_found;
|
|
||||||
}
|
|
||||||
console_initcall(hvc_find_vtys);
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
|
||||||
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
|
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
|
||||||
obj-$(CONFIG_SX) += sx.o generic_serial.o
|
obj-$(CONFIG_SX) += sx.o generic_serial.o
|
||||||
obj-$(CONFIG_RIO) += rio/ generic_serial.o
|
obj-$(CONFIG_RIO) += rio/ generic_serial.o
|
||||||
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o
|
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o
|
||||||
obj-$(CONFIG_RAW_DRIVER) += raw.o
|
obj-$(CONFIG_RAW_DRIVER) += raw.o
|
||||||
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
|
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
|
||||||
obj-$(CONFIG_MMTIMER) += mmtimer.o
|
obj-$(CONFIG_MMTIMER) += mmtimer.o
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/hvconsole.h>
|
#include <asm/hvconsole.h>
|
||||||
#include <asm/vio.h>
|
|
||||||
|
|
||||||
#define HVC_MAJOR 229
|
#define HVC_MAJOR 229
|
||||||
#define HVC_MINOR 0
|
#define HVC_MINOR 0
|
||||||
|
@ -90,7 +89,6 @@ struct hvc_struct {
|
||||||
int irq;
|
int irq;
|
||||||
struct list_head next;
|
struct list_head next;
|
||||||
struct kobject kobj; /* ref count & hvc_struct lifetime */
|
struct kobject kobj; /* ref count & hvc_struct lifetime */
|
||||||
struct vio_dev *vdev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* dynamic list of hvc_struct instances */
|
/* dynamic list of hvc_struct instances */
|
||||||
|
@ -279,6 +277,7 @@ int hvc_instantiate(uint32_t vtermno, int index)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_instantiate);
|
||||||
|
|
||||||
/* Wake the sleeping khvcd */
|
/* Wake the sleeping khvcd */
|
||||||
static void hvc_kick(void)
|
static void hvc_kick(void)
|
||||||
|
@ -738,26 +737,19 @@ static struct kobj_type hvc_kobj_type = {
|
||||||
.release = destroy_hvc_struct,
|
.release = destroy_hvc_struct,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit hvc_probe(
|
struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq)
|
||||||
struct vio_dev *dev,
|
|
||||||
const struct vio_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp;
|
struct hvc_struct *hp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* probed with invalid parameters. */
|
|
||||||
if (!dev || !id)
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
hp = kmalloc(sizeof(*hp), GFP_KERNEL);
|
hp = kmalloc(sizeof(*hp), GFP_KERNEL);
|
||||||
if (!hp)
|
if (!hp)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
memset(hp, 0x00, sizeof(*hp));
|
memset(hp, 0x00, sizeof(*hp));
|
||||||
hp->vtermno = dev->unit_address;
|
|
||||||
hp->vdev = dev;
|
hp->vtermno = vtermno;
|
||||||
hp->vdev->dev.driver_data = hp;
|
hp->irq = irq;
|
||||||
hp->irq = dev->irq;
|
|
||||||
|
|
||||||
kobject_init(&hp->kobj);
|
kobject_init(&hp->kobj);
|
||||||
hp->kobj.ktype = &hvc_kobj_type;
|
hp->kobj.ktype = &hvc_kobj_type;
|
||||||
|
@ -782,12 +774,12 @@ static int __devinit hvc_probe(
|
||||||
list_add_tail(&(hp->next), &hvc_structs);
|
list_add_tail(&(hp->next), &hvc_structs);
|
||||||
spin_unlock(&hvc_structs_lock);
|
spin_unlock(&hvc_structs_lock);
|
||||||
|
|
||||||
return 0;
|
return hp;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_alloc);
|
||||||
|
|
||||||
static int __devexit hvc_remove(struct vio_dev *dev)
|
int __devexit hvc_remove(struct hvc_struct *hp)
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp = dev->dev.driver_data;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct kobject *kobjp;
|
struct kobject *kobjp;
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
|
@ -820,28 +812,12 @@ static int __devexit hvc_remove(struct vio_dev *dev)
|
||||||
tty_hangup(tty);
|
tty_hangup(tty);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_remove);
|
||||||
char hvc_driver_name[] = "hvc_console";
|
|
||||||
|
|
||||||
static struct vio_device_id hvc_driver_table[] __devinitdata= {
|
|
||||||
{"serial", "hvterm1"},
|
|
||||||
{ NULL, }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(vio, hvc_driver_table);
|
|
||||||
|
|
||||||
static struct vio_driver hvc_vio_driver = {
|
|
||||||
.name = hvc_driver_name,
|
|
||||||
.id_table = hvc_driver_table,
|
|
||||||
.probe = hvc_probe,
|
|
||||||
.remove = hvc_remove,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Driver initialization. Follow console initialization. This is where the TTY
|
/* Driver initialization. Follow console initialization. This is where the TTY
|
||||||
* interfaces start to become available. */
|
* interfaces start to become available. */
|
||||||
int __init hvc_init(void)
|
int __init hvc_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* We need more than hvc_count adapters due to hotplug additions. */
|
/* We need more than hvc_count adapters due to hotplug additions. */
|
||||||
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
|
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
|
||||||
if (!hvc_driver)
|
if (!hvc_driver)
|
||||||
|
@ -870,10 +846,7 @@ int __init hvc_init(void)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register as a vio device to receive callbacks */
|
return 0;
|
||||||
rc = vio_register_driver(&hvc_vio_driver);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
module_init(hvc_init);
|
module_init(hvc_init);
|
||||||
|
|
||||||
|
@ -884,7 +857,6 @@ static void __exit hvc_exit(void)
|
||||||
{
|
{
|
||||||
kthread_stop(hvc_task);
|
kthread_stop(hvc_task);
|
||||||
|
|
||||||
vio_unregister_driver(&hvc_vio_driver);
|
|
||||||
tty_unregister_driver(hvc_driver);
|
tty_unregister_driver(hvc_driver);
|
||||||
/* return tty_struct instances allocated in hvc_init(). */
|
/* return tty_struct instances allocated in hvc_init(). */
|
||||||
put_tty_driver(hvc_driver);
|
put_tty_driver(hvc_driver);
|
||||||
|
|
125
drivers/char/hvc_vio.c
Normal file
125
drivers/char/hvc_vio.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* vio driver interface to hvc_console.c
|
||||||
|
*
|
||||||
|
* This code was moved here to allow the remaing code to be reused as a
|
||||||
|
* generic polling mode with semi-reliable transport driver core to the
|
||||||
|
* console and tty subsystems.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
|
||||||
|
* Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
|
||||||
|
* Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
|
||||||
|
* Copyright (C) 2004 IBM Corporation
|
||||||
|
*
|
||||||
|
* Additional Author(s):
|
||||||
|
* Ryan S. Arnold <rsa@us.ibm.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <asm/hvconsole.h>
|
||||||
|
#include <asm/vio.h>
|
||||||
|
#include <asm/prom.h>
|
||||||
|
|
||||||
|
char hvc_driver_name[] = "hvc_console";
|
||||||
|
|
||||||
|
static struct vio_device_id hvc_driver_table[] __devinitdata = {
|
||||||
|
{"serial", "hvterm1"},
|
||||||
|
{ NULL, }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(vio, hvc_driver_table);
|
||||||
|
|
||||||
|
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
|
||||||
|
const struct vio_device_id *id)
|
||||||
|
{
|
||||||
|
struct hvc_struct *hp;
|
||||||
|
|
||||||
|
/* probed with invalid parameters. */
|
||||||
|
if (!vdev || !id)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
hp = hvc_alloc(vdev->unit_address, vdev->irq);
|
||||||
|
if (IS_ERR(hp))
|
||||||
|
return PTR_ERR(hp);
|
||||||
|
dev_set_drvdata(&vdev->dev, hp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit hvc_vio_remove(struct vio_dev *vdev)
|
||||||
|
{
|
||||||
|
struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
|
||||||
|
|
||||||
|
return hvc_remove(hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct vio_driver hvc_vio_driver = {
|
||||||
|
.name = hvc_driver_name,
|
||||||
|
.id_table = hvc_driver_table,
|
||||||
|
.probe = hvc_vio_probe,
|
||||||
|
.remove = hvc_vio_remove,
|
||||||
|
.driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hvc_vio_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Register as a vio device to receive callbacks */
|
||||||
|
rc = vio_register_driver(&hvc_vio_driver);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
|
||||||
|
|
||||||
|
static void hvc_vio_exit(void)
|
||||||
|
{
|
||||||
|
vio_unregister_driver(&hvc_vio_driver);
|
||||||
|
}
|
||||||
|
module_exit(hvc_vio_exit);
|
||||||
|
|
||||||
|
/* the device tree order defines our numbering */
|
||||||
|
static int hvc_find_vtys(void)
|
||||||
|
{
|
||||||
|
struct device_node *vty;
|
||||||
|
int num_found = 0;
|
||||||
|
|
||||||
|
for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
|
||||||
|
vty = of_find_node_by_name(vty, "vty")) {
|
||||||
|
uint32_t *vtermno;
|
||||||
|
|
||||||
|
/* We have statically defined space for only a certain number
|
||||||
|
* of console adapters.
|
||||||
|
*/
|
||||||
|
if (num_found >= MAX_NR_HVC_CONSOLES)
|
||||||
|
break;
|
||||||
|
|
||||||
|
vtermno = (uint32_t *)get_property(vty, "reg", NULL);
|
||||||
|
if (!vtermno)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (device_is_compatible(vty, "hvterm1")) {
|
||||||
|
hvc_instantiate(*vtermno, num_found);
|
||||||
|
++num_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_found;
|
||||||
|
}
|
||||||
|
console_initcall(hvc_find_vtys);
|
|
@ -29,9 +29,16 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_NR_HVC_CONSOLES 16
|
#define MAX_NR_HVC_CONSOLES 16
|
||||||
|
|
||||||
|
/* implemented by a low level driver */
|
||||||
extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
|
extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
|
||||||
extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
|
extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
|
||||||
|
|
||||||
/* Register a vterm and a slot index for use as a console */
|
struct hvc_struct;
|
||||||
|
|
||||||
|
/* Register a vterm and a slot index for use as a console (console_init) */
|
||||||
extern int hvc_instantiate(uint32_t vtermno, int index);
|
extern int hvc_instantiate(uint32_t vtermno, int index);
|
||||||
|
/* register a vterm for hvc tty operation (module_init or hotplug add) */
|
||||||
|
extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq);
|
||||||
|
/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
|
||||||
|
extern int __devexit hvc_remove(struct hvc_struct *hp);
|
||||||
#endif /* _PPC64_HVCONSOLE_H */
|
#endif /* _PPC64_HVCONSOLE_H */
|
||||||
|
|
Loading…
Reference in a new issue