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@xxxxxxxxxxxxx> --- drivers/usb/musb/musb_core.c | 8 +++++++- drivers/usb/musb/musb_cppi41.c | 8 ++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index a5f645b..e5ad77d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1882,8 +1882,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); @@ -1976,6 +1981,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) 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 ae95974..ff9d6de 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; } -- 1.8.4.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html