Merge remote-tracking branch 'usb-gadget/next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Fri, 8 Feb 2019 04:20:54 +0000 (15:20 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 8 Feb 2019 04:20:54 +0000 (15:20 +1100)
26 files changed:
Documentation/devicetree/bindings/usb/keystone-usb.txt
Documentation/devicetree/bindings/usb/qcom,dwc3.txt
Documentation/devicetree/bindings/usb/renesas_usb3.txt
Documentation/devicetree/bindings/usb/renesas_usbhs.txt
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/Kconfig
drivers/usb/dwc3/core.h
drivers/usb/dwc3/debug.h
drivers/usb/dwc3/dwc3-keystone.c
drivers/usb/dwc3/dwc3-qcom.c
drivers/usb/dwc3/gadget.c
drivers/usb/dwc3/gadget.h
drivers/usb/dwc3/trace.h
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_uac1.c
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/function/uvc.h
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/gadget/legacy/inode.c
drivers/usb/gadget/udc/aspeed-vhub/epn.c
drivers/usb/gadget/udc/aspeed-vhub/hub.c
drivers/usb/gadget/udc/bdc/bdc_cmd.c
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/net2280.c
drivers/usb/gadget/udc/renesas_usb3.c

index f96e09f..77df82e 100644 (file)
@@ -3,7 +3,9 @@ TI Keystone Soc USB Controller
 DWC3 GLUE
 
 Required properties:
- - compatible: should be "ti,keystone-dwc3".
+ - compatible: should be
+               "ti,keystone-dwc3" for Keystone 2 SoCs
+               "ti,am654-dwc3" for AM654 SoC
  - #address-cells, #size-cells : should be '1' if the device has sub-nodes
    with 'reg' property.
  - reg : Address and length of the register set for the USB subsystem on
@@ -21,7 +23,7 @@ SoCs only:
 - clock-names:         Must be "usb".
 
 
-The following are mandatory properties for Keystone 2 66AK2G SoCs only:
+The following are mandatory properties for 66AK2G and AM654:
 
 - power-domains:       Should contain a phandle to a PM domain provider node
                        and an args specifier containing the USB device id
index 95afdcf..cb695aa 100644 (file)
@@ -4,6 +4,7 @@ Required properties:
 - compatible:          Compatible list, contains
                        "qcom,dwc3"
                        "qcom,msm8996-dwc3" for msm8996 SOC.
+                       "qcom,msm8998-dwc3" for msm8998 SOC.
                        "qcom,sdm845-dwc3" for sdm845 SOC.
 - reg:                 Offset and length of register set for QSCRATCH wrapper
 - power-domains:       specifies a phandle to PM domain provider node
index d366555..35039e7 100644 (file)
@@ -3,6 +3,7 @@ Renesas Electronics USB3.0 Peripheral driver
 Required properties:
   - compatible: Must contain one of the following:
        - "renesas,r8a774a1-usb3-peri"
+       - "renesas,r8a774c0-usb3-peri"
        - "renesas,r8a7795-usb3-peri"
        - "renesas,r8a7796-usb3-peri"
        - "renesas,r8a77965-usb3-peri"
index 90719f5..d93b6a1 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
        - "renesas,usbhs-r8a7744" for r8a7744 (RZ/G1N) compatible device
        - "renesas,usbhs-r8a7745" for r8a7745 (RZ/G1E) compatible device
        - "renesas,usbhs-r8a774a1" for r8a774a1 (RZ/G2M) compatible device
+       - "renesas,usbhs-r8a774c0" for r8a774c0 (RZ/G2E) compatible device
        - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device
        - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device
        - "renesas,usbhs-r8a7792" for r8a7792 (R-Car V2H) compatible device
index 55ef3cc..6812a8a 100644 (file)
@@ -768,22 +768,13 @@ static u32 dwc2_gadget_get_desc_params(struct dwc2_hsotg_ep *hs_ep, u32 *mask)
        return desc_size;
 }
 
