]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Jan 2013 13:06:33 +0000 (05:06 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Jan 2013 13:06:33 +0000 (05:06 -0800)
added patches:
regulator-max8997-use-uv-in-voltage_map_desc.patch
regulator-max8998-ensure-enough-delay-time-for-max8998_set_voltage_buck_time_sel.patch
regulator-max8998-use-uv-in-voltage_map_desc.patch
usb-ehci-make-debug-port-in-use-detection-functional-again.patch
usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch
xhci-avoid-dead-ports-add-roothub-port-polling.patch
xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch

queue-3.7/regulator-max8997-use-uv-in-voltage_map_desc.patch [new file with mode: 0644]
queue-3.7/regulator-max8998-ensure-enough-delay-time-for-max8998_set_voltage_buck_time_sel.patch [new file with mode: 0644]
queue-3.7/regulator-max8998-use-uv-in-voltage_map_desc.patch [new file with mode: 0644]
queue-3.7/series
queue-3.7/usb-ehci-make-debug-port-in-use-detection-functional-again.patch [new file with mode: 0644]
queue-3.7/usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch [new file with mode: 0644]
queue-3.7/xhci-avoid-dead-ports-add-roothub-port-polling.patch [new file with mode: 0644]
queue-3.7/xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch [new file with mode: 0644]

diff --git a/queue-3.7/regulator-max8997-use-uv-in-voltage_map_desc.patch b/queue-3.7/regulator-max8997-use-uv-in-voltage_map_desc.patch
new file mode 100644 (file)
index 0000000..fcaf1a3
--- /dev/null
@@ -0,0 +1,150 @@
+From bc3b7756b5ff66828acf7bc24f148d28b8d61108 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Fri, 28 Dec 2012 17:09:03 +0800
+Subject: regulator: max8997: Use uV in voltage_map_desc
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit bc3b7756b5ff66828acf7bc24f148d28b8d61108 upstream.
+
+Current code does integer division (min_vol = min_uV / 1000) before pass
+min_vol to max8997_get_voltage_proper_val().
+So it is possible min_vol is truncated to a smaller value.
+
+For example, if the request min_uV is 800900 for ldo.
+min_vol = 800900 / 1000 = 800 (mV)
+Then max8997_get_voltage_proper_val returns 800 mV for this case which is lower
+than the requested voltage.
+
+Use uV rather than mV in voltage_map_desc to prevent truncation by integer
+division.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/max8997.c |   36 +++++++++++++++++-------------------
+ 1 file changed, 17 insertions(+), 19 deletions(-)
+
+--- a/drivers/regulator/max8997.c
++++ b/drivers/regulator/max8997.c
+@@ -69,26 +69,26 @@ struct voltage_map_desc {
+       int step;
+ };
+-/* Voltage maps in mV */
++/* Voltage maps in uV */
+ static const struct voltage_map_desc ldo_voltage_map_desc = {
+-      .min = 800,     .max = 3950,    .step = 50,
++      .min = 800000,  .max = 3950000, .step = 50000,
+ }; /* LDO1 ~ 18, 21 all */
+ static const struct voltage_map_desc buck1245_voltage_map_desc = {
+-      .min = 650,     .max = 2225,    .step = 25,
++      .min = 650000,  .max = 2225000, .step = 25000,
+ }; /* Buck1, 2, 4, 5 */
+ static const struct voltage_map_desc buck37_voltage_map_desc = {
+-      .min = 750,     .max = 3900,    .step = 50,
++      .min = 750000,  .max = 3900000, .step = 50000,
+ }; /* Buck3, 7 */
+-/* current map in mA */
++/* current map in uA */
+ static const struct voltage_map_desc charger_current_map_desc = {
+-      .min = 200,     .max = 950,     .step = 50,
++      .min = 200000,  .max = 950000,  .step = 50000,
+ };
+ static const struct voltage_map_desc topoff_current_map_desc = {
+-      .min = 50,      .max = 200,     .step = 10,
++      .min = 50000,   .max = 200000,  .step = 10000,
+ };
+ static const struct voltage_map_desc *reg_voltage_map[] = {
+@@ -192,7 +192,7 @@ static int max8997_list_voltage(struct r
+       if (val > desc->max)
+               return -EINVAL;
+-      return val * 1000;
++      return val;
+ }
+ static int max8997_get_enable_register(struct regulator_dev *rdev,
+@@ -483,7 +483,6 @@ static int max8997_set_voltage_ldobuck(s
+ {
+       struct max8997_data *max8997 = rdev_get_drvdata(rdev);
+       struct i2c_client *i2c = max8997->iodev->i2c;
+-      int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       const struct voltage_map_desc *desc;
+       int rid = rdev_get_id(rdev);
+       int i, reg, shift, mask, ret;
+@@ -507,7 +506,7 @@ static int max8997_set_voltage_ldobuck(s
+       desc = reg_voltage_map[rid];
+-      i = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
++      i = max8997_get_voltage_proper_val(desc, min_uV, max_uV);
+       if (i < 0)
+               return i;
+@@ -555,7 +554,7 @@ static int max8997_set_voltage_ldobuck_t
+       case MAX8997_BUCK4:
+       case MAX8997_BUCK5:
+               return DIV_ROUND_UP(desc->step * (new_selector - old_selector),
+-                                  max8997->ramp_delay);
++                                  max8997->ramp_delay * 1000);
+       }
+       return 0;
+@@ -654,7 +653,6 @@ static int max8997_set_voltage_buck(stru
+       const struct voltage_map_desc *desc;
+       int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
+       bool gpio_dvs_mode = false;
+-      int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       if (rid < MAX8997_BUCK1 || rid > MAX8997_BUCK7)
+               return -EINVAL;
+@@ -679,7 +677,7 @@ static int max8997_set_voltage_buck(stru
+                                               selector);
+       desc = reg_voltage_map[rid];
+-      new_val = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
++      new_val = max8997_get_voltage_proper_val(desc, min_uV, max_uV);
+       if (new_val < 0)
+               return new_val;
+@@ -977,8 +975,8 @@ static __devinit int max8997_pmic_probe(
+               max8997->buck1_vol[i] = ret =
+                       max8997_get_voltage_proper_val(
+                                       &buck1245_voltage_map_desc,
+-                                      pdata->buck1_voltage[i] / 1000,
+-                                      pdata->buck1_voltage[i] / 1000 +
++                                      pdata->buck1_voltage[i],
++                                      pdata->buck1_voltage[i] +
+                                       buck1245_voltage_map_desc.step);
+               if (ret < 0)
+                       goto err_out;
+@@ -986,8 +984,8 @@ static __devinit int max8997_pmic_probe(
+               max8997->buck2_vol[i] = ret =
+                       max8997_get_voltage_proper_val(
+                                       &buck1245_voltage_map_desc,
+-                                      pdata->buck2_voltage[i] / 1000,
+-                                      pdata->buck2_voltage[i] / 1000 +
++                                      pdata->buck2_voltage[i],
++                                      pdata->buck2_voltage[i] +
+                                       buck1245_voltage_map_desc.step);
+               if (ret < 0)
+                       goto err_out;
+@@ -995,8 +993,8 @@ static __devinit int max8997_pmic_probe(
+               max8997->buck5_vol[i] = ret =
+                       max8997_get_voltage_proper_val(
+                                       &buck1245_voltage_map_desc,
+-                                      pdata->buck5_voltage[i] / 1000,
+-                                      pdata->buck5_voltage[i] / 1000 +
++                                      pdata->buck5_voltage[i],
++                                      pdata->buck5_voltage[i] +
+                                       buck1245_voltage_map_desc.step);
+               if (ret < 0)
+                       goto err_out;
diff --git a/queue-3.7/regulator-max8998-ensure-enough-delay-time-for-max8998_set_voltage_buck_time_sel.patch b/queue-3.7/regulator-max8998-ensure-enough-delay-time-for-max8998_set_voltage_buck_time_sel.patch
new file mode 100644 (file)
index 0000000..b12ad8e
--- /dev/null
@@ -0,0 +1,31 @@
+From 81d0a6ae7befb24c06f4aa4856af7f8d1f612171 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Wed, 9 Jan 2013 19:34:57 +0800
+Subject: regulator: max8998: Ensure enough delay time for max8998_set_voltage_buck_time_sel
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit 81d0a6ae7befb24c06f4aa4856af7f8d1f612171 upstream.
+
+Use DIV_ROUND_UP to prevent truncation by integer division issue.
+This ensures we return enough delay time.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/max8998.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -447,7 +447,7 @@ static int max8998_set_voltage_buck_time
+       difference = (new_selector - old_selector) * desc->step / 1000;
+       if (difference > 0)
+-              return difference / ((val & 0x0f) + 1);
++              return DIV_ROUND_UP(difference, (val & 0x0f) + 1);
+       return 0;
+ }
diff --git a/queue-3.7/regulator-max8998-use-uv-in-voltage_map_desc.patch b/queue-3.7/regulator-max8998-use-uv-in-voltage_map_desc.patch
new file mode 100644 (file)
index 0000000..cbb8394
--- /dev/null
@@ -0,0 +1,150 @@
+From adf6178ad5552a7f2f742a8c85343c50f080c412 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Fri, 28 Dec 2012 17:10:20 +0800
+Subject: regulator: max8998: Use uV in voltage_map_desc
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit adf6178ad5552a7f2f742a8c85343c50f080c412 upstream.
+
+Integer division may truncate.
+This happens when pdata->buckx_voltagex setting is not align with 1000 uV.
+Thus use uV in voltage_map_desc, this ensures the selected voltage won't less
+than pdata buckx_voltagex settings.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/max8998.c |   42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -51,39 +51,39 @@ struct voltage_map_desc {
+       int step;
+ };
+-/* Voltage maps */
++/* Voltage maps in uV*/
+ static const struct voltage_map_desc ldo23_voltage_map_desc = {
+-      .min = 800,     .step = 50,     .max = 1300,
++      .min = 800000,  .step = 50000,  .max = 1300000,
+ };
+ static const struct voltage_map_desc ldo456711_voltage_map_desc = {
+-      .min = 1600,    .step = 100,    .max = 3600,
++      .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc ldo8_voltage_map_desc = {
+-      .min = 3000,    .step = 100,    .max = 3600,
++      .min = 3000000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc ldo9_voltage_map_desc = {
+-      .min = 2800,    .step = 100,    .max = 3100,
++      .min = 2800000, .step = 100000, .max = 3100000,
+ };
+ static const struct voltage_map_desc ldo10_voltage_map_desc = {
+-      .min = 950,     .step = 50,     .max = 1300,
++      .min = 95000,   .step = 50000,  .max = 1300000,
+ };
+ static const struct voltage_map_desc ldo1213_voltage_map_desc = {
+-      .min = 800,     .step = 100,    .max = 3300,
++      .min = 800000,  .step = 100000, .max = 3300000,
+ };
+ static const struct voltage_map_desc ldo1415_voltage_map_desc = {
+-      .min = 1200,    .step = 100,    .max = 3300,
++      .min = 1200000, .step = 100000, .max = 3300000,
+ };
+ static const struct voltage_map_desc ldo1617_voltage_map_desc = {
+-      .min = 1600,    .step = 100,    .max = 3600,
++      .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc buck12_voltage_map_desc = {
+-      .min = 750,     .step = 25,     .max = 1525,
++      .min = 750000,  .step = 25000,  .max = 1525000,
+ };
+ static const struct voltage_map_desc buck3_voltage_map_desc = {
+-      .min = 1600,    .step = 100,    .max = 3600,
++      .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc buck4_voltage_map_desc = {
+-      .min = 800,     .step = 100,    .max = 2300,
++      .min = 800000,  .step = 100000, .max = 2300000,
+ };
+ static const struct voltage_map_desc *ldo_voltage_map[] = {
+@@ -445,7 +445,7 @@ static int max8998_set_voltage_buck_time
+       if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
+               return 0;
+-      difference = (new_selector - old_selector) * desc->step;
++      difference = (new_selector - old_selector) * desc->step / 1000;
+       if (difference > 0)
+               return difference / ((val & 0x0f) + 1);
+@@ -702,7 +702,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck1_voltage1 / 1000))
++                     < pdata->buck1_voltage1)
+                       i++;
+               max8998->buck1_vol[0] = i;
+               ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
+@@ -713,7 +713,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck1_voltage2 / 1000))
++                     < pdata->buck1_voltage2)
+                       i++;
+               max8998->buck1_vol[1] = i;
+@@ -725,7 +725,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck1_voltage3 / 1000))
++                     < pdata->buck1_voltage3)
+                       i++;
+               max8998->buck1_vol[2] = i;
+@@ -737,7 +737,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck1_voltage4 / 1000))
++                     < pdata->buck1_voltage4)
+                       i++;
+               max8998->buck1_vol[3] = i;
+@@ -763,7 +763,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck2_voltage1 / 1000))
++                     < pdata->buck2_voltage1)
+                       i++;
+               max8998->buck2_vol[0] = i;
+               ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
+@@ -774,7 +774,7 @@ static __devinit int max8998_pmic_probe(
+               i = 0;
+               while (buck12_voltage_map_desc.min +
+                      buck12_voltage_map_desc.step*i
+-                     < (pdata->buck2_voltage2 / 1000))
++                     < pdata->buck2_voltage2)
+                       i++;
+               max8998->buck2_vol[1] = i;
+               ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
+@@ -792,8 +792,8 @@ static __devinit int max8998_pmic_probe(
+                       int count = (desc->max - desc->min) / desc->step + 1;
+                       regulators[index].n_voltages = count;
+-                      regulators[index].min_uV = desc->min * 1000;
+-                      regulators[index].uV_step = desc->step * 1000;
++                      regulators[index].min_uV = desc->min;
++                      regulators[index].uV_step = desc->step;
+               }
+               config.dev = max8998->dev;
index 479b430ca60e8f37117a7a0c37e2f18bc844129a..9939ff6e9b9b07d975cd967b5b4b03f2fbedd9c8 100644 (file)
@@ -174,3 +174,10 @@ usb-allow-usb-3.0-ports-to-be-disabled.patch
 usb-increase-reset-timeout.patch
 usb-ignore-port-state-until-reset-completes.patch
 usb-handle-warm-reset-failure-on-empty-port.patch
