Commit bd8766b1 authored by Sjoerd Simons's avatar Sjoerd Simons Committed by Greg Kroah-Hartman

serial: pl010: Move uart_register_driver call to device probe

uart_register_driver call binds the driver to a specific device
node through tty_register_driver call. This should typically
happen during device probe call.

In a multiplatform scenario, it is possible that multiple serial
drivers are part of the kernel. Currently the driver registration fails
if multiple serial drivers with overlapping major/minor numbers are
included.
Signed-off-by: default avatarSjoerd Simons <sjoerd.simons@collabora.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1cf4a7ef
...@@ -697,6 +697,7 @@ static struct console amba_console = { ...@@ -697,6 +697,7 @@ static struct console amba_console = {
#define AMBA_CONSOLE NULL #define AMBA_CONSOLE NULL
#endif #endif
static DEFINE_MUTEX(amba_reg_lock);
static struct uart_driver amba_reg = { static struct uart_driver amba_reg = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.driver_name = "ttyAM", .driver_name = "ttyAM",
...@@ -749,6 +750,19 @@ static int pl010_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -749,6 +750,19 @@ static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
amba_ports[i] = uap; amba_ports[i] = uap;
amba_set_drvdata(dev, uap); amba_set_drvdata(dev, uap);
mutex_lock(&amba_reg_lock);
if (!amba_reg.state) {
ret = uart_register_driver(&amba_reg);
if (ret < 0) {
mutex_unlock(&amba_reg_lock);
dev_err(uap->port.dev,
"Failed to register AMBA-PL010 driver\n");
return ret;
}
}
mutex_unlock(&amba_reg_lock);
ret = uart_add_one_port(&amba_reg, &uap->port); ret = uart_add_one_port(&amba_reg, &uap->port);
if (ret) if (ret)
amba_ports[i] = NULL; amba_ports[i] = NULL;
...@@ -760,12 +774,18 @@ static int pl010_remove(struct amba_device *dev) ...@@ -760,12 +774,18 @@ static int pl010_remove(struct amba_device *dev)
{ {
struct uart_amba_port *uap = amba_get_drvdata(dev); struct uart_amba_port *uap = amba_get_drvdata(dev);
int i; int i;
bool busy = false;
uart_remove_one_port(&amba_reg, &uap->port); uart_remove_one_port(&amba_reg, &uap->port);
for (i = 0; i < ARRAY_SIZE(amba_ports); i++) for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap) if (amba_ports[i] == uap)
amba_ports[i] = NULL; amba_ports[i] = NULL;
else if (amba_ports[i])
busy = true;
if (!busy)
uart_unregister_driver(&amba_reg);
return 0; return 0;
} }
...@@ -816,23 +836,14 @@ static struct amba_driver pl010_driver = { ...@@ -816,23 +836,14 @@ static struct amba_driver pl010_driver = {
static int __init pl010_init(void) static int __init pl010_init(void)
{ {
int ret;
printk(KERN_INFO "Serial: AMBA driver\n"); printk(KERN_INFO "Serial: AMBA driver\n");
ret = uart_register_driver(&amba_reg); return amba_driver_register(&pl010_driver);
if (ret == 0) {
ret = amba_driver_register(&pl010_driver);
if (ret)
uart_unregister_driver(&amba_reg);
}
return ret;
} }
static void __exit pl010_exit(void) static void __exit pl010_exit(void)
{ {
amba_driver_unregister(&pl010_driver); amba_driver_unregister(&pl010_driver);
uart_unregister_driver(&amba_reg);
} }
module_init(pl010_init); module_init(pl010_init);
......
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