diff options
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index cb5e255a84c6..80eef50c50fd 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -298,29 +298,30 @@ static int pmbus_check_status_cml(struct i2c_client *client) | |||
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | 300 | ||
301 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) | 301 | static bool pmbus_check_register(struct i2c_client *client, |
302 | int (*func)(struct i2c_client *client, | ||
303 | int page, int reg), | ||
304 | int page, int reg) | ||
302 | { | 305 | { |
303 | int rv; | 306 | int rv; |
304 | struct pmbus_data *data = i2c_get_clientdata(client); | 307 | struct pmbus_data *data = i2c_get_clientdata(client); |
305 | 308 | ||
306 | rv = _pmbus_read_byte_data(client, page, reg); | 309 | rv = func(client, page, reg); |
307 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) | 310 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) |
308 | rv = pmbus_check_status_cml(client); | 311 | rv = pmbus_check_status_cml(client); |
309 | pmbus_clear_fault_page(client, -1); | 312 | pmbus_clear_fault_page(client, -1); |
310 | return rv >= 0; | 313 | return rv >= 0; |
311 | } | 314 | } |
315 | |||
316 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) | ||
317 | { | ||
318 | return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); | ||
319 | } | ||
312 | EXPORT_SYMBOL_GPL(pmbus_check_byte_register); | 320 | EXPORT_SYMBOL_GPL(pmbus_check_byte_register); |
313 | 321 | ||
314 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) | 322 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) |
315 | { | 323 | { |
316 | int rv; | 324 | return pmbus_check_register(client, _pmbus_read_word_data, page, reg); |
317 | struct pmbus_data *data = i2c_get_clientdata(client); | ||
318 | |||
319 | rv = _pmbus_read_word_data(client, page, reg); | ||
320 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) | ||
321 | rv = pmbus_check_status_cml(client); | ||
322 | pmbus_clear_fault_page(client, -1); | ||
323 | return rv >= 0; | ||
324 | } | 325 | } |
325 | EXPORT_SYMBOL_GPL(pmbus_check_word_register); | 326 | EXPORT_SYMBOL_GPL(pmbus_check_word_register); |
326 | 327 | ||
@@ -332,6 +333,19 @@ const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) | |||
332 | } | 333 | } |
333 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); | 334 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); |
334 | 335 | ||
336 | static struct _pmbus_status { | ||
337 | u32 func; | ||
338 | u16 base; | ||
339 | u16 reg; | ||
340 | } pmbus_status[] = { | ||
341 | { PMBUS_HAVE_STATUS_VOUT, PB_STATUS_VOUT_BASE, PMBUS_STATUS_VOUT }, | ||
342 | { PMBUS_HAVE_STATUS_IOUT, PB_STATUS_IOUT_BASE, PMBUS_STATUS_IOUT }, | ||
343 | { PMBUS_HAVE_STATUS_TEMP, PB_STATUS_TEMP_BASE, | ||
344 | PMBUS_STATUS_TEMPERATURE }, | ||
345 | { PMBUS_HAVE_STATUS_FAN12, PB_STATUS_FAN_BASE, PMBUS_STATUS_FAN_12 }, | ||
346 | { PMBUS_HAVE_STATUS_FAN34, PB_STATUS_FAN34_BASE, PMBUS_STATUS_FAN_34 }, | ||
347 | }; | ||
348 | |||
335 | static struct pmbus_data *pmbus_update_device(struct device *dev) | 349 | static struct pmbus_data *pmbus_update_device(struct device *dev) |
336 | { | 350 | { |
337 | struct i2c_client *client = to_i2c_client(dev); | 351 | struct i2c_client *client = to_i2c_client(dev); |
@@ -341,45 +355,21 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) | |||
341 | 355 | ||
342 | mutex_lock(&data->update_lock); | 356 | mutex_lock(&data->update_lock); |
343 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 357 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
344 | int i; | 358 | int i, j; |
345 | 359 | ||
346 | for (i = 0; i < info->pages; i++) | 360 | for (i = 0; i < info->pages; i++) { |
347 | data->status[PB_STATUS_BASE + i] | 361 | data->status[PB_STATUS_BASE + i] |
348 | = _pmbus_read_byte_data(client, i, | 362 | = _pmbus_read_byte_data(client, i, |
349 | data->status_register); | 363 | data->status_register); |
350 | for (i = 0; i < info->pages; i++) { | 364 | for (j = 0; j < ARRAY_SIZE(pmbus_status); j++) { |
351 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) | 365 | struct _pmbus_status *s = &pmbus_status[j]; |
352 | continue; | 366 | |
353 | data->status[PB_STATUS_VOUT_BASE + i] | 367 | if (!(info->func[i] & s->func)) |
354 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_VOUT); | 368 | continue; |
355 | } | 369 | data->status[s->base + i] |
356 | for (i = 0; i < info->pages; i++) { | 370 | = _pmbus_read_byte_data(client, i, |
357 | if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT)) | 371 | s->reg); |
358 | continue; | 372 | } |
359 | data->status[PB_STATUS_IOUT_BASE + i] | ||
360 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_IOUT); | ||
361 | } | ||
362 | for (i = 0; i < info->pages; i++) { | ||
363 | if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP)) | ||
364 | continue; | ||
365 | data->status[PB_STATUS_TEMP_BASE + i] | ||
366 | = _pmbus_read_byte_data(client, i, | ||
367 | PMBUS_STATUS_TEMPERATURE); | ||
368 | } | ||
369 | for (i = 0; i < info->pages; i++) { | ||
370 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12)) | ||
371 | continue; | ||
372 | data->status[PB_STATUS_FAN_BASE + i] | ||
373 | = _pmbus_read_byte_data(client, i, | ||
374 | PMBUS_STATUS_FAN_12); | ||
375 | } | ||
376 | |||
377 | for (i = 0; i < info->pages; i++) { | ||
378 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34)) | ||
379 | continue; | ||
380 | data->status[PB_STATUS_FAN34_BASE + i] | ||
381 | = _pmbus_read_byte_data(client, i, | ||
382 | PMBUS_STATUS_FAN_34); | ||
383 | } | 373 | } |
384 | 374 | ||
385 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) | 375 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) |
@@ -913,12 +903,12 @@ static int pmbus_add_label(struct pmbus_data *data, | |||
913 | */ | 903 | */ |
914 | struct pmbus_limit_attr { | 904 | struct pmbus_limit_attr { |
915 | u16 reg; /* Limit register */ | 905 | u16 reg; /* Limit register */ |
906 | u16 sbit; /* Alarm attribute status bit */ | ||
916 | bool update; /* True if register needs updates */ | 907 | bool update; /* True if register needs updates */ |
917 | bool low; /* True if low limit; for limits with compare | 908 | bool low; /* True if low limit; for limits with compare |
918 | functions only */ | 909 | functions only */ |
919 | const char *attr; /* Attribute name */ | 910 | const char *attr; /* Attribute name */ |
920 | const char *alarm; /* Alarm attribute name */ | 911 | const char *alarm; /* Alarm attribute name */ |
921 | u32 sbit; /* Alarm attribute status bit */ | ||
922 | }; | 912 | }; |
923 | 913 | ||
924 | /* | 914 | /* |
@@ -927,6 +917,8 @@ struct pmbus_limit_attr { | |||
927 | */ | 917 | */ |
928 | struct pmbus_sensor_attr { | 918 | struct pmbus_sensor_attr { |
929 | u16 reg; /* sensor register */ | 919 | u16 reg; /* sensor register */ |
920 | u8 gbit; /* generic status bit */ | ||
921 | u8 nlimit; /* # of limit registers */ | ||
930 | enum pmbus_sensor_classes class;/* sensor class */ | 922 | enum pmbus_sensor_classes class;/* sensor class */ |
931 | const char *label; /* sensor label */ | 923 | const char *label; /* sensor label */ |
932 | bool paged; /* true if paged sensor */ | 924 | bool paged; /* true if paged sensor */ |
@@ -935,9 +927,7 @@ struct pmbus_sensor_attr { | |||
935 | u32 func; /* sensor mask */ | 927 | u32 func; /* sensor mask */ |
936 | u32 sfunc; /* sensor status mask */ | 928 | u32 sfunc; /* sensor status mask */ |
937 | int sbase; /* status base register */ | 929 | int sbase; /* status base register */ |
938 | u32 gbit; /* generic status bit */ | ||
939 | const struct pmbus_limit_attr *limit;/* limit registers */ | 930 | const struct pmbus_limit_attr *limit;/* limit registers */ |
940 | int nlimit; /* # of limit registers */ | ||
941 | }; | 931 | }; |
942 | 932 | ||
943 | /* | 933 | /* |