]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Mar 2016 07:12:37 +0000 (23:12 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Mar 2016 07:12:37 +0000 (23:12 -0800)
added patches:
clocksource-drivers-vt8500-increase-the-minimum-delta.patch
dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch
genirq-prevent-chip-buslock-deadlock.patch

queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch [new file with mode: 0644]
queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch [new file with mode: 0644]
queue-3.10/genirq-prevent-chip-buslock-deadlock.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch b/queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch
new file mode 100644 (file)
index 0000000..c9d1826
--- /dev/null
@@ -0,0 +1,81 @@
+From f9eccf24615672896dc13251410c3f2f33a14f95 Mon Sep 17 00:00:00 2001
+From: Roman Volkov <rvolkov@v1ros.org>
+Date: Fri, 1 Jan 2016 16:24:41 +0300
+Subject: clocksource/drivers/vt8500: Increase the minimum delta
+
+From: Roman Volkov <rvolkov@v1ros.org>
+
+commit f9eccf24615672896dc13251410c3f2f33a14f95 upstream.
+
+The vt8500 clocksource driver declares itself as capable to handle the
+minimum delay of 4 cycles by passing the value into
+clockevents_config_and_register(). The vt8500_timer_set_next_event()
+requires the passed cycles value to be at least 16. The impact is that
+userspace hangs in nanosleep() calls with small delay intervals.
+
+This problem is reproducible in Linux 4.2 starting from:
+c6eb3f70d448 ('hrtimer: Get rid of hrtimer softirq')
+
+From Russell King, more detailed explanation:
+
+"It's a speciality of the StrongARM/PXA hardware. It takes a certain
+number of OSCR cycles for the value written to hit the compare registers.
+So, if a very small delta is written (eg, the compare register is written
+with a value of OSCR + 1), the OSCR will have incremented past this value
+before it hits the underlying hardware. The result is, that you end up
+waiting a very long time for the OSCR to wrap before the event fires.
+
+So, we introduce a check in set_next_event() to detect this and return
+-ETIME if the calculated delta is too small, which causes the generic
+clockevents code to retry after adding the min_delta specified in
+clockevents_config_and_register() to the current time value.
+
+min_delta must be sufficient that we don't re-trip the -ETIME check - if
+we do, we will return -ETIME, forward the next event time, try to set it,
+return -ETIME again, and basically lock the system up. So, min_delta
+must be larger than the check inside set_next_event(). A factor of two
+was chosen to ensure that this situation would never occur.
+
+The PXA code worked on PXA systems for years, and I'd suggest no one
+changes this mechanism without access to a wide range of PXA systems,
+otherwise they're risking breakage."
+
+Cc: Russell King <linux@arm.linux.org.uk>
+Acked-by: Alexey Charkov <alchark@gmail.com>
+Signed-off-by: Roman Volkov <rvolkov@v1ros.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clocksource/vt8500_timer.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/clocksource/vt8500_timer.c
++++ b/drivers/clocksource/vt8500_timer.c
+@@ -50,6 +50,8 @@
+ #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
++#define MIN_OSCR_DELTA                16
++
+ static void __iomem *regbase;
+ static cycle_t vt8500_timer_read(struct clocksource *cs)
+@@ -80,7 +82,7 @@ static int vt8500_timer_set_next_event(u
+               cpu_relax();
+       writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
+-      if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
++      if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA)
+               return -ETIME;
+       writel(1, regbase + TIMER_IER_VAL);
+@@ -162,7 +164,7 @@ static void __init vt8500_timer_init(str
+               pr_err("%s: setup_irq failed for %s\n", __func__,
+                                                       clockevent.name);
+       clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ,
+-                                      4, 0xf0000000);
++                                      MIN_OSCR_DELTA * 2, 0xf0000000);
+ }
+ CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init);
diff --git a/queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch b/queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch
new file mode 100644 (file)
index 0000000..50de5db
--- /dev/null
@@ -0,0 +1,40 @@
+From 0f090bf14e51e7eefb71d9d1c545807f8b627986 Mon Sep 17 00:00:00 2001
+From: Roman Volkov <rvolkov@v1ros.org>
+Date: Fri, 1 Jan 2016 16:38:11 +0300
+Subject: dts: vt8500: Add SDHC node to DTS file for WM8650
+
+From: Roman Volkov <rvolkov@v1ros.org>
+
+commit 0f090bf14e51e7eefb71d9d1c545807f8b627986 upstream.
+
+Since WM8650 has the same 'WMT' SDHC controller as WM8505, and the driver
+is already in the kernel, this node enables the controller support for
+WM8650
+
+Signed-off-by: Roman Volkov <rvolkov@v1ros.org>
+Reviewed-by: Alexey Charkov <alchark@gmail.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/wm8650.dtsi |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm/boot/dts/wm8650.dtsi
++++ b/arch/arm/boot/dts/wm8650.dtsi
+@@ -130,6 +130,15 @@
+                       interrupts = <43>;
+               };
++              sdhc@d800a000 {
++                      compatible = "wm,wm8505-sdhc";
++                      reg = <0xd800a000 0x400>;
++                      interrupts = <20>, <21>;
++                      clocks = <&clksdhc>;
++                      bus-width = <4>;
++                      sdon-inverted;
++              };
++
+               fb: fb@d8050800 {
+                       compatible = "wm,wm8505-fb";
+                       reg = <0xd8050800 0x200>;
diff --git a/queue-3.10/genirq-prevent-chip-buslock-deadlock.patch b/queue-3.10/genirq-prevent-chip-buslock-deadlock.patch
new file mode 100644 (file)
index 0000000..57b370f
--- /dev/null
@@ -0,0 +1,80 @@
+From abc7e40c81d113ef4bacb556f0a77ca63ac81d85 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 13 Dec 2015 18:12:30 +0100
+Subject: genirq: Prevent chip buslock deadlock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit abc7e40c81d113ef4bacb556f0a77ca63ac81d85 upstream.
+
+If a interrupt chip utilizes chip->buslock then free_irq() can
+deadlock in the following way:
+
+CPU0                           CPU1
+                               interrupt(X) (Shared or spurious)
+free_irq(X)                    interrupt_thread(X)
+chip_bus_lock(X)
+                                  irq_finalize_oneshot(X)
+                                    chip_bus_lock(X)
+synchronize_irq(X)
+
+synchronize_irq() waits for the interrupt thread to complete,
+i.e. forever.
+
+Solution is simple: Drop chip_bus_lock() before calling
+synchronize_irq() as we do with the irq_desc lock. There is nothing to
+be protected after the point where irq_desc lock has been released.
+
+This adds chip_bus_lock/unlock() to the remove_irq() code path, but
+that's actually correct in the case where remove_irq() is called on
+such an interrupt. The current users of remove_irq() are not affected
+as none of those interrupts is on a chip which requires buslock.
+
+Reported-by: Fredrik Markström <fredrik.markstrom@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/manage.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -1229,6 +1229,7 @@ static struct irqaction *__free_irq(unsi
+       if (!desc)
+               return NULL;
++      chip_bus_lock(desc);
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       /*
+@@ -1242,7 +1243,7 @@ static struct irqaction *__free_irq(unsi
+               if (!action) {
+                       WARN(1, "Trying to free already-free IRQ %d\n", irq);
+                       raw_spin_unlock_irqrestore(&desc->lock, flags);
+-
++                      chip_bus_sync_unlock(desc);
+                       return NULL;
+               }
+@@ -1265,6 +1266,7 @@ static struct irqaction *__free_irq(unsi
+ #endif
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
++      chip_bus_sync_unlock(desc);
+       unregister_handler_proc(irq, action);
+@@ -1338,9 +1340,7 @@ void free_irq(unsigned int irq, void *de
+               desc->affinity_notify = NULL;
+ #endif
+-      chip_bus_lock(desc);
+       kfree(__free_irq(irq, dev_id));
+-      chip_bus_sync_unlock(desc);
+ }
+ EXPORT_SYMBOL(free_irq);
index 7a42adabf3b6da2f1ff884f6ec71fb26731e0360..41b3e7efe0016dba89ce3996d5eb45db6a29c778 100644 (file)
@@ -19,3 +19,6 @@ mips-kvm-uninit-vcpu-in-vcpu_create-error-path.patch
 splice-sendfile-at-once-fails-for-big-files.patch
 failing-to-send-a-close-if-file-is-opened-wronly-and-server-reboots-on-a-4.x-mount.patch
 unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch
+genirq-prevent-chip-buslock-deadlock.patch
+dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch
+clocksource-drivers-vt8500-increase-the-minimum-delta.patch