-/*
- * dwc2_gadget_config_nonisoc_xfer_ddma - prepare non ISOC DMA desc chain.
- * @hs_ep: The endpoint
- * @dma_buff: DMA address to use
- * @len: Length of the transfer
- *
- * This function will iterate over descriptor chain and fill its entries
- * with corresponding information based on transfer data.
- */
-static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
+static void dwc2_gadget_fill_nonisoc_xfer_ddma_one(struct dwc2_hsotg_ep *hs_ep,
+                                                struct dwc2_dma_desc **desc,
                                                 dma_addr_t dma_buff,
-                                                unsigned int len)
+                                                unsigned int len,
+                                                bool true_last)
 {
-       struct dwc2_hsotg *hsotg = hs_ep->parent;
        int dir_in = hs_ep->dir_in;
-       struct dwc2_dma_desc *desc = hs_ep->desc_list;
        u32 mps = hs_ep->ep.maxpacket;
        u32 maxsize = 0;
        u32 offset = 0;
@@ -798,39 +789,77 @@ static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
                hs_ep->desc_count = 1;
 
        for (i = 0; i < hs_ep->desc_count; ++i) {
-               desc->status = 0;
-               desc->status |= (DEV_DMA_BUFF_STS_HBUSY
+               (*desc)->status = 0;
+               (*desc)->status |= (DEV_DMA_BUFF_STS_HBUSY
                                 << DEV_DMA_BUFF_STS_SHIFT);
 
                if (len > maxsize) {
                        if (!hs_ep->index && !dir_in)
-                               desc->status |= (DEV_DMA_L | DEV_DMA_IOC);
+                               (*desc)->status |= (DEV_DMA_L | DEV_DMA_IOC);
 
-                       desc->status |= (maxsize <<
-                                               DEV_DMA_NBYTES_SHIFT & mask);
-                       desc->buf = dma_buff + offset;
+                       (*desc)->status |=
+                               maxsize << DEV_DMA_NBYTES_SHIFT & mask;
+                       (*desc)->buf = dma_buff + offset;
 
                        len -= maxsize;
                        offset += maxsize;
                } else {
-                       desc->status |= (DEV_DMA_L | DEV_DMA_IOC);
+                       if (true_last)
+                               (*desc)->status |= (DEV_DMA_L | DEV_DMA_IOC);
 
                        if (dir_in)
-                               desc->status |= (len % mps) ? DEV_DMA_SHORT :
-                                       ((hs_ep->send_zlp) ? DEV_DMA_SHORT : 0);
-                       if (len > maxsize)
-                               dev_err(hsotg->dev, "wrong len %d\n", len);
+                               (*desc)->status |= (len % mps) ? DEV_DMA_SHORT :
+                                       ((hs_ep->send_zlp && true_last) ?
+                                       DEV_DMA_SHORT : 0);
 
-                       desc->status |=
+                       (*desc)->status |=
                                len << DEV_DMA_NBYTES_SHIFT & mask;
-                       desc->buf = dma_buff + offset;
+                       (*desc)->buf = dma_buff + offset;
                }
 
-               desc->status &= ~DEV_DMA_BUFF_STS_MASK;
-               desc->status |= (DEV_DMA_BUFF_STS_HREADY
+               (*desc)->status &= ~DEV_DMA_BUFF_STS_MASK;
+               (*desc)->status |= (DEV_DMA_BUFF_STS_HREADY
                                 << DEV_DMA_BUFF_STS_SHIFT);
-               desc++;
+               (*desc)++;
+       }
+}
+
+/*
+ * dwc2_gadget_config_nonisoc_xfer_ddma - prepare non ISOC DMA desc chain.
+ * @hs_ep: The endpoint
+ * @ureq: Request to transfer
+ * @offset: offset in bytes
+ * @len: Length of the transfer
+ *
+ * This function will iterate over descriptor chain and fill its entries
+ * with corresponding information based on transfer data.
+ */
+static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
+                                                struct usb_request *ureq,
+                                                unsigned int offset,
+                                                unsigned int len)
+{
+       struct dwc2_dma_desc *desc = hs_ep->desc_list;
+       struct scatterlist *sg;
+       int i;
+       u8 desc_count = 0;
+
+       /* non-DMA sg buffer */
+       if (!ureq->num_sgs) {
+               dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
+                       ureq->dma + offset, len, true);
+               return;
        }
+
+       /* DMA sg buffer */
+       for_each_sg(ureq->sg, sg, ureq->num_sgs, i) {
+               dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
+                       sg_dma_address(sg) + sg->offset, sg_dma_len(sg),
+                       sg_is_last(sg));
+               desc_count += hs_ep->desc_count;
+       }
+
+       hs_ep->desc_count = desc_count;
 }
 
 /*
@@ -944,7 +973,13 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
 
        hs_ep->next_desc = 0;
        list_for_each_entry_safe(hs_req, treq, &hs_ep->queue, queue) {
-               ret = dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma,
+               dma_addr_t dma_addr = hs_req->req.dma;
+
+               if (hs_req->req.num_sgs) {
+                       WARN_ON(hs_req->req.num_sgs > 1);
+                       dma_addr = sg_dma_address(hs_req->req.sg);
+               }
+               ret = dwc2_gadget_fill_isoc_desc(hs_ep, dma_addr,
                                                 hs_req->req.length);
                if (ret)
                        break;
@@ -1100,7 +1135,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
                        offset = ureq->actual;
 
                /* Fill DDMA chain entries */
-               dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq->dma + offset,
+               dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq, offset,
                                                     length);
 
                /* write descriptor chain address to control register */
@@ -1399,7 +1434,13 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
         */
        if (using_desc_dma(hs) && hs_ep->isochronous) {
                if (hs_ep->target_frame != TARGET_FRAME_INITIAL) {
-                       dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma,
+                       dma_addr_t dma_addr = hs_req->req.dma;
+
+                       if (hs_req->req.num_sgs) {
+                               WARN_ON(hs_req->req.num_sgs > 1);
+                               dma_addr = sg_dma_address(hs_req->req.sg);
+                       }
+                       dwc2_gadget_fill_isoc_desc(hs_ep, dma_addr,
                                                   hs_req->req.length);
                }
                return 0;
@@ -1987,13 +2028,12 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
                dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
                        index);
        if (using_desc_dma(hsotg)) {
-               /* Not specific buffer needed for ep0 ZLP */
-               dma_addr_t dma = hs_ep->desc_list_dma;
-
                if (!index)
                        dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);
 
