Merge 5.16-rc3 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Nov 2021 07:04:46 +0000 (08:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Nov 2021 07:04:46 +0000 (08:04 +0100)
We need the USB driver fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 files changed:
Documentation/devicetree/bindings/usb/dwc2.yaml
Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
Documentation/driver-api/usb/writing_usb_driver.rst
drivers/usb/cdns3/cdnsp-gadget.c
drivers/usb/chipidea/otg.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/dwc3-meson-g12a.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/udc/at91_udc.c
drivers/usb/gadget/udc/at91_udc.h
drivers/usb/gadget/udc/mv_udc_core.c
drivers/usb/gadget/udc/udc-xilinx.c
drivers/usb/host/ehci-brcm.c
drivers/usb/host/u132-hcd.c
drivers/usb/host/xhci-mtk.c
drivers/usb/phy/phy-mv-usb.c
drivers/usb/typec/ucsi/ucsi.c
drivers/usb/usbip/usbip_event.c

index 56a8184..94e7276 100644 (file)
@@ -136,6 +136,16 @@ properties:
     description: If present indicates that we need to reset the PHY when we 
       detect a wakeup. This is due to a hardware errata.
 
+  port:
+    description:
+      Any connector to the data bus of this controller should be modelled
+      using the OF graph bindings specified, if the "usb-role-switch"
+      property is used.
+    $ref: /schemas/graph.yaml#/properties/port
+
+dependencies:
+  port: [ usb-role-switch ]
+
 required:
   - compatible
   - reg
index 2bdaba0..55a4637 100644 (file)
@@ -13,7 +13,9 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,ipq4019-dwc3
           - qcom,ipq6018-dwc3
+          - qcom,ipq8064-dwc3
           - qcom,msm8996-dwc3
           - qcom,msm8998-dwc3
           - qcom,sc7180-dwc3
index b43e1ce..95c4f5d 100644 (file)
@@ -94,8 +94,8 @@ usually in the driver's init function, as shown here::
            /* register this driver with the USB subsystem */
            result = usb_register(&skel_driver);
            if (result < 0) {
-                   err("usb_register failed for the "__FILE__ "driver."
-                       "Error number %d", result);
+                   pr_err("usb_register failed for the %s driver. Error number %d\n",
+                          skel_driver.name, result);
                    return -1;
            }
 
@@ -170,8 +170,8 @@ structure. This is done so that future calls to file operations will
 enable the driver to determine which device the user is addressing. All
 of this is done with the following code::
 
-    /* increment our usage count for the module */
-    ++skel->open_count;
+    /* increment our usage count for the device */
+    kref_get(&dev->kref);
 
     /* save our object in the file's private structure */
     file->private_data = dev;
@@ -188,24 +188,26 @@ space, points the urb to the data and submits the urb to the USB
 subsystem. This can be seen in the following code::
 
     /* we can only write as much as 1 urb will hold */
-    bytes_written = (count > skel->bulk_out_size) ? skel->bulk_out_size : count;
+    size_t writesize = min_t(size_t, count, MAX_TRANSFER);
 
     /* copy the data from user space into our urb */
-    copy_from_user(skel->write_urb->transfer_buffer, buffer, bytes_written);
+    copy_from_user(buf, user_buffer, writesize);
 
     /* set up our urb */
-    usb_fill_bulk_urb(skel->write_urb,
-                     skel->dev,
-                     usb_sndbulkpipe(skel->dev, skel->bulk_out_endpointAddr),
-                     skel->write_urb->transfer_buffer,
-                     bytes_written,
+    usb_fill_bulk_urb(urb,
+                     dev->udev,
+                     usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
+                     buf,
+                     writesize,
                      skel_write_bulk_callback,
-                     skel);
+                     dev);
 
     /* send the data out the bulk port */
-    result = usb_submit_urb(skel->write_urb);
-    if (result) {
-           err("Failed submitting write urb, error %d", result);
+    retval = usb_submit_urb(urb, GFP_KERNEL);
+    if (retval) {
+           dev_err(&dev->interface->dev,
+                "%s - failed submitting write urb, error %d\n",
+                __func__, retval);
     }
 
 
index 27df0c6..05439e6 100644 (file)
@@ -81,7 +81,7 @@ int cdnsp_find_next_ext_cap(void __iomem *base, u32 start, int id)
                offset = HCC_EXT_CAPS(val) << 2;
                if (!offset)
                        return 0;
-       };
+       }
 
        do {
                val = readl(base + offset);
index 8dd5928..7b53274 100644 (file)
@@ -255,10 +255,9 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci)
  */
 void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
 {
-       if (ci->wq) {
-               flush_workqueue(ci->wq);
+       if (ci->wq)
                destroy_workqueue(ci->wq);
-       }
+
        /* Disable all OTG irq and clear status */
        hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
                                                OTGSC_INT_STATUS_BITS);
