Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
authorHuang, Tao <huangtao@rock-chips.com>
Sat, 6 May 2017 06:23:00 +0000 (14:23 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Sat, 6 May 2017 06:23:00 +0000 (14:23 +0800)
* linux-linaro-lsk-v4.4-android: (521 commits)
  Linux 4.4.66
  ftrace/x86: Fix triple fault with graph tracing and suspend-to-ram
  ARCv2: save r30 on kernel entry as gcc uses it for code-gen
  nfsd: check for oversized NFSv2/v3 arguments
  Input: i8042 - add Clevo P650RS to the i8042 reset list
  p9_client_readdir() fix
  MIPS: Avoid BUG warning in arch_check_elf
  MIPS: KGDB: Use kernel context for sleeping threads
  ALSA: seq: Don't break snd_use_lock_sync() loop by timeout
  ALSA: firewire-lib: fix inappropriate assignment between signed/unsigned type
  ipv6: check raw payload size correctly in ioctl
  ipv6: check skb->protocol before lookup for nexthop
  macvlan: Fix device ref leak when purging bc_queue
  ip6mr: fix notification device destruction
  netpoll: Check for skb->queue_mapping
  net: ipv6: RTF_PCPU should not be settable from userspace
  dp83640: don't recieve time stamps twice
  tcp: clear saved_syn in tcp_disconnect()
  sctp: listen on the sock only when it's state is listening or closed
  net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given
  ...

Conflicts:
drivers/usb/dwc3/gadget.c
include/linux/usb/quirks.h

Change-Id: I490f766b9a530b10da3107e20709538e4536a99d

20 files changed:
1  2 
Makefile
arch/arm64/Makefile
drivers/base/power/opp/core.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_interactive.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/mmc/core/mmc.c
drivers/mmc/host/sdhci.c
drivers/pci/pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_accessory.c
drivers/usb/gadget/function/f_mtp.c
fs/proc/task_mmu.c
include/linux/mmc/card.h
include/linux/mmc/mmc.h
include/linux/usb/quirks.h
kernel/sched/fair.c

diff --combined Makefile
index bafc3d9b22d3bdc944b8b160808bd6cc2a852d0c,583cb0f989c10df5ec49dcfe9778ea58e2479d5d..facf96b2ad6b3c2d14ae264c6e8245a2a48f0fc7
+++ b/Makefile
@@@ -1,6 -1,6 +1,6 @@@
  VERSION = 4
  PATCHLEVEL = 4
- SUBLEVEL = 55
+ SUBLEVEL = 66
  EXTRAVERSION =
  NAME = Blurry Fish Butt
  
@@@ -146,7 -146,7 +146,7 @@@ PHONY += $(MAKECMDGOALS) sub-mak
  $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
        @:
  
- sub-make: FORCE
+ sub-make:
        $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
        -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))
  
@@@ -252,18 -252,7 +252,18 @@@ SUBARCH := $(shell uname -m | sed -e s/
  # "make" in the configured kernel build directory always uses that.
  # Default value for CROSS_COMPILE is not to prefix executables
  # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 +ARCH          ?= arm64
  ARCH          ?= $(SUBARCH)
 +ifeq ($(ARCH),arm64)
 +ifneq ($(wildcard $(srctree)/../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9),)
 +CROSS_COMPILE ?= $(srctree)/../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
 +endif
 +endif
 +ifeq ($(ARCH),arm)
 +ifneq ($(wildcard $(srctree)/../prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9),)
 +CROSS_COMPILE ?= $(srctree)/../prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
 +endif
 +endif
  CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
  
  # Architecture as present in compile.h
@@@ -372,12 -361,6 +372,12 @@@ PERL             = per
  PYTHON                = python
  CHECK         = sparse
  
 +# Use the wrapper for the compiler. This wrapper scans for new
 +# warnings and causes the build to stop upon encountering them.
 +ifneq ($(wildcard $(srctree)/scripts/gcc-wrapper.py),)
 +CC            = $(srctree)/scripts/gcc-wrapper.py $(CROSS_COMPILE)gcc
 +endif
 +
  CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
                  -Wbitwise -Wno-return-void $(CF)
  CFLAGS_MODULE   =
@@@ -809,11 -792,6 +809,11 @@@ KBUILD_ARFLAGS := $(call ar-option,D
  ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y)
        KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
        KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
 +else ifneq ($(findstring aarch64-linux-android, $(CROSS_COMPILE)),)
 +# It seems than android gcc can't pass gcc-goto.sh check, but asm goto work.
 +# So let's active it.
 +      KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
 +      KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
  endif
  
  include scripts/Makefile.kasan
@@@ -1022,7 -1000,7 +1022,7 @@@ prepare1: prepare2 $(version_h) include
  
  archprepare: archheaders archscripts prepare1 scripts_basic
  
- prepare0: archprepare FORCE
+ prepare0: archprepare
        $(Q)$(MAKE) $(build)=.
  
  # All the preparing..
@@@ -1067,7 -1045,7 +1067,7 @@@ INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib
  export INSTALL_FW_PATH
  
  PHONY += firmware_install
- firmware_install: FORCE
+ firmware_install:
        @mkdir -p $(objtree)/firmware
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install
  
@@@ -1087,7 -1065,7 +1087,7 @@@ PHONY += archscript
  archscripts:
  
  PHONY += __headers
- __headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE
+ __headers: $(version_h) scripts_basic asm-generic archheaders archscripts
        $(Q)$(MAKE) $(build)=scripts build_unifdef
  
  PHONY += headers_install_all
diff --combined arch/arm64/Makefile
index 85de2131537ecbdf73985288af03dfb2906d4fad,f1d8a05727cfb46c5efdad263cf877acd8f13a1d..897ffdeadbe892c9ff9987b6fb12aa6debcb1f40
@@@ -61,7 -61,9 +61,9 @@@ head-y                := arch/arm64/kernel/head.
  
  # The byte offset of the kernel image in RAM from the start of RAM.
  ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
- TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}')
+ TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
+                int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
+                rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
  else
  TEXT_OFFSET := 0x00080000
  endif
@@@ -85,7 -87,7 +87,7 @@@ core-$(CONFIG_EFI_STUB) += $(objtree)/d
  
  # Default target when executing plain make
  ifeq ($(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),y)
- KBUILD_IMAGE  := Image.gz-dtb
+ KBUILD_IMAGE  := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_KERNEL_IMAGE_NAME))
  else
  KBUILD_IMAGE  := Image.gz
  endif
@@@ -128,6 -130,16 +130,16 @@@ archclean
        $(Q)$(MAKE) $(clean)=$(boot)
        $(Q)$(MAKE) $(clean)=$(boot)/dts
  
+ # We need to generate vdso-offsets.h before compiling certain files in kernel/.
+ # In order to do that, we should use the archprepare target, but we can't since
+ # asm-offsets.h is included in some files used to generate vdso-offsets.h, and
+ # asm-offsets.h is built in prepare0, for which archprepare is a dependency.
+ # Therefore we need to generate the header after prepare0 has been made, hence
+ # this hack.
+ prepare: vdso_prepare
+ vdso_prepare: prepare0
+       $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h
  define archhelp
    echo  '* Image.gz      - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
    echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
    echo  '                  (distribution) /sbin/installkernel or'
    echo  '                  install to $$(INSTALL_PATH) and run lilo'
  endef
 +
 +kernel.img: Image
 +      $(Q)$(srctree)/scripts/mkkrnlimg $(objtree)/arch/arm64/boot/Image $(objtree)/kernel.img >/dev/null
 +      @echo '  Image:  kernel.img is ready'
 +
 +LOGO := $(notdir $(wildcard $(srctree)/logo.bmp))
 +LOGO_KERNEL := $(notdir $(wildcard $(srctree)/logo_kernel.bmp))
 +%.img: rockchip/%.dtb kernel.img $(LOGO) $(LOGO_KERNEL)
 +      $(Q) if [ -f $(srctree)/$(LOGO) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO) $(objtree)/; fi
 +      $(Q) if [ -f $(srctree)/$(LOGO_KERNEL) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO_KERNEL) $(objtree)/; fi
 +      $(Q)$(srctree)/scripts/resource_tool $(objtree)/arch/arm64/boot/dts/rockchip/$*.dtb $(LOGO) $(LOGO_KERNEL)
 +      @echo '  Image:  resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready'
index f5be560858cba71c9cc566eecc31ca60bfda7f81,d8f4cc22856c924b1be7bf1aa97f175b6579c554..9d7bec3bbbcfe15ac7dd3e3bcd06795b3021deba
@@@ -259,9 -259,6 +259,6 @@@ unsigned long dev_pm_opp_get_max_volt_l
        reg = opp_table->regulator;
        if (IS_ERR(reg)) {
                /* Regulator may not be required for device */
-               if (reg)
-                       dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__,
-                               PTR_ERR(reg));
                rcu_read_unlock();
                return 0;
        }
@@@ -706,120 -703,6 +703,120 @@@ restore_voltage
  }
  EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate);
  
 +/**
 + * dev_pm_opp_check_initial_rate() - Configure new OPP based on initial rate
 + * @dev:       device for which we do this operation
 + *
 + * This configures the power-supplies and clock source to the levels specified
 + * by the OPP corresponding to the system initial rate.
 + *
 + * Locking: This function takes rcu_read_lock().
 + */
 +int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq)
 +{
 +      struct opp_table *opp_table;
 +      struct dev_pm_opp *opp;
 +      struct regulator *reg;
 +      struct clk *clk;
 +      unsigned long target_freq, old_freq;
 +      unsigned long u_volt, u_volt_min, u_volt_max;
 +      int old_volt;
 +      int ret;
 +
 +      rcu_read_lock();
 +
 +      opp_table = _find_opp_table(dev);
 +      if (IS_ERR(opp_table)) {
 +              dev_err(dev, "%s: device opp doesn't exist\n", __func__);
 +              rcu_read_unlock();
 +              return PTR_ERR(opp_table);
 +      }
 +
 +      clk = opp_table->clk;
 +      reg = opp_table->regulator;
 +      if (IS_ERR_OR_NULL(clk) || IS_ERR_OR_NULL(reg)) {
 +              dev_err(dev, "clk or regulater is unavailable\n");
 +              rcu_read_unlock();
 +              return -EINVAL;
 +      }
 +
 +      old_freq = clk_get_rate(clk);
 +      *cur_freq = old_freq;
 +      target_freq = old_freq;
 +
 +      opp = dev_pm_opp_find_freq_ceil(dev, &target_freq);
 +      if (IS_ERR(opp)) {
 +              opp = dev_pm_opp_find_freq_floor(dev, &target_freq);
 +              if (IS_ERR(opp)) {
 +                      dev_err(dev, "failed to find OPP for freq %lu\n",
 +                              target_freq);
 +                      rcu_read_unlock();
 +                      return PTR_ERR(opp);
 +              }
 +      }
 +
 +      u_volt = opp->u_volt;
 +      u_volt_min = opp->u_volt_min;
 +      u_volt_max = opp->u_volt_max;
 +
 +      rcu_read_unlock();
 +
 +      target_freq = clk_round_rate(clk, target_freq);
 +      old_volt = regulator_get_voltage(reg);
 +      if (old_volt <= 0) {
 +              dev_err(dev, "failed to get volt %d\n", old_volt);
 +              return -EINVAL;
 +      }
 +
 +      dev_dbg(dev, "%lu Hz %d uV --> %lu Hz %lu uV\n", old_freq, old_volt,
 +              target_freq, u_volt);
 +
 +      if (old_freq == target_freq && old_volt == u_volt)
 +              return 0;
 +
 +      if (old_freq == target_freq && old_volt != u_volt) {
 +              ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min,
 +                                     u_volt_max);
 +              if (ret) {
 +                      dev_err(dev, "failed to set volt %lu\n", u_volt);
 +                      return ret;
 +              }
 +              return 0;
 +      }
 +
 +      /* Scaling up? Scale voltage before frequency */
 +      if (target_freq > old_freq) {
 +              ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min,
 +                                     u_volt_max);
 +              if (ret) {
 +                      dev_err(dev, "failed to set volt %lu\n", u_volt);
 +                      return ret;
 +              }
 +      }
 +
 +      /* Change frequency */
 +      ret = clk_set_rate(clk, target_freq);
 +      if (ret) {
 +              dev_err(dev, "failed to set clock rate %lu\n", target_freq);
 +              return ret;
 +      }
 +
 +      *cur_freq = clk_get_rate(clk);
 +
 +      /* Scaling down? Scale voltage after frequency */
 +      if (target_freq < old_freq) {
 +              ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min,
 +                                     u_volt_max);
 +              if (ret) {
 +                      dev_err(dev, "failed to set volt %lu\n", u_volt);
 +                      return ret;
 +              }
 +      }
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(dev_pm_opp_check_initial_rate);
 +
  /* OPP-dev Helpers */
  static void _kfree_opp_dev_rcu(struct rcu_head *head)
  {
@@@ -958,6 -841,12 +955,6 @@@ static void _remove_opp_table(struct op
        if (!list_empty(&opp_table->opp_list))
                return;
  
 -      if (opp_table->supported_hw)
 -              return;
 -
 -      if (opp_table->prop_name)
 -              return;
 -
        if (!IS_ERR(opp_table->regulator))
                return;
  
index 0e94bec22807ec855a52a96ba3c0f75386841f5a,0ceb0a889ebf717f868480ca89da2069f49c41ff..9c62104c2112fd0ea30047d429ff02326ac30c52
@@@ -688,9 -688,11 +688,11 @@@ static ssize_t show_cpuinfo_cur_freq(st
                                        char *buf)
  {
        unsigned int cur_freq = __cpufreq_get(policy);
-       if (!cur_freq)
-               return sprintf(buf, "<unknown>");
-       return sprintf(buf, "%u\n", cur_freq);
+       if (cur_freq)
+               return sprintf(buf, "%u\n", cur_freq);
+       return sprintf(buf, "<unknown>\n");
  }
  
  /**
@@@ -1246,6 -1248,9 +1248,9 @@@ static int cpufreq_online(unsigned int 
                for_each_cpu(j, policy->related_cpus)
                        per_cpu(cpufreq_cpu_data, j) = policy;
                write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+       } else {
+               policy->min = policy->user_policy.min;
+               policy->max = policy->user_policy.max;
        }
  
        if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
                }
        }
  
 -      blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
 -                                   CPUFREQ_START, policy);
 -
        if (new_policy) {
                ret = cpufreq_add_dev_interface(policy);
                if (ret)
                write_unlock_irqrestore(&cpufreq_driver_lock, flags);
        }
  
 +      blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
 +                                   CPUFREQ_START, policy);
 +
        ret = cpufreq_init_policy(policy);
        if (ret) {
                pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n",
index 055e990a2f1db035cbbff273fccefe8c0dfd13c8,889c9b8b2237d5da4325d515e0f5f0ee41c249d3..beaae304d1e3f71ad33e05e8c92799b6be044337
@@@ -19,9 -19,6 +19,9 @@@
  #include <linux/cpu.h>
  #include <linux/cpumask.h>
  #include <linux/cpufreq.h>
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +#include <linux/input.h>
 +#endif
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/rwsem.h>
@@@ -109,14 -106,6 +109,14 @@@ struct cpufreq_interactive_tunables 
        int boostpulse_duration_val;
        /* End time of boost pulse in ktime converted to usecs */
        u64 boostpulse_endtime;
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +      /* Frequency to which a touch boost takes the cpus to */
 +      unsigned long touchboost_freq;
 +      /* Duration of a touchboost pulse in usecs */
 +      int touchboostpulse_duration_val;
 +      /* End time of touchboost pulse in ktime converted to usecs */
 +      u64 touchboostpulse_endtime;
 +#endif
        bool boosted;
        /*
         * Max additional time to wait in idle, beyond timer_rate, at speeds
@@@ -323,13 -312,13 +323,13 @@@ static u64 update_load(int cpu
                pcpu->policy->governor_data;
        u64 now;
        u64 now_idle;
-       unsigned int delta_idle;
-       unsigned int delta_time;
+       u64 delta_idle;
+       u64 delta_time;
        u64 active_time;
  
        now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
-       delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle);
-       delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp);
+       delta_idle = (now_idle - pcpu->time_in_idle);
+       delta_time = (now - pcpu->time_in_idle_timestamp);
  
        if (delta_time <= delta_idle)
                active_time = 0;
@@@ -394,12 -383,7 +394,12 @@@ static void cpufreq_interactive_timer(u
                                pcpu->policy->cur < tunables->hispeed_freq)
                        new_freq = tunables->hispeed_freq;
        }
 -
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +      if ((now < tunables->touchboostpulse_endtime) &&
 +          (new_freq < tunables->touchboost_freq)) {
 +              new_freq = tunables->touchboost_freq;
 +      }
 +#endif
        if (pcpu->policy->cur >= tunables->hispeed_freq &&
            new_freq > pcpu->policy->cur &&
            now - pcpu->pol_hispeed_val_time <
@@@ -1149,150 -1133,6 +1149,150 @@@ static struct notifier_block cpufreq_in
        .notifier_call = cpufreq_interactive_idle_notifier,
  };
  
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +static void cpufreq_interactive_input_event(struct input_handle *handle,
 +                                          unsigned int type,
 +                                          unsigned int code,
 +                                          int value)
 +{
 +      u64 now, endtime;
 +      int i;
 +      int anyboost = 0;
 +      unsigned long flags[2];
 +      struct cpufreq_interactive_cpuinfo *pcpu;
 +      struct cpufreq_interactive_tunables *tunables;
 +
 +      if ((type != EV_ABS) && (type != EV_KEY))
 +              return;
 +
 +      trace_cpufreq_interactive_boost("touch");
 +      spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);
 +
 +      now = ktime_to_us(ktime_get());
 +      for_each_online_cpu(i) {
 +              pcpu = &per_cpu(cpuinfo, i);
 +              if (!pcpu->policy)
 +                      continue;
 +
 +              if (have_governor_per_policy())
 +                      tunables = pcpu->policy->governor_data;
 +              else
 +                      tunables = common_tunables;
 +              if (!tunables)
 +                      continue;
 +
 +              endtime = now + tunables->touchboostpulse_duration_val;
 +              if (endtime < (tunables->touchboostpulse_endtime +
 +                             10 * USEC_PER_MSEC))
 +                      continue;
 +              tunables->touchboostpulse_endtime = endtime;
 +
 +              spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
 +              if (pcpu->target_freq < tunables->touchboost_freq) {
 +                      pcpu->target_freq = tunables->touchboost_freq;
 +                      cpumask_set_cpu(i, &speedchange_cpumask);
 +                      pcpu->loc_hispeed_val_time =
 +                                      ktime_to_us(ktime_get());
 +                      anyboost = 1;
 +              }
 +
 +              pcpu->floor_freq = tunables->touchboost_freq;
 +              pcpu->loc_floor_val_time = ktime_to_us(ktime_get());
 +
 +              spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]);
 +      }
 +
 +      spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);
 +
 +      if (anyboost)
 +              wake_up_process(speedchange_task);
 +}
 +
 +static int cpufreq_interactive_input_connect(struct input_handler *handler,
 +                                           struct input_dev *dev,
 +                                           const struct input_device_id *id)
 +{
 +      struct input_handle *handle;
 +      int error;
 +
 +      handle = kzalloc(sizeof(*handle), GFP_KERNEL);
 +      if (!handle)
 +              return -ENOMEM;
 +
 +      handle->dev = dev;
 +      handle->handler = handler;
 +      handle->name = "cpufreq";
 +
 +      error = input_register_handle(handle);
 +      if (error)
 +              goto err2;
 +
 +      error = input_open_device(handle);
 +      if (error)
 +              goto err1;
 +
 +      return 0;
 +err1:
 +      input_unregister_handle(handle);
 +err2:
 +      kfree(handle);
 +      return error;
 +}
 +
 +static void cpufreq_interactive_input_disconnect(struct input_handle *handle)
 +{
 +      input_close_device(handle);
 +      input_unregister_handle(handle);
 +      kfree(handle);
 +}
 +
 +static const struct input_device_id cpufreq_interactive_ids[] = {
 +      {
 +              .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 +                      INPUT_DEVICE_ID_MATCH_ABSBIT,
 +              .evbit = { BIT_MASK(EV_ABS) },
 +              .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
 +                      BIT_MASK(ABS_MT_POSITION_X) |
 +                      BIT_MASK(ABS_MT_POSITION_Y) },
 +      },
 +      {
 +              .flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
 +                      INPUT_DEVICE_ID_MATCH_ABSBIT,
 +              .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
 +              .absbit = { [BIT_WORD(ABS_X)] =
 +                      BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
 +      },
 +      {
 +              .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
 +              .evbit = { BIT_MASK(EV_KEY) },
 +      },
 +      { },
 +};
 +
 +static struct input_handler cpufreq_interactive_input_handler = {
 +      .event          = cpufreq_interactive_input_event,
 +      .connect        = cpufreq_interactive_input_connect,
 +      .disconnect     = cpufreq_interactive_input_disconnect,
 +      .name           = "cpufreq_interactive",
 +      .id_table       = cpufreq_interactive_ids,
 +};
 +
 +static void rockchip_cpufreq_policy_init(struct cpufreq_policy *policy)
 +{
 +      struct cpufreq_interactive_tunables *tunables = policy->governor_data;
 +
 +      tunables->min_sample_time = 40 * USEC_PER_MSEC;
 +      tunables->boostpulse_duration_val = 40 * USEC_PER_MSEC;
 +      if (policy->cpu == 0) {
 +              tunables->hispeed_freq = 1008000;
 +              tunables->touchboostpulse_duration_val = 500 * USEC_PER_MSEC;
 +              tunables->touchboost_freq = 1200000;
 +      } else {
 +              tunables->hispeed_freq = 816000;
 +      }
 +}
 +#endif
 +
  static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
                unsigned int event)
  {
                        common_tunables = tunables;
                }
  
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +              rockchip_cpufreq_policy_init(policy);
 +#endif
 +
                rc = sysfs_create_group(get_governor_parent_kobj(policy),
                                get_sysfs_attr());
                if (rc) {
                        idle_notifier_register(&cpufreq_interactive_idle_nb);
                        cpufreq_register_notifier(&cpufreq_notifier_block,
                                        CPUFREQ_TRANSITION_NOTIFIER);
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +                      rc = input_register_handler(&cpufreq_interactive_input_handler);
 +#endif
 +
                }
  
                break;
        case CPUFREQ_GOV_POLICY_EXIT:
                if (!--tunables->usage_count) {
                        if (policy->governor->initialized == 1) {
 +#ifdef CONFIG_ARCH_ROCKCHIP
 +                              input_unregister_handler(&cpufreq_interactive_input_handler);
 +#endif
                                cpufreq_unregister_notifier(&cpufreq_notifier_block,
                                                CPUFREQ_TRANSITION_NOTIFIER);
                                idle_notifier_unregister(&cpufreq_interactive_idle_nb);
diff --combined drivers/misc/Kconfig
index 4727abb80ed9a6e4c1c1e500a19033c34842dc43,5847d3be083571697f05cb7b16c299d6adc35cc1..b9f9289cde7abe029e30ad70387a43e96a41597c
@@@ -4,13 -4,6 +4,13 @@@
  
  menu "Misc devices"
  
 +config ROCKCHIP_SCR
 +      tristate "Rockchip Smartcard Reader Controller support"
 +      default n
 +      help
 +        say Y here to enable Rockchip Smartcard Reader Controller driver
 +        for Soc such as RK3128,RK322x,RK3288,RK3368,RK3366 and etc.
 +
  config SENSORS_LIS3LV02D
        tristate
        depends on INPUT
@@@ -532,11 -525,13 +532,13 @@@ config VEXPRESS_SYSCF
          bus. System Configuration interface is one of the possible means
          of generating transactions on this bus.
  
- config UID_CPUTIME
-       bool "Per-UID cpu time statistics"
+ config UID_SYS_STATS
+       bool "Per-UID statistics"
        depends on PROFILING
        help
          Per UID based cpu time statistics exported to /proc/uid_cputime
+         Per UID based io statistics exported to /proc/uid_io
+         Per UID based procstat control in /proc/uid_procstat
  
  config MEMORY_STATE_TIME
        tristate "Memory freq/bandwidth time statistics"
        help
          Memory time statistics exported to /sys/kernel/memory_state_time
  
 +config USB_CAM_GPIO
 +      bool "usb camera gpio driver"
 +      default n
 +      help
 +        Enable this driver will support usb camera gpio control
 +
  source "drivers/misc/c2port/Kconfig"
  source "drivers/misc/eeprom/Kconfig"
  source "drivers/misc/cb710/Kconfig"
diff --combined drivers/misc/Makefile
index 06750b9428275a1760218ddfeb553a5ef660a430,9a3b402921b22aa485f7648d282d10e9d2dafb32..c73cc3ee844922364a9633f1afbb8cd94b58d08b
@@@ -2,7 -2,6 +2,7 @@@
  # Makefile for misc devices that really don't fit anywhere else.
  #
  
 +obj-$(CONFIG_ROCKCHIP_SCR)    += rk_scr.o
  obj-$(CONFIG_IBM_ASM)         += ibmasm/
  obj-$(CONFIG_AD525X_DPOT)     += ad525x_dpot.o
  obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
@@@ -57,6 -56,5 +57,6 @@@ obj-$(CONFIG_GENWQE)          += genwqe
  obj-$(CONFIG_ECHO)            += echo/
  obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
  obj-$(CONFIG_CXL_BASE)                += cxl/
- obj-$(CONFIG_UID_CPUTIME) += uid_cputime.o
+ obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o
  obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o
 +obj-$(CONFIG_USB_CAM_GPIO)    += usb_cam_gpio.o
diff --combined drivers/mmc/core/mmc.c
index b394c437a8c80e5a0f5c2a309fe129ed494b57a7,83b9bf88083454fab57b28435a703c3ab54d248f..a814eb6882aa02a1e04dbf155633812999286e1e
@@@ -235,11 -235,6 +235,11 @@@ static void mmc_select_card_type(struc
                avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;
        }
  
 +      if ((caps2 & MMC_CAP2_HS400_ES) &&
 +          card->ext_csd.strobe_support &&
 +          (avail_type & EXT_CSD_CARD_TYPE_HS400))
 +              avail_type |= EXT_CSD_CARD_TYPE_HS400ES;
 +
        card->ext_csd.hs_max_dtr = hs_max_dtr;
        card->ext_csd.hs200_max_dtr = hs200_max_dtr;
        card->mmc_avail_type = avail_type;
@@@ -391,7 -386,6 +391,7 @@@ static int mmc_decode_ext_csd(struct mm
                        mmc_card_set_blockaddr(card);
        }
  
 +      card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
        card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
        mmc_select_card_type(card);
  
                card->ext_csd.ffu_capable =
                        (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
                        !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
+               card->ext_csd.pre_eol_info = ext_csd[EXT_CSD_PRE_EOL_INFO];
+               card->ext_csd.device_life_time_est_typ_a =
+                       ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
+               card->ext_csd.device_life_time_est_typ_b =
+                       ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
        }
  out:
        return err;
@@@ -727,13 -727,17 +733,18 @@@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->
  MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
  MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
  MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);
+ MMC_DEV_ATTR(rev, "0x%x\n", card->ext_csd.rev);
+ MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info);
+ MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n",
+       card->ext_csd.device_life_time_est_typ_a,
+       card->ext_csd.device_life_time_est_typ_b);
  MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
  MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
                card->ext_csd.enhanced_area_offset);
  MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
  MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
  MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
 +MMC_DEV_ATTR(ocr, "%08x\n", card->ocr);
  
  static ssize_t mmc_fwrev_show(struct device *dev,
                              struct device_attribute *attr,
  
  static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL);
  
 +static ssize_t mmc_dsr_show(struct device *dev,
 +                          struct device_attribute *attr,
 +                          char *buf)
 +{
 +      struct mmc_card *card = mmc_dev_to_card(dev);
 +      struct mmc_host *host = card->host;
 +
 +      if (card->csd.dsr_imp && host->dsr_req)
 +              return sprintf(buf, "0x%x\n", host->dsr);
 +      else
 +              /* return default DSR value */
 +              return sprintf(buf, "0x%x\n", 0x404);
 +}
 +
 +static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL);
 +
  static struct attribute *mmc_std_attrs[] = {
        &dev_attr_cid.attr,
        &dev_attr_csd.attr,
        &dev_attr_name.attr,
        &dev_attr_oemid.attr,
        &dev_attr_prv.attr,
+       &dev_attr_rev.attr,
+       &dev_attr_pre_eol_info.attr,
+       &dev_attr_life_time.attr,
        &dev_attr_serial.attr,
        &dev_attr_enhanced_area_offset.attr,
        &dev_attr_enhanced_area_size.attr,
        &dev_attr_raw_rpmb_size_mult.attr,
        &dev_attr_rel_sectors.attr,
 +      &dev_attr_ocr.attr,
 +      &dev_attr_dsr.attr,
        NULL,
  };
  ATTRIBUTE_GROUPS(mmc_std);
@@@ -977,26 -966,13 +991,26 @@@ static int mmc_select_bus_width(struct 
                        break;
                } else {
                        pr_warn("%s: switch to bus width %d failed\n",
 -                              mmc_hostname(host), ext_csd_bits[idx]);
 +                              mmc_hostname(host), 1 << bus_width);
                }
        }
  
        return err;
  }
  
 +/* Caller must hold re-tuning */
 +static int mmc_switch_status(struct mmc_card *card)
 +{
 +      u32 status;
 +      int err;
 +
 +      err = mmc_send_status(card, &status);
 +      if (err)
 +              return err;
 +
 +      return mmc_switch_status_error(card->host, status);
 +}
 +
  /*
   * Switch to the high-speed mode
   */
@@@ -1007,14 -983,10 +1021,14 @@@ static int mmc_select_hs(struct mmc_car
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
                           card->ext_csd.generic_cmd6_time,
 -                         true, true, true);
 +                         true, false, true);
        if (!err)
                mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
  
 +      if (err)
 +              pr_warn("%s: switch to high-speed failed, err:%d\n",
 +                      mmc_hostname(card->host), err);
 +
        return err;
  }
  
@@@ -1089,9 -1061,23 +1103,9 @@@ static int mmc_select_hs_ddr(struct mmc
        return err;
  }
  
 -/* Caller must hold re-tuning */
 -static int mmc_switch_status(struct mmc_card *card)
 -{
 -      u32 status;
 -      int err;
 -
 -      err = mmc_send_status(card, &status);
 -      if (err)
 -              return err;
 -
 -      return mmc_switch_status_error(card->host, status);
 -}
 -
  static int mmc_select_hs400(struct mmc_card *card)
  {
        struct mmc_host *host = card->host;
 -      bool send_status = true;
        unsigned int max_dtr;
        int err = 0;
        u8 val;
              host->ios.bus_width == MMC_BUS_WIDTH_8))
                return 0;
  
 -      if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
 -              send_status = false;
 -
 -      /* Reduce frequency to HS frequency */
 -      max_dtr = card->ext_csd.hs_max_dtr;
 -      mmc_set_clock(host, max_dtr);
 -
        /* Switch card to HS mode */
        val = EXT_CSD_TIMING_HS;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, val,
                           card->ext_csd.generic_cmd6_time,
 -                         true, send_status, true);
 +                         true, false, true);
        if (err) {
                pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
                        mmc_hostname(host), err);
        /* Set host controller to HS timing */
        mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
  
 -      if (!send_status) {
 -              err = mmc_switch_status(card);
 -              if (err)
 -                      goto out_err;
 -      }
 +      /* Reduce frequency to HS frequency */
 +      max_dtr = card->ext_csd.hs_max_dtr;
 +      mmc_set_clock(host, max_dtr);
 +
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
  
        /* Switch card to DDR */
        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, val,
                           card->ext_csd.generic_cmd6_time,
 -                         true, send_status, true);
 +                         true, false, true);
        if (err) {
                pr_err("%s: switch to hs400 failed, err:%d\n",
                         mmc_hostname(host), err);
        mmc_set_timing(host, MMC_TIMING_MMC_HS400);
        mmc_set_bus_speed(card);
  
 -      if (!send_status) {
 -              err = mmc_switch_status(card);
 -              if (err)
 -                      goto out_err;
 -      }
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
  
        return 0;
  
@@@ -1174,10 -1167,14 +1188,10 @@@ int mmc_hs200_to_hs400(struct mmc_card 
  int mmc_hs400_to_hs200(struct mmc_card *card)
  {
        struct mmc_host *host = card->host;
 -      bool send_status = true;
        unsigned int max_dtr;
        int err;
        u8 val;
  
 -      if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
 -              send_status = false;
 -
        /* Reduce frequency to HS */
        max_dtr = card->ext_csd.hs_max_dtr;
        mmc_set_clock(host, max_dtr);
        val = EXT_CSD_TIMING_HS;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
                           val, card->ext_csd.generic_cmd6_time,
 -                         true, send_status, true);
 +                         true, false, true);
        if (err)
                goto out_err;
  
        mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
  
 -      if (!send_status) {
 -              err = mmc_switch_status(card);
 -              if (err)
 -                      goto out_err;
 -      }
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
  
        /* Switch HS DDR to HS */
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
                           EXT_CSD_BUS_WIDTH_8, card->ext_csd.generic_cmd6_time,
 -                         true, send_status, true);
 +                         true, false, true);
        if (err)
                goto out_err;
  
        mmc_set_timing(host, MMC_TIMING_MMC_HS);
  
 -      if (!send_status) {
 -              err = mmc_switch_status(card);
 -              if (err)
 -                      goto out_err;
 -      }
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
  
        /* Switch HS to HS200 */
        val = EXT_CSD_TIMING_HS200 |
              card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
 -                         val, card->ext_csd.generic_cmd6_time, true,
 -                         send_status, true);
 +                         val, card->ext_csd.generic_cmd6_time,
 +                         true, false, true);
        if (err)
                goto out_err;
  
        mmc_set_timing(host, MMC_TIMING_MMC_HS200);
  
 -      if (!send_status) {
 -              err = mmc_switch_status(card);
 -              if (err)
 -                      goto out_err;
 -      }
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
  
        mmc_set_bus_speed(card);
  
@@@ -1234,87 -1237,6 +1248,87 @@@ out_err
        return err;
  }
  
 +static int mmc_select_hs400es(struct mmc_card *card)
 +{
 +      struct mmc_host *host = card->host;
 +      int err = 0;
 +      u8 val;
 +
 +      if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
 +              err = -ENOTSUPP;
 +              goto out_err;
 +      }
 +
 +      if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
 +              err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
 +
 +      if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
 +              err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
 +
 +      /* If fails try again during next card power cycle */
 +      if (err)
 +              goto out_err;
 +
 +      err = mmc_select_bus_width(card);
 +      if (err < 0)
 +              goto out_err;
 +
 +      /* Switch card to HS mode */
 +      err = mmc_select_hs(card);
 +      if (err)
 +              goto out_err;
 +
 +      mmc_set_clock(host, card->ext_csd.hs_max_dtr);
 +
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
 +
 +      /* Switch card to DDR with strobe bit */
 +      val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE;
 +      err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 +                       EXT_CSD_BUS_WIDTH,
 +                       val,
 +                       card->ext_csd.generic_cmd6_time);
 +      if (err) {
 +              pr_err("%s: switch to bus width for hs400es failed, err:%d\n",
 +                      mmc_hostname(host), err);
 +              goto out_err;
 +      }
 +
 +      /* Switch card to HS400 */
 +      val = EXT_CSD_TIMING_HS400 |
 +            card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
 +      err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 +                         EXT_CSD_HS_TIMING, val,
 +                         card->ext_csd.generic_cmd6_time,
 +                         true, false, true);
 +      if (err) {
 +              pr_err("%s: switch to hs400es failed, err:%d\n",
 +                      mmc_hostname(host), err);
 +              goto out_err;
 +      }
 +
 +      /* Set host controller to HS400 timing and frequency */
 +      mmc_set_timing(host, MMC_TIMING_MMC_HS400);
 +
 +      /* Controller enable enhanced strobe function */
 +      host->ios.enhanced_strobe = true;
 +      if (host->ops->hs400_enhanced_strobe)
 +              host->ops->hs400_enhanced_strobe(host, &host->ios);
 +
 +      err = mmc_switch_status(card);
 +      if (err)
 +              goto out_err;
 +
 +      return 0;
 +
 +out_err:
 +      pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
 +             __func__, err);
 +      return err;
 +}
 +
  static void mmc_select_driver_type(struct mmc_card *card)
  {
        int card_drv_type, drive_strength, drv_type;
  static int mmc_select_hs200(struct mmc_card *card)
  {
        struct mmc_host *host = card->host;
 -      bool send_status = true;
 -      unsigned int old_timing;
 +      unsigned int old_timing, old_signal_voltage;
        int err = -EINVAL;
        u8 val;
  
 +      old_signal_voltage = host->ios.signal_voltage;
        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
                err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
  
  
        /* If fails try again during next card power cycle */
        if (err)
 -              goto err;
 +              return err;
  
        mmc_select_driver_type(card);
  
 -      if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
 -              send_status = false;
 -
        /*
         * Set the bus width(4 or 8) with host's support and
         * switch to HS200 mode if bus width is set successfully.
         */
        err = mmc_select_bus_width(card);
 -      if (!IS_ERR_VALUE(err)) {
 +      if (err > 0) {
                val = EXT_CSD_TIMING_HS200 |
                      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
                err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                   EXT_CSD_HS_TIMING, val,
                                   card->ext_csd.generic_cmd6_time,
 -                                 true, send_status, true);
 +                                 true, false, true);
                if (err)
                        goto err;
                old_timing = host->ios.timing;
                mmc_set_timing(host, MMC_TIMING_MMC_HS200);
 -              if (!send_status) {
 -                      err = mmc_switch_status(card);
 -                      /*
 -                       * mmc_select_timing() assumes timing has not changed if
 -                       * it is a switch error.
 -                       */
 -                      if (err == -EBADMSG)
 -                              mmc_set_timing(host, old_timing);
 -              }
        }
  err:
 -      if (err)
 +      if (err) {
 +              /* fall back to the old signal voltage, if fails report error */
 +              if (__mmc_set_signal_voltage(host, old_signal_voltage))
 +                      err = -EIO;
 +
                pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
                       __func__, err);
 +      }
        return err;
  }
  
  /*
 - * Activate High Speed or HS200 mode if supported.
 + * Activate High Speed, HS200 or HS400ES mode if supported.
   */
  static int mmc_select_timing(struct mmc_card *card)
  {
        if (!mmc_can_ext_csd(card))
                goto bus_speed;
  
 -      if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
 +      if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)
 +              err = mmc_select_hs400es(card);
 +      else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
                err = mmc_select_hs200(card);
        else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
                err = mmc_select_hs(card);
        if (err && err != -EBADMSG)
                return err;
  
 -      if (err) {
 -              pr_warn("%s: switch to %s failed\n",
 -                      mmc_card_hs(card) ? "high-speed" :
 -                      (mmc_card_hs200(card) ? "hs200" : ""),
 -                      mmc_hostname(card->host));
 -              err = 0;
 -      }
 -
  bus_speed:
        /*
         * Set the bus speed to the selected bus timing.
         * If timing is not selected, backward compatible is the default.
         */
        mmc_set_bus_speed(card);
 -      return err;
 +      return 0;
  }
  
  /*
@@@ -1569,13 -1504,12 +1583,13 @@@ static int mmc_init_card(struct mmc_hos
                if (err)
                        goto free_card;
  
 -              /* If doing byte addressing, check if required to do sector
 +              /*
 +               * If doing byte addressing, check if required to do sector
                 * addressing.  Handle the case of <2GB cards needing sector
                 * addressing.  See section 8.1 JEDEC Standard JED84-A441;
                 * ocr register has bit 30 set for sector addressing.
                 */
 -              if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30)))
 +              if (rocr & BIT(30))
                        mmc_card_set_blockaddr(card);
  
                /* Erase size depends on CSD and Extended CSD */
                err = mmc_select_hs400(card);
                if (err)
                        goto free_card;
 -      } else {
 +      } else if (!mmc_card_hs400es(card)) {
                /* Select the desired bus width optionally */
                err = mmc_select_bus_width(card);
 -              if (!IS_ERR_VALUE(err) && mmc_card_hs(card)) {
 +              if (err > 0 && mmc_card_hs(card)) {
                        err = mmc_select_hs_ddr(card);
                        if (err)
                                goto free_card;
@@@ -1948,7 -1882,6 +1962,7 @@@ static int mmc_suspend(struct mmc_host 
  static int _mmc_resume(struct mmc_host *host)
  {
        int err = 0;
 +      int i;
  
        BUG_ON(!host);
        BUG_ON(!host->card);
        if (!mmc_card_suspended(host->card))
                goto out;
  
 -      mmc_power_up(host, host->card->ocr);
 -      err = mmc_init_card(host, host->card->ocr, host->card);
 +      /*
 +       * Let's try to fallback the host->f_init
 +       * if failing to init mmc card after resume.
 +       */
 +      for (i = 0; i < ARRAY_SIZE(freqs); i++) {
 +              if (host->f_init < max(freqs[i], host->f_min))
 +                      continue;
 +              else
 +                      host->f_init = max(freqs[i], host->f_min);
 +
 +              mmc_power_up(host, host->card->ocr);
 +              err = mmc_init_card(host, host->card->ocr, host->card);
 +              if (!err)
 +                      break;
 +      }
 +
        mmc_card_clr_suspended(host->card);
  
  out:
@@@ -2007,8 -1926,16 +2021,8 @@@ static int mmc_shutdown(struct mmc_hos
   */
  static int mmc_resume(struct mmc_host *host)
  {
 -      int err = 0;
 -
 -      if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
 -              err = _mmc_resume(host);
 -              pm_runtime_set_active(&host->card->dev);
 -              pm_runtime_mark_last_busy(&host->card->dev);
 -      }
        pm_runtime_enable(&host->card->dev);
 -
 -      return err;
 +      return 0;
  }
  
  /*
@@@ -2036,9 -1963,12 +2050,9 @@@ static int mmc_runtime_resume(struct mm
  {
        int err;
  
 -      if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME)))
 -              return 0;
 -
        err = _mmc_resume(host);
 -      if (err)
 -              pr_err("%s: error %d doing aggressive resume\n",
 +      if (err && err != -ENOMEDIUM)
 +              pr_err("%s: error %d doing runtime resume\n",
                        mmc_hostname(host), err);
  
        return 0;
diff --combined drivers/mmc/host/sdhci.c
index bc5312b1798a0f71905087624ba7b4c5f4a3b077,62d37d2ac557b264ddb57a339dd19ac915ccbe80..7209df518d45510bf99d3b4c1709e47cd57550ae
@@@ -1274,7 -1274,9 +1274,9 @@@ clock_set
                        return;
                }
                timeout--;
-               mdelay(1);
+               spin_unlock_irq(&host->lock);
+               usleep_range(900, 1100);
+               spin_lock_irq(&host->lock);
        }
  
        clk |= SDHCI_CLOCK_CARD_EN;
@@@ -1872,11 -1874,11 +1874,11 @@@ static int sdhci_card_busy(struct mmc_h
        u32 present_state;
  
        sdhci_runtime_pm_get(host);
 -      /* Check whether DAT[3:0] is 0000 */
 +      /* Check whether DAT[0] is 0 */
        present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
        sdhci_runtime_pm_put(host);
  
 -      return !(present_state & SDHCI_DATA_LVL_MASK);
 +      return !(present_state & SDHCI_DATA_0_LVL_MASK);
  }
  
  static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
@@@ -2025,9 -2027,9 +2027,9 @@@ static int sdhci_execute_tuning(struct 
  
                spin_unlock_irqrestore(&host->lock, flags);
                /* Wait for Buffer Read Ready interrupt */
 -              wait_event_interruptible_timeout(host->buf_ready_int,
 -                                      (host->tuning_done == 1),
 -                                      msecs_to_jiffies(50));
 +              wait_event_timeout(host->buf_ready_int,
 +                                 (host->tuning_done == 1),
 +                                 msecs_to_jiffies(50));
                spin_lock_irqsave(&host->lock, flags);
  
                if (!host->tuning_done) {
@@@ -2738,6 -2740,7 +2740,6 @@@ int sdhci_suspend_host(struct sdhci_hos
                free_irq(host->irq, host);
        } else {
                sdhci_enable_irq_wakeups(host);
 -              enable_irq_wake(host->irq);
        }
        return 0;
  }
@@@ -2773,6 -2776,7 +2775,6 @@@ int sdhci_resume_host(struct sdhci_hos
                        return ret;
        } else {
                sdhci_disable_irq_wakeups(host);
 -              disable_irq_wake(host->irq);
        }
  
        sdhci_enable_card_detection(host);
diff --combined drivers/pci/pci.c
index b767915dcb4ee2549d9d76165a5dafe70f4bc428,0e53488f8ec1af75a3ac8b306a0ebf5769720df4..365676b3e0c5b56731d254f3c26eb0e8e60ee09f
@@@ -25,7 -25,7 +25,7 @@@
  #include <linux/device.h>
  #include <linux/pm_runtime.h>
  #include <linux/pci_hotplug.h>
 -#include <asm-generic/pci-bridge.h>
 +#include <linux/vmalloc.h>
  #include <asm/setup.h>
  #include <linux/aer.h>
  #include "pci.h"
@@@ -519,10 -519,6 +519,6 @@@ static void pci_restore_bars(struct pci
  {
        int i;
  
-       /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
-       if (dev->is_virtfn)
-               return;
        for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
                pci_update_resource(dev, i);
  }
@@@ -3057,23 -3053,6 +3053,23 @@@ int __weak pci_remap_iospace(const stru
  #endif
  }
  
 +/**
 + *    pci_unmap_iospace - Unmap the memory mapped I/O space
 + *    @res: resource to be unmapped
 + *
 + *    Unmap the CPU virtual address @res from virtual address space.
 + *    Only architectures that have memory mapped IO functions defined
 + *    (and the PCI_IOBASE value defined) should call this function.
 + */
 +void pci_unmap_iospace(struct resource *res)
 +{
 +#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
 +      unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
 +
 +      unmap_kernel_range(vaddr, resource_size(res));
 +#endif
 +}
 +
  static void __pci_set_master(struct pci_dev *dev, bool enable)
  {
        u16 old_cmd, cmd;
@@@ -4489,36 -4468,6 +4485,6 @@@ int pci_select_bars(struct pci_dev *dev
  }
  EXPORT_SYMBOL(pci_select_bars);
  
- /**
-  * pci_resource_bar - get position of the BAR associated with a resource
-  * @dev: the PCI device
-  * @resno: the resource number
-  * @type: the BAR type to be filled in
-  *
-  * Returns BAR position in config space, or 0 if the BAR is invalid.
-  */
- int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
- {
-       int reg;
-       if (resno < PCI_ROM_RESOURCE) {
-               *type = pci_bar_unknown;
-               return PCI_BASE_ADDRESS_0 + 4 * resno;
-       } else if (resno == PCI_ROM_RESOURCE) {
-               *type = pci_bar_mem32;
-               return dev->rom_base_reg;
-       } else if (resno < PCI_BRIDGE_RESOURCES) {
-               /* device specific resource */
-               *type = pci_bar_unknown;
-               reg = pci_iov_resource_bar(dev, resno);
-               if (reg)
-                       return reg;
-       }
-       dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
-       return 0;
- }
  /* Some architectures require additional programming to enable VGA */
  static arch_set_vga_state_t arch_set_vga_state;
  
diff --combined drivers/usb/core/hcd.c
index ff23a9c74ccf89a0792f72623b6da98798f742d7,ca2cbdb3aa672117f09bbf30bf75e6ef5ba9c2c9..7ea608761f29e89fba0df4e96a4cde5d1e11b927
@@@ -499,8 -499,10 +499,10 @@@ static int rh_call_control (struct usb_
         */
        tbuf_size =  max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
        tbuf = kzalloc(tbuf_size, GFP_KERNEL);
-       if (!tbuf)
-               return -ENOMEM;
+       if (!tbuf) {
+               status = -ENOMEM;
+               goto err_alloc;
+       }
  
        bufp = tbuf;
  
@@@ -705,6 -707,7 +707,7 @@@ error
        }
  
        kfree(tbuf);
+  err_alloc:
  
        /* any errors get returned through the urb completion */
        spin_lock_irq(&hcd_root_hub_lock);
@@@ -2991,7 -2994,6 +2994,7 @@@ void usb_remove_hcd(struct usb_hcd *hcd
        }
  
        usb_put_invalidate_rhdev(hcd);
 +      hcd->flags = 0;
  }
  EXPORT_SYMBOL_GPL(usb_remove_hcd);
  
diff --combined drivers/usb/core/hub.c
index 92c99d999f07f7c0864517091a8fc473cae03dff,7c2d87befb516adff119fed378f66f4cf7bb7610..57b8a363ca1bba2b5f7039ee8c8b4a7f389d3319
@@@ -1682,8 -1682,7 +1682,8 @@@ static int hub_probe(struct usb_interfa
         * bus_resume methods.
         */
        if (hdev->parent) {             /* normal device */
 -              usb_enable_autosuspend(hdev);
 +              if (!(hdev->parent->quirks & USB_QUIRK_AUTO_SUSPEND))
 +                      usb_enable_autosuspend(hdev);
        } else {                        /* root hub */
                const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
  
@@@ -2603,8 -2602,15 +2603,15 @@@ static int hub_port_wait_reset(struct u
                if (ret < 0)
                        return ret;
  
-               /* The port state is unknown until the reset completes. */
-               if (!(portstatus & USB_PORT_STAT_RESET))
+               /*
+                * The port state is unknown until the reset completes.
+                *
+                * On top of that, some chips may require additional time
+                * to re-establish a connection after the reset is complete,
+                * so also wait for the connection to be re-established.
+                */
+               if (!(portstatus & USB_PORT_STAT_RESET) &&
+                   (portstatus & USB_PORT_STAT_CONNECTION))
                        break;
  
                /* switch to the long delay after two short delay failures */
@@@ -4200,7 -4206,7 +4207,7 @@@ static void hub_set_initial_usb2_lpm_po
        struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
        int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
  
-       if (!udev->usb2_hw_lpm_capable)
+       if (!udev->usb2_hw_lpm_capable || !udev->bos)
                return;
  
        if (hub)
index 3399679513a8a310ca50156cce5642ea4572004a,ec7a50f98f57a70e3ddb640215794fe4a6f66677..46c7bb4cfd10412b2db15d5d6a9ee4d4f5526143
@@@ -146,42 -146,113 +146,43 @@@ int dwc3_gadget_set_link_state(struct d
  }
  
  /**
 - * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
 - * @dwc: pointer to our context structure
 - *
 - * This function will a best effort FIFO allocation in order
 - * to improve FIFO usage and throughput, while still allowing
 - * us to enable as many endpoints as possible.
 - *
 - * Keep in mind that this operation will be highly dependent
 - * on the configured size for RAM1 - which contains TxFifo -,
 - * the amount of endpoints enabled on coreConsultant tool, and
 - * the width of the Master Bus.
 - *
 - * In the ideal world, we would always be able to satisfy the
 - * following equation:
 + * dwc3_ep_inc_trb() - Increment a TRB index.
 + * @index - Pointer to the TRB index to increment.
   *
 - * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
 - * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
 - *
 - * Unfortunately, due to many variables that's not always the case.
 + * The index should never point to the link TRB. After incrementing,
 + * if it is point to the link TRB, wrap around to the beginning. The
 + * link TRB is always at the last TRB entry.
   */
 -int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
 +static void dwc3_ep_inc_trb(u8 *index)
  {
 -      int             last_fifo_depth = 0;
 -      int             ram1_depth;
 -      int             fifo_size;
 -      int             mdwidth;
 -      int             num;
 -
 -      if (!dwc->needs_fifo_resize)
 -              return 0;
 -
 -      ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
 -      mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
 -
 -      /* MDWIDTH is represented in bits, we need it in bytes */
 -      mdwidth >>= 3;
 -
 -      /*
 -       * FIXME For now we will only allocate 1 wMaxPacketSize space
 -       * for each enabled endpoint, later patches will come to
 -       * improve this algorithm so that we better use the internal
 -       * FIFO space
 -       */
 -      for (num = 0; num < dwc->num_in_eps; num++) {
 -              /* bit0 indicates direction; 1 means IN ep */
 -              struct dwc3_ep  *dep = dwc->eps[(num << 1) | 1];
 -              int             mult = 1;
 -              int             tmp;
 -
 -              if (!(dep->flags & DWC3_EP_ENABLED))
 -                      continue;
 -
 -              if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
 -                              || usb_endpoint_xfer_isoc(dep->endpoint.desc))
 -                      mult = 3;
 -
 -              /*
 -               * REVISIT: the following assumes we will always have enough
 -               * space available on the FIFO RAM for all possible use cases.
 -               * Make sure that's true somehow and change FIFO allocation
 -               * accordingly.
 -               *
 -               * If we have Bulk or Isochronous endpoints, we want
 -               * them to be able to be very, very fast. So we're giving
 -               * those endpoints a fifo_size which is enough for 3 full
 -               * packets
 -               */
 -              tmp = mult * (dep->endpoint.maxpacket + mdwidth);
 -              tmp += mdwidth;
 -
 -              fifo_size = DIV_ROUND_UP(tmp, mdwidth);
 -
 -              fifo_size |= (last_fifo_depth << 16);
 -
 -              dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d",
 -                              dep->name, last_fifo_depth, fifo_size & 0xffff);
 -
 -              dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
 +      (*index)++;
 +      if (*index == (DWC3_TRB_NUM - 1))
 +              *index = 0;
 +}
  
 -              last_fifo_depth += (fifo_size & 0xffff);
 -      }
 +static void dwc3_ep_inc_enq(struct dwc3_ep *dep)
 +{
 +      dwc3_ep_inc_trb(&dep->trb_enqueue);
 +}
  
 -      return 0;
 +static void dwc3_ep_inc_deq(struct dwc3_ep *dep)
 +{
 +      dwc3_ep_inc_trb(&dep->trb_dequeue);
  }
  
  void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
                int status)
  {
        struct dwc3                     *dwc = dep->dwc;
+       unsigned int                    unmap_after_complete = false;
        int                             i;
  
 -      if (req->queued) {
 +      if (req->started) {
                i = 0;
                do {
 -                      dep->busy_slot++;
 -                      /*
 -                       * Skip LINK TRB. We can't use req->trb and check for
 -                       * DWC3_TRBCTL_LINK_TRB because it points the TRB we
 -                       * just completed (not the LINK TRB).
 -                       */
 -                      if (((dep->busy_slot & DWC3_TRB_MASK) ==
 -                              DWC3_TRB_NUM- 1) &&
 -                              usb_endpoint_xfer_isoc(dep->endpoint.desc))
 -                              dep->busy_slot++;
 +                      dwc3_ep_inc_deq(dep);
                } while(++i < req->request.num_mapped_sgs);
 -              req->queued = false;
 +              req->started = false;
        }
        list_del(&req->list);
        req->trb = NULL;
        if (req->request.status == -EINPROGRESS)
                req->request.status = status;
  
-       if (dwc->ep0_bounced && dep->number <= 1)
+       /*
+        * NOTICE we don't want to unmap before calling ->complete() if we're
+        * dealing with a bounced ep0 request. If we unmap it here, we would end
+        * up overwritting the contents of req->buf and this could confuse the
+        * gadget driver.
+        */
+       if (dwc->ep0_bounced && dep->number <= 1) {
                dwc->ep0_bounced = false;
-       usb_gadget_unmap_request(&dwc->gadget, &req->request,
-                       req->direction);
+               unmap_after_complete = true;
+       } else {
+               usb_gadget_unmap_request(&dwc->gadget,
+                               &req->request, req->direction);
+       }
  
 -      dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
 -                      req, dep->name, req->request.actual,
 -                      req->request.length, status);
        trace_dwc3_gadget_giveback(req);
  
        spin_unlock(&dwc->lock);
        usb_gadget_giveback_request(&dep->endpoint, &req->request);
        spin_lock(&dwc->lock);
  
+       if (unmap_after_complete)
+               usb_gadget_unmap_request(&dwc->gadget,
+                               &req->request, req->direction);
++
 +      if (dep->number > 1)
 +              pm_runtime_put(dwc->dev);
  }
  
  int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
  {
        u32             timeout = 500;
 +      int             status = 0;
 +      int             ret = 0;
        u32             reg;
  
 -      trace_dwc3_gadget_generic_cmd(cmd, param);
 -
        dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
        dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
  
        do {
                reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
                if (!(reg & DWC3_DGCMD_CMDACT)) {
 -                      dwc3_trace(trace_dwc3_gadget,
 -                                      "Command Complete --> %d",
 -                                      DWC3_DGCMD_STATUS(reg));
 -                      if (DWC3_DGCMD_STATUS(reg))
 -                              return -EINVAL;
 -                      return 0;
 +                      status = DWC3_DGCMD_STATUS(reg);
 +                      if (status)
 +                              ret = -EINVAL;
 +                      break;
                }
 +      } while (timeout--);
  
 -              /*
 -               * We can't sleep here, because it's also called from
 -               * interrupt context.
 -               */
 -              timeout--;
 -              if (!timeout) {
 -                      dwc3_trace(trace_dwc3_gadget,
 -                                      "Command Timed Out");
 -                      return -ETIMEDOUT;
 -              }
 -              udelay(1);
 -      } while (1);
 +      if (!timeout) {
 +              ret = -ETIMEDOUT;
 +              status = -ETIMEDOUT;
 +      }
 +
 +      trace_dwc3_gadget_generic_cmd(cmd, param, status);
 +
 +      return ret;
  }
  
 -int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 -              unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
 +static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
 +
 +int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 +              struct dwc3_gadget_ep_cmd_params *params)
  {
 -      struct dwc3_ep          *dep = dwc->eps[ep];
 +      struct dwc3             *dwc = dep->dwc;
        u32                     timeout = 500;
        u32                     reg;
  
 -      trace_dwc3_gadget_ep_cmd(dep, cmd, params);
 +      int                     cmd_status = 0;
 +      int                     susphy = false;
 +      int                     ret = -EINVAL;
  
 -      dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
 -      dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
 -      dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
 +      /*
 +       * Synopsys Databook 2.60a states, on section 6.3.2.5.[1-8], that if
 +       * we're issuing an endpoint command, we must check if
 +       * GUSB2PHYCFG.SUSPHY bit is set. If it is, then we need to clear it.
 +       *
 +       * We will also set SUSPHY bit to what it was before returning as stated
 +       * by the same section on Synopsys databook.
 +       */
 +      if (dwc->gadget.speed <= USB_SPEED_HIGH) {
 +              reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 +              if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
 +                      susphy = true;
 +                      reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 +                      dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 +              }
 +      }
  
 -      dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
 +      if (cmd == DWC3_DEPCMD_STARTTRANSFER) {
 +              int             needs_wakeup;
 +
 +              needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 ||
 +                              dwc->link_state == DWC3_LINK_STATE_U2 ||
 +                              dwc->link_state == DWC3_LINK_STATE_U3);
 +
 +              if (unlikely(needs_wakeup)) {
 +                      ret = __dwc3_gadget_wakeup(dwc);
 +                      dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
 +                                      ret);
 +              }
 +      }
 +
 +      dwc3_writel(dep->regs, DWC3_DEPCMDPAR0, params->param0);
 +      dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
 +      dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
 +
 +      dwc3_writel(dep->regs, DWC3_DEPCMD, cmd | DWC3_DEPCMD_CMDACT);
        do {
 -              reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep));
 +              reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
                if (!(reg & DWC3_DEPCMD_CMDACT)) {
 -                      dwc3_trace(trace_dwc3_gadget,
 -                                      "Command Complete --> %d",
 -                                      DWC3_DEPCMD_STATUS(reg));
 -                      if (DWC3_DEPCMD_STATUS(reg))
 -                              return -EINVAL;
 -                      return 0;
 -              }
 +                      cmd_status = DWC3_DEPCMD_STATUS(reg);
  
 -              /*
 -               * We can't sleep here, because it is also called from
 -               * interrupt context.
 -               */
 -              timeout--;
 -              if (!timeout) {
 -                      dwc3_trace(trace_dwc3_gadget,
 -                                      "Command Timed Out");
 -                      return -ETIMEDOUT;
 +                      switch (cmd_status) {
 +                      case 0:
 +                              ret = 0;
 +                              break;
 +                      case DEPEVT_TRANSFER_NO_RESOURCE:
 +                              ret = -EINVAL;
 +                              break;
 +                      case DEPEVT_TRANSFER_BUS_EXPIRY:
 +                              /*
 +                               * SW issues START TRANSFER command to
 +                               * isochronous ep with future frame interval. If
 +                               * future interval time has already passed when
 +                               * core receives the command, it will respond
 +                               * with an error status of 'Bus Expiry'.
 +                               *
 +                               * Instead of always returning -EINVAL, let's
 +                               * give a hint to the gadget driver that this is
 +                               * the case by returning -EAGAIN.
 +                               */
 +                              ret = -EAGAIN;
 +                              break;
 +                      default:
 +                              dev_WARN(dwc->dev, "UNKNOWN cmd status\n");
 +                      }
 +
 +                      break;
                }
 +      } while (--timeout);
  
 -              udelay(1);
 -      } while (1);
 +      if (timeout == 0) {
 +              ret = -ETIMEDOUT;
 +              cmd_status = -ETIMEDOUT;
 +      }
 +
 +      trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status);
 +
 +      if (unlikely(susphy)) {
 +              reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 +              reg |= DWC3_GUSB2PHYCFG_SUSPHY;
 +              dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 +      }
 +
 +      return ret;
 +}
 +
 +static int dwc3_send_clear_stall_ep_cmd(struct dwc3_ep *dep)
 +{
 +      struct dwc3 *dwc = dep->dwc;
 +      struct dwc3_gadget_ep_cmd_params params;
 +      u32 cmd = DWC3_DEPCMD_CLEARSTALL;
 +
 +      /*
 +       * As of core revision 2.60a the recommended programming model
 +       * is to set the ClearPendIN bit when issuing a Clear Stall EP
 +       * command for IN endpoints. This is to prevent an issue where
 +       * some (non-compliant) hosts may not send ACK TPs for pending
 +       * IN transfers due to a mishandled error condition. Synopsys
 +       * STAR 9000614252.
 +       */
 +      if (dep->direction && (dwc->revision >= DWC3_REVISION_260A))
 +              cmd |= DWC3_DEPCMD_CLEARPENDIN;
 +
 +      memset(&params, 0, sizeof(params));
 +
 +      return dwc3_send_gadget_ep_cmd(dep, cmd, &params);
  }
  
  static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
@@@ -441,7 -448,7 +454,7 @@@ static int dwc3_gadget_start_config(str
        memset(&params, 0x00, sizeof(params));
        cmd = DWC3_DEPCMD_DEPSTARTCFG;
  
 -      ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
 +      ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
        if (ret)
                return ret;
  
  static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
                const struct usb_endpoint_descriptor *desc,
                const struct usb_ss_ep_comp_descriptor *comp_desc,
 -              bool ignore, bool restore)
 +              bool modify, bool restore)
  {
        struct dwc3_gadget_ep_cmd_params params;
  
 +      if (dev_WARN_ONCE(dwc->dev, modify && restore,
 +                                      "Can't modify and restore\n"))
 +              return -EINVAL;
 +
        memset(&params, 0x00, sizeof(params));
  
        params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc))
                | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc));
  
        /* Burst size is only needed in SuperSpeed mode */
 -      if (dwc->gadget.speed == USB_SPEED_SUPER) {
 -              u32 burst = dep->endpoint.maxburst - 1;
 -
 -              params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst);
 +      if (dwc->gadget.speed >= USB_SPEED_SUPER) {
 +              u32 burst = dep->endpoint.maxburst;
 +              params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst - 1);
        }
  
 -      if (ignore)
 -              params.param0 |= DWC3_DEPCFG_IGN_SEQ_NUM;
 -
 -      if (restore) {
 +      if (modify) {
 +              params.param0 |= DWC3_DEPCFG_ACTION_MODIFY;
 +      } else if (restore) {
                params.param0 |= DWC3_DEPCFG_ACTION_RESTORE;
                params.param2 |= dep->saved_state;
 +      } else {
 +              params.param0 |= DWC3_DEPCFG_ACTION_INIT;
        }
  
        params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
                dep->interval = 1 << (desc->bInterval - 1);
        }
  
 -      return dwc3_send_gadget_ep_cmd(dwc, dep->number,
 -                      DWC3_DEPCMD_SETEPCONFIG, &params);
 +      return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, &params);
  }
  
  static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)
  
        params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1);
  
 -      return dwc3_send_gadget_ep_cmd(dwc, dep->number,
 -                      DWC3_DEPCMD_SETTRANSFRESOURCE, &params);
 +      return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETTRANSFRESOURCE,
 +                      &params);
  }
  
  /**
  static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
                const struct usb_endpoint_descriptor *desc,
                const struct usb_ss_ep_comp_descriptor *comp_desc,
 -              bool ignore, bool restore)
 +              bool modify, bool restore)
  {
        struct dwc3             *dwc = dep->dwc;
        u32                     reg;
                        return ret;
        }
  
 -      ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc, ignore,
 +      ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc, modify,
                        restore);
        if (ret)
                return ret;
                reg |= DWC3_DALEPENA_EP(dep->number);
                dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
  
 -              if (!usb_endpoint_xfer_isoc(desc))
 +              if (usb_endpoint_xfer_control(desc))
                        return 0;
  
 -              /* Link TRB for ISOC. The HWO bit is never reset */
 +              /* Initialize the TRB ring */
 +              dep->trb_dequeue = 0;
 +              dep->trb_enqueue = 0;
 +              memset(dep->trb_pool, 0,
 +                     sizeof(struct dwc3_trb) * DWC3_TRB_NUM);
 +
 +              /* Link TRB. The HWO bit is never reset */
                trb_st_hw = &dep->trb_pool[0];
  
                trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1];
 -              memset(trb_link, 0, sizeof(*trb_link));
 -
                trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
                trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
                trb_link->ctrl |= DWC3_TRBCTL_LINK_TRB;
                trb_link->ctrl |= DWC3_TRB_CTRL_HWO;
        }
  
 -      switch (usb_endpoint_type(desc)) {
 -      case USB_ENDPOINT_XFER_CONTROL:
 -              strlcat(dep->name, "-control", sizeof(dep->name));
 -              break;
 -      case USB_ENDPOINT_XFER_ISOC:
 -              strlcat(dep->name, "-isoc", sizeof(dep->name));
 -              break;
 -      case USB_ENDPOINT_XFER_BULK:
 -              strlcat(dep->name, "-bulk", sizeof(dep->name));
 -              break;
 -      case USB_ENDPOINT_XFER_INT:
 -              strlcat(dep->name, "-int", sizeof(dep->name));
 -              break;
 -      default:
 -              dev_err(dwc->dev, "invalid endpoint transfer type\n");
 -      }
 -
        return 0;
  }
  
@@@ -606,17 -623,19 +619,17 @@@ static void dwc3_remove_requests(struc
  {
        struct dwc3_request             *req;
  
 -      if (!list_empty(&dep->req_queued)) {
 -              dwc3_stop_active_transfer(dwc, dep->number, true);
 +      dwc3_stop_active_transfer(dwc, dep->number, true);
  
 -              /* - giveback all requests to gadget driver */
 -              while (!list_empty(&dep->req_queued)) {
 -                      req = next_request(&dep->req_queued);
 +      /* - giveback all requests to gadget driver */
 +      while (!list_empty(&dep->started_list)) {
 +              req = next_request(&dep->started_list);
  
 -                      dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
 -              }
 +              dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
        }
  
 -      while (!list_empty(&dep->request_list)) {
 -              req = next_request(&dep->request_list);
 +      while (!list_empty(&dep->pending_list)) {
 +              req = next_request(&dep->pending_list);
  
                dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
        }
@@@ -653,6 -672,10 +666,6 @@@ static int __dwc3_gadget_ep_disable(str
        dep->type = 0;
        dep->flags = 0;
  
 -      snprintf(dep->name, sizeof(dep->name), "ep%d%s",
 -                      dep->number >> 1,
 -                      (dep->number & 1) ? "in" : "out");
 -
        return 0;
  }
  
@@@ -692,10 -715,11 +705,10 @@@ static int dwc3_gadget_ep_enable(struc
        dep = to_dwc3_ep(ep);
        dwc = dep->dwc;
  
 -      if (dep->flags & DWC3_EP_ENABLED) {
 -              dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",
 -                              dep->name);
 +      if (dev_WARN_ONCE(dwc->dev, dep->flags & DWC3_EP_ENABLED,
 +                                      "%s is already enabled\n",
 +                                      dep->name))
                return 0;
 -      }
  
        spin_lock_irqsave(&dwc->lock, flags);
        ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false);
@@@ -719,10 -743,11 +732,10 @@@ static int dwc3_gadget_ep_disable(struc
        dep = to_dwc3_ep(ep);
        dwc = dep->dwc;
  
 -      if (!(dep->flags & DWC3_EP_ENABLED)) {
 -              dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n",
 -                              dep->name);
 +      if (dev_WARN_ONCE(dwc->dev, !(dep->flags & DWC3_EP_ENABLED),
 +                                      "%s is already disabled\n",
 +                                      dep->name))
                return 0;
 -      }
  
        spin_lock_irqsave(&dwc->lock, flags);
        ret = __dwc3_gadget_ep_disable(dep);
@@@ -744,8 -769,6 +757,8 @@@ static struct usb_request *dwc3_gadget_
        req->epnum      = dep->number;
        req->dep        = dep;
  
 +      dep->allocated_requests++;
 +
        trace_dwc3_alloc_request(req);
  
        return &req->request;
@@@ -755,9 -778,7 +768,9 @@@ static void dwc3_gadget_ep_free_request
                struct usb_request *request)
  {
        struct dwc3_request             *req = to_dwc3_request(request);
 +      struct dwc3_ep                  *dep = to_dwc3_ep(ep);
  
 +      dep->allocated_requests--;
        trace_dwc3_free_request(req);
        kfree(req);
  }
@@@ -779,16 -800,20 +792,16 @@@ static void dwc3_prepare_one_trb(struc
                        chain ? " chain" : "");
  
  
 -      trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
 +      trb = &dep->trb_pool[dep->trb_enqueue];
  
        if (!req->trb) {
 -              dwc3_gadget_move_request_queued(req);
 +              dwc3_gadget_move_started_request(req);
                req->trb = trb;
                req->trb_dma = dwc3_trb_dma_offset(dep, trb);
 -              req->start_slot = dep->free_slot & DWC3_TRB_MASK;
 +              req->first_trb_index = dep->trb_enqueue;
        }
  
 -      dep->free_slot++;
 -      /* Skip the LINK-TRB on ISOC */
 -      if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
 -                      usb_endpoint_xfer_isoc(dep->endpoint.desc))
 -              dep->free_slot++;
 +      dwc3_ep_inc_enq(dep);
  
        trb->size = DWC3_TRB_SIZE_LENGTH(length);
        trb->bpl = lower_32_bits(dma);
                        trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
                else
                        trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
 +
 +              /* always enable Interrupt on Missed ISOC */
 +              trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
                break;
  
        case USB_ENDPOINT_XFER_BULK:
                BUG();
        }
  
 +      /* always enable Continue on Short Packet */
 +      trb->ctrl |= DWC3_TRB_CTRL_CSP;
 +
        if (!req->request.no_interrupt && !chain)
 -              trb->ctrl |= DWC3_TRB_CTRL_IOC;
 +              trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI;
  
 -      if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 -              trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
 -              trb->ctrl |= DWC3_TRB_CTRL_CSP;
 -      } else if (last) {
 +      if (last)
                trb->ctrl |= DWC3_TRB_CTRL_LST;
 -      }
  
        if (chain)
                trb->ctrl |= DWC3_TRB_CTRL_CHN;
  
        trb->ctrl |= DWC3_TRB_CTRL_HWO;
  
 +      dep->queued_requests++;
 +
        trace_dwc3_prepare_trb(dep, trb);
  }
  
 -/*
 - * dwc3_prepare_trbs - setup TRBs from requests
 - * @dep: endpoint for which requests are being prepared
 - * @starting: true if the endpoint is idle and no requests are queued.
 +/**
 + * dwc3_ep_prev_trb() - Returns the previous TRB in the ring
 + * @dep: The endpoint with the TRB ring
 + * @index: The index of the current TRB in the ring
   *
 - * The function goes through the requests list and sets up TRBs for the
 - * transfers. The function returns once there are no more TRBs available or
 - * it runs out of requests.
 + * Returns the TRB prior to the one pointed to by the index. If the
 + * index is 0, we will wrap backwards, skip the link TRB, and return
 + * the one just before that.
   */
 -static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 +static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index)
  {
 -      struct dwc3_request     *req, *n;
 -      u32                     trbs_left;
 -      u32                     max;
 -      unsigned int            last_one = 0;
 -
 -      BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
 +      if (!index)
 +              index = DWC3_TRB_NUM - 2;
 +      else
 +              index = dep->trb_enqueue - 1;
  
 -      /* the first request must not be queued */
 -      trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
 +      return &dep->trb_pool[index];
 +}
  
 -      /* Can't wrap around on a non-isoc EP since there's no link TRB */
 -      if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 -              max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK);
 -              if (trbs_left > max)
 -                      trbs_left = max;
 -      }
 +static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
 +{
 +      struct dwc3_trb         *tmp;
 +      u8                      trbs_left;
  
        /*
 -       * If busy & slot are equal than it is either full or empty. If we are
 -       * starting to process requests then we are empty. Otherwise we are
 -       * full and don't do anything
 +       * If enqueue & dequeue are equal than it is either full or empty.
 +       *
 +       * One way to know for sure is if the TRB right before us has HWO bit
 +       * set or not. If it has, then we're definitely full and can't fit any
 +       * more transfers in our ring.
         */
 -      if (!trbs_left) {
 -              if (!starting)
 -                      return;
 -              trbs_left = DWC3_TRB_NUM;
 -              /*
 -               * In case we start from scratch, we queue the ISOC requests
 -               * starting from slot 1. This is done because we use ring
 -               * buffer and have no LST bit to stop us. Instead, we place
 -               * IOC bit every TRB_NUM/4. We try to avoid having an interrupt
 -               * after the first request so we start at slot 1 and have
 -               * 7 requests proceed before we hit the first IOC.
 -               * Other transfer types don't use the ring buffer and are
 -               * processed from the first TRB until the last one. Since we
 -               * don't wrap around we have to start at the beginning.
 -               */
 -              if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 -                      dep->busy_slot = 1;
 -                      dep->free_slot = 1;
 -              } else {
 -                      dep->busy_slot = 0;
 -                      dep->free_slot = 0;
 -              }
 +      if (dep->trb_enqueue == dep->trb_dequeue) {
 +              tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
 +
 +              if (!(tmp->ctrl & DWC3_TRB_CTRL_HWO) ||
 +                  ((tmp->ctrl & DWC3_TRB_CTRL_HWO) &&
 +                   (tmp->ctrl & DWC3_TRB_CTRL_CSP) &&
 +                   !dep->direction))
 +                      return DWC3_TRB_NUM - 1;
 +
 +              return 0;
        }
  
 -      /* The last TRB is a link TRB, not used for xfer */
 -      if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc))
 -              return;
 +      trbs_left = dep->trb_dequeue - dep->trb_enqueue;
 +      trbs_left &= (DWC3_TRB_NUM - 1);
  
 -      list_for_each_entry_safe(req, n, &dep->request_list, list) {
 -              unsigned        length;
 -              dma_addr_t      dma;
 -              last_one = false;
 +      if (dep->trb_dequeue < dep->trb_enqueue)
 +              trbs_left--;
  
 -              if (req->request.num_mapped_sgs > 0) {
 -                      struct usb_request *request = &req->request;
 -                      struct scatterlist *sg = request->sg;
 -                      struct scatterlist *s;
 -                      int             i;
 +      return trbs_left;
 +}
  
 -                      for_each_sg(sg, s, request->num_mapped_sgs, i) {
 -                              unsigned chain = true;
 +static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 +              struct dwc3_request *req, unsigned int trbs_left,
 +              unsigned int more_coming)
 +{
 +      struct usb_request *request = &req->request;
 +      struct scatterlist *sg = request->sg;
 +      struct scatterlist *s;
 +      unsigned int    last = false;
 +      unsigned int    length;
 +      dma_addr_t      dma;
 +      int             i;
  
 -                              length = sg_dma_len(s);
 -                              dma = sg_dma_address(s);
 +      for_each_sg(sg, s, request->num_mapped_sgs, i) {
 +              unsigned chain = true;
  
 -                              if (i == (request->num_mapped_sgs - 1) ||
 -                                              sg_is_last(s)) {
 -                                      if (list_empty(&dep->request_list))
 -                                              last_one = true;
 -                                      chain = false;
 -                              }
 +              length = sg_dma_len(s);
 +              dma = sg_dma_address(s);
  
 -                              trbs_left--;
 -                              if (!trbs_left)
 -                                      last_one = true;
 +              if (sg_is_last(s)) {
 +                      if (usb_endpoint_xfer_int(dep->endpoint.desc) ||
 +                              !more_coming)
 +                              last = true;
  
 -                              if (last_one)
 -                                      chain = false;
 +                      chain = false;
 +              }
  
 -                              dwc3_prepare_one_trb(dep, req, dma, length,
 -                                              last_one, chain, i);
 +              if (!trbs_left--)
 +                      last = true;
  
 -                              if (last_one)
 -                                      break;
 -                      }
 +              if (last)
 +                      chain = false;
  
 -                      if (last_one)
 -                              break;
 -              } else {
 -                      dma = req->request.dma;
 -                      length = req->request.length;
 -                      trbs_left--;
 +              dwc3_prepare_one_trb(dep, req, dma, length,
 +                              last, chain, i);
  
 -                      if (!trbs_left)
 -                              last_one = 1;
 +              if (last)
 +                      break;
 +      }
 +}
  
 -                      /* Is this the last request? */
 -                      if (list_is_last(&req->list, &dep->request_list))
 -                              last_one = 1;
 +static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
 +              struct dwc3_request *req, unsigned int trbs_left,
 +              unsigned int more_coming)
 +{
 +      unsigned int    last = false;
 +      unsigned int    length;
 +      dma_addr_t      dma;
  
 -                      dwc3_prepare_one_trb(dep, req, dma, length,
 -                                      last_one, false, 0);
 +      dma = req->request.dma;
 +      length = req->request.length;
  
 -                      if (last_one)
 -                              break;
 -              }
 +      if (!trbs_left)
 +              last = true;
 +
 +      /* Is this the last request? */
 +      if (usb_endpoint_xfer_int(dep->endpoint.desc) || !more_coming)
 +              last = true;
 +
 +      dwc3_prepare_one_trb(dep, req, dma, length,
 +                      last, false, 0);
 +}
 +
 +/*
 + * dwc3_prepare_trbs - setup TRBs from requests
 + * @dep: endpoint for which requests are being prepared
 + *
 + * The function goes through the requests list and sets up TRBs for the
 + * transfers. The function returns once there are no more TRBs available or
 + * it runs out of requests.
 + */
 +static void dwc3_prepare_trbs(struct dwc3_ep *dep)
 +{
 +      struct dwc3_request     *req, *n;
 +      unsigned int            more_coming;
 +      u32                     trbs_left;
 +
 +      BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
 +
 +      trbs_left = dwc3_calc_trbs_left(dep);
 +      if (!trbs_left)
 +              return;
 +
 +      more_coming = dep->allocated_requests - dep->queued_requests;
 +
 +      list_for_each_entry_safe(req, n, &dep->pending_list, list) {
 +              if (req->request.num_mapped_sgs > 0)
 +                      dwc3_prepare_one_trb_sg(dep, req, trbs_left--,
 +                                      more_coming);
 +              else
 +                      dwc3_prepare_one_trb_linear(dep, req, trbs_left--,
 +                                      more_coming);
 +
 +              if (!trbs_left)
 +                      return;
        }
  }
  
 -static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 -              int start_new)
 +static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
  {
        struct dwc3_gadget_ep_cmd_params params;
        struct dwc3_request             *req;
        struct dwc3                     *dwc = dep->dwc;
 +      int                             starting;
        int                             ret;
        u32                             cmd;
  
 -      if (start_new && (dep->flags & DWC3_EP_BUSY)) {
 -              dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name);
 -              return -EBUSY;
 -      }
 -
 -      /*
 -       * If we are getting here after a short-out-packet we don't enqueue any
 -       * new requests as we try to set the IOC bit only on the last request.
 -       */
 -      if (start_new) {
 -              if (list_empty(&dep->req_queued))
 -                      dwc3_prepare_trbs(dep, start_new);
 -
 -              /* req points to the first request which will be sent */
 -              req = next_request(&dep->req_queued);
 -      } else {
 -              dwc3_prepare_trbs(dep, start_new);
 +      starting = !(dep->flags & DWC3_EP_BUSY);
  
 -              /*
 -               * req points to the first request where HWO changed from 0 to 1
 -               */
 -              req = next_request(&dep->req_queued);
 -      }
 +      dwc3_prepare_trbs(dep);
 +      req = next_request(&dep->started_list);
        if (!req) {
                dep->flags |= DWC3_EP_PENDING_REQUEST;
                return 0;
  
        memset(&params, 0, sizeof(params));
  
 -      if (start_new) {
 +      if (starting) {
                params.param0 = upper_32_bits(req->trb_dma);
                params.param1 = lower_32_bits(req->trb_dma);
 -              cmd = DWC3_DEPCMD_STARTTRANSFER;
 +              cmd = DWC3_DEPCMD_STARTTRANSFER |
 +                      DWC3_DEPCMD_PARAM(cmd_param);
        } else {
 -              cmd = DWC3_DEPCMD_UPDATETRANSFER;
 +              cmd = DWC3_DEPCMD_UPDATETRANSFER |
 +                      DWC3_DEPCMD_PARAM(dep->resource_index);
        }
  
 -      cmd |= DWC3_DEPCMD_PARAM(cmd_param);
 -      ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
 +      ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
        if (ret < 0) {
 -              dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
 -
                /*
                 * FIXME we need to iterate over the list of requests
                 * here and stop, unmap, free and del each of the linked
  
        dep->flags |= DWC3_EP_BUSY;
  
 -      if (start_new) {
 -              dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc,
 -                              dep->number);
 +      if (starting) {
 +              dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep);
                WARN_ON_ONCE(!dep->resource_index);
        }
  
@@@ -1050,7 -1065,7 +1063,7 @@@ static void __dwc3_gadget_start_isoc(st
  {
        u32 uf;
  
 -      if (list_empty(&dep->request_list)) {
 +      if (list_empty(&dep->pending_list)) {
                dwc3_trace(trace_dwc3_gadget,
                                "ISOC ep %s run out for requests",
                                dep->name);
        /* 4 micro frames in the future */
        uf = cur_uf + dep->interval * 4;
  
 -      __dwc3_gadget_kick_transfer(dep, uf, 1);
 +      __dwc3_gadget_kick_transfer(dep, uf);
  }
  
  static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
@@@ -1080,22 -1095,6 +1093,22 @@@ static int __dwc3_gadget_ep_queue(struc
        struct dwc3             *dwc = dep->dwc;
        int                     ret;
  
 +      if (!dep->endpoint.desc) {
 +              dwc3_trace(trace_dwc3_gadget,
 +                              "trying to queue request %p to disabled %s",
 +                              &req->request, dep->endpoint.name);
 +              return -ESHUTDOWN;
 +      }
 +
 +      if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
 +                              &req->request, req->dep->name)) {
 +              dwc3_trace(trace_dwc3_gadget, "request %p belongs to '%s'",
 +                              &req->request, req->dep->name);
 +              return -EINVAL;
 +      }
 +
 +      pm_runtime_get(dwc->dev);
 +
        req->request.actual     = 0;
        req->request.status     = -EINPROGRESS;
        req->direction          = dep->direction;
  
        trace_dwc3_ep_queue(req);
  
 +      /*
 +       * Per databook, the total size of buffer must be a multiple
 +       * of MaxPacketSize for OUT endpoints. And MaxPacketSize is
 +       * configed for endpoints in dwc3_gadget_set_ep_config(),
 +       * set to usb_endpoint_descriptor->wMaxPacketSize.
 +       */
 +      if (dep->direction == 0 &&
 +          req->request.length % dep->endpoint.desc->wMaxPacketSize)
 +              req->request.length = roundup(req->request.length,
 +                                      dep->endpoint.desc->wMaxPacketSize);
 +
        /*
         * We only add to our list of requests now and
         * start consuming the list once we get XferNotReady
        if (ret)
                return ret;
  
 -      list_add_tail(&req->list, &dep->request_list);
 +      list_add_tail(&req->list, &dep->pending_list);
  
        /*
         * If there are no pending requests and the endpoint isn't already
         * little bit faster.
         */
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 -                      !usb_endpoint_xfer_int(dep->endpoint.desc) &&
 -                      !(dep->flags & DWC3_EP_BUSY)) {
 -              ret = __dwc3_gadget_kick_transfer(dep, 0, true);
 +                      !usb_endpoint_xfer_int(dep->endpoint.desc)) {
 +              ret = __dwc3_gadget_kick_transfer(dep, 0);
                goto out;
        }
  
                 * notion of current microframe.
                 */
                if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 -                      if (list_empty(&dep->req_queued)) {
 +                      if (list_empty(&dep->started_list)) {
                                dwc3_stop_active_transfer(dwc, dep->number, true);
                                dep->flags = DWC3_EP_ENABLED;
                        }
                        return 0;
                }
  
 -              ret = __dwc3_gadget_kick_transfer(dep, 0, true);
 +              ret = __dwc3_gadget_kick_transfer(dep, 0);
                if (!ret)
                        dep->flags &= ~DWC3_EP_PENDING_REQUEST;
  
                        (dep->flags & DWC3_EP_BUSY) &&
                        !(dep->flags & DWC3_EP_MISSED_ISOC)) {
                WARN_ON_ONCE(!dep->resource_index);
 -              ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
 -                              false);
 +              ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index);
                goto out;
        }
  
         * handled.
         */
        if (dep->stream_capable)
 -              ret = __dwc3_gadget_kick_transfer(dep, 0, true);
 +              ret = __dwc3_gadget_kick_transfer(dep, 0);
  
  out:
        if (ret && ret != -EBUSY)
 -              dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
 +              dwc3_trace(trace_dwc3_gadget,
 +                              "%s: failed to kick transfers",
                                dep->name);
        if (ret == -EBUSY)
                ret = 0;
        return ret;
  }
  
 +static void __dwc3_gadget_ep_zlp_complete(struct usb_ep *ep,
 +              struct usb_request *request)
 +{
 +      dwc3_gadget_ep_free_request(ep, request);
 +}
 +
 +static int __dwc3_gadget_ep_queue_zlp(struct dwc3 *dwc, struct dwc3_ep *dep)
 +{
 +      struct dwc3_request             *req;
 +      struct usb_request              *request;
 +      struct usb_ep                   *ep = &dep->endpoint;
 +
 +      dwc3_trace(trace_dwc3_gadget, "queueing ZLP");
 +      request = dwc3_gadget_ep_alloc_request(ep, GFP_ATOMIC);
 +      if (!request)
 +              return -ENOMEM;
 +
 +      request->length = 0;
 +      request->buf = dwc->zlp_buf;
 +      request->complete = __dwc3_gadget_ep_zlp_complete;
 +
 +      req = to_dwc3_request(request);
 +
 +      return __dwc3_gadget_ep_queue(dep, req);
 +}
 +
  static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
        gfp_t gfp_flags)
  {
        int                             ret;
  
        spin_lock_irqsave(&dwc->lock, flags);
 -      if (!dep->endpoint.desc) {
 -              dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
 -                              request, ep->name);
 -              ret = -ESHUTDOWN;
 -              goto out;
 -      }
 -
 -      if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
 -                              request, req->dep->name)) {
 -              ret = -EINVAL;
 -              goto out;
 -      }
 -
        ret = __dwc3_gadget_ep_queue(dep, req);
  
 -out:
 +      /*
 +       * Okay, here's the thing, if gadget driver has requested for a ZLP by
 +       * setting request->zero, instead of doing magic, we will just queue an
 +       * extra usb_request ourselves so that it gets handled the same way as
 +       * any other request.
 +       */
 +      if (ret == 0 && request->zero && request->length &&
 +          (request->length % ep->desc->wMaxPacketSize == 0))
 +              ret = __dwc3_gadget_ep_queue_zlp(dwc, dep);
 +
        spin_unlock_irqrestore(&dwc->lock, flags);
  
        return ret;
@@@ -1282,13 -1249,13 +1295,13 @@@ static int dwc3_gadget_ep_dequeue(struc
  
        spin_lock_irqsave(&dwc->lock, flags);
  
 -      list_for_each_entry(r, &dep->request_list, list) {
 +      list_for_each_entry(r, &dep->pending_list, list) {
                if (r == req)
                        break;
        }
  
        if (r != req) {
 -              list_for_each_entry(r, &dep->req_queued, list) {
 +              list_for_each_entry(r, &dep->started_list, list) {
                        if (r == req)
                                break;
                }
@@@ -1327,37 -1294,24 +1340,37 @@@ int __dwc3_gadget_ep_set_halt(struct dw
        memset(&params, 0x00, sizeof(params));
  
        if (value) {
 -              if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) ||
 -                              (!list_empty(&dep->req_queued) ||
 -                               !list_empty(&dep->request_list)))) {
 -                      dev_dbg(dwc->dev, "%s: pending request, cannot halt\n",
 +              struct dwc3_trb *trb;
 +
 +              unsigned transfer_in_flight;
 +              unsigned started;
 +
 +              if (dep->number > 1)
 +                      trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
 +              else
 +                      trb = &dwc->ep0_trb[dep->trb_enqueue];
 +
 +              transfer_in_flight = trb->ctrl & DWC3_TRB_CTRL_HWO;
 +              started = !list_empty(&dep->started_list);
 +
 +              if (!protocol && ((dep->direction && transfer_in_flight) ||
 +                              (!dep->direction && started))) {
 +                      dwc3_trace(trace_dwc3_gadget,
 +                                      "%s: pending request, cannot halt",
                                        dep->name);
                        return -EAGAIN;
                }
  
 -              ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
 -                      DWC3_DEPCMD_SETSTALL, &params);
 +              ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETSTALL,
 +                              &params);
                if (ret)
                        dev_err(dwc->dev, "failed to set STALL on %s\n",
                                        dep->name);
                else
                        dep->flags |= DWC3_EP_STALL;
        } else {
 -              ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
 -                      DWC3_DEPCMD_CLEARSTALL, &params);
 +
 +              ret = dwc3_send_clear_stall_ep_cmd(dep);
                if (ret)
                        dev_err(dwc->dev, "failed to clear STALL on %s\n",
                                        dep->name);
@@@ -1444,16 -1398,22 +1457,16 @@@ static int dwc3_gadget_get_frame(struc
        return DWC3_DSTS_SOFFN(reg);
  }
  
 -static int dwc3_gadget_wakeup(struct usb_gadget *g)
 +static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
  {
 -      struct dwc3             *dwc = gadget_to_dwc(g);
 -
        unsigned long           timeout;
 -      unsigned long           flags;
  
 +      int                     ret;
        u32                     reg;
  
 -      int                     ret = 0;
 -
        u8                      link_state;
        u8                      speed;
  
 -      spin_lock_irqsave(&dwc->lock, flags);
 -
        /*
         * According to the Databook Remote wakeup request should
         * be issued only when the device is in early suspend state.
  
        speed = reg & DWC3_DSTS_CONNECTSPD;
        if (speed == DWC3_DSTS_SUPERSPEED) {
 -              dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n");
 -              ret = -EINVAL;
 -              goto out;
 +              dwc3_trace(trace_dwc3_gadget, "no wakeup on SuperSpeed");
 +              return 0;
        }
  
        link_state = DWC3_DSTS_USBLNKST(reg);
        case DWC3_LINK_STATE_U3:        /* in HS, means SUSPEND */
                break;
        default:
 -              dev_dbg(dwc->dev, "can't wakeup from link state %d\n",
 -                              link_state);
 -              ret = -EINVAL;
 -              goto out;
 +              dwc3_trace(trace_dwc3_gadget,
 +                              "can't wakeup from '%s'",
 +                              dwc3_gadget_link_string(link_state));
 +              return -EINVAL;
        }
  
        ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV);
        if (ret < 0) {
                dev_err(dwc->dev, "failed to put link in Recovery\n");
 -              goto out;
 +              return ret;
        }
  
        /* Recent versions do this automatically */
  
        if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) {
                dev_err(dwc->dev, "failed to send remote wakeup\n");
 -              ret = -EINVAL;
 +              return -EINVAL;
        }
  
 -out:
 +      return 0;
 +}
 +
 +static int dwc3_gadget_wakeup(struct usb_gadget *g)
 +{
 +      struct dwc3             *dwc = gadget_to_dwc(g);
 +      unsigned long           flags;
 +      int                     ret;
 +
 +      spin_lock_irqsave(&dwc->lock, flags);
 +      ret = __dwc3_gadget_wakeup(dwc);
        spin_unlock_irqrestore(&dwc->lock, flags);
  
        return ret;
@@@ -1545,9 -1496,6 +1558,9 @@@ static int dwc3_gadget_run_stop(struct 
        u32                     reg;
        u32                     timeout = 500;
  
 +      if (pm_runtime_suspended(dwc->dev))
 +              return 0;
 +
        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
        if (is_on) {
                if (dwc->revision <= DWC3_REVISION_187A) {
  
        do {
                reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 -              if (is_on) {
 -                      if (!(reg & DWC3_DSTS_DEVCTRLHLT))
 -                              break;
 -              } else {
 -                      if (reg & DWC3_DSTS_DEVCTRLHLT)
 -                              break;
 -              }
 -              timeout--;
 -              if (!timeout)
 -                      return -ETIMEDOUT;
 -              udelay(1);
 -      } while (1);
 +              reg &= DWC3_DSTS_DEVCTRLHLT;
 +      } while (--timeout && !(!is_on ^ !reg));
 +
 +      if (!timeout)
 +              return -ETIMEDOUT;
  
        dwc3_trace(trace_dwc3_gadget, "gadget %s data soft-%s",
                        dwc->gadget_driver
@@@ -1632,52 -1587,36 +1645,52 @@@ static void dwc3_gadget_disable_irq(str
  static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
  static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc);
  
 -static int dwc3_gadget_start(struct usb_gadget *g,
 -              struct usb_gadget_driver *driver)
 +/**
 + * dwc3_gadget_setup_nump - Calculate and initialize NUMP field of DCFG
 + * dwc: pointer to our context structure
 + *
 + * The following looks like complex but it's actually very simple. In order to
 + * calculate the number of packets we can burst at once on OUT transfers, we're
 + * gonna use RxFIFO size.
 + *
 + * To calculate RxFIFO size we need two numbers:
 + * MDWIDTH = size, in bits, of the internal memory bus
 + * RAM2_DEPTH = depth, in MDWIDTH, of internal RAM2 (where RxFIFO sits)
 + *
 + * Given these two numbers, the formula is simple:
 + *
 + * RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16;
 + *
 + * 24 bytes is for 3x SETUP packets
 + * 16 bytes is a clock domain crossing tolerance
 + *
 + * Given RxFIFO Size, NUMP = RxFIFOSize / 1024;
 + */
 +static void dwc3_gadget_setup_nump(struct dwc3 *dwc)
  {
 -      struct dwc3             *dwc = gadget_to_dwc(g);
 -      struct dwc3_ep          *dep;
 -      unsigned long           flags;
 -      int                     ret = 0;
 -      int                     irq;
 -      u32                     reg;
 +      u32 ram2_depth;
 +      u32 mdwidth;
 +      u32 nump;
 +      u32 reg;
  
 -      irq = platform_get_irq(to_platform_device(dwc->dev), 0);
 -      ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
 -                      IRQF_SHARED, "dwc3", dwc);
 -      if (ret) {
 -              dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
 -                              irq, ret);
 -              goto err0;
 -      }
 +      ram2_depth = DWC3_GHWPARAMS7_RAM2_DEPTH(dwc->hwparams.hwparams7);
 +      mdwidth = DWC3_GHWPARAMS0_MDWIDTH(dwc->hwparams.hwparams0);
  
 -      spin_lock_irqsave(&dwc->lock, flags);
 +      nump = ((ram2_depth * mdwidth / 8) - 24 - 16) / 1024;
 +      nump = min_t(u32, nump, 16);
  
 -      if (dwc->gadget_driver) {
 -              dev_err(dwc->dev, "%s is already bound to %s\n",
 -                              dwc->gadget.name,
 -                              dwc->gadget_driver->driver.name);
 -              ret = -EBUSY;
 -              goto err1;
 -      }
 +      /* update NumP */
 +      reg = dwc3_readl(dwc->regs, DWC3_DCFG);
 +      reg &= ~DWC3_DCFG_NUMP_MASK;
 +      reg |= nump << DWC3_DCFG_NUMP_SHIFT;
 +      dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 +}
  
 -      dwc->gadget_driver      = driver;
 +static int __dwc3_gadget_start(struct dwc3 *dwc)
 +{
 +      struct dwc3_ep          *dep;
 +      int                     ret = 0;
 +      u32                     reg;
  
        reg = dwc3_readl(dwc->regs, DWC3_DCFG);
        reg &= ~(DWC3_DCFG_SPEED_MASK);
        } else {
                switch (dwc->maximum_speed) {
                case USB_SPEED_LOW:
 -                      reg |= DWC3_DSTS_LOWSPEED;
 +                      reg |= DWC3_DCFG_LOWSPEED;
                        break;
                case USB_SPEED_FULL:
 -                      reg |= DWC3_DSTS_FULLSPEED1;
 +                      reg |= DWC3_DCFG_FULLSPEED1;
                        break;
                case USB_SPEED_HIGH:
 -                      reg |= DWC3_DSTS_HIGHSPEED;
 +                      reg |= DWC3_DCFG_HIGHSPEED;
                        break;
                case USB_SPEED_SUPER:   /* FALLTHROUGH */
                case USB_SPEED_UNKNOWN: /* FALTHROUGH */
                default:
 -                      reg |= DWC3_DSTS_SUPERSPEED;
 +                      reg |= DWC3_DCFG_SUPERSPEED;
                }
        }
        dwc3_writel(dwc->regs, DWC3_DCFG, reg);
  
 +      /*
 +       * We are telling dwc3 that we want to use DCFG.NUMP as ACK TP's NUMP
 +       * field instead of letting dwc3 itself calculate that automatically.
 +       *
 +       * This way, we maximize the chances that we'll be able to get several
 +       * bursts of data without going through any sort of endpoint throttling.
 +       */
 +      reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
 +      reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL;
 +      dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
 +
 +      dwc3_gadget_setup_nump(dwc);
 +
        /* Start with SuperSpeed Default */
        dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
  
                        false);
        if (ret) {
                dev_err(dwc->dev, "failed to enable %s\n", dep->name);
 -              goto err2;
 +              goto err0;
        }
  
        dep = dwc->eps[1];
                        false);
        if (ret) {
                dev_err(dwc->dev, "failed to enable %s\n", dep->name);
 -              goto err3;
 +              goto err1;
        }
  
        /* begin to receive SETUP packets */
  
        dwc3_gadget_enable_irq(dwc);
  
 -      spin_unlock_irqrestore(&dwc->lock, flags);
 -
        return 0;
  
 -err3:
 -      __dwc3_gadget_ep_disable(dwc->eps[0]);
 -
 -err2:
 -      dwc->gadget_driver = NULL;
 -
  err1:
 -      spin_unlock_irqrestore(&dwc->lock, flags);
 -
 -      free_irq(irq, dwc);
 +      __dwc3_gadget_ep_disable(dwc->eps[0]);
  
  err0:
        return ret;
  }
  
 -static int dwc3_gadget_stop(struct usb_gadget *g)
 +static int dwc3_gadget_start(struct usb_gadget *g,
 +              struct usb_gadget_driver *driver)
  {
        struct dwc3             *dwc = gadget_to_dwc(g);
        unsigned long           flags;
 +      int                     ret = 0;
        int                     irq;
  
 +      irq = dwc->irq_gadget;
 +      ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
 +                      IRQF_SHARED, "dwc3", dwc->ev_buf);
 +      if (ret) {
 +              dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
 +                              irq, ret);
 +              goto err0;
 +      }
 +
        spin_lock_irqsave(&dwc->lock, flags);
 +      if (dwc->gadget_driver) {
 +              dev_err(dwc->dev, "%s is already bound to %s\n",
 +                              dwc->gadget.name,
 +                              dwc->gadget_driver->driver.name);
 +              ret = -EBUSY;
 +              goto err1;
 +      }
 +
 +      dwc->gadget_driver      = driver;
 +
 +      if (pm_runtime_active(dwc->dev))
 +              __dwc3_gadget_start(dwc);
 +
 +      spin_unlock_irqrestore(&dwc->lock, flags);
 +
 +      return 0;
 +
 +err1:
 +      spin_unlock_irqrestore(&dwc->lock, flags);
 +      free_irq(irq, dwc);
 +
 +err0:
 +      return ret;
 +}
 +
 +static void __dwc3_gadget_stop(struct dwc3 *dwc)
 +{
 +      if (pm_runtime_suspended(dwc->dev))
 +              return;
  
        dwc3_gadget_disable_irq(dwc);
        __dwc3_gadget_ep_disable(dwc->eps[0]);
        __dwc3_gadget_ep_disable(dwc->eps[1]);
 +}
  
 -      dwc->gadget_driver      = NULL;
 +static int dwc3_gadget_stop(struct usb_gadget *g)
 +{
 +      struct dwc3             *dwc = gadget_to_dwc(g);
 +      unsigned long           flags;
  
 +      spin_lock_irqsave(&dwc->lock, flags);
 +      __dwc3_gadget_stop(dwc);
 +      dwc->gadget_driver      = NULL;
        spin_unlock_irqrestore(&dwc->lock, flags);
  
 -      irq = platform_get_irq(to_platform_device(dwc->dev), 0);
 -      free_irq(irq, dwc);
 +      free_irq(dwc->irq_gadget, dwc->ev_buf);
  
        return 0;
  }
