diff options
Diffstat (limited to 'drivers/usb/gadget/udc')
-rw-r--r-- | drivers/usb/gadget/udc/aspeed-vhub/epn.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/at91_udc.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.c | 84 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.h | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/fotg210-udc.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/fusb300_udc.c | 5 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/lpc32xx_udc.c | 172 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/net2272.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/net2280.c | 5 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/omap_udc.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/renesas_usb3.c | 93 |
12 files changed, 237 insertions, 162 deletions
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c index 83340f4fdc6e..35941dc125f9 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c @@ -593,10 +593,6 @@ static int ast_vhub_epn_disable(struct usb_ep* u_ep) static int ast_vhub_epn_enable(struct usb_ep* u_ep, const struct usb_endpoint_descriptor *desc) { - static const char *ep_type_string[] __maybe_unused = { "ctrl", - "isoc", - "bulk", - "intr" }; struct ast_vhub_ep *ep = to_ast_ep(u_ep); struct ast_vhub_dev *dev; struct ast_vhub *vhub; @@ -646,7 +642,7 @@ static int ast_vhub_epn_enable(struct usb_ep* u_ep, ep->epn.wedged = false; EPDBG(ep, "Enabling [%s] %s num %d maxpacket=%d\n", - ep->epn.is_in ? "in" : "out", ep_type_string[type], + ep->epn.is_in ? "in" : "out", usb_ep_type_string(type), usb_endpoint_num(desc), maxpacket); /* Can we use DMA descriptor mode ? */ diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 03959dc86cfd..194ffb1ed462 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -799,7 +799,6 @@ static int at91_wakeup(struct usb_gadget *gadget) { struct at91_udc *udc = to_udc(gadget); u32 glbstate; - int status = -EINVAL; unsigned long flags; DBG("%s\n", __func__ ); @@ -818,7 +817,7 @@ static int at91_wakeup(struct usb_gadget *gadget) done: spin_unlock_irqrestore(&udc->lock, flags); - return status; + return 0; } /* reinit == restore initial software state */ diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 660712e0bf98..503d275bc4c4 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -358,8 +358,20 @@ static inline u32 usba_int_enb_get(struct usba_udc *udc) return udc->int_enb_cache; } -static inline void usba_int_enb_set(struct usba_udc *udc, u32 val) +static inline void usba_int_enb_set(struct usba_udc *udc, u32 mask) { + u32 val; + + val = udc->int_enb_cache | mask; + usba_writel(udc, INT_ENB, val); + udc->int_enb_cache = val; +} + +static inline void usba_int_enb_clear(struct usba_udc *udc, u32 mask) +{ + u32 val; + + val = udc->int_enb_cache & ~mask; usba_writel(udc, INT_ENB, val); udc->int_enb_cache = val; } @@ -629,14 +641,12 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) if (ep->can_dma) { u32 ctrl; - usba_int_enb_set(udc, usba_int_enb_get(udc) | - USBA_BF(EPT_INT, 1 << ep->index) | + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1 << ep->index) | USBA_BF(DMA_INT, 1 << ep->index)); ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; usba_ep_writel(ep, CTL_ENB, ctrl); } else { - usba_int_enb_set(udc, usba_int_enb_get(udc) | - USBA_BF(EPT_INT, 1 << ep->index)); + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1 << ep->index)); } spin_unlock_irqrestore(&udc->lock, flags); @@ -680,8 +690,7 @@ static int usba_ep_disable(struct usb_ep *_ep) usba_dma_readl(ep, STATUS); } usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); - usba_int_enb_set(udc, usba_int_enb_get(udc) & - ~USBA_BF(EPT_INT, 1 << ep->index)); + usba_int_enb_clear(udc, USBA_BF(EPT_INT, 1 << ep->index)); request_complete_list(ep, &req_list, -ESHUTDOWN); @@ -1694,6 +1703,9 @@ static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep) } } +static int start_clock(struct usba_udc *udc); +static void stop_clock(struct usba_udc *udc); + static irqreturn_t usba_udc_irq(int irq, void *devid) { struct usba_udc *udc = devid; @@ -1708,10 +1720,13 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) DBG(DBG_INT, "irq, status=%#08x\n", status); if (status & USBA_DET_SUSPEND) { + usba_writel(udc, INT_CLR, USBA_DET_SUSPEND|USBA_WAKE_UP); + usba_int_enb_set(udc, USBA_WAKE_UP); + usba_int_enb_clear(udc, USBA_DET_SUSPEND); + udc->suspended = true; toggle_bias(udc, 0); - usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); - usba_int_enb_set(udc, int_enb | USBA_WAKE_UP); udc->bias_pulse_needed = true; + stop_clock(udc); DBG(DBG_BUS, "Suspend detected\n"); if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver && udc->driver->suspend) { @@ -1722,14 +1737,17 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) } if (status & USBA_WAKE_UP) { + start_clock(udc); toggle_bias(udc, 1); usba_writel(udc, INT_CLR, USBA_WAKE_UP); - usba_int_enb_set(udc, int_enb & ~USBA_WAKE_UP); DBG(DBG_BUS, "Wake Up CPU detected\n"); } if (status & USBA_END_OF_RESUME) { + udc->suspended = false; usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); + usba_int_enb_clear(udc, USBA_WAKE_UP); + usba_int_enb_set(udc, USBA_DET_SUSPEND); generate_bias_pulse(udc); DBG(DBG_BUS, "Resume detected\n"); if (udc->gadget.speed != USB_SPEED_UNKNOWN @@ -1744,6 +1762,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (dma_status) { int i; + usba_int_enb_set(udc, USBA_DET_SUSPEND); + for (i = 1; i <= USBA_NR_DMAS; i++) if (dma_status & (1 << i)) usba_dma_irq(udc, &udc->usba_ep[i]); @@ -1753,6 +1773,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (ep_status) { int i; + usba_int_enb_set(udc, USBA_DET_SUSPEND); + for (i = 0; i < udc->num_ep; i++) if (ep_status & (1 << i)) { if (ep_is_control(&udc->usba_ep[i])) @@ -1766,7 +1788,9 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) struct usba_ep *ep0, *ep; int i, n; - usba_writel(udc, INT_CLR, USBA_END_OF_RESET); + usba_writel(udc, INT_CLR, + USBA_END_OF_RESET|USBA_END_OF_RESUME + |USBA_DET_SUSPEND|USBA_WAKE_UP); generate_bias_pulse(udc); reset_all_endpoints(udc); @@ -1793,7 +1817,12 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); usba_ep_writel(ep0, CTL_ENB, USBA_EPT_ENABLE | USBA_RX_SETUP); - usba_int_enb_set(udc, int_enb | USBA_BF(EPT_INT, 1) | + + /* If we get reset while suspended... */ + udc->suspended = false; + usba_int_enb_clear(udc, USBA_WAKE_UP); + + usba_int_enb_set(udc, USBA_BF(EPT_INT, 1) | USBA_DET_SUSPEND | USBA_END_OF_RESUME); /* @@ -1827,6 +1856,8 @@ static int start_clock(struct usba_udc *udc) if (udc->clocked) return 0; + pm_stay_awake(&udc->pdev->dev); + ret = clk_prepare_enable(udc->pclk); if (ret) return ret; @@ -1849,6 +1880,8 @@ static void stop_clock(struct usba_udc *udc) clk_disable_unprepare(udc->pclk); udc->clocked = false; + + pm_relax(&udc->pdev->dev); } static int usba_start(struct usba_udc *udc) @@ -1860,9 +1893,19 @@ static int usba_start(struct usba_udc *udc) if (ret) return ret; + if (udc->suspended) + return 0; + spin_lock_irqsave(&udc->lock, flags); toggle_bias(udc, 1); usba_writel(udc, CTRL, USBA_ENABLE_MASK); + /* Clear all requested and pending interrupts... */ + usba_writel(udc, INT_ENB, 0); + udc->int_enb_cache = 0; + usba_writel(udc, INT_CLR, + USBA_END_OF_RESET|USBA_END_OF_RESUME + |USBA_DET_SUSPEND|USBA_WAKE_UP); + /* ...and enable just 'reset' IRQ to get us started */ usba_int_enb_set(udc, USBA_END_OF_RESET); spin_unlock_irqrestore(&udc->lock, flags); @@ -1873,6 +1916,9 @@ static void usba_stop(struct usba_udc *udc) { unsigned long flags; + if (udc->suspended) + return; + spin_lock_irqsave(&udc->lock, flags); udc->gadget.speed = USB_SPEED_UNKNOWN; reset_all_endpoints(udc); @@ -1900,6 +1946,7 @@ static irqreturn_t usba_vbus_irq_thread(int irq, void *devid) if (vbus) { usba_start(udc); } else { + udc->suspended = false; usba_stop(udc); if (udc->driver->disconnect) @@ -1963,6 +2010,7 @@ static int atmel_usba_stop(struct usb_gadget *gadget) if (fifo_mode == 0) udc->configured_ep = 1; + udc->suspended = false; usba_stop(udc); udc->driver = NULL; @@ -2276,6 +2324,7 @@ static int usba_udc_suspend(struct device *dev) mutex_lock(&udc->vbus_mutex); if (!device_may_wakeup(dev)) { + udc->suspended = false; usba_stop(udc); goto out; } @@ -2285,10 +2334,13 @@ static int usba_udc_suspend(struct device *dev) * to request vbus irq, assuming always on. */ if (udc->vbus_pin) { + /* FIXME: right to stop here...??? */ usba_stop(udc); enable_irq_wake(gpiod_to_irq(udc->vbus_pin)); } + enable_irq_wake(udc->irq); + out: mutex_unlock(&udc->vbus_mutex); return 0; @@ -2302,8 +2354,12 @@ static int usba_udc_resume(struct device *dev) if (!udc->driver) return 0; - if (device_may_wakeup(dev) && udc->vbus_pin) - disable_irq_wake(gpiod_to_irq(udc->vbus_pin)); + if (device_may_wakeup(dev)) { + if (udc->vbus_pin) + disable_irq_wake(gpiod_to_irq(udc->vbus_pin)); + + disable_irq_wake(udc->irq); + } /* If Vbus is present, enable the controller and wait for reset */ mutex_lock(&udc->vbus_mutex); diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index 030bf797cd25..a0225e4543d4 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h @@ -331,6 +331,7 @@ struct usba_udc { struct usba_ep *usba_ep; bool bias_pulse_needed; bool clocked; + bool suspended; u16 devstatus; diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 213b52508621..8414fac74493 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -617,21 +617,7 @@ static int dummy_enable(struct usb_ep *_ep, _ep->name, desc->bEndpointAddress & 0x0f, (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", - ({ char *val; - switch (usb_endpoint_type(desc)) { - case USB_ENDPOINT_XFER_BULK: - val = "bulk"; - break; - case USB_ENDPOINT_XFER_ISOC: - val = "iso"; - break; - case USB_ENDPOINT_XFER_INT: - val = "intr"; - break; - default: - val = "ctrl"; - break; - } val; }), + usb_ep_type_string(usb_endpoint_type(desc)), max, ep->stream_en ? "enabled" : "disabled"); /* at this point real hardware should be NAKing transfers diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index cec49294bac6..21f3e6c4e4d6 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c @@ -481,7 +481,6 @@ static int fotg210_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge) struct fotg210_ep *ep; struct fotg210_udc *fotg210; unsigned long flags; - int ret = 0; ep = container_of(_ep, struct fotg210_ep, ep); @@ -504,7 +503,7 @@ static int fotg210_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge) } spin_unlock_irqrestore(&ep->fotg210->lock, flags); - return ret; + return 0; } static int fotg210_ep_set_halt(struct usb_ep *_ep, int value) diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 263804d154a7..00e3f66836a9 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1342,12 +1342,15 @@ static const struct usb_gadget_ops fusb300_gadget_ops = { static int fusb300_remove(struct platform_device *pdev) { struct fusb300 *fusb300 = platform_get_drvdata(pdev); + int i; usb_del_gadget_udc(&fusb300->gadget); iounmap(fusb300->reg); free_irq(platform_get_irq(pdev, 0), fusb300); fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); + for (i = 0; i < FUSB300_MAX_NUM_EP; i++) + kfree(fusb300->ep[i]); kfree(fusb300); return 0; @@ -1491,6 +1494,8 @@ clean_up: if (fusb300->ep0_req) fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); + for (i = 0; i < FUSB300_MAX_NUM_EP; i++) + kfree(fusb300->ep[i]); kfree(fusb300); } if (reg) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index b0781771704e..5f1b14f3e5a0 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -115,6 +115,11 @@ struct lpc32xx_ep { bool wedge; }; +enum atx_type { + ISP1301, + STOTG04, +}; + /* * Common UDC structure */ @@ -129,8 +134,6 @@ struct lpc32xx_udc { /* Board and device specific */ struct lpc32xx_usbd_cfg *board; - u32 io_p_start; - u32 io_p_size; void __iomem *udp_baseaddr; int udp_irq[4]; struct clk *usb_slv_clk; @@ -151,10 +154,10 @@ struct lpc32xx_udc { u8 last_vbus; int pullup; int poweron; + enum atx_type atx; /* Work queues related to I2C support */ struct work_struct pullup_job; - struct work_struct vbus_job; struct work_struct power_job; /* USB device peripheral - various */ @@ -553,6 +556,15 @@ static inline void remove_debug_file(struct lpc32xx_udc *udc) {} /* Primary initialization sequence for the ISP1301 transceiver */ static void isp1301_udc_configure(struct lpc32xx_udc *udc) { + u8 value; + s32 vendor, product; + + vendor = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00); + product = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02); + + if (vendor == 0x0483 && product == 0xa0c4) + udc->atx = STOTG04; + /* LPC32XX only supports DAT_SE0 USB mode */ /* This sequence is important */ @@ -572,8 +584,12 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc) */ i2c_smbus_write_byte_data(udc->isp1301_i2c_client, (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR), ~0); + + value = MC2_BI_DI; + if (udc->atx != STOTG04) + value |= MC2_SPD_SUSP_CTRL; i2c_smbus_write_byte_data(udc->isp1301_i2c_client, - ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_SPD_SUSP_CTRL)); + ISP1301_I2C_MODE_CONTROL_2, value); /* Driver VBUS_DRV high or low depending on board setup */ if (udc->board->vbus_drv_pol != 0) @@ -601,24 +617,19 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc) (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), OTG1_VBUS_DISCHRG); - /* Clear and enable VBUS high edge interrupt */ i2c_smbus_write_byte_data(udc->isp1301_i2c_client, ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, ~0); + i2c_smbus_write_byte_data(udc->isp1301_i2c_client, ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); i2c_smbus_write_byte_data(udc->isp1301_i2c_client, - ISP1301_I2C_INTERRUPT_FALLING, INT_VBUS_VLD); - i2c_smbus_write_byte_data(udc->isp1301_i2c_client, ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); - i2c_smbus_write_byte_data(udc->isp1301_i2c_client, - ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD); - dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", - i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00)); - dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n", - i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02)); + dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", vendor); + dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n", product); dev_info(udc->dev, "ISP1301 Version ID : 0x%04x\n", i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x14)); + } /* Enables or disables the USB device pullup via the ISP1301 transceiver */ @@ -661,6 +672,10 @@ static void isp1301_pullup_enable(struct lpc32xx_udc *udc, int en_pullup, /* Powers up or down the ISP1301 transceiver */ static void isp1301_set_powerstate(struct lpc32xx_udc *udc, int enable) { + /* There is no "global power down" register for stotg04 */ + if (udc->atx == STOTG04) + return; + if (enable != 0) /* Power up ISP1301 - this ISP1301 will automatically wakeup when VBUS is detected */ @@ -922,8 +937,7 @@ static struct lpc32xx_usbd_dd_gad *udc_dd_alloc(struct lpc32xx_udc *udc) dma_addr_t dma; struct lpc32xx_usbd_dd_gad *dd; - dd = (struct lpc32xx_usbd_dd_gad *) dma_pool_alloc( - udc->dd_cache, (GFP_KERNEL | GFP_DMA), &dma); + dd = dma_pool_alloc(udc->dd_cache, GFP_ATOMIC | GFP_DMA, &dma); if (dd) dd->this_dma = dma; @@ -2830,11 +2844,9 @@ static irqreturn_t lpc32xx_usb_devdma_irq(int irq, void *_udc) * VBUS detection, pullup handler, and Gadget cable state notification * */ -static void vbus_work(struct work_struct *work) +static void vbus_work(struct lpc32xx_udc *udc) { u8 value; - struct lpc32xx_udc *udc = container_of(work, struct lpc32xx_udc, - vbus_job); if (udc->enabled != 0) { /* Discharge VBUS real quick */ @@ -2870,18 +2882,13 @@ static void vbus_work(struct work_struct *work) lpc32xx_vbus_session(&udc->gadget, udc->vbus); } } - - /* Re-enable after completion */ - enable_irq(udc->udp_irq[IRQ_USB_ATX]); } static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc) { struct lpc32xx_udc *udc = _udc; - /* Defer handling of VBUS IRQ to work queue */ - disable_irq_nosync(udc->udp_irq[IRQ_USB_ATX]); - schedule_work(&udc->vbus_job); + vbus_work(udc); return IRQ_HANDLED; } @@ -2890,7 +2897,6 @@ static int lpc32xx_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct lpc32xx_udc *udc = to_udc(gadget); - int i; if (!driver || driver->max_speed < USB_SPEED_FULL || !driver->setup) { dev_err(udc->dev, "bad parameter.\n"); @@ -2910,22 +2916,25 @@ static int lpc32xx_start(struct usb_gadget *gadget, /* Force VBUS process once to check for cable insertion */ udc->last_vbus = udc->vbus = 0; - schedule_work(&udc->vbus_job); + vbus_work(udc); - /* Do not re-enable ATX IRQ (3) */ - for (i = IRQ_USB_LP; i < IRQ_USB_ATX; i++) - enable_irq(udc->udp_irq[i]); + /* enable interrupts */ + i2c_smbus_write_byte_data(udc->isp1301_i2c_client, + ISP1301_I2C_INTERRUPT_FALLING, INT_SESS_VLD | INT_VBUS_VLD); + i2c_smbus_write_byte_data(udc->isp1301_i2c_client, + ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD); return 0; } static int lpc32xx_stop(struct usb_gadget *gadget) { - int i; struct lpc32xx_udc *udc = to_udc(gadget); - for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) - disable_irq(udc->udp_irq[i]); + i2c_smbus_write_byte_data(udc->isp1301_i2c_client, + ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); + i2c_smbus_write_byte_data(udc->isp1301_i2c_client, + ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); if (udc->clocked) { spin_lock(&udc->lock); @@ -2999,7 +3008,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) dma_addr_t dma_handle; struct device_node *isp1301_node; - udc = kmemdup(&controller_template, sizeof(*udc), GFP_KERNEL); + udc = devm_kmemdup(dev, &controller_template, sizeof(*udc), GFP_KERNEL); if (!udc) return -ENOMEM; @@ -3022,8 +3031,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); if (!udc->isp1301_i2c_client) { - retval = -EPROBE_DEFER; - goto phy_fail; + return -EPROBE_DEFER; } dev_info(udc->dev, "ISP1301 I2C device at address 0x%x\n", @@ -3032,7 +3040,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) pdev->dev.dma_mask = &lpc32xx_usbd_dmamask; retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (retval) - goto resource_fail; + return retval; udc->board = &lpc32xx_usbddata; @@ -3045,10 +3053,8 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) * IORESOURCE_IRQ, USB transceiver interrupt number */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENXIO; - goto resource_fail; - } + if (!res) + return -ENXIO; spin_lock_init(&udc->lock); @@ -3058,45 +3064,33 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) if (udc->udp_irq[i] < 0) { dev_err(udc->dev, "irq resource %d not available!\n", i); - retval = udc->udp_irq[i]; - goto irq_fail; + return udc->udp_irq[i]; } } - udc->io_p_start = res->start; - udc->io_p_size = resource_size(res); - if (!request_mem_region(udc->io_p_start, udc->io_p_size, driver_name)) { - dev_err(udc->dev, "someone's using UDC memory\n"); - retval = -EBUSY; - goto request_mem_region_fail; - } - - udc->udp_baseaddr = ioremap(udc->io_p_start, udc->io_p_size); - if (!udc->udp_baseaddr) { - retval = -ENOMEM; + udc->udp_baseaddr = devm_ioremap_resource(dev, res); + if (IS_ERR(udc->udp_baseaddr)) { dev_err(udc->dev, "IO map failure\n"); - goto io_map_fail; + return PTR_ERR(udc->udp_baseaddr); } /* Get USB device clock */ - udc->usb_slv_clk = clk_get(&pdev->dev, NULL); + udc->usb_slv_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(udc->usb_slv_clk)) { dev_err(udc->dev, "failed to acquire USB device clock\n"); - retval = PTR_ERR(udc->usb_slv_clk); - goto usb_clk_get_fail; + return PTR_ERR(udc->usb_slv_clk); } /* Enable USB device clock */ retval = clk_prepare_enable(udc->usb_slv_clk); if (retval < 0) { dev_err(udc->dev, "failed to start USB device clock\n"); - goto usb_clk_enable_fail; + return retval; } /* Setup deferred workqueue data */ udc->poweron = udc->pullup = 0; INIT_WORK(&udc->pullup_job, pullup_work); - INIT_WORK(&udc->vbus_job, vbus_work); #ifdef CONFIG_PM INIT_WORK(&udc->power_job, power_work); #endif @@ -3134,47 +3128,44 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) /* Request IRQs - low and high priority USB device IRQs are routed to * the same handler, while the DMA interrupt is routed elsewhere */ - retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq, - 0, "udc_lp", udc); + retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_LP], + lpc32xx_usb_lp_irq, 0, "udc_lp", udc); if (retval < 0) { dev_err(udc->dev, "LP request irq %d failed\n", udc->udp_irq[IRQ_USB_LP]); - goto irq_lp_fail; + goto irq_req_fail; } - retval = request_irq(udc->udp_irq[IRQ_USB_HP], lpc32xx_usb_hp_irq, - 0, "udc_hp", udc); + retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_HP], + lpc32xx_usb_hp_irq, 0, "udc_hp", udc); if (retval < 0) { dev_err(udc->dev, "HP request irq %d failed\n", udc->udp_irq[IRQ_USB_HP]); - goto irq_hp_fail; + goto irq_req_fail; } - retval = request_irq(udc->udp_irq[IRQ_USB_DEVDMA], - lpc32xx_usb_devdma_irq, 0, "udc_dma", udc); + retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_DEVDMA], + lpc32xx_usb_devdma_irq, 0, "udc_dma", udc); if (retval < 0) { dev_err(udc->dev, "DEV request irq %d failed\n", udc->udp_irq[IRQ_USB_DEVDMA]); - goto irq_dev_fail; + goto irq_req_fail; } /* The transceiver interrupt is used for VBUS detection and will kick off the VBUS handler function */ - retval = request_irq(udc->udp_irq[IRQ_USB_ATX], lpc32xx_usb_vbus_irq, - 0, "udc_otg", udc); + retval = devm_request_threaded_irq(dev, udc->udp_irq[IRQ_USB_ATX], NULL, + lpc32xx_usb_vbus_irq, IRQF_ONESHOT, + "udc_otg", udc); if (retval < 0) { dev_err(udc->dev, "VBUS request irq %d failed\n", udc->udp_irq[IRQ_USB_ATX]); - goto irq_xcvr_fail; + goto irq_req_fail; } /* Initialize wait queue */ init_waitqueue_head(&udc->ep_disable_wait_queue); atomic_set(&udc->enabled_ep_cnt, 0); - /* Keep all IRQs disabled until GadgetFS starts up */ - for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) - disable_irq(udc->udp_irq[i]); - retval = usb_add_gadget_udc(dev, &udc->gadget); if (retval < 0) goto add_gadget_fail; @@ -3190,32 +3181,15 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) return 0; add_gadget_fail: - free_irq(udc->udp_irq[IRQ_USB_ATX], udc); -irq_xcvr_fail: - free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc); -irq_dev_fail: - free_irq(udc->udp_irq[IRQ_USB_HP], udc); -irq_hp_fail: - free_irq(udc->udp_irq[IRQ_USB_LP], udc); -irq_lp_fail: +irq_req_fail: dma_pool_destroy(udc->dd_cache); dma_alloc_fail: dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); i2c_fail: clk_disable_unprepare(udc->usb_slv_clk); -usb_clk_enable_fail: - clk_put(udc->usb_slv_clk); -usb_clk_get_fail: - iounmap(udc->udp_baseaddr); -io_map_fail: - release_mem_region(udc->io_p_start, udc->io_p_size); dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval); -request_mem_region_fail: -irq_fail: -resource_fail: -phy_fail: - kfree(udc); + return retval; } @@ -3231,24 +3205,14 @@ static int lpc32xx_udc_remove(struct platform_device *pdev) udc_disable(udc); pullup(udc, 0); - free_irq(udc->udp_irq[IRQ_USB_ATX], udc); - device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); dma_pool_destroy(udc->dd_cache); dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); - free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc); - free_irq(udc->udp_irq[IRQ_USB_HP], udc); - free_irq(udc->udp_irq[IRQ_USB_LP], udc); clk_disable_unprepare(udc->usb_slv_clk); - clk_put(udc->usb_slv_clk); - - iounmap(udc->udp_baseaddr); - release_mem_region(udc->io_p_start, udc->io_p_size); - kfree(udc); return 0; } diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index c2011cd7df8c..247de0faaeb7 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -573,8 +573,7 @@ net2272_read_fifo(struct net2272_ep *ep, struct net2272_request *req) /* completion */ if (unlikely(cleanup || is_short || - ((req->req.actual == req->req.length) - && !req->req.zero))) { + req->req.actual == req->req.length)) { if (cleanup) { net2272_out_flush(ep); @@ -1179,11 +1178,6 @@ registers_show(struct device *_dev, struct device_attribute *attr, char *buf) size = PAGE_SIZE; spin_lock_irqsave(&dev->lock, flags); - if (dev->driver) - s = dev->driver->driver.name; - else - s = "(none)"; - /* Main Control Registers */ t = scnprintf(next, size, "%s version %s," "chiprev %02x, locctl %02x\n" diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 898339e5df10..b6bbe2e448ba 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -789,8 +789,7 @@ static int read_fifo(struct net2280_ep *ep, struct net2280_request *req) (void) readl(&ep->regs->ep_rsp); } - return is_short || ((req->req.actual == req->req.length) && - !req->req.zero); + return is_short || req->req.actual == req->req.length; } /* fill out dma descriptor to match a given request */ @@ -1058,7 +1057,7 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* PIO ... stuff the fifo, or unblock it. */ if (ep->is_in) write_fifo(ep, _req); - else if (list_empty(&ep->queue)) { + else { u32 s; /* OUT FIFO might have packet(s) buffered */ diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index fcf13ef33b31..f36f0730afab 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -2103,7 +2103,6 @@ done: static int omap_udc_stop(struct usb_gadget *g) { unsigned long flags; - int status = -ENODEV; if (udc->dc_clk != NULL) omap_udc_enable_clock(1); @@ -2125,7 +2124,7 @@ static int omap_udc_stop(struct usb_gadget *g) if (udc->dc_clk != NULL) omap_udc_enable_clock(0); - return status; + return 0; } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 7dc248546fd4..87062d22134d 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -351,6 +351,8 @@ struct renesas_usb3 { int disabled_count; struct usb_request *ep0_req; + + enum usb_role connection_state; u16 test_mode; u8 ep0_buf[USB3_EP0_BUF_SIZE]; bool softconnect; @@ -359,6 +361,7 @@ struct renesas_usb3 { bool extcon_usb; /* check vbus and set EXTCON_USB */ bool forced_b_device; bool start_to_connect; + bool role_sw_by_connector; }; #define gadget_to_renesas_usb3(_gadget) \ @@ -699,8 +702,11 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) unsigned long flags; spin_lock_irqsave(&usb3->lock, flags); - usb3_set_mode_by_role_sw(usb3, host); - usb3_vbus_out(usb3, a_dev); + if (!usb3->role_sw_by_connector || + usb3->connection_state != USB_ROLE_NONE) { + usb3_set_mode_by_role_sw(usb3, host); + usb3_vbus_out(usb3, a_dev); + } /* for A-Peripheral or forced B-device mode */ if ((!host && a_dev) || usb3->start_to_connect) usb3_connect(usb3); @@ -716,7 +722,8 @@ static void usb3_check_id(struct renesas_usb3 *usb3) { usb3->extcon_host = usb3_is_a_device(usb3); - if (usb3->extcon_host && !usb3->forced_b_device) + if ((!usb3->role_sw_by_connector && usb3->extcon_host && + !usb3->forced_b_device) || usb3->connection_state == USB_ROLE_HOST) usb3_mode_config(usb3, true, true); else usb3_mode_config(usb3, false, false); @@ -1161,7 +1168,7 @@ static void usb3_set_status_stage(struct renesas_usb3_ep *usb3_ep, static void usb3_p0_xfer(struct renesas_usb3_ep *usb3_ep, struct renesas_usb3_request *usb3_req) { - int ret = -EAGAIN; + int ret; if (usb3_ep->dir_in) ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_P0_WRITE); @@ -2343,14 +2350,65 @@ static enum usb_role renesas_usb3_role_switch_get(struct device *dev) return cur_role; } -static int renesas_usb3_role_switch_set(struct device *dev, - enum usb_role role) +static void handle_ext_role_switch_states(struct device *dev, + enum usb_role role) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + struct device *host = usb3->host_dev; + enum usb_role cur_role = renesas_usb3_role_switch_get(dev); + + switch (role) { + case USB_ROLE_NONE: + usb3->connection_state = USB_ROLE_NONE; + if (usb3->driver) + usb3_disconnect(usb3); + usb3_vbus_out(usb3, false); + break; + case USB_ROLE_DEVICE: + if (usb3->connection_state == USB_ROLE_NONE) { + usb3->connection_state = USB_ROLE_DEVICE; + usb3_set_mode(usb3, false); + if (usb3->driver) + usb3_connect(usb3); + } else if (cur_role == USB_ROLE_HOST) { + device_release_driver(host); + usb3_set_mode(usb3, false); + if (usb3->driver) + usb3_connect(usb3); + } + usb3_vbus_out(usb3, false); + break; + case USB_ROLE_HOST: + if (usb3->connection_state == USB_ROLE_NONE) { + if (usb3->driver) + usb3_disconnect(usb3); + + usb3->connection_state = USB_ROLE_HOST; + usb3_set_mode(usb3, true); + usb3_vbus_out(usb3, true); + if (device_attach(host) < 0) + dev_err(dev, "device_attach(host) failed\n"); + } else if (cur_role == USB_ROLE_DEVICE) { + usb3_disconnect(usb3); + /* Must set the mode before device_attach of the host */ + usb3_set_mode(usb3, true); + /* This device_attach() might sleep */ + if (device_attach(host) < 0) + dev_err(dev, "device_attach(host) failed\n"); + } + break; + default: + break; + } +} + +static void handle_role_switch_states(struct device *dev, + enum usb_role role) { struct renesas_usb3 *usb3 = dev_get_drvdata(dev); struct device *host = usb3->host_dev; enum usb_role cur_role = renesas_usb3_role_switch_get(dev); - pm_runtime_get_sync(dev); if (cur_role == USB_ROLE_HOST && role == USB_ROLE_DEVICE) { device_release_driver(host); usb3_set_mode(usb3, false); @@ -2361,6 +2419,20 @@ static int renesas_usb3_role_switch_set(struct device *dev, if (device_attach(host) < 0) dev_err(dev, "device_attach(host) failed\n"); } +} + +static int renesas_usb3_role_switch_set(struct device *dev, + enum usb_role role) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + + if (usb3->role_sw_by_connector) + handle_ext_role_switch_states(dev, role); + else + handle_role_switch_states(dev, role); + pm_runtime_put(dev); return 0; @@ -2650,7 +2722,7 @@ static const unsigned int renesas_usb3_cable[] = { EXTCON_NONE, }; -static const struct usb_role_switch_desc renesas_usb3_role_switch_desc = { +static struct usb_role_switch_desc renesas_usb3_role_switch_desc = { .set = renesas_usb3_role_switch_set, .get = renesas_usb3_role_switch_get, .allow_userspace_control = true, @@ -2741,6 +2813,11 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (ret < 0) goto err_dev_create; + if (device_property_read_bool(&pdev->dev, "usb-role-switch")) { + usb3->role_sw_by_connector = true; + renesas_usb3_role_switch_desc.fwnode = dev_fwnode(&pdev->dev); + } + INIT_WORK(&usb3->role_work, renesas_usb3_role_work); usb3->role_sw = usb_role_switch_register(&pdev->dev, &renesas_usb3_role_switch_desc); |