[SERIAL] sunzilog: Fix bugs in device deregristration.

1) Need to unregister 2 ports per of_device.
2) Need to of_iounmap() 1 mapping per of_device.
3) Need to free up the IRQ only after all devices
   have been unregistered.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index cbdf9d6..98342ee 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1335,9 +1335,10 @@
 	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;
@@ -1413,24 +1414,33 @@
 		}
 	}
 
+	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;
 
-	of_iounmap(channel, sizeof(struct zilog_channel));
+	zs_remove_one(&up[0]);
+	zs_remove_one(&up[1]);
+
+	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 +1499,11 @@
 {
 	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();