diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/of_serial.c | 27 |
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 | ||
20 | struct 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, | |||
62 | static int __devinit of_platform_serial_probe(struct of_device *ofdev, | 67 | static 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; |
93 | out: | 105 | out: |
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 | */ |
101 | static int of_platform_serial_remove(struct of_device *ofdev) | 114 | static 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 | ||