]> Git Repo - linux.git/commitdiff
Merge tag 'v5.13-rc6' into usb-next
authorGreg Kroah-Hartman <[email protected]>
Mon, 14 Jun 2021 07:18:07 +0000 (09:18 +0200)
committerGreg Kroah-Hartman <[email protected]>
Mon, 14 Jun 2021 07:18:07 +0000 (09:18 +0200)
We want the usb fixes in here as well, and this resolves some merge
issues with:
drivers/usb/dwc3/debugfs.c
drivers/usb/dwc3/gadget.c

Signed-off-by: Greg Kroah-Hartman <[email protected]>
13 files changed:
1  2 
drivers/pci/probe.c
drivers/usb/cdns3/cdns3-gadget.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_hid.c
drivers/usb/gadget/function/f_printer.c
drivers/usb/musb/musb_core.c
drivers/usb/typec/mux.c
drivers/usb/typec/mux/intel_pmc_mux.c
drivers/usb/typec/tcpm/tcpm.c
drivers/usb/typec/tcpm/wcove.c
drivers/usb/typec/ucsi/ucsi.c

diff --combined drivers/pci/probe.c
index 812e0d7fd7a71cf5eabc73ff60a1f427db81be9d,275204646c68c08b27ef7cdb9596cc638940836e..76a2f33c6b484ab1dcdfe0810564f9d2c7002769
@@@ -925,7 -925,8 +925,8 @@@ static int pci_register_host_bridge(str
        device_enable_async_suspend(bus->bridge);
        pci_set_bus_of_node(bus);
        pci_set_bus_msi_domain(bus);
-       if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev))
+       if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
+           !pci_host_of_has_msi_map(parent))
                bus->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
  
        if (!parent)
@@@ -1575,26 -1576,6 +1576,26 @@@ static void set_pcie_untrusted(struct p
                dev->untrusted = true;
  }
  
 +static void pci_set_removable(struct pci_dev *dev)
 +{
 +      struct pci_dev *parent = pci_upstream_bridge(dev);
 +
 +      /*
 +       * We (only) consider everything downstream from an external_facing
 +       * device to be removable by the user. We're mainly concerned with
 +       * consumer platforms with user accessible thunderbolt ports that are
 +       * vulnerable to DMA attacks, and we expect those ports to be marked by
 +       * the firmware as external_facing. Devices in traditional hotplug
 +       * slots can technically be removed, but the expectation is that unless
 +       * the port is marked with external_facing, such devices are less
 +       * accessible to user / may not be removed by end user, and thus not
 +       * exposed as "removable" to userspace.
 +       */
 +      if (parent &&
 +          (parent->external_facing || dev_is_removable(&parent->dev)))
 +              dev_set_removable(&dev->dev, DEVICE_REMOVABLE);
 +}
 +
  /**
   * pci_ext_cfg_is_aliased - Is ext config space just an alias of std config?
   * @dev: PCI device
@@@ -1842,8 -1823,6 +1843,8 @@@ int pci_setup_device(struct pci_dev *de
        /* Early fixups, before probing the BARs */
        pci_fixup_device(pci_fixup_early, dev);
  
 +      pci_set_removable(dev);
 +
        pci_info(dev, "[%04x:%04x] type %02x class %#08x\n",
                 dev->vendor, dev->device, dev->hdr_type, dev->class);
  
index 279077dae86a757ea9d7f44052e698bae3c1071b,5281f8d3fb3d130e36fd7099c62b1b5d0ed9e4bb..ab29a66f0eae6f6bdae3cb538b9f71fad745c2fd
@@@ -155,7 -155,7 +155,7 @@@ static struct cdns3_request *cdns3_next
  }
  
  /**
 - * select_ep - selects endpoint
 + * cdns3_select_ep - selects endpoint
   * @priv_dev:  extended gadget object
   * @ep: endpoint address
   */
@@@ -1835,7 -1835,7 +1835,7 @@@ __must_hold(&priv_dev->lock
  }
  
  /**
 - * cdns3_device_irq_handler- interrupt handler for device part of controller
 + * cdns3_device_irq_handler - interrupt handler for device part of controller
   *
   * @irq: irq number for cdns3 core device
   * @data: structure of cdns3
@@@ -1879,7 -1879,7 +1879,7 @@@ static irqreturn_t cdns3_device_irq_han
  }
  
  /**
 - * cdns3_device_thread_irq_handler- interrupt handler for device part
 + * cdns3_device_thread_irq_handler - interrupt handler for device part
   * of controller
   *
   * @irq: irq number for cdns3 core device
@@@ -2007,7 -2007,7 +2007,7 @@@ static void cdns3_configure_dmult(struc
                else
                        mask = BIT(priv_ep->num);
  
-               if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) {
+               if (priv_ep->type != USB_ENDPOINT_XFER_ISOC  && !priv_ep->dir) {
                        cdns3_set_register_bit(&regs->tdl_from_trb, mask);
                        cdns3_set_register_bit(&regs->tdl_beh, mask);
                        cdns3_set_register_bit(&regs->tdl_beh2, mask);
  }
  
  /**
 - * cdns3_ep_config Configure hardware endpoint
 + * cdns3_ep_config Configure hardware endpoint
   * @priv_ep: extended endpoint object
   * @enable: set EP_CFG_ENABLE bit in ep_cfg register.
   */
@@@ -2046,15 -2046,13 +2046,13 @@@ int cdns3_ep_config(struct cdns3_endpoi
        case USB_ENDPOINT_XFER_INT:
                ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT);
  
-               if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) ||
-                   priv_dev->dev_ver > DEV_VER_V2)
+               if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
                        ep_cfg |= EP_CFG_TDL_CHK;
                break;
        case USB_ENDPOINT_XFER_BULK:
                ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK);
  
-               if ((priv_dev->dev_ver == DEV_VER_V2  && !priv_ep->dir) ||
-                   priv_dev->dev_ver > DEV_VER_V2)
+               if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
                        ep_cfg |= EP_CFG_TDL_CHK;
                break;
        default:
