[PATCH 21/28] staging: most: dim2: fix startup sequence

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
---
 drivers/staging/most/dim2/dim2.c | 90 +++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 51 deletions(-)

diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c
index 3c385b3..e60efa0 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
-- 
2.7.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux