diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-10-26 10:57:00 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-10-29 11:26:35 +0100 |
commit | 28b38c1804d761257397f41ae2bbc071cd009935 (patch) | |
tree | de0d9053eb521b2cadbf0450d73f396b8dad20ca /drivers | |
parent | 7da5b5cd93050ce264ba36556f2f2720a0a39acd (diff) | |
download | barebox-28b38c1804d761257397f41ae2bbc071cd009935.tar.gz barebox-28b38c1804d761257397f41ae2bbc071cd009935.tar.xz |
usb: gadget: fsl_udc: pass controller instance to unregister
ci_udc_unregister() used to unregister "the controller". Since we
may register multiple chipidea devices we called ci_udc_unregister()
for each of them. This led to messages like:
ERROR: imx-usb 53f80000.usb: gadget not registered.
Fix this by returning the registered controller. This allows us to call
ci_udc_unregister() only when we actually registered one before.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/fsl_udc.c | 30 | ||||
-rw-r--r-- | drivers/usb/imx/chipidea-imx.c | 13 |
2 files changed, 30 insertions, 13 deletions
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c index 7782d4bdd9..061ee5185f 100644 --- a/drivers/usb/gadget/fsl_udc.c +++ b/drivers/usb/gadget/fsl_udc.c @@ -528,7 +528,6 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) static struct usb_dr_device __iomem *dr_regs; -static struct fsl_udc *udc_controller = NULL; static const struct usb_endpoint_descriptor fsl_ep0_desc = { @@ -2226,8 +2225,9 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, return 0; } -int ci_udc_register(struct device_d *dev, void __iomem *regs) +struct fsl_udc *ci_udc_register(struct device_d *dev, void __iomem *regs) { + struct fsl_udc *udc_controller; int ret, i; u32 dccparams; @@ -2293,31 +2293,41 @@ int ci_udc_register(struct device_d *dev, void __iomem *regs) if (ret) goto err_out; - return 0; + return udc_controller; err_out: - return ret; + free(udc_controller); + + return ERR_PTR(ret); } -void ci_udc_unregister(void) +void ci_udc_unregister(struct fsl_udc *udc) { - if (udc_controller) - usb_del_gadget_udc(&udc_controller->gadget); - + usb_del_gadget_udc(&udc->gadget); + free(udc); } static int fsl_udc_probe(struct device_d *dev) { + struct fsl_udc *udc; void __iomem *regs = dev_request_mem_region(dev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); - return ci_udc_register(dev, regs); + udc = ci_udc_register(dev, regs); + if (IS_ERR(udc)) + return PTR_ERR(udc); + + dev->priv = udc; + + return 0; } static void fsl_udc_remove(struct device_d *dev) { - ci_udc_unregister(); + struct fsl_udc *udc = dev->priv; + + ci_udc_unregister(udc); } static struct driver_d fsl_udc_driver = { diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index 7bf2ef76c5..8792217706 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -47,6 +47,7 @@ struct imx_chipidea { struct usb_phy *usbphy; struct clk *clk; struct ehci_host *ehci; + struct fsl_udc *udc; }; static int imx_chipidea_port_init(void *drvdata) @@ -216,8 +217,14 @@ static int ci_register_role(struct imx_chipidea *ci) if (ci->mode == IMX_USB_MODE_DEVICE) { if (IS_ENABLED(CONFIG_USB_GADGET_DRIVER_ARC)) { + struct fsl_udc *udc; ci->role_registered = IMX_USB_MODE_DEVICE; - return ci_udc_register(ci->dev, ci->base); + + udc = ci_udc_register(ci->dev, ci->base); + if (IS_ERR(udc)) + return PTR_ERR(udc); + + ci->udc = udc; } else { dev_err(ci->dev, "USB device support not available\n"); return -ENODEV; @@ -369,8 +376,8 @@ static void imx_chipidea_remove(struct device_d *dev) if (ci->ehci) ehci_unregister(ci->ehci); - if (IS_ENABLED(CONFIG_USB_GADGET_DRIVER_ARC)) - ci_udc_unregister(); + if (IS_ENABLED(CONFIG_USB_GADGET_DRIVER_ARC) && ci->udc) + ci_udc_unregister(ci->udc); } static __maybe_unused struct of_device_id imx_chipidea_dt_ids[] = { |