aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-06-14 16:03:47 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-14 16:03:47 -0700
commit209280a6e58de1ade661eea4bb94571bad7a5f8c (patch)
tree6c5579373755a4becb87e94e3d5155e7c99337ea
parent02bdf5fc5f222119ecfa709354e540a594ae4b10 (diff)
downloadpatches-209280a6e58de1ade661eea4bb94571bad7a5f8c.tar.gz
patches
-rw-r--r--driver-core/hotplug-support-kernel-hotplug-sysctl-variable-when-config_net.patch38
-rw-r--r--driver-core/hwmon-add-driver-for-smsc-emc2103-temperature-monitor-and-fan-controller.patch795
-rw-r--r--driver-core/uio-remove-irqf_disabled-flag-from-uio_cif.c.patch30
-rw-r--r--driver-core/uio-remove-irqf_disabled-flag-from-uio_pdrv_genirq.c.patch29
-rw-r--r--driver-core/uio-remove-irqf_disabled-from-uio_sercos3.c.patch31
-rw-r--r--series21
-rw-r--r--staging.current/staging-batman-adv-fix-function-prototype.patch79
-rw-r--r--staging.current/staging-batman-adv-return-efault-on-copy_to_user-errors.patch33
-rw-r--r--staging.current/staging-mrst-touchscreen-fix-dereferencing-free-memory.patch33
-rw-r--r--usb.current/usb-g_serial-don-t-set-low_latency-flag.patch59
-rw-r--r--usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch31
-rw-r--r--usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch50
-rw-r--r--usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch34
-rw-r--r--usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch196
-rw-r--r--usb/usb-add-check-to-detect-host-controller-hardware-removal.patch44
-rw-r--r--usb/usb-don-t-stop-root-hub-status-polls-too-soon.patch156
-rw-r--r--usb/usb-fix-failure-path-in-usb_add_hcd.patch82
-rw-r--r--usb/usb-speedtouch-fixed-brace-and-spacing-coding-style-issues.patch64
-rw-r--r--usb/usb-speedtouch-fixed-more-brace-and-spacing-coding-style-issues.patch115
-rw-r--r--usb/usb-uhci-acquire-spinlock-before-calling-start_rh.patch61
-rw-r--r--usb/usb-xhci-remove-obsolete-debugging-printk.patch32
-rw-r--r--version2
22 files changed, 2014 insertions, 1 deletions
diff --git a/driver-core/hotplug-support-kernel-hotplug-sysctl-variable-when-config_net.patch b/driver-core/hotplug-support-kernel-hotplug-sysctl-variable-when-config_net.patch
new file mode 100644
index 00000000000000..010a69b969aab9
--- /dev/null
+++ b/driver-core/hotplug-support-kernel-hotplug-sysctl-variable-when-config_net.patch
@@ -0,0 +1,38 @@
+From abbotti@mev.co.uk Mon Jun 14 15:34:26 2010
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 7 Jun 2010 12:57:12 +0100
+Subject: hotplug: Support kernel/hotplug sysctl variable when !CONFIG_NET
+Cc: Greg Kroah-Hartman <gregkh@suse.de>, Ian Abbott <abbotti@mev.co.uk>
+Message-ID: <1275911832-11667-1-git-send-email-abbotti@mev.co.uk>
+
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+The kernel/hotplug sysctl variable (/proc/sys/kernel/hotplug file) was
+made conditional on CONFIG_NET by commit
+f743ca5e10f4145e0b3e6d11b9b46171e16af7ce (applied in 2.6.18) to fix
+problems with undefined references in 2.6.16 when CONFIG_HOTPLUG=y &&
+!CONFIG_NET, but this restriction is no longer needed.
+
+This patch makes the kernel/hotplug sysctl variable depend only on
+CONFIG_HOTPLUG.
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Acked-by: Randy Dunlap <randy.dunlap@oracle.COM>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sysctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -562,7 +562,7 @@ static struct ctl_table kern_table[] = {
+ .extra2 = &one,
+ },
+ #endif
+-#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
++#ifdef CONFIG_HOTPLUG
+ {
+ .procname = "hotplug",
+ .data = &uevent_helper,
diff --git a/driver-core/hwmon-add-driver-for-smsc-emc2103-temperature-monitor-and-fan-controller.patch b/driver-core/hwmon-add-driver-for-smsc-emc2103-temperature-monitor-and-fan-controller.patch
new file mode 100644
index 00000000000000..c313132bb82ed6
--- /dev/null
+++ b/driver-core/hwmon-add-driver-for-smsc-emc2103-temperature-monitor-and-fan-controller.patch
@@ -0,0 +1,795 @@
+From steve.glendinning@smsc.com Mon Jun 14 15:25:47 2010
+From: Steve Glendinning <steve.glendinning@smsc.com>
+Date: Thu, 10 Jun 2010 07:46:21 +0100
+Subject: hwmon: Add driver for SMSC EMC2103 temperature monitor and fan controller
+To: gregkh@suse.de
+Message-ID: <1276152381-2088-1-git-send-email-steve.glendinning@smsc.com>
+
+
+SMSC's EMC2103 family of temperature/fan controllers have 1
+onboard and up to 3 external temperature sensors, and allow
+closed-loop control of one fan. This patch adds support for
+them.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ MAINTAINERS | 6
+ drivers/hwmon/Kconfig | 10
+ drivers/hwmon/Makefile | 1
+ drivers/hwmon/emc2103.c | 723 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 740 insertions(+)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5205,6 +5205,12 @@ M: Nicolas Pitre <nico@fluxnic.net>
+ S: Odd Fixes
+ F: drivers/net/smc91x.*
+
++SMSC EMC2103 HARDWARE MONITOR DRIVER
++M: Steve Glendinning <steve.glendinning@smsc.com>
++L: lm-sensors@lm-sensors.org
++S: Supported
++F: drivers/hwmon/emc2103.c
++
+ SMSC47B397 HARDWARE MONITOR DRIVER
+ M: "Mark M. Hoffman" <mhoffman@lightlink.com>
+ L: lm-sensors@lm-sensors.org
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -794,6 +794,16 @@ config SENSORS_SMSC47M192
+ This driver can also be built as a module. If so, the module
+ will be called smsc47m192.
+
++config SENSORS_EMC2103
++ tristate "SMSC EMC2103"
++ depends on I2C
++ help
++ If you say yes here you get support for the temperature
++ and fan sensors of the SMSC EMC2103 chips.
++
++ This driver can also be built as a module. If so, the module
++ will be called emc2103.
++
+ config SENSORS_SMSC47B397
+ tristate "SMSC LPC47B397-NC"
+ depends on EXPERIMENTAL
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595
+ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
+ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
+ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
++obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
+ obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
+ obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
+ obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
+--- /dev/null
++++ b/drivers/hwmon/emc2103.c
+@@ -0,0 +1,723 @@
++/*
++ emc2103.c - Support for SMSC EMC2103
++ Copyright (c) 2010 SMSC
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++
++/* Addresses scanned */
++static const unsigned short normal_i2c[] = { 0x2E, I2C_CLIENT_END };
++
++static u8 REG_TEMP[4] = { 0x00, 0x02, 0x04, 0x06 };
++static u8 REG_TEMP_MIN[4] = { 0x3c, 0x38, 0x39, 0x3a };
++static u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 };
++
++#define REG_CONF1 (0x20)
++#define REG_TEMP_MAX_ALARM (0x24)
++#define REG_TEMP_MIN_ALARM (0x25)
++#define REG_FAN_CONF1 (0x42)
++#define REG_FAN_TARGET_LO (0x4c)
++#define REG_FAN_TARGET_HI (0x4d)
++#define REG_FAN_TACH_HI (0x4e)
++#define REG_FAN_TACH_LO (0x4f)
++#define REG_PRODUCT_ID (0xfd)
++#define REG_MFG_ID (0xfe)
++#define FAN_RPM_FACTOR (3932160)
++
++static int apd = 1;
++module_param(apd, bool, 0);
++MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode");
++
++struct temperature {
++ s8 degrees;
++ u8 fraction; /* 0-7 multiples of 0.125 */
++};
++
++struct emc2103_data {
++ struct device *hwmon_dev;
++ struct mutex update_lock;
++ bool valid; /* registers are valid */
++ bool fan_rpm_control;
++ bool have_temp3;
++ bool have_temp4;
++ unsigned long last_updated; /* in jiffies */
++ struct temperature temp[4]; /* internal + 3 external */
++ s8 temp_min[4]; /* no fractional part */
++ s8 temp_max[4]; /* no fractional part */
++ u8 temp_min_alarm;
++ u8 temp_max_alarm;
++ u8 fan_range;
++ u16 fan_tach;
++ u16 fan_target;
++};
++
++static void read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output)
++{
++ int status = i2c_smbus_read_byte_data(client, i2c_reg);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ i2c_reg, status);
++ } else {
++ *output = status;
++ }
++}
++
++static void read_s8_from_i2c(struct i2c_client *client, u8 i2c_reg, s8 *output)
++{
++ int status = i2c_smbus_read_byte_data(client, i2c_reg);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ i2c_reg, status);
++ } else {
++ *output = status;
++ }
++}
++
++static void read_temp_from_i2c(struct i2c_client *client, u8 i2c_reg,
++ struct temperature *temp)
++{
++ /* read integer part */
++ int status = i2c_smbus_read_byte_data(client, i2c_reg);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ i2c_reg, status);
++ } else {
++ temp->degrees = status;
++ }
++
++ /* Read fractional part from the next register offset */
++ status = i2c_smbus_read_byte_data(client, i2c_reg + 1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ i2c_reg, status);
++ } else {
++ temp->fraction = (status & 0xe0) >> 5;
++ }
++}
++
++static void read_fan_from_i2c(struct i2c_client *client, u16 *output,
++ u8 hi_addr, u8 lo_addr)
++{
++ u16 high_byte;
++
++ int status = i2c_smbus_read_byte_data(client, hi_addr);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ hi_addr, status);
++ } else {
++ high_byte = status & 0xff;
++
++ status = i2c_smbus_read_byte_data(client, lo_addr);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ lo_addr, status);
++ } else {
++ *output = (high_byte << 5) | ((status & 0xf8) >> 3);
++ }
++ }
++}
++
++static void write_fan_target_to_i2c(struct i2c_client *client, u16 new_target)
++{
++ u8 high_byte = (new_target & 0x1fe0) >> 5;
++ u8 low_byte = (new_target & 0x001f) << 3;
++ i2c_smbus_write_byte_data(client, REG_FAN_TARGET_LO, low_byte);
++ i2c_smbus_write_byte_data(client, REG_FAN_TARGET_HI, high_byte);
++}
++
++static void read_fan_range_from_i2c(struct i2c_client *client, u8 *output)
++
++{
++ int status = i2c_smbus_read_byte_data(client, REG_FAN_CONF1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ REG_FAN_CONF1, status);
++ } else {
++ *output = (status & 0x60) >> 5;
++ }
++}
++
++static struct emc2103_data *emc2103_update_device(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct emc2103_data *data = i2c_get_clientdata(client);
++
++ mutex_lock(&data->update_lock);
++
++ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
++ || !data->valid) {
++ int i;
++
++ dev_dbg(&client->dev, "Starting emc2103 update\n");
++
++ for (i = 0; i < 4; i++) {
++ read_temp_from_i2c(client, REG_TEMP[i], &data->temp[i]);
++ read_s8_from_i2c(client, REG_TEMP_MIN[i],
++ &data->temp_min[i]);
++ read_s8_from_i2c(client, REG_TEMP_MAX[i],
++ &data->temp_max[i]);
++ }
++
++ read_u8_from_i2c(client, REG_TEMP_MIN_ALARM,
++ &data->temp_min_alarm);
++ read_u8_from_i2c(client, REG_TEMP_MAX_ALARM,
++ &data->temp_max_alarm);
++
++ read_fan_from_i2c(client, &data->fan_tach,
++ REG_FAN_TACH_HI, REG_FAN_TACH_LO);
++ read_fan_from_i2c(client, &data->fan_target,
++ REG_FAN_TARGET_HI, REG_FAN_TARGET_LO);
++ read_fan_range_from_i2c(client, &data->fan_range);
++
++ data->last_updated = jiffies;
++ data->valid = true;
++ }
++
++ mutex_unlock(&data->update_lock);
++
++ return data;
++}
++
++static ssize_t
++show_temp(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int millidegrees = data->temp[attr->index].degrees * 1000
++ + data->temp[attr->index].fraction * 125;
++ return sprintf(buf, "%d\n", millidegrees);
++}
++
++static ssize_t
++show_temp_min(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int millidegrees = data->temp_min[attr->index] * 1000;
++ return sprintf(buf, "%d\n", millidegrees);
++}
++
++static ssize_t
++show_temp_max(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int millidegrees = data->temp_max[attr->index] * 1000;
++ return sprintf(buf, "%d\n", millidegrees);
++}
++
++static ssize_t
++show_temp_fault(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ bool fault = (data->temp[attr->index].degrees == -128);
++ return sprintf(buf, "%d\n", fault ? 1 : 0);
++}
++
++static ssize_t
++show_temp_min_alarm(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ bool alarm = data->temp_min_alarm & (1 << attr->index);
++ return sprintf(buf, "%d\n", alarm ? 1 : 0);
++}
++
++static ssize_t
++show_temp_max_alarm(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ bool alarm = data->temp_max_alarm & (1 << attr->index);
++ return sprintf(buf, "%d\n", alarm ? 1 : 0);
++}
++
++static ssize_t set_temp_min(struct device *dev, struct device_attribute *da,
++ const char *buf, size_t count)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ struct i2c_client *client = to_i2c_client(dev);
++ long val;
++
++ int result = strict_strtol(buf, 10, &val);
++ if (result < 0)
++ return -EINVAL;
++
++ val = val / 1000;
++ if ((val < -63) || (val > 127))
++ return -EINVAL;
++
++ mutex_lock(&data->update_lock);
++ data->temp_min[attr->index] = val;
++ i2c_smbus_write_byte_data(client, REG_TEMP_MIN[attr->index], val);
++ mutex_unlock(&data->update_lock);
++
++ return count;
++}
++
++static ssize_t set_temp_max(struct device *dev, struct device_attribute *da,
++ const char *buf, size_t count)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct emc2103_data *data = emc2103_update_device(dev);
++ struct i2c_client *client = to_i2c_client(dev);
++ long val;
++
++ int result = strict_strtol(buf, 10, &val);
++ if (result < 0)
++ return -EINVAL;
++
++ if ((val < -63) || (val > 127))
++ return -EINVAL;
++
++ mutex_lock(&data->update_lock);
++ data->temp_max[attr->index] = val;
++ i2c_smbus_write_byte_data(client, REG_TEMP_MAX[attr->index], val);
++ mutex_unlock(&data->update_lock);
++
++ return count;
++}
++
++static ssize_t
++show_fan(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int fan_div = 1 << data->fan_range;
++ int rpm = (FAN_RPM_FACTOR * fan_div) / data->fan_tach;
++ return sprintf(buf, "%d\n", rpm);
++}
++
++static ssize_t
++show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int fan_div = 1 << data->fan_range;
++ return sprintf(buf, "%d\n", fan_div);
++}
++
++/* Note: we also update the fan target here, because its value is
++ determined in part by the fan clock divider. This follows the principle
++ of least surprise; the user doesn't expect the fan target to change just
++ because the divider changed. */
++static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
++ const char *buf, size_t count)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ struct i2c_client *client = to_i2c_client(dev);
++ int status, old_div = 1 << data->fan_range;
++ long new_div;
++
++ int result = strict_strtol(buf, 10, &new_div);
++ if (result < 0)
++ return -EINVAL;
++
++ if (new_div == old_div) /* No change */
++ return count;
++
++ mutex_lock(&data->update_lock);
++ switch (new_div) {
++ case 1:
++ data->fan_range = 0;
++ break;
++ case 2:
++ data->fan_range = 1;
++ break;
++ case 4:
++ data->fan_range = 2;
++ break;
++ case 8:
++ data->fan_range = 3;
++ break;
++ default:
++ mutex_unlock(&data->update_lock);
++ return -EINVAL;
++ }
++
++ status = i2c_smbus_read_byte_data(client, REG_FAN_CONF1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ REG_FAN_CONF1, status);
++ mutex_unlock(&data->update_lock);
++ return -EIO;
++ }
++ status &= 0x9F;
++ status |= (data->fan_range << 5) & 0x60;
++ i2c_smbus_write_byte_data(client, REG_FAN_CONF1, status);
++
++ /* update fan target if high word is not disabled */
++ if ((data->fan_target & 0x1fe0) != 0x1fe0) {
++ data->fan_target = (data->fan_target * new_div) / old_div;
++ write_fan_target_to_i2c(client, data->fan_target);
++ }
++
++ /* invalidate data to force re-read from hardware */
++ data->valid = false;
++
++ mutex_unlock(&data->update_lock);
++ return count;
++}
++
++static ssize_t
++show_fan_target(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ int fan_div = 1 << data->fan_range;
++ int rpm = (FAN_RPM_FACTOR * fan_div) / data->fan_target;
++
++ /* high byte of 0xff = disabled so return 0 */
++ if ((data->fan_target & 0x1fe0) == 0x1fe0)
++ rpm = 0;
++
++ return sprintf(buf, "%d\n", rpm);
++}
++
++static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
++ const char *buf, size_t count)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ struct i2c_client *client = to_i2c_client(dev);
++ long rpm_target;
++ int fan_div = 1 << data->fan_range;
++
++ int result = strict_strtol(buf, 10, &rpm_target);
++ if (result < 0)
++ return -EINVAL;
++
++ if ((rpm_target < 0) || (rpm_target > 16384))
++ return -EINVAL;
++
++ mutex_lock(&data->update_lock);
++
++ if (rpm_target == 0)
++ data->fan_target = 0x1fff;
++ else
++ data->fan_target =
++ ((FAN_RPM_FACTOR * fan_div) / rpm_target) & 0x1fff;
++
++ write_fan_target_to_i2c(client, data->fan_target);
++
++ if (!data->fan_rpm_control) {
++ /* RPM control mode is not currently enabled */
++ int status = i2c_smbus_read_byte_data(client, REG_FAN_CONF1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ REG_FAN_CONF1, status);
++ mutex_unlock(&data->update_lock);
++ return -EIO;
++ }
++ status |= 0x80;
++ i2c_smbus_write_byte_data(client, REG_FAN_CONF1, status);
++
++ data->fan_rpm_control = true;
++ }
++
++ mutex_unlock(&data->update_lock);
++ return count;
++}
++
++static ssize_t
++show_fan_fault(struct device *dev, struct device_attribute *da, char *buf)
++{
++ struct emc2103_data *data = emc2103_update_device(dev);
++ bool fault = ((data->fan_tach & 0x1fe0) == 0x1fe0);
++ return sprintf(buf, "%d\n", fault ? 1 : 0);
++}
++
++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
++static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp_min,
++ set_temp_min, 0);
++static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp_max,
++ set_temp_max, 0);
++static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);
++static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm,
++ NULL, 0);
++static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm,
++ NULL, 0);
++
++static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
++static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, show_temp_min,
++ set_temp_min, 1);
++static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
++ set_temp_max, 1);
++static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);
++static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm,
++ NULL, 1);
++static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm,
++ NULL, 1);
++
++static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
++static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, show_temp_min,
++ set_temp_min, 2);
++static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
++ set_temp_max, 2);
++static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2);
++static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm,
++ NULL, 2);
++static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm,
++ NULL, 2);
++
++static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
++static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR, show_temp_min,
++ set_temp_min, 3);
++static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO | S_IWUSR, show_temp_max,
++ set_temp_max, 3);
++static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3);
++static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_temp_min_alarm,
++ NULL, 3);
++static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_temp_max_alarm,
++ NULL, 3);
++
++static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
++static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div,
++ set_fan_div, 0);
++static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_fan_target,
++ set_fan_target, 0);
++static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
++
++/* sensors present on all models */
++static struct attribute *emc2103_attributes[] = {
++ &sensor_dev_attr_temp1_input.dev_attr.attr,
++ &sensor_dev_attr_temp1_min.dev_attr.attr,
++ &sensor_dev_attr_temp1_max.dev_attr.attr,
++ &sensor_dev_attr_temp1_fault.dev_attr.attr,
++ &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
++ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
++ &sensor_dev_attr_temp2_input.dev_attr.attr,
++ &sensor_dev_attr_temp2_min.dev_attr.attr,
++ &sensor_dev_attr_temp2_max.dev_attr.attr,
++ &sensor_dev_attr_temp2_fault.dev_attr.attr,
++ &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
++ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
++ &sensor_dev_attr_fan1_input.dev_attr.attr,
++ &sensor_dev_attr_fan1_div.dev_attr.attr,
++ &sensor_dev_attr_fan1_target.dev_attr.attr,
++ &sensor_dev_attr_fan1_fault.dev_attr.attr,
++ NULL
++};
++
++/* extra temperature sensors only present on 2103-2 and 2103-4 */
++static struct attribute *emc2103_attributes_temp3[] = {
++ &sensor_dev_attr_temp3_input.dev_attr.attr,
++ &sensor_dev_attr_temp3_min.dev_attr.attr,
++ &sensor_dev_attr_temp3_max.dev_attr.attr,
++ &sensor_dev_attr_temp3_fault.dev_attr.attr,
++ &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
++ &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
++ NULL
++};
++
++/* extra temperature sensors only present on 2103-2 and 2103-4 in APD mode */
++static struct attribute *emc2103_attributes_temp4[] = {
++ &sensor_dev_attr_temp4_input.dev_attr.attr,
++ &sensor_dev_attr_temp4_min.dev_attr.attr,
++ &sensor_dev_attr_temp4_max.dev_attr.attr,
++ &sensor_dev_attr_temp4_fault.dev_attr.attr,
++ &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
++ &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group emc2103_group = {
++ .attrs = emc2103_attributes,
++};
++
++static const struct attribute_group emc2103_temp3_group = {
++ .attrs = emc2103_attributes_temp3,
++};
++
++static const struct attribute_group emc2103_temp4_group = {
++ .attrs = emc2103_attributes_temp4,
++};
++
++static int
++emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++ struct emc2103_data *data;
++ int status;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
++ return -EIO;
++
++ data = kzalloc(sizeof(struct emc2103_data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, data);
++ mutex_init(&data->update_lock);
++
++ /* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */
++ status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID);
++ data->have_temp3 = (status == 0x26);
++
++ /* check if the device is already in RPM control mode */
++ status = i2c_smbus_read_byte_data(client, REG_FAN_CONF1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
++ REG_FAN_CONF1, status);
++ return -EIO;
++ }
++ data->fan_rpm_control = (status & 0x80);
++
++ if (data->have_temp3) {
++ /* Configure anti-parallel diode mode */
++ data->have_temp4 = apd;
++ status = i2c_smbus_read_byte_data(client, REG_CONF1);
++ if (status < 0) {
++ dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1,
++ status);
++ return -EIO;
++ }
++
++ if (data->have_temp4)
++ status |= 0x01;
++ else
++ status &= ~(0x01);
++
++ i2c_smbus_write_byte_data(client, REG_CONF1, status & 0xff);
++ }
++
++ /* Register sysfs hooks */
++ status = sysfs_create_group(&client->dev.kobj, &emc2103_group);
++ if (status)
++ goto exit_free;
++
++ if (data->have_temp3) {
++ status = sysfs_create_group(&client->dev.kobj,
++ &emc2103_temp3_group);
++ if (status)
++ goto exit_remove;
++ }
++
++ if (data->have_temp4) {
++ status = sysfs_create_group(&client->dev.kobj,
++ &emc2103_temp4_group);
++ if (status)
++ goto exit_remove_temp3;
++ }
++
++ data->hwmon_dev = hwmon_device_register(&client->dev);
++ if (IS_ERR(data->hwmon_dev)) {
++ status = PTR_ERR(data->hwmon_dev);
++ goto exit_remove_temp4;
++ }
++
++ dev_info(&client->dev, "%s: sensor '%s'\n",
++ dev_name(data->hwmon_dev), client->name);
++
++ return 0;
++
++exit_remove_temp4:
++ if (data->have_temp4)
++ sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
++exit_remove_temp3:
++ if (data->have_temp3)
++ sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
++exit_remove:
++ sysfs_remove_group(&client->dev.kobj, &emc2103_group);
++exit_free:
++ i2c_set_clientdata(client, NULL);
++ kfree(data);
++ return status;
++}
++
++static int emc2103_remove(struct i2c_client *client)
++{
++ struct emc2103_data *data = i2c_get_clientdata(client);
++
++ hwmon_device_unregister(data->hwmon_dev);
++
++ if (data->have_temp4)
++ sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
++
++ if (data->have_temp3)
++ sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
++
++ sysfs_remove_group(&client->dev.kobj, &emc2103_group);
++
++ i2c_set_clientdata(client, NULL);
++ kfree(data);
++ return 0;
++}
++
++static const struct i2c_device_id emc2103_ids[] = {
++ { "emc2103", 0, },
++ { /* LIST END */ }
++};
++MODULE_DEVICE_TABLE(i2c, emc2103_ids);
++
++/* Return 0 if detection is successful, -ENODEV otherwise */
++static int
++emc2103_detect(struct i2c_client *new_client, struct i2c_board_info *info)
++{
++ struct i2c_adapter *adapter = new_client->adapter;
++ int manufacturer, product;
++
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++ return -ENODEV;
++
++ manufacturer = i2c_smbus_read_byte_data(new_client, REG_MFG_ID);
++ if (manufacturer != 0x5D)
++ return -ENODEV;
++
++ product = i2c_smbus_read_byte_data(new_client, REG_PRODUCT_ID);
++ if ((product != 0x24) && (product != 0x26))
++ return -ENODEV;
++
++ strlcpy(info->type, "emc2103", I2C_NAME_SIZE);
++
++ return 0;
++}
++
++static struct i2c_driver emc2103_driver = {
++ .class = I2C_CLASS_HWMON,
++ .driver = {
++ .name = "emc2103",
++ },
++ .probe = emc2103_probe,
++ .remove = emc2103_remove,
++ .id_table = emc2103_ids,
++ .detect = emc2103_detect,
++ .address_list = normal_i2c,
++};
++
++static int __init sensors_emc2103_init(void)
++{
++ return i2c_add_driver(&emc2103_driver);
++}
++
++static void __exit sensors_emc2103_exit(void)
++{
++ i2c_del_driver(&emc2103_driver);
++}
++
++MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
++MODULE_DESCRIPTION("SMSC EMCxxxx hwmon driver");
++MODULE_LICENSE("GPL");
++
++module_init(sensors_emc2103_init);
++module_exit(sensors_emc2103_exit);
diff --git a/driver-core/uio-remove-irqf_disabled-flag-from-uio_cif.c.patch b/driver-core/uio-remove-irqf_disabled-flag-from-uio_cif.c.patch
new file mode 100644
index 00000000000000..70383463256ca2
--- /dev/null
+++ b/driver-core/uio-remove-irqf_disabled-flag-from-uio_cif.c.patch
@@ -0,0 +1,30 @@
+From hjk@linutronix.de Mon Jun 14 15:26:43 2010
+From: "Hans J. Koch" <hjk@linutronix.de>
+Date: Thu, 10 Jun 2010 01:18:08 +0200
+Subject: uio: Remove IRQF_DISABLED flag from uio_cif.c
+Cc: Benedikt Spranger <b.spranger@linutronix.de>, Greg KH <gregkh@suse.de>
+Message-ID: <20100609231807.GE2555@local>
+Content-Disposition: inline
+
+
+Remove IRQF_DISABLED since it is deprecated and a no-op in the
+current kernel.
+
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio_cif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/uio/uio_cif.c
++++ b/drivers/uio/uio_cif.c
+@@ -79,7 +79,7 @@ static int __devinit hilscher_pci_probe(
+ }
+ info->version = "0.0.1";
+ info->irq = dev->irq;
+- info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
++ info->irq_flags = IRQF_SHARED;
+ info->handler = hilscher_handler;
+
+ if (uio_register_device(&dev->dev, info))
diff --git a/driver-core/uio-remove-irqf_disabled-flag-from-uio_pdrv_genirq.c.patch b/driver-core/uio-remove-irqf_disabled-flag-from-uio_pdrv_genirq.c.patch
new file mode 100644
index 00000000000000..c9a4204ee18084
--- /dev/null
+++ b/driver-core/uio-remove-irqf_disabled-flag-from-uio_pdrv_genirq.c.patch
@@ -0,0 +1,29 @@
+From hjk@linutronix.de Mon Jun 14 15:26:07 2010
+From: "Hans J. Koch" <hjk@linutronix.de>
+Date: Thu, 10 Jun 2010 01:12:32 +0200
+Subject: uio: Remove IRQF_DISABLED flag from uio_pdrv_genirq.c
+Cc: Magnus Damm <magnus.damm@gmail.com>, Greg KH <gregkh@suse.de>
+Message-ID: <20100609231232.GC2555@local>
+Content-Disposition: inline
+
+
+Remove IRQF_DISABLED flag since it is deprecated and a no-op in the
+current kernel.
+
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio_pdrv_genirq.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/uio/uio_pdrv_genirq.c
++++ b/drivers/uio/uio_pdrv_genirq.c
+@@ -155,7 +155,6 @@ static int uio_pdrv_genirq_probe(struct
+ * Interrupt sharing is not supported.
+ */
+
+- uioinfo->irq_flags |= IRQF_DISABLED;
+ uioinfo->handler = uio_pdrv_genirq_handler;
+ uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
+ uioinfo->open = uio_pdrv_genirq_open;
diff --git a/driver-core/uio-remove-irqf_disabled-from-uio_sercos3.c.patch b/driver-core/uio-remove-irqf_disabled-from-uio_sercos3.c.patch
new file mode 100644
index 00000000000000..576a69f8ab0cba
--- /dev/null
+++ b/driver-core/uio-remove-irqf_disabled-from-uio_sercos3.c.patch
@@ -0,0 +1,31 @@
+From hjk@linutronix.de Mon Jun 14 15:26:29 2010
+From: "Hans J. Koch" <hjk@linutronix.de>
+Date: Thu, 10 Jun 2010 01:15:49 +0200
+Subject: uio: Remove IRQF_DISABLED from uio_sercos3.c
+Cc: John Ogness <john.ogness@linutronix.de>, Greg KH <gregkh@suse.de>
+Message-ID: <20100609231549.GD2555@local>
+Content-Disposition: inline
+
+
+Remove IRQF_DISABLED since it is deprecated and a no-op in the
+current kernel.
+
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Acked-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio_sercos3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/uio/uio_sercos3.c
++++ b/drivers/uio/uio_sercos3.c
+@@ -154,7 +154,7 @@ static int __devinit sercos3_pci_probe(s
+ info->name = "Sercos_III_PCI";
+ info->version = "0.0.1";
+ info->irq = dev->irq;
+- info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
++ info->irq_flags = IRQF_SHARED;
+ info->handler = sercos3_handler;
+ info->irqcontrol = sercos3_irqcontrol;
+
diff --git a/series b/series
index a29d820a935ed5..3232bae3e60553 100644
--- a/series
+++ b/series
@@ -16,11 +16,19 @@ gregkh/gkh-version.patch
#################################
# USB patches for 2.6.35
#################################
+usb.current/usb-g_serial-don-t-set-low_latency-flag.patch
+usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch
+usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch
+usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch
+usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch
#################################
# Staging patches for 2.6.35
#################################
staging.current/staging-usbip-usbip_common-kill-rx-thread-on-tx-thread-creation-error.patch
+staging.current/staging-batman-adv-return-efault-on-copy_to_user-errors.patch
+staging.current/staging-batman-adv-fix-function-prototype.patch
+staging.current/staging-mrst-touchscreen-fix-dereferencing-free-memory.patch
#####################################################################
@@ -30,6 +38,11 @@ staging.current/staging-usbip-usbip_common-kill-rx-thread-on-tx-thread-creation-
#############################################
# Driver core patches for after 2.6.35 is out
#############################################
+driver-core/hwmon-add-driver-for-smsc-emc2103-temperature-monitor-and-fan-controller.patch
+driver-core/uio-remove-irqf_disabled-flag-from-uio_pdrv_genirq.c.patch
+driver-core/uio-remove-irqf_disabled-from-uio_sercos3.c.patch
+driver-core/uio-remove-irqf_disabled-flag-from-uio_cif.c.patch
+driver-core/hotplug-support-kernel-hotplug-sysctl-variable-when-config_net.patch
#####################################
# TTY patches for after 2.6.35 is out
@@ -38,7 +51,15 @@ staging.current/staging-usbip-usbip_common-kill-rx-thread-on-tx-thread-creation-
###################################
# USB stuff for after 2.6.35 is out
###################################
+usb/usb-fix-failure-path-in-usb_add_hcd.patch
+usb/usb-don-t-stop-root-hub-status-polls-too-soon.patch
+usb/usb-add-check-to-detect-host-controller-hardware-removal.patch
+usb/usb-uhci-acquire-spinlock-before-calling-start_rh.patch
+usb/usb-speedtouch-fixed-brace-and-spacing-coding-style-issues.patch
+usb/usb-speedtouch-fixed-more-brace-and-spacing-coding-style-issues.patch
+usb/usb-xhci-remove-obsolete-debugging-printk.patch
# staging stuff is now in the staging-next tree on git.kernel.org
+
diff --git a/staging.current/staging-batman-adv-fix-function-prototype.patch b/staging.current/staging-batman-adv-fix-function-prototype.patch
new file mode 100644
index 00000000000000..24b18e1e8d2acb
--- /dev/null
+++ b/staging.current/staging-batman-adv-fix-function-prototype.patch
@@ -0,0 +1,79 @@
+From sven.eckelmann@gmx.de Mon Jun 14 15:50:02 2010
+From: Sven Eckelmann <sven.eckelmann@gmx.de>
+Date: Sun, 6 Jun 2010 21:03:05 +0200
+Subject: Staging: batman-adv: fix function prototype
+To: gregkh@suse.de, b.a.t.m.a.n@lists.open-mesh.net
+Cc: Javier Martinez Canillas <martinez.javier@gmail.com>, Sven Eckelmann <sven.eckelmann@gmx.de>
+Message-ID: <1275850985-27105-3-git-send-email-sven.eckelmann@gmx.de>
+
+
+From: Javier Martinez Canillas <martinez.javier@gmail.com>
+
+In today linux-next I got a compile warning in staging/batman-adv.
+
+This is due a struct bin_attribute read function prototype change and the driver was not updated.
+
+This patch solves the issue
+
+Signed-off-by: Javier Martinez Canillas <martinez.javier@gmail.com>
+Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/bat_sysfs.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/staging/batman-adv/bat_sysfs.c
++++ b/drivers/staging/batman-adv/bat_sysfs.c
+@@ -225,9 +225,9 @@ static struct bat_attribute *mesh_attrs[
+ NULL,
+ };
+
+-static ssize_t transtable_local_read(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buff, loff_t off, size_t count)
++static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buff, loff_t off, size_t count)
+ {
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
+@@ -235,9 +235,9 @@ static ssize_t transtable_local_read(str
+ return hna_local_fill_buffer_text(net_dev, buff, count, off);
+ }
+
+-static ssize_t transtable_global_read(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buff, loff_t off, size_t count)
++static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buff, loff_t off, size_t count)
+ {
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
+@@ -245,9 +245,9 @@ static ssize_t transtable_global_read(st
+ return hna_global_fill_buffer_text(net_dev, buff, count, off);
+ }
+
+-static ssize_t originators_read(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buff, loff_t off, size_t count)
++static ssize_t originators_read(struct file *filp, struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buff, loff_t off, size_t count)
+ {
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
+@@ -255,9 +255,9 @@ static ssize_t originators_read(struct k
+ return orig_fill_buffer_text(net_dev, buff, count, off);
+ }
+
+-static ssize_t vis_data_read(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buff, loff_t off, size_t count)
++static ssize_t vis_data_read(struct file *filp, struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buff, loff_t off, size_t count)
+ {
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
diff --git a/staging.current/staging-batman-adv-return-efault-on-copy_to_user-errors.patch b/staging.current/staging-batman-adv-return-efault-on-copy_to_user-errors.patch
new file mode 100644
index 00000000000000..1b9eb25e427748
--- /dev/null
+++ b/staging.current/staging-batman-adv-return-efault-on-copy_to_user-errors.patch
@@ -0,0 +1,33 @@
+From sven.eckelmann@gmx.de Mon Jun 14 15:49:49 2010
+From: Sven Eckelmann <sven.eckelmann@gmx.de>
+Date: Sun, 6 Jun 2010 21:03:04 +0200
+Subject: Staging: batman-adv: return -EFAULT on copy_to_user errors
+To: gregkh@suse.de, b.a.t.m.a.n@lists.open-mesh.net
+Cc: Dan Carpenter <error27@gmail.com>, Sven Eckelmann <sven.eckelmann@gmx.de>
+Message-ID: <1275850985-27105-2-git-send-email-sven.eckelmann@gmx.de>
+
+
+From: Dan Carpenter <error27@gmail.com>
+
+copy_to_user() returns the number of bites remaining but we want to
+return a negative error code here.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/batman-adv/device.c
++++ b/drivers/staging/batman-adv/device.c
+@@ -196,7 +196,7 @@ ssize_t bat_device_read(struct file *fil
+ kfree(device_packet);
+
+ if (error)
+- return error;
++ return -EFAULT;
+
+ return sizeof(struct icmp_packet);
+ }
diff --git a/staging.current/staging-mrst-touchscreen-fix-dereferencing-free-memory.patch b/staging.current/staging-mrst-touchscreen-fix-dereferencing-free-memory.patch
new file mode 100644
index 00000000000000..006982d77bca0b
--- /dev/null
+++ b/staging.current/staging-mrst-touchscreen-fix-dereferencing-free-memory.patch
@@ -0,0 +1,33 @@
+From error27@gmail.com Mon Jun 14 15:51:12 2010
+From: Dan Carpenter <error27@gmail.com>
+Date: Sat, 5 Jun 2010 19:16:42 +0200
+Subject: Staging: mrst-touchscreen: fix dereferencing free memory
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: devel@driverdev.osuosl.org, kernel-janitors@vger.kernel.org, Alan Cox <alan@linux.intel.com>
+Message-ID: <20100605171642.GM5483@bicker>
+Content-Disposition: inline
+
+
+I moved the kfree() down a couple lines after the dereference.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/mrst-touchscreen/intel-mid-touch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/mrst-touchscreen/intel-mid-touch.c
++++ b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
+@@ -817,9 +817,9 @@ static int mrstouch_remove(struct spi_de
+ free_irq(mrstouchdevp->irq, mrstouchdevp);
+ input_unregister_device(mrstouchdevp->input);
+ input_free_device(mrstouchdevp->input);
+- kfree(mrstouchdevp);
+ if (mrstouchdevp->pendet_thrd)
+ kthread_stop(mrstouchdevp->pendet_thrd);
++ kfree(mrstouchdevp);
+ return 0;
+ }
+
diff --git a/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch b/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch
new file mode 100644
index 00000000000000..3a04c087c82c5b
--- /dev/null
+++ b/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch
@@ -0,0 +1,59 @@
+From jon.povey@racelogic.co.uk Mon Jun 14 15:21:46 2010
+From: Jon Povey <jon.povey@racelogic.co.uk>
+Date: Mon, 14 Jun 2010 19:41:04 +0900
+Subject: USB: g_serial: don't set low_latency flag
+To: linux-usb@vger.kernel.org
+Cc: Jon Povey <jon.povey@racelogic.co.uk>, chrisv@cyberswitching.com, david-b@pacbell.net
+Message-ID: <1276512064-3229-1-git-send-email-jon.povey@racelogic.co.uk>
+
+
+No longer set low_latency flag as it causes this warning backtrace:
+
+ WARNING: at kernel/mutex.c:207 __mutex_lock_slowpath+0x6c/0x288()
+
+Fix associated locking and wakeups.
+
+Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk>
+Cc: Maulik Mankad <x0082077@ti.com>
+CcL stable <stable@kernel.org>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/u_serial.c | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -536,17 +536,11 @@ recycle:
+ list_move(&req->list, &port->read_pool);
+ }
+
+- /* Push from tty to ldisc; this is immediate with low_latency, and
+- * may trigger callbacks to this driver ... so drop the spinlock.
++ /* Push from tty to ldisc; without low_latency set this is handled by
++ * a workqueue, so we won't get callbacks and can hold port_lock
+ */
+ if (tty && do_push) {
+- spin_unlock_irq(&port->port_lock);
+ tty_flip_buffer_push(tty);
+- wake_up_interruptible(&tty->read_wait);
+- spin_lock_irq(&port->port_lock);
+-
+- /* tty may have been closed */
+- tty = port->port_tty;
+ }
+
+
+@@ -784,11 +778,6 @@ static int gs_open(struct tty_struct *tt
+ port->open_count = 1;
+ port->openclose = false;
+
+- /* low_latency means ldiscs work in tasklet context, without
+- * needing a workqueue schedule ... easier to keep up.
+- */
+- tty->low_latency = 1;
+-
+ /* if connected, start the I/O stream */
+ if (port->port_usb) {
+ struct gserial *gser = port->port_usb;
diff --git a/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch b/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch
new file mode 100644
index 00000000000000..833a9258c4db2e
--- /dev/null
+++ b/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch
@@ -0,0 +1,31 @@
+From jon.povey@racelogic.co.uk Mon Jun 14 15:22:32 2010
+From: Jon Povey <jon.povey@racelogic.co.uk>
+Date: Mon, 14 Jun 2010 19:42:10 +0900
+Subject: USB: g_serial: fix tty cleanup on unload
+To: linux-usb@vger.kernel.org
+Cc: Jon Povey <jon.povey@racelogic.co.uk>, chrisv@cyberswitching.com, david-b@pacbell.net
+Message-ID: <1276512130-3317-1-git-send-email-jon.povey@racelogic.co.uk>
+
+
+Call put_tty_driver() in cleanup function, to fix Oops when trying to open
+gadget serial char device after module unload.
+
+Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/u_serial.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -1184,6 +1184,7 @@ void gserial_cleanup(void)
+ n_ports = 0;
+
+ tty_unregister_driver(gs_tty_driver);
++ put_tty_driver(gs_tty_driver);
+ gs_tty_driver = NULL;
+
+ pr_debug("%s: cleaned up ttyGS* support\n", __func__);
diff --git a/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch b/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch
new file mode 100644
index 00000000000000..e5677d0b03fdec
--- /dev/null
+++ b/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch
@@ -0,0 +1,50 @@
+From m.nazarewicz@samsung.com Mon Jun 14 15:23:58 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Mon, 14 Jun 2010 10:43:34 +0200
+Subject: [PATCH] USB: gadget: g_fs: possible invalid pointer reference bug fixed
+To: linux-usb@vger.kernel.org
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Kyungmin Park <kyungmin.park@samsung.com>, Marek Szyprowski <m.szyprowski@samsung.com>, linux-kernel@vger.kernel.org
+Message-ID: <f8fbee30a711b740b5875514715c3c58b4eb196c.1276170819.git.m.nazarewicz@samsung.com>
+
+
+During __gfs_do_config() some invalid pointers may be left
+in usb_configuration::interfaces array from previous calls
+to the __gfs_do_config() for the same configuration. This
+will always happen if an user space function which has
+a fewer then the last user space function registers itself.
+Composite's set_config() function that a pointer after the
+last interface in usb_configuration::interface is NULL
+unless the array is full.
+
+This patch makes the __gfs_do_config() make sure that if the
+usb_configuration::interface is not full then a pointer
+after the last interface is NULL.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/g_ffs.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -392,6 +392,17 @@ static int __gfs_do_config(struct usb_co
+ if (unlikely(ret < 0))
+ return ret;
+
++ /* After previous do_configs there may be some invalid
++ * pointers in c->interface array. This happens every time
++ * a user space function with fewer interfaces than a user
++ * space function that was run before the new one is run. The
++ * compasit's set_config() assumes that if there is no more
++ * then MAX_CONFIG_INTERFACES interfaces in a configuration
++ * then there is a NULL pointer after the last interface in
++ * c->interface array. We need to make sure this is true. */
++ if (c->next_interface_id < ARRAY_SIZE(c->interface))
++ c->interface[c->next_interface_id] = NULL;
++
+ return 0;
+ }
+
diff --git a/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch b/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch
new file mode 100644
index 00000000000000..720e5023a9b3fd
--- /dev/null
+++ b/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch
@@ -0,0 +1,34 @@
+From nobuhiro.iwamatsu.yj@renesas.com Mon Jun 14 15:48:15 2010
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Mon, 7 Jun 2010 16:55:56 +0900
+Subject: USB: r8a66597: Fix failure in change of status
+To: gregkh@suse.de
+Cc: stern@rowland.harvard.edu, shimoda.yoshihiro@renesas.com, Paul Mundt <lethal@linux-sh.org>
+Message-ID: <AANLkTimQgvU-pG67QWVjXY5rzLCclelHc7hhsUb_fpJF@mail.gmail.com>
+
+
+In the change by 749da5f82fe33ff68dd4aa1a5e35cd9aa6246dab,
+The change in the status when the USB device is connected is wrong.
+Therefore, the device is not recognized.
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+CC: Paul Mundt" <lethal@linux-sh.org>
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/r8a66597-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/r8a66597-hcd.c
++++ b/drivers/usb/host/r8a66597-hcd.c
+@@ -1065,7 +1065,7 @@ static void r8a66597_usb_connect(struct
+ else if (speed == LSMODE)
+ rh->port |= USB_PORT_STAT_LOW_SPEED;
+
+- rh->port &= USB_PORT_STAT_RESET;
++ rh->port &= ~USB_PORT_STAT_RESET;
+ rh->port |= USB_PORT_STAT_ENABLE;
+ }
+
diff --git a/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch b/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch
new file mode 100644
index 00000000000000..ba943d301b1b08
--- /dev/null
+++ b/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch
@@ -0,0 +1,196 @@
+From sarah.a.sharp@linux.intel.com Mon Jun 14 15:25:09 2010
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 10 Jun 2010 12:25:28 -0700
+Subject: USB: xHCI: Fix bug in link TRB activation change.
+To: Greg KH <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, John Youn <John.Youn@synopsys.com>
+Message-ID: <20100610192528.GA17572@xanatos>
+Content-Disposition: inline
+
+
+Commit 6c12db90f19727c76990e7f4801c67a148b30111 introduced a bug for
+control transfers. The patch was supposed to change when the link TRBs at
+the end of each ring segment were given to the hardware. If a transfer
+descriptor (TD) ended just before the link TRB, the code wouldn't give
+back the link TRB to the hardware; instead it would be given back in
+prepare_ring() just before the next TD was enqueued at the top of the
+ring.
+
+Unfortunately, the code relied on checking the chain bit of the TRB to
+determine whether the TD ended just before the link TRB. It assumed that
+the ring enqueuing code would call prepare_ring() before enqueuing the
+next TD. However, control transfers are made of multiple TDs, and
+prepare_ring() is only called once before enqueuing two or three TDs.
+
+If the first or second TD of the control transfer ended just before the
+link TRB, then the code in inc_enq() would not move the enqueue pointer
+past the link TRB, and the link TRB would get overwritten. This would
+cause the xHCI driver to start writing to memory past the ring segment,
+and eventually the system would crash or hang.
+
+The fix is to add a flag to inc_enq() that says whether the caller will
+enqueue more TDs before calling prepare_ring(). If the chain bit is
+cleared (meaning this is the last TRB in a TD), and the caller will not
+enqueue more TDs, then we defer giving back the link TRB.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 62 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 46 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -182,8 +182,12 @@ static void inc_deq(struct xhci_hcd *xhc
+ * set, but other sections talk about dealing with the chain bit set. This was
+ * fixed in the 0.96 specification errata, but we have to assume that all 0.95
+ * xHCI hardware can't handle the chain bit being cleared on a link TRB.
++ *
++ * @more_trbs_coming: Will you enqueue more TRBs before calling
++ * prepare_transfer()?
+ */
+-static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
++static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
++ bool consumer, bool more_trbs_coming)
+ {
+ u32 chain;
+ union xhci_trb *next;
+@@ -199,15 +203,28 @@ static void inc_enq(struct xhci_hcd *xhc
+ while (last_trb(xhci, ring, ring->enq_seg, next)) {
+ if (!consumer) {
+ if (ring != xhci->event_ring) {
+- if (chain) {
+- next->link.control |= TRB_CHAIN;
+-
+- /* Give this link TRB to the hardware */
+- wmb();
+- next->link.control ^= TRB_CYCLE;
+- } else {
++ /*
++ * If the caller doesn't plan on enqueueing more
++ * TDs before ringing the doorbell, then we
++ * don't want to give the link TRB to the
++ * hardware just yet. We'll give the link TRB
++ * back in prepare_ring() just before we enqueue
++ * the TD at the top of the ring.
++ */
++ if (!chain && !more_trbs_coming)
+ break;
++
++ /* If we're not dealing with 0.95 hardware,
++ * carry over the chain bit of the previous TRB
++ * (which may mean the chain bit is cleared).
++ */
++ if (!xhci_link_trb_quirk(xhci)) {
++ next->link.control &= ~TRB_CHAIN;
++ next->link.control |= chain;
+ }
++ /* Give this link TRB to the hardware */
++ wmb();
++ next->link.control ^= TRB_CYCLE;
+ }
+ /* Toggle the cycle bit after the last ring segment. */
+ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) {
+@@ -1707,9 +1724,12 @@ void xhci_handle_event(struct xhci_hcd *
+ /*
+ * Generic function for queueing a TRB on a ring.
+ * The caller must have checked to make sure there's room on the ring.
++ *
++ * @more_trbs_coming: Will you enqueue more TRBs before calling
++ * prepare_transfer()?
+ */
+ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
+- bool consumer,
++ bool consumer, bool more_trbs_coming,
+ u32 field1, u32 field2, u32 field3, u32 field4)
+ {
+ struct xhci_generic_trb *trb;
+@@ -1719,7 +1739,7 @@ static void queue_trb(struct xhci_hcd *x
+ trb->field[1] = field2;
+ trb->field[2] = field3;
+ trb->field[3] = field4;
+- inc_enq(xhci, ring, consumer);
++ inc_enq(xhci, ring, consumer, more_trbs_coming);
+ }
+
+ /*
+@@ -1988,6 +2008,7 @@ static int queue_bulk_sg_tx(struct xhci_
+ int trb_buff_len, this_sg_len, running_total;
+ bool first_trb;
+ u64 addr;
++ bool more_trbs_coming;
+
+ struct xhci_generic_trb *start_trb;
+ int start_cycle;
+@@ -2073,7 +2094,11 @@ static int queue_bulk_sg_tx(struct xhci_
+ length_field = TRB_LEN(trb_buff_len) |
+ remainder |
+ TRB_INTR_TARGET(0);
+- queue_trb(xhci, ep_ring, false,
++ if (num_trbs > 1)
++ more_trbs_coming = true;
++ else
++ more_trbs_coming = false;
++ queue_trb(xhci, ep_ring, false, more_trbs_coming,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -2124,6 +2149,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ int num_trbs;
+ struct xhci_generic_trb *start_trb;
+ bool first_trb;
++ bool more_trbs_coming;
+ int start_cycle;
+ u32 field, length_field;
+
+@@ -2212,7 +2238,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ length_field = TRB_LEN(trb_buff_len) |
+ remainder |
+ TRB_INTR_TARGET(0);
+- queue_trb(xhci, ep_ring, false,
++ if (num_trbs > 1)
++ more_trbs_coming = true;
++ else
++ more_trbs_coming = false;
++ queue_trb(xhci, ep_ring, false, more_trbs_coming,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -2291,7 +2321,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ /* Queue setup TRB - see section 6.4.1.2.1 */
+ /* FIXME better way to translate setup_packet into two u32 fields? */
+ setup = (struct usb_ctrlrequest *) urb->setup_packet;
+- queue_trb(xhci, ep_ring, false,
++ queue_trb(xhci, ep_ring, false, true,
+ /* FIXME endianness is probably going to bite my ass here. */
+ setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16,
+ setup->wIndex | setup->wLength << 16,
+@@ -2307,7 +2337,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,
++ queue_trb(xhci, ep_ring, false, true,
+ lower_32_bits(urb->transfer_dma),
+ upper_32_bits(urb->transfer_dma),
+ length_field,
+@@ -2324,7 +2354,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ field = 0;
+ else
+ field = TRB_DIR_IN;
+- queue_trb(xhci, ep_ring, false,
++ queue_trb(xhci, ep_ring, false, false,
+ 0,
+ 0,
+ TRB_INTR_TARGET(0),
+@@ -2361,7 +2391,7 @@ static int queue_command(struct xhci_hcd
+ "unfailable commands failed.\n");
+ return -ENOMEM;
+ }
+- queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
++ queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3,
+ field4 | xhci->cmd_ring->cycle_state);
+ return 0;
+ }
diff --git a/usb/usb-add-check-to-detect-host-controller-hardware-removal.patch b/usb/usb-add-check-to-detect-host-controller-hardware-removal.patch
new file mode 100644
index 00000000000000..83772a7dcd453b
--- /dev/null
+++ b/usb/usb-add-check-to-detect-host-controller-hardware-removal.patch
@@ -0,0 +1,44 @@
+From stern@rowland.harvard.edu Mon Jun 14 15:28:22 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 9 Jun 2010 17:34:27 -0400 (EDT)
+Subject: USB: add check to detect host controller hardware removal
+To: Greg KH <greg@kroah.com>
+Cc: "Evans, Robert" <Robert.Evans@stratus.com>, "Cao, Lei" <Lei.Cao@stratus.com>, James Paradis <jparadis@redhat.com>, Donald Zickus <dzickus@redhat.com>
+Message-ID: <Pine.LNX.4.44L0.1006091728430.1533-100000@iolanthe.rowland.org>
+
+
+This patch (as1391) fixes a problem that can occur when USB host
+controller hardware is hot-unplugged. If no interrupts are generated
+by the unplug then the HCD may not realize that the controller is
+gone, and the subsequent unbind may hang waiting for interrupts that
+never arrive.
+
+The solution (for PCI-based controllers) is to call the HCD's
+interrupt handler at the start of usb_hcd_pci_remove(). If the
+hardware is gone, the handler will realize this when it tries to read
+the controller's status register.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hcd-pci.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -292,6 +292,14 @@ void usb_hcd_pci_remove(struct pci_dev *
+ if (!hcd)
+ return;
+
++ /* Fake an interrupt request in order to give the driver a chance
++ * to test whether the controller hardware has been removed (e.g.,
++ * cardbus physical eject).
++ */
++ local_irq_disable();
++ usb_hcd_irq(0, hcd);
++ local_irq_enable();
++
+ usb_remove_hcd(hcd);
+ if (hcd->driver->flags & HCD_MEMORY) {
+ iounmap(hcd->regs);
diff --git a/usb/usb-don-t-stop-root-hub-status-polls-too-soon.patch b/usb/usb-don-t-stop-root-hub-status-polls-too-soon.patch
new file mode 100644
index 00000000000000..5f6dbeaa2a36a2
--- /dev/null
+++ b/usb/usb-don-t-stop-root-hub-status-polls-too-soon.patch
@@ -0,0 +1,156 @@
+From stern@rowland.harvard.edu Mon Jun 14 15:28:05 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 9 Jun 2010 17:34:17 -0400 (EDT)
+Subject: USB: don't stop root-hub status polls too soon
+To: Greg KH <greg@kroah.com>
+Cc: "Evans, Robert" <Robert.Evans@stratus.com>, "Cao, Lei" <Lei.Cao@stratus.com>, James Paradis <jparadis@redhat.com>, Donald Zickus <dzickus@redhat.com>
+Message-ID: <Pine.LNX.4.44L0.1006091727050.1533-100000@iolanthe.rowland.org>
+
+
+This patch (as1390) fixes a problem that crops up when a UHCI host
+controller is unbound from uhci-hcd while there are still some active
+URBs. The URBs have to be unlinked when the root hub is unregistered,
+and uhci-hcd relies upon root-hub status polls as part of its
+unlinking procedure. But usb_hcd_poll_rh_status() won't make those
+status calls if hcd->rh_registered is clear, and the flag is cleared
+_before_ the unregistration takes place.
+
+Since hcd->rh_registered is used for other things and needs to be
+cleared early, the solution is to add a new flag (rh_pollable) and use
+it instead. It gets cleared _after_ the root hub is unregistered.
+
+Now that the status polls don't end too soon, we have to make sure
+they also don't occur too late -- after the root hub's usb_device
+structure or the HCD's private structures are deallocated. Therefore
+the patch adds usb_get_device() and usb_put_device() calls to protect
+the root hub structure, and it adds an extra del_timer_sync() to
+prevent the root-hub timer from causing an unexpected status poll.
+
+This additional complexity would not be needed if the HCD framework
+had provided separate stop() and release() callbacks instead of just
+stop(). This lack could be fixed at some future time (although it
+would require changes to every host controller driver); when that
+happens this patch won't be needed any more.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hcd.c | 32 +++++++++++++++++++++++++-------
+ include/linux/usb/hcd.h | 1 +
+ 2 files changed, 26 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -667,7 +667,7 @@ void usb_hcd_poll_rh_status(struct usb_h
+ unsigned long flags;
+ char buffer[6]; /* Any root hubs with > 31 ports? */
+
+- if (unlikely(!hcd->rh_registered))
++ if (unlikely(!hcd->rh_pollable))
+ return;
+ if (!hcd->uses_new_polling && !hcd->status_urb)
+ return;
+@@ -2217,6 +2217,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ retval = -ENOMEM;
+ goto err_allocate_root_hub;
+ }
++ hcd->self.root_hub = rhdev;
+
+ switch (hcd->driver->flags & HCD_MASK) {
+ case HCD_USB11:
+@@ -2231,7 +2232,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ default:
+ goto err_set_rh_speed;
+ }
+- hcd->self.root_hub = rhdev;
+
+ /* wakeup flag init defaults to "everything works" for root hubs,
+ * but drivers can override it in reset() if needed, along with
+@@ -2246,6 +2246,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ dev_err(hcd->self.controller, "can't setup\n");
+ goto err_hcd_driver_setup;
+ }
++ hcd->rh_pollable = 1;
+
+ /* NOTE: root hub and controller capabilities may not be the same */
+ if (device_can_wakeup(hcd->self.controller)
+@@ -2315,9 +2316,12 @@ error_create_attr_group:
+ cancel_work_sync(&hcd->wakeup_work);
+ #endif
+ mutex_lock(&usb_bus_list_lock);
+- usb_disconnect(&hcd->self.root_hub);
++ usb_disconnect(&rhdev); /* Sets rhdev to NULL */
+ mutex_unlock(&usb_bus_list_lock);
+ err_register_root_hub:
++ hcd->rh_pollable = 0;
++ hcd->poll_rh = 0;
++ del_timer_sync(&hcd->rh_timer);
+ hcd->driver->stop(hcd);
+ hcd->state = HC_STATE_HALT;
+ hcd->poll_rh = 0;
+@@ -2328,8 +2332,7 @@ err_hcd_driver_start:
+ err_request_irq:
+ err_hcd_driver_setup:
+ err_set_rh_speed:
+- hcd->self.root_hub = NULL;
+- usb_put_dev(rhdev);
++ usb_put_dev(hcd->self.root_hub);
+ err_allocate_root_hub:
+ usb_deregister_bus(&hcd->self);
+ err_register_bus:
+@@ -2348,9 +2351,12 @@ EXPORT_SYMBOL_GPL(usb_add_hcd);
+ */
+ void usb_remove_hcd(struct usb_hcd *hcd)
+ {
++ struct usb_device *rhdev = hcd->self.root_hub;
++
+ dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
+
+- sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
++ usb_get_dev(rhdev);
++ sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);
+
+ if (HC_IS_RUNNING (hcd->state))
+ hcd->state = HC_STATE_QUIESCING;
+@@ -2365,17 +2371,29 @@ void usb_remove_hcd(struct usb_hcd *hcd)
+ #endif
+
+ mutex_lock(&usb_bus_list_lock);
+- usb_disconnect(&hcd->self.root_hub);
++ usb_disconnect(&rhdev); /* Sets rhdev to NULL */
+ mutex_unlock(&usb_bus_list_lock);
+
++ /* Prevent any more root-hub status calls from the timer.
++ * The HCD might still restart the timer (if a port status change
++ * interrupt occurs), but usb_hcd_poll_rh_status() won't invoke
++ * the hub_status_data() callback.
++ */
++ hcd->rh_pollable = 0;
++ hcd->poll_rh = 0;
++ del_timer_sync(&hcd->rh_timer);
++
+ hcd->driver->stop(hcd);
+ hcd->state = HC_STATE_HALT;
+
++ /* In case the HCD restarted the timer, stop it again. */
+ hcd->poll_rh = 0;
+ del_timer_sync(&hcd->rh_timer);
+
+ if (hcd->irq >= 0)
+ free_irq(hcd->irq, hcd);
++
++ usb_put_dev(hcd->self.root_hub);
+ usb_deregister_bus(&hcd->self);
+ hcd_buffer_destroy(hcd);
+ }
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -95,6 +95,7 @@ struct usb_hcd {
+ #define HCD_FLAG_SAW_IRQ 0x00000002
+
+ unsigned rh_registered:1;/* is root hub registered? */
++ unsigned rh_pollable:1; /* may we poll the root hub? */
+
+ /* The next flag is a stopgap, to be removed when all the HCDs
+ * support the new root-hub polling mechanism. */
diff --git a/usb/usb-fix-failure-path-in-usb_add_hcd.patch b/usb/usb-fix-failure-path-in-usb_add_hcd.patch
new file mode 100644
index 00000000000000..16e5662a6fe77b
--- /dev/null
+++ b/usb/usb-fix-failure-path-in-usb_add_hcd.patch
@@ -0,0 +1,82 @@
+From stern@rowland.harvard.edu Mon Jun 14 15:27:36 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 9 Jun 2010 17:34:05 -0400 (EDT)
+Subject: USB: fix failure path in usb_add_hcd()
+To: Greg KH <greg@kroah.com>
+Cc: "Evans, Robert" <Robert.Evans@stratus.com>, "Cao, Lei" <Lei.Cao@stratus.com>, James Paradis <jparadis@redhat.com>, Donald Zickus <dzickus@redhat.com>
+Message-ID: <Pine.LNX.4.44L0.1006091725480.1533-100000@iolanthe.rowland.org>
+
+
+This patch (as1389) fixes some errors in the failure pathway of
+usb_add_hcd(). The actions it takes ought to be exactly the same as
+those taken by usb_remove_hcd(), but they aren't.
+
+In one case (removal of the usb_bus_attr_group), the two routines are
+brought into agreement by changing usb_remove_hcd(). All the other
+discrepancies are fixed by changing usb_add_hcd().
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hcd.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -2229,7 +2229,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ rhdev->speed = USB_SPEED_SUPER;
+ break;
+ default:
+- goto err_allocate_root_hub;
++ goto err_set_rh_speed;
+ }
+ hcd->self.root_hub = rhdev;
+
+@@ -2305,16 +2305,29 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ return retval;
+
+ error_create_attr_group:
++ if (HC_IS_RUNNING(hcd->state))
++ hcd->state = HC_STATE_QUIESCING;
++ spin_lock_irq(&hcd_root_hub_lock);
++ hcd->rh_registered = 0;
++ spin_unlock_irq(&hcd_root_hub_lock);
++
++#ifdef CONFIG_USB_SUSPEND
++ cancel_work_sync(&hcd->wakeup_work);
++#endif
+ mutex_lock(&usb_bus_list_lock);
+ usb_disconnect(&hcd->self.root_hub);
+ mutex_unlock(&usb_bus_list_lock);
+ err_register_root_hub:
+ hcd->driver->stop(hcd);
++ hcd->state = HC_STATE_HALT;
++ hcd->poll_rh = 0;
++ del_timer_sync(&hcd->rh_timer);
+ err_hcd_driver_start:
+ if (hcd->irq >= 0)
+ free_irq(irqnum, hcd);
+ err_request_irq:
+ err_hcd_driver_setup:
++err_set_rh_speed:
+ hcd->self.root_hub = NULL;
+ usb_put_dev(rhdev);
+ err_allocate_root_hub:
+@@ -2337,6 +2350,8 @@ void usb_remove_hcd(struct usb_hcd *hcd)
+ {
+ dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
+
++ sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
++
+ if (HC_IS_RUNNING (hcd->state))
+ hcd->state = HC_STATE_QUIESCING;
+
+@@ -2349,7 +2364,6 @@ void usb_remove_hcd(struct usb_hcd *hcd)
+ cancel_work_sync(&hcd->wakeup_work);
+ #endif
+
+- sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
+ mutex_lock(&usb_bus_list_lock);
+ usb_disconnect(&hcd->self.root_hub);
+ mutex_unlock(&usb_bus_list_lock);
diff --git a/usb/usb-speedtouch-fixed-brace-and-spacing-coding-style-issues.patch b/usb/usb-speedtouch-fixed-brace-and-spacing-coding-style-issues.patch
new file mode 100644
index 00000000000000..2fc055b34a3bf7
--- /dev/null
+++ b/usb/usb-speedtouch-fixed-brace-and-spacing-coding-style-issues.patch
@@ -0,0 +1,64 @@
+From nikai@nikai.net Mon Jun 14 15:29:03 2010
+From: Nicolas Kaiser <nikai@nikai.net>
+Date: Wed, 9 Jun 2010 20:22:03 +0200
+Subject: USB: speedtouch: fixed brace and spacing coding style issues
+To: Duncan Sands <duncan.sands@free.fr>
+Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
+Message-ID: <20100609202203.66ab0192@absol.kitzblitz>
+
+
+Fixed brace coding style issues.
+
+Signed-off-by: Nicolas Kaiser <nikai@nikai.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/atm/speedtch.c | 4 +++-
+ drivers/usb/atm/usbatm.c | 9 +++------
+ 2 files changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/atm/speedtch.c
++++ b/drivers/usb/atm/speedtch.c
+@@ -753,7 +753,9 @@ static struct usb_driver speedtch_usb_dr
+ .id_table = speedtch_usb_ids
+ };
+
+-static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_interfaces) {
++static void speedtch_release_interfaces(struct usb_device *usb_dev,
++ int num_interfaces)
++{
+ struct usb_interface *cur_intf;
+ int i;
+
+--- a/drivers/usb/atm/usbatm.c
++++ b/drivers/usb/atm/usbatm.c
+@@ -273,8 +273,7 @@ static void usbatm_complete(struct urb *
+
+ if (unlikely(status) &&
+ (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) ||
+- status != -EILSEQ ))
+- {
++ status != -EILSEQ )) {
+ if (status == -ESHUTDOWN)
+ return;
+
+@@ -516,8 +515,7 @@ static unsigned int usbatm_write_cells(s
+ target[3] |= 0x2; /* adjust PTI */
+
+ ctrl->len = 0; /* tag this skb finished */
+- }
+- else
++ } else
+ ctrl->crc = crc32_be(ctrl->crc, ptr, left);
+ }
+
+@@ -1390,9 +1388,8 @@ static int usbatm_print_packet(const uns
+ for (i = 0; i < len;) {
+ buffer[0] = '\0';
+ sprintf(buffer, "%.3d :", i);
+- for (j = 0; (j < 16) && (i < len); j++, i++) {
++ for (j = 0; (j < 16) && (i < len); j++, i++)
+ sprintf(buffer, "%s %2.2x", buffer, data[i]);
+- }
+ dbg("%s", buffer);
+ }
+ return i;
diff --git a/usb/usb-speedtouch-fixed-more-brace-and-spacing-coding-style-issues.patch b/usb/usb-speedtouch-fixed-more-brace-and-spacing-coding-style-issues.patch
new file mode 100644
index 00000000000000..db82276700c566
--- /dev/null
+++ b/usb/usb-speedtouch-fixed-more-brace-and-spacing-coding-style-issues.patch
@@ -0,0 +1,115 @@
+From nikai@nikai.net Mon Jun 14 15:29:43 2010
+From: Nicolas Kaiser <nikai@nikai.net>
+Date: Wed, 9 Jun 2010 20:43:03 +0200
+Subject: USB: speedtouch: fixed more brace and spacing coding style issues
+To: Duncan Sands <duncan.sands@free.fr>
+Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
+Message-ID: <20100609204303.489ca8c2@absol.kitzblitz>
+
+
+Fixed spacing coding style issues.
+
+Signed-off-by: Nicolas Kaiser <nikai@nikai.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/atm/speedtch.c | 6 +++---
+ drivers/usb/atm/usbatm.c | 16 ++++++++--------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/atm/speedtch.c
++++ b/drivers/usb/atm/speedtch.c
+@@ -759,7 +759,7 @@ static void speedtch_release_interfaces(
+ struct usb_interface *cur_intf;
+ int i;
+
+- for(i = 0; i < num_interfaces; i++)
++ for (i = 0; i < num_interfaces; i++)
+ if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) {
+ usb_set_intfdata(cur_intf, NULL);
+ usb_driver_release_interface(&speedtch_usb_driver, cur_intf);
+@@ -794,7 +794,7 @@ static int speedtch_bind(struct usbatm_d
+
+ /* claim all interfaces */
+
+- for (i=0; i < num_interfaces; i++) {
++ for (i = 0; i < num_interfaces; i++) {
+ cur_intf = usb_ifnum_to_if(usb_dev, i);
+
+ if ((i != ifnum) && cur_intf) {
+@@ -844,7 +844,7 @@ static int speedtch_bind(struct usbatm_d
+
+ use_isoc = 0; /* fall back to bulk if endpoint not found */
+
+- for (i=0; i<desc->desc.bNumEndpoints; i++) {
++ for (i = 0; i < desc->desc.bNumEndpoints; i++) {
+ const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
+
+ if ((endpoint_desc->bEndpointAddress == target_address)) {
+--- a/drivers/usb/atm/usbatm.c
++++ b/drivers/usb/atm/usbatm.c
+@@ -84,8 +84,8 @@
+
+ #ifdef VERBOSE_DEBUG
+ static int usbatm_print_packet(const unsigned char *data, int len);
+-#define PACKETDEBUG(arg...) usbatm_print_packet (arg)
+-#define vdbg(arg...) dbg (arg)
++#define PACKETDEBUG(arg...) usbatm_print_packet(arg)
++#define vdbg(arg...) dbg(arg)
+ #else
+ #define PACKETDEBUG(arg...)
+ #define vdbg(arg...)
+@@ -273,7 +273,7 @@ static void usbatm_complete(struct urb *
+
+ if (unlikely(status) &&
+ (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) ||
+- status != -EILSEQ )) {
++ status != -EILSEQ)) {
+ if (status == -ESHUTDOWN)
+ return;
+
+@@ -493,7 +493,7 @@ static unsigned int usbatm_write_cells(s
+ ptr += data_len;
+ __skb_pull(skb, data_len);
+
+- if(!left)
++ if (!left)
+ continue;
+
+ memset(ptr, 0, left);
+@@ -505,7 +505,7 @@ static unsigned int usbatm_write_cells(s
+ trailer[2] = ctrl->len >> 8;
+ trailer[3] = ctrl->len;
+
+- ctrl->crc = ~ crc32_be(ctrl->crc, ptr, left - 4);
++ ctrl->crc = ~crc32_be(ctrl->crc, ptr, left - 4);
+
+ trailer[4] = ctrl->crc >> 24;
+ trailer[5] = ctrl->crc >> 16;
+@@ -1144,7 +1144,7 @@ int usbatm_usb_probe(struct usb_interfac
+ instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
+
+ /* tx buffer size must be a positive multiple of the stride */
+- instance->tx_channel.buf_size = max (instance->tx_channel.stride,
++ instance->tx_channel.buf_size = max(instance->tx_channel.stride,
+ snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
+
+ /* rx buffer size must be a positive multiple of the endpoint maxpacket */
+@@ -1157,7 +1157,7 @@ int usbatm_usb_probe(struct usb_interfac
+ goto fail_unbind;
+ }
+
+- num_packets = max (1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */
++ num_packets = max(1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */
+
+ if (num_packets * maxpacket > UDSL_MAX_BUF_SIZE)
+ num_packets--;
+@@ -1260,7 +1260,7 @@ int usbatm_usb_probe(struct usb_interfac
+ usb_free_urb(instance->urbs[i]);
+ }
+
+- kfree (instance);
++ kfree(instance);
+
+ return error;
+ }
diff --git a/usb/usb-uhci-acquire-spinlock-before-calling-start_rh.patch b/usb/usb-uhci-acquire-spinlock-before-calling-start_rh.patch
new file mode 100644
index 00000000000000..7d6d2f5daefa40
--- /dev/null
+++ b/usb/usb-uhci-acquire-spinlock-before-calling-start_rh.patch
@@ -0,0 +1,61 @@
+From stern@rowland.harvard.edu Mon Jun 14 15:28:38 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 9 Jun 2010 17:34:39 -0400 (EDT)
+Subject: USB: UHCI: acquire spinlock before calling start_rh()
+To: Greg KH <greg@kroah.com>
+Cc: "Evans, Robert" <Robert.Evans@stratus.com>, "Cao, Lei" <Lei.Cao@stratus.com>, James Paradis <jparadis@redhat.com>, Donald Zickus <dzickus@redhat.com>
+Message-ID: <Pine.LNX.4.44L0.1006091730230.1533-100000@iolanthe.rowland.org>
+
+
+This patch (as1392) fixes a bug in uhci-hcd: The start_rh() routine is
+supposed to be called with the private spinlock held. If an IRQ comes
+in at just the wrong time, the driver will think the controller has
+died when in fact it simply hasn't start yet.
+
+The patch also addresses some issues that may prevent an URB from
+being unlinked after the controller has stopped. This is an abnormal
+occurrence (ordinarily the controller stops only when the entire bus
+is suspended and hence there are no active URBs), so the pathways
+haven't gotten much testing. These two changes may be a little more
+than is strictly necessary, but clearly they won't hurt.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/uhci-hcd.c | 2 ++
+ drivers/usb/host/uhci-q.c | 4 ++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -691,7 +691,9 @@ static int uhci_start(struct usb_hcd *hc
+
+ configure_hc(uhci);
+ uhci->is_initialized = 1;
++ spin_lock_irq(&uhci->lock);
+ start_rh(uhci);
++ spin_unlock_irq(&uhci->lock);
+ return 0;
+
+ /*
+--- a/drivers/usb/host/uhci-q.c
++++ b/drivers/usb/host/uhci-q.c
+@@ -565,7 +565,7 @@ static void uhci_unlink_qh(struct uhci_h
+ qh->unlink_frame = uhci->frame_number;
+
+ /* Force an interrupt so we know when the QH is fully unlinked */
+- if (list_empty(&uhci->skel_unlink_qh->node))
++ if (list_empty(&uhci->skel_unlink_qh->node) || uhci->is_stopped)
+ uhci_set_next_interrupt(uhci);
+
+ /* Move the QH from its old list to the end of the unlinking list */
+@@ -1667,7 +1667,7 @@ static int uhci_advance_check(struct uhc
+ qh->advance_jiffies = jiffies;
+ goto done;
+ }
+- ret = 0;
++ ret = uhci->is_stopped;
+ }
+
+ /* The queue hasn't advanced; check for timeout */
diff --git a/usb/usb-xhci-remove-obsolete-debugging-printk.patch b/usb/usb-xhci-remove-obsolete-debugging-printk.patch
new file mode 100644
index 00000000000000..36377b6b81c639
--- /dev/null
+++ b/usb/usb-xhci-remove-obsolete-debugging-printk.patch
@@ -0,0 +1,32 @@
+From sarah.a.sharp@linux.intel.com Mon Jun 14 15:33:23 2010
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Mon, 7 Jun 2010 09:11:33 -0700
+Subject: USB: xhci: Remove obsolete debugging printk.
+To: Greg KH <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, Sergei Shtylyov <sshtylyov@mvista.com>
+Message-ID: <20100607161133.GA8530@xanatos>
+Content-Disposition: inline
+
+
+When code to manipulate the command register was refactored from
+xhci_run() to xhci_start(), a debugging statement was left behind that no
+longer applies. Remove that statement.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Reported-by: Sergei Shtylyov <sshtylyov@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -495,7 +495,6 @@ int xhci_run(struct usb_hcd *hcd)
+ return -ENODEV;
+ }
+
+- xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
+ if (doorbell)
+ (*doorbell)(xhci);
+ if (xhci->quirks & XHCI_NEC_HOST)
diff --git a/version b/version
index 56004b3e6022df..03c21b7a9355f5 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.6.35-rc2
+2.6.35-rc3