+xhci-avoid-dead-ports-add-roothub-port-polling.patch
+usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch
+xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch
+usb-ehci-make-debug-port-in-use-detection-functional-again.patch
+regulator-max8997-use-uv-in-voltage_map_desc.patch
+regulator-max8998-use-uv-in-voltage_map_desc.patch
+regulator-max8998-ensure-enough-delay-time-for-max8998_set_voltage_buck_time_sel.patch
diff --git a/queue-3.7/usb-ehci-make-debug-port-in-use-detection-functional-again.patch b/queue-3.7/usb-ehci-make-debug-port-in-use-detection-functional-again.patch
new file mode 100644 (file)
index 0000000..26cf461
--- /dev/null
@@ -0,0 +1,85 @@
+From 75e1a2ae1f61ce1ae640410ba757bba84bd9fefe Mon Sep 17 00:00:00 2001
+From: Jan Beulich <JBeulich@suse.com>
+Date: Wed, 19 Dec 2012 16:15:56 +0000
+Subject: USB: ehci: make debug port in-use detection functional again
+
+From: Jan Beulich <JBeulich@suse.com>
+
+commit 75e1a2ae1f61ce1ae640410ba757bba84bd9fefe upstream.
+
+Debug port in-use determination must be done before the controller gets
+reset the first time, i.e. before the call to ehci_setup() as of commit
+1a49e2ac9651df7349867a5cf44e2c83de1046af. That commit effectively
+rendered commit 9fa5780beea1274d498a224822397100022da7d4 useless.
+
+While moving that code around, also fix the BAR determination - the
+respective capability field is a 3- rather than a 2-bit one -, and use
+PCI_CAP_ID_DBG instead of the literal 0x0a.
+
+It's unclear to me whether the debug port functionality is important
+enough to warrant fixing this in stable kernels too.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-pci.c |   39 ++++++++++++++++++++-------------------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -192,6 +192,26 @@ static int ehci_pci_setup(struct usb_hcd
+               break;
+       }
++      /* optional debug port, normally in the first BAR */
++      temp = pci_find_capability(pdev, PCI_CAP_ID_DBG);
++      if (temp) {
++              pci_read_config_dword(pdev, temp, &temp);
++              temp >>= 16;
++              if (((temp >> 13) & 7) == 1) {
++                      u32 hcs_params = ehci_readl(ehci,
++                                                  &ehci->caps->hcs_params);
++
++                      temp &= 0x1fff;
++                      ehci->debug = hcd->regs + temp;
++                      temp = ehci_readl(ehci, &ehci->debug->control);
++                      ehci_info(ehci, "debug port %d%s\n",
++                                HCS_DEBUG_PORT(hcs_params),
++                                (temp & DBGP_ENABLED) ? " IN USE" : "");
++                      if (!(temp & DBGP_ENABLED))
++                              ehci->debug = NULL;
++              }
++      }
++
+       retval = ehci_setup(hcd);
+       if (retval)
+               return retval;
+@@ -226,25 +246,6 @@ static int ehci_pci_setup(struct usb_hcd
+               break;
+       }
+-      /* optional debug port, normally in the first BAR */
+-      temp = pci_find_capability(pdev, 0x0a);
+-      if (temp) {
+-              pci_read_config_dword(pdev, temp, &temp);
+-              temp >>= 16;
+-              if ((temp & (3 << 13)) == (1 << 13)) {
+-                      temp &= 0x1fff;
+-                      ehci->debug = hcd->regs + temp;
+-                      temp = ehci_readl(ehci, &ehci->debug->control);
+-                      ehci_info(ehci, "debug port %d%s\n",
+-                              HCS_DEBUG_PORT(ehci->hcs_params),
+-                              (temp & DBGP_ENABLED)
+-                                      ? " IN USE"
+-                                      : "");
+-                      if (!(temp & DBGP_ENABLED))
+-                              ehci->debug = NULL;
+-              }
+-      }
+-
+       /* at least the Genesys GL880S needs fixup here */
+       temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
+       temp &= 0x0f;
diff --git a/queue-3.7/usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch b/queue-3.7/usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch
new file mode 100644 (file)
index 0000000..0c2139b
--- /dev/null
@@ -0,0 +1,50 @@
+From 07e72b95f5038cc82304b9a4a2eb7f9fc391ea68 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Thu, 29 Nov 2012 15:05:57 +0100
+Subject: USB: hub: handle claim of enabled remote wakeup after reset
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 07e72b95f5038cc82304b9a4a2eb7f9fc391ea68 upstream.
+
+Some touchscreens have buggy firmware which claims
+remote wakeup to be enabled after a reset. They nevertheless
+crash if the feature is cleared by the host.
+Add a check for reset resume before checking for
+an enabled remote wakeup feature. On compliant
+devices the feature must be cleared after a reset anyway.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2960,7 +2960,7 @@ int usb_port_suspend(struct usb_device *
+ static int finish_port_resume(struct usb_device *udev)
+ {
+       int     status = 0;
+-      u16     devstatus;
++      u16     devstatus = 0;
+       /* caller owns the udev device lock */
+       dev_dbg(&udev->dev, "%s\n",
+@@ -3005,7 +3005,13 @@ static int finish_port_resume(struct usb
+       if (status) {
+               dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
+                               status);
+-      } else if (udev->actconfig) {
++      /*
++       * There are a few quirky devices which violate the standard
++       * by claiming to have remote wakeup enabled after a reset,
++       * which crash if the feature is cleared, hence check for
++       * udev->reset_resume
++       */
++      } else if (udev->actconfig && !udev->reset_resume) {
+               le16_to_cpus(&devstatus);
+               if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+                       status = usb_control_msg(udev,
diff --git a/queue-3.7/xhci-avoid-dead-ports-add-roothub-port-polling.patch b/queue-3.7/xhci-avoid-dead-ports-add-roothub-port-polling.patch
new file mode 100644 (file)
index 0000000..f4693e6
--- /dev/null
@@ -0,0 +1,119 @@
+From c52804a472649b2e5005342308739434cbd51119 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 27 Nov 2012 12:30:23 -0800
+Subject: xhci: Avoid "dead ports", add roothub port polling.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit c52804a472649b2e5005342308739434cbd51119 upstream.
+
+The USB core hub thread (khubd) is designed with external USB hubs in
+mind.  It expects that if a port status change bit is set, the hub will
+continue to send a notification through the hub status data transfer.
+Basically, it expects hub notifications to be level-triggered.
+
+The xHCI host controller is designed to be edge-triggered on the logical
+'OR' of all the port status change bits.  When all port status change
+bits are clear, and a new change bit is set, the xHC will generate a
+Port Status Change Event.  If another change bit is set in the same port
+status register before the first bit is cleared, it will not send
+another event.
+
+This means that the hub code may lose port status changes because of
+race conditions between clearing change bits.  The user sees this as a
+"dead port" that doesn't react to device connects.
+
+The fix is to turn on port polling whenever a new change bit is set.
+Once the USB core issues a hub status request that shows that no change
+bits are set in any USB ports, turn off port polling.
+
+We can't allow the USB core to poll the roothub for port events during
+host suspend because if the PCI host is in D3cold, the port registers
+will be all f's.  Instead, stop the port polling timer, and
+unconditionally restart it when the host resumes.  If there are no port
+change bits set after the resume, the first call to hub_status_data will
+disable polling.
+
+This patch should be backported to stable kernels with the first xHCI
+support, 2.6.31 and newer, that include the commit
+0f2a79300a1471cf92ab43af165ea13555c8b0a5 "USB: xhci: Root hub support."
+There will be merge conflicts because the check for HC_STATE_SUSPENDED
+was moved into xhci_suspend in 3.8.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c  |    7 +++++++
+ drivers/usb/host/xhci-ring.c |    9 +++++++++
+ drivers/usb/host/xhci.c      |   10 ++++++++++
+ 3 files changed, 26 insertions(+)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -984,6 +984,7 @@ int xhci_hub_status_data(struct usb_hcd
+       int max_ports;
+       __le32 __iomem **port_array;
+       struct xhci_bus_state *bus_state;
++      bool reset_change = false;
+       max_ports = xhci_get_ports(hcd, &port_array);
+       bus_state = &xhci->bus_state[hcd_index(hcd)];
+@@ -1015,6 +1016,12 @@ int xhci_hub_status_data(struct usb_hcd
+                       buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
+                       status = 1;
+               }
++              if ((temp & PORT_RC))
++                      reset_change = true;
++      }
++      if (!status && !reset_change) {
++              xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
++              clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+       }
+       spin_unlock_irqrestore(&xhci->lock, flags);
+       return status ? retval : 0;
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1725,6 +1725,15 @@ cleanup:
+       if (bogus_port_status)
+               return;
++      /*
++       * xHCI port-status-change events occur when the "or" of all the
++       * status-change bits in the portsc register changes from 0 to 1.
++       * New status changes won't cause an event if any other change
++       * bits are still set.  When an event occurs, switch over to
++       * polling to avoid losing status changes.
++       */
++      xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
++      set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+       spin_unlock(&xhci->lock);
+       /* Pass this up to the core */
+       usb_hcd_poll_rh_status(hcd);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -880,6 +880,11 @@ int xhci_suspend(struct xhci_hcd *xhci)
+       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
+       u32                     command;
++      /* Don't poll the roothubs on bus suspend. */
++      xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
++      clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
++      del_timer_sync(&hcd->rh_timer);
++
+       spin_lock_irq(&xhci->lock);
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
+@@ -1064,6 +1069,11 @@ int xhci_resume(struct xhci_hcd *xhci, b
+       if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+               compliance_mode_recovery_timer_init(xhci);
++      /* Re-enable port polling. */
++      xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
++      set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
++      usb_hcd_poll_rh_status(hcd);
++
+       return retval;
+ }
+ #endif        /* CONFIG_PM */
diff --git a/queue-3.7/xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch b/queue-3.7/xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch
new file mode 100644 (file)
index 0000000..01e95de
--- /dev/null
@@ -0,0 +1,47 @@
+From 55c1945edaac94c5338a3647bc2e85ff75d9cf36 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Mon, 17 Dec 2012 14:12:35 -0800
+Subject: xhci: Handle HS bulk/ctrl endpoints that don't NAK.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 55c1945edaac94c5338a3647bc2e85ff75d9cf36 upstream.
+
+A high speed control or bulk endpoint may have bInterval set to zero,
+which means it does not NAK.  If bInterval is non-zero, it means the
+endpoint NAKs at a rate of 2^(bInterval - 1).
+
+The xHCI code to compute the NAK interval does not handle the special
+case of zero properly.  The current code unconditionally subtracts one
+from bInterval and uses it as an exponent.  This causes a very large
+bInterval to be used, and warning messages like these will be printed:
+
+usb 1-1: ep 0x1 - rounding interval to 32768 microframes, ep desc says 0 microframes
+
+This may cause the xHCI host hardware to reject the Configure Endpoint
+command, which means the HS device will be unusable under xHCI ports.
+
+This patch should be backported to kernels as old as 2.6.31, that contain
+commit dfa49c4ad120a784ef1ff0717168aa79f55a483a "USB: xhci - fix math in
+xhci_get_endpoint_interval()".
+
+Reported-by: Vincent Pelletier <plr.vincent@gmail.com>
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1250,6 +1250,8 @@ static unsigned int xhci_microframes_to_
+ static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+ {
++      if (ep->desc.bInterval == 0)
++              return 0;
+       return xhci_microframes_to_exponent(udev, ep,
+                       ep->desc.bInterval, 0, 15);
+ }