-               dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);
+               /* Not specific buffer needed for ep0 ZLP */
+               dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &hs_ep->desc_list,
+                       hs_ep->desc_list_dma, 0, true);
        } else {
                dwc2_writel(hsotg, DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
                            DXEPTSIZ_XFERSIZE(0),
@@ -4005,6 +4045,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
                        ret = -ENOMEM;
                        goto error1;
                }
+               epctrl &= ~(DXEPCTL_TXFNUM_LIMIT << DXEPCTL_TXFNUM_SHIFT);
                hsotg->fifo_map |= 1 << fifo_index;
                epctrl |= DXEPCTL_TXFNUM(fifo_index);
                hs_ep->fifo_index = fifo_index;
@@ -4385,6 +4426,7 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
        hsotg->enabled = 0;
        spin_unlock_irqrestore(&hsotg->lock, flags);
 
+       gadget->sg_supported = using_desc_dma(hsotg);
        dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 
        return 0;
index d7e4cab..2b14944 100644 (file)
@@ -88,11 +88,11 @@ config USB_DWC3_HAPS
          platform, please say 'Y' or 'M' here.
 
 config USB_DWC3_KEYSTONE
-       tristate "Texas Instruments Keystone2 Platforms"
-       depends on ARCH_KEYSTONE || COMPILE_TEST
+       tristate "Texas Instruments Keystone2/AM654 Platforms"
+       depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
        default USB_DWC3
        help
-         Support of USB2/3 functionality in TI Keystone2 platforms.
+         Support of USB2/3 functionality in TI Keystone2 and AM654 platforms.
          Say 'Y' or 'M' here if you have one such device
 
 config USB_DWC3_OF_SIMPLE
index df87641..1528d39 100644 (file)
@@ -692,7 +692,6 @@ struct dwc3_ep {
 #define DWC3_EP_WEDGE          BIT(2)
 #define DWC3_EP_TRANSFER_STARTED BIT(3)
 #define DWC3_EP_PENDING_REQUEST        BIT(5)
-#define DWC3_EP_END_TRANSFER_PENDING   BIT(7)
 
        /* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN                BIT(31)
@@ -863,6 +862,7 @@ struct dwc3_hwparams {
  * @num_pending_sgs: counter to pending sgs
  * @num_queued_sgs: counter to the number of sgs which already got queued
  * @remaining: amount of data remaining
+ * @status: internal dwc3 request status tracking
  * @epnum: endpoint number to which this request refers
  * @trb: pointer to struct dwc3_trb
  * @trb_dma: DMA address of @trb
@@ -871,7 +871,6 @@ struct dwc3_hwparams {
  *     or unaligned OUT)
  * @direction: IN or OUT direction flag
  * @mapped: true when request has been dma-mapped
- * @started: request is started
  */
 struct dwc3_request {
        struct usb_request      request;
@@ -883,6 +882,14 @@ struct dwc3_request {
        unsigned                num_pending_sgs;
        unsigned int            num_queued_sgs;
        unsigned                remaining;
+
+       unsigned int            status;
+#define DWC3_REQUEST_STATUS_QUEUED     0
+#define DWC3_REQUEST_STATUS_STARTED    1
+#define DWC3_REQUEST_STATUS_CANCELLED  2
+#define DWC3_REQUEST_STATUS_COMPLETED  3
+#define DWC3_REQUEST_STATUS_UNKNOWN    -1
+
        u8                      epnum;
        struct dwc3_trb         *trb;
        dma_addr_t              trb_dma;
@@ -892,7 +899,6 @@ struct dwc3_request {
        unsigned                needs_extra_trb:1;
        unsigned                direction:1;
        unsigned                mapped:1;
-       unsigned                started:1;
 };
 
 /*
index 4f75ab3..6759a7e 100644 (file)
@@ -193,65 +193,69 @@ static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
  * dwc3_gadget_event_string - returns event name
  * @event: the event code
  */
-static inline const char *
-dwc3_gadget_event_string(char *str, const struct dwc3_event_devt *event)
+static inline const char *dwc3_gadget_event_string(char *str, size_t size,
+               const struct dwc3_event_devt *event)
 {
        enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK;
 
        switch (event->type) {
        case DWC3_DEVICE_EVENT_DISCONNECT:
-               sprintf(str, "Disconnect: [%s]",
+               snprintf(str, size, "Disconnect: [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_RESET:
-               sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state));
+               snprintf(str, size, "Reset [%s]",
+                               dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_CONNECT_DONE:
-               sprintf(str, "Connection Done [%s]",
+               snprintf(str, size, "Connection Done [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
-               sprintf(str, "Link Change [%s]",
+               snprintf(str, size, "Link Change [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_WAKEUP:
-               sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state));
+               snprintf(str, size, "WakeUp [%s]",
+                               dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_EOPF:
-               sprintf(str, "End-Of-Frame [%s]",
+               snprintf(str, size, "End-Of-Frame [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_SOF:
-               sprintf(str, "Start-Of-Frame [%s]",
+               snprintf(str, size, "Start-Of-Frame [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
-               sprintf(str, "Erratic Error [%s]",
+               snprintf(str, size, "Erratic Error [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_CMD_CMPL:
-               sprintf(str, "Command Complete [%s]",
+               snprintf(str, size, "Command Complete [%s]",
                                dwc3_gadget_link_string(state));
                break;
        case DWC3_DEVICE_EVENT_OVERFLOW:
-               sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state));
+               snprintf(str, size, "Overflow [%s]",
+                               dwc3_gadget_link_string(state));
                break;
        default:
-               sprintf(str, "UNKNOWN");
+               snprintf(str, size, "UNKNOWN");
        }
 
        return str;
 }
 
-static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str)
+static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str,
+               size_t size)
 {
        switch (t & USB_RECIP_MASK) {
        case USB_RECIP_INTERFACE:
-               sprintf(str, "Get Interface Status(Intf = %d, Length = %d)",
-                       i, l);
+               snprintf(str, size, "Get Interface Status(Intf = %d, Length = %d)",
+                               i, l);
                break;
        case USB_RECIP_ENDPOINT:
-               sprintf(str, "Get Endpoint Status(ep%d%s)",
+               snprintf(str, size, "Get Endpoint Status(ep%d%s)",
                        i & ~USB_DIR_IN,
                        i & USB_DIR_IN ? "in" : "out");
                break;
@@ -259,11 +263,11 @@ static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str)
 }
 
 static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v,
-                                                __u16 i, char *str)
+               __u16 i, char *str, size_t size)
 {
        switch (t & USB_RECIP_MASK) {
        case USB_RECIP_DEVICE:
-               sprintf(str, "%s Device Feature(%s%s)",
+               snprintf(str, size, "%s Device Feature(%s%s)",
                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
                        ({char *s;
                                switch (v) {
@@ -311,13 +315,13 @@ static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v,
                                } s; }) : "");
                break;
        case USB_RECIP_INTERFACE:
-               sprintf(str, "%s Interface Feature(%s)",
+               snprintf(str, size, "%s Interface Feature(%s)",
                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
                        v == USB_INTRF_FUNC_SUSPEND ?
                        "Function Suspend" : "UNKNOWN");
                break;
        case USB_RECIP_ENDPOINT:
-               sprintf(str, "%s Endpoint Feature(%s ep%d%s)",
+               snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
                        b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
                        v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
                        i & ~USB_DIR_IN,
@@ -326,15 +330,15 @@ static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v,
        }
 }
 
-static inline void dwc3_decode_set_address(__u16 v, char *str)
+static inline void dwc3_decode_set_address(__u16 v, char *str, size_t size)
 {
-       sprintf(str, "Set Address(Addr = %02x)", v);
+       snprintf(str, size, "Set Address(Addr = %02x)", v);
 }
 
 static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v,
-                                                 __u16 i, __u16 l, char *str)
+               __u16 i, __u16 l, char *str, size_t size)
 {
-       sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)",
+       snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
                b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
                ({ char *s;
                        switch (v >> 8) {
@@ -393,87 +397,92 @@ static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v,
 }
 
 
-static inline void dwc3_decode_get_configuration(__u16 l, char *str)
+static inline void dwc3_decode_get_configuration(__u16 l, char *str,
+               size_t size)
 {
-       sprintf(str, "Get Configuration(Length = %d)", l);
+       snprintf(str, size, "Get Configuration(Length = %d)", l);
 }
 
-static inline void dwc3_decode_set_configuration(__u8 v, char *str)
+static inline void dwc3_decode_set_configuration(__u8 v, char *str, size_t size)
 {
-       sprintf(str, "Set Configuration(Config = %d)", v);
+       snprintf(str, size, "Set Configuration(Config = %d)", v);
 }
 
-static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str)
+static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str,
+               size_t size)
 {
-       sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l);
+       snprintf(str, size, "Get Interface(Intf = %d, Length = %d)", i, l);
 }
 
-static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str)
+static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str, size_t size)
 {
-       sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v);
+       snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v);
 }
 
-static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str)
+static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str,
+               size_t size)
 {
-       sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l);
+       snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)", i, l);
 }
 
-static inline void dwc3_decode_set_sel(__u16 l, char *str)
+static inline void dwc3_decode_set_sel(__u16 l, char *str, size_t size)
 {
-       sprintf(str, "Set SEL(Length = %d)", l);
+       snprintf(str, size, "Set SEL(Length = %d)", l);
 }
 
-static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str)
+static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str, size_t size)
 {
-       sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v);
+       snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", v);
 }
 
 /**
  * dwc3_decode_ctrl - returns a string represetion of ctrl request
  */
