]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/serial/sunzilog.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6-omap-h63xx.git] / drivers / serial / sunzilog.c
index cbdf9d605b3fd5ab1525347d944efedc8d2d35b4..a1456d9352cba115bb7471ba5a43aacc9c75f0e8 100644 (file)
@@ -12,7 +12,6 @@
  *  Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net)
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -1335,9 +1334,10 @@ static int __devinit zs_get_instance(struct device_node *dp)
        return ret;
 }
 
+static int zilog_irq = -1;
+
 static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       static int zilog_irq = -1;
        struct of_device *op = to_of_device(&dev->dev);
        struct uart_sunzilog_port *up;
        struct zilog_layout __iomem *rp;
@@ -1354,7 +1354,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
 
        if (zilog_irq == -1) {
                zilog_irq = op->irqs[0];
-               err = request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ,
+               err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
                                  "zs", sunzilog_irq_chain);
                if (err) {
                        of_iounmap(rp, sizeof(struct zilog_layout));
@@ -1413,24 +1413,33 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
                }
        }
 
+       dev_set_drvdata(&dev->dev, &up[0]);
+
        return 0;
 }
 
-static int __devexit zs_remove(struct of_device *dev)
+static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
 {
-       struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
-       struct zilog_channel __iomem *channel;
-
        if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
 #ifdef CONFIG_SERIO
                serio_unregister_port(&up->serio);
 #endif
        } else
                uart_remove_one_port(&sunzilog_reg, &up->port);
+}
 
-       channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+static int __devexit zs_remove(struct of_device *dev)
+{
+       struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
+       struct zilog_layout __iomem *regs;
+
+       zs_remove_one(&up[0]);
+       zs_remove_one(&up[1]);
 
-       of_iounmap(channel, sizeof(struct zilog_channel));
+       regs = sunzilog_chip_regs[up[0].port.line / 2];
+       of_iounmap(regs, sizeof(struct zilog_layout));
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
@@ -1489,6 +1498,11 @@ static void __exit sunzilog_exit(void)
 {
        of_unregister_driver(&zs_driver);
 
+       if (zilog_irq != -1) {
+               free_irq(zilog_irq, sunzilog_irq_chain);
+               zilog_irq = -1;
+       }
+
        if (NUM_SUNZILOG) {
                uart_unregister_driver(&sunzilog_reg);
                sunzilog_free_tables();
@@ -1500,4 +1514,5 @@ module_exit(sunzilog_exit);
 
 MODULE_AUTHOR("David S. Miller");
 MODULE_DESCRIPTION("Sun Zilog serial port driver");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");