summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-05-04 11:09:28 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-12 15:02:42 -0700
commitb9d41d81abb6dba3ce122138f9593f4693f60dc9 (patch)
treebac4b811d7bd7646f853548a51969a8ccb498b44 /drivers/i2c
parentf6b7c3cb24d76757a2c4901f31dac6caa2930c3b (diff)
downloadkernel-common-b9d41d81abb6dba3ce122138f9593f4693f60dc9.tar.gz
kernel-common-b9d41d81abb6dba3ce122138f9593f4693f60dc9.tar.bz2
kernel-common-b9d41d81abb6dba3ce122138f9593f4693f60dc9.zip
i2c: Fix probing of FSC hardware monitoring chips
commit b1d4b390ea4bb480e65974ce522a04022608a8df upstream. Some FSC hardware monitoring chips (Syleus at least) doesn't like quick writes we typically use to probe for I2C chips. Use a regular byte read instead for the address they live at (0x73). These are the only known chips living at this address on PC systems. For clarity, this fix should not be needed for kernels 2.6.30 and later, as we started instantiating the hwmon devices explicitly based on DMI data. Still, this fix is valuable in the following two cases: * Support for recent FSC chips on older kernels. The DMI-based device instantiation is more difficult to backport than the device support itself. * Case where the DMI-based device instantiation fails, whatever the reason. We fall back to probing in that case, so it should work. This fixes kernel bug #15634: https://bugzilla.kernel.org/show_bug.cgi?id=15634 Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c-core.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 10be7b5fbe97..855911ebdb4d 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1210,12 +1210,23 @@ static int i2c_detect_address(struct i2c_client *temp_client,
return 0;
/* Make sure there is something at this address */
- if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
- return 0;
+ if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
+ /* Special probe for FSC hwmon chips */
+ union i2c_smbus_data dummy;
- /* Prevent 24RF08 corruption */
- if ((addr & ~0x0f) == 0x50)
- i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
+ if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
+ I2C_SMBUS_BYTE_DATA, &dummy) < 0)
+ return 0;
+ } else {
+ if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+ I2C_SMBUS_QUICK, NULL) < 0)
+ return 0;
+
+ /* Prevent 24RF08 corruption */
+ if ((addr & ~0x0f) == 0x50)
+ i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+ I2C_SMBUS_QUICK, NULL);
+ }
/* Finally call the custom detection function */
memset(&info, 0, sizeof(struct i2c_board_info));