diff options
author | Michal Simek <michal.simek@xilinx.com> | 2018-09-03 15:10:54 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-18 16:07:22 +0200 |
commit | e4bbb5194ea3bc77ab843fe01c9f243cf8c6c6b2 (patch) | |
tree | 6b8a0f0e3138d8dadbd795752744632eb116a3e3 /drivers/tty/serial/xilinx_uartps.c | |
parent | 14090ad1805f93418f69d2f661b6b9bb130b7824 (diff) | |
download | linux-stable-e4bbb5194ea3bc77ab843fe01c9f243cf8c6c6b2.tar.gz linux-stable-e4bbb5194ea3bc77ab843fe01c9f243cf8c6c6b2.tar.bz2 linux-stable-e4bbb5194ea3bc77ab843fe01c9f243cf8c6c6b2.zip |
serial: uartps: Move register to probe based on run time detection
Register uart driver in probe to be able to register one device with
unique major/minor separately. Also calculate number of instances of
this driver to be able to call uart_unregister_driver() when there is no
instance.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/xilinx_uartps.c')
-rw-r--r-- | drivers/tty/serial/xilinx_uartps.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index dff39b424662..382f11c6720c 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1394,6 +1394,9 @@ static const struct of_device_id cdns_uart_of_match[] = { }; MODULE_DEVICE_TABLE(of, cdns_uart_of_match); +/* Temporary variable for storing number of instances */ +static int instances; + /** * cdns_uart_probe - Platform driver probe * @pdev: Pointer to the platform device structure @@ -1426,6 +1429,14 @@ static int cdns_uart_probe(struct platform_device *pdev) return -ENODEV; } + if (!cdns_uart_uart_driver.state) { + rc = uart_register_driver(&cdns_uart_uart_driver); + if (rc < 0) { + dev_err(&pdev->dev, "Failed to register driver\n"); + return rc; + } + } + cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver; match = of_match_node(cdns_uart_of_match, pdev->dev.of_node); @@ -1443,7 +1454,8 @@ static int cdns_uart_probe(struct platform_device *pdev) } if (IS_ERR(cdns_uart_data->pclk)) { dev_err(&pdev->dev, "pclk clock not found.\n"); - return PTR_ERR(cdns_uart_data->pclk); + rc = PTR_ERR(cdns_uart_data->pclk); + goto err_out_unregister_driver; } cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk"); @@ -1454,13 +1466,14 @@ static int cdns_uart_probe(struct platform_device *pdev) } if (IS_ERR(cdns_uart_data->uartclk)) { dev_err(&pdev->dev, "uart_clk clock not found.\n"); - return PTR_ERR(cdns_uart_data->uartclk); + rc = PTR_ERR(cdns_uart_data->uartclk); + goto err_out_unregister_driver; } rc = clk_prepare_enable(cdns_uart_data->pclk); if (rc) { dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); - return rc; + goto err_out_unregister_driver; } rc = clk_prepare_enable(cdns_uart_data->uartclk); if (rc) { @@ -1539,6 +1552,7 @@ static int cdns_uart_probe(struct platform_device *pdev) console_port = NULL; #endif + instances++; return 0; err_out_pm_disable: @@ -1553,7 +1567,9 @@ err_out_clk_disable: clk_disable_unprepare(cdns_uart_data->uartclk); err_out_clk_dis_pclk: clk_disable_unprepare(cdns_uart_data->pclk); - +err_out_unregister_driver: + if (!instances) + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); return rc; } @@ -1581,6 +1597,8 @@ static int cdns_uart_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); + if (!--instances) + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); return rc; } @@ -1596,28 +1614,14 @@ static struct platform_driver cdns_uart_platform_driver = { static int __init cdns_uart_init(void) { - int retval = 0; - - /* Register the cdns_uart driver with the serial core */ - retval = uart_register_driver(&cdns_uart_uart_driver); - if (retval) - return retval; - /* Register the platform driver */ - retval = platform_driver_register(&cdns_uart_platform_driver); - if (retval) - uart_unregister_driver(&cdns_uart_uart_driver); - - return retval; + return platform_driver_register(&cdns_uart_platform_driver); } static void __exit cdns_uart_exit(void) { /* Unregister the platform driver */ platform_driver_unregister(&cdns_uart_platform_driver); - - /* Unregister the cdns_uart driver */ - uart_unregister_driver(&cdns_uart_uart_driver); } arch_initcall(cdns_uart_init); |