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