@@@ -2223,7 -2221,7 +2221,7 @@@ usb_ep *cdns3_gadget_match_ep(struct us
  }
  
  /**
 - * cdns3_gadget_ep_alloc_request Allocates request
 + * cdns3_gadget_ep_alloc_request Allocates request
   * @ep: endpoint object associated with request
   * @gfp_flags: gfp flags
   *
@@@ -2246,7 -2244,7 +2244,7 @@@ struct usb_request *cdns3_gadget_ep_all
  }
  
  /**
 - * cdns3_gadget_ep_free_request Free memory occupied by request
 + * cdns3_gadget_ep_free_request Free memory occupied by request
   * @ep: endpoint object associated with request
   * @request: request to free memory
   */
@@@ -2263,7 -2261,7 +2261,7 @@@ void cdns3_gadget_ep_free_request(struc
  }
  
  /**
 - * cdns3_gadget_ep_enable Enable endpoint
 + * cdns3_gadget_ep_enable Enable endpoint
   * @ep: endpoint object
   * @desc: endpoint descriptor
   *
@@@ -2398,7 -2396,7 +2396,7 @@@ exit
  }
  
  /**
 - * cdns3_gadget_ep_disable Disable endpoint
 + * cdns3_gadget_ep_disable Disable endpoint
   * @ep: endpoint object
   *
   * Returns 0 on success, error code elsewhere
@@@ -2488,7 -2486,7 +2486,7 @@@ static int cdns3_gadget_ep_disable(stru
  }
  
  /**
 - * cdns3_gadget_ep_queue Transfer data on endpoint
 + * __cdns3_gadget_ep_queue - Transfer data on endpoint
   * @ep: endpoint object
   * @request: request object
   * @gfp_flags: gfp flags
@@@ -2588,7 -2586,7 +2586,7 @@@ static int cdns3_gadget_ep_queue(struc
  }
  
  /**
 - * cdns3_gadget_ep_dequeue Remove request from transfer queue
 + * cdns3_gadget_ep_dequeue Remove request from transfer queue
   * @ep: endpoint object associated with request
   * @request: request object
   *
@@@ -2655,7 -2653,7 +2653,7 @@@ not_found
  }
  
  /**
 - * __cdns3_gadget_ep_set_halt Sets stall on selected endpoint
 + * __cdns3_gadget_ep_set_halt Sets stall on selected endpoint
   * Should be called after acquiring spin_lock and selecting ep
   * @priv_ep: endpoint object to set stall on.
   */
@@@ -2676,7 -2674,7 +2674,7 @@@ void __cdns3_gadget_ep_set_halt(struct 
  }
  
  /**
 - * __cdns3_gadget_ep_clear_halt Clears stall on selected endpoint
 + * __cdns3_gadget_ep_clear_halt Clears stall on selected endpoint
   * Should be called after acquiring spin_lock and selecting ep
   * @priv_ep: endpoint object to clear stall on
   */
@@@ -2721,7 -2719,7 +2719,7 @@@ int __cdns3_gadget_ep_clear_halt(struc
  }
  
  /**
 - * cdns3_gadget_ep_set_halt Sets/clears stall on selected endpoint
 + * cdns3_gadget_ep_set_halt Sets/clears stall on selected endpoint
   * @ep: endpoint object to set/clear stall on
   * @value: 1 for set stall, 0 for clear stall
   *
@@@ -2767,7 -2765,7 +2765,7 @@@ static const struct usb_ep_ops cdns3_ga
  };
  
  /**
 - * cdns3_gadget_get_frame Returns number of actual ITP frame
 + * cdns3_gadget_get_frame Returns number of actual ITP frame
   * @gadget: gadget object
   *
   * Returns number of actual ITP frame
@@@ -2876,7 -2874,7 +2874,7 @@@ static void cdns3_gadget_config(struct 
  }
  
  /**
 - * cdns3_gadget_udc_start Gadget start
 + * cdns3_gadget_udc_start Gadget start
   * @gadget: gadget object
   * @driver: driver which operates on this gadget
   *
@@@ -2922,7 -2920,7 +2920,7 @@@ static int cdns3_gadget_udc_start(struc
  }
  
  /**
 - * cdns3_gadget_udc_stop Stops gadget
 + * cdns3_gadget_udc_stop Stops gadget
   * @gadget: gadget object
   *
   * Returns 0
@@@ -2985,7 -2983,7 +2983,7 @@@ static void cdns3_free_all_eps(struct c
  }
  
  /**
 - * cdns3_init_eps Initializes software endpoints of gadget
 + * cdns3_init_eps Initializes software endpoints of gadget
   * @priv_dev: extended gadget object
   *
   * Returns 0 on success, error code elsewhere
diff --combined drivers/usb/dwc3/core.c
index 45b28e2f641db88b00df93a4973eb18d295eef70,21129d357f29578b50814f41414c90f21e3b61a0..e0a8e796c158bfbcfcdfba12889a1c8ccd7a8d36
@@@ -1545,10 -1545,6 +1545,10 @@@ static int dwc3_probe(struct platform_d
  
        dwc3_get_properties(dwc);
  
 +      ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
 +      if (ret)
 +              return ret;
 +
        dwc->reset = devm_reset_control_array_get_optional_shared(dev);
        if (IS_ERR(dwc->reset))
                return PTR_ERR(dwc->reset);
@@@ -1675,8 -1671,8 +1675,8 @@@ static int dwc3_remove(struct platform_
  
        pm_runtime_get_sync(&pdev->dev);
  
 -      dwc3_debugfs_exit(dwc);
        dwc3_core_exit_mode(dwc);
 +      dwc3_debugfs_exit(dwc);
  
        dwc3_core_exit(dwc);
        dwc3_ulpi_exit(dwc);
        return 0;
  }
  
- static void dwc3_shutdown(struct platform_device *pdev)
- {
-       dwc3_remove(pdev);
- }
  #ifdef CONFIG_PM
  static int dwc3_core_init_for_resume(struct dwc3 *dwc)
  {
@@@ -2016,7 -2007,6 +2011,6 @@@ MODULE_DEVICE_TABLE(acpi, dwc3_acpi_mat
  static struct platform_driver dwc3_driver = {
        .probe          = dwc3_probe,
        .remove         = dwc3_remove,
-       .shutdown   = dwc3_shutdown,
        .driver         = {
                .name   = "dwc3",
                .of_match_table = of_match_ptr(of_dwc3_match),
index 026a2ad0fc80fffa41d86a4699ed819042e049e0,f14c2aa83759825fcc6b81e887b030b53a32b479..af6d7f157989daa5bb596926cbf712b3f15f1c66
@@@ -2261,13 -2261,10 +2261,10 @@@ static int dwc3_gadget_pullup(struct us
        }
  
        /*
-        * Synchronize any pending event handling before executing the controller
-        * halt routine.
+        * Synchronize and disable any further event handling while controller
+        * is being enabled/disabled.
         */
