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 = {
#define AMBA_CONSOLE NULL
#endif
static DEFINE_MUTEX(amba_reg_lock);
static struct uart_driver amba_reg = {
.owner = THIS_MODULE,
.driver_name = "ttyAM",
......@@ -749,6 +750,19 @@ static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
amba_ports[i] = 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);
if (ret)
amba_ports[i] = NULL;
......@@ -760,12 +774,18 @@ static int pl010_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);
int i;
bool busy = false;
uart_remove_one_port(&amba_reg, &uap->port);
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
else if (amba_ports[i])
busy = true;
if (!busy)
uart_unregister_driver(&amba_reg);
return 0;
}
......@@ -816,23 +836,14 @@ static struct amba_driver pl010_driver = {
static int __init pl010_init(void)
{
int ret;
printk(KERN_INFO "Serial: AMBA driver\n");
ret = uart_register_driver(&amba_reg);
if (ret == 0) {
ret = amba_driver_register(&pl010_driver);
if (ret)
uart_unregister_driver(&amba_reg);
}
return ret;
return amba_driver_register(&pl010_driver);
}
static void __exit pl010_exit(void)
{
amba_driver_unregister(&pl010_driver);
uart_unregister_driver(&amba_reg);
}
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