aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/most
diff options
context:
space:
mode:
authorChristian Gromm <christian.gromm@microchip.com>2018-05-08 11:45:09 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-05-08 13:41:50 +0200
commit021fa2dbc49b7759945735250b56eba40e5166ce (patch)
tree3409254d36f6ed0ba9010bd2b083abbcef1ea4f4 /drivers/staging/most
parentstaging: most: cdev: fix function return value (diff)
downloadlinux-dev-021fa2dbc49b7759945735250b56eba40e5166ce.tar.xz
linux-dev-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.c90
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