aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 11:01:39 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:39 -0400
commit84d19d92f78e10f8bdc1b3e1b5ddcaf5895edaf7 (patch)
tree821191576f79e2562e7bb79d130309133ee60e20
parent47ece9645f288d46420d64dab90a182bde87bbbb (diff)
hwmon: (nct6775) Add power management support
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/nct6775.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index ffb56bb8c27d..56d7652d303b 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -511,6 +511,12 @@ struct nct6775_data {
511 u16 have_temp; 511 u16 have_temp;
512 u16 have_temp_fixed; 512 u16 have_temp_fixed;
513 u16 have_in; 513 u16 have_in;
514#ifdef CONFIG_PM
515 /* Remember extra register values over suspend/resume */
516 u8 vbat;
517 u8 fandiv1;
518 u8 fandiv2;
519#endif
514}; 520};
515 521
516struct nct6775_sio_data { 522struct nct6775_sio_data {
@@ -2270,10 +2276,90 @@ static int nct6775_remove(struct platform_device *pdev)
2270 return 0; 2276 return 0;
2271} 2277}
2272 2278
2279#ifdef CONFIG_PM
2280static int nct6775_suspend(struct device *dev)
2281{
2282 struct nct6775_data *data = nct6775_update_device(dev);
2283 struct nct6775_sio_data *sio_data = dev->platform_data;
2284
2285 mutex_lock(&data->update_lock);
2286 data->vbat = nct6775_read_value(data, data->REG_VBAT);
2287 if (sio_data->kind == nct6775) {
2288 data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
2289 data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
2290 }
2291 mutex_unlock(&data->update_lock);
2292
2293 return 0;
2294}
2295
2296static int nct6775_resume(struct device *dev)
2297{
2298 struct nct6775_data *data = dev_get_drvdata(dev);
2299 struct nct6775_sio_data *sio_data = dev->platform_data;
2300 int i, j;
2301
2302 mutex_lock(&data->update_lock);
2303 data->bank = 0xff; /* Force initial bank selection */
2304
2305 /* Restore limits */
2306 for (i = 0; i < data->in_num; i++) {
2307 if (!(data->have_in & (1 << i)))
2308 continue;
2309
2310 nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
2311 data->in[i][1]);
2312 nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
2313 data->in[i][2]);
2314 }
2315
2316 for (i = 0; i < 5; i++) {
2317 if (!(data->has_fan_min & (1 << i)))
2318 continue;
2319
2320 nct6775_write_value(data, data->REG_FAN_MIN[i],
2321 data->fan_min[i]);
2322 }
2323
2324 for (i = 0; i < NUM_TEMP; i++) {
2325 if (!(data->have_temp & (1 << i)))
2326 continue;
2327
2328 for (j = 1; j < 4; j++)
2329 if (data->reg_temp[j][i])
2330 nct6775_write_temp(data, data->reg_temp[j][i],
2331 data->temp[j][i]);
2332 }
2333
2334 /* Restore other settings */
2335 nct6775_write_value(data, data->REG_VBAT, data->vbat);
2336 if (sio_data->kind == nct6775) {
2337 nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
2338 nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
2339 }
2340
2341 /* Force re-reading all values */
2342 data->valid = false;
2343 mutex_unlock(&data->update_lock);
2344
2345 return 0;
2346}
2347
2348static const struct dev_pm_ops nct6775_dev_pm_ops = {
2349 .suspend = nct6775_suspend,
2350 .resume = nct6775_resume,
2351};
2352
2353#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops)
2354#else
2355#define NCT6775_DEV_PM_OPS NULL
2356#endif /* CONFIG_PM */
2357
2273static struct platform_driver nct6775_driver = { 2358static struct platform_driver nct6775_driver = {
2274 .driver = { 2359 .driver = {
2275 .owner = THIS_MODULE, 2360 .owner = THIS_MODULE,
2276 .name = DRVNAME, 2361 .name = DRVNAME,
2362 .pm = NCT6775_DEV_PM_OPS,
2277 }, 2363 },
2278 .probe = nct6775_probe, 2364 .probe = nct6775_probe,
2279 .remove = nct6775_remove, 2365 .remove = nct6775_remove,