-       if (!is_on) {
-               dwc3_gadget_disable_irq(dwc);
-               synchronize_irq(dwc->irq_gadget);
-       }
+       disable_irq(dwc->irq_gadget);
  
        spin_lock_irqsave(&dwc->lock, flags);
  
  
        ret = dwc3_gadget_run_stop(dwc, is_on, false);
        spin_unlock_irqrestore(&dwc->lock, flags);
+       enable_irq(dwc->irq_gadget);
        pm_runtime_put(dwc->dev);
  
        return ret;
@@@ -2799,9 -2798,7 +2798,9 @@@ static void dwc3_gadget_free_endpoints(
                        list_del(&dep->endpoint.ep_list);
                }
  
 -              debugfs_remove_recursive(debugfs_lookup(dep->name, dwc->root));
 +              debugfs_remove_recursive(debugfs_lookup(dep->name,
 +                              debugfs_lookup(dev_name(dep->dwc->dev),
 +                                             usb_debug_root)));
                kfree(dep);
        }
  }
@@@ -4051,6 -4048,7 +4050,7 @@@ err5
        dwc3_gadget_free_endpoints(dwc);
  err4:
        usb_put_gadget(dwc->gadget);
+       dwc->gadget = NULL;
  err3:
        dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
                        dwc->bounce_addr);
@@@ -4070,6 -4068,9 +4070,9 @@@ err0
  
  void dwc3_gadget_exit(struct dwc3 *dwc)
  {
+       if (!dwc->gadget)
+               return;
        usb_del_gadget(dwc->gadget);
        dwc3_gadget_free_endpoints(dwc);
        usb_put_gadget(dwc->gadget);
index 5cb324e040c8658722c6b5c5a9de16c2263a41c2,d4844afeaffc272fae24b726ca44344eda15fb5e..9c0c393abb39b0a7d30de767dbb86f50fa1adf7f
@@@ -250,8 -250,8 +250,8 @@@ EXPORT_SYMBOL_GPL(ffs_lock)
  static struct ffs_dev *_ffs_find_dev(const char *name);
  static struct ffs_dev *_ffs_alloc_dev(void);
  static void _ffs_free_dev(struct ffs_dev *dev);
 -static void *ffs_acquire_dev(const char *dev_name);
 -static void ffs_release_dev(struct ffs_data *ffs_data);
 +static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data);
 +static void ffs_release_dev(struct ffs_dev *ffs_dev);
  static int ffs_ready(struct ffs_data *ffs);
  static void ffs_closed(struct ffs_data *ffs);
  
@@@ -1554,8 -1554,8 +1554,8 @@@ unmapped_value
  static int ffs_fs_get_tree(struct fs_context *fc)
  {
        struct ffs_sb_fill_data *ctx = fc->fs_private;
 -      void *ffs_dev;
        struct ffs_data *ffs;
 +      int ret;
  
        ENTER();
  
                return -ENOMEM;
        }
  
 -      ffs_dev = ffs_acquire_dev(ffs->dev_name);
 -      if (IS_ERR(ffs_dev)) {
 +      ret = ffs_acquire_dev(ffs->dev_name, ffs);
 +      if (ret) {
                ffs_data_put(ffs);
 -              return PTR_ERR(ffs_dev);
 +              return ret;
        }
  
 -      ffs->private_data = ffs_dev;
        ctx->ffs_data = ffs;
        return get_tree_nodev(fc, ffs_sb_fill);
  }
