aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lis3lv02d.c
diff options
context:
space:
mode:
authorEric Piel <eric.piel@tremplin-utc.net>2009-06-16 18:34:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 22:47:57 -0400
commita002ee896dfd08ce9fba44e9ae513c9094699a27 (patch)
tree3a66ea80ad5523359e3f3f34be39d902d84706bb /drivers/hwmon/lis3lv02d.c
parentc28842421cb6a29fd952043381bc5391bdf6be50 (diff)
lis3: remove automatic shutdown of the device
After measurement on my laptop, it seems that turning off the device does not bring any energy saving (within 0.1W precision). So let's keep the device always on. It simplifies the code, and it avoids the problem of reading a wrong value sometimes just after turning the device on. Moreover, since commit ef2cfc790bf5f0ff189b01eabc0f4feb5e8524df had been too zealous, the device was actually never turned off anyway. This patch also restores the damages done by this commit concerning the initialisation/poweroff. Also do more clean up with the usage of the lis3_dev global variable. Signed-off-by: Eric Piel <eric.piel@tremplin-utc.net> Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/lis3lv02d.c')
-rw-r--r--drivers/hwmon/lis3lv02d.c88
1 files changed, 29 insertions, 59 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 17f200341bc1..df3f58613f7b 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -105,56 +105,39 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
105{ 105{
106 int position[3]; 106 int position[3];
107 107
108 position[0] = lis3_dev.read_data(lis3, OUTX); 108 position[0] = lis3->read_data(lis3, OUTX);
109 position[1] = lis3_dev.read_data(lis3, OUTY); 109 position[1] = lis3->read_data(lis3, OUTY);
110 position[2] = lis3_dev.read_data(lis3, OUTZ); 110 position[2] = lis3->read_data(lis3, OUTZ);
111 111
112 *x = lis3lv02d_get_axis(lis3_dev.ac.x, position); 112 *x = lis3lv02d_get_axis(lis3->ac.x, position);
113 *y = lis3lv02d_get_axis(lis3_dev.ac.y, position); 113 *y = lis3lv02d_get_axis(lis3->ac.y, position);
114 *z = lis3lv02d_get_axis(lis3_dev.ac.z, position); 114 *z = lis3lv02d_get_axis(lis3->ac.z, position);
115} 115}
116 116
117void lis3lv02d_poweroff(struct lis3lv02d *lis3) 117void lis3lv02d_poweroff(struct lis3lv02d *lis3)
118{ 118{
119 lis3_dev.is_on = 0; 119 /* disable X,Y,Z axis and power down */
120 lis3->write(lis3, CTRL_REG1, 0x00);
120} 121}
121EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); 122EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
122 123
123void lis3lv02d_poweron(struct lis3lv02d *lis3) 124void lis3lv02d_poweron(struct lis3lv02d *lis3)
124{ 125{
125 lis3_dev.is_on = 1; 126 u8 reg;
126 lis3_dev.init(lis3);
127}
128EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
129 127
130/* 128 lis3->init(lis3);
131 * To be called before starting to use the device. It makes sure that the
132 * device will always be on until a call to lis3lv02d_decrease_use(). Not to be
133 * used from interrupt context.
134 */
135static void lis3lv02d_increase_use(struct lis3lv02d *dev)
136{
137 mutex_lock(&dev->lock);
138 dev->usage++;
139 if (dev->usage == 1) {
140 if (!dev->is_on)
141 lis3lv02d_poweron(dev);
142 }
143 mutex_unlock(&dev->lock);
144}
145 129
146/* 130 /*
147 * To be called whenever a usage of the device is stopped. 131 * Common configuration
148 * It will make sure to turn off the device when there is not usage. 132 * BDU: LSB and MSB values are not updated until both have been read.
149 */ 133 * So the value read will always be correct.
150static void lis3lv02d_decrease_use(struct lis3lv02d *dev) 134 */
151{ 135 lis3->read(lis3, CTRL_REG2, &reg);
152 mutex_lock(&dev->lock); 136 reg |= CTRL2_BDU;
153 dev->usage--; 137 lis3->write(lis3, CTRL_REG2, reg);
154 if (dev->usage == 0)
155 lis3lv02d_poweroff(dev);
156 mutex_unlock(&dev->lock);
157} 138}
139EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
140
158 141
159static irqreturn_t lis302dl_interrupt(int irq, void *dummy) 142static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
160{ 143{
@@ -198,14 +181,12 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
198 printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); 181 printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq);
199 return -EBUSY; 182 return -EBUSY;
200 } 183 }
201 lis3lv02d_increase_use(&lis3_dev);
202 return 0; 184 return 0;
203} 185}
204 186
205static int lis3lv02d_misc_release(struct inode *inode, struct file *file) 187static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
206{ 188{
207 fasync_helper(-1, file, 0, &lis3_dev.async_queue); 189 fasync_helper(-1, file, 0, &lis3_dev.async_queue);
208 lis3lv02d_decrease_use(&lis3_dev);
209 free_irq(lis3_dev.irq, &lis3_dev); 190 free_irq(lis3_dev.irq, &lis3_dev);
210 clear_bit(0, &lis3_dev.misc_opened); /* release the device */ 191 clear_bit(0, &lis3_dev.misc_opened); /* release the device */
211 return 0; 192 return 0;
@@ -314,10 +295,8 @@ static int lis3lv02d_joystick_kthread(void *data)
314 295
315static int lis3lv02d_joystick_open(struct input_dev *input) 296static int lis3lv02d_joystick_open(struct input_dev *input)
316{ 297{
317 lis3lv02d_increase_use(&lis3_dev);
318 lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); 298 lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
319 if (IS_ERR(lis3_dev.kthread)) { 299 if (IS_ERR(lis3_dev.kthread)) {
320 lis3lv02d_decrease_use(&lis3_dev);
321 return PTR_ERR(lis3_dev.kthread); 300 return PTR_ERR(lis3_dev.kthread);
322 } 301 }
323 302
@@ -327,7 +306,6 @@ static int lis3lv02d_joystick_open(struct input_dev *input)
327static void lis3lv02d_joystick_close(struct input_dev *input) 306static void lis3lv02d_joystick_close(struct input_dev *input)
328{ 307{
329 kthread_stop(lis3_dev.kthread); 308 kthread_stop(lis3_dev.kthread);
330 lis3lv02d_decrease_use(&lis3_dev);
331} 309}
332 310
333static inline void lis3lv02d_calibrate_joystick(void) 311static inline void lis3lv02d_calibrate_joystick(void)
@@ -390,9 +368,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
390{ 368{
391 int x, y, z; 369 int x, y, z;
392 370
393 lis3lv02d_increase_use(&lis3_dev);
394 lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); 371 lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
395 lis3lv02d_decrease_use(&lis3_dev);
396 return sprintf(buf, "(%d,%d,%d)\n", x, y, z); 372 return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
397} 373}
398 374
@@ -406,9 +382,7 @@ static ssize_t lis3lv02d_calibrate_store(struct device *dev,
406 struct device_attribute *attr, 382 struct device_attribute *attr,
407 const char *buf, size_t count) 383 const char *buf, size_t count)
408{ 384{
409 lis3lv02d_increase_use(&lis3_dev);
410 lis3lv02d_calibrate_joystick(); 385 lis3lv02d_calibrate_joystick();
411 lis3lv02d_decrease_use(&lis3_dev);
412 return count; 386 return count;
413} 387}
414 388
@@ -420,9 +394,7 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
420 u8 ctrl; 394 u8 ctrl;
421 int val; 395 int val;
422 396
423 lis3lv02d_increase_use(&lis3_dev);
424 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); 397 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
425 lis3lv02d_decrease_use(&lis3_dev);
426 val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; 398 val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
427 return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); 399 return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
428} 400}
@@ -446,17 +418,17 @@ static struct attribute_group lis3lv02d_attribute_group = {
446 418
447static int lis3lv02d_add_fs(struct lis3lv02d *lis3) 419static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
448{ 420{
449 lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); 421 lis3->pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
450 if (IS_ERR(lis3_dev.pdev)) 422 if (IS_ERR(lis3->pdev))
451 return PTR_ERR(lis3_dev.pdev); 423 return PTR_ERR(lis3->pdev);
452 424
453 return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); 425 return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
454} 426}
455 427
456int lis3lv02d_remove_fs(void) 428int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
457{ 429{
458 sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); 430 sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
459 platform_device_unregister(lis3_dev.pdev); 431 platform_device_unregister(lis3->pdev);
460 return 0; 432 return 0;
461} 433}
462EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); 434EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -482,13 +454,12 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
482 break; 454 break;
483 default: 455 default:
484 printk(KERN_ERR DRIVER_NAME 456 printk(KERN_ERR DRIVER_NAME
485 ": unknown sensor type 0x%X\n", lis3_dev.whoami); 457 ": unknown sensor type 0x%X\n", dev->whoami);
486 return -EINVAL; 458 return -EINVAL;
487 } 459 }
488 460
489 mutex_init(&dev->lock);
490 lis3lv02d_add_fs(dev); 461 lis3lv02d_add_fs(dev);
491 lis3lv02d_increase_use(dev); 462 lis3lv02d_poweron(dev);
492 463
493 if (lis3lv02d_joystick_enable()) 464 if (lis3lv02d_joystick_enable())
494 printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); 465 printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
@@ -503,7 +474,6 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
503 if (misc_register(&lis3lv02d_misc_device)) 474 if (misc_register(&lis3lv02d_misc_device))
504 printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); 475 printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
505out: 476out:
506 lis3lv02d_decrease_use(dev);
507 return 0; 477 return 0;
508} 478}
509EXPORT_SYMBOL_GPL(lis3lv02d_init_device); 479EXPORT_SYMBOL_GPL(lis3lv02d_init_device);