diff options
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r-- | drivers/hwmon/pmbus/lm25066.c | 91 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/ltc2978.c | 16 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 24 |
3 files changed, 103 insertions, 28 deletions
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 6a9d6edaacb3..a26b1d1d9514 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 | 2 | * Hardware monitoring driver for LM25056 / LM25063 / LM25066 / LM5064 / LM5066 |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 4 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013 Guenter Roeck | 5 | * Copyright (c) 2013 Guenter Roeck |
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include "pmbus.h" | 28 | #include "pmbus.h" |
29 | 29 | ||
30 | enum chips { lm25056, lm25066, lm5064, lm5066 }; | 30 | enum chips { lm25056, lm25063, lm25066, lm5064, lm5066 }; |
31 | 31 | ||
32 | #define LM25066_READ_VAUX 0xd0 | 32 | #define LM25066_READ_VAUX 0xd0 |
33 | #define LM25066_MFR_READ_IIN 0xd1 | 33 | #define LM25066_MFR_READ_IIN 0xd1 |
@@ -52,6 +52,11 @@ enum chips { lm25056, lm25066, lm5064, lm5066 }; | |||
52 | #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) | 52 | #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) |
53 | #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) | 53 | #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) |
54 | 54 | ||
55 | /* LM25063 only */ | ||
56 | |||
57 | #define LM25063_READ_VOUT_MAX 0xe5 | ||
58 | #define LM25063_READ_VOUT_MIN 0xe6 | ||
59 | |||
55 | struct __coeff { | 60 | struct __coeff { |
56 | short m, b, R; | 61 | short m, b, R; |
57 | }; | 62 | }; |
@@ -59,7 +64,7 @@ struct __coeff { | |||
59 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) | 64 | #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) |
60 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) | 65 | #define PSC_POWER_L (PSC_NUM_CLASSES + 1) |
61 | 66 | ||
62 | static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | 67 | static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = { |
63 | [lm25056] = { | 68 | [lm25056] = { |
64 | [PSC_VOLTAGE_IN] = { | 69 | [PSC_VOLTAGE_IN] = { |
65 | .m = 16296, | 70 | .m = 16296, |
@@ -116,6 +121,36 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | |||
116 | .m = 16, | 121 | .m = 16, |
117 | }, | 122 | }, |
118 | }, | 123 | }, |
124 | [lm25063] = { | ||
125 | [PSC_VOLTAGE_IN] = { | ||
126 | .m = 16000, | ||
127 | .R = -2, | ||
128 | }, | ||
129 | [PSC_VOLTAGE_OUT] = { | ||
130 | .m = 16000, | ||
131 | .R = -2, | ||
132 | }, | ||
133 | [PSC_CURRENT_IN] = { | ||
134 | .m = 10000, | ||
135 | .R = -2, | ||
136 | }, | ||
137 | [PSC_CURRENT_IN_L] = { | ||
138 | .m = 10000, | ||
139 | .R = -2, | ||
140 | }, | ||
141 | [PSC_POWER] = { | ||
142 | .m = 5000, | ||
143 | .R = -3, | ||
144 | }, | ||
145 | [PSC_POWER_L] = { | ||
146 | .m = 5000, | ||
147 | .R = -3, | ||
148 | }, | ||
149 | [PSC_TEMPERATURE] = { | ||
150 | .m = 15596, | ||
151 | .R = -3, | ||
152 | }, | ||
153 | }, | ||
119 | [lm5064] = { | 154 | [lm5064] = { |
120 | [PSC_VOLTAGE_IN] = { | 155 | [PSC_VOLTAGE_IN] = { |
121 | .m = 4611, | 156 | .m = 4611, |
@@ -178,6 +213,7 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { | |||
178 | 213 | ||
179 | struct lm25066_data { | 214 | struct lm25066_data { |
180 | int id; | 215 | int id; |
216 | u16 rlimit; /* Maximum register value */ | ||
181 | struct pmbus_driver_info info; | 217 | struct pmbus_driver_info info; |
182 | }; | 218 | }; |
183 | 219 | ||
@@ -200,6 +236,10 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
200 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ | 236 | /* VIN: 6.14 mV VAUX: 293 uV LSB */ |
201 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); | 237 | ret = DIV_ROUND_CLOSEST(ret * 293, 6140); |
202 | break; | 238 | break; |
239 | case lm25063: | ||
240 | /* VIN: 6.25 mV VAUX: 200.0 uV LSB */ | ||
241 | ret = DIV_ROUND_CLOSEST(ret * 20, 625); | ||
242 | break; | ||
203 | case lm25066: | 243 | case lm25066: |
204 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ | 244 | /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ |
205 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); | 245 | ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); |
@@ -253,6 +293,24 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
253 | return ret; | 293 | return ret; |
254 | } | 294 | } |
255 | 295 | ||
296 | static int lm25063_read_word_data(struct i2c_client *client, int page, int reg) | ||
297 | { | ||
298 | int ret; | ||
299 | |||
300 | switch (reg) { | ||
301 | case PMBUS_VIRT_READ_VOUT_MAX: | ||
302 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX); | ||
303 | break; | ||
304 | case PMBUS_VIRT_READ_VOUT_MIN: | ||
305 | ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN); | ||
306 | break; | ||
307 | default: | ||
308 | ret = lm25066_read_word_data(client, page, reg); | ||
309 | break; | ||
310 | } | ||
311 | return ret; | ||
312 | } | ||
313 | |||
256 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) | 314 | static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) |
257 | { | 315 | { |
258 | int ret; | 316 | int ret; |
@@ -308,27 +366,34 @@ static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) | |||
308 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | 366 | static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, |
309 | u16 word) | 367 | u16 word) |
310 | { | 368 | { |
369 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
370 | const struct lm25066_data *data = to_lm25066_data(info); | ||
311 | int ret; | 371 | int ret; |
312 | 372 | ||
313 | switch (reg) { | 373 | switch (reg) { |
374 | case PMBUS_POUT_OP_FAULT_LIMIT: | ||
375 | case PMBUS_POUT_OP_WARN_LIMIT: | ||
314 | case PMBUS_VOUT_UV_WARN_LIMIT: | 376 | case PMBUS_VOUT_UV_WARN_LIMIT: |
315 | case PMBUS_OT_FAULT_LIMIT: | 377 | case PMBUS_OT_FAULT_LIMIT: |
316 | case PMBUS_OT_WARN_LIMIT: | 378 | case PMBUS_OT_WARN_LIMIT: |
379 | case PMBUS_IIN_OC_FAULT_LIMIT: | ||
317 | case PMBUS_VIN_UV_WARN_LIMIT: | 380 | case PMBUS_VIN_UV_WARN_LIMIT: |
381 | case PMBUS_VIN_UV_FAULT_LIMIT: | ||
382 | case PMBUS_VIN_OV_FAULT_LIMIT: | ||
318 | case PMBUS_VIN_OV_WARN_LIMIT: | 383 | case PMBUS_VIN_OV_WARN_LIMIT: |
319 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 384 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
320 | ret = pmbus_write_word_data(client, 0, reg, word); | 385 | ret = pmbus_write_word_data(client, 0, reg, word); |
321 | pmbus_clear_cache(client); | 386 | pmbus_clear_cache(client); |
322 | break; | 387 | break; |
323 | case PMBUS_IIN_OC_WARN_LIMIT: | 388 | case PMBUS_IIN_OC_WARN_LIMIT: |
324 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 389 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
325 | ret = pmbus_write_word_data(client, 0, | 390 | ret = pmbus_write_word_data(client, 0, |
326 | LM25066_MFR_IIN_OC_WARN_LIMIT, | 391 | LM25066_MFR_IIN_OC_WARN_LIMIT, |
327 | word); | 392 | word); |
328 | pmbus_clear_cache(client); | 393 | pmbus_clear_cache(client); |
329 | break; | 394 | break; |
330 | case PMBUS_PIN_OP_WARN_LIMIT: | 395 | case PMBUS_PIN_OP_WARN_LIMIT: |
331 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 396 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
332 | ret = pmbus_write_word_data(client, 0, | 397 | ret = pmbus_write_word_data(client, 0, |
333 | LM25066_MFR_PIN_OP_WARN_LIMIT, | 398 | LM25066_MFR_PIN_OP_WARN_LIMIT, |
334 | word); | 399 | word); |
@@ -337,7 +402,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
337 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: | 402 | case PMBUS_VIRT_VMON_UV_WARN_LIMIT: |
338 | /* Adjust from VIN coefficients (for LM25056) */ | 403 | /* Adjust from VIN coefficients (for LM25056) */ |
339 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | 404 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
340 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 405 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
341 | ret = pmbus_write_word_data(client, 0, | 406 | ret = pmbus_write_word_data(client, 0, |
342 | LM25056_VAUX_UV_WARN_LIMIT, word); | 407 | LM25056_VAUX_UV_WARN_LIMIT, word); |
343 | pmbus_clear_cache(client); | 408 | pmbus_clear_cache(client); |
@@ -345,7 +410,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
345 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: | 410 | case PMBUS_VIRT_VMON_OV_WARN_LIMIT: |
346 | /* Adjust from VIN coefficients (for LM25056) */ | 411 | /* Adjust from VIN coefficients (for LM25056) */ |
347 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); | 412 | word = DIV_ROUND_CLOSEST((int)word * 6140, 293); |
348 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); | 413 | word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); |
349 | ret = pmbus_write_word_data(client, 0, | 414 | ret = pmbus_write_word_data(client, 0, |
350 | LM25056_VAUX_OV_WARN_LIMIT, word); | 415 | LM25056_VAUX_OV_WARN_LIMIT, word); |
351 | pmbus_clear_cache(client); | 416 | pmbus_clear_cache(client); |
@@ -399,9 +464,16 @@ static int lm25066_probe(struct i2c_client *client, | |||
399 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; | 464 | info->func[0] |= PMBUS_HAVE_STATUS_VMON; |
400 | info->read_word_data = lm25056_read_word_data; | 465 | info->read_word_data = lm25056_read_word_data; |
401 | info->read_byte_data = lm25056_read_byte_data; | 466 | info->read_byte_data = lm25056_read_byte_data; |
467 | data->rlimit = 0x0fff; | ||
468 | } else if (data->id == lm25063) { | ||
469 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
470 | | PMBUS_HAVE_POUT; | ||
471 | info->read_word_data = lm25063_read_word_data; | ||
472 | data->rlimit = 0xffff; | ||
402 | } else { | 473 | } else { |
403 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 474 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; |
404 | info->read_word_data = lm25066_read_word_data; | 475 | info->read_word_data = lm25066_read_word_data; |
476 | data->rlimit = 0x0fff; | ||
405 | } | 477 | } |
406 | info->write_word_data = lm25066_write_word_data; | 478 | info->write_word_data = lm25066_write_word_data; |
407 | 479 | ||
@@ -432,6 +504,7 @@ static int lm25066_probe(struct i2c_client *client, | |||
432 | 504 | ||
433 | static const struct i2c_device_id lm25066_id[] = { | 505 | static const struct i2c_device_id lm25066_id[] = { |
434 | {"lm25056", lm25056}, | 506 | {"lm25056", lm25056}, |
507 | {"lm25063", lm25063}, | ||
435 | {"lm25066", lm25066}, | 508 | {"lm25066", lm25066}, |
436 | {"lm5064", lm5064}, | 509 | {"lm5064", lm5064}, |
437 | {"lm5066", lm5066}, | 510 | {"lm5066", lm5066}, |
@@ -453,5 +526,5 @@ static struct i2c_driver lm25066_driver = { | |||
453 | module_i2c_driver(lm25066_driver); | 526 | module_i2c_driver(lm25066_driver); |
454 | 527 | ||
455 | MODULE_AUTHOR("Guenter Roeck"); | 528 | MODULE_AUTHOR("Guenter Roeck"); |
456 | MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); | 529 | MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips"); |
457 | MODULE_LICENSE("GPL"); | 530 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 586a89ef9e0f..de3c152a1d9a 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883 | 2 | * Hardware monitoring driver for LTC2974, LTC2977, LTC2978, LTC3880, |
3 | * and LTC3883 | ||
3 | * | 4 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 5 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013 Guenter Roeck | 6 | * Copyright (c) 2013 Guenter Roeck |
@@ -27,7 +28,7 @@ | |||
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include "pmbus.h" | 29 | #include "pmbus.h" |
29 | 30 | ||
30 | enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; | 31 | enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883 }; |
31 | 32 | ||
32 | /* Common for all chips */ | 33 | /* Common for all chips */ |
33 | #define LTC2978_MFR_VOUT_PEAK 0xdd | 34 | #define LTC2978_MFR_VOUT_PEAK 0xdd |
@@ -35,7 +36,7 @@ enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; | |||
35 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf | 36 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf |
36 | #define LTC2978_MFR_SPECIAL_ID 0xe7 | 37 | #define LTC2978_MFR_SPECIAL_ID 0xe7 |
37 | 38 | ||
38 | /* LTC2974 and LTC2978 */ | 39 | /* LTC2974, LCT2977, and LTC2978 */ |
39 | #define LTC2978_MFR_VOUT_MIN 0xfb | 40 | #define LTC2978_MFR_VOUT_MIN 0xfb |
40 | #define LTC2978_MFR_VIN_MIN 0xfc | 41 | #define LTC2978_MFR_VIN_MIN 0xfc |
41 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd | 42 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd |
@@ -53,8 +54,10 @@ enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; | |||
53 | #define LTC3883_MFR_IIN_PEAK 0xe1 | 54 | #define LTC3883_MFR_IIN_PEAK 0xe1 |
54 | 55 | ||
55 | #define LTC2974_ID 0x0212 | 56 | #define LTC2974_ID 0x0212 |
57 | #define LTC2977_ID 0x0130 | ||
56 | #define LTC2978_ID_REV1 0x0121 | 58 | #define LTC2978_ID_REV1 0x0121 |
57 | #define LTC2978_ID_REV2 0x0122 | 59 | #define LTC2978_ID_REV2 0x0122 |
60 | #define LTC2978A_ID 0x0124 | ||
58 | #define LTC3880_ID 0x4000 | 61 | #define LTC3880_ID 0x4000 |
59 | #define LTC3880_ID_MASK 0xff00 | 62 | #define LTC3880_ID_MASK 0xff00 |
60 | #define LTC3883_ID 0x4300 | 63 | #define LTC3883_ID 0x4300 |
@@ -363,6 +366,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, | |||
363 | 366 | ||
364 | static const struct i2c_device_id ltc2978_id[] = { | 367 | static const struct i2c_device_id ltc2978_id[] = { |
365 | {"ltc2974", ltc2974}, | 368 | {"ltc2974", ltc2974}, |
369 | {"ltc2977", ltc2977}, | ||
366 | {"ltc2978", ltc2978}, | 370 | {"ltc2978", ltc2978}, |
367 | {"ltc3880", ltc3880}, | 371 | {"ltc3880", ltc3880}, |
368 | {"ltc3883", ltc3883}, | 372 | {"ltc3883", ltc3883}, |
@@ -392,7 +396,10 @@ static int ltc2978_probe(struct i2c_client *client, | |||
392 | 396 | ||
393 | if (chip_id == LTC2974_ID) { | 397 | if (chip_id == LTC2974_ID) { |
394 | data->id = ltc2974; | 398 | data->id = ltc2974; |
395 | } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { | 399 | } else if (chip_id == LTC2977_ID) { |
400 | data->id = ltc2977; | ||
401 | } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 || | ||
402 | chip_id == LTC2978A_ID) { | ||
396 | data->id = ltc2978; | 403 | data->id = ltc2978; |
397 | } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { | 404 | } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { |
398 | data->id = ltc3880; | 405 | data->id = ltc3880; |
@@ -438,6 +445,7 @@ static int ltc2978_probe(struct i2c_client *client, | |||
438 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | 445 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; |
439 | } | 446 | } |
440 | break; | 447 | break; |
448 | case ltc2977: | ||
441 | case ltc2978: | 449 | case ltc2978: |
442 | info->read_word_data = ltc2978_read_word_data; | 450 | info->read_word_data = ltc2978_read_word_data; |
443 | info->pages = LTC2978_NUM_PAGES; | 451 | info->pages = LTC2978_NUM_PAGES; |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 9319fcf142d9..3cbf66e9d861 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -97,6 +97,7 @@ struct pmbus_data { | |||
97 | int max_attributes; | 97 | int max_attributes; |
98 | int num_attributes; | 98 | int num_attributes; |
99 | struct attribute_group group; | 99 | struct attribute_group group; |
100 | const struct attribute_group *groups[2]; | ||
100 | 101 | ||
101 | struct pmbus_sensor *sensors; | 102 | struct pmbus_sensor *sensors; |
102 | 103 | ||
@@ -156,7 +157,7 @@ EXPORT_SYMBOL_GPL(pmbus_write_byte); | |||
156 | 157 | ||
157 | /* | 158 | /* |
158 | * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if | 159 | * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if |
159 | * a device specific mapping funcion exists and calls it if necessary. | 160 | * a device specific mapping function exists and calls it if necessary. |
160 | */ | 161 | */ |
161 | static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) | 162 | static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
162 | { | 163 | { |
@@ -348,7 +349,7 @@ static struct _pmbus_status { | |||
348 | 349 | ||
349 | static struct pmbus_data *pmbus_update_device(struct device *dev) | 350 | static struct pmbus_data *pmbus_update_device(struct device *dev) |
350 | { | 351 | { |
351 | struct i2c_client *client = to_i2c_client(dev); | 352 | struct i2c_client *client = to_i2c_client(dev->parent); |
352 | struct pmbus_data *data = i2c_get_clientdata(client); | 353 | struct pmbus_data *data = i2c_get_clientdata(client); |
353 | const struct pmbus_driver_info *info = data->info; | 354 | const struct pmbus_driver_info *info = data->info; |
354 | struct pmbus_sensor *sensor; | 355 | struct pmbus_sensor *sensor; |
@@ -686,7 +687,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b, | |||
686 | if (!s1 && !s2) { | 687 | if (!s1 && !s2) { |
687 | ret = !!regval; | 688 | ret = !!regval; |
688 | } else if (!s1 || !s2) { | 689 | } else if (!s1 || !s2) { |
689 | BUG(); | 690 | WARN(1, "Bad boolean descriptor %p: s1=%p, s2=%p\n", b, s1, s2); |
690 | return 0; | 691 | return 0; |
691 | } else { | 692 | } else { |
692 | long v1, v2; | 693 | long v1, v2; |
@@ -733,7 +734,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, | |||
733 | struct device_attribute *devattr, | 734 | struct device_attribute *devattr, |
734 | const char *buf, size_t count) | 735 | const char *buf, size_t count) |
735 | { | 736 | { |
736 | struct i2c_client *client = to_i2c_client(dev); | 737 | struct i2c_client *client = to_i2c_client(dev->parent); |
737 | struct pmbus_data *data = i2c_get_clientdata(client); | 738 | struct pmbus_data *data = i2c_get_clientdata(client); |
738 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); | 739 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); |
739 | ssize_t rv = count; | 740 | ssize_t rv = count; |
@@ -1768,22 +1769,16 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | |||
1768 | goto out_kfree; | 1769 | goto out_kfree; |
1769 | } | 1770 | } |
1770 | 1771 | ||
1771 | /* Register sysfs hooks */ | 1772 | data->groups[0] = &data->group; |
1772 | ret = sysfs_create_group(&dev->kobj, &data->group); | 1773 | data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, |
1773 | if (ret) { | 1774 | data, data->groups); |
1774 | dev_err(dev, "Failed to create sysfs entries\n"); | ||
1775 | goto out_kfree; | ||
1776 | } | ||
1777 | data->hwmon_dev = hwmon_device_register(dev); | ||
1778 | if (IS_ERR(data->hwmon_dev)) { | 1775 | if (IS_ERR(data->hwmon_dev)) { |
1779 | ret = PTR_ERR(data->hwmon_dev); | 1776 | ret = PTR_ERR(data->hwmon_dev); |
1780 | dev_err(dev, "Failed to register hwmon device\n"); | 1777 | dev_err(dev, "Failed to register hwmon device\n"); |
1781 | goto out_hwmon_device_register; | 1778 | goto out_kfree; |
1782 | } | 1779 | } |
1783 | return 0; | 1780 | return 0; |
1784 | 1781 | ||
1785 | out_hwmon_device_register: | ||
1786 | sysfs_remove_group(&dev->kobj, &data->group); | ||
1787 | out_kfree: | 1782 | out_kfree: |
1788 | kfree(data->group.attrs); | 1783 | kfree(data->group.attrs); |
1789 | return ret; | 1784 | return ret; |
@@ -1794,7 +1789,6 @@ int pmbus_do_remove(struct i2c_client *client) | |||
1794 | { | 1789 | { |
1795 | struct pmbus_data *data = i2c_get_clientdata(client); | 1790 | struct pmbus_data *data = i2c_get_clientdata(client); |
1796 | hwmon_device_unregister(data->hwmon_dev); | 1791 | hwmon_device_unregister(data->hwmon_dev); |
1797 | sysfs_remove_group(&client->dev.kobj, &data->group); | ||
1798 | kfree(data->group.attrs); | 1792 | kfree(data->group.attrs); |
1799 | return 0; | 1793 | return 0; |
1800 | } | 1794 | } |