From 8c38d28ba8da98f7102c31d35359b4dbe9d1f329 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Wed, 22 Oct 2014 03:37:08 +0200 Subject: [PATCH 01/66] clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write EXYNOS4_MCT_L_MASK is defined as 0xffffff00, so applying this bitmask produces a number outside the range 0x00 to 0xff, which always results in execution of the default switch statement. Obviously this is wrong and git history shows that the bitmask inversion was incorrectly set during a refactoring of the MCT code. Fix this by putting the inversion at the correct position again. Cc: stable@vger.kernel.org Acked-by: Kukjin Kim Reported-by: GP Orcullo Reviewed-by: Doug Anderson Signed-off-by: Tobias Jakobi Signed-off-by: Daniel Lezcano --- drivers/clocksource/exynos_mct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 9403061a2acc78..83564c9cfdbe3b 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -97,8 +97,8 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset) writel_relaxed(value, reg_base + offset); if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { - stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; - switch (offset & EXYNOS4_MCT_L_MASK) { + stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; + switch (offset & ~EXYNOS4_MCT_L_MASK) { case MCT_L_TCON_OFFSET: mask = 1 << 3; /* L_TCON write status */ break; From ff4bcc84a9e720ffa6cb7cf01e9e938568147cd6 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 8 Dec 2014 13:42:02 -0800 Subject: [PATCH 02/66] clocksource: kona: fix __iomem annotation It makes no sense to hide the __iomem annotation from the function that uses it, especially since it causes a sparse warning: drivers/clocksource/bcm_kona_timer.c:118:38: warning: incorrect type in argument 1 (different address spaces) drivers/clocksource/bcm_kona_timer.c:118:38: expected void *timer_base drivers/clocksource/bcm_kona_timer.c:118:38: got void [noderef] *static [toplevel] tmr_regs Signed-off-by: Olof Johansson Acked-by: Florian Fainelli Signed-off-by: Daniel Lezcano --- drivers/clocksource/bcm_kona_timer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index 0595dc6c453e6e..f1e33d08dd834a 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c @@ -68,9 +68,8 @@ static void kona_timer_disable_and_clear(void __iomem *base) } static void -kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) +kona_timer_get_counter(void __iomem *timer_base, uint32_t *msw, uint32_t *lsw) { - void __iomem *base = IOMEM(timer_base); int loop_limit = 4; /* @@ -86,9 +85,9 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) */ while (--loop_limit) { - *msw = readl(base + KONA_GPTIMER_STCHI_OFFSET); - *lsw = readl(base + KONA_GPTIMER_STCLO_OFFSET); - if (*msw == readl(base + KONA_GPTIMER_STCHI_OFFSET)) + *msw = readl(timer_base + KONA_GPTIMER_STCHI_OFFSET); + *lsw = readl(timer_base + KONA_GPTIMER_STCLO_OFFSET); + if (*msw == readl(timer_base + KONA_GPTIMER_STCHI_OFFSET)) break; } if (!loop_limit) { From f2a5473861cf69c03d0f0ee5d0ea1b853b9e582e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Dec 2014 18:48:54 +0900 Subject: [PATCH 03/66] clocksource: sh_tmu: Set cpu_possible_mask to fix SMP broadcast Update the TMU driver to use cpu_possible_mask as cpumask to make r8a7779 SMP work as expected with or without the ARM TWD timer. Signed-off-by: Magnus Damm Signed-off-by: Daniel Lezcano --- drivers/clocksource/sh_tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 0f665b8f2461f0..f150ca82bfaf10 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -428,7 +428,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch, ced->features = CLOCK_EVT_FEAT_PERIODIC; ced->features |= CLOCK_EVT_FEAT_ONESHOT; ced->rating = 200; - ced->cpumask = cpumask_of(0); + ced->cpumask = cpu_possible_mask; ced->set_next_event = sh_tmu_clock_event_next; ced->set_mode = sh_tmu_clock_event_mode; ced->suspend = sh_tmu_clock_event_suspend; From 596c4051eb6b0c7f5fc5437c2269b7191b59ff3b Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Wed, 10 Dec 2014 17:55:02 +0800 Subject: [PATCH 04/66] irqchip: mtk-sysirq: Use IS_ERR() instead of NULL pointer check Beniamino noticed a bug that an invalid DT file for the mediatek interrupt polarity extension will cause kernel oops. The reason is that the interrupt polarity support for mediatek chips merely checks for NULL pointer instead of a casted error return value in mtk_sysirq_of_init() so any other casted error value passes the NULL pointer check and causes a kernel panic when dereferenced. Use IS_ERR() and return the error value via PTR_ERR(). [ jac: took V2 over V3 for diff formatting, hand-added V3 changes, tweaked subject line. ] Reported-by: Beniamino Galvani Signed-off-by: Yingjoe Chen Link: https://lkml.kernel.org/r/1418205302-22531-1-git-send-email-yingjoe.chen@mediatek.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-mtk-sysirq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 7e342df6a62f58..0b0d2c00a2df8d 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -137,9 +137,9 @@ static int __init mtk_sysirq_of_init(struct device_node *node, return -ENOMEM; chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); - if (!chip_data->intpol_base) { + if (IS_ERR(chip_data->intpol_base)) { pr_err("mtk_sysirq: unable to map sysirq register\n"); - ret = -ENOMEM; + ret = PTR_ERR(chip_data->intpol_base); goto out_free; } From 03d3d45be413196790f82d601dc0527539804830 Mon Sep 17 00:00:00 2001 From: Wang Long Date: Thu, 11 Dec 2014 11:03:36 +0000 Subject: [PATCH 05/66] irqchip: hip04: Initialize hip04_cpu_map to 0xffff HiP04 GIC extends to support 16 cores, so we should initialize the hip04_cpu_map to 0xffff. Signed-off-by: Wang Long Acked-by: Haojian Zhuang Link: https://lkml.kernel.org/r/1418295816-179583-1-git-send-email-long.wanglong@huawei.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-hip04.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 29b8f21b74d0a5..6bc2deb73d533b 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -381,7 +381,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent) * It will be refined as each CPU probes its ID. */ for (i = 0; i < NR_HIP04_CPU_IF; i++) - hip04_cpu_map[i] = 0xff; + hip04_cpu_map[i] = 0xffff; /* * Find out how many interrupts are supported. From 96555c474b917963da7065f88cdab376c8af0e87 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 17 Dec 2014 14:11:09 +0000 Subject: [PATCH 06/66] irqchip: gic-v3-its: Fix use of max with decimal constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arm64 defconfig spits out the following compiler warning from the ITS driver: In file included from include/linux/bitmap.h:9:0, from drivers/irqchip/irq-gic-v3-its.c:18: drivers/irqchip/irq-gic-v3-its.c: In function ‘its_create_device’: include/linux/kernel.h:716:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ drivers/irqchip/irq-gic-v3-its.c:1056:12: note: in expansion of macro ‘max’ nr_ites = max(2, roundup_pow_of_two(nvecs)); Fix the warning by specifying the decimal constant `2' explicitly as an unsigned long type. Cc: Marc Zyngier Signed-off-by: Will Deacon Acked-by: Marc Zyngier Link: https://lkml.kernel.org/r/1418825469-30529-1-git-send-email-will.deacon@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 86e4684adeb12d..d8996bdf0f61e9 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1053,7 +1053,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, * of two entries. No, the architecture doesn't let you * express an ITT with a single entry. */ - nr_ites = max(2, roundup_pow_of_two(nvecs)); + nr_ites = max(2UL, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kmalloc(sz, GFP_KERNEL); From 4b149e417463bbb6d1d9b805f729627ca2b54495 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 6 Jan 2015 14:38:08 -0600 Subject: [PATCH 07/66] irqchip: omap-intc: Fix legacy DMA regression commit 55601c9f2467 (arm: omap: intc: switch over to linear irq domain) introduced a regression with SDMA legacy driver because that driver strictly depends on INTC's IRQs starting at NR_IRQs. Aparently irq_domain_add_linear() won't guarantee that, since we see a 7 IRQs difference when booting with and without the commit cited above. Until arch/arm/plat-omap/dma.c is properly fixed, we must maintain OMAP2/3 using irq_domain_add_legacy(). A FIXME note was added so people know to delete that code once that legacy DMA driver is fixed up. Fixes: 55601c9f2467 (arm: omap: intc: switch over to linear irq domain) Cc: # v3.18 Tested-by: Aaro Koskinen Tested-by: Tony Lindgren Signed-off-by: Felipe Balbi Link: https://lkml.kernel.org/r/1420576688-10604-1-git-send-email-balbi@ti.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-omap-intc.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index 28718d3e828103..c03f140acbaebf 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -263,7 +263,7 @@ static int __init omap_init_irq_of(struct device_node *node) return ret; } -static int __init omap_init_irq_legacy(u32 base) +static int __init omap_init_irq_legacy(u32 base, struct device_node *node) { int j, irq_base; @@ -277,7 +277,7 @@ static int __init omap_init_irq_legacy(u32 base) irq_base = 0; } - domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0, + domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0, &irq_domain_simple_ops, NULL); omap_irq_soft_reset(); @@ -301,10 +301,26 @@ static int __init omap_init_irq(u32 base, struct device_node *node) { int ret; - if (node) + /* + * FIXME legacy OMAP DMA driver sitting under arch/arm/plat-omap/dma.c + * depends is still not ready for linear IRQ domains; because of that + * we need to temporarily "blacklist" OMAP2 and OMAP3 devices from using + * linear IRQ Domain until that driver is finally fixed. + */ + if (of_device_is_compatible(node, "ti,omap2-intc") || + of_device_is_compatible(node, "ti,omap3-intc")) { + struct resource res; + + if (of_address_to_resource(node, 0, &res)) + return -ENOMEM; + + base = res.start; + ret = omap_init_irq_legacy(base, node); + } else if (node) { ret = omap_init_irq_of(node); - else - ret = omap_init_irq_legacy(base); + } else { + ret = omap_init_irq_legacy(base, NULL); + } if (ret == 0) omap_irq_enable_protection(); From 91d1179212161f220938198b742c328ad38fd0a3 Mon Sep 17 00:00:00 2001 From: Gavin Li Date: Tue, 6 Jan 2015 18:47:23 -0800 Subject: [PATCH 08/66] irqchip: atmel-aic-common: Prevent clobbering of priority when changing IRQ type This patch makes the bitmask for AIC_SRCTYPE consistent with that of its valid values, and prevents the priority field at bits 2:0 from being clobbered by an incorrect AND with the AIC_SRCTYPE mask. Signed-off-by: Gavin Li Cc: # v3.17+ Acked-by: Boris Brezillon Acked-by: Nicolas Ferre Link: https://lkml.kernel.org/r/1420598843-8409-1-git-send-email-gavinli@thegavinli.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-atmel-aic-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index d111ac779c4058..63cd031b2c28d4 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -28,7 +28,7 @@ #define AT91_AIC_IRQ_MIN_PRIORITY 0 #define AT91_AIC_IRQ_MAX_PRIORITY 7 -#define AT91_AIC_SRCTYPE GENMASK(7, 6) +#define AT91_AIC_SRCTYPE GENMASK(6, 5) #define AT91_AIC_SRCTYPE_LOW (0 << 5) #define AT91_AIC_SRCTYPE_FALLING (1 << 5) #define AT91_AIC_SRCTYPE_HIGH (2 << 5) @@ -74,7 +74,7 @@ int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val) return -EINVAL; } - *val &= AT91_AIC_SRCTYPE; + *val &= ~AT91_AIC_SRCTYPE; *val |= aic_type; return 0; From 6ada1fc0e1c4775de0e043e1bd3ae9d065491aa5 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 19:22:48 -0500 Subject: [PATCH 09/66] time: settimeofday: Validate the values of tv from user An unvalidated user input is multiplied by a constant, which can result in an undefined behaviour for large values. While this is validated later, we should avoid triggering undefined behaviour. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: stable Signed-off-by: Sasha Levin [jstultz: include trivial milisecond->microsecond correction noticed by Andy] Signed-off-by: John Stultz --- include/linux/time.h | 13 +++++++++++++ kernel/time/time.c | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/include/linux/time.h b/include/linux/time.h index 8c42cf8d24440a..5989b0ead1ec99 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -99,6 +99,19 @@ static inline bool timespec_valid_strict(const struct timespec *ts) return true; } +static inline bool timeval_valid(const struct timeval *tv) +{ + /* Dates before 1970 are bogus */ + if (tv->tv_sec < 0) + return false; + + /* Can't have more microseconds then a second */ + if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) + return false; + + return true; +} + extern struct timespec timespec_trunc(struct timespec t, unsigned gran); #define CURRENT_TIME (current_kernel_time()) diff --git a/kernel/time/time.c b/kernel/time/time.c index a9ae20fb0b11ca..22d5d3b73970d9 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -196,6 +196,10 @@ SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, if (tv) { if (copy_from_user(&user_tv, tv, sizeof(*tv))) return -EFAULT; + + if (!timeval_valid(&user_tv)) + return -EINVAL; + new_ts.tv_sec = user_tv.tv_sec; new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; } From 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 19:25:05 -0500 Subject: [PATCH 10/66] time: adjtimex: Validate the ADJ_FREQUENCY values Verify that the frequency value from userspace is valid and makes sense. Unverified values can cause overflows later on. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: stable Signed-off-by: Sasha Levin [jstultz: Fix up bug for negative values and drop redunent cap check] Signed-off-by: John Stultz --- kernel/time/ntp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 87a346fd6d61ff..28bf91c60a0b41 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -633,6 +633,13 @@ int ntp_validate_timex(struct timex *txc) if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME))) return -EPERM; + if (txc->modes & ADJ_FREQUENCY) { + if (LONG_MIN / PPM_SCALE > txc->freq) + return -EINVAL; + if (LONG_MAX / PPM_SCALE < txc->freq) + return -EINVAL; + } + return 0; } From 8c6067355f72e330695968601f0aef3436b473ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 15 Jan 2015 09:38:03 -0600 Subject: [PATCH 11/66] arm: boot: dts: dra7: enable dwc3 suspend PHY quirk Whenever Suspend PHY bit is set on DRA7x devices, USB will not work due to Set EP Configuration command always failing. This was only found after a recent commit 2164a47 (usb: dwc3: set SUSPHY bit for all cores, which will be merged for v3.19) added a missing *required* step to dwc3 initialization. Synopsys Databook requires that we enable Suspend PHY bit after initialization but that, unfortunately, breaks DRA7x. Note that the same regression was already patched for AM437x. Reported-by: Roger Quadros Signed-off-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 22771bc1643afc..63f8b007bdc513 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -1257,6 +1257,8 @@ tx-fifo-resize; maximum-speed = "super-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; @@ -1278,6 +1280,8 @@ tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; @@ -1299,6 +1303,8 @@ tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; From 6222d1721dd7d533b43747642419a8ff78ad6f99 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 15 Jan 2015 15:19:10 -0700 Subject: [PATCH 12/66] NVMe: cq_vector should be signed This was inadvertently dropped from an earlier commit, otherwise the check against cq_vector == -1 to prevent double free doesn't make any sense. Fixes: 2b25d981790b Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index cb529e9a82dd68..d826bf3e62c862 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -106,7 +106,7 @@ struct nvme_queue { dma_addr_t cq_dma_addr; u32 __iomem *q_db; u16 q_depth; - u16 cq_vector; + s16 cq_vector; u16 sq_head; u16 sq_tail; u16 cq_head; From 1fbbc3f0c5440a4c674b3d6de0a9dd447666b508 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 16 Jan 2015 10:17:10 +0900 Subject: [PATCH 13/66] ARM: shmobile: r8a7778: Instantiate GIC from C board code in legacy builds As of commit 9a1091ef0017c40a ("irqchip: gic: Support hierarchy irq domain."), Bock-W legacy hangs during boot with: Unable to handle kernel paging request at virtual address cf86a128 pgd = c0004000 [cf86a128] *pgd=6f80041e(bad) Internal error: Oops: 8000000d [#1] SMP ARM CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.19.0-rc4 #1 Hardware name: bockw task: cf823b40 ti: cf824000 task.ti: cf824000 PC is at 0xcf86a128 LR is at request_threaded_irq+0xbc/0x124 This happens because the IRQ numbers of the GIC are now virtual, and no longer match the hardcoded hardware IRQ numbers in the platform board code. To fix this, instantiate the GIC from platform board code when compiling a legacy kernel, like is done for the sh73a0 and r8a7740 legacy code. Follows same style as the r8a7740 legacy GIC fix by Geert Uytterhoeven, thanks to him for the initial work. Signed-off-by: Magnus Damm Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 85fe016d6a872a..5d7a00952591d0 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -586,11 +586,18 @@ void __init r8a7778_init_delay(void) void __init r8a7778_init_irq_dt(void) { void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000); +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + void __iomem *gic_dist_base = ioremap_nocache(0xfe438000, 0x1000); + void __iomem *gic_cpu_base = ioremap_nocache(0xfe430000, 0x1000); +#endif BUG_ON(!base); +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + gic_init(0, 29, gic_dist_base, gic_cpu_base); +#else irqchip_init(); - +#endif /* route all interrupts to ARM */ __raw_writel(0x73ffffff, base + INT2NTSR0); __raw_writel(0xffffffff, base + INT2NTSR1); From f469cde20a7ee342070b4a459b6fce469a3186db Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 16 Jan 2015 10:49:19 +0900 Subject: [PATCH 14/66] ARM: shmobile: r8a7779: Instantiate GIC from C board code in legacy builds As of commit 9a1091ef0017c40a ("irqchip: gic: Support hierarchy irq domain."), Marzen legacy hangs during boot with: Image Name: 'Linux-3.19.0-rc4' Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3445880 Bytes = 3.3 MiB Load Address: 60008000 Entry Point: 60008000 Verifying Checksum ... OK Loading Kernel Image ... OK OK Starting kernel ... Enabling DEBUG_LL does not seem to change the situation, however this patch by itself fixes this issue and re-enables normal boot. This issue happens because the IRQ numbers of the GIC are now virtual, and no longer match the hardcoded hardware IRQ numbers in the platform board code. To fix this, instantiate the GIC from platform board code when compiling a legacy kernel, like is done for the sh73a0, r8a7740 and r8a7778 legacy code. Follows same style as the r8a7740 legacy GIC fix by Geert Uytterhoeven, thanks to him for the initial work. Signed-off-by: Magnus Damm Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7779.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 434d1504066a66..ca60683452b941 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -724,10 +724,17 @@ static int r8a7779_set_wake(struct irq_data *data, unsigned int on) void __init r8a7779_init_irq_dt(void) { +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000); + void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000); +#endif gic_arch_extn.irq_set_wake = r8a7779_set_wake; +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + gic_init(0, 29, gic_dist_base, gic_cpu_base); +#else irqchip_init(); - +#endif /* route all interrupts to ARM */ __raw_writel(0xffffffff, INT2NTSR0); __raw_writel(0x3fffffff, INT2NTSR1); From 0fb22a8fb7f3bc1b00a36d4a97ce4f93191f7559 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 17 Jan 2015 10:21:08 +0000 Subject: [PATCH 15/66] ARM: OMAP: Work around hardcoded interrupts Commit 9a1091ef0017 ("irqchip: gic: Support hierarchy irq domain") changed the GIC driver to use a non-legacy IRQ domain on DT platforms. This patch assumes that DT-driven systems are getting all of their interrupts from device tree. Turns out that OMAP has quite a few hidden gems, and still uses hardcoded interrupts despite having fairly complete DTs. This patch attempts to work around these by offering a translation method that can be called directly from the hwmod code, if present. The same hack is sprinkled over PRCM and TWL. It isn't pretty, but it seems to do the job without having to add more hacks to the interrupt controller code. Tested on OMAP4 (Panda-ES) and OMAP5 (UEVM5432). Signed-off-by: Marc Zyngier Acked-by: Nishanth Menon [tony@atomide.com: updated to fix make randconfig issue] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap4-common.c | 32 ++++++++++++++++++++++ arch/arm/mach-omap2/omap_hwmod.c | 10 +++++-- arch/arm/mach-omap2/omap_hwmod.h | 1 + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 5 ++++ arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 1 + arch/arm/mach-omap2/prcm-common.h | 1 + arch/arm/mach-omap2/prm44xx.c | 5 +++- arch/arm/mach-omap2/prm_common.c | 14 ++++++++-- arch/arm/mach-omap2/twl-common.c | 7 ++++- 10 files changed, 71 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index db57741c9c8ae6..64e44d6d07c0c8 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -211,6 +211,7 @@ extern struct device *omap2_get_iva_device(void); extern struct device *omap2_get_l3_device(void); extern struct device *omap4_get_dsp_device(void); +unsigned int omap4_xlate_irq(unsigned int hwirq); void omap_gic_of_init(void); #ifdef CONFIG_CACHE_L2X0 diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index b7cb44abe49b35..cc30e49a4cc278 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -256,6 +256,38 @@ static int __init omap4_sar_ram_init(void) } omap_early_initcall(omap4_sar_ram_init); +static struct of_device_id gic_match[] = { + { .compatible = "arm,cortex-a9-gic", }, + { .compatible = "arm,cortex-a15-gic", }, + { }, +}; + +static struct device_node *gic_node; + +unsigned int omap4_xlate_irq(unsigned int hwirq) +{ + struct of_phandle_args irq_data; + unsigned int irq; + + if (!gic_node) + gic_node = of_find_matching_node(NULL, gic_match); + + if (WARN_ON(!gic_node)) + return hwirq; + + irq_data.np = gic_node; + irq_data.args_count = 3; + irq_data.args[0] = 0; + irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START; + irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH; + + irq = irq_create_of_mapping(&irq_data); + if (WARN_ON(!irq)) + irq = hwirq; + + return irq; +} + void __init omap_gic_of_init(void) { struct device_node *np; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index cbb908dc5cf0e0..9025ffffd2dc1d 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3534,9 +3534,15 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) mpu_irqs_cnt = _count_mpu_irqs(oh); for (i = 0; i < mpu_irqs_cnt; i++) { + unsigned int irq; + + if (oh->xlate_irq) + irq = oh->xlate_irq((oh->mpu_irqs + i)->irq); + else + irq = (oh->mpu_irqs + i)->irq; (res + r)->name = (oh->mpu_irqs + i)->name; - (res + r)->start = (oh->mpu_irqs + i)->irq; - (res + r)->end = (oh->mpu_irqs + i)->irq; + (res + r)->start = irq; + (res + r)->end = irq; (res + r)->flags = IORESOURCE_IRQ; r++; } diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 35ca6efbec31eb..5b42fafcaf5510 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -676,6 +676,7 @@ struct omap_hwmod { spinlock_t _lock; struct list_head node; struct omap_hwmod_ocp_if *_mpu_port; + unsigned int (*xlate_irq)(unsigned int); u16 flags; u8 mpu_rt_idx; u8 response_lat; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c314b3c31117e8..f5e68a78202513 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -479,6 +479,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = { .class = &omap44xx_dma_hwmod_class, .clkdm_name = "l3_dma_clkdm", .mpu_irqs = omap44xx_dma_system_irqs, + .xlate_irq = omap4_xlate_irq, .main_clk = "l3_div_ck", .prcm = { .omap4 = { @@ -640,6 +641,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .class = &omap44xx_dispc_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dispc_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -693,6 +695,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi1_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -726,6 +729,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi2_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -784,6 +788,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { */ .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_dss_hdmi_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", .prcm = { diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 3e9523084b2ace..7c3fac035e9368 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -288,6 +288,7 @@ static struct omap_hwmod omap54xx_dma_system_hwmod = { .class = &omap54xx_dma_hwmod_class, .clkdm_name = "dma_clkdm", .mpu_irqs = omap54xx_dma_system_irqs, + .xlate_irq = omap4_xlate_irq, .main_clk = "l3_iclk_div", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index a8e4b582c52747..6163d66102a356 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -498,6 +498,7 @@ struct omap_prcm_irq_setup { u8 nr_irqs; const struct omap_prcm_irq *irqs; int irq; + unsigned int (*xlate_irq)(unsigned int); void (*read_pending_irqs)(unsigned long *events); void (*ocp_barrier)(void); void (*save_and_clear_irqen)(u32 *saved_mask); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index cc170fb81ff76d..408c64efb80700 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -49,6 +49,7 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { .irqs = omap4_prcm_irqs, .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), .irq = 11 + OMAP44XX_IRQ_GIC_START, + .xlate_irq = omap4_xlate_irq, .read_pending_irqs = &omap44xx_prm_read_pending_irqs, .ocp_barrier = &omap44xx_prm_ocp_barrier, .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, @@ -751,8 +752,10 @@ static int omap44xx_prm_late_init(void) } /* Once OMAP4 DT is filled as well */ - if (irq_num >= 0) + if (irq_num >= 0) { omap4_prcm_irq_setup.irq = irq_num; + omap4_prcm_irq_setup.xlate_irq = NULL; + } } omap44xx_prm_enable_io_wakeup(); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 779940cb6e5651..dea2833ca627c8 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -187,6 +187,7 @@ int omap_prcm_event_to_irq(const char *name) */ void omap_prcm_irq_cleanup(void) { + unsigned int irq; int i; if (!prcm_irq_setup) { @@ -211,7 +212,11 @@ void omap_prcm_irq_cleanup(void) kfree(prcm_irq_setup->priority_mask); prcm_irq_setup->priority_mask = NULL; - irq_set_chained_handler(prcm_irq_setup->irq, NULL); + if (prcm_irq_setup->xlate_irq) + irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq); + else + irq = prcm_irq_setup->irq; + irq_set_chained_handler(irq, NULL); if (prcm_irq_setup->base_irq > 0) irq_free_descs(prcm_irq_setup->base_irq, @@ -259,6 +264,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) int offset, i; struct irq_chip_generic *gc; struct irq_chip_type *ct; + unsigned int irq; if (!irq_setup) return -EINVAL; @@ -298,7 +304,11 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) 1 << (offset & 0x1f); } - irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler); + if (irq_setup->xlate_irq) + irq = irq_setup->xlate_irq(irq_setup->irq); + else + irq = irq_setup->irq; + irq_set_chained_handler(irq, omap_prcm_irq_handler); irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, 0); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 4457e731f7a4f0..292eca0e78ed07 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -66,19 +66,24 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } +#ifdef CONFIG_ARCH_OMAP4 void __init omap4_pmic_init(const char *pmic_type, struct twl4030_platform_data *pmic_data, struct i2c_board_info *devices, int nr_devices) { /* PMIC part*/ + unsigned int irq; + omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); - omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); + irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START); + omap_pmic_init(1, 400, pmic_type, irq, pmic_data); /* Register additional devices on i2c1 bus if needed */ if (devices) i2c_register_board_info(1, devices, nr_devices); } +#endif void __init omap_pmic_late_init(void) { From 8f1e8ee28660018a935c7576b9af8ffe1feab54c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 16 Jan 2015 17:11:27 +0100 Subject: [PATCH 16/66] ARM: mvebu: completely disable hardware I/O coherency The current hardware I/O coherency is known to cause problems with DMA coherent buffers, as it still requires explicit I/O synchronization barriers, which is not compatible with the semantics expected by the Linux DMA coherent buffers API. So, in order to have enough time to validate a new solution based on automatic I/O synchronization barriers, this commit disables hardware I/O coherency entirely. Future patches will re-enable it. Signed-off-by: Thomas Petazzoni Cc: # v3.8+ Signed-off-by: Andrew Lunn --- arch/arm/mach-mvebu/coherency.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 3585cb394e9b95..caa21e9b8cd981 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -246,9 +246,14 @@ static int coherency_type(void) return type; } +/* + * As a precaution, we currently completely disable hardware I/O + * coherency, until enough testing is done with automatic I/O + * synchronization barriers to validate that it is a proper solution. + */ int coherency_available(void) { - return coherency_type() != COHERENCY_FABRIC_TYPE_NONE; + return false; } int __init coherency_init(void) From f2c3c67f008f18f22a5fc68c0c279a6a59705042 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Sun, 18 Jan 2015 16:45:21 -0800 Subject: [PATCH 17/66] Merge tag 'mvebu-fixes-3.19-3' of git://git.infradead.org/linux-mvebu into fixes Merge " mvebu fixes for 3.19-rc (part #3)" from Andrew Lunn: mvebu: completely disable hardware I/O coherency * tag 'mvebu-fixes-3.19-3' of git://git.infradead.org/linux-mvebu: ARM: mvebu: completely disable hardware I/O coherency Signed-off-by: Olof Johansson --- arch/arm/mach-mvebu/coherency.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 3585cb394e9b95..caa21e9b8cd981 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -246,9 +246,14 @@ static int coherency_type(void) return type; } +/* + * As a precaution, we currently completely disable hardware I/O + * coherency, until enough testing is done with automatic I/O + * synchronization barriers to validate that it is a proper solution. + */ int coherency_available(void) { - return coherency_type() != COHERENCY_FABRIC_TYPE_NONE; + return false; } int __init coherency_init(void) From 378ff1a53b5724f3ac97b0aba3c9ecac072f6fcd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Jan 2015 23:37:32 -0500 Subject: [PATCH 18/66] fix deadlock in cifs_ioctl_clone() It really needs to check that src is non-directory *and* use {un,}lock_two_nodirectories(). As it is, it's trivial to cause double-lock (ioctl(fd, CIFS_IOC_COPYCHUNK_FILE, fd)) and if the last argument is an fd of directory, we are asking for trouble by violating the locking order - all directories go before all non-directories. If the last argument is an fd of parent directory, it has 50% odds of locking child before parent, which will cause AB-BA deadlock if we race with unlink(). Cc: stable@vger.kernel.org @ 3.13+ Signed-off-by: Al Viro --- fs/cifs/ioctl.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 45cb59bcc79188..8b7898b7670f88 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, } src_inode = file_inode(src_file.file); + rc = -EINVAL; + if (S_ISDIR(src_inode->i_mode)) + goto out_fput; /* * Note: cifs case is easier than btrfs since server responsible for * checks for proper open modes and file type and if it wants * server could even support copy of range where source = target */ - - /* so we do not deadlock racing two ioctls on same files */ - if (target_inode < src_inode) { - mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); - } else { - mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_CHILD); - } + lock_two_nondirectories(target_inode, src_inode); /* determine range to clone */ rc = -EINVAL; @@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, out_unlock: /* although unlocking in the reverse order from locking is not strictly necessary here it is a little cleaner to be consistent */ - if (target_inode < src_inode) { - mutex_unlock(&src_inode->i_mutex); - mutex_unlock(&target_inode->i_mutex); - } else { - mutex_unlock(&target_inode->i_mutex); - mutex_unlock(&src_inode->i_mutex); - } + unlock_two_nondirectories(src_inode, target_inode); out_fput: fdput(src_file); out_drop_write: From 6cdb08172bc89f0a39e1643c5e7eab362692fd1b Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 30 Oct 2014 17:27:10 -0500 Subject: [PATCH 19/66] ipr: wait for aborted command responses Fixes a race condition in abort handling that was injected when multiple interrupt support was added. When only a single interrupt is present, the adapter guarantees it will send responses for aborted commands prior to the response for the abort command itself. With multiple interrupts, these responses generally come back on different interrupts, so we need to ensure the abort thread waits until the aborted command is complete so we don't perform a double completion. This race condition was being hit frequently in environments which were triggering command timeouts, which was resulting in a double completion causing a kernel oops. Cc: Signed-off-by: Brian King Reviewed-by: Wendy Xiong Tested-by: Wendy Xiong Signed-off-by: Christoph Hellwig --- drivers/scsi/ipr.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/ipr.h | 1 + 2 files changed, 93 insertions(+) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index df4e27cd996a3c..9219953ee949a9 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd, ipr_reinit_ipr_cmnd(ipr_cmd); ipr_cmd->u.scratch = 0; ipr_cmd->sibling = NULL; + ipr_cmd->eh_comp = NULL; ipr_cmd->fast_done = fast_done; init_timer(&ipr_cmd->timer); } @@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) scsi_dma_unmap(ipr_cmd->scsi_cmd); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } @@ -4811,6 +4814,84 @@ static int ipr_slave_alloc(struct scsi_device *sdev) return rc; } +/** + * ipr_match_lun - Match function for specified LUN + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * + * Returns: + * 1 if command matches sdev / 0 if command does not match sdev + **/ +static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) +{ + if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) + return 1; + return 0; +} + +/** + * ipr_wait_for_ops - Wait for matching commands to complete + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * @match: match function to use + * + * Returns: + * SUCCESS / FAILED + **/ +static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, + int (*match)(struct ipr_cmnd *, void *)) +{ + struct ipr_cmnd *ipr_cmd; + int wait; + unsigned long flags; + struct ipr_hrr_queue *hrrq; + signed long timeout = IPR_ABORT_TASK_TIMEOUT; + DECLARE_COMPLETION_ONSTACK(comp); + + ENTER; + do { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = ∁ + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) { + timeout = wait_for_completion_timeout(&comp, timeout); + + if (!timeout) { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = NULL; + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) + dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n"); + LEAVE; + return wait ? FAILED : SUCCESS; + } + } + } while (wait); + + LEAVE; + return SUCCESS; +} + static int ipr_eh_host_reset(struct scsi_cmnd *cmd) { struct ipr_ioa_cfg *ioa_cfg; @@ -5030,11 +5111,17 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) { int rc; + struct ipr_ioa_cfg *ioa_cfg; + + ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; spin_lock_irq(cmd->device->host->host_lock); rc = __ipr_eh_dev_reset(cmd); spin_unlock_irq(cmd->device->host->host_lock); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); + return rc; } @@ -5234,13 +5321,18 @@ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) { unsigned long flags; int rc; + struct ipr_ioa_cfg *ioa_cfg; ENTER; + ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; + spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); rc = ipr_cancel_op(scsi_cmd); spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); LEAVE; return rc; } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b4f3eec51bc9b1..ec03b42fa2b9fe 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1606,6 +1606,7 @@ struct ipr_cmnd { struct scsi_device *sdev; } u; + struct completion *eh_comp; struct ipr_hrr_queue *hrrq; struct ipr_ioa_cfg *ioa_cfg; }; From 38bdf45f4aa5cb6186d50a29e6cbbd9d486a1519 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 18 Jan 2015 09:46:10 -0600 Subject: [PATCH 20/66] bus: mvebu-mbus: fix support of MBus window 13 On Armada XP, 375 and 38x the MBus window 13 has the remap capability, like windows 0 to 7. However, the mvebu-mbus driver isn't currently taking into account this special case, which means that when window 13 is actually used, the remap registers are left to 0, making the device using this MBus window unavailable. As a minimal fix for stable, don't use window 13. A full fix will follow later. Fixes: fddddb52a6c ("bus: introduce an Marvell EBU MBus driver") Cc: # v3.10+ Reviewed-by: Thomas Petazzoni Signed-off-by: Andrew Lunn --- drivers/bus/mvebu-mbus.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index eb7682dc123be4..81bf297f1034ab 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -210,12 +210,25 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, } /* Checks whether the given window number is available */ + +/* On Armada XP, 375 and 38x the MBus window 13 has the remap + * capability, like windows 0 to 7. However, the mvebu-mbus driver + * isn't currently taking into account this special case, which means + * that when window 13 is actually used, the remap registers are left + * to 0, making the device using this MBus window unavailable. The + * quick fix for stable is to not use window 13. A follow up patch + * will correctly handle this window. +*/ static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, const int win) { void __iomem *addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win); u32 ctrl = readl(addr + WIN_CTRL_OFF); + + if (win == 13) + return false; + return !(ctrl & WIN_CTRL_ENABLE); } From 7ecd0bde5bfea524a843ad8fa8cb66ccbce68779 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 14 Jan 2015 11:11:03 -0200 Subject: [PATCH 21/66] ARM: dts: imx25: Fix PWM "per" clocks Currently PWM functionality is broken on mx25 due to the wrong assignment of the PWM "per" clock. According to Documentation/devicetree/bindings/clock/imx25-clock.txt: pwm_ipg_per 52 ,so update the pwm "per" to use 'pwm_ipg_per' instead of 'per10' clock. With this change PWM can work fine on mx25. Cc: Reported-by: Carlos Soto Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx25.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index d238676a910753..e4d3aecc4ed2c0 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -369,7 +369,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa0000 0x4000>; - clocks = <&clks 106>, <&clks 36>; + clocks = <&clks 106>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <36>; }; @@ -388,7 +388,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa8000 0x4000>; - clocks = <&clks 107>, <&clks 36>; + clocks = <&clks 107>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <41>; }; @@ -429,7 +429,7 @@ pwm4: pwm@53fc8000 { compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; reg = <0x53fc8000 0x4000>; - clocks = <&clks 108>, <&clks 36>; + clocks = <&clks 108>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <42>; }; @@ -476,7 +476,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fe0000 0x4000>; - clocks = <&clks 105>, <&clks 36>; + clocks = <&clks 105>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <26>; }; From 99531e6063283da4468741185fe48b8eb037d919 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 17 Jan 2015 17:47:37 -0500 Subject: [PATCH 22/66] scsi_debug: use atomic allocation in resp_rsup_opcodes resp_rsup_opcodes() may get called from atomic context and would need to use GFP_ATOMIC for allocations: [ 1237.913419] BUG: sleeping function called from invalid context at mm/slub.c:1262 [ 1237.914865] in_atomic(): 1, irqs_disabled(): 0, pid: 7556, name: trinity-c311 [ 1237.916142] 3 locks held by trinity-c311/7556: [ 1237.916981] #0: (sb_writers#5){.+.+.+}, at: do_readv_writev (include/linux/fs.h:2346 fs/read_write.c:844) [ 1237.919713] #1: (&of->mutex){+.+.+.}, at: kernfs_fop_write (fs/kernfs/file.c:297) [ 1237.922626] Mutex: counter: -1 owner: trinity-c311 [ 1237.924044] #2: (s_active#51){.+.+.+}, at: kernfs_fop_write (fs/kernfs/file.c:297) [ 1237.925960] Preemption disabled blk_execute_rq_nowait (block/blk-exec.c:95) [ 1237.927416] [ 1237.927680] CPU: 24 PID: 7556 Comm: trinity-c311 Not tainted 3.19.0-rc4-next-20150116-sasha-00054-g4ad498c-dirty #1744 [ 1237.929603] ffff8804fc9d8000 ffff8804d9bc3548 ffffffff9d439fb2 0000000000000000 [ 1237.931097] 0000000000000000 ffff8804d9bc3588 ffffffff9a18389a ffff8804d9bc3598 [ 1237.932466] ffffffff9a1b1715 ffffffffa15935d8 ffffffff9e6f8cb1 00000000000004ee [ 1237.933984] Call Trace: [ 1237.934434] dump_stack (lib/dump_stack.c:52) [ 1237.935323] ___might_sleep (kernel/sched/core.c:7339) [ 1237.936259] ? mark_held_locks (kernel/locking/lockdep.c:2549) [ 1237.937293] __might_sleep (kernel/sched/core.c:7305) [ 1237.938272] __kmalloc (mm/slub.c:1262 mm/slub.c:2419 mm/slub.c:2491 mm/slub.c:3291) [ 1237.939137] ? resp_rsup_opcodes (include/linux/slab.h:435 drivers/scsi/scsi_debug.c:1689) [ 1237.940173] resp_rsup_opcodes (include/linux/slab.h:435 drivers/scsi/scsi_debug.c:1689) [ 1237.941211] ? add_host_store (drivers/scsi/scsi_debug.c:1584) [ 1237.942261] scsi_debug_queuecommand (drivers/scsi/scsi_debug.c:5276) [ 1237.943404] ? blk_rq_map_sg (block/blk-merge.c:254) [ 1237.944398] ? scsi_init_sgtable (drivers/scsi/scsi_lib.c:1095) [ 1237.945402] sdebug_queuecommand_lock_or_not (drivers/scsi/scsi_debug.c:5300) [ 1237.946735] scsi_dispatch_cmd (drivers/scsi/scsi_lib.c:1706) [ 1237.947720] scsi_queue_rq (drivers/scsi/scsi_lib.c:1996) [ 1237.948687] __blk_mq_run_hw_queue (block/blk-mq.c:816) [ 1237.949796] blk_mq_run_hw_queue (block/blk-mq.c:896) [ 1237.950903] ? _raw_spin_unlock (./arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:154 kernel/locking/spinlock.c:183) [ 1237.951862] blk_mq_insert_request (block/blk-mq.c:1037) [ 1237.952876] blk_execute_rq_nowait (block/blk-exec.c:95) [ 1237.953981] ? lockdep_init_map (kernel/locking/lockdep.c:3034) [ 1237.954967] blk_execute_rq (block/blk-exec.c:131) [ 1237.955929] ? blk_rq_bio_prep (block/blk-core.c:2835) [ 1237.956913] scsi_execute (drivers/scsi/scsi_lib.c:252) [ 1237.957821] scsi_execute_req_flags (drivers/scsi/scsi_lib.c:281) [ 1237.958968] scsi_report_opcode (drivers/scsi/scsi.c:956) [ 1237.960009] sd_revalidate_disk (drivers/scsi/sd.c:2707 drivers/scsi/sd.c:2792) [ 1237.961139] revalidate_disk (fs/block_dev.c:1081) [ 1237.962223] sd_rescan (drivers/scsi/sd.c:1532) [ 1237.963142] scsi_rescan_device (drivers/scsi/scsi_scan.c:1579) [ 1237.964165] store_rescan_field (drivers/scsi/scsi_sysfs.c:672) [ 1237.965254] dev_attr_store (drivers/base/core.c:138) [ 1237.966319] sysfs_kf_write (fs/sysfs/file.c:131) [ 1237.967289] kernfs_fop_write (fs/kernfs/file.c:311) [ 1237.968274] do_readv_writev (fs/read_write.c:722 fs/read_write.c:854) [ 1237.969295] ? __acct_update_integrals (kernel/tsacct.c:145) [ 1237.970452] ? kernfs_fop_open (fs/kernfs/file.c:271) [ 1237.971505] ? _raw_spin_unlock (./arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:154 kernel/locking/spinlock.c:183) [ 1237.972512] ? context_tracking_user_exit (include/linux/vtime.h:89 include/linux/jump_label.h:114 include/trace/events/context_tracking.h:47 kernel/context_tracking.c:140) [ 1237.973668] ? trace_hardirqs_on_caller (kernel/locking/lockdep.c:2578 kernel/locking/lockdep.c:2625) [ 1237.974882] ? trace_hardirqs_on (kernel/locking/lockdep.c:2633) [ 1237.975850] vfs_writev (fs/read_write.c:893) [ 1237.976691] SyS_writev (fs/read_write.c:926 fs/read_write.c:917) [ 1237.977538] system_call_fastpath (arch/x86/kernel/entry_64.S:423) Signed-off-by: Sasha Levin Acked-by: Douglas Gilbert Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7b8b51bc29b435..9a74f425db9321 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1631,7 +1631,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) a_len = 8192; else a_len = alloc_len; - arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL); + arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC); if (NULL == arr) { mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, INSUFF_RES_ASCQ); From 91724c20613484555ba7e7b3d8549dac1e24f7a8 Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Thu, 15 Jan 2015 10:02:12 -0500 Subject: [PATCH 23/66] scsi: Avoid crashing if device uses DIX but adapter does not support it This can happen if a multipathed device uses DIX and another path is added via an adapter that does not support it. Multipath should not allow this path to be added, but we should not depend upon that to avoid crashing. Signed-off-by: Ewan D. Milne Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_lib.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6d5c0b8cb0bb47..17bb541f7cc259 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1143,7 +1143,17 @@ int scsi_init_io(struct scsi_cmnd *cmd) struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; int ivecs, count; - BUG_ON(prot_sdb == NULL); + if (prot_sdb == NULL) { + /* + * This can happen if someone (e.g. multipath) + * queues a command to a device on an adapter + * that does not support DIX. + */ + WARN_ON_ONCE(1); + error = BLKPREP_KILL; + goto err_exit; + } + ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { From fb32c76d16aa40f3057f53273ac483a8e2468004 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Jan 2015 17:57:53 +0000 Subject: [PATCH 24/66] VFS: Convert file->f_dentry->d_inode to file_inode() Convert file->f_dentry->d_inode to file_inode() so as to get layered filesystems right. Found with: git grep '[.>]f_dentry' Signed-off-by: David Howells Signed-off-by: Al Viro --- arch/cris/arch-v32/drivers/sync_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index 08a313fc22418c..f772068d9e797e 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -604,7 +604,7 @@ static ssize_t __sync_serial_read(struct file *file, struct timespec *ts) { unsigned long flags; - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); int avail; struct sync_port *port; unsigned char *start; From b568b8601f05a591a7ff09d8ee1cedb5b2e815fe Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:05 +0800 Subject: [PATCH 25/66] x86/xen: Treat SCI interrupt as normal GSI interrupt Currently Xen Domain0 has special treatment for ACPI SCI interrupt, that is initialize irq for ACPI SCI at early stage in a special way as: xen_init_IRQ() ->pci_xen_initial_domain() ->xen_setup_acpi_sci() Allocate and initialize irq for ACPI SCI Function xen_setup_acpi_sci() calls acpi_gsi_to_irq() to get an irq number for ACPI SCI. But unfortunately acpi_gsi_to_irq() depends on IOAPIC irqdomains through following path acpi_gsi_to_irq() ->mp_map_gsi_to_irq() ->mp_map_pin_to_irq() ->check IOAPIC irqdomain For PV domains, it uses Xen event based interrupt manangement and doesn't make uses of native IOAPIC, so no irqdomains created for IOAPIC. This causes Xen domain0 fail to install interrupt handler for ACPI SCI and all ACPI events will be lost. Please refer to: https://lkml.org/lkml/2014/12/19/178 So the fix is to get rid of special treatment for ACPI SCI, just treat ACPI SCI as normal GSI interrupt as: acpi_gsi_to_irq() ->acpi_register_gsi() ->acpi_register_gsi_xen() ->xen_register_gsi() With above change, there's no need for xen_setup_acpi_sci() anymore. The above change also works with bare metal kernel too. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: xen-devel@lists.xenproject.org Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Rafael J. Wysocki Cc: Len Brown Cc: Pavel Machek Cc: Bjorn Helgaas Link: http://lkml.kernel.org/r/1421720467-7709-2-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/acpi/boot.c | 26 ++++++++++---------- arch/x86/pci/xen.c | 47 ------------------------------------- 2 files changed, 13 insertions(+), 60 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d1626364a28a16..b9e30daa0881b3 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { - int irq; - - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { - *irqp = gsi; - } else { - mutex_lock(&acpi_ioapic_lock); - irq = mp_map_gsi_to_irq(gsi, - IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); - mutex_unlock(&acpi_ioapic_lock); - if (irq < 0) - return -1; - *irqp = irq; + int rc, irq, trigger, polarity; + + rc = acpi_get_override_irq(gsi, &trigger, &polarity); + if (rc == 0) { + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; + irq = acpi_register_gsi(NULL, gsi, trigger, polarity); + if (irq >= 0) { + *irqp = irq; + return 0; + } } - return 0; + + return -1; } EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c489ef2c1a3915..6e5e89c3c64437 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -471,52 +471,6 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 -static __init void xen_setup_acpi_sci(void) -{ - int rc; - int trigger, polarity; - int gsi = acpi_sci_override_gsi; - int irq = -1; - int gsi_override = -1; - - if (!gsi) - return; - - rc = acpi_get_override_irq(gsi, &trigger, &polarity); - if (rc) { - printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" - " sci, rc=%d\n", rc); - return; - } - trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - - printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " - "polarity=%d\n", gsi, trigger, polarity); - - /* Before we bind the GSI to a Linux IRQ, check whether - * we need to override it with bus_irq (IRQ) value. Usually for - * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: - * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) - * but there are oddballs where the IRQ != GSI: - * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) - * which ends up being: gsi_to_irq[9] == 20 - * (which is what acpi_gsi_to_irq ends up calling when starting the - * the ACPI interpreter and keels over since IRQ 9 has not been - * setup as we had setup IRQ 20 for it). - */ - if (acpi_gsi_to_irq(gsi, &irq) == 0) { - /* Use the provided value if it's valid. */ - if (irq >= 0) - gsi_override = irq; - } - - gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); - printk(KERN_INFO "xen: acpi sci %d\n", gsi); - - return; -} - int __init pci_xen_initial_domain(void) { int irq; @@ -527,7 +481,6 @@ int __init pci_xen_initial_domain(void) x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; pci_msi_ignore_mask = 1; #endif - xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; /* Pre-allocate legacy irqs */ for (irq = 0; irq < nr_legacy_irqs(); irq++) { From 9889eaeb7c999cae64006bb98c47f40f412ec875 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:06 +0800 Subject: [PATCH 26/66] ACPI: pci: Do not clear pci_dev->irq in acpi_pci_irq_disable() Xen pciback driver assumes that pci_dev->irq won't change after calling pci_disable_device(). But commit cffe0a2b5a34c95a4dadc9ec7132690a5b0f6687 ("x86, irq: Keep balance of IOAPIC pin reference count") frees irq resources and resets pci_dev->irq to zero when pci_disable_device() is called. So this is a hotfix for 3.19 to avoid resetting pci_dev->irq, and another proper fix will be prepared for next merging window. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Rafael J. Wysocki Cc: Len Brown Link: http://lkml.kernel.org/r/1421720467-7709-3-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- drivers/acpi/pci_irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 5277a0ee57042b..b1def411c0b89c 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); if (gsi >= 0) { acpi_unregister_gsi(gsi); - dev->irq = 0; dev->irq_managed = 0; } } From 8abb850a03a3a8b11a0e92949e5b99d9cc178e35 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:07 +0800 Subject: [PATCH 27/66] x86/xen: Override ACPI IRQ management callback __acpi_unregister_gsi Xen overrides __acpi_register_gsi and leaves __acpi_unregister_gsi as is. That means, an IRQ allocated by acpi_register_gsi_xen_hvm() or acpi_register_gsi_xen() will be freed by acpi_unregister_gsi_ioapic(), which may cause undesired effects. So override __acpi_unregister_gsi to NULL for safety. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: xen-devel@lists.xenproject.org Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Bjorn Helgaas Cc: Graeme Gregory Cc: Lv Zheng Link: http://lkml.kernel.org/r/1421720467-7709-4-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/acpi.h | 1 + arch/x86/pci/xen.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 0ab4f9fd268764..3a45668f6dc383 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -50,6 +50,7 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity); +extern void (*__acpi_unregister_gsi)(u32 gsi); static inline void disable_acpi(void) { diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6e5e89c3c64437..9098d880c476cf 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -458,6 +458,7 @@ int __init pci_xen_hvm_init(void) * just how GSIs get registered. */ __acpi_register_gsi = acpi_register_gsi_xen_hvm; + __acpi_unregister_gsi = NULL; #endif #ifdef CONFIG_PCI_MSI @@ -482,6 +483,7 @@ int __init pci_xen_initial_domain(void) pci_msi_ignore_mask = 1; #endif __acpi_register_gsi = acpi_register_gsi_xen; + __acpi_unregister_gsi = NULL; /* Pre-allocate legacy irqs */ for (irq = 0; irq < nr_legacy_irqs(); irq++) { int trigger, polarity; From f285f4a21c3253887caceed493089ece17579d59 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 15 Jan 2015 16:51:46 -0800 Subject: [PATCH 28/66] x86, boot: Skip relocs when load address unchanged On 64-bit, relocation is not required unless the load address gets changed. Without this, relocations do unexpected things when the kernel is above 4G. Reported-by: Baoquan He Signed-off-by: Kees Cook Tested-by: Thomas D. Cc: Vivek Goyal Cc: Jan Beulich Cc: Junjie Mao Cc: Andi Kleen Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20150116005146.GA4212@www.outflux.net Signed-off-by: Thomas Gleixner --- arch/x86/boot/compressed/misc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index dcc1c536cc212d..a950864a64dab3 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -373,6 +373,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, unsigned long output_len, unsigned long run_size) { + unsigned char *output_orig = output; + real_mode = rmode; sanitize_boot_params(real_mode); @@ -421,7 +423,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, debug_putstr("\nDecompressing Linux... "); decompress(input_data, input_len, NULL, NULL, output, NULL, error); parse_elf(output); - handle_relocations(output, output_len); + /* + * 32-bit always performs relocations. 64-bit relocations are only + * needed if kASLR has chosen a different load address. + */ + if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig) + handle_relocations(output, output_len); debug_putstr("done.\nBooting the kernel.\n"); return output; } From 4a0d3107d6b19125f21172c2b7d95f9c30ecaf6f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 16 Jan 2015 15:47:07 +0000 Subject: [PATCH 29/66] x86, irq: Properly tag virtualization entry in /proc/interrupts The mis-naming likely was a copy-and-paste effect. Signed-off-by: Jan Beulich Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/54B9408B0200007800055E8B@mail.emea.novell.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 6307a0f0cf17ab..705ef8d48e2dc4 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_puts(p, " Machine check polls\n"); #endif #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) - seq_printf(p, "%*s: ", prec, "THR"); + seq_printf(p, "%*s: ", prec, "HYP"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); seq_puts(p, " Hypervisor callback interrupts\n"); From 9d34cfdf47963905d792ae9c000efa522739abe4 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 12 Jan 2015 06:15:45 +0100 Subject: [PATCH 30/66] x86: Don't rely on VMWare emulating PAT MSR correctly VMWare seems not to emulate the PAT MSR correctly: reaeding MSR_IA32_CR_PAT returns 0 even after writing another value to it. Commit bd809af16e3ab triggers this VMWare bug when the kernel is booted as a VMWare guest. Detect this bug and don't use the read value if it is 0. Fixes: bd809af16e3ab "x86: Enable PAT to use cache mode translation tables" Reported-and-tested-by: Jongman Heo Acked-by: Alok N Kataria Signed-off-by: Juergen Gross Link: http://lkml.kernel.org/r/1421039745-14335-1-git-send-email-jgross@suse.com Signed-off-by: Thomas Gleixner --- arch/x86/mm/pat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index edf299c8ff6c77..7ac68698406c3b 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -234,8 +234,13 @@ void pat_init(void) PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); /* Boot CPU check */ - if (!boot_pat_state) + if (!boot_pat_state) { rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); + if (!boot_pat_state) { + pat_disable("PAT read returns always zero, disabled."); + return; + } + } wrmsrl(MSR_IA32_CR_PAT, pat); From 32c6590d126836a062b3140ed52d898507987017 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 12 Jan 2015 16:26:02 -0800 Subject: [PATCH 31/66] x86, hyperv: Mark the Hyper-V clocksource as being continuous The Hyper-V clocksource is continuous; mark it accordingly. Signed-off-by: K. Y. Srinivasan Acked-by: jasowang@redhat.com Cc: gregkh@linuxfoundation.org Cc: devel@linuxdriverproject.org Cc: olaf@aepfle.de Cc: apw@canonical.com Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1421108762-3331-1-git-send-email-kys@microsoft.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/mshyperv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373e8e9169..939155ffdecec6 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { .rating = 400, /* use this when running on Hyperv*/ .read = read_hv_clock, .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void __init ms_hyperv_init_platform(void) From 76d697d10769048e5721510100bf3a9413a56385 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 20 Jan 2015 11:00:56 +0800 Subject: [PATCH 32/66] blk-mq: fix hctx/ctx kobject use-after-free The kobject memory shouldn't have been freed before the kobject is released because driver core can access it freely before its release. This patch frees hctx in its release callback. For ctx, they share one single per-cpu variable which is associated with the request queue, so free ctx in q->mq_kobj's release handler. Signed-off-by: Sasha Levin (fix ctx kobjects) Signed-off-by: Ming Lei Signed-off-by: Jens Axboe --- block/blk-mq-sysfs.c | 25 +++++++++++++++++++++++-- block/blk-mq.c | 6 +----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 1630a20d5dcfa5..6774a0e6986759 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -15,6 +15,26 @@ static void blk_mq_sysfs_release(struct kobject *kobj) { + struct request_queue *q; + + q = container_of(kobj, struct request_queue, mq_kobj); + free_percpu(q->queue_ctx); +} + +static void blk_mq_ctx_release(struct kobject *kobj) +{ + struct blk_mq_ctx *ctx; + + ctx = container_of(kobj, struct blk_mq_ctx, kobj); + kobject_put(&ctx->queue->mq_kobj); +} + +static void blk_mq_hctx_release(struct kobject *kobj) +{ + struct blk_mq_hw_ctx *hctx; + + hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); + kfree(hctx); } struct blk_mq_ctx_sysfs_entry { @@ -318,13 +338,13 @@ static struct kobj_type blk_mq_ktype = { static struct kobj_type blk_mq_ctx_ktype = { .sysfs_ops = &blk_mq_sysfs_ops, .default_attrs = default_ctx_attrs, - .release = blk_mq_sysfs_release, + .release = blk_mq_ctx_release, }; static struct kobj_type blk_mq_hw_ktype = { .sysfs_ops = &blk_mq_hw_sysfs_ops, .default_attrs = default_hw_ctx_attrs, - .release = blk_mq_sysfs_release, + .release = blk_mq_hctx_release, }; static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx) @@ -355,6 +375,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) return ret; hctx_for_each_ctx(hctx, ctx, i) { + kobject_get(&q->mq_kobj); ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); if (ret) break; diff --git a/block/blk-mq.c b/block/blk-mq.c index 2f95747c287eac..9ee3b87c44984d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1641,10 +1641,8 @@ static void blk_mq_free_hw_queues(struct request_queue *q, struct blk_mq_hw_ctx *hctx; unsigned int i; - queue_for_each_hw_ctx(q, hctx, i) { + queue_for_each_hw_ctx(q, hctx, i) free_cpumask_var(hctx->cpumask); - kfree(hctx); - } } static int blk_mq_init_hctx(struct request_queue *q, @@ -2002,11 +2000,9 @@ void blk_mq_free_queue(struct request_queue *q) percpu_ref_exit(&q->mq_usage_counter); - free_percpu(q->queue_ctx); kfree(q->queue_hw_ctx); kfree(q->mq_map); - q->queue_ctx = NULL; q->queue_hw_ctx = NULL; q->mq_map = NULL; From bbd5900935be8755b6344386373174b20cd474a2 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 16 Oct 2014 11:44:15 +0800 Subject: [PATCH 33/66] watchdog: imx2_wdt: Improve power management support. Improve power management operations(suspend and resume) as part of dev_pm_ops for IMX2 watchdog driver. If PM will be supported, please make sure that the wdev->clk could disable the watchdog's counter input clock source or can mask watchdog's reset request to the core. If watchdog is still used by consumers and resumes from deep sleep state, we need to restart the watchdog again without enabling the timer. If watchdog been has started --> stopped by the consumers and resumes from non-deep sleep state, then start the timer again. If watchdog has been started --> stopped by the consumers and resumes from deep sleep state, will do nothing. The watchdog will be restarted by consumers next time to be used. Signed-off-by: Xiubo Li Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx2_wdt.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index d6add516a7a763..c50c7d85689fd7 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -327,18 +327,21 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -/* Disable watchdog if it is active during suspend */ +/* Disable watchdog if it is active or non-active but still running */ static int imx2_wdt_suspend(struct device *dev) { struct watchdog_device *wdog = dev_get_drvdata(dev); struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); - imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); - imx2_wdt_ping(wdog); + /* The watchdog IP block is running */ + if (imx2_wdt_is_running(wdev)) { + imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); + imx2_wdt_ping(wdog); - /* Watchdog has been stopped but IP block is still running */ - if (!watchdog_active(wdog) && imx2_wdt_is_running(wdev)) - del_timer_sync(&wdev->timer); + /* The watchdog is not active */ + if (!watchdog_active(wdog)) + del_timer_sync(&wdev->timer); + } clk_disable_unprepare(wdev->clk); @@ -354,15 +357,25 @@ static int imx2_wdt_resume(struct device *dev) clk_prepare_enable(wdev->clk); if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) { - /* Resumes from deep sleep we need restart - * the watchdog again. + /* + * If the watchdog is still active and resumes + * from deep sleep state, need to restart the + * watchdog again. */ imx2_wdt_setup(wdog); imx2_wdt_set_timeout(wdog, wdog->timeout); imx2_wdt_ping(wdog); } else if (imx2_wdt_is_running(wdev)) { + /* Resuming from non-deep sleep state. */ + imx2_wdt_set_timeout(wdog, wdog->timeout); imx2_wdt_ping(wdog); - mod_timer(&wdev->timer, jiffies + wdog->timeout * HZ / 2); + /* + * But the watchdog is not active, then start + * the timer again. + */ + if (!watchdog_active(wdog)) + mod_timer(&wdev->timer, + jiffies + wdog->timeout * HZ / 2); } return 0; From 5fe65ce7ccbb47b16e17a88bcdac73cffadb80fa Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Mon, 8 Sep 2014 09:14:07 +0200 Subject: [PATCH 34/66] watchdog: imx2_wdt: Disable power down counter on boot Disable power down counter of the watchdog to avoid system resets. The watchdog power down counter is set automatically by the chip. If it is not set to 0 in the driver, the system resets. Signed-off-by: Markus Pargmann Acked-by: Shawn Guo Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx2_wdt.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index c50c7d85689fd7..5142bbabe0279f 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -52,6 +52,8 @@ #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ #define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ +#define IMX2_WDT_WMCR 0x08 /* Misc Register */ + #define IMX2_WDT_MAX_TIME 128 #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ @@ -274,6 +276,13 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) imx2_wdt_ping_if_active(wdog); + /* + * Disable the watchdog power down counter at boot. Otherwise the power + * down counter will pull down the #WDOG interrupt line for one clock + * cycle. + */ + regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); + ret = watchdog_register_device(wdog); if (ret) { dev_err(&pdev->dev, "cannot register watchdog device\n"); From 7a32757eda68a53626f003018733d09f94138334 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 21 Dec 2014 22:14:43 +0100 Subject: [PATCH 35/66] watchdog: drop owner assignment from platform_drivers This platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/cadence_wdt.c | 1 - drivers/watchdog/meson_wdt.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 5927c0a98a74b2..bcfd2a22208f34 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -503,7 +503,6 @@ static struct platform_driver cdns_wdt_driver = { .shutdown = cdns_wdt_shutdown, .driver = { .name = "cdns-wdt", - .owner = THIS_MODULE, .of_match_table = cdns_wdt_of_match, .pm = &cdns_wdt_pm_ops, }, diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index ef6a298e8c4583..1f4155ee3404de 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -215,7 +215,6 @@ static struct platform_driver meson_wdt_driver = { .remove = meson_wdt_remove, .shutdown = meson_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = meson_wdt_dt_ids, }, From 3cb99af5ea00da4ef3db31b45c4efaff1664c181 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Dec 2014 14:02:57 -0300 Subject: [PATCH 36/66] [media] tlg2300: Fix media dependencies X-Patchwork-Delegate: m.chehab@samsung.com Changeset ea2e813e8cc3 moved the driver to staging, but it forgot to preserve the existing dependency. Fixes: ea2e813e8cc3 ("[media] tlg2300: move to staging in preparation for removal") Reported-by: Jim Davis Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/tlg2300/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/tlg2300/Kconfig b/drivers/staging/media/tlg2300/Kconfig index 81784c6f7b8872..77d8753f6ba40d 100644 --- a/drivers/staging/media/tlg2300/Kconfig +++ b/drivers/staging/media/tlg2300/Kconfig @@ -1,6 +1,7 @@ config VIDEO_TLG2300 tristate "Telegent TLG2300 USB video capture support (Deprecated)" depends on VIDEO_DEV && I2C && SND && DVB_CORE + depends on MEDIA_USB_SUPPORT select VIDEO_TUNER select VIDEO_TVEEPROM depends on RC_CORE From 721f3223f26bbe81c7e55f84188e74d99df50a16 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Mon, 22 Dec 2014 19:51:39 -0300 Subject: [PATCH 37/66] [media] cx23885: Split Hauppauge WinTV Starburst from HVR4400 card entry Unconditionally attaching Si2161/Si2165 demod driver breaks Hauppauge WinTV Starburst. So create own card entry for this. Add card name comments to the subsystem ids. This fixes a regression introduced in 3.17 by 36efec48e2e6016e05364906720a0ec350a5d768 ([media] cx23885: Add si2165 support for HVR-5500) Signed-off-by: Matthias Schwarzott Tested-by: Antti Palosaari Signed-off-by: Hans Verkuil CC: stable@vger.kernel.org # for 3.17 and upper Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 23 +++++++++++++++++------ drivers/media/pci/cx23885/cx23885-dvb.c | 11 +++++++++++ drivers/media/pci/cx23885/cx23885.h | 1 + 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index db99ca2613ba42..06931f6fa26cc0 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -614,7 +614,7 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR4400] = { - .name = "Hauppauge WinTV-HVR4400", + .name = "Hauppauge WinTV-HVR4400/HVR5500", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, @@ -622,6 +622,10 @@ struct cx23885_board cx23885_boards[] = { .tuner_addr = 0x60, /* 0xc0 >> 1 */ .tuner_bus = 1, }, + [CX23885_BOARD_HAUPPAUGE_STARBURST] = { + .name = "Hauppauge WinTV Starburst", + .portb = CX23885_MPEG_DVB, + }, [CX23885_BOARD_AVERMEDIA_HC81R] = { .name = "AVerTV Hybrid Express Slim HC81R", .tuner_type = TUNER_XC2028, @@ -936,19 +940,19 @@ struct cx23885_subid cx23885_subids[] = { }, { .subvendor = 0x0070, .subdevice = 0xc108, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-4400 (Model 121xxx, Hybrid DVB-T/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc138, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc12a, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_STARBURST, /* Hauppauge WinTV Starburst (Model 121x00, DVB-S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc1f8, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x1461, .subdevice = 0xd939, @@ -1545,8 +1549,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: /* GPIO-8 tda10071 demod reset */ - /* GPIO-9 si2165 demod reset */ + /* GPIO-9 si2165 demod reset (only HVR4400/HVR5500)*/ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); @@ -1872,6 +1877,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); @@ -1980,6 +1986,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T982: ts1->gen_ctrl_val = 0x5; /* Parallel */ diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index c47d18270cfc88..a9c450d4b54e4a 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1710,6 +1710,17 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + i2c_bus = &dev->i2c_bus[0]; + fe0->dvb.frontend = dvb_attach(tda10071_attach, + &hauppauge_tda10071_config, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(a8293_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_a8293_config); + } + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S950: i2c_bus = &dev->i2c_bus[0]; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f55cd12da0fde3..36f2f96c40e436 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -99,6 +99,7 @@ #define CX23885_BOARD_DVBSKY_S950 49 #define CX23885_BOARD_DVBSKY_S952 50 #define CX23885_BOARD_DVBSKY_T982 51 +#define CX23885_BOARD_HAUPPAUGE_STARBURST 52 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 From d0bb12c9f4811b8a8c0a87ac1b5fbab19861e7e0 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Fri, 2 Jan 2015 14:55:17 -0300 Subject: [PATCH 38/66] [media] Fix Mygica T230 support Commit 2adb177e57417cf8409e86bda2c516e5f99a2099 removed 2 devices from the cxusb device table but failed to fix up the T230 properties that follow, meaning that this device no longer gets detected properly. Adjust the cxusb_table index appropriate so detection works. Signed-off-by: Jonathan McDowell Reviewed-by: Olli Salonen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cxusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 0f345b1f90145d..f327c49d7e0936 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -2232,7 +2232,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { { "Mygica T230 DVB-T/T2/C", { NULL }, - { &cxusb_table[22], NULL }, + { &cxusb_table[20], NULL }, }, } }; From 7d96c3e446b4a786a6a4a7733deb9d1634a9ad4d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 18 Jan 2015 16:30:11 -0300 Subject: [PATCH 39/66] [media] soc-camera: fix device capabilities in multiple camera host drivers The V4L2 API requires both .capabilities and .device_caps fields of struct v4l2_capability to be set. Otherwise the compliance checker complains and since commit "v4l2-ioctl: WARN_ON if querycap didn't fill device_caps" a compile-time warning is issued. Fix this non-compliance in several soc-camera camera host drivers. Reported-by: Geert Uytterhoeven Signed-off-by: Guennadi Liakhovetski Tested-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/atmel-isi.c | 5 +++-- drivers/media/platform/soc_camera/mx2_camera.c | 3 ++- drivers/media/platform/soc_camera/mx3_camera.c | 3 ++- drivers/media/platform/soc_camera/omap1_camera.c | 3 ++- drivers/media/platform/soc_camera/pxa_camera.c | 3 ++- drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 4 +++- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ee5650f4ea2df7..494447fcdc8b4f 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -760,8 +760,9 @@ static int isi_camera_querycap(struct soc_camera_host *ici, { strcpy(cap->driver, "atmel-isi"); strcpy(cap->card, "Atmel Image Sensor Interface"); - cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ce72bd26a6acae..192377f55840b5 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1256,7 +1256,8 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 8e52ccce66deae..000d0231991f73 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -967,7 +967,8 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index e6b93281f246c3..16f65ecb70a3e1 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1427,7 +1427,8 @@ static int omap1_cam_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 951226af0ebacc..8d6e343fec0f28 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1576,7 +1576,8 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 5f58ed9953208c..ca6283930f8576 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1652,7 +1652,9 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } From 42d74e4fe6508308abc1baac95ba36ad0cc5143e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 13 Jan 2015 21:55:02 -0300 Subject: [PATCH 40/66] [media] rcar_vin: Update device_caps and capabilities in querycap The V4L2 API requires both .capabilities and .device_caps fields of struct v4l2_capability to be set. Otherwise the compliance checker complains and since commit "v4l2-ioctl: WARN_ON if querycap didn't fill device_caps" a compile-time warning is issued. Fix this non-compliance in the rcar_vin driver. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/rcar_vin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 44461c5552aad5..9c28278a32d546 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1799,7 +1799,9 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } From 6cf11ee6300f38b7cfc43af9b7be2afaa5e05869 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 06:16:18 -0300 Subject: [PATCH 41/66] [media] vb2: fix vb2_thread_stop race conditions The locking scheme inside the vb2 thread is unsafe when stopping the thread. In particular kthread_stop was called *after* internal data structures were cleaned up instead of doing that before. In addition, internal vb2 functions were called after threadio->stop was set to true and vb2_internal_streamoff was called. This is also not allowed. All this led to a variety of race conditions and kernel warnings and/or oopses. Fixed by moving the kthread_stop call up before the cleanup takes place, and by checking threadio->stop before calling internal vb2 queuing operations. Signed-off-by: Hans Verkuil Cc: # for v3.16 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a8916e94005..bc08a829bc1320 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -3146,27 +3146,26 @@ static int vb2_thread(void *data) prequeue--; } else { call_void_qop(q, wait_finish, q); - ret = vb2_internal_dqbuf(q, &fileio->b, 0); + if (!threadio->stop) + ret = vb2_internal_dqbuf(q, &fileio->b, 0); call_void_qop(q, wait_prepare, q); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); } - if (threadio->stop) - break; - if (ret) + if (ret || threadio->stop) break; try_to_freeze(); vb = q->bufs[fileio->b.index]; if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) - ret = threadio->fnc(vb, threadio->priv); - if (ret) - break; + if (threadio->fnc(vb, threadio->priv)) + break; call_void_qop(q, wait_finish, q); if (set_timestamp) v4l2_get_timestamp(&fileio->b.timestamp); - ret = vb2_internal_qbuf(q, &fileio->b); + if (!threadio->stop) + ret = vb2_internal_qbuf(q, &fileio->b); call_void_qop(q, wait_prepare, q); - if (ret) + if (ret || threadio->stop) break; } @@ -3235,11 +3234,11 @@ int vb2_thread_stop(struct vb2_queue *q) threadio->stop = true; vb2_internal_streamoff(q, q->type); call_void_qop(q, wait_prepare, q); + err = kthread_stop(threadio->thread); q->fileio = NULL; fileio->req.count = 0; vb2_reqbufs(q, &fileio->req); kfree(fileio); - err = kthread_stop(threadio->thread); threadio->thread = NULL; kfree(threadio); q->fileio = NULL; From 42639f6de69433cd531c79390fd8eccf311ed44e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 06:23:26 -0300 Subject: [PATCH 42/66] [media] pvrusb2: fix missing device_caps in querycap The VIDIOC_QUERYCAP function should set device_caps, but this was missing. In addition, it set the version field as well, but that should be done by the core, not by the driver. If a driver doesn't set device_caps the v4l2 core will issue a WARN_ON, so it's important that this is set correctly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 1b158f1167ed07..536210b39428c9 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -89,16 +89,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; module_param_array(vbi_nr, int, NULL, 0444); MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); -static struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = LINUX_VERSION_CODE, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_READWRITE), -}; - static struct v4l2_fmtdesc pvr_fmtdesc [] = { { .index = 0, @@ -160,10 +150,22 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability * struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); + strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver)); strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), sizeof(cap->bus_info)); strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_RADIO | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + switch (fh->pdi->devbase.vfl_type) { + case VFL_TYPE_GRABBER: + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; + break; + case VFL_TYPE_RADIO: + cap->device_caps = V4L2_CAP_RADIO; + break; + } + cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE; return 0; } From 8d4d9329cde6ff5369656d7d50630d8aac907bfa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 07:14:14 -0300 Subject: [PATCH 43/66] [media] cx23885: fix free interrupt bug First free the interrupt, then disable the PCI device. The other way around will lead to this warning: Jan 19 11:42:02 telek kernel: [ 1440.161234] WARNING: CPU: 0 PID: 2191 at kernel/irq/manage.c:1311 __free_irq+0x97/0x1f0() Jan 19 11:42:02 telek kernel: [ 1440.161236] Trying to free already-free IRQ 0 Jan 19 11:42:02 telek kernel: [ 1440.161237] Modules linked in: tda8290 tda10048 cx25840 cx23885(-) altera_ci tda18271 altera_stapl videobuf2_dvb tveeprom cx2341x videobuf2_dma_sg dvb_core rc_core videobuf2_memops videobuf2_core v4l2_common videodev media nouveau x86_pkg_temp_thermal cfbfillrect cfbimgblt cfbcopyarea ttm drm_kms_helper processor button isci Jan 19 11:42:02 telek kernel: [ 1440.161266] CPU: 0 PID: 2191 Comm: rmmod Tainted: G W 3.19.0-rc1-telek #345 Jan 19 11:42:02 telek kernel: [ 1440.161268] Hardware name: ASUSTeK COMPUTER INC. Z9PE-D8 WS/Z9PE-D8 WS, BIOS 5404 02/10/2014 Jan 19 11:42:02 telek kernel: [ 1440.161270] ffffffff81bf1fce ffff8808958b7cc8 ffffffff8194a97f 0000000000000000 Jan 19 11:42:02 telek kernel: [ 1440.161274] ffff8808958b7d18 ffff8808958b7d08 ffffffff810c56b0 0000000000000286 Jan 19 11:42:02 telek kernel: [ 1440.161279] 0000000000000000 0000000000000000 ffff88089f808890 ffff88089f808800 Jan 19 11:42:02 telek kernel: [ 1440.161284] Call Trace: Jan 19 11:42:02 telek kernel: [ 1440.161290] [] dump_stack+0x4f/0x7b Jan 19 11:42:02 telek kernel: [ 1440.161295] [] warn_slowpath_common+0x80/0xc0 Jan 19 11:42:02 telek kernel: [ 1440.161299] [] warn_slowpath_fmt+0x41/0x50 Jan 19 11:42:02 telek kernel: [ 1440.161303] [] ? _raw_spin_lock_irqsave+0x56/0x70 Jan 19 11:42:02 telek kernel: [ 1440.161307] [] ? __free_irq+0x49/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161311] [] __free_irq+0x97/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161316] [] free_irq+0x48/0xd0 Jan 19 11:42:02 telek kernel: [ 1440.161323] [] cx23885_finidev+0x4b/0x90 [cx23885] Jan 19 11:42:02 telek kernel: [ 1440.161329] [] pci_device_remove+0x3a/0xc0 Jan 19 11:42:02 telek kernel: [ 1440.161334] [] __device_release_driver+0x7a/0xf0 Jan 19 11:42:02 telek kernel: [ 1440.161338] [] driver_detach+0xc8/0xd0 Jan 19 11:42:02 telek kernel: [ 1440.161341] [] bus_remove_driver+0x4e/0xb0 Jan 19 11:42:02 telek kernel: [ 1440.161345] [] driver_unregister+0x2b/0x60 Jan 19 11:42:02 telek kernel: [ 1440.161349] [] pci_unregister_driver+0x25/0x70 Jan 19 11:42:02 telek kernel: [ 1440.161355] [] cx23885_fini+0x10/0x12 [cx23885] Jan 19 11:42:02 telek kernel: [ 1440.161360] [] SyS_delete_module+0x1a8/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161364] [] system_call_fastpath+0x12/0x17 Jan 19 11:42:02 telek kernel: [ 1440.161367] ---[ end trace a9c07cb5f3357020 ]--- Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index d07b04a5ce36e7..eadb65e2d61cae 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2049,11 +2049,11 @@ static void cx23885_finidev(struct pci_dev *pci_dev) cx23885_shutdown(dev); - pci_disable_device(pci_dev); - /* unregister stuff */ free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev); + cx23885_dev_unregister(dev); vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); v4l2_ctrl_handler_free(&dev->ctrl_handler); From 2c0108e1c02f9fc95f465adc4d2ce1ad8688290a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 1 Jan 2015 18:13:54 -0300 Subject: [PATCH 44/66] [media] omap3isp: Correctly set QUERYCAP capabilities device_caps in struct v4l2_capability were inadequately set in VIDIOC_QUERYCAP. Fix this. Without this a WARN_ON in the v4l2 core is triggered. This WARN_ON was added for kernel 3.19 exactly to detect these situations. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispvideo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index b463fe172d164a..3fe9047ef466fa 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -602,10 +602,13 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) strlcpy(cap->card, video->video.name, sizeof(cap->card)); strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; else - cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; return 0; } From 6d310dfb382a303cbaf838e1b680f55cef18ae03 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 22 Jan 2015 11:20:40 +0000 Subject: [PATCH 45/66] scsi_debug: test always evaluates to false, || should be used instead cppcheck found the following issue: (warning) Logical conjunction always evaluates to false: alloc_len < 4 && alloc_len > 65535. ..the test should be instead: if (alloc_len < 4 || alloc_len > 65536) This error was introduced by recent commit 38d5c8336e60bf6e53a1da9 ("scsi_debug: add Report supported opcodes+tmfs; Compare and write") Signed-off-by: Colin Ian King Acked-by: Douglas Gilbert Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9a74f425db9321..4aca1b0378c245 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1623,7 +1623,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) req_opcode = cmd[3]; req_sa = get_unaligned_be16(cmd + 4); alloc_len = get_unaligned_be32(cmd + 6); - if (alloc_len < 4 && alloc_len > 0xffff) { + if (alloc_len < 4 || alloc_len > 0xffff) { mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); return check_condition_result; } From 2a5a69d8f79bfe1c98ee59cc91e9e743290c5d4e Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 21 Jan 2015 09:13:41 -0700 Subject: [PATCH 46/66] MAINTAINERS: Remove self as isci maintainer Removing myself as a maintainer. Signed-off-by: Dave Jiang Signed-off-by: Christoph Hellwig --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f6dee56ac3df25..5daac16f49a5df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4951,7 +4951,6 @@ K: \b(ABS|SYN)_MT_ INTEL C600 SERIES SAS CONTROLLER DRIVER M: Intel SCU Linux support M: Artur Paszkiewicz -M: Dave Jiang L: linux-scsi@vger.kernel.org T: git git://git.code.sf.net/p/intel-sas/isci S: Supported From 44b4dad9b5719f28ce1635d4c2dc08c398a1815b Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Mon, 12 Jan 2015 16:31:35 -0800 Subject: [PATCH 47/66] MAINTAINERS: ibmvfc driver maintainer change Change maintainer of ibmvfc driver to Tyrel Datwyler. Signed-off-by: Tyrel Datwyler Cc: Nathan Fontenot Cc: Brian King Signed-off-by: Christoph Hellwig --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5daac16f49a5df..047582f78d0e1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4761,7 +4761,7 @@ F: drivers/scsi/ibmvscsi/ibmvscsi* F: drivers/scsi/ibmvscsi/viosrp.h IBM Power Virtual FC Device Drivers -M: Brian King +M: Tyrel Datwyler L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ibmvscsi/ibmvfc* From bcbde52b14b70c6b3d500e8d18c261d7b1c6fed3 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Mon, 12 Jan 2015 16:31:34 -0800 Subject: [PATCH 48/66] MAINTAINERS: ibmvscsi driver maintainer change Change maintainer of ibmvscsi driver to Tyrel Datwyler. Signed-off-by: Tyrel Datwyler Acked-by: Nathan Fontenot Cc: Brian King Signed-off-by: Christoph Hellwig --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 047582f78d0e1b..2a97e05e1f4d5f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4754,7 +4754,7 @@ S: Supported F: drivers/net/ethernet/ibm/ibmveth.* IBM Power Virtual SCSI Device Drivers -M: Nathan Fontenot +M: Tyrel Datwyler L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ibmvscsi/ibmvscsi* From 814564a0a1d2faee11ff9de43245d78cb79c85ac Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:20 -0800 Subject: [PATCH 49/66] x86, mpx: Explicitly disable 32-bit MPX support on 64-bit kernels We had originally planned on submitting MPX support in one patch set. We eventually broke it up in to two pieces for easier review. One of the features that didn't make the first round was supporting 32-bit binaries on 64-bit kernels. Once we split the set up, we never added code to restrict 32-bit binaries from _using_ MPX on 64-bit kernels. The 32-bit bounds tables are a different format than the 64-bit ones. Without this patch, the kernel will try to read a 32-bit binary's tables as if they were the 64-bit version. They will likely be noticed as being invalid rather quickly and the app will get killed, but that's kinda mean. This patch adds an explicit check, and will make a 64-bit kernel essentially behave as if it has no MPX support when called from a 32-bit binary. Signed-off-by: Dave Hansen Cc: Andy Lutomirski Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223020.9E9AA511@viggo.jf.intel.com Signed-off-by: Thomas Gleixner --- arch/x86/mm/mpx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index 67ebf57512229a..c439ec47821601 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c @@ -348,6 +348,12 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk) if (!cpu_feature_enabled(X86_FEATURE_MPX)) return MPX_INVALID_BOUNDS_DIR; + /* + * 32-bit binaries on 64-bit kernels are currently + * unsupported. + */ + if (IS_ENABLED(CONFIG_X86_64) && test_thread_flag(TIF_IA32)) + return MPX_INVALID_BOUNDS_DIR; /* * The bounds directory pointer is stored in a register * only accessible if we first do an xsave. From c922228efeeefa32e57f875764bfa6ca8053a68a Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:21 -0800 Subject: [PATCH 50/66] x86, mpx: Fix potential performance issue on unmaps The 3.19 merge window saw some TLB modifications merged which caused a performance regression. They were fixed in commit 045bbb9fa. Once that fix was applied, I also noticed that there was a small but intermittent regression still present. It was not present consistently enough to bisect reliably, but I'm fairly confident that it came from (my own) MPX patches. The source was reading a relatively unused field in the mm_struct via arch_unmap. I also noted that this code was in the main instruction flow of do_munmap() and probably had more icache impact than we want. This patch does two things: 1. Adds a static (via Kconfig) and dynamic (via cpuid) check for MPX with cpu_feature_enabled(). This keeps us from reading that cacheline in the mm and trades it for a check of the global CPUID variables at least on CPUs without MPX. 2. Adds an unlikely() to ensure that the MPX call ends up out of the main instruction flow in do_munmap(). I've added a detailed comment about why this was done and why we want it even on systems where MPX is present. Signed-off-by: Dave Hansen Cc: luto@amacapital.net Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223021.AEEAB987@viggo.jf.intel.com Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/mmu_context.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 40269a2bf6f90f..4b75d591eb5ed1 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -130,7 +130,25 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end) { - mpx_notify_unmap(mm, vma, start, end); + /* + * mpx_notify_unmap() goes and reads a rarely-hot + * cacheline in the mm_struct. That can be expensive + * enough to be seen in profiles. + * + * The mpx_notify_unmap() call and its contents have been + * observed to affect munmap() performance on hardware + * where MPX is not present. + * + * The unlikely() optimizes for the fast case: no MPX + * in the CPU, or no MPX use in the process. Even if + * we get this wrong (in the unlikely event that MPX + * is widely enabled on some system) the overhead of + * MPX itself (reading bounds tables) is expected to + * overwhelm the overhead of getting this unlikely() + * consistently wrong. + */ + if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX))) + mpx_notify_unmap(mm, vma, start, end); } #endif /* _ASM_X86_MMU_CONTEXT_H */ From e9d1b4f3c60997fe197bf0243cb4a41a44387a88 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:22 -0800 Subject: [PATCH 51/66] x86, mpx: Strictly enforce empty prctl() args Description from Michael Kerrisk. He suggested an identical patch to one I had already coded up and tested. commit fe3d197f8431 "x86, mpx: On-demand kernel allocation of bounds tables" added two new prctl() operations, PR_MPX_ENABLE_MANAGEMENT and PR_MPX_DISABLE_MANAGEMENT. However, no checks were included to ensure that unused arguments are zero, as is done in many existing prctl()s and as should be done for all new prctl()s. This patch adds the required checks. Suggested-by: Andy Lutomirski Suggested-by: Michael Kerrisk Signed-off-by: Dave Hansen Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223022.7F56FD13@viggo.jf.intel.com Signed-off-by: Thomas Gleixner --- kernel/sys.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/sys.c b/kernel/sys.c index a8c9f5a7dda68f..ea9c881098941e 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2210,9 +2210,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, up_write(&me->mm->mmap_sem); break; case PR_MPX_ENABLE_MANAGEMENT: + if (arg2 || arg3 || arg4 || arg5) + return -EINVAL; error = MPX_ENABLE_MANAGEMENT(me); break; case PR_MPX_DISABLE_MANAGEMENT: + if (arg2 || arg3 || arg4 || arg5) + return -EINVAL; error = MPX_DISABLE_MANAGEMENT(me); break; default: From e30ab185c490e9a9381385529e0fd32f0a399495 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 22 Jan 2015 11:27:58 -0800 Subject: [PATCH 52/66] x86, tls, ldt: Stop checking lm in LDT_empty 32-bit programs don't have an lm bit in their ABI, so they can't reliably cause LDT_empty to return true without resorting to memset. They shouldn't need to do this. This should fix a longstanding, if minor, issue in all 64-bit kernels as well as a potential regression in the TLS hardening code. Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix Cc: stable@vger.kernel.org Signed-off-by: Andy Lutomirski Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/72a059de55e86ad5e2935c80aa91880ddf19d07c.1421954363.git.luto@amacapital.net Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/desc.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 50d033a8947db6..fc237fd0259a9b 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#define _LDT_empty(info) \ +/* This intentionally ignores lm, since 32-bit apps don't have that field. */ +#define LDT_empty(info) \ ((info)->base_addr == 0 && \ (info)->limit == 0 && \ (info)->contents == 0 && \ @@ -261,12 +262,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) (info)->seg_not_present == 1 && \ (info)->useable == 0) -#ifdef CONFIG_X86_64 -#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) -#else -#define LDT_empty(info) (_LDT_empty(info)) -#endif - static inline void clear_LDT(void) { set_ldt(NULL, 0); From 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 22 Jan 2015 11:27:59 -0800 Subject: [PATCH 53/66] x86, tls: Interpret an all-zero struct user_desc as "no segment" The Witcher 2 did something like this to allocate a TLS segment index: struct user_desc u_info; bzero(&u_info, sizeof(u_info)); u_info.entry_number = (uint32_t)-1; syscall(SYS_set_thread_area, &u_info); Strictly speaking, this code was never correct. It should have set read_exec_only and seg_not_present to 1 to indicate that it wanted to find a free slot without putting anything there, or it should have put something sensible in the TLS slot if it wanted to allocate a TLS entry for real. The actual effect of this code was to allocate a bogus segment that could be used to exploit espfix. The set_thread_area hardening patches changed the behavior, causing set_thread_area to return -EINVAL and crashing the game. This changes set_thread_area to interpret this as a request to find a free slot and to leave it empty, which isn't *quite* what the game expects but should be close enough to keep it working. In particular, using the code above to allocate two segments will allocate the same segment both times. According to FrostbittenKing on Github, this fixes The Witcher 2. If this somehow still causes problems, we could instead allocate a limit==0 32-bit data segment, but that seems rather ugly to me. Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix Signed-off-by: Andy Lutomirski Cc: stable@vger.kernel.org Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/0cb251abe1ff0958b8e468a9a9a905b80ae3a746.1421954363.git.luto@amacapital.net Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/desc.h | 13 +++++++++++++ arch/x86/kernel/tls.c | 25 +++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index fc237fd0259a9b..a94b82e8f156f3 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -262,6 +262,19 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) (info)->seg_not_present == 1 && \ (info)->useable == 0) +/* Lots of programs expect an all-zero user_desc to mean "no segment at all". */ +static inline bool LDT_zero(const struct user_desc *info) +{ + return (info->base_addr == 0 && + info->limit == 0 && + info->contents == 0 && + info->read_exec_only == 0 && + info->seg_32bit == 0 && + info->limit_in_pages == 0 && + info->seg_not_present == 0 && + info->useable == 0); +} + static inline void clear_LDT(void) { set_ldt(NULL, 0); diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 4e942f31b1a7c9..7fc5e843f247b3 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -29,7 +29,28 @@ static int get_free_idx(void) static bool tls_desc_okay(const struct user_desc *info) { - if (LDT_empty(info)) + /* + * For historical reasons (i.e. no one ever documented how any + * of the segmentation APIs work), user programs can and do + * assume that a struct user_desc that's all zeros except for + * entry_number means "no segment at all". This never actually + * worked. In fact, up to Linux 3.19, a struct user_desc like + * this would create a 16-bit read-write segment with base and + * limit both equal to zero. + * + * That was close enough to "no segment at all" until we + * hardened this function to disallow 16-bit TLS segments. Fix + * it up by interpreting these zeroed segments the way that they + * were almost certainly intended to be interpreted. + * + * The correct way to ask for "no segment at all" is to specify + * a user_desc that satisfies LDT_empty. To keep everything + * working, we accept both. + * + * Note that there's a similar kludge in modify_ldt -- look at + * the distinction between modes 1 and 0x11. + */ + if (LDT_empty(info) || LDT_zero(info)) return true; /* @@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, cpu = get_cpu(); while (n-- > 0) { - if (LDT_empty(info)) + if (LDT_empty(info) || LDT_zero(info)) desc->a = desc->b = 0; else fill_ldt(desc, info); From 31bb7723706ba9660504a6c3903ea46198f98fd1 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 22 Jan 2015 12:43:17 +0100 Subject: [PATCH 54/66] x86, mm: Change cachemode exports to non-gpl Commit 281d4078bec3 ("x86: Make page cache mode a real type") introduced the symbols __cachemode2pte_tbl and __pte2cachemode_tbl and exported them via EXPORT_SYMBOL_GPL. The exports are part of a replacement of code which has been EXPORT_SYMBOL before these changes resulting in build breakage of out-of-tree non-gpl modules. Change EXPORT_SYMBOL_GPL to EXPORT-SYMBOL for these two symbols. Fixes: 281d4078bec3 "x86: Make page cache mode a real type" Reported-and-tested-by: Steven Noonan Signed-off-by: Juergen Gross Reviewed-by: Toshi Kani Link: http://lkml.kernel.org/r/1421926997-28615-1-git-send-email-jgross@suse.com Signed-off-by: Thomas Gleixner --- arch/x86/mm/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 08a7d313538a72..079c3b6a3ff181 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -43,7 +43,7 @@ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WT] = _PAGE_PCD, [_PAGE_CACHE_MODE_WP] = _PAGE_PCD, }; -EXPORT_SYMBOL_GPL(__cachemode2pte_tbl); +EXPORT_SYMBOL(__cachemode2pte_tbl); uint8_t __pte2cachemode_tbl[8] = { [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, @@ -54,7 +54,7 @@ uint8_t __pte2cachemode_tbl[8] = { [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, }; -EXPORT_SYMBOL_GPL(__pte2cachemode_tbl); +EXPORT_SYMBOL(__pte2cachemode_tbl); static unsigned long __initdata pgt_buf_start; static unsigned long __initdata pgt_buf_end; From 38a1dfda8e77d7ba74c94d06d8bc41ba98a4bc8c Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 22 Jan 2015 22:58:49 +0000 Subject: [PATCH 55/66] x86/apic: Re-enable PCI_MSI support for non-SMP X86_32 Commit 0dbc6078c06bc0 ('x86, build, pci: Fix PCI_MSI build on !SMP') introduced the dependency that X86_UP_APIC is only available when PCI_MSI is false. This effectively prevents PCI_MSI support on 32bit UP systems because it disables both APIC and IO-APIC. But APIC support is architecturally required for PCI_MSI. The intention of the patch was to enforce APIC support when PCI_MSI is enabled, but failed to do so. Remove the !PCI_MSI dependency from X86_UP_APIC and enforce X86_UP_APIC when PCI_MSI support is enabled on 32bit UP systems. [ tglx: Massaged changelog ] Fixes 0dbc6078c06bc0 'x86, build, pci: Fix PCI_MSI build on !SMP' Signed-off-by: Bryan O'Donoghue Suggested-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Cc: Thomas Petazzoni Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1421967529-9037-1-git-send-email-pure.logic@nexus-software.ie Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ba397bde794820..0dc9d0144a2795 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -857,7 +857,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI + depends on X86_32 && !SMP && !X86_32_NON_STANDARD ---help--- A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -868,6 +868,10 @@ config X86_UP_APIC performance counters), and the NMI watchdog which detects hard lockups. +config X86_UP_APIC_MSI + def_bool y + select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI + config X86_UP_IOAPIC bool "IO-APIC support on uniprocessors" depends on X86_UP_APIC From 520452172e6b318f3a8bd9d4fe1e25066393de25 Mon Sep 17 00:00:00 2001 From: Alexandre Demers Date: Tue, 9 Dec 2014 01:27:50 -0500 Subject: [PATCH 56/66] x86/tsc: Change Fast TSC calibration failed from error to info Many users see this message when booting without knowning that it is of no importance and that TSC calibration may have succeeded by another way. As explained by Paul Bolle in http://lkml.kernel.org/r/1348488259.1436.22.camel@x61.thuisdomein "Fast TSC calibration failed" should not be considered as an error since other calibration methods are being tried afterward. At most, those send a warning if they fail (not an error). So let's change the message from error to warning. [ tglx: Make if pr_info. It's really not important at all ] Fixes: c767a54ba065 x86/debug: Add KERN_ to bare printks, convert printks to pr_ Signed-off-by: Alexandre Demers Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1418106470-6906-1-git-send-email-alexandre.f.demers@gmail.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/tsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index b7e50bba3bbbb9..505449700e0cf4 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -617,7 +617,7 @@ static unsigned long quick_pit_calibrate(void) goto success; } } - pr_err("Fast TSC calibration failed\n"); + pr_info("Fast TSC calibration failed\n"); return 0; success: From 9b1cc9f251affdd27f29fe46d0989ba76c33faf6 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 23 Jan 2015 10:00:07 +0000 Subject: [PATCH 57/66] dm cache: share cache-metadata object across inactive and active DM tables If a DM table is reloaded with an inactive table when the device is not suspended (normal procedure for LVM2), then there will be two dm-bufio objects that can diverge. This can lead to a situation where the inactive table uses bufio to read metadata at the same time the active table writes metadata -- resulting in the inactive table having stale metadata buffers once it is promoted to the active table slot. Fix this by using reference counting and a global list of cache metadata objects to ensure there is only one metadata object per metadata device. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org --- drivers/md/dm-cache-metadata.c | 101 +++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 9fc616c2755ed7..21b156242e4266 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -94,6 +94,9 @@ struct cache_disk_superblock { } __packed; struct dm_cache_metadata { + atomic_t ref_count; + struct list_head list; + struct block_device *bdev; struct dm_block_manager *bm; struct dm_space_map *metadata_sm; @@ -669,10 +672,10 @@ static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned *flags) /*----------------------------------------------------------------*/ -struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, - sector_t data_block_size, - bool may_format_device, - size_t policy_hint_size) +static struct dm_cache_metadata *metadata_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) { int r; struct dm_cache_metadata *cmd; @@ -683,6 +686,7 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, return NULL; } + atomic_set(&cmd->ref_count, 1); init_rwsem(&cmd->root_lock); cmd->bdev = bdev; cmd->data_block_size = data_block_size; @@ -705,10 +709,95 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, return cmd; } +/* + * We keep a little list of ref counted metadata objects to prevent two + * different target instances creating separate bufio instances. This is + * an issue if a table is reloaded before the suspend. + */ +static DEFINE_MUTEX(table_lock); +static LIST_HEAD(table); + +static struct dm_cache_metadata *lookup(struct block_device *bdev) +{ + struct dm_cache_metadata *cmd; + + list_for_each_entry(cmd, &table, list) + if (cmd->bdev == bdev) { + atomic_inc(&cmd->ref_count); + return cmd; + } + + return NULL; +} + +static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) +{ + struct dm_cache_metadata *cmd, *cmd2; + + mutex_lock(&table_lock); + cmd = lookup(bdev); + mutex_unlock(&table_lock); + + if (cmd) + return cmd; + + cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); + if (cmd) { + mutex_lock(&table_lock); + cmd2 = lookup(bdev); + if (cmd2) { + mutex_unlock(&table_lock); + __destroy_persistent_data_objects(cmd); + kfree(cmd); + return cmd2; + } + list_add(&cmd->list, &table); + mutex_unlock(&table_lock); + } + + return cmd; +} + +static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size) +{ + if (cmd->data_block_size != data_block_size) { + DMERR("data_block_size (%llu) different from that in metadata (%llu)\n", + (unsigned long long) data_block_size, + (unsigned long long) cmd->data_block_size); + return false; + } + + return true; +} + +struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) +{ + struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, + may_format_device, policy_hint_size); + if (cmd && !same_params(cmd, data_block_size)) { + dm_cache_metadata_close(cmd); + return NULL; + } + + return cmd; +} + void dm_cache_metadata_close(struct dm_cache_metadata *cmd) { - __destroy_persistent_data_objects(cmd); - kfree(cmd); + if (atomic_dec_and_test(&cmd->ref_count)) { + mutex_lock(&table_lock); + list_del(&cmd->list); + mutex_unlock(&table_lock); + + __destroy_persistent_data_objects(cmd); + kfree(cmd); + } } /* From a59db67656021fa212e9b95a583f13c34eb67cd9 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 23 Jan 2015 10:16:16 +0000 Subject: [PATCH 58/66] dm cache: fix problematic dual use of a single migration count variable Introduce a new variable to count the number of allocated migration structures. The existing variable cache->nr_migrations became overloaded. It was used to: i) track of the number of migrations in flight for the purposes of quiescing during suspend. ii) to estimate the amount of background IO occuring. Recent discard changes meant that REQ_DISCARD bios are processed with a migration. Discards are not background IO so nr_migrations was not incremented. However this could cause quiescing to complete early. (i) is now handled with a new variable cache->nr_allocated_migrations. cache->nr_migrations has been renamed cache->nr_io_migrations. cleanup_migration() is now called free_io_migration(), since it decrements that variable. Also, remove the unused cache->next_migration variable that got replaced with with prealloc_structs a while ago. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org --- drivers/md/dm-cache-target.c | 89 ++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1e96d7889f51ea..e1650539cc2f82 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -221,7 +221,13 @@ struct cache { struct list_head need_commit_migrations; sector_t migration_threshold; wait_queue_head_t migration_wait; - atomic_t nr_migrations; + atomic_t nr_allocated_migrations; + + /* + * The number of in flight migrations that are performing + * background io. eg, promotion, writeback. + */ + atomic_t nr_io_migrations; wait_queue_head_t quiescing_wait; atomic_t quiescing; @@ -258,7 +264,6 @@ struct cache { struct dm_deferred_set *all_io_ds; mempool_t *migration_pool; - struct dm_cache_migration *next_migration; struct dm_cache_policy *policy; unsigned policy_nr_args; @@ -350,10 +355,31 @@ static void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell *cel dm_bio_prison_free_cell(cache->prison, cell); } +static struct dm_cache_migration *alloc_migration(struct cache *cache) +{ + struct dm_cache_migration *mg; + + mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); + if (mg) { + mg->cache = cache; + atomic_inc(&mg->cache->nr_allocated_migrations); + } + + return mg; +} + +static void free_migration(struct dm_cache_migration *mg) +{ + if (atomic_dec_and_test(&mg->cache->nr_allocated_migrations)) + wake_up(&mg->cache->migration_wait); + + mempool_free(mg, mg->cache->migration_pool); +} + static int prealloc_data_structs(struct cache *cache, struct prealloc *p) { if (!p->mg) { - p->mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); + p->mg = alloc_migration(cache); if (!p->mg) return -ENOMEM; } @@ -382,7 +408,7 @@ static void prealloc_free_structs(struct cache *cache, struct prealloc *p) free_prison_cell(cache, p->cell1); if (p->mg) - mempool_free(p->mg, cache->migration_pool); + free_migration(p->mg); } static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p) @@ -854,24 +880,14 @@ static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, * Migration covers moving data from the origin device to the cache, or * vice versa. *--------------------------------------------------------------*/ -static void free_migration(struct dm_cache_migration *mg) -{ - mempool_free(mg, mg->cache->migration_pool); -} - -static void inc_nr_migrations(struct cache *cache) +static void inc_io_migrations(struct cache *cache) { - atomic_inc(&cache->nr_migrations); + atomic_inc(&cache->nr_io_migrations); } -static void dec_nr_migrations(struct cache *cache) +static void dec_io_migrations(struct cache *cache) { - atomic_dec(&cache->nr_migrations); - - /* - * Wake the worker in case we're suspending the target. - */ - wake_up(&cache->migration_wait); + atomic_dec(&cache->nr_io_migrations); } static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, @@ -894,11 +910,10 @@ static void cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, wake_worker(cache); } -static void cleanup_migration(struct dm_cache_migration *mg) +static void free_io_migration(struct dm_cache_migration *mg) { - struct cache *cache = mg->cache; + dec_io_migrations(mg->cache); free_migration(mg); - dec_nr_migrations(cache); } static void migration_failure(struct dm_cache_migration *mg) @@ -923,7 +938,7 @@ static void migration_failure(struct dm_cache_migration *mg) cell_defer(cache, mg->new_ocell, true); } - cleanup_migration(mg); + free_io_migration(mg); } static void migration_success_pre_commit(struct dm_cache_migration *mg) @@ -934,7 +949,7 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) if (mg->writeback) { clear_dirty(cache, mg->old_oblock, mg->cblock); cell_defer(cache, mg->old_ocell, false); - cleanup_migration(mg); + free_io_migration(mg); return; } else if (mg->demote) { @@ -944,14 +959,14 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) mg->old_oblock); if (mg->promote) cell_defer(cache, mg->new_ocell, true); - cleanup_migration(mg); + free_io_migration(mg); return; } } else { if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); policy_remove_mapping(cache->policy, mg->new_oblock); - cleanup_migration(mg); + free_io_migration(mg); return; } } @@ -984,7 +999,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) } else { if (mg->invalidate) policy_remove_mapping(cache->policy, mg->old_oblock); - cleanup_migration(mg); + free_io_migration(mg); } } else { @@ -999,7 +1014,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) bio_endio(mg->new_ocell->holder, 0); cell_defer(cache, mg->new_ocell, false); } - cleanup_migration(mg); + free_io_migration(mg); } } @@ -1251,7 +1266,7 @@ static void promote(struct cache *cache, struct prealloc *structs, mg->new_ocell = cell; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1275,7 +1290,7 @@ static void writeback(struct cache *cache, struct prealloc *structs, mg->new_ocell = NULL; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1302,7 +1317,7 @@ static void demote_then_promote(struct cache *cache, struct prealloc *structs, mg->new_ocell = new_ocell; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1330,7 +1345,7 @@ static void invalidate(struct cache *cache, struct prealloc *structs, mg->new_ocell = NULL; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1412,7 +1427,7 @@ static void process_discard_bio(struct cache *cache, struct prealloc *structs, static bool spare_migration_bandwidth(struct cache *cache) { - sector_t current_volume = (atomic_read(&cache->nr_migrations) + 1) * + sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) * cache->sectors_per_block; return current_volume < cache->migration_threshold; } @@ -1764,7 +1779,7 @@ static void stop_quiescing(struct cache *cache) static void wait_for_migrations(struct cache *cache) { - wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations)); + wait_event(cache->migration_wait, !atomic_read(&cache->nr_allocated_migrations)); } static void stop_worker(struct cache *cache) @@ -1876,9 +1891,6 @@ static void destroy(struct cache *cache) { unsigned i; - if (cache->next_migration) - mempool_free(cache->next_migration, cache->migration_pool); - if (cache->migration_pool) mempool_destroy(cache->migration_pool); @@ -2424,7 +2436,8 @@ static int cache_create(struct cache_args *ca, struct cache **result) INIT_LIST_HEAD(&cache->quiesced_migrations); INIT_LIST_HEAD(&cache->completed_migrations); INIT_LIST_HEAD(&cache->need_commit_migrations); - atomic_set(&cache->nr_migrations, 0); + atomic_set(&cache->nr_allocated_migrations, 0); + atomic_set(&cache->nr_io_migrations, 0); init_waitqueue_head(&cache->migration_wait); init_waitqueue_head(&cache->quiescing_wait); @@ -2487,8 +2500,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) goto bad; } - cache->next_migration = NULL; - cache->need_tick_bio = true; cache->sized = false; cache->invalidate = false; From e0b21800107edbf73385a48275c1fd5a9ecaa4db Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 22 Jan 2015 11:21:32 +0000 Subject: [PATCH 59/66] arm64: dts: add baud rate to Juno stdout-path Without explicit command-line parameters, the Juno UART ends up running at 57600 baud in the kernel, which is at odds with the 115200 baud used by the rest of the firmware. Since commit 7914a7c5651a5161 now lets us fix this by specifying default options in stdout-path, do so. Acked-by: Mark Rutland Signed-off-by: Robin Murphy Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/arm/juno.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index cb3073e4e7a83e..d429129ecb3d03 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -22,7 +22,7 @@ }; chosen { - stdout-path = &soc_uart0; + stdout-path = "serial0:115200n8"; }; psci { From ada072816be1f284cda273f1d980a429b007566a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: [PATCH 60/66] hwmon: (i5500_temp) New driver for the Intel 5500/5520/X58 chipsets The Intel 5500, 5520 and X58 chipsets embed a digital thermal sensor. This new driver supports it. Note that on many boards the sensor seems to be disabled and reports the minimum value (36.5 degrees Celsius) all the time. Signed-off-by: Jean Delvare Tested-by: Romain Dolbeau Reviewed-by: Guenter Roeck --- drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/i5500_temp.c | 201 +++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 drivers/hwmon/i5500_temp.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6529c09c46f0fe..a7de26d1ac8013 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -574,6 +574,16 @@ config SENSORS_IIO_HWMON for those channels specified in the map. This map can be provided either via platform data or the device tree bindings. +config SENSORS_I5500 + tristate "Intel 5500/5520/X58 temperature sensor" + depends on X86 && PCI + help + If you say yes here you get support for the temperature + sensor inside the Intel 5500, 5520 and X58 chipsets. + + This driver can also be built as a module. If so, the module + will be called i5500_temp. + config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 67280643bcf009..6c941472e707a5 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o obj-$(CONFIG_SENSORS_HTU21) += htu21.o obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o +obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c new file mode 100644 index 00000000000000..cbc822dec942b7 --- /dev/null +++ b/drivers/hwmon/i5500_temp.c @@ -0,0 +1,201 @@ +/* + * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor + * + * Copyright (C) 2012, 2014 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions from datasheet */ +#define REG_TSTHRCATA 0xE2 +#define REG_TSCTRL 0xE8 +#define REG_TSTHRRPEX 0xEB +#define REG_TSTHRLO 0xEC +#define REG_TSTHRHI 0xEE +#define REG_CTHINT 0xF0 +#define REG_TSFSC 0xF3 +#define REG_CTSTS 0xF4 +#define REG_TSTHRRQPI 0xF5 +#define REG_CTCTRL 0xF7 +#define REG_TSTIMER 0xF8 + +struct i5500_temp_data { + struct device *hwmon_dev; + const char *name; +}; + +/* + * Sysfs stuff + */ + +/* Sensor resolution : 0.5 degree C */ +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + long temp; + u16 tsthrhi; + s8 tsfsc; + + pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + temp = ((long)tsthrhi - tsfsc) * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_thresh(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int reg = to_sensor_dev_attr(devattr)->index; + long temp; + u16 tsthr; + + pci_read_config_word(pdev, reg, &tsthr); + temp = tsthr * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int nr = to_sensor_dev_attr(devattr)->index; + u8 ctsts; + + pci_read_config_byte(pdev, REG_CTSTS, &ctsts); + return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); +} + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct i5500_temp_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", data->name); +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static struct attribute *i5500_temp_attributes[] = { + &dev_attr_temp1_input.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_name.attr, + NULL +}; + +static const struct attribute_group i5500_temp_group = { + .attrs = i5500_temp_attributes, +}; + +static const struct pci_device_id i5500_temp_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(pci, i5500_temp_ids); + +static int i5500_temp_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct i5500_temp_data *data; + + data = kzalloc(sizeof(struct i5500_temp_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + data->name = "intel5500"; + dev_set_drvdata(&pdev->dev, data); + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device\n"); + goto exit_free; + } + + /* Register sysfs hooks */ + err = sysfs_create_group(&pdev->dev.kobj, &i5500_temp_group); + if (err) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + return 0; + + exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); + exit_free: + kfree(data); + exit: + return err; +} + +static void i5500_temp_remove(struct pci_dev *pdev) +{ + struct i5500_temp_data *data = dev_get_drvdata(&pdev->dev); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); + kfree(data); +} + +static struct pci_driver i5500_temp_driver = { + .name = "i5500_temp", + .id_table = i5500_temp_ids, + .probe = i5500_temp_probe, + .remove = i5500_temp_remove, +}; + +static int __init i5500_temp_init(void) +{ + return pci_register_driver(&i5500_temp_driver); +} + +static void __exit i5500_temp_exit(void) +{ + pci_unregister_driver(&i5500_temp_driver); +} + +MODULE_AUTHOR("Jean Delvare "); +MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); +MODULE_LICENSE("GPL"); + +module_init(i5500_temp_init) +module_exit(i5500_temp_exit) From b8d48ce9519b21021e5875dce1a69f2941b17d1e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: [PATCH 61/66] hwmon: (i5500_temp) Convert to devm_hwmon_device_register_with_groups Use devm_hwmon_device_register_with_groups() to simplify the code a bit. Signed-off-by: Jean Delvare Cc: Romain Dolbeau Reviewed-by: Guenter Roeck --- drivers/hwmon/i5500_temp.c | 73 ++++++++------------------------------ 1 file changed, 15 insertions(+), 58 deletions(-) diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index cbc822dec942b7..fdcfa9fcf5c475 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -37,11 +38,6 @@ #define REG_CTCTRL 0xF7 #define REG_TSTIMER 0xF8 -struct i5500_temp_data { - struct device *hwmon_dev; - const char *name; -}; - /* * Sysfs stuff */ @@ -50,7 +46,7 @@ struct i5500_temp_data { static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); long temp; u16 tsthrhi; s8 tsfsc; @@ -65,7 +61,7 @@ static ssize_t show_temp(struct device *dev, static ssize_t show_thresh(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); int reg = to_sensor_dev_attr(devattr)->index; long temp; u16 tsthr; @@ -79,7 +75,7 @@ static ssize_t show_thresh(struct device *dev, static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); int nr = to_sensor_dev_attr(devattr)->index; u8 ctsts; @@ -87,21 +83,12 @@ static ssize_t show_alarm(struct device *dev, return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); } -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct i5500_temp_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} - static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *i5500_temp_attributes[] = { &dev_attr_temp1_input.attr, @@ -110,7 +97,6 @@ static struct attribute *i5500_temp_attributes[] = { &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &dev_attr_name.attr, NULL }; @@ -118,6 +104,11 @@ static const struct attribute_group i5500_temp_group = { .attrs = i5500_temp_attributes, }; +static const struct attribute_group *i5500_temp_groups[] = { + &i5500_temp_group, + NULL +}; + static const struct pci_device_id i5500_temp_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, { 0 }, @@ -129,58 +120,24 @@ static int i5500_temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err; - struct i5500_temp_data *data; - - data = kzalloc(sizeof(struct i5500_temp_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - data->name = "intel5500"; - dev_set_drvdata(&pdev->dev, data); + struct device *hwmon_dev; err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Failed to enable device\n"); - goto exit_free; - } - - /* Register sysfs hooks */ - err = sysfs_create_group(&pdev->dev.kobj, &i5500_temp_group); - if (err) - goto exit_free; - - data->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; + return err; } - return 0; - - exit_remove: - sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); - exit_free: - kfree(data); - exit: - return err; -} - -static void i5500_temp_remove(struct pci_dev *pdev) -{ - struct i5500_temp_data *data = dev_get_drvdata(&pdev->dev); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); - kfree(data); + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, + "intel5500", NULL, + i5500_temp_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } static struct pci_driver i5500_temp_driver = { .name = "i5500_temp", .id_table = i5500_temp_ids, .probe = i5500_temp_probe, - .remove = i5500_temp_remove, }; static int __init i5500_temp_init(void) From e3d982034dd74b32f621fcba7adeb77716fa0fb4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: [PATCH 62/66] hwmon: (i5500_temp) Don't bind to disabled sensors On many motherboards, for an unknown reason, the thermal sensor seems to be disabled and will return a constant temperature value of 36.5 degrees Celsius. Don't bind to the device in that case, so that we don't report this bogus value to userspace. Signed-off-by: Jean Delvare Cc: Romain Dolbeau Reviewed-by: Guenter Roeck --- drivers/hwmon/i5500_temp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index fdcfa9fcf5c475..fb84a0ecbbad9d 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -121,6 +121,8 @@ static int i5500_temp_probe(struct pci_dev *pdev, { int err; struct device *hwmon_dev; + u32 tstimer; + s8 tsfsc; err = pci_enable_device(pdev); if (err) { @@ -128,6 +130,13 @@ static int i5500_temp_probe(struct pci_dev *pdev, return err; } + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); + if (tsfsc == 0x7F && tstimer == 0x07D30D40) { + dev_warn(&pdev->dev, "Sensor seems to be disabled\n"); + return -ENODEV; + } + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "intel5500", NULL, i5500_temp_groups); From aef64d0d380132c11e27c44b0f73afb9bdb59771 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Jan 2015 14:16:22 +0100 Subject: [PATCH 63/66] hwmon: (i5500_temp) Convert to module_pci_driver Use module_pci_driver to simplify the code a bit. Signed-off-by: Axel Lin Reviewed-by: Guenter Roeck Signed-off-by: Jean Delvare --- drivers/hwmon/i5500_temp.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index fb84a0ecbbad9d..2922be3ef83f22 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -149,19 +149,8 @@ static struct pci_driver i5500_temp_driver = { .probe = i5500_temp_probe, }; -static int __init i5500_temp_init(void) -{ - return pci_register_driver(&i5500_temp_driver); -} - -static void __exit i5500_temp_exit(void) -{ - pci_unregister_driver(&i5500_temp_driver); -} +module_pci_driver(i5500_temp_driver); MODULE_AUTHOR("Jean Delvare "); MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); MODULE_LICENSE("GPL"); - -module_init(i5500_temp_init) -module_exit(i5500_temp_exit) From 86c725e3c5a6baa5316787e0b017d8ac8b0facd8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Jan 2015 14:16:22 +0100 Subject: [PATCH 64/66] hwmon: (i5500_temp) Convert to use ATTRIBUTE_GROUPS macro Use ATTRIBUTE_GROUPS macro to simplify the code a bit. Signed-off-by: Axel Lin Signed-off-by: Jean Delvare --- drivers/hwmon/i5500_temp.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index 2922be3ef83f22..3e3ccbf18b4efb 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -90,7 +90,7 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); -static struct attribute *i5500_temp_attributes[] = { +static struct attribute *i5500_temp_attrs[] = { &dev_attr_temp1_input.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, @@ -100,14 +100,7 @@ static struct attribute *i5500_temp_attributes[] = { NULL }; -static const struct attribute_group i5500_temp_group = { - .attrs = i5500_temp_attributes, -}; - -static const struct attribute_group *i5500_temp_groups[] = { - &i5500_temp_group, - NULL -}; +ATTRIBUTE_GROUPS(i5500_temp); static const struct pci_device_id i5500_temp_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, @@ -133,7 +126,7 @@ static int i5500_temp_probe(struct pci_dev *pdev, pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); if (tsfsc == 0x7F && tstimer == 0x07D30D40) { - dev_warn(&pdev->dev, "Sensor seems to be disabled\n"); + dev_notice(&pdev->dev, "Sensor seems to be disabled\n"); return -ENODEV; } From 96b26c8c64c7a30488b8b404f7a63346df4c3bff Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 8 Jan 2015 18:52:26 -0500 Subject: [PATCH 65/66] dm: fix handling of multiple internal suspends Commit ffcc393641 ("dm: enhance internal suspend and resume interface") attempted to handle multiple internal suspends on the same device, but it did that incorrectly. When these functions are called in this order on the same device the device is no longer suspended, but it should be: dm_internal_suspend_noflush dm_internal_suspend_noflush dm_internal_resume Fix this bug by maintaining an 'internal_suspend_count' and resuming the device when this count drops to zero. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b98cd9d84435fe..2caf5b374649af 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -206,6 +206,9 @@ struct mapped_device { /* zero-length flush that will be cloned and submitted to targets */ struct bio flush_bio; + /* the number of internal suspends */ + unsigned internal_suspend_count; + struct dm_stats stats; }; @@ -2928,7 +2931,7 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla { struct dm_table *map = NULL; - if (dm_suspended_internally_md(md)) + if (md->internal_suspend_count++) return; /* nested internal suspend */ if (dm_suspended_md(md)) { @@ -2953,7 +2956,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla static void __dm_internal_resume(struct mapped_device *md) { - if (!dm_suspended_internally_md(md)) + BUG_ON(!md->internal_suspend_count); + + if (--md->internal_suspend_count) return; /* resume from nested internal suspend */ if (dm_suspended_md(md)) From 26bc420b59a38e4e6685a73345a0def461136dce Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 25 Jan 2015 20:04:41 -0800 Subject: [PATCH 66/66] Linux 3.19-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fb93350cf6456c..95a0e827ecd30a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Diseased Newt # *DOCUMENTATION*