diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-12-01 18:14:54 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-12-01 18:14:54 +0100 |
commit | a4861761e563568c2617851987eb2801dcc325f2 (patch) | |
tree | 834f5a5c4c62ec9e475a800155fbed9f1d6216d9 | |
parent | Linux 4.4-rc3 (diff) | |
parent | usb: dwc2: fix kernel oops during driver probe (diff) | |
download | linux-a4861761e563568c2617851987eb2801dcc325f2.tar.xz linux-a4861761e563568c2617851987eb2801dcc325f2.zip |
Merge tag 'fixes-for-v4.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes:
usb: fixes for v4.4-rc3
Here's our second round of fixes. Some of the bugs are pretty old like
the one on pxa27x suspend implementation.
The most important part is a randbuild warning fix on MUSB CPPI DMA
engine by Arnd, a couple fixes by Felipe Tonello on f_midi (first one
makes sure we only transmit on enabled ep IN while second plugs a memory
leak) and a NULL pointer dereference fix on renesas usbhs.
Note that we also have a new compatible string being added for the MXS
PHY.
-rw-r--r-- | drivers/usb/dwc2/platform.c | 81 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_midi.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/pxa27x_udc.c | 3 | ||||
-rw-r--r-- | drivers/usb/musb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/phy/phy-mxs-usb.c | 5 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 11 |
7 files changed, 76 insertions, 35 deletions
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index e61d773cf65e..39c1cbf0e75d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) if (ret) return ret; - ret = clk_prepare_enable(hsotg->clk); - if (ret) - return ret; + if (hsotg->clk) { + ret = clk_prepare_enable(hsotg->clk); + if (ret) + return ret; + } if (hsotg->uphy) ret = usb_phy_init(hsotg->uphy); @@ -175,7 +177,8 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (ret) return ret; - clk_disable_unprepare(hsotg->clk); + if (hsotg->clk) + clk_disable_unprepare(hsotg->clk); ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) */ hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); if (IS_ERR(hsotg->phy)) { - hsotg->phy = NULL; + ret = PTR_ERR(hsotg->phy); + switch (ret) { + case -ENODEV: + case -ENOSYS: + hsotg->phy = NULL; + break; + case -EPROBE_DEFER: + return ret; + default: + dev_err(hsotg->dev, "error getting phy %d\n", ret); + return ret; + } + } + + if (!hsotg->phy) { hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2); - if (IS_ERR(hsotg->uphy)) - hsotg->uphy = NULL; - else - hsotg->plat = dev_get_platdata(hsotg->dev); + if (IS_ERR(hsotg->uphy)) { + ret = PTR_ERR(hsotg->uphy); + switch (ret) { + case -ENODEV: + case -ENXIO: + hsotg->uphy = NULL; + break; + case -EPROBE_DEFER: + return ret; + default: + dev_err(hsotg->dev, "error getting usb phy %d\n", + ret); + return ret; + } + } } + hsotg->plat = dev_get_platdata(hsotg->dev); + if (hsotg->phy) { /* * If using the generic PHY framework, check if the PHY bus @@ -229,11 +259,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) hsotg->phyif = GUSBCFG_PHYIF8; } - if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) { - dev_err(hsotg->dev, "no platform data or transceiver defined\n"); - return -EPROBE_DEFER; - } - /* Clock */ hsotg->clk = devm_clk_get(hsotg->dev, "otg"); if (IS_ERR(hsotg->clk)) { @@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; - irq = platform_get_irq(dev, 0); - if (irq < 0) { - dev_err(&dev->dev, "missing IRQ resource\n"); - return irq; - } - - dev_dbg(hsotg->dev, "registering common handler for irq%d\n", - irq); - retval = devm_request_irq(hsotg->dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg->dev), hsotg); - if (retval) - return retval; - res = platform_get_resource(dev, IORESOURCE_MEM, 0); hsotg->regs = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(hsotg->regs)) @@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_set_all_params(hsotg->core_params, -1); + irq = platform_get_irq(dev, 0); + if (irq < 0) { + dev_err(&dev->dev, "missing IRQ resource\n"); + return irq; + } + + dev_dbg(hsotg->dev, "registering common handler for irq%d\n", + irq); + retval = devm_request_irq(hsotg->dev, irq, + dwc2_handle_common_intr, IRQF_SHARED, + dev_name(hsotg->dev), hsotg); + if (retval) + return retval; + retval = dwc2_lowlevel_hw_enable(hsotg); if (retval) return retval; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index adc6d52efa46..cf43e9e18368 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, spin_unlock_irq(&ffs->ev.waitq.lock); mutex_unlock(&ffs->mutex); - return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size; + return unlikely(copy_to_user(buf, events, size)) ? -EFAULT : size; } static ssize_t ffs_ep0_read(struct file *file, char __user *buf, @@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, /* unlocks spinlock */ ret = __ffs_ep0_queue_wait(ffs, data, len); - if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len))) + if (likely(ret > 0) && unlikely(copy_to_user(buf, data, len))) ret = -EFAULT; goto done_mutex; @@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len) if (unlikely(!data)) return ERR_PTR(-ENOMEM); - if (unlikely(__copy_from_user(data, buf, len))) { + if (unlikely(copy_from_user(data, buf, len))) { kfree(data); return ERR_PTR(-EFAULT); } diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 42acb45e1ab4..898a570319f1 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) { ERROR(midi, "%s queue req: %d\n", midi->out_ep->name, err); + free_ep_req(midi->out_ep, req); } } @@ -545,7 +546,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) } } - if (req->length > 0) { + if (req->length > 0 && ep->enabled) { int err; err = usb_ep_queue(ep, req, GFP_ATOMIC); diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 670ac0b12f00..001a3b74a993 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) udc->pullup_resume = udc->pullup_on; dplus_pullup(udc, 0); + if (udc->driver) + udc->driver->disconnect(&udc->gadget); + return 0; } diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 1f2037bbeb0d..45c83baf675d 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA config USB_TI_CPPI41_DMA bool 'TI CPPI 4.1 (AM335x)' - depends on ARCH_OMAP + depends on ARCH_OMAP && DMADEVICES select TI_CPPI41 config USB_TUSB_OMAP_DMA diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index b7536af777ab..c2936dc48ca7 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -143,12 +143,17 @@ static const struct mxs_phy_data imx6sx_phy_data = { .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, }; +static const struct mxs_phy_data imx6ul_phy_data = { + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, +}; + static const struct of_device_id mxs_phy_dt_ids[] = { { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, }, { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, }, + { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index de4f97d84a82..8f7a78e70975 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -131,7 +131,8 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep, struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); - dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); + if (pipe) + dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); ureq->req.status = status; spin_unlock(usbhs_priv_to_lock(priv)); @@ -685,7 +686,13 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); - usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); + if (pipe) + usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); + + /* + * To dequeue a request, this driver should call the usbhsg_queue_pop() + * even if the pipe is NULL. + */ usbhsg_queue_pop(uep, ureq, -ECONNRESET); return 0; |