Merge tag 'v4.9.201' into khadas-vims-4.9.y
authorNick Xie <nick@khadas.com>
Fri, 15 Nov 2019 14:16:43 +0000 (22:16 +0800)
committerNick Xie <nick@khadas.com>
Fri, 15 Nov 2019 14:16:43 +0000 (22:16 +0800)
This is the 4.9.201 stable release

 Conflicts:
drivers/usb/gadget/configfs.c

1  2 
Makefile
drivers/nfc/fdp/i2c.c
drivers/usb/dwc3/core.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
fs/fs-writeback.c
include/linux/mm.h
include/linux/mm_types.h
include/net/sock.h
mm/filemap.c

diff --cc Makefile
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -108,12 -60,8 +108,14 @@@ struct gadget_info 
        bool use_os_desc;
        char b_vendor_code;
        char qw_sign[OS_STRING_QW_SIGN_LEN];
 +#ifdef CONFIG_USB_CONFIGFS_UEVENT
 +      bool connected;
 +      bool sw_connected;
 +      struct work_struct work;
 +      struct device *dev;
 +#endif
+       spinlock_t spinlock;
+       bool unbind;
  };
  
  static inline struct gadget_info *to_gadget_info(struct config_item *item)
@@@ -1295,11 -1243,9 +1297,12 @@@ static int configfs_composite_bind(stru
        int                             ret;
  
        /* the gi->lock is hold by the caller */
+       gi->unbind = 0;
        cdev->gadget = gadget;
        set_gadget_data(gadget, cdev);
 +#ifdef CONFIG_AMLOGIC_USB
 +      wakeup_source_init(&Gadget_Lock.wakesrc, "gadget-connect");
 +#endif
        ret = composite_dev_prepare(composite, cdev);
        if (ret)
                return ret;
@@@ -1501,100 -1391,113 +1508,193 @@@ static void configfs_composite_unbind(s
        purge_configs_funcs(gi);
        composite_dev_cleanup(cdev);
        usb_ep_autoconfig_reset(cdev->gadget);
 +#ifdef CONFIG_AMLOGIC_USB
 +      wakeup_source_trash(&Gadget_Lock.wakesrc);
 +#endif
+       spin_lock_irqsave(&gi->spinlock, flags);
        cdev->gadget = NULL;
        set_gadget_data(gadget, NULL);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+ }
+ static int configfs_composite_setup(struct usb_gadget *gadget,
+               const struct usb_ctrlrequest *ctrl)
+ {
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+       int ret;
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return 0;
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return 0;
+       }
+       ret = composite_setup(gadget, ctrl);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+       return ret;
+ }
+ static void configfs_composite_disconnect(struct usb_gadget *gadget)
+ {
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+       composite_disconnect(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+ }
+ static void configfs_composite_suspend(struct usb_gadget *gadget)
+ {
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+       composite_suspend(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+ }
+ static void configfs_composite_resume(struct usb_gadget *gadget)
+ {
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+       composite_resume(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
  }
  
 +#ifdef CONFIG_USB_CONFIGFS_UEVENT
 +static int android_setup(struct usb_gadget *gadget,
 +                      const struct usb_ctrlrequest *c)
 +{
 +      struct usb_composite_dev *cdev = get_gadget_data(gadget);
 +      unsigned long flags;
 +      struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
 +      int value = -EOPNOTSUPP;
 +      struct usb_function_instance *fi;
 +
 +      spin_lock_irqsave(&cdev->lock, flags);
 +      if (!gi->connected) {
 +              gi->connected = 1;
 +              schedule_work(&gi->work);
 +      }
 +      spin_unlock_irqrestore(&cdev->lock, flags);
 +      list_for_each_entry(fi, &gi->available_func, cfs_list) {
 +              if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
 +                      value = fi->f->setup(fi->f, c);
 +                      if (value >= 0)
 +                              break;
 +              }
 +      }
 +
 +#ifdef CONFIG_USB_CONFIGFS_F_ACC
 +      if (value < 0)
 +              value = acc_ctrlrequest(cdev, c);
 +#endif
 +
 +      if (value < 0)
 +              value = composite_setup(gadget, c);
 +
 +      spin_lock_irqsave(&cdev->lock, flags);
 +      if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
 +                                              cdev->config) {
 +              schedule_work(&gi->work);
 +      }
 +      spin_unlock_irqrestore(&cdev->lock, flags);
 +
 +      return value;
 +}
 +
 +static void android_disconnect(struct usb_gadget *gadget)
 +{
 +      struct usb_composite_dev        *cdev = get_gadget_data(gadget);
 +      struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
 +
 +      /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
 +       * to set the gadget driver to NULL in the udc driver and this drivers
 +       * gadget disconnect fn which likely checks for the gadget driver to
 +       * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
 +       * is called before the gadget driver is set to NULL and the udc driver
 +       * calls disconnect fn which results in cdev being a null ptr.
 +       */
 +      if (cdev == NULL) {
 +              WARN(1, "%s: gadget driver already disconnected\n", __func__);
 +              return;
 +      }
 +
 +      /* accessory HID support can be active while the
 +              accessory function is not actually enabled,
 +              so we need to inform it when we are disconnected.
 +      */
 +
 +#ifdef CONFIG_USB_CONFIGFS_F_ACC
 +      acc_disconnect();
 +#endif
 +      gi->connected = 0;
 +      schedule_work(&gi->work);
 +      composite_disconnect(gadget);
 +}
 +#endif
 +
  static const struct usb_gadget_driver configfs_driver_template = {
        .bind           = configfs_composite_bind,
        .unbind         = configfs_composite_unbind,
 -
 +#ifdef CONFIG_USB_CONFIGFS_UEVENT
 +      .setup          = android_setup,
 +      .reset          = android_disconnect,
 +      .disconnect     = android_disconnect,
 +#else
-       .setup          = composite_setup,
-       .reset          = composite_disconnect,
-       .disconnect     = composite_disconnect,
+       .setup          = configfs_composite_setup,
+       .reset          = configfs_composite_disconnect,
+       .disconnect     = configfs_composite_disconnect,
 -
 +#endif
-       .suspend        = composite_suspend,
-       .resume         = composite_resume,
+       .suspend        = configfs_composite_suspend,
+       .resume         = configfs_composite_resume,
  
        .max_speed      = USB_SPEED_SUPER,
        .driver = {
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc mm/filemap.c
Simple merge