--- /dev/null
+From 7838f994b4fceff24c343f4e26a6cf4393869579 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+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 <holt@sgi.com>
+
+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 <holt@sgi.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
+ #include <linux/err.h>
+ #include <linux/slab.h>
+ #include <asm/uv/uv_hub.h>
+@@ -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.");
--- /dev/null
+From 7dbfb315b2aaef0a115765946bf3026d074c33a7 Mon Sep 17 00:00:00 2001
+From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+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 <anemo@mba.ocn.ne.jp>
+
+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 <newten82@gmail.com>
+Tested-by: James Nute <newten82@gmail.com>
+Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 5efcc76c13a745f98e7b6604d6aca49761be1970 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse@redhat.com>
+Date: Fri, 17 Aug 2012 14:40:04 -0400
+Subject: drm/radeon: avoid turning off spread spectrum for used pll
+
+From: Jerome Glisse <jglisse@redhat.com>
+
+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 <jglisse@redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)) {
+@@ -1036,7 +1053,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,
+@@ -1059,7 +1076,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);
+ }
+ }
+
+@@ -1576,11 +1593,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);
+ }
+
+ }
--- /dev/null
+From e43b5ec05afdc232be25aa481315035c1888d389 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse@redhat.com>
+Date: Mon, 6 Aug 2012 12:32:21 -0400
+Subject: drm/radeon: fence virtual address and free it once idle v4
+
+From: Jerome Glisse <jglisse@redhat.com>
+
+commit e43b5ec05afdc232be25aa481315035c1888d389 upstream.
+
+Virtual address need to be fenced to know when we can safely remove it.
+This patch also properly clear the pagetable. Previously it was
+serouisly broken.
+
+Kernel 3.5/3.4 need a similar patch but adapted for difference in mutex locking.
+
+v2: For to update pagetable when unbinding bo (don't bailout if
+ bo_va->valid is true).
+v3: Add kernel 3.5/3.4 comment.
+v4: Fix compilation warnings.
+
+Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon.h | 1 +
+ drivers/gpu/drm/radeon/radeon_cs.c | 30 +++++++++++++++++++++++++++---
+ drivers/gpu/drm/radeon/radeon_gart.c | 24 ++++++++++++++++++++++--
+ drivers/gpu/drm/radeon/radeon_gem.c | 13 ++-----------
+ drivers/gpu/drm/radeon/radeon_object.c | 6 +-----
+ 5 files changed, 53 insertions(+), 21 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -323,6 +323,7 @@ struct radeon_bo_va {
+ uint64_t soffset;
+ uint64_t eoffset;
+ uint32_t flags;
++ struct radeon_fence *fence;
+ bool valid;
+ };
+
+--- a/drivers/gpu/drm/radeon/radeon_cs.c
++++ b/drivers/gpu/drm/radeon/radeon_cs.c
+@@ -294,6 +294,28 @@ int radeon_cs_parser_init(struct radeon_
+ return 0;
+ }
+
++static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser,
++ struct radeon_fence *fence)
++{
++ struct radeon_fpriv *fpriv = parser->filp->driver_priv;
++ struct radeon_vm *vm = &fpriv->vm;
++ struct radeon_bo_list *lobj;
++
++ if (parser->chunk_ib_idx == -1)
++ return;
++ if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
++ return;
++
++ list_for_each_entry(lobj, &parser->validated, tv.head) {
++ struct radeon_bo_va *bo_va;
++ struct radeon_bo *rbo = lobj->bo;
++
++ bo_va = radeon_bo_va(rbo, vm);
++ radeon_fence_unref(&bo_va->fence);
++ bo_va->fence = radeon_fence_ref(fence);
++ }
++}
++
+ /**
+ * cs_parser_fini() - clean parser states
+ * @parser: parser structure holding parsing context.
+@@ -306,11 +328,14 @@ static void radeon_cs_parser_fini(struct
+ {
+ unsigned i;
+
+- if (!error)
++ if (!error) {
++ /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */
++ radeon_bo_vm_fence_va(parser, parser->ib.fence);
+ ttm_eu_fence_buffer_objects(&parser->validated,
+ parser->ib.fence);
+- else
++ } else {
+ ttm_eu_backoff_reservation(&parser->validated);
++ }
+
+ if (parser->relocs != NULL) {
+ for (i = 0; i < parser->nrelocs; i++) {
+@@ -407,7 +432,6 @@ static int radeon_cs_ib_vm_chunk(struct
+
+ if (parser->chunk_ib_idx == -1)
+ return 0;
+-
+ if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
+ return 0;
+
+--- a/drivers/gpu/drm/radeon/radeon_gart.c
++++ b/drivers/gpu/drm/radeon/radeon_gart.c
+@@ -564,7 +564,7 @@ int radeon_vm_bo_update_pte(struct radeo
+ return -EINVAL;
+ }
+
+- if (bo_va->valid)
++ if (bo_va->valid && mem)
+ return 0;
+
+ ngpu_pages = radeon_bo_ngpu_pages(bo);
+@@ -597,11 +597,27 @@ int radeon_vm_bo_rmv(struct radeon_devic
+ struct radeon_bo *bo)
+ {
+ struct radeon_bo_va *bo_va;
++ int r;
+
+ bo_va = radeon_bo_va(bo, vm);
+ if (bo_va == NULL)
+ return 0;
+
++ /* wait for va use to end */
++ while (bo_va->fence) {
++ r = radeon_fence_wait(bo_va->fence, false);
++ if (r) {
++ DRM_ERROR("error while waiting for fence: %d\n", r);
++ }
++ if (r == -EDEADLK) {
++ r = radeon_gpu_reset(rdev);
++ if (!r)
++ continue;
++ }
++ break;
++ }
++ radeon_fence_unref(&bo_va->fence);
++
+ radeon_mutex_lock(&rdev->cs_mutex);
+ mutex_lock(&vm->mutex);
+ radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
+@@ -661,12 +677,15 @@ void radeon_vm_fini(struct radeon_device
+ radeon_vm_unbind_locked(rdev, vm);
+ radeon_mutex_unlock(&rdev->cs_mutex);
+
+- /* remove all bo */
++ /* remove all bo at this point non are busy any more because unbind
++ * waited for the last vm fence to signal
++ */
+ r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
+ if (!r) {
+ bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm);
+ list_del_init(&bo_va->bo_list);
+ list_del_init(&bo_va->vm_list);
++ radeon_fence_unref(&bo_va->fence);
+ radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
+ kfree(bo_va);
+ }
+@@ -678,6 +697,7 @@ void radeon_vm_fini(struct radeon_device
+ r = radeon_bo_reserve(bo_va->bo, false);
+ if (!r) {
+ list_del_init(&bo_va->bo_list);
++ radeon_fence_unref(&bo_va->fence);
+ radeon_bo_unreserve(bo_va->bo);
+ kfree(bo_va);
+ }
+--- a/drivers/gpu/drm/radeon/radeon_gem.c
++++ b/drivers/gpu/drm/radeon/radeon_gem.c
+@@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_
+ struct radeon_device *rdev = rbo->rdev;
+ struct radeon_fpriv *fpriv = file_priv->driver_priv;
+ struct radeon_vm *vm = &fpriv->vm;
+- struct radeon_bo_va *bo_va, *tmp;
+
+ if (rdev->family < CHIP_CAYMAN) {
+ return;
+ }
+
+ if (radeon_bo_reserve(rbo, false)) {
++ dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n");
+ return;
+ }
+- list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) {
+- if (bo_va->vm == vm) {
+- /* remove from this vm address space */
+- mutex_lock(&vm->mutex);
+- list_del(&bo_va->vm_list);
+- mutex_unlock(&vm->mutex);
+- list_del(&bo_va->bo_list);
+- kfree(bo_va);
+- }
+- }
++ radeon_vm_bo_rmv(rdev, vm, rbo);
+ radeon_bo_unreserve(rbo);
+ }
+
+--- a/drivers/gpu/drm/radeon/radeon_object.c
++++ b/drivers/gpu/drm/radeon/radeon_object.c
+@@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo
+
+ list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) {
+ /* remove from all vm address space */
+- mutex_lock(&bo_va->vm->mutex);
+- list_del(&bo_va->vm_list);
+- mutex_unlock(&bo_va->vm->mutex);
+- list_del(&bo_va->bo_list);
+- kfree(bo_va);
++ radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo);
+ }
+ }
+
--- /dev/null
+From 5317670692f61675394db2eb6713484b67383750 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 21 Aug 2012 18:52:56 -0400
+Subject: drm/radeon/ss: use num_crtc rather than hardcoded 6
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 5317670692f61675394db2eb6713484b67383750 upstream.
+
+When checking if a pll is in use.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 &&
--- /dev/null
+From d8636a2717bb3da2a7ce2154bf08de90bb8c87b0 Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+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 <airlied@redhat.com>
+
+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 <airlied@redhat.com>
+Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Tested-by: Josh Boyer <jwboyer@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+
--- /dev/null
+From 0bce9c46bf3b15f485d82d7e81dabed6ebcc24b1 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Fri, 10 Aug 2012 15:22:09 +0100
+Subject: mutex: Place lock in contended state after fastpath_lock failure
+
+From: Will Deacon <will.deacon@arm.com>
+
+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 <will.deacon@arm.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Chris Mason <chris.mason@fusionio.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Reviewed-by: Nicolas Pitre <nico@linaro.org>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Link: http://lkml.kernel.org/n/tip-6e9lrw2avczr0617fzl5vqb8@git.kernel.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 55d7ec4520e86d735d178c15d7df33d507bd43c6 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rjw@sisk.pl>
+Date: Wed, 15 Aug 2012 21:32:04 +0200
+Subject: PM / Runtime: Check device PM QoS setting before "no callbacks" check
+
+From: "Rafael J. Wysocki" <rjw@sisk.pl>
+
+commit 55d7ec4520e86d735d178c15d7df33d507bd43c6 upstream.
+
+If __dev_pm_qos_read_value(dev) returns a negative value,
+rpm_suspend() should return -EPERM for dev even if its
+power.no_callbacks flag is set. For this to happen, the device's
+power.no_callbacks flag has to be checked after the PM QoS check,
+so move the PM QoS check to rpm_check_suspend_allowed() (this will
+make it cover idle notifications as well as runtime suspend too).
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/runtime.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(str
+ || (dev->power.request_pending
+ && dev->power.request == RPM_REQ_RESUME))
+ retval = -EAGAIN;
++ else if (__dev_pm_qos_read_value(dev) < 0)
++ retval = -EPERM;
+ else if (dev->power.runtime_status == RPM_SUSPENDED)
+ retval = 1;
+
+@@ -402,12 +404,6 @@ static int rpm_suspend(struct device *de
+ goto out;
+ }
+
+- if (__dev_pm_qos_read_value(dev) < 0) {
+- /* Negative PM QoS constraint means "never suspend". */
+- retval = -EPERM;
+- goto out;
+- }
+-
+ __update_runtime_status(dev, RPM_SUSPENDING);
+
+ if (dev->pm_domain)
--- /dev/null
+From 58a34de7b1a920d287d17d2ca08bc9aaf7e6d35b Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rjw@sisk.pl>
+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" <rjw@sisk.pl>
+
+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 <rjw@sisk.pl>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -388,7 +388,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. */
+
+@@ -440,6 +439,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;
--- /dev/null
+From 7f321c26c04807834fef4c524d2b21573423fc74 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rjw@sisk.pl>
+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" <rjw@sisk.pl>
+
+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 <rjw@sisk.pl>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -584,6 +584,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);
+@@ -664,7 +665,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:
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
+tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch
+mutex-place-lock-in-contended-state-after-fastpath_lock-failure.patch
+x86-avx-don-t-use-avx-instructions-with-noxsave-boot-param.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
+pm-runtime-check-device-pm-qos-setting-before-no-callbacks-check.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
+drm-radeon-fence-virtual-address-and-free-it-once-idle-v4.patch
--- /dev/null
+From 9ec1882df244c4ee1baa692676fef5e8b0f5487d Mon Sep 17 00:00:00 2001
+From: Xinyu Chen <xinyu.chen@freescale.com>
+Date: Mon, 27 Aug 2012 09:36:51 +0200
+Subject: tty: serial: imx: console write routing is unsafe on SMP
+
+From: Xinyu Chen <xinyu.chen@freescale.com>
+
+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 <xinyu.chen@freescale.com>
+Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
+CC: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -758,6 +758,7 @@ static int imx_startup(struct uart_port
+ }
+ }
+
++ spin_lock_irqsave(&sport->port.lock, flags);
+ /*
+ * Finally, clear and enable interrupts
+ */
+@@ -811,7 +812,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);
+
+@@ -841,10 +841,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;
+@@ -873,12 +876,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
+@@ -1221,6 +1226,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
+@@ -1246,6 +1254,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);
+ }
+
+ /*
--- /dev/null
+From 7be0670f7b9198382938a03ff3db7f47ef6b4780 Mon Sep 17 00:00:00 2001
+From: Dirk Behme <dirk.behme@de.bosch.com>
+Date: Fri, 31 Aug 2012 10:02:47 +0200
+Subject: tty: serial: imx: don't reinit clock in imx_setup_ufcr()
+
+From: Dirk Behme <dirk.behme@de.bosch.com>
+
+commit 7be0670f7b9198382938a03ff3db7f47ef6b4780 upstream.
+
+Remove the clock configuration from imx_setup_ufcr(). This
+isn't needed here and will cause garbage output if done.
+
+To be be sure that we only touch the bits we want (TXTL and RXTL)
+we have to mask out all other bits of the UFCR register. Add
+one non-existing bit macro for this, too (bit 6, DCEDTE on i.MX6).
+
+Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
+CC: Shawn Guo <shawn.guo@linaro.org>
+CC: Sascha Hauer <s.hauer@pengutronix.de>
+CC: Troy Kisky <troy.kisky@boundarydevices.com>
+CC: Xinyu Chen <xinyu.chen@freescale.com>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/imx.c | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -132,6 +132,7 @@
+ #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
+ #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
+ #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
++#define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */
+ #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
+ #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7)
+ #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
+@@ -668,22 +669,11 @@ static void imx_break_ctl(struct uart_po
+ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
+ {
+ unsigned int val;
+- unsigned int ufcr_rfdiv;
+-
+- /* set receiver / transmitter trigger level.
+- * RFDIV is set such way to satisfy requested uartclk value
+- */
+- val = TXTL << 10 | RXTL;
+- ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2)
+- / sport->port.uartclk;
+-
+- if(!ufcr_rfdiv)
+- ufcr_rfdiv = 1;
+-
+- val |= UFCR_RFDIV_REG(ufcr_rfdiv);
+
++ /* set receiver / transmitter trigger level */
++ val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE);
++ val |= TXTL << UFCR_TXTL_SHF | RXTL;
+ writel(val, sport->port.membase + UFCR);
+-
+ return 0;
+ }
+
--- /dev/null
+From c6fd893da927c6cefb2ece22402765379921a834 Mon Sep 17 00:00:00 2001
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+Date: Tue, 31 Jul 2012 10:29:14 -0700
+Subject: x86, avx: don't use avx instructions with "noxsave" boot param
+
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+
+commit c6fd893da927c6cefb2ece22402765379921a834 upstream.
+
+Clear AVX, AVX2 features along with clearing XSAVE feature bits,
+as part of the parsing "noxsave" parameter.
+
+Fixes the kernel boot panic with "noxsave" boot parameter.
+
+We could have checked cpu_has_osxsave along with cpu_has_avx etc, but Peter
+mentioned clearing the feature bits will be better for uses like
+static_cpu_has() etc.
+
+Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Link: http://lkml.kernel.org/r/1343755754.2041.2.camel@sbsiddha-desk.sc.intel.com
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -144,6 +144,8 @@ static int __init x86_xsave_setup(char *
+ {
+ setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
++ setup_clear_cpu_cap(X86_FEATURE_AVX);
++ setup_clear_cpu_cap(X86_FEATURE_AVX2);
+ return 1;
+ }
+ __setup("noxsave", x86_xsave_setup);