Commit 021fa2db authored by Christian Gromm's avatar Christian Gromm Committed by Greg Kroah-Hartman
Browse files

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: default avatarChristian Gromm <christian.gromm@microchip.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d56f62d
Loading
Loading
Loading
Loading
+39 −51
Original line number Diff line number Diff line
@@ -149,38 +149,6 @@ void dimcb_on_error(u8 error_id, const char *error_message)
	       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