From: Greg Kroah-Hartman Date: Sat, 2 May 2015 17:47:42 +0000 (+0200) Subject: 4.0-stable patches X-Git-Tag: v3.10.77~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5215bc20c519202286c1007befca4b276149bd9;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: drm-adv7511-fix-ddc-error-interrupt-handling.patch drm-adv7511-fix-nested-sleep-when-reading-edid.patch drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch drm-i915-cope-with-large-i2c-transfers.patch drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch drm-radeon-fix-doublescan-modes-v2.patch rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch --- diff --git a/queue-4.0/drm-adv7511-fix-ddc-error-interrupt-handling.patch b/queue-4.0/drm-adv7511-fix-ddc-error-interrupt-handling.patch new file mode 100644 index 00000000000..0b15449c5fe --- /dev/null +++ b/queue-4.0/drm-adv7511-fix-ddc-error-interrupt-handling.patch @@ -0,0 +1,63 @@ +From 2e96206c4f952295e11c311fbb2a7aa2105024af Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +Date: Wed, 18 Feb 2015 15:19:33 +0200 +Subject: drm: adv7511: Fix DDC error interrupt handling + +From: Laurent Pinchart + +commit 2e96206c4f952295e11c311fbb2a7aa2105024af upstream. + +The DDC error interrupt bit is located in REG_INT1, not REG_INT0. Update +both the interrupt wait code and the interrupt sources reset code +accordingly. + +Signed-off-by: Laurent Pinchart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i2c/adv7511.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i2c/adv7511.c ++++ b/drivers/gpu/drm/i2c/adv7511.c +@@ -467,14 +467,16 @@ static int adv7511_get_edid_block(void * + block); + ret = adv7511_wait_for_interrupt(adv7511, + ADV7511_INT0_EDID_READY | +- ADV7511_INT1_DDC_ERROR, 200); ++ (ADV7511_INT1_DDC_ERROR << 8), 200); + + if (!(ret & ADV7511_INT0_EDID_READY)) + return -EIO; + } + + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), +- ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); ++ ADV7511_INT0_EDID_READY); ++ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), ++ ADV7511_INT1_DDC_ERROR); + + /* Break this apart, hopefully more I2C controllers will + * support 64 byte transfers than 256 byte transfers +@@ -528,7 +530,9 @@ static int adv7511_get_modes(struct drm_ + /* Reading the EDID only works if the device is powered */ + if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) { + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), +- ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); ++ ADV7511_INT0_EDID_READY); ++ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), ++ ADV7511_INT1_DDC_ERROR); + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, 0); + adv7511->current_edid_segment = -1; +@@ -563,7 +567,9 @@ static void adv7511_encoder_dpms(struct + adv7511->current_edid_segment = -1; + + regmap_write(adv7511->regmap, ADV7511_REG_INT(0), +- ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); ++ ADV7511_INT0_EDID_READY); ++ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), ++ ADV7511_INT1_DDC_ERROR); + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, + ADV7511_POWER_POWER_DOWN, 0); + /* diff --git a/queue-4.0/drm-adv7511-fix-nested-sleep-when-reading-edid.patch b/queue-4.0/drm-adv7511-fix-nested-sleep-when-reading-edid.patch new file mode 100644 index 00000000000..b4314229226 --- /dev/null +++ b/queue-4.0/drm-adv7511-fix-nested-sleep-when-reading-edid.patch @@ -0,0 +1,175 @@ +From a5241289c4139f0521b89e34a70f5f998463ae15 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +Date: Wed, 18 Feb 2015 15:19:33 +0200 +Subject: drm: adv7511: Fix nested sleep when reading EDID + +From: Laurent Pinchart + +commit a5241289c4139f0521b89e34a70f5f998463ae15 upstream. + +The EDID read code waits for the read completion interrupt to occur +using wait_event_interruptible(). The condition passed to the macro +reads I2C registers. This results in sleeping with the task state set +to TASK_INTERRUPTIBLE, triggering a WARN_ON() introduced in commit +8eb23b9f35aae ("sched: Debug nested sleeps"). + +Fix this by reworking the EDID read code. Instead of checking whether +the read is complete through I2C reads, handle the interrupt registers +in the interrupt handler and update a new edid_read flag accordingly. As +a side effect both the IRQ and polling code paths now process the +interrupt sources through the same code path, simplifying the code. + +Signed-off-by: Laurent Pinchart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i2c/adv7511.c | 96 ++++++++++++++++++++---------------------- + 1 file changed, 46 insertions(+), 50 deletions(-) + +--- a/drivers/gpu/drm/i2c/adv7511.c ++++ b/drivers/gpu/drm/i2c/adv7511.c +@@ -33,6 +33,7 @@ struct adv7511 { + + unsigned int current_edid_segment; + uint8_t edid_buf[256]; ++ bool edid_read; + + wait_queue_head_t wq; + struct drm_encoder *encoder; +@@ -379,69 +380,71 @@ static bool adv7511_hpd(struct adv7511 * + return false; + } + +-static irqreturn_t adv7511_irq_handler(int irq, void *devid) +-{ +- struct adv7511 *adv7511 = devid; +- +- if (adv7511_hpd(adv7511)) +- drm_helper_hpd_irq_event(adv7511->encoder->dev); +- +- wake_up_all(&adv7511->wq); +- +- return IRQ_HANDLED; +-} +- +-static unsigned int adv7511_is_interrupt_pending(struct adv7511 *adv7511, +- unsigned int irq) ++static int adv7511_irq_process(struct adv7511 *adv7511) + { + unsigned int irq0, irq1; +- unsigned int pending; + int ret; + + ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0); + if (ret < 0) +- return 0; ++ return ret; ++ + ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1); + if (ret < 0) +- return 0; ++ return ret; ++ ++ regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0); ++ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); ++ ++ if (irq0 & ADV7511_INT0_HDP) ++ drm_helper_hpd_irq_event(adv7511->encoder->dev); ++ ++ if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { ++ adv7511->edid_read = true; ++ ++ if (adv7511->i2c_main->irq) ++ wake_up_all(&adv7511->wq); ++ } ++ ++ return 0; ++} + +- pending = (irq1 << 8) | irq0; ++static irqreturn_t adv7511_irq_handler(int irq, void *devid) ++{ ++ struct adv7511 *adv7511 = devid; ++ int ret; + +- return pending & irq; ++ ret = adv7511_irq_process(adv7511); ++ return ret < 0 ? IRQ_NONE : IRQ_HANDLED; + } + +-static int adv7511_wait_for_interrupt(struct adv7511 *adv7511, int irq, +- int timeout) ++/* ----------------------------------------------------------------------------- ++ * EDID retrieval ++ */ ++ ++static int adv7511_wait_for_edid(struct adv7511 *adv7511, int timeout) + { +- unsigned int pending; + int ret; + + if (adv7511->i2c_main->irq) { + ret = wait_event_interruptible_timeout(adv7511->wq, +- adv7511_is_interrupt_pending(adv7511, irq), +- msecs_to_jiffies(timeout)); +- if (ret <= 0) +- return 0; +- pending = adv7511_is_interrupt_pending(adv7511, irq); ++ adv7511->edid_read, msecs_to_jiffies(timeout)); + } else { +- if (timeout < 25) +- timeout = 25; +- do { +- pending = adv7511_is_interrupt_pending(adv7511, irq); +- if (pending) ++ for (; timeout > 0; timeout -= 25) { ++ ret = adv7511_irq_process(adv7511); ++ if (ret < 0) ++ break; ++ ++ if (adv7511->edid_read) + break; ++ + msleep(25); +- timeout -= 25; +- } while (timeout >= 25); ++ } + } + +- return pending; ++ return adv7511->edid_read ? 0 : -EIO; + } + +-/* ----------------------------------------------------------------------------- +- * EDID retrieval +- */ +- + static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, + size_t len) + { +@@ -463,21 +466,14 @@ static int adv7511_get_edid_block(void * + return ret; + + if (status != 2) { ++ adv7511->edid_read = false; + regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, + block); +- ret = adv7511_wait_for_interrupt(adv7511, +- ADV7511_INT0_EDID_READY | +- (ADV7511_INT1_DDC_ERROR << 8), 200); +- +- if (!(ret & ADV7511_INT0_EDID_READY)) +- return -EIO; ++ ret = adv7511_wait_for_edid(adv7511, 200); ++ if (ret < 0) ++ return ret; + } + +- regmap_write(adv7511->regmap, ADV7511_REG_INT(0), +- ADV7511_INT0_EDID_READY); +- regmap_write(adv7511->regmap, ADV7511_REG_INT(1), +- ADV7511_INT1_DDC_ERROR); +- + /* Break this apart, hopefully more I2C controllers will + * support 64 byte transfers than 256 byte transfers + */ diff --git a/queue-4.0/drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch b/queue-4.0/drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch new file mode 100644 index 00000000000..8ec3623552c --- /dev/null +++ b/queue-4.0/drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch @@ -0,0 +1,149 @@ +From 1c363c7cccf64128087002b0779986ad16aff6dc Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 7 Apr 2015 22:28:50 +0900 +Subject: drm/exynos: Enable DP clock to fix display on Exynos5250 and other +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krzysztof Kozlowski + +commit 1c363c7cccf64128087002b0779986ad16aff6dc upstream. + +After adding display power domain for Exynos5250 in commit +2d2c9a8d0a4f ("ARM: dts: add display power domain for exynos5250") the +display on Chromebook Snow and others stopped working after boot. + +The reason for this suggested Andrzej Hajda: the DP clock was disabled. +This clock is required by Display Port and is enabled by bootloader. +However when FIMD driver probing was deferred, the display power domain +was turned off. This effectively reset the value of DP clock enable +register. + +When exynos-dp is later probed, the clock is not enabled and display is +not properly configured: + +exynos-dp 145b0000.dp-controller: Timeout of video streamclk ok +exynos-dp 145b0000.dp-controller: unable to config video + +Fixes: 2d2c9a8d0a4f ("ARM: dts: add display power domain for exynos5250") + +Signed-off-by: Krzysztof Kozlowski +Reported-by: Javier Martinez Canillas +Tested-by: Javier Martinez Canillas +Tested-by: Andreas Färber +Signed-off-by: Inki Dae +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/exynos/exynos_dp_core.c | 10 ++++++++++ + drivers/gpu/drm/exynos/exynos_drm_fimd.c | 19 +++++++++++++++++++ + drivers/gpu/drm/exynos/exynos_drm_fimd.h | 15 +++++++++++++++ + include/video/samsung_fimd.h | 6 ++++++ + 4 files changed, 50 insertions(+) + +--- a/drivers/gpu/drm/exynos/exynos_dp_core.c ++++ b/drivers/gpu/drm/exynos/exynos_dp_core.c +@@ -32,10 +32,16 @@ + #include + + #include "exynos_dp_core.h" ++#include "exynos_drm_fimd.h" + + #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ + connector) + ++static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp) ++{ ++ return to_exynos_crtc(dp->encoder->crtc); ++} ++ + static inline struct exynos_dp_device * + display_to_dp(struct exynos_drm_display *d) + { +@@ -1070,6 +1076,8 @@ static void exynos_dp_poweron(struct exy + } + } + ++ fimd_dp_clock_enable(dp_to_crtc(dp), true); ++ + clk_prepare_enable(dp->clock); + exynos_dp_phy_init(dp); + exynos_dp_init_dp(dp); +@@ -1094,6 +1102,8 @@ static void exynos_dp_poweroff(struct ex + exynos_dp_phy_exit(dp); + clk_disable_unprepare(dp->clock); + ++ fimd_dp_clock_enable(dp_to_crtc(dp), false); ++ + if (dp->panel) { + if (drm_panel_unprepare(dp->panel)) + DRM_ERROR("failed to turnoff the panel\n"); +--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c +@@ -32,6 +32,7 @@ + #include "exynos_drm_fbdev.h" + #include "exynos_drm_crtc.h" + #include "exynos_drm_iommu.h" ++#include "exynos_drm_fimd.h" + + /* + * FIMD stands for Fully Interactive Mobile Display and +@@ -1233,6 +1234,24 @@ static int fimd_remove(struct platform_d + return 0; + } + ++void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) ++{ ++ struct fimd_context *ctx = crtc->ctx; ++ u32 val; ++ ++ /* ++ * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE ++ * clock. On these SoCs the bootloader may enable it but any ++ * power domain off/on will reset it to disable state. ++ */ ++ if (ctx->driver_data != &exynos5_fimd_driver_data) ++ return; ++ ++ val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; ++ writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON); ++} ++EXPORT_SYMBOL_GPL(fimd_dp_clock_enable); ++ + struct platform_driver fimd_driver = { + .probe = fimd_probe, + .remove = fimd_remove, +--- /dev/null ++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.h +@@ -0,0 +1,15 @@ ++/* ++ * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * ++ * 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. ++ */ ++ ++#ifndef _EXYNOS_DRM_FIMD_H_ ++#define _EXYNOS_DRM_FIMD_H_ ++ ++extern void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable); ++ ++#endif /* _EXYNOS_DRM_FIMD_H_ */ +--- a/include/video/samsung_fimd.h ++++ b/include/video/samsung_fimd.h +@@ -436,6 +436,12 @@ + #define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) + #define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0) + ++/* Display port clock control */ ++#define DP_MIE_CLKCON 0x27c ++#define DP_MIE_CLK_DISABLE 0x0 ++#define DP_MIE_CLK_DP_ENABLE 0x2 ++#define DP_MIE_CLK_MIE_ENABLE 0x3 ++ + /* Notes on per-window bpp settings + * + * Value Win0 Win1 Win2 Win3 Win 4 diff --git a/queue-4.0/drm-i915-cope-with-large-i2c-transfers.patch b/queue-4.0/drm-i915-cope-with-large-i2c-transfers.patch new file mode 100644 index 00000000000..490c1a94c86 --- /dev/null +++ b/queue-4.0/drm-i915-cope-with-large-i2c-transfers.patch @@ -0,0 +1,145 @@ +From 9535c4757b881e06fae72a857485ad57c422b8d2 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 21 Apr 2015 09:49:11 -0700 +Subject: drm/i915: cope with large i2c transfers + +From: Dmitry Torokhov + +commit 9535c4757b881e06fae72a857485ad57c422b8d2 upstream. + +The hardware, according to the specs, is limited to 256 byte transfers, +and current driver has no protections in case users attempt to do larger +transfers. The code will just stomp over status register and mayhem +ensues. + +Let's split larger transfers into digestable chunks. Doing this allows +Atmel MXT driver on Pixel 1 function properly (it hasn't since commit +9d8dc3e529a19e427fd379118acd132520935c5d "Input: atmel_mxt_ts - +implement T44 message handling" which tries to consume multiple +touchscreen/touchpad reports in a single transaction). + +Reviewed-by: Chris Wilson +Signed-off-by: Dmitry Torokhov +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_i2c.c | 66 +++++++++++++++++++++++++++++++++------ + 2 files changed, 57 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1740,6 +1740,7 @@ enum punit_power_well { + #define GMBUS_CYCLE_INDEX (2<<25) + #define GMBUS_CYCLE_STOP (4<<25) + #define GMBUS_BYTE_COUNT_SHIFT 16 ++#define GMBUS_BYTE_COUNT_MAX 256U + #define GMBUS_SLAVE_INDEX_SHIFT 8 + #define GMBUS_SLAVE_ADDR_SHIFT 1 + #define GMBUS_SLAVE_READ (1<<0) +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -270,18 +270,17 @@ gmbus_wait_idle(struct drm_i915_private + } + + static int +-gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, +- u32 gmbus1_index) ++gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, ++ unsigned short addr, u8 *buf, unsigned int len, ++ u32 gmbus1_index) + { + int reg_offset = dev_priv->gpio_mmio_base; +- u16 len = msg->len; +- u8 *buf = msg->buf; + + I915_WRITE(GMBUS1 + reg_offset, + gmbus1_index | + GMBUS_CYCLE_WAIT | + (len << GMBUS_BYTE_COUNT_SHIFT) | +- (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | ++ (addr << GMBUS_SLAVE_ADDR_SHIFT) | + GMBUS_SLAVE_READ | GMBUS_SW_RDY); + while (len) { + int ret; +@@ -303,11 +302,35 @@ gmbus_xfer_read(struct drm_i915_private + } + + static int +-gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) ++gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, ++ u32 gmbus1_index) + { +- int reg_offset = dev_priv->gpio_mmio_base; +- u16 len = msg->len; + u8 *buf = msg->buf; ++ unsigned int rx_size = msg->len; ++ unsigned int len; ++ int ret; ++ ++ do { ++ len = min(rx_size, GMBUS_BYTE_COUNT_MAX); ++ ++ ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, ++ buf, len, gmbus1_index); ++ if (ret) ++ return ret; ++ ++ rx_size -= len; ++ buf += len; ++ } while (rx_size != 0); ++ ++ return 0; ++} ++ ++static int ++gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, ++ unsigned short addr, u8 *buf, unsigned int len) ++{ ++ int reg_offset = dev_priv->gpio_mmio_base; ++ unsigned int chunk_size = len; + u32 val, loop; + + val = loop = 0; +@@ -319,8 +342,8 @@ gmbus_xfer_write(struct drm_i915_private + I915_WRITE(GMBUS3 + reg_offset, val); + I915_WRITE(GMBUS1 + reg_offset, + GMBUS_CYCLE_WAIT | +- (msg->len << GMBUS_BYTE_COUNT_SHIFT) | +- (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | ++ (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | ++ (addr << GMBUS_SLAVE_ADDR_SHIFT) | + GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); + while (len) { + int ret; +@@ -337,6 +360,29 @@ gmbus_xfer_write(struct drm_i915_private + if (ret) + return ret; + } ++ ++ return 0; ++} ++ ++static int ++gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) ++{ ++ u8 *buf = msg->buf; ++ unsigned int tx_size = msg->len; ++ unsigned int len; ++ int ret; ++ ++ do { ++ len = min(tx_size, GMBUS_BYTE_COUNT_MAX); ++ ++ ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len); ++ if (ret) ++ return ret; ++ ++ buf += len; ++ tx_size -= len; ++ } while (tx_size != 0); ++ + return 0; + } + diff --git a/queue-4.0/drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch b/queue-4.0/drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch new file mode 100644 index 00000000000..ee20ec137a1 --- /dev/null +++ b/queue-4.0/drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch @@ -0,0 +1,71 @@ +From 37ef01ab5d24d1d520dc79f6a98099d451c2a901 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 1 Apr 2015 13:43:46 +0200 +Subject: drm/i915: Dont enable CS_PARSER_ERROR interrupts at all + +From: Daniel Vetter + +commit 37ef01ab5d24d1d520dc79f6a98099d451c2a901 upstream. + +We stopped handling them in + +commit aaecdf611a05cac26a94713bad25297e60225c29 +Author: Daniel Vetter +Date: Tue Nov 4 15:52:22 2014 +0100 + + drm/i915: Stop gathering error states for CS error interrupts + +but just clearing is apparently not enough: A sufficiently dead gpu +left behind by firmware (*cough* coreboot *cough*) can keep the gpu in +an endless loop of such interrupts, eventually leading to the nmi +firing. And definitely to what looks like a machine hang. + +Since we don't even enable these interrupts on gen5+ let's do the same +on earlier platforms. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=93171 +Tested-by: Mono +Tested-by: info@gluglug.org.uk +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_irq.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -3718,14 +3718,12 @@ static int i8xx_irq_postinstall(struct d + ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | +- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | +- I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); ++ I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); + I915_WRITE16(IMR, dev_priv->irq_mask); + + I915_WRITE16(IER, + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | +- I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT | + I915_USER_INTERRUPT); + POSTING_READ16(IER); + +@@ -3887,14 +3885,12 @@ static int i915_irq_postinstall(struct d + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | +- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | +- I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); ++ I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); + + enable_mask = + I915_ASLE_INTERRUPT | + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | +- I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT | + I915_USER_INTERRUPT; + + if (I915_HAS_HOTPLUG(dev)) { diff --git a/queue-4.0/drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch b/queue-4.0/drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch new file mode 100644 index 00000000000..d170ab6dba7 --- /dev/null +++ b/queue-4.0/drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch @@ -0,0 +1,59 @@ +From b5f1c97f944482e98e6e39208af356630389d1ea Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 15 Apr 2015 16:52:30 -0700 +Subject: drm/i915: vlv: fix save/restore of GFX_MAX_REQ_COUNT reg + +From: Imre Deak + +commit b5f1c97f944482e98e6e39208af356630389d1ea upstream. + +Due this typo we don't save/restore the GFX_MAX_REQ_COUNT register across +suspend/resume, so fix this. + +This was introduced in + +commit ddeea5b0c36f3665446518c609be91f9336ef674 +Author: Imre Deak +Date: Mon May 5 15:19:56 2014 +0300 + + drm/i915: vlv: add runtime PM support + +I noticed this only by reading the code. To my knowledge it shouldn't +cause any real problems at the moment, since the power well backing this +register remains on across a runtime s/r. This may change once +system-wide s0ix functionality is enabled in the kernel. + +v2: +- resend after a missing git add -u :/ + +Signed-off-by: Imre Deak +Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com) +Signed-off-by: Rodrigo Vivi +Reviewed-by: Mika Kuoppala +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1042,7 +1042,7 @@ static void vlv_save_gunit_s0ix_state(st + s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4); + + s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); +- s->gfx_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); ++ s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT); + + s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7); + s->ecochk = I915_READ(GAM_ECOCHK); +@@ -1124,7 +1124,7 @@ static void vlv_restore_gunit_s0ix_state + I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]); + + I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); +- I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->gfx_max_req_count); ++ I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count); + + I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); + I915_WRITE(GAM_ECOCHK, s->ecochk); diff --git a/queue-4.0/drm-radeon-fix-doublescan-modes-v2.patch b/queue-4.0/drm-radeon-fix-doublescan-modes-v2.patch new file mode 100644 index 00000000000..baae5e8a923 --- /dev/null +++ b/queue-4.0/drm-radeon-fix-doublescan-modes-v2.patch @@ -0,0 +1,46 @@ +From fd99a0943ffaa0320ea4f69d09ed188f950c0432 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 24 Feb 2015 11:29:21 -0500 +Subject: drm/radeon: fix doublescan modes (v2) + +From: Alex Deucher + +commit fd99a0943ffaa0320ea4f69d09ed188f950c0432 upstream. + +Use the correct flags for atom. + +v2: handle DRM_MODE_FLAG_DBLCLK + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -330,8 +330,10 @@ atombios_set_crtc_dtd_timing(struct drm_ + misc |= ATOM_COMPOSITESYNC; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + misc |= ATOM_INTERLACE; +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) + misc |= ATOM_DOUBLE_CLOCK_MODE; ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2; + + args.susModeMiscInfo.usAccess = cpu_to_le16(misc); + args.ucCRTC = radeon_crtc->crtc_id; +@@ -374,8 +376,10 @@ static void atombios_crtc_set_timing(str + misc |= ATOM_COMPOSITESYNC; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + misc |= ATOM_INTERLACE; +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) + misc |= ATOM_DOUBLE_CLOCK_MODE; ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2; + + args.susModeMiscInfo.usAccess = cpu_to_le16(misc); + args.ucCRTC = radeon_crtc->crtc_id; diff --git a/queue-4.0/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch b/queue-4.0/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch new file mode 100644 index 00000000000..510e2015d97 --- /dev/null +++ b/queue-4.0/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch @@ -0,0 +1,45 @@ +From 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 24 Apr 2015 15:47:07 -0400 +Subject: RCU pathwalk breakage when running into a symlink overmounting something + +From: Al Viro + +commit 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 upstream. + +Calling unlazy_walk() in walk_component() and do_last() when we find +a symlink that needs to be followed doesn't acquire a reference to vfsmount. +That's fine when the symlink is on the same vfsmount as the parent directory +(which is almost always the case), but it's not always true - one _can_ +manage to bind a symlink on top of something. And in such cases we end up +with excessive mntput(). + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namei.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1591,7 +1591,8 @@ static inline int walk_component(struct + + if (should_follow_link(path->dentry, follow)) { + if (nd->flags & LOOKUP_RCU) { +- if (unlikely(unlazy_walk(nd, path->dentry))) { ++ if (unlikely(nd->path.mnt != path->mnt || ++ unlazy_walk(nd, path->dentry))) { + err = -ECHILD; + goto out_err; + } +@@ -3047,7 +3048,8 @@ finish_lookup: + + if (should_follow_link(path->dentry, !symlink_ok)) { + if (nd->flags & LOOKUP_RCU) { +- if (unlikely(unlazy_walk(nd, path->dentry))) { ++ if (unlikely(nd->path.mnt != path->mnt || ++ unlazy_walk(nd, path->dentry))) { + error = -ECHILD; + goto out; + } diff --git a/queue-4.0/series b/queue-4.0/series index 9bb989b8c3a..fd7cb737dd4 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -186,3 +186,11 @@ i2c-mux-use-proper-dev-when-removing-channel-x-symlinks.patch i2c-rk3x-report-number-of-messages-transmitted.patch i2c-mark-adapter-devices-with-pm_runtime_no_callbacks.patch i2c-core-export-bus-recovery-functions.patch +drm-radeon-fix-doublescan-modes-v2.patch +drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch +drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch +drm-adv7511-fix-ddc-error-interrupt-handling.patch +drm-adv7511-fix-nested-sleep-when-reading-edid.patch +drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch +drm-i915-cope-with-large-i2c-transfers.patch +rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch