tangled
alpha
login
or
join now
tjh.dev
/
kernel
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Pull ec into release branch
Len Brown
18 years ago
d88da66f
6712a4fb
+45
-68
1 changed file
expand all
collapse all
unified
split
drivers
acpi
ec.c
+45
-68
drivers/acpi/ec.c
···
471
}
472
}
473
mutex_unlock(&ec->lock);
474
-
printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
475
}
476
477
static u32 acpi_ec_gpe_handler(void *data)
···
652
}
653
654
static acpi_status
655
-
acpi_ec_register_query_methods(acpi_handle handle, u32 level,
656
-
void *context, void **return_value)
657
{
658
-
struct acpi_namespace_node *node = handle;
659
-
struct acpi_ec *ec = context;
660
-
int value = 0;
661
-
if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
662
-
acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
663
-
}
664
-
return AE_OK;
665
-
}
666
667
-
static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
668
-
{
669
-
if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
670
-
ec_parse_io_ports, ec)))
671
-
return -EINVAL;
672
673
/* Get GPE bit assignment (EC events). */
674
/* TODO: Add support for _GPE returning a package */
675
-
if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
676
-
return -EINVAL;
0
677
678
/* Use the global lock for all EC transactions? */
679
acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
680
681
-
/* Find and register all query methods */
682
-
acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
683
-
acpi_ec_register_query_methods, ec, NULL);
684
-
685
ec->handle = handle;
686
687
-
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
688
ec->gpe, ec->command_addr, ec->data_addr);
689
690
-
return 0;
0
0
0
0
0
0
0
0
691
}
692
693
static int acpi_ec_add(struct acpi_device *device)
···
701
if (!ec)
702
return -ENOMEM;
703
704
-
if (ec_parse_device(ec, device->handle)) {
0
705
kfree(ec);
706
return -EINVAL;
707
}
···
710
/* Check if we found the boot EC */
711
if (boot_ec) {
712
if (boot_ec->gpe == ec->gpe) {
713
-
/* We might have incorrect info for GL at boot time */
714
-
mutex_lock(&boot_ec->lock);
715
-
boot_ec->global_lock = ec->global_lock;
716
-
/* Copy handlers from new ec into boot ec */
717
-
list_splice(&ec->list, &boot_ec->list);
718
-
mutex_unlock(&boot_ec->lock);
719
-
kfree(ec);
720
-
ec = boot_ec;
721
}
722
-
} else
0
723
first_ec = ec;
724
ec->handle = device->handle;
725
acpi_driver_data(device) = ec;
···
728
static int acpi_ec_remove(struct acpi_device *device, int type)
729
{
730
struct acpi_ec *ec;
731
-
struct acpi_ec_query_handler *handler;
732
733
if (!device)
734
return -EINVAL;
735
736
ec = acpi_driver_data(device);
737
mutex_lock(&ec->lock);
738
-
list_for_each_entry(handler, &ec->list, node) {
739
list_del(&handler->node);
740
kfree(handler);
741
}
···
745
if (ec == first_ec)
746
first_ec = NULL;
747
748
-
/* Don't touch boot EC */
749
-
if (boot_ec != ec)
750
-
kfree(ec);
751
return 0;
752
}
753
···
808
if (!ec)
809
return -EINVAL;
810
811
-
/* Boot EC is already working */
812
-
if (ec != boot_ec)
813
-
ret = ec_install_handlers(ec);
814
815
/* EC is fully operational, allow queries */
816
atomic_set(&ec->query_pending, 0);
···
818
819
static int acpi_ec_stop(struct acpi_device *device, int type)
820
{
821
-
acpi_status status;
822
struct acpi_ec *ec;
823
824
if (!device)
···
826
ec = acpi_driver_data(device);
827
if (!ec)
828
return -EINVAL;
829
-
830
-
/* Don't touch boot EC */
831
-
if (ec == boot_ec)
832
-
return 0;
833
-
834
-
status = acpi_remove_address_space_handler(ec->handle,
835
-
ACPI_ADR_SPACE_EC,
836
-
&acpi_ec_space_handler);
837
-
if (ACPI_FAILURE(status))
838
-
return -ENODEV;
839
-
840
-
status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
841
-
if (ACPI_FAILURE(status))
842
-
return -ENODEV;
843
-
844
return 0;
845
}
846
···
842
/*
843
* Generate a boot ec context
844
*/
845
-
846
status = acpi_get_table(ACPI_SIG_ECDT, 1,
847
(struct acpi_table_header **)&ecdt_ptr);
848
-
if (ACPI_FAILURE(status))
849
-
goto error;
850
-
851
-
printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
852
-
853
-
boot_ec->command_addr = ecdt_ptr->control.address;
854
-
boot_ec->data_addr = ecdt_ptr->data.address;
855
-
boot_ec->gpe = ecdt_ptr->gpe;
856
-
boot_ec->handle = ACPI_ROOT_OBJECT;
0
0
0
0
857
858
ret = ec_install_handlers(boot_ec);
859
if (!ret) {
···
471
}
472
}
473
mutex_unlock(&ec->lock);
0
474
}
475
476
static u32 acpi_ec_gpe_handler(void *data)
···
653
}
654
655
static acpi_status
656
+
ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
0
657
{
658
+
acpi_status status;
0
0
0
0
0
0
0
659
660
+
struct acpi_ec *ec = context;
661
+
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
662
+
ec_parse_io_ports, ec);
663
+
if (ACPI_FAILURE(status))
664
+
return status;
665
666
/* Get GPE bit assignment (EC events). */
667
/* TODO: Add support for _GPE returning a package */
668
+
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
669
+
if (ACPI_FAILURE(status))
670
+
return status;
671
672
/* Use the global lock for all EC transactions? */
673
acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
674
0
0
0
0
675
ec->handle = handle;
676
677
+
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
678
ec->gpe, ec->command_addr, ec->data_addr);
679
680
+
return AE_CTRL_TERMINATE;
681
+
}
682
+
683
+
static void ec_remove_handlers(struct acpi_ec *ec)
684
+
{
685
+
acpi_remove_address_space_handler(ec->handle,
686
+
ACPI_ADR_SPACE_EC,
687
+
&acpi_ec_space_handler);
688
+
acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
689
}
690
691
static int acpi_ec_add(struct acpi_device *device)
···
705
if (!ec)
706
return -ENOMEM;
707
708
+
if (ec_parse_device(device->handle, 0, ec, NULL) !=
709
+
AE_CTRL_TERMINATE) {
710
kfree(ec);
711
return -EINVAL;
712
}
···
713
/* Check if we found the boot EC */
714
if (boot_ec) {
715
if (boot_ec->gpe == ec->gpe) {
716
+
ec_remove_handlers(boot_ec);
717
+
mutex_destroy(&boot_ec->lock);
718
+
kfree(boot_ec);
719
+
first_ec = boot_ec = NULL;
0
0
0
0
720
}
721
+
}
722
+
if (!first_ec)
723
first_ec = ec;
724
ec->handle = device->handle;
725
acpi_driver_data(device) = ec;
···
734
static int acpi_ec_remove(struct acpi_device *device, int type)
735
{
736
struct acpi_ec *ec;
737
+
struct acpi_ec_query_handler *handler, *tmp;
738
739
if (!device)
740
return -EINVAL;
741
742
ec = acpi_driver_data(device);
743
mutex_lock(&ec->lock);
744
+
list_for_each_entry_safe(handler, tmp, &ec->list, node) {
745
list_del(&handler->node);
746
kfree(handler);
747
}
···
751
if (ec == first_ec)
752
first_ec = NULL;
753
0
0
0
754
return 0;
755
}
756
···
817
if (!ec)
818
return -EINVAL;
819
820
+
ret = ec_install_handlers(ec);
0
0
821
822
/* EC is fully operational, allow queries */
823
atomic_set(&ec->query_pending, 0);
···
829
830
static int acpi_ec_stop(struct acpi_device *device, int type)
831
{
0
832
struct acpi_ec *ec;
833
834
if (!device)
···
838
ec = acpi_driver_data(device);
839
if (!ec)
840
return -EINVAL;
841
+
ec_remove_handlers(ec);
0
0
0
0
0
0
0
0
0
0
0
0
0
0
842
return 0;
843
}
844
···
868
/*
869
* Generate a boot ec context
870
*/
0
871
status = acpi_get_table(ACPI_SIG_ECDT, 1,
872
(struct acpi_table_header **)&ecdt_ptr);
873
+
if (ACPI_SUCCESS(status)) {
874
+
printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
875
+
boot_ec->command_addr = ecdt_ptr->control.address;
876
+
boot_ec->data_addr = ecdt_ptr->data.address;
877
+
boot_ec->gpe = ecdt_ptr->gpe;
878
+
boot_ec->handle = ACPI_ROOT_OBJECT;
879
+
} else {
880
+
printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
881
+
status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
882
+
boot_ec, NULL);
883
+
if (ACPI_FAILURE(status))
884
+
goto error;
885
+
}
886
887
ret = ec_install_handlers(boot_ec);
888
if (!ret) {