Commit 37fd245e authored by Mark M. Hoffman's avatar Mark M. Hoffman Committed by Greg Kroah-Hartman

[PATCH] I2C: more w83781d fixes

This patch fixes the various return values in the w83781d_detect()
error paths.  It also cleans up some formatting here and there.
It should be applied on top of the previous one.

It works for me; same caveat as above w.r.t. ISA.
parent 7e357e0d
...@@ -1039,7 +1039,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, ...@@ -1039,7 +1039,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
struct i2c_client *new_client) struct i2c_client *new_client)
{ {
int i, val1 = 0, id; int i, val1 = 0, id;
int err = 0; int err;
const char *client_name; const char *client_name;
struct w83781d_data *data = i2c_get_clientdata(new_client); struct w83781d_data *data = i2c_get_clientdata(new_client);
...@@ -1058,7 +1058,8 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, ...@@ -1058,7 +1058,8 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
force_subclients[i] > 0x4f) { force_subclients[i] > 0x4f) {
dev_err(&new_client->dev, "Invalid subclient " dev_err(&new_client->dev, "Invalid subclient "
"address %d; must be 0x48-0x4f\n", "address %d; must be 0x48-0x4f\n",
force_subclients[i]); force_subclients[i]);
err = -EINVAL;
goto ERROR_SC_1; goto ERROR_SC_1;
} }
} }
...@@ -1082,6 +1083,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, ...@@ -1082,6 +1083,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
dev_err(&new_client->dev, dev_err(&new_client->dev,
"Duplicate addresses 0x%x for subclients.\n", "Duplicate addresses 0x%x for subclients.\n",
data->lm75[0].addr); data->lm75[0].addr);
err = -EBUSY;
goto ERROR_SC_1; goto ERROR_SC_1;
} }
} }
...@@ -1119,7 +1121,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, ...@@ -1119,7 +1121,7 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
break; break;
} }
return err; return 0;
/* Undo inits in case of errors */ /* Undo inits in case of errors */
ERROR_SC_2: ERROR_SC_2:
...@@ -1136,18 +1138,22 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1136,18 +1138,22 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
int i = 0, val1 = 0, val2; int i = 0, val1 = 0, val2;
struct i2c_client *new_client; struct i2c_client *new_client;
struct w83781d_data *data; struct w83781d_data *data;
int err = 0; int err;
const char *client_name = ""; const char *client_name = "";
int is_isa = i2c_is_isa_adapter(adapter); int is_isa = i2c_is_isa_adapter(adapter);
enum vendor { winbond, asus } vendid; enum vendor { winbond, asus } vendid;
if (!is_isa if (!is_isa
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
err = -EINVAL;
goto ERROR0; goto ERROR0;
}
if (is_isa) if (is_isa)
if (!request_region(address, W83781D_EXTENT, "w83781d")) if (!request_region(address, W83781D_EXTENT, "w83781d")) {
err = -EBUSY;
goto ERROR0; goto ERROR0;
}
/* Probe whether there is anything available on this address. Already /* Probe whether there is anything available on this address. Already
done for SMBus clients */ done for SMBus clients */
...@@ -1155,15 +1161,21 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1155,15 +1161,21 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
if (is_isa) { if (is_isa) {
#define REALLY_SLOW_IO #define REALLY_SLOW_IO
/* We need the timeouts for at least some LM78-like chips. But only /* We need the timeouts for at least some LM78-like
if we read 'undefined' registers. */ chips. But only if we read 'undefined' registers. */
i = inb_p(address + 1); i = inb_p(address + 1);
if (inb_p(address + 2) != i) if (inb_p(address + 2) != i) {
err = -ENODEV;
goto ERROR1; goto ERROR1;
if (inb_p(address + 3) != i) }
if (inb_p(address + 3) != i) {
err = -ENODEV;
goto ERROR1; goto ERROR1;
if (inb_p(address + 7) != i) }
if (inb_p(address + 7) != i) {
err = -ENODEV;
goto ERROR1; goto ERROR1;
}
#undef REALLY_SLOW_IO #undef REALLY_SLOW_IO
/* Let's just hope nothing breaks here */ /* Let's just hope nothing breaks here */
...@@ -1171,7 +1183,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1171,7 +1183,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
outb_p(~i & 0x7f, address + 5); outb_p(~i & 0x7f, address + 5);
if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
outb_p(i, address + 5); outb_p(i, address + 5);
return 0; err = -ENODEV;
goto ERROR1;
} }
} }
} }
...@@ -1204,8 +1217,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1204,8 +1217,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
force_*=... parameter, and the Winbond will be reset to the right force_*=... parameter, and the Winbond will be reset to the right
bank. */ bank. */
if (kind < 0) { if (kind < 0) {
if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80){
err = -ENODEV;
goto ERROR2; goto ERROR2;
}
val1 = w83781d_read_value(new_client, W83781D_REG_BANK); val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN); val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
/* Check for Winbond or Asus ID if in bank 0 */ /* Check for Winbond or Asus ID if in bank 0 */
...@@ -1213,14 +1228,19 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1213,14 +1228,19 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3) (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)
&& (val2 != 0x94)) && (val2 != 0x94))
|| ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12) || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)
&& (val2 != 0x06)))) && (val2 != 0x06)))) {
err = -ENODEV;
goto ERROR2; goto ERROR2;
/* If Winbond SMBus, check address at 0x48. Asus doesn't support */ }
/* If Winbond SMBus, check address at 0x48.
Asus doesn't support */
if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) || if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
((val1 & 0x80) && (val2 == 0x5c)))) { ((val1 & 0x80) && (val2 == 0x5c)))) {
if (w83781d_read_value if (w83781d_read_value
(new_client, W83781D_REG_I2C_ADDR) != address) (new_client, W83781D_REG_I2C_ADDR) != address) {
err = -ENODEV;
goto ERROR2; goto ERROR2;
}
} }
} }
...@@ -1239,8 +1259,11 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1239,8 +1259,11 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
vendid = winbond; vendid = winbond;
else if ((val2 == 0x12) || (val2 == 0x06)) else if ((val2 == 0x12) || (val2 == 0x06))
vendid = asus; vendid = asus;
else else {
err = -ENODEV;
goto ERROR2; goto ERROR2;
}
/* mask off lower bit, not reliable */ /* mask off lower bit, not reliable */
val1 = val1 =
w83781d_read_value(new_client, W83781D_REG_WCHIPID) & 0xfe; w83781d_read_value(new_client, W83781D_REG_WCHIPID) & 0xfe;
...@@ -1262,6 +1285,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1262,6 +1285,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
"Ignoring 'force' parameter for unknown chip at" "Ignoring 'force' parameter for unknown chip at"
"adapter %d, address 0x%02x\n", "adapter %d, address 0x%02x\n",
i2c_adapter_id(adapter), address); i2c_adapter_id(adapter), address);
err = -EINVAL;
goto ERROR2; goto ERROR2;
} }
} }
...@@ -1279,7 +1303,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1279,7 +1303,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
} else if (kind == w83697hf) { } else if (kind == w83697hf) {
client_name = "W83697HF chip"; client_name = "W83697HF chip";
} else { } else {
dev_err(&new_client->dev, "Internal error: unknown kind (%d)?!?", kind); dev_err(&new_client->dev, "Internal error: unknown "
"kind (%d)?!?", kind);
err = -ENODEV;
goto ERROR2; goto ERROR2;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment