]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Feb 2015 02:28:23 +0000 (10:28 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Feb 2015 02:28:23 +0000 (10:28 +0800)
added patches:
alsa-ak411x-fix-stall-in-work-callback.patch
asoc-atmel_ssc_dai-fix-start-event-for-i2s-mode.patch
asoc-sgtl5000-add-delay-before-first-i2c-access.patch
asoc-wm8731-init-mutex-in-i2c-init-path.patch
smpboot-add-missing-get_online_cpus-in-smpboot_register_percpu_thread.patch

queue-3.10/alsa-ak411x-fix-stall-in-work-callback.patch [new file with mode: 0644]
queue-3.10/asoc-atmel_ssc_dai-fix-start-event-for-i2s-mode.patch [new file with mode: 0644]
queue-3.10/asoc-sgtl5000-add-delay-before-first-i2c-access.patch [new file with mode: 0644]
queue-3.10/asoc-wm8731-init-mutex-in-i2c-init-path.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/smpboot-add-missing-get_online_cpus-in-smpboot_register_percpu_thread.patch [new file with mode: 0644]

diff --git a/queue-3.10/alsa-ak411x-fix-stall-in-work-callback.patch b/queue-3.10/alsa-ak411x-fix-stall-in-work-callback.patch
new file mode 100644 (file)
index 0000000..f505001
--- /dev/null
@@ -0,0 +1,151 @@
+From 4161b4505f1690358ac0a9ee59845a7887336b21 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 13 Jan 2015 10:53:20 +0100
+Subject: ALSA: ak411x: Fix stall in work callback
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 4161b4505f1690358ac0a9ee59845a7887336b21 upstream.
+
+When ak4114 work calls its callback and the callback invokes
+ak4114_reinit(), it stalls due to flush_delayed_work().  For avoiding
+this, control the reentrance by introducing a refcount.  Also
+flush_delayed_work() is replaced with cancel_delayed_work_sync().
+
+The exactly same bug is present in ak4113.c and fixed as well.
+
+Reported-by: Pavel Hofman <pavel.hofman@ivitera.com>
+Acked-by: Jaroslav Kysela <perex@perex.cz>
+Tested-by: Pavel Hofman <pavel.hofman@ivitera.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/sound/ak4113.h   |    2 +-
+ include/sound/ak4114.h   |    2 +-
+ sound/i2c/other/ak4113.c |   17 ++++++++---------
+ sound/i2c/other/ak4114.c |   18 ++++++++----------
+ 4 files changed, 18 insertions(+), 21 deletions(-)
+
+--- a/include/sound/ak4113.h
++++ b/include/sound/ak4113.h
+@@ -286,7 +286,7 @@ struct ak4113 {
+       ak4113_write_t *write;
+       ak4113_read_t *read;
+       void *private_data;
+-      unsigned int init:1;
++      atomic_t wq_processing;
+       spinlock_t lock;
+       unsigned char regmap[AK4113_WRITABLE_REGS];
+       struct snd_kcontrol *kctls[AK4113_CONTROLS];
+--- a/include/sound/ak4114.h
++++ b/include/sound/ak4114.h
+@@ -168,7 +168,7 @@ struct ak4114 {
+       ak4114_write_t * write;
+       ak4114_read_t * read;
+       void * private_data;
+-      unsigned int init: 1;
++      atomic_t wq_processing;
+       spinlock_t lock;
+       unsigned char regmap[7];
+       unsigned char txcsb[5];
+--- a/sound/i2c/other/ak4113.c
++++ b/sound/i2c/other/ak4113.c
+@@ -56,8 +56,7 @@ static inline unsigned char reg_read(str
+ static void snd_ak4113_free(struct ak4113 *chip)
+ {
+-      chip->init = 1; /* don't schedule new work */
+-      mb();
++      atomic_inc(&chip->wq_processing);       /* don't schedule new work */
+       cancel_delayed_work_sync(&chip->work);
+       kfree(chip);
+ }
+@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *c
+       chip->write = write;
+       chip->private_data = private_data;
+       INIT_DELAYED_WORK(&chip->work, ak4113_stats);
++      atomic_set(&chip->wq_processing, 0);
+       for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
+               chip->regmap[reg] = pgm[reg];
+@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak41
+ void snd_ak4113_reinit(struct ak4113 *chip)
+ {
+-      chip->init = 1;
+-      mb();
+-      flush_delayed_work(&chip->work);
++      if (atomic_inc_return(&chip->wq_processing) == 1)
++              cancel_delayed_work_sync(&chip->work);
+       ak4113_init_regs(chip);
+       /* bring up statistics / event queing */
+-      chip->init = 0;
+-      if (chip->kctls[0])
++      if (atomic_dec_and_test(&chip->wq_processing))
+               schedule_delayed_work(&chip->work, HZ / 10);
+ }
+ EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
+@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_str
+ {
+       struct ak4113 *chip = container_of(work, struct ak4113, work.work);
+-      if (!chip->init)
++      if (atomic_inc_return(&chip->wq_processing) == 1)
+               snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
+-      schedule_delayed_work(&chip->work, HZ / 10);
++      if (atomic_dec_and_test(&chip->wq_processing))
++              schedule_delayed_work(&chip->work, HZ / 10);
+ }
+--- a/sound/i2c/other/ak4114.c
++++ b/sound/i2c/other/ak4114.c
+@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak41
+ static void snd_ak4114_free(struct ak4114 *chip)
+ {
+-      chip->init = 1; /* don't schedule new work */
+-      mb();
++      atomic_inc(&chip->wq_processing);       /* don't schedule new work */
+       cancel_delayed_work_sync(&chip->work);
+       kfree(chip);
+ }
+@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *c
+       chip->write = write;
+       chip->private_data = private_data;
+       INIT_DELAYED_WORK(&chip->work, ak4114_stats);
++      atomic_set(&chip->wq_processing, 0);
+       for (reg = 0; reg < 7; reg++)
+               chip->regmap[reg] = pgm[reg];
+@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak41
+ void snd_ak4114_reinit(struct ak4114 *chip)
+ {
+-      chip->init = 1;
+-      mb();
+-      flush_delayed_work(&chip->work);
++      if (atomic_inc_return(&chip->wq_processing) == 1)
++              cancel_delayed_work_sync(&chip->work);
+       ak4114_init_regs(chip);
+       /* bring up statistics / event queing */
+-      chip->init = 0;
+-      if (chip->kctls[0])
++      if (atomic_dec_and_test(&chip->wq_processing))
+               schedule_delayed_work(&chip->work, HZ / 10);
+ }
+@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_str
+ {
+       struct ak4114 *chip = container_of(work, struct ak4114, work.work);
+-      if (!chip->init)
++      if (atomic_inc_return(&chip->wq_processing) == 1)
+               snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
+-
+-      schedule_delayed_work(&chip->work, HZ / 10);
++      if (atomic_dec_and_test(&chip->wq_processing))
++              schedule_delayed_work(&chip->work, HZ / 10);
+ }
+ EXPORT_SYMBOL(snd_ak4114_create);
diff --git a/queue-3.10/asoc-atmel_ssc_dai-fix-start-event-for-i2s-mode.patch b/queue-3.10/asoc-atmel_ssc_dai-fix-start-event-for-i2s-mode.patch
new file mode 100644 (file)
index 0000000..66a0aad
--- /dev/null
@@ -0,0 +1,80 @@
+From a43bd7e125143b875caae6d4f9938855b440faaf Mon Sep 17 00:00:00 2001
+From: Bo Shen <voice.shen@atmel.com>
+Date: Tue, 20 Jan 2015 15:43:16 +0800
+Subject: ASoC: atmel_ssc_dai: fix start event for I2S mode
+
+From: Bo Shen <voice.shen@atmel.com>
+
+commit a43bd7e125143b875caae6d4f9938855b440faaf upstream.
+
+According to the I2S specification information as following:
+  - WS = 0, channel 1 (left)
+  - WS = 1, channel 2 (right)
+So, the start event should be TF/RF falling edge.
+
+Reported-by: Songjun Wu <songjun.wu@atmel.com>
+Signed-off-by: Bo Shen <voice.shen@atmel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/atmel/atmel_ssc_dai.c |   18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/sound/soc/atmel/atmel_ssc_dai.c
++++ b/sound/soc/atmel/atmel_ssc_dai.c
+@@ -331,7 +331,6 @@ static int atmel_ssc_hw_params(struct sn
+       struct atmel_pcm_dma_params *dma_params;
+       int dir, channels, bits;
+       u32 tfmr, rfmr, tcmr, rcmr;
+-      int start_event;
+       int ret;
+       /*
+@@ -450,19 +449,10 @@ static int atmel_ssc_hw_params(struct sn
+                * The SSC transmit clock is obtained from the BCLK signal on
+                * on the TK line, and the SSC receive clock is
+                * generated from the transmit clock.
+-               *
+-               *  For single channel data, one sample is transferred
+-               * on the falling edge of the LRC clock.
+-               * For two channel data, one sample is
+-               * transferred on both edges of the LRC clock.
+                */
+-              start_event = ((channels == 1)
+-                              ? SSC_START_FALLING_RF
+-                              : SSC_START_EDGE_RF);
+-
+               rcmr =    SSC_BF(RCMR_PERIOD, 0)
+                       | SSC_BF(RCMR_STTDLY, START_DELAY)
+-                      | SSC_BF(RCMR_START, start_event)
++                      | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
+                       | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
+                       | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
+@@ -470,14 +460,14 @@ static int atmel_ssc_hw_params(struct sn
+               rfmr =    SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
+                       | SSC_BF(RFMR_FSLEN, 0)
+-                      | SSC_BF(RFMR_DATNB, 0)
++                      | SSC_BF(RFMR_DATNB, (channels - 1))
+                       | SSC_BIT(RFMR_MSBF)
+                       | SSC_BF(RFMR_LOOP, 0)
+                       | SSC_BF(RFMR_DATLEN, (bits - 1));
+               tcmr =    SSC_BF(TCMR_PERIOD, 0)
+                       | SSC_BF(TCMR_STTDLY, START_DELAY)
+-                      | SSC_BF(TCMR_START, start_event)
++                      | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
+                       | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
+                       | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+@@ -486,7 +476,7 @@ static int atmel_ssc_hw_params(struct sn
+                       | SSC_BF(TFMR_FSDEN, 0)
+                       | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
+                       | SSC_BF(TFMR_FSLEN, 0)
+-                      | SSC_BF(TFMR_DATNB, 0)
++                      | SSC_BF(TFMR_DATNB, (channels - 1))
+                       | SSC_BIT(TFMR_MSBF)
+                       | SSC_BF(TFMR_DATDEF, 0)
+                       | SSC_BF(TFMR_DATLEN, (bits - 1));
diff --git a/queue-3.10/asoc-sgtl5000-add-delay-before-first-i2c-access.patch b/queue-3.10/asoc-sgtl5000-add-delay-before-first-i2c-access.patch
new file mode 100644 (file)
index 0000000..f252a07
--- /dev/null
@@ -0,0 +1,38 @@
+From 58cc9c9a175885bbf6bae3acf18233d0a8229a84 Mon Sep 17 00:00:00 2001
+From: Eric Nelson <eric.nelson@boundarydevices.com>
+Date: Fri, 30 Jan 2015 14:07:55 -0700
+Subject: ASoC: sgtl5000: add delay before first I2C access
+
+From: Eric Nelson <eric.nelson@boundarydevices.com>
+
+commit 58cc9c9a175885bbf6bae3acf18233d0a8229a84 upstream.
+
+To quote from section 1.3.1 of the data sheet:
+       The SGTL5000 has an internal reset that is deasserted
+       8 SYS_MCLK cycles after all power rails have been brought
+       up. After this time, communication can start
+
+       ...
+       1.0us represents 8 SYS_MCLK cycles at the minimum 8.0 MHz SYS_MCLK.
+
+Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com>
+Reviewed-by: Fabio Estevam <fabio.estevam@freescale.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/sgtl5000.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/sound/soc/codecs/sgtl5000.c
++++ b/sound/soc/codecs/sgtl5000.c
+@@ -1242,6 +1242,9 @@ static int sgtl5000_enable_regulators(st
+       /* wait for all power rails bring up */
+       udelay(10);
++      /* Need 8 clocks before I2C accesses */
++      udelay(1);
++
+       /* read chip information */
+       reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
+       if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
diff --git a/queue-3.10/asoc-wm8731-init-mutex-in-i2c-init-path.patch b/queue-3.10/asoc-wm8731-init-mutex-in-i2c-init-path.patch
new file mode 100644 (file)
index 0000000..e76ea26
--- /dev/null
@@ -0,0 +1,31 @@
+From 8a6cf30bf93df2c0f2637156e4a5070594bddebf Mon Sep 17 00:00:00 2001
+From: Manuel Lauss <manuel.lauss@gmail.com>
+Date: Mon, 19 Jan 2015 08:23:43 +0100
+Subject: ASoC: wm8731: init mutex in i2c init path
+
+From: Manuel Lauss <manuel.lauss@gmail.com>
+
+commit 8a6cf30bf93df2c0f2637156e4a5070594bddebf upstream.
+
+The I2C init path forgot to init the mutex, leading to an oops when
+controls are accessed.
+
+Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm8731.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/soc/codecs/wm8731.c
++++ b/sound/soc/codecs/wm8731.c
+@@ -690,6 +690,8 @@ static int wm8731_i2c_probe(struct i2c_c
+       if (wm8731 == NULL)
+               return -ENOMEM;
++      mutex_init(&wm8731->lock);
++
+       wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap);
+       if (IS_ERR(wm8731->regmap)) {
+               ret = PTR_ERR(wm8731->regmap);
index 2bac19b7e97732ced8f2cc42f297f4c6741f7e06..24da9d5d74addada84b9b10d7a561218c2bbd590 100644 (file)
@@ -9,3 +9,8 @@ nilfs2-fix-deadlock-of-segment-constructor-over-i_sync-flag.patch
 arm64-fix-up-proc-cpuinfo.patch
 ext4-prevent-bugon-on-race-between-write-fcntl.patch
 lib-checksum.c-fix-build-for-generic-csum_tcpudp_nofold.patch
+asoc-wm8731-init-mutex-in-i2c-init-path.patch
+asoc-atmel_ssc_dai-fix-start-event-for-i2s-mode.patch
+asoc-sgtl5000-add-delay-before-first-i2c-access.patch
+alsa-ak411x-fix-stall-in-work-callback.patch
+smpboot-add-missing-get_online_cpus-in-smpboot_register_percpu_thread.patch
diff --git a/queue-3.10/smpboot-add-missing-get_online_cpus-in-smpboot_register_percpu_thread.patch b/queue-3.10/smpboot-add-missing-get_online_cpus-in-smpboot_register_percpu_thread.patch
new file mode 100644 (file)
index 0000000..0d37a38
--- /dev/null
@@ -0,0 +1,62 @@
+From 4bee96860a65c3a62d332edac331b3cf936ba3ad Mon Sep 17 00:00:00 2001
+From: Lai Jiangshan <laijs@cn.fujitsu.com>
+Date: Thu, 31 Jul 2014 11:30:17 +0800
+Subject: smpboot: Add missing get_online_cpus() in smpboot_register_percpu_thread()
+
+From: Lai Jiangshan <laijs@cn.fujitsu.com>
+
+commit 4bee96860a65c3a62d332edac331b3cf936ba3ad upstream.
+
+The following race exists in the smpboot percpu threads management:
+
+CPU0                        CPU1
+cpu_up(2)
+  get_online_cpus();
+  smpboot_create_threads(2);
+                            smpboot_register_percpu_thread();
+                            for_each_online_cpu();
+                              __smpboot_create_thread();
+  __cpu_up(2);
+
+This results in a missing per cpu thread for the newly onlined cpu2 and
+in a NULL pointer dereference on a consecutive offline of that cpu.
+
+Proctect smpboot_register_percpu_thread() with get_online_cpus() to
+prevent that.
+
+[ tglx: Massaged changelog and removed the change in
+        smpboot_unregister_percpu_thread() because that's an
+        optimization and therefor not stable material. ]
+
+Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
+Cc: David Rientjes <rientjes@google.com>
+Link: http://lkml.kernel.org/r/1406777421-12830-1-git-send-email-laijs@cn.fujitsu.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/smpboot.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/smpboot.c
++++ b/kernel/smpboot.c
+@@ -279,6 +279,7 @@ int smpboot_register_percpu_thread(struc
+       unsigned int cpu;
+       int ret = 0;
++      get_online_cpus();
+       mutex_lock(&smpboot_threads_lock);
+       for_each_online_cpu(cpu) {
+               ret = __smpboot_create_thread(plug_thread, cpu);
+@@ -291,6 +292,7 @@ int smpboot_register_percpu_thread(struc
+       list_add(&plug_thread->list, &hotplug_threads);
+ out:
+       mutex_unlock(&smpboot_threads_lock);
++      put_online_cpus();
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);