提交 96ae93b4 编写于 作者: G Greg Kroah-Hartman

Merge tag 'fixes-for-v4.20-rc4' of...

Merge tag 'fixes-for-v4.20-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

USB: fixes for v4.20-rc4

In this second set of fixes for the current -rc cycle, we have some
regressions fixes for the old omap_udc driver done by Aaro Koskinen.

We're also reverting an old patch on dwc3 which is, now, known to
break USB certification in some cases.

We have a fix on u_ether for an unsafe list iteration.

* tag 'fixes-for-v4.20-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb:
  usb: gadget: u_ether: fix unsafe list iteration
  USB: omap_udc: fix rejection of out transfers when DMA is used
  USB: omap_udc: fix USB gadget functionality on Palm Tungsten E
  USB: omap_udc: fix omap_udc_start() on 15xx machines
  USB: omap_udc: fix crashes on probe error and module removal
  USB: omap_udc: use devm_request_irq()
  Revert "usb: dwc3: gadget: skip Set/Clear Halt when invalid"
...@@ -1470,9 +1470,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) ...@@ -1470,9 +1470,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
unsigned transfer_in_flight; unsigned transfer_in_flight;
unsigned started; unsigned started;
if (dep->flags & DWC3_EP_STALL)
return 0;
if (dep->number > 1) if (dep->number > 1)
trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue); trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
else else
...@@ -1494,8 +1491,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) ...@@ -1494,8 +1491,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
else else
dep->flags |= DWC3_EP_STALL; dep->flags |= DWC3_EP_STALL;
} else { } else {
if (!(dep->flags & DWC3_EP_STALL))
return 0;
ret = dwc3_send_clear_stall_ep_cmd(dep); ret = dwc3_send_clear_stall_ep_cmd(dep);
if (ret) if (ret)
......
...@@ -401,12 +401,12 @@ static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n) ...@@ -401,12 +401,12 @@ static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)
static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags)
{ {
struct usb_request *req; struct usb_request *req;
struct usb_request *tmp;
unsigned long flags; unsigned long flags;
/* fill unused rxq slots with some skb */ /* fill unused rxq slots with some skb */
spin_lock_irqsave(&dev->req_lock, flags); spin_lock_irqsave(&dev->req_lock, flags);
list_for_each_entry_safe(req, tmp, &dev->rx_reqs, list) { while (!list_empty(&dev->rx_reqs)) {
req = list_first_entry(&dev->rx_reqs, struct usb_request, list);
list_del_init(&req->list); list_del_init(&req->list);
spin_unlock_irqrestore(&dev->req_lock, flags); spin_unlock_irqrestore(&dev->req_lock, flags);
...@@ -1125,7 +1125,6 @@ void gether_disconnect(struct gether *link) ...@@ -1125,7 +1125,6 @@ void gether_disconnect(struct gether *link)
{ {
struct eth_dev *dev = link->ioport; struct eth_dev *dev = link->ioport;
struct usb_request *req; struct usb_request *req;
struct usb_request *tmp;
WARN_ON(!dev); WARN_ON(!dev);
if (!dev) if (!dev)
...@@ -1142,7 +1141,8 @@ void gether_disconnect(struct gether *link) ...@@ -1142,7 +1141,8 @@ void gether_disconnect(struct gether *link)
*/ */
usb_ep_disable(link->in_ep); usb_ep_disable(link->in_ep);
spin_lock(&dev->req_lock); spin_lock(&dev->req_lock);
list_for_each_entry_safe(req, tmp, &dev->tx_reqs, list) { while (!list_empty(&dev->tx_reqs)) {
req = list_first_entry(&dev->tx_reqs, struct usb_request, list);
list_del(&req->list); list_del(&req->list);
spin_unlock(&dev->req_lock); spin_unlock(&dev->req_lock);
...@@ -1154,7 +1154,8 @@ void gether_disconnect(struct gether *link) ...@@ -1154,7 +1154,8 @@ void gether_disconnect(struct gether *link)
usb_ep_disable(link->out_ep); usb_ep_disable(link->out_ep);
spin_lock(&dev->req_lock); spin_lock(&dev->req_lock);
list_for_each_entry_safe(req, tmp, &dev->rx_reqs, list) { while (!list_empty(&dev->rx_reqs)) {
req = list_first_entry(&dev->rx_reqs, struct usb_request, list);
list_del(&req->list); list_del(&req->list);
spin_unlock(&dev->req_lock); spin_unlock(&dev->req_lock);
......
...@@ -2033,6 +2033,7 @@ static inline int machine_without_vbus_sense(void) ...@@ -2033,6 +2033,7 @@ static inline int machine_without_vbus_sense(void)
{ {
return machine_is_omap_innovator() return machine_is_omap_innovator()
|| machine_is_omap_osk() || machine_is_omap_osk()
|| machine_is_omap_palmte()
|| machine_is_sx1() || machine_is_sx1()
/* No known omap7xx boards with vbus sense */ /* No known omap7xx boards with vbus sense */
|| cpu_is_omap7xx(); || cpu_is_omap7xx();
...@@ -2041,7 +2042,7 @@ static inline int machine_without_vbus_sense(void) ...@@ -2041,7 +2042,7 @@ static inline int machine_without_vbus_sense(void)
static int omap_udc_start(struct usb_gadget *g, static int omap_udc_start(struct usb_gadget *g,
struct usb_gadget_driver *driver) struct usb_gadget_driver *driver)
{ {
int status = -ENODEV; int status;
struct omap_ep *ep; struct omap_ep *ep;
unsigned long flags; unsigned long flags;
...@@ -2079,6 +2080,7 @@ static int omap_udc_start(struct usb_gadget *g, ...@@ -2079,6 +2080,7 @@ static int omap_udc_start(struct usb_gadget *g,
goto done; goto done;
} }
} else { } else {
status = 0;
if (can_pullup(udc)) if (can_pullup(udc))
pullup_enable(udc); pullup_enable(udc);
else else
...@@ -2593,9 +2595,22 @@ omap_ep_setup(char *name, u8 addr, u8 type, ...@@ -2593,9 +2595,22 @@ omap_ep_setup(char *name, u8 addr, u8 type,
static void omap_udc_release(struct device *dev) static void omap_udc_release(struct device *dev)
{ {
complete(udc->done); pullup_disable(udc);
if (!IS_ERR_OR_NULL(udc->transceiver)) {
usb_put_phy(udc->transceiver);
udc->transceiver = NULL;
}
omap_writew(0, UDC_SYSCON1);
remove_proc_file();
if (udc->dc_clk) {
if (udc->clk_requested)
omap_udc_enable_clock(0);
clk_put(udc->hhc_clk);
clk_put(udc->dc_clk);
}
if (udc->done)
complete(udc->done);
kfree(udc); kfree(udc);
udc = NULL;
} }
static int static int
...@@ -2627,6 +2642,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) ...@@ -2627,6 +2642,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv)
udc->gadget.speed = USB_SPEED_UNKNOWN; udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->gadget.max_speed = USB_SPEED_FULL; udc->gadget.max_speed = USB_SPEED_FULL;
udc->gadget.name = driver_name; udc->gadget.name = driver_name;
udc->gadget.quirk_ep_out_aligned_size = 1;
udc->transceiver = xceiv; udc->transceiver = xceiv;
/* ep0 is special; put it right after the SETUP buffer */ /* ep0 is special; put it right after the SETUP buffer */
...@@ -2867,8 +2883,8 @@ static int omap_udc_probe(struct platform_device *pdev) ...@@ -2867,8 +2883,8 @@ static int omap_udc_probe(struct platform_device *pdev)
udc->clr_halt = UDC_RESET_EP; udc->clr_halt = UDC_RESET_EP;
/* USB general purpose IRQ: ep0, state changes, dma, etc */ /* USB general purpose IRQ: ep0, state changes, dma, etc */
status = request_irq(pdev->resource[1].start, omap_udc_irq, status = devm_request_irq(&pdev->dev, pdev->resource[1].start,
0, driver_name, udc); omap_udc_irq, 0, driver_name, udc);
if (status != 0) { if (status != 0) {
ERR("can't get irq %d, err %d\n", ERR("can't get irq %d, err %d\n",
(int) pdev->resource[1].start, status); (int) pdev->resource[1].start, status);
...@@ -2876,20 +2892,20 @@ static int omap_udc_probe(struct platform_device *pdev) ...@@ -2876,20 +2892,20 @@ static int omap_udc_probe(struct platform_device *pdev)
} }
/* USB "non-iso" IRQ (PIO for all but ep0) */ /* USB "non-iso" IRQ (PIO for all but ep0) */
status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, status = devm_request_irq(&pdev->dev, pdev->resource[2].start,
0, "omap_udc pio", udc); omap_udc_pio_irq, 0, "omap_udc pio", udc);
if (status != 0) { if (status != 0) {
ERR("can't get irq %d, err %d\n", ERR("can't get irq %d, err %d\n",
(int) pdev->resource[2].start, status); (int) pdev->resource[2].start, status);
goto cleanup2; goto cleanup1;
} }
#ifdef USE_ISO #ifdef USE_ISO
status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, status = devm_request_irq(&pdev->dev, pdev->resource[3].start,
0, "omap_udc iso", udc); omap_udc_iso_irq, 0, "omap_udc iso", udc);
if (status != 0) { if (status != 0) {
ERR("can't get irq %d, err %d\n", ERR("can't get irq %d, err %d\n",
(int) pdev->resource[3].start, status); (int) pdev->resource[3].start, status);
goto cleanup3; goto cleanup1;
} }
#endif #endif
if (cpu_is_omap16xx() || cpu_is_omap7xx()) { if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
...@@ -2900,23 +2916,8 @@ static int omap_udc_probe(struct platform_device *pdev) ...@@ -2900,23 +2916,8 @@ static int omap_udc_probe(struct platform_device *pdev)
} }
create_proc_file(); create_proc_file();
status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, return usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
omap_udc_release); omap_udc_release);
if (status)
goto cleanup4;
return 0;
cleanup4:
remove_proc_file();
#ifdef USE_ISO
cleanup3:
free_irq(pdev->resource[2].start, udc);
#endif
cleanup2:
free_irq(pdev->resource[1].start, udc);
cleanup1: cleanup1:
kfree(udc); kfree(udc);
...@@ -2943,42 +2944,15 @@ static int omap_udc_remove(struct platform_device *pdev) ...@@ -2943,42 +2944,15 @@ static int omap_udc_remove(struct platform_device *pdev)
{ {
DECLARE_COMPLETION_ONSTACK(done); DECLARE_COMPLETION_ONSTACK(done);
if (!udc)
return -ENODEV;
usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
udc->done = &done; udc->done = &done;
pullup_disable(udc); usb_del_gadget_udc(&udc->gadget);
if (!IS_ERR_OR_NULL(udc->transceiver)) {
usb_put_phy(udc->transceiver);
udc->transceiver = NULL;
}
omap_writew(0, UDC_SYSCON1);
remove_proc_file();
#ifdef USE_ISO
free_irq(pdev->resource[3].start, udc);
#endif
free_irq(pdev->resource[2].start, udc);
free_irq(pdev->resource[1].start, udc);
if (udc->dc_clk) { wait_for_completion(&done);
if (udc->clk_requested)
omap_udc_enable_clock(0);
clk_put(udc->hhc_clk);
clk_put(udc->dc_clk);
}
release_mem_region(pdev->resource[0].start, release_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1); pdev->resource[0].end - pdev->resource[0].start + 1);
wait_for_completion(&done);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册