aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/hdaps.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 7636c1a58f9c..1659f6c41458 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -33,7 +33,6 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/timer.h> 34#include <linux/timer.h>
35#include <linux/dmi.h> 35#include <linux/dmi.h>
36#include <linux/mutex.h>
37#include <asm/io.h> 36#include <asm/io.h>
38 37
39#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ 38#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@@ -71,10 +70,10 @@ static u8 km_activity;
71static int rest_x; 70static int rest_x;
72static int rest_y; 71static int rest_y;
73 72
74static DEFINE_MUTEX(hdaps_mutex); 73static DECLARE_MUTEX(hdaps_sem);
75 74
76/* 75/*
77 * __get_latch - Get the value from a given port. Callers must hold hdaps_mutex. 76 * __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
78 */ 77 */
79static inline u8 __get_latch(u16 port) 78static inline u8 __get_latch(u16 port)
80{ 79{
@@ -83,7 +82,7 @@ static inline u8 __get_latch(u16 port)
83 82
84/* 83/*
85 * __check_latch - Check a port latch for a given value. Returns zero if the 84 * __check_latch - Check a port latch for a given value. Returns zero if the
86 * port contains the given value. Callers must hold hdaps_mutex. 85 * port contains the given value. Callers must hold hdaps_sem.
87 */ 86 */
88static inline int __check_latch(u16 port, u8 val) 87static inline int __check_latch(u16 port, u8 val)
89{ 88{
@@ -94,7 +93,7 @@ static inline int __check_latch(u16 port, u8 val)
94 93
95/* 94/*
96 * __wait_latch - Wait up to 100us for a port latch to get a certain value, 95 * __wait_latch - Wait up to 100us for a port latch to get a certain value,
97 * returning zero if the value is obtained. Callers must hold hdaps_mutex. 96 * returning zero if the value is obtained. Callers must hold hdaps_sem.
98 */ 97 */
99static int __wait_latch(u16 port, u8 val) 98static int __wait_latch(u16 port, u8 val)
100{ 99{
@@ -111,7 +110,7 @@ static int __wait_latch(u16 port, u8 val)
111 110
112/* 111/*
113 * __device_refresh - request a refresh from the accelerometer. Does not wait 112 * __device_refresh - request a refresh from the accelerometer. Does not wait
114 * for refresh to complete. Callers must hold hdaps_mutex. 113 * for refresh to complete. Callers must hold hdaps_sem.
115 */ 114 */
116static void __device_refresh(void) 115static void __device_refresh(void)
117{ 116{
@@ -125,7 +124,7 @@ static void __device_refresh(void)
125/* 124/*
126 * __device_refresh_sync - request a synchronous refresh from the 125 * __device_refresh_sync - request a synchronous refresh from the
127 * accelerometer. We wait for the refresh to complete. Returns zero if 126 * accelerometer. We wait for the refresh to complete. Returns zero if
128 * successful and nonzero on error. Callers must hold hdaps_mutex. 127 * successful and nonzero on error. Callers must hold hdaps_sem.
129 */ 128 */
130static int __device_refresh_sync(void) 129static int __device_refresh_sync(void)
131{ 130{
@@ -135,7 +134,7 @@ static int __device_refresh_sync(void)
135 134
136/* 135/*
137 * __device_complete - indicate to the accelerometer that we are done reading 136 * __device_complete - indicate to the accelerometer that we are done reading
138 * data, and then initiate an async refresh. Callers must hold hdaps_mutex. 137 * data, and then initiate an async refresh. Callers must hold hdaps_sem.
139 */ 138 */
140static inline void __device_complete(void) 139static inline void __device_complete(void)
141{ 140{
@@ -153,7 +152,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
153{ 152{
154 int ret; 153 int ret;
155 154
156 mutex_lock(&hdaps_mutex); 155 down(&hdaps_sem);
157 156
158 /* do a sync refresh -- we need to be sure that we read fresh data */ 157 /* do a sync refresh -- we need to be sure that we read fresh data */
159 ret = __device_refresh_sync(); 158 ret = __device_refresh_sync();
@@ -164,7 +163,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
164 __device_complete(); 163 __device_complete();
165 164
166out: 165out:
167 mutex_unlock(&hdaps_mutex); 166 up(&hdaps_sem);
168 return ret; 167 return ret;
169} 168}
170 169
@@ -199,9 +198,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
199{ 198{
200 int ret; 199 int ret;
201 200
202 mutex_lock(&hdaps_mutex); 201 down(&hdaps_sem);
203 ret = __hdaps_read_pair(port1, port2, val1, val2); 202 ret = __hdaps_read_pair(port1, port2, val1, val2);
204 mutex_unlock(&hdaps_mutex); 203 up(&hdaps_sem);
205 204
206 return ret; 205 return ret;
207} 206}
@@ -214,7 +213,7 @@ static int hdaps_device_init(void)
214{ 213{
215 int total, ret = -ENXIO; 214 int total, ret = -ENXIO;
216 215
217 mutex_lock(&hdaps_mutex); 216 down(&hdaps_sem);
218 217
219 outb(0x13, 0x1610); 218 outb(0x13, 0x1610);
220 outb(0x01, 0x161f); 219 outb(0x01, 0x161f);
@@ -280,7 +279,7 @@ static int hdaps_device_init(void)
280 } 279 }
281 280
282out: 281out:
283 mutex_unlock(&hdaps_mutex); 282 up(&hdaps_sem);
284 return ret; 283 return ret;
285} 284}
286 285
@@ -314,7 +313,7 @@ static struct platform_driver hdaps_driver = {
314}; 313};
315 314
316/* 315/*
317 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mutex. 316 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
318 */ 317 */
319static void hdaps_calibrate(void) 318static void hdaps_calibrate(void)
320{ 319{
@@ -326,7 +325,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
326 int x, y; 325 int x, y;
327 326
328 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ 327 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
329 if (!mutex_trylock(&hdaps_mutex)) { 328 if (down_trylock(&hdaps_sem)) {
330 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); 329 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
331 return; 330 return;
332 } 331 }
@@ -341,7 +340,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
341 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); 340 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
342 341
343out: 342out:
344 mutex_unlock(&hdaps_mutex); 343 up(&hdaps_sem);
345} 344}
346 345
347 346
@@ -421,9 +420,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev,
421 struct device_attribute *attr, 420 struct device_attribute *attr,
422 const char *buf, size_t count) 421 const char *buf, size_t count)
423{ 422{
424 mutex_lock(&hdaps_mutex); 423 down(&hdaps_sem);
425 hdaps_calibrate(); 424 hdaps_calibrate();
426 mutex_unlock(&hdaps_mutex); 425 up(&hdaps_sem);
427 426
428 return count; 427 return count;
429} 428}
@@ -510,12 +509,22 @@ static int hdaps_dmi_match_invert(struct dmi_system_id *id)
510 } \ 509 } \
511} 510}
512 511
512#define HDAPS_DMI_MATCH_LENOVO(model) { \
513 .ident = "Lenovo " model, \
514 .callback = hdaps_dmi_match_invert, \
515 .matches = { \
516 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), \
517 DMI_MATCH(DMI_PRODUCT_VERSION, model) \
518 } \
519}
520
513static int __init hdaps_init(void) 521static int __init hdaps_init(void)
514{ 522{
515 int ret; 523 int ret;
516 524
517 /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ 525 /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */
518 struct dmi_system_id hdaps_whitelist[] = { 526 struct dmi_system_id hdaps_whitelist[] = {
527 HDAPS_DMI_MATCH_NORMAL("ThinkPad H"),
519 HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), 528 HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
520 HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), 529 HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
521 HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), 530 HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
@@ -525,15 +534,17 @@ static int __init hdaps_init(void)
525 HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), 534 HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
526 HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), 535 HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
527 HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), 536 HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
537 HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"),
528 HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), 538 HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
529 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), 539 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),
530 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), 540 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
541 HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"),
531 { .ident = NULL } 542 { .ident = NULL }
532 }; 543 };
533 544
534 if (!dmi_check_system(hdaps_whitelist)) { 545 if (!dmi_check_system(hdaps_whitelist)) {
535 printk(KERN_WARNING "hdaps: supported laptop not found!\n"); 546 printk(KERN_WARNING "hdaps: supported laptop not found!\n");
536 ret = -ENXIO; 547 ret = -ENODEV;
537 goto out; 548 goto out;
538 } 549 }
539 550