diff options
author | Rich Townsend <rhdt@bartol.udel.edu> | 2005-12-19 23:07:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-05-19 00:49:52 -0400 |
commit | f9a6ee1afb84fd767508428ec5d1df4fb60a03ad (patch) | |
tree | 5180efc6208c58676001b637fec8bba7ba542f33 /drivers/acpi/ec.c | |
parent | a54c9d30dbb06391ec4422aaf0e1dc2c8c53bd3e (diff) |
ACPI: replace spin_lock_irq with mutex for ec poll mode
http://bugzilla.kernel.org/show_bug.cgi?id=5764
Signed-off-by: Luming Yu <luming.yu@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index eee0864ba300..d2638209c604 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -116,7 +116,7 @@ union acpi_ec { | |||
116 | struct acpi_generic_address command_addr; | 116 | struct acpi_generic_address command_addr; |
117 | struct acpi_generic_address data_addr; | 117 | struct acpi_generic_address data_addr; |
118 | unsigned long global_lock; | 118 | unsigned long global_lock; |
119 | spinlock_t lock; | 119 | struct semaphore sem; |
120 | } poll; | 120 | } poll; |
121 | }; | 121 | }; |
122 | 122 | ||
@@ -323,7 +323,6 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) | |||
323 | { | 323 | { |
324 | acpi_status status = AE_OK; | 324 | acpi_status status = AE_OK; |
325 | int result = 0; | 325 | int result = 0; |
326 | unsigned long flags = 0; | ||
327 | u32 glk = 0; | 326 | u32 glk = 0; |
328 | 327 | ||
329 | ACPI_FUNCTION_TRACE("acpi_ec_read"); | 328 | ACPI_FUNCTION_TRACE("acpi_ec_read"); |
@@ -339,8 +338,11 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) | |||
339 | return_VALUE(-ENODEV); | 338 | return_VALUE(-ENODEV); |
340 | } | 339 | } |
341 | 340 | ||
342 | spin_lock_irqsave(&ec->poll.lock, flags); | 341 | if (down_interruptible(&ec->poll.sem)) { |
343 | 342 | result = -ERESTARTSYS; | |
343 | goto end_nosem; | ||
344 | } | ||
345 | |||
344 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, | 346 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, |
345 | &ec->common.command_addr); | 347 | &ec->common.command_addr); |
346 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 348 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
@@ -358,8 +360,8 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) | |||
358 | *data, address)); | 360 | *data, address)); |
359 | 361 | ||
360 | end: | 362 | end: |
361 | spin_unlock_irqrestore(&ec->poll.lock, flags); | 363 | up(&ec->poll.sem); |
362 | 364 | end_nosem: | |
363 | if (ec->common.global_lock) | 365 | if (ec->common.global_lock) |
364 | acpi_release_global_lock(glk); | 366 | acpi_release_global_lock(glk); |
365 | 367 | ||
@@ -370,7 +372,6 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) | |||
370 | { | 372 | { |
371 | int result = 0; | 373 | int result = 0; |
372 | acpi_status status = AE_OK; | 374 | acpi_status status = AE_OK; |
373 | unsigned long flags = 0; | ||
374 | u32 glk = 0; | 375 | u32 glk = 0; |
375 | 376 | ||
376 | ACPI_FUNCTION_TRACE("acpi_ec_write"); | 377 | ACPI_FUNCTION_TRACE("acpi_ec_write"); |
@@ -384,8 +385,11 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) | |||
384 | return_VALUE(-ENODEV); | 385 | return_VALUE(-ENODEV); |
385 | } | 386 | } |
386 | 387 | ||
387 | spin_lock_irqsave(&ec->poll.lock, flags); | 388 | if (down_interruptible(&ec->poll.sem)) { |
388 | 389 | result = -ERESTARTSYS; | |
390 | goto end_nosem; | ||
391 | } | ||
392 | |||
389 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, | 393 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, |
390 | &ec->common.command_addr); | 394 | &ec->common.command_addr); |
391 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 395 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
@@ -406,8 +410,8 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) | |||
406 | data, address)); | 410 | data, address)); |
407 | 411 | ||
408 | end: | 412 | end: |
409 | spin_unlock_irqrestore(&ec->poll.lock, flags); | 413 | up(&ec->poll.sem); |
410 | 414 | end_nosem: | |
411 | if (ec->common.global_lock) | 415 | if (ec->common.global_lock) |
412 | acpi_release_global_lock(glk); | 416 | acpi_release_global_lock(glk); |
413 | 417 | ||
@@ -568,7 +572,6 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) | |||
568 | { | 572 | { |
569 | int result = 0; | 573 | int result = 0; |
570 | acpi_status status = AE_OK; | 574 | acpi_status status = AE_OK; |
571 | unsigned long flags = 0; | ||
572 | u32 glk = 0; | 575 | u32 glk = 0; |
573 | 576 | ||
574 | ACPI_FUNCTION_TRACE("acpi_ec_query"); | 577 | ACPI_FUNCTION_TRACE("acpi_ec_query"); |
@@ -589,8 +592,11 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) | |||
589 | * Note that successful completion of the query causes the ACPI_EC_SCI | 592 | * Note that successful completion of the query causes the ACPI_EC_SCI |
590 | * bit to be cleared (and thus clearing the interrupt source). | 593 | * bit to be cleared (and thus clearing the interrupt source). |
591 | */ | 594 | */ |
592 | spin_lock_irqsave(&ec->poll.lock, flags); | 595 | if (down_interruptible(&ec->poll.sem)) { |
593 | 596 | result = -ERESTARTSYS; | |
597 | goto end_nosem; | ||
598 | } | ||
599 | |||
594 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, | 600 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, |
595 | &ec->common.command_addr); | 601 | &ec->common.command_addr); |
596 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 602 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
@@ -602,8 +608,8 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) | |||
602 | result = -ENODATA; | 608 | result = -ENODATA; |
603 | 609 | ||
604 | end: | 610 | end: |
605 | spin_unlock_irqrestore(&ec->poll.lock, flags); | 611 | up(&ec->poll.sem); |
606 | 612 | end_nosem: | |
607 | if (ec->common.global_lock) | 613 | if (ec->common.global_lock) |
608 | acpi_release_global_lock(glk); | 614 | acpi_release_global_lock(glk); |
609 | 615 | ||
@@ -680,7 +686,6 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt) | |||
680 | { | 686 | { |
681 | union acpi_ec *ec = (union acpi_ec *)ec_cxt; | 687 | union acpi_ec *ec = (union acpi_ec *)ec_cxt; |
682 | u32 value = 0; | 688 | u32 value = 0; |
683 | unsigned long flags = 0; | ||
684 | static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; | 689 | static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; |
685 | const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', | 690 | const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', |
686 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | 691 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' |
@@ -691,9 +696,11 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt) | |||
691 | if (!ec_cxt) | 696 | if (!ec_cxt) |
692 | goto end; | 697 | goto end; |
693 | 698 | ||
694 | spin_lock_irqsave(&ec->poll.lock, flags); | 699 | if (down_interruptible (&ec->poll.sem)) { |
700 | return_VOID; | ||
701 | } | ||
695 | acpi_hw_low_level_read(8, &value, &ec->common.command_addr); | 702 | acpi_hw_low_level_read(8, &value, &ec->common.command_addr); |
696 | spin_unlock_irqrestore(&ec->poll.lock, flags); | 703 | up(&ec->poll.sem); |
697 | 704 | ||
698 | /* TBD: Implement asynch events! | 705 | /* TBD: Implement asynch events! |
699 | * NOTE: All we care about are EC-SCI's. Other EC events are | 706 | * NOTE: All we care about are EC-SCI's. Other EC events are |
@@ -1005,7 +1012,7 @@ static int acpi_ec_poll_add(struct acpi_device *device) | |||
1005 | 1012 | ||
1006 | ec->common.handle = device->handle; | 1013 | ec->common.handle = device->handle; |
1007 | ec->common.uid = -1; | 1014 | ec->common.uid = -1; |
1008 | spin_lock_init(&ec->poll.lock); | 1015 | init_MUTEX(&ec->poll.sem); |
1009 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 1016 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
1010 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 1017 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
1011 | acpi_driver_data(device) = ec; | 1018 | acpi_driver_data(device) = ec; |
@@ -1300,7 +1307,7 @@ acpi_fake_ecdt_poll_callback(acpi_handle handle, | |||
1300 | &ec_ecdt->common.gpe_bit); | 1307 | &ec_ecdt->common.gpe_bit); |
1301 | if (ACPI_FAILURE(status)) | 1308 | if (ACPI_FAILURE(status)) |
1302 | return status; | 1309 | return status; |
1303 | spin_lock_init(&ec_ecdt->poll.lock); | 1310 | init_MUTEX(&ec_ecdt->poll.sem); |
1304 | ec_ecdt->common.global_lock = TRUE; | 1311 | ec_ecdt->common.global_lock = TRUE; |
1305 | ec_ecdt->common.handle = handle; | 1312 | ec_ecdt->common.handle = handle; |
1306 | 1313 | ||
@@ -1416,7 +1423,7 @@ static int __init acpi_ec_poll_get_real_ecdt(void) | |||
1416 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; | 1423 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; |
1417 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; | 1424 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; |
1418 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; | 1425 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; |
1419 | spin_lock_init(&ec_ecdt->poll.lock); | 1426 | init_MUTEX(&ec_ecdt->poll.sem); |
1420 | /* use the GL just to be safe */ | 1427 | /* use the GL just to be safe */ |
1421 | ec_ecdt->common.global_lock = TRUE; | 1428 | ec_ecdt->common.global_lock = TRUE; |
1422 | ec_ecdt->common.uid = ecdt_ptr->uid; | 1429 | ec_ecdt->common.uid = ecdt_ptr->uid; |