aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLuming Yu <luming.yu@intel.com>2005-08-10 01:40:00 -0400
committerLen Brown <len.brown@intel.com>2005-08-11 17:30:51 -0400
commit716e084edb0230910b174000dc3490f9e91652e3 (patch)
treea3f5c00b87efa64a26127c9bc1c73d3a51d703cd /drivers/acpi
parentcbfc1bae55bbd053308ef0fa6b6448cd1ddf3e67 (diff)
[ACPI] Fix "ec_burst=1" mode latency issue
http://bugzilla.kernel.org/show_bug.cgi?id=3851 Signed-off-by: Luming Yu <luming.yu@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ec.c169
1 files changed, 59 insertions, 110 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1ac5731d45e5..31067a0a3671 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -234,18 +234,29 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
234 ec->burst.expect_event = event; 234 ec->burst.expect_event = event;
235 smp_mb(); 235 smp_mb();
236 236
237 result = wait_event_interruptible_timeout(ec->burst.wait, 237 switch (event) {
238 case ACPI_EC_EVENT_OBF:
239 if (acpi_ec_read_status(ec) & event) {
240 ec->burst.expect_event = 0;
241 return_VALUE(0);
242 }
243 break;
244
245 case ACPI_EC_EVENT_IBE:
246 if (~acpi_ec_read_status(ec) & event) {
247 ec->burst.expect_event = 0;
248 return_VALUE(0);
249 }
250 break;
251 }
252
253 result = wait_event_timeout(ec->burst.wait,
238 !ec->burst.expect_event, 254 !ec->burst.expect_event,
239 msecs_to_jiffies(ACPI_EC_DELAY)); 255 msecs_to_jiffies(ACPI_EC_DELAY));
240 256
241 ec->burst.expect_event = 0; 257 ec->burst.expect_event = 0;
242 smp_mb(); 258 smp_mb();
243 259
244 if (result < 0){
245 ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result = %d ", result));
246 return_VALUE(result);
247 }
248
249 /* 260 /*
250 * Verify that the event in question has actually happened by 261 * Verify that the event in question has actually happened by
251 * querying EC status. Do the check even if operation timed-out 262 * querying EC status. Do the check even if operation timed-out
@@ -280,14 +291,14 @@ acpi_ec_enter_burst_mode (
280 status = acpi_ec_read_status(ec); 291 status = acpi_ec_read_status(ec);
281 if (status != -EINVAL && 292 if (status != -EINVAL &&
282 !(status & ACPI_EC_FLAG_BURST)){ 293 !(status & ACPI_EC_FLAG_BURST)){
294 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
295 if(status)
296 goto end;
283 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); 297 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
284 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 298 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
285 if (status){ 299 if (status)
286 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
287 return_VALUE(-EINVAL); 300 return_VALUE(-EINVAL);
288 }
289 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); 301 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
290 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
291 if(tmp != 0x90 ) {/* Burst ACK byte*/ 302 if(tmp != 0x90 ) {/* Burst ACK byte*/
292 return_VALUE(-EINVAL); 303 return_VALUE(-EINVAL);
293 } 304 }
@@ -295,31 +306,19 @@ acpi_ec_enter_burst_mode (
295 306
296 atomic_set(&ec->burst.leaving_burst , 0); 307 atomic_set(&ec->burst.leaving_burst , 0);
297 return_VALUE(0); 308 return_VALUE(0);
309end:
310 printk("Error in acpi_ec_wait\n");
311 return_VALUE(-1);
298} 312}
299 313
300static int 314static int
301acpi_ec_leave_burst_mode ( 315acpi_ec_leave_burst_mode (
302 union acpi_ec *ec) 316 union acpi_ec *ec)
303{ 317{
304 int status =0;
305 318
306 ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); 319 ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
307 320
308 atomic_set(&ec->burst.leaving_burst , 1); 321 atomic_set(&ec->burst.leaving_burst, 1);
309 status = acpi_ec_read_status(ec);
310 if (status != -EINVAL &&
311 (status & ACPI_EC_FLAG_BURST)){
312 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
313 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
314 if (status){
315 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
316 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
317 return_VALUE(-EINVAL);
318 }
319 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
320 status = acpi_ec_read_status(ec);
321 }
322
323 return_VALUE(0); 322 return_VALUE(0);
324} 323}
325 324
@@ -461,7 +460,6 @@ acpi_ec_burst_read (
461 if (!ec || !data) 460 if (!ec || !data)
462 return_VALUE(-EINVAL); 461 return_VALUE(-EINVAL);
463 462
464retry:
465 *data = 0; 463 *data = 0;
466 464
467 if (ec->common.global_lock) { 465 if (ec->common.global_lock) {
@@ -473,26 +471,25 @@ retry:
473 WARN_ON(in_interrupt()); 471 WARN_ON(in_interrupt());
474 down(&ec->burst.sem); 472 down(&ec->burst.sem);
475 473
476 if(acpi_ec_enter_burst_mode(ec)) 474 acpi_ec_enter_burst_mode(ec);
475 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
476 if (status) {
477 printk("read EC, IB not empty\n");
477 goto end; 478 goto end;
478 479 }
479 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); 480 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
480 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 481 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
481 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
482 if (status) { 482 if (status) {
483 goto end; 483 printk("read EC, IB not empty\n");
484 } 484 }
485 485
486 acpi_hw_low_level_write(8, address, &ec->common.data_addr); 486 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
487 status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 487 status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
488 if (status){ 488 if (status){
489 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 489 printk("read EC, OB not full\n");
490 goto end; 490 goto end;
491 } 491 }
492
493 acpi_hw_low_level_read(8, data, &ec->common.data_addr); 492 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
494 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
495
496 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", 493 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
497 *data, address)); 494 *data, address));
498 495
@@ -503,15 +500,6 @@ end:
503 if (ec->common.global_lock) 500 if (ec->common.global_lock)
504 acpi_release_global_lock(glk); 501 acpi_release_global_lock(glk);
505 502
506 if(atomic_read(&ec->burst.leaving_burst) == 2){
507 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
508 while(atomic_read(&ec->burst.pending_gpe)){
509 msleep(1);
510 }
511 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
512 goto retry;
513 }
514
515 return_VALUE(status); 503 return_VALUE(status);
516} 504}
517 505
@@ -524,13 +512,12 @@ acpi_ec_burst_write (
524{ 512{
525 int status = 0; 513 int status = 0;
526 u32 glk; 514 u32 glk;
527 u32 tmp;
528 515
529 ACPI_FUNCTION_TRACE("acpi_ec_write"); 516 ACPI_FUNCTION_TRACE("acpi_ec_write");
530 517
531 if (!ec) 518 if (!ec)
532 return_VALUE(-EINVAL); 519 return_VALUE(-EINVAL);
533retry: 520
534 if (ec->common.global_lock) { 521 if (ec->common.global_lock) {
535 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 522 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
536 if (ACPI_FAILURE(status)) 523 if (ACPI_FAILURE(status))
@@ -540,61 +527,35 @@ retry:
540 WARN_ON(in_interrupt()); 527 WARN_ON(in_interrupt());
541 down(&ec->burst.sem); 528 down(&ec->burst.sem);
542 529
543 if(acpi_ec_enter_burst_mode(ec)) 530 acpi_ec_enter_burst_mode(ec);
544 goto end;
545 531
546 status = acpi_ec_read_status(ec); 532 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
547 if (status != -EINVAL && 533 if ( status) {
548 !(status & ACPI_EC_FLAG_BURST)){ 534 printk("write EC, IB not empty\n");
549 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
550 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
551 if (status)
552 goto end;
553 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
554 if(tmp != 0x90 ) /* Burst ACK byte*/
555 goto end;
556 } 535 }
557 /*Now we are in burst mode*/
558
559 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); 536 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
560 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 537 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
561 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 538 if (status) {
562 if (status){ 539 printk ("write EC, IB not empty\n");
563 goto end;
564 } 540 }
565 541
566 acpi_hw_low_level_write(8, address, &ec->common.data_addr); 542 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
567 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 543 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
568 if (status){ 544 if (status){
569 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 545 printk("write EC, IB not empty\n");
570 goto end;
571 } 546 }
572 547
573 acpi_hw_low_level_write(8, data, &ec->common.data_addr); 548 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
574 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
575 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
576 if (status)
577 goto end;
578 549
579 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 550 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
580 data, address)); 551 data, address));
581 552
582end:
583 acpi_ec_leave_burst_mode(ec); 553 acpi_ec_leave_burst_mode(ec);
584 up(&ec->burst.sem); 554 up(&ec->burst.sem);
585 555
586 if (ec->common.global_lock) 556 if (ec->common.global_lock)
587 acpi_release_global_lock(glk); 557 acpi_release_global_lock(glk);
588 558
589 if(atomic_read(&ec->burst.leaving_burst) == 2){
590 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
591 while(atomic_read(&ec->burst.pending_gpe)){
592 msleep(1);
593 }
594 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
595 goto retry;
596 }
597
598 return_VALUE(status); 559 return_VALUE(status);
599} 560}
600 561
@@ -719,8 +680,12 @@ acpi_ec_burst_query (
719 } 680 }
720 681
721 down(&ec->burst.sem); 682 down(&ec->burst.sem);
722 if(acpi_ec_enter_burst_mode(ec)) 683
684 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
685 if (status) {
686 printk("query EC, IB not empty\n");
723 goto end; 687 goto end;
688 }
724 /* 689 /*
725 * Query the EC to find out which _Qxx method we need to evaluate. 690 * Query the EC to find out which _Qxx method we need to evaluate.
726 * Note that successful completion of the query causes the ACPI_EC_SCI 691 * Note that successful completion of the query causes the ACPI_EC_SCI
@@ -729,27 +694,20 @@ acpi_ec_burst_query (
729 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); 694 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
730 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 695 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
731 if (status){ 696 if (status){
732 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 697 printk("query EC, OB not full\n");
733 goto end; 698 goto end;
734 } 699 }
735 700
736 acpi_hw_low_level_read(8, data, &ec->common.data_addr); 701 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
737 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
738 if (!*data) 702 if (!*data)
739 status = -ENODATA; 703 status = -ENODATA;
740 704
741end: 705end:
742 acpi_ec_leave_burst_mode(ec);
743 up(&ec->burst.sem); 706 up(&ec->burst.sem);
744 707
745 if (ec->common.global_lock) 708 if (ec->common.global_lock)
746 acpi_release_global_lock(glk); 709 acpi_release_global_lock(glk);
747 710
748 if(atomic_read(&ec->burst.leaving_burst) == 2){
749 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
750 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
751 status = -ENODATA;
752 }
753 return_VALUE(status); 711 return_VALUE(status);
754} 712}
755 713
@@ -885,31 +843,21 @@ acpi_ec_gpe_burst_handler (
885 if (!ec) 843 if (!ec)
886 return ACPI_INTERRUPT_NOT_HANDLED; 844 return ACPI_INTERRUPT_NOT_HANDLED;
887 845
888 acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); 846 acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
889
890 value = acpi_ec_read_status(ec); 847 value = acpi_ec_read_status(ec);
891 848
892 if((value & ACPI_EC_FLAG_IBF) && 849 switch ( ec->burst.expect_event) {
893 !(value & ACPI_EC_FLAG_BURST) && 850 case ACPI_EC_EVENT_OBF:
894 (atomic_read(&ec->burst.leaving_burst) == 0)) { 851 if (!(value & ACPI_EC_FLAG_OBF))
895 /* 852 break;
896 * the embedded controller disables 853 case ACPI_EC_EVENT_IBE:
897 * burst mode for any reason other 854 if ((value & ACPI_EC_FLAG_IBF))
898 * than the burst disable command 855 break;
899 * to process critical event. 856 ec->burst.expect_event = 0;
900 */
901 atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
902 and retry */
903 wake_up(&ec->burst.wait); 857 wake_up(&ec->burst.wait);
904 }else { 858 return ACPI_INTERRUPT_HANDLED;
905 if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF && 859 default:
906 (value & ACPI_EC_FLAG_OBF)) || 860 break;
907 (ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
908 !(value & ACPI_EC_FLAG_IBF))) {
909 ec->burst.expect_event = 0;
910 wake_up(&ec->burst.wait);
911 return ACPI_INTERRUPT_HANDLED;
912 }
913 } 861 }
914 862
915 if (value & ACPI_EC_FLAG_SCI){ 863 if (value & ACPI_EC_FLAG_SCI){
@@ -1242,6 +1190,7 @@ acpi_ec_burst_add (
1242 if (result) 1190 if (result)
1243 goto end; 1191 goto end;
1244 1192
1193 printk("burst-mode-ec-10-Aug\n");
1245 printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", 1194 printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
1246 acpi_device_name(device), acpi_device_bid(device), 1195 acpi_device_name(device), acpi_device_bid(device),
1247 (u32) ec->common.gpe_bit); 1196 (u32) ec->common.gpe_bit);