aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/hp_accel.c10
-rw-r--r--drivers/hwmon/lis3lv02d.c88
-rw-r--r--drivers/hwmon/lis3lv02d.h5
3 files changed, 32 insertions, 71 deletions
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index abca7e9f953b..0ebd0099e602 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -324,7 +324,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
324 flush_work(&hpled_led.work); 324 flush_work(&hpled_led.work);
325 led_classdev_unregister(&hpled_led.led_classdev); 325 led_classdev_unregister(&hpled_led.led_classdev);
326 326
327 return lis3lv02d_remove_fs(); 327 return lis3lv02d_remove_fs(&lis3_dev);
328} 328}
329 329
330 330
@@ -338,13 +338,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
338 338
339static int lis3lv02d_resume(struct acpi_device *device) 339static int lis3lv02d_resume(struct acpi_device *device)
340{ 340{
341 /* put back the device in the right state (ACPI might turn it on) */ 341 lis3lv02d_poweron(&lis3_dev);
342 mutex_lock(&lis3_dev.lock);
343 if (lis3_dev.usage > 0)
344 lis3lv02d_poweron(&lis3_dev);
345 else
346 lis3lv02d_poweroff(&lis3_dev);
347 mutex_unlock(&lis3_dev.lock);
348 return 0; 342 return 0;
349} 343}
350#else 344#else
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);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 745ec96806d4..b007d8184212 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -171,14 +171,11 @@ struct lis3lv02d {
171 171
172 struct input_dev *idev; /* input device */ 172 struct input_dev *idev; /* input device */
173 struct task_struct *kthread; /* kthread for input */ 173 struct task_struct *kthread; /* kthread for input */
174 struct mutex lock;
175 struct platform_device *pdev; /* platform device */ 174 struct platform_device *pdev; /* platform device */
176 atomic_t count; /* interrupt count after last read */ 175 atomic_t count; /* interrupt count after last read */
177 int xcalib; /* calibrated null value for x */ 176 int xcalib; /* calibrated null value for x */
178 int ycalib; /* calibrated null value for y */ 177 int ycalib; /* calibrated null value for y */
179 int zcalib; /* calibrated null value for z */ 178 int zcalib; /* calibrated null value for z */
180 unsigned char is_on; /* whether the device is on or off */
181 unsigned char usage; /* usage counter */
182 struct axis_conversion ac; /* hw -> logical axis */ 179 struct axis_conversion ac; /* hw -> logical axis */
183 180
184 u32 irq; /* IRQ number */ 181 u32 irq; /* IRQ number */
@@ -192,6 +189,6 @@ int lis3lv02d_joystick_enable(void);
192void lis3lv02d_joystick_disable(void); 189void lis3lv02d_joystick_disable(void);
193void lis3lv02d_poweroff(struct lis3lv02d *lis3); 190void lis3lv02d_poweroff(struct lis3lv02d *lis3);
194void lis3lv02d_poweron(struct lis3lv02d *lis3); 191void lis3lv02d_poweron(struct lis3lv02d *lis3);
195int lis3lv02d_remove_fs(void); 192int lis3lv02d_remove_fs(struct lis3lv02d *lis3);
196 193
197extern struct lis3lv02d lis3_dev; 194extern struct lis3lv02d lis3_dev;