--- /dev/null
+From f52c619a590fa75276c07dfcaf380dee53e4ea4c Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 14 Oct 2011 11:45:40 +0200
+Subject: drm/i915/panel: Always record the backlight level again (but cleverly)
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit f52c619a590fa75276c07dfcaf380dee53e4ea4c upstream.
+
+The commit 47356eb67285014527a5ab87543ba1fae3d1e10a introduced a
+mechanism to record the backlight level only at disabling time, but it
+also introduced a regression. Since intel_lvds_enable() may be called
+without disabling (e.g. intel_lvds_commit() calls it unconditionally),
+the backlight gets back to the last recorded value. For example, this
+happens when you dim the backlight, close the lid and open the lid,
+then the backlight suddenly goes to the brightest.
+
+This patch fixes the bug by recording the backlight level always
+when changed via intel_panel_set_backlight(). And,
+intel_panel_{enable|disable}_backlight() call the internal function not
+to update the recorded level wrongly.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Reviewed-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_panel.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_panel.c
++++ b/drivers/gpu/drm/i915/intel_panel.c
+@@ -226,7 +226,7 @@ static void intel_pch_panel_set_backligh
+ I915_WRITE(BLC_PWM_CPU_CTL, val | level);
+ }
+
+-void intel_panel_set_backlight(struct drm_device *dev, u32 level)
++static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 tmp;
+@@ -254,16 +254,21 @@ void intel_panel_set_backlight(struct dr
+ I915_WRITE(BLC_PWM_CTL, tmp | level);
+ }
+
+-void intel_panel_disable_backlight(struct drm_device *dev)
++void intel_panel_set_backlight(struct drm_device *dev, u32 level)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+- if (dev_priv->backlight_enabled) {
+- dev_priv->backlight_level = intel_panel_get_backlight(dev);
+- dev_priv->backlight_enabled = false;
+- }
++ dev_priv->backlight_level = level;
++ if (dev_priv->backlight_enabled)
++ intel_panel_actually_set_backlight(dev, level);
++}
++
++void intel_panel_disable_backlight(struct drm_device *dev)
++{
++ struct drm_i915_private *dev_priv = dev->dev_private;
+
+- intel_panel_set_backlight(dev, 0);
++ dev_priv->backlight_enabled = false;
++ intel_panel_actually_set_backlight(dev, 0);
+ }
+
+ void intel_panel_enable_backlight(struct drm_device *dev)
+@@ -273,8 +278,8 @@ void intel_panel_enable_backlight(struct
+ if (dev_priv->backlight_level == 0)
+ dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+
+- intel_panel_set_backlight(dev, dev_priv->backlight_level);
+ dev_priv->backlight_enabled = true;
++ intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
+ }
+
+ void intel_panel_setup_backlight(struct drm_device *dev)
--- /dev/null
+From 8c241fef3e6f69f3f675678ae03599ece3f562e2 Mon Sep 17 00:00:00 2001
+From: Keith Packard <keithp@keithp.com>
+Date: Wed, 28 Sep 2011 16:38:44 -0700
+Subject: drm/i915: Wrap DP EDID fetch functions to enable eDP panel
+ power
+
+From: Keith Packard <keithp@keithp.com>
+
+commit 8c241fef3e6f69f3f675678ae03599ece3f562e2 upstream.
+
+Talking to the eDP DDC channel requires that the panel be powered
+up. Wrap both the EDID and modes fetch code with calls to turn the vdd
+power on and back off.
+
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_dp.c | 31 ++++++++++++++++++++++++++++---
+ 1 file changed, 28 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -1658,6 +1658,31 @@ g4x_dp_detect(struct intel_dp *intel_dp)
+ return status;
+ }
+
++static struct edid *
++intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
++{
++ struct intel_dp *intel_dp = intel_attached_dp(connector);
++ struct edid *edid;
++
++ ironlake_edp_panel_vdd_on(intel_dp);
++ edid = drm_get_edid(connector, adapter);
++ ironlake_edp_panel_vdd_off(intel_dp);
++ return edid;
++}
++
++static int
++intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *adapter)
++{
++ struct intel_dp *intel_dp = intel_attached_dp(connector);
++ int ret;
++
++ ironlake_edp_panel_vdd_on(intel_dp);
++ ret = intel_ddc_get_modes(connector, adapter);
++ ironlake_edp_panel_vdd_off(intel_dp);
++ return ret;
++}
++
++
+ /**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
+ *
+@@ -1684,7 +1709,7 @@ intel_dp_detect(struct drm_connector *co
+ if (intel_dp->force_audio) {
+ intel_dp->has_audio = intel_dp->force_audio > 0;
+ } else {
+- edid = drm_get_edid(connector, &intel_dp->adapter);
++ edid = intel_dp_get_edid(connector, &intel_dp->adapter);
+ if (edid) {
+ intel_dp->has_audio = drm_detect_monitor_audio(edid);
+ connector->display_info.raw_edid = NULL;
+@@ -1705,7 +1730,7 @@ static int intel_dp_get_modes(struct drm
+ /* We should parse the EDID data and find out if it has an audio sink
+ */
+
+- ret = intel_ddc_get_modes(connector, &intel_dp->adapter);
++ ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
+ if (ret) {
+ if (is_edp(intel_dp) && !dev_priv->panel_fixed_mode) {
+ struct drm_display_mode *newmode;
+@@ -1741,7 +1766,7 @@ intel_dp_detect_audio(struct drm_connect
+ struct edid *edid;
+ bool has_audio = false;
+
+- edid = drm_get_edid(connector, &intel_dp->adapter);
++ edid = intel_dp_get_edid(connector, &intel_dp->adapter);
+ if (edid) {
+ has_audio = drm_detect_monitor_audio(edid);
+
--- /dev/null
+From 5f0a26128d66ef81613fe923d5c288942844ccdc Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 7 Oct 2011 14:23:47 -0400
+Subject: drm/radeon/kms: bail early in dvi_detect for digital only connectors
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 5f0a26128d66ef81613fe923d5c288942844ccdc upstream.
+
+DVI-D and HDMI-A are digital only, so there's no need to
+attempt analog load detect. Also, skip bail before the
+!force check, or we fail to get a disconnect events.
+The next patches in the series attempt to fix disconnect
+events for connectors with analog support (DVI-I, HDMI-B,
+DVI-A).
+
+Fixes:
+https://bugs.freedesktop.org/show_bug.cgi?id=41561
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/radeon_connectors.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -950,6 +950,11 @@ radeon_dvi_detect(struct drm_connector *
+ if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
+ goto out;
+
++ /* DVI-D and HDMI-A are digital only */
++ if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||
++ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
++ goto out;
++
+ if (!force) {
+ ret = connector->status;
+ goto out;
--- /dev/null
+From 286e0c94f9c3f292cb38a977fbbde3433347a868 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Thu, 6 Oct 2011 18:16:24 +0200
+Subject: drm/radeon/kms: Fix I2C mask definitions
+
+From: Jean Delvare <jdelvare@suse.de>
+
+commit 286e0c94f9c3f292cb38a977fbbde3433347a868 upstream.
+
+Commit 9b9fe724 accidentally used RADEON_GPIO_EN_* where
+RADEON_GPIO_MASK_* was intended. This caused improper initialization
+of I2C buses, mostly visible when setting i2c_algo_bit.bit_test=1.
+Using the right constants fixes the problem.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Jerome Glisse <j.glisse@gmail.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/radeon_combios.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -620,8 +620,8 @@ static struct radeon_i2c_bus_rec combios
+ i2c.y_data_mask = 0x80;
+ } else {
+ /* default masks for ddc pads */
+- i2c.mask_clk_mask = RADEON_GPIO_EN_1;
+- i2c.mask_data_mask = RADEON_GPIO_EN_0;
++ i2c.mask_clk_mask = RADEON_GPIO_MASK_1;
++ i2c.mask_data_mask = RADEON_GPIO_MASK_0;
+ i2c.a_clk_mask = RADEON_GPIO_A_1;
+ i2c.a_data_mask = RADEON_GPIO_A_0;
+ i2c.en_clk_mask = RADEON_GPIO_EN_1;
--- /dev/null
+From d0d0a225e6ad43314c9aa7ea081f76adc5098ad4 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 7 Oct 2011 14:23:48 -0400
+Subject: drm/radeon/kms: handle !force case in connector detect more gracefully
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit d0d0a225e6ad43314c9aa7ea081f76adc5098ad4 upstream.
+
+When force == false, we don't do load detection in the connector
+detect functions. Unforunately, we also return the previous
+connector state so we never get disconnect events for DVI-I, DVI-A,
+or VGA. Save whether we detected the monitor via load detection
+previously and use that to determine whether we return the previous
+state or not.
+
+Fixes:
+https://bugs.freedesktop.org/show_bug.cgi?id=41561
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/radeon_connectors.c | 23 ++++++++++++++++++++---
+ drivers/gpu/drm/radeon/radeon_mode.h | 1 +
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -715,6 +715,7 @@ radeon_vga_detect(struct drm_connector *
+ dret = radeon_ddc_probe(radeon_connector,
+ radeon_connector->requires_extended_probe);
+ if (dret) {
++ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+@@ -741,12 +742,21 @@ radeon_vga_detect(struct drm_connector *
+ } else {
+
+ /* if we aren't forcing don't do destructive polling */
+- if (!force)
+- return connector->status;
++ if (!force) {
++ /* only return the previous status if we last
++ * detected a monitor via load.
++ */
++ if (radeon_connector->detected_by_load)
++ return connector->status;
++ else
++ return ret;
++ }
+
+ if (radeon_connector->dac_load_detect && encoder) {
+ encoder_funcs = encoder->helper_private;
+ ret = encoder_funcs->detect(encoder, connector);
++ if (ret == connector_status_connected)
++ radeon_connector->detected_by_load = true;
+ }
+ }
+
+@@ -888,6 +898,7 @@ radeon_dvi_detect(struct drm_connector *
+ dret = radeon_ddc_probe(radeon_connector,
+ radeon_connector->requires_extended_probe);
+ if (dret) {
++ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+@@ -955,8 +966,13 @@ radeon_dvi_detect(struct drm_connector *
+ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
+ goto out;
+
++ /* if we aren't forcing don't do destructive polling */
+ if (!force) {
+- ret = connector->status;
++ /* only return the previous status if we last
++ * detected a monitor via load.
++ */
++ if (radeon_connector->detected_by_load)
++ ret = connector->status;
+ goto out;
+ }
+
+@@ -980,6 +996,7 @@ radeon_dvi_detect(struct drm_connector *
+ ret = encoder_funcs->detect(encoder, connector);
+ if (ret == connector_status_connected) {
+ radeon_connector->use_digital = false;
++ radeon_connector->detected_by_load = true;
+ }
+ }
+ break;
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -447,6 +447,7 @@ struct radeon_connector {
+ struct edid *edid;
+ void *con_priv;
+ bool dac_load_detect;
++ bool detected_by_load; /* if the connection status was determined by load */
+ uint16_t connector_object_id;
+ struct radeon_hpd hpd;
+ struct radeon_router router;
--- /dev/null
+From 2093c6b49c8f1dc581d8953aca71297d4cace55e Mon Sep 17 00:00:00 2001
+From: Matthieu CASTET <castet.matthieu@free.fr>
+Date: Sat, 2 Jul 2011 19:47:33 +0200
+Subject: EHCI : introduce a common ehci_setup
+
+From: Matthieu CASTET <castet.matthieu@free.fr>
+
+commit 2093c6b49c8f1dc581d8953aca71297d4cace55e upstream.
+
+This allow to clean duplicated code in most of SOC driver.
+
+Signed-off-by: Matthieu CASTET <castet.matthieu@free.fr>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hcd.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -761,6 +761,35 @@ static int ehci_run (struct usb_hcd *hcd
+ return 0;
+ }
+
++static int __maybe_unused ehci_setup (struct usb_hcd *hcd)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ int retval;
++
++ ehci->regs = (void __iomem *)ehci->caps +
++ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
++ dbg_hcs_params(ehci, "reset");
++ dbg_hcc_params(ehci, "reset");
++
++ /* cache this readonly data; minimize chip reads */
++ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
++
++ ehci->sbrn = HCD_USB2;
++
++ retval = ehci_halt(ehci);
++ if (retval)
++ return retval;
++
++ /* data structure init */
++ retval = ehci_init(hcd);
++ if (retval)
++ return retval;
++
++ ehci_reset(ehci);
++
++ return 0;
++}
++
+ /*-------------------------------------------------------------------------*/
+
+ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
--- /dev/null
+From 68aa95d5d4de31c9348c1628ffa85c805305ebc5 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 12 Oct 2011 10:39:14 -0400
+Subject: EHCI: workaround for MosChip controller bug
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 68aa95d5d4de31c9348c1628ffa85c805305ebc5 upstream.
+
+This patch (as1489) works around a hardware bug in MosChip EHCI
+controllers. Evidently when one of these controllers increments the
+frame-index register, it changes the three low-order bits (the
+microframe counter) before changing the higher order bits (the frame
+counter). If the register is read at just the wrong time, the value
+obtained is too low by 8.
+
+When the appropriate quirk flag is set, we work around this problem by
+reading the frame-index register a second time if the first value's
+three low-order bits are all 0. This gives the hardware a chance to
+finish updating the register, yielding the correct value.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Jason N Pitt <jpitt@fhcrc.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-dbg.c | 2 +-
+ drivers/usb/host/ehci-hcd.c | 3 +--
+ drivers/usb/host/ehci-pci.c | 5 +++++
+ drivers/usb/host/ehci-sched.c | 30 +++++++++++++++++++++++++-----
+ drivers/usb/host/ehci.h | 17 +++++++++++++++++
+ 5 files changed, 49 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/host/ehci-dbg.c
++++ b/drivers/usb/host/ehci-dbg.c
+@@ -808,7 +808,7 @@ static ssize_t fill_registers_buffer(str
+ next += temp;
+
+ temp = scnprintf (next, size, "uframe %04x\n",
+- ehci_readl(ehci, &ehci->regs->frame_index));
++ ehci_read_frame_index(ehci));
+ size -= temp;
+ next += temp;
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -1188,8 +1188,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd,
+ static int ehci_get_frame (struct usb_hcd *hcd)
+ {
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+- return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) %
+- ehci->periodic_size;
++ return (ehci_read_frame_index(ehci) >> 3) % ehci->periodic_size;
+ }
+
+ /*-------------------------------------------------------------------------*/
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -224,6 +224,11 @@ static int ehci_pci_setup(struct usb_hcd
+ pci_dev_put(p_smbus);
+ }
+ break;
++ case PCI_VENDOR_ID_NETMOS:
++ /* MosChip frame-index-register bug */
++ ehci_info(ehci, "applying MosChip frame-index workaround\n");
++ ehci->frame_index_bug = 1;
++ break;
+ }
+
+ /* optional debug port, normally in the first BAR */
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -36,6 +36,27 @@
+
+ static int ehci_get_frame (struct usb_hcd *hcd);
+
++#ifdef CONFIG_PCI
++
++static unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
++{
++ unsigned uf;
++
++ /*
++ * The MosChip MCS9990 controller updates its microframe counter
++ * a little before the frame counter, and occasionally we will read
++ * the invalid intermediate value. Avoid problems by checking the
++ * microframe number (the low-order 3 bits); if they are 0 then
++ * re-read the register to get the correct value.
++ */
++ uf = ehci_readl(ehci, &ehci->regs->frame_index);
++ if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
++ uf = ehci_readl(ehci, &ehci->regs->frame_index);
++ return uf;
++}
++
++#endif
++
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -482,7 +503,7 @@ static int enable_periodic (struct ehci_
+ ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;
+
+ /* make sure ehci_work scans these */
+- ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
++ ehci->next_uframe = ehci_read_frame_index(ehci)
+ % (ehci->periodic_size << 3);
+ if (unlikely(ehci->broken_periodic))
+ ehci->last_periodic_enable = ktime_get_real();
+@@ -1412,7 +1433,7 @@ iso_stream_schedule (
+ goto fail;
+ }
+
+- now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1);
++ now = ehci_read_frame_index(ehci) & (mod - 1);
+
+ /* Typical case: reuse current schedule, stream is still active.
+ * Hopefully there are no gaps from the host falling behind
+@@ -2279,7 +2300,7 @@ scan_periodic (struct ehci_hcd *ehci)
+ */
+ now_uframe = ehci->next_uframe;
+ if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
+- clock = ehci_readl(ehci, &ehci->regs->frame_index);
++ clock = ehci_read_frame_index(ehci);
+ clock_frame = (clock >> 3) & (ehci->periodic_size - 1);
+ } else {
+ clock = now_uframe + mod - 1;
+@@ -2458,8 +2479,7 @@ restart:
+ || ehci->periodic_sched == 0)
+ break;
+ ehci->next_uframe = now_uframe;
+- now = ehci_readl(ehci, &ehci->regs->frame_index) &
+- (mod - 1);
++ now = ehci_read_frame_index(ehci) & (mod - 1);
+ if (now_uframe == now)
+ break;
+
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -137,6 +137,7 @@ struct ehci_hcd { /* one per controlle
+ unsigned fs_i_thresh:1; /* Intel iso scheduling */
+ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
+ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
++ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
+
+ /* required for usb32 quirk */
+ #define OHCI_CTRL_HCFS (3 << 6)
+@@ -735,6 +736,22 @@ static inline u32 hc32_to_cpup (const st
+ }
+
+ #endif
++
++/*-------------------------------------------------------------------------*/
++
++#ifdef CONFIG_PCI
++
++/* For working around the MosChip frame-index-register bug */
++static unsigned ehci_read_frame_index(struct ehci_hcd *ehci);
++
++#else
++
++static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
++{
++ return ehci_readl(ehci, &ehci->regs->frame_index);
++}
++
++#endif
+
+ /*-------------------------------------------------------------------------*/
+
--- /dev/null
+From 5238acbe36dd5100fb6b035a995ae5fc89dd0708 Mon Sep 17 00:00:00 2001
+From: Andrei Warkentin <andrey.warkentin@gmail.com>
+Date: Sat, 24 Sep 2011 12:12:30 -0400
+Subject: mmc: core: ext_csd.raw_* used in comparison but never set
+
+From: Andrei Warkentin <andrey.warkentin@gmail.com>
+
+commit 5238acbe36dd5100fb6b035a995ae5fc89dd0708 upstream.
+
+f39b2dd9d ("mmc: core: Bus width testing needs to handle suspend/resume")
+added code to only compare read-only ext_csd fields in bus width testing
+code, yet it's comparing some fields that are never set.
+
+The affected fields are ext_csd.raw_erased_mem_count and
+ext_csd.raw_partition_support.
+
+Signed-off-by: Andrei Warkentin <andrey.warkentin@gmail.com>
+Acked-by: Philip Rakity <prakity@marvell.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/mmc/core/mmc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -359,6 +359,7 @@ static int mmc_read_ext_csd(struct mmc_c
+ * card has the Enhanced area enabled. If so, export enhanced
+ * area offset and size to user by adding sysfs interface.
+ */
++ card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
+ if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
+ (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
+ u8 hc_erase_grp_sz =
+@@ -405,6 +406,7 @@ static int mmc_read_ext_csd(struct mmc_c
+ if (card->ext_csd.rev >= 5)
+ card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+
++ card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
+ if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
+ card->erased_byte = 0xFF;
+ else
--- /dev/null
+From 7f7e4129c23f0419257184dff6fec89d2d5a8964 Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@stericsson.com>
+Date: Wed, 21 Sep 2011 14:08:13 -0400
+Subject: mmc: core: Fix hangs related to insert/remove of cards
+
+From: Ulf Hansson <ulf.hansson@stericsson.com>
+
+commit 7f7e4129c23f0419257184dff6fec89d2d5a8964 upstream.
+
+During a rescan operation mmc_attach(sd|mmc|sdio) functions are
+called. The error handling in these function can trigger a detach
+of the bus, which also meant a power off. This is not notified by
+the rescan operation which then continues to the next attach function.
+
+If a power off has been done, the framework must never send any
+new commands to the host driver, without first doing a new power up.
+This will most likely trigger any host driver to hang.
+
+Moving power off out of detach and instead handle power off
+separately when it is actually needed, solves the issue.
+
+Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/mmc/core/core.c | 10 +++++-----
+ drivers/mmc/core/core.h | 1 +
+ drivers/mmc/core/mmc.c | 1 +
+ drivers/mmc/core/sd.c | 1 +
+ drivers/mmc/core/sdio.c | 1 +
+ 5 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1057,7 +1057,7 @@ static void mmc_power_up(struct mmc_host
+ mmc_host_clk_release(host);
+ }
+
+-static void mmc_power_off(struct mmc_host *host)
++void mmc_power_off(struct mmc_host *host)
+ {
+ mmc_host_clk_hold(host);
+
+@@ -1147,8 +1147,7 @@ void mmc_attach_bus(struct mmc_host *hos
+ }
+
+ /*
+- * Remove the current bus handler from a host. Assumes that there are
+- * no interesting cards left, so the bus is powered down.
++ * Remove the current bus handler from a host.
+ */
+ void mmc_detach_bus(struct mmc_host *host)
+ {
+@@ -1165,8 +1164,6 @@ void mmc_detach_bus(struct mmc_host *hos
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+- mmc_power_off(host);
+-
+ mmc_bus_put(host);
+ }
+
+@@ -1675,6 +1672,7 @@ void mmc_stop_host(struct mmc_host *host
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ mmc_bus_put(host);
+ return;
+@@ -1796,6 +1794,7 @@ int mmc_suspend_host(struct mmc_host *ho
+ host->bus_ops->remove(host);
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ host->pm_flags = 0;
+ err = 0;
+@@ -1883,6 +1882,7 @@ int mmc_pm_notify(struct notifier_block
+ host->bus_ops->remove(host);
+
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ host->pm_flags = 0;
+ break;
+--- a/drivers/mmc/core/core.h
++++ b/drivers/mmc/core/core.h
+@@ -43,6 +43,7 @@ int mmc_set_signal_voltage(struct mmc_ho
+ bool cmd11);
+ void mmc_set_timing(struct mmc_host *host, unsigned int timing);
+ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
++void mmc_power_off(struct mmc_host *host);
+
+ static inline void mmc_delay(unsigned int ms)
+ {
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -891,6 +891,7 @@ static void mmc_detect(struct mmc_host *
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ }
+ }
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1008,6 +1008,7 @@ static void mmc_sd_detect(struct mmc_hos
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ }
+ }
+--- a/drivers/mmc/core/sdio.c
++++ b/drivers/mmc/core/sdio.c
+@@ -597,6 +597,7 @@ out:
+
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
++ mmc_power_off(host);
+ mmc_release_host(host);
+ }
+ }
--- /dev/null
+From 3e309cdf07c930f29a4e0f233e47d399bea34c68 Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Wed, 5 Oct 2011 11:44:50 -0400
+Subject: PCI quirk: mmc: Always check for lower base frequency quirk for Ricoh 1180:e823
+
+From: Josh Boyer <jwboyer@redhat.com>
+
+commit 3e309cdf07c930f29a4e0f233e47d399bea34c68 upstream.
+
+Commit 15bed0f2f added a quirk for the e823 Ricoh card reader to lower the
+base frequency. However, the quirk first checks to see if the proprietary
+MMC controller is disabled, and returns if so. On some devices, such as the
+Lenovo X220, the MMC controller is already disabled by firmware it seems,
+but the frequency change is still needed so sdhci-pci can talk to the cards.
+Since the MMC controller is disabled, the frequency fixup was never being run
+on these machines.
+
+This moves the e823 check above the MMC controller check so that it always
+gets run.
+
+This fixes https://bugzilla.redhat.com/show_bug.cgi?id=722509
+
+Signed-off-by: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/quirks.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -2745,20 +2745,6 @@ static void ricoh_mmc_fixup_r5c832(struc
+ /* disable must be done via function #0 */
+ if (PCI_FUNC(dev->devfn))
+ return;
+-
+- pci_read_config_byte(dev, 0xCB, &disable);
+-
+- if (disable & 0x02)
+- return;
+-
+- pci_read_config_byte(dev, 0xCA, &write_enable);
+- pci_write_config_byte(dev, 0xCA, 0x57);
+- pci_write_config_byte(dev, 0xCB, disable | 0x02);
+- pci_write_config_byte(dev, 0xCA, write_enable);
+-
+- dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
+- dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+-
+ /*
+ * RICOH 0xe823 SD/MMC card reader fails to recognize
+ * certain types of SD/MMC cards. Lowering the SD base
+@@ -2781,6 +2767,20 @@ static void ricoh_mmc_fixup_r5c832(struc
+
+ dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
+ }
++
++ pci_read_config_byte(dev, 0xCB, &disable);
++
++ if (disable & 0x02)
++ return;
++
++ pci_read_config_byte(dev, 0xCA, &write_enable);
++ pci_write_config_byte(dev, 0xCA, 0x57);
++ pci_write_config_byte(dev, 0xCB, disable | 0x02);
++ pci_write_config_byte(dev, 0xCA, write_enable);
++
++ dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
++ dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
++
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
usb-qcserial-add-device-id-for-hp-un2430-mobile-broadband-module.patch
serial-pxa-work-around-for-errata-20.patch
serial-core-power-up-uart-port-early-before-we-do-set_termios-when-resuming.patch
+ehci-introduce-a-common-ehci_setup.patch
+usb-fix-ehci-alignment-error.patch
+ehci-workaround-for-moschip-controller-bug.patch
+xhci-mem.c-check-for-ring-first_seg-null.patch
+xhci-amd-isoc-link-trb-chain-bit-quirk.patch
+drm-i915-wrap-dp-edid-fetch-functions-to-enable-edp-panel.patch
+drm-i915-panel-always-record-the-backlight-level-again-but-cleverly.patch
+drm-radeon-kms-bail-early-in-dvi_detect-for-digital-only-connectors.patch
+drm-radeon-kms-handle-force-case-in-connector-detect-more-gracefully.patch
+drm-radeon-kms-fix-i2c-mask-definitions.patch
+mmc-core-fix-hangs-related-to-insert-remove-of-cards.patch
+mmc-core-ext_csd.raw_-used-in-comparison-but-never-set.patch
+pci-quirk-mmc-always-check-for-lower-base-frequency-quirk-for-ricoh-1180-e823.patch
--- /dev/null
+From 276532ba9666b36974cbe16f303fc8be99c9da17 Mon Sep 17 00:00:00 2001
+From: Harro Haan <hrhaan@gmail.com>
+Date: Mon, 10 Oct 2011 14:38:27 +0200
+Subject: USB: fix ehci alignment error
+
+From: Harro Haan <hrhaan@gmail.com>
+
+commit 276532ba9666b36974cbe16f303fc8be99c9da17 upstream.
+
+The Kirkwood gave an unaligned memory access error on
+line 742 of drivers/usb/host/echi-hcd.c:
+"ehci->last_periodic_enable = ktime_get_real();"
+
+Signed-off-by: Harro Haan <hrhaan@gmail.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/hcd.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -178,7 +178,7 @@ struct usb_hcd {
+ * this structure.
+ */
+ unsigned long hcd_priv[0]
+- __attribute__ ((aligned(sizeof(unsigned long))));
++ __attribute__ ((aligned(sizeof(s64))));
+ };
+
+ /* 2.4 does this a bit differently ... */
--- /dev/null
+From 7e393a834b41001174a8fb3ae3bc23a749467760 Mon Sep 17 00:00:00 2001
+From: Andiry Xu <andiry.xu@amd.com>
+Date: Fri, 23 Sep 2011 14:19:54 -0700
+Subject: xHCI: AMD isoc link TRB chain bit quirk
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+commit 7e393a834b41001174a8fb3ae3bc23a749467760 upstream.
+
+Setting the chain (CH) bit in the link TRB of isochronous transfer rings
+is required by AMD 0.96 xHCI host controller to successfully transverse
+multi-TRB TD that span through different memory segments.
+
+When a Missed Service Error event occurs, if the chain bit is not set in
+the link TRB and the host skips TDs which just across a link TRB, the
+host may falsely recognize the link TRB as a normal TRB. You can see
+this may cause big trouble - the host does not jump to the right address
+which is pointed by the link TRB, but continue fetching the memory which
+is after the link TRB address, which may not even belong to the host,
+and the result cannot be predicted.
+
+This causes some big problems. Without the former patch I sent: "xHCI:
+prevent infinite loop when processing MSE event", the system may hang.
+With that patch applied, system does not hang, but the host still access
+wrong memory address and isoc transfer will fail. With this patch,
+isochronous transfer works as expected.
+
+This patch should be applied to kernels as old as 2.6.36, which was when
+the first isochronous support was added for the xHCI host controller.
+
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-mem.c | 32 ++++++++++++++-----------
+ drivers/usb/host/xhci-pci.c | 3 ++
+ drivers/usb/host/xhci-ring.c | 53 +++++++++++++++++++++++--------------------
+ drivers/usb/host/xhci.h | 1
+ 4 files changed, 51 insertions(+), 38 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -81,7 +81,7 @@ static void xhci_segment_free(struct xhc
+ * related flags, such as End TRB, Toggle Cycle, and no snoop.
+ */
+ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
+- struct xhci_segment *next, bool link_trbs)
++ struct xhci_segment *next, bool link_trbs, bool isoc)
+ {
+ u32 val;
+
+@@ -97,7 +97,9 @@ static void xhci_link_segments(struct xh
+ val &= ~TRB_TYPE_BITMASK;
+ val |= TRB_TYPE(TRB_LINK);
+ /* Always set the chain bit with 0.95 hardware */
+- if (xhci_link_trb_quirk(xhci))
++ /* Set chain bit for isoc rings on AMD 0.96 host */
++ if (xhci_link_trb_quirk(xhci) ||
++ (isoc && (xhci->quirks & XHCI_AMD_0x96_HOST)))
+ val |= TRB_CHAIN;
+ prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val);
+ }
+@@ -154,7 +156,7 @@ static void xhci_initialize_ring_info(st
+ * See section 4.9.1 and figures 15 and 16.
+ */
+ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
+- unsigned int num_segs, bool link_trbs, gfp_t flags)
++ unsigned int num_segs, bool link_trbs, bool isoc, gfp_t flags)
+ {
+ struct xhci_ring *ring;
+ struct xhci_segment *prev;
+@@ -180,12 +182,12 @@ static struct xhci_ring *xhci_ring_alloc
+ next = xhci_segment_alloc(xhci, flags);
+ if (!next)
+ goto fail;
+- xhci_link_segments(xhci, prev, next, link_trbs);
++ xhci_link_segments(xhci, prev, next, link_trbs, isoc);
+
+ prev = next;
+ num_segs--;
+ }
+- xhci_link_segments(xhci, prev, ring->first_seg, link_trbs);
++ xhci_link_segments(xhci, prev, ring->first_seg, link_trbs, isoc);
+
+ if (link_trbs) {
+ /* See section 4.9.2.1 and 6.4.4.1 */
+@@ -231,14 +233,14 @@ void xhci_free_or_cache_endpoint_ring(st
+ * pointers to the beginning of the ring.
+ */
+ static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
+- struct xhci_ring *ring)
++ struct xhci_ring *ring, bool isoc)
+ {
+ struct xhci_segment *seg = ring->first_seg;
+ do {
+ memset(seg->trbs, 0,
+ sizeof(union xhci_trb)*TRBS_PER_SEGMENT);
+ /* All endpoint rings have link TRBs */
+- xhci_link_segments(xhci, seg, seg->next, 1);
++ xhci_link_segments(xhci, seg, seg->next, 1, isoc);
+ seg = seg->next;
+ } while (seg != ring->first_seg);
+ xhci_initialize_ring_info(ring);
+@@ -542,7 +544,7 @@ struct xhci_stream_info *xhci_alloc_stre
+ */
+ for (cur_stream = 1; cur_stream < num_streams; cur_stream++) {
+ stream_info->stream_rings[cur_stream] =
+- xhci_ring_alloc(xhci, 1, true, mem_flags);
++ xhci_ring_alloc(xhci, 1, true, false, mem_flags);
+ cur_ring = stream_info->stream_rings[cur_stream];
+ if (!cur_ring)
+ goto cleanup_rings;
+@@ -767,7 +769,7 @@ int xhci_alloc_virt_device(struct xhci_h
+ }
+
+ /* Allocate endpoint 0 ring */
+- dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags);
++ dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, false, flags);
+ if (!dev->eps[0].ring)
+ goto fail;
+
+@@ -1177,10 +1179,10 @@ int xhci_endpoint_init(struct xhci_hcd *
+ */
+ if (usb_endpoint_xfer_isoc(&ep->desc))
+ virt_dev->eps[ep_index].new_ring =
+- xhci_ring_alloc(xhci, 8, true, mem_flags);
++ xhci_ring_alloc(xhci, 8, true, true, mem_flags);
+ else
+ virt_dev->eps[ep_index].new_ring =
+- xhci_ring_alloc(xhci, 1, true, mem_flags);
++ xhci_ring_alloc(xhci, 1, true, false, mem_flags);
+ if (!virt_dev->eps[ep_index].new_ring) {
+ /* Attempt to use the ring cache */
+ if (virt_dev->num_rings_cached == 0)
+@@ -1189,7 +1191,8 @@ int xhci_endpoint_init(struct xhci_hcd *
+ virt_dev->ring_cache[virt_dev->num_rings_cached];
+ virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
+ virt_dev->num_rings_cached--;
+- xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring);
++ xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
++ usb_endpoint_xfer_isoc(&ep->desc) ? true : false);
+ }
+ virt_dev->eps[ep_index].skip = false;
+ ep_ring = virt_dev->eps[ep_index].new_ring;
+@@ -2003,7 +2006,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ goto fail;
+
+ /* Set up the command ring to have one segments for now. */
+- xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, flags);
++ xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, false, flags);
+ if (!xhci->cmd_ring)
+ goto fail;
+ xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
+@@ -2034,7 +2037,8 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ * the event ring segment table (ERST). Section 4.9.3.
+ */
+ xhci_dbg(xhci, "// Allocating event ring\n");
+- xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags);
++ xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, false,
++ flags);
+ if (!xhci->event_ring)
+ goto fail;
+ if (xhci_check_trb_in_td_math(xhci, flags) < 0)
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -128,6 +128,9 @@ static int xhci_pci_setup(struct usb_hcd
+ if (pdev->vendor == PCI_VENDOR_ID_NEC)
+ xhci->quirks |= XHCI_NEC_HOST;
+
++ if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96)
++ xhci->quirks |= XHCI_AMD_0x96_HOST;
++
+ /* AMD PLL quirk */
+ if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
+ xhci->quirks |= XHCI_AMD_PLL_FIX;
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -187,7 +187,7 @@ static void inc_deq(struct xhci_hcd *xhc
+ * prepare_transfer()?
+ */
+ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
+- bool consumer, bool more_trbs_coming)
++ bool consumer, bool more_trbs_coming, bool isoc)
+ {
+ u32 chain;
+ union xhci_trb *next;
+@@ -214,11 +214,13 @@ static void inc_enq(struct xhci_hcd *xhc
+ if (!chain && !more_trbs_coming)
+ break;
+
+- /* If we're not dealing with 0.95 hardware,
++ /* If we're not dealing with 0.95 hardware or
++ * isoc rings on AMD 0.96 host,
+ * carry over the chain bit of the previous TRB
+ * (which may mean the chain bit is cleared).
+ */
+- if (!xhci_link_trb_quirk(xhci)) {
++ if (!(isoc && (xhci->quirks & XHCI_AMD_0x96_HOST))
++ && !xhci_link_trb_quirk(xhci)) {
+ next->link.control &=
+ cpu_to_le32(~TRB_CHAIN);
+ next->link.control |=
+@@ -2398,7 +2400,7 @@ irqreturn_t xhci_msi_irq(int irq, struct
+ * prepare_transfer()?
+ */
+ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
+- bool consumer, bool more_trbs_coming,
++ bool consumer, bool more_trbs_coming, bool isoc,
+ u32 field1, u32 field2, u32 field3, u32 field4)
+ {
+ struct xhci_generic_trb *trb;
+@@ -2408,7 +2410,7 @@ static void queue_trb(struct xhci_hcd *x
+ trb->field[1] = cpu_to_le32(field2);
+ trb->field[2] = cpu_to_le32(field3);
+ trb->field[3] = cpu_to_le32(field4);
+- inc_enq(xhci, ring, consumer, more_trbs_coming);
++ inc_enq(xhci, ring, consumer, more_trbs_coming, isoc);
+ }
+
+ /*
+@@ -2416,7 +2418,7 @@ static void queue_trb(struct xhci_hcd *x
+ * FIXME allocate segments if the ring is full.
+ */
+ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
+- u32 ep_state, unsigned int num_trbs, gfp_t mem_flags)
++ u32 ep_state, unsigned int num_trbs, bool isoc, gfp_t mem_flags)
+ {
+ /* Make sure the endpoint has been added to xHC schedule */
+ switch (ep_state) {
+@@ -2458,10 +2460,11 @@ static int prepare_ring(struct xhci_hcd
+ next = ring->enqueue;
+
+ while (last_trb(xhci, ring, ring->enq_seg, next)) {
+- /* If we're not dealing with 0.95 hardware,
+- * clear the chain bit.
++ /* If we're not dealing with 0.95 hardware or isoc rings
++ * on AMD 0.96 host, clear the chain bit.
+ */
+- if (!xhci_link_trb_quirk(xhci))
++ if (!xhci_link_trb_quirk(xhci) && !(isoc &&
++ (xhci->quirks & XHCI_AMD_0x96_HOST)))
+ next->link.control &= cpu_to_le32(~TRB_CHAIN);
+ else
+ next->link.control |= cpu_to_le32(TRB_CHAIN);
+@@ -2494,6 +2497,7 @@ static int prepare_transfer(struct xhci_
+ unsigned int num_trbs,
+ struct urb *urb,
+ unsigned int td_index,
++ bool isoc,
+ gfp_t mem_flags)
+ {
+ int ret;
+@@ -2511,7 +2515,7 @@ static int prepare_transfer(struct xhci_
+
+ ret = prepare_ring(xhci, ep_ring,
+ le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK,
+- num_trbs, mem_flags);
++ num_trbs, isoc, mem_flags);
+ if (ret)
+ return ret;
+
+@@ -2734,7 +2738,7 @@ static int queue_bulk_sg_tx(struct xhci_
+
+ trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+- num_trbs, urb, 0, mem_flags);
++ num_trbs, urb, 0, false, mem_flags);
+ if (trb_buff_len < 0)
+ return trb_buff_len;
+
+@@ -2829,7 +2833,7 @@ static int queue_bulk_sg_tx(struct xhci_
+ more_trbs_coming = true;
+ else
+ more_trbs_coming = false;
+- queue_trb(xhci, ep_ring, false, more_trbs_coming,
++ queue_trb(xhci, ep_ring, false, more_trbs_coming, false,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -2920,7 +2924,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+- num_trbs, urb, 0, mem_flags);
++ num_trbs, urb, 0, false, mem_flags);
+ if (ret < 0)
+ return ret;
+
+@@ -2992,7 +2996,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ more_trbs_coming = true;
+ else
+ more_trbs_coming = false;
+- queue_trb(xhci, ep_ring, false, more_trbs_coming,
++ queue_trb(xhci, ep_ring, false, more_trbs_coming, false,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -3052,7 +3056,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ num_trbs++;
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+- num_trbs, urb, 0, mem_flags);
++ num_trbs, urb, 0, false, mem_flags);
+ if (ret < 0)
+ return ret;
+
+@@ -3085,7 +3089,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ }
+ }
+
+- queue_trb(xhci, ep_ring, false, true,
++ queue_trb(xhci, ep_ring, false, true, false,
+ setup->bRequestType | setup->bRequest << 8 | le16_to_cpu(setup->wValue) << 16,
+ le16_to_cpu(setup->wIndex) | le16_to_cpu(setup->wLength) << 16,
+ TRB_LEN(8) | TRB_INTR_TARGET(0),
+@@ -3105,7 +3109,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ if (urb->transfer_buffer_length > 0) {
+ if (setup->bRequestType & USB_DIR_IN)
+ field |= TRB_DIR_IN;
+- queue_trb(xhci, ep_ring, false, true,
++ queue_trb(xhci, ep_ring, false, true, false,
+ lower_32_bits(urb->transfer_dma),
+ upper_32_bits(urb->transfer_dma),
+ length_field,
+@@ -3121,7 +3125,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ field = 0;
+ else
+ field = TRB_DIR_IN;
+- queue_trb(xhci, ep_ring, false, false,
++ queue_trb(xhci, ep_ring, false, false, false,
+ 0,
+ 0,
+ TRB_INTR_TARGET(0),
+@@ -3270,7 +3274,8 @@ static int xhci_queue_isoc_tx(struct xhc
+ trbs_per_td = count_isoc_trbs_needed(xhci, urb, i);
+
+ ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
+- urb->stream_id, trbs_per_td, urb, i, mem_flags);
++ urb->stream_id, trbs_per_td, urb, i, true,
++ mem_flags);
+ if (ret < 0) {
+ if (i == 0)
+ return ret;
+@@ -3340,7 +3345,7 @@ static int xhci_queue_isoc_tx(struct xhc
+ remainder |
+ TRB_INTR_TARGET(0);
+
+- queue_trb(xhci, ep_ring, false, more_trbs_coming,
++ queue_trb(xhci, ep_ring, false, more_trbs_coming, true,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -3422,7 +3427,7 @@ int xhci_queue_isoc_tx_prepare(struct xh
+ * Do not insert any td of the urb to the ring if the check failed.
+ */
+ ret = prepare_ring(xhci, ep_ring, le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK,
+- num_trbs, mem_flags);
++ num_trbs, true, mem_flags);
+ if (ret)
+ return ret;
+
+@@ -3481,7 +3486,7 @@ static int queue_command(struct xhci_hcd
+ reserved_trbs++;
+
+ ret = prepare_ring(xhci, xhci->cmd_ring, EP_STATE_RUNNING,
+- reserved_trbs, GFP_ATOMIC);
++ reserved_trbs, false, GFP_ATOMIC);
+ if (ret < 0) {
+ xhci_err(xhci, "ERR: No room for command on command ring\n");
+ if (command_must_succeed)
+@@ -3489,8 +3494,8 @@ static int queue_command(struct xhci_hcd
+ "unfailable commands failed.\n");
+ return ret;
+ }
+- queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3,
+- field4 | xhci->cmd_ring->cycle_state);
++ queue_trb(xhci, xhci->cmd_ring, false, false, false, field1, field2,
++ field3, field4 | xhci->cmd_ring->cycle_state);
+ return 0;
+ }
+
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1311,6 +1311,7 @@ struct xhci_hcd {
+ #define XHCI_EP_LIMIT_QUIRK (1 << 5)
+ #define XHCI_BROKEN_MSI (1 << 6)
+ #define XHCI_RESET_ON_RESUME (1 << 7)
++#define XHCI_AMD_0x96_HOST (1 << 9)
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+ /* There are two roothubs to keep track of bus suspend info for */
--- /dev/null
+From 0e6c7f746ea99089fb3263709075c20485a479ae Mon Sep 17 00:00:00 2001
+From: Kautuk Consul <consul.kautuk@gmail.com>
+Date: Mon, 19 Sep 2011 16:53:12 -0700
+Subject: xhci-mem.c: Check for ring->first_seg != NULL
+
+From: Kautuk Consul <consul.kautuk@gmail.com>
+
+commit 0e6c7f746ea99089fb3263709075c20485a479ae upstream.
+
+There are 2 situations wherein the xhci_ring* might not get freed:
+- When xhci_ring_alloc() -> xhci_segment_alloc() returns NULL and
+ we goto the fail: label in xhci_ring_alloc. In this case, the ring
+ will not get kfreed.
+- When the num_segs argument to xhci_ring_alloc is passed as 0 and
+ we try to free the rung after that.
+ ( This doesn't really happen as of now in the code but we seem to
+ be entertaining num_segs=0 in xhci_ring_alloc )
+
+This should be backported to kernels as old as 2.6.31.
+
+Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-mem.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -112,18 +112,20 @@ void xhci_ring_free(struct xhci_hcd *xhc
+ struct xhci_segment *seg;
+ struct xhci_segment *first_seg;
+
+- if (!ring || !ring->first_seg)
++ if (!ring)
+ return;
+- first_seg = ring->first_seg;
+- seg = first_seg->next;
+- xhci_dbg(xhci, "Freeing ring at %p\n", ring);
+- while (seg != first_seg) {
+- struct xhci_segment *next = seg->next;
+- xhci_segment_free(xhci, seg);
+- seg = next;
++ if (ring->first_seg) {
++ first_seg = ring->first_seg;
++ seg = first_seg->next;
++ xhci_dbg(xhci, "Freeing ring at %p\n", ring);
++ while (seg != first_seg) {
++ struct xhci_segment *next = seg->next;
++ xhci_segment_free(xhci, seg);
++ seg = next;
++ }
++ xhci_segment_free(xhci, first_seg);
++ ring->first_seg = NULL;
+ }
+- xhci_segment_free(xhci, first_seg);
+- ring->first_seg = NULL;
+ kfree(ring);
+ }
+