-static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType,
-               __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength)
+static inline const char *dwc3_decode_ctrl(char *str, size_t size,
+               __u8 bRequestType, __u8 bRequest, __u16 wValue, __u16 wIndex,
+               __u16 wLength)
 {
        switch (bRequest) {
        case USB_REQ_GET_STATUS:
-               dwc3_decode_get_status(bRequestType, wIndex, wLength, str);
+               dwc3_decode_get_status(bRequestType, wIndex, wLength, str,
+                               size);
                break;
        case USB_REQ_CLEAR_FEATURE:
        case USB_REQ_SET_FEATURE:
                dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue,
-                                             wIndex, str);
+                               wIndex, str, size);
                break;
        case USB_REQ_SET_ADDRESS:
-               dwc3_decode_set_address(wValue, str);
+               dwc3_decode_set_address(wValue, str, size);
                break;
        case USB_REQ_GET_DESCRIPTOR:
        case USB_REQ_SET_DESCRIPTOR:
                dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue,
-                                              wIndex, wLength, str);
+                               wIndex, wLength, str, size);
                break;
        case USB_REQ_GET_CONFIGURATION:
-               dwc3_decode_get_configuration(wLength, str);
+               dwc3_decode_get_configuration(wLength, str, size);
                break;
        case USB_REQ_SET_CONFIGURATION:
-               dwc3_decode_set_configuration(wValue, str);
+               dwc3_decode_set_configuration(wValue, str, size);
                break;
        case USB_REQ_GET_INTERFACE:
-               dwc3_decode_get_intf(wIndex, wLength, str);
+               dwc3_decode_get_intf(wIndex, wLength, str, size);
                break;
        case USB_REQ_SET_INTERFACE:
-               dwc3_decode_set_intf(wValue, wIndex, str);
+               dwc3_decode_set_intf(wValue, wIndex, str, size);
                break;
        case USB_REQ_SYNCH_FRAME:
-               dwc3_decode_synch_frame(wIndex, wLength, str);
+               dwc3_decode_synch_frame(wIndex, wLength, str, size);
                break;
        case USB_REQ_SET_SEL:
-               dwc3_decode_set_sel(wLength, str);
+               dwc3_decode_set_sel(wLength, str, size);
                break;
        case USB_REQ_SET_ISOCH_DELAY:
-               dwc3_decode_set_isoch_delay(wValue, str);
+               dwc3_decode_set_isoch_delay(wValue, str, size);
                break;
        default:
-               sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x",
+               snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
                        bRequestType, bRequest,
                        cpu_to_le16(wValue) & 0xff,
                        cpu_to_le16(wValue) >> 8,
@@ -490,16 +499,15 @@ static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType,
  * dwc3_ep_event_string - returns event name
  * @event: then event code
  */
-static inline const char *
-dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event,
-                    u32 ep0state)
+static inline const char *dwc3_ep_event_string(char *str, size_t size,
+               const struct dwc3_event_depevt *event, u32 ep0state)
 {
        u8 epnum = event->endpoint_number;
        size_t len;
        int status;
        int ret;
 
-       ret = sprintf(str, "ep%d%s: ", epnum >> 1,
+       ret = snprintf(str, size, "ep%d%s: ", epnum >> 1,
                        (epnum & 1) ? "in" : "out");
        if (ret < 0)
                return "UNKNOWN";
@@ -509,7 +517,7 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event,
        switch (event->endpoint_event) {
        case DWC3_DEPEVT_XFERCOMPLETE:
                len = strlen(str);
-               sprintf(str + len, "Transfer Complete (%c%c%c)",
+               snprintf(str + len, size - len, "Transfer Complete (%c%c%c)",
                                status & DEPEVT_STATUS_SHORT ? 'S' : 's',
                                status & DEPEVT_STATUS_IOC ? 'I' : 'i',
                                status & DEPEVT_STATUS_LST ? 'L' : 'l');
@@ -517,12 +525,13 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event,
                len = strlen(str);
 
                if (epnum <= 1)
-                       sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state));
+                       snprintf(str + len, size - len, " [%s]",
+                                       dwc3_ep0_state_string(ep0state));
                break;
        case DWC3_DEPEVT_XFERINPROGRESS:
                len = strlen(str);
 
-               sprintf(str + len, "Transfer In Progress [%d] (%c%c%c)",
+               snprintf(str + len, size - len, "Transfer In Progress [%d] (%c%c%c)",
                                event->parameters,
                                status & DEPEVT_STATUS_SHORT ? 'S' : 's',
                                status & DEPEVT_STATUS_IOC ? 'I' : 'i',
@@ -531,47 +540,51 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event,
        case DWC3_DEPEVT_XFERNOTREADY:
                len = strlen(str);
 
-               sprintf(str + len, "Transfer Not Ready [%d]%s",
+               snprintf(str + len, size - len, "Transfer Not Ready [%d]%s",
                                event->parameters,
                                status & DEPEVT_STATUS_TRANSFER_ACTIVE ?
                                " (Active)" : " (Not Active)");
 
+               len = strlen(str);
+
                /* Control Endpoints */
                if (epnum <= 1) {
                        int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status);
 
                        switch (phase) {
                        case DEPEVT_STATUS_CONTROL_DATA:
-                               strcat(str, " [Data Phase]");
+                               snprintf(str + ret, size - ret,
+                                               " [Data Phase]");
                                break;
                        case DEPEVT_STATUS_CONTROL_STATUS:
-                               strcat(str, " [Status Phase]");
+                               snprintf(str + ret, size - ret,
+                                               " [Status Phase]");
                        }
                }
                break;
        case DWC3_DEPEVT_RXTXFIFOEVT:
-               strcat(str, "FIFO");
+               snprintf(str + ret, size - ret, "FIFO");
                break;
        case DWC3_DEPEVT_STREAMEVT:
                status = event->status;
 
                switch (status) {
                case DEPEVT_STREAMEVT_FOUND:
-                       sprintf(str + ret, " Stream %d Found",
+                       snprintf(str + ret, size - ret, " Stream %d Found",
                                        event->parameters);
                        break;
                case DEPEVT_STREAMEVT_NOTFOUND:
                default:
-                       strcat(str, " Stream Not Found");
+                       snprintf(str + ret, size - ret, " Stream Not Found");
                        break;
                }
 
                break;
        case DWC3_DEPEVT_EPCMDCMPLT:
-               strcat(str, "Endpoint Command Complete");
+               snprintf(str + ret, size - ret, "Endpoint Command Complete");
                break;
        default:
-               sprintf(str, "UNKNOWN");
+               snprintf(str, size, "UNKNOWN");
        }
 
        return str;
@@ -611,14 +624,15 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
        }
 }
 
-static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state)
+static inline const char *dwc3_decode_event(char *str, size_t size, u32 event,
+               u32 ep0state)
 {
        const union dwc3_event evt = (union dwc3_event) event;
 
        if (evt.type.is_devspec)
-               return dwc3_gadget_event_string(str, &evt.devt);
+               return dwc3_gadget_event_string(str, size, &evt.devt);
        else
-               return dwc3_ep_event_string(str, &evt.depevt, ep0state);
+               return dwc3_ep_event_string(str, size, &evt.depevt, ep0state);
 }
 
 static inline const char *dwc3_ep_cmd_status_string(int status)
index 193a9a8..cbee5fb 100644 (file)
@@ -106,6 +106,10 @@ static int kdwc3_probe(struct platform_device *pdev)
                goto err_irq;
        }
 
