summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-10-16 12:50:08 +0200
committerFelipe Balbi <balbi@ti.com>2013-10-17 11:32:08 -0500
commit4805414705df77d946b41df4f8b315e2b089eec4 (patch)
tree6473991e3baed083623eea274af5472327347cea /drivers/usb
parent8d1aad7485e653c2c5fd985b326096f680f7d918 (diff)
downloadlinux-4805414705df77d946b41df4f8b315e2b089eec4.tar.gz
linux-4805414705df77d946b41df4f8b315e2b089eec4.tar.bz2
linux-4805414705df77d946b41df4f8b315e2b089eec4.zip
usb: musb: cppi41: allow to defer probing if DMA isn't yet available
If everything (musb, cppi41, phy) is built-in then musb will start without the dma engine printing only |musb-hdrc musb-hdrc.0.auto: Falied to request rx1. The reason for this is that the musb device structs are created & probed before those of the cppi41 device. So the cppi41 device is probed too late. As a workaround for this allow the musb_cppi41 part to defer the probe if everything is fine except for the missing DMA controller. In case of another error we continue. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/musb_core.c8
-rw-r--r--drivers/usb/musb/musb_cppi41.c8
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 7fd213785d52..4db987f07f67 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1838,8 +1838,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
pm_runtime_get_sync(musb->controller);
- if (use_dma && dev->dma_mask)
+ if (use_dma && dev->dma_mask) {
musb->dma_controller = dma_controller_create(musb, musb->mregs);
+ if (IS_ERR(musb->dma_controller)) {
+ status = PTR_ERR(musb->dma_controller);
+ goto fail2_5;
+ }
+ }
/* be sure interrupts are disabled before connecting ISR */
musb_platform_disable(musb);
@@ -1932,6 +1937,7 @@ fail4:
fail3:
if (musb->dma_controller)
dma_controller_destroy(musb->dma_controller);
+fail2_5:
pm_runtime_put_sync(musb->controller);
fail2:
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index ae959746f77f..ff9d6de2b746 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -484,6 +484,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
if (ret)
goto err;
+ ret = -EINVAL;
if (port > MUSB_DMA_NUM_CHANNELS || !port)
goto err;
if (is_tx)
@@ -503,6 +504,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
dc = dma_request_slave_channel(dev, str);
if (!dc) {
dev_err(dev, "Falied to request %s.\n", str);
+ ret = -EPROBE_DEFER;
goto err;
}
cppi41_channel->dc = dc;
@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
return 0;
err:
cppi41_release_all_dma_chans(controller);
- return -EINVAL;
+ return ret;
}
void dma_controller_destroy(struct dma_controller *c)
@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
void __iomem *base)
{
struct cppi41_dma_controller *controller;
- int ret;
+ int ret = 0;
if (!musb->controller->of_node) {
dev_err(musb->controller, "Need DT for the DMA engine.\n");
@@ -553,5 +555,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
plat_get_fail:
kfree(controller);
kzalloc_fail:
+ if (ret == -EPROBE_DEFER)
+ return ERR_PTR(ret);
return NULL;
}