aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ec.c51
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 364end_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 414end_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 612end_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;