+       /* IRQ processing not required currently for AM65 */
+       if (of_device_is_compatible(node, "ti,am654-dwc3"))
+               goto skip_irq;
+
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(&pdev->dev, "missing irq\n");
@@ -123,6 +127,7 @@ static int kdwc3_probe(struct platform_device *pdev)
 
        kdwc3_enable_irqs(kdwc);
 
+skip_irq:
        error = of_platform_populate(node, NULL, NULL, dev);
        if (error) {
                dev_err(&pdev->dev, "failed to create dwc3 core\n");
@@ -152,8 +157,11 @@ static int kdwc3_remove_core(struct device *dev, void *c)
 static int kdwc3_remove(struct platform_device *pdev)
 {
        struct dwc3_keystone *kdwc = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+
+       if (!of_device_is_compatible(node, "ti,am654-dwc3"))
+               kdwc3_disable_irqs(kdwc);
 
-       kdwc3_disable_irqs(kdwc);
        device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core);
        pm_runtime_put_sync(kdwc->dev);
        pm_runtime_disable(kdwc->dev);
@@ -165,6 +173,7 @@ static int kdwc3_remove(struct platform_device *pdev)
 
 static const struct of_device_id kdwc3_of_match[] = {
        { .compatible = "ti,keystone-dwc3", },
+       { .compatible = "ti,am654-dwc3" },
        {},
 };
 MODULE_DEVICE_TABLE(of, kdwc3_of_match);
index a6d0203..184df4d 100644 (file)
@@ -595,6 +595,7 @@ static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
 static const struct of_device_id dwc3_qcom_of_match[] = {
        { .compatible = "qcom,dwc3" },
        { .compatible = "qcom,msm8996-dwc3" },
+       { .compatible = "qcom,msm8998-dwc3" },
        { .compatible = "qcom,sdm845-dwc3" },
        { }
 };
index 6c9b76b..e83f84e 100644 (file)
@@ -174,7 +174,6 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep,
 {
        struct dwc3                     *dwc = dep->dwc;
 
-       req->started = false;
        list_del(&req->list);
        req->remaining = 0;
        req->needs_extra_trb = false;
@@ -209,6 +208,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
        struct dwc3                     *dwc = dep->dwc;
 
        dwc3_gadget_del_and_unmap_request(dep, req, status);
+       req->status = DWC3_REQUEST_STATUS_COMPLETED;
 
        spin_unlock(&dwc->lock);
        usb_gadget_giveback_request(&dep->endpoint, &req->request);
@@ -384,19 +384,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 
        trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status);
 
-       if (ret == 0) {
-               switch (DWC3_DEPCMD_CMD(cmd)) {
-               case DWC3_DEPCMD_STARTTRANSFER:
-                       dep->flags |= DWC3_EP_TRANSFER_STARTED;
-                       dwc3_gadget_ep_get_transfer_index(dep);
-                       break;
-               case DWC3_DEPCMD_ENDTRANSFER:
-                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
-                       break;
-               default:
-                       /* nothing */
-                       break;
-               }
+       if (ret == 0 && DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
+               dep->flags |= DWC3_EP_TRANSFER_STARTED;
+               dwc3_gadget_ep_get_transfer_index(dep);
        }
 
        if (saved_config) {
@@ -642,7 +632,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
 
                dep->type = usb_endpoint_type(desc);
                dep->flags |= DWC3_EP_ENABLED;
-               dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
 
                reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
                reg |= DWC3_DALEPENA_EP(dep->number);
@@ -748,7 +737,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
 
        dep->stream_capable = false;
        dep->type = 0;
-       dep->flags &= DWC3_EP_END_TRANSFER_PENDING;
+       dep->flags = 0;
 
        /* Clear out the ep descriptors for non-ep0 */
        if (dep->number > 1) {
@@ -847,6 +836,7 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
        req->direction  = dep->direction;
        req->epnum      = dep->number;
        req->dep        = dep;
+       req->status     = DWC3_REQUEST_STATUS_UNKNOWN;
 
        trace_dwc3_alloc_request(req);
 
@@ -1435,6 +1425,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
                                &req->request, req->dep->name))
                return -EINVAL;
 
+       if (WARN(req->status < DWC3_REQUEST_STATUS_COMPLETED,
+                               "%s: request %pK already in flight\n",
+                               dep->name, &req->request))
+               return -EINVAL;
+
        pm_runtime_get(dwc->dev);
 
        req->request.actual     = 0;
@@ -1443,6 +1438,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
        trace_dwc3_ep_queue(req);
 
        list_add_tail(&req->list, &dep->pending_list);
+       req->status = DWC3_REQUEST_STATUS_QUEUED;
 
        /*
         * NOTICE: Isochronous endpoints should NEVER be prestarted. We must
@@ -1553,7 +1549,10 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
                                goto out0;
 
                        dwc3_gadget_move_cancelled_request(req);
-                       goto out0;
+                       if (dep->flags & DWC3_EP_TRANSFER_STARTED)
+                               goto out0;
+                       else
+                               goto out1;
                }
                dev_err(dwc->dev, "request %pK was not queued to %s\n",
                                request, ep->name);
@@ -1561,6 +1560,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
                goto out0;
        }
 
+out1:
        dwc3_gadget_giveback(dep, req, -ECONNRESET);
 
 out0:
@@ -2547,7 +2547,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
        dep = dwc->eps[epnum];
 
        if (!(dep->flags & DWC3_EP_ENABLED)) {
-               if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+               if (!(dep->flags & DWC3_EP_TRANSFER_STARTED))
                        return;
 
                /* Handle only EPCMDCMPLT when EP disabled */
@@ -2571,7 +2571,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
                cmd = DEPEVT_PARAMETER_CMD(event->parameters);
 
                if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
-                       dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
                        dwc3_gadget_ep_cleanup_cancelled_requests(dep);
                }
                break;
@@ -2628,8 +2628,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force)
        u32 cmd;
        int ret;
 
