Commit 48054147 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Felipe Balbi

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: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 8d1aad74
...@@ -1838,8 +1838,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1838,8 +1838,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
pm_runtime_get_sync(musb->controller); 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); 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 */ /* be sure interrupts are disabled before connecting ISR */
musb_platform_disable(musb); musb_platform_disable(musb);
...@@ -1932,6 +1937,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1932,6 +1937,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
fail3: fail3:
if (musb->dma_controller) if (musb->dma_controller)
dma_controller_destroy(musb->dma_controller); dma_controller_destroy(musb->dma_controller);
fail2_5:
pm_runtime_put_sync(musb->controller); pm_runtime_put_sync(musb->controller);
fail2: fail2:
......
...@@ -484,6 +484,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ...@@ -484,6 +484,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
if (ret) if (ret)
goto err; goto err;
ret = -EINVAL;
if (port > MUSB_DMA_NUM_CHANNELS || !port) if (port > MUSB_DMA_NUM_CHANNELS || !port)
goto err; goto err;
if (is_tx) if (is_tx)
...@@ -503,6 +504,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ...@@ -503,6 +504,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
dc = dma_request_slave_channel(dev, str); dc = dma_request_slave_channel(dev, str);
if (!dc) { if (!dc) {
dev_err(dev, "Falied to request %s.\n", str); dev_err(dev, "Falied to request %s.\n", str);
ret = -EPROBE_DEFER;
goto err; goto err;
} }
cppi41_channel->dc = dc; cppi41_channel->dc = dc;
...@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ...@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
return 0; return 0;
err: err:
cppi41_release_all_dma_chans(controller); cppi41_release_all_dma_chans(controller);
return -EINVAL; return ret;
} }
void dma_controller_destroy(struct dma_controller *c) void dma_controller_destroy(struct dma_controller *c)
...@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, ...@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
void __iomem *base) void __iomem *base)
{ {
struct cppi41_dma_controller *controller; struct cppi41_dma_controller *controller;
int ret; int ret = 0;
if (!musb->controller->of_node) { if (!musb->controller->of_node) {
dev_err(musb->controller, "Need DT for the DMA engine.\n"); dev_err(musb->controller, "Need DT for the DMA engine.\n");
...@@ -553,5 +555,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, ...@@ -553,5 +555,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
plat_get_fail: plat_get_fail:
kfree(controller); kfree(controller);
kzalloc_fail: kzalloc_fail:
if (ret == -EPROBE_DEFER)
return ERR_PTR(ret);
return NULL; return NULL;
} }
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