aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r--drivers/hwmon/pmbus/lm25066.c91
-rw-r--r--drivers/hwmon/pmbus/ltc2978.c16
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c24
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
30enum chips { lm25056, lm25066, lm5064, lm5066 }; 30enum 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
55struct __coeff { 60struct __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
62static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { 67static 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
179struct lm25066_data { 214struct 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
296static 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
256static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) 314static 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)
308static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, 366static 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
433static const struct i2c_device_id lm25066_id[] = { 505static 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 = {
453module_i2c_driver(lm25066_driver); 526module_i2c_driver(lm25066_driver);
454 527
455MODULE_AUTHOR("Guenter Roeck"); 528MODULE_AUTHOR("Guenter Roeck");
456MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); 529MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips");
457MODULE_LICENSE("GPL"); 530MODULE_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
30enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; 31enum 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
364static const struct i2c_device_id ltc2978_id[] = { 367static 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 */
161static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) 162static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value)
162{ 163{
@@ -348,7 +349,7 @@ static struct _pmbus_status {
348 349
349static struct pmbus_data *pmbus_update_device(struct device *dev) 350static 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
1785out_hwmon_device_register:
1786 sysfs_remove_group(&dev->kobj, &data->group);
1787out_kfree: 1782out_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}