-       if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) ||
-           !dep->resource_index)
+       if (!(dep->flags & DWC3_EP_TRANSFER_STARTED))
                return;
 
        /*
@@ -2672,10 +2671,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force)
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
-       if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) {
-               dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+       if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
                udelay(100);
-       }
 }
 
 static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
@@ -3339,6 +3336,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
                goto err4;
        }
 
+       dwc3_gadget_set_speed(&dwc->gadget, dwc->maximum_speed);
+
        return 0;
 
 err4:
index 023a473..3ed738e 100644 (file)
@@ -75,7 +75,7 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
 {
        struct dwc3_ep          *dep = req->dep;
 
-       req->started = true;
+       req->status = DWC3_REQUEST_STATUS_STARTED;
        list_move_tail(&req->list, &dep->started_list);
 }
 
@@ -90,7 +90,7 @@ static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req)
 {
        struct dwc3_ep          *dep = req->dep;
 
-       req->started = false;
+       req->status = DWC3_REQUEST_STATUS_CANCELLED;
        list_move_tail(&req->list, &dep->cancelled_list);
 }
 
index e97a005..818a63d 100644 (file)
@@ -59,8 +59,8 @@ DECLARE_EVENT_CLASS(dwc3_log_event,
                __entry->ep0state = dwc->ep0state;
        ),
        TP_printk("event (%08x): %s", __entry->event,
-                       dwc3_decode_event(__get_str(str), __entry->event,
-                                         __entry->ep0state))
+                       dwc3_decode_event(__get_str(str), DWC3_MSG_MAX,
+                                       __entry->event, __entry->ep0state))
 );
 
 DEFINE_EVENT(dwc3_log_event, dwc3_event,
@@ -86,7 +86,8 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl,
                __entry->wIndex = le16_to_cpu(ctrl->wIndex);
                __entry->wLength = le16_to_cpu(ctrl->wLength);
        ),
-       TP_printk("%s", dwc3_decode_ctrl(__get_str(str), __entry->bRequestType,
+       TP_printk("%s", dwc3_decode_ctrl(__get_str(str), DWC3_MSG_MAX,
+                                       __entry->bRequestType,
                                        __entry->bRequest, __entry->wValue,
                                        __entry->wIndex, __entry->wLength)
        )
@@ -305,7 +306,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep,
                __entry->trb_enqueue = dep->trb_enqueue;
                __entry->trb_dequeue = dep->trb_dequeue;
        ),
-       TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c:%c",
+       TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c",
                __get_str(name), __entry->maxpacket,
                __entry->maxpacket_limit, __entry->max_streams,
                __entry->maxburst, __entry->trb_enqueue,
@@ -315,7 +316,6 @@ DECLARE_EVENT_CLASS(dwc3_log_ep,
                __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',
                __entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',
                __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
-               __entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',
                __entry->direction ? '<' : '>'
        )
 );
index 71b15c6..1eb4fa2 100644 (file)
@@ -67,9 +67,6 @@ struct usb_ep *usb_ep_autoconfig_ss(
 )
 {
        struct usb_ep   *ep;
-       u8              type;
-
-       type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
 
        if (gadget->ops->match_ep) {
                ep = gadget->ops->match_ep(gadget, desc, ep_comp);
@@ -109,16 +106,6 @@ found_ep:
                desc->bEndpointAddress |= gadget->out_epnum;
        }
 
-       /* report (variable) full speed bulk maxpacket */
-       if ((type == USB_ENDPOINT_XFER_BULK) && !ep_comp) {
-               int size = ep->maxpacket_limit;
-
-               /* min() doesn't work on bitfields with gcc-3.5 */
-               if (size > 64)
-                       size = 64;
-               desc->wMaxPacketSize = cpu_to_le16(size);
-       }
-
        ep->address = desc->bEndpointAddress;
        ep->desc = NULL;
        ep->comp_desc = NULL;
@@ -152,9 +139,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
  *
  * On success, this returns an claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
- * is initialized as if the endpoint were used at full speed.  To prevent
- * the endpoint from being returned by a later autoconfig call, claims it
- * by assigning ep->claimed to true.
+ * is initialized as if the endpoint were used at full speed. Because of
+ * that the users must consider adjusting the autoconfigured descriptor.
+ * To prevent the endpoint from being returned by a later autoconfig call,
+ * claims it by assigning ep->claimed to true.
  *
  * On failure, this returns a null endpoint descriptor.
  */
@@ -163,7 +151,26 @@ struct usb_ep *usb_ep_autoconfig(
        struct usb_endpoint_descriptor  *desc
 )
 {
-       return usb_ep_autoconfig_ss(gadget, desc, NULL);
+       struct usb_ep   *ep;
+       u8              type;
+
+       ep = usb_ep_autoconfig_ss(gadget, desc, NULL);
+       if (!ep)
+               return NULL;
+
+       type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+       /* report (variable) full speed bulk maxpacket */
+       if (type == USB_ENDPOINT_XFER_BULK) {
+               int size = ep->maxpacket_limit;
+
+               /* min() doesn't work on bitfields with gcc-3.5 */
+               if (size > 64)
+                       size = 64;
+               desc->wMaxPacketSize = cpu_to_le16(size);
+       }
+
+       return ep;
 }
 EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
 
