--- /dev/null
+From 83f7fd055eb3f1e843803cd906179d309553967b Mon Sep 17 00:00:00 2001
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+Date: Mon, 5 Apr 2010 14:03:51 -0700
+Subject: drm/i915: don't queue flips during a flip pending event
+
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit 83f7fd055eb3f1e843803cd906179d309553967b upstream.
+
+Hardware will set the flip pending ISR bit as soon as it receives the
+flip instruction, and (supposedly) clear it once the flip completes
+(e.g. at the next vblank). If we try to send down a flip instruction
+while the ISR bit is set, the hardware can become very confused, and we
+may never receive the corresponding flip pending interrupt, effectively
+hanging the chip.
+
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4232,6 +4232,7 @@ static int intel_crtc_page_flip(struct d
+ unsigned long flags;
+ int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
+ int ret, pipesrc;
++ u32 flip_mask;
+ RING_LOCALS;
+
+ work = kzalloc(sizeof *work, GFP_KERNEL);
+@@ -4282,6 +4283,16 @@ static int intel_crtc_page_flip(struct d
+ atomic_inc(&obj_priv->pending_flip);
+ work->pending_flip_obj = obj;
+
++ if (intel_crtc->plane)
++ flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
++ else
++ flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
++
++ /* Wait for any previous flip to finish */
++ if (IS_GEN3(dev))
++ while (I915_READ(ISR) & flip_mask)
++ ;
++
+ BEGIN_LP_RING(4);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_DISPLAY_FLIP |
--- /dev/null
+From 1afe3e9d4335bf3bc5615e37243dc8fef65dac8f Mon Sep 17 00:00:00 2001
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+Date: Fri, 26 Mar 2010 10:35:20 -0700
+Subject: drm/i915: gen3 page flipping fixes
+
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit 1afe3e9d4335bf3bc5615e37243dc8fef65dac8f upstream.
+
+Gen3 chips have slightly different flip commands, and also contain a bit
+that indicates whether a "flip pending" interrupt means the flip has
+been queued or has been completed.
+
+So implement support for the gen3 flip command, and make sure we use the
+flip pending interrupt correctly depending on the value of ECOSKPD bit
+0.
+
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_dma.c | 4 ++++
+ drivers/gpu/drm/i915/i915_drv.h | 1 +
+ drivers/gpu/drm/i915/i915_irq.c | 16 ++++++++++++----
+ drivers/gpu/drm/i915/i915_reg.h | 4 ++++
+ drivers/gpu/drm/i915/intel_display.c | 29 ++++++++++++++++++++++++-----
+ drivers/gpu/drm/i915/intel_drv.h | 1 +
+ 6 files changed, 46 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -1488,6 +1488,10 @@ static int i915_load_modeset_init(struct
+ if (ret)
+ goto destroy_ringbuffer;
+
++ /* IIR "flip pending" bit means done if this bit is set */
++ if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE))
++ dev_priv->flip_pending_is_done = true;
++
+ intel_modeset_init(dev);
+
+ ret = drm_irq_install(dev);
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -611,6 +611,7 @@ typedef struct drm_i915_private {
+ struct drm_crtc *plane_to_crtc_mapping[2];
+ struct drm_crtc *pipe_to_crtc_mapping[2];
+ wait_queue_head_t pending_flip_queue;
++ bool flip_pending_is_done;
+
+ /* Reclocking support */
+ bool render_reclock_avail;
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -932,22 +932,30 @@ irqreturn_t i915_driver_irq_handler(DRM_
+ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
+ }
+
+- if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
++ if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
+ intel_prepare_page_flip(dev, 0);
++ if (dev_priv->flip_pending_is_done)
++ intel_finish_page_flip_plane(dev, 0);
++ }
+
+- if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
++ if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) {
++ if (dev_priv->flip_pending_is_done)
++ intel_finish_page_flip_plane(dev, 1);
+ intel_prepare_page_flip(dev, 1);
++ }
+
+ if (pipea_stats & vblank_status) {
+ vblank++;
+ drm_handle_vblank(dev, 0);
+- intel_finish_page_flip(dev, 0);
++ if (!dev_priv->flip_pending_is_done)
++ intel_finish_page_flip(dev, 0);
+ }
+
+ if (pipeb_stats & vblank_status) {
+ vblank++;
+ drm_handle_vblank(dev, 1);
+- intel_finish_page_flip(dev, 1);
++ if (!dev_priv->flip_pending_is_done)
++ intel_finish_page_flip(dev, 1);
+ }
+
+ if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -178,6 +178,7 @@
+ #define MI_OVERLAY_OFF (0x2<<21)
+ #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+ #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
++#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
+ #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
+ #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
+ #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
+@@ -431,6 +432,9 @@
+ #define CM0_RC_OP_FLUSH_DISABLE (1<<0)
+ #define BB_ADDR 0x02140 /* 8 bytes */
+ #define GFX_FLSH_CNTL 0x02170 /* 915+ only */
++#define ECOSKPD 0x021d0
++#define ECO_GATING_CX_ONLY (1<<3)
++#define ECO_FLIP_DONE (1<<0)
+
+
+ /*
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4139,10 +4139,10 @@ static void intel_unpin_work_fn(struct w
+ kfree(work);
+ }
+
+-void intel_finish_page_flip(struct drm_device *dev, int pipe)
++static void do_intel_finish_page_flip(struct drm_device *dev,
++ struct drm_crtc *crtc)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+- struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_unpin_work *work;
+ struct drm_i915_gem_object *obj_priv;
+@@ -4186,6 +4186,22 @@ void intel_finish_page_flip(struct drm_d
+ schedule_work(&work->work);
+ }
+
++void intel_finish_page_flip(struct drm_device *dev, int pipe)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
++
++ do_intel_finish_page_flip(dev, crtc);
++}
++
++void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++ struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
++
++ do_intel_finish_page_flip(dev, crtc);
++}
++
+ void intel_prepare_page_flip(struct drm_device *dev, int plane)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+@@ -4267,14 +4283,17 @@ static int intel_crtc_page_flip(struct d
+ work->pending_flip_obj = obj;
+
+ BEGIN_LP_RING(4);
+- OUT_RING(MI_DISPLAY_FLIP |
+- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+- OUT_RING(fb->pitch);
+ if (IS_I965G(dev)) {
++ OUT_RING(MI_DISPLAY_FLIP |
++ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
++ OUT_RING(fb->pitch);
+ OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
+ pipesrc = I915_READ(pipesrc_reg);
+ OUT_RING(pipesrc & 0x0fff0fff);
+ } else {
++ OUT_RING(MI_DISPLAY_FLIP_I915 |
++ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
++ OUT_RING(fb->pitch);
+ OUT_RING(obj_priv->gtt_offset);
+ OUT_RING(MI_NOOP);
+ }
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -219,6 +219,7 @@ extern int intel_framebuffer_create(stru
+
+ extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
+ extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
++extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
+
+ extern void intel_setup_overlay(struct drm_device *dev);
+ extern void intel_cleanup_overlay(struct drm_device *dev);
--- /dev/null
+From be9a3dbf65a69933b06011f049b1e2fdfa6bc8b9 Mon Sep 17 00:00:00 2001
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+Date: Fri, 23 Jul 2010 12:03:37 -0700
+Subject: drm/i915: handle shared framebuffers when flipping
+
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit be9a3dbf65a69933b06011f049b1e2fdfa6bc8b9 upstream.
+
+If a framebuffer is shared across CRTCs, the x,y position of one of them
+is likely to be something other than the origin (e.g. for extended
+desktop configs). So calculate the offset at flip time so such
+configurations can work.
+
+Fixes https://bugs.freedesktop.org/show_bug.cgi?id=28518.
+
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Tested-by: Thomas M. <tmezzadra@gmail.com>
+Tested-by: fangxun <xunx.fang@intel.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4229,7 +4229,7 @@ static int intel_crtc_page_flip(struct d
+ struct drm_gem_object *obj;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_unpin_work *work;
+- unsigned long flags;
++ unsigned long flags, offset;
+ int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
+ int ret, pipesrc;
+ u32 flip_mask;
+@@ -4297,19 +4297,23 @@ static int intel_crtc_page_flip(struct d
+ while (I915_READ(ISR) & flip_mask)
+ ;
+
++ /* Offset into the new buffer for cases of shared fbs between CRTCs */
++ offset = obj_priv->gtt_offset;
++ offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
++
+ BEGIN_LP_RING(4);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+- OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
++ OUT_RING(offset | obj_priv->tiling_mode);
+ pipesrc = I915_READ(pipesrc_reg);
+ OUT_RING(pipesrc & 0x0fff0fff);
+ } else {
+ OUT_RING(MI_DISPLAY_FLIP_I915 |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+- OUT_RING(obj_priv->gtt_offset);
++ OUT_RING(offset);
+ OUT_RING(MI_NOOP);
+ }
+ ADVANCE_LP_RING();
--- /dev/null
+From 468f0b44ce4b002ca7d9260f802a341854752c02 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Thu, 27 May 2010 13:18:13 +0100
+Subject: drm/i915: Hold the spinlock whilst resetting unpin_work along error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 468f0b44ce4b002ca7d9260f802a341854752c02 upstream.
+
+Delay taking the mutex until we need to and ensure that we hold the
+spinlock when resetting unpin_work on the error path. Also defer the
+debugging print messages until after we have released the spinlock.
+
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
+Cc: Kristian Høgsberg <krh@bitplanet.net>
+Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4239,8 +4239,6 @@ static int intel_crtc_page_flip(struct d
+ if (work == NULL)
+ return -ENOMEM;
+
+- mutex_lock(&dev->struct_mutex);
+-
+ work->event = event;
+ work->dev = crtc->dev;
+ intel_fb = to_intel_framebuffer(crtc->fb);
+@@ -4250,10 +4248,10 @@ static int intel_crtc_page_flip(struct d
+ /* We borrow the event spin lock for protecting unpin_work */
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (intel_crtc->unpin_work) {
+- DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(work);
+- mutex_unlock(&dev->struct_mutex);
++
++ DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+ return -EBUSY;
+ }
+ intel_crtc->unpin_work = work;
+@@ -4262,13 +4260,19 @@ static int intel_crtc_page_flip(struct d
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
++ mutex_lock(&dev->struct_mutex);
+ ret = intel_pin_and_fence_fb_obj(dev, obj);
+ if (ret != 0) {
+- DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
+- to_intel_bo(obj));
+- kfree(work);
+- intel_crtc->unpin_work = NULL;
+ mutex_unlock(&dev->struct_mutex);
++
++ spin_lock_irqsave(&dev->event_lock, flags);
++ intel_crtc->unpin_work = NULL;
++ spin_unlock_irqrestore(&dev->event_lock, flags);
++
++ kfree(work);
++
++ DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
++ to_intel_bo(obj));
+ return ret;
+ }
+
--- /dev/null
+From 8bed607fa4330dab2878562c024fb8efccb3fa17 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Jul 2010 23:59:18 +0100
+Subject: ethtool: Fix potential user buffer overflow for ETHTOOL_{G, S}RXFH
+
+commit bf988435bd5b53529f4408a8efb1f433f6ddfda9 upstream.
+
+struct ethtool_rxnfc was originally defined in 2.6.27 for the
+ETHTOOL_{G,S}RXFH command with only the cmd, flow_type and data
+fields. It was then extended in 2.6.30 to support various additional
+commands. These commands should have been defined to use a new
+structure, but it is too late to change that now.
+
+Since user-space may still be using the old structure definition
+for the ETHTOOL_{G,S}RXFH commands, and since they do not need the
+additional fields, only copy the originally defined fields to and
+from user-space.
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/ethtool.h | 2 ++
+ net/core/ethtool.c | 38 +++++++++++++++++++++++++++++---------
+ 2 files changed, 31 insertions(+), 9 deletions(-)
+
+--- a/include/linux/ethtool.h
++++ b/include/linux/ethtool.h
+@@ -378,6 +378,8 @@ struct ethtool_rxnfc {
+ __u32 flow_type;
+ /* The rx flow hash value or the rule DB size */
+ __u64 data;
++ /* The following fields are not valid and must not be used for
++ * the ETHTOOL_{G,X}RXFH commands. */
+ struct ethtool_rx_flow_spec fs;
+ __u32 rule_cnt;
+ __u32 rule_locs[0];
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -300,22 +300,34 @@ out:
+ return ret;
+ }
+
+-static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
++static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
++ u32 cmd, void __user *useraddr)
+ {
+- struct ethtool_rxnfc cmd;
++ struct ethtool_rxnfc info;
++ size_t info_size = sizeof(info);
+
+ if (!dev->ethtool_ops->set_rxnfc)
+ return -EOPNOTSUPP;
+
+- if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
++ /* struct ethtool_rxnfc was originally defined for
++ * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
++ * members. User-space might still be using that
++ * definition. */
++ if (cmd == ETHTOOL_SRXFH)
++ info_size = (offsetof(struct ethtool_rxnfc, data) +
++ sizeof(info.data));
++
++ if (copy_from_user(&info, useraddr, info_size))
+ return -EFAULT;
+
+- return dev->ethtool_ops->set_rxnfc(dev, &cmd);
++ return dev->ethtool_ops->set_rxnfc(dev, &info);
+ }
+
+-static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
++static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
++ u32 cmd, void __user *useraddr)
+ {
+ struct ethtool_rxnfc info;
++ size_t info_size = sizeof(info);
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ int ret;
+ void *rule_buf = NULL;
+@@ -323,7 +335,15 @@ static noinline_for_stack int ethtool_ge
+ if (!ops->get_rxnfc)
+ return -EOPNOTSUPP;
+
+- if (copy_from_user(&info, useraddr, sizeof(info)))
++ /* struct ethtool_rxnfc was originally defined for
++ * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
++ * members. User-space might still be using that
++ * definition. */
++ if (cmd == ETHTOOL_GRXFH)
++ info_size = (offsetof(struct ethtool_rxnfc, data) +
++ sizeof(info.data));
++
++ if (copy_from_user(&info, useraddr, info_size))
+ return -EFAULT;
+
+ if (info.cmd == ETHTOOL_GRXCLSRLALL) {
+@@ -341,7 +361,7 @@ static noinline_for_stack int ethtool_ge
+ goto err_out;
+
+ ret = -EFAULT;
+- if (copy_to_user(useraddr, &info, sizeof(info)))
++ if (copy_to_user(useraddr, &info, info_size))
+ goto err_out;
+
+ if (rule_buf) {
+@@ -1492,12 +1512,12 @@ int dev_ethtool(struct net *net, struct
+ case ETHTOOL_GRXCLSRLCNT:
+ case ETHTOOL_GRXCLSRULE:
+ case ETHTOOL_GRXCLSRLALL:
+- rc = ethtool_get_rxnfc(dev, useraddr);
++ rc = ethtool_get_rxnfc(dev, ethcmd, useraddr);
+ break;
+ case ETHTOOL_SRXFH:
+ case ETHTOOL_SRXCLSRLDEL:
+ case ETHTOOL_SRXCLSRLINS:
+- rc = ethtool_set_rxnfc(dev, useraddr);
++ rc = ethtool_set_rxnfc(dev, ethcmd, useraddr);
+ break;
+ case ETHTOOL_GGRO:
+ rc = ethtool_get_gro(dev, useraddr);
usb-add-quirk-for-broadcom-bt-dongle.patch
usb-ftdi-add-support-for-the-rt-system-vx-7-radio-programming-cable.patch
usb-musb-tusb6010-fix-compile-error-with-n8x0_defconfig.patch
+drm-i915-gen3-page-flipping-fixes.patch
+drm-i915-don-t-queue-flips-during-a-flip-pending-event.patch
+drm-i915-hold-the-spinlock-whilst-resetting-unpin_work-along-error-path.patch
+drm-i915-handle-shared-framebuffers-when-flipping.patch
+ethtool-fix-potential-user-buffer-overflow-for-ethtool_-g-s-rxfh.patch