aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2007-04-28 23:12:56 -0400
committerLen Brown <len.brown@intel.com>2007-04-28 23:12:56 -0400
commit03feb0524660bcd890674d11d29a1873ca14d13c (patch)
tree6e1f75a2205568c27a8bd9534b8186d529cd0146 /drivers/acpi
parentfb16596997ded3e70d308bec58e32c1e2c5cf9b0 (diff)
parent9fd9f8e8bdcfc9aa309dae5bccc55d02804337d0 (diff)
Pull ec into release branch
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Makefile7
-rw-r--r--drivers/acpi/ec.c495
2 files changed, 181 insertions, 321 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 92642ab15451..b6266e79af00 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -1,6 +1,6 @@
1# 1#
2# Makefile for the Linux ACPI interpreter 2# Makefile for the Linux ACPI interpreter
3# 3#
4 4
5export ACPI_CFLAGS 5export ACPI_CFLAGS
6 6
@@ -32,16 +32,17 @@ obj-y += osl.o utils.o \
32processor-objs += processor_core.o processor_throttling.o \ 32processor-objs += processor_core.o processor_throttling.o \
33 processor_idle.o processor_thermal.o 33 processor_idle.o processor_thermal.o
34ifdef CONFIG_CPU_FREQ 34ifdef CONFIG_CPU_FREQ
35processor-objs += processor_perflib.o 35processor-objs += processor_perflib.o
36endif 36endif
37 37
38obj-y += sleep/ 38obj-y += sleep/
39obj-y += bus.o glue.o 39obj-y += bus.o glue.o
40obj-y += scan.o 40obj-y += scan.o
41# Keep EC driver first. Initialization of others depend on it.
42obj-$(CONFIG_ACPI_EC) += ec.o
41obj-$(CONFIG_ACPI_AC) += ac.o 43obj-$(CONFIG_ACPI_AC) += ac.o
42obj-$(CONFIG_ACPI_BATTERY) += battery.o 44obj-$(CONFIG_ACPI_BATTERY) += battery.o
43obj-$(CONFIG_ACPI_BUTTON) += button.o 45obj-$(CONFIG_ACPI_BUTTON) += button.o
44obj-$(CONFIG_ACPI_EC) += ec.o
45obj-$(CONFIG_ACPI_FAN) += fan.o 46obj-$(CONFIG_ACPI_FAN) += fan.o
46obj-$(CONFIG_ACPI_DOCK) += dock.o 47obj-$(CONFIG_ACPI_DOCK) += dock.o
47obj-$(CONFIG_ACPI_BAY) += bay.o 48obj-$(CONFIG_ACPI_BAY) += bay.o
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a802962ff2b4..e08cf98f504f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $) 2 * ec.c - ACPI Embedded Controller Driver (v2.0)
3 * 3 *
4 * Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
5 * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> 6 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 7 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 8 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -91,9 +93,9 @@ static struct acpi_driver acpi_ec_driver = {
91}; 93};
92 94
93/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 95/* If we find an EC via the ECDT, we need to keep a ptr to its context */
96/* External interfaces use first EC only, so remember */
94static struct acpi_ec { 97static struct acpi_ec {
95 acpi_handle handle; 98 acpi_handle handle;
96 unsigned long uid;
97 unsigned long gpe; 99 unsigned long gpe;
98 unsigned long command_addr; 100 unsigned long command_addr;
99 unsigned long data_addr; 101 unsigned long data_addr;
@@ -101,12 +103,8 @@ static struct acpi_ec {
101 struct mutex lock; 103 struct mutex lock;
102 atomic_t query_pending; 104 atomic_t query_pending;
103 atomic_t event_count; 105 atomic_t event_count;
104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
105 wait_queue_head_t wait; 106 wait_queue_head_t wait;
106} *ec_ecdt; 107} *boot_ec, *first_ec;
107
108/* External interfaces use first EC only, so remember */
109static struct acpi_device *first_ec;
110 108
111/* -------------------------------------------------------------------------- 109/* --------------------------------------------------------------------------
112 Transaction Management 110 Transaction Management
@@ -173,56 +171,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, unsigned count)
173 return -ETIME; 171 return -ETIME;
174} 172}
175 173
176#ifdef ACPI_FUTURE_USAGE
177/*
178 * Note: samsung nv5000 doesn't work with ec burst mode.
179 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
180 */
181int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
182{
183 u8 tmp = 0;
184 u8 status = 0;
185
186 status = acpi_ec_read_status(ec);
187 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
188 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
189 if (status)
190 goto end;
191 acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
192 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
193 tmp = acpi_ec_read_data(ec);
194 if (tmp != 0x90) { /* Burst ACK byte */
195 return -EINVAL;
196 }
197 }
198
199 atomic_set(&ec->leaving_burst, 0);
200 return 0;
201 end:
202 ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
203 return -1;
204}
205
206int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
207{
208 u8 status = 0;
209
210 status = acpi_ec_read_status(ec);
211 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
212 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
213 if (status)
214 goto end;
215 acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
216 acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
217 }
218 atomic_set(&ec->leaving_burst, 1);
219 return 0;
220 end:
221 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
222 return -1;
223}
224#endif /* ACPI_FUTURE_USAGE */
225
226static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, 174static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
227 const u8 * wdata, unsigned wdata_len, 175 const u8 * wdata, unsigned wdata_len,
228 u8 * rdata, unsigned rdata_len) 176 u8 * rdata, unsigned rdata_len)
@@ -312,6 +260,21 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
312 return status; 260 return status;
313} 261}
314 262
263/*
264 * Note: samsung nv5000 doesn't work with ec burst mode.
265 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
266 */
267int acpi_ec_burst_enable(struct acpi_ec *ec)
268{
269 u8 d;
270 return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1);
271}
272
273int acpi_ec_burst_disable(struct acpi_ec *ec)
274{
275 return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0);
276}
277
315static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) 278static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
316{ 279{
317 int result; 280 int result;
@@ -333,18 +296,33 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
333/* 296/*
334 * Externally callable EC access functions. For now, assume 1 EC only 297 * Externally callable EC access functions. For now, assume 1 EC only
335 */ 298 */
299int ec_burst_enable(void)
300{
301 if (!first_ec)
302 return -ENODEV;
303 return acpi_ec_burst_enable(first_ec);
304}
305
306EXPORT_SYMBOL(ec_burst_enable);
307
308int ec_burst_disable(void)
309{
310 if (!first_ec)
311 return -ENODEV;
312 return acpi_ec_burst_disable(first_ec);
313}
314
315EXPORT_SYMBOL(ec_burst_disable);
316
336int ec_read(u8 addr, u8 * val) 317int ec_read(u8 addr, u8 * val)
337{ 318{
338 struct acpi_ec *ec;
339 int err; 319 int err;
340 u8 temp_data; 320 u8 temp_data;
341 321
342 if (!first_ec) 322 if (!first_ec)
343 return -ENODEV; 323 return -ENODEV;
344 324
345 ec = acpi_driver_data(first_ec); 325 err = acpi_ec_read(first_ec, addr, &temp_data);
346
347 err = acpi_ec_read(ec, addr, &temp_data);
348 326
349 if (!err) { 327 if (!err) {
350 *val = temp_data; 328 *val = temp_data;
@@ -357,15 +335,12 @@ EXPORT_SYMBOL(ec_read);
357 335
358int ec_write(u8 addr, u8 val) 336int ec_write(u8 addr, u8 val)
359{ 337{
360 struct acpi_ec *ec;
361 int err; 338 int err;
362 339
363 if (!first_ec) 340 if (!first_ec)
364 return -ENODEV; 341 return -ENODEV;
365 342
366 ec = acpi_driver_data(first_ec); 343 err = acpi_ec_write(first_ec, addr, val);
367
368 err = acpi_ec_write(ec, addr, val);
369 344
370 return err; 345 return err;
371} 346}
@@ -376,14 +351,10 @@ int ec_transaction(u8 command,
376 const u8 * wdata, unsigned wdata_len, 351 const u8 * wdata, unsigned wdata_len,
377 u8 * rdata, unsigned rdata_len) 352 u8 * rdata, unsigned rdata_len)
378{ 353{
379 struct acpi_ec *ec;
380
381 if (!first_ec) 354 if (!first_ec)
382 return -ENODEV; 355 return -ENODEV;
383 356
384 ec = acpi_driver_data(first_ec); 357 return acpi_ec_transaction(first_ec, command, wdata,
385
386 return acpi_ec_transaction(ec, command, wdata,
387 wdata_len, rdata, rdata_len); 358 wdata_len, rdata, rdata_len);
388} 359}
389 360
@@ -420,7 +391,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
420 391
421static void acpi_ec_gpe_query(void *ec_cxt) 392static void acpi_ec_gpe_query(void *ec_cxt)
422{ 393{
423 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; 394 struct acpi_ec *ec = ec_cxt;
424 u8 value = 0; 395 u8 value = 0;
425 char object_name[8]; 396 char object_name[8];
426 397
@@ -438,8 +409,9 @@ static u32 acpi_ec_gpe_handler(void *data)
438{ 409{
439 acpi_status status = AE_OK; 410 acpi_status status = AE_OK;
440 u8 value; 411 u8 value;
441 struct acpi_ec *ec = (struct acpi_ec *)data; 412 struct acpi_ec *ec = data;
442 atomic_inc(&ec->event_count); 413 atomic_inc(&ec->event_count);
414
443 if (acpi_ec_mode == EC_INTR) { 415 if (acpi_ec_mode == EC_INTR) {
444 wake_up(&ec->wait); 416 wake_up(&ec->wait);
445 } 417 }
@@ -482,7 +454,7 @@ acpi_ec_space_handler(u32 function,
482 void *handler_context, void *region_context) 454 void *handler_context, void *region_context)
483{ 455{
484 int result = 0; 456 int result = 0;
485 struct acpi_ec *ec = NULL; 457 struct acpi_ec *ec = handler_context;
486 u64 temp = *value; 458 u64 temp = *value;
487 acpi_integer f_v = 0; 459 acpi_integer f_v = 0;
488 int i = 0; 460 int i = 0;
@@ -494,8 +466,6 @@ acpi_ec_space_handler(u32 function,
494 return AE_BAD_PARAMETER; 466 return AE_BAD_PARAMETER;
495 } 467 }
496 468
497 ec = (struct acpi_ec *)handler_context;
498
499 next_byte: 469 next_byte:
500 switch (function) { 470 switch (function) {
501 case ACPI_READ: 471 case ACPI_READ:
@@ -551,18 +521,16 @@ static struct proc_dir_entry *acpi_ec_dir;
551 521
552static int acpi_ec_read_info(struct seq_file *seq, void *offset) 522static int acpi_ec_read_info(struct seq_file *seq, void *offset)
553{ 523{
554 struct acpi_ec *ec = (struct acpi_ec *)seq->private; 524 struct acpi_ec *ec = seq->private;
555 525
556 if (!ec) 526 if (!ec)
557 goto end; 527 goto end;
558 528
559 seq_printf(seq, "gpe: 0x%02x\n", (u32) ec->gpe); 529 seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
560 seq_printf(seq, "ports: 0x%02x, 0x%02x\n", 530 seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
561 (u32) ec->command_addr, (u32) ec->data_addr); 531 (unsigned)ec->command_addr, (unsigned)ec->data_addr);
562 seq_printf(seq, "use global lock: %s\n", 532 seq_printf(seq, "use global lock:\t%s\n",
563 ec->global_lock ? "yes" : "no"); 533 ec->global_lock ? "yes" : "no");
564 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
565
566 end: 534 end:
567 return 0; 535 return 0;
568} 536}
@@ -619,154 +587,122 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
619/* -------------------------------------------------------------------------- 587/* --------------------------------------------------------------------------
620 Driver Interface 588 Driver Interface
621 -------------------------------------------------------------------------- */ 589 -------------------------------------------------------------------------- */
590static acpi_status
591ec_parse_io_ports(struct acpi_resource *resource, void *context);
592
593static acpi_status
594ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
595
596static struct acpi_ec *make_acpi_ec(void)
597{
598 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
599 if (!ec)
600 return NULL;
601
602 atomic_set(&ec->query_pending, 1);
603 atomic_set(&ec->event_count, 1);
604 mutex_init(&ec->lock);
605 init_waitqueue_head(&ec->wait);
606
607 return ec;
608}
622 609
623static int acpi_ec_add(struct acpi_device *device) 610static int acpi_ec_add(struct acpi_device *device)
624{ 611{
625 int result = 0;
626 acpi_status status = AE_OK; 612 acpi_status status = AE_OK;
627 struct acpi_ec *ec = NULL; 613 struct acpi_ec *ec = NULL;
628 614
629 if (!device) 615 if (!device)
630 return -EINVAL; 616 return -EINVAL;
631 617
632 ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
633 if (!ec)
634 return -ENOMEM;
635
636 ec->handle = device->handle;
637 ec->uid = -1;
638 mutex_init(&ec->lock);
639 atomic_set(&ec->query_pending, 0);
640 atomic_set(&ec->event_count, 1);
641 if (acpi_ec_mode == EC_INTR) {
642 atomic_set(&ec->leaving_burst, 1);
643 init_waitqueue_head(&ec->wait);
644 }
645 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 618 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
646 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 619 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
647 acpi_driver_data(device) = ec;
648
649 /* Use the global lock for all EC transactions? */
650 acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
651
652 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
653 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
654 if (ec_ecdt) {
655 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
656 ACPI_ADR_SPACE_EC,
657 &acpi_ec_space_handler);
658 620
659 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe, 621 ec = make_acpi_ec();
660 &acpi_ec_gpe_handler); 622 if (!ec)
623 return -ENOMEM;
661 624
662 kfree(ec_ecdt); 625 status = ec_parse_device(device->handle, 0, ec, NULL);
626 if (status != AE_CTRL_TERMINATE) {
627 kfree(ec);
628 return -EINVAL;
663 } 629 }
664 630
665 /* Get GPE bit assignment (EC events). */ 631 /* Check if we found the boot EC */
666 /* TODO: Add support for _GPE returning a package */ 632 if (boot_ec) {
667 status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe); 633 if (boot_ec->gpe == ec->gpe) {
668 if (ACPI_FAILURE(status)) { 634 /* We might have incorrect info for GL at boot time */
669 ACPI_EXCEPTION((AE_INFO, status, 635 mutex_lock(&boot_ec->lock);
670 "Obtaining GPE bit assignment")); 636 boot_ec->global_lock = ec->global_lock;
671 result = -ENODEV; 637 mutex_unlock(&boot_ec->lock);
672 goto end; 638 kfree(ec);
673 } 639 ec = boot_ec;
640 }
641 } else
642 first_ec = ec;
643 ec->handle = device->handle;
644 acpi_driver_data(device) = ec;
674 645
675 result = acpi_ec_add_fs(device); 646 acpi_ec_add_fs(device);
676 if (result)
677 goto end;
678 647
679 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", 648 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
680 acpi_device_name(device), acpi_device_bid(device), 649 acpi_device_name(device), acpi_device_bid(device),
681 (u32) ec->gpe)); 650 (u32) ec->gpe));
682 651
683 if (!first_ec) 652 return 0;
684 first_ec = device;
685
686 end:
687 if (result)
688 kfree(ec);
689
690 return result;
691} 653}
692 654
693static int acpi_ec_remove(struct acpi_device *device, int type) 655static int acpi_ec_remove(struct acpi_device *device, int type)
694{ 656{
695 struct acpi_ec *ec = NULL; 657 struct acpi_ec *ec;
696 658
697 if (!device) 659 if (!device)
698 return -EINVAL; 660 return -EINVAL;
699 661
700 ec = acpi_driver_data(device); 662 ec = acpi_driver_data(device);
701
702 acpi_ec_remove_fs(device); 663 acpi_ec_remove_fs(device);
664 acpi_driver_data(device) = NULL;
665 if (ec == first_ec)
666 first_ec = NULL;
703 667
704 kfree(ec); 668 /* Don't touch boot EC */
705 669 if (boot_ec != ec)
670 kfree(ec);
706 return 0; 671 return 0;
707} 672}
708 673
709static acpi_status 674static acpi_status
710acpi_ec_io_ports(struct acpi_resource *resource, void *context) 675ec_parse_io_ports(struct acpi_resource *resource, void *context)
711{ 676{
712 struct acpi_ec *ec = (struct acpi_ec *)context; 677 struct acpi_ec *ec = context;
713 678
714 if (resource->type != ACPI_RESOURCE_TYPE_IO) { 679 if (resource->type != ACPI_RESOURCE_TYPE_IO)
715 return AE_OK; 680 return AE_OK;
716 }
717 681
718 /* 682 /*
719 * The first address region returned is the data port, and 683 * The first address region returned is the data port, and
720 * the second address region returned is the status/command 684 * the second address region returned is the status/command
721 * port. 685 * port.
722 */ 686 */
723 if (ec->data_addr == 0) { 687 if (ec->data_addr == 0)
724 ec->data_addr = resource->data.io.minimum; 688 ec->data_addr = resource->data.io.minimum;
725 } else if (ec->command_addr == 0) { 689 else if (ec->command_addr == 0)
726 ec->command_addr = resource->data.io.minimum; 690 ec->command_addr = resource->data.io.minimum;
727 } else { 691 else
728 return AE_CTRL_TERMINATE; 692 return AE_CTRL_TERMINATE;
729 }
730 693
731 return AE_OK; 694 return AE_OK;
732} 695}
733 696
734static int acpi_ec_start(struct acpi_device *device) 697static int ec_install_handlers(struct acpi_ec *ec)
735{ 698{
736 acpi_status status = AE_OK; 699 acpi_status status;
737 struct acpi_ec *ec = NULL;
738
739 if (!device)
740 return -EINVAL;
741
742 ec = acpi_driver_data(device);
743
744 if (!ec)
745 return -EINVAL;
746
747 /*
748 * Get I/O port addresses. Convert to GAS format.
749 */
750 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
751 acpi_ec_io_ports, ec);
752 if (ACPI_FAILURE(status) || ec->command_addr == 0) {
753 ACPI_EXCEPTION((AE_INFO, status,
754 "Error getting I/O port addresses"));
755 return -ENODEV;
756 }
757
758 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
759 ec->gpe, ec->command_addr, ec->data_addr));
760
761 /*
762 * Install GPE handler
763 */
764 status = acpi_install_gpe_handler(NULL, ec->gpe, 700 status = acpi_install_gpe_handler(NULL, ec->gpe,
765 ACPI_GPE_EDGE_TRIGGERED, 701 ACPI_GPE_EDGE_TRIGGERED,
766 &acpi_ec_gpe_handler, ec); 702 &acpi_ec_gpe_handler, ec);
767 if (ACPI_FAILURE(status)) { 703 if (ACPI_FAILURE(status))
768 return -ENODEV; 704 return -ENODEV;
769 } 705
770 acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); 706 acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
771 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 707 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
772 708
@@ -779,18 +715,49 @@ static int acpi_ec_start(struct acpi_device *device)
779 return -ENODEV; 715 return -ENODEV;
780 } 716 }
781 717
782 return AE_OK; 718 /* EC is fully operational, allow queries */
719 atomic_set(&ec->query_pending, 0);
720
721 return 0;
722}
723
724static int acpi_ec_start(struct acpi_device *device)
725{
726 struct acpi_ec *ec;
727
728 if (!device)
729 return -EINVAL;
730
731 ec = acpi_driver_data(device);
732
733 if (!ec)
734 return -EINVAL;
735
736 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
737 ec->gpe, ec->command_addr, ec->data_addr));
738
739 /* Boot EC is already working */
740 if (ec == boot_ec)
741 return 0;
742
743 return ec_install_handlers(ec);
783} 744}
784 745
785static int acpi_ec_stop(struct acpi_device *device, int type) 746static int acpi_ec_stop(struct acpi_device *device, int type)
786{ 747{
787 acpi_status status = AE_OK; 748 acpi_status status;
788 struct acpi_ec *ec = NULL; 749 struct acpi_ec *ec;
789 750
790 if (!device) 751 if (!device)
791 return -EINVAL; 752 return -EINVAL;
792 753
793 ec = acpi_driver_data(device); 754 ec = acpi_driver_data(device);
755 if (!ec)
756 return -EINVAL;
757
758 /* Don't touch boot EC */
759 if (ec == boot_ec)
760 return 0;
794 761
795 status = acpi_remove_address_space_handler(ec->handle, 762 status = acpi_remove_address_space_handler(ec->handle,
796 ACPI_ADR_SPACE_EC, 763 ACPI_ADR_SPACE_EC,
@@ -805,164 +772,67 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
805 return 0; 772 return 0;
806} 773}
807 774
808static acpi_status __init 775static acpi_status
809acpi_fake_ecdt_callback(acpi_handle handle, 776ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
810 u32 Level, void *context, void **retval)
811{ 777{
812 acpi_status status; 778 acpi_status status;
813 779
814 mutex_init(&ec_ecdt->lock); 780 struct acpi_ec *ec = context;
815 atomic_set(&ec_ecdt->event_count, 1);
816 if (acpi_ec_mode == EC_INTR) {
817 init_waitqueue_head(&ec_ecdt->wait);
818 }
819 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 781 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
820 acpi_ec_io_ports, ec_ecdt); 782 ec_parse_io_ports, ec);
821 if (ACPI_FAILURE(status)) 783 if (ACPI_FAILURE(status))
822 return status; 784 return status;
823 785
824 ec_ecdt->uid = -1; 786 /* Get GPE bit assignment (EC events). */
825 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); 787 /* TODO: Add support for _GPE returning a package */
826 788 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
827 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
828 if (ACPI_FAILURE(status)) 789 if (ACPI_FAILURE(status))
829 return status; 790 return status;
830 ec_ecdt->global_lock = TRUE;
831 ec_ecdt->handle = handle;
832
833 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
834 ec_ecdt->gpe, ec_ecdt->command_addr,
835 ec_ecdt->data_addr));
836 791
837 return AE_CTRL_TERMINATE; 792 /* Use the global lock for all EC transactions? */
838} 793 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
839
840/*
841 * Some BIOS (such as some from Gateway laptops) access EC region very early
842 * such as in BAT0._INI or EC._INI before an EC device is found and
843 * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
844 * required, but if EC regison is accessed early, it is required.
845 * The routine tries to workaround the BIOS bug by pre-scan EC device
846 * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
847 * op region (since _REG isn't invoked yet). The assumption is true for
848 * all systems found.
849 */
850static int __init acpi_ec_fake_ecdt(void)
851{
852 acpi_status status;
853 int ret = 0;
854 794
855 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); 795 ec->handle = handle;
856 796
857 ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); 797 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
858 if (!ec_ecdt) { 798 ec->gpe, ec->command_addr, ec->data_addr));
859 ret = -ENOMEM;
860 goto error;
861 }
862 799
863 status = acpi_get_devices(ACPI_EC_HID, 800 return AE_CTRL_TERMINATE;
864 acpi_fake_ecdt_callback, NULL, NULL);
865 if (ACPI_FAILURE(status)) {
866 kfree(ec_ecdt);
867 ec_ecdt = NULL;
868 ret = -ENODEV;
869 ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
870 goto error;
871 }
872 return 0;
873 error:
874 return ret;
875} 801}
876 802
877static int __init acpi_ec_get_real_ecdt(void) 803int __init acpi_ec_ecdt_probe(void)
878{ 804{
805 int ret;
879 acpi_status status; 806 acpi_status status;
880 struct acpi_table_ecdt *ecdt_ptr; 807 struct acpi_table_ecdt *ecdt_ptr;
881 808
882 status = acpi_get_table(ACPI_SIG_ECDT, 1, 809 boot_ec = make_acpi_ec();
883 (struct acpi_table_header **)&ecdt_ptr); 810 if (!boot_ec)
884 if (ACPI_FAILURE(status)) 811 return -ENOMEM;
885 return -ENODEV;
886
887 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
888
889 /* 812 /*
890 * Generate a temporary ec context to use until the namespace is scanned 813 * Generate a boot ec context
891 */ 814 */
892 ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
893 if (!ec_ecdt)
894 return -ENOMEM;
895 815
896 mutex_init(&ec_ecdt->lock); 816 status = acpi_get_table(ACPI_SIG_ECDT, 1,
897 atomic_set(&ec_ecdt->event_count, 1); 817 (struct acpi_table_header **)&ecdt_ptr);
898 if (acpi_ec_mode == EC_INTR) { 818 if (ACPI_FAILURE(status))
899 init_waitqueue_head(&ec_ecdt->wait);
900 }
901 ec_ecdt->command_addr = ecdt_ptr->control.address;
902 ec_ecdt->data_addr = ecdt_ptr->data.address;
903 ec_ecdt->gpe = ecdt_ptr->gpe;
904 /* use the GL just to be safe */
905 ec_ecdt->global_lock = TRUE;
906 ec_ecdt->uid = ecdt_ptr->uid;
907
908 status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle);
909 if (ACPI_FAILURE(status)) {
910 goto error; 819 goto error;
911 }
912
913 return 0;
914 error:
915 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
916 kfree(ec_ecdt);
917 ec_ecdt = NULL;
918 820
919 return -ENODEV; 821 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
920}
921
922static int __initdata acpi_fake_ecdt_enabled;
923int __init acpi_ec_ecdt_probe(void)
924{
925 acpi_status status;
926 int ret;
927 822
928 ret = acpi_ec_get_real_ecdt(); 823 boot_ec->command_addr = ecdt_ptr->control.address;
929 /* Try to make a fake ECDT */ 824 boot_ec->data_addr = ecdt_ptr->data.address;
930 if (ret && acpi_fake_ecdt_enabled) { 825 boot_ec->gpe = ecdt_ptr->gpe;
931 ret = acpi_ec_fake_ecdt(); 826 boot_ec->handle = ACPI_ROOT_OBJECT;
932 }
933 827
934 if (ret) 828 ret = ec_install_handlers(boot_ec);
829 if (!ret) {
830 first_ec = boot_ec;
935 return 0; 831 return 0;
936
937 /*
938 * Install GPE handler
939 */
940 status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe,
941 ACPI_GPE_EDGE_TRIGGERED,
942 &acpi_ec_gpe_handler, ec_ecdt);
943 if (ACPI_FAILURE(status)) {
944 goto error;
945 } 832 }
946 acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME);
947 acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR);
948
949 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
950 ACPI_ADR_SPACE_EC,
951 &acpi_ec_space_handler,
952 &acpi_ec_space_setup,
953 ec_ecdt);
954 if (ACPI_FAILURE(status)) {
955 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
956 &acpi_ec_gpe_handler);
957 goto error;
958 }
959
960 return 0;
961
962 error: 833 error:
963 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); 834 kfree(boot_ec);
964 kfree(ec_ecdt); 835 boot_ec = NULL;
965 ec_ecdt = NULL;
966 836
967 return -ENODEV; 837 return -ENODEV;
968} 838}
@@ -1003,13 +873,6 @@ static void __exit acpi_ec_exit(void)
1003} 873}
1004#endif /* 0 */ 874#endif /* 0 */
1005 875
1006static int __init acpi_fake_ecdt_setup(char *str)
1007{
1008 acpi_fake_ecdt_enabled = 1;
1009 return 1;
1010}
1011
1012__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
1013static int __init acpi_ec_set_intr_mode(char *str) 876static int __init acpi_ec_set_intr_mode(char *str)
1014{ 877{
1015 int intr; 878 int intr;
@@ -1017,12 +880,8 @@ static int __init acpi_ec_set_intr_mode(char *str)
1017 if (!get_option(&str, &intr)) 880 if (!get_option(&str, &intr))
1018 return 0; 881 return 0;
1019 882
1020 if (intr) { 883 acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
1021 acpi_ec_mode = EC_INTR; 884
1022 } else {
1023 acpi_ec_mode = EC_POLL;
1024 }
1025 acpi_ec_driver.ops.add = acpi_ec_add;
1026 printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling"); 885 printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
1027 886
1028 return 1; 887 return 1;