@@@ -1590,6 -1591,7 +1590,6 @@@ static void ffs_fs_free_fc(struct fs_co
  
        if (ctx) {
                if (ctx->ffs_data) {
 -                      ffs_release_dev(ctx->ffs_data);
                        ffs_data_put(ctx->ffs_data);
                }
  
@@@ -1628,8 -1630,10 +1628,8 @@@ ffs_fs_kill_sb(struct super_block *sb
        ENTER();
  
        kill_litter_super(sb);
 -      if (sb->s_fs_info) {
 -              ffs_release_dev(sb->s_fs_info);
 +      if (sb->s_fs_info)
                ffs_data_closed(sb->s_fs_info);
 -      }
  }
  
  static struct file_system_type ffs_fs_type = {
@@@ -1699,7 -1703,6 +1699,7 @@@ static void ffs_data_put(struct ffs_dat
        if (refcount_dec_and_test(&ffs->ref)) {
                pr_info("%s(): freeing\n", __func__);
                ffs_data_clear(ffs);
 +              ffs_release_dev(ffs->private_data);
                BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
                       swait_active(&ffs->ep0req_completion.wait) ||
                       waitqueue_active(&ffs->wait));
@@@ -3029,7 -3032,6 +3029,7 @@@ static inline struct f_fs_opts *ffs_do_
        struct ffs_function *func = ffs_func_from_usb(f);
        struct f_fs_opts *ffs_opts =
                container_of(f->fi, struct f_fs_opts, func_inst);
 +      struct ffs_data *ffs_data;
        int ret;
  
        ENTER();
        if (!ffs_opts->no_configfs)
                ffs_dev_lock();
        ret = ffs_opts->dev->desc_ready ? 0 : -ENODEV;
 -      func->ffs = ffs_opts->dev->ffs_data;
 +      ffs_data = ffs_opts->dev->ffs_data;
        if (!ffs_opts->no_configfs)
                ffs_dev_unlock();
        if (ret)
                return ERR_PTR(ret);
  
 +      func->ffs = ffs_data;
        func->conf = c;
        func->gadget = c->cdev->gadget;
  
@@@ -3505,7 -3506,6 +3505,7 @@@ static void ffs_free_inst(struct usb_fu
        struct f_fs_opts *opts;
  
        opts = to_f_fs_opts(f);
 +      ffs_release_dev(opts->dev);
        ffs_dev_lock();
        _ffs_free_dev(opts->dev);
        ffs_dev_unlock();
@@@ -3567,6 -3567,9 +3567,9 @@@ static void ffs_func_unbind(struct usb_
                ffs->func = NULL;
        }
  
+       /* Drain any pending AIO completions */
+       drain_workqueue(ffs->io_completion_wq);
        if (!--opts->refcnt)
                functionfs_unbind(ffs);
  
@@@ -3690,48 -3693,47 +3693,48 @@@ static void _ffs_free_dev(struct ffs_de
  {
        list_del(&dev->entry);
  
 -      /* Clear the private_data pointer to stop incorrect dev access */
 -      if (dev->ffs_data)
 -              dev->ffs_data->private_data = NULL;
 -
        kfree(dev);
        if (list_empty(&ffs_devices))
                functionfs_cleanup();
  }
  
 -static void *ffs_acquire_dev(const char *dev_name)
 +static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data)
  {
 +      int ret = 0;
        struct ffs_dev *ffs_dev;
  
        ENTER();
        ffs_dev_lock();
  
        ffs_dev = _ffs_find_dev(dev_name);
 -      if (!ffs_dev)
 -              ffs_dev = ERR_PTR(-ENOENT);
 -      else if (ffs_dev->mounted)
 -              ffs_dev = ERR_PTR(-EBUSY);
 -      else if (ffs_dev->ffs_acquire_dev_callback &&
 -          ffs_dev->ffs_acquire_dev_callback(ffs_dev))
 -              ffs_dev = ERR_PTR(-ENOENT);
 -      else
 +      if (!ffs_dev) {
 +              ret = -ENOENT;
 +      } else if (ffs_dev->mounted) {
 +              ret = -EBUSY;
 +      else if (ffs_dev->ffs_acquire_dev_callback &&
 +                 ffs_dev->ffs_acquire_dev_callback(ffs_dev)) {
 +              ret = -ENOENT;
 +      } else {
                ffs_dev->mounted = true;
 +              ffs_dev->ffs_data = ffs_data;
 +              ffs_data->private_data = ffs_dev;
 +      }
  
        ffs_dev_unlock();
 -      return ffs_dev;
 +      return ret;
  }
  
 -static void ffs_release_dev(struct ffs_data *ffs_data)
 +static void ffs_release_dev(struct ffs_dev *ffs_dev)
  {
 -      struct ffs_dev *ffs_dev;
 -
        ENTER();
        ffs_dev_lock();
  
 -      ffs_dev = ffs_data->private_data;
 -      if (ffs_dev) {
 +      if (ffs_dev && ffs_dev->mounted) {
                ffs_dev->mounted = false;
 +              if (ffs_dev->ffs_data) {
 +                      ffs_dev->ffs_data->private_data = NULL;
 +                      ffs_dev->ffs_data = NULL;
 +              }
  
                if (ffs_dev->ffs_release_dev_callback)
                        ffs_dev->ffs_release_dev_callback(ffs_dev);
@@@ -3759,6 -3761,7 +3762,6 @@@ static int ffs_ready(struct ffs_data *f
        }
  
        ffs_obj->desc_ready = true;
 -      ffs_obj->ffs_data = ffs;
  
        if (ffs_obj->ffs_ready_callback) {
                ret = ffs_obj->ffs_ready_callback(ffs);
@@@ -3786,6 -3789,7 +3789,6 @@@ static void ffs_closed(struct ffs_data 
                goto done;
  
        ffs_obj->desc_ready = false;
 -      ffs_obj->ffs_data = NULL;
  
        if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) &&
            ffs_obj->ffs_closed_callback)
index 0c964be5840688cc73f9115ab3dd7b61ca0a5317,e556993081170ffb4294024473b6e2a76770eaa9..70774d8cb14ec5d8047e742452fd37628588737a
@@@ -802,7 -802,8 +802,8 @@@ static int hidg_bind(struct usb_configu
                hidg_fs_out_ep_desc.bEndpointAddress;
  
        status = usb_assign_descriptors(f, hidg_fs_descriptors,
-                       hidg_hs_descriptors, hidg_ss_descriptors, NULL);
+                       hidg_hs_descriptors, hidg_ss_descriptors,
+                       hidg_ss_descriptors);
        if (status)
                goto fail;
  
@@@ -1117,7 -1118,7 +1118,7 @@@ static struct usb_function *hidg_alloc(
        hidg->func.setup   = hidg_setup;
        hidg->func.free_func = hidg_free;
  
 -      /* this could me made configurable at some point */
 +      /* this could be made configurable at some point */
        hidg->qlen         = 4;
  
        return &hidg->func;
index b5112f6974f23197658a1628529ff829304c4433,59d382fe1bbfc6e2b32e23b4c90e55c7cae9a7d8..abec5c58f5251ae3e7c3a34a8521b1b9465ea86e
@@@ -667,7 -667,8 +667,7 @@@ printer_write(struct file *fd, const ch
                value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
                spin_lock(&dev->lock);
                if (value) {
 -                      list_del(&req->list);
 -                      list_add(&req->list, &dev->tx_reqs);
 +                      list_move(&req->list, &dev->tx_reqs);
                        spin_unlock_irqrestore(&dev->lock, flags);
                        mutex_unlock(&dev->lock_printer_io);
                        return -EAGAIN;
@@@ -1100,7 -1101,8 +1100,8 @@@ autoconf_fail
        ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
  
        ret = usb_assign_descriptors(f, fs_printer_function,
-                       hs_printer_function, ss_printer_function, NULL);
+                       hs_printer_function, ss_printer_function,
+                       ss_printer_function);
        if (ret)
                return ret;
  
index 71ae84031c1f4a3d27ebac8d879645a0dd9b28b1,4c8f0112481f379cce95ffdc4d88bb7d03e2deec..8637dfd84b6796d55325274dc05d05a3c89bfc50
@@@ -2009,9 -2009,8 +2009,8 @@@ static void musb_pm_runtime_check_sessi
                        schedule_delayed_work(&musb->irq_work,
                                              msecs_to_jiffies(1000));
                        musb->quirk_retries--;
-                       break;
                }
-               fallthrough;
+               break;
        case MUSB_QUIRK_B_INVALID_VBUS_91:
                if (musb->quirk_retries && !musb->flush_irq_work) {
                        musb_dbg(musb,
                        dev_err(musb->controller, "Could not enable: %i\n",
                                error);
                musb->quirk_retries = 3;
 +
 +              /*
 +               * We can get a spurious MUSB_INTR_SESSREQ interrupt on start-up
 +               * in B-peripheral mode with nothing connected and the session
 +               * bit clears silently. Check status again in 3 seconds.
 +               */
 +              if (devctl & MUSB_DEVCTL_BDEVICE)
 +                      schedule_delayed_work(&musb->irq_work,
 +                                            msecs_to_jiffies(3000));
        } else {
                musb_dbg(musb, "Allow PM with no session: %02x", devctl);
                pm_runtime_mark_last_busy(musb->controller);
diff --combined drivers/usb/typec/mux.c
index 664fb3513f480e5727f47104e71e99ff14c48036,77dabd306ba8d84e11250a2fb6fe24aa2d4a9d64..c8340de0ed495fea8c33b0ca73a14fe40676dedc
  #include "class.h"
  #include "mux.h"
  
 -static bool dev_name_ends_with(struct device *dev, const char *suffix)
 -{
 -      const char *name = dev_name(dev);
 -      const int name_len = strlen(name);
 -      const int suffix_len = strlen(suffix);
 -
 -      if (suffix_len > name_len)
 -              return false;
 -
 -      return strcmp(name + (name_len - suffix_len), suffix) == 0;
 -}
 -
  static int switch_fwnode_match(struct device *dev, const void *fwnode)
  {
 -      return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-switch");
 +      if (!is_typec_switch(dev))
 +              return 0;
 +
 +      return dev_fwnode(dev) == fwnode;
  }
  
  static void *typec_switch_match(struct fwnode_handle *fwnode, const char *id,
  {
        struct device *dev;
  
 +      /*
 +       * Device graph (OF graph) does not give any means to identify the
 +       * device type or the device class of the remote port parent that @fwnode
 +       * represents, so in order to identify the type or the class of @fwnode
 +       * an additional device property is needed. With typec switches the
 +       * property is named "orientation-switch" (@id). The value of the device
 +       * property is ignored.
 +       */
        if (id && !fwnode_property_present(fwnode, id))
                return NULL;
  
 +      /*
 +       * At this point we are sure that @fwnode is a typec switch in all
 +       * cases. If the switch hasn't yet been registered for some reason, the
 +       * function "defers probe" for now.
 +       */
        dev = class_find_device(&typec_mux_class, NULL, fwnode,
                                switch_fwnode_match);
  
@@@ -94,7 -90,7 +94,7 @@@ static void typec_switch_release(struc
        kfree(to_typec_switch(dev));
  }
  
 -static const struct device_type typec_switch_dev_type = {
 +const struct device_type typec_switch_dev_type = {
        .name = "orientation_switch",
        .release = typec_switch_release,
  };
@@@ -184,10 -180,7 +184,10 @@@ EXPORT_SYMBOL_GPL(typec_switch_get_drvd
  
  static int mux_fwnode_match(struct device *dev, const void *fwnode)
  {
 -      return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-mux");
 +      if (!is_typec_mux(dev))
 +              return 0;
 +
 +      return dev_fwnode(dev) == fwnode;
  }
  
  static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id,
@@@ -246,7 -239,7 +246,7 @@@ find_mux
        dev = class_find_device(&typec_mux_class, NULL, fwnode,
                                mux_fwnode_match);
  
-       return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
+       return dev ? to_typec_mux(dev) : ERR_PTR(-EPROBE_DEFER);
  }
  
  /**
@@@ -302,7 -295,7 +302,7 @@@ static void typec_mux_release(struct de
        kfree(to_typec_mux(dev));
  }
  
 -static const struct device_type typec_mux_dev_type = {
 +const struct device_type typec_mux_dev_type = {
        .name = "mode_switch",
        .release = typec_mux_release,
  };
index dc8689db01000e844706aa7d8ac29e5c664538b4,ffa8aa12d5f116980f476b309ac6c8d40c566cc9..2cdd22130834e3813ac9fc31e38e1f00be6693cc
@@@ -83,6 -83,8 +83,6 @@@ enum 
  /*
   * Input Output Manager (IOM) PORT STATUS
   */
 -#define IOM_PORT_STATUS_OFFSET                                0x560
 -
  #define IOM_PORT_STATUS_ACTIVITY_TYPE_MASK            GENMASK(9, 6)
  #define IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT           6
  #define IOM_PORT_STATUS_ACTIVITY_TYPE_USB             0x03
@@@ -142,7 -144,6 +142,7 @@@ struct pmc_usb 
        struct pmc_usb_port *port;
        struct acpi_device *iom_adev;
        void __iomem *iom_base;
 +      u32 iom_port_status_offset;
  };
  
  static void update_port_status(struct pmc_usb_port *port)
        /* SoC expects the USB Type-C port numbers to start with 0 */
        port_num = port->usb3_port - 1;
  
 -      port->iom_status = readl(port->pmc->iom_base + IOM_PORT_STATUS_OFFSET +
 +      port->iom_status = readl(port->pmc->iom_base +
 +                               port->pmc->iom_port_status_offset +
                                 port_num * sizeof(u32));
  }
  
@@@ -559,32 -559,14 +559,32 @@@ static int is_memory(struct acpi_resour
        return !acpi_dev_resource_memory(res, &r);
  }
  
 +/* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */
 +static const struct acpi_device_id iom_acpi_ids[] = {
 +      /* TigerLake */
 +      { "INTC1072", 0x560, },
 +
 +      /* AlderLake */
 +      { "INTC1079", 0x160, },
 +      {}
 +};
 +
  static int pmc_usb_probe_iom(struct pmc_usb *pmc)
  {
        struct list_head resource_list;
        struct resource_entry *rentry;
 -      struct acpi_device *adev;
 +      static const struct acpi_device_id *dev_id;
 +      struct acpi_device *adev = NULL;
        int ret;
  
 -      adev = acpi_dev_get_first_match_dev("INTC1072", NULL, -1);
 +      for (dev_id = &iom_acpi_ids[0]; dev_id->id[0]; dev_id++) {
 +              if (acpi_dev_present(dev_id->id, NULL, -1)) {
 +                      pmc->iom_port_status_offset = (u32)dev_id->driver_data;
 +                      adev = acpi_dev_get_first_match_dev(dev_id->id, NULL, -1);
 +                      break;
 +              }
 +      }
 +
        if (!adev)
                return -ENODEV;
  
        acpi_dev_free_resource_list(&resource_list);
  
        if (!pmc->iom_base) {
-               put_device(&adev->dev);
+               acpi_dev_put(adev);
                return -ENOMEM;
        }
  
+       if (IS_ERR(pmc->iom_base)) {
+               acpi_dev_put(adev);
+               return PTR_ERR(pmc->iom_base);
+       }
        pmc->iom_adev = adev;
  
        return 0;
@@@ -654,8 -641,10 +659,10 @@@ static int pmc_usb_probe(struct platfor
                        break;
  
                ret = pmc_usb_register_port(pmc, i, fwnode);
-               if (ret)
+               if (ret) {
+                       fwnode_handle_put(fwnode);
                        goto err_remove_ports;
+               }
        }
  
        platform_set_drvdata(pdev, pmc);
@@@ -669,7 -658,7 +676,7 @@@ err_remove_ports
                usb_role_switch_unregister(pmc->port[i].usb_sw);
        }
  
-       put_device(&pmc->iom_adev->dev);
+       acpi_dev_put(pmc->iom_adev);
  
        return ret;
  }
@@@ -685,7 -674,7 +692,7 @@@ static int pmc_usb_remove(struct platfo
                usb_role_switch_unregister(pmc->port[i].usb_sw);
        }
  
-       put_device(&pmc->iom_adev->dev);
+       acpi_dev_put(pmc->iom_adev);
  
        return 0;
  }
index 0db685d5d9c01b1bbdd1af72554dbf316c12c55a,63470cf7f4cd9796e3c550382bb8d469364552ea..197556038ba4d3def538a7a3c410a6412bb1e427
@@@ -401,6 -401,8 +401,8 @@@ struct tcpm_port 
        unsigned int nr_src_pdo;
        u32 snk_pdo[PDO_MAX_OBJECTS];
        unsigned int nr_snk_pdo;
+       u32 snk_vdo_v1[VDO_MAX_OBJECTS];
+       unsigned int nr_snk_vdo_v1;
        u32 snk_vdo[VDO_MAX_OBJECTS];
        unsigned int nr_snk_vdo;
  
@@@ -774,34 -776,6 +776,34 @@@ static void tcpm_set_cc(struct tcpm_por
        port->tcpc->set_cc(port->tcpc, cc);
  }
  
 +static int tcpm_enable_auto_vbus_discharge(struct tcpm_port *port, bool enable)
 +{
 +      int ret = 0;
 +
 +      if (port->tcpc->enable_auto_vbus_discharge) {
 +              ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, enable);
 +              tcpm_log_force(port, "%s vbus discharge ret:%d", enable ? "enable" : "disable",
 +                             ret);
 +              if (!ret)
 +                      port->auto_vbus_discharge_enabled = enable;
 +      }
 +
 +      return ret;
 +}
 +
 +static void tcpm_apply_rc(struct tcpm_port *port)
 +{
 +      /*
 +       * TCPCI: Move to APPLY_RC state to prevent disconnect during PR_SWAP
 +       * when Vbus auto discharge on disconnect is enabled.
 +       */
 +      if (port->tcpc->enable_auto_vbus_discharge && port->tcpc->apply_rc) {
 +              tcpm_log(port, "Apply_RC");
 +              port->tcpc->apply_rc(port->tcpc, port->cc_req, port->polarity);
 +              tcpm_enable_auto_vbus_discharge(port, false);
 +      }
 +}
 +
  /*
   * Determine RP value to set based on maximum current supported
   * by a port if configured as source.
@@@ -1575,42 -1549,45 +1577,45 @@@ static int tcpm_pd_svdm(struct tcpm_por
                        if (PD_VDO_VID(p[0]) != USB_SID_PD)
                                break;
  
-                       if (PD_VDO_SVDM_VER(p[0]) < svdm_version)
+                       if (PD_VDO_SVDM_VER(p[0]) < svdm_version) {
                                typec_partner_set_svdm_version(port->partner,
                                                               PD_VDO_SVDM_VER(p[0]));
+                               svdm_version = PD_VDO_SVDM_VER(p[0]);
+                       }
  
-                       tcpm_ams_start(port, DISCOVER_IDENTITY);
-                       /* 6.4.4.3.1: Only respond as UFP (device) */
-                       if (port->data_role == TYPEC_DEVICE &&
+                       port->ams = DISCOVER_IDENTITY;
+                       /*
+                        * PD2.0 Spec 6.10.3: respond with NAK as DFP (data host)
+                        * PD3.1 Spec 6.4.4.2.5.1: respond with NAK if "invalid field" or
+                        * "wrong configuation" or "Unrecognized"
+                        */
+                       if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) &&
                            port->nr_snk_vdo) {
-                               /*
-                                * Product Type DFP and Connector Type are not defined in SVDM
-                                * version 1.0 and shall be set to zero.
-                                */
-                               if (typec_get_negotiated_svdm_version(typec) < SVDM_VER_2_0)
-                                       response[1] = port->snk_vdo[0] & ~IDH_DFP_MASK
-                                                     & ~IDH_CONN_MASK;
-                               else
-                                       response[1] = port->snk_vdo[0];
-                               for (i = 1; i <  port->nr_snk_vdo; i++)
-                                       response[i + 1] = port->snk_vdo[i];
-                               rlen = port->nr_snk_vdo + 1;
+                               if (svdm_version < SVDM_VER_2_0) {
+                                       for (i = 0; i < port->nr_snk_vdo_v1; i++)
+                                               response[i + 1] = port->snk_vdo_v1[i];
+                                       rlen = port->nr_snk_vdo_v1 + 1;
+                               } else {
+                                       for (i = 0; i < port->nr_snk_vdo; i++)
+                                               response[i + 1] = port->snk_vdo[i];
+                                       rlen = port->nr_snk_vdo + 1;
+                               }
                        }
                        break;
                case CMD_DISCOVER_SVID:
-                       tcpm_ams_start(port, DISCOVER_SVIDS);
+                       port->ams = DISCOVER_SVIDS;
                        break;
                case CMD_DISCOVER_MODES:
-                       tcpm_ams_start(port, DISCOVER_MODES);
+                       port->ams = DISCOVER_MODES;
                        break;
                case CMD_ENTER_MODE:
-                       tcpm_ams_start(port, DFP_TO_UFP_ENTER_MODE);
+                       port->ams = DFP_TO_UFP_ENTER_MODE;
                        break;
                case CMD_EXIT_MODE:
-                       tcpm_ams_start(port, DFP_TO_UFP_EXIT_MODE);
+                       port->ams = DFP_TO_UFP_EXIT_MODE;
                        break;
                case CMD_ATTENTION:
-                       tcpm_ams_start(port, ATTENTION);
                        /* Attention command does not have response */
                        *adev_action = ADEV_ATTENTION;
                        return 0;
@@@ -1965,6 -1942,9 +1970,9 @@@ static void vdm_run_state_machine(struc
                        tcpm_log(port, "VDM Tx error, retry");
                        port->vdm_retries++;
                        port->vdm_state = VDM_STATE_READY;
+                       if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMDT(vdo_hdr) == CMDT_INIT)
+                               tcpm_ams_finish(port);
+               } else {
                        tcpm_ams_finish(port);
                }
                break;
@@@ -2211,20 -2191,25 +2219,25 @@@ static void tcpm_handle_alert(struct tc
  
        if (!type) {
                tcpm_log(port, "Alert message received with no type");
+               tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
                return;
        }
  
        /* Just handling non-battery alerts for now */
        if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) {
-               switch (port->state) {
-               case SRC_READY:
-               case SNK_READY:
+               if (port->pwr_role == TYPEC_SOURCE) {
+                       port->upcoming_state = GET_STATUS_SEND;
+                       tcpm_ams_start(port, GETTING_SOURCE_SINK_STATUS);
+               } else {
+                       /*
+                        * Do not check SinkTxOk here in case the Source doesn't set its Rp to
+                        * SinkTxOk in time.
+                        */
+                       port->ams = GETTING_SOURCE_SINK_STATUS;
                        tcpm_set_state(port, GET_STATUS_SEND, 0);
-                       break;
-               default:
-                       tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
-                       break;
                }
+       } else {
+               tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
        }
  }
  
@@@ -2468,7 -2453,12 +2481,12 @@@ static void tcpm_pd_data_request(struc
                tcpm_pd_handle_state(port, BIST_RX, BIST, 0);
                break;
        case PD_DATA_ALERT:
-               tcpm_handle_alert(port, msg->payload, cnt);
+               if (port->state != SRC_READY && port->state != SNK_READY)
+                       tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
+                                            SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
+                                            NONE_AMS, 0);
+               else
+                       tcpm_handle_alert(port, msg->payload, cnt);
                break;
        case PD_DATA_BATT_STATUS:
        case PD_DATA_GET_COUNTRY_INFO:
@@@ -2792,24 -2782,16 +2810,16 @@@ static void tcpm_pd_ext_msg_request(str
  
        switch (type) {
        case PD_EXT_STATUS:
-               /*
-                * If PPS related events raised then get PPS status to clear
-                * (see USB PD 3.0 Spec, 6.5.2.4)
-                */
-               if (msg->ext_msg.data[USB_PD_EXT_SDB_EVENT_FLAGS] &
-                   USB_PD_EXT_SDB_PPS_EVENTS)
-                       tcpm_pd_handle_state(port, GET_PPS_STATUS_SEND,
-                                            GETTING_SOURCE_SINK_STATUS, 0);
-               else
-                       tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
-               break;
        case PD_EXT_PPS_STATUS:
-               /*
-                * For now the PPS status message is used to clear events
-                * and nothing more.
-                */
-               tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
+               if (port->ams == GETTING_SOURCE_SINK_STATUS) {
+                       tcpm_ams_finish(port);
+                       tcpm_set_state(port, ready_state(port), 0);
+               } else {
+                       /* unexpected Status or PPS_Status Message */
+                       tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
+                                            SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
+                                            NONE_AMS, 0);
+               }
                break;
        case PD_EXT_SOURCE_CAP_EXT:
        case PD_EXT_GET_BATT_CAP:
@@@ -3533,7 -3515,12 +3543,7 @@@ static int tcpm_src_attach(struct tcpm_
        if (ret < 0)
                return ret;
  
 -      if (port->tcpc->enable_auto_vbus_discharge) {
 -              ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true);
 -              tcpm_log_force(port, "enable vbus discharge ret:%d", ret);
 -              if (!ret)
 -                      port->auto_vbus_discharge_enabled = true;
 -      }
 +      tcpm_enable_auto_vbus_discharge(port, true);
  
        ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port));
        if (ret < 0)
@@@ -3610,7 -3597,14 +3620,7 @@@ static void tcpm_set_partner_usb_comm_c
  
  static void tcpm_reset_port(struct tcpm_port *port)
  {
 -      int ret;
 -
 -      if (port->tcpc->enable_auto_vbus_discharge) {
 -              ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, false);
 -              tcpm_log_force(port, "Disable vbus discharge ret:%d", ret);
 -              if (!ret)
 -                      port->auto_vbus_discharge_enabled = false;
 -      }
 +      tcpm_enable_auto_vbus_discharge(port, false);
        port->in_ams = false;
        port->ams = NONE_AMS;
        port->vdm_sm_running = false;
@@@ -3678,7 -3672,13 +3688,7 @@@ static int tcpm_snk_attach(struct tcpm_
        if (ret < 0)
                return ret;
  
 -      if (port->tcpc->enable_auto_vbus_discharge) {
 -              tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V);
 -              ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true);
 -              tcpm_log_force(port, "enable vbus discharge ret:%d", ret);
 -              if (!ret)
 -                      port->auto_vbus_discharge_enabled = true;
 -      }
 +      tcpm_enable_auto_vbus_discharge(port, true);
  
        ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port));
        if (ret < 0)
@@@ -4515,7 -4515,6 +4525,7 @@@ static void run_state_machine(struct tc
                tcpm_set_state(port, ready_state(port), 0);
                break;
        case PR_SWAP_START:
 +              tcpm_apply_rc(port);
                if (port->pwr_role == TYPEC_SOURCE)
                        tcpm_set_state(port, PR_SWAP_SRC_SNK_TRANSITION_OFF,
                                       PD_T_SRC_TRANSITION);
                tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON_PRS);
                break;
        case PR_SWAP_SRC_SNK_SINK_ON:
 +              tcpm_enable_auto_vbus_discharge(port, true);
                /* Set the vbus disconnect threshold for implicit contract */
                tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V);
                tcpm_set_state(port, SNK_STARTUP, 0);
                               PD_T_PS_SOURCE_OFF);
                break;
        case PR_SWAP_SNK_SRC_SOURCE_ON:
 +              tcpm_enable_auto_vbus_discharge(port, true);
                tcpm_set_cc(port, tcpm_rp_cc(port));
                tcpm_set_vbus(port, true);
                /*
@@@ -5201,9 -5198,6 +5211,9 @@@ static void _tcpm_pd_vbus_vsafe0v(struc
                                tcpm_set_state(port, SNK_UNATTACHED, 0);
                }
                break;
 +      case PR_SWAP_SNK_SRC_SINK_OFF:
 +              /* Do nothing, vsafe0v is expected during transition */
 +              break;
        default:
                if (port->pwr_role == TYPEC_SINK && port->auto_vbus_discharge_enabled)
                        tcpm_set_state(port, SNK_UNATTACHED, 0);
@@@ -5963,6 -5957,22 +5973,22 @@@ sink
                        return ret;
        }
  
+       /* If sink-vdos is found, sink-vdos-v1 is expected for backward compatibility. */
+       if (port->nr_snk_vdo) {
+               ret = fwnode_property_count_u32(fwnode, "sink-vdos-v1");
+               if (ret < 0)
+                       return ret;
+               else if (ret == 0)
+                       return -ENODATA;
+               port->nr_snk_vdo_v1 = min(ret, VDO_MAX_OBJECTS);
+               ret = fwnode_property_read_u32_array(fwnode, "sink-vdos-v1",
+                                                    port->snk_vdo_v1,
+                                                    port->nr_snk_vdo_v1);
+               if (ret < 0)
+                       return ret;
+       }
        return 0;
  }
  
@@@ -6328,6 -6338,11 +6354,11 @@@ void tcpm_unregister_port(struct tcpm_p
  {
        int i;
  
+       hrtimer_cancel(&port->send_discover_timer);
+       hrtimer_cancel(&port->enable_frs_timer);
+       hrtimer_cancel(&port->vdm_state_machine_timer);
+       hrtimer_cancel(&port->state_machine_timer);
        tcpm_reset_port(port);
        for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++)
                typec_unregister_altmode(port->port_altmode[i]);
index 8072e222eb998170242a8df43201fa6933a46c33,5d125339687a34a61b5017b67a756d8ead90ffbc..20917d85d6f4c3f0824cf9f944e153225cdc8e50
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/**
 +/*
   * typec_wcove.c - WhiskeyCove PMIC USB Type-C PHY driver
   *
   * Copyright (C) 2017 Intel Corporation
@@@ -378,7 -378,7 +378,7 @@@ static int wcove_pd_transmit(struct tcp
                const u8 *data = (void *)msg;
                int i;
  
-               for (i = 0; i < pd_header_cnt(msg->header) * 4 + 2; i++) {
+               for (i = 0; i < pd_header_cnt_le(msg->header) * 4 + 2; i++) {
                        ret = regmap_write(wcove->regmap, USBC_TX_DATA + i,
                                           data[i]);
                        if (ret)
index 48ca1134fdd0b224350d17bc42a1acb6cb2f5da1,b7d104c80d8570fa12113a746c80fab98f42a855..5ef5bd0e87cf237d03554a6733eee59c74d1a82f
@@@ -1219,7 -1219,7 +1219,7 @@@ static int ucsi_init(struct ucsi *ucsi
                goto err_reset;
        }
  
 -      /* Allocate the connectors. Released in ucsi_unregister_ppm() */
 +      /* Allocate the connectors. Released in ucsi_unregister() */
        ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1,
                                  sizeof(*ucsi->connector), GFP_KERNEL);
        if (!ucsi->connector) {
@@@ -1253,6 -1253,7 +1253,7 @@@ err_unregister
        }
  
  err_reset:
+       memset(&ucsi->cap, 0, sizeof(ucsi->cap));
        ucsi_reset_ppm(ucsi);
  err:
        return ret;
@@@ -1279,7 -1280,7 +1280,7 @@@ void *ucsi_get_drvdata(struct ucsi *ucs
  EXPORT_SYMBOL_GPL(ucsi_get_drvdata);
  
  /**
 - * ucsi_get_drvdata - Assign private driver data pointer
 + * ucsi_set_drvdata - Assign private driver data pointer
   * @ucsi: UCSI interface
   * @data: Private data pointer
   */
This page took 0.156389 seconds and 4 git commands to generate.