From 10fcd25bfea481445ad4d837fd16024e13e16406 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 7 Jul 2005 17:56:24 -0700 Subject: [PATCH] --- yaml --- r: 4231 b: refs/heads/master c: acad9559f1054487292eb10d7bb81f256e9d8f2d h: refs/heads/master i: 4229: ed31919f2ae06910f38769fa3b5c0911bb30832f 4227: ac13c87566e0d2c0b0a963a057115939bc2ca53f 4223: 15d672f9580706ce44613224eba0f16379f6e6b6 v: v3 --- [refs] | 2 +- trunk/arch/ppc64/kernel/hvconsole.c | 33 -------- trunk/drivers/char/Makefile | 2 +- trunk/drivers/char/hvc_console.c | 50 +++-------- trunk/drivers/char/hvc_vio.c | 125 ++++++++++++++++++++++++++++ trunk/include/asm-ppc64/hvconsole.h | 9 +- 6 files changed, 146 insertions(+), 75 deletions(-) create mode 100644 trunk/drivers/char/hvc_vio.c diff --git a/[refs] b/[refs] index 6a380d8c0826..fd57555e35ab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d5ee257c3342185ba8ab642d125d192eb99ea8f2 +refs/heads/master: acad9559f1054487292eb10d7bb81f256e9d8f2d diff --git a/trunk/arch/ppc64/kernel/hvconsole.c b/trunk/arch/ppc64/kernel/hvconsole.c index 94fb06198ea2..9d8876d92eb9 100644 --- a/trunk/arch/ppc64/kernel/hvconsole.c +++ b/trunk/arch/ppc64/kernel/hvconsole.c @@ -27,7 +27,6 @@ #include #include #include -#include /** * 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); - -/* - * 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); diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 1aff819f3832..08f69287ea36 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o 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_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index d59c642f9654..df282cc9a7ab 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -41,7 +41,6 @@ #include #include #include -#include #define HVC_MAJOR 229 #define HVC_MINOR 0 @@ -90,7 +89,6 @@ struct hvc_struct { int irq; struct list_head next; struct kobject kobj; /* ref count & hvc_struct lifetime */ - struct vio_dev *vdev; }; /* dynamic list of hvc_struct instances */ @@ -279,6 +277,7 @@ int hvc_instantiate(uint32_t vtermno, int index) return 0; } +EXPORT_SYMBOL(hvc_instantiate); /* Wake the sleeping khvcd */ static void hvc_kick(void) @@ -738,26 +737,19 @@ static struct kobj_type hvc_kobj_type = { .release = destroy_hvc_struct, }; -static int __devinit hvc_probe( - struct vio_dev *dev, - const struct vio_device_id *id) +struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq) { struct hvc_struct *hp; int i; - /* probed with invalid parameters. */ - if (!dev || !id) - return -EPERM; - hp = kmalloc(sizeof(*hp), GFP_KERNEL); if (!hp) - return -ENOMEM; + return ERR_PTR(-ENOMEM); memset(hp, 0x00, sizeof(*hp)); - hp->vtermno = dev->unit_address; - hp->vdev = dev; - hp->vdev->dev.driver_data = hp; - hp->irq = dev->irq; + + hp->vtermno = vtermno; + hp->irq = irq; kobject_init(&hp->kobj); hp->kobj.ktype = &hvc_kobj_type; @@ -782,12 +774,12 @@ static int __devinit hvc_probe( list_add_tail(&(hp->next), &hvc_structs); 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; struct kobject *kobjp; struct tty_struct *tty; @@ -820,28 +812,12 @@ static int __devexit hvc_remove(struct vio_dev *dev) tty_hangup(tty); return 0; } - -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, -}; +EXPORT_SYMBOL(hvc_remove); /* Driver initialization. Follow console initialization. This is where the TTY * interfaces start to become available. */ int __init hvc_init(void) { - int rc; - /* We need more than hvc_count adapters due to hotplug additions. */ hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); if (!hvc_driver) @@ -870,10 +846,7 @@ int __init hvc_init(void) return -EIO; } - /* Register as a vio device to receive callbacks */ - rc = vio_register_driver(&hvc_vio_driver); - - return rc; + return 0; } module_init(hvc_init); @@ -884,7 +857,6 @@ static void __exit hvc_exit(void) { kthread_stop(hvc_task); - vio_unregister_driver(&hvc_vio_driver); tty_unregister_driver(hvc_driver); /* return tty_struct instances allocated in hvc_init(). */ put_tty_driver(hvc_driver); diff --git a/trunk/drivers/char/hvc_vio.c b/trunk/drivers/char/hvc_vio.c new file mode 100644 index 000000000000..d2928f90ab51 --- /dev/null +++ b/trunk/drivers/char/hvc_vio.c @@ -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 , IBM + * Copyright (C) 2001 Paul Mackerras , IBM + * Copyright (C) 2004 Benjamin Herrenschmidt , IBM Corp. + * Copyright (C) 2004 IBM Corporation + * + * Additional Author(s): + * Ryan S. Arnold + * + * 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 +#include +#include +#include +#include + +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); diff --git a/trunk/include/asm-ppc64/hvconsole.h b/trunk/include/asm-ppc64/hvconsole.h index 91c2414ac00b..14667a78716d 100644 --- a/trunk/include/asm-ppc64/hvconsole.h +++ b/trunk/include/asm-ppc64/hvconsole.h @@ -29,9 +29,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_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); +/* 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 */