From 7ecdda082ad004f523b176cfd364a45176ed9c08 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Nov 2014 09:21:10 +0900 Subject: [PATCH] 3.17-stable patches added patches: alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch i2c-at91-don-t-account-as-iowait.patch irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch irqchip-armada-370-xp-fix-msi-interrupt-handling.patch powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch powerpc-use-device_online-offline-instead-of-cpu_up-down.patch regulator-max77693-fix-use-of-uninitialized-regulator-config.patch sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch --- ...ute-led-problem-for-three-hp-laptops.patch | 42 +++++++ .../i2c-at91-don-t-account-as-iowait.patch | 32 +++++ ...a-370-xp-fix-mpic-interrupt-handling.patch | 84 +++++++++++++ ...da-370-xp-fix-msi-interrupt-handling.patch | 44 +++++++ ...-with-bad-thread_info-flags-argument.patch | 53 +++++++++ ...-properly-fix-lpc-debugfs-endianness.patch | 112 ++++++++++++++++++ ...nline-offline-instead-of-cpu_up-down.patch | 54 +++++++++ ...se-of-uninitialized-regulator-config.patch | 37 ++++++ queue-3.17/series | 9 ++ ...glue-dir-race-condition-by-gdp_mutex.patch | 103 ++++++++++++++++ 10 files changed, 570 insertions(+) create mode 100644 queue-3.17/alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch create mode 100644 queue-3.17/i2c-at91-don-t-account-as-iowait.patch create mode 100644 queue-3.17/irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch create mode 100644 queue-3.17/irqchip-armada-370-xp-fix-msi-interrupt-handling.patch create mode 100644 queue-3.17/powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch create mode 100644 queue-3.17/powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch create mode 100644 queue-3.17/powerpc-use-device_online-offline-instead-of-cpu_up-down.patch create mode 100644 queue-3.17/regulator-max77693-fix-use-of-uninitialized-regulator-config.patch create mode 100644 queue-3.17/sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch diff --git a/queue-3.17/alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch b/queue-3.17/alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch new file mode 100644 index 00000000000..7b244aca79e --- /dev/null +++ b/queue-3.17/alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch @@ -0,0 +1,42 @@ +From c922c4e87b9b5a3b50d4d17b96f189121430f511 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 5 Nov 2014 12:17:58 +0800 +Subject: ALSA: hda - fix mute led problem for three HP laptops + +From: Hui Wang + +commit c922c4e87b9b5a3b50d4d17b96f189121430f511 upstream. + +Without the fix, the mute led can't work on these three machines. + +After apply this fix, these three machines will fall back on the led +control quirk as below, and through testing, the mute led works very +well. +PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED, + ALC282_STANDARD_PINS, + {0x12, 0x90a60140}, + ... + +BugLink: https://bugs.launchpad.net/bugs/1389497 +Tested-by: TieFu Chen +Cc: Kailang Yang +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5008,9 +5008,6 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x2224, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), +- SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), +- SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), +- SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), diff --git a/queue-3.17/i2c-at91-don-t-account-as-iowait.patch b/queue-3.17/i2c-at91-don-t-account-as-iowait.patch new file mode 100644 index 00000000000..453c7e1df48 --- /dev/null +++ b/queue-3.17/i2c-at91-don-t-account-as-iowait.patch @@ -0,0 +1,32 @@ +From 11cfbfb098b22d3e57f1f2be217cad20e2d48463 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Mon, 3 Nov 2014 21:16:16 +0100 +Subject: i2c: at91: don't account as iowait + +From: Wolfram Sang + +commit 11cfbfb098b22d3e57f1f2be217cad20e2d48463 upstream. + +iowait is for blkio [1]. I2C shouldn't use it. + +[1] https://lkml.org/lkml/2014/11/3/317 + +Signed-off-by: Wolfram Sang +Acked-by: Ludovic Desroches +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-at91.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -434,7 +434,7 @@ static int at91_do_twi_transfer(struct a + } + } + +- ret = wait_for_completion_io_timeout(&dev->cmd_complete, ++ ret = wait_for_completion_timeout(&dev->cmd_complete, + dev->adapter.timeout); + if (ret == 0) { + dev_err(dev->dev, "controller timed out\n"); diff --git a/queue-3.17/irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch b/queue-3.17/irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch new file mode 100644 index 00000000000..064300089ab --- /dev/null +++ b/queue-3.17/irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch @@ -0,0 +1,84 @@ +From 758e8366754d3fa57da978fef9d2c652f7b55c02 Mon Sep 17 00:00:00 2001 +From: Grzegorz Jaszczyk +Date: Thu, 25 Sep 2014 13:17:19 +0200 +Subject: irqchip: armada-370-xp: Fix MPIC interrupt handling + +From: Grzegorz Jaszczyk + +commit 758e8366754d3fa57da978fef9d2c652f7b55c02 upstream. + +In both Armada-375 and Armada-38x MPIC interrupts should be identified by +reading cause register multiplied by the interrupt mask. + +A lack of above mentioned multiplication resulted in a bug, caused by the +fact that in Armada-375 and Armada-38x some of the interrupts +(e.g. network interrupts) can be handled either as a GIC or MPIC interrupts. +Therefore during MPIC interrupts handling, cause register shows hits from +interrupts even if they are masked for MPIC but unmasked for a GIC. + +This resulted in 'bad IRQ' error, because masked MPIC interrupt without +registered interrupt handler, was trying to be handled during interrupt +handling procedure of some other unmasked MPIC interrupt (e.g. local timer +irq). + +This commit fixes that by ensuring that during MPIC interrupt handling only +interrupts that are unmasked for MPIC are processed. + +Signed-off-by: Grzegorz Jaszczyk +Reviewed-by: Gregory CLEMENT +Fixes: bc69b8adfe22 ("irqchip: armada-370-xp: Setup a chained handler for the MPIC") +Acked-by: Ezequiel Garcia +Link: https://lkml.kernel.org/r/1411643839-64925-3-git-send-email-jaz@semihalf.com +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-armada-370-xp.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/irqchip/irq-armada-370-xp.c ++++ b/drivers/irqchip/irq-armada-370-xp.c +@@ -43,6 +43,7 @@ + #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) + #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) + #define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF ++#define ARMADA_370_XP_INT_IRQ_FIQ_MASK(cpuid) ((BIT(0) | BIT(8)) << cpuid) + + #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) + #define ARMADA_375_PPI_CAUSE (0x10) +@@ -410,19 +411,29 @@ static void armada_370_xp_mpic_handle_ca + struct irq_desc *desc) + { + struct irq_chip *chip = irq_get_chip(irq); +- unsigned long irqmap, irqn; ++ unsigned long irqmap, irqn, irqsrc, cpuid; + unsigned int cascade_irq; + + chained_irq_enter(chip, desc); + + irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); +- +- if (irqmap & BIT(1)) { +- armada_370_xp_handle_msi_irq(NULL, true); +- irqmap &= ~BIT(1); +- } ++ cpuid = cpu_logical_map(smp_processor_id()); + + for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { ++ irqsrc = readl_relaxed(main_int_base + ++ ARMADA_370_XP_INT_SOURCE_CTL(irqn)); ++ ++ /* Check if the interrupt is not masked on current CPU. ++ * Test IRQ (0-1) and FIQ (8-9) mask bits. ++ */ ++ if (!(irqsrc & ARMADA_370_XP_INT_IRQ_FIQ_MASK(cpuid))) ++ continue; ++ ++ if (irqn == 1) { ++ armada_370_xp_handle_msi_irq(NULL, true); ++ continue; ++ } ++ + cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); + generic_handle_irq(cascade_irq); + } diff --git a/queue-3.17/irqchip-armada-370-xp-fix-msi-interrupt-handling.patch b/queue-3.17/irqchip-armada-370-xp-fix-msi-interrupt-handling.patch new file mode 100644 index 00000000000..64deb408a27 --- /dev/null +++ b/queue-3.17/irqchip-armada-370-xp-fix-msi-interrupt-handling.patch @@ -0,0 +1,44 @@ +From 298dcb2dd0267d51e4f7c94a628cd0765a50ad75 Mon Sep 17 00:00:00 2001 +From: Grzegorz Jaszczyk +Date: Thu, 25 Sep 2014 13:17:18 +0200 +Subject: irqchip: armada-370-xp: Fix MSI interrupt handling + +From: Grzegorz Jaszczyk + +commit 298dcb2dd0267d51e4f7c94a628cd0765a50ad75 upstream. + +The MSI interrupts use the 16 high doorbells, which are notified by using IRQ1 +of the main interrupt controller. + +The MSI interrupts were handled correctly for Armada-XP and Armada-370 but not +for Armada-375 and Armada-38x, which use chained handler for the MPIC. + +This commit fixes that by checking proper interrupt number in chained handler +for the MPIC. + +Signed-off-by: Grzegorz Jaszczyk +Reviewed-by: Gregory CLEMENT +Fixes: bc69b8adfe22 ("irqchip: armada-370-xp: Setup a chained handler for the MPIC") +Acked-by: Ezequiel Garcia +Link: https://lkml.kernel.org/r/1411643839-64925-2-git-send-email-jaz@semihalf.com +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-armada-370-xp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/irqchip/irq-armada-370-xp.c ++++ b/drivers/irqchip/irq-armada-370-xp.c +@@ -417,9 +417,9 @@ static void armada_370_xp_mpic_handle_ca + + irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); + +- if (irqmap & BIT(0)) { ++ if (irqmap & BIT(1)) { + armada_370_xp_handle_msi_irq(NULL, true); +- irqmap &= ~BIT(0); ++ irqmap &= ~BIT(1); + } + + for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { diff --git a/queue-3.17/powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch b/queue-3.17/powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch new file mode 100644 index 00000000000..93b6431c390 --- /dev/null +++ b/queue-3.17/powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch @@ -0,0 +1,53 @@ +From 808be31426af57af22268ef0fcb42617beb3d15b Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Fri, 31 Oct 2014 16:50:57 +1100 +Subject: powerpc: do_notify_resume can be called with bad thread_info flags argument + +From: Anton Blanchard + +commit 808be31426af57af22268ef0fcb42617beb3d15b upstream. + +Back in 7230c5644188 ("powerpc: Rework lazy-interrupt handling") we +added a call out to restore_interrupts() (written in c) before calling +do_notify_resume: + + bl restore_interrupts + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_notify_resume + +Unfortunately do_notify_resume takes two arguments, the second one +being the thread_info flags: + +void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) + +We do populate r4 (the second argument) earlier, but +restore_interrupts() is free to muck it up all it wants. My guess is +the gcc compiler gods shone down on us and its register allocator +never used r4. Sometimes, rarely, luck is on our side. + +LLVM on the other hand did trample r4. + +Signed-off-by: Anton Blanchard +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/entry_64.S | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -659,7 +659,13 @@ _GLOBAL(ret_from_except_lite) + 3: + #endif + bl save_nvgprs ++ /* ++ * Use a non volatile GPR to save and restore our thread_info flags ++ * across the call to restore_interrupts. ++ */ ++ mr r30,r4 + bl restore_interrupts ++ mr r4,r30 + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_notify_resume + b ret_from_except diff --git a/queue-3.17/powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch b/queue-3.17/powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch new file mode 100644 index 00000000000..7c87b86ee96 --- /dev/null +++ b/queue-3.17/powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch @@ -0,0 +1,112 @@ +From 325e4114043469e5f9923d902b4d30bcc2be8163 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Thu, 30 Oct 2014 16:19:13 +1100 +Subject: powerpc/powernv: Properly fix LPC debugfs endianness + +From: Benjamin Herrenschmidt + +commit 325e4114043469e5f9923d902b4d30bcc2be8163 upstream. + +Endian is hard, especially when I designed a stupid FW interface, and +I should know better... oh well, this is attempt #2 at fixing this +properly. This time it seems to work with all access sizes and I +can run my flashing tool (which exercises all sort of access sizes +and types to access the SPI controller in the BMC) just fine. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/powernv/opal-lpc.c | 59 ++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +--- a/arch/powerpc/platforms/powernv/opal-lpc.c ++++ b/arch/powerpc/platforms/powernv/opal-lpc.c +@@ -216,14 +216,54 @@ static ssize_t lpc_debug_read(struct fil + &data, len); + if (rc) + return -ENXIO; ++ ++ /* ++ * Now there is some trickery with the data returned by OPAL ++ * as it's the desired data right justified in a 32-bit BE ++ * word. ++ * ++ * This is a very bad interface and I'm to blame for it :-( ++ * ++ * So we can't just apply a 32-bit swap to what comes from OPAL, ++ * because user space expects the *bytes* to be in their proper ++ * respective positions (ie, LPC position). ++ * ++ * So what we really want to do here is to shift data right ++ * appropriately on a LE kernel. ++ * ++ * IE. If the LPC transaction has bytes B0, B1, B2 and B3 in that ++ * order, we have in memory written to by OPAL at the "data" ++ * pointer: ++ * ++ * Bytes: OPAL "data" LE "data" ++ * 32-bit: B0 B1 B2 B3 B0B1B2B3 B3B2B1B0 ++ * 16-bit: B0 B1 0000B0B1 B1B00000 ++ * 8-bit: B0 000000B0 B0000000 ++ * ++ * So a BE kernel will have the leftmost of the above in the MSB ++ * and rightmost in the LSB and can just then "cast" the u32 "data" ++ * down to the appropriate quantity and write it. ++ * ++ * However, an LE kernel can't. It doesn't need to swap because a ++ * load from data followed by a store to user are going to preserve ++ * the byte ordering which is the wire byte order which is what the ++ * user wants, but in order to "crop" to the right size, we need to ++ * shift right first. ++ */ + switch(len) { + case 4: + rc = __put_user((u32)data, (u32 __user *)ubuf); + break; + case 2: ++#ifdef __LITTLE_ENDIAN__ ++ data >>= 16; ++#endif + rc = __put_user((u16)data, (u16 __user *)ubuf); + break; + default: ++#ifdef __LITTLE_ENDIAN__ ++ data >>= 24; ++#endif + rc = __put_user((u8)data, (u8 __user *)ubuf); + break; + } +@@ -263,12 +303,31 @@ static ssize_t lpc_debug_write(struct fi + else if (todo > 1 && (pos & 1) == 0) + len = 2; + } ++ ++ /* ++ * Similarly to the read case, we have some trickery here but ++ * it's different to handle. We need to pass the value to OPAL in ++ * a register whose layout depends on the access size. We want ++ * to reproduce the memory layout of the user, however we aren't ++ * doing a load from user and a store to another memory location ++ * which would achieve that. Here we pass the value to OPAL via ++ * a register which is expected to contain the "BE" interpretation ++ * of the byte sequence. IE: for a 32-bit access, byte 0 should be ++ * in the MSB. So here we *do* need to byteswap on LE. ++ * ++ * User bytes: LE "data" OPAL "data" ++ * 32-bit: B0 B1 B2 B3 B3B2B1B0 B0B1B2B3 ++ * 16-bit: B0 B1 0000B1B0 0000B0B1 ++ * 8-bit: B0 000000B0 000000B0 ++ */ + switch(len) { + case 4: + rc = __get_user(data, (u32 __user *)ubuf); ++ data = cpu_to_be32(data); + break; + case 2: + rc = __get_user(data, (u16 __user *)ubuf); ++ data = cpu_to_be16(data); + break; + default: + rc = __get_user(data, (u8 __user *)ubuf); diff --git a/queue-3.17/powerpc-use-device_online-offline-instead-of-cpu_up-down.patch b/queue-3.17/powerpc-use-device_online-offline-instead-of-cpu_up-down.patch new file mode 100644 index 00000000000..ea8e8bf2492 --- /dev/null +++ b/queue-3.17/powerpc-use-device_online-offline-instead-of-cpu_up-down.patch @@ -0,0 +1,54 @@ +From 10ccaf178b2b961d8bca252d647ed7ed8aae2a20 Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Fri, 31 Oct 2014 15:41:34 -0400 +Subject: powerpc: use device_online/offline() instead of cpu_up/down() + +From: Dan Streetman + +commit 10ccaf178b2b961d8bca252d647ed7ed8aae2a20 upstream. + +In powerpc pseries platform dlpar operations, use device_online() and +device_offline() instead of cpu_up() and cpu_down(). + +Calling cpu_up/down() directly does not update the cpu device offline +field, which is used to online/offline a cpu from sysfs. Calling +device_online/offline() instead keeps the sysfs cpu online value +correct. The hotplug lock, which is required to be held when calling +device_online/offline(), is already held when dlpar_online/offline_cpu() +are called, since they are called only from cpu_probe|release_store(). + +This patch fixes errors on phyp (PowerVM) systems that have cpu(s) +added/removed using dlpar operations; without this patch, the +/sys/devices/system/cpu/cpuN/online nodes do not correctly show the +online state of added/removed cpus. + +Signed-off-by: Dan Streetman +Cc: Nathan Fontenot +Fixes: 0902a9044fa5 ("Driver core: Use generic offline/online for CPU offline/online") +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/pseries/dlpar.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/platforms/pseries/dlpar.c ++++ b/arch/powerpc/platforms/pseries/dlpar.c +@@ -379,7 +379,7 @@ static int dlpar_online_cpu(struct devic + BUG_ON(get_cpu_current_state(cpu) + != CPU_STATE_OFFLINE); + cpu_maps_update_done(); +- rc = cpu_up(cpu); ++ rc = device_online(get_cpu_device(cpu)); + if (rc) + goto out; + cpu_maps_update_begin(); +@@ -462,7 +462,7 @@ static int dlpar_offline_cpu(struct devi + if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { + set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); + cpu_maps_update_done(); +- rc = cpu_down(cpu); ++ rc = device_offline(get_cpu_device(cpu)); + if (rc) + goto out; + cpu_maps_update_begin(); diff --git a/queue-3.17/regulator-max77693-fix-use-of-uninitialized-regulator-config.patch b/queue-3.17/regulator-max77693-fix-use-of-uninitialized-regulator-config.patch new file mode 100644 index 00000000000..f6e27df273e --- /dev/null +++ b/queue-3.17/regulator-max77693-fix-use-of-uninitialized-regulator-config.patch @@ -0,0 +1,37 @@ +From ca0c37a0b489bb14bf3e1549e7a8d0c9a17f4919 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Mon, 3 Nov 2014 15:07:05 +0100 +Subject: regulator: max77693: Fix use of uninitialized regulator config + +From: Krzysztof Kozlowski + +commit ca0c37a0b489bb14bf3e1549e7a8d0c9a17f4919 upstream. + +Driver allocated on stack struct regulator_config but didn't initialize +it fully. Few fields (driver_data, ena_gpio) were left untouched. This +lead to using random ena_gpio values as GPIOs for max77693 regulators. + +On occasion these values could match real GPIO numbers leading to +interfering with other drivers and to unsuccessful enable/disable of +regulator. + +Signed-off-by: Krzysztof Kozlowski +Fixes: 80b022e29bfd ("regulator: max77693: Add max77693 regualtor driver.") +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/regulator/max77693.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/regulator/max77693.c ++++ b/drivers/regulator/max77693.c +@@ -227,7 +227,7 @@ static int max77693_pmic_probe(struct pl + struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct max77693_regulator_data *rdata = NULL; + int num_rdata, i; +- struct regulator_config config; ++ struct regulator_config config = { }; + + num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata); + if (!rdata || num_rdata <= 0) { diff --git a/queue-3.17/series b/queue-3.17/series index bf43bab029e..ea499b6fba5 100644 --- a/queue-3.17/series +++ b/queue-3.17/series @@ -296,3 +296,12 @@ samsung-laptop-add-broken-acpi-video-quirk-for-nc210-nc110.patch fix-breakage-in-o2net_send_tcp_msg.patch pinctrl-baytrail-show-output-gpio-state-correctly-on-intel-baytrail.patch arm-pxa-fix-hang-on-startup-with-debug_ll.patch +powerpc-use-device_online-offline-instead-of-cpu_up-down.patch +powerpc-powernv-properly-fix-lpc-debugfs-endianness.patch +powerpc-do_notify_resume-can-be-called-with-bad-thread_info-flags-argument.patch +alsa-hda-fix-mute-led-problem-for-three-hp-laptops.patch +regulator-max77693-fix-use-of-uninitialized-regulator-config.patch +irqchip-armada-370-xp-fix-msi-interrupt-handling.patch +irqchip-armada-370-xp-fix-mpic-interrupt-handling.patch +i2c-at91-don-t-account-as-iowait.patch +sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch diff --git a/queue-3.17/sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch b/queue-3.17/sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch new file mode 100644 index 00000000000..e2b7fe4a037 --- /dev/null +++ b/queue-3.17/sysfs-driver-core-fix-glue-dir-race-condition-by-gdp_mutex.patch @@ -0,0 +1,103 @@ +From e4a60d139060975eb956717e4f63ae348d4d8cc5 Mon Sep 17 00:00:00 2001 +From: Yijing Wang +Date: Fri, 7 Nov 2014 12:05:49 +0800 +Subject: sysfs: driver core: Fix glue dir race condition by gdp_mutex + +From: Yijing Wang + +commit e4a60d139060975eb956717e4f63ae348d4d8cc5 upstream. + +There is a race condition when removing glue directory. +It can be reproduced in following test: + +path 1: Add first child device +device_add() + get_device_parent() + /*find parent from glue_dirs.list*/ + list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) + if (k->parent == parent_kobj) { + kobj = kobject_get(k); + break; + } + .... + class_dir_create_and_add() + +path2: Remove last child device under glue dir +device_del() + cleanup_device_parent() + cleanup_glue_dir() + kobject_put(glue_dir); + +If path2 has been called cleanup_glue_dir(), but not +call kobject_put(glue_dir), the glue dir is still +in parent's kset list. Meanwhile, path1 find the glue +dir from the glue_dirs.list. Path2 may release glue dir +before path1 call kobject_get(). So kernel will report +the warning and bug_on. + +This is a "classic" problem we have of a kref in a list +that can be found while the last instance could be removed +at the same time. + +This patch reuse gdp_mutex to fix this race condition. + +The following calltrace is captured in kernel 3.4, but +the latest kernel still has this bug. + +----------------------------------------------------- +<4>[ 3965.441471] WARNING: at ...include/linux/kref.h:41 kobject_get+0x33/0x40() +<4>[ 3965.441474] Hardware name: Romley +<4>[ 3965.441475] Modules linked in: isd_iop(O) isd_xda(O)... +... +<4>[ 3965.441605] Call Trace: +<4>[ 3965.441611] [] warn_slowpath_common+0x7a/0xb0 +<4>[ 3965.441615] [] warn_slowpath_null+0x15/0x20 +<4>[ 3965.441618] [] kobject_get+0x33/0x40 +<4>[ 3965.441624] [] get_device_parent.isra.11+0x135/0x1f0 +<4>[ 3965.441627] [] device_add+0xd4/0x6d0 +<4>[ 3965.441631] [] ? dev_set_name+0x3c/0x40 +.... +<2>[ 3965.441912] kernel BUG at ..../fs/sysfs/group.c:65! +<4>[ 3965.441915] invalid opcode: 0000 [#1] SMP +... +<4>[ 3965.686743] [] sysfs_create_group+0xe/0x10 +<4>[ 3965.686748] [] blk_trace_init_sysfs+0x14/0x20 +<4>[ 3965.686753] [] blk_register_queue+0x3b/0x120 +<4>[ 3965.686756] [] add_disk+0x1cc/0x490 +.... +------------------------------------------------------- + +Signed-off-by: Yijing Wang +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -724,12 +724,12 @@ class_dir_create_and_add(struct class *c + return &dir->kobj; + } + ++static DEFINE_MUTEX(gdp_mutex); + + static struct kobject *get_device_parent(struct device *dev, + struct device *parent) + { + if (dev->class) { +- static DEFINE_MUTEX(gdp_mutex); + struct kobject *kobj = NULL; + struct kobject *parent_kobj; + struct kobject *k; +@@ -793,7 +793,9 @@ static void cleanup_glue_dir(struct devi + glue_dir->kset != &dev->class->p->glue_dirs) + return; + ++ mutex_lock(&gdp_mutex); + kobject_put(glue_dir); ++ mutex_unlock(&gdp_mutex); + } + + static void cleanup_device_parent(struct device *dev) -- 2.47.3