@@@ -1849,7 -1739,7 +1862,7 @@@ static int dwc3_gadget_init_hw_endpoint
        u8                              i;
  
        for (i = 0; i < num; i++) {
 -              u8 epnum = (i << 1) | (!!direction);
 +              u8 epnum = (i << 1) | (direction ? 1 : 0);
  
                dep = kzalloc(sizeof(*dep), GFP_KERNEL);
                if (!dep)
                dep->dwc = dwc;
                dep->number = epnum;
                dep->direction = !!direction;
 +              dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
                dwc->eps[epnum] = dep;
  
                snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
                                (epnum & 1) ? "in" : "out");
  
                dep->endpoint.name = dep->name;
 +              spin_lock_init(&dep->lock);
  
                dwc3_trace(trace_dwc3_gadget, "initializing %s", dep->name);
  
                dep->endpoint.caps.dir_in = !!direction;
                dep->endpoint.caps.dir_out = !direction;
  
 -              INIT_LIST_HEAD(&dep->request_list);
 -              INIT_LIST_HEAD(&dep->req_queued);
 +              INIT_LIST_HEAD(&dep->pending_list);
 +              INIT_LIST_HEAD(&dep->started_list);
        }
  
        return 0;
@@@ -1967,7 -1855,6 +1980,7 @@@ static int __dwc3_cleanup_done_trbs(str
        unsigned int            s_pkt = 0;
        unsigned int            trb_status;
  
 +      dep->queued_requests--;
        trace_dwc3_complete_trb(dep, trb);
  
        if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
                if (count) {
                        trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size);
                        if (trb_status == DWC3_TRBSTS_MISSED_ISOC) {
 -                              dev_dbg(dwc->dev, "incomplete IN transfer %s\n",
 +                              dwc3_trace(trace_dwc3_gadget,
 +                                              "%s: incomplete IN transfer",
                                                dep->name);
                                /*
                                 * If missed isoc occurred and there is
                                 * If there are still queued request
                                 * then wait, do not issue either END
                                 * or UPDATE TRANSFER, just attach next
 -                               * request in request_list during
 +                               * request in pending_list during
                                 * giveback.If any future queued request
                                 * is successfully transferred then we
                                 * will issue UPDATE TRANSFER for all
 -                               * request in the request_list.
 +                               * request in the pending_list.
                                 */
                                dep->flags |= DWC3_EP_MISSED_ISOC;
                        } else {
@@@ -2042,14 -1928,16 +2055,14 @@@ static int dwc3_cleanup_done_reqs(struc
        int                     ret;
  
        do {
 -              req = next_request(&dep->req_queued);
 -              if (!req) {
 -                      WARN_ON_ONCE(1);
 +              req = next_request(&dep->started_list);
 +              if (WARN_ON_ONCE(!req))
                        return 1;
 -              }
 +
                i = 0;
                do {
 -                      slot = req->start_slot + i;
 -                      if ((slot == DWC3_TRB_NUM - 1) &&
 -                              usb_endpoint_xfer_isoc(dep->endpoint.desc))
 +                      slot = req->first_trb_index + i;
 +                      if (slot == DWC3_TRB_NUM - 1)
                                slot++;
                        slot %= DWC3_TRB_NUM;
                        trb = &dep->trb_pool[slot];
                        break;
        } while (1);
  
 +      /*
 +       * Our endpoint might get disabled by another thread during
 +       * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 +       * early on so DWC3_EP_BUSY flag gets cleared
 +       */
 +      if (!dep->endpoint.desc)
 +              return 1;
 +
        if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 -                      list_empty(&dep->req_queued)) {
 -              if (list_empty(&dep->request_list)) {
 +                      list_empty(&dep->started_list)) {
 +              if (list_empty(&dep->pending_list)) {
                        /*
                         * If there is no entry in request list then do
                         * not issue END TRANSFER now. Just set PENDING
@@@ -2121,7 -2001,7 +2134,7 @@@ static void dwc3_endpoint_transfer_comp
                status = -ECONNRESET;
  
        clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status);
 -      if (clean_busy && (is_xfer_complete ||
 +      if (clean_busy && (!dep->endpoint.desc || is_xfer_complete ||
                                usb_endpoint_xfer_isoc(dep->endpoint.desc)))
                dep->flags &= ~DWC3_EP_BUSY;
  
                        if (!(dep->flags & DWC3_EP_ENABLED))
                                continue;
  
 -                      if (!list_empty(&dep->req_queued))
 +                      if (!list_empty(&dep->started_list))
                                return;
                }
  
                dwc->u1u2 = 0;
        }
  
 +      /*
 +       * Our endpoint might get disabled by another thread during
 +       * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 +       * early on so DWC3_EP_BUSY flag gets cleared
 +       */
 +      if (!dep->endpoint.desc)
 +              return;
 +
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
                int ret;
  
 -              ret = __dwc3_gadget_kick_transfer(dep, 0, is_xfer_complete);
 +              ret = __dwc3_gadget_kick_transfer(dep, 0);
                if (!ret || ret == -EBUSY)
                        return;
        }
@@@ -2179,9 -2051,6 +2192,9 @@@ static void dwc3_endpoint_interrupt(str
                return;
  
        if (epnum == 0 || epnum == 1) {
 +              if (!dwc->connected &&
 +                  event->endpoint_event == DWC3_DEPEVT_XFERCOMPLETE)
 +                      dwc->connected = true;
                dwc3_ep0_interrupt(dwc, event);
                return;
        }
                dep->resource_index = 0;
  
                if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 -                      dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",
 +                      dwc3_trace(trace_dwc3_gadget,
 +                                      "%s is an Isochronous endpoint",
                                        dep->name);
                        return;
                }
                                        dep->name, active ? "Transfer Active"
                                        : "Transfer Not Active");
  
 -                      ret = __dwc3_gadget_kick_transfer(dep, 0, !active);
 +                      ret = __dwc3_gadget_kick_transfer(dep, 0);
                        if (!ret || ret == -EBUSY)
                                return;
  
 -                      dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
 +                      dwc3_trace(trace_dwc3_gadget,
 +                                      "%s: failed to kick transfers",
                                        dep->name);
                }
  
                case DEPEVT_STREAMEVT_NOTFOUND:
                        /* FALLTHROUGH */
                default:
 -                      dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
 +                      dwc3_trace(trace_dwc3_gadget,
 +                                      "unable to find suitable stream");
                }
                break;
        case DWC3_DEPEVT_RXTXFIFOEVT:
 -              dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
 +              dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun", dep->name);
                break;
        case DWC3_DEPEVT_EPCMDCMPLT:
                dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete");
@@@ -2330,7 -2196,7 +2343,7 @@@ static void dwc3_stop_active_transfer(s
        cmd |= DWC3_DEPCMD_CMDIOC;
        cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
        memset(&params, 0, sizeof(params));
 -      ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
 +      ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
        dep->flags &= ~DWC3_EP_BUSY;
@@@ -2361,6 -2227,7 +2374,6 @@@ static void dwc3_clear_stall_all_ep(str
  
        for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
                struct dwc3_ep *dep;
 -              struct dwc3_gadget_ep_cmd_params params;
                int ret;
  
                dep = dwc->eps[epnum];
  
                dep->flags &= ~DWC3_EP_STALL;
  
 -              memset(&params, 0, sizeof(params));
 -              ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
 -                              DWC3_DEPCMD_CLEARSTALL, &params);
 +              ret = dwc3_send_clear_stall_ep_cmd(dep);
                WARN_ON_ONCE(ret);
        }
  }
@@@ -2393,8 -2262,6 +2406,8 @@@ static void dwc3_gadget_disconnect_inte
        dwc->gadget.speed = USB_SPEED_UNKNOWN;
        dwc->setup_packet_pending = false;
        usb_gadget_set_state(&dwc->gadget, USB_STATE_NOTATTACHED);
 +
 +      dwc->connected = false;
  }
  
  static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
         *
         * Our suggested workaround is to follow the Disconnect
         * Event steps here, instead, based on a setup_packet_pending
 -       * flag. Such flag gets set whenever we have a XferNotReady
 -       * event on EP0 and gets cleared on XferComplete for the
 +       * flag. Such flag gets set whenever we have a SETUP_PENDING
 +       * status for EP0 TRBs and gets cleared on XferComplete for the
         * same endpoint.
         *
         * Refers to:
@@@ -2487,7 -2354,7 +2500,7 @@@ static void dwc3_gadget_conndone_interr
        dwc3_update_ram_clk_sel(dwc, speed);
  
        switch (speed) {
 -      case DWC3_DCFG_SUPERSPEED:
 +      case DWC3_DSTS_SUPERSPEED:
                /*
                 * WORKAROUND: DWC3 revisions <1.90a have an issue which
                 * would cause a missing USB3 Reset event.
                dwc->gadget.ep0->maxpacket = 512;
                dwc->gadget.speed = USB_SPEED_SUPER;
                break;
 -      case DWC3_DCFG_HIGHSPEED:
 +      case DWC3_DSTS_HIGHSPEED:
                dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
                dwc->gadget.ep0->maxpacket = 64;
                dwc->gadget.speed = USB_SPEED_HIGH;
                break;
 -      case DWC3_DCFG_FULLSPEED2:
 -      case DWC3_DCFG_FULLSPEED1:
 +      case DWC3_DSTS_FULLSPEED2:
 +      case DWC3_DSTS_FULLSPEED1:
                dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
                dwc->gadget.ep0->maxpacket = 64;
                dwc->gadget.speed = USB_SPEED_FULL;
                break;
 -      case DWC3_DCFG_LOWSPEED:
 +      case DWC3_DSTS_LOWSPEED:
                dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);
                dwc->gadget.ep0->maxpacket = 8;
                dwc->gadget.speed = USB_SPEED_LOW;
  
        /* Enable USB2 LPM Capability */
  
 -      if ((dwc->revision > DWC3_REVISION_194A)
 -                      && (speed != DWC3_DCFG_SUPERSPEED)) {
 +      if ((dwc->revision > DWC3_REVISION_194A) &&
 +          (speed != DWC3_DSTS_SUPERSPEED)) {
                reg = dwc3_readl(dwc->regs, DWC3_DCFG);
                reg |= DWC3_DCFG_LPM_CAP;
                dwc3_writel(dwc->regs, DWC3_DCFG, reg);
@@@ -2591,11 -2458,7 +2604,11 @@@ static void dwc3_gadget_wakeup_interrup
         * implemented.
         */
  
 -      dwc->gadget_driver->resume(&dwc->gadget);
 +      if (dwc->gadget_driver && dwc->gadget_driver->resume) {
 +              spin_unlock(&dwc->lock);
 +              dwc->gadget_driver->resume(&dwc->gadget);
 +              spin_lock(&dwc->lock);
 +      }
  }
  
  static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
        dwc->link_state = next;
  }
  
 +static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc,
 +                                        unsigned int evtinfo)
 +{
 +      enum dwc3_link_state next = evtinfo & DWC3_LINK_STATE_MASK;
 +
 +      if (dwc->link_state != next && next == DWC3_LINK_STATE_U3)
 +              dwc3_suspend_gadget(dwc);
 +
 +      dwc->link_state = next;
 +}
 +
  static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
                unsigned int evtinfo)
  {
@@@ -2760,20 -2612,7 +2773,20 @@@ static void dwc3_gadget_interrupt(struc
                dwc3_gadget_linksts_change_interrupt(dwc, event->event_info);
                break;
        case DWC3_DEVICE_EVENT_EOPF:
 -              dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame");
 +              /* It changed to be suspend event for version 2.30a and above */
 +              if (dwc->revision < DWC3_REVISION_230A) {
 +                      dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame");
 +              } else {
 +                      dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event");
 +
 +                      /*
 +                       * Ignore suspend event until the gadget enters into
 +                       * USB_STATE_CONFIGURED state.
 +                       */
 +                      if (dwc->gadget.state >= USB_STATE_CONFIGURED)
 +                              dwc3_gadget_suspend_interrupt(dwc,
 +                                              event->event_info);
 +              }
                break;
        case DWC3_DEVICE_EVENT_SOF:
                dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame");
@@@ -2813,13 -2652,14 +2826,13 @@@ static void dwc3_process_event_entry(st
        }
  }
  
 -static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
 +static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
  {
 -      struct dwc3_event_buffer *evt;
 +      struct dwc3 *dwc = evt->dwc;
        irqreturn_t ret = IRQ_NONE;
        int left;
        u32 reg;
  
 -      evt = dwc->ev_buffs[buf];
        left = evt->count;
  
        if (!(evt->flags & DWC3_EVENT_PENDING))
                evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
                left -= 4;
  
 -              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
 +              dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 4);
        }
  
        evt->count = 0;
        ret = IRQ_HANDLED;
  
        /* Unmask interrupt */
 -      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
 +      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
        reg &= ~DWC3_GEVNTSIZ_INTMASK;
 -      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
 +      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
  
        return ret;
  }
  
 -static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc)
 +static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt)
  {
 -      struct dwc3 *dwc = _dwc;
 +      struct dwc3_event_buffer *evt = _evt;
 +      struct dwc3 *dwc = evt->dwc;
        unsigned long flags;
        irqreturn_t ret = IRQ_NONE;
 -      int i;
  
        spin_lock_irqsave(&dwc->lock, flags);
 -
 -      for (i = 0; i < dwc->num_event_buffers; i++)
 -              ret |= dwc3_process_event_buf(dwc, i);
 -
 +      ret = dwc3_process_event_buf(evt);
        spin_unlock_irqrestore(&dwc->lock, flags);
  
        return ret;
  }
  
 -static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
 +static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
  {
 -      struct dwc3_event_buffer *evt;
 +      struct dwc3 *dwc = evt->dwc;
        u32 count;
        u32 reg;
  
 -      evt = dwc->ev_buffs[buf];
 +      reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 +
 +      if (pm_runtime_suspended(dwc->dev) &&
 +          DWC3_GCTL_PRTCAP(reg) != DWC3_GCTL_PRTCAP_HOST) {
 +              pm_runtime_get(dwc->dev);
 +              disable_irq_nosync(dwc->irq_gadget);
 +              dwc->pending_events = true;
 +              return IRQ_HANDLED;
 +      }
  
 -      count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
 +      count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
        count &= DWC3_GEVNTCOUNT_MASK;
        if (!count)
                return IRQ_NONE;
        evt->flags |= DWC3_EVENT_PENDING;
  
        /* Mask interrupt */
 -      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
 +      reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
        reg |= DWC3_GEVNTSIZ_INTMASK;
 -      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
 +      dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
  
        return IRQ_WAKE_THREAD;
  }
  
 -static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
 +static irqreturn_t dwc3_interrupt(int irq, void *_evt)
  {
 -      struct dwc3                     *dwc = _dwc;
 -      int                             i;
 -      irqreturn_t                     ret = IRQ_NONE;
 -
 -      for (i = 0; i < dwc->num_event_buffers; i++) {
 -              irqreturn_t status;
 +      struct dwc3_event_buffer        *evt = _evt;
  
 -              status = dwc3_check_event_buf(dwc, i);
 -              if (status == IRQ_WAKE_THREAD)
 -                      ret = status;
 -      }
 -
 -      return ret;
 +      return dwc3_check_event_buf(evt);
  }
  
  /**
   */
  int dwc3_gadget_init(struct dwc3 *dwc)
  {
 -      int                                     ret;
 +      int ret, irq;
 +      struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
 +
 +      irq = platform_get_irq_byname(dwc3_pdev, "peripheral");
 +      if (irq == -EPROBE_DEFER)
 +              return irq;
 +
 +      if (irq <= 0) {
 +              irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
 +              if (irq == -EPROBE_DEFER)
 +                      return irq;
 +
 +              if (irq <= 0) {
 +                      irq = platform_get_irq(dwc3_pdev, 0);
 +                      if (irq <= 0) {
 +                              if (irq != -EPROBE_DEFER) {
 +                                      dev_err(dwc->dev,
 +                                              "missing peripheral IRQ\n");
 +                              }
 +                              if (!irq)
 +                                      irq = -EINVAL;
 +                              return irq;
 +                      }
 +              }
 +      }
 +
 +      dwc->irq_gadget = irq;
  
        dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
                        &dwc->ctrl_req_addr, GFP_KERNEL);
                goto err3;
        }
  
 +      dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL);
 +      if (!dwc->zlp_buf) {
 +              ret = -ENOMEM;
 +              goto err4;
 +      }
 +
        dwc->gadget.ops                 = &dwc3_gadget_ops;
        dwc->gadget.speed               = USB_SPEED_UNKNOWN;
        dwc->gadget.sg_supported        = true;
        dwc->gadget.name                = "dwc3-gadget";
 +      dwc->gadget.is_otg              = dwc->dr_mode == USB_DR_MODE_OTG;
  
        /*
         * FIXME We might be setting max_speed to <SUPER, however versions
         */
        if (dwc->revision < DWC3_REVISION_220A)
                dwc3_trace(trace_dwc3_gadget,
 -                              "Changing max_speed on rev %08x\n",
 +                              "Changing max_speed on rev %08x",
                                dwc->revision);
  
        dwc->gadget.max_speed           = dwc->maximum_speed;
  
        ret = dwc3_gadget_init_endpoints(dwc);
        if (ret)
 -              goto err4;
 +              goto err5;
  
        ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
        if (ret) {
                dev_err(dwc->dev, "failed to register udc\n");
 -              goto err4;
 +              goto err5;
        }
  
        return 0;
  
 +err5:
 +      kfree(dwc->zlp_buf);
 +
  err4:
        dwc3_gadget_free_endpoints(dwc);
        dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
