--- /dev/null
+From 62db7152c924e4c060e42b34a69cd39658e8a0dc Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 29 Jun 2016 15:23:08 +0200
+Subject: ALSA: au88x0: Fix calculation in vortex_wtdma_bufshift()
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 62db7152c924e4c060e42b34a69cd39658e8a0dc upstream.
+
+vortex_wtdma_bufshift() function does calculate the page index
+wrongly, first masking then shift, which always results in zero.
+The proper computation is to first shift, then mask.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/au88x0/au88x0_core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/pci/au88x0/au88x0_core.c
++++ b/sound/pci/au88x0/au88x0_core.c
+@@ -1444,9 +1444,8 @@ static int vortex_wtdma_bufshift(vortex_
+ int page, p, pp, delta, i;
+
+ page =
+- (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
+- WT_SUBBUF_MASK)
+- >> WT_SUBBUF_SHIFT;
++ (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2))
++ >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
+ if (dma->nr_periods >= 4)
+ delta = (page - dma->period_real) & 3;
+ else {
--- /dev/null
+From f388cdcdd160687c6650833f286b9c89c50960ff Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 8 Jul 2016 08:05:19 +0200
+Subject: ALSA: ctl: Stop notification after disconnection
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit f388cdcdd160687c6650833f286b9c89c50960ff upstream.
+
+snd_ctl_remove() has a notification for the removal event. It's
+superfluous when done during the device got disconnected. Although
+the notification itself is mostly harmless, it may potentially be
+harmful, and should be suppressed. Actually some components PCM may
+free ctl elements during the disconnect or free callbacks, thus it's
+no theoretical issue.
+
+This patch adds the check of card->shutdown flag for avoiding
+unnecessary notifications after (or during) the disconnect.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/control.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -160,6 +160,8 @@ void snd_ctl_notify(struct snd_card *car
+
+ if (snd_BUG_ON(!card || !id))
+ return;
++ if (card->shutdown)
++ return;
+ read_lock(&card->ctl_files_rwlock);
+ #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
+ card->mixer_oss_change_count++;
--- /dev/null
+From d5dbbe6569481bf12dcbe3e12cff72c5f78d272c Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 24 Jun 2016 15:15:26 +0200
+Subject: ALSA: dummy: Fix a use-after-free at closing
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit d5dbbe6569481bf12dcbe3e12cff72c5f78d272c upstream.
+
+syzkaller fuzzer spotted a potential use-after-free case in snd-dummy
+driver when hrtimer is used as backend:
+> ==================================================================
+> BUG: KASAN: use-after-free in rb_erase+0x1b17/0x2010 at addr ffff88005e5b6f68
+> Read of size 8 by task syz-executor/8984
+> =============================================================================
+> BUG kmalloc-192 (Not tainted): kasan: bad access detected
+> -----------------------------------------------------------------------------
+>
+> Disabling lock debugging due to kernel taint
+> INFO: Allocated in 0xbbbbbbbbbbbbbbbb age=18446705582212484632
+> ....
+> [< none >] dummy_hrtimer_create+0x49/0x1a0 sound/drivers/dummy.c:464
+> ....
+> INFO: Freed in 0xfffd8e09 age=18446705496313138713 cpu=2164287125 pid=-1
+> [< none >] dummy_hrtimer_free+0x68/0x80 sound/drivers/dummy.c:481
+> ....
+> Call Trace:
+> [<ffffffff8179e59e>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:333
+> [< inline >] rb_set_parent include/linux/rbtree_augmented.h:111
+> [< inline >] __rb_erase_augmented include/linux/rbtree_augmented.h:218
+> [<ffffffff82ca5787>] rb_erase+0x1b17/0x2010 lib/rbtree.c:427
+> [<ffffffff82cb02e8>] timerqueue_del+0x78/0x170 lib/timerqueue.c:86
+> [<ffffffff814d0c80>] __remove_hrtimer+0x90/0x220 kernel/time/hrtimer.c:903
+> [< inline >] remove_hrtimer kernel/time/hrtimer.c:945
+> [<ffffffff814d23da>] hrtimer_try_to_cancel+0x22a/0x570 kernel/time/hrtimer.c:1046
+> [<ffffffff814d2742>] hrtimer_cancel+0x22/0x40 kernel/time/hrtimer.c:1066
+> [<ffffffff85420531>] dummy_hrtimer_stop+0x91/0xb0 sound/drivers/dummy.c:417
+> [<ffffffff854228bf>] dummy_pcm_trigger+0x17f/0x1e0 sound/drivers/dummy.c:507
+> [<ffffffff85392170>] snd_pcm_do_stop+0x160/0x1b0 sound/core/pcm_native.c:1106
+> [<ffffffff85391b26>] snd_pcm_action_single+0x76/0x120 sound/core/pcm_native.c:956
+> [<ffffffff85391e01>] snd_pcm_action+0x231/0x290 sound/core/pcm_native.c:974
+> [< inline >] snd_pcm_stop sound/core/pcm_native.c:1139
+> [<ffffffff8539754d>] snd_pcm_drop+0x12d/0x1d0 sound/core/pcm_native.c:1784
+> [<ffffffff8539d3be>] snd_pcm_common_ioctl1+0xfae/0x2150 sound/core/pcm_native.c:2805
+> [<ffffffff8539ee91>] snd_pcm_capture_ioctl1+0x2a1/0x5e0 sound/core/pcm_native.c:2976
+> [<ffffffff8539f2ec>] snd_pcm_kernel_ioctl+0x11c/0x160 sound/core/pcm_native.c:3020
+> [<ffffffff853d9a44>] snd_pcm_oss_sync+0x3a4/0xa30 sound/core/oss/pcm_oss.c:1693
+> [<ffffffff853da27d>] snd_pcm_oss_release+0x1ad/0x280 sound/core/oss/pcm_oss.c:2483
+> .....
+
+A workaround is to call hrtimer_cancel() in dummy_hrtimer_sync() which
+is called certainly before other blocking ops.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/drivers/dummy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/drivers/dummy.c
++++ b/sound/drivers/dummy.c
+@@ -420,6 +420,7 @@ static int dummy_hrtimer_stop(struct snd
+
+ static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
+ {
++ hrtimer_cancel(&dpcm->timer);
+ tasklet_kill(&dpcm->tasklet);
+ }
+
--- /dev/null
+From 9c6795a9b3cbb56a9fbfaf43909c5c22999ba317 Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Mon, 27 Jun 2016 21:06:51 +0200
+Subject: ALSA: echoaudio: Fix memory allocation
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+commit 9c6795a9b3cbb56a9fbfaf43909c5c22999ba317 upstream.
+
+'commpage_bak' is allocated with 'sizeof(struct echoaudio)' bytes.
+We then copy 'sizeof(struct comm_page)' bytes in it.
+On my system, smatch complains because one is 2960 and the other is 3072.
+
+This would result in memory corruption or a oops.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/echoaudio/echoaudio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/echoaudio/echoaudio.c
++++ b/sound/pci/echoaudio/echoaudio.c
+@@ -2200,11 +2200,11 @@ static int snd_echo_resume(struct device
+ u32 pipe_alloc_mask;
+ int err;
+
+- commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
++ commpage_bak = kmalloc(sizeof(*commpage), GFP_KERNEL);
+ if (commpage_bak == NULL)
+ return -ENOMEM;
+ commpage = chip->comm_page;
+- memcpy(commpage_bak, commpage, sizeof(struct comm_page));
++ memcpy(commpage_bak, commpage, sizeof(*commpage));
+
+ err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
+ if (err < 0) {
--- /dev/null
+From d716fb03f76411fc7e138692e33b749cada5c094 Mon Sep 17 00:00:00 2001
+From: Awais Belal <awais_belal@mentor.com>
+Date: Tue, 12 Jul 2016 15:21:28 +0500
+Subject: ALSA: hda: add AMD Stoney PCI ID with proper driver caps
+
+From: Awais Belal <awais_belal@mentor.com>
+
+commit d716fb03f76411fc7e138692e33b749cada5c094 upstream.
+
+This allows the device to correctly show up as ATI HDMI
+rather than a generic one and allows the driver to use
+the available caps.
+
+Signed-off-by: Awais Belal <awais_belal@mentor.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2269,6 +2269,8 @@ static const struct pci_device_id azx_id
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+ { PCI_DEVICE(0x1002, 0x157a),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++ { PCI_DEVICE(0x1002, 0x15b3),
++ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+ { PCI_DEVICE(0x1002, 0x793b),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x7919),
--- /dev/null
+From 6858107e78b4ecb9f244db814ffbdba1b5ce759b Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Wed, 29 Jun 2016 10:27:52 +0530
+Subject: ALSA: hda - Add PCI ID for Kabylake-H
+
+From: Vinod Koul <vinod.koul@intel.com>
+
+commit 6858107e78b4ecb9f244db814ffbdba1b5ce759b upstream.
+
+Kabylake-H shows up as PCI ID 0xa2f0. We missed adding this
+earlier with other KBL IDs.
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -367,9 +367,10 @@ enum {
+ #define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+ #define IS_KBL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171)
+ #define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
++#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
+ #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+ #define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
+- IS_KBL(pci) || IS_KBL_LP(pci)
++ IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)
+
+ static char *driver_short_names[] = {
+ [AZX_DRIVER_ICH] = "HDA Intel",
+@@ -2190,6 +2191,9 @@ static const struct pci_device_id azx_id
+ /* Kabylake-LP */
+ { PCI_DEVICE(0x8086, 0x9d71),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
++ /* Kabylake-H */
++ { PCI_DEVICE(0x8086, 0xa2f0),
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ /* Broxton-P(Apollolake) */
+ { PCI_DEVICE(0x8086, 0x5a98),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
--- /dev/null
+From 81e43960dce1c8e58e682fb3ec26c1d8f83a9afc Mon Sep 17 00:00:00 2001
+From: Bob Copeland <me@bobcopeland.com>
+Date: Sat, 25 Jun 2016 07:58:45 -0400
+Subject: ALSA: hda - fix read before array start
+
+From: Bob Copeland <me@bobcopeland.com>
+
+commit 81e43960dce1c8e58e682fb3ec26c1d8f83a9afc upstream.
+
+UBSAN reports the following warning from accessing path->path[-1]
+in set_path_power():
+
+[ 16.078040] ================================================================================
+[ 16.078124] UBSAN: Undefined behaviour in sound/pci/hda/hda_generic.c:3981:17
+[ 16.078198] index -1 is out of range for type 'hda_nid_t [10]'
+[ 16.078270] CPU: 2 PID: 1738 Comm: modprobe Not tainted 4.7.0-rc1-wt+ #47
+[ 16.078274] Hardware name: LENOVO 3443CTO/3443CTO, BIOS G6ET23WW (1.02 ) 08/14/2012
+[ 16.078278] ffff8800cb246000 ffff8800cb3638b8 ffffffff815c4fe3 0000000000000032
+[ 16.078286] ffff8800cb3638e0 ffffffffffffffff ffff8800cb3638d0 ffffffff8162443d
+[ 16.078294] ffffffffa0894200 ffff8800cb363920 ffffffff81624af7 0000000000000292
+[ 16.078302] Call Trace:
+[ 16.078311] [<ffffffff815c4fe3>] dump_stack+0x86/0xd3
+[ 16.078317] [<ffffffff8162443d>] ubsan_epilogue+0xd/0x40
+[ 16.078324] [<ffffffff81624af7>] __ubsan_handle_out_of_bounds+0x67/0x70
+[ 16.078335] [<ffffffffa087665f>] set_path_power+0x1bf/0x230 [snd_hda_codec_generic]
+[ 16.078344] [<ffffffffa087880d>] add_pin_power_ctls+0x8d/0xc0 [snd_hda_codec_generic]
+[ 16.078352] [<ffffffffa087f190>] ? pin_power_down_callback+0x20/0x20 [snd_hda_codec_generic]
+[ 16.078360] [<ffffffffa0878947>] add_all_pin_power_ctls+0x107/0x150 [snd_hda_codec_generic]
+[ 16.078370] [<ffffffffa08842b3>] snd_hda_gen_parse_auto_config+0x2d73/0x49e0 [snd_hda_codec_generic]
+[ 16.078376] [<ffffffff81173360>] ? trace_hardirqs_on_caller+0x1b0/0x2c0
+[ 16.078390] [<ffffffffa089df27>] alc_parse_auto_config+0x147/0x310 [snd_hda_codec_realtek]
+[ 16.078402] [<ffffffffa08a332a>] patch_alc269+0x23a/0x560 [snd_hda_codec_realtek]
+[ 16.078417] [<ffffffffa0838644>] hda_codec_driver_probe+0xa4/0x1a0 [snd_hda_codec]
+[ 16.078424] [<ffffffff817bbac1>] driver_probe_device+0x101/0x380
+[ 16.078430] [<ffffffff817bbdf9>] __driver_attach+0xb9/0x100
+[ 16.078438] [<ffffffff817bbd40>] ? driver_probe_device+0x380/0x380
+[ 16.078444] [<ffffffff817b8d20>] bus_for_each_dev+0x70/0xc0
+[ 16.078449] [<ffffffff817bb087>] driver_attach+0x27/0x50
+[ 16.078454] [<ffffffff817ba956>] bus_add_driver+0x166/0x2c0
+[ 16.078460] [<ffffffffa0369000>] ? 0xffffffffa0369000
+[ 16.078465] [<ffffffff817bd13d>] driver_register+0x7d/0x130
+[ 16.078477] [<ffffffffa083816f>] __hda_codec_driver_register+0x6f/0x90 [snd_hda_codec]
+[ 16.078488] [<ffffffffa036901e>] realtek_driver_init+0x1e/0x1000 [snd_hda_codec_realtek]
+[ 16.078493] [<ffffffff8100215e>] do_one_initcall+0x4e/0x1d0
+[ 16.078499] [<ffffffff8119f54d>] ? rcu_read_lock_sched_held+0x6d/0x80
+[ 16.078504] [<ffffffff813701b1>] ? kmem_cache_alloc_trace+0x391/0x560
+[ 16.078510] [<ffffffff812bb314>] ? do_init_module+0x28/0x273
+[ 16.078515] [<ffffffff812bb387>] do_init_module+0x9b/0x273
+[ 16.078522] [<ffffffff811e3782>] load_module+0x20b2/0x3410
+[ 16.078527] [<ffffffff811df140>] ? m_show+0x210/0x210
+[ 16.078533] [<ffffffff813b2b26>] ? kernel_read+0x66/0xe0
+[ 16.078541] [<ffffffff811e4cfa>] SYSC_finit_module+0xba/0xc0
+[ 16.078547] [<ffffffff811e4d1e>] SyS_finit_module+0xe/0x10
+[ 16.078552] [<ffffffff81a860fc>] entry_SYSCALL_64_fastpath+0x1f/0xbd
+[ 16.078556] ================================================================================
+
+Fix by checking path->depth before use.
+
+Signed-off-by: Bob Copeland <me@bobcopeland.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_generic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -3977,6 +3977,8 @@ static hda_nid_t set_path_power(struct h
+
+ for (n = 0; n < spec->paths.used; n++) {
+ path = snd_array_elem(&spec->paths, n);
++ if (!path->depth)
++ continue;
+ if (path->path[0] == nid ||
+ path->path[path->depth - 1] == nid) {
+ bool pin_old = path->pin_enabled;
--- /dev/null
+From f83c32925d45926cd0e0f18bf28e6039116c4486 Mon Sep 17 00:00:00 2001
+From: Woodrow Shen <woodrow.shen@gmail.com>
+Date: Fri, 24 Jun 2016 15:58:34 +0800
+Subject: ALSA: hda - Fix the headset mic jack detection on Dell machine
+
+From: Woodrow Shen <woodrow.shen@gmail.com>
+
+commit f83c32925d45926cd0e0f18bf28e6039116c4486 upstream.
+
+The new Dell laptop with codec 3246 can't detect headset mic when
+headset was inserted on the machine. So adding pin configurations
+into quirk table makes headset mic work correctly.
+
+Codec: Realtek ALC3246
+Vendor Id: 0x10ec0256
+Subsystem Id: 0x10280781
+
+Signed-off-by: Woodrow Shen <woodrow.shen@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5832,6 +5832,10 @@ static const struct snd_hda_pin_quirk al
+ {0x14, 0x90170120},
+ {0x21, 0x02211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++ {0x12, 0x90a60170},
++ {0x14, 0x90170120},
++ {0x21, 0x02211030}),
++ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ ALC256_STANDARD_PINS),
+ SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
+ {0x12, 0x90a60130},
--- /dev/null
+From ab58d8cc870ef3f0771c197700441936898d1f1d Mon Sep 17 00:00:00 2001
+From: Peter Wu <peter@lekensteyn.nl>
+Date: Mon, 11 Jul 2016 19:51:06 +0200
+Subject: ALSA: hda - fix use-after-free after module unload
+
+From: Peter Wu <peter@lekensteyn.nl>
+
+commit ab58d8cc870ef3f0771c197700441936898d1f1d upstream.
+
+register_vga_switcheroo() sets the PM ops from the hda structure which
+is freed later in azx_free. Make sure that these ops are cleared.
+
+Caught by KASAN, initially noticed due to a general protection fault.
+
+Fixes: 246efa4a072f ("snd/hda: add runtime suspend/resume on optimus support (v4)")
+Signed-off-by: Peter Wu <peter@lekensteyn.nl>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1218,8 +1218,10 @@ static int azx_free(struct azx *chip)
+ if (use_vga_switcheroo(hda)) {
+ if (chip->disabled && hda->probe_continued)
+ snd_hda_unlock_devices(&chip->bus);
+- if (hda->vga_switcheroo_registered)
++ if (hda->vga_switcheroo_registered) {
+ vga_switcheroo_unregister_client(chip->pci);
++ vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
++ }
+ }
+
+ if (bus->chip_init) {
--- /dev/null
+From 9cd25743765cfe851aed8d655a62d60156aed293 Mon Sep 17 00:00:00 2001
+From: Torsten Hilbrich <torsten.hilbrich@secunet.com>
+Date: Tue, 5 Jul 2016 10:40:22 +0200
+Subject: ALSA: hda/realtek: Add Lenovo L460 to docking unit fixup
+
+From: Torsten Hilbrich <torsten.hilbrich@secunet.com>
+
+commit 9cd25743765cfe851aed8d655a62d60156aed293 upstream.
+
+This solves the issue that a headphone is not working on the docking
+unit.
+
+Signed-off-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5651,6 +5651,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
+ SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
+ SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
++ SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
+ SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
+ SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
--- /dev/null
+From 8a132099f080d7384bb6ab4cc168f76cb4b47d08 Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Fri, 8 Jul 2016 14:26:57 +0800
+Subject: ALSA: hda/realtek - add new pin definition in alc225 pin quirk table
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit 8a132099f080d7384bb6ab4cc168f76cb4b47d08 upstream.
+
+We have some Dell laptops which can't detect headset mic, the machines
+use the codec ALC225, they have some new pin configuration values,
+after adding them in the alc225 pin quirk table, they work well.
+
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5738,7 +5738,6 @@ static const struct hda_model_fixup alc2
+ {}
+ };
+ #define ALC225_STANDARD_PINS \
+- {0x12, 0xb7a60130}, \
+ {0x21, 0x04211020}
+
+ #define ALC256_STANDARD_PINS \
+@@ -5763,10 +5762,24 @@ static const struct hda_model_fixup alc2
+ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+ ALC225_STANDARD_PINS,
++ {0x12, 0xb7a60130},
+ {0x14, 0x901701a0}),
+ SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+ ALC225_STANDARD_PINS,
++ {0x12, 0xb7a60130},
+ {0x14, 0x901701b0}),
++ SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++ ALC225_STANDARD_PINS,
++ {0x12, 0xb7a60150},
++ {0x14, 0x901701a0}),
++ SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++ ALC225_STANDARD_PINS,
++ {0x12, 0xb7a60150},
++ {0x14, 0x901701b0}),
++ SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++ ALC225_STANDARD_PINS,
++ {0x12, 0xb7a60130},
++ {0x1b, 0x90170110}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
+ {0x14, 0x90170110},
+ {0x21, 0x02211020}),
--- /dev/null
+From 0f087ee3f3b86a4507db4ff1d2d5a3880e4cfd16 Mon Sep 17 00:00:00 2001
+From: Jaroslav Kysela <perex@perex.cz>
+Date: Fri, 24 Jun 2016 15:13:16 +0200
+Subject: ALSA: hda / realtek - add two more Thinkpad IDs (5050,5053) for tpt460 fixup
+
+From: Jaroslav Kysela <perex@perex.cz>
+
+commit 0f087ee3f3b86a4507db4ff1d2d5a3880e4cfd16 upstream.
+
+ See: https://bugzilla.redhat.com/show_bug.cgi?id=1349539
+ See: https://bugzilla.kernel.org/show_bug.cgi?id=120961
+
+Signed-off-by: Jaroslav Kysela <perex@perex.cz>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5650,6 +5650,8 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
+ SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
+ SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
++ SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
++ SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
+ SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
+ SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
--- /dev/null
+From 8198868f0a283eb23e264951632ce61ec2f82228 Mon Sep 17 00:00:00 2001
+From: Jaroslav Kysela <perex@perex.cz>
+Date: Fri, 17 Jun 2016 13:35:56 +0200
+Subject: ALSA: hdac_regmap - fix the register access for runtime PM
+
+From: Jaroslav Kysela <perex@perex.cz>
+
+commit 8198868f0a283eb23e264951632ce61ec2f82228 upstream.
+
+Call path:
+
+ 1) snd_hdac_power_up_pm()
+ 2) snd_hdac_power_up()
+ 3) pm_runtime_get_sync()
+ 4) __pm_runtime_resume()
+ 5) rpm_resume()
+
+The rpm_resume() returns 1 when the device is already active.
+Because the return value is unmodified, the hdac regmap read/write
+functions should allow this value for the retry I/O operation, too.
+
+Signed-off-by: Jaroslav Kysela <perex@perex.cz>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/hda/hdac_regmap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/hda/hdac_regmap.c
++++ b/sound/hda/hdac_regmap.c
+@@ -444,7 +444,7 @@ int snd_hdac_regmap_write_raw(struct hda
+ err = reg_raw_write(codec, reg, val);
+ if (err == -EAGAIN) {
+ err = snd_hdac_power_up_pm(codec);
+- if (!err)
++ if (err >= 0)
+ err = reg_raw_write(codec, reg, val);
+ snd_hdac_power_down_pm(codec);
+ }
+@@ -470,7 +470,7 @@ static int __snd_hdac_regmap_read_raw(st
+ err = reg_raw_read(codec, reg, val, uncached);
+ if (err == -EAGAIN) {
+ err = snd_hdac_power_up_pm(codec);
+- if (!err)
++ if (err >= 0)
+ err = reg_raw_read(codec, reg, val, uncached);
+ snd_hdac_power_down_pm(codec);
+ }
--- /dev/null
+From a8ff48cb70835f48de5703052760312019afea55 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 8 Jul 2016 08:23:43 +0200
+Subject: ALSA: pcm: Free chmap at PCM free callback, too
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit a8ff48cb70835f48de5703052760312019afea55 upstream.
+
+The chmap ctls assigned to PCM streams are freed in the PCM disconnect
+callback. However, since the disconnect callback isn't called when
+the card gets freed before registering, the chmap ctls may still be
+left assigned. They are eventually freed together with other ctls,
+but it may cause an Oops at pcm_chmap_ctl_private_free(), as the
+function refers to the assigned PCM stream, while the PCM objects have
+been already freed beforehand.
+
+The fix is to free the chmap ctls also at PCM free callback, not only
+at PCM disconnect.
+
+Reported-by: Laxminath Kasam <b_lkasam@codeaurora.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/pcm.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/sound/core/pcm.c
++++ b/sound/core/pcm.c
+@@ -849,6 +849,14 @@ int snd_pcm_new_internal(struct snd_card
+ }
+ EXPORT_SYMBOL(snd_pcm_new_internal);
+
++static void free_chmap(struct snd_pcm_str *pstr)
++{
++ if (pstr->chmap_kctl) {
++ snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
++ pstr->chmap_kctl = NULL;
++ }
++}
++
+ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
+ {
+ struct snd_pcm_substream *substream, *substream_next;
+@@ -871,6 +879,7 @@ static void snd_pcm_free_stream(struct s
+ kfree(setup);
+ }
+ #endif
++ free_chmap(pstr);
+ if (pstr->substream_count)
+ put_device(&pstr->dev);
+ }
+@@ -1135,10 +1144,7 @@ static int snd_pcm_dev_disconnect(struct
+ for (cidx = 0; cidx < 2; cidx++) {
+ if (!pcm->internal)
+ snd_unregister_device(&pcm->streams[cidx].dev);
+- if (pcm->streams[cidx].chmap_kctl) {
+- snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
+- pcm->streams[cidx].chmap_kctl = NULL;
+- }
++ free_chmap(&pcm->streams[cidx]);
+ }
+ mutex_unlock(&pcm->open_mutex);
+ mutex_unlock(®ister_mutex);
--- /dev/null
+From 3fa6993fef634e05d200d141a85df0b044572364 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 4 Jul 2016 14:02:15 +0200
+Subject: ALSA: timer: Fix negative queue usage by racy accesses
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 3fa6993fef634e05d200d141a85df0b044572364 upstream.
+
+The user timer tu->qused counter may go to a negative value when
+multiple concurrent reads are performed since both the check and the
+decrement of tu->qused are done in two individual locked contexts.
+This results in bogus read outs, and the endless loop in the
+user-space side.
+
+The fix is to move the decrement of the tu->qused counter into the
+same spinlock context as the zero-check of the counter.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1954,6 +1954,7 @@ static ssize_t snd_timer_user_read(struc
+
+ qhead = tu->qhead++;
+ tu->qhead %= tu->queue_size;
++ tu->qused--;
+ spin_unlock_irq(&tu->qlock);
+
+ if (tu->tread) {
+@@ -1967,7 +1968,6 @@ static ssize_t snd_timer_user_read(struc
+ }
+
+ spin_lock_irq(&tu->qlock);
+- tu->qused--;
+ if (err < 0)
+ goto _error;
+ result += unit;
--- /dev/null
+From 76df52969711ae3725a98f26fbbc6a349803dcbf Mon Sep 17 00:00:00 2001
+From: Kazuki Oikawa <k@oikw.org>
+Date: Mon, 18 Jul 2016 01:16:15 +0900
+Subject: ALSA: usb-audio: Fix quirks code is not called
+
+From: Kazuki Oikawa <k@oikw.org>
+
+commit 76df52969711ae3725a98f26fbbc6a349803dcbf upstream.
+
+snd_usb_{set_interface,ctl_msg}_quirk checks chip->usb_id to need
+calling a quirks code. But existed code path that not calling
+dev_set_drvdata in usb_audio_probe.
+
+Fixes: 79289e24194a ("ALSA: usb-audio: Refer to chip->usb_id for quirks and MIDI creation")
+Signed-off-by: Kazuki Oikawa <k@oikw.org>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Tested-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/card.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -552,7 +552,6 @@ static int usb_audio_probe(struct usb_in
+ goto __error;
+ }
+ chip = usb_chip[i];
+- dev_set_drvdata(&dev->dev, chip);
+ atomic_inc(&chip->active); /* avoid autopm */
+ break;
+ }
+@@ -578,6 +577,7 @@ static int usb_audio_probe(struct usb_in
+ goto __error;
+ }
+ }
++ dev_set_drvdata(&dev->dev, chip);
+
+ /*
+ * For devices with more than one control interface, we assume the
--- /dev/null
+From 929e604efa3dc0522214e0dc18984be23993e9f0 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 16 Jun 2016 15:42:27 +0200
+Subject: ARM: dts: armada-38x: fix MBUS_ID for crypto SRAM on Armada 385 Linksys
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit 929e604efa3dc0522214e0dc18984be23993e9f0 upstream.
+
+When the support for the Marvell crypto engine was added in the Device
+Tree of the various Armada 385 Device Tree files in commit
+d716f2e837ac6 ("ARM: mvebu: define crypto SRAM ranges for all armada-38x
+boards"), a typo was made in the MBus window attributes for the Armada
+385 Linksys board: 0x09/0x05 are used instead of 0x19/0x15. This commit
+fixes this typo, which makes the CESA engines operational on Armada 385
+Linksys boards.
+
+Reported-by: Terry Stockert <stockert@inkblotadmirer.me>
+Cc: Terry Stockert <stockert@inkblotadmirer.me>
+Cc: Imre Kaloz <kaloz@openwrt.org>
+Cc: Boris Brezillon <boris.brezillon@free-electrons.com>
+Fixes: d716f2e837ac6 ("ARM: mvebu: define crypto SRAM ranges for all armada-38x boards")
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/armada-385-linksys.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -58,8 +58,8 @@
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+- MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+- MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
++ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
++ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+
+ internal-regs {
+
--- /dev/null
+From c5379ba8fccd99d5f99632c789f0393d84a57805 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 16 Jun 2016 15:42:25 +0200
+Subject: ARM: mvebu: fix HW I/O coherency related deadlocks
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit c5379ba8fccd99d5f99632c789f0393d84a57805 upstream.
+
+Until now, our understanding for HW I/O coherency to work on the
+Cortex-A9 based Marvell SoC was that only the PCIe regions should be
+mapped strongly-ordered. However, we were still encountering some
+deadlocks, especially when testing the CESA crypto engine. After
+checking with the HW designers, it was concluded that all the MMIO
+registers should be mapped as strongly ordered for the HW I/O coherency
+mechanism to work properly.
+
+This fixes some easy to reproduce deadlocks with the CESA crypto engine
+driver (dmcrypt on a sufficiently large disk partition).
+
+Tested-by: Terry Stockert <stockert@inkblotadmirer.me>
+Tested-by: Romain Perier <romain.perier@free-electrons.com>
+Cc: Terry Stockert <stockert@inkblotadmirer.me>
+Cc: Romain Perier <romain.perier@free-electrons.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-mvebu/coherency.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -162,22 +162,16 @@ exit:
+ }
+
+ /*
+- * This ioremap hook is used on Armada 375/38x to ensure that PCIe
+- * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
+- * is needed as a workaround for a deadlock issue between the PCIe
+- * interface and the cache controller.
++ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
++ * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
++ * needed for the HW I/O coherency mechanism to work properly without
++ * deadlock.
+ */
+ static void __iomem *
+-armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+- unsigned int mtype, void *caller)
++armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
++ unsigned int mtype, void *caller)
+ {
+- struct resource pcie_mem;
+-
+- mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
+-
+- if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
+- mtype = MT_UNCACHED;
+-
++ mtype = MT_UNCACHED;
+ return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+
+@@ -186,7 +180,7 @@ static void __init armada_375_380_cohere
+ struct device_node *cache_dn;
+
+ coherency_cpu_base = of_iomap(np, 0);
+- arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
++ arch_ioremap_caller = armada_wa_ioremap_caller;
+
+ /*
+ * We should switch the PL310 to I/O coherency mode only if
--- /dev/null
+From 5fc39d347267bd029fcc9099c70e2fe2d53130e9 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Wed, 15 Jun 2016 13:20:19 +0200
+Subject: ARM: sunxi/dt: make the CHIP inherit from allwinner,sun5i-a13
+
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+
+commit 5fc39d347267bd029fcc9099c70e2fe2d53130e9 upstream.
+
+The sun4i-timer driver registers its sched_clock only if the machine is
+compatible with "allwinner,sun5i-a13", "allwinner,sun5i-a10s" or
+"allwinner,sun4i-a10".
+Add the missing "allwinner,sun5i-a13" string to the machine compatible.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Fixes: 465a225fb2af ("ARM: sun5i: Add C.H.I.P DTS")
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/sun5i-r8-chip.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
++++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
+@@ -52,7 +52,7 @@
+
+ / {
+ model = "NextThing C.H.I.P.";
+- compatible = "nextthing,chip", "allwinner,sun5i-r8";
++ compatible = "nextthing,chip", "allwinner,sun5i-r8", "allwinner,sun5i-a13";
+
+ aliases {
+ i2c0 = &i2c0;
--- /dev/null
+From 5ce91714b0d8c0a3ff9b858966721f508351cf4c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com>
+Date: Sat, 18 Jun 2016 00:54:47 +0200
+Subject: hwmon: (dell-smm) Cache fan_type() calls and change fan detection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali.rohar@gmail.com>
+
+commit 5ce91714b0d8c0a3ff9b858966721f508351cf4c upstream.
+
+On more Dell machines (e.g. Dell Precision M3800) fan_type() call is too
+expensive (CPU is too long in SMM mode) and cause kernel to hang. This is
+bug in Dell SMM or BIOS.
+
+This patch caches type for each fan (as it should not change) and changes
+the way how fan presense is detected. First it try function fan_status()
+as was before commit f989e55452c7 ("i8k: Add support for fan labels"). And
+if that fails fallback to fan_type(). *_status() functions can fail in case
+fan is not currently accessible (e.g. present on GPU which is currently
+turned off).
+
+Reported-by: Tolga Cakir <cevelnet@gmail.com>
+Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=112021
+Tested-by: Tolga Cakir <cevelnet@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/dell-smm-hwmon.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -237,7 +237,7 @@ static int i8k_get_fan_speed(int fan)
+ /*
+ * Read the fan type.
+ */
+-static int i8k_get_fan_type(int fan)
++static int _i8k_get_fan_type(int fan)
+ {
+ struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
+
+@@ -248,6 +248,17 @@ static int i8k_get_fan_type(int fan)
+ return i8k_smm(®s) ? : regs.eax & 0xff;
+ }
+
++static int i8k_get_fan_type(int fan)
++{
++ /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
++ static int types[2] = { INT_MIN, INT_MIN };
++
++ if (types[fan] == INT_MIN)
++ types[fan] = _i8k_get_fan_type(fan);
++
++ return types[fan];
++}
++
+ /*
+ * Read the fan nominal rpm for specific fan speed.
+ */
+@@ -777,13 +788,17 @@ static int __init i8k_init_hwmon(void)
+ if (err >= 0)
+ i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
+
+- /* First fan attributes, if fan type is OK */
+- err = i8k_get_fan_type(0);
++ /* First fan attributes, if fan status or type is OK */
++ err = i8k_get_fan_status(0);
++ if (err < 0)
++ err = i8k_get_fan_type(0);
+ if (err >= 0)
+ i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
+
+- /* Second fan attributes, if fan type is OK */
+- err = i8k_get_fan_type(1);
++ /* Second fan attributes, if fan status or type is OK */
++ err = i8k_get_fan_status(1);
++ if (err < 0)
++ err = i8k_get_fan_type(1);
+ if (err >= 0)
+ i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
+
--- /dev/null
+From 2744d2fde00dc8bcc3679eb72c81a63058e90faa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com>
+Date: Sat, 18 Jun 2016 00:54:46 +0200
+Subject: hwmon: (dell-smm) Disallow fan_type() calls on broken machines
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali.rohar@gmail.com>
+
+commit 2744d2fde00dc8bcc3679eb72c81a63058e90faa upstream.
+
+Some Dell machines have especially broken SMM or BIOS which cause that once
+fan_type() is called then CPU fan speed going randomly up and down. And for
+fixing this behaviour reboot is required.
+
+So this patch creates fan_type blacklist of affected Dell machines and
+disallow fan_type() call on them to prevent that erratic behaviour.
+
+Old blacklist which disabled loading driver on some machines added in
+commits a4b45b25f18d ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8100")
+and 6220f4ebd7b4 ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8000") were
+moved to FAN_TYPE blacklist.
+
+Reported-by: Jan C Peters <jcpeters89@gmail.com>
+Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=100121
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/dell-smm-hwmon.c | 36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -72,6 +72,7 @@ static u32 i8k_hwmon_flags;
+ static uint i8k_fan_mult = I8K_FAN_MULT;
+ static uint i8k_pwm_mult;
+ static uint i8k_fan_max = I8K_FAN_HIGH;
++static bool disallow_fan_type_call;
+
+ #define I8K_HWMON_HAVE_TEMP1 (1 << 0)
+ #define I8K_HWMON_HAVE_TEMP2 (1 << 1)
+@@ -240,6 +241,9 @@ static int i8k_get_fan_type(int fan)
+ {
+ struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
+
++ if (disallow_fan_type_call)
++ return -EINVAL;
++
+ regs.ebx = fan & 0xff;
+ return i8k_smm(®s) ? : regs.eax & 0xff;
+ }
+@@ -721,6 +725,9 @@ static struct attribute *i8k_attrs[] = {
+ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
+ int index)
+ {
++ if (disallow_fan_type_call &&
++ (index == 9 || index == 12))
++ return 0;
+ if (index >= 0 && index <= 1 &&
+ !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
+ return 0;
+@@ -932,12 +939,14 @@ static struct dmi_system_id i8k_dmi_tabl
+
+ MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
+
+-static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
++/*
++ * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed
++ * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist
++ * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.
++ * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121
++ */
++static struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initdata = {
+ {
+- /*
+- * CPU fan speed going up and down on Dell Studio XPS 8000
+- * for unknown reasons.
+- */
+ .ident = "Dell Studio XPS 8000",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+@@ -945,16 +954,19 @@ static struct dmi_system_id i8k_blacklis
+ },
+ },
+ {
+- /*
+- * CPU fan speed going up and down on Dell Studio XPS 8100
+- * for unknown reasons.
+- */
+ .ident = "Dell Studio XPS 8100",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
+ },
+ },
++ {
++ .ident = "Dell Inspiron 580",
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
++ },
++ },
+ { }
+ };
+
+@@ -969,8 +981,7 @@ static int __init i8k_probe(void)
+ /*
+ * Get DMI information
+ */
+- if (!dmi_check_system(i8k_dmi_table) ||
+- dmi_check_system(i8k_blacklist_dmi_table)) {
++ if (!dmi_check_system(i8k_dmi_table)) {
+ if (!ignore_dmi && !force)
+ return -ENODEV;
+
+@@ -981,6 +992,9 @@ static int __init i8k_probe(void)
+ i8k_get_dmi_data(DMI_BIOS_VERSION));
+ }
+
++ if (dmi_check_system(i8k_blacklist_fan_type_dmi_table))
++ disallow_fan_type_call = true;
++
+ strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
+ sizeof(bios_version));
+ strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
--- /dev/null
+From 7613663cc186f8f3c50279390ddc60286758001c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com>
+Date: Sat, 18 Jun 2016 00:54:45 +0200
+Subject: hwmon: (dell-smm) Restrict fan control and serial number to CAP_SYS_ADMIN by default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali.rohar@gmail.com>
+
+commit 7613663cc186f8f3c50279390ddc60286758001c upstream.
+
+For security reasons ordinary user must not be able to control fan speed
+via /proc/i8k by default. Some malicious software running under "nobody"
+user could be able to turn fan off and cause HW problems. So this patch
+changes default value of "restricted" parameter to 1.
+
+Also restrict reading of DMI_PRODUCT_SERIAL from /proc/i8k via "restricted"
+parameter. It is because non root user cannot read DMI_PRODUCT_SERIAL from
+sysfs file /sys/class/dmi/id/product_serial.
+
+Old non secure behaviour of file /proc/i8k can be achieved by loading this
+module with "restricted" parameter set to 0.
+
+Note that this patch has effects only for kernels compiled with CONFIG_I8K
+and only for file /proc/i8k. Hwmon interface provided by this driver was
+not changed and root access for setting fan speed was needed also before.
+
+Reported-by: Mario Limonciello <Mario_Limonciello@dell.com>
+Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/dell-smm-hwmon.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -66,6 +66,7 @@
+
+ static DEFINE_MUTEX(i8k_mutex);
+ static char bios_version[4];
++static char bios_machineid[16];
+ static struct device *i8k_hwmon_dev;
+ static u32 i8k_hwmon_flags;
+ static uint i8k_fan_mult = I8K_FAN_MULT;
+@@ -94,13 +95,13 @@ module_param(ignore_dmi, bool, 0);
+ MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+
+ #if IS_ENABLED(CONFIG_I8K)
+-static bool restricted;
++static bool restricted = true;
+ module_param(restricted, bool, 0);
+-MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
++MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
+
+ static bool power_status;
+ module_param(power_status, bool, 0600);
+-MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
++MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
+ #endif
+
+ static uint fan_mult;
+@@ -392,9 +393,11 @@ i8k_ioctl_unlocked(struct file *fp, unsi
+ break;
+
+ case I8K_MACHINE_ID:
+- memset(buff, 0, 16);
+- strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+- sizeof(buff));
++ if (restricted && !capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ memset(buff, 0, sizeof(buff));
++ strlcpy(buff, bios_machineid, sizeof(buff));
+ break;
+
+ case I8K_FN_STATUS:
+@@ -511,7 +514,7 @@ static int i8k_proc_show(struct seq_file
+ seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
+ I8K_PROC_FMT,
+ bios_version,
+- i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
++ (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : bios_machineid,
+ cpu_temp,
+ left_fan, right_fan, left_speed, right_speed,
+ ac_power, fn_key);
+@@ -980,6 +983,8 @@ static int __init i8k_probe(void)
+
+ strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
+ sizeof(bios_version));
++ strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
++ sizeof(bios_machineid));
+
+ /*
+ * Get SMM Dell signature
--- /dev/null
+From 0c1f91b98552da49d9d8eed32b3132a58d2f4598 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Fri, 17 Jun 2016 15:22:24 +0200
+Subject: iio: accel: kxsd9: fix the usage of spi_w8r8()
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+commit 0c1f91b98552da49d9d8eed32b3132a58d2f4598 upstream.
+
+These two spi_w8r8() calls return a value with is used by the code
+following the error check. The dubious use was caused by a cleanup
+patch.
+
+Fixes: d34dbee8ac8e ("staging:iio:accel:kxsd9 cleanup and conversion to iio_chan_spec.")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/accel/kxsd9.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/accel/kxsd9.c
++++ b/drivers/iio/accel/kxsd9.c
+@@ -81,7 +81,7 @@ static int kxsd9_write_scale(struct iio_
+
+ mutex_lock(&st->buf_lock);
+ ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+- if (ret)
++ if (ret < 0)
+ goto error_ret;
+ st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
+ st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
+@@ -163,7 +163,7 @@ static int kxsd9_read_raw(struct iio_dev
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+- if (ret)
++ if (ret < 0)
+ goto error_ret;
+ *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
+ ret = IIO_VAL_INT_PLUS_MICRO;
--- /dev/null
+From 6b7f4e25f3309f106a5c7ff42c8231494cf285d3 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 20 Jun 2016 13:53:32 +0100
+Subject: iio:ad7266: Fix broken regulator error handling
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 6b7f4e25f3309f106a5c7ff42c8231494cf285d3 upstream.
+
+All regulator_get() variants return either a pointer to a regulator or an
+ERR_PTR() so testing for NULL makes no sense and may lead to bugs if we
+use NULL as a valid regulator. Fix this by using IS_ERR() as expected.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad7266.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/ad7266.c
++++ b/drivers/iio/adc/ad7266.c
+@@ -397,7 +397,7 @@ static int ad7266_probe(struct spi_devic
+ st = iio_priv(indio_dev);
+
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+- if (!IS_ERR_OR_NULL(st->reg)) {
++ if (!IS_ERR(st->reg)) {
+ ret = regulator_enable(st->reg);
+ if (ret)
+ return ret;
--- /dev/null
+From 68b356eb3d9f5e38910fb62e22a78e2a18d544ae Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 20 Jun 2016 13:53:34 +0100
+Subject: iio:ad7266: Fix probe deferral for vref
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 68b356eb3d9f5e38910fb62e22a78e2a18d544ae upstream.
+
+Currently the ad7266 driver treats any failure to get vref as though the
+regulator were not present but this means that if probe deferral is
+triggered the driver will act as though the regulator were not present.
+Instead only use the internal reference if we explicitly got -ENODEV which
+is what is returned for absent regulators.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad7266.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/iio/adc/ad7266.c
++++ b/drivers/iio/adc/ad7266.c
+@@ -408,6 +408,9 @@ static int ad7266_probe(struct spi_devic
+
+ st->vref_mv = ret / 1000;
+ } else {
++ /* Any other error indicates that the regulator does exist */
++ if (PTR_ERR(st->reg) != -ENODEV)
++ return PTR_ERR(st->reg);
+ /* Use internal reference */
+ st->vref_mv = 2500;
+ }
--- /dev/null
+From e5511c816e5ac4909bdd38e85ac344e2b9b8e984 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 20 Jun 2016 13:53:33 +0100
+Subject: iio:ad7266: Fix support for optional regulators
+
+From: Mark Brown <broonie@kernel.org>
+
+commit e5511c816e5ac4909bdd38e85ac344e2b9b8e984 upstream.
+
+The ad7266 driver attempts to support deciding between the use of internal
+and external power supplies by checking to see if an error is returned when
+requesting the regulator. This doesn't work with the current code since the
+driver uses a normal regulator_get() which is for non-optional supplies
+and so assumes that if a regulator is not provided by the platform then
+this is a bug in the platform integration and so substitutes a dummy
+regulator. Use regulator_get_optional() instead which indicates to the
+framework that the regulator may be absent and provides a dummy regulator
+instead.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad7266.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/ad7266.c
++++ b/drivers/iio/adc/ad7266.c
+@@ -396,7 +396,7 @@ static int ad7266_probe(struct spi_devic
+
+ st = iio_priv(indio_dev);
+
+- st->reg = devm_regulator_get(&spi->dev, "vref");
++ st->reg = devm_regulator_get_optional(&spi->dev, "vref");
+ if (!IS_ERR(st->reg)) {
+ ret = regulator_enable(st->reg);
+ if (ret)
--- /dev/null
+From 99543823357966ac938d9a310947e731b67338e6 Mon Sep 17 00:00:00 2001
+From: Crestez Dan Leonard <leonard.crestez@intel.com>
+Date: Tue, 3 May 2016 15:27:09 +0300
+Subject: iio: Fix error handling in iio_trigger_attach_poll_func
+
+From: Crestez Dan Leonard <leonard.crestez@intel.com>
+
+commit 99543823357966ac938d9a310947e731b67338e6 upstream.
+
+When attaching a pollfunc iio_trigger_attach_poll_func will allocate a
+virtual irq and call the driver's set_trigger_state function. Fix error
+handling to undo previous steps if any fails.
+
+In particular this fixes handling errors from a driver's
+set_trigger_state function. When using triggered buffers a failure to
+enable the trigger used to make the buffer unusable.
+
+Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/industrialio-trigger.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/iio/industrialio-trigger.c
++++ b/drivers/iio/industrialio-trigger.c
+@@ -210,22 +210,35 @@ static int iio_trigger_attach_poll_func(
+
+ /* Prevent the module from being removed whilst attached to a trigger */
+ __module_get(pf->indio_dev->info->driver_module);
++
++ /* Get irq number */
+ pf->irq = iio_trigger_get_irq(trig);
++ if (pf->irq < 0)
++ goto out_put_module;
++
++ /* Request irq */
+ ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
+ pf->type, pf->name,
+ pf);
+- if (ret < 0) {
+- module_put(pf->indio_dev->info->driver_module);
+- return ret;
+- }
++ if (ret < 0)
++ goto out_put_irq;
+
++ /* Enable trigger in driver */
+ if (trig->ops && trig->ops->set_trigger_state && notinuse) {
+ ret = trig->ops->set_trigger_state(trig, true);
+ if (ret < 0)
+- module_put(pf->indio_dev->info->driver_module);
++ goto out_free_irq;
+ }
+
+ return ret;
++
++out_free_irq:
++ free_irq(pf->irq, pf);
++out_put_irq:
++ iio_trigger_put_irq(trig, pf->irq);
++out_put_module:
++ module_put(pf->indio_dev->info->driver_module);
++ return ret;
+ }
+
+ static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
--- /dev/null
+From 94bef000f1d4aa111f4ddda1482cf3b30ad069ce Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sun, 29 May 2016 19:52:02 -0700
+Subject: iio: hudmidity: hdc100x: fix incorrect shifting and scaling
+
+From: Matt Ranostay <mranostay@gmail.com>
+
+commit 94bef000f1d4aa111f4ddda1482cf3b30ad069ce upstream.
+
+Shifting sensor data to the right 2 bits was incorrect and caused the
+scaling values + offsets to be invalid.
+
+Reported-by: Alison Schofield <amsfield22@gmail.com>
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+Tested-by: Alison Schofield <amsfield22@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/humidity/hdc100x.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/iio/humidity/hdc100x.c
++++ b/drivers/iio/humidity/hdc100x.c
+@@ -164,14 +164,14 @@ static int hdc100x_get_measurement(struc
+ dev_err(&client->dev, "cannot read high byte measurement");
+ return ret;
+ }
+- val = ret << 6;
++ val = ret << 8;
+
+ ret = i2c_smbus_read_byte(client);
+ if (ret < 0) {
+ dev_err(&client->dev, "cannot read low byte measurement");
+ return ret;
+ }
+- val |= ret >> 2;
++ val |= ret;
+
+ return val;
+ }
+@@ -212,17 +212,17 @@ static int hdc100x_read_raw(struct iio_d
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type == IIO_TEMP) {
+ *val = 165000;
+- *val2 = 65536 >> 2;
++ *val2 = 65536;
+ return IIO_VAL_FRACTIONAL;
+ } else {
+- *val = 0;
+- *val2 = 10000;
+- return IIO_VAL_INT_PLUS_MICRO;
++ *val = 100;
++ *val2 = 65536;
++ return IIO_VAL_FRACTIONAL;
+ }
+ break;
+ case IIO_CHAN_INFO_OFFSET:
+- *val = -3971;
+- *val2 = 879096;
++ *val = -15887;
++ *val2 = 515151;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
--- /dev/null
+From 0e35cf5ce00d873d6e529d2b2cd7598d52438051 Mon Sep 17 00:00:00 2001
+From: Alison Schofield <amsfield22@gmail.com>
+Date: Fri, 20 May 2016 10:06:41 -0700
+Subject: iio: humidity: hdc100x: correct humidity integration time mask
+
+From: Alison Schofield <amsfield22@gmail.com>
+
+commit 0e35cf5ce00d873d6e529d2b2cd7598d52438051 upstream.
+
+Apply the correct mask to enable all available humidity integration
+times. Currently, the driver defaults to 6500 and all is okay with that.
+However, if 3850 is selected we get a stuck bit and can't change back
+to 6500 or select 2500. (Verified with HDC1008)
+
+Signed-off-by: Alison Schofield <amsfield22@gmail.com>
+Cc: Daniel Baluta <daniel.baluta@gmail.com>
+Reviewed-by: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/humidity/hdc100x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/humidity/hdc100x.c
++++ b/drivers/iio/humidity/hdc100x.c
+@@ -55,7 +55,7 @@ static const struct {
+ },
+ { /* IIO_HUMIDITYRELATIVE channel */
+ .shift = 8,
+- .mask = 2,
++ .mask = 3,
+ },
+ };
+
--- /dev/null
+From 09bc0ddaab6cab0fa95a67d5535ec772e2671193 Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Thu, 26 May 2016 19:55:06 -0700
+Subject: iio: humidity: hdc100x: fix IIO_TEMP channel reporting
+
+From: Matt Ranostay <mranostay@gmail.com>
+
+commit 09bc0ddaab6cab0fa95a67d5535ec772e2671193 upstream.
+
+IIO_TEMP channel was being incorrectly reported back as Celsius when it
+should have been milliCelsius. This is via an incorrect scale value being
+returned to userspace.
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/humidity/hdc100x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/humidity/hdc100x.c
++++ b/drivers/iio/humidity/hdc100x.c
+@@ -211,7 +211,7 @@ static int hdc100x_read_raw(struct iio_d
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type == IIO_TEMP) {
+- *val = 165;
++ *val = 165000;
+ *val2 = 65536 >> 2;
+ return IIO_VAL_FRACTIONAL;
+ } else {
--- /dev/null
+From 590b92a30242dd3f73de3d9a51d9924f1ab33e93 Mon Sep 17 00:00:00 2001
+From: Yong Li <sdliyong@gmail.com>
+Date: Thu, 5 May 2016 16:10:49 +0800
+Subject: iio: light apds9960: Add the missing dev.parent
+
+From: Yong Li <sdliyong@gmail.com>
+
+commit 590b92a30242dd3f73de3d9a51d9924f1ab33e93 upstream.
+
+Without this, the iio:deviceX is missing in the /sys/bus/i2c/devices/0-0039
+Some userspace tools use this path to identify a specific instance of the
+device.
+
+Signed-off-by: Yong Li <sdliyong@gmail.com>
+Reviewed-By: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/light/apds9960.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/light/apds9960.c
++++ b/drivers/iio/light/apds9960.c
+@@ -1006,6 +1006,7 @@ static int apds9960_probe(struct i2c_cli
+
+ iio_device_attach_buffer(indio_dev, buffer);
+
++ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &apds9960_info;
+ indio_dev->name = APDS9960_DRV_NAME;
+ indio_dev->channels = apds9960_channels;
--- /dev/null
+From 5138806f16c74c7cb8ac3e408a859c79eb7c9567 Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 21 May 2016 20:01:01 -0700
+Subject: iio: proximity: as3935: correct IIO_CHAN_INFO_RAW output
+
+From: Matt Ranostay <mranostay@gmail.com>
+
+commit 5138806f16c74c7cb8ac3e408a859c79eb7c9567 upstream.
+
+IIO_CHAN_INFO_RAW was returning processed data which was incorrect.
+This also adds the IIO_CHAN_INFO_SCALE value to convert to a processed value.
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 | 2 +-
+ drivers/iio/proximity/as3935.c | 10 ++++++++--
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
++++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
+@@ -1,4 +1,4 @@
+-What /sys/bus/iio/devices/iio:deviceX/in_proximity_raw
++What /sys/bus/iio/devices/iio:deviceX/in_proximity_input
+ Date: March 2014
+ KernelVersion: 3.15
+ Contact: Matt Ranostay <mranostay@gmail.com>
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -72,7 +72,8 @@ static const struct iio_chan_spec as3935
+ .type = IIO_PROXIMITY,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+- BIT(IIO_CHAN_INFO_PROCESSED),
++ BIT(IIO_CHAN_INFO_PROCESSED) |
++ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+@@ -181,7 +182,12 @@ static int as3935_read_raw(struct iio_de
+ /* storm out of range */
+ if (*val == AS3935_DATA_MASK)
+ return -EINVAL;
+- *val *= 1000;
++
++ if (m == IIO_CHAN_INFO_PROCESSED)
++ *val *= 1000;
++ break;
++ case IIO_CHAN_INFO_SCALE:
++ *val = 1000;
+ break;
+ default:
+ return -EINVAL;
--- /dev/null
+From 37b1ba2c68cfbe37f5f45bb91bcfaf2b016ae6a1 Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 21 May 2016 20:01:03 -0700
+Subject: iio: proximity: as3935: fix buffer stack trashing
+
+From: Matt Ranostay <mranostay@gmail.com>
+
+commit 37b1ba2c68cfbe37f5f45bb91bcfaf2b016ae6a1 upstream.
+
+Buffer wasn't of a valid size to allow the timestamp, and correct padding.
+This patchset also moves the buffer off the stack, and onto the heap.
+
+Cc: george.mccollister@gmail.com
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/proximity/as3935.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -64,6 +64,7 @@ struct as3935_state {
+ struct delayed_work work;
+
+ u32 tune_cap;
++ u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
+ u8 buf[2] ____cacheline_aligned;
+ };
+
+@@ -212,9 +213,10 @@ static irqreturn_t as3935_trigger_handle
+ ret = as3935_read(st, AS3935_DATA, &val);
+ if (ret)
+ goto err_read;
+- val &= AS3935_DATA_MASK;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
++ st->buffer[0] = val & AS3935_DATA_MASK;
++ iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
++ pf->timestamp);
+ err_read:
+ iio_trigger_notify_done(indio_dev->trig);
+
--- /dev/null
+From 7d0643634ea567969bf3f3ed6193a9d6fc75653b Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 21 May 2016 20:01:02 -0700
+Subject: iio: proximity: as3935: remove triggered buffer processing
+
+From: Matt Ranostay <mranostay@gmail.com>
+
+commit 7d0643634ea567969bf3f3ed6193a9d6fc75653b upstream.
+
+Triggered buffers shouldn't return processed data, and the respective
+conversion was overflowing the defined .realbits for the channel.
+
+Cc: george.mccollister@gmail.com
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/proximity/as3935.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -213,7 +213,6 @@ static irqreturn_t as3935_trigger_handle
+ if (ret)
+ goto err_read;
+ val &= AS3935_DATA_MASK;
+- val *= 1000;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
+ err_read:
--- /dev/null
+From d43a41152f8e9e4c0d19850884d1fada076dee10 Mon Sep 17 00:00:00 2001
+From: Gregor Boirie <gregor.boirie@parrot.com>
+Date: Tue, 19 Apr 2016 11:18:33 +0200
+Subject: iio:st_pressure: fix sampling gains (bring inline with ABI)
+
+From: Gregor Boirie <gregor.boirie@parrot.com>
+
+commit d43a41152f8e9e4c0d19850884d1fada076dee10 upstream.
+
+Temperature channels report scaled samples in Celsius although expected as
+milli degree Celsius in Documentation/ABI/testing/sysfs-bus-iio.
+Gains are not implemented at all for LPS001WP pressure and temperature
+channels.
+
+This patch ensures that proper offsets and scales are exposed to userpace
+for both pressure and temperature channels.
+Also fix a NULL pointer exception when userspace reads content of sysfs
+scale attribute when gains are not defined.
+
+Signed-off-by: Gregor Boirie <gregor.boirie@parrot.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/pressure/st_pressure_core.c | 80 ++++++++++++++++++++------------
+ 1 file changed, 50 insertions(+), 30 deletions(-)
+
+--- a/drivers/iio/pressure/st_pressure_core.c
++++ b/drivers/iio/pressure/st_pressure_core.c
+@@ -28,15 +28,21 @@
+ #include <linux/iio/common/st_sensors.h>
+ #include "st_pressure.h"
+
++#define MCELSIUS_PER_CELSIUS 1000
++
++/* Default pressure sensitivity */
+ #define ST_PRESS_LSB_PER_MBAR 4096UL
+ #define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
+ ST_PRESS_LSB_PER_MBAR)
++
++/* Default temperature sensitivity */
+ #define ST_PRESS_LSB_PER_CELSIUS 480UL
+-#define ST_PRESS_CELSIUS_NANO_SCALE (1000000000UL / \
+- ST_PRESS_LSB_PER_CELSIUS)
++#define ST_PRESS_MILLI_CELSIUS_OFFSET 42500UL
++
+ #define ST_PRESS_NUMBER_DATA_CHANNELS 1
+
+ /* FULLSCALE */
++#define ST_PRESS_FS_AVL_1100MB 1100
+ #define ST_PRESS_FS_AVL_1260MB 1260
+
+ #define ST_PRESS_1_OUT_XL_ADDR 0x28
+@@ -54,9 +60,6 @@
+ #define ST_PRESS_LPS331AP_PW_MASK 0x80
+ #define ST_PRESS_LPS331AP_FS_ADDR 0x23
+ #define ST_PRESS_LPS331AP_FS_MASK 0x30
+-#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL 0x00
+-#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
+-#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
+ #define ST_PRESS_LPS331AP_BDU_ADDR 0x20
+ #define ST_PRESS_LPS331AP_BDU_MASK 0x04
+ #define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR 0x22
+@@ -65,9 +68,14 @@
+ #define ST_PRESS_LPS331AP_IHL_IRQ_ADDR 0x22
+ #define ST_PRESS_LPS331AP_IHL_IRQ_MASK 0x80
+ #define ST_PRESS_LPS331AP_MULTIREAD_BIT true
+-#define ST_PRESS_LPS331AP_TEMP_OFFSET 42500
+
+ /* CUSTOM VALUES FOR LPS001WP SENSOR */
++
++/* LPS001WP pressure resolution */
++#define ST_PRESS_LPS001WP_LSB_PER_MBAR 16UL
++/* LPS001WP temperature resolution */
++#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS 64UL
++
+ #define ST_PRESS_LPS001WP_WAI_EXP 0xba
+ #define ST_PRESS_LPS001WP_ODR_ADDR 0x20
+ #define ST_PRESS_LPS001WP_ODR_MASK 0x30
+@@ -76,6 +84,8 @@
+ #define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL 0x03
+ #define ST_PRESS_LPS001WP_PW_ADDR 0x20
+ #define ST_PRESS_LPS001WP_PW_MASK 0x40
++#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
++ (100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
+ #define ST_PRESS_LPS001WP_BDU_ADDR 0x20
+ #define ST_PRESS_LPS001WP_BDU_MASK 0x04
+ #define ST_PRESS_LPS001WP_MULTIREAD_BIT true
+@@ -92,11 +102,6 @@
+ #define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL 0x04
+ #define ST_PRESS_LPS25H_PW_ADDR 0x20
+ #define ST_PRESS_LPS25H_PW_MASK 0x80
+-#define ST_PRESS_LPS25H_FS_ADDR 0x00
+-#define ST_PRESS_LPS25H_FS_MASK 0x00
+-#define ST_PRESS_LPS25H_FS_AVL_1260_VAL 0x00
+-#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
+-#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
+ #define ST_PRESS_LPS25H_BDU_ADDR 0x20
+ #define ST_PRESS_LPS25H_BDU_MASK 0x04
+ #define ST_PRESS_LPS25H_DRDY_IRQ_ADDR 0x23
+@@ -105,7 +110,6 @@
+ #define ST_PRESS_LPS25H_IHL_IRQ_ADDR 0x22
+ #define ST_PRESS_LPS25H_IHL_IRQ_MASK 0x80
+ #define ST_PRESS_LPS25H_MULTIREAD_BIT true
+-#define ST_PRESS_LPS25H_TEMP_OFFSET 42500
+ #define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28
+ #define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b
+
+@@ -157,7 +161,9 @@ static const struct iio_chan_spec st_pre
+ .storagebits = 16,
+ .endianness = IIO_LE,
+ },
+- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_separate =
++ BIT(IIO_CHAN_INFO_RAW) |
++ BIT(IIO_CHAN_INFO_SCALE),
+ .modified = 0,
+ },
+ {
+@@ -173,7 +179,7 @@ static const struct iio_chan_spec st_pre
+ },
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+- BIT(IIO_CHAN_INFO_OFFSET),
++ BIT(IIO_CHAN_INFO_SCALE),
+ .modified = 0,
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1)
+@@ -208,11 +214,14 @@ static const struct st_sensor_settings s
+ .addr = ST_PRESS_LPS331AP_FS_ADDR,
+ .mask = ST_PRESS_LPS331AP_FS_MASK,
+ .fs_avl = {
++ /*
++ * Pressure and temperature sensitivity values
++ * as defined in table 3 of LPS331AP datasheet.
++ */
+ [0] = {
+ .num = ST_PRESS_FS_AVL_1260MB,
+- .value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
+- .gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
+- .gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
++ .gain = ST_PRESS_KPASCAL_NANO_SCALE,
++ .gain2 = ST_PRESS_LSB_PER_CELSIUS,
+ },
+ },
+ },
+@@ -254,7 +263,17 @@ static const struct st_sensor_settings s
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .fs = {
+- .addr = 0,
++ .fs_avl = {
++ /*
++ * Pressure and temperature resolution values
++ * as defined in table 3 of LPS001WP datasheet.
++ */
++ [0] = {
++ .num = ST_PRESS_FS_AVL_1100MB,
++ .gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
++ .gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
++ },
++ },
+ },
+ .bdu = {
+ .addr = ST_PRESS_LPS001WP_BDU_ADDR,
+@@ -291,14 +310,15 @@ static const struct st_sensor_settings s
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .fs = {
+- .addr = ST_PRESS_LPS25H_FS_ADDR,
+- .mask = ST_PRESS_LPS25H_FS_MASK,
+ .fs_avl = {
++ /*
++ * Pressure and temperature sensitivity values
++ * as defined in table 3 of LPS25H datasheet.
++ */
+ [0] = {
+ .num = ST_PRESS_FS_AVL_1260MB,
+- .value = ST_PRESS_LPS25H_FS_AVL_1260_VAL,
+- .gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN,
+- .gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN,
++ .gain = ST_PRESS_KPASCAL_NANO_SCALE,
++ .gain2 = ST_PRESS_LSB_PER_CELSIUS,
+ },
+ },
+ },
+@@ -354,26 +374,26 @@ static int st_press_read_raw(struct iio_
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+- *val = 0;
+-
+ switch (ch->type) {
+ case IIO_PRESSURE:
++ *val = 0;
+ *val2 = press_data->current_fullscale->gain;
+- break;
++ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_TEMP:
++ *val = MCELSIUS_PER_CELSIUS;
+ *val2 = press_data->current_fullscale->gain2;
+- break;
++ return IIO_VAL_FRACTIONAL;
+ default:
+ err = -EINVAL;
+ goto read_error;
+ }
+
+- return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_OFFSET:
+ switch (ch->type) {
+ case IIO_TEMP:
+- *val = 425;
+- *val2 = 10;
++ *val = ST_PRESS_MILLI_CELSIUS_OFFSET *
++ press_data->current_fullscale->gain2;
++ *val2 = MCELSIUS_PER_CELSIUS;
+ break;
+ default:
+ err = -EINVAL;
--- /dev/null
+From 07a2daab49c549a37b5b744cbebb6e3f445f12bc Mon Sep 17 00:00:00 2001
+From: Vivek Goyal <vgoyal@redhat.com>
+Date: Fri, 1 Jul 2016 16:34:25 -0400
+Subject: ovl: Copy up underlying inode's ->i_mode to overlay inode
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+commit 07a2daab49c549a37b5b744cbebb6e3f445f12bc upstream.
+
+Right now when a new overlay inode is created, we initialize overlay
+inode's ->i_mode from underlying inode ->i_mode but we retain only
+file type bits (S_IFMT) and discard permission bits.
+
+This patch changes it and retains permission bits too. This should allow
+overlay to do permission checks on overlay inode itself in task context.
+
+[SzM] It also fixes clearing suid/sgid bits on write.
+
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Reported-by: Eryu Guan <eguan@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c | 3 +--
+ fs/overlayfs/overlayfs.h | 1 +
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -423,12 +423,11 @@ struct inode *ovl_new_inode(struct super
+ if (!inode)
+ return NULL;
+
+- mode &= S_IFMT;
+-
+ inode->i_ino = get_next_ino();
+ inode->i_mode = mode;
+ inode->i_flags |= S_NOATIME | S_NOCMTIME;
+
++ mode &= S_IFMT;
+ switch (mode) {
+ case S_IFDIR:
+ inode->i_private = oe;
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -185,6 +185,7 @@ static inline void ovl_copyattr(struct i
+ {
+ to->i_uid = from->i_uid;
+ to->i_gid = from->i_gid;
++ to->i_mode = from->i_mode;
+ }
+
+ /* dir.c */
--- /dev/null
+From a4859d75944a726533ab86d24bb5ffd1b2b7d6cc Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 29 Jun 2016 08:26:59 +0200
+Subject: ovl: fix dentry leak for default_permissions
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit a4859d75944a726533ab86d24bb5ffd1b2b7d6cc upstream.
+
+When using the 'default_permissions' mount option, ovl_permission() on
+non-directories was missing a dput(alias), resulting in "BUG Dentry still
+in use".
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 8d3095f4ad47 ("ovl: default permissions")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -121,16 +121,18 @@ int ovl_permission(struct inode *inode,
+
+ err = vfs_getattr(&realpath, &stat);
+ if (err)
+- return err;
++ goto out_dput;
+
++ err = -ESTALE;
+ if ((stat.mode ^ inode->i_mode) & S_IFMT)
+- return -ESTALE;
++ goto out_dput;
+
+ inode->i_mode = stat.mode;
+ inode->i_uid = stat.uid;
+ inode->i_gid = stat.gid;
+
+- return generic_permission(inode, mask);
++ err = generic_permission(inode, mask);
++ goto out_dput;
+ }
+
+ /* Careful in RCU walk mode */
--- /dev/null
+From 03bea60409328de54e4ff7ec41672e12a9cb0908 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 29 Jun 2016 16:03:55 +0200
+Subject: ovl: get_write_access() in truncate
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 03bea60409328de54e4ff7ec41672e12a9cb0908 upstream.
+
+When truncating a file we should check write access on the underlying
+inode. And we should do so on the lower file as well (before copy-up) for
+consistency.
+
+Original patch and test case by Aihua Zhang.
+
+ - - >o >o - - test.c - - >o >o - -
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ ret = truncate(argv[0], 4096);
+ if (ret != -1) {
+ fprintf(stderr, "truncate(argv[0]) should have failed\n");
+ return 1;
+ }
+ if (errno != ETXTBSY) {
+ perror("truncate(argv[0])");
+ return 1;
+ }
+
+ return 0;
+}
+ - - >o >o - - >o >o - - >o >o - -
+
+Reported-by: Aihua Zhang <zhangaihua1@huawei.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -59,16 +59,37 @@ int ovl_setattr(struct dentry *dentry, s
+ if (err)
+ goto out;
+
++ if (attr->ia_valid & ATTR_SIZE) {
++ struct inode *realinode = d_inode(ovl_dentry_real(dentry));
++
++ err = -ETXTBSY;
++ if (atomic_read(&realinode->i_writecount) < 0)
++ goto out_drop_write;
++ }
++
+ err = ovl_copy_up(dentry);
+ if (!err) {
++ struct inode *winode = NULL;
++
+ upperdentry = ovl_dentry_upper(dentry);
+
++ if (attr->ia_valid & ATTR_SIZE) {
++ winode = d_inode(upperdentry);
++ err = get_write_access(winode);
++ if (err)
++ goto out_drop_write;
++ }
++
+ inode_lock(upperdentry->d_inode);
+ err = notify_change(upperdentry, attr, NULL);
+ if (!err)
+ ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
+ inode_unlock(upperdentry->d_inode);
++
++ if (winode)
++ put_write_access(winode);
+ }
++out_drop_write:
+ ovl_drop_write(dentry);
+ out:
+ return err;
--- /dev/null
+From b99c2d913810e56682a538c9f2394d76fca808f8 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Mon, 4 Jul 2016 16:49:48 +0200
+Subject: ovl: handle ATTR_KILL*
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit b99c2d913810e56682a538c9f2394d76fca808f8 upstream.
+
+Before 4bacc9c9234c ("overlayfs: Make f_path...") file->f_path pointed to
+the underlying file, hence suid/sgid removal on write worked fine.
+
+After that patch file->f_path pointed to the overlay file, and the file
+mode bits weren't copied to overlay_inode->i_mode. So the suid/sgid
+removal simply stopped working.
+
+The fix is to copy the mode bits, but then ovl_setattr() needs to clear
+ATTR_MODE to avoid the BUG() in notify_change(). So do this first, then in
+the next patch copy the mode.
+
+Reported-by: Eryu Guan <eguan@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -80,6 +80,9 @@ int ovl_setattr(struct dentry *dentry, s
+ goto out_drop_write;
+ }
+
++ if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
++ attr->ia_valid &= ~ATTR_MODE;
++
+ inode_lock(upperdentry->d_inode);
+ err = notify_change(upperdentry, attr, NULL);
+ if (!err)
--- /dev/null
+From cfc9fde0b07c3b44b570057c5f93dda59dca1c94 Mon Sep 17 00:00:00 2001
+From: Maxim Patlasov <mpatlasov@virtuozzo.com>
+Date: Thu, 21 Jul 2016 18:24:26 -0700
+Subject: ovl: verify upper dentry in ovl_remove_and_whiteout()
+
+From: Maxim Patlasov <mpatlasov@virtuozzo.com>
+
+commit cfc9fde0b07c3b44b570057c5f93dda59dca1c94 upstream.
+
+The upper dentry may become stale before we call ovl_lock_rename_workdir.
+For example, someone could (mistakenly or maliciously) manually unlink(2)
+it directly from upperdir.
+
+To ensure it is not stale, let's lookup it after ovl_lock_rename_workdir
+and and check if it matches the upper dentry.
+
+Essentially, it is the same problem and similar solution as in
+commit 11f3710417d0 ("ovl: verify upper dentry before unlink and rename").
+
+Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/dir.c | 56 +++++++++++++++++++++++------------------------------
+ 1 file changed, 25 insertions(+), 31 deletions(-)
+
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -511,6 +511,7 @@ static int ovl_remove_and_whiteout(struc
+ struct dentry *upper;
+ struct dentry *opaquedir = NULL;
+ int err;
++ int flags = 0;
+
+ if (WARN_ON(!workdir))
+ return -EROFS;
+@@ -540,46 +541,39 @@ static int ovl_remove_and_whiteout(struc
+ if (err)
+ goto out_dput;
+
++ upper = lookup_one_len(dentry->d_name.name, upperdir,
++ dentry->d_name.len);
++ err = PTR_ERR(upper);
++ if (IS_ERR(upper))
++ goto out_unlock;
++
++ err = -ESTALE;
++ if ((opaquedir && upper != opaquedir) ||
++ (!opaquedir && ovl_dentry_upper(dentry) &&
++ upper != ovl_dentry_upper(dentry))) {
++ goto out_dput_upper;
++ }
++
+ whiteout = ovl_whiteout(workdir, dentry);
+ err = PTR_ERR(whiteout);
+ if (IS_ERR(whiteout))
+- goto out_unlock;
++ goto out_dput_upper;
+
+- upper = ovl_dentry_upper(dentry);
+- if (!upper) {
+- upper = lookup_one_len(dentry->d_name.name, upperdir,
+- dentry->d_name.len);
+- err = PTR_ERR(upper);
+- if (IS_ERR(upper))
+- goto kill_whiteout;
+-
+- err = ovl_do_rename(wdir, whiteout, udir, upper, 0);
+- dput(upper);
+- if (err)
+- goto kill_whiteout;
+- } else {
+- int flags = 0;
+-
+- if (opaquedir)
+- upper = opaquedir;
+- err = -ESTALE;
+- if (upper->d_parent != upperdir)
+- goto kill_whiteout;
+-
+- if (is_dir)
+- flags |= RENAME_EXCHANGE;
+-
+- err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
+- if (err)
+- goto kill_whiteout;
++ if (d_is_dir(upper))
++ flags = RENAME_EXCHANGE;
++
++ err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
++ if (err)
++ goto kill_whiteout;
++ if (flags)
++ ovl_cleanup(wdir, upper);
+
+- if (is_dir)
+- ovl_cleanup(wdir, upper);
+- }
+ ovl_dentry_version_inc(dentry->d_parent);
+ out_d_drop:
+ d_drop(dentry);
+ dput(whiteout);
++out_dput_upper:
++ dput(upper);
+ out_unlock:
+ unlock_rename(workdir, upperdir);
+ out_dput:
drm-vmwgfx-fix-error-paths-when-mapping-framebuffer.patch
memory-omap-gpmc-fix-omap-gpmc-extradelay-timing.patch
pci-fix-unaligned-accesses-in-vc-code.patch
+xen-balloon-fix-declared-but-not-defined-warning.patch
+iio-fix-error-handling-in-iio_trigger_attach_poll_func.patch
+iio-st_pressure-fix-sampling-gains-bring-inline-with-abi.patch
+iio-light-apds9960-add-the-missing-dev.parent.patch
+iio-proximity-as3935-correct-iio_chan_info_raw-output.patch
+iio-proximity-as3935-remove-triggered-buffer-processing.patch
+iio-proximity-as3935-fix-buffer-stack-trashing.patch
+iio-humidity-hdc100x-correct-humidity-integration-time-mask.patch
+iio-humidity-hdc100x-fix-iio_temp-channel-reporting.patch
+iio-hudmidity-hdc100x-fix-incorrect-shifting-and-scaling.patch
+staging-iio-accel-fix-error-check.patch
+iio-accel-kxsd9-fix-the-usage-of-spi_w8r8.patch
+iio-ad7266-fix-broken-regulator-error-handling.patch
+iio-ad7266-fix-support-for-optional-regulators.patch
+iio-ad7266-fix-probe-deferral-for-vref.patch
+tty-vt-fix-soft-lockup-in-fbcon-cursor-blink-timer.patch
+tty-vt-keyboard-fix-oob-access-in-do_compute_shiftstate.patch
+hwmon-dell-smm-restrict-fan-control-and-serial-number-to-cap_sys_admin-by-default.patch
+hwmon-dell-smm-disallow-fan_type-calls-on-broken-machines.patch
+hwmon-dell-smm-cache-fan_type-calls-and-change-fan-detection.patch
+alsa-dummy-fix-a-use-after-free-at-closing.patch
+alsa-hdac_regmap-fix-the-register-access-for-runtime-pm.patch
+alsa-hda-fix-the-headset-mic-jack-detection-on-dell-machine.patch
+alsa-hda-realtek-add-two-more-thinkpad-ids-5050-5053-for-tpt460-fixup.patch
+alsa-au88x0-fix-calculation-in-vortex_wtdma_bufshift.patch
+alsa-echoaudio-fix-memory-allocation.patch
+alsa-timer-fix-negative-queue-usage-by-racy-accesses.patch
+alsa-hda-realtek-add-lenovo-l460-to-docking-unit-fixup.patch
+alsa-hda-add-pci-id-for-kabylake-h.patch
+alsa-hda-fix-read-before-array-start.patch
+alsa-usb-audio-fix-quirks-code-is-not-called.patch
+alsa-hda-realtek-add-new-pin-definition-in-alc225-pin-quirk-table.patch
+alsa-pcm-free-chmap-at-pcm-free-callback-too.patch
+alsa-ctl-stop-notification-after-disconnection.patch
+alsa-hda-fix-use-after-free-after-module-unload.patch
+alsa-hda-add-amd-stoney-pci-id-with-proper-driver-caps.patch
+arm-sunxi-dt-make-the-chip-inherit-from-allwinner-sun5i-a13.patch
+arm-dts-armada-38x-fix-mbus_id-for-crypto-sram-on-armada-385-linksys.patch
+arm-mvebu-fix-hw-i-o-coherency-related-deadlocks.patch
+ovl-fix-dentry-leak-for-default_permissions.patch
+ovl-get_write_access-in-truncate.patch
+ovl-copy-up-underlying-inode-s-i_mode-to-overlay-inode.patch
+ovl-handle-attr_kill.patch
+ovl-verify-upper-dentry-in-ovl_remove_and_whiteout.patch
--- /dev/null
+From ef3149eb3ddb7f9125e11c90f8330e371b55cffd Mon Sep 17 00:00:00 2001
+From: Luis de Bethencourt <luisbg@osg.samsung.com>
+Date: Wed, 22 Jun 2016 20:43:30 +0100
+Subject: staging: iio: accel: fix error check
+
+From: Luis de Bethencourt <luisbg@osg.samsung.com>
+
+commit ef3149eb3ddb7f9125e11c90f8330e371b55cffd upstream.
+
+sca3000_read_ctrl_reg() returns a negative number on failure, check for
+this instead of zero.
+
+Signed-off-by: Luis de Bethencourt <luisbg@osg.samsung.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/iio/accel/sca3000_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/iio/accel/sca3000_core.c
++++ b/drivers/staging/iio/accel/sca3000_core.c
+@@ -594,7 +594,7 @@ static ssize_t sca3000_read_frequency(st
+ goto error_ret_mut;
+ ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+ mutex_unlock(&st->lock);
+- if (ret)
++ if (ret < 0)
+ goto error_ret;
+ val = ret;
+ if (base_freq > 0)
--- /dev/null
+From 1b45996d2ebf9680ccd0db875fc668aa025f40fd Mon Sep 17 00:00:00 2001
+From: David Daney <david.daney@cavium.com>
+Date: Tue, 17 May 2016 11:41:04 -0700
+Subject: tty: vt: Fix soft lockup in fbcon cursor blink timer.
+
+From: David Daney <david.daney@cavium.com>
+
+commit 1b45996d2ebf9680ccd0db875fc668aa025f40fd upstream.
+
+We are getting somewhat random soft lockups with this signature:
+
+[ 86.992215] [<fffffc00080935e0>] el1_irq+0xa0/0x10c
+[ 86.997082] [<fffffc000841822c>] cursor_timer_handler+0x30/0x54
+[ 87.002991] [<fffffc000810ec44>] call_timer_fn+0x54/0x1a8
+[ 87.008378] [<fffffc000810ef88>] run_timer_softirq+0x1c4/0x2bc
+[ 87.014200] [<fffffc000809077c>] __do_softirq+0x114/0x344
+[ 87.019590] [<fffffc00080af45c>] irq_exit+0x74/0x98
+[ 87.024458] [<fffffc00080fac20>] __handle_domain_irq+0x98/0xfc
+[ 87.030278] [<fffffc000809056c>] gic_handle_irq+0x94/0x190
+
+This is caused by the vt visual_init() function calling into
+fbcon_init() with a vc_cur_blink_ms value of zero. This is a
+transient condition, as it is later set to a non-zero value. But, if
+the timer happens to expire while the blink rate is zero, it goes into
+an endless loop, and we get soft lockup.
+
+The fix is to initialize vc_cur_blink_ms before calling the con_init()
+function.
+
+Signed-off-by: David Daney <david.daney@cavium.com>
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Tested-by: Ming Lei <ming.lei@canonical.com>
+Acked-by: Scot Doyle <lkml14@scotdoyle.com>
+Tested-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -750,6 +750,7 @@ static void visual_init(struct vc_data *
+ vc->vc_complement_mask = 0;
+ vc->vc_can_do_color = 0;
+ vc->vc_panic_force_write = false;
++ vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
+ vc->vc_sw->con_init(vc, init);
+ if (!vc->vc_complement_mask)
+ vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
--- /dev/null
+From 510cccb5b0c8868a2b302a0ab524da7912da648b Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 27 Jun 2016 14:12:34 -0700
+Subject: tty/vt/keyboard: fix OOB access in do_compute_shiftstate()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 510cccb5b0c8868a2b302a0ab524da7912da648b upstream.
+
+The size of individual keymap in drivers/tty/vt/keyboard.c is NR_KEYS,
+which is currently 256, whereas number of keys/buttons in input device (and
+therefor in key_down) is much larger - KEY_CNT - 768, and that can cause
+out-of-bound access when we do
+
+ sym = U(key_maps[0][k]);
+
+with large 'k'.
+
+To fix it we should not attempt iterating beyond smaller of NR_KEYS and
+KEY_CNT.
+
+Also while at it let's switch to for_each_set_bit() instead of open-coding
+it.
+
+Reported-by: Sasha Levin <sasha.levin@oracle.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/keyboard.c | 30 +++++++++---------------------
+ 1 file changed, 9 insertions(+), 21 deletions(-)
+
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -366,34 +366,22 @@ static void to_utf8(struct vc_data *vc,
+
+ static void do_compute_shiftstate(void)
+ {
+- unsigned int i, j, k, sym, val;
++ unsigned int k, sym, val;
+
+ shift_state = 0;
+ memset(shift_down, 0, sizeof(shift_down));
+
+- for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+-
+- if (!key_down[i])
++ for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
++ sym = U(key_maps[0][k]);
++ if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+ continue;
+
+- k = i * BITS_PER_LONG;
+-
+- for (j = 0; j < BITS_PER_LONG; j++, k++) {
+-
+- if (!test_bit(k, key_down))
+- continue;
+-
+- sym = U(key_maps[0][k]);
+- if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+- continue;
+-
+- val = KVAL(sym);
+- if (val == KVAL(K_CAPSSHIFT))
+- val = KVAL(K_SHIFT);
++ val = KVAL(sym);
++ if (val == KVAL(K_CAPSSHIFT))
++ val = KVAL(K_SHIFT);
+
+- shift_down[val]++;
+- shift_state |= (1 << val);
+- }
++ shift_down[val]++;
++ shift_state |= BIT(val);
+ }
+ }
+
--- /dev/null
+From 842775f1509054ea969f1787f38d6a0ec2ccfaba Mon Sep 17 00:00:00 2001
+From: Ross Lagerwall <ross.lagerwall@citrix.com>
+Date: Tue, 10 May 2016 10:27:54 +0100
+Subject: xen/balloon: Fix declared-but-not-defined warning
+
+From: Ross Lagerwall <ross.lagerwall@citrix.com>
+
+commit 842775f1509054ea969f1787f38d6a0ec2ccfaba upstream.
+
+Fix a declared-but-not-defined warning when building with
+XEN_BALLOON_MEMORY_HOTPLUG=n. This fixes a regression introduced by
+commit dfd74a1edfab ("xen/balloon: Fix crash when ballooning on x86 32
+bit PAE").
+
+Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
+Acked-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/balloon.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -151,8 +151,6 @@ static DECLARE_WAIT_QUEUE_HEAD(balloon_w
+ static void balloon_process(struct work_struct *work);
+ static DECLARE_DELAYED_WORK(balloon_worker, balloon_process);
+
+-static void release_memory_resource(struct resource *resource);
+-
+ /* When ballooning out (allocating memory to return to Xen) we don't really
+ want the kernel to try too hard since that can trigger the oom killer. */
+ #define GFP_BALLOON \
+@@ -248,6 +246,19 @@ static enum bp_state update_schedule(enu
+ }
+
+ #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
++static void release_memory_resource(struct resource *resource)
++{
++ if (!resource)
++ return;
++
++ /*
++ * No need to reset region to identity mapped since we now
++ * know that no I/O can be in this region
++ */
++ release_resource(resource);
++ kfree(resource);
++}
++
+ static struct resource *additional_memory_resource(phys_addr_t size)
+ {
+ struct resource *res;
+@@ -286,19 +297,6 @@ static struct resource *additional_memor
+ return res;
+ }
+
+-static void release_memory_resource(struct resource *resource)
+-{
+- if (!resource)
+- return;
+-
+- /*
+- * No need to reset region to identity mapped since we now
+- * know that no I/O can be in this region
+- */
+- release_resource(resource);
+- kfree(resource);
+-}
+-
+ static enum bp_state reserve_additional_memory(void)
+ {
+ long credit;