Merge tag 'usb-serial-5.14-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Jul 2021 18:51:14 +0000 (20:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Jul 2021 18:51:14 +0000 (20:51 +0200)
Johan writes:

USB-serial fixes for 5.14-rc3

Here are some new device ids and a device-id comment fix.

All have been in linux-next with no reported issues.

* tag 'usb-serial-5.14-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial:
  USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick
  USB: serial: cp210x: fix comments for GE CS1000
  USB: serial: option: add support for u-blox LARA-R6 family

34 files changed:
MAINTAINERS
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/ipq8074.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998.dtsi
arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/sc7180.dtsi
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sm8150.dtsi
drivers/usb/class/cdc-wdm.c
drivers/usb/core/devio.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/core.h
drivers/usb/dwc2/core_intr.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/hcd.c
drivers/usb/dwc2/params.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/udc/tegra-xudc.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/max3421-hcd.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci-renesas.c
drivers/usb/host/xhci-pci.c
drivers/usb/phy/phy.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/storage/unusual_uas.h
drivers/usb/typec/stusb160x.c
drivers/usb/typec/tipd/core.c

index a61f4f3..6f86a58 100644 (file)
@@ -19114,7 +19114,7 @@ M:      Mauro Carvalho Chehab <mchehab@kernel.org>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml
-F:     drivers/phy/hisilicon/phy-kirin970-usb3.c
+F:     drivers/phy/hisilicon/phy-hi3670-usb3.c
 
 USB ISP116X DRIVER
 M:     Olav Kongas <ok@artecdesign.ee>
index 0686923..51e1709 100644 (file)
        status = "okay";
        extcon = <&usb2_id>;
 