@@@ -3072,7 -2881,6 +3085,7 @@@ void dwc3_gadget_exit(struct dwc3 *dwc
                        dwc->ep0_bounce, dwc->ep0_bounce_addr);
  
        kfree(dwc->setup_buf);
 +      kfree(dwc->zlp_buf);
  
        dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
                        dwc->ep0_trb, dwc->ep0_trb_addr);
  
  int dwc3_gadget_suspend(struct dwc3 *dwc)
  {
 -      if (dwc->pullups_connected) {
 -              dwc3_gadget_disable_irq(dwc);
 -              dwc3_gadget_run_stop(dwc, true, true);
 -      }
 +      int ret;
  
 -      __dwc3_gadget_ep_disable(dwc->eps[0]);
 -      __dwc3_gadget_ep_disable(dwc->eps[1]);
 +      if (!dwc->gadget_driver)
 +              return 0;
 +
 +      ret = dwc3_gadget_run_stop(dwc, false, false);
 +      if (ret < 0)
 +              dev_err(dwc->dev, "dwc3 gadget stop timeout\n");
  
 -      dwc->dcfg = dwc3_readl(dwc->regs, DWC3_DCFG);
 +      dwc3_disconnect_gadget(dwc);
 +      __dwc3_gadget_stop(dwc);
  
        return 0;
  }
  
  int dwc3_gadget_resume(struct dwc3 *dwc)
  {
 -      struct dwc3_ep          *dep;
        int                     ret;
  
 -      /* Start with SuperSpeed Default */
 -      dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 +      if (!dwc->gadget_driver)
 +              return 0;
  
 -      dep = dwc->eps[0];
 -      ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
 -                      false);
 -      if (ret)
 +      ret = __dwc3_gadget_start(dwc);
 +      if (ret < 0)
                goto err0;
  
 -      dep = dwc->eps[1];
 -      ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
 -                      false);
 -      if (ret)
 +      ret = dwc3_gadget_run_stop(dwc, true, false);
 +      if (ret < 0)
                goto err1;
  
 -      /* begin to receive SETUP packets */
 -      dwc->ep0state = EP0_SETUP_PHASE;
 -      dwc3_ep0_out_start(dwc);
 -
 -      dwc3_writel(dwc->regs, DWC3_DCFG, dwc->dcfg);
 -
 -      if (dwc->pullups_connected) {
 -              dwc3_gadget_enable_irq(dwc);
 -              dwc3_gadget_run_stop(dwc, true, false);
 -      }
 -
        return 0;
  
  err1:
 -      __dwc3_gadget_ep_disable(dwc->eps[0]);
 +      __dwc3_gadget_stop(dwc);
  
  err0:
        return ret;
  }
 +
 +void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
 +{
 +      if (dwc->pending_events) {
 +              dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
 +              dwc->pending_events = false;
 +              enable_irq(dwc->irq_gadget);
 +      }
 +}
index 49dbef82a8622aed75d4d5301815dad2c44375d1,76b8ae08a55168609141b2849c7001b9705497fb..36fdb9d5f0424c0aaeb1391efd50b2b7c82379e7
@@@ -77,9 -77,13 +77,13 @@@ struct acc_dev 
        struct usb_ep *ep_in;
        struct usb_ep *ep_out;
  
-       /* set to 1 when we connect */
+       /* online indicates state of function_set_alt & function_unbind
+        * set to 1 when we connect
+        */
        int online:1;
-       /* Set to 1 when we disconnect.
+       /* disconnected indicates state of open & release
+        * Set to 1 when we disconnect.
         * Not cleared until our file is closed.
         */
        int disconnected:1;
@@@ -263,7 -267,6 +267,6 @@@ static struct usb_request *req_get(stru
  
  static void acc_set_disconnected(struct acc_dev *dev)
  {
-       dev->online = 0;
        dev->disconnected = 1;
  }
  
@@@ -676,9 -679,10 +679,10 @@@ static ssize_t acc_write(struct file *f
                        req->zero = 0;
                } else {
                        xfer = count;
-                       /* If the data length is a multple of the
+                       /*
+                        * If the data length is a multple of the
                         * maxpacket size then send a zero length packet(ZLP).
-                       */
+                        */
                        req->zero = ((xfer % dev->ep_in->maxpacket) == 0);
                }
                if (copy_from_user(req->buf, buf, xfer)) {
@@@ -763,7 -767,10 +767,10 @@@ static int acc_release(struct inode *ip
        printk(KERN_INFO "acc_release\n");
  
        WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0));
-       _acc_dev->disconnected = 0;
+       /* indicate that we are disconnected
+        * still could be online so don't touch online flag
+        */
+       _acc_dev->disconnected = 1;
        return 0;
  }
  
@@@ -773,9 -780,6 +780,9 @@@ static const struct file_operations acc
        .read = acc_read,
        .write = acc_write,
        .unlocked_ioctl = acc_ioctl,
 +#ifdef CONFIG_COMPAT
 +      .compat_ioctl = acc_ioctl,
 +#endif
        .open = acc_open,
        .release = acc_release,
  };
@@@ -823,11 -827,11 +830,11 @@@ int acc_ctrlrequest(struct usb_composit
        unsigned long flags;
  
  /*
-       printk(KERN_INFO "acc_ctrlrequest "
-                       "%02x.%02x v%04x i%04x l%u\n",
-                       b_requestType, b_request,
-                       w_value, w_index, w_length);
- */
+  *    printk(KERN_INFO "acc_ctrlrequest "
+  *                    "%02x.%02x v%04x i%04x l%u\n",
+  *                    b_requestType, b_request,
+  *                    w_value, w_index, w_length);
 */
  
        if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) {
                if (b_request == ACCESSORY_START) {
@@@ -1014,6 -1018,10 +1021,10 @@@ acc_function_unbind(struct usb_configur
        struct usb_request *req;
        int i;
  
+       dev->online = 0;                /* clear online flag */
+       wake_up(&dev->read_wq);         /* unblock reads on closure */
+       wake_up(&dev->write_wq);        /* likewise for writes */
        while ((req = req_get(dev, &dev->tx_idle)))
                acc_request_free(req, dev->ep_in);
        for (i = 0; i < RX_REQ_MAX; i++)
@@@ -1145,6 -1153,7 +1156,7 @@@ static int acc_function_set_alt(struct 
        }
  
        dev->online = 1;
+       dev->disconnected = 0; /* if online then not disconnected */
  
        /* readers may be blocked waiting for us to go online */
        wake_up(&dev->read_wq);
@@@ -1157,7 -1166,8 +1169,8 @@@ static void acc_function_disable(struc
        struct usb_composite_dev        *cdev = dev->cdev;
  
        DBG(cdev, "acc_function_disable\n");
-       acc_set_disconnected(dev);
+       acc_set_disconnected(dev); /* this now only sets disconnected */
+       dev->online = 0; /* so now need to clear online flag here too */
        usb_ep_disable(dev->ep_in);
        usb_ep_disable(dev->ep_out);
  
index e37ece7b6e3ea632d131174c4cd17af5dd4d81d1,b37cc8d87ca44f41cb8922699780a7e20959ab29..ca82e43f73a592f1638dbc77b035c4c58adda93c
@@@ -540,10 -540,12 +540,12 @@@ static ssize_t mtp_read(struct file *fp
        ssize_t r = count;
        unsigned xfer;
        int ret = 0;
+       size_t len;
  
        DBG(cdev, "mtp_read(%zu)\n", count);
  
-       if (count > MTP_BULK_BUFFER_SIZE)
+       len = usb_ep_align_maybe(cdev->gadget, dev->ep_out, count);
+       if (len > MTP_BULK_BUFFER_SIZE)
                return -EINVAL;
  
        /* we will block until we're online */
  requeue_req:
        /* queue a request */
        req = dev->rx_req[0];
-       req->length = count;
+       req->length = len;
        dev->rx_done = 0;
        ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
        if (ret < 0) {
@@@ -1009,25 -1011,6 +1011,25 @@@ static long mtp_ioctl(struct file *fp, 
                        ret = mtp_send_event(dev, &event);
                goto out;
        }
 +#ifdef CONFIG_COMPAT
 +      case MTP_SEND_EVENT_32:
 +      {
 +              struct mtp_event_32     event_32;
 +              struct mtp_event        event;
 +              /* return here so we don't change dev->state below,
 +               * which would interfere with bulk transfer state.
 +               */
 +              if (copy_from_user(&event_32, (void __user *)value,
 +                                 sizeof(event_32)))
 +                      ret = -EFAULT;
 +              else {
 +                      event.length = event_32.length;
 +                      event.data = (void *)(unsigned long)event_32.data;
 +                      ret = mtp_send_event(dev, &event);
 +              }
 +              goto out;
 +      }
 +#endif
        }
  
  fail:
@@@ -1071,9 -1054,6 +1073,9 @@@ static const struct file_operations mtp
        .read = mtp_read,
        .write = mtp_write,
        .unlocked_ioctl = mtp_ioctl,
 +#ifdef CONFIG_COMPAT
 +      .compat_ioctl = mtp_ioctl,
 +#endif
        .open = mtp_open,
        .release = mtp_release,
  };
diff --combined fs/proc/task_mmu.c
index 25d70a001c519c1ec48bebee9b6c501f92b64497,2bd15577abe21ef119b782e247bf45689e4c654e..9799ec20446143ae17113bcaa2f4dc3a8efa5075
@@@ -865,7 -865,14 +865,14 @@@ static inline void clear_soft_dirty(str
  static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma,
                unsigned long addr, pmd_t *pmdp)
  {
-       pmd_t pmd = pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp);
+       pmd_t pmd = *pmdp;
+       /* See comment in change_huge_pmd() */
+       pmdp_invalidate(vma, addr, pmdp);
+       if (pmd_dirty(*pmdp))
+               pmd = pmd_mkdirty(pmd);
+       if (pmd_young(*pmdp))
+               pmd = pmd_mkyoung(pmd);
  
        pmd = pmd_wrprotect(pmd);
        pmd = pmd_clear_soft_dirty(pmd);
@@@ -1396,16 -1403,6 +1403,16 @@@ static int pagemap_open(struct inode *i
  {
        struct mm_struct *mm;
  
 +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_ANDROID)
 +      /*
 +       * For pass CTS
 +       * FileSystemPermissionTest: Assert /proc/self/pagemap not readable
 +       */
 +      /* do not disclose physical addresses: attack vector */
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EPERM;
 +#endif
 +
        mm = proc_mem_open(inode, PTRACE_MODE_READ);
        if (IS_ERR(mm))
                return PTR_ERR(mm);
diff --combined include/linux/mmc/card.h
index 22defc2a83b78ca720f2e8666d540120f5fccc6b,8f23fb2c5ed275c2d2fb79a7943eff8b55ebffb5..fca73a076ec077d9379f4dd237d5fc8566298e46
@@@ -95,7 -95,6 +95,7 @@@ struct mmc_ext_csd 
        u8                      raw_partition_support;  /* 160 */
        u8                      raw_rpmb_size_mult;     /* 168 */
        u8                      raw_erased_mem_count;   /* 181 */
 +      u8                      strobe_support;         /* 184 */
        u8                      raw_ext_csd_structure;  /* 194 */
        u8                      raw_card_type;          /* 196 */
        u8                      raw_driver_strength;    /* 197 */
        u8                      raw_pwr_cl_ddr_200_360; /* 253 */
        u8                      raw_bkops_status;       /* 246 */
        u8                      raw_sectors[4];         /* 212 - 4 bytes */
+       u8                      pre_eol_info;           /* 267 */
+       u8                      device_life_time_est_typ_a;     /* 268 */
+       u8                      device_life_time_est_typ_b;     /* 269 */
  
        unsigned int            feature_support;
  #define MMC_DISCARD_FEATURE   BIT(0)                  /* CMD38 feature */
diff --combined include/linux/mmc/mmc.h
index c376209c70ef4424e19e342c441670439c8a7d68,2c6b1d45626ef9ae8f34e150b803cf43ebe56140..a034d07c218d17ecb79ba416078bdf6397689abe
@@@ -297,7 -297,6 +297,7 @@@ struct _mmc_csd 
  #define EXT_CSD_PART_CONFIG           179     /* R/W */
  #define EXT_CSD_ERASED_MEM_CONT               181     /* RO */
  #define EXT_CSD_BUS_WIDTH             183     /* R/W */
 +#define EXT_CSD_STROBE_SUPPORT                184     /* RO */
  #define EXT_CSD_HS_TIMING             185     /* R/W */
  #define EXT_CSD_POWER_CLASS           187     /* R/W */
  #define EXT_CSD_REV                   192     /* RO */
  #define EXT_CSD_CACHE_SIZE            249     /* RO, 4 bytes */
  #define EXT_CSD_PWR_CL_DDR_200_360    253     /* RO */
  #define EXT_CSD_FIRMWARE_VERSION      254     /* RO, 8 bytes */
+ #define EXT_CSD_PRE_EOL_INFO          267     /* RO */
+ #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A    268     /* RO */
+ #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B    269     /* RO */
  #define EXT_CSD_SUPPORTED_MODE                493     /* RO */
  #define EXT_CSD_TAG_UNIT_SIZE         498     /* RO */
  #define EXT_CSD_DATA_TAG_SUPPORT      499     /* RO */
  #define EXT_CSD_CARD_TYPE_HS400_1_2V  (1<<7)  /* Card can run at 200MHz DDR, 1.2V */
  #define EXT_CSD_CARD_TYPE_HS400               (EXT_CSD_CARD_TYPE_HS400_1_8V | \
                                         EXT_CSD_CARD_TYPE_HS400_1_2V)
 +#define EXT_CSD_CARD_TYPE_HS400ES     (1<<8)  /* Card can run at HS400ES */
  
  #define EXT_CSD_BUS_WIDTH_1   0       /* Card is in 1 bit mode */
  #define EXT_CSD_BUS_WIDTH_4   1       /* Card is in 4 bit mode */
  #define EXT_CSD_BUS_WIDTH_8   2       /* Card is in 8 bit mode */
  #define EXT_CSD_DDR_BUS_WIDTH_4       5       /* Card is in 4 bit DDR mode */
  #define EXT_CSD_DDR_BUS_WIDTH_8       6       /* Card is in 8 bit DDR mode */
 +#define EXT_CSD_BUS_WIDTH_STROBE BIT(7)       /* Enhanced strobe mode */
  
  #define EXT_CSD_TIMING_BC     0       /* Backwards compatility */
  #define EXT_CSD_TIMING_HS     1       /* High speed */
index 56939098675ef0ce0f9b25596be7b76838f15f85,de2a722fe3cf7c457352eb02548f0351a669ddf5..594385d1ad363e0639c4c9d41175a15ac06b8e3a
  /* device can't handle Link Power Management */
  #define USB_QUIRK_NO_LPM                      BIT(10)
  
- #define USB_QUIRK_AUTO_SUSPEND                        BIT(11)
+ /*
+  * Device reports its bInterval as linear frames instead of the
+  * USB 2.0 calculation.
+  */
+ #define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
 +/* device can't support auto suspend function */
++#define USB_QUIRK_AUTO_SUSPEND                        BIT(12)
 +
  #endif /* __LINUX_USB_QUIRKS_H */
diff --combined kernel/sched/fair.c
index f03f54704c6d6036ec7f73b065c5675a32dbbb2b,83cfb72b2d95a0ad3f32f9331077ef63a1e96ba1..a87426f6033491897190f7cfa9cbf633af149b2c
@@@ -4919,7 -4919,7 +4919,7 @@@ long group_norm_util(struct energy_env 
  }
  
  static int find_new_capacity(struct energy_env *eenv,
-       const struct sched_group_energy const *sge)
+       const struct sched_group_energy * const sge)
  {
        int idx;
        unsigned long util = group_max_util(eenv);
@@@ -7128,10 -7128,8 +7128,10 @@@ static void update_cpu_capacity(struct 
                mcc->cpu = cpu;
  #ifdef CONFIG_SCHED_DEBUG
                raw_spin_unlock_irqrestore(&mcc->lock, flags);
 +/*
                printk_deferred(KERN_INFO "CPU%d: update max cpu_capacity %lu\n",
                                cpu, capacity);
 +*/
                goto skip_unlock;
  #endif
        }