diff options
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r-- | drivers/hwmon/applesmc.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 62c2e32e25ef..3288f13d2d87 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -230,6 +230,7 @@ static int send_argument(const char *key) | |||
230 | 230 | ||
231 | static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) | 231 | static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) |
232 | { | 232 | { |
233 | u8 status, data = 0; | ||
233 | int i; | 234 | int i; |
234 | 235 | ||
235 | if (send_command(cmd) || send_argument(key)) { | 236 | if (send_command(cmd) || send_argument(key)) { |
@@ -237,6 +238,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) | |||
237 | return -EIO; | 238 | return -EIO; |
238 | } | 239 | } |
239 | 240 | ||
241 | /* This has no effect on newer (2012) SMCs */ | ||
240 | if (send_byte(len, APPLESMC_DATA_PORT)) { | 242 | if (send_byte(len, APPLESMC_DATA_PORT)) { |
241 | pr_warn("%.4s: read len fail\n", key); | 243 | pr_warn("%.4s: read len fail\n", key); |
242 | return -EIO; | 244 | return -EIO; |
@@ -250,6 +252,17 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) | |||
250 | buffer[i] = inb(APPLESMC_DATA_PORT); | 252 | buffer[i] = inb(APPLESMC_DATA_PORT); |
251 | } | 253 | } |
252 | 254 | ||
255 | /* Read the data port until bit0 is cleared */ | ||
256 | for (i = 0; i < 16; i++) { | ||
257 | udelay(APPLESMC_MIN_WAIT); | ||
258 | status = inb(APPLESMC_CMD_PORT); | ||
259 | if (!(status & 0x01)) | ||
260 | break; | ||
261 | data = inb(APPLESMC_DATA_PORT); | ||
262 | } | ||
263 | if (i) | ||
264 | pr_warn("flushed %d bytes, last value is: %d\n", i, data); | ||
265 | |||
253 | return 0; | 266 | return 0; |
254 | } | 267 | } |
255 | 268 | ||
@@ -525,16 +538,25 @@ static int applesmc_init_smcreg_try(void) | |||
525 | { | 538 | { |
526 | struct applesmc_registers *s = &smcreg; | 539 | struct applesmc_registers *s = &smcreg; |
527 | bool left_light_sensor, right_light_sensor; | 540 | bool left_light_sensor, right_light_sensor; |
541 | unsigned int count; | ||
528 | u8 tmp[1]; | 542 | u8 tmp[1]; |
529 | int ret; | 543 | int ret; |
530 | 544 | ||
531 | if (s->init_complete) | 545 | if (s->init_complete) |
532 | return 0; | 546 | return 0; |
533 | 547 | ||
534 | ret = read_register_count(&s->key_count); | 548 | ret = read_register_count(&count); |
535 | if (ret) | 549 | if (ret) |
536 | return ret; | 550 | return ret; |
537 | 551 | ||
552 | if (s->cache && s->key_count != count) { | ||
553 | pr_warn("key count changed from %d to %d\n", | ||
554 | s->key_count, count); | ||
555 | kfree(s->cache); | ||
556 | s->cache = NULL; | ||
557 | } | ||
558 | s->key_count = count; | ||
559 | |||
538 | if (!s->cache) | 560 | if (!s->cache) |
539 | s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); | 561 | s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); |
540 | if (!s->cache) | 562 | if (!s->cache) |