diff options
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 c036e2a69f33..18b3ea9dace2 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 |
@@ -1003,7 +1010,7 @@ static int acpi_ec_poll_add(struct acpi_device *device) | |||
1003 | 1010 | ||
1004 | ec->common.handle = device->handle; | 1011 | ec->common.handle = device->handle; |
1005 | ec->common.uid = -1; | 1012 | ec->common.uid = -1; |
1006 | spin_lock_init(&ec->poll.lock); | 1013 | init_MUTEX(&ec->poll.sem); |
1007 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 1014 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
1008 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 1015 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
1009 | acpi_driver_data(device) = ec; | 1016 | acpi_driver_data(device) = ec; |
@@ -1295,7 +1302,7 @@ acpi_fake_ecdt_poll_callback(acpi_handle handle, | |||
1295 | &ec_ecdt->common.gpe_bit); | 1302 | &ec_ecdt->common.gpe_bit); |
1296 | if (ACPI_FAILURE(status)) | 1303 | if (ACPI_FAILURE(status)) |
1297 | return status; | 1304 | return status; |
1298 | spin_lock_init(&ec_ecdt->poll.lock); | 1305 | init_MUTEX(&ec_ecdt->poll.sem); |
1299 | ec_ecdt->common.global_lock = TRUE; | 1306 | ec_ecdt->common.global_lock = TRUE; |
1300 | ec_ecdt->common.handle = handle; | 1307 | ec_ecdt->common.handle = handle; |
1301 | 1308 | ||
@@ -1411,7 +1418,7 @@ static int __init acpi_ec_poll_get_real_ecdt(void) | |||
1411 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; | 1418 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; |
1412 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; | 1419 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; |
1413 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; | 1420 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; |
1414 | spin_lock_init(&ec_ecdt->poll.lock); | 1421 | init_MUTEX(&ec_ecdt->poll.sem); |
1415 | /* use the GL just to be safe */ | 1422 | /* use the GL just to be safe */ |
1416 | ec_ecdt->common.global_lock = TRUE; | 1423 | ec_ecdt->common.global_lock = TRUE; |
1417 | ec_ecdt->common.uid = ecdt_ptr->uid; | 1424 | ec_ecdt->common.uid = ecdt_ptr->uid; |