From: Greg Kroah-Hartman Date: Wed, 10 Mar 2010 00:28:10 +0000 (-0800) Subject: .33 stuff X-Git-Tag: v2.6.32.10~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=51093dad5ef65c56df583834aa362691998b2ca8;p=thirdparty%2Fkernel%2Fstable-queue.git .33 stuff --- diff --git a/queue-2.6.33/gpio-cs5535-gpio-fix-input-direction.patch b/queue-2.6.33/gpio-cs5535-gpio-fix-input-direction.patch new file mode 100644 index 00000000000..7ab952b7cbe --- /dev/null +++ b/queue-2.6.33/gpio-cs5535-gpio-fix-input-direction.patch @@ -0,0 +1,65 @@ +From a8a5164c297c16c2f4be776714ca47dba252cc3d Mon Sep 17 00:00:00 2001 +From: Ben Gardner +Date: Fri, 5 Mar 2010 13:44:38 -0800 +Subject: gpio: cs5535-gpio: fix input direction + +From: Ben Gardner + +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 +Acked-by: Andres Salomon +Cc: Andrew Morton +Cc: David Brownell +Cc: Mark Brown +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.33/gpiolib-actually-set-output-state-in-wm831x_gpio_direction_output.patch b/queue-2.6.33/gpiolib-actually-set-output-state-in-wm831x_gpio_direction_output.patch new file mode 100644 index 00000000000..427565e070e --- /dev/null +++ b/queue-2.6.33/gpiolib-actually-set-output-state-in-wm831x_gpio_direction_output.patch @@ -0,0 +1,60 @@ +From 3383d23d86791503559cb87837491af37469d9e5 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Wed, 17 Feb 2010 18:04:35 +0000 +Subject: gpiolib: Actually set output state in wm831x_gpio_direction_output() + +From: Mark Brown + +commit 3383d23d86791503559cb87837491af37469d9e5 upstream. + +wm831x_gpio_direction_output() ignored the state passed into it. + +Signed-off-by: Mark Brown +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.33/hwmon-fix-off-by-one-kind-values.patch b/queue-2.6.33/hwmon-fix-off-by-one-kind-values.patch new file mode 100644 index 00000000000..752204a3fb0 --- /dev/null +++ b/queue-2.6.33/hwmon-fix-off-by-one-kind-values.patch @@ -0,0 +1,137 @@ +From dc71afe5ac7e8d049bb991330518e4c898a7d92e Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Fri, 5 Mar 2010 22:17:26 +0100 +Subject: hwmon: Fix off-by-one kind values + +From: Jean Delvare + +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 +Signed-off-by: Jean Delvare +Cc: Hans de Goede +Cc: Andre Prendel +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-2.6.33/hwmon-tmp421-fix-temperature-conversions.patch b/queue-2.6.33/hwmon-tmp421-fix-temperature-conversions.patch new file mode 100644 index 00000000000..60c7801a8cf --- /dev/null +++ b/queue-2.6.33/hwmon-tmp421-fix-temperature-conversions.patch @@ -0,0 +1,41 @@ +From a44908d742a577fb5ccb9a8c082326d4cea234c2 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Fri, 5 Mar 2010 22:17:25 +0100 +Subject: hwmon: (tmp421) Fix temperature conversions + +From: Jean Delvare + +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 +Tested-by: Andre Prendel +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.33/hwmon-tmp421-restore-missing-inputs.patch b/queue-2.6.33/hwmon-tmp421-restore-missing-inputs.patch new file mode 100644 index 00000000000..d276f152ef5 --- /dev/null +++ b/queue-2.6.33/hwmon-tmp421-restore-missing-inputs.patch @@ -0,0 +1,73 @@ +From 8d59582a867470a3e0c3eced4a01625ae8dc546b Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Fri, 5 Mar 2010 22:17:25 +0100 +Subject: hwmon: (tmp421) Restore missing inputs + +From: Jean Delvare + +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 +Tested-by: Andre Prendel +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.33/series b/queue-2.6.33/series index 48376e9aff4..534593e1497 100644 --- a/queue-2.6.33/series +++ b/queue-2.6.33/series @@ -58,3 +58,8 @@ usb-serial-sierra-driver-indat_callback-fix.patch 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