Commit a4861761 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'fixes-for-v4.4-rc3' of...

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.
parents 31ade3b8 f74875dc
...@@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) ...@@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
if (ret) if (ret)
return ret; return ret;
if (hsotg->clk) {
ret = clk_prepare_enable(hsotg->clk); ret = clk_prepare_enable(hsotg->clk);
if (ret) if (ret)
return ret; return ret;
}
if (hsotg->uphy) if (hsotg->uphy)
ret = usb_phy_init(hsotg->uphy); ret = usb_phy_init(hsotg->uphy);
...@@ -175,6 +177,7 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) ...@@ -175,6 +177,7 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
if (ret) if (ret)
return ret; return ret;
if (hsotg->clk)
clk_disable_unprepare(hsotg->clk); clk_disable_unprepare(hsotg->clk);
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
...@@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) ...@@ -212,14 +215,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
*/ */
hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
if (IS_ERR(hsotg->phy)) { if (IS_ERR(hsotg->phy)) {
ret = PTR_ERR(hsotg->phy);
switch (ret) {
case -ENODEV:
case -ENOSYS:
hsotg->phy = NULL; 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); hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
if (IS_ERR(hsotg->uphy)) if (IS_ERR(hsotg->uphy)) {
ret = PTR_ERR(hsotg->uphy);
switch (ret) {
case -ENODEV:
case -ENXIO:
hsotg->uphy = NULL; hsotg->uphy = NULL;
else break;
hsotg->plat = dev_get_platdata(hsotg->dev); 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 (hsotg->phy) {
/* /*
* If using the generic PHY framework, check if the PHY bus * 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) ...@@ -229,11 +259,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
hsotg->phyif = GUSBCFG_PHYIF8; 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 */ /* Clock */
hsotg->clk = devm_clk_get(hsotg->dev, "otg"); hsotg->clk = devm_clk_get(hsotg->dev, "otg");
if (IS_ERR(hsotg->clk)) { if (IS_ERR(hsotg->clk)) {
...@@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev) ...@@ -342,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
if (retval) if (retval)
return 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); res = platform_get_resource(dev, IORESOURCE_MEM, 0);
hsotg->regs = devm_ioremap_resource(&dev->dev, res); hsotg->regs = devm_ioremap_resource(&dev->dev, res);
if (IS_ERR(hsotg->regs)) if (IS_ERR(hsotg->regs))
...@@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev) ...@@ -390,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev)
dwc2_set_all_params(hsotg->core_params, -1); 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); retval = dwc2_lowlevel_hw_enable(hsotg);
if (retval) if (retval)
return retval; return retval;
......
...@@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, ...@@ -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); spin_unlock_irq(&ffs->ev.waitq.lock);
mutex_unlock(&ffs->mutex); 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, 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, ...@@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
/* unlocks spinlock */ /* unlocks spinlock */
ret = __ffs_ep0_queue_wait(ffs, data, len); 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; ret = -EFAULT;
goto done_mutex; goto done_mutex;
...@@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len) ...@@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
if (unlikely(!data)) if (unlikely(!data))
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (unlikely(__copy_from_user(data, buf, len))) { if (unlikely(copy_from_user(data, buf, len))) {
kfree(data); kfree(data);
return ERR_PTR(-EFAULT); return ERR_PTR(-EFAULT);
} }
......
...@@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -370,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
if (err) { if (err) {
ERROR(midi, "%s queue req: %d\n", ERROR(midi, "%s queue req: %d\n",
midi->out_ep->name, err); 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) ...@@ -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; int err;
err = usb_ep_queue(ep, req, GFP_ATOMIC); err = usb_ep_queue(ep, req, GFP_ATOMIC);
......
...@@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) ...@@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
udc->pullup_resume = udc->pullup_on; udc->pullup_resume = udc->pullup_on;
dplus_pullup(udc, 0); dplus_pullup(udc, 0);
if (udc->driver)
udc->driver->disconnect(&udc->gadget);
return 0; return 0;
} }
......
...@@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA ...@@ -159,7 +159,7 @@ config USB_TI_CPPI_DMA
config USB_TI_CPPI41_DMA config USB_TI_CPPI41_DMA
bool 'TI CPPI 4.1 (AM335x)' bool 'TI CPPI 4.1 (AM335x)'
depends on ARCH_OMAP depends on ARCH_OMAP && DMADEVICES
select TI_CPPI41 select TI_CPPI41
config USB_TUSB_OMAP_DMA config USB_TUSB_OMAP_DMA
......
...@@ -143,12 +143,17 @@ static const struct mxs_phy_data imx6sx_phy_data = { ...@@ -143,12 +143,17 @@ static const struct mxs_phy_data imx6sx_phy_data = {
.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, .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[] = { static const struct of_device_id mxs_phy_dt_ids[] = {
{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, }, { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
{ .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
{ .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
{ .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, }, { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
{ .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
......
...@@ -131,6 +131,7 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep, ...@@ -131,6 +131,7 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep,
struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct device *dev = usbhsg_gpriv_to_dev(gpriv);
struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
if (pipe)
dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
ureq->req.status = status; ureq->req.status = status;
...@@ -685,7 +686,13 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) ...@@ -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 usbhsg_request *ureq = usbhsg_req_to_ureq(req);
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
if (pipe)
usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); 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); usbhsg_queue_pop(uep, ureq, -ECONNRESET);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment