[PATCH] hvc_console: Separate hvc_console and vio code 2
authorMilton Miller <miltonm@bga.com>
Fri, 8 Jul 2005 00:56:24 +0000 (17:56 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 8 Jul 2005 01:23:39 +0000 (18:23 -0700)
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>
arch/ppc64/kernel/hvconsole.c
drivers/char/Makefile
drivers/char/hvc_console.c
drivers/char/hvc_vio.c [new file with mode: 0644]
include/asm-ppc64/hvconsole.h

index 94fb06198ea2d3ca10a278ef6d9ad3f3bead5319..9d8876d92eb9970a12d4b26fa5bfd7d512b9f3c4 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <asm/hvcall.h>
 #include <asm/hvconsole.h>
-#include <asm/prom.h>
 
 /**
  * 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);
index 1aff819f3832d33f11fc9a60a21bf2b30d847b30..08f69287ea36157c31477f23c8a4fc856637bebb 100644 (file)
@@ -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
index d59c642f9654c5a189ce62634f1368c859e2702c..df282cc9a7abaf288018c53c17b75654480b0474 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/hvconsole.h>
-#include <asm/vio.h>
 
 #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/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
new file mode 100644 (file)
index 0000000..d2928f9
--- /dev/null
@@ -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);
index 91c2414ac00b69a4658416949c71deebc5e46326..14667a78716d2068f8b17b548f20a8d7d307fa6e 100644 (file)
  */
 #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 */