aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/of_serial.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index d7752af1c7ec..a64d85821996 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -17,6 +17,11 @@
17#include <asm/of_platform.h> 17#include <asm/of_platform.h>
18#include <asm/prom.h> 18#include <asm/prom.h>
19 19
20struct of_serial_info {
21 int type;
22 int line;
23};
24
20/* 25/*
21 * Fill a struct uart_port for a given device node 26 * Fill a struct uart_port for a given device node
22 */ 27 */
@@ -62,6 +67,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
62static int __devinit of_platform_serial_probe(struct of_device *ofdev, 67static int __devinit of_platform_serial_probe(struct of_device *ofdev,
63 const struct of_device_id *id) 68 const struct of_device_id *id)
64{ 69{
70 struct of_serial_info *info;
65 struct uart_port port; 71 struct uart_port port;
66 int port_type; 72 int port_type;
67 int ret; 73 int ret;
@@ -69,6 +75,10 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
69 if (of_find_property(ofdev->node, "used-by-rtas", NULL)) 75 if (of_find_property(ofdev->node, "used-by-rtas", NULL))
70 return -EBUSY; 76 return -EBUSY;
71 77
78 info = kmalloc(sizeof(*info), GFP_KERNEL);
79 if (info == NULL)
80 return -ENOMEM;
81
72 port_type = (unsigned long)id->data; 82 port_type = (unsigned long)id->data;
73 ret = of_platform_serial_setup(ofdev, port_type, &port); 83 ret = of_platform_serial_setup(ofdev, port_type, &port);
74 if (ret) 84 if (ret)
@@ -88,9 +98,12 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
88 if (ret < 0) 98 if (ret < 0)
89 goto out; 99 goto out;
90 100
91 ofdev->dev.driver_data = (void *)(unsigned long)ret; 101 info->type = port_type;
102 info->line = ret;
103 ofdev->dev.driver_data = info;
92 return 0; 104 return 0;
93out: 105out:
106 kfree(info);
94 irq_dispose_mapping(port.irq); 107 irq_dispose_mapping(port.irq);
95 return ret; 108 return ret;
96} 109}
@@ -100,8 +113,16 @@ out:
100 */ 113 */
101static int of_platform_serial_remove(struct of_device *ofdev) 114static int of_platform_serial_remove(struct of_device *ofdev)
102{ 115{
103 int line = (unsigned long)ofdev->dev.driver_data; 116 struct of_serial_info *info = ofdev->dev.driver_data;
104 serial8250_unregister_port(line); 117 switch (info->type) {
118 case PORT_8250 ... PORT_MAX_8250:
119 serial8250_unregister_port(info->line);
120 break;
121 default:
122 /* need to add code for these */
123 break;
124 }
125 kfree(info);
105 return 0; 126 return 0;
106} 127}
107 128