[PATCH 3/3] usb: musb: cppi41: allow to defer probing if DMA isn't yet available

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux