From a968aeb31ca9da80281a2bfef48e2bad6b1a52f3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 26 Sep 2012 15:55:23 -0700 Subject: [PATCH] 3.4-stable patches added patches: drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch --- ...d-when-cpu-0-is-out-of-irq-resources.patch | 167 ++++++++++++++++++ ....c-fix-hour-decoding-in-12-hour-mode.patch | 53 ++++++ ...ing-off-spread-spectrum-for-used-pll.patch | 85 +++++++++ ...use-num_crtc-rather-than-hardcoded-6.patch | 29 +++ ...n-console-lock-and-cursor-timer-v1.1.patch | 72 ++++++++ ...ed-state-after-fastpath_lock-failure.patch | 82 +++++++++ ...red_resume-on-success-in-rpm_suspend.patch | 49 +++++ ...urn-value-for-power.no_callbacks-set.patch | 46 +++++ queue-3.4/series | 9 + ...nsole-write-routing-is-unsafe-on-smp.patch | 102 +++++++++++ 10 files changed, 694 insertions(+) create mode 100644 queue-3.4/drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch create mode 100644 queue-3.4/drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch create mode 100644 queue-3.4/drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch create mode 100644 queue-3.4/drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch create mode 100644 queue-3.4/fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch create mode 100644 queue-3.4/mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch create mode 100644 queue-3.4/pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch create mode 100644 queue-3.4/pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch create mode 100644 queue-3.4/tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch diff --git a/queue-3.4/drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch b/queue-3.4/drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch new file mode 100644 index 00000000000..70948198550 --- /dev/null +++ b/queue-3.4/drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch @@ -0,0 +1,167 @@ +From 7838f994b4fceff24c343f4e26a6cf4393869579 Mon Sep 17 00:00:00 2001 +From: Robin Holt +Date: Tue, 21 Aug 2012 16:16:02 -0700 +Subject: drivers/misc/sgi-xp/xpc_uv.c: SGI XPC fails to load when cpu 0 is out of IRQ resources + +From: Robin Holt + +commit 7838f994b4fceff24c343f4e26a6cf4393869579 upstream. + +On many of our larger systems, CPU 0 has had all of its IRQ resources +consumed before XPC loads. Worst cases on machines with multiple 10 +GigE cards and multiple IB cards have depleted the entire first socket +of IRQs. + +This patch makes selecting the node upon which IRQs are allocated (as +well as all the other GRU Message Queue structures) specifiable as a +module load param and has a default behavior of searching all nodes/cpus +for an available resources. + +[akpm@linux-foundation.org: fix build: include cpu.h and module.h] +Signed-off-by: Robin Holt +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/sgi-xp/xpc_uv.c | 84 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 65 insertions(+), 19 deletions(-) + +--- a/drivers/misc/sgi-xp/xpc_uv.c ++++ b/drivers/misc/sgi-xp/xpc_uv.c +@@ -18,6 +18,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_hear + XPC_NOTIFY_MSG_SIZE_UV) + #define XPC_NOTIFY_IRQ_NAME "xpc_notify" + ++static int xpc_mq_node = -1; ++ + static struct xpc_gru_mq_uv *xpc_activate_mq_uv; + static struct xpc_gru_mq_uv *xpc_notify_mq_uv; + +@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_ + #if defined CONFIG_X86_64 + mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, + UV_AFFINITY_CPU); +- if (mq->irq < 0) { +- dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", +- -mq->irq); ++ if (mq->irq < 0) + return mq->irq; +- } + + mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); + +@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_siz + mq->mmr_blade = uv_cpu_to_blade_id(cpu); + + nid = cpu_to_node(cpu); +- page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, +- pg_order); ++ page = alloc_pages_exact_node(nid, ++ GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, ++ pg_order); + if (page == NULL) { + dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " + "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); +@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_ar + .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, + }; + ++static int ++xpc_init_mq_node(int nid) ++{ ++ int cpu; ++ ++ get_online_cpus(); ++ ++ for_each_cpu(cpu, cpumask_of_node(nid)) { ++ xpc_activate_mq_uv = ++ xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, ++ XPC_ACTIVATE_IRQ_NAME, ++ xpc_handle_activate_IRQ_uv); ++ if (!IS_ERR(xpc_activate_mq_uv)) ++ break; ++ } ++ if (IS_ERR(xpc_activate_mq_uv)) { ++ put_online_cpus(); ++ return PTR_ERR(xpc_activate_mq_uv); ++ } ++ ++ for_each_cpu(cpu, cpumask_of_node(nid)) { ++ xpc_notify_mq_uv = ++ xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, ++ XPC_NOTIFY_IRQ_NAME, ++ xpc_handle_notify_IRQ_uv); ++ if (!IS_ERR(xpc_notify_mq_uv)) ++ break; ++ } ++ if (IS_ERR(xpc_notify_mq_uv)) { ++ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); ++ put_online_cpus(); ++ return PTR_ERR(xpc_notify_mq_uv); ++ } ++ ++ put_online_cpus(); ++ return 0; ++} ++ + int + xpc_init_uv(void) + { ++ int nid; ++ int ret = 0; ++ + xpc_arch_ops = xpc_arch_ops_uv; + + if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { +@@ -1742,21 +1785,21 @@ xpc_init_uv(void) + return -E2BIG; + } + +- xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, +- XPC_ACTIVATE_IRQ_NAME, +- xpc_handle_activate_IRQ_uv); +- if (IS_ERR(xpc_activate_mq_uv)) +- return PTR_ERR(xpc_activate_mq_uv); ++ if (xpc_mq_node < 0) ++ for_each_online_node(nid) { ++ ret = xpc_init_mq_node(nid); + +- xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, +- XPC_NOTIFY_IRQ_NAME, +- xpc_handle_notify_IRQ_uv); +- if (IS_ERR(xpc_notify_mq_uv)) { +- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); +- return PTR_ERR(xpc_notify_mq_uv); +- } ++ if (!ret) ++ break; ++ } ++ else ++ ret = xpc_init_mq_node(xpc_mq_node); + +- return 0; ++ if (ret < 0) ++ dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", ++ -ret); ++ ++ return ret; + } + + void +@@ -1765,3 +1808,6 @@ xpc_exit_uv(void) + xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); + } ++ ++module_param(xpc_mq_node, int, 0); ++MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); diff --git a/queue-3.4/drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch b/queue-3.4/drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch new file mode 100644 index 00000000000..9c29ce5506a --- /dev/null +++ b/queue-3.4/drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch @@ -0,0 +1,53 @@ +From 7dbfb315b2aaef0a115765946bf3026d074c33a7 Mon Sep 17 00:00:00 2001 +From: Atsushi Nemoto +Date: Tue, 21 Aug 2012 16:16:10 -0700 +Subject: drivers/rtc/rtc-rs5c348.c: fix hour decoding in 12-hour mode + +From: Atsushi Nemoto + +commit 7dbfb315b2aaef0a115765946bf3026d074c33a7 upstream. + +Correct the offset by subtracting 20 from tm_hour before taking the +modulo 12. + +[ "Why 20?" I hear you ask. Or at least I did. + + Here's the reason why: RS5C348_BIT_PM is 32, and is - stupidly - + included in the RS5C348_HOURS_MASK define. So it's really subtracting + out that bit to get "hour+12". But then because it does things modulo + 12, it needs to add the 12 in again afterwards anyway. + + This code is confused. It would be much clearer if RS5C348_HOURS_MASK + just didn't include the RS5C348_BIT_PM bit at all, then it wouldn't + need to do the silly subtract either. + + Whatever. It's all just math, the end result is the same. - Linus ] + +Reported-by: James Nute +Tested-by: James Nute +Signed-off-by: Atsushi Nemoto +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-rs5c348.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/rtc/rtc-rs5c348.c ++++ b/drivers/rtc/rtc-rs5c348.c +@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev + tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); + tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); + if (!pdata->rtc_24h) { +- tm->tm_hour %= 12; +- if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) ++ if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { ++ tm->tm_hour -= 20; ++ tm->tm_hour %= 12; + tm->tm_hour += 12; ++ } else ++ tm->tm_hour %= 12; + } + tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); + tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); diff --git a/queue-3.4/drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch b/queue-3.4/drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch new file mode 100644 index 00000000000..71f49ea9007 --- /dev/null +++ b/queue-3.4/drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch @@ -0,0 +1,85 @@ +From 5efcc76c13a745f98e7b6604d6aca49761be1970 Mon Sep 17 00:00:00 2001 +From: Jerome Glisse +Date: Fri, 17 Aug 2012 14:40:04 -0400 +Subject: drm/radeon: avoid turning off spread spectrum for used pll + +From: Jerome Glisse + +commit 5efcc76c13a745f98e7b6604d6aca49761be1970 upstream. + +If spread spectrum is enabled and in use for a given pll we +should not turn it off as it will lead to turning off display +for crtc that use the pll (this behavior was observed on chelsea +edp). + +Signed-off-by: Jerome Glisse +Reviewed-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -444,11 +444,28 @@ union atom_enable_ss { + static void atombios_crtc_program_ss(struct radeon_device *rdev, + int enable, + int pll_id, ++ int crtc_id, + struct radeon_atom_ss *ss) + { ++ unsigned i; + int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); + union atom_enable_ss args; + ++ if (!enable) { ++ for (i = 0; i < 6; i++) { ++ if (rdev->mode_info.crtcs[i] && ++ rdev->mode_info.crtcs[i]->enabled && ++ i != crtc_id && ++ pll_id == rdev->mode_info.crtcs[i]->pll_id) { ++ /* one other crtc is using this pll don't turn ++ * off spread spectrum as it might turn off ++ * display on active crtc ++ */ ++ return; ++ } ++ } ++ } ++ + memset(&args, 0, sizeof(args)); + + if (ASIC_IS_DCE5(rdev)) { +@@ -1039,7 +1056,7 @@ static void atombios_crtc_set_pll(struct + radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, + &ref_div, &post_div); + +- atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); ++ atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); + + atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, + encoder_mode, radeon_encoder->encoder_id, mode->clock, +@@ -1062,7 +1079,7 @@ static void atombios_crtc_set_pll(struct + ss.step = step_size; + } + +- atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); ++ atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); + } + } + +@@ -1571,11 +1588,11 @@ void radeon_atom_disp_eng_pll_init(struc + ASIC_INTERNAL_SS_ON_DCPLL, + rdev->clock.default_dispclk); + if (ss_enabled) +- atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); ++ atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss); + /* XXX: DCE5, make sure voltage, dispclk is high enough */ + atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); + if (ss_enabled) +- atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); ++ atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss); + } + + } diff --git a/queue-3.4/drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch b/queue-3.4/drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch new file mode 100644 index 00000000000..187dd9bc583 --- /dev/null +++ b/queue-3.4/drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch @@ -0,0 +1,29 @@ +From 5317670692f61675394db2eb6713484b67383750 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 21 Aug 2012 18:52:56 -0400 +Subject: drm/radeon/ss: use num_crtc rather than hardcoded 6 + +From: Alex Deucher + +commit 5317670692f61675394db2eb6713484b67383750 upstream. + +When checking if a pll is in use. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -452,7 +452,7 @@ static void atombios_crtc_program_ss(str + union atom_enable_ss args; + + if (!enable) { +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < rdev->num_crtc; i++) { + if (rdev->mode_info.crtcs[i] && + rdev->mode_info.crtcs[i]->enabled && + i != crtc_id && diff --git a/queue-3.4/fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch b/queue-3.4/fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch new file mode 100644 index 00000000000..f82e1473304 --- /dev/null +++ b/queue-3.4/fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch @@ -0,0 +1,72 @@ +From d8636a2717bb3da2a7ce2154bf08de90bb8c87b0 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Tue, 21 Aug 2012 16:29:47 +1000 +Subject: fbcon: fix race condition between console lock and cursor timer (v1.1) + +From: Dave Airlie + +commit d8636a2717bb3da2a7ce2154bf08de90bb8c87b0 upstream. + +So we've had a fair few reports of fbcon handover breakage between +efi/vesafb and i915 surface recently, so I dedicated a couple of +days to finding the problem. + +Essentially the last thing we saw was the conflicting framebuffer +message and that was all. + +So after much tracing with direct netconsole writes (printks +under console_lock not so useful), I think I found the race. + +Thread A (driver load) Thread B (timer thread) + unbind_con_driver -> | + bind_con_driver -> | + vc->vc_sw->con_deinit -> | + fbcon_deinit -> | + console_lock() | + | | + | fbcon_flashcursor timer fires + | console_lock() <- blocked for A + | + | +fbcon_del_cursor_timer -> + del_timer_sync + (BOOM) + +Of course because all of this is under the console lock, +we never see anything, also since we also just unbound the active +console guess what we never see anything. + +Hopefully this fixes the problem for anyone seeing vesafb->kms +driver handoff. + +v1.1: add comment suggestion from Alan. + +Signed-off-by: Dave Airlie +Acked-by: Alan Cox +Tested-by: Josh Boyer +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/fbcon.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -372,8 +372,15 @@ static void fb_flashcursor(struct work_s + struct vc_data *vc = NULL; + int c; + int mode; ++ int ret; ++ ++ /* FIXME: we should sort out the unbind locking instead */ ++ /* instead we just fail to flash the cursor if we can't get ++ * the lock instead of blocking fbcon deinit */ ++ ret = console_trylock(); ++ if (ret == 0) ++ return; + +- console_lock(); + if (ops && ops->currcon != -1) + vc = vc_cons[ops->currcon].d; + diff --git a/queue-3.4/mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch b/queue-3.4/mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch new file mode 100644 index 00000000000..32c45c9f6a9 --- /dev/null +++ b/queue-3.4/mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch @@ -0,0 +1,82 @@ +From 0bce9c46bf3b15f485d82d7e81dabed6ebcc24b1 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Fri, 10 Aug 2012 15:22:09 +0100 +Subject: mutex: Place lock in contended state after fastpath_lock failure + +From: Will Deacon + +commit 0bce9c46bf3b15f485d82d7e81dabed6ebcc24b1 upstream. + +ARM recently moved to asm-generic/mutex-xchg.h for its mutex +implementation after the previous implementation was found to be missing +some crucial memory barriers. However, this has revealed some problems +running hackbench on SMP platforms due to the way in which the +MUTEX_SPIN_ON_OWNER code operates. + +The symptoms are that a bunch of hackbench tasks are left waiting on an +unlocked mutex and therefore never get woken up to claim it. This boils +down to the following sequence of events: + + Task A Task B Task C Lock value +0 1 +1 lock() 0 +2 lock() 0 +3 spin(A) 0 +4 unlock() 1 +5 lock() 0 +6 cmpxchg(1,0) 0 +7 contended() -1 +8 lock() 0 +9 spin(C) 0 +10 unlock() 1 +11 cmpxchg(1,0) 0 +12 unlock() 1 + +At this point, the lock is unlocked, but Task B is in an uninterruptible +sleep with nobody to wake it up. + +This patch fixes the problem by ensuring we put the lock into the +contended state if we fail to acquire it on the fastpath, ensuring that +any blocked waiters are woken up when the mutex is released. + +Signed-off-by: Will Deacon +Cc: Arnd Bergmann +Cc: Chris Mason +Cc: Ingo Molnar +Reviewed-by: Nicolas Pitre +Signed-off-by: Peter Zijlstra +Link: http://lkml.kernel.org/n/tip-6e9lrw2avczr0617fzl5vqb8@git.kernel.org +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/mutex-xchg.h | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/include/asm-generic/mutex-xchg.h ++++ b/include/asm-generic/mutex-xchg.h +@@ -26,7 +26,13 @@ static inline void + __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) + { + if (unlikely(atomic_xchg(count, 0) != 1)) +- fail_fn(count); ++ /* ++ * We failed to acquire the lock, so mark it contended ++ * to ensure that any waiting tasks are woken up by the ++ * unlock slow path. ++ */ ++ if (likely(atomic_xchg(count, -1) != 1)) ++ fail_fn(count); + } + + /** +@@ -43,7 +49,8 @@ static inline int + __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) + { + if (unlikely(atomic_xchg(count, 0) != 1)) +- return fail_fn(count); ++ if (likely(atomic_xchg(count, -1) != 1)) ++ return fail_fn(count); + return 0; + } + diff --git a/queue-3.4/pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch b/queue-3.4/pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch new file mode 100644 index 00000000000..d5455d8f46a --- /dev/null +++ b/queue-3.4/pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch @@ -0,0 +1,49 @@ +From 58a34de7b1a920d287d17d2ca08bc9aaf7e6d35b Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 15 Aug 2012 21:31:55 +0200 +Subject: PM / Runtime: Clear power.deferred_resume on success in rpm_suspend() + +From: "Rafael J. Wysocki" + +commit 58a34de7b1a920d287d17d2ca08bc9aaf7e6d35b upstream. + +The power.deferred_resume can only be set if the runtime PM status +of device is RPM_SUSPENDING and it should be cleared after its +status has been changed, regardless of whether or not the runtime +suspend has been successful. However, it only is cleared on +suspend failure, while it may remain set on successful suspend and +is happily leaked to rpm_resume() executed in that case. + +That shouldn't happen, so if power.deferred_resume is set in +rpm_suspend() after the status has been changed to RPM_SUSPENDED, +clear it before calling rpm_resume(). Then, it doesn't need to be +cleared before changing the status to RPM_SUSPENDING any more, +because it's always cleared after the status has been changed to +either RPM_SUSPENDED (on success) or RPM_ACTIVE (on failure). + +Signed-off-by: Rafael J. Wysocki +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/runtime.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -430,7 +430,6 @@ static int rpm_suspend(struct device *de + goto repeat; + } + +- dev->power.deferred_resume = false; + if (dev->power.no_callbacks) + goto no_callback; /* Assume success. */ + +@@ -506,6 +505,7 @@ static int rpm_suspend(struct device *de + wake_up_all(&dev->power.wait_queue); + + if (dev->power.deferred_resume) { ++ dev->power.deferred_resume = false; + rpm_resume(dev, 0); + retval = -EAGAIN; + goto out; diff --git a/queue-3.4/pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch b/queue-3.4/pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch new file mode 100644 index 00000000000..23216ca998c --- /dev/null +++ b/queue-3.4/pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch @@ -0,0 +1,46 @@ +From 7f321c26c04807834fef4c524d2b21573423fc74 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 15 Aug 2012 21:31:45 +0200 +Subject: PM / Runtime: Fix rpm_resume() return value for power.no_callbacks set + +From: "Rafael J. Wysocki" + +commit 7f321c26c04807834fef4c524d2b21573423fc74 upstream. + +For devices whose power.no_callbacks flag is set, rpm_resume() +should return 1 if the device's parent is already active, so that +the callers of pm_runtime_get() don't think that they have to wait +for the device to resume (asynchronously) in that case (the core +won't queue up an asynchronous resume in that case, so there's +nothing to wait for anyway). + +Modify the code accordingly (and make sure that an idle notification +will be queued up on success, even if 1 is to be returned). + +Signed-off-by: Rafael J. Wysocki +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/runtime.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -652,6 +652,7 @@ static int rpm_resume(struct device *dev + || dev->parent->power.runtime_status == RPM_ACTIVE) { + atomic_inc(&dev->parent->power.child_count); + spin_unlock(&dev->parent->power.lock); ++ retval = 1; + goto no_callback; /* Assume success. */ + } + spin_unlock(&dev->parent->power.lock); +@@ -735,7 +736,7 @@ static int rpm_resume(struct device *dev + } + wake_up_all(&dev->power.wait_queue); + +- if (!retval) ++ if (retval >= 0) + rpm_idle(dev, RPM_ASYNC); + + out: diff --git a/queue-3.4/series b/queue-3.4/series index 88b682ff59f..0927ab8bb48 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -136,3 +136,12 @@ xhci-fix-a-logical-vs-bitwise-and-bug.patch xhci-make-handover-code-more-robust.patch xhci-recognize-usb-3.0-devices-as-superspeed-at-powerup.patch usb-host-xhci-fix-compilation-error-for-non-pci-based-stacks.patch +tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch +mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch +drivers-rtc-rtc-rs5c348.c-fix-hour-decoding-in-12-hour-mode.patch +pm-runtime-fix-rpm_resume-return-value-for-power.no_callbacks-set.patch +pm-runtime-clear-power.deferred_resume-on-success-in-rpm_suspend.patch +drivers-misc-sgi-xp-xpc_uv.c-sgi-xpc-fails-to-load-when-cpu-0-is-out-of-irq-resources.patch +fbcon-fix-race-condition-between-console-lock-and-cursor-timer-v1.1.patch +drm-radeon-avoid-turning-off-spread-spectrum-for-used-pll.patch +drm-radeon-ss-use-num_crtc-rather-than-hardcoded-6.patch diff --git a/queue-3.4/tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch b/queue-3.4/tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch new file mode 100644 index 00000000000..c3fc019e816 --- /dev/null +++ b/queue-3.4/tty-serial-imx-console-write-routing-is-unsafe-on-smp.patch @@ -0,0 +1,102 @@ +From 9ec1882df244c4ee1baa692676fef5e8b0f5487d Mon Sep 17 00:00:00 2001 +From: Xinyu Chen +Date: Mon, 27 Aug 2012 09:36:51 +0200 +Subject: tty: serial: imx: console write routing is unsafe on SMP + +From: Xinyu Chen + +commit 9ec1882df244c4ee1baa692676fef5e8b0f5487d upstream. + +The console feature's write routing is unsafe on SMP with +the startup/shutdown call. + +There could be several consumers of the console +* the kernel printk +* the init process using /dev/kmsg to call printk to show log +* shell, which open /dev/console and write with sys_write() + +The shell goes into the normal uart open/write routing, +but the other two go into the console operations. +The open routing calls imx serial startup, which will write USR1/2 +register without any lock and critical with imx_console_write call. + +Add a spin_lock for startup/shutdown/console_write routing. + +This patch is a port from Freescale's Android kernel. + +Signed-off-by: Xinyu Chen +Tested-by: Dirk Behme +CC: Sascha Hauer +Acked-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/imx.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -756,6 +756,7 @@ static int imx_startup(struct uart_port + } + } + ++ spin_lock_irqsave(&sport->port.lock, flags); + /* + * Finally, clear and enable interrupts + */ +@@ -809,7 +810,6 @@ static int imx_startup(struct uart_port + /* + * Enable modem status interrupts + */ +- spin_lock_irqsave(&sport->port.lock,flags); + imx_enable_ms(&sport->port); + spin_unlock_irqrestore(&sport->port.lock,flags); + +@@ -839,10 +839,13 @@ static void imx_shutdown(struct uart_por + { + struct imx_port *sport = (struct imx_port *)port; + unsigned long temp; ++ unsigned long flags; + ++ spin_lock_irqsave(&sport->port.lock, flags); + temp = readl(sport->port.membase + UCR2); + temp &= ~(UCR2_TXEN); + writel(temp, sport->port.membase + UCR2); ++ spin_unlock_irqrestore(&sport->port.lock, flags); + + if (USE_IRDA(sport)) { + struct imxuart_platform_data *pdata; +@@ -871,12 +874,14 @@ static void imx_shutdown(struct uart_por + * Disable all interrupts, port and break condition. + */ + ++ spin_lock_irqsave(&sport->port.lock, flags); + temp = readl(sport->port.membase + UCR1); + temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); + if (USE_IRDA(sport)) + temp &= ~(UCR1_IREN); + + writel(temp, sport->port.membase + UCR1); ++ spin_unlock_irqrestore(&sport->port.lock, flags); + } + + static void +@@ -1219,6 +1224,9 @@ imx_console_write(struct console *co, co + struct imx_port *sport = imx_ports[co->index]; + struct imx_port_ucrs old_ucr; + unsigned int ucr1; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sport->port.lock, flags); + + /* + * First, save UCR1/2/3 and then disable interrupts +@@ -1244,6 +1252,8 @@ imx_console_write(struct console *co, co + while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); + + imx_port_ucrs_restore(&sport->port, &old_ucr); ++ ++ spin_unlock_irqrestore(&sport->port.lock, flags); + } + + /* -- 2.47.3