summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-10-26 10:57:00 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-10-29 11:26:35 +0100
commit28b38c1804d761257397f41ae2bbc071cd009935 (patch)
treede0d9053eb521b2cadbf0450d73f396b8dad20ca /drivers
parent7da5b5cd93050ce264ba36556f2f2720a0a39acd (diff)
downloadbarebox-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.c30
-rw-r--r--drivers/usb/imx/chipidea-imx.c13
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[] = {