aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/applesmc.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-11-10 05:58:03 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-01-08 13:55:38 -0500
commit5874583d5662de5550b0ed1c54a9dea70bcdcba4 (patch)
tree4f2ccb1b543674d183469cb562f8f2b0cce00c53 /drivers/hwmon/applesmc.c
parent1ee7c71bd1aa9758f14e1be92310215a5bd0abe7 (diff)
hwmon: (applesmc) Introduce a register lookup table
One main problem with the current driver is the inability to quickly search for supported keys, resulting in detailed feature maps per machine model which are cumbersome to maintain. This patch adds a register lookup table, which enables binary search for supported keys. The lookup also reduces the io frequency, so the original mutex is replaced by locks around the actual io. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> [guenter.roeck@ericsson.com: Added value range check to key_at_index_store()] Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r--drivers/hwmon/applesmc.c539
1 files changed, 297 insertions, 242 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 5f67e390e45c..f213997adaec 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/input-polldev.h> 33#include <linux/input-polldev.h>
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/slab.h>
35#include <linux/module.h> 36#include <linux/module.h>
36#include <linux/timer.h> 37#include <linux/timer.h>
37#include <linux/dmi.h> 38#include <linux/dmi.h>
@@ -51,6 +52,7 @@
51 52
52#define APPLESMC_MAX_DATA_LENGTH 32 53#define APPLESMC_MAX_DATA_LENGTH 32
53 54
55/* wait up to 32 ms for a status change. */
54#define APPLESMC_MIN_WAIT 0x0040 56#define APPLESMC_MIN_WAIT 0x0040
55#define APPLESMC_MAX_WAIT 0x8000 57#define APPLESMC_MAX_WAIT 0x8000
56 58
@@ -200,6 +202,25 @@ struct dmi_match_data {
200 int temperature_set; 202 int temperature_set;
201}; 203};
202 204
205/* AppleSMC entry - cached register information */
206struct applesmc_entry {
207 char key[5]; /* four-letter key code */
208 u8 valid; /* set when entry is successfully read once */
209 u8 len; /* bounded by APPLESMC_MAX_DATA_LENGTH */
210 char type[5]; /* four-letter type code */
211 u8 flags; /* 0x10: func; 0x40: write; 0x80: read */
212};
213
214/* Register lookup and registers common to all SMCs */
215static struct applesmc_registers {
216 struct mutex mutex; /* register read/write mutex */
217 unsigned int key_count; /* number of SMC registers */
218 bool init_complete; /* true when fully initialized */
219 struct applesmc_entry *cache; /* cached key entries */
220} smcreg = {
221 .mutex = __MUTEX_INITIALIZER(smcreg.mutex),
222};
223
203static const int debug; 224static const int debug;
204static struct platform_device *pdev; 225static struct platform_device *pdev;
205static s16 rest_x; 226static s16 rest_x;
@@ -221,8 +242,6 @@ static unsigned int fans_handled;
221/* Indicates which temperature sensors set to use. */ 242/* Indicates which temperature sensors set to use. */
222static unsigned int applesmc_temperature_set; 243static unsigned int applesmc_temperature_set;
223 244
224static DEFINE_MUTEX(applesmc_lock);
225
226/* 245/*
227 * Last index written to key_at_index sysfs file, and value to use for all other 246 * Last index written to key_at_index sysfs file, and value to use for all other
228 * key_at_index_* sysfs files. 247 * key_at_index_* sysfs files.
@@ -245,16 +264,10 @@ static int __wait_status(u8 val)
245 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { 264 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
246 udelay(us); 265 udelay(us);
247 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { 266 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
248 if (debug)
249 printk(KERN_DEBUG
250 "Waited %d us for status %x\n",
251 2 * us - APPLESMC_MIN_WAIT, val);
252 return 0; 267 return 0;
253 } 268 }
254 } 269 }
255 270
256 pr_warn("wait status failed: %x != %x\n", val, inb(APPLESMC_CMD_PORT));
257
258 return -EIO; 271 return -EIO;
259} 272}
260 273
@@ -272,156 +285,228 @@ static int send_command(u8 cmd)
272 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) 285 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
273 return 0; 286 return 0;
274 } 287 }
275 pr_warn("command failed: %x -> %x\n", cmd, inb(APPLESMC_CMD_PORT));
276 return -EIO; 288 return -EIO;
277} 289}
278 290
279/* 291static int send_argument(const char *key)
280 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
281 * Returns zero on success or a negative error on failure. Callers must
282 * hold applesmc_lock.
283 */
284static int applesmc_read_key(const char* key, u8* buffer, u8 len)
285{ 292{
286 int i; 293 int i;
287 294
288 if (len > APPLESMC_MAX_DATA_LENGTH) {
289 pr_err("%s(): cannot read more than %d bytes\n",
290 __func__, APPLESMC_MAX_DATA_LENGTH);
291 return -EINVAL;
292 }
293
294 if (send_command(APPLESMC_READ_CMD))
295 return -EIO;
296
297 for (i = 0; i < 4; i++) { 295 for (i = 0; i < 4; i++) {
298 outb(key[i], APPLESMC_DATA_PORT); 296 outb(key[i], APPLESMC_DATA_PORT);
299 if (__wait_status(0x04)) 297 if (__wait_status(0x04))
300 return -EIO; 298 return -EIO;
301 } 299 }
302 if (debug) 300 return 0;
303 printk(KERN_DEBUG "<%s", key); 301}
302
303static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
304{
305 int i;
306
307 if (send_command(cmd) || send_argument(key)) {
308 pr_warn("%s: read arg fail\n", key);
309 return -EIO;
310 }
304 311
305 outb(len, APPLESMC_DATA_PORT); 312 outb(len, APPLESMC_DATA_PORT);
306 if (debug)
307 printk(KERN_DEBUG ">%x", len);
308 313
309 for (i = 0; i < len; i++) { 314 for (i = 0; i < len; i++) {
310 if (__wait_status(0x05)) 315 if (__wait_status(0x05)) {
316 pr_warn("%s: read data fail\n", key);
311 return -EIO; 317 return -EIO;
318 }
312 buffer[i] = inb(APPLESMC_DATA_PORT); 319 buffer[i] = inb(APPLESMC_DATA_PORT);
313 if (debug)
314 printk(KERN_DEBUG "<%x", buffer[i]);
315 } 320 }
316 if (debug)
317 printk(KERN_DEBUG "\n");
318 321
319 return 0; 322 return 0;
320} 323}
321 324
322/* 325static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
323 * applesmc_write_key - writes len bytes from buffer to a given key.
324 * Returns zero on success or a negative error on failure. Callers must
325 * hold applesmc_lock.
326 */
327static int applesmc_write_key(const char* key, u8* buffer, u8 len)
328{ 326{
329 int i; 327 int i;
330 328
331 if (len > APPLESMC_MAX_DATA_LENGTH) { 329 if (send_command(cmd) || send_argument(key)) {
332 pr_err("%s(): cannot write more than %d bytes\n", 330 pr_warn("%s: write arg fail\n", key);
333 __func__, APPLESMC_MAX_DATA_LENGTH);
334 return -EINVAL;
335 }
336
337 if (send_command(APPLESMC_WRITE_CMD))
338 return -EIO; 331 return -EIO;
339
340 for (i = 0; i < 4; i++) {
341 outb(key[i], APPLESMC_DATA_PORT);
342 if (__wait_status(0x04))
343 return -EIO;
344 } 332 }
345 333
346 outb(len, APPLESMC_DATA_PORT); 334 outb(len, APPLESMC_DATA_PORT);
347 335
348 for (i = 0; i < len; i++) { 336 for (i = 0; i < len; i++) {
349 if (__wait_status(0x04)) 337 if (__wait_status(0x04)) {
338 pr_warn("%s: write data fail\n", key);
350 return -EIO; 339 return -EIO;
340 }
351 outb(buffer[i], APPLESMC_DATA_PORT); 341 outb(buffer[i], APPLESMC_DATA_PORT);
352 } 342 }
353 343
354 return 0; 344 return 0;
355} 345}
356 346
347static int read_register_count(unsigned int *count)
348{
349 __be32 be;
350 int ret;
351
352 ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
353 if (ret)
354 return ret;
355
356 *count = be32_to_cpu(be);
357 return 0;
358}
359
357/* 360/*
358 * applesmc_get_key_at_index - get key at index, and put the result in key 361 * Serialized I/O
359 * (char[6]). Returns zero on success or a negative error on failure. Callers 362 *
360 * must hold applesmc_lock. 363 * Returns zero on success or a negative error on failure.
364 * All functions below are concurrency safe - callers should NOT hold lock.
361 */ 365 */
362static int applesmc_get_key_at_index(int index, char* key) 366
367static int applesmc_read_entry(const struct applesmc_entry *entry,
368 u8 *buf, u8 len)
363{ 369{
364 int i; 370 int ret;
365 u8 readkey[4];
366 readkey[0] = index >> 24;
367 readkey[1] = index >> 16;
368 readkey[2] = index >> 8;
369 readkey[3] = index;
370 371
371 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) 372 if (entry->len != len)
372 return -EIO; 373 return -EINVAL;
374 mutex_lock(&smcreg.mutex);
375 ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len);
376 mutex_unlock(&smcreg.mutex);
373 377
374 for (i = 0; i < 4; i++) { 378 return ret;
375 outb(readkey[i], APPLESMC_DATA_PORT); 379}
376 if (__wait_status(0x04)) 380
377 return -EIO; 381static int applesmc_write_entry(const struct applesmc_entry *entry,
382 const u8 *buf, u8 len)
383{
384 int ret;
385
386 if (entry->len != len)
387 return -EINVAL;
388 mutex_lock(&smcreg.mutex);
389 ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len);
390 mutex_unlock(&smcreg.mutex);
391 return ret;
392}
393
394static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
395{
396 struct applesmc_entry *cache = &smcreg.cache[index];
397 u8 key[4], info[6];
398 __be32 be;
399 int ret = 0;
400
401 if (cache->valid)
402 return cache;
403
404 mutex_lock(&smcreg.mutex);
405
406 if (cache->valid)
407 goto out;
408 be = cpu_to_be32(index);
409 ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
410 if (ret)
411 goto out;
412 ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
413 if (ret)
414 goto out;
415
416 memcpy(cache->key, key, 4);
417 cache->len = info[0];
418 memcpy(cache->type, &info[1], 4);
419 cache->flags = info[5];
420 cache->valid = 1;
421
422out:
423 mutex_unlock(&smcreg.mutex);
424 if (ret)
425 return ERR_PTR(ret);
426 return cache;
427}
428
429static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
430{
431 int begin = 0, end = smcreg.key_count;
432 const struct applesmc_entry *entry;
433
434 while (begin != end) {
435 int middle = begin + (end - begin) / 2;
436 entry = applesmc_get_entry_by_index(middle);
437 if (IS_ERR(entry))
438 return PTR_ERR(entry);
439 if (strcmp(entry->key, key) < 0)
440 begin = middle + 1;
441 else
442 end = middle;
378 } 443 }
379 444
380 outb(4, APPLESMC_DATA_PORT); 445 *lo = begin;
446 return 0;
447}
381 448
382 for (i = 0; i < 4; i++) { 449static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
383 if (__wait_status(0x05)) 450{
384 return -EIO; 451 int begin = 0, end = smcreg.key_count;
385 key[i] = inb(APPLESMC_DATA_PORT); 452 const struct applesmc_entry *entry;
453
454 while (begin != end) {
455 int middle = begin + (end - begin) / 2;
456 entry = applesmc_get_entry_by_index(middle);
457 if (IS_ERR(entry))
458 return PTR_ERR(entry);
459 if (strcmp(key, entry->key) < 0)
460 end = middle;
461 else
462 begin = middle + 1;
386 } 463 }
387 key[4] = 0;
388 464
465 *hi = begin;
389 return 0; 466 return 0;
390} 467}
391 468
392/* 469static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key)
393 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
394 * Returns zero on success or a negative error on failure. Callers must
395 * hold applesmc_lock.
396 */
397static int applesmc_get_key_type(char* key, char* type)
398{ 470{
399 int i; 471 int begin, end;
472 int ret;
400 473
401 if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) 474 ret = applesmc_get_lower_bound(&begin, key);
402 return -EIO; 475 if (ret)
476 return ERR_PTR(ret);
477 ret = applesmc_get_upper_bound(&end, key);
478 if (ret)
479 return ERR_PTR(ret);
480 if (end - begin != 1)
481 return ERR_PTR(-EINVAL);
403 482
404 for (i = 0; i < 4; i++) { 483 return applesmc_get_entry_by_index(begin);
405 outb(key[i], APPLESMC_DATA_PORT); 484}
406 if (__wait_status(0x04))
407 return -EIO;
408 }
409 485
410 outb(6, APPLESMC_DATA_PORT); 486static int applesmc_read_key(const char *key, u8 *buffer, u8 len)
487{
488 const struct applesmc_entry *entry;
411 489
412 for (i = 0; i < 6; i++) { 490 entry = applesmc_get_entry_by_key(key);
413 if (__wait_status(0x05)) 491 if (IS_ERR(entry))
414 return -EIO; 492 return PTR_ERR(entry);
415 type[i] = inb(APPLESMC_DATA_PORT);
416 }
417 type[5] = 0;
418 493
419 return 0; 494 return applesmc_read_entry(entry, buffer, len);
495}
496
497static int applesmc_write_key(const char *key, const u8 *buffer, u8 len)
498{
499 const struct applesmc_entry *entry;
500
501 entry = applesmc_get_entry_by_key(key);
502 if (IS_ERR(entry))
503 return PTR_ERR(entry);
504
505 return applesmc_write_entry(entry, buffer, len);
420} 506}
421 507
422/* 508/*
423 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must 509 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z).
424 * hold applesmc_lock.
425 */ 510 */
426static int applesmc_read_motion_sensor(int index, s16* value) 511static int applesmc_read_motion_sensor(int index, s16* value)
427{ 512{
@@ -458,12 +543,10 @@ static void applesmc_device_init(void)
458 if (!applesmc_accelerometer) 543 if (!applesmc_accelerometer)
459 return; 544 return;
460 545
461 mutex_lock(&applesmc_lock);
462
463 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { 546 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
464 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && 547 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
465 (buffer[0] != 0x00 || buffer[1] != 0x00)) 548 (buffer[0] != 0x00 || buffer[1] != 0x00))
466 goto out; 549 return;
467 buffer[0] = 0xe0; 550 buffer[0] = 0xe0;
468 buffer[1] = 0x00; 551 buffer[1] = 0x00;
469 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); 552 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
@@ -471,34 +554,93 @@ static void applesmc_device_init(void)
471 } 554 }
472 555
473 pr_warn("failed to init the device\n"); 556 pr_warn("failed to init the device\n");
474
475out:
476 mutex_unlock(&applesmc_lock);
477} 557}
478 558
479/* 559/*
480 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold 560 * applesmc_get_fan_count - get the number of fans.
481 * applesmc_lock.
482 */ 561 */
483static int applesmc_get_fan_count(void) 562static int applesmc_get_fan_count(void)
484{ 563{
485 int ret; 564 int ret;
486 u8 buffer[1]; 565 u8 buffer[1];
487 566
488 mutex_lock(&applesmc_lock);
489
490 ret = applesmc_read_key(FANS_COUNT, buffer, 1); 567 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
491 568
492 mutex_unlock(&applesmc_lock);
493 if (ret) 569 if (ret)
494 return ret; 570 return ret;
495 else 571 else
496 return buffer[0]; 572 return buffer[0];
497} 573}
498 574
575/*
576 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
577 */
578static int applesmc_init_smcreg_try(void)
579{
580 struct applesmc_registers *s = &smcreg;
581 int ret;
582
583 if (s->init_complete)
584 return 0;
585
586 ret = read_register_count(&s->key_count);
587 if (ret)
588 return ret;
589
590 if (!s->cache)
591 s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL);
592 if (!s->cache)
593 return -ENOMEM;
594
595 s->init_complete = true;
596
597 pr_info("key=%d\n", s->key_count);
598
599 return 0;
600}
601
602/*
603 * applesmc_init_smcreg - Initialize register cache.
604 *
605 * Retries until initialization is successful, or the operation times out.
606 *
607 */
608static int applesmc_init_smcreg(void)
609{
610 int ms, ret;
611
612 for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) {
613 ret = applesmc_init_smcreg_try();
614 if (!ret) {
615 if (ms)
616 pr_info("init_smcreg() took %d ms\n", ms);
617 return 0;
618 }
619 msleep(INIT_WAIT_MSECS);
620 }
621
622 kfree(smcreg.cache);
623 smcreg.cache = NULL;
624
625 return ret;
626}
627
628static void applesmc_destroy_smcreg(void)
629{
630 kfree(smcreg.cache);
631 smcreg.cache = NULL;
632 smcreg.init_complete = false;
633}
634
499/* Device model stuff */ 635/* Device model stuff */
500static int applesmc_probe(struct platform_device *dev) 636static int applesmc_probe(struct platform_device *dev)
501{ 637{
638 int ret;
639
640 ret = applesmc_init_smcreg();
641 if (ret)
642 return ret;
643
502 applesmc_device_init(); 644 applesmc_device_init();
503 645
504 return 0; 646 return 0;
@@ -507,10 +649,8 @@ static int applesmc_probe(struct platform_device *dev)
507/* Synchronize device with memorized backlight state */ 649/* Synchronize device with memorized backlight state */
508static int applesmc_pm_resume(struct device *dev) 650static int applesmc_pm_resume(struct device *dev)
509{ 651{
510 mutex_lock(&applesmc_lock);
511 if (applesmc_light) 652 if (applesmc_light)
512 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); 653 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
513 mutex_unlock(&applesmc_lock);
514 return 0; 654 return 0;
515} 655}
516 656
@@ -551,20 +691,15 @@ static void applesmc_idev_poll(struct input_polled_dev *dev)
551 struct input_dev *idev = dev->input; 691 struct input_dev *idev = dev->input;
552 s16 x, y; 692 s16 x, y;
553 693
554 mutex_lock(&applesmc_lock);
555
556 if (applesmc_read_motion_sensor(SENSOR_X, &x)) 694 if (applesmc_read_motion_sensor(SENSOR_X, &x))
557 goto out; 695 return;
558 if (applesmc_read_motion_sensor(SENSOR_Y, &y)) 696 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
559 goto out; 697 return;
560 698
561 x = -x; 699 x = -x;
562 input_report_abs(idev, ABS_X, x - rest_x); 700 input_report_abs(idev, ABS_X, x - rest_x);
563 input_report_abs(idev, ABS_Y, y - rest_y); 701 input_report_abs(idev, ABS_Y, y - rest_y);
564 input_sync(idev); 702 input_sync(idev);
565
566out:
567 mutex_unlock(&applesmc_lock);
568} 703}
569 704
570/* Sysfs Files */ 705/* Sysfs Files */
@@ -581,8 +716,6 @@ static ssize_t applesmc_position_show(struct device *dev,
581 int ret; 716 int ret;
582 s16 x, y, z; 717 s16 x, y, z;
583 718
584 mutex_lock(&applesmc_lock);
585
586 ret = applesmc_read_motion_sensor(SENSOR_X, &x); 719 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
587 if (ret) 720 if (ret)
588 goto out; 721 goto out;
@@ -594,7 +727,6 @@ static ssize_t applesmc_position_show(struct device *dev,
594 goto out; 727 goto out;
595 728
596out: 729out:
597 mutex_unlock(&applesmc_lock);
598 if (ret) 730 if (ret)
599 return ret; 731 return ret;
600 else 732 else
@@ -604,18 +736,19 @@ out:
604static ssize_t applesmc_light_show(struct device *dev, 736static ssize_t applesmc_light_show(struct device *dev,
605 struct device_attribute *attr, char *sysfsbuf) 737 struct device_attribute *attr, char *sysfsbuf)
606{ 738{
739 const struct applesmc_entry *entry;
607 static int data_length; 740 static int data_length;
608 int ret; 741 int ret;
609 u8 left = 0, right = 0; 742 u8 left = 0, right = 0;
610 u8 buffer[10], query[6]; 743 u8 buffer[10];
611
612 mutex_lock(&applesmc_lock);
613 744
614 if (!data_length) { 745 if (!data_length) {
615 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query); 746 entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY);
616 if (ret) 747 if (IS_ERR(entry))
617 goto out; 748 return PTR_ERR(entry);
618 data_length = clamp_val(query[0], 0, 10); 749 if (entry->len > 10)
750 return -ENXIO;
751 data_length = entry->len;
619 pr_info("light sensor data length set to %d\n", data_length); 752 pr_info("light sensor data length set to %d\n", data_length);
620 } 753 }
621 754
@@ -632,7 +765,6 @@ static ssize_t applesmc_light_show(struct device *dev,
632 right = buffer[2]; 765 right = buffer[2];
633 766
634out: 767out:
635 mutex_unlock(&applesmc_lock);
636 if (ret) 768 if (ret)
637 return ret; 769 return ret;
638 else 770 else
@@ -661,14 +793,10 @@ static ssize_t applesmc_show_temperature(struct device *dev,
661 const char* key = 793 const char* key =
662 temperature_sensors_sets[applesmc_temperature_set][attr->index]; 794 temperature_sensors_sets[applesmc_temperature_set][attr->index];
663 795
664 mutex_lock(&applesmc_lock);
665
666 ret = applesmc_read_key(key, buffer, 2); 796 ret = applesmc_read_key(key, buffer, 2);
667 temp = buffer[0]*1000; 797 temp = buffer[0]*1000;
668 temp += (buffer[1] >> 6) * 250; 798 temp += (buffer[1] >> 6) * 250;
669 799
670 mutex_unlock(&applesmc_lock);
671
672 if (ret) 800 if (ret)
673 return ret; 801 return ret;
674 else 802 else
@@ -691,12 +819,9 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
691 newkey[3] = fan_speed_keys[sensor_attr->nr][3]; 819 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
692 newkey[4] = 0; 820 newkey[4] = 0;
693 821
694 mutex_lock(&applesmc_lock);
695
696 ret = applesmc_read_key(newkey, buffer, 2); 822 ret = applesmc_read_key(newkey, buffer, 2);
697 speed = ((buffer[0] << 8 | buffer[1]) >> 2); 823 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
698 824
699 mutex_unlock(&applesmc_lock);
700 if (ret) 825 if (ret)
701 return ret; 826 return ret;
702 else 827 else
@@ -725,13 +850,10 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
725 newkey[3] = fan_speed_keys[sensor_attr->nr][3]; 850 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
726 newkey[4] = 0; 851 newkey[4] = 0;
727 852
728 mutex_lock(&applesmc_lock);
729
730 buffer[0] = (speed >> 6) & 0xff; 853 buffer[0] = (speed >> 6) & 0xff;
731 buffer[1] = (speed << 2) & 0xff; 854 buffer[1] = (speed << 2) & 0xff;
732 ret = applesmc_write_key(newkey, buffer, 2); 855 ret = applesmc_write_key(newkey, buffer, 2);
733 856
734 mutex_unlock(&applesmc_lock);
735 if (ret) 857 if (ret)
736 return ret; 858 return ret;
737 else 859 else
@@ -746,12 +868,9 @@ static ssize_t applesmc_show_fan_manual(struct device *dev,
746 u8 buffer[2]; 868 u8 buffer[2];
747 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 869 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
748 870
749 mutex_lock(&applesmc_lock);
750
751 ret = applesmc_read_key(FANS_MANUAL, buffer, 2); 871 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
752 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; 872 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
753 873
754 mutex_unlock(&applesmc_lock);
755 if (ret) 874 if (ret)
756 return ret; 875 return ret;
757 else 876 else
@@ -770,8 +889,6 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
770 889
771 input = simple_strtoul(sysfsbuf, NULL, 10); 890 input = simple_strtoul(sysfsbuf, NULL, 10);
772 891
773 mutex_lock(&applesmc_lock);
774
775 ret = applesmc_read_key(FANS_MANUAL, buffer, 2); 892 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
776 val = (buffer[0] << 8 | buffer[1]); 893 val = (buffer[0] << 8 | buffer[1]);
777 if (ret) 894 if (ret)
@@ -788,7 +905,6 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
788 ret = applesmc_write_key(FANS_MANUAL, buffer, 2); 905 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
789 906
790out: 907out:
791 mutex_unlock(&applesmc_lock);
792 if (ret) 908 if (ret)
793 return ret; 909 return ret;
794 else 910 else
@@ -810,12 +926,9 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
810 newkey[3] = FAN_POSITION[3]; 926 newkey[3] = FAN_POSITION[3];
811 newkey[4] = 0; 927 newkey[4] = 0;
812 928
813 mutex_lock(&applesmc_lock);
814
815 ret = applesmc_read_key(newkey, buffer, 16); 929 ret = applesmc_read_key(newkey, buffer, 16);
816 buffer[16] = 0; 930 buffer[16] = 0;
817 931
818 mutex_unlock(&applesmc_lock);
819 if (ret) 932 if (ret)
820 return ret; 933 return ret;
821 else 934 else
@@ -831,18 +944,14 @@ static ssize_t applesmc_calibrate_show(struct device *dev,
831static ssize_t applesmc_calibrate_store(struct device *dev, 944static ssize_t applesmc_calibrate_store(struct device *dev,
832 struct device_attribute *attr, const char *sysfsbuf, size_t count) 945 struct device_attribute *attr, const char *sysfsbuf, size_t count)
833{ 946{
834 mutex_lock(&applesmc_lock);
835 applesmc_calibrate(); 947 applesmc_calibrate();
836 mutex_unlock(&applesmc_lock);
837 948
838 return count; 949 return count;
839} 950}
840 951
841static void applesmc_backlight_set(struct work_struct *work) 952static void applesmc_backlight_set(struct work_struct *work)
842{ 953{
843 mutex_lock(&applesmc_lock);
844 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); 954 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
845 mutex_unlock(&applesmc_lock);
846} 955}
847static DECLARE_WORK(backlight_work, &applesmc_backlight_set); 956static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
848 957
@@ -865,13 +974,10 @@ static ssize_t applesmc_key_count_show(struct device *dev,
865 u8 buffer[4]; 974 u8 buffer[4];
866 u32 count; 975 u32 count;
867 976
868 mutex_lock(&applesmc_lock);
869
870 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); 977 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
871 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + 978 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
872 ((u32)buffer[2]<<8) + buffer[3]; 979 ((u32)buffer[2]<<8) + buffer[3];
873 980
874 mutex_unlock(&applesmc_lock);
875 if (ret) 981 if (ret)
876 return ret; 982 return ret;
877 else 983 else
@@ -881,113 +987,53 @@ static ssize_t applesmc_key_count_show(struct device *dev,
881static ssize_t applesmc_key_at_index_read_show(struct device *dev, 987static ssize_t applesmc_key_at_index_read_show(struct device *dev,
882 struct device_attribute *attr, char *sysfsbuf) 988 struct device_attribute *attr, char *sysfsbuf)
883{ 989{
884 char key[5]; 990 const struct applesmc_entry *entry;
885 char info[6];
886 int ret; 991 int ret;
887 992
888 mutex_lock(&applesmc_lock); 993 entry = applesmc_get_entry_by_index(key_at_index);
889 994 if (IS_ERR(entry))
890 ret = applesmc_get_key_at_index(key_at_index, key); 995 return PTR_ERR(entry);
891 996 ret = applesmc_read_entry(entry, sysfsbuf, entry->len);
892 if (ret || !key[0]) { 997 if (ret)
893 mutex_unlock(&applesmc_lock);
894
895 return -EINVAL;
896 }
897
898 ret = applesmc_get_key_type(key, info);
899
900 if (ret) {
901 mutex_unlock(&applesmc_lock);
902
903 return ret; 998 return ret;
904 }
905 999
906 /* 1000 return entry->len;
907 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
908 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
909 */
910 ret = applesmc_read_key(key, sysfsbuf, info[0]);
911
912 mutex_unlock(&applesmc_lock);
913
914 if (!ret) {
915 return info[0];
916 } else {
917 return ret;
918 }
919} 1001}
920 1002
921static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, 1003static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
922 struct device_attribute *attr, char *sysfsbuf) 1004 struct device_attribute *attr, char *sysfsbuf)
923{ 1005{
924 char key[5]; 1006 const struct applesmc_entry *entry;
925 char info[6];
926 int ret;
927
928 mutex_lock(&applesmc_lock);
929 1007
930 ret = applesmc_get_key_at_index(key_at_index, key); 1008 entry = applesmc_get_entry_by_index(key_at_index);
1009 if (IS_ERR(entry))
1010 return PTR_ERR(entry);
931 1011
932 if (ret || !key[0]) { 1012 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", entry->len);
933 mutex_unlock(&applesmc_lock);
934
935 return -EINVAL;
936 }
937
938 ret = applesmc_get_key_type(key, info);
939
940 mutex_unlock(&applesmc_lock);
941
942 if (!ret)
943 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
944 else
945 return ret;
946} 1013}
947 1014
948static ssize_t applesmc_key_at_index_type_show(struct device *dev, 1015static ssize_t applesmc_key_at_index_type_show(struct device *dev,
949 struct device_attribute *attr, char *sysfsbuf) 1016 struct device_attribute *attr, char *sysfsbuf)
950{ 1017{
951 char key[5]; 1018 const struct applesmc_entry *entry;
952 char info[6];
953 int ret;
954
955 mutex_lock(&applesmc_lock);
956
957 ret = applesmc_get_key_at_index(key_at_index, key);
958
959 if (ret || !key[0]) {
960 mutex_unlock(&applesmc_lock);
961
962 return -EINVAL;
963 }
964
965 ret = applesmc_get_key_type(key, info);
966 1019
967 mutex_unlock(&applesmc_lock); 1020 entry = applesmc_get_entry_by_index(key_at_index);
1021 if (IS_ERR(entry))
1022 return PTR_ERR(entry);
968 1023
969 if (!ret) 1024 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->type);
970 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
971 else
972 return ret;
973} 1025}
974 1026
975static ssize_t applesmc_key_at_index_name_show(struct device *dev, 1027static ssize_t applesmc_key_at_index_name_show(struct device *dev,
976 struct device_attribute *attr, char *sysfsbuf) 1028 struct device_attribute *attr, char *sysfsbuf)
977{ 1029{
978 char key[5]; 1030 const struct applesmc_entry *entry;
979 int ret;
980
981 mutex_lock(&applesmc_lock);
982 1031
983 ret = applesmc_get_key_at_index(key_at_index, key); 1032 entry = applesmc_get_entry_by_index(key_at_index);
1033 if (IS_ERR(entry))
1034 return PTR_ERR(entry);
984 1035
985 mutex_unlock(&applesmc_lock); 1036 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
986
987 if (!ret && key[0])
988 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
989 else
990 return -EINVAL;
991} 1037}
992 1038
993static ssize_t applesmc_key_at_index_show(struct device *dev, 1039static ssize_t applesmc_key_at_index_show(struct device *dev,
@@ -999,12 +1045,13 @@ static ssize_t applesmc_key_at_index_show(struct device *dev,
999static ssize_t applesmc_key_at_index_store(struct device *dev, 1045static ssize_t applesmc_key_at_index_store(struct device *dev,
1000 struct device_attribute *attr, const char *sysfsbuf, size_t count) 1046 struct device_attribute *attr, const char *sysfsbuf, size_t count)
1001{ 1047{
1002 mutex_lock(&applesmc_lock); 1048 unsigned long newkey;
1003 1049
1004 key_at_index = simple_strtoul(sysfsbuf, NULL, 10); 1050 if (strict_strtoul(sysfsbuf, 10, &newkey) < 0
1005 1051 || newkey >= smcreg.key_count)
1006 mutex_unlock(&applesmc_lock); 1052 return -EINVAL;
1007 1053
1054 key_at_index = newkey;
1008 return count; 1055 return count;
1009} 1056}
1010 1057
@@ -1646,10 +1693,15 @@ static int __init applesmc_init(void)
1646 goto out_driver; 1693 goto out_driver;
1647 } 1694 }
1648 1695
1649 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); 1696 /* create register cache */
1697 ret = applesmc_init_smcreg();
1650 if (ret) 1698 if (ret)
1651 goto out_device; 1699 goto out_device;
1652 1700
1701 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1702 if (ret)
1703 goto out_smcreg;
1704
1653 /* Create key enumeration sysfs files */ 1705 /* Create key enumeration sysfs files */
1654 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); 1706 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1655 if (ret) 1707 if (ret)
@@ -1751,6 +1803,8 @@ out_fans:
1751 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); 1803 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1752out_name: 1804out_name:
1753 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); 1805 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1806out_smcreg:
1807 applesmc_destroy_smcreg();
1754out_device: 1808out_device:
1755 platform_device_unregister(pdev); 1809 platform_device_unregister(pdev);
1756out_driver: 1810out_driver:
@@ -1779,6 +1833,7 @@ static void __exit applesmc_exit(void)
1779 &fan_attribute_groups[--fans_handled]); 1833 &fan_attribute_groups[--fans_handled]);
1780 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); 1834 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1781 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); 1835 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1836 applesmc_destroy_smcreg();
1782 platform_device_unregister(pdev); 1837 platform_device_unregister(pdev);
1783 platform_driver_unregister(&applesmc_driver); 1838 platform_driver_unregister(&applesmc_driver);
1784 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); 1839 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);