commit:     26c3d37f6333cc85f0ab2f9107f9ee2103f0ea29
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Jan 27 23:57:45 2015 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Jan 27 23:57:45 2015 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/linux-patches.git;a=commit;h=26c3d37f

Linux patch 3.10.66

---
 0000_README              |    6 +-
 1065_linux-3.10.66.patch | 1519 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1524 insertions(+), 1 deletion(-)

diff --git a/0000_README b/0000_README
index 755963e..1f0923b 100644
--- a/0000_README
+++ b/0000_README
@@ -298,10 +298,14 @@ Patch:  1063_linux-3.10.64.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.10.64
 
-Patch:  1063_linux-3.10.65.patch
+Patch:  1064_linux-3.10.65.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.10.65
 
+Patch:  1065_linux-3.10.66.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.10.66
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1065_linux-3.10.66.patch b/1065_linux-3.10.66.patch
new file mode 100644
index 0000000..4cd0ef4
--- /dev/null
+++ b/1065_linux-3.10.66.patch
@@ -0,0 +1,1519 @@
+diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
+index 1311a48a7367..98da831a14ba 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1061,6 +1061,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
+       i8042.notimeout [HW] Ignore timeout condition signalled by controller
+       i8042.reset     [HW] Reset the controller during init and cleanup
+       i8042.unlock    [HW] Unlock (ignore) the keylock
++      i8042.kbdreset  [HW] Reset device connected to KBD port
+ 
+       i810=           [HW,DRM]
+ 
+diff --git a/Makefile b/Makefile
+index 7889b38766db..12ae1ef5437a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 10
+-SUBLEVEL = 65
++SUBLEVEL = 66
+ EXTRAVERSION =
+ NAME = TOSSUG Baby Fish
+ 
+diff --git a/arch/arc/boot/dts/nsimosci.dts b/arch/arc/boot/dts/nsimosci.dts
+index 398064cef746..4c169d825415 100644
+--- a/arch/arc/boot/dts/nsimosci.dts
++++ b/arch/arc/boot/dts/nsimosci.dts
+@@ -20,7 +20,7 @@
+               /* this is for console on PGU */
+               /* bootargs = "console=tty0 consoleblank=0"; */
+               /* this is for console on serial */
+-              bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 
console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
++              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 
console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
+       };
+ 
+       aliases {
+@@ -46,9 +46,9 @@
+                       #interrupt-cells = <1>;
+               };
+ 
+-              uart0: serial@c0000000 {
++              uart0: serial@f0000000 {
+                       compatible = "ns8250";
+-                      reg = <0xc0000000 0x2000>;
++                      reg = <0xf0000000 0x2000>;
+                       interrupts = <11>;
+                       clock-frequency = <3686400>;
+                       baud = <115200>;
+@@ -57,21 +57,21 @@
+                       no-loopback-test = <1>;
+               };
+ 
+-              pgu0: pgu@c9000000 {
++              pgu0: pgu@f9000000 {
+                       compatible = "snps,arcpgufb";
+-                      reg = <0xc9000000 0x400>;
++                      reg = <0xf9000000 0x400>;
+               };
+ 
+-              ps2: ps2@c9001000 {
++              ps2: ps2@f9001000 {
+                       compatible = "snps,arc_ps2";
+-                      reg = <0xc9000400 0x14>;
++                      reg = <0xf9000400 0x14>;
+                       interrupts = <13>;
+                       interrupt-names = "arc_ps2_irq";
+               };
+ 
+-              eth0: ethernet@c0003000 {
++              eth0: ethernet@f0003000 {
+                       compatible = "snps,oscilan";
+-                      reg = <0xc0003000 0x44>;
++                      reg = <0xf0003000 0x44>;
+                       interrupts = <7>, <8>;
+                       interrupt-names = "rx", "tx";
+               };
+diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
+index 701153992c69..82897e2d8d5a 100644
+--- a/arch/arm/boot/dts/imx25.dtsi
++++ b/arch/arm/boot/dts/imx25.dtsi
+@@ -141,7 +141,7 @@
+                               #size-cells = <0>;
+                               compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+                               reg = <0x43fa4000 0x4000>;
+-                              clocks = <&clks 62>, <&clks 62>;
++                              clocks = <&clks 78>, <&clks 78>;
+                               clock-names = "ipg", "per";
+                               interrupts = <14>;
+                               status = "disabled";
+diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
+index 0b9e437719bd..2acaded8025d 100644
+--- a/arch/arm/mach-imx/clk-imx6q.c
++++ b/arch/arm/mach-imx/clk-imx6q.c
+@@ -301,8 +301,8 @@ int __init mx6q_clocks_init(void)
+               post_div_table[1].div = 1;
+               post_div_table[2].div = 1;
+               video_div_table[1].div = 1;
+-              video_div_table[2].div = 1;
+-      };
++              video_div_table[3].div = 1;
++      }
+ 
+       /*                   type                               name         
parent_name  base     div_mask */
+       clk[pll1_sys]      = imx_clk_pllv3(IMX_PLLV3_SYS,       "pll1_sys",     
"osc", base,        0x7f);
+diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
+index f8b23b8040d9..3f3259e74fd3 100644
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -503,11 +503,11 @@ static void __init realtime_counter_init(void)
+       rate = clk_get_rate(sys_clk);
+       /* Numerator/denumerator values refer TRM Realtime Counter section */
+       switch (rate) {
+-      case 1200000:
++      case 12000000:
+               num = 64;
+               den = 125;
+               break;
+-      case 1300000:
++      case 13000000:
+               num = 768;
+               den = 1625;
+               break;
+@@ -515,11 +515,11 @@ static void __init realtime_counter_init(void)
+               num = 8;
+               den = 25;
+               break;
+-      case 2600000:
++      case 26000000:
+               num = 384;
+               den = 1625;
+               break;
+-      case 2700000:
++      case 27000000:
+               num = 256;
+               den = 1125;
+               break;
+diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c 
b/arch/arm/mach-shmobile/setup-sh73a0.c
+index 9696f3646864..ea788c8e32e8 100644
+--- a/arch/arm/mach-shmobile/setup-sh73a0.c
++++ b/arch/arm/mach-shmobile/setup-sh73a0.c
+@@ -814,6 +814,7 @@ static struct platform_device ipmmu_device = {
+ 
+ static struct renesas_intc_irqpin_config irqpin0_platform_data = {
+       .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
++      .control_parent = true,
+ };
+ 
+ static struct resource irqpin0_resources[] = {
+@@ -875,6 +876,7 @@ static struct platform_device irqpin1_device = {
+ 
+ static struct renesas_intc_irqpin_config irqpin2_platform_data = {
+       .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
++      .control_parent = true,
+ };
+ 
+ static struct resource irqpin2_resources[] = {
+@@ -905,6 +907,7 @@ static struct platform_device irqpin2_device = {
+ 
+ static struct renesas_intc_irqpin_config irqpin3_platform_data = {
+       .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
++      .control_parent = true,
+ };
+ 
+ static struct resource irqpin3_resources[] = {
+diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
+index bceee6623b00..d1ff46c0559b 100644
+--- a/arch/um/Kconfig.common
++++ b/arch/um/Kconfig.common
+@@ -8,6 +8,7 @@ config UML
+       default y
+       select HAVE_GENERIC_HARDIRQS
+       select HAVE_UID16
++      select HAVE_FUTEX_CMPXCHG if FUTEX
+       select GENERIC_IRQ_SHOW
+       select GENERIC_CPU_DEVICES
+       select GENERIC_IO
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 211bce445522..0c6c07cea3f7 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -1017,6 +1017,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, 
struct pt_regs *regs)
+       regs->flags &= ~X86_EFLAGS_IF;
+       trace_hardirqs_off();
+       regs->ip = (unsigned long)(jp->entry);
++
++      /*
++       * jprobes use jprobe_return() which skips the normal return
++       * path of the function, and this messes up the accounting of the
++       * function graph tracer to get messed up.
++       *
++       * Pause function graph tracing while performing the jprobe function.
++       */
++      pause_graph_tracing();
+       return 1;
+ }
+ 
+@@ -1042,24 +1051,25 @@ int __kprobes longjmp_break_handler(struct kprobe *p, 
struct pt_regs *regs)
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+       u8 *addr = (u8 *) (regs->ip - 1);
+       struct jprobe *jp = container_of(p, struct jprobe, kp);
++      void *saved_sp = kcb->jprobe_saved_sp;
+ 
+       if ((addr > (u8 *) jprobe_return) &&
+           (addr < (u8 *) jprobe_return_end)) {
+-              if (stack_addr(regs) != kcb->jprobe_saved_sp) {
++              if (stack_addr(regs) != saved_sp) {
+                       struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
+                       printk(KERN_ERR
+                              "current sp %p does not match saved sp %p\n",
+-                             stack_addr(regs), kcb->jprobe_saved_sp);
++                             stack_addr(regs), saved_sp);
+                       printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
+                       show_regs(saved_regs);
+                       printk(KERN_ERR "Current registers\n");
+                       show_regs(regs);
+                       BUG();
+               }
++              /* It's OK to start function graph tracing again */
++              unpause_graph_tracing();
+               *regs = kcb->jprobe_saved_regs;
+-              memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp),
+-                     kcb->jprobes_stack,
+-                     MIN_STACK_SIZE(kcb->jprobe_saved_sp));
++              memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
+               preempt_enable_no_resched();
+               return 1;
+       }
+diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
+index 531d4269e2e3..bd16d6c370ec 100644
+--- a/arch/x86/um/sys_call_table_32.c
++++ b/arch/x86/um/sys_call_table_32.c
+@@ -34,7 +34,7 @@ typedef asmlinkage void (*sys_call_ptr_t)(void);
+ 
+ extern asmlinkage void sys_ni_syscall(void);
+ 
+-const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
++const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
+       /*
+        * Smells like a compiler bug -- it doesn't work
+        * when the & below is removed.
+diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
+index f2f0723070ca..95783087f0d3 100644
+--- a/arch/x86/um/sys_call_table_64.c
++++ b/arch/x86/um/sys_call_table_64.c
+@@ -46,7 +46,7 @@ typedef void (*sys_call_ptr_t)(void);
+ 
+ extern void sys_ni_syscall(void);
+ 
+-const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
++const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
+       /*
+        * Smells like a compiler bug -- it doesn't work
+        * when the & below is removed.
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index 665f9530c950..af909a20dd70 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -12,6 +12,7 @@
+  */
+ 
+ #include <linux/device.h>
++#include <linux/err.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
+ #include <linux/io.h>
+@@ -42,8 +43,14 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, 
void *data)
+               return false;
+ 
+       ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags);
+-      if (ret < 0)
+-              return false;
++      if (ret < 0) {
++              /* We've found the gpio chip, but the translation failed.
++               * Return true to stop looking and return the translation
++               * error via out_gpio
++               */
++              gg_data->out_gpio = ERR_PTR(ret);
++              return true;
++       }
+ 
+       gg_data->out_gpio = ret + gc->base;
+       return true;
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
+index 2d90f96c19d0..7695b5dd9d2d 100644
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -317,6 +317,7 @@
+ #define   PIPE_CONTROL_GLOBAL_GTT_IVB                 (1<<24) /* gen7+ */
+ #define   PIPE_CONTROL_CS_STALL                               (1<<20)
+ #define   PIPE_CONTROL_TLB_INVALIDATE                 (1<<18)
++#define   PIPE_CONTROL_MEDIA_STATE_CLEAR              (1<<16)
+ #define   PIPE_CONTROL_QW_WRITE                               (1<<14)
+ #define   PIPE_CONTROL_DEPTH_STALL                    (1<<13)
+ #define   PIPE_CONTROL_WRITE_FLUSH                    (1<<12)
+diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
+index 4605c3877c95..ef4cde15c15c 100644
+--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
+@@ -314,12 +314,15 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
+               flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
++              flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
+               /*
+                * TLB invalidate requires a post-sync write.
+                */
+               flags |= PIPE_CONTROL_QW_WRITE;
+               flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+ 
++              flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD;
++
+               /* Workaround: we must issue a pipe_control with CS-stall bit
+                * set before a pipe_control command that has the state cache
+                * invalidate bit set. */
+diff --git a/drivers/gpu/drm/radeon/atombios_dp.c 
b/drivers/gpu/drm/radeon/atombios_dp.c
+index 4c05f2b015cf..d4a5118911fd 100644
+--- a/drivers/gpu/drm/radeon/atombios_dp.c
++++ b/drivers/gpu/drm/radeon/atombios_dp.c
+@@ -574,6 +574,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector 
*connector,
+       struct radeon_connector_atom_dig *dig_connector;
+       int dp_clock;
+ 
++      if ((mode->clock > 340000) &&
++          (!radeon_connector_is_dp12_capable(connector)))
++              return MODE_CLOCK_HIGH;
++
+       if (!radeon_connector->con_priv)
+               return MODE_CLOCK_HIGH;
+       dig_connector = radeon_connector->con_priv;
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
+index 6c0ce8915fac..4a14e113369d 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -189,7 +189,7 @@ static void radeon_evict_flags(struct ttm_buffer_object 
*bo,
+       rbo = container_of(bo, struct radeon_bo, tbo);
+       switch (bo->mem.mem_type) {
+       case TTM_PL_VRAM:
+-              if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false)
++              if (rbo->rdev->ring[radeon_copy_ring_index(rbo->rdev)].ready == 
false)
+                       radeon_ttm_placement_from_domain(rbo, 
RADEON_GEM_DOMAIN_CPU);
+               else
+                       radeon_ttm_placement_from_domain(rbo, 
RADEON_GEM_DOMAIN_GTT);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+index c62d20e8a6f1..ee742f14ddc2 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -1049,6 +1049,8 @@ int vmw_event_fence_action_create(struct drm_file 
*file_priv,
+       if (ret != 0)
+               goto out_no_queue;
+ 
++      return 0;
++
+ out_no_queue:
+       event->base.destroy(&event->base);
+ out_no_event:
+@@ -1123,17 +1125,10 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void 
*data,
+ 
+       BUG_ON(fence == NULL);
+ 
+-      if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME)
+-              ret = vmw_event_fence_action_create(file_priv, fence,
+-                                                  arg->flags,
+-                                                  arg->user_data,
+-                                                  true);
+-      else
+-              ret = vmw_event_fence_action_create(file_priv, fence,
+-                                                  arg->flags,
+-                                                  arg->user_data,
+-                                                  true);
+-
++      ret = vmw_event_fence_action_create(file_priv, fence,
++                                          arg->flags,
++                                          arg->user_data,
++                                          true);
+       if (unlikely(ret != 0)) {
+               if (ret != -ERESTARTSYS)
+                       DRM_ERROR("Failed to attach event to fence.\n");
+diff --git a/drivers/input/serio/i8042-x86ia64io.h 
b/drivers/input/serio/i8042-x86ia64io.h
+index ce715b1bee46..78227f32d6fa 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -408,6 +408,13 @@ static const struct dmi_system_id __initconst 
i8042_dmi_nomux_table[] = {
+               },
+       },
+       {
++              /* Acer Aspire 7738 */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
++              },
++      },
++      {
+               /* Gericom Bellagio */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+@@ -721,6 +728,35 @@ static const struct dmi_system_id __initconst 
i8042_dmi_dritek_table[] = {
+       { }
+ };
+ 
++/*
++ * Some laptops need keyboard reset before probing for the trackpad to get
++ * it detected, initialised & finally work.
++ */
++static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
++      {
++              /* Gigabyte P35 v2 - Elantech touchpad */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
++              },
++      },
++              {
++              /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
++              },
++      },
++      {
++              /* Gigabyte P34 - Elantech touchpad */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
++              },
++      },
++      { }
++};
++
+ #endif /* CONFIG_X86 */
+ 
+ #ifdef CONFIG_PNP
+@@ -1001,6 +1037,9 @@ static int __init i8042_platform_init(void)
+       if (dmi_check_system(i8042_dmi_dritek_table))
+               i8042_dritek = true;
+ 
++      if (dmi_check_system(i8042_dmi_kbdreset_table))
++              i8042_kbdreset = true;
++
+       /*
+        * A20 was already enabled during early kernel init. But some buggy
+        * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index 78e4de42efaa..9870c540e6fb 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -67,6 +67,10 @@ static bool i8042_notimeout;
+ module_param_named(notimeout, i8042_notimeout, bool, 0);
+ MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042");
+ 
++static bool i8042_kbdreset;
++module_param_named(kbdreset, i8042_kbdreset, bool, 0);
++MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port");
++
+ #ifdef CONFIG_X86
+ static bool i8042_dritek;
+ module_param_named(dritek, i8042_dritek, bool, 0);
+@@ -783,6 +787,16 @@ static int __init i8042_check_aux(void)
+               return -1;
+ 
+ /*
++ * Reset keyboard (needed on some laptops to successfully detect
++ * touchpad, e.g., some Gigabyte laptop models with Elantech
++ * touchpads).
++ */
++      if (i8042_kbdreset) {
++              pr_warn("Attempting to reset device connected to KBD port\n");
++              i8042_kbd_write(NULL, (unsigned char) 0xff);
++      }
++
++/*
+  * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
+  * used it for a PCI card or somethig else.
+  */
+diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c
+index d8d5da7c52db..942305129e15 100644
+--- a/drivers/media/i2c/smiapp-pll.c
++++ b/drivers/media/i2c/smiapp-pll.c
+@@ -67,7 +67,7 @@ static void print_pll(struct device *dev, struct smiapp_pll 
*pll)
+ {
+       dev_dbg(dev, "pre_pll_clk_div\t%d\n",  pll->pre_pll_clk_div);
+       dev_dbg(dev, "pll_multiplier \t%d\n",  pll->pll_multiplier);
+-      if (pll->flags != SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
++      if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) {
+               dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div);
+               dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div);
+       }
+@@ -77,7 +77,7 @@ static void print_pll(struct device *dev, struct smiapp_pll 
*pll)
+       dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz);
+       dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz);
+       dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz);
+-      if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
++      if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) {
+               dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n",
+                       pll->op_sys_clk_freq_hz);
+               dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n",
+diff --git a/drivers/media/i2c/smiapp/smiapp-core.c 
b/drivers/media/i2c/smiapp/smiapp-core.c
+index b280216de31b..de8bc35d8b0b 100644
+--- a/drivers/media/i2c/smiapp/smiapp-core.c
++++ b/drivers/media/i2c/smiapp/smiapp-core.c
+@@ -2629,7 +2629,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
+               pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
+       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+ 
++      mutex_lock(&sensor->mutex);
+       rval = smiapp_update_mode(sensor);
++      mutex_unlock(&sensor->mutex);
+       if (rval) {
+               dev_err(&client->dev, "update mode failed\n");
+               goto out_nvm_release;
+diff --git a/drivers/media/usb/dvb-usb/af9005.c 
b/drivers/media/usb/dvb-usb/af9005.c
+index af176b6ce738..e6d3561eea47 100644
+--- a/drivers/media/usb/dvb-usb/af9005.c
++++ b/drivers/media/usb/dvb-usb/af9005.c
+@@ -1081,9 +1081,12 @@ static int __init af9005_usb_module_init(void)
+               err("usb_register failed. (%d)", result);
+               return result;
+       }
++#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE)
++      /* FIXME: convert to todays kernel IR infrastructure */
+       rc_decode = symbol_request(af9005_rc_decode);
+       rc_keys = symbol_request(rc_map_af9005_table);
+       rc_keys_size = symbol_request(rc_map_af9005_table_size);
++#endif
+       if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
+               err("af9005_rc_decode function not found, disabling remote");
+               af9005_properties.rc.legacy.rc_query = NULL;
+diff --git a/drivers/media/usb/uvc/uvc_driver.c 
b/drivers/media/usb/uvc/uvc_driver.c
+index 5dbefa68b1d2..363cdbf4ac8d 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1603,12 +1603,12 @@ static void uvc_delete(struct uvc_device *dev)
+ {
+       struct list_head *p, *n;
+ 
+-      usb_put_intf(dev->intf);
+-      usb_put_dev(dev->udev);
+-
+       uvc_status_cleanup(dev);
+       uvc_ctrl_cleanup_device(dev);
+ 
++      usb_put_intf(dev->intf);
++      usb_put_dev(dev->udev);
++
+       if (dev->vdev.dev)
+               v4l2_device_unregister(&dev->vdev);
+ #ifdef CONFIG_MEDIA_CONTROLLER
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 2ea429c27714..836e2ac36a0d 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1316,6 +1316,8 @@ static void sdhci_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
+ 
+       sdhci_runtime_pm_get(host);
+ 
++      present = mmc_gpio_get_cd(host->mmc);
++
+       spin_lock_irqsave(&host->lock, flags);
+ 
+       WARN_ON(host->mrq != NULL);
+@@ -1344,7 +1346,6 @@ static void sdhci_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
+        *     zero: cd-gpio is used, and card is removed
+        *     one: cd-gpio is used, and card is present
+        */
+-      present = mmc_gpio_get_cd(host->mmc);
+       if (present < 0) {
+               /* If polling, assume that the card is always present. */
+               if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+diff --git a/drivers/net/can/usb/kvaser_usb.c 
b/drivers/net/can/usb/kvaser_usb.c
+index cc3df8aebb87..63fb90b006ba 100644
+--- a/drivers/net/can/usb/kvaser_usb.c
++++ b/drivers/net/can/usb/kvaser_usb.c
+@@ -1238,6 +1238,9 @@ static int kvaser_usb_close(struct net_device *netdev)
+       if (err)
+               netdev_warn(netdev, "Cannot stop device, error %d\n", err);
+ 
++      /* reset tx contexts */
++      kvaser_usb_unlink_tx_urbs(priv);
++
+       priv->can.state = CAN_STATE_STOPPED;
+       close_candev(priv->netdev);
+ 
+@@ -1286,12 +1289,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct 
sk_buff *skb,
+       if (!urb) {
+               netdev_err(netdev, "No memory left for URBs\n");
+               stats->tx_dropped++;
+-              goto nourbmem;
++              dev_kfree_skb(skb);
++              return NETDEV_TX_OK;
+       }
+ 
+       buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
+       if (!buf) {
+               stats->tx_dropped++;
++              dev_kfree_skb(skb);
+               goto nobufmem;
+       }
+ 
+@@ -1326,6 +1331,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff 
*skb,
+               }
+       }
+ 
++      /* This should never happen; it implies a flow control bug */
+       if (!context) {
+               netdev_warn(netdev, "cannot find free context\n");
+               ret =  NETDEV_TX_BUSY;
+@@ -1356,9 +1362,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff 
*skb,
+       if (unlikely(err)) {
+               can_free_echo_skb(netdev, context->echo_index);
+ 
+-              skb = NULL; /* set to NULL to avoid double free in
+-                           * dev_kfree_skb(skb) */
+-
+               atomic_dec(&priv->active_tx_urbs);
+               usb_unanchor_urb(urb);
+ 
+@@ -1380,8 +1383,6 @@ releasebuf:
+       kfree(buf);
+ nobufmem:
+       usb_free_urb(urb);
+-nourbmem:
+-      dev_kfree_skb(skb);
+       return ret;
+ }
+ 
+@@ -1493,6 +1494,10 @@ static int kvaser_usb_init_one(struct usb_interface 
*intf,
+       struct kvaser_usb_net_priv *priv;
+       int i, err;
+ 
++      err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel);
++      if (err)
++              return err;
++
+       netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
+       if (!netdev) {
+               dev_err(&intf->dev, "Cannot alloc candev\n");
+@@ -1596,9 +1601,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
+ 
+       usb_set_intfdata(intf, dev);
+ 
+-      for (i = 0; i < MAX_NET_DEVICES; i++)
+-              kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);
+-
+       err = kvaser_usb_get_software_info(dev);
+       if (err) {
+               dev_err(&intf->dev,
+diff --git a/drivers/net/ethernet/atheros/alx/main.c 
b/drivers/net/ethernet/atheros/alx/main.c
+index d30085c2b454..a85a9c2f1385 100644
+--- a/drivers/net/ethernet/atheros/alx/main.c
++++ b/drivers/net/ethernet/atheros/alx/main.c
+@@ -184,15 +184,16 @@ static void alx_schedule_reset(struct alx_priv *alx)
+       schedule_work(&alx->reset_wk);
+ }
+ 
+-static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)
++static int alx_clean_rx_irq(struct alx_priv *alx, int budget)
+ {
+       struct alx_rx_queue *rxq = &alx->rxq;
+       struct alx_rrd *rrd;
+       struct alx_buffer *rxb;
+       struct sk_buff *skb;
+       u16 length, rfd_cleaned = 0;
++      int work = 0;
+ 
+-      while (budget > 0) {
++      while (work < budget) {
+               rrd = &rxq->rrd[rxq->rrd_read_idx];
+               if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT)))
+                       break;
+@@ -203,7 +204,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int 
budget)
+                   ALX_GET_FIELD(le32_to_cpu(rrd->word0),
+                                 RRD_NOR) != 1) {
+                       alx_schedule_reset(alx);
+-                      return 0;
++                      return work;
+               }
+ 
+               rxb = &rxq->bufs[rxq->read_idx];
+@@ -243,7 +244,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int 
budget)
+               }
+ 
+               napi_gro_receive(&alx->napi, skb);
+-              budget--;
++              work++;
+ 
+ next_pkt:
+               if (++rxq->read_idx == alx->rx_ringsz)
+@@ -258,21 +259,22 @@ next_pkt:
+       if (rfd_cleaned)
+               alx_refill_rx_ring(alx, GFP_ATOMIC);
+ 
+-      return budget > 0;
++      return work;
+ }
+ 
+ static int alx_poll(struct napi_struct *napi, int budget)
+ {
+       struct alx_priv *alx = container_of(napi, struct alx_priv, napi);
+       struct alx_hw *hw = &alx->hw;
+-      bool complete = true;
+       unsigned long flags;
++      bool tx_complete;
++      int work;
+ 
+-      complete = alx_clean_tx_irq(alx) &&
+-                 alx_clean_rx_irq(alx, budget);
++      tx_complete = alx_clean_tx_irq(alx);
++      work = alx_clean_rx_irq(alx, budget);
+ 
+-      if (!complete)
+-              return 1;
++      if (!tx_complete || work == budget)
++              return budget;
+ 
+       napi_complete(&alx->napi);
+ 
+@@ -284,7 +286,7 @@ static int alx_poll(struct napi_struct *napi, int budget)
+ 
+       alx_post_write(hw);
+ 
+-      return 0;
++      return work;
+ }
+ 
+ static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr)
+diff --git a/drivers/net/ethernet/broadcom/tg3.c 
b/drivers/net/ethernet/broadcom/tg3.c
+index 5501cad30cfa..8c1eab1151b8 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -17389,23 +17389,6 @@ static int tg3_init_one(struct pci_dev *pdev,
+               goto err_out_apeunmap;
+       }
+ 
+-      /*
+-       * Reset chip in case UNDI or EFI driver did not shutdown
+-       * DMA self test will enable WDMAC and we'll see (spurious)
+-       * pending DMA on the PCI bus at that point.
+-       */
+-      if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
+-          (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
+-              tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
+-              tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+-      }
+-
+-      err = tg3_test_dma(tp);
+-      if (err) {
+-              dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
+-              goto err_out_apeunmap;
+-      }
+-
+       intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+       rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+       sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+@@ -17450,6 +17433,23 @@ static int tg3_init_one(struct pci_dev *pdev,
+                       sndmbx += 0xc;
+       }
+ 
++      /*
++       * Reset chip in case UNDI or EFI driver did not shutdown
++       * DMA self test will enable WDMAC and we'll see (spurious)
++       * pending DMA on the PCI bus at that point.
++       */
++      if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
++          (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
++              tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
++              tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
++      }
++
++      err = tg3_test_dma(tp);
++      if (err) {
++              dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
++              goto err_out_apeunmap;
++      }
++
+       tg3_init_coal(tp);
+ 
+       pci_set_drvdata(pdev, dev);
+diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c 
b/drivers/net/ethernet/cisco/enic/enic_main.c
+index 635f55992d7e..8cc0eaa9d6f1 100644
+--- a/drivers/net/ethernet/cisco/enic/enic_main.c
++++ b/drivers/net/ethernet/cisco/enic/enic_main.c
+@@ -1294,10 +1294,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
+               skb_put(skb, bytes_written);
+               skb->protocol = eth_type_trans(skb, netdev);
+ 
+-              if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
+-                      skb->csum = htons(checksum);
+-                      skb->ip_summed = CHECKSUM_COMPLETE;
+-              }
++              /* Hardware does not provide whole packet checksum. It only
++               * provides pseudo checksum. Since hw validates the packet
++               * checksum but not provide us the checksum value. use
++               * CHECSUM_UNNECESSARY.
++               */
++              if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok &&
++                  ipv4_csum_ok)
++                      skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 
+               if (vlan_stripped)
+                       __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), 
vlan_tci);
+diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
+index 0ed96df20162..3458eb6fd491 100644
+--- a/drivers/platform/x86/hp_accel.c
++++ b/drivers/platform/x86/hp_accel.c
+@@ -237,6 +237,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
+       AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap),
+       AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap),
+       AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
++      AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted),
+       { NULL, }
+ /* Laptop models without axis info (yet):
+  * "NC6910" "HP Compaq 6910"
+diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
+index bb86494e2b7b..19915c5b256f 100644
+--- a/drivers/s390/char/con3215.c
++++ b/drivers/s390/char/con3215.c
+@@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data)
+       unsigned long flags;
+ 
+       spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
+-      if (raw->flags & RAW3215_TIMER_RUNS) {
+-              del_timer(&raw->timer);
+-              raw->flags &= ~RAW3215_TIMER_RUNS;
+-              if (!(raw->port.flags & ASYNC_SUSPENDED)) {
+-                      raw3215_mk_write_req(raw);
+-                      raw3215_start_io(raw);
++      raw->flags &= ~RAW3215_TIMER_RUNS;
++      if (!(raw->port.flags & ASYNC_SUSPENDED)) {
++              raw3215_mk_write_req(raw);
++              raw3215_start_io(raw);
++              if ((raw->queued_read || raw->queued_write) &&
++                  !(raw->flags & RAW3215_WORKING) &&
++                  !(raw->flags & RAW3215_TIMER_RUNS)) {
++                      raw->timer.expires = RAW3215_TIMEOUT + jiffies;
++                      add_timer(&raw->timer);
++                      raw->flags |= RAW3215_TIMER_RUNS;
+               }
+       }
+       spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
+@@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct raw3215_info 
*raw)
+                   (raw->flags & RAW3215_FLUSHING)) {
+                       /* execute write requests bigger than minimum size */
+                       raw3215_start_io(raw);
+-                      if (raw->flags & RAW3215_TIMER_RUNS) {
+-                              del_timer(&raw->timer);
+-                              raw->flags &= ~RAW3215_TIMER_RUNS;
+-                      }
+-              } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
+-                      /* delay small writes */
+-                      raw->timer.expires = RAW3215_TIMEOUT + jiffies;
+-                      add_timer(&raw->timer);
+-                      raw->flags |= RAW3215_TIMER_RUNS;
+               }
+       }
++      if ((raw->queued_read || raw->queued_write) &&
++          !(raw->flags & RAW3215_WORKING) &&
++          !(raw->flags & RAW3215_TIMER_RUNS)) {
++              raw->timer.expires = RAW3215_TIMEOUT + jiffies;
++              add_timer(&raw->timer);
++              raw->flags |= RAW3215_TIMER_RUNS;
++      }
+ }
+ 
+ /*
+@@ -1027,12 +1029,26 @@ static int tty3215_write(struct tty_struct * tty,
+                        const unsigned char *buf, int count)
+ {
+       struct raw3215_info *raw;
++      int i, written;
+ 
+       if (!tty)
+               return 0;
+       raw = (struct raw3215_info *) tty->driver_data;
+-      raw3215_write(raw, buf, count);
+-      return count;
++      written = count;
++      while (count > 0) {
++              for (i = 0; i < count; i++)
++                      if (buf[i] == '\t' || buf[i] == '\n')
++                              break;
++              raw3215_write(raw, buf, i);
++              count -= i;
++              buf += i;
++              if (count > 0) {
++                      raw3215_putchar(raw, *buf);
++                      count--;
++                      buf++;
++              }
++      }
++      return written;
+ }
+ 
+ /*
+@@ -1180,7 +1196,7 @@ static int __init tty3215_init(void)
+       driver->subtype = SYSTEM_TYPE_TTY;
+       driver->init_termios = tty_std_termios;
+       driver->init_termios.c_iflag = IGNBRK | IGNPAR;
+-      driver->init_termios.c_oflag = ONLCR | XTABS;
++      driver->init_termios.c_oflag = ONLCR;
+       driver->init_termios.c_lflag = ISIG;
+       driver->flags = TTY_DRIVER_REAL_RAW;
+       tty_set_operations(driver, &tty3215_ops);
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 87ca72d36d5b..a8990783ba66 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1439,13 +1439,12 @@ static int storvsc_queuecommand(struct Scsi_Host 
*host, struct scsi_cmnd *scmnd)
+       if (ret == -EAGAIN) {
+               /* no more space */
+ 
+-              if (cmd_request->bounce_sgl_count) {
++              if (cmd_request->bounce_sgl_count)
+                       destroy_bounce_buffer(cmd_request->bounce_sgl,
+                                       cmd_request->bounce_sgl_count);
+ 
+-                      ret = SCSI_MLQUEUE_DEVICE_BUSY;
+-                      goto queue_error;
+-              }
++              ret = SCSI_MLQUEUE_DEVICE_BUSY;
++              goto queue_error;
+       }
+ 
+       return 0;
+diff --git a/drivers/target/iscsi/iscsi_target_util.c 
b/drivers/target/iscsi/iscsi_target_util.c
+index c9790f6fdd89..016e882356d6 100644
+--- a/drivers/target/iscsi/iscsi_target_util.c
++++ b/drivers/target/iscsi/iscsi_target_util.c
+@@ -1349,15 +1349,15 @@ static int iscsit_do_tx_data(
+       struct iscsi_conn *conn,
+       struct iscsi_data_count *count)
+ {
+-      int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len;
++      int ret, iov_len;
+       struct kvec *iov_p;
+       struct msghdr msg;
+ 
+       if (!conn || !conn->sock || !conn->conn_ops)
+               return -1;
+ 
+-      if (data <= 0) {
+-              pr_err("Data length is: %d\n", data);
++      if (count->data_length <= 0) {
++              pr_err("Data length is: %d\n", count->data_length);
+               return -1;
+       }
+ 
+@@ -1366,20 +1366,16 @@ static int iscsit_do_tx_data(
+       iov_p = count->iov;
+       iov_len = count->iov_count;
+ 
+-      while (total_tx < data) {
+-              tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
+-                                      (data - total_tx));
+-              if (tx_loop <= 0) {
+-                      pr_debug("tx_loop: %d total_tx %d\n",
+-                              tx_loop, total_tx);
+-                      return tx_loop;
+-              }
+-              total_tx += tx_loop;
+-              pr_debug("tx_loop: %d, total_tx: %d, data: %d\n",
+-                                      tx_loop, total_tx, data);
++      ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
++                           count->data_length);
++      if (ret != count->data_length) {
++              pr_err("Unexpected ret: %d send data %d\n",
++                     ret, count->data_length);
++              return -EPIPE;
+       }
++      pr_debug("ret: %d, sent data: %d\n", ret, count->data_length);
+ 
+-      return total_tx;
++      return ret;
+ }
+ 
+ int rx_data(
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 8f8e75e392de..87f8fc63b3e1 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -907,8 +907,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool 
starting)
+ 
+                               if (i == (request->num_mapped_sgs - 1) ||
+                                               sg_is_last(s)) {
+-                                      if (list_is_last(&req->list,
+-                                                      &dep->request_list))
++                                      if (list_empty(&dep->request_list))
+                                               last_one = true;
+                                       chain = false;
+                               }
+@@ -926,6 +925,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool 
starting)
+                               if (last_one)
+                                       break;
+                       }
++
++                      if (last_one)
++                              break;
+               } else {
+                       dma = req->request.dma;
+                       length = req->request.length;
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 9cfe3af3101a..66c905884496 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -470,7 +470,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
+ {
+       void __iomem *base;
+       u32 control;
+-      u32 fminterval;
++      u32 fminterval = 0;
++      bool no_fminterval = false;
+       int cnt;
+ 
+       if (!mmio_resource_enabled(pdev, 0))
+@@ -480,6 +481,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
+       if (base == NULL)
+               return;
+ 
++      /*
++       * ULi M5237 OHCI controller locks the whole system when accessing
++       * the OHCI_FMINTERVAL offset.
++       */
++      if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237)
++              no_fminterval = true;
++
+       control = readl(base + OHCI_CONTROL);
+ 
+ /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
+@@ -518,7 +526,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
+       }
+ 
+       /* software reset of the controller, preserving HcFmInterval */
+-      fminterval = readl(base + OHCI_FMINTERVAL);
++      if (!no_fminterval)
++              fminterval = readl(base + OHCI_FMINTERVAL);
++
+       writel(OHCI_HCR, base + OHCI_CMDSTATUS);
+ 
+       /* reset requires max 10 us delay */
+@@ -527,7 +537,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
+                       break;
+               udelay(1);
+       }
+-      writel(fminterval, base + OHCI_FMINTERVAL);
++
++      if (!no_fminterval)
++              writel(fminterval, base + OHCI_FMINTERVAL);
+ 
+       /* Now the controller is safely in SUSPEND and nothing can wake it up */
+       iounmap(base);
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index a24714f6f88f..8e15acd204ef 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
+       { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
+       { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+-      { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */
++      { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */
++      { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
+       { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
+       { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB 
Device */
+       { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
++      { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
+       { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index f0e65c970d35..cec377b8bb8b 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -418,6 +418,8 @@ static void        usa26_instat_callback(struct urb *urb)
+       }
+       port = serial->port[msg->port];
+       p_priv = usb_get_serial_port_data(port);
++      if (!p_priv)
++              goto resubmit;
+ 
+       /* Update handshaking pin state information */
+       old_dcd_state = p_priv->dcd_state;
+@@ -428,7 +430,7 @@ static void        usa26_instat_callback(struct urb *urb)
+ 
+       if (old_dcd_state != p_priv->dcd_state)
+               tty_port_tty_hangup(&port->port, true);
+-
++resubmit:
+       /* Resubmit urb so we continue receiving */
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+@@ -543,6 +545,8 @@ static void        usa28_instat_callback(struct urb *urb)
+       }
+       port = serial->port[msg->port];
+       p_priv = usb_get_serial_port_data(port);
++      if (!p_priv)
++              goto resubmit;
+ 
+       /* Update handshaking pin state information */
+       old_dcd_state = p_priv->dcd_state;
+@@ -553,7 +557,7 @@ static void        usa28_instat_callback(struct urb *urb)
+ 
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
+-
++resubmit:
+               /* Resubmit urb so we continue receiving */
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+@@ -630,6 +634,8 @@ static void        usa49_instat_callback(struct urb *urb)
+       }
+       port = serial->port[msg->portNumber];
+       p_priv = usb_get_serial_port_data(port);
++      if (!p_priv)
++              goto resubmit;
+ 
+       /* Update handshaking pin state information */
+       old_dcd_state = p_priv->dcd_state;
+@@ -640,7 +646,7 @@ static void        usa49_instat_callback(struct urb *urb)
+ 
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
+-
++resubmit:
+       /* Resubmit urb so we continue receiving */
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+@@ -878,6 +884,8 @@ static void        usa90_instat_callback(struct urb *urb)
+ 
+       port = serial->port[0];
+       p_priv = usb_get_serial_port_data(port);
++      if (!p_priv)
++              goto resubmit;
+ 
+       /* Update handshaking pin state information */
+       old_dcd_state = p_priv->dcd_state;
+@@ -888,7 +896,7 @@ static void        usa90_instat_callback(struct urb *urb)
+ 
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
+-
++resubmit:
+       /* Resubmit urb so we continue receiving */
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+@@ -949,6 +957,8 @@ static void        usa67_instat_callback(struct urb *urb)
+ 
+       port = serial->port[msg->port];
+       p_priv = usb_get_serial_port_data(port);
++      if (!p_priv)
++              goto resubmit;
+ 
+       /* Update handshaking pin state information */
+       old_dcd_state = p_priv->dcd_state;
+@@ -957,7 +967,7 @@ static void        usa67_instat_callback(struct urb *urb)
+ 
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
+-
++resubmit:
+       /* Resubmit urb so we continue receiving */
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
+index ac3725440d64..dc55bc254c5c 100644
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -519,13 +519,11 @@ static const struct vfio_device_ops vfio_pci_ops = {
+ 
+ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id 
*id)
+ {
+-      u8 type;
+       struct vfio_pci_device *vdev;
+       struct iommu_group *group;
+       int ret;
+ 
+-      pci_read_config_byte(pdev, PCI_HEADER_TYPE, &type);
+-      if ((type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL)
++      if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
+               return -EINVAL;
+ 
+       group = iommu_group_get(&pdev->dev);
+diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
+index 080c35b34bbb..cc5dbb5b2f71 100644
+--- a/drivers/video/logo/logo.c
++++ b/drivers/video/logo/logo.c
+@@ -25,6 +25,21 @@ static bool nologo;
+ module_param(nologo, bool, 0);
+ MODULE_PARM_DESC(nologo, "Disables startup logo");
+ 
++/*
++ * Logos are located in the initdata, and will be freed in kernel_init.
++ * Use late_init to mark the logos as freed to prevent any further use.
++ */
++
++static bool logos_freed;
++
++static int __init fb_logo_late_init(void)
++{
++      logos_freed = true;
++      return 0;
++}
++
++late_initcall(fb_logo_late_init);
++
+ /* logo's are marked __initdata. Use __init_refok to tell
+  * modpost that it is intended that this function uses data
+  * marked __initdata.
+@@ -33,7 +48,7 @@ const struct linux_logo * __init_refok fb_find_logo(int 
depth)
+ {
+       const struct linux_logo *logo = NULL;
+ 
+-      if (nologo)
++      if (nologo || logos_freed)
+               return NULL;
+ 
+       if (depth >= 1) {
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index 9c8a5a6d33df..7a318480ab7a 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -137,10 +137,6 @@ lockd(void *vrqstp)
+ 
+       dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
+ 
+-      if (!nlm_timeout)
+-              nlm_timeout = LOCKD_DFLT_TIMEO;
+-      nlmsvc_timeout = nlm_timeout * HZ;
+-
+       /*
+        * The main request loop. We don't terminate until the last
+        * NFS mount or NFS daemon has gone away.
+@@ -346,6 +342,10 @@ static struct svc_serv *lockd_create_svc(void)
+               printk(KERN_WARNING
+                       "lockd_up: no pid, %d users??\n", nlmsvc_users);
+ 
++      if (!nlm_timeout)
++              nlm_timeout = LOCKD_DFLT_TIMEO;
++      nlmsvc_timeout = nlm_timeout * HZ;
++
+       serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
+       if (!serv) {
+               printk(KERN_WARNING "lockd_up: create service failed\n");
+diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
+index cc143ee7a56e..519833d0457e 100644
+--- a/fs/nfs/nfs4client.c
++++ b/fs/nfs/nfs4client.c
+@@ -394,20 +394,14 @@ static bool nfs4_match_clientids(struct nfs_client *a, 
struct nfs_client *b)
+ }
+ 
+ /*
+- * Returns true if the server owners match
++ * Returns true if the server major ids match
+  */
+ static bool
+-nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b)
++nfs4_check_clientid_trunking(struct nfs_client *a, struct nfs_client *b)
+ {
+       struct nfs41_server_owner *o1 = a->cl_serverowner;
+       struct nfs41_server_owner *o2 = b->cl_serverowner;
+ 
+-      if (o1->minor_id != o2->minor_id) {
+-              dprintk("NFS: --> %s server owner minor IDs do not match\n",
+-                      __func__);
+-              return false;
+-      }
+-
+       if (o1->major_id_sz != o2->major_id_sz)
+               goto out_major_mismatch;
+       if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0)
+@@ -483,7 +477,12 @@ int nfs41_walk_client_list(struct nfs_client *new,
+               if (!nfs4_match_clientids(pos, new))
+                       continue;
+ 
+-              if (!nfs4_match_serverowners(pos, new))
++              /*
++               * Note that session trunking is just a special subcase of
++               * client id trunking. In either case, we want to fall back
++               * to using the existing nfs_client.
++               */
++              if (!nfs4_check_clientid_trunking(pos, new))
+                       continue;
+ 
+               atomic_inc(&pos->cl_count);
+diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
+index 74825be65b7b..fbb9dfb7b1d2 100644
+--- a/fs/notify/inode_mark.c
++++ b/fs/notify/inode_mark.c
+@@ -288,20 +288,25 @@ void fsnotify_unmount_inodes(struct list_head *list)
+               spin_unlock(&inode->i_lock);
+ 
+               /* In case the dropping of a reference would nuke next_i. */
+-              if ((&next_i->i_sb_list != list) &&
+-                  atomic_read(&next_i->i_count)) {
++              while (&next_i->i_sb_list != list) {
+                       spin_lock(&next_i->i_lock);
+-                      if (!(next_i->i_state & (I_FREEING | I_WILL_FREE))) {
++                      if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) &&
++                                              atomic_read(&next_i->i_count)) {
+                               __iget(next_i);
+                               need_iput = next_i;
++                              spin_unlock(&next_i->i_lock);
++                              break;
+                       }
+                       spin_unlock(&next_i->i_lock);
++                      next_i = list_entry(next_i->i_sb_list.next,
++                                              struct inode, i_sb_list);
+               }
+ 
+               /*
+-               * We can safely drop inode_sb_list_lock here because we hold
+-               * references on both inode and next_i.  Also no new inodes
+-               * will be added since the umount has begun.
++               * We can safely drop inode_sb_list_lock here because either
++               * we actually hold references on both inode and next_i or
++               * end of list.  Also no new inodes will be added since the
++               * umount has begun.
+                */
+               spin_unlock(&inode_sb_list_lock);
+ 
+diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
+index 31c5f7675fbf..f504027d66a8 100644
+--- a/lib/decompress_bunzip2.c
++++ b/lib/decompress_bunzip2.c
+@@ -184,7 +184,7 @@ static int INIT get_next_block(struct bunzip_data *bd)
+       if (get_bits(bd, 1))
+               return RETVAL_OBSOLETE_INPUT;
+       origPtr = get_bits(bd, 24);
+-      if (origPtr > dbufSize)
++      if (origPtr >= dbufSize)
+               return RETVAL_DATA_ERROR;
+       /* mapping table: if some byte values are never used (encoding things
+          like ascii text), the compression code removes the gaps to have fewer
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 11ef25c9cf43..923146c4f007 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1862,7 +1862,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int 
mss_now, int nonagle,
+               if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
+                       break;
+ 
+-              if (tso_segs == 1) {
++              if (tso_segs == 1 || !sk->sk_gso_max_segs) {
+                       if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
+                                                    (tcp_skb_is_last(sk, skb) ?
+                                                     nonagle : 
TCP_NAGLE_PUSH))))
+@@ -1899,7 +1899,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int 
mss_now, int nonagle,
+               }
+ 
+               limit = mss_now;
+-              if (tso_segs > 1 && !tcp_urg_mode(tp))
++              if (tso_segs > 1 && sk->sk_gso_max_segs && !tcp_urg_mode(tp))
+                       limit = tcp_mss_split_point(sk, skb, mss_now,
+                                                   min_t(unsigned int,
+                                                         cwnd_quota,
+diff --git a/net/netfilter/ipset/ip_set_core.c 
b/net/netfilter/ipset/ip_set_core.c
+index f77139007983..3b04dfd34554 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1754,6 +1754,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void 
__user *user, int *len)
+       if (*op < IP_SET_OP_VERSION) {
+               /* Check the version at the beginning of operations */
+               struct ip_set_req_version *req_version = data;
++
++              if (*len < sizeof(struct ip_set_req_version)) {
++                      ret = -EINVAL;
++                      goto done;
++              }
++
+               if (req_version->version != IPSET_PROTOCOL) {
+                       ret = -EPROTO;
+                       goto done;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index afe41178c9fb..f7ad5c630b65 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -374,14 +374,14 @@ out:
+       return err;
+ }
+ 
+-static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr)
++static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr, 
unsigned int nm_len)
+ {
+ #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1
+       struct page *p_start, *p_end;
+ 
+       /* First page is flushed through netlink_{get,set}_status */
+       p_start = pgvec_to_page(hdr + PAGE_SIZE);
+-      p_end   = pgvec_to_page((void *)hdr + NL_MMAP_HDRLEN + hdr->nm_len - 1);
++      p_end   = pgvec_to_page((void *)hdr + NL_MMAP_HDRLEN + nm_len - 1);
+       while (p_start <= p_end) {
+               flush_dcache_page(p_start);
+               p_start++;
+@@ -399,9 +399,9 @@ static enum nl_mmap_status netlink_get_status(const struct 
nl_mmap_hdr *hdr)
+ static void netlink_set_status(struct nl_mmap_hdr *hdr,
+                              enum nl_mmap_status status)
+ {
++      smp_mb();
+       hdr->nm_status = status;
+       flush_dcache_page(pgvec_to_page(hdr));
+-      smp_wmb();
+ }
+ 
+ static struct nl_mmap_hdr *
+@@ -563,24 +563,16 @@ static int netlink_mmap_sendmsg(struct sock *sk, struct 
msghdr *msg,
+       struct nl_mmap_hdr *hdr;
+       struct sk_buff *skb;
+       unsigned int maxlen;
+-      bool excl = true;
+       int err = 0, len = 0;
+ 
+-      /* Netlink messages are validated by the receiver before processing.
+-       * In order to avoid userspace changing the contents of the message
+-       * after validation, the socket and the ring may only be used by a
+-       * single process, otherwise we fall back to copying.
+-       */
+-      if (atomic_long_read(&sk->sk_socket->file->f_count) > 1 ||
+-          atomic_read(&nlk->mapped) > 1)
+-              excl = false;
+-
+       mutex_lock(&nlk->pg_vec_lock);
+ 
+       ring   = &nlk->tx_ring;
+       maxlen = ring->frame_size - NL_MMAP_HDRLEN;
+ 
+       do {
++              unsigned int nm_len;
++
+               hdr = netlink_current_frame(ring, NL_MMAP_STATUS_VALID);
+               if (hdr == NULL) {
+                       if (!(msg->msg_flags & MSG_DONTWAIT) &&
+@@ -588,35 +580,23 @@ static int netlink_mmap_sendmsg(struct sock *sk, struct 
msghdr *msg,
+                               schedule();
+                       continue;
+               }
+-              if (hdr->nm_len > maxlen) {
++
++              nm_len = ACCESS_ONCE(hdr->nm_len);
++              if (nm_len > maxlen) {
+                       err = -EINVAL;
+                       goto out;
+               }
+ 
+-              netlink_frame_flush_dcache(hdr);
++              netlink_frame_flush_dcache(hdr, nm_len);
+ 
+-              if (likely(dst_portid == 0 && dst_group == 0 && excl)) {
+-                      skb = alloc_skb_head(GFP_KERNEL);
+-                      if (skb == NULL) {
+-                              err = -ENOBUFS;
+-                              goto out;
+-                      }
+-                      sock_hold(sk);
+-                      netlink_ring_setup_skb(skb, sk, ring, hdr);
+-                      NETLINK_CB(skb).flags |= NETLINK_SKB_TX;
+-                      __skb_put(skb, hdr->nm_len);
+-                      netlink_set_status(hdr, NL_MMAP_STATUS_RESERVED);
+-                      atomic_inc(&ring->pending);
+-              } else {
+-                      skb = alloc_skb(hdr->nm_len, GFP_KERNEL);
+-                      if (skb == NULL) {
+-                              err = -ENOBUFS;
+-                              goto out;
+-                      }
+-                      __skb_put(skb, hdr->nm_len);
+-                      memcpy(skb->data, (void *)hdr + NL_MMAP_HDRLEN, 
hdr->nm_len);
+-                      netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED);
++              skb = alloc_skb(nm_len, GFP_KERNEL);
++              if (skb == NULL) {
++                      err = -ENOBUFS;
++                      goto out;
+               }
++              __skb_put(skb, nm_len);
++              memcpy(skb->data, (void *)hdr + NL_MMAP_HDRLEN, nm_len);
++              netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED);
+ 
+               netlink_increment_head(ring);
+ 
+@@ -662,7 +642,7 @@ static void netlink_queue_mmaped_skb(struct sock *sk, 
struct sk_buff *skb)
+       hdr->nm_pid     = NETLINK_CB(skb).creds.pid;
+       hdr->nm_uid     = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid);
+       hdr->nm_gid     = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid);
+-      netlink_frame_flush_dcache(hdr);
++      netlink_frame_flush_dcache(hdr, hdr->nm_len);
+       netlink_set_status(hdr, NL_MMAP_STATUS_VALID);
+ 
+       NETLINK_CB(skb).flags |= NETLINK_SKB_DELIVERED;
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index fd556ac05fdb..e69a17da1e84 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -338,7 +338,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
+ {
+       struct ieee80211_sta_ht_cap *ht_cap;
+       struct ieee80211_sta_vht_cap *vht_cap;
+-      u32 width, control_freq;
++      u32 width, control_freq, cap;
+ 
+       if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+               return false;
+@@ -370,7 +370,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
+                       return false;
+               break;
+       case NL80211_CHAN_WIDTH_80P80:
+-              if (!(vht_cap->cap & 
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
++              cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
++              if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+                       return false;
+       case NL80211_CHAN_WIDTH_80:
+               if (!vht_cap->vht_supported)
+@@ -381,7 +382,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
+       case NL80211_CHAN_WIDTH_160:
+               if (!vht_cap->vht_supported)
+                       return false;
+-              if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
++              cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
++              if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
++                  cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+                       return false;
+               prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
+               width = 160;

Reply via email to