summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-07-26 15:54:06 +0200
committerHenrik Rydberg <rydberg@euromail.se>2012-07-27 14:15:51 +0200
commit9130f8aef481626b733f9e0d535728c55b9bd706 (patch)
treee864baeb179653cc39d12400001e595805efb1ad /usr
parente704f5eb16d58debf7d815942fc377392af60ebc (diff)
Update to pre-3.6
This also solves read and write errors on all machines. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'usr')
-rw-r--r--usr/src/dkms_source_tree/applesmc.c269
1 files changed, 146 insertions, 123 deletions
diff --git a/usr/src/dkms_source_tree/applesmc.c b/usr/src/dkms_source_tree/applesmc.c
index 7b22f67..2827088 100644
--- a/usr/src/dkms_source_tree/applesmc.c
+++ b/usr/src/dkms_source_tree/applesmc.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Based on hdaps.c driver: 9 * Based on hdaps.c driver:
10 * Copyright (C) 2005 Robert Love <rml@novell.com> 10 * Copyright (C) 2005 Robert Love <rml@novell.com>
11 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> 11 * Copyright (C) 2005 Jesper Juhl <jj@chaosbits.net>
12 * 12 *
13 * Fan control based on smcFanControl: 13 * Fan control based on smcFanControl:
14 * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com> 14 * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
@@ -44,16 +44,6 @@
44#include <linux/hwmon.h> 44#include <linux/hwmon.h>
45#include <linux/workqueue.h> 45#include <linux/workqueue.h>
46 46
47#ifndef pr_info
48#define pr_info(fmt, ...) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
49#endif
50#ifndef pr_err
51#define pr_err(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
52#endif
53#ifndef pr_warn
54#define pr_warn(fmt, ...) printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
55#endif
56
57/* data port used by Apple SMC */ 47/* data port used by Apple SMC */
58#define APPLESMC_DATA_PORT 0x300 48#define APPLESMC_DATA_PORT 0x300
59/* command/status port used by Apple SMC */ 49/* command/status port used by Apple SMC */
@@ -64,10 +54,10 @@
64#define APPLESMC_MAX_DATA_LENGTH 32 54#define APPLESMC_MAX_DATA_LENGTH 32
65 55
66/* wait up to 32 ms for a status change. */ 56/* wait up to 32 ms for a status change. */
67#define APPLESMC_MIN_WAIT 0x0040 57#define APPLESMC_MIN_WAIT 0x0010
58#define APPLESMC_RETRY_WAIT 0x0100
68#define APPLESMC_MAX_WAIT 0x8000 59#define APPLESMC_MAX_WAIT 0x8000
69 60
70#define APPLESMC_STATUS_MASK 0x0f
71#define APPLESMC_READ_CMD 0x10 61#define APPLESMC_READ_CMD 0x10
72#define APPLESMC_WRITE_CMD 0x11 62#define APPLESMC_WRITE_CMD 0x11
73#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 63#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
@@ -90,6 +80,8 @@
90#define FANS_MANUAL "FS! " /* r-w ui16 */ 80#define FANS_MANUAL "FS! " /* r-w ui16 */
91#define FAN_ID_FMT "F%dID" /* r-o char[16] */ 81#define FAN_ID_FMT "F%dID" /* r-o char[16] */
92 82
83#define TEMP_SENSOR_TYPE "sp78"
84
93/* List of keys used to read/write fan speeds */ 85/* List of keys used to read/write fan speeds */
94static const char *const fan_speed_fmt[] = { 86static const char *const fan_speed_fmt[] = {
95 "F%dAc", /* actual speed */ 87 "F%dAc", /* actual speed */
@@ -106,10 +98,6 @@ static const char *const fan_speed_fmt[] = {
106#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ 98#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
107#define APPLESMC_INPUT_FLAT 4 99#define APPLESMC_INPUT_FLAT 4
108 100
109#define SENSOR_X 0
110#define SENSOR_Y 1
111#define SENSOR_Z 2
112
113#define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff) 101#define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff)
114#define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16) 102#define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16)
115 103
@@ -145,11 +133,13 @@ static struct applesmc_registers {
145 unsigned int temp_count; /* number of temperature registers */ 133 unsigned int temp_count; /* number of temperature registers */
146 unsigned int temp_begin; /* temperature lower index bound */ 134 unsigned int temp_begin; /* temperature lower index bound */
147 unsigned int temp_end; /* temperature upper index bound */ 135 unsigned int temp_end; /* temperature upper index bound */
136 unsigned int index_count; /* size of temperature index array */
148 int num_light_sensors; /* number of light sensors */ 137 int num_light_sensors; /* number of light sensors */
149 bool has_accelerometer; /* has motion sensor */ 138 bool has_accelerometer; /* has motion sensor */
150 bool has_key_backlight; /* has keyboard backlight */ 139 bool has_key_backlight; /* has keyboard backlight */
151 bool init_complete; /* true when fully initialized */ 140 bool init_complete; /* true when fully initialized */
152 struct applesmc_entry *cache; /* cached key entries */ 141 struct applesmc_entry *cache; /* cached key entries */
142 const char **index; /* temperature key index */
153} smcreg = { 143} smcreg = {
154 .mutex = __MUTEX_INITIALIZER(smcreg.mutex), 144 .mutex = __MUTEX_INITIALIZER(smcreg.mutex),
155}; 145};
@@ -172,52 +162,68 @@ static unsigned int key_at_index;
172static struct workqueue_struct *applesmc_led_wq; 162static struct workqueue_struct *applesmc_led_wq;
173 163
174/* 164/*
175 * __wait_status - Wait up to 32ms for the status port to get a certain value 165 * wait_read - Wait for a byte to appear on SMC port. Callers must
176 * (masked with 0x0f), returning zero if the value is obtained. Callers must
177 * hold applesmc_lock. 166 * hold applesmc_lock.
178 */ 167 */
179static int __wait_status(u8 val) 168static int wait_read(void)
180{ 169{
170 u8 status;
181 int us; 171 int us;
182
183 val = val & APPLESMC_STATUS_MASK;
184
185 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { 172 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
186 udelay(us); 173 udelay(us);
187 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { 174 status = inb(APPLESMC_CMD_PORT);
175 /* read: wait for smc to settle */
176 if (status & 0x01)
188 return 0; 177 return 0;
189 }
190 } 178 }
191 179
180 pr_warn("wait_read() fail: 0x%02x\n", status);
192 return -EIO; 181 return -EIO;
193} 182}
194 183
195/* 184/*
196 * special treatment of command port - on newer macbooks, it seems necessary 185 * send_byte - Write to SMC port, retrying when necessary. Callers
197 * to resend the command byte before polling the status again. Callers must 186 * must hold applesmc_lock.
198 * hold applesmc_lock.
199 */ 187 */
200static int send_command(u8 cmd) 188static int send_byte(u8 cmd, u16 port)
201{ 189{
190 u8 status;
202 int us; 191 int us;
192
193 outb(cmd, port);
203 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { 194 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
204 outb(cmd, APPLESMC_CMD_PORT);
205 udelay(us); 195 udelay(us);
206 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) 196 status = inb(APPLESMC_CMD_PORT);
197 /* write: wait for smc to settle */
198 if (status & 0x02)
199 continue;
200 /* ready: cmd accepted, return */
201 if (status & 0x04)
207 return 0; 202 return 0;
203 /* timeout: give up */
204 if (us << 1 == APPLESMC_MAX_WAIT)
205 break;
206 /* busy: long wait and resend */
207 udelay(APPLESMC_RETRY_WAIT);
208 outb(cmd, port);
208 } 209 }
210
211 pr_warn("send_byte(0x%02x, 0x%04x) fail: 0x%02x\n", cmd, port, status);
209 return -EIO; 212 return -EIO;
210} 213}
211 214
215static int send_command(u8 cmd)
216{
217 return send_byte(cmd, APPLESMC_CMD_PORT);
218}
219
212static int send_argument(const char *key) 220static int send_argument(const char *key)
213{ 221{
214 int i; 222 int i;
215 223
216 for (i = 0; i < 4; i++) { 224 for (i = 0; i < 4; i++)
217 outb(key[i], APPLESMC_DATA_PORT); 225 if (send_byte(key[i], APPLESMC_DATA_PORT))
218 if (__wait_status(0x04))
219 return -EIO; 226 return -EIO;
220 }
221 return 0; 227 return 0;
222} 228}
223 229
@@ -226,15 +232,18 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
226 int i; 232 int i;
227 233
228 if (send_command(cmd) || send_argument(key)) { 234 if (send_command(cmd) || send_argument(key)) {
229 pr_warn("%s: read arg fail\n", key); 235 pr_warn("%.4s: read arg fail\n", key);
230 return -EIO; 236 return -EIO;
231 } 237 }
232 238
233 outb(len, APPLESMC_DATA_PORT); 239 if (send_byte(len, APPLESMC_DATA_PORT)) {
240 pr_warn("%.4s: read len fail\n", key);
241 return -EIO;
242 }
234 243
235 for (i = 0; i < len; i++) { 244 for (i = 0; i < len; i++) {
236 if (__wait_status(0x05)) { 245 if (wait_read()) {
237 pr_warn("%s: read data fail\n", key); 246 pr_warn("%.4s: read data[%d] fail\n", key, i);
238 return -EIO; 247 return -EIO;
239 } 248 }
240 buffer[i] = inb(APPLESMC_DATA_PORT); 249 buffer[i] = inb(APPLESMC_DATA_PORT);
@@ -252,14 +261,16 @@ static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
252 return -EIO; 261 return -EIO;
253 } 262 }
254 263
255 outb(len, APPLESMC_DATA_PORT); 264 if (send_byte(len, APPLESMC_DATA_PORT)) {
265 pr_warn("%.4s: write len fail\n", key);
266 return -EIO;
267 }
256 268
257 for (i = 0; i < len; i++) { 269 for (i = 0; i < len; i++) {
258 if (__wait_status(0x04)) { 270 if (send_byte(buffer[i], APPLESMC_DATA_PORT)) {
259 pr_warn("%s: write data fail\n", key); 271 pr_warn("%s: write data fail\n", key);
260 return -EIO; 272 return -EIO;
261 } 273 }
262 outb(buffer[i], APPLESMC_DATA_PORT);
263 } 274 }
264 275
265 return 0; 276 return 0;
@@ -355,8 +366,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
355 while (begin != end) { 366 while (begin != end) {
356 int middle = begin + (end - begin) / 2; 367 int middle = begin + (end - begin) / 2;
357 entry = applesmc_get_entry_by_index(middle); 368 entry = applesmc_get_entry_by_index(middle);
358 if (IS_ERR(entry)) 369 if (IS_ERR(entry)) {
370 *lo = 0;
359 return PTR_ERR(entry); 371 return PTR_ERR(entry);
372 }
360 if (strcmp(entry->key, key) < 0) 373 if (strcmp(entry->key, key) < 0)
361 begin = middle + 1; 374 begin = middle + 1;
362 else 375 else
@@ -375,8 +388,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
375 while (begin != end) { 388 while (begin != end) {
376 int middle = begin + (end - begin) / 2; 389 int middle = begin + (end - begin) / 2;
377 entry = applesmc_get_entry_by_index(middle); 390 entry = applesmc_get_entry_by_index(middle);
378 if (IS_ERR(entry)) 391 if (IS_ERR(entry)) {
392 *hi = smcreg.key_count;
379 return PTR_ERR(entry); 393 return PTR_ERR(entry);
394 }
380 if (strcmp(key, entry->key) < 0) 395 if (strcmp(key, entry->key) < 0)
381 end = middle; 396 end = middle;
382 else 397 else
@@ -439,30 +454,19 @@ static int applesmc_has_key(const char *key, bool *value)
439} 454}
440 455
441/* 456/*
442 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). 457 * applesmc_read_s16 - Read 16-bit signed big endian register
443 */ 458 */
444static int applesmc_read_motion_sensor(int index, s16* value) 459static int applesmc_read_s16(const char *key, s16 *value)
445{ 460{
446 u8 buffer[2]; 461 u8 buffer[2];
447 int ret; 462 int ret;
448 463
449 switch (index) { 464 ret = applesmc_read_key(key, buffer, 2);
450 case SENSOR_X: 465 if (ret)
451 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2); 466 return ret;
452 break;
453 case SENSOR_Y:
454 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
455 break;
456 case SENSOR_Z:
457 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
458 break;
459 default:
460 ret = -EINVAL;
461 }
462 467
463 *value = ((s16)buffer[0] << 8) | buffer[1]; 468 *value = ((s16)buffer[0] << 8) | buffer[1];
464 469 return 0;
465 return ret;
466} 470}
467 471
468/* 472/*
@@ -489,6 +493,30 @@ static void applesmc_device_init(void)
489 pr_warn("failed to init the device\n"); 493 pr_warn("failed to init the device\n");
490} 494}
491 495
496static int applesmc_init_index(struct applesmc_registers *s)
497{
498 const struct applesmc_entry *entry;
499 unsigned int i;
500
501 if (s->index)
502 return 0;
503
504 s->index = kcalloc(s->temp_count, sizeof(s->index[0]), GFP_KERNEL);
505 if (!s->index)
506 return -ENOMEM;
507
508 for (i = s->temp_begin; i < s->temp_end; i++) {
509 entry = applesmc_get_entry_by_index(i);
510 if (IS_ERR(entry))
511 continue;
512 if (strcmp(entry->type, TEMP_SENSOR_TYPE))
513 continue;
514 s->index[s->index_count++] = entry->key;
515 }
516
517 return 0;
518}
519
492/* 520/*
493 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. 521 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
494 */ 522 */
@@ -524,6 +552,10 @@ static int applesmc_init_smcreg_try(void)
524 return ret; 552 return ret;
525 s->temp_count = s->temp_end - s->temp_begin; 553 s->temp_count = s->temp_end - s->temp_begin;
526 554
555 ret = applesmc_init_index(s);
556 if (ret)
557 return ret;
558
527 ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); 559 ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
528 if (ret) 560 if (ret)
529 return ret; 561 return ret;
@@ -540,8 +572,8 @@ static int applesmc_init_smcreg_try(void)
540 s->num_light_sensors = left_light_sensor + right_light_sensor; 572 s->num_light_sensors = left_light_sensor + right_light_sensor;
541 s->init_complete = true; 573 s->init_complete = true;
542 574
543 pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n", 575 pr_info("key=%d fan=%d temp=%d index=%d acc=%d lux=%d kbd=%d\n",
544 s->key_count, s->fan_count, s->temp_count, 576 s->key_count, s->fan_count, s->temp_count, s->index_count,
545 s->has_accelerometer, 577 s->has_accelerometer,
546 s->num_light_sensors, 578 s->num_light_sensors,
547 s->has_key_backlight); 579 s->has_key_backlight);
@@ -549,6 +581,15 @@ static int applesmc_init_smcreg_try(void)
549 return 0; 581 return 0;
550} 582}
551 583
584static void applesmc_destroy_smcreg(void)
585{
586 kfree(smcreg.index);
587 smcreg.index = NULL;
588 kfree(smcreg.cache);
589 smcreg.cache = NULL;
590 smcreg.init_complete = false;
591}
592
552/* 593/*
553 * applesmc_init_smcreg - Initialize register cache. 594 * applesmc_init_smcreg - Initialize register cache.
554 * 595 *
@@ -569,19 +610,11 @@ static int applesmc_init_smcreg(void)
569 msleep(INIT_WAIT_MSECS); 610 msleep(INIT_WAIT_MSECS);
570 } 611 }
571 612
572 kfree(smcreg.cache); 613 applesmc_destroy_smcreg();
573 smcreg.cache = NULL;
574 614
575 return ret; 615 return ret;
576} 616}
577 617
578static void applesmc_destroy_smcreg(void)
579{
580 kfree(smcreg.cache);
581 smcreg.cache = NULL;
582 smcreg.init_complete = false;
583}
584
585/* Device model stuff */ 618/* Device model stuff */
586static int applesmc_probe(struct platform_device *dev) 619static int applesmc_probe(struct platform_device *dev)
587{ 620{
@@ -631,8 +664,8 @@ static struct platform_driver applesmc_driver = {
631 */ 664 */
632static void applesmc_calibrate(void) 665static void applesmc_calibrate(void)
633{ 666{
634 applesmc_read_motion_sensor(SENSOR_X, &rest_x); 667 applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x);
635 applesmc_read_motion_sensor(SENSOR_Y, &rest_y); 668 applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y);
636 rest_x = -rest_x; 669 rest_x = -rest_x;
637} 670}
638 671
@@ -641,9 +674,9 @@ static void applesmc_idev_poll(struct input_polled_dev *dev)
641 struct input_dev *idev = dev->input; 674 struct input_dev *idev = dev->input;
642 s16 x, y; 675 s16 x, y;
643 676
644 if (applesmc_read_motion_sensor(SENSOR_X, &x)) 677 if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x))
645 return; 678 return;
646 if (applesmc_read_motion_sensor(SENSOR_Y, &y)) 679 if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y))
647 return; 680 return;
648 681
649 x = -x; 682 x = -x;
@@ -666,13 +699,13 @@ static ssize_t applesmc_position_show(struct device *dev,
666 int ret; 699 int ret;
667 s16 x, y, z; 700 s16 x, y, z;
668 701
669 ret = applesmc_read_motion_sensor(SENSOR_X, &x); 702 ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x);
670 if (ret) 703 if (ret)
671 goto out; 704 goto out;
672 ret = applesmc_read_motion_sensor(SENSOR_Y, &y); 705 ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y);
673 if (ret) 706 if (ret)
674 goto out; 707 goto out;
675 ret = applesmc_read_motion_sensor(SENSOR_Z, &z); 708 ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z);
676 if (ret) 709 if (ret)
677 goto out; 710 goto out;
678 711
@@ -725,44 +758,27 @@ out:
725static ssize_t applesmc_show_sensor_label(struct device *dev, 758static ssize_t applesmc_show_sensor_label(struct device *dev,
726 struct device_attribute *devattr, char *sysfsbuf) 759 struct device_attribute *devattr, char *sysfsbuf)
727{ 760{
728 int index = smcreg.temp_begin + to_index(devattr); 761 const char *key = smcreg.index[to_index(devattr)];
729 const struct applesmc_entry *entry;
730
731 entry = applesmc_get_entry_by_index(index);
732 if (IS_ERR(entry))
733 return PTR_ERR(entry);
734 762
735 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); 763 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
736} 764}
737 765
738/* Displays degree Celsius * 1000 */ 766/* Displays degree Celsius * 1000 */
739static ssize_t applesmc_show_temperature(struct device *dev, 767static ssize_t applesmc_show_temperature(struct device *dev,
740 struct device_attribute *devattr, char *sysfsbuf) 768 struct device_attribute *devattr, char *sysfsbuf)
741{ 769{
742 int index = smcreg.temp_begin + to_index(devattr); 770 const char *key = smcreg.index[to_index(devattr)];
743 const struct applesmc_entry *entry;
744 int ret; 771 int ret;
745 u8 buffer[2]; 772 s16 value;
746 unsigned int temp; 773 int temp;
747 774
748 entry = applesmc_get_entry_by_index(index); 775 ret = applesmc_read_s16(key, &value);
749 if (IS_ERR(entry))
750 return PTR_ERR(entry);
751 if (entry->len > 2)
752 return -EINVAL;
753
754 ret = applesmc_read_entry(entry, buffer, entry->len);
755 if (ret) 776 if (ret)
756 return ret; 777 return ret;
757 778
758 if (entry->len == 2) { 779 temp = 250 * (value >> 6);
759 temp = buffer[0] * 1000;
760 temp += (buffer[1] >> 6) * 250;
761 } else {
762 temp = buffer[0] * 4000;
763 }
764 780
765 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); 781 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", temp);
766} 782}
767 783
768static ssize_t applesmc_show_fan_speed(struct device *dev, 784static ssize_t applesmc_show_fan_speed(struct device *dev,
@@ -789,14 +805,12 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
789 const char *sysfsbuf, size_t count) 805 const char *sysfsbuf, size_t count)
790{ 806{
791 int ret; 807 int ret;
792 u32 speed; 808 unsigned long speed;
793 char newkey[5]; 809 char newkey[5];
794 u8 buffer[2]; 810 u8 buffer[2];
795 811
796 speed = simple_strtoul(sysfsbuf, NULL, 10); 812 if (kstrtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000)
797 813 return -EINVAL; /* Bigger than a 14-bit value */
798 if (speed > 0x4000) /* Bigger than a 14-bit value */
799 return -EINVAL;
800 814
801 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); 815 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
802 816
@@ -832,10 +846,11 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
832{ 846{
833 int ret; 847 int ret;
834 u8 buffer[2]; 848 u8 buffer[2];
835 u32 input; 849 unsigned long input;
836 u16 val; 850 u16 val;
837 851
838 input = simple_strtoul(sysfsbuf, NULL, 10); 852 if (kstrtoul(sysfsbuf, 10, &input) < 0)
853 return -EINVAL;
839 854
840 ret = applesmc_read_key(FANS_MANUAL, buffer, 2); 855 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
841 val = (buffer[0] << 8 | buffer[1]); 856 val = (buffer[0] << 8 | buffer[1]);
@@ -987,8 +1002,13 @@ static ssize_t applesmc_key_at_index_show(struct device *dev,
987static ssize_t applesmc_key_at_index_store(struct device *dev, 1002static ssize_t applesmc_key_at_index_store(struct device *dev,
988 struct device_attribute *attr, const char *sysfsbuf, size_t count) 1003 struct device_attribute *attr, const char *sysfsbuf, size_t count)
989{ 1004{
990 key_at_index = simple_strtoul(sysfsbuf, NULL, 10); 1005 unsigned long newkey;
991 1006
1007 if (kstrtoul(sysfsbuf, 10, &newkey) < 0
1008 || newkey >= smcreg.key_count)
1009 return -EINVAL;
1010
1011 key_at_index = newkey;
992 return count; 1012 return count;
993} 1013}
994 1014
@@ -1079,6 +1099,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
1079 node->sda.dev_attr.show = grp->show; 1099 node->sda.dev_attr.show = grp->show;
1080 node->sda.dev_attr.store = grp->store; 1100 node->sda.dev_attr.store = grp->store;
1081 attr = &node->sda.dev_attr.attr; 1101 attr = &node->sda.dev_attr.attr;
1102 sysfs_attr_init(attr);
1082 attr->name = node->name; 1103 attr->name = node->name;
1083 attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0); 1104 attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0);
1084 ret = sysfs_create_file(&pdev->dev.kobj, attr); 1105 ret = sysfs_create_file(&pdev->dev.kobj, attr);
@@ -1195,32 +1216,34 @@ static int applesmc_dmi_match(const struct dmi_system_id *id)
1195 return 1; 1216 return 1;
1196} 1217}
1197 1218
1198/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". 1219/*
1199 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ 1220 * Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1221 * So we need to put "Apple MacBook Pro" before "Apple MacBook".
1222 */
1200static __initdata struct dmi_system_id applesmc_whitelist[] = { 1223static __initdata struct dmi_system_id applesmc_whitelist[] = {
1201 { applesmc_dmi_match, "Apple MacBook Air", { 1224 { applesmc_dmi_match, "Apple MacBook Air", {
1202 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1225 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1203 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, 1226 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1204 }, 1227 },
1205 { applesmc_dmi_match, "Apple MacBook Pro", { 1228 { applesmc_dmi_match, "Apple MacBook Pro", {
1206 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1229 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1207 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, 1230 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro") },
1208 }, 1231 },
1209 { applesmc_dmi_match, "Apple MacBook", { 1232 { applesmc_dmi_match, "Apple MacBook", {
1210 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1233 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1211 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, 1234 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") },
1212 }, 1235 },
1213 { applesmc_dmi_match, "Apple Macmini", { 1236 { applesmc_dmi_match, "Apple Macmini", {
1214 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1237 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1215 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, 1238 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") },
1216 }, 1239 },
1217 { applesmc_dmi_match, "Apple MacPro", { 1240 { applesmc_dmi_match, "Apple MacPro", {
1218 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1241 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1219 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, 1242 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1220 }, 1243 },
1221 { applesmc_dmi_match, "Apple iMac", { 1244 { applesmc_dmi_match, "Apple iMac", {
1222 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1245 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1223 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, 1246 DMI_MATCH(DMI_PRODUCT_NAME, "iMac") },
1224 }, 1247 },
1225 { .ident = NULL } 1248 { .ident = NULL }
1226}; 1249};
@@ -1265,7 +1288,7 @@ static int __init applesmc_init(void)
1265 if (ret) 1288 if (ret)
1266 goto out_info; 1289 goto out_info;
1267 1290
1268 ret = applesmc_create_nodes(temp_group, smcreg.temp_count); 1291 ret = applesmc_create_nodes(temp_group, smcreg.index_count);
1269 if (ret) 1292 if (ret)
1270 goto out_fans; 1293 goto out_fans;
1271 1294