diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 270 |
1 files changed, 95 insertions, 175 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 391f331674c7..f70796081c4c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -42,12 +42,12 @@ | |||
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | #include <linux/dmi.h> | ||
45 | 46 | ||
46 | #define ACPI_EC_CLASS "embedded_controller" | 47 | #define ACPI_EC_CLASS "embedded_controller" |
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 48 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 49 | #define ACPI_EC_FILE_INFO "info" |
49 | 50 | ||
50 | #undef PREFIX | ||
51 | #define PREFIX "ACPI: EC: " | 51 | #define PREFIX "ACPI: EC: " |
52 | 52 | ||
53 | /* EC status register */ | 53 | /* EC status register */ |
@@ -68,15 +68,13 @@ enum ec_command { | |||
68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
71 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
71 | 72 | ||
72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
73 | per one transaction */ | 74 | per one transaction */ |
74 | 75 | ||
75 | enum { | 76 | enum { |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
77 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent | ||
78 | * for status change */ | ||
79 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | ||
80 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
82 | * OpReg are installed */ | 80 | * OpReg are installed */ |
@@ -170,7 +168,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
170 | acpi_ec_write_cmd(ec, ec->curr->command); | 168 | acpi_ec_write_cmd(ec, ec->curr->command); |
171 | } | 169 | } |
172 | 170 | ||
173 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 171 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
174 | { | 172 | { |
175 | unsigned long flags; | 173 | unsigned long flags; |
176 | spin_lock_irqsave(&ec->curr_lock, flags); | 174 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -201,29 +199,6 @@ unlock: | |||
201 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 199 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
202 | } | 200 | } |
203 | 201 | ||
204 | static int acpi_ec_wait(struct acpi_ec *ec) | ||
205 | { | ||
206 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
207 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
208 | return 0; | ||
209 | /* try restart command if we get any false interrupts */ | ||
210 | if (ec->curr->irq_count && | ||
211 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
212 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
213 | start_transaction(ec); | ||
214 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
215 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
216 | return 0; | ||
217 | } | ||
218 | /* missing GPEs, switch back to poll mode */ | ||
219 | if (printk_ratelimit()) | ||
220 | pr_info(PREFIX "missing confirmations, " | ||
221 | "switch off interrupt mode.\n"); | ||
222 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
223 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | static void acpi_ec_gpe_query(void *ec_cxt); | 202 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | 203 | ||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 204 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -236,43 +211,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
236 | return 0; | 211 | return 0; |
237 | } | 212 | } |
238 | 213 | ||
239 | static void ec_delay(void) | ||
240 | { | ||
241 | /* EC in MSI notebooks don't tolerate delays other than 550 usec */ | ||
242 | if (EC_FLAGS_MSI) | ||
243 | udelay(ACPI_EC_DELAY); | ||
244 | else | ||
245 | /* Use shortest sleep available */ | ||
246 | msleep(1); | ||
247 | } | ||
248 | |||
249 | static int ec_poll(struct acpi_ec *ec) | 214 | static int ec_poll(struct acpi_ec *ec) |
250 | { | 215 | { |
251 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 216 | unsigned long flags; |
252 | udelay(ACPI_EC_CDELAY); | 217 | int repeat = 2; /* number of command restarts */ |
253 | while (time_before(jiffies, delay)) { | 218 | while (repeat--) { |
254 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 219 | unsigned long delay = jiffies + |
255 | ec_delay(); | 220 | msecs_to_jiffies(ACPI_EC_DELAY); |
256 | if (ec_transaction_done(ec)) | 221 | do { |
257 | return 0; | 222 | /* don't sleep with disabled interrupts */ |
223 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
224 | udelay(ACPI_EC_MSI_UDELAY); | ||
225 | if (ec_transaction_done(ec)) | ||
226 | return 0; | ||
227 | } else { | ||
228 | if (wait_event_timeout(ec->wait, | ||
229 | ec_transaction_done(ec), | ||
230 | msecs_to_jiffies(1))) | ||
231 | return 0; | ||
232 | } | ||
233 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
234 | } while (time_before(jiffies, delay)); | ||
235 | if (!ec->curr->irq_count || | ||
236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
237 | break; | ||
238 | /* try restart command if we get any false interrupts */ | ||
239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
240 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
241 | start_transaction(ec); | ||
242 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
258 | } | 243 | } |
259 | return -ETIME; | 244 | return -ETIME; |
260 | } | 245 | } |
261 | 246 | ||
262 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 247 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
263 | struct transaction *t, | 248 | struct transaction *t) |
264 | int force_poll) | ||
265 | { | 249 | { |
266 | unsigned long tmp; | 250 | unsigned long tmp; |
267 | int ret = 0; | 251 | int ret = 0; |
268 | pr_debug(PREFIX "transaction start\n"); | 252 | pr_debug(PREFIX "transaction start\n"); |
269 | /* disable GPE during transaction if storm is detected */ | 253 | /* disable GPE during transaction if storm is detected */ |
270 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 254 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
271 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
272 | acpi_disable_gpe(NULL, ec->gpe); | 255 | acpi_disable_gpe(NULL, ec->gpe); |
273 | } | 256 | } |
274 | if (EC_FLAGS_MSI) | 257 | if (EC_FLAGS_MSI) |
275 | udelay(ACPI_EC_DELAY); | 258 | udelay(ACPI_EC_MSI_UDELAY); |
276 | /* start transaction */ | 259 | /* start transaction */ |
277 | spin_lock_irqsave(&ec->curr_lock, tmp); | 260 | spin_lock_irqsave(&ec->curr_lock, tmp); |
278 | /* following two actions should be kept atomic */ | 261 | /* following two actions should be kept atomic */ |
@@ -281,11 +264,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
281 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 264 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
282 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 265 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
283 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 266 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
284 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 267 | ret = ec_poll(ec); |
285 | if (force_poll || | ||
286 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || | ||
287 | acpi_ec_wait(ec)) | ||
288 | ret = ec_poll(ec); | ||
289 | pr_debug(PREFIX "transaction end\n"); | 268 | pr_debug(PREFIX "transaction end\n"); |
290 | spin_lock_irqsave(&ec->curr_lock, tmp); | 269 | spin_lock_irqsave(&ec->curr_lock, tmp); |
291 | ec->curr = NULL; | 270 | ec->curr = NULL; |
@@ -295,8 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
295 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 274 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
296 | /* it is safe to enable GPE outside of transaction */ | 275 | /* it is safe to enable GPE outside of transaction */ |
297 | acpi_enable_gpe(NULL, ec->gpe); | 276 | acpi_enable_gpe(NULL, ec->gpe); |
298 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 277 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
299 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
300 | pr_info(PREFIX "GPE storm detected, " | 278 | pr_info(PREFIX "GPE storm detected, " |
301 | "transactions will use polling mode\n"); | 279 | "transactions will use polling mode\n"); |
302 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 280 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -314,16 +292,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
314 | { | 292 | { |
315 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 293 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
316 | /* interrupt wait manually if GPE mode is not active */ | 294 | /* interrupt wait manually if GPE mode is not active */ |
317 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
318 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
319 | while (time_before(jiffies, delay)) | 295 | while (time_before(jiffies, delay)) |
320 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 296 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
297 | msecs_to_jiffies(1))) | ||
321 | return 0; | 298 | return 0; |
322 | return -ETIME; | 299 | return -ETIME; |
323 | } | 300 | } |
324 | 301 | ||
325 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 302 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
326 | int force_poll) | ||
327 | { | 303 | { |
328 | int status; | 304 | int status; |
329 | u32 glk; | 305 | u32 glk; |
@@ -345,7 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
345 | status = -ETIME; | 321 | status = -ETIME; |
346 | goto end; | 322 | goto end; |
347 | } | 323 | } |
348 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 324 | status = acpi_ec_transaction_unlocked(ec, t); |
349 | end: | 325 | end: |
350 | if (ec->global_lock) | 326 | if (ec->global_lock) |
351 | acpi_release_global_lock(glk); | 327 | acpi_release_global_lock(glk); |
@@ -354,10 +330,6 @@ unlock: | |||
354 | return status; | 330 | return status; |
355 | } | 331 | } |
356 | 332 | ||
357 | /* | ||
358 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
359 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
360 | */ | ||
361 | static int acpi_ec_burst_enable(struct acpi_ec *ec) | 333 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
362 | { | 334 | { |
363 | u8 d; | 335 | u8 d; |
@@ -365,7 +337,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
365 | .wdata = NULL, .rdata = &d, | 337 | .wdata = NULL, .rdata = &d, |
366 | .wlen = 0, .rlen = 1}; | 338 | .wlen = 0, .rlen = 1}; |
367 | 339 | ||
368 | return acpi_ec_transaction(ec, &t, 0); | 340 | return acpi_ec_transaction(ec, &t); |
369 | } | 341 | } |
370 | 342 | ||
371 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 343 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -375,7 +347,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
375 | .wlen = 0, .rlen = 0}; | 347 | .wlen = 0, .rlen = 0}; |
376 | 348 | ||
377 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 349 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
378 | acpi_ec_transaction(ec, &t, 0) : 0; | 350 | acpi_ec_transaction(ec, &t) : 0; |
379 | } | 351 | } |
380 | 352 | ||
381 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 353 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -386,7 +358,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
386 | .wdata = &address, .rdata = &d, | 358 | .wdata = &address, .rdata = &d, |
387 | .wlen = 1, .rlen = 1}; | 359 | .wlen = 1, .rlen = 1}; |
388 | 360 | ||
389 | result = acpi_ec_transaction(ec, &t, 0); | 361 | result = acpi_ec_transaction(ec, &t); |
390 | *data = d; | 362 | *data = d; |
391 | return result; | 363 | return result; |
392 | } | 364 | } |
@@ -398,7 +370,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
398 | .wdata = wdata, .rdata = NULL, | 370 | .wdata = wdata, .rdata = NULL, |
399 | .wlen = 2, .rlen = 0}; | 371 | .wlen = 2, .rlen = 0}; |
400 | 372 | ||
401 | return acpi_ec_transaction(ec, &t, 0); | 373 | return acpi_ec_transaction(ec, &t); |
402 | } | 374 | } |
403 | 375 | ||
404 | /* | 376 | /* |
@@ -466,7 +438,7 @@ int ec_transaction(u8 command, | |||
466 | if (!first_ec) | 438 | if (!first_ec) |
467 | return -ENODEV; | 439 | return -ENODEV; |
468 | 440 | ||
469 | return acpi_ec_transaction(first_ec, &t, force_poll); | 441 | return acpi_ec_transaction(first_ec, &t); |
470 | } | 442 | } |
471 | 443 | ||
472 | EXPORT_SYMBOL(ec_transaction); | 444 | EXPORT_SYMBOL(ec_transaction); |
@@ -487,7 +459,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
487 | * bit to be cleared (and thus clearing the interrupt source). | 459 | * bit to be cleared (and thus clearing the interrupt source). |
488 | */ | 460 | */ |
489 | 461 | ||
490 | result = acpi_ec_transaction(ec, &t, 0); | 462 | result = acpi_ec_transaction(ec, &t); |
491 | if (result) | 463 | if (result) |
492 | return result; | 464 | return result; |
493 | 465 | ||
@@ -570,28 +542,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
570 | pr_debug(PREFIX "~~~> interrupt\n"); | 542 | pr_debug(PREFIX "~~~> interrupt\n"); |
571 | status = acpi_ec_read_status(ec); | 543 | status = acpi_ec_read_status(ec); |
572 | 544 | ||
573 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 545 | advance_transaction(ec, status); |
574 | gpe_transaction(ec, status); | 546 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
575 | if (ec_transaction_done(ec) && | 547 | wake_up(&ec->wait); |
576 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
577 | wake_up(&ec->wait); | ||
578 | } | ||
579 | |||
580 | ec_check_sci(ec, status); | 548 | ec_check_sci(ec, status); |
581 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
582 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | ||
583 | /* this is non-query, must be confirmation */ | ||
584 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
585 | if (printk_ratelimit()) | ||
586 | pr_info(PREFIX "non-query interrupt received," | ||
587 | " switching to interrupt mode\n"); | ||
588 | } else { | ||
589 | /* hush, STORM switches the mode every transaction */ | ||
590 | pr_debug(PREFIX "non-query interrupt received," | ||
591 | " switching to interrupt mode\n"); | ||
592 | } | ||
593 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
594 | } | ||
595 | return ACPI_INTERRUPT_HANDLED; | 549 | return ACPI_INTERRUPT_HANDLED; |
596 | } | 550 | } |
597 | 551 | ||
@@ -617,7 +571,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
617 | if (bits != 8 && acpi_strict) | 571 | if (bits != 8 && acpi_strict) |
618 | return AE_BAD_PARAMETER; | 572 | return AE_BAD_PARAMETER; |
619 | 573 | ||
620 | acpi_ec_burst_enable(ec); | 574 | if (EC_FLAGS_MSI) |
575 | acpi_ec_burst_enable(ec); | ||
621 | 576 | ||
622 | if (function == ACPI_READ) { | 577 | if (function == ACPI_READ) { |
623 | result = acpi_ec_read(ec, address, &temp); | 578 | result = acpi_ec_read(ec, address, &temp); |
@@ -638,7 +593,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
638 | } | 593 | } |
639 | } | 594 | } |
640 | 595 | ||
641 | acpi_ec_burst_disable(ec); | 596 | if (EC_FLAGS_MSI) |
597 | acpi_ec_burst_disable(ec); | ||
642 | 598 | ||
643 | switch (result) { | 599 | switch (result) { |
644 | case -EINVAL: | 600 | case -EINVAL: |
@@ -788,6 +744,42 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
788 | return AE_CTRL_TERMINATE; | 744 | return AE_CTRL_TERMINATE; |
789 | } | 745 | } |
790 | 746 | ||
747 | static int ec_install_handlers(struct acpi_ec *ec) | ||
748 | { | ||
749 | acpi_status status; | ||
750 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
751 | return 0; | ||
752 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
753 | ACPI_GPE_EDGE_TRIGGERED, | ||
754 | &acpi_ec_gpe_handler, ec); | ||
755 | if (ACPI_FAILURE(status)) | ||
756 | return -ENODEV; | ||
757 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
758 | acpi_enable_gpe(NULL, ec->gpe); | ||
759 | status = acpi_install_address_space_handler(ec->handle, | ||
760 | ACPI_ADR_SPACE_EC, | ||
761 | &acpi_ec_space_handler, | ||
762 | NULL, ec); | ||
763 | if (ACPI_FAILURE(status)) { | ||
764 | if (status == AE_NOT_FOUND) { | ||
765 | /* | ||
766 | * Maybe OS fails in evaluating the _REG object. | ||
767 | * The AE_NOT_FOUND error will be ignored and OS | ||
768 | * continue to initialize EC. | ||
769 | */ | ||
770 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
771 | " of EC device. Broken bios is suspected.\n"); | ||
772 | } else { | ||
773 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
774 | &acpi_ec_gpe_handler); | ||
775 | return -ENODEV; | ||
776 | } | ||
777 | } | ||
778 | |||
779 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
791 | static void ec_remove_handlers(struct acpi_ec *ec) | 783 | static void ec_remove_handlers(struct acpi_ec *ec) |
792 | { | 784 | { |
793 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 785 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
@@ -802,9 +794,8 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
802 | static int acpi_ec_add(struct acpi_device *device) | 794 | static int acpi_ec_add(struct acpi_device *device) |
803 | { | 795 | { |
804 | struct acpi_ec *ec = NULL; | 796 | struct acpi_ec *ec = NULL; |
797 | int ret; | ||
805 | 798 | ||
806 | if (!device) | ||
807 | return -EINVAL; | ||
808 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 799 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
809 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 800 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
810 | 801 | ||
@@ -837,9 +828,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
837 | acpi_ec_add_fs(device); | 828 | acpi_ec_add_fs(device); |
838 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 829 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
839 | ec->gpe, ec->command_addr, ec->data_addr); | 830 | ec->gpe, ec->command_addr, ec->data_addr); |
840 | pr_info(PREFIX "driver started in %s mode\n", | 831 | |
841 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 832 | ret = ec_install_handlers(ec); |
842 | return 0; | 833 | |
834 | /* EC is fully operational, allow queries */ | ||
835 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
836 | return ret; | ||
843 | } | 837 | } |
844 | 838 | ||
845 | static int acpi_ec_remove(struct acpi_device *device, int type) | 839 | static int acpi_ec_remove(struct acpi_device *device, int type) |
@@ -851,6 +845,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
851 | return -EINVAL; | 845 | return -EINVAL; |
852 | 846 | ||
853 | ec = acpi_driver_data(device); | 847 | ec = acpi_driver_data(device); |
848 | ec_remove_handlers(ec); | ||
854 | mutex_lock(&ec->lock); | 849 | mutex_lock(&ec->lock); |
855 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 850 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
856 | list_del(&handler->node); | 851 | list_del(&handler->node); |
@@ -888,75 +883,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
888 | return AE_OK; | 883 | return AE_OK; |
889 | } | 884 | } |
890 | 885 | ||
891 | static int ec_install_handlers(struct acpi_ec *ec) | ||
892 | { | ||
893 | acpi_status status; | ||
894 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
895 | return 0; | ||
896 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
897 | ACPI_GPE_EDGE_TRIGGERED, | ||
898 | &acpi_ec_gpe_handler, ec); | ||
899 | if (ACPI_FAILURE(status)) | ||
900 | return -ENODEV; | ||
901 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
902 | acpi_enable_gpe(NULL, ec->gpe); | ||
903 | status = acpi_install_address_space_handler(ec->handle, | ||
904 | ACPI_ADR_SPACE_EC, | ||
905 | &acpi_ec_space_handler, | ||
906 | NULL, ec); | ||
907 | if (ACPI_FAILURE(status)) { | ||
908 | if (status == AE_NOT_FOUND) { | ||
909 | /* | ||
910 | * Maybe OS fails in evaluating the _REG object. | ||
911 | * The AE_NOT_FOUND error will be ignored and OS | ||
912 | * continue to initialize EC. | ||
913 | */ | ||
914 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
915 | " of EC device. Broken bios is suspected.\n"); | ||
916 | } else { | ||
917 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
918 | &acpi_ec_gpe_handler); | ||
919 | return -ENODEV; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int acpi_ec_start(struct acpi_device *device) | ||
928 | { | ||
929 | struct acpi_ec *ec; | ||
930 | int ret = 0; | ||
931 | |||
932 | if (!device) | ||
933 | return -EINVAL; | ||
934 | |||
935 | ec = acpi_driver_data(device); | ||
936 | |||
937 | if (!ec) | ||
938 | return -EINVAL; | ||
939 | |||
940 | ret = ec_install_handlers(ec); | ||
941 | |||
942 | /* EC is fully operational, allow queries */ | ||
943 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | static int acpi_ec_stop(struct acpi_device *device, int type) | ||
948 | { | ||
949 | struct acpi_ec *ec; | ||
950 | if (!device) | ||
951 | return -EINVAL; | ||
952 | ec = acpi_driver_data(device); | ||
953 | if (!ec) | ||
954 | return -EINVAL; | ||
955 | ec_remove_handlers(ec); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | int __init acpi_boot_ec_enable(void) | 886 | int __init acpi_boot_ec_enable(void) |
961 | { | 887 | { |
962 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 888 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
@@ -1054,8 +980,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1054 | { | 980 | { |
1055 | struct acpi_ec *ec = acpi_driver_data(device); | 981 | struct acpi_ec *ec = acpi_driver_data(device); |
1056 | /* Stop using GPE */ | 982 | /* Stop using GPE */ |
1057 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1058 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1059 | acpi_disable_gpe(NULL, ec->gpe); | 983 | acpi_disable_gpe(NULL, ec->gpe); |
1060 | return 0; | 984 | return 0; |
1061 | } | 985 | } |
@@ -1064,8 +988,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1064 | { | 988 | { |
1065 | struct acpi_ec *ec = acpi_driver_data(device); | 989 | struct acpi_ec *ec = acpi_driver_data(device); |
1066 | /* Enable use of GPE back */ | 990 | /* Enable use of GPE back */ |
1067 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1068 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1069 | acpi_enable_gpe(NULL, ec->gpe); | 991 | acpi_enable_gpe(NULL, ec->gpe); |
1070 | return 0; | 992 | return 0; |
1071 | } | 993 | } |
@@ -1077,8 +999,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1077 | .ops = { | 999 | .ops = { |
1078 | .add = acpi_ec_add, | 1000 | .add = acpi_ec_add, |
1079 | .remove = acpi_ec_remove, | 1001 | .remove = acpi_ec_remove, |
1080 | .start = acpi_ec_start, | ||
1081 | .stop = acpi_ec_stop, | ||
1082 | .suspend = acpi_ec_suspend, | 1002 | .suspend = acpi_ec_suspend, |
1083 | .resume = acpi_ec_resume, | 1003 | .resume = acpi_ec_resume, |
1084 | }, | 1004 | }, |