-       usb@7600000 {
+       dwc3@7600000 {
                extcon = <&usb2_id>;
                dr_mode = "otg";
                maximum-speed = "high-speed";
        status = "okay";
        extcon = <&usb3_id>;
 
-       usb@6a00000 {
+       dwc3@6a00000 {
                extcon = <&usb3_id>;
                dr_mode = "otg";
        };
index 95d6cb8..f39bc10 100644 (file)
                        resets = <&gcc GCC_USB0_BCR>;
                        status = "disabled";
 
-                       dwc_0: usb@8a00000 {
+                       dwc_0: dwc3@8a00000 {
                                compatible = "snps,dwc3";
                                reg = <0x8a00000 0xcd00>;
                                interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
                        resets = <&gcc GCC_USB1_BCR>;
                        status = "disabled";
 
-                       dwc_1: usb@8c00000 {
+                       dwc_1: dwc3@8c00000 {
                                compatible = "snps,dwc3";
                                reg = <0x8c00000 0xcd00>;
                                interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
index 0e1bc46..78c55ca 100644 (file)
                        power-domains = <&gcc USB30_GDSC>;
                        status = "disabled";
 
-                       usb@6a00000 {
+                       dwc3@6a00000 {
                                compatible = "snps,dwc3";
                                reg = <0x06a00000 0xcc00>;
                                interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
                        qcom,select-utmi-as-pipe-clk;
                        status = "disabled";
 
-                       usb@7600000 {
+                       dwc3@7600000 {
                                compatible = "snps,dwc3";
                                reg = <0x07600000 0xcc00>;
                                interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>;
index 6f294f9..e9d3ce2 100644 (file)
 
                        resets = <&gcc GCC_USB_30_BCR>;
 
-                       usb3_dwc3: usb@a800000 {
+                       usb3_dwc3: dwc3@a800000 {
                                compatible = "snps,dwc3";
                                reg = <0x0a800000 0xcd00>;
                                interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
index f8a5530..a80c578 100644 (file)
 &usb3 {
        status = "okay";
 
-       usb@7580000 {
+       dwc3@7580000 {
                dr_mode = "host";
        };
 };
index 9c4be02..339790b 100644 (file)
                        assigned-clock-rates = <19200000>, <200000000>;
                        status = "disabled";
 
-                       usb@7580000 {
+                       dwc3@7580000 {
                                compatible = "snps,dwc3";
                                reg = <0x07580000 0xcd00>;
                                interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
                        assigned-clock-rates = <19200000>, <133333333>;
                        status = "disabled";
 
-                       usb@78c0000 {
+                       dwc3@78c0000 {
                                compatible = "snps,dwc3";
                                reg = <0x078c0000 0xcc00>;
                                interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
index a5d58eb..a9a052f 100644 (file)
                                        <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3 0>;
                        interconnect-names = "usb-ddr", "apps-usb";
 
-                       usb_1_dwc3: usb@a600000 {
+                       usb_1_dwc3: dwc3@a600000 {
                                compatible = "snps,dwc3";
                                reg = <0 0x0a600000 0 0xe000>;
                                interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
index 1796ae8..0a86fe7 100644 (file)
                                        <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>;
                        interconnect-names = "usb-ddr", "apps-usb";
 
-                       usb_1_dwc3: usb@a600000 {
+                       usb_1_dwc3: dwc3@a600000 {
                                compatible = "snps,dwc3";
                                reg = <0 0x0a600000 0 0xcd00>;
                                interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
                                        <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_1 0>;
                        interconnect-names = "usb-ddr", "apps-usb";
 
-                       usb_2_dwc3: usb@a800000 {
+                       usb_2_dwc3: dwc3@a800000 {
                                compatible = "snps,dwc3";
                                reg = <0 0x0a800000 0 0xcd00>;
                                interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
index 612dda0..eef9d79 100644 (file)
 
                        resets = <&gcc GCC_USB30_PRIM_BCR>;
 
-                       usb_1_dwc3: usb@a600000 {
+                       usb_1_dwc3: dwc3@a600000 {
                                compatible = "snps,dwc3";
                                reg = <0 0x0a600000 0 0xcd00>;
                                interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
index fdf79bc..35d5908 100644 (file)
@@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = {
 };
 
 /* --- WWAN framework integration --- */
-#ifdef CONFIG_WWAN
+#ifdef CONFIG_WWAN_CORE
 static int wdm_wwan_port_start(struct wwan_port *port)
 {
        struct wdm_device *desc = wwan_port_get_drvdata(port);
@@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length)
        /* inbuf has been copied, it is safe to check for outstanding data */
        schedule_work(&desc->service_outs_intr);
 }
-#else /* CONFIG_WWAN */
+#else /* CONFIG_WWAN_CORE */
 static void wdm_wwan_init(struct wdm_device *desc) {}
 static void wdm_wwan_deinit(struct wdm_device *desc) {}
 static void wdm_wwan_rx(struct wdm_device *desc, int length) {}
-#endif /* CONFIG_WWAN */
+#endif /* CONFIG_WWAN_CORE */
 
 /* --- error handling --- */
 static void wdm_rxwork(struct work_struct *work)
index b974644..9618ba6 100644 (file)
@@ -1133,7 +1133,7 @@ static int do_proc_control(struct usb_dev_state *ps,
                "wIndex=%04x wLength=%04x\n",
                ctrl->bRequestType, ctrl->bRequest, ctrl->wValue,
                ctrl->wIndex, ctrl->wLength);
-       if (ctrl->bRequestType & 0x80) {
+       if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) {
                pipe = usb_rcvctrlpipe(dev, 0);
                snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0);
 
index d1efc71..86658a8 100644 (file)
@@ -48,6 +48,7 @@
 
 #define USB_TP_TRANSMISSION_DELAY      40      /* ns */
 #define USB_TP_TRANSMISSION_DELAY_MAX  65535   /* ns */
+#define USB_PING_RESPONSE_TIME         400     /* ns */
 
 /* Protect struct usb_device->state and ->children members
  * Note: Both are also protected by ->dev.sem, except that ->state can
@@ -182,8 +183,9 @@ int usb_device_supports_lpm(struct usb_device *udev)
 }
 
 /*
- * Set the Maximum Exit Latency (MEL) for the host to initiate a transition from
- * either U1 or U2.
+ * Set the Maximum Exit Latency (MEL) for the host to wakup up the path from
+ * U1/U2, send a PING to the device and receive a PING_RESPONSE.
+ * See USB 3.1 section C.1.5.2
  */
 static void usb_set_lpm_mel(struct usb_device *udev,
                struct usb3_lpm_parameters *udev_lpm_params,
@@ -193,35 +195,37 @@ static void usb_set_lpm_mel(struct usb_device *udev,
                unsigned int hub_exit_latency)
 {
        unsigned int total_mel;
-       unsigned int device_mel;
-       unsigned int hub_mel;
 
        /*
-        * Calculate the time it takes to transition all links from the roothub
-        * to the parent hub into U0.  The parent hub must then decode the
-        * packet (hub header decode latency) to figure out which port it was
-        * bound for.
-        *
-        * The Hub Header decode latency is expressed in 0.1us intervals (0x1
-        * means 0.1us).  Multiply that by 100 to get nanoseconds.
+        * tMEL1. time to transition path from host to device into U0.
+        * MEL for parent already contains the delay up to parent, so only add
+        * the exit latency for the last link (pick the slower exit latency),
+        * and the hub header decode latency. See USB 3.1 section C 2.2.1
+        * Store MEL in nanoseconds
         */
        total_mel = hub_lpm_params->mel +
-               (hub->descriptor->u.ss.bHubHdrDecLat * 100);
+               max(udev_exit_latency, hub_exit_latency) * 1000 +
+               hub->descriptor->u.ss.bHubHdrDecLat * 100;
 
        /*
-        * How long will it take to transition the downstream hub's port into
-        * U0?  The greater of either the hub exit latency or the device exit
-        * latency.
-        *
-        * The BOS U1/U2 exit latencies are expressed in 1us intervals.
-        * Multiply that by 1000 to get nanoseconds.
+        * tMEL2. Time to submit PING packet. Sum of tTPTransmissionDelay for
+        * each link + wHubDelay for each hub. Add only for last link.
+        * tMEL4, the time for PING_RESPONSE to traverse upstream is similar.
+        * Multiply by 2 to include it as well.
         */
-       device_mel = udev_exit_latency * 1000;
-       hub_mel = hub_exit_latency * 1000;
-       if (device_mel > hub_mel)
-               total_mel += device_mel;
-       else
-               total_mel += hub_mel;
+       total_mel += (__le16_to_cpu(hub->descriptor->u.ss.wHubDelay) +
+                     USB_TP_TRANSMISSION_DELAY) * 2;
+
+       /*
+        * tMEL3, tPingResponse. Time taken by device to generate PING_RESPONSE
+        * after receiving PING. Also add 2100ns as stated in USB 3.1 C 1.5.2.4
+        * to cover the delay if the PING_RESPONSE is queued behind a Max Packet
+        * Size DP.
+        * Note these delays should be added only once for the entire path, so
+        * add them to the MEL of the device connected to the roothub.
+        */
+       if (!hub->hdev->parent)
+               total_mel += USB_PING_RESPONSE_TIME + 2100;
 
        udev_lpm_params->mel = total_mel;
 }
@@ -4112,6 +4116,47 @@ static int usb_set_lpm_timeout(struct usb_device *udev,
        return 0;
 }
 
+/*
+ * Don't allow device intiated U1/U2 if the system exit latency + one bus
+ * interval is greater than the minimum service interval of any active
+ * periodic endpoint. See USB 3.2 section 9.4.9
+ */
+static bool usb_device_may_initiate_lpm(struct usb_device *udev,
+                                       enum usb3_link_state state)
+{
+       unsigned int sel;               /* us */
+       int i, j;
+
+       if (state == USB3_LPM_U1)
+               sel = DIV_ROUND_UP(udev->u1_params.sel, 1000);
+       else if (state == USB3_LPM_U2)
+               sel = DIV_ROUND_UP(udev->u2_params.sel, 1000);
+       else
+               return false;
+
+       for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+               struct usb_interface *intf;
+               struct usb_endpoint_descriptor *desc;
+               unsigned int interval;
+
+               intf = udev->actconfig->interface[i];
+               if (!intf)
+                       continue;
+
+               for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) {
+                       desc = &intf->cur_altsetting->endpoint[j].desc;
+
+                       if (usb_endpoint_xfer_int(desc) ||
+                           usb_endpoint_xfer_isoc(desc)) {
+                               interval = (1 << (desc->bInterval - 1)) * 125;
+                               if (sel + 125 > interval)
+                                       return false;
+                       }
+               }
+       }
+       return true;
+}
+
 /*
  * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated
  * U1/U2 entry.
@@ -4184,20 +4229,23 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
         * U1/U2_ENABLE
         */
        if (udev->actconfig &&
-           usb_set_device_initiated_lpm(udev, state, true) == 0) {
-               if (state == USB3_LPM_U1)
-                       udev->usb3_lpm_u1_enabled = 1;
-               else if (state == USB3_LPM_U2)
-                       udev->usb3_lpm_u2_enabled = 1;
-       } else {
-               /* Don't request U1/U2 entry if the device
-                * cannot transition to U1/U2.
-                */
-               usb_set_lpm_timeout(udev, state, 0);
-               hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
+           usb_device_may_initiate_lpm(udev, state)) {
+               if (usb_set_device_initiated_lpm(udev, state, true)) {
+                       /*
+                        * Request to enable device initiated U1/U2 failed,
+                        * better to turn off lpm in this case.
+                        */
+                       usb_set_lpm_timeout(udev, state, 0);
+                       hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
+                       return;
+               }
        }
-}
 
+       if (state == USB3_LPM_U1)
+               udev->usb3_lpm_u1_enabled = 1;
+       else if (state == USB3_LPM_U2)
+               udev->usb3_lpm_u2_enabled = 1;
+}
 /*
  * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated
  * U1/U2 entry.
index 6114cf8..8239fe7 100644 (file)
@@ -501,10 +501,6 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* DJI CineSSD */
        { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
 
-       /* Fibocom L850-GL LTE Modem */
-       { USB_DEVICE(0x2cb7, 0x0007), .driver_info =
-                       USB_QUIRK_IGNORE_REMOTE_WAKEUP },
-
        /* INTEL VALUE SSD */
        { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
 
index ab6b815..483de2b 100644 (file)
@@ -383,6 +383,9 @@ enum dwc2_ep0_state {
  *                     0 - No (default)
  *                     1 - Partial power down
  *                     2 - Hibernation
+ * @no_clock_gating:   Specifies whether to avoid clock gating feature.
+ *                     0 - No (use clock gating)
+ *                     1 - Yes (avoid it)
  * @lpm:               Enable LPM support.
  *                     0 - No
  *                     1 - Yes
@@ -480,6 +483,7 @@ struct dwc2_core_params {
 #define DWC2_POWER_DOWN_PARAM_NONE             0
 #define DWC2_POWER_DOWN_PARAM_PARTIAL          1
 #define DWC2_POWER_DOWN_PARAM_HIBERNATION      2
+       bool no_clock_gating;
 
        bool lpm;
        bool lpm_clock_gating;
index a5ab038..a5c52b2 100644 (file)
@@ -556,7 +556,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
                                 * If neither hibernation nor partial power down are supported,
                                 * clock gating is used to save power.
                                 */
-                               dwc2_gadget_enter_clock_gating(hsotg);
+                               if (!hsotg->params.no_clock_gating)
+                                       dwc2_gadget_enter_clock_gating(hsotg);
                        }
 
                        /*
index c581ee4..3146df6 100644 (file)
@@ -2749,12 +2749,14 @@ static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg,
                return;
        }
 
-       /* Zlp for all endpoints, for ep0 only in DATA IN stage */
+       /* Zlp for all endpoints in non DDMA, for ep0 only in DATA IN stage */
        if (hs_ep->send_zlp) {
-               dwc2_hsotg_program_zlp(hsotg, hs_ep);
                hs_ep->send_zlp = 0;
-               /* transfer will be completed on next complete interrupt */
-               return;
+               if (!using_desc_dma(hsotg)) {
+                       dwc2_hsotg_program_zlp(hsotg, hs_ep);
+                       /* transfer will be completed on next complete interrupt */
+                       return;
+               }
        }
 
        if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) {
@@ -3900,9 +3902,27 @@ static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg,
                                         __func__);
                }
        } else {
+               /* Mask GINTSTS_GOUTNAKEFF interrupt */
+               dwc2_hsotg_disable_gsint(hsotg, GINTSTS_GOUTNAKEFF);
+
                if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF))
                        dwc2_set_bit(hsotg, DCTL, DCTL_SGOUTNAK);
 
+               if (!using_dma(hsotg)) {
+                       /* Wait for GINTSTS_RXFLVL interrupt */
+                       if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
+                                                   GINTSTS_RXFLVL, 100)) {
+                               dev_warn(hsotg->dev, "%s: timeout GINTSTS.RXFLVL\n",
+                                        __func__);
+                       } else {
+                               /*
+                                * Pop GLOBAL OUT NAK status packet from RxFIFO
+                                * to assert GOUTNAKEFF interrupt
+                                */
+                               dwc2_readl(hsotg, GRXSTSP);
+                       }
+               }
+
                /* Wait for global nak to take effect */
                if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
                                            GINTSTS_GOUTNAKEFF, 100))
@@ -4348,6 +4368,9 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now)
                epctl = dwc2_readl(hs, epreg);
 
                if (value) {
+                       /* Unmask GOUTNAKEFF interrupt */
+                       dwc2_hsotg_en_gsint(hs, GINTSTS_GOUTNAKEFF);
+
                        if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF))
                                dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK);
                        // STALL bit will be set in GOUTNAKEFF interrupt handler
index 035d491..2a78289 100644 (file)
@@ -3338,7 +3338,8 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
                 * If not hibernation nor partial power down are supported,
                 * clock gating is used to save power.
                 */
-               dwc2_host_enter_clock_gating(hsotg);
+               if (!hsotg->params.no_clock_gating)
+                       dwc2_host_enter_clock_gating(hsotg);
                break;
        }
 
@@ -4402,7 +4403,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
                 * If not hibernation nor partial power down are supported,
                 * clock gating is used to save power.
                 */
-               dwc2_host_enter_clock_gating(hsotg);
+               if (!hsotg->params.no_clock_gating)
+                       dwc2_host_enter_clock_gating(hsotg);
 
                /* After entering suspend, hardware is not accessible */
                clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
index 67c5eb1..59e1193 100644 (file)
@@ -76,6 +76,7 @@ static void dwc2_set_s3c6400_params(struct dwc2_hsotg *hsotg)
        struct dwc2_core_params *p = &hsotg->params;
 
        p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
+       p->no_clock_gating = true;
        p->phy_utmi_width = 8;
 }
 
index dccdf13..5991766 100644 (file)
@@ -1279,6 +1279,7 @@ struct dwc3 {
        unsigned                dis_metastability_quirk:1;
 
        unsigned                dis_split_quirk:1;
+       unsigned                async_callbacks:1;
 
        u16                     imod_interval;
 };
index 3cd2942..2f9e45e 100644 (file)
@@ -597,11 +597,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 
 static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 {
-       int ret;
+       int ret = -EINVAL;
 
-       spin_unlock(&dwc->lock);
-       ret = dwc->gadget_driver->setup(dwc->gadget, ctrl);
-       spin_lock(&dwc->lock);
+       if (dwc->async_callbacks) {
+               spin_unlock(&dwc->lock);
+               ret = dwc->gadget_driver->setup(dwc->gadget, ctrl);
+               spin_lock(&dwc->lock);
+       }
        return ret;
 }
 
index af6d7f1..45f2bc0 100644 (file)
@@ -2585,6 +2585,16 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
        return ret;
 }
 
+static void dwc3_gadget_async_callbacks(struct usb_gadget *g, bool enable)
+{
+       struct dwc3             *dwc = gadget_to_dwc(g);
+       unsigned long           flags;
+
+       spin_lock_irqsave(&dwc->lock, flags);
+       dwc->async_callbacks = enable;
+       spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
 static const struct usb_gadget_ops dwc3_gadget_ops = {
        .get_frame              = dwc3_gadget_get_frame,
        .wakeup                 = dwc3_gadget_wakeup,
@@ -2596,6 +2606,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
        .udc_set_ssp_rate       = dwc3_gadget_set_ssp_rate,
        .get_config_params      = dwc3_gadget_config_params,
        .vbus_draw              = dwc3_gadget_vbus_draw,
+       .udc_async_callbacks    = dwc3_gadget_async_callbacks,
 };
 
 /* -------------------------------------------------------------------------- */
@@ -3231,7 +3242,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
 
 static void dwc3_disconnect_gadget(struct dwc3 *dwc)
 {
-       if (dwc->gadget_driver && dwc->gadget_driver->disconnect) {
+       if (dwc->async_callbacks && dwc->gadget_driver->disconnect) {
                spin_unlock(&dwc->lock);
                dwc->gadget_driver->disconnect(dwc->gadget);
                spin_lock(&dwc->lock);
@@ -3240,7 +3251,7 @@ static void dwc3_disconnect_gadget(struct dwc3 *dwc)
 
 static void dwc3_suspend_gadget(struct dwc3 *dwc)
 {
-       if (dwc->gadget_driver && dwc->gadget_driver->suspend) {
+       if (dwc->async_callbacks && dwc->gadget_driver->suspend) {
                spin_unlock(&dwc->lock);
                dwc->gadget_driver->suspend(dwc->gadget);
                spin_lock(&dwc->lock);
@@ -3249,7 +3260,7 @@ static void dwc3_suspend_gadget(struct dwc3 *dwc)
 
 static void dwc3_resume_gadget(struct dwc3 *dwc)
 {
-       if (dwc->gadget_driver && dwc->gadget_driver->resume) {
+       if (dwc->async_callbacks && dwc->gadget_driver->resume) {
                spin_unlock(&dwc->lock);
                dwc->gadget_driver->resume(dwc->gadget);
                spin_lock(&dwc->lock);
@@ -3261,7 +3272,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)
        if (!dwc->gadget_driver)
                return;
 
-       if (dwc->gadget->speed != USB_SPEED_UNKNOWN) {
+       if (dwc->async_callbacks && dwc->gadget->speed != USB_SPEED_UNKNOWN) {
                spin_unlock(&dwc->lock);
                usb_gadget_udc_reset(dwc->gadget, dwc->gadget_driver);
                spin_lock(&dwc->lock);
@@ -3585,7 +3596,7 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
         * implemented.
         */
 
-       if (dwc->gadget_driver && dwc->gadget_driver->resume) {
+       if (dwc->async_callbacks && dwc->gadget_driver->resume) {
                spin_unlock(&dwc->lock);
                dwc->gadget_driver->resume(dwc->gadget);
                spin_lock(&dwc->lock);
index bffef8e..281ca76 100644 (file)
@@ -1198,7 +1198,7 @@ void gserial_free_line(unsigned char port_num)
        struct gs_port  *port;
 
        mutex_lock(&ports[port_num].lock);
-       if (WARN_ON(!ports[port_num].port)) {
+       if (!ports[port_num].port) {
                mutex_unlock(&ports[port_num].lock);
                return;
        }
index a54d1ce..c0ca714 100644 (file)
@@ -3853,6 +3853,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
        return 0;
 
 free_eps:
+       pm_runtime_disable(&pdev->dev);
        tegra_xudc_free_eps(xudc);
 free_event_ring:
        tegra_xudc_free_event_ring(xudc);
index 36f5bf6..10b0365 100644 (file)
@@ -703,24 +703,28 @@ EXPORT_SYMBOL_GPL(ehci_setup);
 static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
-       u32                     status, masked_status, pcd_status = 0, cmd;
+       u32                     status, current_status, masked_status, pcd_status = 0;
+       u32                     cmd;
        int                     bh;
 
        spin_lock(&ehci->lock);
 
-       status = ehci_readl(ehci, &ehci->regs->status);
+       status = 0;
+       current_status = ehci_readl(ehci, &ehci->regs->status);
+restart:
 
        /* e.g. cardbus physical eject */
-       if (status == ~(u32) 0) {
+       if (current_status == ~(u32) 0) {
                ehci_dbg (ehci, "device removed\n");
                goto dead;
        }
+       status |= current_status;
 
        /*
         * We don't use STS_FLR, but some controllers don't like it to
         * remain on, so mask it out along with the other status bits.
         */
-       masked_status = status & (INTR_MASK | STS_FLR);
+       masked_status = current_status & (INTR_MASK | STS_FLR);
 
        /* Shared IRQ? */
        if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
@@ -730,6 +734,12 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
        /* clear (just) interrupts */
        ehci_writel(ehci, masked_status, &ehci->regs->status);
+
+       /* For edge interrupts, don't race with an interrupt bit being raised */
+       current_status = ehci_readl(ehci, &ehci->regs->status);
+       if (current_status & INTR_MASK)
+               goto restart;
+
        cmd = ehci_readl(ehci, &ehci->regs->command);
        bh = 0;
 
index e7a8e06..59cc1bc 100644 (file)
@@ -153,8 +153,6 @@ struct max3421_hcd {
         */
        struct urb *curr_urb;
        enum scheduling_pass sched_pass;
-       struct usb_device *loaded_dev;  /* dev that's loaded into the chip */
-       int loaded_epnum;               /* epnum whose toggles are loaded */
        int urb_done;                   /* > 0 -> no errors, < 0: errno */
        size_t curr_len;
        u8 hien;
@@ -492,39 +490,17 @@ max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev)
  * Caller must NOT hold HCD spinlock.
  */
 static void
-max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum,
-                   int force_toggles)
+max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum)
 {
-       struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
-       int old_epnum, same_ep, rcvtog, sndtog;
-       struct usb_device *old_dev;
+       int rcvtog, sndtog;
        u8 hctl;
 
-       old_dev = max3421_hcd->loaded_dev;
-       old_epnum = max3421_hcd->loaded_epnum;
-
-       same_ep = (dev == old_dev && epnum == old_epnum);
-       if (same_ep && !force_toggles)
-               return;
-
-       if (old_dev && !same_ep) {
-               /* save the old end-points toggles: */
-               u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);
-
-               rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1;
-               sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1;
-
-               /* no locking: HCD (i.e., we) own toggles, don't we? */
-               usb_settoggle(old_dev, old_epnum, 0, rcvtog);
-               usb_settoggle(old_dev, old_epnum, 1, sndtog);
-       }
        /* setup new endpoint's toggle bits: */
        rcvtog = usb_gettoggle(dev, epnum, 0);
        sndtog = usb_gettoggle(dev, epnum, 1);
        hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) |
                BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT));
 
-       max3421_hcd->loaded_epnum = epnum;
        spi_wr8(hcd, MAX3421_REG_HCTL, hctl);
 
        /*
@@ -532,7 +508,6 @@ max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum,
         * address-assignment so it's best to just always load the
         * address whenever the end-point changed/was forced.
         */
-       max3421_hcd->loaded_dev = dev;
        spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum);
 }
 
@@ -667,7 +642,7 @@ max3421_select_and_start_urb(struct usb_hcd *hcd)
        struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
        struct urb *urb, *curr_urb = NULL;
        struct max3421_ep *max3421_ep;
-       int epnum, force_toggles = 0;
+       int epnum;
        struct usb_host_endpoint *ep;
        struct list_head *pos;
        unsigned long flags;
@@ -777,7 +752,6 @@ done:
                        usb_settoggle(urb->dev, epnum, 0, 1);
                        usb_settoggle(urb->dev, epnum, 1, 1);
                        max3421_ep->pkt_state = PKT_STATE_SETUP;
-                       force_toggles = 1;
                } else
                        max3421_ep->pkt_state = PKT_STATE_TRANSFER;
        }
@@ -785,7 +759,7 @@ done:
        spin_unlock_irqrestore(&max3421_hcd->lock, flags);
 
        max3421_ep->last_active = max3421_hcd->frame_number;
-       max3421_set_address(hcd, urb->dev, epnum, force_toggles);
+       max3421_set_address(hcd, urb->dev, epnum);
        max3421_set_speed(hcd, urb->dev);
        max3421_next_transfer(hcd, 0);
        return 1;
@@ -1379,6 +1353,16 @@ max3421_urb_done(struct usb_hcd *hcd)
                status = 0;
        urb = max3421_hcd->curr_urb;
        if (urb) {
+               /* save the old end-points toggles: */
+               u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);
+               int rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1;
+               int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1;
+               int epnum = usb_endpoint_num(&urb->ep->desc);
+
+               /* no locking: HCD (i.e., we) own toggles, don't we? */
+               usb_settoggle(urb->dev, epnum, 0, rcvtog);
+               usb_settoggle(urb->dev, epnum, 1, sndtog);
+
                max3421_hcd->curr_urb = NULL;
                spin_lock_irqsave(&max3421_hcd->lock, flags);
                usb_hcd_unlink_urb_from_ep(hcd, urb);
index e9b18fc..151e93c 100644 (file)
@@ -1638,11 +1638,12 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
         * Inform the usbcore about resume-in-progress by returning
         * a non-zero value even if there are no status changes.
         */
+       spin_lock_irqsave(&xhci->lock, flags);
+
        status = bus_state->resuming_ports;
 
        mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;
 
-       spin_lock_irqsave(&xhci->lock, flags);
        /* For each port, did anything change?  If so, set that bit in buf. */
        for (i = 0; i < max_ports; i++) {
                temp = readl(ports[i]->addr);
index 1da6479..5923844 100644 (file)
@@ -207,8 +207,7 @@ static int renesas_check_rom_state(struct pci_dev *pdev)
                        return 0;
 
                case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */
-                       dev_dbg(&pdev->dev, "Unknown ROM status ...\n");
-                       break;
+                       return 0;
 
                case RENESAS_ROM_STATUS_ERROR: /* Error State */
                default: /* All other states are marked as "Reserved states" */
@@ -225,12 +224,13 @@ static int renesas_fw_check_running(struct pci_dev *pdev)
        u8 fw_state;
        int err;
 
-       /*
-        * Only if device has ROM and loaded FW we can skip loading and
-        * return success. Otherwise (even unknown state), attempt to load FW.
-        */
-       if (renesas_check_rom(pdev) && !renesas_check_rom_state(pdev))
-               return 0;
+       /* Check if device has ROM and loaded, if so skip everything */
+       err = renesas_check_rom(pdev);
+       if (err) { /* we have rom */
+               err = renesas_check_rom_state(pdev);
+               if (!err)
+                       return err;
+       }
 
        /*
         * Test if the device is actually needing the firmware. As most
index 18c2bbd..1c9a795 100644 (file)
@@ -636,7 +636,14 @@ static const struct pci_device_id pci_ids[] = {
        { /* end: all zeroes */ }
 };
 MODULE_DEVICE_TABLE(pci, pci_ids);
+
+/*
+ * Without CONFIG_USB_XHCI_PCI_RENESAS renesas_xhci_check_request_fw() won't
+ * load firmware, so don't encumber the xhci-pci driver with it.
+ */
+#if IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS)
 MODULE_FIRMWARE("renesas_usb_fw.mem");
+#endif
 
 /* pci driver glue; this is a "new style" PCI driver module */
 static struct pci_driver xhci_pci_driver = {
index 83ed508..1b24492 100644 (file)
@@ -86,10 +86,10 @@ static struct usb_phy *__device_to_usb_phy(struct device *dev)
 
        list_for_each_entry(usb_phy, &phy_list, head) {
                if (usb_phy->dev == dev)
-                       break;
+                       return usb_phy;
        }
 
-       return usb_phy;
+       return NULL;
 }
 
 static void usb_phy_set_default_current(struct usb_phy *usb_phy)
@@ -150,8 +150,14 @@ static int usb_phy_uevent(struct device *dev, struct kobj_uevent_env *env)
        struct usb_phy *usb_phy;
        char uchger_state[50] = { 0 };
        char uchger_type[50] = { 0 };
+       unsigned long flags;
 
+       spin_lock_irqsave(&phy_lock, flags);
        usb_phy = __device_to_usb_phy(dev);
+       spin_unlock_irqrestore(&phy_lock, flags);
+
+       if (!usb_phy)
+               return -ENODEV;
 
        snprintf(uchger_state, ARRAY_SIZE(uchger_state),
                 "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]);
index b5e7991..a3c2b01 100644 (file)
@@ -101,6 +101,8 @@ static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo,
 #define usbhsf_dma_map(p)      __usbhsf_dma_map_ctrl(p, 1)
 #define usbhsf_dma_unmap(p)    __usbhsf_dma_map_ctrl(p, 0)
 static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map);
+static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable);
+static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable);
 struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
 {
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
@@ -123,6 +125,11 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
                if (chan) {
                        dmaengine_terminate_all(chan);
                        usbhsf_dma_unmap(pkt);
+               } else {
+                       if (usbhs_pipe_is_dir_in(pipe))
+                               usbhsf_rx_irq_ctrl(pipe, 0);
+                       else
+                               usbhsf_tx_irq_ctrl(pipe, 0);
                }
 
                usbhs_pipe_clear_without_sequence(pipe, 0, 0);
index f9677a5..c35a6db 100644 (file)
@@ -45,6 +45,13 @@ UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME),
 
+/* Reported-by: Julian Sikorski <belegdol@gmail.com> */
+UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999,
+               "LaCie",
+               "Rugged USB3-FW",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_IGNORE_UAS),
+
 /*
  * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI
  * commands in UAS mode.  Observed with the 1.28 firmware; are there others?
index 6eaeba9..e7745d1 100644 (file)
@@ -685,6 +685,15 @@ static int stusb160x_probe(struct i2c_client *client)
        if (!fwnode)
                return -ENODEV;
 
+       /*
+        * This fwnode has a "compatible" property, but is never populated as a
+        * struct device. Instead we simply parse it to read the properties.
+        * This it breaks fw_devlink=on. To maintain backward compatibility
+        * with existing DT files, we work around this by deleting any
+        * fwnode_links to/from this fwnode.
+        */
+       fw_devlink_purge_absent_suppliers(fwnode);
+
        /*
         * When both VDD and VSYS power supplies are present, the low power
         * supply VSYS is selected when VSYS voltage is above 3.1 V.
@@ -739,10 +748,6 @@ static int stusb160x_probe(struct i2c_client *client)
        typec_set_pwr_opmode(chip->port, chip->pwr_opmode);
 
        if (client->irq) {
-               ret = stusb160x_irq_init(chip, client->irq);
-               if (ret)
-                       goto port_unregister;
-
                chip->role_sw = fwnode_usb_role_switch_get(fwnode);
                if (IS_ERR(chip->role_sw)) {
                        ret = PTR_ERR(chip->role_sw);
@@ -752,6 +757,10 @@ static int stusb160x_probe(struct i2c_client *client)
                                        ret);
                        goto port_unregister;
                }
+
+               ret = stusb160x_irq_init(chip, client->irq);
+               if (ret)
+                       goto role_sw_put;
        } else {
                /*
                 * If Source or Dual power role, need to enable VDD supply
@@ -775,6 +784,9 @@ static int stusb160x_probe(struct i2c_client *client)
 
        return 0;
 
+role_sw_put:
+       if (chip->role_sw)
+               usb_role_switch_put(chip->role_sw);
 port_unregister:
        typec_unregister_port(chip->port);
 all_reg_disable:
index 938219b..21b3ae2 100644 (file)
@@ -629,6 +629,15 @@ static int tps6598x_probe(struct i2c_client *client)
        if (!fwnode)
                return -ENODEV;
 
+       /*
+        * This fwnode has a "compatible" property, but is never populated as a
+        * struct device. Instead we simply parse it to read the properties.
+        * This breaks fw_devlink=on. To maintain backward compatibility
+        * with existing DT files, we work around this by deleting any
+        * fwnode_links to/from this fwnode.
+        */
+       fw_devlink_purge_absent_suppliers(fwnode);
+
        tps->role_sw = fwnode_usb_role_switch_get(fwnode);
        if (IS_ERR(tps->role_sw)) {
                ret = PTR_ERR(tps->role_sw);