From f3fd93c1c6cc4d9ab5c6e9f4d7475f75e1b659b8 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Tue, 25 Feb 2020 17:57:31 +0100 Subject: USB: MUSB: defer driver probes where necessary Kernel commit 0782e8572c ("ARM: dts: Probe am335x musb with ti-sysc") which we pulled in during the v2020.02.0 dts/ sync moved the USB nodes to be under a ti-sysc bus instead of ti,am33xx-usb. This new probe order broke am335x USB under barebox, because the MUSB drivers couldn't cope with the now different device probe order. Pepper some -EPROBE_DEFER around to make USB work again. Fixes: 574eed3f6f ("dts: update to v5.5-rc1") Reported-by: Yegor Yefremov Signed-off-by: Ahmad Fatoum Tested-by: Yegor Yefremov Signed-off-by: Sascha Hauer --- drivers/usb/musb/musb_core.c | 5 +++-- drivers/usb/musb/musb_dsps.c | 39 +++++++++++++++++++++++++---------- drivers/usb/musb/phy-am335x-control.c | 25 +++++++++++++++------- drivers/usb/musb/phy-am335x.c | 11 +++++++--- 4 files changed, 57 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4c11e6580c..b84da5516c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1136,8 +1136,9 @@ fail2: musb_platform_exit(musb); fail1: - dev_err(musb->controller, - "musb_init_controller failed with status %d\n", status); + if (status != -EPROBE_DEFER) + dev_err(musb->controller, + "musb_init_controller failed with status %d\n", status); musb_free(musb); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index f306729148..d54a663e9d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -314,7 +314,7 @@ static int dsps_set_mode(void *ctx, enum usb_dr_mode mode) static int dsps_probe(struct device_d *dev) { - struct resource *iores; + struct resource *iores[2]; struct musb_hdrc_platform_data *pdata; struct musb_hdrc_config *config; struct device_node *dn = dev->device_node; @@ -354,15 +354,19 @@ static int dsps_probe(struct device_d *dev) pdata = &glue->pdata; - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); - glue->musb.mregs = IOMEM(iores->start); + iores[0] = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores[0])) { + ret = PTR_ERR(iores[0]); + goto free_glue; + } + glue->musb.mregs = IOMEM(iores[0]->start); - iores = dev_request_mem_resource(dev, 1); - if (IS_ERR(iores)) - return PTR_ERR(iores); - glue->musb.ctrl_base = IOMEM(iores->start); + iores[1] = dev_request_mem_resource(dev, 1); + if (IS_ERR(iores[1])) { + ret = PTR_ERR(iores[1]); + goto release_iores0; + } + glue->musb.ctrl_base = IOMEM(iores[1]->start); glue->musb.controller = dev; glue->musb.xceiv = phy_dev->priv; @@ -383,11 +387,24 @@ static int dsps_probe(struct device_d *dev) if (pdata->mode == MUSB_PORT_MODE_DUAL_ROLE) { ret = usb_register_otg_device(dev, dsps_set_mode, glue); if (ret) - return ret; + goto release_iores1; return 0; } - return musb_init_controller(&glue->musb, pdata); + ret = musb_init_controller(&glue->musb, pdata); + if (ret) + goto release_iores1; + + return 0; + +release_iores1: + release_region(iores[1]); +release_iores0: + release_region(iores[0]); +free_glue: + free(glue); + + return ret; } static const struct dsps_musb_wrapper am33xx_driver_data = { diff --git a/drivers/usb/musb/phy-am335x-control.c b/drivers/usb/musb/phy-am335x-control.c index c84525ec7e..41a3689ed3 100644 --- a/drivers/usb/musb/phy-am335x-control.c +++ b/drivers/usb/musb/phy-am335x-control.c @@ -109,15 +109,15 @@ struct phy_control *am335x_get_phy_control(struct device_d *dev) node = of_parse_phandle(dev->device_node, "ti,ctrl_mod", 0); if (!node) - return NULL; + return ERR_PTR(-ENOENT); dev = of_find_device_by_node(node); if (!dev) - return NULL; + return ERR_PTR(-EPROBE_DEFER); ctrl_usb = dev->priv; if (!ctrl_usb) - return NULL; + return ERR_PTR(-EPROBE_DEFER); return &ctrl_usb->phy_ctrl; } @@ -141,13 +141,17 @@ static int am335x_control_usb_probe(struct device_d *dev) ctrl_usb->dev = dev; iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); + if (IS_ERR(iores)) { + ret = PTR_ERR(iores); + goto free_ctrl; + } ctrl_usb->phy_reg = IOMEM(iores->start); iores = dev_request_mem_resource(dev, 1); - if (IS_ERR(iores)) - return PTR_ERR(iores); + if (IS_ERR(iores)) { + ret = PTR_ERR(iores); + goto release_resource; + } ctrl_usb->wkup = IOMEM(iores->start); spin_lock_init(&ctrl_usb->lock); @@ -155,6 +159,13 @@ static int am335x_control_usb_probe(struct device_d *dev) dev->priv = ctrl_usb; return 0; + +release_resource: + release_region(iores); +free_ctrl: + free(ctrl_usb); + + return 0; }; static struct driver_d am335x_control_driver = { diff --git a/drivers/usb/musb/phy-am335x.c b/drivers/usb/musb/phy-am335x.c index 6991f4402d..f2e870d7ee 100644 --- a/drivers/usb/musb/phy-am335x.c +++ b/drivers/usb/musb/phy-am335x.c @@ -37,13 +37,16 @@ static int am335x_phy_probe(struct device_d *dev) am_usbphy->base = IOMEM(iores->start); am_usbphy->phy_ctrl = am335x_get_phy_control(dev); - if (!am_usbphy->phy_ctrl) - return -ENODEV; + if (IS_ERR(am_usbphy->phy_ctrl)) { + ret = PTR_ERR(am_usbphy->phy_ctrl); + goto err_release; + } am_usbphy->id = of_alias_get_id(dev->device_node, "phy"); if (am_usbphy->id < 0) { dev_err(dev, "Missing PHY id: %d\n", am_usbphy->id); - return am_usbphy->id; + ret = am_usbphy->id; + goto err_release; } am_usbphy->phy.init = am335x_init; @@ -53,6 +56,8 @@ static int am335x_phy_probe(struct device_d *dev) return 0; +err_release: + release_region(iores); err_free: free(am_usbphy); -- cgit v1.2.3