|
Lines 59-66
Link Here
|
| 59 |
#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ |
59 |
#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ |
| 60 |
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
60 |
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
| 61 |
|
61 |
|
| 62 |
#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ |
62 |
#define ACPI_EC_MDELAY_MS 1 /* Poll @ 100us increments */ |
| 63 |
#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ |
63 |
#define ACPI_EC_MDELAY_COUNT 10 /* Wait 10ms max. during EC ops */ |
| 64 |
|
64 |
|
| 65 |
#define ACPI_EC_COMMAND_READ 0x80 |
65 |
#define ACPI_EC_COMMAND_READ 0x80 |
| 66 |
#define ACPI_EC_COMMAND_WRITE 0x81 |
66 |
#define ACPI_EC_COMMAND_WRITE 0x81 |
|
Lines 126-132
Link Here
|
| 126 |
struct acpi_generic_address command_addr; |
126 |
struct acpi_generic_address command_addr; |
| 127 |
struct acpi_generic_address data_addr; |
127 |
struct acpi_generic_address data_addr; |
| 128 |
unsigned long global_lock; |
128 |
unsigned long global_lock; |
| 129 |
spinlock_t lock; |
129 |
struct semaphore sem; |
| 130 |
}polling; |
130 |
}polling; |
| 131 |
}; |
131 |
}; |
| 132 |
|
132 |
|
|
Lines 196-202
Link Here
|
| 196 |
u8 event) |
196 |
u8 event) |
| 197 |
{ |
197 |
{ |
| 198 |
u32 acpi_ec_status = 0; |
198 |
u32 acpi_ec_status = 0; |
| 199 |
u32 i = ACPI_EC_UDELAY_COUNT; |
199 |
u32 i = ACPI_EC_MDELAY_COUNT; |
| 200 |
|
200 |
|
| 201 |
if (!ec) |
201 |
if (!ec) |
| 202 |
return -EINVAL; |
202 |
return -EINVAL; |
|
Lines 208-214
Link Here
|
| 208 |
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); |
208 |
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); |
| 209 |
if (acpi_ec_status & ACPI_EC_FLAG_OBF) |
209 |
if (acpi_ec_status & ACPI_EC_FLAG_OBF) |
| 210 |
return 0; |
210 |
return 0; |
| 211 |
udelay(ACPI_EC_UDELAY); |
211 |
msleep(1); |
| 212 |
} while (--i>0); |
212 |
} while (--i>0); |
| 213 |
break; |
213 |
break; |
| 214 |
case ACPI_EC_EVENT_IBE: |
214 |
case ACPI_EC_EVENT_IBE: |
|
Lines 216-222
Link Here
|
| 216 |
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); |
216 |
acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); |
| 217 |
if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) |
217 |
if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) |
| 218 |
return 0; |
218 |
return 0; |
| 219 |
udelay(ACPI_EC_UDELAY); |
219 |
msleep(1); |
| 220 |
} while (--i>0); |
220 |
} while (--i>0); |
| 221 |
break; |
221 |
break; |
| 222 |
default: |
222 |
default: |
|
Lines 353-365
Link Here
|
| 353 |
{ |
353 |
{ |
| 354 |
acpi_status status = AE_OK; |
354 |
acpi_status status = AE_OK; |
| 355 |
int result = 0; |
355 |
int result = 0; |
| 356 |
unsigned long flags = 0; |
|
|
| 357 |
u32 glk = 0; |
356 |
u32 glk = 0; |
| 358 |
|
357 |
|
| 359 |
ACPI_FUNCTION_TRACE("acpi_ec_read"); |
358 |
ACPI_FUNCTION_TRACE("acpi_ec_read"); |
| 360 |
|
359 |
|
| 361 |
if (!ec || !data) |
360 |
if (!ec || !data) |
| 362 |
return_VALUE(-EINVAL); |
361 |
return_VALUE(-EINVAL); |
|
|
362 |
if (in_interrupt()) |
| 363 |
return_VALUE(-ENODEV); |
| 363 |
|
364 |
|
| 364 |
*data = 0; |
365 |
*data = 0; |
| 365 |
|
366 |
|
|
Lines 369-375
Link Here
|
| 369 |
return_VALUE(-ENODEV); |
370 |
return_VALUE(-ENODEV); |
| 370 |
} |
371 |
} |
| 371 |
|
372 |
|
| 372 |
spin_lock_irqsave(&ec->polling.lock, flags); |
373 |
|
|
|
374 |
down(&ec->polling.sem); |
| 373 |
|
375 |
|
| 374 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); |
376 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); |
| 375 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
377 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
|
Lines 387-393
Link Here
|
| 387 |
*data, address)); |
389 |
*data, address)); |
| 388 |
|
390 |
|
| 389 |
end: |
391 |
end: |
| 390 |
spin_unlock_irqrestore(&ec->polling.lock, flags); |
392 |
up(&ec->polling.sem); |
| 391 |
|
393 |
|
| 392 |
if (ec->common.global_lock) |
394 |
if (ec->common.global_lock) |
| 393 |
acpi_release_global_lock(glk); |
395 |
acpi_release_global_lock(glk); |
|
Lines 404-410
Link Here
|
| 404 |
{ |
406 |
{ |
| 405 |
int result = 0; |
407 |
int result = 0; |
| 406 |
acpi_status status = AE_OK; |
408 |
acpi_status status = AE_OK; |
| 407 |
unsigned long flags = 0; |
|
|
| 408 |
u32 glk = 0; |
409 |
u32 glk = 0; |
| 409 |
|
410 |
|
| 410 |
ACPI_FUNCTION_TRACE("acpi_ec_write"); |
411 |
ACPI_FUNCTION_TRACE("acpi_ec_write"); |
|
Lines 412-424
Link Here
|
| 412 |
if (!ec) |
413 |
if (!ec) |
| 413 |
return_VALUE(-EINVAL); |
414 |
return_VALUE(-EINVAL); |
| 414 |
|
415 |
|
|
|
416 |
if (in_interrupt()) |
| 417 |
return_VALUE(-ENODEV); |
| 418 |
|
| 415 |
if (ec->common.global_lock) { |
419 |
if (ec->common.global_lock) { |
| 416 |
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
420 |
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
| 417 |
if (ACPI_FAILURE(status)) |
421 |
if (ACPI_FAILURE(status)) |
| 418 |
return_VALUE(-ENODEV); |
422 |
return_VALUE(-ENODEV); |
| 419 |
} |
423 |
} |
| 420 |
|
424 |
|
| 421 |
spin_lock_irqsave(&ec->polling.lock, flags); |
425 |
down(&ec->polling.sem); |
| 422 |
|
426 |
|
| 423 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); |
427 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); |
| 424 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
428 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
|
Lines 439-445
Link Here
|
| 439 |
data, address)); |
443 |
data, address)); |
| 440 |
|
444 |
|
| 441 |
end: |
445 |
end: |
| 442 |
spin_unlock_irqrestore(&ec->polling.lock, flags); |
446 |
up(&ec->polling.sem); |
| 443 |
|
447 |
|
| 444 |
if (ec->common.global_lock) |
448 |
if (ec->common.global_lock) |
| 445 |
acpi_release_global_lock(glk); |
449 |
acpi_release_global_lock(glk); |
|
Lines 658-664
Link Here
|
| 658 |
{ |
662 |
{ |
| 659 |
int result = 0; |
663 |
int result = 0; |
| 660 |
acpi_status status = AE_OK; |
664 |
acpi_status status = AE_OK; |
| 661 |
unsigned long flags = 0; |
|
|
| 662 |
u32 glk = 0; |
665 |
u32 glk = 0; |
| 663 |
|
666 |
|
| 664 |
ACPI_FUNCTION_TRACE("acpi_ec_query"); |
667 |
ACPI_FUNCTION_TRACE("acpi_ec_query"); |
|
Lines 666-671
Link Here
|
| 666 |
if (!ec || !data) |
669 |
if (!ec || !data) |
| 667 |
return_VALUE(-EINVAL); |
670 |
return_VALUE(-EINVAL); |
| 668 |
|
671 |
|
|
|
672 |
if (in_interrupt()) |
| 673 |
return_VALUE(-EINVAL); |
| 669 |
*data = 0; |
674 |
*data = 0; |
| 670 |
|
675 |
|
| 671 |
if (ec->common.global_lock) { |
676 |
if (ec->common.global_lock) { |
|
Lines 679-685
Link Here
|
| 679 |
* Note that successful completion of the query causes the ACPI_EC_SCI |
684 |
* Note that successful completion of the query causes the ACPI_EC_SCI |
| 680 |
* bit to be cleared (and thus clearing the interrupt source). |
685 |
* bit to be cleared (and thus clearing the interrupt source). |
| 681 |
*/ |
686 |
*/ |
| 682 |
spin_lock_irqsave(&ec->polling.lock, flags); |
687 |
down(&ec->polling.sem); |
| 683 |
|
688 |
|
| 684 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); |
689 |
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); |
| 685 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
690 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
|
Lines 691-697
Link Here
|
| 691 |
result = -ENODATA; |
696 |
result = -ENODATA; |
| 692 |
|
697 |
|
| 693 |
end: |
698 |
end: |
| 694 |
spin_unlock_irqrestore(&ec->polling.lock, flags); |
699 |
up(&ec->polling.sem); |
| 695 |
|
700 |
|
| 696 |
if (ec->common.global_lock) |
701 |
if (ec->common.global_lock) |
| 697 |
acpi_release_global_lock(glk); |
702 |
acpi_release_global_lock(glk); |
|
Lines 779-785
Link Here
|
| 779 |
{ |
784 |
{ |
| 780 |
union acpi_ec *ec = (union acpi_ec *) ec_cxt; |
785 |
union acpi_ec *ec = (union acpi_ec *) ec_cxt; |
| 781 |
u32 value = 0; |
786 |
u32 value = 0; |
| 782 |
unsigned long flags = 0; |
|
|
| 783 |
static char object_name[5] = {'_','Q','0','0','\0'}; |
787 |
static char object_name[5] = {'_','Q','0','0','\0'}; |
| 784 |
const char hex[] = {'0','1','2','3','4','5','6','7', |
788 |
const char hex[] = {'0','1','2','3','4','5','6','7', |
| 785 |
'8','9','A','B','C','D','E','F'}; |
789 |
'8','9','A','B','C','D','E','F'}; |
|
Lines 789-797
Link Here
|
| 789 |
if (!ec_cxt) |
793 |
if (!ec_cxt) |
| 790 |
goto end; |
794 |
goto end; |
| 791 |
|
795 |
|
| 792 |
spin_lock_irqsave(&ec->polling.lock, flags); |
796 |
if (in_interrupt()) |
|
|
797 |
goto end; |
| 798 |
|
| 799 |
down(&ec->polling.sem); |
| 793 |
acpi_hw_low_level_read(8, &value, &ec->common.command_addr); |
800 |
acpi_hw_low_level_read(8, &value, &ec->common.command_addr); |
| 794 |
spin_unlock_irqrestore(&ec->polling.lock, flags); |
801 |
up(&ec->polling.sem); |
| 795 |
|
802 |
|
| 796 |
/* TBD: Implement asynch events! |
803 |
/* TBD: Implement asynch events! |
| 797 |
* NOTE: All we care about are EC-SCI's. Other EC events are |
804 |
* NOTE: All we care about are EC-SCI's. Other EC events are |
|
Lines 1137-1143
Link Here
|
| 1137 |
|
1144 |
|
| 1138 |
ec->common.handle = device->handle; |
1145 |
ec->common.handle = device->handle; |
| 1139 |
ec->common.uid = -1; |
1146 |
ec->common.uid = -1; |
| 1140 |
spin_lock_init(&ec->polling.lock); |
1147 |
init_MUTEX(&ec->polling.sem); |
| 1141 |
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
1148 |
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
| 1142 |
strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
1149 |
strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
| 1143 |
acpi_driver_data(device) = ec; |
1150 |
acpi_driver_data(device) = ec; |
|
Lines 1434-1440
Link Here
|
| 1434 |
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); |
1441 |
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); |
| 1435 |
if (ACPI_FAILURE(status)) |
1442 |
if (ACPI_FAILURE(status)) |
| 1436 |
return status; |
1443 |
return status; |
| 1437 |
spin_lock_init(&ec_ecdt->polling.lock); |
1444 |
init_MUTEX(&ec_ecdt->polling.sem); |
| 1438 |
ec_ecdt->common.global_lock = TRUE; |
1445 |
ec_ecdt->common.global_lock = TRUE; |
| 1439 |
ec_ecdt->common.handle = handle; |
1446 |
ec_ecdt->common.handle = handle; |
| 1440 |
|
1447 |
|
|
Lines 1553-1559
Link Here
|
| 1553 |
ec_ecdt->common.status_addr = ecdt_ptr->ec_control; |
1560 |
ec_ecdt->common.status_addr = ecdt_ptr->ec_control; |
| 1554 |
ec_ecdt->common.data_addr = ecdt_ptr->ec_data; |
1561 |
ec_ecdt->common.data_addr = ecdt_ptr->ec_data; |
| 1555 |
ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; |
1562 |
ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; |
| 1556 |
spin_lock_init(&ec_ecdt->polling.lock); |
1563 |
init_MUTEX(&ec_ecdt->polling.sem); |
| 1557 |
/* use the GL just to be safe */ |
1564 |
/* use the GL just to be safe */ |
| 1558 |
ec_ecdt->common.global_lock = TRUE; |
1565 |
ec_ecdt->common.global_lock = TRUE; |
| 1559 |
ec_ecdt->common.uid = ecdt_ptr->uid; |
1566 |
ec_ecdt->common.uid = ecdt_ptr->uid; |