aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lis3lv02d_i2c.c
diff options
context:
space:
mode:
authorSamu Onkalo <samu.p.onkalo@nokia.com>2010-10-22 07:57:23 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2010-10-25 17:11:38 -0400
commit2a346996626ecbb4269c239e9ff7372a182907e9 (patch)
tree9e1cd9d3f2a44e6dfaae7726613c0c13f2ab33e5 /drivers/hwmon/lis3lv02d_i2c.c
parent0ab83a7ce5c566b84d492d598dc64a19bfaef9ab (diff)
hwmon: lis3: pm_runtime support
Add pm_runtime support to lis3 core driver. Add pm_runtime support to lis3 i2c driver. spi and hp_accel drivers are not yet supported. Old always on functionality remains for those. For sysfs there is 5 second delay before turning off the chip to avoid long ramp up delay. Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com> Acked-by: Jonathan Cameron <jic23@cam.ac.uk> Acked-by: Eric Piel <eric.piel@tremplin-utc.net> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/lis3lv02d_i2c.c')
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index c6f3f341127..d52095603e0 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -29,6 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/pm_runtime.h>
32#include "lis3lv02d.h" 33#include "lis3lv02d.h"
33 34
34#define DRV_NAME "lis3lv02d_i2c" 35#define DRV_NAME "lis3lv02d_i2c"
@@ -94,6 +95,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
94 lis3_dev.write = lis3_i2c_write; 95 lis3_dev.write = lis3_i2c_write;
95 lis3_dev.irq = client->irq; 96 lis3_dev.irq = client->irq;
96 lis3_dev.ac = lis3lv02d_axis_map; 97 lis3_dev.ac = lis3lv02d_axis_map;
98 lis3_dev.pm_dev = &client->dev;
97 99
98 i2c_set_clientdata(client, &lis3_dev); 100 i2c_set_clientdata(client, &lis3_dev);
99 ret = lis3lv02d_init_device(&lis3_dev); 101 ret = lis3lv02d_init_device(&lis3_dev);
@@ -103,21 +105,20 @@ fail:
103 105
104static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) 106static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
105{ 107{
106 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
107 struct lis3lv02d_platform_data *pdata = client->dev.platform_data; 108 struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
108 109
109 if (pdata && pdata->release_resources) 110 if (pdata && pdata->release_resources)
110 pdata->release_resources(); 111 pdata->release_resources();
111 112
112 lis3lv02d_joystick_disable(); 113 lis3lv02d_joystick_disable();
113 lis3lv02d_poweroff(lis3);
114 114
115 return lis3lv02d_remove_fs(&lis3_dev); 115 return lis3lv02d_remove_fs(&lis3_dev);
116} 116}
117 117
118#ifdef CONFIG_PM 118#ifdef CONFIG_PM
119static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 119static int lis3lv02d_i2c_suspend(struct device *dev)
120{ 120{
121 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
121 struct lis3lv02d *lis3 = i2c_get_clientdata(client); 122 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
122 123
123 if (!lis3->pdata || !lis3->pdata->wakeup_flags) 124 if (!lis3->pdata || !lis3->pdata->wakeup_flags)
@@ -125,18 +126,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
125 return 0; 126 return 0;
126} 127}
127 128
128static int lis3lv02d_i2c_resume(struct i2c_client *client) 129static int lis3lv02d_i2c_resume(struct device *dev)
129{ 130{
131 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
130 struct lis3lv02d *lis3 = i2c_get_clientdata(client); 132 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
131 133
132 if (!lis3->pdata || !lis3->pdata->wakeup_flags) 134 /*
135 * pm_runtime documentation says that devices should always
136 * be powered on at resume. Pm_runtime turns them off after system
137 * wide resume is complete.
138 */
139 if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
140 pm_runtime_suspended(dev))
133 lis3lv02d_poweron(lis3); 141 lis3lv02d_poweron(lis3);
134 return 0;
135}
136 142
137static void lis3lv02d_i2c_shutdown(struct i2c_client *client) 143 return 0;
138{
139 lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
140} 144}
141#else 145#else
142#define lis3lv02d_i2c_suspend NULL 146#define lis3lv02d_i2c_suspend NULL
@@ -144,6 +148,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
144#define lis3lv02d_i2c_shutdown NULL 148#define lis3lv02d_i2c_shutdown NULL
145#endif 149#endif
146 150
151static int lis3_i2c_runtime_suspend(struct device *dev)
152{
153 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
154 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
155
156 lis3lv02d_poweroff(lis3);
157 return 0;
158}
159
160static int lis3_i2c_runtime_resume(struct device *dev)
161{
162 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
163 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
164
165 lis3lv02d_poweron(lis3);
166 return 0;
167}
168
147static const struct i2c_device_id lis3lv02d_id[] = { 169static const struct i2c_device_id lis3lv02d_id[] = {
148 {"lis3lv02d", 0 }, 170 {"lis3lv02d", 0 },
149 {} 171 {}
@@ -151,14 +173,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
151 173
152MODULE_DEVICE_TABLE(i2c, lis3lv02d_id); 174MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
153 175
176static const struct dev_pm_ops lis3_pm_ops = {
177 SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
178 lis3lv02d_i2c_resume)
179 SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
180 lis3_i2c_runtime_resume,
181 NULL)
182};
183
154static struct i2c_driver lis3lv02d_i2c_driver = { 184static struct i2c_driver lis3lv02d_i2c_driver = {
155 .driver = { 185 .driver = {
156 .name = DRV_NAME, 186 .name = DRV_NAME,
157 .owner = THIS_MODULE, 187 .owner = THIS_MODULE,
188 .pm = &lis3_pm_ops,
158 }, 189 },
159 .suspend = lis3lv02d_i2c_suspend,
160 .shutdown = lis3lv02d_i2c_shutdown,
161 .resume = lis3lv02d_i2c_resume,
162 .probe = lis3lv02d_i2c_probe, 190 .probe = lis3lv02d_i2c_probe,
163 .remove = __devexit_p(lis3lv02d_i2c_remove), 191 .remove = __devexit_p(lis3lv02d_i2c_remove),
164 .id_table = lis3lv02d_id, 192 .id_table = lis3lv02d_id,