index ab8d7da..b884a83 100644 (file)
@@ -5217,7 +5217,7 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup)
                 * as result BNA interrupt asserted on hibernation exit
                 * by restoring from saved area.
                 */
-               if (hsotg->params.g_dma_desc &&
+               if (using_desc_dma(hsotg) &&
                    (dr->diepctl[i] & DXEPCTL_EPENA))
                        dr->diepdma[i] = hsotg->eps_in[i]->desc_list_dma;
                dwc2_writel(hsotg, dr->dtxfsiz[i], DPTXFSIZN(i));
@@ -5229,7 +5229,7 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup)
                 * as result BNA interrupt asserted on hibernation exit
                 * by restoring from saved area.
                 */
-               if (hsotg->params.g_dma_desc &&
+               if (using_desc_dma(hsotg) &&
                    (dr->doepctl[i] & DXEPCTL_EPENA))
                        dr->doepdma[i] = hsotg->eps_out[i]->desc_list_dma;
                dwc2_writel(hsotg, dr->doepdma[i], DOEPDMA(i));
index d0f9b7c..bd814df 100644 (file)
@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
        ret = dwc3_meson_g12a_get_phys(priv);
        if (ret)
-               goto err_disable_clks;
+               goto err_rearm;
 
        ret = priv->drvdata->setup_regmaps(priv, base);
        if (ret)
-               goto err_disable_clks;
+               goto err_rearm;
 
        if (priv->vbus) {
                ret = regulator_enable(priv->vbus);
                if (ret)
-                       goto err_disable_clks;
+                       goto err_rearm;
        }
 
        /* Get dr_mode */
@@ -825,6 +825,9 @@ err_disable_regulator:
        if (priv->vbus)
                regulator_disable(priv->vbus);
 
+err_rearm:
+       reset_control_rearm(priv->reset);
+
 err_disable_clks:
        clk_bulk_disable_unprepare(priv->drvdata->num_clks,
                                   priv->drvdata->clks);
@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
        pm_runtime_put_noidle(dev);
        pm_runtime_set_suspended(dev);
 
+       reset_control_rearm(priv->reset);
+
        clk_bulk_disable_unprepare(priv->drvdata->num_clks,
                                   priv->drvdata->clks);
 
@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
                phy_exit(priv->phys[i]);
        }
 
-       reset_control_assert(priv->reset);
+       reset_control_rearm(priv->reset);
 
        return 0;
 }
@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
        struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
        int i, ret;
 
-       reset_control_deassert(priv->reset);
+       ret = reset_control_reset(priv->reset);
+       if (ret)
+               return ret;
 
        ret = priv->drvdata->usb_init(priv);
        if (ret)
