]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2013 00:16:00 +0000 (16:16 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2013 00:16:00 +0000 (16:16 -0800)
added patches:
alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch
alsa-hda-fix-mute-led-for-another-hp-machine.patch
arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch
arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch
pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch
pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch
pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch
pci-shpchp-handle-push-button-event-asynchronously.patch
pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch

queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch [new file with mode: 0644]
queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch [new file with mode: 0644]
queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch [new file with mode: 0644]
queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch [new file with mode: 0644]
queue-3.7/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch [new file with mode: 0644]
queue-3.7/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch [new file with mode: 0644]
queue-3.7/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch [new file with mode: 0644]
queue-3.7/pci-shpchp-handle-push-button-event-asynchronously.patch [new file with mode: 0644]
queue-3.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch [new file with mode: 0644]
queue-3.7/series

diff --git a/queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch b/queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch
new file mode 100644 (file)
index 0000000..5121e3c
--- /dev/null
@@ -0,0 +1,43 @@
+From 42c364ace52ae6b4699105b39f2559c256b6cd4c Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 21 Jan 2013 16:53:37 +0100
+Subject: ALSA: hda - Add Conexant CX20755/20756/20757 codec IDs
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 42c364ace52ae6b4699105b39f2559c256b6cd4c upstream.
+
+These are just compatible with other CX2075x codecs.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_conexant.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -4580,6 +4580,12 @@ static const struct hda_codec_preset snd
+         .patch = patch_conexant_auto },
+       { .id = 0x14f15111, .name = "CX20753/4",
+         .patch = patch_conexant_auto },
++      { .id = 0x14f15113, .name = "CX20755",
++        .patch = patch_conexant_auto },
++      { .id = 0x14f15114, .name = "CX20756",
++        .patch = patch_conexant_auto },
++      { .id = 0x14f15115, .name = "CX20757",
++        .patch = patch_conexant_auto },
+       {} /* terminator */
+ };
+@@ -4603,6 +4609,9 @@ MODULE_ALIAS("snd-hda-codec-id:14f150b9"
+ MODULE_ALIAS("snd-hda-codec-id:14f1510f");
+ MODULE_ALIAS("snd-hda-codec-id:14f15110");
+ MODULE_ALIAS("snd-hda-codec-id:14f15111");
++MODULE_ALIAS("snd-hda-codec-id:14f15113");
++MODULE_ALIAS("snd-hda-codec-id:14f15114");
++MODULE_ALIAS("snd-hda-codec-id:14f15115");
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch b/queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch
new file mode 100644 (file)
index 0000000..a9711ad
--- /dev/null
@@ -0,0 +1,31 @@
+From e04340375a314166e14519fca9e5b9e9394b2d7a Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson@canonical.com>
+Date: Fri, 18 Jan 2013 12:00:47 +0100
+Subject: ALSA: hda - Fix mute led for another HP machine
+
+From: David Henningsson <david.henningsson@canonical.com>
+
+commit e04340375a314166e14519fca9e5b9e9394b2d7a upstream.
+
+This machine also has the "HP_Mute_LED_0_A" string in DMI information.
+
+BugLink: https://bugs.launchpad.net/bugs/1096789
+Tested-by: Tammy Yang <tammy.yang@canonical.com>
+Signed-off-by: David Henningsson <david.henningsson@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 |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6211,6 +6211,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED),
++      SND_PCI_QUIRK(0x103c, 0x1977, "HP Pavilion 14", ALC269_FIXUP_MIC1_MUTE_LED),
+       SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
diff --git a/queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch b/queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch
new file mode 100644 (file)
index 0000000..7722eb1
--- /dev/null
@@ -0,0 +1,39 @@
+From 9cf2b72b25f3f6a5a1a46a4f36037e66de52465c Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 22 Jan 2013 15:34:40 +0000
+Subject: arm64: elf: fix core dumping to match what glibc expects
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit 9cf2b72b25f3f6a5a1a46a4f36037e66de52465c upstream.
+
+The kernel's internal definition of ELF_NGREG uses struct pt_regs, which
+means that we disagree with userspace on the size of coredumps since
+glibc correctly uses the user-visible struct user_pt_regs.
+
+This patch fixes our ELF_NGREG definition to use struct user_pt_regs
+and introduces our own ELF_CORE_COPY_REGS to convert between the user
+and kernel structure definitions.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/elf.h |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/elf.h
++++ b/arch/arm64/include/asm/elf.h
+@@ -26,7 +26,10 @@
+ typedef unsigned long elf_greg_t;
+-#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
++#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t))
++#define ELF_CORE_COPY_REGS(dest, regs)        \
++      *(struct user_pt_regs *)&(dest) = (regs)->user_regs;
++
+ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+ typedef struct user_fpsimd_state elf_fpregset_t;
diff --git a/queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch b/queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch
new file mode 100644 (file)
index 0000000..730a5c9
--- /dev/null
@@ -0,0 +1,48 @@
+From f1b99392caf120d7533da260318fae0eb5053737 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Fri, 18 Jan 2013 19:00:47 +0000
+Subject: arm64: makefile: fix uname munging when setting ARCH on native machine
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit f1b99392caf120d7533da260318fae0eb5053737 upstream.
+
+By popular demand, arch/aarch64 is now known as arch/arm64. However,
+uname -m (and indeed the GNU triplet) still use aarch64 as the machine
+string.
+
+This patch fixes native builds of both the kernel and perf tools by
+updating the relevant Makefiles to munge the output of uname -m and
+set the ARCH variable appropriately.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Makefile            |    2 +-
+ tools/perf/Makefile |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -169,7 +169,7 @@ SUBARCH := $(shell uname -m | sed -e s/i
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+-                                -e s/sh[234].*/sh/ )
++                                -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+ # Cross compiling and selecting different set of gcc/bin-utils
+ # ---------------------------------------------------------------------------
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -58,7 +58,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+-                                -e s/sh[234].*/sh/ )
++                                -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+ NO_PERF_REGS := 1
+ CC = $(CROSS_COMPILE)gcc
diff --git a/queue-3.7/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch b/queue-3.7/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch
new file mode 100644 (file)
index 0000000..4e7627a
--- /dev/null
@@ -0,0 +1,32 @@
+From a82b6af37d20bfe6e99a4d890f1cf1d89059929f Mon Sep 17 00:00:00 2001
+From: Betty Dall <betty.dall@hp.com>
+Date: Sun, 13 Jan 2013 15:46:18 -0700
+Subject: PCI/AER: pci_get_domain_bus_and_slot() call missing required pci_dev_put()
+
+From: Betty Dall <betty.dall@hp.com>
+
+commit a82b6af37d20bfe6e99a4d890f1cf1d89059929f upstream.
+
+The function aer_recover_queue() calls pci_get_domain_bus_and_slot(), which
+requires that the caller decrement the reference count with pci_dev_put().
+This patch adds the missing call to pci_dev_put().
+
+Signed-off-by: Betty Dall <betty.dall@hp.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Shuah Khan <shuah.khan@hp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pcie/aer/aerdrv_core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pci/pcie/aer/aerdrv_core.c
++++ b/drivers/pci/pcie/aer/aerdrv_core.c
+@@ -616,6 +616,7 @@ static void aer_recover_work_func(struct
+                       continue;
+               }
+               do_recovery(pdev, entry.severity);
++              pci_dev_put(pdev);
+       }
+ }
+ #endif
diff --git a/queue-3.7/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch b/queue-3.7/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch
new file mode 100644 (file)
index 0000000..46cfce8
--- /dev/null
@@ -0,0 +1,38 @@
+From 9e16721498b0c3d3ebfa0b503c63d35c0a4c0642 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 27 Nov 2012 14:09:40 +0000
+Subject: PCI: Allow pcie_aspm=force even when FADT indicates it is unsupported
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 9e16721498b0c3d3ebfa0b503c63d35c0a4c0642 upstream.
+
+Right now using pcie_aspm=force will not enable ASPM if the FADT indicates
+ASPM is unsupported.  However, the semantics of force should probably allow
+for this, especially as they did before 3c076351c4 ("PCI: Rework ASPM
+disable code")
+
+This patch just skips the clearing of any ASPM setup that the firmware has
+carried out on this bus if pcie_aspm=force is being used.
+
+Reference: http://bugs.launchpad.net/bugs/962038
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pcie/aspm.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -773,6 +773,9 @@ void pcie_clear_aspm(struct pci_bus *bus
+ {
+       struct pci_dev *child;
++      if (aspm_force)
++              return;
++
+       /*
+        * Clear any ASPM setup that the firmware has carried out on this bus
+        */
diff --git a/queue-3.7/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch b/queue-3.7/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch
new file mode 100644 (file)
index 0000000..2174285
--- /dev/null
@@ -0,0 +1,189 @@
+From c2be6f93b383c873a4f9d521afa49b1b67d06085 Mon Sep 17 00:00:00 2001
+From: Yijing Wang <wangyijing@huawei.com>
+Date: Fri, 11 Jan 2013 10:15:54 +0800
+Subject: PCI: pciehp: Use per-slot workqueues to avoid deadlock
+
+From: Yijing Wang <wangyijing@huawei.com>
+
+commit c2be6f93b383c873a4f9d521afa49b1b67d06085 upstream.
+
+When we have a hotplug-capable PCIe port with a second hotplug-capable
+PCIe port below it, removing the device below the upstream port causes
+a deadlock.
+
+The deadlock happens because we use the pciehp_wq workqueue to run
+pciehp_power_thread(), which uses pciehp_disable_slot() to remove devices
+below the upstream port.  When we remove the downstream PCIe port, we call
+pciehp_remove(), the pciehp driver's .remove() method.  That calls
+flush_workqueue(pciehp_wq), which deadlocks because the
+pciehp_power_thread() work item is still running.
+
+This patch avoids the deadlock by creating a workqueue for every PCIe port
+and removing the single shared workqueue.
+
+Here's the call path that leads to the deadlock:
+
+  pciehp_queue_pushbutton_work
+    queue_work(pciehp_wq)                   # queue pciehp_power_thread
+    ...
+
+  pciehp_power_thread
+    pciehp_disable_slot
+      remove_board
+       pciehp_unconfigure_device
+         pci_stop_and_remove_bus_device
+           ...
+             pciehp_remove                 # pciehp driver .remove method
+               pciehp_release_ctrl
+                 pcie_cleanup_slot
+                   flush_workqueue(pciehp_wq)
+
+This is fairly urgent because it can be caused by simply unplugging a
+Thunderbolt adapter, as reported by Daniel below.
+
+[bhelgaas: changelog]
+Reference: http://lkml.kernel.org/r/CAMVG2ssiRgcTD1bej2tkUUfsWmpL5eNtPcNif9va2-Gzb2u8nQ@mail.gmail.com
+Reported-and-tested-by: Daniel J Blueman <daniel@quora.org>
+Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Yijing Wang <wangyijing@huawei.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/pciehp.h      |    2 +-
+ drivers/pci/hotplug/pciehp_core.c |   11 ++---------
+ drivers/pci/hotplug/pciehp_ctrl.c |    8 ++++----
+ drivers/pci/hotplug/pciehp_hpc.c  |   11 ++++++++++-
+ 4 files changed, 17 insertions(+), 15 deletions(-)
+
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -44,7 +44,6 @@ extern bool pciehp_poll_mode;
+ extern int pciehp_poll_time;
+ extern bool pciehp_debug;
+ extern bool pciehp_force;
+-extern struct workqueue_struct *pciehp_wq;
+ #define dbg(format, arg...)                                           \
+ do {                                                                  \
+@@ -78,6 +77,7 @@ struct slot {
+       struct hotplug_slot *hotplug_slot;
+       struct delayed_work work;       /* work for button event */
+       struct mutex lock;
++      struct workqueue_struct *wq;
+ };
+ struct event_info {
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -42,7 +42,6 @@ bool pciehp_debug;
+ bool pciehp_poll_mode;
+ int pciehp_poll_time;
+ bool pciehp_force;
+-struct workqueue_struct *pciehp_wq;
+ #define DRIVER_VERSION        "0.4"
+ #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
+@@ -340,18 +339,13 @@ static int __init pcied_init(void)
+ {
+       int retval = 0;
+-      pciehp_wq = alloc_workqueue("pciehp", 0, 0);
+-      if (!pciehp_wq)
+-              return -ENOMEM;
+-
+       pciehp_firmware_init();
+       retval = pcie_port_service_register(&hpdriver_portdrv);
+       dbg("pcie_port_service_register = %d\n", retval);
+       info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+-      if (retval) {
+-              destroy_workqueue(pciehp_wq);
++      if (retval)
+               dbg("Failure to register service\n");
+-      }
++
+       return retval;
+ }
+@@ -359,7 +353,6 @@ static void __exit pcied_cleanup(void)
+ {
+       dbg("unload_pciehpd()\n");
+       pcie_port_service_unregister(&hpdriver_portdrv);
+-      destroy_workqueue(pciehp_wq);
+       info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
+ }
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -49,7 +49,7 @@ static int queue_interrupt_event(struct
+       info->p_slot = p_slot;
+       INIT_WORK(&info->work, interrupt_event_handler);
+-      queue_work(pciehp_wq, &info->work);
++      queue_work(p_slot->wq, &info->work);
+       return 0;
+ }
+@@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct
+               kfree(info);
+               goto out;
+       }
+-      queue_work(pciehp_wq, &info->work);
++      queue_work(p_slot->wq, &info->work);
+  out:
+       mutex_unlock(&p_slot->lock);
+ }
+@@ -377,7 +377,7 @@ static void handle_button_press_event(st
+               if (ATTN_LED(ctrl))
+                       pciehp_set_attention_status(p_slot, 0);
+-              queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ);
++              queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
+               break;
+       case BLINKINGOFF_STATE:
+       case BLINKINGON_STATE:
+@@ -439,7 +439,7 @@ static void handle_surprise_event(struct
+       else
+               p_slot->state = POWERON_STATE;
+-      queue_work(pciehp_wq, &info->work);
++      queue_work(p_slot->wq, &info->work);
+ }
+ static void interrupt_event_handler(struct work_struct *work)
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -773,23 +773,32 @@ static void pcie_shutdown_notification(s
+ static int pcie_init_slot(struct controller *ctrl)
+ {
+       struct slot *slot;
++      char name[32];
+       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+       if (!slot)
+               return -ENOMEM;
++      snprintf(name, sizeof(name), "pciehp-%u", PSN(ctrl));
++      slot->wq = alloc_workqueue(name, 0, 0);
++      if (!slot->wq)
++              goto abort;
++
+       slot->ctrl = ctrl;
+       mutex_init(&slot->lock);
+       INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
+       ctrl->slot = slot;
+       return 0;
++abort:
++      kfree(slot);
++      return -ENOMEM;
+ }
+ static void pcie_cleanup_slot(struct controller *ctrl)
+ {
+       struct slot *slot = ctrl->slot;
+       cancel_delayed_work(&slot->work);
+-      flush_workqueue(pciehp_wq);
++      destroy_workqueue(slot->wq);
+       kfree(slot);
+ }
diff --git a/queue-3.7/pci-shpchp-handle-push-button-event-asynchronously.patch b/queue-3.7/pci-shpchp-handle-push-button-event-asynchronously.patch
new file mode 100644 (file)
index 0000000..f9ff955
--- /dev/null
@@ -0,0 +1,95 @@
+From d347e75847c1fb299c97736638f45e6ea39702d4 Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Fri, 11 Jan 2013 12:07:22 -0700
+Subject: PCI: shpchp: Handle push button event asynchronously
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit d347e75847c1fb299c97736638f45e6ea39702d4 upstream.
+
+Use non-ordered workqueue for attention button events.
+
+Attention button events on each slot can be handled asynchronously. So
+we should use non-ordered workqueue. This patch also removes ordered
+workqueue in shpchp as a result.
+
+486b10b9f4 ("PCI: pciehp: Handle push button event asynchronously") made
+the same change to pciehp.  I split this out from a patch by Yijing Wang
+<wangyijing@huawei.com> so we fix one thing at a time and to make the
+shpchp history correspond more closely with the pciehp history.
+
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/shpchp.h      |    1 -
+ drivers/pci/hotplug/shpchp_core.c |   10 ----------
+ drivers/pci/hotplug/shpchp_ctrl.c |    2 +-
+ 3 files changed, 1 insertion(+), 12 deletions(-)
+
+--- a/drivers/pci/hotplug/shpchp.h
++++ b/drivers/pci/hotplug/shpchp.h
+@@ -47,7 +47,6 @@ extern bool shpchp_poll_mode;
+ extern int shpchp_poll_time;
+ extern bool shpchp_debug;
+ extern struct workqueue_struct *shpchp_wq;
+-extern struct workqueue_struct *shpchp_ordered_wq;
+ #define dbg(format, arg...)                                           \
+ do {                                                                  \
+--- a/drivers/pci/hotplug/shpchp_core.c
++++ b/drivers/pci/hotplug/shpchp_core.c
+@@ -40,7 +40,6 @@ bool shpchp_debug;
+ bool shpchp_poll_mode;
+ int shpchp_poll_time;
+ struct workqueue_struct *shpchp_wq;
+-struct workqueue_struct *shpchp_ordered_wq;
+ #define DRIVER_VERSION        "0.4"
+ #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
+@@ -181,7 +180,6 @@ void cleanup_slots(struct controller *ct
+               list_del(&slot->slot_list);
+               cancel_delayed_work(&slot->work);
+               flush_workqueue(shpchp_wq);
+-              flush_workqueue(shpchp_ordered_wq);
+               pci_hp_deregister(slot->hotplug_slot);
+       }
+ }
+@@ -370,17 +368,10 @@ static int __init shpcd_init(void)
+       if (!shpchp_wq)
+               return -ENOMEM;
+-      shpchp_ordered_wq = alloc_ordered_workqueue("shpchp_ordered", 0);
+-      if (!shpchp_ordered_wq) {
+-              destroy_workqueue(shpchp_wq);
+-              return -ENOMEM;
+-      }
+-
+       retval = pci_register_driver(&shpc_driver);
+       dbg("%s: pci_register_driver = %d\n", __func__, retval);
+       info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+       if (retval) {
+-              destroy_workqueue(shpchp_ordered_wq);
+               destroy_workqueue(shpchp_wq);
+       }
+       return retval;
+@@ -390,7 +381,6 @@ static void __exit shpcd_cleanup(void)
+ {
+       dbg("unload_shpchpd()\n");
+       pci_unregister_driver(&shpc_driver);
+-      destroy_workqueue(shpchp_ordered_wq);
+       destroy_workqueue(shpchp_wq);
+       info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
+ }
+--- a/drivers/pci/hotplug/shpchp_ctrl.c
++++ b/drivers/pci/hotplug/shpchp_ctrl.c
+@@ -453,7 +453,7 @@ void shpchp_queue_pushbutton_work(struct
+               kfree(info);
+               goto out;
+       }
+-      queue_work(shpchp_ordered_wq, &info->work);
++      queue_work(shpchp_wq, &info->work);
+  out:
+       mutex_unlock(&p_slot->lock);
+ }
diff --git a/queue-3.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch b/queue-3.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch
new file mode 100644 (file)
index 0000000..a3b7217
--- /dev/null
@@ -0,0 +1,180 @@
+From f652e7d2916fe2fcf9e7d709aa5b7476b431e2dd Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Fri, 11 Jan 2013 12:21:15 -0700
+Subject: PCI: shpchp: Use per-slot workqueues to avoid deadlock
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit f652e7d2916fe2fcf9e7d709aa5b7476b431e2dd upstream.
+
+When we have an SHPC-capable bridge with a second SHPC-capable bridge
+below it, pushing the upstream bridge's attention button causes a
+deadlock.
+
+The deadlock happens because we use the shpchp_wq workqueue to run
+shpchp_pushbutton_thread(), which uses shpchp_disable_slot() to remove
+devices below the upstream bridge.  When we remove the downstream bridge,
+we call shpc_remove(), the shpchp driver's .remove() method.  That calls
+flush_workqueue(shpchp_wq), which deadlocks because the
+shpchp_pushbutton_thread() work item is still running.
+
+This patch avoids the deadlock by creating a workqueue for every slot
+and removing the single shared workqueue.
+
+Here's the call path that leads to the deadlock:
+
+  shpchp_queue_pushbutton_work
+    queue_work(shpchp_wq)              # shpchp_pushbutton_thread
+    ...
+
+  shpchp_pushbutton_thread
+    shpchp_disable_slot
+      remove_board
+        shpchp_unconfigure_device
+          pci_stop_and_remove_bus_device
+            ...
+              shpc_remove              # shpchp driver .remove method
+                hpc_release_ctlr
+                  cleanup_slots
+                    flush_workqueue(shpchp_wq)
+
+This change is based on code inspection, since we don't have hardware
+with this topology.
+
+Based-on-patch-by: Yijing Wang <wangyijing@huawei.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/shpchp.h      |    2 +-
+ drivers/pci/hotplug/shpchp_core.c |   25 +++++++++++++------------
+ drivers/pci/hotplug/shpchp_ctrl.c |    6 +++---
+ 3 files changed, 17 insertions(+), 16 deletions(-)
+
+--- a/drivers/pci/hotplug/shpchp.h
++++ b/drivers/pci/hotplug/shpchp.h
+@@ -46,7 +46,6 @@
+ extern bool shpchp_poll_mode;
+ extern int shpchp_poll_time;
+ extern bool shpchp_debug;
+-extern struct workqueue_struct *shpchp_wq;
+ #define dbg(format, arg...)                                           \
+ do {                                                                  \
+@@ -90,6 +89,7 @@ struct slot {
+       struct list_head        slot_list;
+       struct delayed_work work;       /* work for button event */
+       struct mutex lock;
++      struct workqueue_struct *wq;
+       u8 hp_slot;
+ };
+--- a/drivers/pci/hotplug/shpchp_core.c
++++ b/drivers/pci/hotplug/shpchp_core.c
+@@ -39,7 +39,6 @@
+ bool shpchp_debug;
+ bool shpchp_poll_mode;
+ int shpchp_poll_time;
+-struct workqueue_struct *shpchp_wq;
+ #define DRIVER_VERSION        "0.4"
+ #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
+@@ -128,6 +127,14 @@ static int init_slots(struct controller
+               slot->device = ctrl->slot_device_offset + i;
+               slot->hpc_ops = ctrl->hpc_ops;
+               slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
++
++              snprintf(name, sizeof(name), "shpchp-%d", slot->number);
++              slot->wq = alloc_workqueue(name, 0, 0);
++              if (!slot->wq) {
++                      retval = -ENOMEM;
++                      goto error_info;
++              }
++
+               mutex_init(&slot->lock);
+               INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work);
+@@ -147,7 +154,7 @@ static int init_slots(struct controller
+               if (retval) {
+                       ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
+                                retval);
+-                      goto error_info;
++                      goto error_slotwq;
+               }
+               get_power_status(hotplug_slot, &info->power_status);
+@@ -159,6 +166,8 @@ static int init_slots(struct controller
+       }
+       return 0;
++error_slotwq:
++      destroy_workqueue(slot->wq);
+ error_info:
+       kfree(info);
+ error_hpslot:
+@@ -179,7 +188,7 @@ void cleanup_slots(struct controller *ct
+               slot = list_entry(tmp, struct slot, slot_list);
+               list_del(&slot->slot_list);
+               cancel_delayed_work(&slot->work);
+-              flush_workqueue(shpchp_wq);
++              destroy_workqueue(slot->wq);
+               pci_hp_deregister(slot->hotplug_slot);
+       }
+ }
+@@ -362,18 +371,11 @@ static struct pci_driver shpc_driver = {
+ static int __init shpcd_init(void)
+ {
+-      int retval = 0;
+-
+-      shpchp_wq = alloc_ordered_workqueue("shpchp", 0);
+-      if (!shpchp_wq)
+-              return -ENOMEM;
++      int retval;
+       retval = pci_register_driver(&shpc_driver);
+       dbg("%s: pci_register_driver = %d\n", __func__, retval);
+       info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+-      if (retval) {
+-              destroy_workqueue(shpchp_wq);
+-      }
+       return retval;
+ }
+@@ -381,7 +383,6 @@ static void __exit shpcd_cleanup(void)
+ {
+       dbg("unload_shpchpd()\n");
+       pci_unregister_driver(&shpc_driver);
+-      destroy_workqueue(shpchp_wq);
+       info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
+ }
+--- a/drivers/pci/hotplug/shpchp_ctrl.c
++++ b/drivers/pci/hotplug/shpchp_ctrl.c
+@@ -51,7 +51,7 @@ static int queue_interrupt_event(struct
+       info->p_slot = p_slot;
+       INIT_WORK(&info->work, interrupt_event_handler);
+-      queue_work(shpchp_wq, &info->work);
++      queue_work(p_slot->wq, &info->work);
+       return 0;
+ }
+@@ -453,7 +453,7 @@ void shpchp_queue_pushbutton_work(struct
+               kfree(info);
+               goto out;
+       }
+-      queue_work(shpchp_wq, &info->work);
++      queue_work(p_slot->wq, &info->work);
+  out:
+       mutex_unlock(&p_slot->lock);
+ }
+@@ -501,7 +501,7 @@ static void handle_button_press_event(st
+               p_slot->hpc_ops->green_led_blink(p_slot);
+               p_slot->hpc_ops->set_attention_status(p_slot, 0);
+-              queue_delayed_work(shpchp_wq, &p_slot->work, 5*HZ);
++              queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
+               break;
+       case BLINKINGOFF_STATE:
+       case BLINKINGON_STATE:
index fe1bed43869f932e33056efea88017c8fe051d61..12bccb51fbbaa241621108985b7c06acfa7be48b 100644 (file)
@@ -13,3 +13,12 @@ perf-x86-revert-20b279-require-exclude_guest-to-use-pebs-kernel-side.patch
 ptrace-introduce-signal_wake_up_state-and-ptrace_signal_wake_up.patch
 ptrace-ensure-arch_ptrace-ptrace_request-can-never-race-with-sigkill.patch
 wake_up_process-should-be-never-used-to-wakeup-a-task_stopped-traced-task.patch
+alsa-hda-fix-mute-led-for-another-hp-machine.patch
+alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch
+arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch
+arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch
+pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch
+pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch
+pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch
+pci-shpchp-handle-push-button-event-asynchronously.patch
+pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch