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

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
...@@ -149,38 +149,6 @@ void dimcb_on_error(u8 error_id, const char *error_message) ...@@ -149,38 +149,6 @@ void dimcb_on_error(u8 error_id, const char *error_message)
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 * try_start_dim_transfer - try to transfer a buffer on a channel
* @hdm_ch: channel specific data * @hdm_ch: channel specific data
...@@ -722,9 +690,11 @@ static void dma_free(struct mbo *mbo, u32 size) ...@@ -722,9 +690,11 @@ static void dma_free(struct mbo *mbo, u32 size)
*/ */
static int dim2_probe(struct platform_device *pdev) static int dim2_probe(struct platform_device *pdev)
{ {
struct dim2_platform_data *pdata = pdev->dev.platform_data;
struct dim2_hdm *dev; struct dim2_hdm *dev;
struct resource *res; struct resource *res;
int ret, i; int ret, i;
u8 hal_ret;
int irq; int irq;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
...@@ -739,38 +709,59 @@ static int dim2_probe(struct platform_device *pdev) ...@@ -739,38 +709,59 @@ static int dim2_probe(struct platform_device *pdev)
if (IS_ERR(dev->io_base)) if (IS_ERR(dev->io_base))
return PTR_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); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq); 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, ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0,
"dim2_ahb0_int", dev); "dim2_ahb0_int", dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq); 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); irq = platform_get_irq(pdev, 1);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq); 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, ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0,
"dim2_mlb_int", dev); "dim2_mlb_int", dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq); 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); init_waitqueue_head(&dev->netinfo_waitq);
dev->deliver_netinfo = 0; 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"); "dim2_netinfo");
if (IS_ERR(dev->netinfo_task)) if (IS_ERR(dev->netinfo_task)) {
return PTR_ERR(dev->netinfo_task); ret = PTR_ERR(dev->netinfo_task);
goto err_shutdown_dim;
}
for (i = 0; i < DMA_CHANNELS; i++) { for (i = 0; i < DMA_CHANNELS; i++) {
struct most_channel_capability *cap = dev->capabilities + i; struct most_channel_capability *cap = dev->capabilities + i;
...@@ -829,20 +820,17 @@ static int dim2_probe(struct platform_device *pdev) ...@@ -829,20 +820,17 @@ static int dim2_probe(struct platform_device *pdev)
goto err_unreg_iface; 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; return 0;
err_destroy_bus:
dim2_sysfs_destroy(&dev->dev);
err_unreg_iface: err_unreg_iface:
most_deregister_interface(&dev->most_iface); most_deregister_interface(&dev->most_iface);
err_stop_thread: err_stop_thread:
kthread_stop(dev->netinfo_task); kthread_stop(dev->netinfo_task);
err_shutdown_dim:
dim_shutdown();
err_bsp_destroy:
if (pdata && pdata->destroy)
pdata->destroy(pdata);
return ret; return ret;
} }
...@@ -859,6 +847,10 @@ static int dim2_remove(struct platform_device *pdev) ...@@ -859,6 +847,10 @@ static int dim2_remove(struct platform_device *pdev)
struct dim2_platform_data *pdata = pdev->dev.platform_data; struct dim2_platform_data *pdata = pdev->dev.platform_data;
unsigned long flags; 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); spin_lock_irqsave(&dim_lock, flags);
dim_shutdown(); dim_shutdown();
spin_unlock_irqrestore(&dim_lock, flags); spin_unlock_irqrestore(&dim_lock, flags);
...@@ -866,10 +858,6 @@ static int dim2_remove(struct platform_device *pdev) ...@@ -866,10 +858,6 @@ static int dim2_remove(struct platform_device *pdev)
if (pdata && pdata->destroy) if (pdata && pdata->destroy)
pdata->destroy(pdata); 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 * break link to local platform_device_id struct
* to prevent crash by unload platform device module * to prevent crash by unload platform device module
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment