]> err.no Git - linux-2.6/blobdiff - drivers/serial/of_serial.c
[Blackfin] arch: Add proper SW System Reset delay sequence
[linux-2.6] / drivers / serial / of_serial.c
index d7752af1c7ecb2e083a5cb0a4707ab63255b2fa3..a64d858219969d218c9a973d5b04224a838ea433 100644 (file)
 #include <asm/of_platform.h>
 #include <asm/prom.h>
 
+struct of_serial_info {
+       int type;
+       int line;
+};
+
 /*
  * Fill a struct uart_port for a given device node
  */
@@ -62,6 +67,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 static int __devinit of_platform_serial_probe(struct of_device *ofdev,
                                                const struct of_device_id *id)
 {
+       struct of_serial_info *info;
        struct uart_port port;
        int port_type;
        int ret;
@@ -69,6 +75,10 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
        if (of_find_property(ofdev->node, "used-by-rtas", NULL))
                return -EBUSY;
 
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (info == NULL)
+               return -ENOMEM;
+
        port_type = (unsigned long)id->data;
        ret = of_platform_serial_setup(ofdev, port_type, &port);
        if (ret)
@@ -88,9 +98,12 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
        if (ret < 0)
                goto out;
 
-       ofdev->dev.driver_data = (void *)(unsigned long)ret;
+       info->type = port_type;
+       info->line = ret;
+       ofdev->dev.driver_data = info;
        return 0;
 out:
+       kfree(info);
        irq_dispose_mapping(port.irq);
        return ret;
 }
@@ -100,8 +113,16 @@ out:
  */
 static int of_platform_serial_remove(struct of_device *ofdev)
 {
-       int line = (unsigned long)ofdev->dev.driver_data;
-       serial8250_unregister_port(line);
+       struct of_serial_info *info = ofdev->dev.driver_data;
+       switch (info->type) {
+       case PORT_8250 ... PORT_MAX_8250:
+               serial8250_unregister_port(info->line);
+               break;
+       default:
+               /* need to add code for these */
+               break;
+       }
+       kfree(info);
        return 0;
 }