index 1e54304..66a2c16 100644 (file)
@@ -2843,12 +2843,18 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
                struct usb_request *req;
                struct usb_ep *ep;
                u8 bEndpointAddress;
+               u16 wMaxPacketSize;
 
                /*
                 * We back up bEndpointAddress because autoconfig overwrites
                 * it with physical endpoint address.
                 */
                bEndpointAddress = ds->bEndpointAddress;
+               /*
+                * We back up wMaxPacketSize because autoconfig treats
+                * endpoint descriptors as if they were full speed.
+                */
+               wMaxPacketSize = ds->wMaxPacketSize;
                pr_vdebug("autoconfig\n");
                ep = usb_ep_autoconfig(func->gadget, ds);
                if (unlikely(!ep))
@@ -2869,6 +2875,11 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
                 */
                if (func->ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
                        ds->bEndpointAddress = bEndpointAddress;
+               /*
+                * Restore wMaxPacketSize which was potentially
+                * overwritten by autoconfig.
+                */
+               ds->wMaxPacketSize = wMaxPacketSize;
        }
        ffs_dump_mem(": Rewritten ep desc", ds, ds->bLength);
 
index 2746a92..00d3469 100644 (file)
@@ -459,10 +459,10 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        } else if (intf == uac1->as_in_intf) {
                uac1->as_in_alt = alt;
 
-                       if (alt)
-                               ret = u_audio_start_playback(&uac1->g_audio);
-                       else
-                               u_audio_stop_playback(&uac1->g_audio);
+               if (alt)
+                       ret = u_audio_start_playback(&uac1->g_audio);
+               else
+                       u_audio_stop_playback(&uac1->g_audio);
        } else {
                dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
                return -EINVAL;
@@ -568,6 +568,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
                goto fail;
        as_out_interface_alt_0_desc.bInterfaceNumber = status;
        as_out_interface_alt_1_desc.bInterfaceNumber = status;
+       ac_header_desc.baInterfaceNr[0] = status;
        uac1->as_out_intf = status;
        uac1->as_out_alt = 0;
 
@@ -576,6 +577,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
                goto fail;
        as_in_interface_alt_0_desc.bInterfaceNumber = status;
        as_in_interface_alt_1_desc.bInterfaceNumber = status;
+       ac_header_desc.baInterfaceNr[1] = status;
        uac1->as_in_intf = status;
        uac1->as_in_alt = 0;
 
index 29436f7..65f634e 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/tty.h>
@@ -26,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/console.h>
 #include <linux/kthread.h>
+#include <linux/workqueue.h>
 #include <linux/kfifo.h>
 
 #include "u_serial.h"
@@ -110,7 +110,7 @@ struct gs_port {
        int read_allocated;
        struct list_head        read_queue;
        unsigned                n_read;
-       struct tasklet_struct   push;
+       struct delayed_work     push;
 
        struct list_head        write_pool;
        int write_started;
@@ -352,9 +352,10 @@ __acquires(&port->port_lock)
  * So QUEUE_SIZE packets plus however many the FIFO holds (usually two)
  * can be buffered before the TTY layer's buffers (currently 64 KB).
  */
-static void gs_rx_push(unsigned long _port)
+static void gs_rx_push(struct work_struct *work)
 {
-       struct gs_port          *port = (void *)_port;
+       struct delayed_work     *w = to_delayed_work(work);
+       struct gs_port          *port = container_of(w, struct gs_port, push);
        struct tty_struct       *tty;
        struct list_head        *queue = &port->read_queue;
        bool                    disconnect = false;
@@ -429,21 +430,13 @@ static void gs_rx_push(unsigned long _port)
 
        /* We want our data queue to become empty ASAP, keeping data
         * in the tty and ldisc (not here).  If we couldn't push any
-        * this time around, there may be trouble unless there's an
-        * implicit tty_unthrottle() call on its way...
+        * this time around, RX may be starved, so wait until next jiffy.
         *
-        * REVISIT we should probably add a timer to keep the tasklet
-        * from starving ... but it's not clear that case ever happens.
+        * We may leave non-empty queue only when there is a tty, and
+        * either it is throttled or there is no more room in flip buffer.
         */
-       if (!list_empty(queue) && tty) {
-               if (!tty_throttled(tty)) {
-                       if (do_push)
-                               tasklet_schedule(&port->push);
-                       else
-                               pr_warn("ttyGS%d: RX not scheduled?\n",
-                                       port->port_num);
-               }
-       }
+       if (!list_empty(queue) && !tty_throttled(tty))
+               schedule_delayed_work(&port->push, 1);
 
        /* If we're still connected, refill the USB RX queue. */
        if (!disconnect && port->port_usb)
@@ -459,7 +452,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
        /* Queue all received data until the tty layer is ready for it. */
        spin_lock(&port->port_lock);
        list_add_tail(&req->list, &port->read_queue);
-       tasklet_schedule(&port->push);
+       schedule_delayed_work(&port->push, 0);
        spin_unlock(&port->port_lock);
 }
 
@@ -854,8 +847,8 @@ static void gs_unthrottle(struct tty_struct *tty)
                 * rts/cts, or other handshaking with the host, but if the
                 * read queue backs up enough we'll be NAKing OUT packets.
                 */
-               tasklet_schedule(&port->push);
                pr_vdebug("ttyGS%d: unthrottle\n", port->port_num);
+               schedule_delayed_work(&port->push, 0);
        }
        spin_unlock_irqrestore(&port->port_lock, flags);
 }
@@ -1159,7 +1152,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
        init_waitqueue_head(&port->drain_wait);
        init_waitqueue_head(&port->close_wait);
 
-       tasklet_init(&port->push, gs_rx_push, (unsigned long) port);
+       INIT_DELAYED_WORK(&port->push, gs_rx_push);
 
        INIT_LIST_HEAD(&port->read_pool);
        INIT_LIST_HEAD(&port->read_queue);
