Commit 4fa97dcf authored by David S. Miller's avatar David S. Miller Committed by David S. Miller

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent 36764631
...@@ -1335,9 +1335,10 @@ static int __devinit zs_get_instance(struct device_node *dp) ...@@ -1335,9 +1335,10 @@ static int __devinit zs_get_instance(struct device_node *dp)
return ret; return ret;
} }
static int zilog_irq = -1;
static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) 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 of_device *op = to_of_device(&dev->dev);
struct uart_sunzilog_port *up; struct uart_sunzilog_port *up;
struct zilog_layout __iomem *rp; struct zilog_layout __iomem *rp;
...@@ -1413,24 +1414,33 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * ...@@ -1413,24 +1414,33 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
} }
} }
dev_set_drvdata(&dev->dev, &up[0]);
return 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)) { if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
#ifdef CONFIG_SERIO #ifdef CONFIG_SERIO
serio_unregister_port(&up->serio); serio_unregister_port(&up->serio);
#endif #endif
} else } else
uart_remove_one_port(&sunzilog_reg, &up->port); 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; return 0;
} }
...@@ -1489,6 +1499,11 @@ static void __exit sunzilog_exit(void) ...@@ -1489,6 +1499,11 @@ static void __exit sunzilog_exit(void)
{ {
of_unregister_driver(&zs_driver); of_unregister_driver(&zs_driver);
if (zilog_irq != -1) {
free_irq(zilog_irq, sunzilog_irq_chain);
zilog_irq = -1;
}
if (NUM_SUNZILOG) { if (NUM_SUNZILOG) {
uart_unregister_driver(&sunzilog_reg); uart_unregister_driver(&sunzilog_reg);
sunzilog_free_tables(); sunzilog_free_tables();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment