[SERIAL] sunzilog: Register IRQ after all devices have been probed.
Otherwise we will deref half-initialized channel pointers and crash in the interrupt handler. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3932932956
commit
67e23a1e60
|
@ -1336,12 +1336,11 @@ static int __devinit zs_get_instance(struct device_node *dp)
|
||||||
|
|
||||||
static int zilog_irq = -1;
|
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 *op, const struct of_device_id *match)
|
||||||
{
|
{
|
||||||
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;
|
||||||
int inst = zs_get_instance(dev->node);
|
int inst = zs_get_instance(op->node);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
|
sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
|
||||||
|
@ -1413,7 +1412,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_set_drvdata(&dev->dev, &up[0]);
|
dev_set_drvdata(&op->dev, &up[0]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1462,18 +1461,19 @@ static struct of_platform_driver zs_driver = {
|
||||||
static int __init sunzilog_init(void)
|
static int __init sunzilog_init(void)
|
||||||
{
|
{
|
||||||
struct device_node *dp;
|
struct device_node *dp;
|
||||||
int err;
|
int err, uart_count;
|
||||||
|
|
||||||
NUM_SUNZILOG = 0;
|
NUM_SUNZILOG = 0;
|
||||||
for_each_node_by_name(dp, "zs")
|
for_each_node_by_name(dp, "zs")
|
||||||
NUM_SUNZILOG++;
|
NUM_SUNZILOG++;
|
||||||
|
|
||||||
|
uart_count = 0;
|
||||||
if (NUM_SUNZILOG) {
|
if (NUM_SUNZILOG) {
|
||||||
int uart_count;
|
int uart_count;
|
||||||
|
|
||||||
err = sunzilog_alloc_tables();
|
err = sunzilog_alloc_tables();
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
/* Subtract 1 for keyboard, 1 for mouse. */
|
/* Subtract 1 for keyboard, 1 for mouse. */
|
||||||
uart_count = (NUM_SUNZILOG * 2) - 2;
|
uart_count = (NUM_SUNZILOG * 2) - 2;
|
||||||
|
@ -1481,17 +1481,41 @@ static int __init sunzilog_init(void)
|
||||||
sunzilog_reg.nr = uart_count;
|
sunzilog_reg.nr = uart_count;
|
||||||
sunzilog_reg.minor = sunserial_current_minor;
|
sunzilog_reg.minor = sunserial_current_minor;
|
||||||
err = uart_register_driver(&sunzilog_reg);
|
err = uart_register_driver(&sunzilog_reg);
|
||||||
if (err) {
|
if (err)
|
||||||
sunzilog_free_tables();
|
goto out_free_tables;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
|
sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
|
||||||
sunzilog_reg.cons = SUNZILOG_CONSOLE();
|
sunzilog_reg.cons = SUNZILOG_CONSOLE();
|
||||||
|
|
||||||
sunserial_current_minor += uart_count;
|
sunserial_current_minor += uart_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return of_register_driver(&zs_driver, &of_bus_type);
|
err = of_register_driver(&zs_driver, &of_bus_type);
|
||||||
|
if (err)
|
||||||
|
goto out_unregister_uart;
|
||||||
|
|
||||||
|
if (zilog_irq != -1) {
|
||||||
|
err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
|
||||||
|
"zs", sunzilog_irq_chain);
|
||||||
|
if (err)
|
||||||
|
goto out_unregister_driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
|
||||||
|
out_unregister_driver:
|
||||||
|
of_unregister_driver(&zs_driver);
|
||||||
|
|
||||||
|
out_unregister_uart:
|
||||||
|
if (NUM_SUNZILOG) {
|
||||||
|
uart_unregister_driver(&sunzilog_reg);
|
||||||
|
sunzilog_reg.cons = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_free_tables:
|
||||||
|
sunzilog_free_tables();
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit sunzilog_exit(void)
|
static void __exit sunzilog_exit(void)
|
||||||
|
|
Loading…
Reference in New Issue