@@ -1186,7 +1179,7 @@ static int gs_closed(struct gs_port *port)
 
 static void gserial_free_port(struct gs_port *port)
 {
-       tasklet_kill(&port->push);
+       cancel_delayed_work_sync(&port->push);
        /* wait for old opens to finish */
        wait_event(port->close_wait, gs_closed(port));
        WARN_ON(port->port_usb != NULL);
index 099d650..1473d25 100644 (file)
@@ -56,6 +56,8 @@ extern unsigned int uvc_gadget_trace_param;
        dev_dbg(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
 #define uvcg_info(f, fmt, args...) \
        dev_info(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
+#define uvcg_warn(f, fmt, args...) \
+       dev_warn(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
 #define uvcg_err(f, fmt, args...) \
        dev_err(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args)
 
index bc1e2af..8fe85cb 100644 (file)
@@ -1570,10 +1570,6 @@ uvcg_uncompressed_##cname##_store(struct config_item *item,              \
        if (ret)                                                        \
                goto end;                                               \
                                                                        \
-       if (num > 255) {                                                \
-               ret = -EINVAL;                                          \
-               goto end;                                               \
-       }                                                               \
        u->desc.aname = num;                                            \
        ret = len;                                                      \
 end:                                                                   \
@@ -1767,10 +1763,6 @@ uvcg_mjpeg_##cname##_store(struct config_item *item,                     \
        if (ret)                                                        \
                goto end;                                               \
                                                                        \
-       if (num > 255) {                                                \
-               ret = -EINVAL;                                          \
-               goto end;                                               \
-       }                                                               \
        u->desc.aname = num;                                            \
        ret = len;                                                      \
 end:                                                                   \
index 37ca0e6..249277d 100644 (file)
@@ -1218,27 +1218,27 @@ ep0_poll (struct file *fd, poll_table *wait)
        if (dev->state <= STATE_DEV_OPENED)
                return DEFAULT_POLLMASK;
 
-       poll_wait(fd, &dev->wait, wait);
-
-       spin_lock_irq (&dev->lock);
-
-       /* report fd mode change before acting on it */
-       if (dev->setup_abort) {
-               dev->setup_abort = 0;
-               mask = EPOLLHUP;
-               goto out;
-       }
-
-       if (dev->state == STATE_DEV_SETUP) {
-               if (dev->setup_in || dev->setup_can_stall)
-                       mask = EPOLLOUT;
-       } else {
-               if (dev->ev_next != 0)
-                       mask = EPOLLIN;
-       }
+       poll_wait(fd, &dev->wait, wait);
+
+       spin_lock_irq(&dev->lock);
+
+       /* report fd mode change before acting on it */
+       if (dev->setup_abort) {
+               dev->setup_abort = 0;
+               mask = EPOLLHUP;
+               goto out;
+       }
+
+       if (dev->state == STATE_DEV_SETUP) {
+               if (dev->setup_in || dev->setup_can_stall)
+                       mask = EPOLLOUT;
+       } else {
+               if (dev->ev_next != 0)
+                       mask = EPOLLIN;
+       }
 out:
-       spin_unlock_irq(&dev->lock);
-       return mask;
+       spin_unlock_irq(&dev->lock);
+       return mask;
 }
 
 static long dev_ioctl (struct file *fd, unsigned code, unsigned long value)
index 4a28e3f..83340f4 100644 (file)
@@ -120,7 +120,7 @@ static void ast_vhub_epn_handle_ack(struct ast_vhub_ep *ep)
        /* No current DMA ongoing */
        req->active = false;
 
-       /* Grab lenght out of HW */
+       /* Grab length out of HW */
        len = VHUB_EP_DMA_TX_SIZE(stat);
 
        /* If not using DMA, copy data out if needed */
index 35ba0e5..7c040f5 100644 (file)
@@ -295,7 +295,7 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
                dsize = AST_VHUB_HUB_DESC_SIZE;
                memcpy(ep->buf, &ast_vhub_hub_desc, dsize);
                BUILD_BUG_ON(dsize > sizeof(ast_vhub_hub_desc));
-       BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
+               BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
                break;
        default:
                return std_req_stall;
index 6305bf2..44c2a5e 100644 (file)
@@ -311,8 +311,8 @@ int bdc_ep_clear_stall(struct bdc *bdc, int epnum)
                /* if the endpoint it not stallled */
                if (!(ep->flags & BDC_EP_STALL)) {
                        ret = bdc_ep_set_stall(bdc, epnum);
-                               if (ret)
-                                       return ret;
+                       if (ret)
+                               return ret;
                }
        }
        /* Preserve the seq number for ep0 only */
index 87d6b12..7cf34be 100644 (file)
@@ -281,10 +281,10 @@ EXPORT_SYMBOL_GPL(usb_ep_queue);
  * @ep:the endpoint associated with the request
  * @req:the request being canceled
  *
- * If the request is still active on the endpoint, it is dequeued and its
- * completion routine is called (with status -ECONNRESET); else a negative
- * error code is returned. This is guaranteed to happen before the call to
- * usb_ep_dequeue() returns.
+ * If the request is still active on the endpoint, it is dequeued and
+ * eventually its completion routine is called (with status -ECONNRESET);
+ * else a negative error code is returned.  This routine is asynchronous,
+ * that is, it may return before the completion routine runs.
  *
  * Note that some hardware can't clear out write fifos (to unlink the request
  * at the head of the queue) except as part of disconnecting from usb. Such
index e7dae53..f63f824 100644 (file)
@@ -516,8 +516,8 @@ static int net2280_disable(struct usb_ep *_ep)
        unsigned long           flags;
 
        ep = container_of(_ep, struct net2280_ep, ep);
-       if (!_ep || !ep->desc || _ep->name == ep0name) {
-               pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep);
+       if (!_ep || _ep->name == ep0name) {
+               pr_err("%s: Invalid ep=%p\n", __func__, _ep);
                return -EINVAL;
        }
        spin_lock_irqsave(&ep->dev->lock, flags);
@@ -2279,7 +2279,7 @@ static void usb_reinit_338x(struct net2280 *dev)
         * - It is safe to set for all connection speeds; all chip revisions.
         * - R-M-W to leave other bits undisturbed.
         * - Reference PLX TT-7372
-       */
+        */
        val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit);
        val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW);
        writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit);
index 6e34f95..7dc2485 100644 (file)
@@ -2629,6 +2629,10 @@ static const struct of_device_id usb3_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb3_of_match);
 
 static const struct soc_device_attribute renesas_usb3_quirks_match[] = {
+       {
+               .soc_id = "r8a774c0",
+               .data = &renesas_usb3_priv_r8a77990,
+       },
        {
                .soc_id = "r8a7795", .revision = "ES1.*",
                .data = &renesas_usb3_priv_r8a7795_es1,