]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 2 May 2015 17:47:42 +0000 (19:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 2 May 2015 17:47:42 +0000 (19:47 +0200)
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

queue-4.0/drm-adv7511-fix-ddc-error-interrupt-handling.patch [new file with mode: 0644]
queue-4.0/drm-adv7511-fix-nested-sleep-when-reading-edid.patch [new file with mode: 0644]
queue-4.0/drm-exynos-enable-dp-clock-to-fix-display-on-exynos5250-and-other.patch [new file with mode: 0644]
queue-4.0/drm-i915-cope-with-large-i2c-transfers.patch [new file with mode: 0644]
queue-4.0/drm-i915-dont-enable-cs_parser_error-interrupts-at-all.patch [new file with mode: 0644]
queue-4.0/drm-i915-vlv-fix-save-restore-of-gfx_max_req_count-reg.patch [new file with mode: 0644]
queue-4.0/drm-radeon-fix-doublescan-modes-v2.patch [new file with mode: 0644]
queue-4.0/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch [new file with mode: 0644]
queue-4.0/series

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 (file)
index 0000000..0b15449
--- /dev/null
@@ -0,0 +1,63 @@
+From 2e96206c4f952295e11c311fbb2a7aa2105024af Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Date: Wed, 18 Feb 2015 15:19:33 +0200
+Subject: drm: adv7511: Fix DDC error interrupt handling
+
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+
+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 <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..b431422
--- /dev/null
@@ -0,0 +1,175 @@
+From a5241289c4139f0521b89e34a70f5f998463ae15 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Date: Wed, 18 Feb 2015 15:19:33 +0200
+Subject: drm: adv7511: Fix nested sleep when reading EDID
+
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+
+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 <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..8ec3623
--- /dev/null
@@ -0,0 +1,149 @@
+From 1c363c7cccf64128087002b0779986ad16aff6dc Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+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 <k.kozlowski@samsung.com>
+
+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 <k.kozlowski@samsung.com>
+Reported-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Tested-by: Andreas Färber <afaerber@suse.de>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <drm/bridge/ptn3460.h>
+ #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 (file)
index 0000000..490c1a9
--- /dev/null
@@ -0,0 +1,145 @@
+From 9535c4757b881e06fae72a857485ad57c422b8d2 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Tue, 21 Apr 2015 09:49:11 -0700
+Subject: drm/i915: cope with large i2c transfers
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+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 <chris@chris-wilson.co.uk>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ee20ec1
--- /dev/null
@@ -0,0 +1,71 @@
+From 37ef01ab5d24d1d520dc79f6a98099d451c2a901 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Wed, 1 Apr 2015 13:43:46 +0200
+Subject: drm/i915: Dont enable CS_PARSER_ERROR interrupts at all
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 37ef01ab5d24d1d520dc79f6a98099d451c2a901 upstream.
+
+We stopped handling them in
+
+commit aaecdf611a05cac26a94713bad25297e60225c29
+Author: Daniel Vetter <daniel.vetter@ffwll.ch>
+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 <mono-for-kernel-org@donderklumpen.de>
+Tested-by: info@gluglug.org.uk
+Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..d170ab6
--- /dev/null
@@ -0,0 +1,59 @@
+From b5f1c97f944482e98e6e39208af356630389d1ea Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+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 <imre.deak@intel.com>
+
+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 <imre.deak@intel.com>
+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 <imre.deak@intel.com>
+Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..baae5e8
--- /dev/null
@@ -0,0 +1,46 @@
+From fd99a0943ffaa0320ea4f69d09ed188f950c0432 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 24 Feb 2015 11:29:21 -0500
+Subject: drm/radeon: fix doublescan modes (v2)
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit fd99a0943ffaa0320ea4f69d09ed188f950c0432 upstream.
+
+Use the correct flags for atom.
+
+v2: handle DRM_MODE_FLAG_DBLCLK
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_crtc.c |    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 (file)
index 0000000..510e201
--- /dev/null
@@ -0,0 +1,45 @@
+From 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Fri, 24 Apr 2015 15:47:07 -0400
+Subject: RCU pathwalk breakage when running into a symlink overmounting something
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+                       }
index 9bb989b8c3aaf3dac73f01b9d5cd3ffeff67c605..fd7cb737dd462de83e48d99177c09cc2d13eadb5 100644 (file)
@@ -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