All of lore.kernel.org
 help / color / mirror / Atom feed
* [lm-sensors] [PATCH v2] hwmon: (w83627ehf) Add support for suspend
@ 2012-10-26  7:46 Jean Delvare
  2012-10-26 13:57 ` Guenter Roeck
  0 siblings, 1 reply; 2+ messages in thread
From: Jean Delvare @ 2012-10-26  7:46 UTC (permalink / raw)
  To: lm-sensors

On suspend some register values are lost, most notably the Value RAM
areas but also other limits and settings. Restore them on resume.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
---
Changes since v1:
 * Force initial bank selection at resume. Thanks Guenter :)

I also updated the driver at:
  http://khali.linux-fr.org/devel/misc/w83627ehf/

 drivers/hwmon/w83627ehf.c |   95 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)

--- linux-3.7-rc2.orig/drivers/hwmon/w83627ehf.c	2012-10-26 09:34:04.028295469 +0200
+++ linux-3.7-rc2/drivers/hwmon/w83627ehf.c	2012-10-26 09:40:28.102773093 +0200
@@ -1,7 +1,7 @@
 /*
  *  w83627ehf - Driver for the hardware monitoring functionality of
  *		the Winbond W83627EHF Super-I/O chip
- *  Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
+ *  Copyright (C) 2005-2012  Jean Delvare <khali@linux-fr.org>
  *  Copyright (C) 2006  Yuan Mu (Winbond),
  *			Rudolf Marek <r.marek@assembler.cz>
  *			David Hubbard <david.c.hubbard@gmail.com>
@@ -502,6 +502,13 @@ struct w83627ehf_data {
 	u16 have_temp_offset;
 	u8 in6_skip:1;
 	u8 temp3_val_only:1;
+
+#ifdef CONFIG_PM
+	/* Remember extra register values over suspend/resume */
+	u8 vbat;
+	u8 fandiv1;
+	u8 fandiv2;
+#endif
 };
 
 struct w83627ehf_sio_data {
@@ -2608,10 +2615,96 @@ static int __devexit w83627ehf_remove(st
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int w83627ehf_suspend(struct device *dev)
+{
+	struct w83627ehf_data *data = w83627ehf_update_device(dev);
+	struct w83627ehf_sio_data *sio_data = dev->platform_data;
+
+	mutex_lock(&data->update_lock);
+	data->vbat = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
+	if (sio_data->kind = nct6775) {
+		data->fandiv1 = w83627ehf_read_value(data, NCT6775_REG_FANDIV1);
+		data->fandiv2 = w83627ehf_read_value(data, NCT6775_REG_FANDIV2);
+	}
+	mutex_unlock(&data->update_lock);
+
+	return 0;
+}
+
+static int w83627ehf_resume(struct device *dev)
+{
+	struct w83627ehf_data *data = dev_get_drvdata(dev);
+	struct w83627ehf_sio_data *sio_data = dev->platform_data;
+	int i;
+
+	mutex_lock(&data->update_lock);
+	data->bank = 0xff;		/* Force initial bank selection */
+
+	/* Restore limits */
+	for (i = 0; i < data->in_num; i++) {
+		if ((i = 6) && data->in6_skip)
+			continue;
+
+		w83627ehf_write_value(data, W83627EHF_REG_IN_MIN(i),
+				      data->in_min[i]);
+		w83627ehf_write_value(data, W83627EHF_REG_IN_MAX(i),
+				      data->in_max[i]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		if (!(data->has_fan_min & (1 << i)))
+			continue;
+
+		w83627ehf_write_value(data, data->REG_FAN_MIN[i],
+				      data->fan_min[i]);
+	}
+
+	for (i = 0; i < NUM_REG_TEMP; i++) {
+		if (!(data->have_temp & (1 << i)))
+			continue;
+
+		if (data->reg_temp_over[i])
+			w83627ehf_write_temp(data, data->reg_temp_over[i],
+					     data->temp_max[i]);
+		if (data->reg_temp_hyst[i])
+			w83627ehf_write_temp(data, data->reg_temp_hyst[i],
+					     data->temp_max_hyst[i]);
+		if (data->have_temp_offset & (1 << i))
+			w83627ehf_write_value(data,
+					      W83627EHF_REG_TEMP_OFFSET[i],
+					      data->temp_offset[i]);
+	}
+
+	/* Restore other settings */
+	w83627ehf_write_value(data, W83627EHF_REG_VBAT, data->vbat);
+	if (sio_data->kind = nct6775) {
+		w83627ehf_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
+		w83627ehf_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
+	}
+
+	/* Force re-reading all values */
+	data->valid = 0;
+	mutex_unlock(&data->update_lock);
+
+	return 0;
+}
+
+static const struct dev_pm_ops w83627ehf_dev_pm_ops = {
+	.suspend = w83627ehf_suspend,
+	.resume = w83627ehf_resume,
+};
+
+#define W83627EHF_DEV_PM_OPS	(&w83627ehf_dev_pm_ops)
+#else
+#define W83627EHF_DEV_PM_OPS	NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver w83627ehf_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
 		.name	= DRVNAME,
+		.pm	= W83627EHF_DEV_PM_OPS,
 	},
 	.probe		= w83627ehf_probe,
 	.remove		= __devexit_p(w83627ehf_remove),


-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [lm-sensors] [PATCH v2] hwmon: (w83627ehf) Add support for suspend
  2012-10-26  7:46 [lm-sensors] [PATCH v2] hwmon: (w83627ehf) Add support for suspend Jean Delvare
@ 2012-10-26 13:57 ` Guenter Roeck
  0 siblings, 0 replies; 2+ messages in thread
From: Guenter Roeck @ 2012-10-26 13:57 UTC (permalink / raw)
  To: lm-sensors

On Fri, Oct 26, 2012 at 09:46:23AM +0200, Jean Delvare wrote:
> On suspend some register values are lost, most notably the Value RAM
> areas but also other limits and settings. Restore them on resume.
> 
> Signed-off-by: Jean Delvare <khali@linux-fr.org>

Reviewed-and-Tested-by: Guenter Roeck <linux@roeck-us.net>

> ---
> Changes since v1:
>  * Force initial bank selection at resume. Thanks Guenter :)
> 
> I also updated the driver at:
>   http://khali.linux-fr.org/devel/misc/w83627ehf/
> 
>  drivers/hwmon/w83627ehf.c |   95 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 94 insertions(+), 1 deletion(-)
> 
> --- linux-3.7-rc2.orig/drivers/hwmon/w83627ehf.c	2012-10-26 09:34:04.028295469 +0200
> +++ linux-3.7-rc2/drivers/hwmon/w83627ehf.c	2012-10-26 09:40:28.102773093 +0200
> @@ -1,7 +1,7 @@
>  /*
>   *  w83627ehf - Driver for the hardware monitoring functionality of
>   *		the Winbond W83627EHF Super-I/O chip
> - *  Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
> + *  Copyright (C) 2005-2012  Jean Delvare <khali@linux-fr.org>
>   *  Copyright (C) 2006  Yuan Mu (Winbond),
>   *			Rudolf Marek <r.marek@assembler.cz>
>   *			David Hubbard <david.c.hubbard@gmail.com>
> @@ -502,6 +502,13 @@ struct w83627ehf_data {
>  	u16 have_temp_offset;
>  	u8 in6_skip:1;
>  	u8 temp3_val_only:1;
> +
> +#ifdef CONFIG_PM
> +	/* Remember extra register values over suspend/resume */
> +	u8 vbat;
> +	u8 fandiv1;
> +	u8 fandiv2;
> +#endif
>  };
>  
>  struct w83627ehf_sio_data {
> @@ -2608,10 +2615,96 @@ static int __devexit w83627ehf_remove(st
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int w83627ehf_suspend(struct device *dev)
> +{
> +	struct w83627ehf_data *data = w83627ehf_update_device(dev);
> +	struct w83627ehf_sio_data *sio_data = dev->platform_data;
> +
> +	mutex_lock(&data->update_lock);
> +	data->vbat = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
> +	if (sio_data->kind = nct6775) {
> +		data->fandiv1 = w83627ehf_read_value(data, NCT6775_REG_FANDIV1);
> +		data->fandiv2 = w83627ehf_read_value(data, NCT6775_REG_FANDIV2);
> +	}
> +	mutex_unlock(&data->update_lock);
> +
> +	return 0;
> +}
> +
> +static int w83627ehf_resume(struct device *dev)
> +{
> +	struct w83627ehf_data *data = dev_get_drvdata(dev);
> +	struct w83627ehf_sio_data *sio_data = dev->platform_data;
> +	int i;
> +
> +	mutex_lock(&data->update_lock);
> +	data->bank = 0xff;		/* Force initial bank selection */
> +
> +	/* Restore limits */
> +	for (i = 0; i < data->in_num; i++) {
> +		if ((i = 6) && data->in6_skip)
> +			continue;
> +
> +		w83627ehf_write_value(data, W83627EHF_REG_IN_MIN(i),
> +				      data->in_min[i]);
> +		w83627ehf_write_value(data, W83627EHF_REG_IN_MAX(i),
> +				      data->in_max[i]);
> +	}
> +
> +	for (i = 0; i < 5; i++) {
> +		if (!(data->has_fan_min & (1 << i)))
> +			continue;
> +
> +		w83627ehf_write_value(data, data->REG_FAN_MIN[i],
> +				      data->fan_min[i]);
> +	}
> +
> +	for (i = 0; i < NUM_REG_TEMP; i++) {
> +		if (!(data->have_temp & (1 << i)))
> +			continue;
> +
> +		if (data->reg_temp_over[i])
> +			w83627ehf_write_temp(data, data->reg_temp_over[i],
> +					     data->temp_max[i]);
> +		if (data->reg_temp_hyst[i])
> +			w83627ehf_write_temp(data, data->reg_temp_hyst[i],
> +					     data->temp_max_hyst[i]);
> +		if (data->have_temp_offset & (1 << i))
> +			w83627ehf_write_value(data,
> +					      W83627EHF_REG_TEMP_OFFSET[i],
> +					      data->temp_offset[i]);
> +	}
> +
> +	/* Restore other settings */
> +	w83627ehf_write_value(data, W83627EHF_REG_VBAT, data->vbat);
> +	if (sio_data->kind = nct6775) {
> +		w83627ehf_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
> +		w83627ehf_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
> +	}
> +
> +	/* Force re-reading all values */
> +	data->valid = 0;
> +	mutex_unlock(&data->update_lock);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops w83627ehf_dev_pm_ops = {
> +	.suspend = w83627ehf_suspend,
> +	.resume = w83627ehf_resume,
> +};
> +
> +#define W83627EHF_DEV_PM_OPS	(&w83627ehf_dev_pm_ops)
> +#else
> +#define W83627EHF_DEV_PM_OPS	NULL
> +#endif /* CONFIG_PM */
> +
>  static struct platform_driver w83627ehf_driver = {
>  	.driver = {
>  		.owner	= THIS_MODULE,
>  		.name	= DRVNAME,
> +		.pm	= W83627EHF_DEV_PM_OPS,
>  	},
>  	.probe		= w83627ehf_probe,
>  	.remove		= __devexit_p(w83627ehf_remove),
> 
> 
> -- 
> Jean Delvare
> 
> _______________________________________________
> lm-sensors mailing list
> lm-sensors@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
> 

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-10-26 13:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-26  7:46 [lm-sensors] [PATCH v2] hwmon: (w83627ehf) Add support for suspend Jean Delvare
2012-10-26 13:57 ` Guenter Roeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.