Lines 807-812
acpi_battery_remove (
Link Here
|
807 |
} |
807 |
} |
808 |
|
808 |
|
809 |
|
809 |
|
|
|
810 |
/* Battery hotplug support */ |
811 |
static |
812 |
int acpi_battery_device_add( |
813 |
acpi_handle handle, |
814 |
struct acpi_device **device) |
815 |
{ |
816 |
acpi_handle phandle; |
817 |
struct acpi_device *pdev; |
818 |
|
819 |
ACPI_FUNCTION_TRACE("acpi_battery_device_add"); |
820 |
|
821 |
if (acpi_get_parent(handle, &phandle)) { |
822 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
823 |
"Can't get battery's parent\n")); |
824 |
return_VALUE(-ENODEV); |
825 |
} |
826 |
|
827 |
if (acpi_bus_get_device(phandle, &pdev)) { |
828 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
829 |
"Battery's parrent isn't present\n")); |
830 |
return_VALUE(-ENODEV); |
831 |
} |
832 |
|
833 |
/* power on device */ |
834 |
acpi_evaluate_object(handle, "_PS0", NULL, NULL); |
835 |
|
836 |
if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) { |
837 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
838 |
"Add battery device failed\n")); |
839 |
return_VALUE(-ENODEV); |
840 |
} |
841 |
|
842 |
if (!acpi_driver_data(*device)) { |
843 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
844 |
"Init battery device failed\n")); |
845 |
return_VALUE(-ENODEV); |
846 |
} |
847 |
|
848 |
return_VALUE(0); |
849 |
} |
850 |
|
851 |
extern int acpi_bus_trim(struct acpi_device *dev, int); |
852 |
static |
853 |
int acpi_battery_device_remove(struct acpi_device *device) |
854 |
{ |
855 |
int ret; |
856 |
acpi_status status; |
857 |
struct acpi_object_list arg_list; |
858 |
union acpi_object arg; |
859 |
acpi_handle handle = device->handle; |
860 |
|
861 |
ACPI_FUNCTION_TRACE("acpi_battery_device_remove"); |
862 |
|
863 |
ret = acpi_bus_trim(device, 1); |
864 |
if (ret) { |
865 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
866 |
"Remove battery device failed\n")); |
867 |
return_VALUE(ret); |
868 |
} |
869 |
|
870 |
status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); |
871 |
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
872 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
873 |
"Invoking _PS3 method failed\n")); |
874 |
return_VALUE(-EINVAL); |
875 |
} |
876 |
|
877 |
arg_list.count = 1; |
878 |
arg_list.pointer = &arg; |
879 |
arg.type = ACPI_TYPE_INTEGER; |
880 |
arg.integer.value = 1; |
881 |
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); |
882 |
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
883 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
884 |
"Invoking _EJ0 failed\n")); |
885 |
return_VALUE(-EINVAL); |
886 |
} |
887 |
return_VALUE(0); |
888 |
} |
889 |
|
890 |
#define ACPI_STA_PRESENT 0x00000001 |
891 |
static void |
892 |
acpi_battery_hotplug_notify ( |
893 |
acpi_handle handle, |
894 |
u32 event, |
895 |
void *data) |
896 |
{ |
897 |
struct acpi_device *device = NULL; |
898 |
int result; |
899 |
acpi_status status; |
900 |
unsigned long sta = 0; |
901 |
|
902 |
ACPI_FUNCTION_TRACE("acpi_battery_hotplug_notify"); |
903 |
|
904 |
switch (event) { |
905 |
case ACPI_NOTIFY_BUS_CHECK: |
906 |
case ACPI_NOTIFY_DEVICE_CHECK: |
907 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Online battery...\n")); |
908 |
|
909 |
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
910 |
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) { |
911 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
912 |
"Battery Device is not present\n")); |
913 |
return_VOID; |
914 |
} |
915 |
if (acpi_bus_get_device(handle, &device)) { |
916 |
/* device isn't in tree, add it */ |
917 |
result = acpi_battery_device_add(handle, &device); |
918 |
if (result) |
919 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
920 |
"Unable to add the device\n")); |
921 |
} else { |
922 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
923 |
"Battery is present already\n")); |
924 |
} |
925 |
break; |
926 |
case ACPI_NOTIFY_EJECT_REQUEST: |
927 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Offline battery...\n")); |
928 |
|
929 |
if (!acpi_bus_get_device(handle, &device)) { |
930 |
result = acpi_battery_device_remove(device); |
931 |
if (result) |
932 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
933 |
"Eject battery failed\n")); |
934 |
} else { |
935 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
936 |
"Battery isn't present\n")); |
937 |
} |
938 |
break; |
939 |
default: |
940 |
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
941 |
"Unsupported notify type\n")); |
942 |
break; |
943 |
} |
944 |
return_VOID; |
945 |
} |
946 |
|
947 |
#define INSTALL_NOTIFY_HANDLER 0 |
948 |
#define UNINSTALL_NOTIFY_HANDLER 1 |
949 |
static acpi_status |
950 |
battery_walk_namespace_cb(acpi_handle handle, |
951 |
u32 lvl, |
952 |
void *context, |
953 |
void **rv) |
954 |
{ |
955 |
acpi_status status; |
956 |
struct acpi_device_info *info; |
957 |
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
958 |
int *action = context; |
959 |
|
960 |
status = acpi_get_object_info(handle, &buffer); |
961 |
if (!ACPI_SUCCESS(status)) |
962 |
return AE_OK; |
963 |
info = buffer.pointer; |
964 |
if (!(info->valid & ACPI_VALID_HID) || |
965 |
strcmp(ACPI_BATTERY_HID, info->hardware_id.value)) |
966 |
return AE_OK; |
967 |
|
968 |
switch(*action) { |
969 |
case INSTALL_NOTIFY_HANDLER: |
970 |
acpi_install_notify_handler(handle, |
971 |
ACPI_SYSTEM_NOTIFY, |
972 |
acpi_battery_hotplug_notify, |
973 |
NULL); |
974 |
break; |
975 |
case UNINSTALL_NOTIFY_HANDLER: |
976 |
acpi_remove_notify_handler(handle, |
977 |
ACPI_SYSTEM_NOTIFY, |
978 |
acpi_battery_hotplug_notify); |
979 |
break; |
980 |
default: |
981 |
break; |
982 |
} |
983 |
|
984 |
return(AE_OK); |
985 |
} |
986 |
|
987 |
static void acpi_battery_setup_hotplug_notify(int install) |
988 |
{ |
989 |
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
990 |
ACPI_UINT32_MAX, |
991 |
battery_walk_namespace_cb, |
992 |
&install, NULL); |
993 |
} |
994 |
|
810 |
static int __init |
995 |
static int __init |
811 |
acpi_battery_init (void) |
996 |
acpi_battery_init (void) |
812 |
{ |
997 |
{ |
Lines 825-830
acpi_battery_init (void)
Link Here
|
825 |
return_VALUE(-ENODEV); |
1010 |
return_VALUE(-ENODEV); |
826 |
} |
1011 |
} |
827 |
|
1012 |
|
|
|
1013 |
acpi_battery_setup_hotplug_notify(INSTALL_NOTIFY_HANDLER); |
828 |
return_VALUE(0); |
1014 |
return_VALUE(0); |
829 |
} |
1015 |
} |
830 |
|
1016 |
|
Lines 834-839
acpi_battery_exit (void)
Link Here
|
834 |
{ |
1020 |
{ |
835 |
ACPI_FUNCTION_TRACE("acpi_battery_exit"); |
1021 |
ACPI_FUNCTION_TRACE("acpi_battery_exit"); |
836 |
|
1022 |
|
|
|
1023 |
acpi_battery_setup_hotplug_notify(UNINSTALL_NOTIFY_HANDLER); |
1024 |
|
837 |
acpi_bus_unregister_driver(&acpi_battery_driver); |
1025 |
acpi_bus_unregister_driver(&acpi_battery_driver); |
838 |
|
1026 |
|
839 |
remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); |
1027 |
remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); |