--- /dev/null
+From a8a5164c297c16c2f4be776714ca47dba252cc3d Mon Sep 17 00:00:00 2001
+From: Ben Gardner <gardner.ben@gmail.com>
+Date: Fri, 5 Mar 2010 13:44:38 -0800
+Subject: gpio: cs5535-gpio: fix input direction
+
+From: Ben Gardner <gardner.ben@gmail.com>
+
+commit a8a5164c297c16c2f4be776714ca47dba252cc3d upstream.
+
+The cs5535-gpio driver's get() function was returning the output value.
+This means that the GPIO pins would never work as an input, even if
+configured as an input.
+
+The driver should return the READ_BACK value, which is the sensed line
+value. To make that work when the direction is 'output', INPUT_ENABLE
+needs to be set.
+
+In addition, the driver was not disabling OUTPUT_ENABLE when the direction
+is set to 'input'. That would cause the GPIO to continue to drive the pin
+if the direction was ever set to output.
+
+This issue was noticed when attempting to use the gpiolib driver to read
+an external input. I had previously been using the char/cs5535-gpio
+driver.
+
+Signed-off-by: Ben Gardner <gardner.ben@gmail.com>
+Acked-by: Andres Salomon <dilinger@collabora.co.uk>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpio/cs5535-gpio.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/cs5535-gpio.c
++++ b/drivers/gpio/cs5535-gpio.c
+@@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio
+
+ static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
+ {
+- return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
++ return cs5535_gpio_isset(offset, GPIO_READ_BACK);
+ }
+
+ static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+@@ -172,6 +172,7 @@ static int chip_direction_input(struct g
+
+ spin_lock_irqsave(&chip->lock, flags);
+ __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
++ __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
+ spin_unlock_irqrestore(&chip->lock, flags);
+
+ return 0;
+@@ -184,6 +185,7 @@ static int chip_direction_output(struct
+
+ spin_lock_irqsave(&chip->lock, flags);
+
++ __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
+ __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
+ if (val)
+ __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
--- /dev/null
+From 3383d23d86791503559cb87837491af37469d9e5 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Wed, 17 Feb 2010 18:04:35 +0000
+Subject: gpiolib: Actually set output state in wm831x_gpio_direction_output()
+
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+commit 3383d23d86791503559cb87837491af37469d9e5 upstream.
+
+wm831x_gpio_direction_output() ignored the state passed into it.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpio/wm831x-gpio.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpio/wm831x-gpio.c
++++ b/drivers/gpio/wm831x-gpio.c
+@@ -60,23 +60,31 @@ static int wm831x_gpio_get(struct gpio_c
+ return 0;
+ }
+
+-static int wm831x_gpio_direction_out(struct gpio_chip *chip,
+- unsigned offset, int value)
++static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+ {
+ struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+ struct wm831x *wm831x = wm831x_gpio->wm831x;
+
+- return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+- WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
++ wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
++ value << offset);
+ }
+
+-static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
++static int wm831x_gpio_direction_out(struct gpio_chip *chip,
++ unsigned offset, int value)
+ {
+ struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+ struct wm831x *wm831x = wm831x_gpio->wm831x;
++ int ret;
+
+- wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
+- value << offset);
++ ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
++ WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
++ if (ret < 0)
++ return ret;
++
++ /* Can only set GPIO state once it's in output mode */
++ wm831x_gpio_set(chip, offset, value);
++
++ return 0;
+ }
+
+ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
--- /dev/null
+From dc71afe5ac7e8d049bb991330518e4c898a7d92e Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Fri, 5 Mar 2010 22:17:26 +0100
+Subject: hwmon: Fix off-by-one kind values
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit dc71afe5ac7e8d049bb991330518e4c898a7d92e upstream.
+
+Recent changes on the I2C front have left off-by-one array indexes in
+3 hwmon drivers. Fix them.
+
+Faulty commit:
+e5e9f44c2 i2c: Drop I2C_CLIENT_INSMOD_2 to 8
+
+Reported-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Cc: Hans de Goede <hdegoede@redhat.com>
+Cc: Andre Prendel <andre.prendel@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/fschmd.c | 15 ++++++---------
+ drivers/hwmon/tmp401.c | 7 +++----
+ drivers/hwmon/tmp421.c | 4 ++--
+ 3 files changed, 11 insertions(+), 15 deletions(-)
+
+--- a/drivers/hwmon/fschmd.c
++++ b/drivers/hwmon/fschmd.c
+@@ -267,7 +267,7 @@ struct fschmd_data {
+ struct list_head list; /* member of the watchdog_data_list */
+ struct kref kref;
+ struct miscdevice watchdog_miscdev;
+- int kind;
++ enum chips kind;
+ unsigned long watchdog_is_open;
+ char watchdog_expect_close;
+ char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
+@@ -325,8 +325,7 @@ static ssize_t show_in_value(struct devi
+ int index = to_sensor_dev_attr(devattr)->index;
+ struct fschmd_data *data = fschmd_update_device(dev);
+
+- /* fscher / fschrc - 1 as data->kind is an array index, not a chips */
+- if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
++ if (data->kind == fscher || data->kind >= fschrc)
+ return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
+ dmi_mult[index]) / 255 + dmi_offset[index]);
+ else
+@@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(
+ int val = data->fan_min[index];
+
+ /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+- if (val || data->kind == fscsyl - 1)
++ if (val || data->kind == fscsyl)
+ val = val / 2 + 128;
+
+ return sprintf(buf, "%d\n", val);
+@@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm
+ unsigned long v = simple_strtoul(buf, NULL, 10);
+
+ /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+- if (v || data->kind == fscsyl - 1) {
++ if (v || data->kind == fscsyl) {
+ v = SENSORS_LIMIT(v, 128, 255);
+ v = (v - 128) * 2 + 1;
+ }
+@@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_clie
+ else
+ return -ENODEV;
+
+- strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
++ strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE);
+
+ return 0;
+ }
+@@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_clien
+ (where the client is found through a data ptr instead of the
+ otherway around) */
+ data->client = client;
++ data->kind = kind;
+
+ if (kind == fscpos) {
+ /* The Poseidon has hardwired temp limits, fill these
+@@ -1085,9 +1085,6 @@ static int fschmd_probe(struct i2c_clien
+ }
+ }
+
+- /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
+- data->kind = kind - 1;
+-
+ /* Read in some never changing registers */
+ data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
+ data->global_control = i2c_smbus_read_byte_data(client,
+--- a/drivers/hwmon/tmp401.c
++++ b/drivers/hwmon/tmp401.c
+@@ -134,7 +134,7 @@ struct tmp401_data {
+ struct mutex update_lock;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* in jiffies */
+- int kind;
++ enum chips kind;
+
+ /* register values */
+ u8 status;
+@@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_clie
+ if (reg > 15)
+ return -ENODEV;
+
+- strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
++ strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
+
+ return 0;
+ }
+@@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_clien
+ goto exit_remove;
+ }
+
+- dev_info(&client->dev, "Detected TI %s chip\n",
+- names[data->kind - 1]);
++ dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]);
+
+ return 0;
+
+--- a/drivers/hwmon/tmp421.c
++++ b/drivers/hwmon/tmp421.c
+@@ -254,9 +254,9 @@ static int tmp421_detect(struct i2c_clie
+ return -ENODEV;
+ }
+
+- strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
++ strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
+ dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
+- names[kind - 1], client->addr);
++ names[kind], client->addr);
+
+ return 0;
+ }
--- /dev/null
+From a44908d742a577fb5ccb9a8c082326d4cea234c2 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Fri, 5 Mar 2010 22:17:25 +0100
+Subject: hwmon: (tmp421) Fix temperature conversions
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit a44908d742a577fb5ccb9a8c082326d4cea234c2 upstream.
+
+The low bits of temperature registers are status bits, they must be
+masked out before converting the register values to temperatures.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Tested-by: Andre Prendel <andre.prendel@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/tmp421.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/hwmon/tmp421.c
++++ b/drivers/hwmon/tmp421.c
+@@ -80,14 +80,16 @@ struct tmp421_data {
+
+ static int temp_from_s16(s16 reg)
+ {
+- int temp = reg;
++ /* Mask out status bits */
++ int temp = reg & ~0xf;
+
+ return (temp * 1000 + 128) / 256;
+ }
+
+ static int temp_from_u16(u16 reg)
+ {
+- int temp = reg;
++ /* Mask out status bits */
++ int temp = reg & ~0xf;
+
+ /* Add offset for extended temperature range. */
+ temp -= 64 * 256;
--- /dev/null
+From 8d59582a867470a3e0c3eced4a01625ae8dc546b Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Fri, 5 Mar 2010 22:17:25 +0100
+Subject: hwmon: (tmp421) Restore missing inputs
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit 8d59582a867470a3e0c3eced4a01625ae8dc546b upstream.
+
+An off-by-one error caused some inputs to not be created by the driver
+when they should. TMP421 gets only one input instead of two, TMP422
+gets two instead of three, etc. Fix the bug by listing explicitly the
+number of inputs each device has.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Tested-by: Andre Prendel <andre.prendel@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/tmp421.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/hwmon/tmp421.c
++++ b/drivers/hwmon/tmp421.c
+@@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4] = {
+ #define TMP423_DEVICE_ID 0x23
+
+ static const struct i2c_device_id tmp421_id[] = {
+- { "tmp421", tmp421 },
+- { "tmp422", tmp422 },
+- { "tmp423", tmp423 },
++ { "tmp421", 2 },
++ { "tmp422", 3 },
++ { "tmp423", 4 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, tmp421_id);
+@@ -73,7 +73,7 @@ struct tmp421_data {
+ struct mutex update_lock;
+ char valid;
+ unsigned long last_updated;
+- int kind;
++ int channels;
+ u8 config;
+ s16 temp[4];
+ };
+@@ -109,7 +109,7 @@ static struct tmp421_data *tmp421_update
+ data->config = i2c_smbus_read_byte_data(client,
+ TMP421_CONFIG_REG_1);
+
+- for (i = 0; i <= data->kind; i++) {
++ for (i = 0; i < data->channels; i++) {
+ data->temp[i] = i2c_smbus_read_byte_data(client,
+ TMP421_TEMP_MSB[i]) << 8;
+ data->temp[i] |= i2c_smbus_read_byte_data(client,
+@@ -168,7 +168,7 @@ static mode_t tmp421_is_visible(struct k
+ devattr = container_of(a, struct device_attribute, attr);
+ index = to_sensor_dev_attr(devattr)->index;
+
+- if (data->kind > index)
++ if (index < data->channels)
+ return a->mode;
+
+ return 0;
+@@ -273,7 +273,7 @@ static int tmp421_probe(struct i2c_clien
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+- data->kind = id->driver_data;
++ data->channels = id->driver_data;
+
+ err = tmp421_init_client(client);
+ if (err)
usb-fix-i2c-api-usage-in-ohci-pnx4008.patch
p54usb-add-the-usb-id-for-belkin-accton-fd7050e-ver-1010ec.patch
p54pci-handle-dma-mapping-errors.patch
+gpiolib-actually-set-output-state-in-wm831x_gpio_direction_output.patch
+gpio-cs5535-gpio-fix-input-direction.patch
+hwmon-tmp421-fix-temperature-conversions.patch
+hwmon-tmp421-restore-missing-inputs.patch
+hwmon-fix-off-by-one-kind-values.patch