diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-14 16:03:47 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-14 16:03:47 -0700 |
| commit | 209280a6e58de1ade661eea4bb94571bad7a5f8c (patch) | |
| tree | 6c5579373755a4becb87e94e3d5155e7c99337ea | |
| parent | 02bdf5fc5f222119ecfa709354e540a594ae4b10 (diff) | |
| download | patches-209280a6e58de1ade661eea4bb94571bad7a5f8c.tar.gz | |
patches
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; + @@ -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) @@ -1 +1 @@ -2.6.35-rc2 +2.6.35-rc3 |
