aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83627hf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/w83627hf.c')
-rw-r--r--drivers/hwmon/w83627hf.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 7f68b8309d10..81f486520cea 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -5,7 +5,7 @@
5 * Philip Edelbrock <phil@netroedge.com>, 5 * Philip Edelbrock <phil@netroedge.com>,
6 * and Mark Studebaker <mdsxyz123@yahoo.com> 6 * and Mark Studebaker <mdsxyz123@yahoo.com>
7 * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> 7 * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
8 * Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> 8 * Copyright (c) 2007 - 1012 Jean Delvare <khali@linux-fr.org>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -389,6 +389,12 @@ struct w83627hf_data {
389 */ 389 */
390 u8 vrm; 390 u8 vrm;
391 u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ 391 u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */
392
393#ifdef CONFIG_PM
394 /* Remember extra register values over suspend/resume */
395 u8 scfg1;
396 u8 scfg2;
397#endif
392}; 398};
393 399
394 400
@@ -401,10 +407,77 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data);
401static struct w83627hf_data *w83627hf_update_device(struct device *dev); 407static struct w83627hf_data *w83627hf_update_device(struct device *dev);
402static void w83627hf_init_device(struct platform_device *pdev); 408static void w83627hf_init_device(struct platform_device *pdev);
403 409
410#ifdef CONFIG_PM
411static int w83627hf_suspend(struct device *dev)
412{
413 struct w83627hf_data *data = w83627hf_update_device(dev);
414
415 mutex_lock(&data->update_lock);
416 data->scfg1 = w83627hf_read_value(data, W83781D_REG_SCFG1);
417 data->scfg2 = w83627hf_read_value(data, W83781D_REG_SCFG2);
418 mutex_unlock(&data->update_lock);
419
420 return 0;
421}
422
423static int w83627hf_resume(struct device *dev)
424{
425 struct w83627hf_data *data = dev_get_drvdata(dev);
426 int i, num_temps = (data->type == w83697hf) ? 2 : 3;
427
428 /* Restore limits */
429 mutex_lock(&data->update_lock);
430 for (i = 0; i <= 8; i++) {
431 /* skip missing sensors */
432 if (((data->type == w83697hf) && (i == 1)) ||
433 ((data->type != w83627hf && data->type != w83697hf)
434 && (i == 5 || i == 6)))
435 continue;
436 w83627hf_write_value(data, W83781D_REG_IN_MAX(i),
437 data->in_max[i]);
438 w83627hf_write_value(data, W83781D_REG_IN_MIN(i),
439 data->in_min[i]);
440 }
441 for (i = 0; i <= 2; i++)
442 w83627hf_write_value(data, W83627HF_REG_FAN_MIN(i),
443 data->fan_min[i]);
444 for (i = 0; i < num_temps; i++) {
445 w83627hf_write_value(data, w83627hf_reg_temp_over[i],
446 data->temp_max[i]);
447 w83627hf_write_value(data, w83627hf_reg_temp_hyst[i],
448 data->temp_max_hyst[i]);
449 }
450
451 /* Fixup BIOS bugs */
452 if (data->type == w83627thf || data->type == w83637hf ||
453 data->type == w83687thf)
454 w83627hf_write_value(data, W83627THF_REG_VRM_OVT_CFG,
455 data->vrm_ovt);
456 w83627hf_write_value(data, W83781D_REG_SCFG1, data->scfg1);
457 w83627hf_write_value(data, W83781D_REG_SCFG2, data->scfg2);
458
459 /* Force re-reading all values */
460 data->valid = 0;
461 mutex_unlock(&data->update_lock);
462
463 return 0;
464}
465
466static const struct dev_pm_ops w83627hf_dev_pm_ops = {
467 .suspend = w83627hf_suspend,
468 .resume = w83627hf_resume,
469};
470
471#define W83627HF_DEV_PM_OPS (&w83627hf_dev_pm_ops)
472#else
473#define W83627HF_DEV_PM_OPS NULL
474#endif /* CONFIG_PM */
475
404static struct platform_driver w83627hf_driver = { 476static struct platform_driver w83627hf_driver = {
405 .driver = { 477 .driver = {
406 .owner = THIS_MODULE, 478 .owner = THIS_MODULE,
407 .name = DRVNAME, 479 .name = DRVNAME,
480 .pm = W83627HF_DEV_PM_OPS,
408 }, 481 },
409 .probe = w83627hf_probe, 482 .probe = w83627hf_probe,
410 .remove = w83627hf_remove, 483 .remove = w83627hf_remove,
@@ -1659,8 +1732,10 @@ static void w83627hf_init_device(struct platform_device *pdev)
1659 /* Minimize conflicts with other winbond i2c-only clients... */ 1732 /* Minimize conflicts with other winbond i2c-only clients... */
1660 /* disable i2c subclients... how to disable main i2c client?? */ 1733 /* disable i2c subclients... how to disable main i2c client?? */
1661 /* force i2c address to relatively uncommon address */ 1734 /* force i2c address to relatively uncommon address */
1662 w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); 1735 if (type == w83627hf) {
1663 w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); 1736 w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89);
1737 w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c);
1738 }
1664 1739
1665 /* Read VID only once */ 1740 /* Read VID only once */
1666 if (type == w83627hf || type == w83637hf) { 1741 if (type == w83627hf || type == w83637hf) {