diff options
author | Christian Gromm <christian.gromm@microchip.com> | 2018-05-08 11:45:09 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-08 13:41:50 +0200 |
commit | 021fa2dbc49b7759945735250b56eba40e5166ce (patch) | |
tree | 3409254d36f6ed0ba9010bd2b083abbcef1ea4f4 /drivers/staging/most | |
parent | 7d56f62d3c4c3217049ef687827303356c8b1766 (diff) | |
download | linux-021fa2dbc49b7759945735250b56eba40e5166ce.tar.gz linux-021fa2dbc49b7759945735250b56eba40e5166ce.tar.bz2 linux-021fa2dbc49b7759945735250b56eba40e5166ce.zip |
staging: most: dim2: fix startup sequence
Platform specific initialization (data->init) has to be done before
calling dim_startup to start the DIM2 IP.
Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/most')
-rw-r--r-- | drivers/staging/most/dim2/dim2.c | 90 |
1 files changed, 39 insertions, 51 deletions
diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 3c385b3fabec..e60efa00312b 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -150,38 +150,6 @@ void dimcb_on_error(u8 error_id, const char *error_message) } /** - * startup_dim - initialize the dim2 interface - * @pdev: platform device - */ -static int startup_dim(struct platform_device *pdev) -{ - struct dim2_hdm *dev = platform_get_drvdata(pdev); - struct dim2_platform_data *pdata = pdev->dev.platform_data; - u8 hal_ret; - int ret; - - if (!pdata) { - pr_err("missing platform data\n"); - return -EINVAL; - } - - ret = pdata->init ? pdata->init(pdata, dev->io_base) : 0; - if (ret) - return ret; - - pr_info("sync: num of frames per sub-buffer: %u\n", fcnt); - hal_ret = dim_startup(dev->io_base, pdata->clk_speed, fcnt); - if (hal_ret != DIM_NO_ERROR) { - pr_err("dim_startup failed: %d\n", hal_ret); - if (pdata && pdata->destroy) - pdata->destroy(pdata); - return -ENODEV; - } - - return 0; -} - -/** * try_start_dim_transfer - try to transfer a buffer on a channel * @hdm_ch: channel specific data * @@ -722,9 +690,11 @@ static void dma_free(struct mbo *mbo, u32 size) */ static int dim2_probe(struct platform_device *pdev) { + struct dim2_platform_data *pdata = pdev->dev.platform_data; struct dim2_hdm *dev; struct resource *res; int ret, i; + u8 hal_ret; int irq; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); @@ -739,38 +709,59 @@ static int dim2_probe(struct platform_device *pdev) if (IS_ERR(dev->io_base)) return PTR_ERR(dev->io_base); + if (!pdata) { + dev_err(&pdev->dev, "missing platform data\n"); + return -EINVAL; + } + + ret = pdata->init ? pdata->init(pdata, dev->io_base) : 0; + if (ret) + return ret; + + dev_info(&pdev->dev, "sync: num of frames per sub-buffer: %u\n", fcnt); + hal_ret = dim_startup(dev->io_base, pdata->clk_speed, fcnt); + if (hal_ret != DIM_NO_ERROR) { + dev_err(&pdev->dev, "dim_startup failed: %d\n", hal_ret); + ret = -ENODEV; + goto err_bsp_destroy; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq); - return irq; + ret = irq; + goto err_shutdown_dim; } ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0, "dim2_ahb0_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq); - return ret; + goto err_shutdown_dim; } irq = platform_get_irq(pdev, 1); if (irq < 0) { dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq); - return irq; + ret = irq; + goto err_shutdown_dim; } ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0, "dim2_mlb_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq); - return ret; + goto err_shutdown_dim; } init_waitqueue_head(&dev->netinfo_waitq); dev->deliver_netinfo = 0; - dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev, + dev->netinfo_task = kthread_run(&deliver_netinfo_thread, dev, "dim2_netinfo"); - if (IS_ERR(dev->netinfo_task)) - return PTR_ERR(dev->netinfo_task); + if (IS_ERR(dev->netinfo_task)) { + ret = PTR_ERR(dev->netinfo_task); + goto err_shutdown_dim; + } for (i = 0; i < DMA_CHANNELS; i++) { struct most_channel_capability *cap = dev->capabilities + i; @@ -829,20 +820,17 @@ static int dim2_probe(struct platform_device *pdev) goto err_unreg_iface; } - ret = startup_dim(pdev); - if (ret) { - dev_err(&pdev->dev, "failed to initialize DIM2\n"); - goto err_destroy_bus; - } - return 0; -err_destroy_bus: - dim2_sysfs_destroy(&dev->dev); err_unreg_iface: most_deregister_interface(&dev->most_iface); err_stop_thread: kthread_stop(dev->netinfo_task); +err_shutdown_dim: + dim_shutdown(); +err_bsp_destroy: + if (pdata && pdata->destroy) + pdata->destroy(pdata); return ret; } @@ -859,6 +847,10 @@ static int dim2_remove(struct platform_device *pdev) struct dim2_platform_data *pdata = pdev->dev.platform_data; unsigned long flags; + dim2_sysfs_destroy(&dev->dev); + most_deregister_interface(&dev->most_iface); + kthread_stop(dev->netinfo_task); + spin_lock_irqsave(&dim_lock, flags); dim_shutdown(); spin_unlock_irqrestore(&dim_lock, flags); @@ -866,10 +858,6 @@ static int dim2_remove(struct platform_device *pdev) if (pdata && pdata->destroy) pdata->destroy(pdata); - dim2_sysfs_destroy(&dev->dev); - most_deregister_interface(&dev->most_iface); - kthread_stop(dev->netinfo_task); - /* * break link to local platform_device_id struct * to prevent crash by unload platform device module |