aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/hvc_console.c50
-rw-r--r--drivers/char/hvc_vio.c125
3 files changed, 137 insertions, 40 deletions
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 1aff819f3832..08f69287ea36 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
40obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 40obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
41obj-$(CONFIG_SX) += sx.o generic_serial.o 41obj-$(CONFIG_SX) += sx.o generic_serial.o
42obj-$(CONFIG_RIO) += rio/ generic_serial.o 42obj-$(CONFIG_RIO) += rio/ generic_serial.o
43obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o 43obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o
44obj-$(CONFIG_RAW_DRIVER) += raw.o 44obj-$(CONFIG_RAW_DRIVER) += raw.o
45obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 45obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
46obj-$(CONFIG_MMTIMER) += mmtimer.o 46obj-$(CONFIG_MMTIMER) += mmtimer.o
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index d59c642f9654..df282cc9a7ab 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -41,7 +41,6 @@
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/hvconsole.h> 43#include <asm/hvconsole.h>
44#include <asm/vio.h>
45 44
46#define HVC_MAJOR 229 45#define HVC_MAJOR 229
47#define HVC_MINOR 0 46#define HVC_MINOR 0
@@ -90,7 +89,6 @@ struct hvc_struct {
90 int irq; 89 int irq;
91 struct list_head next; 90 struct list_head next;
92 struct kobject kobj; /* ref count & hvc_struct lifetime */ 91 struct kobject kobj; /* ref count & hvc_struct lifetime */
93 struct vio_dev *vdev;
94}; 92};
95 93
96/* dynamic list of hvc_struct instances */ 94/* dynamic list of hvc_struct instances */
@@ -279,6 +277,7 @@ int hvc_instantiate(uint32_t vtermno, int index)
279 277
280 return 0; 278 return 0;
281} 279}
280EXPORT_SYMBOL(hvc_instantiate);
282 281
283/* Wake the sleeping khvcd */ 282/* Wake the sleeping khvcd */
284static void hvc_kick(void) 283static void hvc_kick(void)
@@ -738,26 +737,19 @@ static struct kobj_type hvc_kobj_type = {
738 .release = destroy_hvc_struct, 737 .release = destroy_hvc_struct,
739}; 738};
740 739
741static int __devinit hvc_probe( 740struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq)
742 struct vio_dev *dev,
743 const struct vio_device_id *id)
744{ 741{
745 struct hvc_struct *hp; 742 struct hvc_struct *hp;
746 int i; 743 int i;
747 744
748 /* probed with invalid parameters. */
749 if (!dev || !id)
750 return -EPERM;
751
752 hp = kmalloc(sizeof(*hp), GFP_KERNEL); 745 hp = kmalloc(sizeof(*hp), GFP_KERNEL);
753 if (!hp) 746 if (!hp)
754 return -ENOMEM; 747 return ERR_PTR(-ENOMEM);
755 748
756 memset(hp, 0x00, sizeof(*hp)); 749 memset(hp, 0x00, sizeof(*hp));
757 hp->vtermno = dev->unit_address; 750
758 hp->vdev = dev; 751 hp->vtermno = vtermno;
759 hp->vdev->dev.driver_data = hp; 752 hp->irq = irq;
760 hp->irq = dev->irq;
761 753
762 kobject_init(&hp->kobj); 754 kobject_init(&hp->kobj);
763 hp->kobj.ktype = &hvc_kobj_type; 755 hp->kobj.ktype = &hvc_kobj_type;
@@ -782,12 +774,12 @@ static int __devinit hvc_probe(
782 list_add_tail(&(hp->next), &hvc_structs); 774 list_add_tail(&(hp->next), &hvc_structs);
783 spin_unlock(&hvc_structs_lock); 775 spin_unlock(&hvc_structs_lock);
784 776
785 return 0; 777 return hp;
786} 778}
779EXPORT_SYMBOL(hvc_alloc);
787 780
788static int __devexit hvc_remove(struct vio_dev *dev) 781int __devexit hvc_remove(struct hvc_struct *hp)
789{ 782{
790 struct hvc_struct *hp = dev->dev.driver_data;
791 unsigned long flags; 783 unsigned long flags;
792 struct kobject *kobjp; 784 struct kobject *kobjp;
793 struct tty_struct *tty; 785 struct tty_struct *tty;
@@ -820,28 +812,12 @@ static int __devexit hvc_remove(struct vio_dev *dev)
820 tty_hangup(tty); 812 tty_hangup(tty);
821 return 0; 813 return 0;
822} 814}
823 815EXPORT_SYMBOL(hvc_remove);
824char hvc_driver_name[] = "hvc_console";
825
826static struct vio_device_id hvc_driver_table[] __devinitdata= {
827 {"serial", "hvterm1"},
828 { NULL, }
829};
830MODULE_DEVICE_TABLE(vio, hvc_driver_table);
831
832static struct vio_driver hvc_vio_driver = {
833 .name = hvc_driver_name,
834 .id_table = hvc_driver_table,
835 .probe = hvc_probe,
836 .remove = hvc_remove,
837};
838 816
839/* Driver initialization. Follow console initialization. This is where the TTY 817/* Driver initialization. Follow console initialization. This is where the TTY
840 * interfaces start to become available. */ 818 * interfaces start to become available. */
841int __init hvc_init(void) 819int __init hvc_init(void)
842{ 820{
843 int rc;
844
845 /* We need more than hvc_count adapters due to hotplug additions. */ 821 /* We need more than hvc_count adapters due to hotplug additions. */
846 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); 822 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
847 if (!hvc_driver) 823 if (!hvc_driver)
@@ -870,10 +846,7 @@ int __init hvc_init(void)
870 return -EIO; 846 return -EIO;
871 } 847 }
872 848
873 /* Register as a vio device to receive callbacks */ 849 return 0;
874 rc = vio_register_driver(&hvc_vio_driver);
875
876 return rc;
877} 850}
878module_init(hvc_init); 851module_init(hvc_init);
879 852
@@ -884,7 +857,6 @@ static void __exit hvc_exit(void)
884{ 857{
885 kthread_stop(hvc_task); 858 kthread_stop(hvc_task);
886 859
887 vio_unregister_driver(&hvc_vio_driver);
888 tty_unregister_driver(hvc_driver); 860 tty_unregister_driver(hvc_driver);
889 /* return tty_struct instances allocated in hvc_init(). */ 861 /* return tty_struct instances allocated in hvc_init(). */
890 put_tty_driver(hvc_driver); 862 put_tty_driver(hvc_driver);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
new file mode 100644
index 000000000000..d2928f90ab51
--- /dev/null
+++ b/drivers/char/hvc_vio.c
@@ -0,0 +1,125 @@
1/*
2 * vio driver interface to hvc_console.c
3 *
4 * This code was moved here to allow the remaing code to be reused as a
5 * generic polling mode with semi-reliable transport driver core to the
6 * console and tty subsystems.
7 *
8 *
9 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
10 * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
11 * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
12 * Copyright (C) 2004 IBM Corporation
13 *
14 * Additional Author(s):
15 * Ryan S. Arnold <rsa@us.ibm.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/types.h>
33#include <linux/init.h>
34#include <asm/hvconsole.h>
35#include <asm/vio.h>
36#include <asm/prom.h>
37
38char hvc_driver_name[] = "hvc_console";
39
40static struct vio_device_id hvc_driver_table[] __devinitdata = {
41 {"serial", "hvterm1"},
42 { NULL, }
43};
44MODULE_DEVICE_TABLE(vio, hvc_driver_table);
45
46static int __devinit hvc_vio_probe(struct vio_dev *vdev,
47 const struct vio_device_id *id)
48{
49 struct hvc_struct *hp;
50
51 /* probed with invalid parameters. */
52 if (!vdev || !id)
53 return -EPERM;
54
55 hp = hvc_alloc(vdev->unit_address, vdev->irq);
56 if (IS_ERR(hp))
57 return PTR_ERR(hp);
58 dev_set_drvdata(&vdev->dev, hp);
59
60 return 0;
61}
62
63static int __devexit hvc_vio_remove(struct vio_dev *vdev)
64{
65 struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
66
67 return hvc_remove(hp);
68}
69
70static struct vio_driver hvc_vio_driver = {
71 .name = hvc_driver_name,
72 .id_table = hvc_driver_table,
73 .probe = hvc_vio_probe,
74 .remove = hvc_vio_remove,
75 .driver = {
76 .owner = THIS_MODULE,
77 }
78};
79
80static int hvc_vio_init(void)
81{
82 int rc;
83
84 /* Register as a vio device to receive callbacks */
85 rc = vio_register_driver(&hvc_vio_driver);
86
87 return rc;
88}
89module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
90
91static void hvc_vio_exit(void)
92{
93 vio_unregister_driver(&hvc_vio_driver);
94}
95module_exit(hvc_vio_exit);
96
97/* the device tree order defines our numbering */
98static int hvc_find_vtys(void)
99{
100 struct device_node *vty;
101 int num_found = 0;
102
103 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
104 vty = of_find_node_by_name(vty, "vty")) {
105 uint32_t *vtermno;
106
107 /* We have statically defined space for only a certain number
108 * of console adapters.
109 */
110 if (num_found >= MAX_NR_HVC_CONSOLES)
111 break;
112
113 vtermno = (uint32_t *)get_property(vty, "reg", NULL);
114 if (!vtermno)
115 continue;
116
117 if (device_is_compatible(vty, "hvterm1")) {
118 hvc_instantiate(*vtermno, num_found);
119 ++num_found;
120 }
121 }
122
123 return num_found;
124}
125console_initcall(hvc_find_vtys);