]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 May 2020 15:56:09 +0000 (17:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 May 2020 15:56:09 +0000 (17:56 +0200)
added patches:
asoc-fsl_ssi-mark-sacnt-register-volatile.patch
asoc-intel-pass-correct-parameter-in-sst_alloc_stream_mrfld.patch
asoc-tegra_alc5632-check-return-value.patch
clk-rockchip-revert-clk-rockchip-reset-init-state-before-mmc-card-initialization.patch
input-edt-ft5x06-fix-setting-gain-offset-and-threshold-via-device-tree.patch
input-gpio-keys-fix-check-for-disabling-unsupported-keys.patch
mac80211-fix-bw-upgrade-for-tdls-peers.patch
mac80211-fix-mgmt-tx-abort-cookie-and-leak.patch
mac80211-tdls-always-downgrade-invalid-chandefs.patch
mac80211-tdls-change-bw-calculation-for-wider_bw-peers.patch
mmc-block-return-error-on-failed-mmc_blk_get.patch
mmc-debugfs-correct-wrong-voltage-value.patch
mmc-dw_mmc-rockchip-set-the-drive-phase-properly.patch
mmc-moxart-fix-wait_for_completion_interruptible_timeout-return-variable-type.patch
mmc-sd-limit-sd-card-power-limit-according-to-cards-capabilities.patch
mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch
mmc-sdhci-restore-behavior-when-setting-vdd-via-external-regulator.patch
mtd-nand-denali-add-missing-nand_release-call-in-denali_remove.patch
mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch
net-get-rid-of-an-signed-integer-overflow-in-ip_idents_reserve.patch
net-xfrm_input-fix-possible-null-deref-of-tunnel.ip6-parms.i_key.patch
nfs-fix-an-lock-open-race-when-unlinking-an-open-file.patch
revert-acpi-lpss-allow-to-use-specific-pm-domain-during-probe.patch
xfrm-fix-memory-leak-of-aead-algorithm-name.patch
xfrm_user-propagate-sec-ctx-allocation-errors.patch

26 files changed:
queue-4.4/asoc-fsl_ssi-mark-sacnt-register-volatile.patch [new file with mode: 0644]
queue-4.4/asoc-intel-pass-correct-parameter-in-sst_alloc_stream_mrfld.patch [new file with mode: 0644]
queue-4.4/asoc-tegra_alc5632-check-return-value.patch [new file with mode: 0644]
queue-4.4/clk-rockchip-revert-clk-rockchip-reset-init-state-before-mmc-card-initialization.patch [new file with mode: 0644]
queue-4.4/input-edt-ft5x06-fix-setting-gain-offset-and-threshold-via-device-tree.patch [new file with mode: 0644]
queue-4.4/input-gpio-keys-fix-check-for-disabling-unsupported-keys.patch [new file with mode: 0644]
queue-4.4/mac80211-fix-bw-upgrade-for-tdls-peers.patch [new file with mode: 0644]
queue-4.4/mac80211-fix-mgmt-tx-abort-cookie-and-leak.patch [new file with mode: 0644]
queue-4.4/mac80211-tdls-always-downgrade-invalid-chandefs.patch [new file with mode: 0644]
queue-4.4/mac80211-tdls-change-bw-calculation-for-wider_bw-peers.patch [new file with mode: 0644]
queue-4.4/mmc-block-return-error-on-failed-mmc_blk_get.patch [new file with mode: 0644]
queue-4.4/mmc-debugfs-correct-wrong-voltage-value.patch [new file with mode: 0644]
queue-4.4/mmc-dw_mmc-rockchip-set-the-drive-phase-properly.patch [new file with mode: 0644]
queue-4.4/mmc-moxart-fix-wait_for_completion_interruptible_timeout-return-variable-type.patch [new file with mode: 0644]
queue-4.4/mmc-sd-limit-sd-card-power-limit-according-to-cards-capabilities.patch [new file with mode: 0644]
queue-4.4/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch [new file with mode: 0644]
queue-4.4/mmc-sdhci-restore-behavior-when-setting-vdd-via-external-regulator.patch [new file with mode: 0644]
queue-4.4/mtd-nand-denali-add-missing-nand_release-call-in-denali_remove.patch [new file with mode: 0644]
queue-4.4/mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch [new file with mode: 0644]
queue-4.4/net-get-rid-of-an-signed-integer-overflow-in-ip_idents_reserve.patch [new file with mode: 0644]
queue-4.4/net-xfrm_input-fix-possible-null-deref-of-tunnel.ip6-parms.i_key.patch [new file with mode: 0644]
queue-4.4/nfs-fix-an-lock-open-race-when-unlinking-an-open-file.patch [new file with mode: 0644]
queue-4.4/revert-acpi-lpss-allow-to-use-specific-pm-domain-during-probe.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/xfrm-fix-memory-leak-of-aead-algorithm-name.patch [new file with mode: 0644]
queue-4.4/xfrm_user-propagate-sec-ctx-allocation-errors.patch [new file with mode: 0644]

diff --git a/queue-4.4/asoc-fsl_ssi-mark-sacnt-register-volatile.patch b/queue-4.4/asoc-fsl_ssi-mark-sacnt-register-volatile.patch
new file mode 100644 (file)
index 0000000..748da9f
--- /dev/null
@@ -0,0 +1,64 @@
+From 3f1c241f0f5f90046258e6b8d4aeb6463ffdc08e Mon Sep 17 00:00:00 2001
+From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
+Date: Sun, 20 Dec 2015 21:30:25 +0100
+Subject: ASoC: fsl_ssi: mark SACNT register volatile
+
+From: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
+
+commit 3f1c241f0f5f90046258e6b8d4aeb6463ffdc08e upstream.
+
+SACNT register should be marked volatile since
+its WR and RD bits are cleared by SSI after
+completing the relevant operation.
+This unbreaks AC'97 register access.
+
+Fixes: 05cf237972fe ("ASoC: fsl_ssi: Add driver suspend and resume to support MEGA Fast")
+
+Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
+Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/fsl/fsl_ssi.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/fsl/fsl_ssi.c
++++ b/sound/soc/fsl/fsl_ssi.c
+@@ -146,6 +146,7 @@ static bool fsl_ssi_volatile_reg(struct
+       case CCSR_SSI_SRX1:
+       case CCSR_SSI_SISR:
+       case CCSR_SSI_SFCSR:
++      case CCSR_SSI_SACNT:
+       case CCSR_SSI_SACADD:
+       case CCSR_SSI_SACDAT:
+       case CCSR_SSI_SATAG:
+@@ -239,8 +240,9 @@ struct fsl_ssi_private {
+       unsigned int baudclk_streams;
+       unsigned int bitclk_freq;
+-      /*regcache for SFCSR*/
++      /* regcache for volatile regs */
+       u32 regcache_sfcsr;
++      u32 regcache_sacnt;
+       /* DMA params */
+       struct snd_dmaengine_dai_dma_data dma_params_tx;
+@@ -1597,6 +1599,8 @@ static int fsl_ssi_suspend(struct device
+       regmap_read(regs, CCSR_SSI_SFCSR,
+                       &ssi_private->regcache_sfcsr);
++      regmap_read(regs, CCSR_SSI_SACNT,
++                      &ssi_private->regcache_sacnt);
+       regcache_cache_only(regs, true);
+       regcache_mark_dirty(regs);
+@@ -1615,6 +1619,8 @@ static int fsl_ssi_resume(struct device
+                       CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
+                       CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
+                       ssi_private->regcache_sfcsr);
++      regmap_write(regs, CCSR_SSI_SACNT,
++                      ssi_private->regcache_sacnt);
+       return regcache_sync(regs);
+ }
diff --git a/queue-4.4/asoc-intel-pass-correct-parameter-in-sst_alloc_stream_mrfld.patch b/queue-4.4/asoc-intel-pass-correct-parameter-in-sst_alloc_stream_mrfld.patch
new file mode 100644 (file)
index 0000000..e1b7d93
--- /dev/null
@@ -0,0 +1,34 @@
+From d16a2b9f2465b5486f830178fbfb7d203e0a17ae Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 18 Nov 2015 13:04:20 +0300
+Subject: ASoC: Intel: pass correct parameter in sst_alloc_stream_mrfld()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit d16a2b9f2465b5486f830178fbfb7d203e0a17ae upstream.
+
+"data" is always NULL in this function.  I think we should be passing
+"&data" to sst_prepare_and_post_msg() instead of "data".
+
+Fixes: 3d9ff34622ba ('ASoC: Intel: sst: add stream operations')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Tested-by: Dinesh Mirche <dinesh.mirche@intel.com>
+Acked-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/intel/atom/sst/sst_stream.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/intel/atom/sst/sst_stream.c
++++ b/sound/soc/intel/atom/sst/sst_stream.c
+@@ -108,7 +108,7 @@ int sst_alloc_stream_mrfld(struct intel_
+                       str_id, pipe_id);
+       ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
+                       IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
+-                      &alloc_param, data, true, true, false, true);
++                      &alloc_param, &data, true, true, false, true);
+       if (ret < 0) {
+               dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
diff --git a/queue-4.4/asoc-tegra_alc5632-check-return-value.patch b/queue-4.4/asoc-tegra_alc5632-check-return-value.patch
new file mode 100644 (file)
index 0000000..273150e
--- /dev/null
@@ -0,0 +1,44 @@
+From 319c32597fc22a58b946a6146f2be1fd208582e0 Mon Sep 17 00:00:00 2001
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Date: Tue, 1 Dec 2015 16:09:51 +0530
+Subject: ASoC: tegra_alc5632: check return value
+
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+
+commit 319c32597fc22a58b946a6146f2be1fd208582e0 upstream.
+
+We have been returning success even if snd_soc_card_jack_new() fails.
+Lets check the return value and return error if it fails.
+
+Fixes: 12cc6d1dca4d ("ASoC: tegra_alc5632: Register jacks at the card level")
+Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/tegra/tegra_alc5632.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/tegra/tegra_alc5632.c
++++ b/sound/soc/tegra/tegra_alc5632.c
+@@ -101,12 +101,16 @@ static const struct snd_kcontrol_new teg
+ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
+ {
++      int ret;
+       struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
+-      snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
+-                            &tegra_alc5632_hs_jack,
+-                            tegra_alc5632_hs_jack_pins,
+-                            ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
++      ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
++                                  SND_JACK_HEADSET,
++                                  &tegra_alc5632_hs_jack,
++                                  tegra_alc5632_hs_jack_pins,
++                                  ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
++      if (ret)
++              return ret;
+       if (gpio_is_valid(machine->gpio_hp_det)) {
+               tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
diff --git a/queue-4.4/clk-rockchip-revert-clk-rockchip-reset-init-state-before-mmc-card-initialization.patch b/queue-4.4/clk-rockchip-revert-clk-rockchip-reset-init-state-before-mmc-card-initialization.patch
new file mode 100644 (file)
index 0000000..c44d196
--- /dev/null
@@ -0,0 +1,104 @@
+From 4715f81afc342996f680b08c944a712d9cbef11b Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 12 May 2016 11:03:16 -0700
+Subject: clk: rockchip: Revert "clk: rockchip: reset init state before mmc card initialization"
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit 4715f81afc342996f680b08c944a712d9cbef11b upstream.
+
+This reverts commit 7a03fe6f48f3 ("clk: rockchip: reset init state
+before mmc card initialization").
+
+Though not totally obvious from the commit message nor from the source
+code, that commit appears to be trying to reset the "_drv" MMC clocks to
+90 degrees (note that the "_sample" MMC clocks have a shift of 0 so are
+not touched).
+
+The major problem here is that it doesn't properly reset things.  The
+phase is a two bit field and the commit only touches one of the two
+bits.  Thus the commit had the following affect:
+- phase   0  => phase  90
+- phase  90  => phase  90
+- phase 180  => phase 270
+- phase 270  => phase 270
+
+Things get even weirder if you happen to have a bootloader that was
+actually using delay elements (should be no reason to, but you never
+know), since those are additional bits that weren't touched by the
+original patch.
+
+This is unlikely to be what we actually want.  Checking on rk3288-veyron
+devices, I can see that the bootloader leaves these clocks as:
+- emmc:  phase 180
+- sdmmc: phase 90
+- sdio0: phase 90
+
+Thus on rk3288-veyron devices the commit we're reverting had the effect
+of changing the eMMC clock to phase 270.  This probably explains the
+scattered reports I've heard of eMMC devices not working on some veyron
+devices when using the upstream kernel.
+
+The original commit was presumably made because previously the kernel
+didn't touch the "_drv" phase at all and relied on whatever value was
+there when the kernel started.  If someone was using a bootloader that
+touched the "_drv" phase then, indeed, we should have code in the kernel
+to fix that.  ...and also, to get ideal timings, we should also have the
+kernel change the phase depending on the speed mode.  In fact, that's
+the subject of a recent patch I posted at
+<https://patchwork.kernel.org/patch/9075141/>.
+
+Ideally, we should take both the patch posted to dw_mmc and this
+revert.  Since those will likely go through different trees, here I
+describe behavior with the combos:
+
+1. Just this revert: likely will fix rk3288-veyron eMMC on some devices
+   + other cases; might break someone with a strange bootloader that
+   sets the phase to 0 or one that uses delay elements (pretty
+   unpredicable what would happen in that case).
+2. Just dw_mmc patch: fixes everyone.  Effectly the dw_mmc patch will
+   totally override the broken patch and fix everything.
+3. Both patches: fixes everyone.  Once dw_mmc is initting properly then
+   any defaults from the clock code doesn't mattery.
+
+Fixes: 7a03fe6f48f3 ("clk: rockchip: reset init state before mmc card initialization")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[emmc and sdmmc still work on all current boards in mainline after this
+revert, so they should take precedence over any out-of-tree board that
+will hopefully again get fixed with the better upcoming dw_mmc change.]
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+
+---
+ drivers/clk/rockchip/clk-mmc-phase.c |   11 -----------
+ 1 file changed, 11 deletions(-)
+
+--- a/drivers/clk/rockchip/clk-mmc-phase.c
++++ b/drivers/clk/rockchip/clk-mmc-phase.c
+@@ -41,8 +41,6 @@ static unsigned long rockchip_mmc_recalc
+ #define ROCKCHIP_MMC_DEGREE_MASK 0x3
+ #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
+ #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+-#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
+-#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
+ #define PSECS_PER_SEC 1000000000000LL
+@@ -183,15 +181,6 @@ struct clk *rockchip_clk_register_mmc(co
+       mmc_clock->reg = reg;
+       mmc_clock->shift = shift;
+-      /*
+-       * Assert init_state to soft reset the CLKGEN
+-       * for mmc tuning phase and degree
+-       */
+-      if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
+-              writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
+-                                   ROCKCHIP_MMC_INIT_STATE_RESET,
+-                                   mmc_clock->shift), mmc_clock->reg);
+-
+       clk = clk_register(NULL, &mmc_clock->hw);
+       if (IS_ERR(clk))
+               goto err_free;
diff --git a/queue-4.4/input-edt-ft5x06-fix-setting-gain-offset-and-threshold-via-device-tree.patch b/queue-4.4/input-edt-ft5x06-fix-setting-gain-offset-and-threshold-via-device-tree.patch
new file mode 100644 (file)
index 0000000..7e9eeb8
--- /dev/null
@@ -0,0 +1,55 @@
+From dc262dfaaeda7617ae0b15b5ce1252a6cd102b19 Mon Sep 17 00:00:00 2001
+From: Philipp Zabel <p.zabel@pengutronix.de>
+Date: Tue, 9 Feb 2016 09:32:42 -0800
+Subject: Input: edt-ft5x06 - fix setting gain, offset, and threshold via device tree
+
+From: Philipp Zabel <p.zabel@pengutronix.de>
+
+commit dc262dfaaeda7617ae0b15b5ce1252a6cd102b19 upstream.
+
+A recent patch broke parsing the gain, offset, and threshold parameters
+from device tree. Instead of setting the cached values and writing them
+to the correct registers during probe, it would write the values from DT
+into the register address variables and never write them to the chip
+during normal operation.
+
+Fixes: 2e23b7a96372 ("Input: edt-ft5x06 - use generic properties API")
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/touchscreen/edt-ft5x06.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -822,16 +822,22 @@ static void edt_ft5x06_ts_get_defaults(s
+       int error;
+       error = device_property_read_u32(dev, "threshold", &val);
+-      if (!error)
+-              reg_addr->reg_threshold = val;
++      if (!error) {
++              edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold, val);
++              tsdata->threshold = val;
++      }
+       error = device_property_read_u32(dev, "gain", &val);
+-      if (!error)
+-              reg_addr->reg_gain = val;
++      if (!error) {
++              edt_ft5x06_register_write(tsdata, reg_addr->reg_gain, val);
++              tsdata->gain = val;
++      }
+       error = device_property_read_u32(dev, "offset", &val);
+-      if (!error)
+-              reg_addr->reg_offset = val;
++      if (!error) {
++              edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, val);
++              tsdata->offset = val;
++      }
+ }
+ static void
diff --git a/queue-4.4/input-gpio-keys-fix-check-for-disabling-unsupported-keys.patch b/queue-4.4/input-gpio-keys-fix-check-for-disabling-unsupported-keys.patch
new file mode 100644 (file)
index 0000000..b931ccb
--- /dev/null
@@ -0,0 +1,92 @@
+From 8679ee4204cfd5cf78b996508ccadc1ec6130f1a Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Wed, 6 Jan 2016 14:20:07 -0800
+Subject: Input: gpio-keys - fix check for disabling unsupported keys
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 8679ee4204cfd5cf78b996508ccadc1ec6130f1a upstream.
+
+Commit 4ea14a53d8f881034fa9e186653821c4e3d9a8fb ("Input: gpio-keys - report
+error when disabling unsupported key") tried let user know that they
+attempted to disable an unsupported key, unfortunately the check is wrong
+as it believes that all codes are invalid. Fix it by ensuring that keys
+that we try to disable are subset of keys (or switches) that device
+reports.
+
+Fixes: 4ea14a53d8f8 ("Input: gpio-keys - report error when disabling unsupported key")
+Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/keyboard/gpio_keys.c |   29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/input/keyboard/gpio_keys.c
++++ b/drivers/input/keyboard/gpio_keys.c
+@@ -96,7 +96,7 @@ struct gpio_keys_drvdata {
+  * Return value of this function can be used to allocate bitmap
+  * large enough to hold all bits for given type.
+  */
+-static inline int get_n_events_by_type(int type)
++static int get_n_events_by_type(int type)
+ {
+       BUG_ON(type != EV_SW && type != EV_KEY);
+@@ -104,6 +104,22 @@ static inline int get_n_events_by_type(i
+ }
+ /**
++ * get_bm_events_by_type() - returns bitmap of supported events per @type
++ * @input: input device from which bitmap is retrieved
++ * @type: type of button (%EV_KEY, %EV_SW)
++ *
++ * Return value of this function can be used to allocate bitmap
++ * large enough to hold all bits for given type.
++ */
++static const unsigned long *get_bm_events_by_type(struct input_dev *dev,
++                                                int type)
++{
++      BUG_ON(type != EV_SW && type != EV_KEY);
++
++      return (type == EV_KEY) ? dev->keybit : dev->swbit;
++}
++
++/**
+  * gpio_keys_disable_button() - disables given GPIO button
+  * @bdata: button data for button to be disabled
+  *
+@@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_help
+                                          const char *buf, unsigned int type)
+ {
+       int n_events = get_n_events_by_type(type);
++      const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type);
+       unsigned long *bits;
+       ssize_t error;
+       int i;
+@@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_help
+               goto out;
+       /* First validate */
++      if (!bitmap_subset(bits, bitmap, n_events)) {
++              error = -EINVAL;
++              goto out;
++      }
++
+       for (i = 0; i < ddata->pdata->nbuttons; i++) {
+               struct gpio_button_data *bdata = &ddata->data[i];
+@@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_help
+               }
+       }
+-      if (i == ddata->pdata->nbuttons) {
+-              error = -EINVAL;
+-              goto out;
+-      }
+-
+       mutex_lock(&ddata->disable_lock);
+       for (i = 0; i < ddata->pdata->nbuttons; i++) {
diff --git a/queue-4.4/mac80211-fix-bw-upgrade-for-tdls-peers.patch b/queue-4.4/mac80211-fix-bw-upgrade-for-tdls-peers.patch
new file mode 100644 (file)
index 0000000..e8934e9
--- /dev/null
@@ -0,0 +1,46 @@
+From 4b559ec0bfc3a9f41a127cea6964f38b2b4bb323 Mon Sep 17 00:00:00 2001
+From: Ilan Peer <ilan.peer@intel.com>
+Date: Tue, 8 Mar 2016 13:35:31 +0200
+Subject: mac80211: Fix BW upgrade for TDLS peers
+
+From: Ilan Peer <ilan.peer@intel.com>
+
+commit 4b559ec0bfc3a9f41a127cea6964f38b2b4bb323 upstream.
+
+It is possible that the station is connected to an AP
+with bandwidth of 80+80MHz or 160MHz. In such cases
+there is no need to perform an upgrade as the maximal
+supported bandwidth is 80MHz.
+
+In addition, when upgrading and setting center_freq1
+and bandwidth to 80MHz also set center_freq2 to 0.
+
+Fixes: 0fabfaafec3a ("mac80211: upgrade BW of TDLS peers when possible"
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/tdls.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/tdls.c
++++ b/net/mac80211/tdls.c
+@@ -314,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
+       if (max_width > NL80211_CHAN_WIDTH_80)
+               max_width = NL80211_CHAN_WIDTH_80;
+-      if (uc.width == max_width)
++      if (uc.width >= max_width)
+               return;
+       /*
+        * Channel usage constrains in the IEEE802.11ac-2013 specification only
+@@ -325,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
+       for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++)
+               if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) {
+                       uc.center_freq1 = centers_80mhz[i];
++                      uc.center_freq2 = 0;
+                       uc.width = NL80211_CHAN_WIDTH_80;
+                       break;
+               }
diff --git a/queue-4.4/mac80211-fix-mgmt-tx-abort-cookie-and-leak.patch b/queue-4.4/mac80211-fix-mgmt-tx-abort-cookie-and-leak.patch
new file mode 100644 (file)
index 0000000..bb289c0
--- /dev/null
@@ -0,0 +1,38 @@
+From e673a65952b4ab045a3e3eb200fdf408004fb4fd Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 24 Nov 2015 20:28:27 +0100
+Subject: mac80211: fix mgmt-tx abort cookie and leak
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit e673a65952b4ab045a3e3eb200fdf408004fb4fd upstream.
+
+If a mgmt-tx operation is aborted before it runs, the wrong
+cookie is reported back to userspace, and the ack_skb gets
+leaked since the frame is freed directly instead of freeing
+it using ieee80211_free_txskb(). Fix that.
+
+Fixes: 3b79af973cf4 ("mac80211: stop using pointers as userspace cookies")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/offchannel.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/net/mac80211/offchannel.c
++++ b/net/mac80211/offchannel.c
+@@ -308,11 +308,10 @@ void ieee80211_roc_notify_destroy(struct
+       /* was never transmitted */
+       if (roc->frame) {
+-              cfg80211_mgmt_tx_status(&roc->sdata->wdev,
+-                                      (unsigned long)roc->frame,
++              cfg80211_mgmt_tx_status(&roc->sdata->wdev, roc->mgmt_tx_cookie,
+                                       roc->frame->data, roc->frame->len,
+                                       false, GFP_KERNEL);
+-              kfree_skb(roc->frame);
++              ieee80211_free_txskb(&roc->sdata->local->hw, roc->frame);
+       }
+       if (!roc->mgmt_tx_cookie)
diff --git a/queue-4.4/mac80211-tdls-always-downgrade-invalid-chandefs.patch b/queue-4.4/mac80211-tdls-always-downgrade-invalid-chandefs.patch
new file mode 100644 (file)
index 0000000..a4938e3
--- /dev/null
@@ -0,0 +1,34 @@
+From db8d99774c2682559b7648857697b9b588c6795a Mon Sep 17 00:00:00 2001
+From: Arik Nemtsov <arik@wizery.com>
+Date: Wed, 2 Mar 2016 23:28:31 +0200
+Subject: mac80211: TDLS: always downgrade invalid chandefs
+
+From: Arik Nemtsov <arik@wizery.com>
+
+commit db8d99774c2682559b7648857697b9b588c6795a upstream.
+
+Even if the current chandef width is equal to the station's max-BW, it
+doesn't mean it's a valid width for TDLS. Make sure to always check
+regulatory constraints in these cases.
+
+Fixes: 0fabfaafec3a ("mac80211: upgrade BW of TDLS peers when possible")
+Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/tdls.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/tdls.c
++++ b/net/mac80211/tdls.c
+@@ -332,7 +332,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
+               return;
+       /* proceed to downgrade the chandef until usable or the same */
+-      while (uc.width > max_width &&
++      while (uc.width > max_width ||
+              !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc,
+                                             sdata->wdev.iftype))
+               ieee80211_chandef_downgrade(&uc);
diff --git a/queue-4.4/mac80211-tdls-change-bw-calculation-for-wider_bw-peers.patch b/queue-4.4/mac80211-tdls-change-bw-calculation-for-wider_bw-peers.patch
new file mode 100644 (file)
index 0000000..16d3f2c
--- /dev/null
@@ -0,0 +1,189 @@
+From 59021c675995281d453eee45b3e2e1e3edbc0ec2 Mon Sep 17 00:00:00 2001
+From: Arik Nemtsov <arik@wizery.com>
+Date: Wed, 2 Mar 2016 23:28:32 +0200
+Subject: mac80211: TDLS: change BW calculation for WIDER_BW peers
+
+From: Arik Nemtsov <arik@wizery.com>
+
+commit 59021c675995281d453eee45b3e2e1e3edbc0ec2 upstream.
+
+The previous approach simply ignored chandef restrictions when calculating
+the appropriate peer BW for a WIDER_BW peer. This could result in a
+regulatory violation if both peers indicated 80MHz support, but the
+regdomain forbade it.
+
+Change the approach to setting a WIDER_BW peer's BW. Don't exempt it from
+the chandef width at first. If during TDLS negotiation the chandef width
+is upgraded, update the peer's BW to match.
+
+Fixes: 0fabfaafec3a ("mac80211: upgrade BW of TDLS peers when possible")
+Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/ieee80211_i.h |    4 ++++
+ net/mac80211/tdls.c        |   38 ++++++++++++++++++++++++++++++++------
+ net/mac80211/vht.c         |   30 +++++++++++++++++++++++++-----
+ 3 files changed, 61 insertions(+), 11 deletions(-)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1706,6 +1706,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru
+ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
+ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
+ void ieee80211_sta_set_rx_nss(struct sta_info *sta);
++enum ieee80211_sta_rx_bandwidth
++ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
++enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta);
++void ieee80211_sta_set_rx_nss(struct sta_info *sta);
+ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
+                                   struct sta_info *sta, u8 opmode,
+                                 enum ieee80211_band band);
+--- a/net/mac80211/tdls.c
++++ b/net/mac80211/tdls.c
+@@ -4,7 +4,7 @@
+  * Copyright 2006-2010        Johannes Berg <johannes@sipsolutions.net>
+  * Copyright 2014, Intel Corporation
+  * Copyright 2014  Intel Mobile Communications GmbH
+- * Copyright 2015  Intel Deutschland GmbH
++ * Copyright 2015 - 2016 Intel Deutschland GmbH
+  *
+  * This file is GPLv2 as found in COPYING.
+  */
+@@ -15,6 +15,7 @@
+ #include <linux/rtnetlink.h>
+ #include "ieee80211_i.h"
+ #include "driver-ops.h"
++#include "rate.h"
+ /* give usermode some time for retries in setting up the TDLS session */
+ #define TDLS_PEER_SETUP_TIMEOUT       (15 * HZ)
+@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
+       /* IEEE802.11ac-2013 Table E-4 */
+       u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 };
+       struct cfg80211_chan_def uc = sta->tdls_chandef;
+-      enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta);
++      enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta);
+       int i;
+       /* only support upgrading non-narrow channels up to 80Mhz */
+@@ -1242,18 +1243,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wi
+       return ret;
+ }
+-static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata)
++static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata,
++                                       struct sta_info *sta)
+ {
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_chanctx_conf *conf;
+       struct ieee80211_chanctx *ctx;
++      enum nl80211_chan_width width;
++      struct ieee80211_supported_band *sband;
+       mutex_lock(&local->chanctx_mtx);
+       conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
+                                        lockdep_is_held(&local->chanctx_mtx));
+       if (conf) {
++              width = conf->def.width;
++              sband = local->hw.wiphy->bands[conf->def.chan->band];
+               ctx = container_of(conf, struct ieee80211_chanctx, conf);
+               ieee80211_recalc_chanctx_chantype(local, ctx);
++
++              /* if width changed and a peer is given, update its BW */
++              if (width != conf->def.width && sta &&
++                  test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) {
++                      enum ieee80211_sta_rx_bandwidth bw;
++
++                      bw = ieee80211_chan_width_to_rx_bw(conf->def.width);
++                      bw = min(bw, ieee80211_sta_cap_rx_bw(sta));
++                      if (bw != sta->sta.bandwidth) {
++                              sta->sta.bandwidth = bw;
++                              rate_control_rate_update(local, sband, sta,
++                                                       IEEE80211_RC_BW_CHANGED);
++                              /*
++                               * if a TDLS peer BW was updated, we need to
++                               * recalc the chandef width again, to get the
++                               * correct chanctx min_def
++                               */
++                              ieee80211_recalc_chanctx_chantype(local, ctx);
++                      }
++              }
++
+       }
+       mutex_unlock(&local->chanctx_mtx);
+ }
+@@ -1350,8 +1377,6 @@ int ieee80211_tdls_oper(struct wiphy *wi
+                       break;
+               }
+-              iee80211_tdls_recalc_chanctx(sdata);
+-
+               mutex_lock(&local->sta_mtx);
+               sta = sta_info_get(sdata, peer);
+               if (!sta) {
+@@ -1360,6 +1385,7 @@ int ieee80211_tdls_oper(struct wiphy *wi
+                       break;
+               }
++              iee80211_tdls_recalc_chanctx(sdata, sta);
+               iee80211_tdls_recalc_ht_protection(sdata, sta);
+               set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
+@@ -1390,7 +1416,7 @@ int ieee80211_tdls_oper(struct wiphy *wi
+               iee80211_tdls_recalc_ht_protection(sdata, NULL);
+               mutex_unlock(&local->sta_mtx);
+-              iee80211_tdls_recalc_chanctx(sdata);
++              iee80211_tdls_recalc_chanctx(sdata, NULL);
+               break;
+       default:
+               ret = -ENOTSUPP;
+--- a/net/mac80211/vht.c
++++ b/net/mac80211/vht.c
+@@ -299,7 +299,30 @@ enum ieee80211_sta_rx_bandwidth ieee8021
+       return IEEE80211_STA_RX_BW_80;
+ }
+-static enum ieee80211_sta_rx_bandwidth
++enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
++{
++      struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
++      u32 cap_width;
++
++      if (!vht_cap->vht_supported) {
++              if (!sta->sta.ht_cap.ht_supported)
++                      return NL80211_CHAN_WIDTH_20_NOHT;
++
++              return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
++                              NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20;
++      }
++
++      cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
++
++      if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
++              return NL80211_CHAN_WIDTH_160;
++      else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
++              return NL80211_CHAN_WIDTH_80P80;
++
++      return NL80211_CHAN_WIDTH_80;
++}
++
++enum ieee80211_sta_rx_bandwidth
+ ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
+ {
+       switch (width) {
+@@ -327,10 +350,7 @@ enum ieee80211_sta_rx_bandwidth ieee8021
+       bw = ieee80211_sta_cap_rx_bw(sta);
+       bw = min(bw, sta->cur_max_bandwidth);
+-
+-      /* do not cap the BW of TDLS WIDER_BW peers by the bss */
+-      if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
+-              bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
++      bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
+       return bw;
+ }
diff --git a/queue-4.4/mmc-block-return-error-on-failed-mmc_blk_get.patch b/queue-4.4/mmc-block-return-error-on-failed-mmc_blk_get.patch
new file mode 100644 (file)
index 0000000..4322545
--- /dev/null
@@ -0,0 +1,39 @@
+From f00ab14c252ac459e86194747a1f580ab503c954 Mon Sep 17 00:00:00 2001
+From: Olof Johansson <olof@lixom.net>
+Date: Tue, 9 Feb 2016 09:34:30 -0800
+Subject: mmc: block: return error on failed mmc_blk_get()
+
+From: Olof Johansson <olof@lixom.net>
+
+commit f00ab14c252ac459e86194747a1f580ab503c954 upstream.
+
+This used to return -EFAULT, but the function above returns -EINVAL on
+the same condition so let's stick to that.
+
+The removal of error return on this path was introduced with b093410c9aef
+('mmc: block: copy resp[] data on err for MMC_IOC_MULTI_CMD').
+
+Fixes: b093410c9aef ('mmc: block: copy resp[] data on err for MMC_IOC_MULTI_CMD').
+Signed-off-by: Olof Johansson <olof@lixom.net>
+Cc: Grant Grundler <grundler@google.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/card/block.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -668,8 +668,10 @@ static int mmc_blk_ioctl_multi_cmd(struc
+       }
+       md = mmc_blk_get(bdev->bd_disk);
+-      if (!md)
++      if (!md) {
++              err = -EINVAL;
+               goto cmd_err;
++      }
+       card = md->queue.card;
+       if (IS_ERR(card)) {
diff --git a/queue-4.4/mmc-debugfs-correct-wrong-voltage-value.patch b/queue-4.4/mmc-debugfs-correct-wrong-voltage-value.patch
new file mode 100644 (file)
index 0000000..c3b2a18
--- /dev/null
@@ -0,0 +1,32 @@
+From 0036e74686344f1051afc3107740140abfd03616 Mon Sep 17 00:00:00 2001
+From: Chuanxiao Dong <chuanxiao.dong@intel.com>
+Date: Mon, 18 Jan 2016 10:35:19 +0100
+Subject: mmc: debugfs: correct wrong voltage value
+
+From: Chuanxiao Dong <chuanxiao.dong@intel.com>
+
+commit 0036e74686344f1051afc3107740140abfd03616 upstream.
+
+Correct the wrong voltage value shown in debugfs for mmc/sd/sdio.
+
+Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
+Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
+Fixes: 42cd95a0603e ("mmc: core: debugfs: Add signal_voltage to ios dump")
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/debugfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mmc/core/debugfs.c
++++ b/drivers/mmc/core/debugfs.c
+@@ -170,7 +170,7 @@ static int mmc_ios_show(struct seq_file
+               str = "invalid";
+               break;
+       }
+-      seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str);
++      seq_printf(s, "signal voltage:\t%u (%s)\n", ios->signal_voltage, str);
+       switch (ios->drv_type) {
+       case MMC_SET_DRIVER_TYPE_A:
diff --git a/queue-4.4/mmc-dw_mmc-rockchip-set-the-drive-phase-properly.patch b/queue-4.4/mmc-dw_mmc-rockchip-set-the-drive-phase-properly.patch
new file mode 100644 (file)
index 0000000..ea86304
--- /dev/null
@@ -0,0 +1,143 @@
+From d4aa908c7978f60557a799ca53b5ae4166fd8355 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 12 May 2016 11:31:50 -0700
+Subject: mmc: dw_mmc: rockchip: Set the drive phase properly
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit d4aa908c7978f60557a799ca53b5ae4166fd8355 upstream.
+
+Historically for Rockchip devices we've relied on the power-on
+default (or perhaps the firmware setting) to get the correct drive
+phase for dw_mmc devices.  This worked OK for the most part, but:
+
+* Relying on the setting just "being right" is a bit fragile.
+
+* As soon as there is an instance where the power on default is wrong or
+  where the firmware didn't configure this properly then we'll get a
+  mysterious failure.
+
+In commit 7a03fe6f48f3 ("clk: rockchip: reset init state before mmc card
+initialization") we actually started setting this explicitly in the
+kernel, but that commit wasn't quite right and also wasn't quite
+enough.  See <https://patchwork.kernel.org/patch/9085311/> for some
+details.
+
+Let's explicitly set this phase in dw_mmc.
+
+The comments inside this patch try to explain the situation quite
+throughly, but the high level overview of this is:
+
+Before this patch on rk3288 devices tested (after revert of the clock
+patch described above):
+* eMMC: 180 degrees
+* SDMMC/SDIO0/SDIO1: 90 degrees
+
+After this patch:
+* Use 90 degree phase offset usually.
+* Use 180 degree phase offset for MMC_DDR52, SDR104, HS200.
+
+That means we are _changing_ behavior for those devices in this way:
+
+* If we have HS200 eMMC or DDR52 eMMC, we'll run ID mode at 90
+  degrees (vs 180) but otherwise have no change.
+
+* For any non-HS200 / non-DDR52 eMMC devices we'll now _always_ run at
+  90 degrees (vs 180).  It seems fairly unlikely that building modern
+  hardware is using an eMMC that isn't using DDR52 or HS200, of course.
+
+* For SDR104 cards we'll now run with 180 degree phase offset (vs 90).
+  It's expected that 90 degree phase offset would have worked OK, but
+  this gives us extra margin.
+
+I have tested this by inserting my collection of uSD cards (mostly UHS,
+though a few not) into a veyron_minnie and confirmed that they still
+seem to enumerate properly.  For a subset of them I tried putting a
+filesystem on them and also tried running mmc_test.
+
+Fixes: 7a03fe6f48f3 ("clk: rockchip: reset init state before mmc card initialization")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/dw_mmc-rockchip.c |   64 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+--- a/drivers/mmc/host/dw_mmc-rockchip.c
++++ b/drivers/mmc/host/dw_mmc-rockchip.c
+@@ -78,6 +78,70 @@ static void dw_mci_rk3288_set_ios(struct
+       /* Make sure we use phases which we can enumerate with */
+       if (!IS_ERR(priv->sample_clk))
+               clk_set_phase(priv->sample_clk, priv->default_sample_phase);
++
++      /*
++       * Set the drive phase offset based on speed mode to achieve hold times.
++       *
++       * NOTE: this is _not_ a value that is dynamically tuned and is also
++       * _not_ a value that will vary from board to board.  It is a value
++       * that could vary between different SoC models if they had massively
++       * different output clock delays inside their dw_mmc IP block (delay_o),
++       * but since it's OK to overshoot a little we don't need to do complex
++       * calculations and can pick values that will just work for everyone.
++       *
++       * When picking values we'll stick with picking 0/90/180/270 since
++       * those can be made very accurately on all known Rockchip SoCs.
++       *
++       * Note that these values match values from the DesignWare Databook
++       * tables for the most part except for SDR12 and "ID mode".  For those
++       * two modes the databook calculations assume a clock in of 50MHz.  As
++       * seen above, we always use a clock in rate that is exactly the
++       * card's input clock (times RK3288_CLKGEN_DIV, but that gets divided
++       * back out before the controller sees it).
++       *
++       * From measurement of a single device, it appears that delay_o is
++       * about .5 ns.  Since we try to leave a bit of margin, it's expected
++       * that numbers here will be fine even with much larger delay_o
++       * (the 1.4 ns assumed by the DesignWare Databook would result in the
++       * same results, for instance).
++       */
++      if (!IS_ERR(priv->drv_clk)) {
++              int phase;
++
++              /*
++               * In almost all cases a 90 degree phase offset will provide
++               * sufficient hold times across all valid input clock rates
++               * assuming delay_o is not absurd for a given SoC.  We'll use
++               * that as a default.
++               */
++              phase = 90;
++
++              switch (ios->timing) {
++              case MMC_TIMING_MMC_DDR52:
++                      /*
++                       * Since clock in rate with MMC_DDR52 is doubled when
++                       * bus width is 8 we need to double the phase offset
++                       * to get the same timings.
++                       */
++                      if (ios->bus_width == MMC_BUS_WIDTH_8)
++                              phase = 180;
++                      break;
++              case MMC_TIMING_UHS_SDR104:
++              case MMC_TIMING_MMC_HS200:
++                      /*
++                       * In the case of 150 MHz clock (typical max for
++                       * Rockchip SoCs), 90 degree offset will add a delay
++                       * of 1.67 ns.  That will meet min hold time of .8 ns
++                       * as long as clock output delay is < .87 ns.  On
++                       * SoCs measured this seems to be OK, but it doesn't
++                       * hurt to give margin here, so we use 180.
++                       */
++                      phase = 180;
++                      break;
++              }
++
++              clk_set_phase(priv->drv_clk, phase);
++      }
+ }
+ #define NUM_PHASES                    360
diff --git a/queue-4.4/mmc-moxart-fix-wait_for_completion_interruptible_timeout-return-variable-type.patch b/queue-4.4/mmc-moxart-fix-wait_for_completion_interruptible_timeout-return-variable-type.patch
new file mode 100644 (file)
index 0000000..8242cca
--- /dev/null
@@ -0,0 +1,42 @@
+From 41f469cac2663a41a7b0c84cb94e8f7024385ae4 Mon Sep 17 00:00:00 2001
+From: Nicholas Mc Guire <hofrat@osadl.org>
+Date: Mon, 25 Jul 2016 19:59:23 +0200
+Subject: mmc: moxart: fix wait_for_completion_interruptible_timeout return variable type
+
+From: Nicholas Mc Guire <hofrat@osadl.org>
+
+commit 41f469cac2663a41a7b0c84cb94e8f7024385ae4 upstream.
+
+wait_for_completion_timeout_interruptible returns long not unsigned long
+so dma_time, which is used exclusively here, is changed to long.
+
+Fixes: 1b66e94e6b99 ("mmc: moxart: Add MOXA ART SD/MMC driver")
+Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/moxart-mmc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/moxart-mmc.c
++++ b/drivers/mmc/host/moxart-mmc.c
+@@ -257,7 +257,7 @@ static void moxart_dma_complete(void *pa
+ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
+ {
+       u32 len, dir_data, dir_slave;
+-      unsigned long dma_time;
++      long dma_time;
+       struct dma_async_tx_descriptor *desc = NULL;
+       struct dma_chan *dma_chan;
+@@ -397,7 +397,8 @@ static void moxart_prepare_data(struct m
+ static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ {
+       struct moxart_host *host = mmc_priv(mmc);
+-      unsigned long pio_time, flags;
++      long pio_time;
++      unsigned long flags;
+       u32 status;
+       spin_lock_irqsave(&host->lock, flags);
diff --git a/queue-4.4/mmc-sd-limit-sd-card-power-limit-according-to-cards-capabilities.patch b/queue-4.4/mmc-sd-limit-sd-card-power-limit-according-to-cards-capabilities.patch
new file mode 100644 (file)
index 0000000..92caca9
--- /dev/null
@@ -0,0 +1,79 @@
+From d9812780a020bcec44565b5950b2a8b31afb5545 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sat, 2 Jan 2016 10:06:29 +0000
+Subject: mmc: sd: limit SD card power limit according to cards capabilities
+
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+
+commit d9812780a020bcec44565b5950b2a8b31afb5545 upstream.
+
+The SD card specification allows cards to error out a SWITCH command
+where the requested function in a group is not supported.  The spec
+provides for a set of capabilities which indicate which functions are
+supported.
+
+In the case of the power limit, requesting an unsupported power level
+via the SWITCH command fails, resulting in the power level remaining at
+the power-on default of 0.72W, even though the host and card may support
+higher powers levels.
+
+This has been seen with SanDisk 8GB cards, which support the default
+0.72W and 1.44W (200mA and 400mA) in combination with an iMX6 host,
+supporting up to 2.88W (800mA).  This currently causes us to try to set
+a power limit function value of '3' (2.88W) which the card errors out
+on, and thereby causes the power level to remain at 0.72W rather than
+the desired 1.44W.
+
+Arrange to limit the selected current limit by the capabilities reported
+by the card to avoid the SWITCH command failing.  Select the highest
+current limit that the host and card combination support.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Fixes: a39ca6ae0a08 ("mmc: core: Simplify and fix for SD switch processing")
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/sd.c |   20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -337,6 +337,7 @@ static int mmc_read_switch(struct mmc_ca
+               card->sw_caps.sd3_bus_mode = status[13];
+               /* Driver Strengths supported by the card */
+               card->sw_caps.sd3_drv_type = status[9];
++              card->sw_caps.sd3_curr_limit = status[7] | status[6] << 8;
+       }
+ out:
+@@ -553,14 +554,25 @@ static int sd_set_current_limit(struct m
+        * when we set current limit to 200ma, the card will draw 200ma, and
+        * when we set current limit to 400/600/800ma, the card will draw its
+        * maximum 300ma from the host.
++       *
++       * The above is incorrect: if we try to set a current limit that is
++       * not supported by the card, the card can rightfully error out the
++       * attempt, and remain at the default current limit.  This results
++       * in a 300mA card being limited to 200mA even though the host
++       * supports 800mA. Failures seen with SanDisk 8GB UHS cards with
++       * an iMX6 host. --rmk
+        */
+-      if (max_current >= 800)
++      if (max_current >= 800 &&
++          card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
+               current_limit = SD_SET_CURRENT_LIMIT_800;
+-      else if (max_current >= 600)
++      else if (max_current >= 600 &&
++               card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
+               current_limit = SD_SET_CURRENT_LIMIT_600;
+-      else if (max_current >= 400)
++      else if (max_current >= 400 &&
++               card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
+               current_limit = SD_SET_CURRENT_LIMIT_400;
+-      else if (max_current >= 200)
++      else if (max_current >= 200 &&
++               card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
+               current_limit = SD_SET_CURRENT_LIMIT_200;
+       if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
diff --git a/queue-4.4/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch b/queue-4.4/mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch
new file mode 100644 (file)
index 0000000..7cad636
--- /dev/null
@@ -0,0 +1,209 @@
+From 1dceb0415aa0c6bc11dacdab47c9ef83a3604166 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 29 Mar 2016 12:45:43 +0300
+Subject: mmc: sdhci: Fix regression setting power on Trats2 board
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 1dceb0415aa0c6bc11dacdab47c9ef83a3604166 upstream.
+
+Several commits relating to setting power have been introducing
+problems by putting driver-specific rules into generic SDHCI code.
+
+Krzysztof Kozlowski reported that after commit 918f4cbd4340 ("mmc:
+sdhci: restore behavior when setting VDD via external regulator")
+on Trats2 board there are warnings for invalid VDD  value (2.8V):
+
+[    3.119656] ------------[ cut here ]------------
+[    3.119666] WARNING: CPU: 3 PID: 90 at
+../drivers/mmc/host/sdhci.c:1234 sdhci_do_set_ios+0x4cc/0x5e0
+[    3.119669] mmc0: Invalid vdd 0x10
+[    3.119673] Modules linked in:
+[    3.119679] CPU: 3 PID: 90 Comm: kworker/3:1 Tainted: G        W
+   4.5.0-next-20160324 #23
+[    3.119681] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
+[    3.119690] Workqueue: events_freezable mmc_rescan
+[    3.119708] [<c010e0ac>] (unwind_backtrace) from [<c010ae10>]
+(show_stack+0x10/0x14)
+[    3.119719] [<c010ae10>] (show_stack) from [<c0323260>]
+(dump_stack+0x88/0x9c)
+[    3.119728] [<c0323260>] (dump_stack) from [<c011b754>] (__warn+0xe8/0x100)
+[    3.119734] [<c011b754>] (__warn) from [<c011b7a4>]
+(warn_slowpath_fmt+0x38/0x48)
+[    3.119740] [<c011b7a4>] (warn_slowpath_fmt) from [<c0527d28>]
+(sdhci_do_set_ios+0x4cc/0x5e0)
+[    3.119748] [<c0527d28>] (sdhci_do_set_ios) from [<c0528018>]
+(sdhci_runtime_resume_host+0x60/0x114)
+[    3.119758] [<c0528018>] (sdhci_runtime_resume_host) from
+[<c0402570>] (__rpm_callback+0x2c/0x60)
+[    3.119767] [<c0402570>] (__rpm_callback) from [<c04025c4>]
+(rpm_callback+0x20/0x80)
+[    3.119773] [<c04025c4>] (rpm_callback) from [<c04034b8>]
+(rpm_resume+0x36c/0x558)
+[    3.119780] [<c04034b8>] (rpm_resume) from [<c04036f0>]
+(__pm_runtime_resume+0x4c/0x64)
+[    3.119788] [<c04036f0>] (__pm_runtime_resume) from [<c0512728>]
+(__mmc_claim_host+0x170/0x1b0)
+[    3.119795] [<c0512728>] (__mmc_claim_host) from [<c0514e2c>]
+(mmc_rescan+0x54/0x348)
+[    3.119807] [<c0514e2c>] (mmc_rescan) from [<c0130dac>]
+(process_one_work+0x120/0x3f4)
+[    3.119815] [<c0130dac>] (process_one_work) from [<c01310b8>]
+(worker_thread+0x38/0x554)
+[    3.119823] [<c01310b8>] (worker_thread) from [<c01365a4>]
+(kthread+0xdc/0xf4)
+[    3.119831] [<c01365a4>] (kthread) from [<c0107878>]
+(ret_from_fork+0x14/0x3c)
+[    3.119834] ---[ end trace a22d652aa3276886 ]---
+
+Fix by adding a 'set_power' callback and restoring the default
+behaviour prior to commit 918f4cbd4340 ("mmc: sdhci: restore
+behavior when setting VDD via external regulator").  The desired
+behaviour of that commit is gotten by having sdhci-pxav3 provide
+its own set_power callback.
+
+Reported-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Link: http://lkml.kernel.org/r/CAJKOXPcGDnPm-Ykh6wHqV1YxfTaov5E8iVqBoBn4OJc7BnhgEQ@mail.gmail.com
+Fixes: 918f4cbd4340 ("mmc: sdhci: restore behavior when setting VDD...)
+Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Tested-by: Ludovic Desroches <ludovic.desroches@atmel.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org # v4.5+
+Reviewed-by: Jisheng Zhang <jszhang@marvell.com>
+Tested-by: Jisheng Zhang <jszhang@marvell.com>
+Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
+Tested-by: Anand Moon <linux.amoon@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-pxav3.c |   22 ++++++++++++++++++++++
+ drivers/mmc/host/sdhci.c       |   39 ++++++++++++++++++++++++++++++---------
+ drivers/mmc/host/sdhci.h       |    4 ++++
+ 3 files changed, 56 insertions(+), 9 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-pxav3.c
++++ b/drivers/mmc/host/sdhci-pxav3.c
+@@ -307,8 +307,30 @@ static void pxav3_set_uhs_signaling(stru
+               __func__, uhs, ctrl_2);
+ }
++static void pxav3_set_power(struct sdhci_host *host, unsigned char mode,
++                          unsigned short vdd)
++{
++      struct mmc_host *mmc = host->mmc;
++      u8 pwr = host->pwr;
++
++      sdhci_set_power(host, mode, vdd);
++
++      if (host->pwr == pwr)
++              return;
++
++      if (host->pwr == 0)
++              vdd = 0;
++
++      if (!IS_ERR(mmc->supply.vmmc)) {
++              spin_unlock_irq(&host->lock);
++              mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
++              spin_lock_irq(&host->lock);
++      }
++}
++
+ static const struct sdhci_ops pxav3_sdhci_ops = {
+       .set_clock = sdhci_set_clock,
++      .set_power = pxav3_set_power,
+       .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
+       .get_max_clock = sdhci_pltfm_clk_get_max_clock,
+       .set_bus_width = sdhci_set_bus_width,
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1284,10 +1284,24 @@ clock_set:
+ }
+ EXPORT_SYMBOL_GPL(sdhci_set_clock);
+-static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+-                          unsigned short vdd)
++static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
++                              unsigned short vdd)
+ {
+       struct mmc_host *mmc = host->mmc;
++
++      spin_unlock_irq(&host->lock);
++      mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
++      spin_lock_irq(&host->lock);
++
++      if (mode != MMC_POWER_OFF)
++              sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
++      else
++              sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
++}
++
++void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
++                   unsigned short vdd)
++{
+       u8 pwr = 0;
+       if (mode != MMC_POWER_OFF) {
+@@ -1319,7 +1333,6 @@ static void sdhci_set_power(struct sdhci
+               sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+               if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
+                       sdhci_runtime_pm_bus_off(host);
+-              vdd = 0;
+       } else {
+               /*
+                * Spec says that we should clear the power reg before setting
+@@ -1350,12 +1363,20 @@ static void sdhci_set_power(struct sdhci
+               if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
+                       mdelay(10);
+       }
++}
++EXPORT_SYMBOL_GPL(sdhci_set_power);
+-      if (!IS_ERR(mmc->supply.vmmc)) {
+-              spin_unlock_irq(&host->lock);
+-              mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+-              spin_lock_irq(&host->lock);
+-      }
++static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode,
++                            unsigned short vdd)
++{
++      struct mmc_host *mmc = host->mmc;
++
++      if (host->ops->set_power)
++              host->ops->set_power(host, mode, vdd);
++      else if (!IS_ERR(mmc->supply.vmmc))
++              sdhci_set_power_reg(host, mode, vdd);
++      else
++              sdhci_set_power(host, mode, vdd);
+ }
+ /*****************************************************************************\
+@@ -1505,7 +1526,7 @@ static void sdhci_do_set_ios(struct sdhc
+               }
+       }
+-      sdhci_set_power(host, ios->power_mode, ios->vdd);
++      __sdhci_set_power(host, ios->power_mode, ios->vdd);
+       if (host->ops->platform_send_init_74_clocks)
+               host->ops->platform_send_init_74_clocks(host, ios->power_mode);
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -529,6 +529,8 @@ struct sdhci_ops {
+ #endif
+       void    (*set_clock)(struct sdhci_host *host, unsigned int clock);
++      void    (*set_power)(struct sdhci_host *host, unsigned char mode,
++                           unsigned short vdd);
+       int             (*enable_dma)(struct sdhci_host *host);
+       unsigned int    (*get_max_clock)(struct sdhci_host *host);
+@@ -660,6 +662,8 @@ static inline bool sdhci_sdio_irq_enable
+ }
+ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
++void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
++                   unsigned short vdd);
+ void sdhci_set_bus_width(struct sdhci_host *host, int width);
+ void sdhci_reset(struct sdhci_host *host, u8 mask);
+ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
diff --git a/queue-4.4/mmc-sdhci-restore-behavior-when-setting-vdd-via-external-regulator.patch b/queue-4.4/mmc-sdhci-restore-behavior-when-setting-vdd-via-external-regulator.patch
new file mode 100644 (file)
index 0000000..de81878
--- /dev/null
@@ -0,0 +1,79 @@
+From 918f4cbd4340ddd1eb389cd8efa3b07ac74ec4c0 Mon Sep 17 00:00:00 2001
+From: Jisheng Zhang <jszhang@marvell.com>
+Date: Fri, 11 Dec 2015 21:36:29 +0800
+Subject: mmc: sdhci: restore behavior when setting VDD via external regulator
+
+From: Jisheng Zhang <jszhang@marvell.com>
+
+commit 918f4cbd4340ddd1eb389cd8efa3b07ac74ec4c0 upstream.
+
+After commit 52221610dd84 ("mmc: sdhci: Improve external VDD regulator
+support"), for the VDD is supplied via external regulators, we ignore
+the code to convert a VDD voltage request into one of the standard
+SDHCI voltage levels, then program it in the SDHCI_POWER_CONTROL. This
+brings two issues:
+
+1. SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON quirk isn't handled properly any
+more.
+
+2. What's more, once SDHCI_POWER_ON bit is set, some controllers such
+as the sdhci-pxav3 used in marvell berlin SoCs require the voltage
+levels programming in the SDHCI_POWER_CONTROL register, even the VDD
+is supplied by external regulator. So the host in marvell berlin SoCs
+still works fine after the commit. However, commit 3cbc6123a93d ("mmc:
+sdhci: Set SDHCI_POWER_ON with external vmmc") sets the SDHCI_POWER_ON
+bit, this would make the host in marvell berlin SoCs won't work any
+more with external vmmc.
+
+This patch restores the behavior when setting VDD through external
+regulator by moving the call of mmc_regulator_set_ocr() to the end
+of sdhci_set_power() function.
+
+After this patch, the sdcard on Marvell Berlin SoC boards work again.
+
+Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
+Fixes: 52221610dd84 ("mmc: sdhci: Improve external VDD ...")
+Reviewed-by: Ludovic Desroches <ludovic.desroches@atmel.com>
+Tested-by: Ludovic Desroches <ludovic.desroches@atmel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci.c |   19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1290,19 +1290,6 @@ static void sdhci_set_power(struct sdhci
+       struct mmc_host *mmc = host->mmc;
+       u8 pwr = 0;
+-      if (!IS_ERR(mmc->supply.vmmc)) {
+-              spin_unlock_irq(&host->lock);
+-              mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+-              spin_lock_irq(&host->lock);
+-
+-              if (mode != MMC_POWER_OFF)
+-                      sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+-              else
+-                      sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+-
+-              return;
+-      }
+-
+       if (mode != MMC_POWER_OFF) {
+               switch (1 << vdd) {
+               case MMC_VDD_165_195:
+@@ -1363,6 +1350,12 @@ static void sdhci_set_power(struct sdhci
+               if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
+                       mdelay(10);
+       }
++
++      if (!IS_ERR(mmc->supply.vmmc)) {
++              spin_unlock_irq(&host->lock);
++              mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
++              spin_lock_irq(&host->lock);
++      }
+ }
+ /*****************************************************************************\
diff --git a/queue-4.4/mtd-nand-denali-add-missing-nand_release-call-in-denali_remove.patch b/queue-4.4/mtd-nand-denali-add-missing-nand_release-call-in-denali_remove.patch
new file mode 100644 (file)
index 0000000..95d83ea
--- /dev/null
@@ -0,0 +1,45 @@
+From 320092a05dab2f44819c42f33d6b51efb6c474f2 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <bbrezillon@kernel.org>
+Date: Fri, 11 Dec 2015 15:02:34 +0100
+Subject: mtd: nand: denali: add missing nand_release() call in denali_remove()
+
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+
+commit 320092a05dab2f44819c42f33d6b51efb6c474f2 upstream.
+
+Unregister the NAND device from the NAND subsystem when removing a denali
+NAND controller, otherwise the MTD attached to the NAND device is still
+exposed by the MTD layer, and accesses to this device will likely crash
+the system.
+
+Fixes: 2a0a288ec258 ("mtd: denali: split the generic driver and PCI layer")
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Acked-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/denali.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/denali.c
++++ b/drivers/mtd/nand/denali.c
+@@ -1622,9 +1622,16 @@ EXPORT_SYMBOL(denali_init);
+ /* driver exit point */
+ void denali_remove(struct denali_nand_info *denali)
+ {
++      /*
++       * Pre-compute DMA buffer size to avoid any problems in case
++       * nand_release() ever changes in a way that mtd->writesize and
++       * mtd->oobsize are not reliable after this call.
++       */
++      int bufsize = denali->mtd.writesize + denali->mtd.oobsize;
++
++      nand_release(&denali->mtd);
+       denali_irq_cleanup(denali->irq, denali);
+-      dma_unmap_single(denali->dev, denali->buf.dma_buf,
+-                       denali->mtd.writesize + denali->mtd.oobsize,
++      dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize,
+                        DMA_BIDIRECTIONAL);
+ }
+ EXPORT_SYMBOL(denali_remove);
diff --git a/queue-4.4/mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch b/queue-4.4/mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch
new file mode 100644 (file)
index 0000000..5d32ece
--- /dev/null
@@ -0,0 +1,41 @@
+From 9097103f06332d099c5ab06d1e7f22f4bcaca6e2 Mon Sep 17 00:00:00 2001
+From: Robert Jarzmik <robert.jarzmik@free.fr>
+Date: Fri, 12 Feb 2016 23:29:04 +0100
+Subject: mtd: nand: pxa3xx_nand: fix dmaengine initialization
+
+From: Robert Jarzmik <robert.jarzmik@free.fr>
+
+commit 9097103f06332d099c5ab06d1e7f22f4bcaca6e2 upstream.
+
+When the driver is initialized in a pure device-tree platform, the
+driver's probe fails allocating the dma channel :
+[  525.624435] pxa3xx-nand 43100000.nand: no resource defined for data DMA
+[  525.632088] pxa3xx-nand 43100000.nand: alloc nand resource failed
+
+The reason is that the DMA IO resource is not acquired through platform
+resources but by OF bindings.
+
+Fix this by ensuring that DMA IO resources are only queried in the non
+device-tree case.
+
+Fixes: 8f5ba31aa565 ("mtd: nand: pxa3xx-nand: switch to dmaengine")
+Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
+Acked-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/pxa3xx_nand.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1750,7 +1750,7 @@ static int alloc_nand_resource(struct pl
+       if (ret < 0)
+               return ret;
+-      if (use_dma) {
++      if (!np && use_dma) {
+               r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+               if (r == NULL) {
+                       dev_err(&pdev->dev,
diff --git a/queue-4.4/net-get-rid-of-an-signed-integer-overflow-in-ip_idents_reserve.patch b/queue-4.4/net-get-rid-of-an-signed-integer-overflow-in-ip_idents_reserve.patch
new file mode 100644 (file)
index 0000000..6f1e700
--- /dev/null
@@ -0,0 +1,51 @@
+From adb03115f4590baa280ddc440a8eff08a6be0cb7 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 20 Sep 2016 18:06:17 -0700
+Subject: net: get rid of an signed integer overflow in ip_idents_reserve()
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit adb03115f4590baa280ddc440a8eff08a6be0cb7 upstream.
+
+Jiri Pirko reported an UBSAN warning happening in ip_idents_reserve()
+
+[] UBSAN: Undefined behaviour in ./arch/x86/include/asm/atomic.h:156:11
+[] signed integer overflow:
+[] -2117905507 + -695755206 cannot be represented in type 'int'
+
+Since we do not have uatomic_add_return() yet, use atomic_cmpxchg()
+so that the arithmetics can be done using unsigned int.
+
+Fixes: 04ca6973f7c1 ("ip: make IP identifiers less predictable")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/route.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -477,12 +477,18 @@ u32 ip_idents_reserve(u32 hash, int segs
+       atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ;
+       u32 old = ACCESS_ONCE(*p_tstamp);
+       u32 now = (u32)jiffies;
+-      u32 delta = 0;
++      u32 new, delta = 0;
+       if (old != now && cmpxchg(p_tstamp, old, now) == old)
+               delta = prandom_u32_max(now - old);
+-      return atomic_add_return(segs + delta, p_id) - segs;
++      /* Do not use atomic_add_return() as it makes UBSAN unhappy */
++      do {
++              old = (u32)atomic_read(p_id);
++              new = old + delta + segs;
++      } while (atomic_cmpxchg(p_id, old, new) != old);
++
++      return new - segs;
+ }
+ EXPORT_SYMBOL(ip_idents_reserve);
diff --git a/queue-4.4/net-xfrm_input-fix-possible-null-deref-of-tunnel.ip6-parms.i_key.patch b/queue-4.4/net-xfrm_input-fix-possible-null-deref-of-tunnel.ip6-parms.i_key.patch
new file mode 100644 (file)
index 0000000..36b1c72
--- /dev/null
@@ -0,0 +1,74 @@
+From 1625f4529957738be7d87cf157e107b8fb9d23b9 Mon Sep 17 00:00:00 2001
+From: Alexey Kodanev <alexey.kodanev@oracle.com>
+Date: Wed, 10 Aug 2016 13:54:57 +0300
+Subject: net/xfrm_input: fix possible NULL deref of tunnel.ip6->parms.i_key
+
+From: Alexey Kodanev <alexey.kodanev@oracle.com>
+
+commit 1625f4529957738be7d87cf157e107b8fb9d23b9 upstream.
+
+Running LTP 'icmp-uni-basic.sh -6 -p ipcomp -m tunnel' test over
+openvswitch + veth can trigger kernel panic:
+
+  BUG: unable to handle kernel NULL pointer dereference
+  at 00000000000000e0 IP: [<ffffffff8169d1d2>] xfrm_input+0x82/0x750
+  ...
+  [<ffffffff816d472e>] xfrm6_rcv_spi+0x1e/0x20
+  [<ffffffffa082c3c2>] xfrm6_tunnel_rcv+0x42/0x50 [xfrm6_tunnel]
+  [<ffffffffa082727e>] tunnel6_rcv+0x3e/0x8c [tunnel6]
+  [<ffffffff8169f365>] ip6_input_finish+0xd5/0x430
+  [<ffffffff8169fc53>] ip6_input+0x33/0x90
+  [<ffffffff8169f1d5>] ip6_rcv_finish+0xa5/0xb0
+  ...
+
+It seems that tunnel.ip6 can have garbage values and also dereferenced
+without a proper check, only tunnel.ip4 is being verified. Fix it by
+adding one more if block for AF_INET6 and initialize tunnel.ip6 with NULL
+inside xfrm6_rcv_spi() (which is similar to xfrm4_rcv_spi()).
+
+Fixes: 049f8e2 ("xfrm: Override skb->mark with tunnel->parm.i_key in xfrm_input")
+
+Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/xfrm6_input.c |    1 +
+ net/xfrm/xfrm_input.c  |   14 +++++++-------
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/net/ipv6/xfrm6_input.c
++++ b/net/ipv6/xfrm6_input.c
+@@ -23,6 +23,7 @@ int xfrm6_extract_input(struct xfrm_stat
+ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+ {
++      XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
+       XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
+       XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+       return xfrm_input(skb, nexthdr, spi, 0);
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int
+       family = XFRM_SPI_SKB_CB(skb)->family;
+       /* if tunnel is present override skb->mark value with tunnel i_key */
+-      if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) {
+-              switch (family) {
+-              case AF_INET:
++      switch (family) {
++      case AF_INET:
++              if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
+                       mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
+-                      break;
+-              case AF_INET6:
++              break;
++      case AF_INET6:
++              if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
+                       mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
+-                      break;
+-              }
++              break;
+       }
+       /* Allocate new secpath or COW existing one. */
diff --git a/queue-4.4/nfs-fix-an-lock-open-race-when-unlinking-an-open-file.patch b/queue-4.4/nfs-fix-an-lock-open-race-when-unlinking-an-open-file.patch
new file mode 100644 (file)
index 0000000..da49f94
--- /dev/null
@@ -0,0 +1,73 @@
+From 11476e9dec39d90fe1e9bf12abc6f3efe35a073d Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Mon, 11 Apr 2016 16:20:22 -0400
+Subject: NFS: Fix an LOCK/OPEN race when unlinking an open file
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 11476e9dec39d90fe1e9bf12abc6f3efe35a073d upstream.
+
+At Connectathon 2016, we found that recent upstream Linux clients
+would occasionally send a LOCK operation with a zero stateid. This
+appeared to happen in close proximity to another thread returning
+a delegation before unlinking the same file while it remained open.
+
+Earlier, the client received a write delegation on this file and
+returned the open stateid. Now, as it is getting ready to unlink the
+file, it returns the write delegation. But there is still an open
+file descriptor on that file, so the client must OPEN the file
+again before it returns the delegation.
+
+Since commit 24311f884189 ('NFSv4: Recovery of recalled read
+delegations is broken'), nfs_open_delegation_recall() clears the
+NFS_DELEGATED_STATE flag _before_ it sends the OPEN. This allows a
+racing LOCK on the same inode to be put on the wire before the OPEN
+operation has returned a valid open stateid.
+
+To eliminate this race, serialize delegation return with the
+acquisition of a file lock on the same file. Adopt the same approach
+as is used in the unlock path.
+
+This patch also eliminates a similar race seen when sending a LOCK
+operation at the same time as returning a delegation on the same file.
+
+Fixes: 24311f884189 ('NFSv4: Recovery of recalled read ... ')
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[Anna: Add sentence about LOCK / delegation race]
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6054,6 +6054,7 @@ static int nfs41_lock_expired(struct nfs
+ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
+ {
+       struct nfs_inode *nfsi = NFS_I(state->inode);
++      struct nfs4_state_owner *sp = state->owner;
+       unsigned char fl_flags = request->fl_flags;
+       int status = -ENOLCK;
+@@ -6068,6 +6069,7 @@ static int _nfs4_proc_setlk(struct nfs4_
+       status = do_vfs_lock(state->inode, request);
+       if (status < 0)
+               goto out;
++      mutex_lock(&sp->so_delegreturn_mutex);
+       down_read(&nfsi->rwsem);
+       if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+               /* Yes: cache locks! */
+@@ -6075,9 +6077,11 @@ static int _nfs4_proc_setlk(struct nfs4_
+               request->fl_flags = fl_flags & ~FL_SLEEP;
+               status = do_vfs_lock(state->inode, request);
+               up_read(&nfsi->rwsem);
++              mutex_unlock(&sp->so_delegreturn_mutex);
+               goto out;
+       }
+       up_read(&nfsi->rwsem);
++      mutex_unlock(&sp->so_delegreturn_mutex);
+       status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
+ out:
+       request->fl_flags = fl_flags;
diff --git a/queue-4.4/revert-acpi-lpss-allow-to-use-specific-pm-domain-during-probe.patch b/queue-4.4/revert-acpi-lpss-allow-to-use-specific-pm-domain-during-probe.patch
new file mode 100644 (file)
index 0000000..e4a975b
--- /dev/null
@@ -0,0 +1,49 @@
+From b5f88dd1d6efc472e35ca1b21a44e662c5422088 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 4 Dec 2015 23:49:18 +0200
+Subject: Revert "ACPI / LPSS: allow to use specific PM domain during ->probe()"
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit b5f88dd1d6efc472e35ca1b21a44e662c5422088 upstream.
+
+The specific power domain can't be used in a way provided by the commit
+01ac170ba29a, i.e. pointer to platform device is a subject to change during
+unbound / bind cycle.
+
+This reverts commit 01ac170ba29a9903ee590e1ef2d8e6b27b49a16c.
+
+Fixes: 3df2da968744 (Revert "ACPI / LPSS: introduce a 'proxy' device to power on LPSS for DMA")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/acpi_lpss.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/acpi_lpss.c
++++ b/drivers/acpi/acpi_lpss.c
+@@ -704,8 +704,13 @@ static int acpi_lpss_platform_notify(str
+       }
+       switch (action) {
+-      case BUS_NOTIFY_ADD_DEVICE:
++      case BUS_NOTIFY_BOUND_DRIVER:
+               pdev->dev.pm_domain = &acpi_lpss_pm_domain;
++              break;
++      case BUS_NOTIFY_UNBOUND_DRIVER:
++              pdev->dev.pm_domain = NULL;
++              break;
++      case BUS_NOTIFY_ADD_DEVICE:
+               if (pdata->dev_desc->flags & LPSS_LTR)
+                       return sysfs_create_group(&pdev->dev.kobj,
+                                                 &lpss_attr_group);
+@@ -713,7 +718,6 @@ static int acpi_lpss_platform_notify(str
+       case BUS_NOTIFY_DEL_DEVICE:
+               if (pdata->dev_desc->flags & LPSS_LTR)
+                       sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
+-              pdev->dev.pm_domain = NULL;
+               break;
+       default:
+               break;
index 3a137c9e635d0f9907157718279dbc08c841ef93..1292bb3b27383c7403b05644f0108bdb9f553ebf 100644 (file)
@@ -118,3 +118,28 @@ serial-samsung-fix-possible-out-of-bounds-access-on-non-dt-platform.patch
 drivers-hv-utils-use-memdup_user-in-hvt_op_write.patch
 isa-call-isa_bus_init-before-dependent-isa-bus-drivers-register.patch
 btrfs-clean-up-an-error-code-in-btrfs_init_space_info.patch
+input-gpio-keys-fix-check-for-disabling-unsupported-keys.patch
+input-edt-ft5x06-fix-setting-gain-offset-and-threshold-via-device-tree.patch
+net-xfrm_input-fix-possible-null-deref-of-tunnel.ip6-parms.i_key.patch
+xfrm_user-propagate-sec-ctx-allocation-errors.patch
+xfrm-fix-memory-leak-of-aead-algorithm-name.patch
+mac80211-fix-mgmt-tx-abort-cookie-and-leak.patch
+mac80211-tdls-always-downgrade-invalid-chandefs.patch
+mac80211-tdls-change-bw-calculation-for-wider_bw-peers.patch
+mac80211-fix-bw-upgrade-for-tdls-peers.patch
+nfs-fix-an-lock-open-race-when-unlinking-an-open-file.patch
+net-get-rid-of-an-signed-integer-overflow-in-ip_idents_reserve.patch
+mtd-nand-denali-add-missing-nand_release-call-in-denali_remove.patch
+mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch
+asoc-intel-pass-correct-parameter-in-sst_alloc_stream_mrfld.patch
+asoc-tegra_alc5632-check-return-value.patch
+asoc-fsl_ssi-mark-sacnt-register-volatile.patch
+revert-acpi-lpss-allow-to-use-specific-pm-domain-during-probe.patch
+mmc-sdhci-restore-behavior-when-setting-vdd-via-external-regulator.patch
+mmc-sd-limit-sd-card-power-limit-according-to-cards-capabilities.patch
+mmc-debugfs-correct-wrong-voltage-value.patch
+mmc-block-return-error-on-failed-mmc_blk_get.patch
+clk-rockchip-revert-clk-rockchip-reset-init-state-before-mmc-card-initialization.patch
+mmc-dw_mmc-rockchip-set-the-drive-phase-properly.patch
+mmc-moxart-fix-wait_for_completion_interruptible_timeout-return-variable-type.patch
+mmc-sdhci-fix-regression-setting-power-on-trats2-board.patch
diff --git a/queue-4.4/xfrm-fix-memory-leak-of-aead-algorithm-name.patch b/queue-4.4/xfrm-fix-memory-leak-of-aead-algorithm-name.patch
new file mode 100644 (file)
index 0000000..1088a4d
--- /dev/null
@@ -0,0 +1,38 @@
+From b588479358ce26f32138e0f0a7ab0678f8e3e601 Mon Sep 17 00:00:00 2001
+From: Ilan Tayari <ilant@mellanox.com>
+Date: Sun, 18 Sep 2016 07:42:53 +0000
+Subject: xfrm: Fix memory leak of aead algorithm name
+
+From: Ilan Tayari <ilant@mellanox.com>
+
+commit b588479358ce26f32138e0f0a7ab0678f8e3e601 upstream.
+
+commit 1a6509d99122 ("[IPSEC]: Add support for combined mode algorithms")
+introduced aead. The function attach_aead kmemdup()s the algorithm
+name during xfrm_state_construct().
+However this memory is never freed.
+Implementation has since been slightly modified in
+commit ee5c23176fcc ("xfrm: Clone states properly on migration")
+without resolving this leak.
+This patch adds a kfree() call for the aead algorithm name.
+
+Fixes: 1a6509d99122 ("[IPSEC]: Add support for combined mode algorithms")
+Signed-off-by: Ilan Tayari <ilant@mellanox.com>
+Acked-by: Rami Rosen <roszenrami@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_state.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -332,6 +332,7 @@ static void xfrm_state_gc_destroy(struct
+ {
+       tasklet_hrtimer_cancel(&x->mtimer);
+       del_timer_sync(&x->rtimer);
++      kfree(x->aead);
+       kfree(x->aalg);
+       kfree(x->ealg);
+       kfree(x->calg);
diff --git a/queue-4.4/xfrm_user-propagate-sec-ctx-allocation-errors.patch b/queue-4.4/xfrm_user-propagate-sec-ctx-allocation-errors.patch
new file mode 100644 (file)
index 0000000..1c60965
--- /dev/null
@@ -0,0 +1,47 @@
+From 2f30ea5090cbc57ea573cdc66421264b3de3fb0a Mon Sep 17 00:00:00 2001
+From: Mathias Krause <minipli@googlemail.com>
+Date: Thu, 8 Sep 2016 18:09:57 +0200
+Subject: xfrm_user: propagate sec ctx allocation errors
+
+From: Mathias Krause <minipli@googlemail.com>
+
+commit 2f30ea5090cbc57ea573cdc66421264b3de3fb0a upstream.
+
+When we fail to attach the security context in xfrm_state_construct()
+we'll return 0 as error value which, in turn, will wrongly claim success
+to userland when, in fact, we won't be adding / updating the XFRM state.
+
+This is a regression introduced by commit fd21150a0fe1 ("[XFRM] netlink:
+Inline attach_encap_tmpl(), attach_sec_ctx(), and attach_one_addr()").
+
+Fix it by propagating the error returned by security_xfrm_state_alloc()
+in this case.
+
+Fixes: fd21150a0fe1 ("[XFRM] netlink: Inline attach_encap_tmpl()...")
+Signed-off-by: Mathias Krause <minipli@googlemail.com>
+Cc: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_user.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -609,9 +609,12 @@ static struct xfrm_state *xfrm_state_con
+       if (err)
+               goto error;
+-      if (attrs[XFRMA_SEC_CTX] &&
+-          security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX])))
+-              goto error;
++      if (attrs[XFRMA_SEC_CTX]) {
++              err = security_xfrm_state_alloc(x,
++                                              nla_data(attrs[XFRMA_SEC_CTX]));
++              if (err)
++                      goto error;
++      }
+       if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn,
+                                              attrs[XFRMA_REPLAY_ESN_VAL])))