aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c124
1 files changed, 45 insertions, 79 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 0f232e719daf..ae05e8c11480 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -72,7 +72,7 @@ enum {
72 72
73enum { 73enum {
74 EC_INTR = 1, /* Output buffer full */ 74 EC_INTR = 1, /* Output buffer full */
75 EC_POLL, /* Input buffer empty */ 75 EC_POLL, /* Input buffer empty */
76}; 76};
77 77
78static int acpi_ec_remove(struct acpi_device *device, int type); 78static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -91,22 +91,20 @@ static struct acpi_driver acpi_ec_driver = {
91 .stop = acpi_ec_stop, 91 .stop = acpi_ec_stop,
92 }, 92 },
93}; 93};
94
95/* If we find an EC via the ECDT, we need to keep a ptr to its context */
94struct acpi_ec { 96struct acpi_ec {
95 acpi_handle handle; 97 acpi_handle handle;
96 unsigned long uid; 98 unsigned long uid;
97 unsigned long gpe_bit; 99 unsigned long gpe_bit;
98 struct acpi_generic_address status_addr; 100 unsigned long command_addr;
99 struct acpi_generic_address command_addr; 101 unsigned long data_addr;
100 struct acpi_generic_address data_addr;
101 unsigned long global_lock; 102 unsigned long global_lock;
102 struct semaphore sem; 103 struct semaphore sem;
103 unsigned int expect_event; 104 unsigned int expect_event;
104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ 105 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
105 wait_queue_head_t wait; 106 wait_queue_head_t wait;
106}; 107} *ec_ecdt;
107
108/* If we find an EC via the ECDT, we need to keep a ptr to its context */
109static struct acpi_ec *ec_ecdt;
110 108
111/* External interfaces use first EC only, so remember */ 109/* External interfaces use first EC only, so remember */
112static struct acpi_device *first_ec; 110static struct acpi_device *first_ec;
@@ -116,34 +114,28 @@ static int acpi_ec_mode = EC_INTR;
116 Transaction Management 114 Transaction Management
117 -------------------------------------------------------------------------- */ 115 -------------------------------------------------------------------------- */
118 116
119static u32 acpi_ec_read_status(struct acpi_ec *ec) 117static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
120{ 118{
121 u32 status = 0; 119 return inb(ec->command_addr);
122
123 acpi_hw_low_level_read(8, &status, &ec->status_addr);
124 return status;
125} 120}
126 121
127static u32 acpi_ec_read_data(struct acpi_ec *ec) 122static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
128{ 123{
129 u32 data = 0; 124 return inb(ec->data_addr);
130
131 acpi_hw_low_level_read(8, &data, &ec->data_addr);
132 return data;
133} 125}
134 126
135static void acpi_ec_write_cmd(struct acpi_ec *ec, u32 command) 127static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
136{ 128{
137 acpi_hw_low_level_write(8, command, &ec->command_addr); 129 outb(command, ec->command_addr);
138} 130}
139 131
140static void acpi_ec_write_data(struct acpi_ec *ec, u32 data) 132static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
141{ 133{
142 acpi_hw_low_level_write(8, data, &ec->data_addr); 134 outb(data, ec->data_addr);
143} 135}
144 136
145static int acpi_ec_check_status(u32 status, u8 event) { 137static int acpi_ec_check_status(u8 status, u8 event)
146 138{
147 switch (event) { 139 switch (event) {
148 case ACPI_EC_EVENT_OBF_1: 140 case ACPI_EC_EVENT_OBF_1:
149 if (status & ACPI_EC_FLAG_OBF) 141 if (status & ACPI_EC_FLAG_OBF)
@@ -201,8 +193,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
201 */ 193 */
202int acpi_ec_enter_burst_mode(struct acpi_ec *ec) 194int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
203{ 195{
204 u32 tmp = 0; 196 u8 tmp = 0;
205 u32 status = 0; 197 u8 status = 0;
206 198
207 199
208 status = acpi_ec_read_status(ec); 200 status = acpi_ec_read_status(ec);
@@ -227,7 +219,7 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
227 219
228int acpi_ec_leave_burst_mode(struct acpi_ec *ec) 220int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
229{ 221{
230 u32 status = 0; 222 u8 status = 0;
231 223
232 224
233 status = acpi_ec_read_status(ec); 225 status = acpi_ec_read_status(ec);
@@ -268,14 +260,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
268 } 260 }
269 261
270 for (; rdata_len > 0; rdata_len --) { 262 for (; rdata_len > 0; rdata_len --) {
271 u32 d;
272
273 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); 263 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
274 if (result) 264 if (result)
275 return result; 265 return result;
276 266
277 d = acpi_ec_read_data(ec); 267 *(rdata++) = acpi_ec_read_data(ec);
278 *(rdata++) = (u8) d;
279 } 268 }
280 269
281 return 0; 270 return 0;
@@ -320,7 +309,7 @@ end:
320 return status; 309 return status;
321} 310}
322 311
323static int acpi_ec_read(struct acpi_ec *ec, u8 address, u32 * data) 312static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
324{ 313{
325 int result; 314 int result;
326 u8 d; 315 u8 d;
@@ -330,6 +319,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u32 * data)
330 *data = d; 319 *data = d;
331 return result; 320 return result;
332} 321}
322
333static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) 323static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
334{ 324{
335 u8 wdata[2] = { address, data }; 325 u8 wdata[2] = { address, data };
@@ -340,11 +330,11 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
340/* 330/*
341 * Externally callable EC access functions. For now, assume 1 EC only 331 * Externally callable EC access functions. For now, assume 1 EC only
342 */ 332 */
343int ec_read(u8 addr, u8 * val) 333int ec_read(u8 addr, u8 *val)
344{ 334{
345 struct acpi_ec *ec; 335 struct acpi_ec *ec;
346 int err; 336 int err;
347 u32 temp_data; 337 u8 temp_data;
348 338
349 if (!first_ec) 339 if (!first_ec)
350 return -ENODEV; 340 return -ENODEV;
@@ -394,7 +384,7 @@ extern int ec_transaction(u8 command,
394 wdata_len, rdata, rdata_len); 384 wdata_len, rdata, rdata_len);
395} 385}
396 386
397static int acpi_ec_query(struct acpi_ec *ec, u32 * data) 387static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
398{ 388{
399 int result; 389 int result;
400 u8 d; 390 u8 d;
@@ -431,14 +421,10 @@ struct acpi_ec_query_data {
431static void acpi_ec_gpe_query(void *ec_cxt) 421static void acpi_ec_gpe_query(void *ec_cxt)
432{ 422{
433 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; 423 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
434 u32 value = 0; 424 u8 value = 0;
435 static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; 425 static char object_name[8];
436 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
437 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
438 };
439
440 426
441 if (!ec_cxt) 427 if (!ec)
442 goto end; 428 goto end;
443 429
444 value = acpi_ec_read_status(ec); 430 value = acpi_ec_read_status(ec);
@@ -449,8 +435,7 @@ static void acpi_ec_gpe_query(void *ec_cxt)
449 if (acpi_ec_query(ec, &value)) 435 if (acpi_ec_query(ec, &value))
450 goto end; 436 goto end;
451 437
452 object_name[2] = hex[((value >> 4) & 0x0F)]; 438 snprintf(object_name, 8, "_Q%2.2X", value);
453 object_name[3] = hex[(value & 0x0F)];
454 439
455 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); 440 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
456 441
@@ -463,8 +448,7 @@ static void acpi_ec_gpe_query(void *ec_cxt)
463static u32 acpi_ec_gpe_handler(void *data) 448static u32 acpi_ec_gpe_handler(void *data)
464{ 449{
465 acpi_status status = AE_OK; 450 acpi_status status = AE_OK;
466 u32 value; 451 u8 value;
467 u8 exec_mode;
468 struct acpi_ec *ec = (struct acpi_ec *)data; 452 struct acpi_ec *ec = (struct acpi_ec *)data;
469 453
470 acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); 454 acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
@@ -475,13 +459,10 @@ static u32 acpi_ec_gpe_handler(void *data)
475 ec->expect_event = 0; 459 ec->expect_event = 0;
476 wake_up(&ec->wait); 460 wake_up(&ec->wait);
477 } 461 }
478 exec_mode = OSL_EC_BURST_HANDLER;
479 } else {
480 exec_mode = OSL_EC_POLL_HANDLER;
481 } 462 }
482 463
483 if (value & ACPI_EC_FLAG_SCI) { 464 if (value & ACPI_EC_FLAG_SCI) {
484 status = acpi_os_execute(exec_mode, acpi_ec_gpe_query, ec); 465 status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
485 return status == AE_OK ? 466 return status == AE_OK ?
486 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 467 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
487 } 468 }
@@ -535,7 +516,7 @@ acpi_ec_space_handler(u32 function,
535 switch (function) { 516 switch (function) {
536 case ACPI_READ: 517 case ACPI_READ:
537 temp = 0; 518 temp = 0;
538 result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); 519 result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
539 break; 520 break;
540 case ACPI_WRITE: 521 case ACPI_WRITE:
541 result = acpi_ec_write(ec, (u8) address, (u8) temp); 522 result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -595,8 +576,8 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset)
595 seq_printf(seq, "gpe bit: 0x%02x\n", 576 seq_printf(seq, "gpe bit: 0x%02x\n",
596 (u32) ec->gpe_bit); 577 (u32) ec->gpe_bit);
597 seq_printf(seq, "ports: 0x%02x, 0x%02x\n", 578 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
598 (u32) ec->status_addr.address, 579 (u32) ec->command_addr,
599 (u32) ec->data_addr.address); 580 (u32) ec->data_addr);
600 seq_printf(seq, "use global lock: %s\n", 581 seq_printf(seq, "use global lock: %s\n",
601 ec->global_lock ? "yes" : "no"); 582 ec->global_lock ? "yes" : "no");
602 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); 583 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
@@ -752,7 +733,6 @@ static acpi_status
752acpi_ec_io_ports(struct acpi_resource *resource, void *context) 733acpi_ec_io_ports(struct acpi_resource *resource, void *context)
753{ 734{
754 struct acpi_ec *ec = (struct acpi_ec *)context; 735 struct acpi_ec *ec = (struct acpi_ec *)context;
755 struct acpi_generic_address *addr;
756 736
757 if (resource->type != ACPI_RESOURCE_TYPE_IO) { 737 if (resource->type != ACPI_RESOURCE_TYPE_IO) {
758 return AE_OK; 738 return AE_OK;
@@ -763,19 +743,14 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
763 * the second address region returned is the status/command 743 * the second address region returned is the status/command
764 * port. 744 * port.
765 */ 745 */
766 if (ec->data_addr.register_bit_width == 0) { 746 if (ec->data_addr == 0) {
767 addr = &ec->data_addr; 747 ec->data_addr = resource->data.io.minimum;
768 } else if (ec->command_addr.register_bit_width == 0) { 748 } else if (ec->command_addr == 0) {
769 addr = &ec->command_addr; 749 ec->command_addr = resource->data.io.minimum;
770 } else { 750 } else {
771 return AE_CTRL_TERMINATE; 751 return AE_CTRL_TERMINATE;
772 } 752 }
773 753
774 addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
775 addr->register_bit_width = 8;
776 addr->register_bit_offset = 0;
777 addr->address = resource->data.io.minimum;
778
779 return AE_OK; 754 return AE_OK;
780} 755}
781 756
@@ -798,19 +773,14 @@ static int acpi_ec_start(struct acpi_device *device)
798 */ 773 */
799 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, 774 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
800 acpi_ec_io_ports, ec); 775 acpi_ec_io_ports, ec);
801 if (ACPI_FAILURE(status) 776 if (ACPI_FAILURE(status) || ec->command_addr == 0) {
802 || ec->command_addr.register_bit_width == 0) {
803 ACPI_EXCEPTION((AE_INFO, status, 777 ACPI_EXCEPTION((AE_INFO, status,
804 "Error getting I/O port addresses")); 778 "Error getting I/O port addresses"));
805 return -ENODEV; 779 return -ENODEV;
806 } 780 }
807 781
808 ec->status_addr = ec->command_addr; 782 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
809 783 ec->gpe_bit, ec->command_addr, ec->data_addr));
810 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x",
811 (u32) ec->gpe_bit,
812 (u32) ec->command_addr.address,
813 (u32) ec->data_addr.address));
814 784
815 /* 785 /*
816 * Install GPE handler 786 * Install GPE handler
@@ -877,7 +847,6 @@ acpi_fake_ecdt_callback(acpi_handle handle,
877 acpi_ec_io_ports, ec_ecdt); 847 acpi_ec_io_ports, ec_ecdt);
878 if (ACPI_FAILURE(status)) 848 if (ACPI_FAILURE(status))
879 return status; 849 return status;
880 ec_ecdt->status_addr = ec_ecdt->command_addr;
881 850
882 ec_ecdt->uid = -1; 851 ec_ecdt->uid = -1;
883 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); 852 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
@@ -890,10 +859,8 @@ acpi_fake_ecdt_callback(acpi_handle handle,
890 ec_ecdt->global_lock = TRUE; 859 ec_ecdt->global_lock = TRUE;
891 ec_ecdt->handle = handle; 860 ec_ecdt->handle = handle;
892 861
893 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02x, ports=0x%2x, 0x%2x", 862 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
894 (u32) ec_ecdt->gpe_bit, 863 ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
895 (u32) ec_ecdt->command_addr.address,
896 (u32) ec_ecdt->data_addr.address));
897 864
898 return AE_CTRL_TERMINATE; 865 return AE_CTRL_TERMINATE;
899} 866}
@@ -961,9 +928,8 @@ static int __init acpi_ec_get_real_ecdt(void)
961 if (acpi_ec_mode == EC_INTR) { 928 if (acpi_ec_mode == EC_INTR) {
962 init_waitqueue_head(&ec_ecdt->wait); 929 init_waitqueue_head(&ec_ecdt->wait);
963 } 930 }
964 ec_ecdt->command_addr = ecdt_ptr->ec_control; 931 ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
965 ec_ecdt->status_addr = ecdt_ptr->ec_control; 932 ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
966 ec_ecdt->data_addr = ecdt_ptr->ec_data;
967 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; 933 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
968 /* use the GL just to be safe */ 934 /* use the GL just to be safe */
969 ec_ecdt->global_lock = TRUE; 935 ec_ecdt->global_lock = TRUE;