index 504c1cb..c5528e0 100644 (file)
@@ -159,6 +159,8 @@ int config_ep_by_speed_and_alt(struct usb_gadget *g,
        int want_comp_desc = 0;
 
        struct usb_descriptor_header **d_spd; /* cursor for speed desc */
+       struct usb_composite_dev *cdev;
+       bool incomplete_desc = false;
 
        if (!g || !f || !_ep)
                return -EIO;
@@ -167,28 +169,43 @@ int config_ep_by_speed_and_alt(struct usb_gadget *g,
        switch (g->speed) {
        case USB_SPEED_SUPER_PLUS:
                if (gadget_is_superspeed_plus(g)) {
-                       speed_desc = f->ssp_descriptors;
-                       want_comp_desc = 1;
-                       break;
+                       if (f->ssp_descriptors) {
+                               speed_desc = f->ssp_descriptors;
+                               want_comp_desc = 1;
+                               break;
+                       }
+                       incomplete_desc = true;
                }
                fallthrough;
        case USB_SPEED_SUPER:
                if (gadget_is_superspeed(g)) {
-                       speed_desc = f->ss_descriptors;
-                       want_comp_desc = 1;
-                       break;
+                       if (f->ss_descriptors) {
+                               speed_desc = f->ss_descriptors;
+                               want_comp_desc = 1;
+                               break;
+                       }
+                       incomplete_desc = true;
                }
                fallthrough;
        case USB_SPEED_HIGH:
                if (gadget_is_dualspeed(g)) {
-                       speed_desc = f->hs_descriptors;
-                       break;
+                       if (f->hs_descriptors) {
+                               speed_desc = f->hs_descriptors;
+                               break;
+                       }
+                       incomplete_desc = true;
                }
                fallthrough;
        default:
                speed_desc = f->fs_descriptors;
        }
 
+       cdev = get_gadget_data(g);
+       if (incomplete_desc)
+               WARNING(cdev,
+                       "%s doesn't hold the descriptors for current speed\n",
+                       f->name);
+
        /* find correct alternate setting descriptor */
        for_each_desc(speed_desc, d_spd, USB_DT_INTERFACE) {
                int_desc = (struct usb_interface_descriptor *)*d_spd;
@@ -244,12 +261,8 @@ ep_found:
                        _ep->maxburst = comp_desc->bMaxBurst + 1;
                        break;
                default:
-                       if (comp_desc->bMaxBurst != 0) {
-                               struct usb_composite_dev *cdev;
-
-                               cdev = get_gadget_data(g);
+                       if (comp_desc->bMaxBurst != 0)
                                ERROR(cdev, "ep0 bMaxBurst must be 0\n");
-                       }
                        _ep->maxburst = 1;
                        break;
                }
index 36c611d..d4a678c 100644 (file)
@@ -89,10 +89,6 @@ struct gadget_strings {
        struct list_head list;
 };
 
-struct os_desc {
-       struct config_group group;
-};
-
 struct gadget_config_name {
        struct usb_gadget_strings stringtab_dev;
        struct usb_string strings;
@@ -420,9 +416,8 @@ static int config_usb_cfg_link(
        struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
        struct gadget_info *gi = cfg_to_gadget_info(cfg);
 
-       struct config_group *group = to_config_group(usb_func_ci);
-       struct usb_function_instance *fi = container_of(group,
-                       struct usb_function_instance, group);
+       struct usb_function_instance *fi =
+                       to_usb_function_instance(usb_func_ci);
        struct usb_function_instance *a_fi;
        struct usb_function *f;
        int ret;
@@ -470,9 +465,8 @@ static void config_usb_cfg_unlink(
        struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
        struct gadget_info *gi = cfg_to_gadget_info(cfg);
 
-       struct config_group *group = to_config_group(usb_func_ci);
-       struct usb_function_instance *fi = container_of(group,
-                       struct usb_function_instance, group);
+       struct usb_function_instance *fi =
+                       to_usb_function_instance(usb_func_ci);
        struct usb_function *f;
 
        /*
@@ -783,15 +777,11 @@ static void gadget_strings_attr_release(struct config_item *item)
 USB_CONFIG_STRING_RW_OPS(gadget_strings);
 USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info);
 
-static inline struct os_desc *to_os_desc(struct config_item *item)
-{
-       return container_of(to_config_group(item), struct os_desc, group);
-}
-
 static inline struct gadget_info *os_desc_item_to_gadget_info(
                struct config_item *item)
 {
-       return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
+       return container_of(to_config_group(item),
+                       struct gadget_info, os_desc_group);
 }
 
 static ssize_t os_desc_use_show(struct config_item *item, char *page)
@@ -886,21 +876,12 @@ static struct configfs_attribute *os_desc_attrs[] = {
        NULL,
 };
 
-static void os_desc_attr_release(struct config_item *item)
-{
-       struct os_desc *os_desc = to_os_desc(item);
-       kfree(os_desc);
-}
-
 static int os_desc_link(struct config_item *os_desc_ci,
                        struct config_item *usb_cfg_ci)
 {
-       struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
-                                       struct gadget_info, os_desc_group);
+       struct gadget_info *gi = os_desc_item_to_gadget_info(os_desc_ci);
        struct usb_composite_dev *cdev = &gi->cdev;
-       struct config_usb_cfg *c_target =
-               container_of(to_config_group(usb_cfg_ci),
-                            struct config_usb_cfg, group);
+       struct config_usb_cfg *c_target = to_config_usb_cfg(usb_cfg_ci);
        struct usb_configuration *c;
        int ret;
 
@@ -930,8 +911,7 @@ out:
 static void os_desc_unlink(struct config_item *os_desc_ci,
                          struct config_item *usb_cfg_ci)
 {
-       struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
-                                       struct gadget_info, os_desc_group);
+       struct gadget_info *gi = os_desc_item_to_gadget_info(os_desc_ci);
        struct usb_composite_dev *cdev = &gi->cdev;
 
        mutex_lock(&gi->lock);
@@ -943,7 +923,6 @@ static void os_desc_unlink(struct config_item *os_desc_ci,
 }
 
 static struct configfs_item_operations os_desc_ops = {
-       .release                = os_desc_attr_release,
        .allow_link             = os_desc_link,
        .drop_link              = os_desc_unlink,
 };
index e20c19a..3c584da 100644 (file)
@@ -614,7 +614,7 @@ static int ffs_ep0_open(struct inode *inode, struct file *file)
        file->private_data = ffs;
        ffs_data_opened(ffs);
 
-       return 0;
+       return stream_open(inode, file);
 }
 
 static int ffs_ep0_release(struct inode *inode, struct file *file)
@@ -1154,7 +1154,7 @@ ffs_epfile_open(struct inode *inode, struct file *file)
        file->private_data = epfile;
        ffs_data_opened(epfile->ffs);
 
-       return 0;
+       return stream_open(inode, file);
 }
 
 static int ffs_aio_cancel(struct kiocb *kiocb)
index 71a1a26..fddf539 100644 (file)
@@ -1097,7 +1097,7 @@ static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
-       result = sprintf(page, "%d\n", opts->name);                     \
+       result = sprintf(page, "%u\n", opts->name);                     \
        mutex_unlock(&opts->lock);                                      \
                                                                        \
        return result;                                                  \
@@ -1134,7 +1134,51 @@ end:                                                                     \
                                                                        \
 CONFIGFS_ATTR(f_midi_opts_, name);
 
-F_MIDI_OPT(index, true, SNDRV_CARDS);
+#define F_MIDI_OPT_SIGNED(name, test_limit, limit)                             \
+static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \
+{                                                                      \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
+       int result;                                                     \
+                                                                       \
+       mutex_lock(&opts->lock);                                        \
+       result = sprintf(page, "%d\n", opts->name);                     \
+       mutex_unlock(&opts->lock);                                      \
+                                                                       \
+       return result;                                                  \
+}                                                                      \
+                                                                       \
+static ssize_t f_midi_opts_##name##_store(struct config_item *item,    \
+                                        const char *page, size_t len)  \
+{                                                                      \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
+       int ret;                                                        \
+       s32 num;                                                        \
+                                                                       \
+       mutex_lock(&opts->lock);                                        \
+       if (opts->refcnt > 1) {                                         \
+               ret = -EBUSY;                                           \
+               goto end;                                               \
+       }                                                               \
+                                                                       \
+       ret = kstrtos32(page, 0, &num);                                 \
+       if (ret)                                                        \
+               goto end;                                               \
+                                                                       \
+       if (test_limit && num > limit) {                                \
+               ret = -EINVAL;                                          \
+               goto end;                                               \
+       }                                                               \
+       opts->name = num;                                               \
+       ret = len;                                                      \
+                                                                       \
+end:                                                                   \
+       mutex_unlock(&opts->lock);                                      \
+       return ret;                                                     \
+}                                                                      \
+                                                                       \
+CONFIGFS_ATTR(f_midi_opts_, name);
+
+F_MIDI_OPT_SIGNED(index, true, SNDRV_CARDS);
 F_MIDI_OPT(buflen, false, 0);
 F_MIDI_OPT(qlen, false, 0);
 F_MIDI_OPT(in_ports, true, MAX_PORTS);
index d9ad9ad..dd0819d 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/platform_data/atmel.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
@@ -1510,7 +1510,6 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
 
 static void at91_vbus_update(struct at91_udc *udc, unsigned value)
 {
-       value ^= udc->board.vbus_active_low;
        if (value != udc->vbus)
                at91_vbus_session(&udc->gadget, value);
 }
@@ -1521,7 +1520,7 @@ static irqreturn_t at91_vbus_irq(int irq, void *_udc)
 
        /* vbus needs at least brief debouncing */
        udelay(10);
-       at91_vbus_update(udc, gpio_get_value(udc->board.vbus_pin));
+       at91_vbus_update(udc, gpiod_get_value(udc->board.vbus_pin));
 
        return IRQ_HANDLED;
 }
@@ -1531,7 +1530,7 @@ static void at91_vbus_timer_work(struct work_struct *work)
        struct at91_udc *udc = container_of(work, struct at91_udc,
                                            vbus_timer_work);
 
-       at91_vbus_update(udc, gpio_get_value_cansleep(udc->board.vbus_pin));
+       at91_vbus_update(udc, gpiod_get_value_cansleep(udc->board.vbus_pin));
 
        if (!timer_pending(&udc->vbus_timer))
                mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
@@ -1595,7 +1594,6 @@ static void at91udc_shutdown(struct platform_device *dev)
 static int at91rm9200_udc_init(struct at91_udc *udc)
 {
        struct at91_ep *ep;
-       int ret;
        int i;
 
        for (i = 0; i < NUM_ENDPOINTS; i++) {
@@ -1615,32 +1613,23 @@ static int at91rm9200_udc_init(struct at91_udc *udc)
                }
        }
 
-       if (!gpio_is_valid(udc->board.pullup_pin)) {
+       if (!udc->board.pullup_pin) {
                DBG("no D+ pullup?\n");
                return -ENODEV;
        }
 
-       ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin,
-                               "udc_pullup");
-       if (ret) {
-               DBG("D+ pullup is busy\n");
-               return ret;
-       }
-
-       gpio_direction_output(udc->board.pullup_pin,
-                             udc->board.pullup_active_low);
+       gpiod_direction_output(udc->board.pullup_pin,
+                              gpiod_is_active_low(udc->board.pullup_pin));
 
        return 0;
 }
 
 static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
 {
-       int active = !udc->board.pullup_active_low;
-
        if (is_on)
-               gpio_set_value(udc->board.pullup_pin, active);
+               gpiod_set_value(udc->board.pullup_pin, 1);
        else
-               gpio_set_value(udc->board.pullup_pin, !active);
+               gpiod_set_value(udc->board.pullup_pin, 0);
 }
 
 static const struct at91_udc_caps at91rm9200_udc_caps = {
@@ -1783,20 +1772,20 @@ static void at91udc_of_init(struct at91_udc *udc, struct device_node *np)
 {
        struct at91_udc_data *board = &udc->board;
        const struct of_device_id *match;
-       enum of_gpio_flags flags;
        u32 val;
 
        if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
                board->vbus_polled = 1;
 
-       board->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
-                                                 &flags);
-       board->vbus_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+       board->vbus_pin = gpiod_get_from_of_node(np, "atmel,vbus-gpio", 0,
+                                                GPIOD_IN, "udc_vbus");
+       if (IS_ERR(board->vbus_pin))
+               board->vbus_pin = NULL;
 
-       board->pullup_pin = of_get_named_gpio_flags(np, "atmel,pullup-gpio", 0,
-                                                 &flags);
-
-       board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+       board->pullup_pin = gpiod_get_from_of_node(np, "atmel,pullup-gpio", 0,
+                                                  GPIOD_ASIS, "udc_pullup");
+       if (IS_ERR(board->pullup_pin))
+               board->pullup_pin = NULL;
 
        match = of_match_node(at91_udc_dt_ids, np);
        if (match)
@@ -1886,22 +1875,14 @@ static int at91udc_probe(struct platform_device *pdev)
                goto err_unprepare_iclk;
        }
 
-       if (gpio_is_valid(udc->board.vbus_pin)) {
-               retval = devm_gpio_request(dev, udc->board.vbus_pin,
-                                          "udc_vbus");
-               if (retval) {
-                       DBG("request vbus pin failed\n");
-                       goto err_unprepare_iclk;
-               }
-
-               gpio_direction_input(udc->board.vbus_pin);
+       if (udc->board.vbus_pin) {
+               gpiod_direction_input(udc->board.vbus_pin);
 
                /*
                 * Get the initial state of VBUS - we cannot expect
                 * a pending interrupt.
                 */
-               udc->vbus = gpio_get_value_cansleep(udc->board.vbus_pin) ^
-                       udc->board.vbus_active_low;
+               udc->vbus = gpiod_get_value_cansleep(udc->board.vbus_pin);
 
                if (udc->board.vbus_polled) {
                        INIT_WORK(&udc->vbus_timer_work, at91_vbus_timer_work);
@@ -1910,7 +1891,7 @@ static int at91udc_probe(struct platform_device *pdev)
                                  jiffies + VBUS_POLL_TIMEOUT);
                } else {
                        retval = devm_request_irq(dev,
-                                       gpio_to_irq(udc->board.vbus_pin),
+                                       gpiod_to_irq(udc->board.vbus_pin),
                                        at91_vbus_irq, 0, driver_name, udc);
                        if (retval) {
                                DBG("request vbus irq %d failed\n",
@@ -1988,8 +1969,8 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
                enable_irq_wake(udc->udp_irq);
 
        udc->active_suspend = wake;
-       if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled && wake)
-               enable_irq_wake(udc->board.vbus_pin);
+       if (udc->board.vbus_pin && !udc->board.vbus_polled && wake)
+               enable_irq_wake(gpiod_to_irq(udc->board.vbus_pin));
        return 0;
 }
 
@@ -1998,9 +1979,9 @@ static int at91udc_resume(struct platform_device *pdev)
        struct at91_udc *udc = platform_get_drvdata(pdev);
        unsigned long   flags;
 
-       if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled &&
+       if (udc->board.vbus_pin && !udc->board.vbus_polled &&
            udc->active_suspend)
-               disable_irq_wake(udc->board.vbus_pin);
+               disable_irq_wake(gpiod_to_irq(udc->board.vbus_pin));
 
        /* maybe reconnect to host; if so, clocks on */
        if (udc->active_suspend)
index fd58c5b..28c1042 100644 (file)
@@ -109,11 +109,9 @@ struct at91_udc_caps {
 };
 
 struct at91_udc_data {
-       int     vbus_pin;               /* high == host powering us */
-       u8      vbus_active_low;        /* vbus polarity */
-       u8      vbus_polled;            /* Use polling, not interrupt */
-       int     pullup_pin;             /* active == D+ pulled up */
-       u8      pullup_active_low;      /* true == pullup_pin is active low */
+       struct gpio_desc  *vbus_pin;            /* high == host powering us */
+       u8                vbus_polled;          /* Use polling, not interrupt */
+       struct gpio_desc  *pullup_pin;          /* active == D+ pulled up */
 };
 
 /*
index 7f24ce4..b6d34dd 100644 (file)
@@ -2084,10 +2084,8 @@ static int mv_udc_remove(struct platform_device *pdev)
 
        usb_del_gadget_udc(&udc->gadget);
 
-       if (udc->qwork) {
-               flush_workqueue(udc->qwork);
+       if (udc->qwork)
                destroy_workqueue(udc->qwork);
-       }
 
        /* free memory allocated in probe */
        dma_pool_destroy(udc->dtd_pool);
index 857159d..6ce886f 100644 (file)
@@ -2179,6 +2179,61 @@ static int xudc_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int xudc_suspend(struct device *dev)
+{
+       struct xusb_udc *udc;
+       u32 crtlreg;
+       unsigned long flags;
+
+       udc = dev_get_drvdata(dev);
+
+       spin_lock_irqsave(&udc->lock, flags);
+
+       crtlreg = udc->read_fn(udc->addr + XUSB_CONTROL_OFFSET);
+       crtlreg &= ~XUSB_CONTROL_USB_READY_MASK;
+
+       udc->write_fn(udc->addr, XUSB_CONTROL_OFFSET, crtlreg);
+
+       spin_unlock_irqrestore(&udc->lock, flags);
+       if (udc->driver && udc->driver->suspend)
+               udc->driver->suspend(&udc->gadget);
+
+       clk_disable(udc->clk);
+
+       return 0;
+}
+
+static int xudc_resume(struct device *dev)
+{
+       struct xusb_udc *udc;
+       u32 crtlreg;
+       unsigned long flags;
+       int ret;
+
+       udc = dev_get_drvdata(dev);
+
+       ret = clk_enable(udc->clk);
+       if (ret < 0)
+               return ret;
+
+       spin_lock_irqsave(&udc->lock, flags);
+
+       crtlreg = udc->read_fn(udc->addr + XUSB_CONTROL_OFFSET);
+       crtlreg |= XUSB_CONTROL_USB_READY_MASK;
+
+       udc->write_fn(udc->addr, XUSB_CONTROL_OFFSET, crtlreg);
+
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops xudc_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(xudc_suspend, xudc_resume)
+};
+
 /* Match table for of_platform binding */
 static const struct of_device_id usb_of_match[] = {
        { .compatible = "xlnx,usb2-device-4.00.a", },
@@ -2190,6 +2245,7 @@ static struct platform_driver xudc_driver = {
        .driver = {
                .name = driver_name,
                .of_match_table = usb_of_match,
+               .pm     = &xudc_pm_ops,
        },
        .probe = xudc_probe,
        .remove = xudc_remove,
index d3626bf..6a0f64c 100644 (file)
@@ -62,8 +62,12 @@ static int ehci_brcm_hub_control(
        u32 __iomem     *status_reg;
        unsigned long flags;
        int retval, irq_disabled = 0;
+       u32 temp;
 
-       status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+       temp = (wIndex & 0xff) - 1;
+       if (temp >= HCS_N_PORTS_MAX)    /* Avoid index-out-of-bounds warning */
+               temp = 0;
+       status_reg = &ehci->regs->port_status[temp];
 
        /*
         * RESUME is cleared when GetPortStatus() is called 20ms after start
index ae882d7..d879d6a 100644 (file)
@@ -3211,7 +3211,6 @@ static void __exit u132_hcd_exit(void)
        platform_driver_unregister(&u132_platform_driver);
        printk(KERN_INFO "u132-hcd driver deregistered\n");
        wait_event(u132_hcd_wait, u132_instances == 0);
-       flush_workqueue(workqueue);
        destroy_workqueue(workqueue);
 }
 
index 58a0eae..91738af 100644 (file)
@@ -245,11 +245,12 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
        /* wait for host ip to sleep */
        ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
                          (value & STS1_IP_SLEEP_STS), 100, 100000);
-       if (ret) {
+       if (ret)
                dev_err(mtk->dev, "ip sleep failed!!!\n");
-               return ret;
-       }
-       return 0;
+       else /* workaound for platforms using low level latch */
+               usleep_range(100, 200);
+
+       return ret;
 }
 
 static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk)
@@ -300,7 +301,7 @@ static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable)
        case SSUSB_UWK_V1_1:
                reg = mtk->uwk_reg_base + PERI_WK_CTRL0;
                msk = WC0_IS_EN | WC0_IS_C(0xf) | WC0_IS_P;
-               val = enable ? (WC0_IS_EN | WC0_IS_C(0x8)) : 0;
+               val = enable ? (WC0_IS_EN | WC0_IS_C(0x1)) : 0;
                break;
        case SSUSB_UWK_V1_2:
                reg = mtk->uwk_reg_base + PERI_WK_CTRL0;
@@ -437,11 +438,8 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
        if (ret)
                return ret;
 
-       if (usb_hcd_is_primary_hcd(hcd)) {
+       if (usb_hcd_is_primary_hcd(hcd))
                ret = xhci_mtk_sch_init(mtk);
-               if (ret)
-                       return ret;
-       }
 
        return ret;
 }
index 576d925..86503b7 100644 (file)
@@ -648,10 +648,8 @@ static int mv_otg_remove(struct platform_device *pdev)
 {
        struct mv_otg *mvotg = platform_get_drvdata(pdev);
 
-       if (mvotg->qwork) {
-               flush_workqueue(mvotg->qwork);
+       if (mvotg->qwork)
                destroy_workqueue(mvotg->qwork);
-       }
 
        mv_otg_disable(mvotg);
 
@@ -825,7 +823,6 @@ static int mv_otg_probe(struct platform_device *pdev)
 err_disable_clk:
        mv_otg_disable_internal(mvotg);
 err_destroy_workqueue:
-       flush_workqueue(mvotg->qwork);
        destroy_workqueue(mvotg->qwork);
 
        return retval;
index 6aa2838..9d6b7e0 100644 (file)
@@ -303,6 +303,17 @@ static int ucsi_next_altmode(struct typec_altmode **alt)
        return -ENOENT;
 }
 
+static int ucsi_get_num_altmode(struct typec_altmode **alt)
+{
+       int i;
+
+       for (i = 0; i < UCSI_MAX_ALTMODES; i++)
+               if (!alt[i])
+                       break;
+
+       return i;
+}
+
 static int ucsi_register_altmode(struct ucsi_connector *con,
                                 struct typec_altmode_desc *desc,
                                 u8 recipient)
@@ -607,7 +618,7 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con)
 
 static int ucsi_check_altmodes(struct ucsi_connector *con)
 {
-       int ret;
+       int ret, num_partner_am;
 
        ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
        if (ret && ret != -ETIMEDOUT)
@@ -617,6 +628,9 @@ static int ucsi_check_altmodes(struct ucsi_connector *con)
 
        /* Ignoring the errors in this case. */
        if (con->partner_altmode[0]) {
+               num_partner_am = ucsi_get_num_altmode(con->partner_altmode);
+               if (num_partner_am > 0)
+                       typec_partner_set_num_altmodes(con->partner, num_partner_am);
                ucsi_altmode_update_active(con);
                return 0;
        }
index 086ca76..2651354 100644 (file)
@@ -137,7 +137,6 @@ int usbip_init_eh(void)
 
 void usbip_finish_eh(void)
 {
-       flush_workqueue(usbip_queue);
        destroy_workqueue(usbip_queue);
        usbip_queue = NULL;
 }