diff options
author | Lan Tianyu <tianyu.lan@intel.com> | 2014-05-03 23:07:25 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-05 19:54:39 -0400 |
commit | 3a670cc79342c36d308decd5f90351830ed1685c (patch) | |
tree | 647508446ca87b43c00bed657f194c136a2ed189 | |
parent | e2a7c3d7812369daae56f069eab2e8f3e548d231 (diff) |
ACPI: Revert "ACPI / Battery: Remove battery's proc directory"
The commit 1e2d9cd and 7d7ee95 remove ACPI Proc Battery
directory and breaks some old userspace tools. This patch
is to revert commit 1e2d9cd.
Fixes: 1e2d9cdfb449 (ACPI / Battery: Remove battery's proc directory)
Cc: 3.13+ <stable@vger.kernel.org> # 3.13+
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/battery.c | 329 |
1 files changed, 328 insertions, 1 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9a2c63b20050..6e7b2a12860d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -36,6 +36,12 @@ | |||
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
38 | 38 | ||
39 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
40 | #include <linux/proc_fs.h> | ||
41 | #include <linux/seq_file.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | #endif | ||
44 | |||
39 | #include <linux/acpi.h> | 45 | #include <linux/acpi.h> |
40 | #include <linux/power_supply.h> | 46 | #include <linux/power_supply.h> |
41 | 47 | ||
@@ -64,6 +70,19 @@ static unsigned int cache_time = 1000; | |||
64 | module_param(cache_time, uint, 0644); | 70 | module_param(cache_time, uint, 0644); |
65 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 71 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
66 | 72 | ||
73 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
74 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
75 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
76 | |||
77 | enum acpi_battery_files { | ||
78 | info_tag = 0, | ||
79 | state_tag, | ||
80 | alarm_tag, | ||
81 | ACPI_BATTERY_NUMFILES, | ||
82 | }; | ||
83 | |||
84 | #endif | ||
85 | |||
67 | static const struct acpi_device_id battery_device_ids[] = { | 86 | static const struct acpi_device_id battery_device_ids[] = { |
68 | {"PNP0C0A", 0}, | 87 | {"PNP0C0A", 0}, |
69 | {"", 0}, | 88 | {"", 0}, |
@@ -299,6 +318,14 @@ static enum power_supply_property energy_battery_props[] = { | |||
299 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 318 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
300 | }; | 319 | }; |
301 | 320 | ||
321 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
322 | inline char *acpi_battery_units(struct acpi_battery *battery) | ||
323 | { | ||
324 | return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? | ||
325 | "mA" : "mW"; | ||
326 | } | ||
327 | #endif | ||
328 | |||
302 | /* -------------------------------------------------------------------------- | 329 | /* -------------------------------------------------------------------------- |
303 | Battery Management | 330 | Battery Management |
304 | -------------------------------------------------------------------------- */ | 331 | -------------------------------------------------------------------------- */ |
@@ -717,6 +744,279 @@ static void acpi_battery_refresh(struct acpi_battery *battery) | |||
717 | } | 744 | } |
718 | 745 | ||
719 | /* -------------------------------------------------------------------------- | 746 | /* -------------------------------------------------------------------------- |
747 | FS Interface (/proc) | ||
748 | -------------------------------------------------------------------------- */ | ||
749 | |||
750 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
751 | static struct proc_dir_entry *acpi_battery_dir; | ||
752 | |||
753 | static int acpi_battery_print_info(struct seq_file *seq, int result) | ||
754 | { | ||
755 | struct acpi_battery *battery = seq->private; | ||
756 | |||
757 | if (result) | ||
758 | goto end; | ||
759 | |||
760 | seq_printf(seq, "present: %s\n", | ||
761 | acpi_battery_present(battery) ? "yes" : "no"); | ||
762 | if (!acpi_battery_present(battery)) | ||
763 | goto end; | ||
764 | if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
765 | seq_printf(seq, "design capacity: unknown\n"); | ||
766 | else | ||
767 | seq_printf(seq, "design capacity: %d %sh\n", | ||
768 | battery->design_capacity, | ||
769 | acpi_battery_units(battery)); | ||
770 | |||
771 | if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
772 | seq_printf(seq, "last full capacity: unknown\n"); | ||
773 | else | ||
774 | seq_printf(seq, "last full capacity: %d %sh\n", | ||
775 | battery->full_charge_capacity, | ||
776 | acpi_battery_units(battery)); | ||
777 | |||
778 | seq_printf(seq, "battery technology: %srechargeable\n", | ||
779 | (!battery->technology)?"non-":""); | ||
780 | |||
781 | if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | ||
782 | seq_printf(seq, "design voltage: unknown\n"); | ||
783 | else | ||
784 | seq_printf(seq, "design voltage: %d mV\n", | ||
785 | battery->design_voltage); | ||
786 | seq_printf(seq, "design capacity warning: %d %sh\n", | ||
787 | battery->design_capacity_warning, | ||
788 | acpi_battery_units(battery)); | ||
789 | seq_printf(seq, "design capacity low: %d %sh\n", | ||
790 | battery->design_capacity_low, | ||
791 | acpi_battery_units(battery)); | ||
792 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
793 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | ||
794 | battery->capacity_granularity_1, | ||
795 | acpi_battery_units(battery)); | ||
796 | seq_printf(seq, "capacity granularity 2: %d %sh\n", | ||
797 | battery->capacity_granularity_2, | ||
798 | acpi_battery_units(battery)); | ||
799 | seq_printf(seq, "model number: %s\n", battery->model_number); | ||
800 | seq_printf(seq, "serial number: %s\n", battery->serial_number); | ||
801 | seq_printf(seq, "battery type: %s\n", battery->type); | ||
802 | seq_printf(seq, "OEM info: %s\n", battery->oem_info); | ||
803 | end: | ||
804 | if (result) | ||
805 | seq_printf(seq, "ERROR: Unable to read battery info\n"); | ||
806 | return result; | ||
807 | } | ||
808 | |||
809 | static int acpi_battery_print_state(struct seq_file *seq, int result) | ||
810 | { | ||
811 | struct acpi_battery *battery = seq->private; | ||
812 | |||
813 | if (result) | ||
814 | goto end; | ||
815 | |||
816 | seq_printf(seq, "present: %s\n", | ||
817 | acpi_battery_present(battery) ? "yes" : "no"); | ||
818 | if (!acpi_battery_present(battery)) | ||
819 | goto end; | ||
820 | |||
821 | seq_printf(seq, "capacity state: %s\n", | ||
822 | (battery->state & 0x04) ? "critical" : "ok"); | ||
823 | if ((battery->state & 0x01) && (battery->state & 0x02)) | ||
824 | seq_printf(seq, | ||
825 | "charging state: charging/discharging\n"); | ||
826 | else if (battery->state & 0x01) | ||
827 | seq_printf(seq, "charging state: discharging\n"); | ||
828 | else if (battery->state & 0x02) | ||
829 | seq_printf(seq, "charging state: charging\n"); | ||
830 | else | ||
831 | seq_printf(seq, "charging state: charged\n"); | ||
832 | |||
833 | if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
834 | seq_printf(seq, "present rate: unknown\n"); | ||
835 | else | ||
836 | seq_printf(seq, "present rate: %d %s\n", | ||
837 | battery->rate_now, acpi_battery_units(battery)); | ||
838 | |||
839 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
840 | seq_printf(seq, "remaining capacity: unknown\n"); | ||
841 | else | ||
842 | seq_printf(seq, "remaining capacity: %d %sh\n", | ||
843 | battery->capacity_now, acpi_battery_units(battery)); | ||
844 | if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
845 | seq_printf(seq, "present voltage: unknown\n"); | ||
846 | else | ||
847 | seq_printf(seq, "present voltage: %d mV\n", | ||
848 | battery->voltage_now); | ||
849 | end: | ||
850 | if (result) | ||
851 | seq_printf(seq, "ERROR: Unable to read battery state\n"); | ||
852 | |||
853 | return result; | ||
854 | } | ||
855 | |||
856 | static int acpi_battery_print_alarm(struct seq_file *seq, int result) | ||
857 | { | ||
858 | struct acpi_battery *battery = seq->private; | ||
859 | |||
860 | if (result) | ||
861 | goto end; | ||
862 | |||
863 | if (!acpi_battery_present(battery)) { | ||
864 | seq_printf(seq, "present: no\n"); | ||
865 | goto end; | ||
866 | } | ||
867 | seq_printf(seq, "alarm: "); | ||
868 | if (!battery->alarm) | ||
869 | seq_printf(seq, "unsupported\n"); | ||
870 | else | ||
871 | seq_printf(seq, "%u %sh\n", battery->alarm, | ||
872 | acpi_battery_units(battery)); | ||
873 | end: | ||
874 | if (result) | ||
875 | seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | ||
876 | return result; | ||
877 | } | ||
878 | |||
879 | static ssize_t acpi_battery_write_alarm(struct file *file, | ||
880 | const char __user * buffer, | ||
881 | size_t count, loff_t * ppos) | ||
882 | { | ||
883 | int result = 0; | ||
884 | char alarm_string[12] = { '\0' }; | ||
885 | struct seq_file *m = file->private_data; | ||
886 | struct acpi_battery *battery = m->private; | ||
887 | |||
888 | if (!battery || (count > sizeof(alarm_string) - 1)) | ||
889 | return -EINVAL; | ||
890 | if (!acpi_battery_present(battery)) { | ||
891 | result = -ENODEV; | ||
892 | goto end; | ||
893 | } | ||
894 | if (copy_from_user(alarm_string, buffer, count)) { | ||
895 | result = -EFAULT; | ||
896 | goto end; | ||
897 | } | ||
898 | alarm_string[count] = '\0'; | ||
899 | battery->alarm = simple_strtol(alarm_string, NULL, 0); | ||
900 | result = acpi_battery_set_alarm(battery); | ||
901 | end: | ||
902 | if (!result) | ||
903 | return count; | ||
904 | return result; | ||
905 | } | ||
906 | |||
907 | typedef int(*print_func)(struct seq_file *seq, int result); | ||
908 | |||
909 | static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { | ||
910 | acpi_battery_print_info, | ||
911 | acpi_battery_print_state, | ||
912 | acpi_battery_print_alarm, | ||
913 | }; | ||
914 | |||
915 | static int acpi_battery_read(int fid, struct seq_file *seq) | ||
916 | { | ||
917 | struct acpi_battery *battery = seq->private; | ||
918 | int result = acpi_battery_update(battery); | ||
919 | return acpi_print_funcs[fid](seq, result); | ||
920 | } | ||
921 | |||
922 | #define DECLARE_FILE_FUNCTIONS(_name) \ | ||
923 | static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ | ||
924 | { \ | ||
925 | return acpi_battery_read(_name##_tag, seq); \ | ||
926 | } \ | ||
927 | static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ | ||
928 | { \ | ||
929 | return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ | ||
930 | } | ||
931 | |||
932 | DECLARE_FILE_FUNCTIONS(info); | ||
933 | DECLARE_FILE_FUNCTIONS(state); | ||
934 | DECLARE_FILE_FUNCTIONS(alarm); | ||
935 | |||
936 | #undef DECLARE_FILE_FUNCTIONS | ||
937 | |||
938 | #define FILE_DESCRIPTION_RO(_name) \ | ||
939 | { \ | ||
940 | .name = __stringify(_name), \ | ||
941 | .mode = S_IRUGO, \ | ||
942 | .ops = { \ | ||
943 | .open = acpi_battery_##_name##_open_fs, \ | ||
944 | .read = seq_read, \ | ||
945 | .llseek = seq_lseek, \ | ||
946 | .release = single_release, \ | ||
947 | .owner = THIS_MODULE, \ | ||
948 | }, \ | ||
949 | } | ||
950 | |||
951 | #define FILE_DESCRIPTION_RW(_name) \ | ||
952 | { \ | ||
953 | .name = __stringify(_name), \ | ||
954 | .mode = S_IFREG | S_IRUGO | S_IWUSR, \ | ||
955 | .ops = { \ | ||
956 | .open = acpi_battery_##_name##_open_fs, \ | ||
957 | .read = seq_read, \ | ||
958 | .llseek = seq_lseek, \ | ||
959 | .write = acpi_battery_write_##_name, \ | ||
960 | .release = single_release, \ | ||
961 | .owner = THIS_MODULE, \ | ||
962 | }, \ | ||
963 | } | ||
964 | |||
965 | static const struct battery_file { | ||
966 | struct file_operations ops; | ||
967 | umode_t mode; | ||
968 | const char *name; | ||
969 | } acpi_battery_file[] = { | ||
970 | FILE_DESCRIPTION_RO(info), | ||
971 | FILE_DESCRIPTION_RO(state), | ||
972 | FILE_DESCRIPTION_RW(alarm), | ||
973 | }; | ||
974 | |||
975 | #undef FILE_DESCRIPTION_RO | ||
976 | #undef FILE_DESCRIPTION_RW | ||
977 | |||
978 | static int acpi_battery_add_fs(struct acpi_device *device) | ||
979 | { | ||
980 | struct proc_dir_entry *entry = NULL; | ||
981 | int i; | ||
982 | |||
983 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," | ||
984 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
985 | if (!acpi_device_dir(device)) { | ||
986 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
987 | acpi_battery_dir); | ||
988 | if (!acpi_device_dir(device)) | ||
989 | return -ENODEV; | ||
990 | } | ||
991 | |||
992 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { | ||
993 | entry = proc_create_data(acpi_battery_file[i].name, | ||
994 | acpi_battery_file[i].mode, | ||
995 | acpi_device_dir(device), | ||
996 | &acpi_battery_file[i].ops, | ||
997 | acpi_driver_data(device)); | ||
998 | if (!entry) | ||
999 | return -ENODEV; | ||
1000 | } | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static void acpi_battery_remove_fs(struct acpi_device *device) | ||
1005 | { | ||
1006 | int i; | ||
1007 | if (!acpi_device_dir(device)) | ||
1008 | return; | ||
1009 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) | ||
1010 | remove_proc_entry(acpi_battery_file[i].name, | ||
1011 | acpi_device_dir(device)); | ||
1012 | |||
1013 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | ||
1014 | acpi_device_dir(device) = NULL; | ||
1015 | } | ||
1016 | |||
1017 | #endif | ||
1018 | |||
1019 | /* -------------------------------------------------------------------------- | ||
720 | Driver Interface | 1020 | Driver Interface |
721 | -------------------------------------------------------------------------- */ | 1021 | -------------------------------------------------------------------------- */ |
722 | 1022 | ||
@@ -790,6 +1090,15 @@ static int acpi_battery_add(struct acpi_device *device) | |||
790 | result = acpi_battery_update(battery); | 1090 | result = acpi_battery_update(battery); |
791 | if (result) | 1091 | if (result) |
792 | goto fail; | 1092 | goto fail; |
1093 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1094 | result = acpi_battery_add_fs(device); | ||
1095 | #endif | ||
1096 | if (result) { | ||
1097 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1098 | acpi_battery_remove_fs(device); | ||
1099 | #endif | ||
1100 | goto fail; | ||
1101 | } | ||
793 | 1102 | ||
794 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | 1103 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", |
795 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | 1104 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), |
@@ -816,6 +1125,9 @@ static int acpi_battery_remove(struct acpi_device *device) | |||
816 | return -EINVAL; | 1125 | return -EINVAL; |
817 | battery = acpi_driver_data(device); | 1126 | battery = acpi_driver_data(device); |
818 | unregister_pm_notifier(&battery->pm_nb); | 1127 | unregister_pm_notifier(&battery->pm_nb); |
1128 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1129 | acpi_battery_remove_fs(device); | ||
1130 | #endif | ||
819 | sysfs_remove_battery(battery); | 1131 | sysfs_remove_battery(battery); |
820 | mutex_destroy(&battery->lock); | 1132 | mutex_destroy(&battery->lock); |
821 | mutex_destroy(&battery->sysfs_lock); | 1133 | mutex_destroy(&battery->sysfs_lock); |
@@ -866,7 +1178,19 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) | |||
866 | 1178 | ||
867 | if (dmi_check_system(bat_dmi_table)) | 1179 | if (dmi_check_system(bat_dmi_table)) |
868 | battery_bix_broken_package = 1; | 1180 | battery_bix_broken_package = 1; |
869 | acpi_bus_register_driver(&acpi_battery_driver); | 1181 | |
1182 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1183 | acpi_battery_dir = acpi_lock_battery_dir(); | ||
1184 | if (!acpi_battery_dir) | ||
1185 | return; | ||
1186 | #endif | ||
1187 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | ||
1188 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1189 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1190 | #endif | ||
1191 | return; | ||
1192 | } | ||
1193 | return; | ||
870 | } | 1194 | } |
871 | 1195 | ||
872 | static int __init acpi_battery_init(void) | 1196 | static int __init acpi_battery_init(void) |
@@ -878,6 +1202,9 @@ static int __init acpi_battery_init(void) | |||
878 | static void __exit acpi_battery_exit(void) | 1202 | static void __exit acpi_battery_exit(void) |
879 | { | 1203 | { |
880 | acpi_bus_unregister_driver(&acpi_battery_driver); | 1204 | acpi_bus_unregister_driver(&acpi_battery_driver); |
1205 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1206 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1207 | #endif | ||
881 | } | 1208 | } |
882 | 1209 | ||
883 | module_init(acpi_battery_init); | 1210 | module_init(acpi_battery_init); |