aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 16:12:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 16:12:46 -0400
commitc4ec20717313daafba59225f812db89595952b83 (patch)
tree253337453b1dc965c40668e4949337ed1c46cab7 /drivers/acpi
parentec2626815bf9a9922e49820b03e670e833f3ca3c (diff)
parent00a2b433557f10736e8a02de619b3e9052556c12 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (41 commits) ACPICA: hw: Don't carry spinlock over suspend ACPICA: hw: remove use_lock flag from acpi_hw_register_{read, write} ACPI: cpuidle: port idle timer suspend/resume workaround to cpuidle ACPI: clean up acpi_enter_sleep_state_prep Hibernation: Make sure that ACPI is enabled in acpi_hibernation_finish ACPI: suppress uninitialized var warning cpuidle: consolidate 2.6.22 cpuidle branch into one patch ACPI: thinkpad-acpi: skip blanks before the data when parsing sysfs ACPI: AC: Add sysfs interface ACPI: SBS: Add sysfs alarm ACPI: SBS: Add ACPI_PROCFS around procfs handling code. ACPI: SBS: Add support for power_supply class (and sysfs) ACPI: SBS: Make SBS reads table-driven. ACPI: SBS: Simplify data structures in SBS ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) ACPI: EC: Add new query handler to list head. ACPI: Add acpi_bus_generate_event4() function ACPI: Battery: add sysfs alarm ACPI: Battery: Add sysfs support ACPI: Battery: Misc clean-ups, no functional changes ... Fix up conflicts in drivers/misc/thinkpad_acpi.[ch] manually
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig14
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c33
-rw-r--r--drivers/acpi/battery.c1038
-rw-r--r--drivers/acpi/bus.c23
-rw-r--r--drivers/acpi/ec.c93
-rw-r--r--drivers/acpi/events/evevent.c6
-rw-r--r--drivers/acpi/hardware/hwregs.c89
-rw-r--r--drivers/acpi/hardware/hwsleep.c40
-rw-r--r--drivers/acpi/osl.c8
-rw-r--r--drivers/acpi/processor_core.c22
-rw-r--r--drivers/acpi/processor_idle.c488
-rw-r--r--drivers/acpi/sbs.c1869
-rw-r--r--drivers/acpi/sbshc.c309
-rw-r--r--drivers/acpi/sbshc.h27
-rw-r--r--drivers/acpi/sleep/main.c6
-rw-r--r--drivers/acpi/sleep/sleep.h1
-rw-r--r--drivers/acpi/sleep/wakeup.c117
-rw-r--r--drivers/acpi/tables/tbutils.c2
-rw-r--r--drivers/acpi/thermal.c28
-rw-r--r--drivers/acpi/video.c30
21 files changed, 2008 insertions, 2236 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 4875f0149eb4..b83389145f28 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -88,7 +88,7 @@ config ACPI_PROC_EVENT
88 88
89config ACPI_AC 89config ACPI_AC
90 tristate "AC Adapter" 90 tristate "AC Adapter"
91 depends on X86 91 depends on X86 && POWER_SUPPLY
92 default y 92 default y
93 help 93 help
94 This driver adds support for the AC Adapter object, which indicates 94 This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +97,7 @@ config ACPI_AC
97 97
98config ACPI_BATTERY 98config ACPI_BATTERY
99 tristate "Battery" 99 tristate "Battery"
100 depends on X86 100 depends on X86 && POWER_SUPPLY
101 default y 101 default y
102 help 102 help
103 This driver adds support for battery information through 103 This driver adds support for battery information through
@@ -117,6 +117,7 @@ config ACPI_BUTTON
117config ACPI_VIDEO 117config ACPI_VIDEO
118 tristate "Video" 118 tristate "Video"
119 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL 119 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
120 depends on INPUT
120 help 121 help
121 This driver implement the ACPI Extensions For Display Adapters 122 This driver implement the ACPI Extensions For Display Adapters
122 for integrated graphics devices on motherboard, as specified in 123 for integrated graphics devices on motherboard, as specified in
@@ -349,12 +350,11 @@ config ACPI_HOTPLUG_MEMORY
349 $>modprobe acpi_memhotplug 350 $>modprobe acpi_memhotplug
350 351
351config ACPI_SBS 352config ACPI_SBS
352 tristate "Smart Battery System (EXPERIMENTAL)" 353 tristate "Smart Battery System"
353 depends on X86 354 depends on X86
354 depends on EXPERIMENTAL 355 depends on POWER_SUPPLY
355 help 356 help
356 This driver adds support for the Smart Battery System. 357 This driver adds support for the Smart Battery System, another
357 A "Smart Battery" is quite old and quite rare compared 358 type of access to battery information, found on some laptops.
358 to today's ACPI "Control Method" battery.
359 359
360endif # ACPI 360endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d4336f1730e9..54e3ab0e5fc0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
60obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o 60obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
61obj-y += cm_sbs.o 61obj-y += cm_sbs.o
62obj-$(CONFIG_ACPI_SBS) += sbs.o 62obj-$(CONFIG_ACPI_SBS) += sbs.o
63obj-$(CONFIG_ACPI_SBS) += sbshc.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 26d70702b313..e03de37a750d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -29,6 +29,7 @@
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/power_supply.h>
32#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
33#include <acpi/acpi_drivers.h> 34#include <acpi/acpi_drivers.h>
34 35
@@ -72,16 +73,37 @@ static struct acpi_driver acpi_ac_driver = {
72}; 73};
73 74
74struct acpi_ac { 75struct acpi_ac {
76 struct power_supply charger;
75 struct acpi_device * device; 77 struct acpi_device * device;
76 unsigned long state; 78 unsigned long state;
77}; 79};
78 80
81#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
82
79static const struct file_operations acpi_ac_fops = { 83static const struct file_operations acpi_ac_fops = {
80 .open = acpi_ac_open_fs, 84 .open = acpi_ac_open_fs,
81 .read = seq_read, 85 .read = seq_read,
82 .llseek = seq_lseek, 86 .llseek = seq_lseek,
83 .release = single_release, 87 .release = single_release,
84}; 88};
89static int get_ac_property(struct power_supply *psy,
90 enum power_supply_property psp,
91 union power_supply_propval *val)
92{
93 struct acpi_ac *ac = to_acpi_ac(psy);
94 switch (psp) {
95 case POWER_SUPPLY_PROP_ONLINE:
96 val->intval = ac->state;
97 break;
98 default:
99 return -EINVAL;
100 }
101 return 0;
102}
103
104static enum power_supply_property ac_props[] = {
105 POWER_SUPPLY_PROP_ONLINE,
106};
85 107
86/* -------------------------------------------------------------------------- 108/* --------------------------------------------------------------------------
87 AC Adapter Management 109 AC Adapter Management
@@ -208,6 +230,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
208 acpi_bus_generate_netlink_event(device->pnp.device_class, 230 acpi_bus_generate_netlink_event(device->pnp.device_class,
209 device->dev.bus_id, event, 231 device->dev.bus_id, event,
210 (u32) ac->state); 232 (u32) ac->state);
233 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
211 break; 234 break;
212 default: 235 default:
213 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 236 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -244,7 +267,12 @@ static int acpi_ac_add(struct acpi_device *device)
244 result = acpi_ac_add_fs(device); 267 result = acpi_ac_add_fs(device);
245 if (result) 268 if (result)
246 goto end; 269 goto end;
247 270 ac->charger.name = acpi_device_bid(device);
271 ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
272 ac->charger.properties = ac_props;
273 ac->charger.num_properties = ARRAY_SIZE(ac_props);
274 ac->charger.get_property = get_ac_property;
275 power_supply_register(&ac->device->dev, &ac->charger);
248 status = acpi_install_notify_handler(device->handle, 276 status = acpi_install_notify_handler(device->handle,
249 ACPI_ALL_NOTIFY, acpi_ac_notify, 277 ACPI_ALL_NOTIFY, acpi_ac_notify,
250 ac); 278 ac);
@@ -279,7 +307,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
279 307
280 status = acpi_remove_notify_handler(device->handle, 308 status = acpi_remove_notify_handler(device->handle,
281 ACPI_ALL_NOTIFY, acpi_ac_notify); 309 ACPI_ALL_NOTIFY, acpi_ac_notify);
282 310 if (ac->charger.dev)
311 power_supply_unregister(&ac->charger);
283 acpi_ac_remove_fs(device); 312 acpi_ac_remove_fs(device);
284 313
285 kfree(ac); 314 kfree(ac);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9b2c0f74f869..681e26b56b11 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) 2 * battery.c - ACPI Battery Driver (Revision: 2.0)
3 * 3 *
4 * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
5 * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 6 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 7 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 8 *
@@ -27,244 +29,288 @@
27#include <linux/module.h> 29#include <linux/module.h>
28#include <linux/init.h> 30#include <linux/init.h>
29#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/jiffies.h>
33
34#ifdef CONFIG_ACPI_PROCFS
30#include <linux/proc_fs.h> 35#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 36#include <linux/seq_file.h>
32#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#endif
33 39
34#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
35#include <acpi/acpi_drivers.h> 41#include <acpi/acpi_drivers.h>
36 42
37#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF 43#include <linux/power_supply.h>
38 44
39#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" 45#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
40#define ACPI_BATTERY_FORMAT_BST "NNNN"
41 46
42#define ACPI_BATTERY_COMPONENT 0x00040000 47#define ACPI_BATTERY_COMPONENT 0x00040000
43#define ACPI_BATTERY_CLASS "battery" 48#define ACPI_BATTERY_CLASS "battery"
44#define ACPI_BATTERY_DEVICE_NAME "Battery" 49#define ACPI_BATTERY_DEVICE_NAME "Battery"
45#define ACPI_BATTERY_NOTIFY_STATUS 0x80 50#define ACPI_BATTERY_NOTIFY_STATUS 0x80
46#define ACPI_BATTERY_NOTIFY_INFO 0x81 51#define ACPI_BATTERY_NOTIFY_INFO 0x81
47#define ACPI_BATTERY_UNITS_WATTS "mW"
48#define ACPI_BATTERY_UNITS_AMPS "mA"
49 52
50#define _COMPONENT ACPI_BATTERY_COMPONENT 53#define _COMPONENT ACPI_BATTERY_COMPONENT
51 54
52#define ACPI_BATTERY_UPDATE_TIME 0
53
54#define ACPI_BATTERY_NONE_UPDATE 0
55#define ACPI_BATTERY_EASY_UPDATE 1
56#define ACPI_BATTERY_INIT_UPDATE 2
57
58ACPI_MODULE_NAME("battery"); 55ACPI_MODULE_NAME("battery");
59 56
60MODULE_AUTHOR("Paul Diefenbaugh"); 57MODULE_AUTHOR("Paul Diefenbaugh");
58MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
61MODULE_DESCRIPTION("ACPI Battery Driver"); 59MODULE_DESCRIPTION("ACPI Battery Driver");
62MODULE_LICENSE("GPL"); 60MODULE_LICENSE("GPL");
63 61
64static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; 62static unsigned int cache_time = 1000;
65 63module_param(cache_time, uint, 0644);
66/* 0 - every time, > 0 - by update_time */ 64MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
67module_param(update_time, uint, 0644);
68 65
66#ifdef CONFIG_ACPI_PROCFS
69extern struct proc_dir_entry *acpi_lock_battery_dir(void); 67extern struct proc_dir_entry *acpi_lock_battery_dir(void);
70extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 68extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
71 69
72static int acpi_battery_add(struct acpi_device *device); 70enum acpi_battery_files {
73static int acpi_battery_remove(struct acpi_device *device, int type); 71 info_tag = 0,
74static int acpi_battery_resume(struct acpi_device *device); 72 state_tag,
73 alarm_tag,
74 ACPI_BATTERY_NUMFILES,
75};
76
77#endif
75 78
76static const struct acpi_device_id battery_device_ids[] = { 79static const struct acpi_device_id battery_device_ids[] = {
77 {"PNP0C0A", 0}, 80 {"PNP0C0A", 0},
78 {"", 0}, 81 {"", 0},
79}; 82};
80MODULE_DEVICE_TABLE(acpi, battery_device_ids);
81
82static struct acpi_driver acpi_battery_driver = {
83 .name = "battery",
84 .class = ACPI_BATTERY_CLASS,
85 .ids = battery_device_ids,
86 .ops = {
87 .add = acpi_battery_add,
88 .resume = acpi_battery_resume,
89 .remove = acpi_battery_remove,
90 },
91};
92 83
93struct acpi_battery_state { 84MODULE_DEVICE_TABLE(acpi, battery_device_ids);
94 acpi_integer state;
95 acpi_integer present_rate;
96 acpi_integer remaining_capacity;
97 acpi_integer present_voltage;
98};
99
100struct acpi_battery_info {
101 acpi_integer power_unit;
102 acpi_integer design_capacity;
103 acpi_integer last_full_capacity;
104 acpi_integer battery_technology;
105 acpi_integer design_voltage;
106 acpi_integer design_capacity_warning;
107 acpi_integer design_capacity_low;
108 acpi_integer battery_capacity_granularity_1;
109 acpi_integer battery_capacity_granularity_2;
110 acpi_string model_number;
111 acpi_string serial_number;
112 acpi_string battery_type;
113 acpi_string oem_info;
114};
115
116enum acpi_battery_files{
117 ACPI_BATTERY_INFO = 0,
118 ACPI_BATTERY_STATE,
119 ACPI_BATTERY_ALARM,
120 ACPI_BATTERY_NUMFILES,
121};
122 85
123struct acpi_battery_flags {
124 u8 battery_present_prev;
125 u8 alarm_present;
126 u8 init_update;
127 u8 update[ACPI_BATTERY_NUMFILES];
128 u8 power_unit;
129};
130 86
131struct acpi_battery { 87struct acpi_battery {
132 struct mutex mutex; 88 struct mutex lock;
89 struct power_supply bat;
133 struct acpi_device *device; 90 struct acpi_device *device;
134 struct acpi_battery_flags flags; 91 unsigned long update_time;
135 struct acpi_buffer bif_data; 92 int current_now;
136 struct acpi_buffer bst_data; 93 int capacity_now;
137 unsigned long alarm; 94 int voltage_now;
138 unsigned long update_time[ACPI_BATTERY_NUMFILES]; 95 int design_capacity;
96 int full_charge_capacity;
97 int technology;
98 int design_voltage;
99 int design_capacity_warning;
100 int design_capacity_low;
101 int capacity_granularity_1;
102 int capacity_granularity_2;
103 int alarm;
104 char model_number[32];
105 char serial_number[32];
106 char type[32];
107 char oem_info[32];
108 int state;
109 int power_unit;
110 u8 alarm_present;
139}; 111};
140 112
113#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
114
141inline int acpi_battery_present(struct acpi_battery *battery) 115inline int acpi_battery_present(struct acpi_battery *battery)
142{ 116{
143 return battery->device->status.battery_present; 117 return battery->device->status.battery_present;
144} 118}
145inline char *acpi_battery_power_units(struct acpi_battery *battery)
146{
147 if (battery->flags.power_unit)
148 return ACPI_BATTERY_UNITS_AMPS;
149 else
150 return ACPI_BATTERY_UNITS_WATTS;
151}
152 119
153inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) 120static int acpi_battery_technology(struct acpi_battery *battery)
154{ 121{
155 return battery->device->handle; 122 if (!strcasecmp("NiCd", battery->type))
123 return POWER_SUPPLY_TECHNOLOGY_NiCd;
124 if (!strcasecmp("NiMH", battery->type))
125 return POWER_SUPPLY_TECHNOLOGY_NiMH;
126 if (!strcasecmp("LION", battery->type))
127 return POWER_SUPPLY_TECHNOLOGY_LION;
128 if (!strcasecmp("LiP", battery->type))
129 return POWER_SUPPLY_TECHNOLOGY_LIPO;
130 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
156} 131}
157 132
158/* -------------------------------------------------------------------------- 133static int acpi_battery_get_property(struct power_supply *psy,
159 Battery Management 134 enum power_supply_property psp,
160 -------------------------------------------------------------------------- */ 135 union power_supply_propval *val)
161
162static void acpi_battery_check_result(struct acpi_battery *battery, int result)
163{ 136{
164 if (!battery) 137 struct acpi_battery *battery = to_acpi_battery(psy);
165 return;
166 138
167 if (result) { 139 if ((!acpi_battery_present(battery)) &&
168 battery->flags.init_update = 1; 140 psp != POWER_SUPPLY_PROP_PRESENT)
141 return -ENODEV;
142 switch (psp) {
143 case POWER_SUPPLY_PROP_STATUS:
144 if (battery->state & 0x01)
145 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
146 else if (battery->state & 0x02)
147 val->intval = POWER_SUPPLY_STATUS_CHARGING;
148 else if (battery->state == 0)
149 val->intval = POWER_SUPPLY_STATUS_FULL;
150 break;
151 case POWER_SUPPLY_PROP_PRESENT:
152 val->intval = acpi_battery_present(battery);
153 break;
154 case POWER_SUPPLY_PROP_TECHNOLOGY:
155 val->intval = acpi_battery_technology(battery);
156 break;
157 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
158 val->intval = battery->design_voltage * 1000;
159 break;
160 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
161 val->intval = battery->voltage_now * 1000;
162 break;
163 case POWER_SUPPLY_PROP_CURRENT_NOW:
164 val->intval = battery->current_now * 1000;
165 break;
166 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
167 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
168 val->intval = battery->design_capacity * 1000;
169 break;
170 case POWER_SUPPLY_PROP_CHARGE_FULL:
171 case POWER_SUPPLY_PROP_ENERGY_FULL:
172 val->intval = battery->full_charge_capacity * 1000;
173 break;
174 case POWER_SUPPLY_PROP_CHARGE_NOW:
175 case POWER_SUPPLY_PROP_ENERGY_NOW:
176 val->intval = battery->capacity_now * 1000;
177 break;
178 case POWER_SUPPLY_PROP_MODEL_NAME:
179 val->strval = battery->model_number;
180 break;
181 case POWER_SUPPLY_PROP_MANUFACTURER:
182 val->strval = battery->oem_info;
183 break;
184 default:
185 return -EINVAL;
169 } 186 }
187 return 0;
170} 188}
171 189
172static int acpi_battery_extract_package(struct acpi_battery *battery, 190static enum power_supply_property charge_battery_props[] = {
173 union acpi_object *package, 191 POWER_SUPPLY_PROP_STATUS,
174 struct acpi_buffer *format, 192 POWER_SUPPLY_PROP_PRESENT,
175 struct acpi_buffer *data, 193 POWER_SUPPLY_PROP_TECHNOLOGY,
176 char *package_name) 194 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
195 POWER_SUPPLY_PROP_VOLTAGE_NOW,
196 POWER_SUPPLY_PROP_CURRENT_NOW,
197 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
198 POWER_SUPPLY_PROP_CHARGE_FULL,
199 POWER_SUPPLY_PROP_CHARGE_NOW,
200 POWER_SUPPLY_PROP_MODEL_NAME,
201 POWER_SUPPLY_PROP_MANUFACTURER,
202};
203
204static enum power_supply_property energy_battery_props[] = {
205 POWER_SUPPLY_PROP_STATUS,
206 POWER_SUPPLY_PROP_PRESENT,
207 POWER_SUPPLY_PROP_TECHNOLOGY,
208 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
209 POWER_SUPPLY_PROP_VOLTAGE_NOW,
210 POWER_SUPPLY_PROP_CURRENT_NOW,
211 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
212 POWER_SUPPLY_PROP_ENERGY_FULL,
213 POWER_SUPPLY_PROP_ENERGY_NOW,
214 POWER_SUPPLY_PROP_MODEL_NAME,
215 POWER_SUPPLY_PROP_MANUFACTURER,
216};
217
218#ifdef CONFIG_ACPI_PROCFS
219inline char *acpi_battery_units(struct acpi_battery *battery)
177{ 220{
178 acpi_status status = AE_OK; 221 return (battery->power_unit)?"mA":"mW";
179 struct acpi_buffer data_null = { 0, NULL }; 222}
223#endif
180 224
181 status = acpi_extract_package(package, format, &data_null); 225/* --------------------------------------------------------------------------
182 if (status != AE_BUFFER_OVERFLOW) { 226 Battery Management
183 ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", 227 -------------------------------------------------------------------------- */
184 package_name)); 228struct acpi_offsets {
185 return -ENODEV; 229 size_t offset; /* offset inside struct acpi_sbs_battery */
186 } 230 u8 mode; /* int or string? */
231};
187 232
188 if (data_null.length != data->length) { 233static struct acpi_offsets state_offsets[] = {
189 kfree(data->pointer); 234 {offsetof(struct acpi_battery, state), 0},
190 data->pointer = kzalloc(data_null.length, GFP_KERNEL); 235 {offsetof(struct acpi_battery, current_now), 0},
191 if (!data->pointer) { 236 {offsetof(struct acpi_battery, capacity_now), 0},
192 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); 237 {offsetof(struct acpi_battery, voltage_now), 0},
193 return -ENOMEM; 238};
194 }
195 data->length = data_null.length;
196 }
197 239
198 status = acpi_extract_package(package, format, data); 240static struct acpi_offsets info_offsets[] = {
199 if (ACPI_FAILURE(status)) { 241 {offsetof(struct acpi_battery, power_unit), 0},
200 ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", 242 {offsetof(struct acpi_battery, design_capacity), 0},
201 package_name)); 243 {offsetof(struct acpi_battery, full_charge_capacity), 0},
202 return -ENODEV; 244 {offsetof(struct acpi_battery, technology), 0},
203 } 245 {offsetof(struct acpi_battery, design_voltage), 0},
246 {offsetof(struct acpi_battery, design_capacity_warning), 0},
247 {offsetof(struct acpi_battery, design_capacity_low), 0},
248 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
249 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
250 {offsetof(struct acpi_battery, model_number), 1},
251 {offsetof(struct acpi_battery, serial_number), 1},
252 {offsetof(struct acpi_battery, type), 1},
253 {offsetof(struct acpi_battery, oem_info), 1},
254};
204 255
256static int extract_package(struct acpi_battery *battery,
257 union acpi_object *package,
258 struct acpi_offsets *offsets, int num)
259{
260 int i, *x;
261 union acpi_object *element;
262 if (package->type != ACPI_TYPE_PACKAGE)
263 return -EFAULT;
264 for (i = 0; i < num; ++i) {
265 if (package->package.count <= i)
266 return -EFAULT;
267 element = &package->package.elements[i];
268 if (offsets[i].mode) {
269 if (element->type != ACPI_TYPE_STRING &&
270 element->type != ACPI_TYPE_BUFFER)
271 return -EFAULT;
272 strncpy((u8 *)battery + offsets[i].offset,
273 element->string.pointer, 32);
274 } else {
275 if (element->type != ACPI_TYPE_INTEGER)
276 return -EFAULT;
277 x = (int *)((u8 *)battery + offsets[i].offset);
278 *x = element->integer.value;
279 }
280 }
205 return 0; 281 return 0;
206} 282}
207 283
208static int acpi_battery_get_status(struct acpi_battery *battery) 284static int acpi_battery_get_status(struct acpi_battery *battery)
209{ 285{
210 int result = 0; 286 if (acpi_bus_get_status(battery->device)) {
211
212 result = acpi_bus_get_status(battery->device);
213 if (result) {
214 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); 287 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
215 return -ENODEV; 288 return -ENODEV;
216 } 289 }
217 return result; 290 return 0;
218} 291}
219 292
220static int acpi_battery_get_info(struct acpi_battery *battery) 293static int acpi_battery_get_info(struct acpi_battery *battery)
221{ 294{
222 int result = 0; 295 int result = -EFAULT;
223 acpi_status status = 0; 296 acpi_status status = 0;
224 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 297 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
225 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
226 ACPI_BATTERY_FORMAT_BIF
227 };
228 union acpi_object *package = NULL;
229 struct acpi_buffer *data = NULL;
230 struct acpi_battery_info *bif = NULL;
231
232 battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
233 298
234 if (!acpi_battery_present(battery)) 299 if (!acpi_battery_present(battery))
235 return 0; 300 return 0;
301 mutex_lock(&battery->lock);
302 status = acpi_evaluate_object(battery->device->handle, "_BIF",
303 NULL, &buffer);
304 mutex_unlock(&battery->lock);
236 305
237 /* Evaluate _BIF */
238
239 status =
240 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
241 &buffer);
242 if (ACPI_FAILURE(status)) { 306 if (ACPI_FAILURE(status)) {
243 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 307 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
244 return -ENODEV; 308 return -ENODEV;
245 } 309 }
246 310
247 package = buffer.pointer; 311 result = extract_package(battery, buffer.pointer,
248 312 info_offsets, ARRAY_SIZE(info_offsets));
249 data = &battery->bif_data;
250
251 /* Extract Package Data */
252
253 result =
254 acpi_battery_extract_package(battery, package, &format, data,
255 "_BIF");
256 if (result)
257 goto end;
258
259 end:
260
261 kfree(buffer.pointer); 313 kfree(buffer.pointer);
262
263 if (!result) {
264 bif = data->pointer;
265 battery->flags.power_unit = bif->power_unit;
266 }
267
268 return result; 314 return result;
269} 315}
270 316
@@ -273,342 +319,203 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
273 int result = 0; 319 int result = 0;
274 acpi_status status = 0; 320 acpi_status status = 0;
275 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 321 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
276 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
277 ACPI_BATTERY_FORMAT_BST
278 };
279 union acpi_object *package = NULL;
280 struct acpi_buffer *data = NULL;
281
282 battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
283 322
284 if (!acpi_battery_present(battery)) 323 if (!acpi_battery_present(battery))
285 return 0; 324 return 0;
286 325
287 /* Evaluate _BST */ 326 if (battery->update_time &&
327 time_before(jiffies, battery->update_time +
328 msecs_to_jiffies(cache_time)))
329 return 0;
330
331 mutex_lock(&battery->lock);
332 status = acpi_evaluate_object(battery->device->handle, "_BST",
333 NULL, &buffer);
334 mutex_unlock(&battery->lock);
288 335
289 status =
290 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
291 &buffer);
292 if (ACPI_FAILURE(status)) { 336 if (ACPI_FAILURE(status)) {
293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 337 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
294 return -ENODEV; 338 return -ENODEV;
295 } 339 }
296 340
297 package = buffer.pointer; 341 result = extract_package(battery, buffer.pointer,
298 342 state_offsets, ARRAY_SIZE(state_offsets));
299 data = &battery->bst_data; 343 battery->update_time = jiffies;
300
301 /* Extract Package Data */
302
303 result =
304 acpi_battery_extract_package(battery, package, &format, data,
305 "_BST");
306 if (result)
307 goto end;
308
309 end:
310 kfree(buffer.pointer); 344 kfree(buffer.pointer);
311
312 return result; 345 return result;
313} 346}
314 347
315static int acpi_battery_get_alarm(struct acpi_battery *battery) 348static int acpi_battery_set_alarm(struct acpi_battery *battery)
316{
317 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
318
319 return 0;
320}
321
322static int acpi_battery_set_alarm(struct acpi_battery *battery,
323 unsigned long alarm)
324{ 349{
325 acpi_status status = 0; 350 acpi_status status = 0;
326 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 351 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
327 struct acpi_object_list arg_list = { 1, &arg0 }; 352 struct acpi_object_list arg_list = { 1, &arg0 };
328 353
329 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); 354 if (!acpi_battery_present(battery)|| !battery->alarm_present)
330
331 if (!acpi_battery_present(battery))
332 return -ENODEV; 355 return -ENODEV;
333 356
334 if (!battery->flags.alarm_present) 357 arg0.integer.value = battery->alarm;
335 return -ENODEV;
336
337 arg0.integer.value = alarm;
338 358
339 status = 359 mutex_lock(&battery->lock);
340 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", 360 status = acpi_evaluate_object(battery->device->handle, "_BTP",
341 &arg_list, NULL); 361 &arg_list, NULL);
362 mutex_unlock(&battery->lock);
363
342 if (ACPI_FAILURE(status)) 364 if (ACPI_FAILURE(status))
343 return -ENODEV; 365 return -ENODEV;
344 366
345 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); 367 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
346
347 battery->alarm = alarm;
348
349 return 0; 368 return 0;
350} 369}
351 370
352static int acpi_battery_init_alarm(struct acpi_battery *battery) 371static int acpi_battery_init_alarm(struct acpi_battery *battery)
353{ 372{
354 int result = 0;
355 acpi_status status = AE_OK; 373 acpi_status status = AE_OK;
356 acpi_handle handle = NULL; 374 acpi_handle handle = NULL;
357 struct acpi_battery_info *bif = battery->bif_data.pointer;
358 unsigned long alarm = battery->alarm;
359 375
360 /* See if alarms are supported, and if so, set default */ 376 /* See if alarms are supported, and if so, set default */
361 377 status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
362 status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); 378 if (ACPI_FAILURE(status)) {
363 if (ACPI_SUCCESS(status)) { 379 battery->alarm_present = 0;
364 battery->flags.alarm_present = 1; 380 return 0;
365 if (!alarm && bif) {
366 alarm = bif->design_capacity_warning;
367 }
368 result = acpi_battery_set_alarm(battery, alarm);
369 if (result)
370 goto end;
371 } else {
372 battery->flags.alarm_present = 0;
373 } 381 }
374 382 battery->alarm_present = 1;
375 end: 383 if (!battery->alarm)
376 384 battery->alarm = battery->design_capacity_warning;
377 return result; 385 return acpi_battery_set_alarm(battery);
378} 386}
379 387
380static int acpi_battery_init_update(struct acpi_battery *battery) 388static int acpi_battery_update(struct acpi_battery *battery)
381{ 389{
382 int result = 0; 390 int saved_present = acpi_battery_present(battery);
383 391 int result = acpi_battery_get_status(battery);
384 result = acpi_battery_get_status(battery); 392 if (result || !acpi_battery_present(battery))
385 if (result)
386 return result; 393 return result;
387 394 if (saved_present != acpi_battery_present(battery) ||
388 battery->flags.battery_present_prev = acpi_battery_present(battery); 395 !battery->update_time) {
389 396 battery->update_time = 0;
390 if (acpi_battery_present(battery)) {
391 result = acpi_battery_get_info(battery); 397 result = acpi_battery_get_info(battery);
392 if (result) 398 if (result)
393 return result; 399 return result;
394 result = acpi_battery_get_state(battery); 400 if (battery->power_unit) {
395 if (result) 401 battery->bat.properties = charge_battery_props;
396 return result; 402 battery->bat.num_properties =
397 403 ARRAY_SIZE(charge_battery_props);
398 acpi_battery_init_alarm(battery);
399 }
400
401 return result;
402}
403
404static int acpi_battery_update(struct acpi_battery *battery,
405 int update, int *update_result_ptr)
406{
407 int result = 0;
408 int update_result = ACPI_BATTERY_NONE_UPDATE;
409
410 if (!acpi_battery_present(battery)) {
411 update = 1;
412 }
413
414 if (battery->flags.init_update) {
415 result = acpi_battery_init_update(battery);
416 if (result)
417 goto end;
418 update_result = ACPI_BATTERY_INIT_UPDATE;
419 } else if (update) {
420 result = acpi_battery_get_status(battery);
421 if (result)
422 goto end;
423 if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
424 || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
425 result = acpi_battery_init_update(battery);
426 if (result)
427 goto end;
428 update_result = ACPI_BATTERY_INIT_UPDATE;
429 } else { 404 } else {
430 update_result = ACPI_BATTERY_EASY_UPDATE; 405 battery->bat.properties = energy_battery_props;
406 battery->bat.num_properties =
407 ARRAY_SIZE(energy_battery_props);
431 } 408 }
409 acpi_battery_init_alarm(battery);
432 } 410 }
433 411 return acpi_battery_get_state(battery);
434 end:
435
436 battery->flags.init_update = (result != 0);
437
438 *update_result_ptr = update_result;
439
440 return result;
441}
442
443static void acpi_battery_notify_update(struct acpi_battery *battery)
444{
445 acpi_battery_get_status(battery);
446
447 if (battery->flags.init_update) {
448 return;
449 }
450
451 if ((!battery->flags.battery_present_prev &
452 acpi_battery_present(battery)) ||
453 (battery->flags.battery_present_prev &
454 !acpi_battery_present(battery))) {
455 battery->flags.init_update = 1;
456 } else {
457 battery->flags.update[ACPI_BATTERY_INFO] = 1;
458 battery->flags.update[ACPI_BATTERY_STATE] = 1;
459 battery->flags.update[ACPI_BATTERY_ALARM] = 1;
460 }
461} 412}
462 413
463/* -------------------------------------------------------------------------- 414/* --------------------------------------------------------------------------
464 FS Interface (/proc) 415 FS Interface (/proc)
465 -------------------------------------------------------------------------- */ 416 -------------------------------------------------------------------------- */
466 417
418#ifdef CONFIG_ACPI_PROCFS
467static struct proc_dir_entry *acpi_battery_dir; 419static struct proc_dir_entry *acpi_battery_dir;
468 420
469static int acpi_battery_print_info(struct seq_file *seq, int result) 421static int acpi_battery_print_info(struct seq_file *seq, int result)
470{ 422{
471 struct acpi_battery *battery = seq->private; 423 struct acpi_battery *battery = seq->private;
472 struct acpi_battery_info *bif = NULL;
473 char *units = "?";
474 424
475 if (result) 425 if (result)
476 goto end; 426 goto end;
477 427
478 if (acpi_battery_present(battery)) 428 seq_printf(seq, "present: %s\n",
479 seq_printf(seq, "present: yes\n"); 429 acpi_battery_present(battery)?"yes":"no");
480 else { 430 if (!acpi_battery_present(battery))
481 seq_printf(seq, "present: no\n");
482 goto end;
483 }
484
485 bif = battery->bif_data.pointer;
486 if (!bif) {
487 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
488 result = -ENODEV;
489 goto end; 431 goto end;
490 } 432 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
491
492 /* Battery Units */
493
494 units = acpi_battery_power_units(battery);
495
496 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
497 seq_printf(seq, "design capacity: unknown\n"); 433 seq_printf(seq, "design capacity: unknown\n");
498 else 434 else
499 seq_printf(seq, "design capacity: %d %sh\n", 435 seq_printf(seq, "design capacity: %d %sh\n",
500 (u32) bif->design_capacity, units); 436 battery->design_capacity,
437 acpi_battery_units(battery));
501 438
502 if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 439 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
503 seq_printf(seq, "last full capacity: unknown\n"); 440 seq_printf(seq, "last full capacity: unknown\n");
504 else 441 else
505 seq_printf(seq, "last full capacity: %d %sh\n", 442 seq_printf(seq, "last full capacity: %d %sh\n",
506 (u32) bif->last_full_capacity, units); 443 battery->full_charge_capacity,
444 acpi_battery_units(battery));
507 445
508 switch ((u32) bif->battery_technology) { 446 seq_printf(seq, "battery technology: %srechargeable\n",
509 case 0: 447 (!battery->technology)?"non-":"");
510 seq_printf(seq, "battery technology: non-rechargeable\n");
511 break;
512 case 1:
513 seq_printf(seq, "battery technology: rechargeable\n");
514 break;
515 default:
516 seq_printf(seq, "battery technology: unknown\n");
517 break;
518 }
519 448
520 if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 449 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
521 seq_printf(seq, "design voltage: unknown\n"); 450 seq_printf(seq, "design voltage: unknown\n");
522 else 451 else
523 seq_printf(seq, "design voltage: %d mV\n", 452 seq_printf(seq, "design voltage: %d mV\n",
524 (u32) bif->design_voltage); 453 battery->design_voltage);
525 seq_printf(seq, "design capacity warning: %d %sh\n", 454 seq_printf(seq, "design capacity warning: %d %sh\n",
526 (u32) bif->design_capacity_warning, units); 455 battery->design_capacity_warning,
456 acpi_battery_units(battery));
527 seq_printf(seq, "design capacity low: %d %sh\n", 457 seq_printf(seq, "design capacity low: %d %sh\n",
528 (u32) bif->design_capacity_low, units); 458 battery->design_capacity_low,
459 acpi_battery_units(battery));
529 seq_printf(seq, "capacity granularity 1: %d %sh\n", 460 seq_printf(seq, "capacity granularity 1: %d %sh\n",
530 (u32) bif->battery_capacity_granularity_1, units); 461 battery->capacity_granularity_1,
462 acpi_battery_units(battery));
531 seq_printf(seq, "capacity granularity 2: %d %sh\n", 463 seq_printf(seq, "capacity granularity 2: %d %sh\n",
532 (u32) bif->battery_capacity_granularity_2, units); 464 battery->capacity_granularity_2,
533 seq_printf(seq, "model number: %s\n", bif->model_number); 465 acpi_battery_units(battery));
534 seq_printf(seq, "serial number: %s\n", bif->serial_number); 466 seq_printf(seq, "model number: %s\n", battery->model_number);
535 seq_printf(seq, "battery type: %s\n", bif->battery_type); 467 seq_printf(seq, "serial number: %s\n", battery->serial_number);
536 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 468 seq_printf(seq, "battery type: %s\n", battery->type);
537 469 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
538 end: 470 end:
539
540 if (result) 471 if (result)
541 seq_printf(seq, "ERROR: Unable to read battery info\n"); 472 seq_printf(seq, "ERROR: Unable to read battery info\n");
542
543 return result; 473 return result;
544} 474}
545 475
546static int acpi_battery_print_state(struct seq_file *seq, int result) 476static int acpi_battery_print_state(struct seq_file *seq, int result)
547{ 477{
548 struct acpi_battery *battery = seq->private; 478 struct acpi_battery *battery = seq->private;
549 struct acpi_battery_state *bst = NULL;
550 char *units = "?";
551 479
552 if (result) 480 if (result)
553 goto end; 481 goto end;
554 482
555 if (acpi_battery_present(battery)) 483 seq_printf(seq, "present: %s\n",
556 seq_printf(seq, "present: yes\n"); 484 acpi_battery_present(battery)?"yes":"no");
557 else { 485 if (!acpi_battery_present(battery))
558 seq_printf(seq, "present: no\n");
559 goto end;
560 }
561
562 bst = battery->bst_data.pointer;
563 if (!bst) {
564 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
565 result = -ENODEV;
566 goto end; 486 goto end;
567 }
568
569 /* Battery Units */
570
571 units = acpi_battery_power_units(battery);
572
573 if (!(bst->state & 0x04))
574 seq_printf(seq, "capacity state: ok\n");
575 else
576 seq_printf(seq, "capacity state: critical\n");
577 487
578 if ((bst->state & 0x01) && (bst->state & 0x02)) { 488 seq_printf(seq, "capacity state: %s\n",
489 (battery->state & 0x04)?"critical":"ok");
490 if ((battery->state & 0x01) && (battery->state & 0x02))
579 seq_printf(seq, 491 seq_printf(seq,
580 "charging state: charging/discharging\n"); 492 "charging state: charging/discharging\n");
581 } else if (bst->state & 0x01) 493 else if (battery->state & 0x01)
582 seq_printf(seq, "charging state: discharging\n"); 494 seq_printf(seq, "charging state: discharging\n");
583 else if (bst->state & 0x02) 495 else if (battery->state & 0x02)
584 seq_printf(seq, "charging state: charging\n"); 496 seq_printf(seq, "charging state: charging\n");
585 else { 497 else
586 seq_printf(seq, "charging state: charged\n"); 498 seq_printf(seq, "charging state: charged\n");
587 }
588 499
589 if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) 500 if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
590 seq_printf(seq, "present rate: unknown\n"); 501 seq_printf(seq, "present rate: unknown\n");
591 else 502 else
592 seq_printf(seq, "present rate: %d %s\n", 503 seq_printf(seq, "present rate: %d %s\n",
593 (u32) bst->present_rate, units); 504 battery->current_now, acpi_battery_units(battery));
594 505
595 if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 506 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
596 seq_printf(seq, "remaining capacity: unknown\n"); 507 seq_printf(seq, "remaining capacity: unknown\n");
597 else 508 else
598 seq_printf(seq, "remaining capacity: %d %sh\n", 509 seq_printf(seq, "remaining capacity: %d %sh\n",
599 (u32) bst->remaining_capacity, units); 510 battery->capacity_now, acpi_battery_units(battery));
600 511 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
601 if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
602 seq_printf(seq, "present voltage: unknown\n"); 512 seq_printf(seq, "present voltage: unknown\n");
603 else 513 else
604 seq_printf(seq, "present voltage: %d mV\n", 514 seq_printf(seq, "present voltage: %d mV\n",
605 (u32) bst->present_voltage); 515 battery->voltage_now);
606
607 end: 516 end:
608 517 if (result)
609 if (result) {
610 seq_printf(seq, "ERROR: Unable to read battery state\n"); 518 seq_printf(seq, "ERROR: Unable to read battery state\n");
611 }
612 519
613 return result; 520 return result;
614} 521}
@@ -616,7 +523,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
616static int acpi_battery_print_alarm(struct seq_file *seq, int result) 523static int acpi_battery_print_alarm(struct seq_file *seq, int result)
617{ 524{
618 struct acpi_battery *battery = seq->private; 525 struct acpi_battery *battery = seq->private;
619 char *units = "?";
620 526
621 if (result) 527 if (result)
622 goto end; 528 goto end;
@@ -625,189 +531,121 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
625 seq_printf(seq, "present: no\n"); 531 seq_printf(seq, "present: no\n");
626 goto end; 532 goto end;
627 } 533 }
628
629 /* Battery Units */
630
631 units = acpi_battery_power_units(battery);
632
633 seq_printf(seq, "alarm: "); 534 seq_printf(seq, "alarm: ");
634 if (!battery->alarm) 535 if (!battery->alarm)
635 seq_printf(seq, "unsupported\n"); 536 seq_printf(seq, "unsupported\n");
636 else 537 else
637 seq_printf(seq, "%lu %sh\n", battery->alarm, units); 538 seq_printf(seq, "%u %sh\n", battery->alarm,
638 539 acpi_battery_units(battery));
639 end: 540 end:
640
641 if (result) 541 if (result)
642 seq_printf(seq, "ERROR: Unable to read battery alarm\n"); 542 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
643
644 return result; 543 return result;
645} 544}
646 545
647static ssize_t 546static ssize_t acpi_battery_write_alarm(struct file *file,
648acpi_battery_write_alarm(struct file *file, 547 const char __user * buffer,
649 const char __user * buffer, 548 size_t count, loff_t * ppos)
650 size_t count, loff_t * ppos)
651{ 549{
652 int result = 0; 550 int result = 0;
653 char alarm_string[12] = { '\0' }; 551 char alarm_string[12] = { '\0' };
654 struct seq_file *m = file->private_data; 552 struct seq_file *m = file->private_data;
655 struct acpi_battery *battery = m->private; 553 struct acpi_battery *battery = m->private;
656 int update_result = ACPI_BATTERY_NONE_UPDATE;
657 554
658 if (!battery || (count > sizeof(alarm_string) - 1)) 555 if (!battery || (count > sizeof(alarm_string) - 1))
659 return -EINVAL; 556 return -EINVAL;
660
661 mutex_lock(&battery->mutex);
662
663 result = acpi_battery_update(battery, 1, &update_result);
664 if (result) { 557 if (result) {
665 result = -ENODEV; 558 result = -ENODEV;
666 goto end; 559 goto end;
667 } 560 }
668
669 if (!acpi_battery_present(battery)) { 561 if (!acpi_battery_present(battery)) {
670 result = -ENODEV; 562 result = -ENODEV;
671 goto end; 563 goto end;
672 } 564 }
673
674 if (copy_from_user(alarm_string, buffer, count)) { 565 if (copy_from_user(alarm_string, buffer, count)) {
675 result = -EFAULT; 566 result = -EFAULT;
676 goto end; 567 goto end;
677 } 568 }
678
679 alarm_string[count] = '\0'; 569 alarm_string[count] = '\0';
680 570 battery->alarm = simple_strtol(alarm_string, NULL, 0);
681 result = acpi_battery_set_alarm(battery, 571 result = acpi_battery_set_alarm(battery);
682 simple_strtoul(alarm_string, NULL, 0));
683 if (result)
684 goto end;
685
686 end: 572 end:
687
688 acpi_battery_check_result(battery, result);
689
690 if (!result) 573 if (!result)
691 result = count; 574 return count;
692
693 mutex_unlock(&battery->mutex);
694
695 return result; 575 return result;
696} 576}
697 577
698typedef int(*print_func)(struct seq_file *seq, int result); 578typedef int(*print_func)(struct seq_file *seq, int result);
699typedef int(*get_func)(struct acpi_battery *battery); 579
700 580static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
701static struct acpi_read_mux { 581 acpi_battery_print_info,
702 print_func print; 582 acpi_battery_print_state,
703 get_func get; 583 acpi_battery_print_alarm,
704} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
705 {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
706 {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
707 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
708}; 584};
709 585
710static int acpi_battery_read(int fid, struct seq_file *seq) 586static int acpi_battery_read(int fid, struct seq_file *seq)
711{ 587{
712 struct acpi_battery *battery = seq->private; 588 struct acpi_battery *battery = seq->private;
713 int result = 0; 589 int result = acpi_battery_update(battery);
714 int update_result = ACPI_BATTERY_NONE_UPDATE; 590 return acpi_print_funcs[fid](seq, result);
715 int update = 0; 591}
716 592
717 mutex_lock(&battery->mutex); 593#define DECLARE_FILE_FUNCTIONS(_name) \
718 594static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
719 update = (get_seconds() - battery->update_time[fid] >= update_time); 595{ \
720 update = (update | battery->flags.update[fid]); 596 return acpi_battery_read(_name##_tag, seq); \
721 597} \
722 result = acpi_battery_update(battery, update, &update_result); 598static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
723 if (result) 599{ \
724 goto end; 600 return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
725 601}
726 if (update_result == ACPI_BATTERY_EASY_UPDATE) { 602
727 result = acpi_read_funcs[fid].get(battery); 603DECLARE_FILE_FUNCTIONS(info);
728 if (result) 604DECLARE_FILE_FUNCTIONS(state);
729 goto end; 605DECLARE_FILE_FUNCTIONS(alarm);
606
607#undef DECLARE_FILE_FUNCTIONS
608
609#define FILE_DESCRIPTION_RO(_name) \
610 { \
611 .name = __stringify(_name), \
612 .mode = S_IRUGO, \
613 .ops = { \
614 .open = acpi_battery_##_name##_open_fs, \
615 .read = seq_read, \
616 .llseek = seq_lseek, \
617 .release = single_release, \
618 .owner = THIS_MODULE, \
619 }, \
620 }
621
622#define FILE_DESCRIPTION_RW(_name) \
623 { \
624 .name = __stringify(_name), \
625 .mode = S_IFREG | S_IRUGO | S_IWUSR, \
626 .ops = { \
627 .open = acpi_battery_##_name##_open_fs, \
628 .read = seq_read, \
629 .llseek = seq_lseek, \
630 .write = acpi_battery_write_##_name, \
631 .release = single_release, \
632 .owner = THIS_MODULE, \
633 }, \
730 } 634 }
731 635
732 end:
733 result = acpi_read_funcs[fid].print(seq, result);
734 acpi_battery_check_result(battery, result);
735 battery->flags.update[fid] = result;
736 mutex_unlock(&battery->mutex);
737 return result;
738}
739
740static int acpi_battery_read_info(struct seq_file *seq, void *offset)
741{
742 return acpi_battery_read(ACPI_BATTERY_INFO, seq);
743}
744
745static int acpi_battery_read_state(struct seq_file *seq, void *offset)
746{
747 return acpi_battery_read(ACPI_BATTERY_STATE, seq);
748}
749
750static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
751{
752 return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
753}
754
755static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
756{
757 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
758}
759
760static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
761{
762 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
763}
764
765static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
766{
767 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
768}
769
770static struct battery_file { 636static struct battery_file {
771 struct file_operations ops; 637 struct file_operations ops;
772 mode_t mode; 638 mode_t mode;
773 char *name; 639 char *name;
774} acpi_battery_file[] = { 640} acpi_battery_file[] = {
775 { 641 FILE_DESCRIPTION_RO(info),
776 .name = "info", 642 FILE_DESCRIPTION_RO(state),
777 .mode = S_IRUGO, 643 FILE_DESCRIPTION_RW(alarm),
778 .ops = {
779 .open = acpi_battery_info_open_fs,
780 .read = seq_read,
781 .llseek = seq_lseek,
782 .release = single_release,
783 .owner = THIS_MODULE,
784 },
785 },
786 {
787 .name = "state",
788 .mode = S_IRUGO,
789 .ops = {
790 .open = acpi_battery_state_open_fs,
791 .read = seq_read,
792 .llseek = seq_lseek,
793 .release = single_release,
794 .owner = THIS_MODULE,
795 },
796 },
797 {
798 .name = "alarm",
799 .mode = S_IFREG | S_IRUGO | S_IWUSR,
800 .ops = {
801 .open = acpi_battery_alarm_open_fs,
802 .read = seq_read,
803 .write = acpi_battery_write_alarm,
804 .llseek = seq_lseek,
805 .release = single_release,
806 .owner = THIS_MODULE,
807 },
808 },
809}; 644};
810 645
646#undef FILE_DESCRIPTION_RO
647#undef FILE_DESCRIPTION_RW
648
811static int acpi_battery_add_fs(struct acpi_device *device) 649static int acpi_battery_add_fs(struct acpi_device *device)
812{ 650{
813 struct proc_dir_entry *entry = NULL; 651 struct proc_dir_entry *entry = NULL;
@@ -832,25 +670,51 @@ static int acpi_battery_add_fs(struct acpi_device *device)
832 entry->owner = THIS_MODULE; 670 entry->owner = THIS_MODULE;
833 } 671 }
834 } 672 }
835
836 return 0; 673 return 0;
837} 674}
838 675
839static int acpi_battery_remove_fs(struct acpi_device *device) 676static void acpi_battery_remove_fs(struct acpi_device *device)
840{ 677{
841 int i; 678 int i;
842 if (acpi_device_dir(device)) { 679 if (!acpi_device_dir(device))
843 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { 680 return;
844 remove_proc_entry(acpi_battery_file[i].name, 681 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
682 remove_proc_entry(acpi_battery_file[i].name,
845 acpi_device_dir(device)); 683 acpi_device_dir(device));
846 }
847 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
848 acpi_device_dir(device) = NULL;
849 }
850 684
851 return 0; 685 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
686 acpi_device_dir(device) = NULL;
687}
688
689#endif
690
691static ssize_t acpi_battery_alarm_show(struct device *dev,
692 struct device_attribute *attr,
693 char *buf)
694{
695 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
696 return sprintf(buf, "%d\n", battery->alarm * 1000);
697}
698
699static ssize_t acpi_battery_alarm_store(struct device *dev,
700 struct device_attribute *attr,
701 const char *buf, size_t count)
702{
703 unsigned long x;
704 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
705 if (sscanf(buf, "%ld\n", &x) == 1)
706 battery->alarm = x/1000;
707 if (acpi_battery_present(battery))
708 acpi_battery_set_alarm(battery);
709 return count;
852} 710}
853 711
712static struct device_attribute alarm_attr = {
713 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
714 .show = acpi_battery_alarm_show,
715 .store = acpi_battery_alarm_store,
716};
717
854/* -------------------------------------------------------------------------- 718/* --------------------------------------------------------------------------
855 Driver Interface 719 Driver Interface
856 -------------------------------------------------------------------------- */ 720 -------------------------------------------------------------------------- */
@@ -858,33 +722,17 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
858static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 722static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
859{ 723{
860 struct acpi_battery *battery = data; 724 struct acpi_battery *battery = data;
861 struct acpi_device *device = NULL; 725 struct acpi_device *device;
862
863 if (!battery) 726 if (!battery)
864 return; 727 return;
865
866 device = battery->device; 728 device = battery->device;
867 729 acpi_battery_update(battery);
868 switch (event) { 730 acpi_bus_generate_proc_event(device, event,
869 case ACPI_BATTERY_NOTIFY_STATUS: 731 acpi_battery_present(battery));
870 case ACPI_BATTERY_NOTIFY_INFO: 732 acpi_bus_generate_netlink_event(device->pnp.device_class,
871 case ACPI_NOTIFY_BUS_CHECK: 733 device->dev.bus_id, event,
872 case ACPI_NOTIFY_DEVICE_CHECK:
873 device = battery->device;
874 acpi_battery_notify_update(battery);
875 acpi_bus_generate_proc_event(device, event,
876 acpi_battery_present(battery)); 734 acpi_battery_present(battery));
877 acpi_bus_generate_netlink_event(device->pnp.device_class, 735 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
878 device->dev.bus_id, event,
879 acpi_battery_present(battery));
880 break;
881 default:
882 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
883 "Unsupported event [0x%x]\n", event));
884 break;
885 }
886
887 return;
888} 736}
889 737
890static int acpi_battery_add(struct acpi_device *device) 738static int acpi_battery_add(struct acpi_device *device)
@@ -892,33 +740,27 @@ static int acpi_battery_add(struct acpi_device *device)
892 int result = 0; 740 int result = 0;
893 acpi_status status = 0; 741 acpi_status status = 0;
894 struct acpi_battery *battery = NULL; 742 struct acpi_battery *battery = NULL;
895
896 if (!device) 743 if (!device)
897 return -EINVAL; 744 return -EINVAL;
898
899 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 745 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
900 if (!battery) 746 if (!battery)
901 return -ENOMEM; 747 return -ENOMEM;
902
903 mutex_init(&battery->mutex);
904
905 mutex_lock(&battery->mutex);
906
907 battery->device = device; 748 battery->device = device;
908 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 749 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
909 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 750 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
910 acpi_driver_data(device) = battery; 751 acpi_driver_data(device) = battery;
911 752 mutex_init(&battery->lock);
912 result = acpi_battery_get_status(battery); 753 acpi_battery_update(battery);
913 if (result) 754#ifdef CONFIG_ACPI_PROCFS
914 goto end;
915
916 battery->flags.init_update = 1;
917
918 result = acpi_battery_add_fs(device); 755 result = acpi_battery_add_fs(device);
919 if (result) 756 if (result)
920 goto end; 757 goto end;
921 758#endif
759 battery->bat.name = acpi_device_bid(device);
760 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
761 battery->bat.get_property = acpi_battery_get_property;
762 result = power_supply_register(&battery->device->dev, &battery->bat);
763 result = device_create_file(battery->bat.dev, &alarm_attr);
922 status = acpi_install_notify_handler(device->handle, 764 status = acpi_install_notify_handler(device->handle,
923 ACPI_ALL_NOTIFY, 765 ACPI_ALL_NOTIFY,
924 acpi_battery_notify, battery); 766 acpi_battery_notify, battery);
@@ -927,20 +769,16 @@ static int acpi_battery_add(struct acpi_device *device)
927 result = -ENODEV; 769 result = -ENODEV;
928 goto end; 770 goto end;
929 } 771 }
930
931 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", 772 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
932 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), 773 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
933 device->status.battery_present ? "present" : "absent"); 774 device->status.battery_present ? "present" : "absent");
934
935 end: 775 end:
936
937 if (result) { 776 if (result) {
777#ifdef CONFIG_ACPI_PROCFS
938 acpi_battery_remove_fs(device); 778 acpi_battery_remove_fs(device);
779#endif
939 kfree(battery); 780 kfree(battery);
940 } 781 }
941
942 mutex_unlock(&battery->mutex);
943
944 return result; 782 return result;
945} 783}
946 784
@@ -951,27 +789,19 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
951 789
952 if (!device || !acpi_driver_data(device)) 790 if (!device || !acpi_driver_data(device))
953 return -EINVAL; 791 return -EINVAL;
954
955 battery = acpi_driver_data(device); 792 battery = acpi_driver_data(device);
956
957 mutex_lock(&battery->mutex);
958
959 status = acpi_remove_notify_handler(device->handle, 793 status = acpi_remove_notify_handler(device->handle,
960 ACPI_ALL_NOTIFY, 794 ACPI_ALL_NOTIFY,
961 acpi_battery_notify); 795 acpi_battery_notify);
962 796#ifdef CONFIG_ACPI_PROCFS
963 acpi_battery_remove_fs(device); 797 acpi_battery_remove_fs(device);
964 798#endif
965 kfree(battery->bif_data.pointer); 799 if (battery->bat.dev) {
966 800 device_remove_file(battery->bat.dev, &alarm_attr);
967 kfree(battery->bst_data.pointer); 801 power_supply_unregister(&battery->bat);
968 802 }
969 mutex_unlock(&battery->mutex); 803 mutex_destroy(&battery->lock);
970
971 mutex_destroy(&battery->mutex);
972
973 kfree(battery); 804 kfree(battery);
974
975 return 0; 805 return 0;
976} 806}
977 807
@@ -979,44 +809,48 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
979static int acpi_battery_resume(struct acpi_device *device) 809static int acpi_battery_resume(struct acpi_device *device)
980{ 810{
981 struct acpi_battery *battery; 811 struct acpi_battery *battery;
982
983 if (!device) 812 if (!device)
984 return -EINVAL; 813 return -EINVAL;
985 814 battery = acpi_driver_data(device);
986 battery = device->driver_data; 815 battery->update_time = 0;
987
988 battery->flags.init_update = 1;
989
990 return 0; 816 return 0;
991} 817}
992 818
819static struct acpi_driver acpi_battery_driver = {
820 .name = "battery",
821 .class = ACPI_BATTERY_CLASS,
822 .ids = battery_device_ids,
823 .ops = {
824 .add = acpi_battery_add,
825 .resume = acpi_battery_resume,
826 .remove = acpi_battery_remove,
827 },
828};
829
993static int __init acpi_battery_init(void) 830static int __init acpi_battery_init(void)
994{ 831{
995 int result;
996
997 if (acpi_disabled) 832 if (acpi_disabled)
998 return -ENODEV; 833 return -ENODEV;
999 834#ifdef CONFIG_ACPI_PROCFS
1000 acpi_battery_dir = acpi_lock_battery_dir(); 835 acpi_battery_dir = acpi_lock_battery_dir();
1001 if (!acpi_battery_dir) 836 if (!acpi_battery_dir)
1002 return -ENODEV; 837 return -ENODEV;
1003 838#endif
1004 result = acpi_bus_register_driver(&acpi_battery_driver); 839 if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
1005 if (result < 0) { 840#ifdef CONFIG_ACPI_PROCFS
1006 acpi_unlock_battery_dir(acpi_battery_dir); 841 acpi_unlock_battery_dir(acpi_battery_dir);
842#endif
1007 return -ENODEV; 843 return -ENODEV;
1008 } 844 }
1009
1010 return 0; 845 return 0;
1011} 846}
1012 847
1013static void __exit acpi_battery_exit(void) 848static void __exit acpi_battery_exit(void)
1014{ 849{
1015 acpi_bus_unregister_driver(&acpi_battery_driver); 850 acpi_bus_unregister_driver(&acpi_battery_driver);
1016 851#ifdef CONFIG_ACPI_PROCFS
1017 acpi_unlock_battery_dir(acpi_battery_dir); 852 acpi_unlock_battery_dir(acpi_battery_dir);
1018 853#endif
1019 return;
1020} 854}
1021 855
1022module_init(acpi_battery_init); 856module_init(acpi_battery_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index cbfc81579c9a..fb2cff9a2d24 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -286,15 +286,11 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
286 286
287extern int event_is_open; 287extern int event_is_open;
288 288
289int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) 289int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
290{ 290{
291 struct acpi_bus_event *event = NULL; 291 struct acpi_bus_event *event;
292 unsigned long flags = 0; 292 unsigned long flags = 0;
293 293
294
295 if (!device)
296 return -EINVAL;
297
298 /* drop event on the floor if no one's listening */ 294 /* drop event on the floor if no one's listening */
299 if (!event_is_open) 295 if (!event_is_open)
300 return 0; 296 return 0;
@@ -303,8 +299,8 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
303 if (!event) 299 if (!event)
304 return -ENOMEM; 300 return -ENOMEM;
305 301
306 strcpy(event->device_class, device->pnp.device_class); 302 strcpy(event->device_class, device_class);
307 strcpy(event->bus_id, device->pnp.bus_id); 303 strcpy(event->bus_id, bus_id);
308 event->type = type; 304 event->type = type;
309 event->data = data; 305 event->data = data;
310 306
@@ -315,6 +311,17 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
315 wake_up_interruptible(&acpi_bus_event_queue); 311 wake_up_interruptible(&acpi_bus_event_queue);
316 312
317 return 0; 313 return 0;
314
315}
316
317EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
318
319int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
320{
321 if (!device)
322 return -EINVAL;
323 return acpi_bus_generate_proc_event4(device->pnp.device_class,
324 device->pnp.bus_id, type, data);
318} 325}
319 326
320EXPORT_SYMBOL(acpi_bus_generate_proc_event); 327EXPORT_SYMBOL(acpi_bus_generate_proc_event);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3f7935ab0cf5..7b4178393e34 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -121,6 +121,7 @@ static struct acpi_ec {
121 atomic_t event_count; 121 atomic_t event_count;
122 wait_queue_head_t wait; 122 wait_queue_head_t wait;
123 struct list_head list; 123 struct list_head list;
124 u8 handlers_installed;
124} *boot_ec, *first_ec; 125} *boot_ec, *first_ec;
125 126
126/* -------------------------------------------------------------------------- 127/* --------------------------------------------------------------------------
@@ -425,7 +426,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
425 handler->func = func; 426 handler->func = func;
426 handler->data = data; 427 handler->data = data;
427 mutex_lock(&ec->lock); 428 mutex_lock(&ec->lock);
428 list_add_tail(&handler->node, &ec->list); 429 list_add(&handler->node, &ec->list);
429 mutex_unlock(&ec->lock); 430 mutex_unlock(&ec->lock);
430 return 0; 431 return 0;
431} 432}
@@ -440,7 +441,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
440 if (query_bit == handler->query_bit) { 441 if (query_bit == handler->query_bit) {
441 list_del(&handler->node); 442 list_del(&handler->node);
442 kfree(handler); 443 kfree(handler);
443 break;
444 } 444 }
445 } 445 }
446 mutex_unlock(&ec->lock); 446 mutex_unlock(&ec->lock);
@@ -680,32 +680,50 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
680 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); 680 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
681 if (ACPI_FAILURE(status)) 681 if (ACPI_FAILURE(status))
682 return status; 682 return status;
683
684 /* Find and register all query methods */ 683 /* Find and register all query methods */
685 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, 684 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
686 acpi_ec_register_query_methods, ec, NULL); 685 acpi_ec_register_query_methods, ec, NULL);
687
688 /* Use the global lock for all EC transactions? */ 686 /* Use the global lock for all EC transactions? */
689 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); 687 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
690
691 ec->handle = handle; 688 ec->handle = handle;
692
693 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
694 ec->gpe, ec->command_addr, ec->data_addr);
695
696 return AE_CTRL_TERMINATE; 689 return AE_CTRL_TERMINATE;
697} 690}
698 691
692static void ec_remove_handlers(struct acpi_ec *ec)
693{
694 if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
695 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
696 printk(KERN_ERR PREFIX "failed to remove space handler\n");
697 if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
698 &acpi_ec_gpe_handler)))
699 printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
700 ec->handlers_installed = 0;
701}
702
699static int acpi_ec_add(struct acpi_device *device) 703static int acpi_ec_add(struct acpi_device *device)
700{ 704{
701 struct acpi_ec *ec = NULL; 705 struct acpi_ec *ec = NULL;
702 706
703 if (!device) 707 if (!device)
704 return -EINVAL; 708 return -EINVAL;
705
706 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 709 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
707 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 710 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
708 711
712 /* Check for boot EC */
713 if (boot_ec) {
714 if (boot_ec->handle == device->handle) {
715 /* Pre-loaded EC from DSDT, just move pointer */
716 ec = boot_ec;
717 boot_ec = NULL;
718 goto end;
719 } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
720 /* ECDT-based EC, time to shut it down */
721 ec_remove_handlers(boot_ec);
722 kfree(boot_ec);
723 first_ec = boot_ec = NULL;
724 }
725 }
726
709 ec = make_acpi_ec(); 727 ec = make_acpi_ec();
710 if (!ec) 728 if (!ec)
711 return -ENOMEM; 729 return -ENOMEM;
@@ -715,25 +733,14 @@ static int acpi_ec_add(struct acpi_device *device)
715 kfree(ec); 733 kfree(ec);
716 return -EINVAL; 734 return -EINVAL;
717 } 735 }
718
719 /* Check if we found the boot EC */
720 if (boot_ec) {
721 if (boot_ec->gpe == ec->gpe) {
722 /* We might have incorrect info for GL at boot time */
723 mutex_lock(&boot_ec->lock);
724 boot_ec->global_lock = ec->global_lock;
725 /* Copy handlers from new ec into boot ec */
726 list_splice(&ec->list, &boot_ec->list);
727 mutex_unlock(&boot_ec->lock);
728 kfree(ec);
729 ec = boot_ec;
730 }
731 } else
732 first_ec = ec;
733 ec->handle = device->handle; 736 ec->handle = device->handle;
737 end:
738 if (!first_ec)
739 first_ec = ec;
734 acpi_driver_data(device) = ec; 740 acpi_driver_data(device) = ec;
735
736 acpi_ec_add_fs(device); 741 acpi_ec_add_fs(device);
742 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
743 ec->gpe, ec->command_addr, ec->data_addr);
737 return 0; 744 return 0;
738} 745}
739 746
@@ -756,10 +763,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
756 acpi_driver_data(device) = NULL; 763 acpi_driver_data(device) = NULL;
757 if (ec == first_ec) 764 if (ec == first_ec)
758 first_ec = NULL; 765 first_ec = NULL;
759 766 kfree(ec);
760 /* Don't touch boot EC */
761 if (boot_ec != ec)
762 kfree(ec);
763 return 0; 767 return 0;
764} 768}
765 769
@@ -789,6 +793,8 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
789static int ec_install_handlers(struct acpi_ec *ec) 793static int ec_install_handlers(struct acpi_ec *ec)
790{ 794{
791 acpi_status status; 795 acpi_status status;
796 if (ec->handlers_installed)
797 return 0;
792 status = acpi_install_gpe_handler(NULL, ec->gpe, 798 status = acpi_install_gpe_handler(NULL, ec->gpe,
793 ACPI_GPE_EDGE_TRIGGERED, 799 ACPI_GPE_EDGE_TRIGGERED,
794 &acpi_ec_gpe_handler, ec); 800 &acpi_ec_gpe_handler, ec);
@@ -807,6 +813,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
807 return -ENODEV; 813 return -ENODEV;
808 } 814 }
809 815
816 ec->handlers_installed = 1;
810 return 0; 817 return 0;
811} 818}
812 819
@@ -823,41 +830,22 @@ static int acpi_ec_start(struct acpi_device *device)
823 if (!ec) 830 if (!ec)
824 return -EINVAL; 831 return -EINVAL;
825 832
826 /* Boot EC is already working */ 833 ret = ec_install_handlers(ec);
827 if (ec != boot_ec)
828 ret = ec_install_handlers(ec);
829 834
830 /* EC is fully operational, allow queries */ 835 /* EC is fully operational, allow queries */
831 atomic_set(&ec->query_pending, 0); 836 atomic_set(&ec->query_pending, 0);
832
833 return ret; 837 return ret;
834} 838}
835 839
836static int acpi_ec_stop(struct acpi_device *device, int type) 840static int acpi_ec_stop(struct acpi_device *device, int type)
837{ 841{
838 acpi_status status;
839 struct acpi_ec *ec; 842 struct acpi_ec *ec;
840
841 if (!device) 843 if (!device)
842 return -EINVAL; 844 return -EINVAL;
843
844 ec = acpi_driver_data(device); 845 ec = acpi_driver_data(device);
845 if (!ec) 846 if (!ec)
846 return -EINVAL; 847 return -EINVAL;
847 848 ec_remove_handlers(ec);
848 /* Don't touch boot EC */
849 if (ec == boot_ec)
850 return 0;
851
852 status = acpi_remove_address_space_handler(ec->handle,
853 ACPI_ADR_SPACE_EC,
854 &acpi_ec_space_handler);
855 if (ACPI_FAILURE(status))
856 return -ENODEV;
857
858 status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
859 if (ACPI_FAILURE(status))
860 return -ENODEV;
861 849
862 return 0; 850 return 0;
863} 851}
@@ -877,7 +865,7 @@ int __init acpi_ec_ecdt_probe(void)
877 status = acpi_get_table(ACPI_SIG_ECDT, 1, 865 status = acpi_get_table(ACPI_SIG_ECDT, 1,
878 (struct acpi_table_header **)&ecdt_ptr); 866 (struct acpi_table_header **)&ecdt_ptr);
879 if (ACPI_SUCCESS(status)) { 867 if (ACPI_SUCCESS(status)) {
880 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n"); 868 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
881 boot_ec->command_addr = ecdt_ptr->control.address; 869 boot_ec->command_addr = ecdt_ptr->control.address;
882 boot_ec->data_addr = ecdt_ptr->data.address; 870 boot_ec->data_addr = ecdt_ptr->data.address;
883 boot_ec->gpe = ecdt_ptr->gpe; 871 boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +887,6 @@ int __init acpi_ec_ecdt_probe(void)
899 error: 887 error:
900 kfree(boot_ec); 888 kfree(boot_ec);
901 boot_ec = NULL; 889 boot_ec = NULL;
902
903 return -ENODEV; 890 return -ENODEV;
904} 891}
905 892
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index a1f87b5def2a..e41287815ea1 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -239,10 +239,8 @@ u32 acpi_ev_fixed_event_detect(void)
239 * Read the fixed feature status and enable registers, as all the cases 239 * Read the fixed feature status and enable registers, as all the cases
240 * depend on their values. Ignore errors here. 240 * depend on their values. Ignore errors here.
241 */ 241 */
242 (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 242 (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
243 ACPI_REGISTER_PM1_STATUS, &fixed_status); 243 (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
244 (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
245 ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
246 244
247 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, 245 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
248 "Fixed Event Block: Enable %08X Status %08X\n", 246 "Fixed Event Block: Enable %08X Status %08X\n",
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 1d371fa663f2..73f9c5fb1ba7 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -75,8 +75,7 @@ acpi_status acpi_hw_clear_acpi_status(void)
75 75
76 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 76 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
77 77
78 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 78 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
79 ACPI_REGISTER_PM1_STATUS,
80 ACPI_BITMASK_ALL_FIXED_STATUS); 79 ACPI_BITMASK_ALL_FIXED_STATUS);
81 if (ACPI_FAILURE(status)) { 80 if (ACPI_FAILURE(status)) {
82 goto unlock_and_exit; 81 goto unlock_and_exit;
@@ -259,7 +258,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
259 * 258 *
260 ******************************************************************************/ 259 ******************************************************************************/
261 260
262acpi_status acpi_get_register(u32 register_id, u32 * return_value) 261acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
263{ 262{
264 u32 register_value = 0; 263 u32 register_value = 0;
265 struct acpi_bit_register_info *bit_reg_info; 264 struct acpi_bit_register_info *bit_reg_info;
@@ -276,8 +275,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
276 275
277 /* Read from the register */ 276 /* Read from the register */
278 277
279 status = acpi_hw_register_read(ACPI_MTX_LOCK, 278 status = acpi_hw_register_read(bit_reg_info->parent_register,
280 bit_reg_info->parent_register,
281 &register_value); 279 &register_value);
282 280
283 if (ACPI_SUCCESS(status)) { 281 if (ACPI_SUCCESS(status)) {
@@ -298,6 +296,16 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
298 return_ACPI_STATUS(status); 296 return_ACPI_STATUS(status);
299} 297}
300 298
299acpi_status acpi_get_register(u32 register_id, u32 * return_value)
300{
301 acpi_status status;
302 acpi_cpu_flags flags;
303 flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
304 status = acpi_get_register_unlocked(register_id, return_value);
305 acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
306 return status;
307}
308
301ACPI_EXPORT_SYMBOL(acpi_get_register) 309ACPI_EXPORT_SYMBOL(acpi_get_register)
302 310
303/******************************************************************************* 311/*******************************************************************************
@@ -335,8 +343,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
335 343
336 /* Always do a register read first so we can insert the new bits */ 344 /* Always do a register read first so we can insert the new bits */
337 345
338 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 346 status = acpi_hw_register_read(bit_reg_info->parent_register,
339 bit_reg_info->parent_register,
340 &register_value); 347 &register_value);
341 if (ACPI_FAILURE(status)) { 348 if (ACPI_FAILURE(status)) {
342 goto unlock_and_exit; 349 goto unlock_and_exit;
@@ -363,8 +370,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
363 bit_reg_info-> 370 bit_reg_info->
364 access_bit_mask); 371 access_bit_mask);
365 if (value) { 372 if (value) {
366 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 373 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
367 ACPI_REGISTER_PM1_STATUS,
368 (u16) value); 374 (u16) value);
369 register_value = 0; 375 register_value = 0;
370 } 376 }
@@ -377,8 +383,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
377 bit_reg_info->access_bit_mask, 383 bit_reg_info->access_bit_mask,
378 value); 384 value);
379 385
380 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 386 status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
381 ACPI_REGISTER_PM1_ENABLE,
382 (u16) register_value); 387 (u16) register_value);
383 break; 388 break;
384 389
@@ -397,15 +402,13 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
397 bit_reg_info->access_bit_mask, 402 bit_reg_info->access_bit_mask,
398 value); 403 value);
399 404
400 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 405 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
401 ACPI_REGISTER_PM1_CONTROL,
402 (u16) register_value); 406 (u16) register_value);
403 break; 407 break;
404 408
405 case ACPI_REGISTER_PM2_CONTROL: 409 case ACPI_REGISTER_PM2_CONTROL:
406 410
407 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 411 status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
408 ACPI_REGISTER_PM2_CONTROL,
409 &register_value); 412 &register_value);
410 if (ACPI_FAILURE(status)) { 413 if (ACPI_FAILURE(status)) {
411 goto unlock_and_exit; 414 goto unlock_and_exit;
@@ -430,8 +433,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
430 xpm2_control_block. 433 xpm2_control_block.
431 address))); 434 address)));
432 435
433 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 436 status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
434 ACPI_REGISTER_PM2_CONTROL,
435 (u8) (register_value)); 437 (u8) (register_value));
436 break; 438 break;
437 439
@@ -461,8 +463,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
461 * 463 *
462 * FUNCTION: acpi_hw_register_read 464 * FUNCTION: acpi_hw_register_read
463 * 465 *
464 * PARAMETERS: use_lock - Lock hardware? True/False 466 * PARAMETERS: register_id - ACPI Register ID
465 * register_id - ACPI Register ID
466 * return_value - Where the register value is returned 467 * return_value - Where the register value is returned
467 * 468 *
468 * RETURN: Status and the value read. 469 * RETURN: Status and the value read.
@@ -471,19 +472,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
471 * 472 *
472 ******************************************************************************/ 473 ******************************************************************************/
473acpi_status 474acpi_status
474acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) 475acpi_hw_register_read(u32 register_id, u32 * return_value)
475{ 476{
476 u32 value1 = 0; 477 u32 value1 = 0;
477 u32 value2 = 0; 478 u32 value2 = 0;
478 acpi_status status; 479 acpi_status status;
479 acpi_cpu_flags lock_flags = 0;
480 480
481 ACPI_FUNCTION_TRACE(hw_register_read); 481 ACPI_FUNCTION_TRACE(hw_register_read);
482 482
483 if (ACPI_MTX_LOCK == use_lock) {
484 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
485 }
486
487 switch (register_id) { 483 switch (register_id) {
488 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 484 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
489 485
@@ -491,7 +487,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
491 acpi_hw_low_level_read(16, &value1, 487 acpi_hw_low_level_read(16, &value1,
492 &acpi_gbl_FADT.xpm1a_event_block); 488 &acpi_gbl_FADT.xpm1a_event_block);
493 if (ACPI_FAILURE(status)) { 489 if (ACPI_FAILURE(status)) {
494 goto unlock_and_exit; 490 goto exit;
495 } 491 }
496 492
497 /* PM1B is optional */ 493 /* PM1B is optional */
@@ -507,7 +503,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
507 status = 503 status =
508 acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); 504 acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
509 if (ACPI_FAILURE(status)) { 505 if (ACPI_FAILURE(status)) {
510 goto unlock_and_exit; 506 goto exit;
511 } 507 }
512 508
513 /* PM1B is optional */ 509 /* PM1B is optional */
@@ -523,7 +519,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
523 acpi_hw_low_level_read(16, &value1, 519 acpi_hw_low_level_read(16, &value1,
524 &acpi_gbl_FADT.xpm1a_control_block); 520 &acpi_gbl_FADT.xpm1a_control_block);
525 if (ACPI_FAILURE(status)) { 521 if (ACPI_FAILURE(status)) {
526 goto unlock_and_exit; 522 goto exit;
527 } 523 }
528 524
529 status = 525 status =
@@ -558,10 +554,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
558 break; 554 break;
559 } 555 }
560 556
561 unlock_and_exit: 557 exit:
562 if (ACPI_MTX_LOCK == use_lock) {
563 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
564 }
565 558
566 if (ACPI_SUCCESS(status)) { 559 if (ACPI_SUCCESS(status)) {
567 *return_value = value1; 560 *return_value = value1;
@@ -574,8 +567,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
574 * 567 *
575 * FUNCTION: acpi_hw_register_write 568 * FUNCTION: acpi_hw_register_write
576 * 569 *
577 * PARAMETERS: use_lock - Lock hardware? True/False 570 * PARAMETERS: register_id - ACPI Register ID
578 * register_id - ACPI Register ID
579 * Value - The value to write 571 * Value - The value to write
580 * 572 *
581 * RETURN: Status 573 * RETURN: Status
@@ -597,28 +589,22 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
597 * 589 *
598 ******************************************************************************/ 590 ******************************************************************************/
599 591
600acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) 592acpi_status acpi_hw_register_write(u32 register_id, u32 value)
601{ 593{
602 acpi_status status; 594 acpi_status status;
603 acpi_cpu_flags lock_flags = 0;
604 u32 read_value; 595 u32 read_value;
605 596
606 ACPI_FUNCTION_TRACE(hw_register_write); 597 ACPI_FUNCTION_TRACE(hw_register_write);
607 598
608 if (ACPI_MTX_LOCK == use_lock) {
609 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
610 }
611
612 switch (register_id) { 599 switch (register_id) {
613 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 600 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
614 601
615 /* Perform a read first to preserve certain bits (per ACPI spec) */ 602 /* Perform a read first to preserve certain bits (per ACPI spec) */
616 603
617 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 604 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
618 ACPI_REGISTER_PM1_STATUS,
619 &read_value); 605 &read_value);
620 if (ACPI_FAILURE(status)) { 606 if (ACPI_FAILURE(status)) {
621 goto unlock_and_exit; 607 goto exit;
622 } 608 }
623 609
624 /* Insert the bits to be preserved */ 610 /* Insert the bits to be preserved */
@@ -632,7 +618,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
632 acpi_hw_low_level_write(16, value, 618 acpi_hw_low_level_write(16, value,
633 &acpi_gbl_FADT.xpm1a_event_block); 619 &acpi_gbl_FADT.xpm1a_event_block);
634 if (ACPI_FAILURE(status)) { 620 if (ACPI_FAILURE(status)) {
635 goto unlock_and_exit; 621 goto exit;
636 } 622 }
637 623
638 /* PM1B is optional */ 624 /* PM1B is optional */
@@ -647,7 +633,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
647 status = 633 status =
648 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); 634 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
649 if (ACPI_FAILURE(status)) { 635 if (ACPI_FAILURE(status)) {
650 goto unlock_and_exit; 636 goto exit;
651 } 637 }
652 638
653 /* PM1B is optional */ 639 /* PM1B is optional */
@@ -661,11 +647,10 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
661 /* 647 /*
662 * Perform a read first to preserve certain bits (per ACPI spec) 648 * Perform a read first to preserve certain bits (per ACPI spec)
663 */ 649 */
664 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 650 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
665 ACPI_REGISTER_PM1_CONTROL,
666 &read_value); 651 &read_value);
667 if (ACPI_FAILURE(status)) { 652 if (ACPI_FAILURE(status)) {
668 goto unlock_and_exit; 653 goto exit;
669 } 654 }
670 655
671 /* Insert the bits to be preserved */ 656 /* Insert the bits to be preserved */
@@ -679,7 +664,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
679 acpi_hw_low_level_write(16, value, 664 acpi_hw_low_level_write(16, value,
680 &acpi_gbl_FADT.xpm1a_control_block); 665 &acpi_gbl_FADT.xpm1a_control_block);
681 if (ACPI_FAILURE(status)) { 666 if (ACPI_FAILURE(status)) {
682 goto unlock_and_exit; 667 goto exit;
683 } 668 }
684 669
685 status = 670 status =
@@ -728,11 +713,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
728 break; 713 break;
729 } 714 }
730 715
731 unlock_and_exit: 716 exit:
732 if (ACPI_MTX_LOCK == use_lock) {
733 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
734 }
735
736 return_ACPI_STATUS(status); 717 return_ACPI_STATUS(status);
737} 718}
738 719
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index cf69c0040a39..81b248429703 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -234,15 +234,11 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
234 "While executing method _SST")); 234 "While executing method _SST"));
235 } 235 }
236 236
237 /* 237 /* Disable/Clear all GPEs */
238 * 1) Disable/Clear all GPEs 238
239 */
240 status = acpi_hw_disable_all_gpes(); 239 status = acpi_hw_disable_all_gpes();
241 if (ACPI_FAILURE(status)) {
242 return_ACPI_STATUS(status);
243 }
244 240
245 return_ACPI_STATUS(AE_OK); 241 return_ACPI_STATUS(status);
246} 242}
247 243
248ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) 244ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
@@ -313,8 +309,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
313 309
314 /* Get current value of PM1A control */ 310 /* Get current value of PM1A control */
315 311
316 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 312 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
317 ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
318 if (ACPI_FAILURE(status)) { 313 if (ACPI_FAILURE(status)) {
319 return_ACPI_STATUS(status); 314 return_ACPI_STATUS(status);
320 } 315 }
@@ -341,15 +336,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
341 336
342 /* Write #1: fill in SLP_TYP data */ 337 /* Write #1: fill in SLP_TYP data */
343 338
344 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 339 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
345 ACPI_REGISTER_PM1A_CONTROL,
346 PM1Acontrol); 340 PM1Acontrol);
347 if (ACPI_FAILURE(status)) { 341 if (ACPI_FAILURE(status)) {
348 return_ACPI_STATUS(status); 342 return_ACPI_STATUS(status);
349 } 343 }
350 344
351 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 345 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
352 ACPI_REGISTER_PM1B_CONTROL,
353 PM1Bcontrol); 346 PM1Bcontrol);
354 if (ACPI_FAILURE(status)) { 347 if (ACPI_FAILURE(status)) {
355 return_ACPI_STATUS(status); 348 return_ACPI_STATUS(status);
@@ -364,15 +357,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
364 357
365 ACPI_FLUSH_CPU_CACHE(); 358 ACPI_FLUSH_CPU_CACHE();
366 359
367 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 360 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
368 ACPI_REGISTER_PM1A_CONTROL,
369 PM1Acontrol); 361 PM1Acontrol);
370 if (ACPI_FAILURE(status)) { 362 if (ACPI_FAILURE(status)) {
371 return_ACPI_STATUS(status); 363 return_ACPI_STATUS(status);
372 } 364 }
373 365
374 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 366 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
375 ACPI_REGISTER_PM1B_CONTROL,
376 PM1Bcontrol); 367 PM1Bcontrol);
377 if (ACPI_FAILURE(status)) { 368 if (ACPI_FAILURE(status)) {
378 return_ACPI_STATUS(status); 369 return_ACPI_STATUS(status);
@@ -392,8 +383,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
392 */ 383 */
393 acpi_os_stall(10000000); 384 acpi_os_stall(10000000);
394 385
395 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 386 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
396 ACPI_REGISTER_PM1_CONTROL,
397 sleep_enable_reg_info-> 387 sleep_enable_reg_info->
398 access_bit_mask); 388 access_bit_mask);
399 if (ACPI_FAILURE(status)) { 389 if (ACPI_FAILURE(status)) {
@@ -404,7 +394,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
404 /* Wait until we enter sleep state */ 394 /* Wait until we enter sleep state */
405 395
406 do { 396 do {
407 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); 397 status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
398 &in_value);
408 if (ACPI_FAILURE(status)) { 399 if (ACPI_FAILURE(status)) {
409 return_ACPI_STATUS(status); 400 return_ACPI_STATUS(status);
410 } 401 }
@@ -520,8 +511,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
520 511
521 /* Get current value of PM1A control */ 512 /* Get current value of PM1A control */
522 513
523 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 514 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
524 ACPI_REGISTER_PM1_CONTROL,
525 &PM1Acontrol); 515 &PM1Acontrol);
526 if (ACPI_SUCCESS(status)) { 516 if (ACPI_SUCCESS(status)) {
527 517
@@ -543,11 +533,9 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
543 533
544 /* Just ignore any errors */ 534 /* Just ignore any errors */
545 535
546 (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 536 (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
547 ACPI_REGISTER_PM1A_CONTROL,
548 PM1Acontrol); 537 PM1Acontrol);
549 (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 538 (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
550 ACPI_REGISTER_PM1B_CONTROL,
551 PM1Bcontrol); 539 PM1Bcontrol);
552 } 540 }
553 } 541 }
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 352cf81af581..aabc6ca4a81c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1043,14 +1043,6 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
1043__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); 1043__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
1044 1044
1045/* 1045/*
1046 * max_cstate is defined in the base kernel so modules can
1047 * change it w/o depending on the state of the processor module.
1048 */
1049unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
1050
1051EXPORT_SYMBOL(max_cstate);
1052
1053/*
1054 * Acquire a spinlock. 1046 * Acquire a spinlock.
1055 * 1047 *
1056 * handle is a pointer to the spinlock_t. 1048 * handle is a pointer to the spinlock_t.
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9f11dc296cdd..a7351084f2f8 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -44,6 +44,7 @@
44#include <linux/seq_file.h> 44#include <linux/seq_file.h>
45#include <linux/dmi.h> 45#include <linux/dmi.h>
46#include <linux/moduleparam.h> 46#include <linux/moduleparam.h>
47#include <linux/cpuidle.h>
47 48
48#include <asm/io.h> 49#include <asm/io.h>
49#include <asm/system.h> 50#include <asm/system.h>
@@ -1049,11 +1050,13 @@ static int __init acpi_processor_init(void)
1049 return -ENOMEM; 1050 return -ENOMEM;
1050 acpi_processor_dir->owner = THIS_MODULE; 1051 acpi_processor_dir->owner = THIS_MODULE;
1051 1052
1053 result = cpuidle_register_driver(&acpi_idle_driver);
1054 if (result < 0)
1055 goto out_proc;
1056
1052 result = acpi_bus_register_driver(&acpi_processor_driver); 1057 result = acpi_bus_register_driver(&acpi_processor_driver);
1053 if (result < 0) { 1058 if (result < 0)
1054 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); 1059 goto out_cpuidle;
1055 return result;
1056 }
1057 1060
1058 acpi_processor_install_hotplug_notify(); 1061 acpi_processor_install_hotplug_notify();
1059 1062
@@ -1062,11 +1065,18 @@ static int __init acpi_processor_init(void)
1062 acpi_processor_ppc_init(); 1065 acpi_processor_ppc_init();
1063 1066
1064 return 0; 1067 return 0;
1068
1069out_cpuidle:
1070 cpuidle_unregister_driver(&acpi_idle_driver);
1071
1072out_proc:
1073 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
1074
1075 return result;
1065} 1076}
1066 1077
1067static void __exit acpi_processor_exit(void) 1078static void __exit acpi_processor_exit(void)
1068{ 1079{
1069
1070 acpi_processor_ppc_exit(); 1080 acpi_processor_ppc_exit();
1071 1081
1072 acpi_thermal_cpufreq_exit(); 1082 acpi_thermal_cpufreq_exit();
@@ -1075,6 +1085,8 @@ static void __exit acpi_processor_exit(void)
1075 1085
1076 acpi_bus_unregister_driver(&acpi_processor_driver); 1086 acpi_bus_unregister_driver(&acpi_processor_driver);
1077 1087
1088 cpuidle_unregister_driver(&acpi_idle_driver);
1089
1078 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); 1090 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
1079 1091
1080 return; 1092 return;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 1f6fb38de017..f996d0e37689 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -40,6 +40,7 @@
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h> 41#include <linux/latency.h>
42#include <linux/clockchips.h> 42#include <linux/clockchips.h>
43#include <linux/cpuidle.h>
43 44
44/* 45/*
45 * Include the apic definitions for x86 to have the APIC timer related defines 46 * Include the apic definitions for x86 to have the APIC timer related defines
@@ -64,14 +65,22 @@ ACPI_MODULE_NAME("processor_idle");
64#define ACPI_PROCESSOR_FILE_POWER "power" 65#define ACPI_PROCESSOR_FILE_POWER "power"
65#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) 66#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
66#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) 67#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
68#ifndef CONFIG_CPU_IDLE
67#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 69#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
68#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 70#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
69static void (*pm_idle_save) (void) __read_mostly; 71static void (*pm_idle_save) (void) __read_mostly;
70module_param(max_cstate, uint, 0644); 72#else
73#define C2_OVERHEAD 1 /* 1us */
74#define C3_OVERHEAD 1 /* 1us */
75#endif
76#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
71 77
78static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
79module_param(max_cstate, uint, 0000);
72static unsigned int nocst __read_mostly; 80static unsigned int nocst __read_mostly;
73module_param(nocst, uint, 0000); 81module_param(nocst, uint, 0000);
74 82
83#ifndef CONFIG_CPU_IDLE
75/* 84/*
76 * bm_history -- bit-mask with a bit per jiffy of bus-master activity 85 * bm_history -- bit-mask with a bit per jiffy of bus-master activity
77 * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms 86 * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -82,9 +91,10 @@ module_param(nocst, uint, 0000);
82static unsigned int bm_history __read_mostly = 91static unsigned int bm_history __read_mostly =
83 (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); 92 (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
84module_param(bm_history, uint, 0644); 93module_param(bm_history, uint, 0644);
85/* -------------------------------------------------------------------------- 94
86 Power Management 95static int acpi_processor_set_power_policy(struct acpi_processor *pr);
87 -------------------------------------------------------------------------- */ 96
97#endif
88 98
89/* 99/*
90 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. 100 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -177,6 +187,18 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
177 return ((0xFFFFFFFF - t1) + t2); 187 return ((0xFFFFFFFF - t1) + t2);
178} 188}
179 189
190static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
191{
192 if (t2 >= t1)
193 return PM_TIMER_TICKS_TO_US(t2 - t1);
194 else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
195 return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
196 else
197 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
198}
199
200#ifndef CONFIG_CPU_IDLE
201
180static void 202static void
181acpi_processor_power_activate(struct acpi_processor *pr, 203acpi_processor_power_activate(struct acpi_processor *pr,
182 struct acpi_processor_cx *new) 204 struct acpi_processor_cx *new)
@@ -248,6 +270,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
248 unused = inl(acpi_gbl_FADT.xpm_timer_block.address); 270 unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
249 } 271 }
250} 272}
273#endif /* !CONFIG_CPU_IDLE */
251 274
252#ifdef ARCH_APICTIMER_STOPS_ON_C3 275#ifdef ARCH_APICTIMER_STOPS_ON_C3
253 276
@@ -330,6 +353,7 @@ int acpi_processor_resume(struct acpi_device * device)
330 return 0; 353 return 0;
331} 354}
332 355
356#ifndef CONFIG_CPU_IDLE
333static void acpi_processor_idle(void) 357static void acpi_processor_idle(void)
334{ 358{
335 struct acpi_processor *pr = NULL; 359 struct acpi_processor *pr = NULL;
@@ -427,7 +451,7 @@ static void acpi_processor_idle(void)
427 * an SMP system. We do it here instead of doing it at _CST/P_LVL 451 * an SMP system. We do it here instead of doing it at _CST/P_LVL
428 * detection phase, to work cleanly with logical CPU hotplug. 452 * detection phase, to work cleanly with logical CPU hotplug.
429 */ 453 */
430 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 454 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
431 !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) 455 !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
432 cx = &pr->power.states[ACPI_STATE_C1]; 456 cx = &pr->power.states[ACPI_STATE_C1];
433#endif 457#endif
@@ -727,6 +751,7 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
727 751
728 return 0; 752 return 0;
729} 753}
754#endif /* !CONFIG_CPU_IDLE */
730 755
731static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) 756static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
732{ 757{
@@ -744,7 +769,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
744#ifndef CONFIG_HOTPLUG_CPU 769#ifndef CONFIG_HOTPLUG_CPU
745 /* 770 /*
746 * Check for P_LVL2_UP flag before entering C2 and above on 771 * Check for P_LVL2_UP flag before entering C2 and above on
747 * an SMP system. 772 * an SMP system.
748 */ 773 */
749 if ((num_online_cpus() > 1) && 774 if ((num_online_cpus() > 1) &&
750 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) 775 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
@@ -945,7 +970,12 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
945 * Normalize the C2 latency to expidite policy 970 * Normalize the C2 latency to expidite policy
946 */ 971 */
947 cx->valid = 1; 972 cx->valid = 1;
973
974#ifndef CONFIG_CPU_IDLE
948 cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); 975 cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
976#else
977 cx->latency_ticks = cx->latency;
978#endif
949 979
950 return; 980 return;
951} 981}
@@ -1025,7 +1055,12 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
1025 * use this in our C3 policy 1055 * use this in our C3 policy
1026 */ 1056 */
1027 cx->valid = 1; 1057 cx->valid = 1;
1058
1059#ifndef CONFIG_CPU_IDLE
1028 cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); 1060 cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
1061#else
1062 cx->latency_ticks = cx->latency;
1063#endif
1029 1064
1030 return; 1065 return;
1031} 1066}
@@ -1090,6 +1125,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
1090 1125
1091 pr->power.count = acpi_processor_power_verify(pr); 1126 pr->power.count = acpi_processor_power_verify(pr);
1092 1127
1128#ifndef CONFIG_CPU_IDLE
1093 /* 1129 /*
1094 * Set Default Policy 1130 * Set Default Policy
1095 * ------------------ 1131 * ------------------
@@ -1101,6 +1137,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
1101 result = acpi_processor_set_power_policy(pr); 1137 result = acpi_processor_set_power_policy(pr);
1102 if (result) 1138 if (result)
1103 return result; 1139 return result;
1140#endif
1104 1141
1105 /* 1142 /*
1106 * if one state of type C2 or C3 is available, mark this 1143 * if one state of type C2 or C3 is available, mark this
@@ -1117,35 +1154,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
1117 return 0; 1154 return 0;
1118} 1155}
1119 1156
1120int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1121{
1122 int result = 0;
1123
1124
1125 if (!pr)
1126 return -EINVAL;
1127
1128 if (nocst) {
1129 return -ENODEV;
1130 }
1131
1132 if (!pr->flags.power_setup_done)
1133 return -ENODEV;
1134
1135 /* Fall back to the default idle loop */
1136 pm_idle = pm_idle_save;
1137 synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
1138
1139 pr->flags.power = 0;
1140 result = acpi_processor_get_power_info(pr);
1141 if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
1142 pm_idle = acpi_processor_idle;
1143
1144 return result;
1145}
1146
1147/* proc interface */
1148
1149static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) 1157static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1150{ 1158{
1151 struct acpi_processor *pr = seq->private; 1159 struct acpi_processor *pr = seq->private;
@@ -1227,6 +1235,35 @@ static const struct file_operations acpi_processor_power_fops = {
1227 .release = single_release, 1235 .release = single_release,
1228}; 1236};
1229 1237
1238#ifndef CONFIG_CPU_IDLE
1239
1240int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1241{
1242 int result = 0;
1243
1244
1245 if (!pr)
1246 return -EINVAL;
1247
1248 if (nocst) {
1249 return -ENODEV;
1250 }
1251
1252 if (!pr->flags.power_setup_done)
1253 return -ENODEV;
1254
1255 /* Fall back to the default idle loop */
1256 pm_idle = pm_idle_save;
1257 synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
1258
1259 pr->flags.power = 0;
1260 result = acpi_processor_get_power_info(pr);
1261 if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
1262 pm_idle = acpi_processor_idle;
1263
1264 return result;
1265}
1266
1230#ifdef CONFIG_SMP 1267#ifdef CONFIG_SMP
1231static void smp_callback(void *v) 1268static void smp_callback(void *v)
1232{ 1269{
@@ -1249,7 +1286,366 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
1249static struct notifier_block acpi_processor_latency_notifier = { 1286static struct notifier_block acpi_processor_latency_notifier = {
1250 .notifier_call = acpi_processor_latency_notify, 1287 .notifier_call = acpi_processor_latency_notify,
1251}; 1288};
1289
1290#endif
1291
1292#else /* CONFIG_CPU_IDLE */
1293
1294/**
1295 * acpi_idle_bm_check - checks if bus master activity was detected
1296 */
1297static int acpi_idle_bm_check(void)
1298{
1299 u32 bm_status = 0;
1300
1301 acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
1302 if (bm_status)
1303 acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
1304 /*
1305 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
1306 * the true state of bus mastering activity; forcing us to
1307 * manually check the BMIDEA bit of each IDE channel.
1308 */
1309 else if (errata.piix4.bmisx) {
1310 if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
1311 || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
1312 bm_status = 1;
1313 }
1314 return bm_status;
1315}
1316
1317/**
1318 * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
1319 * @pr: the processor
1320 * @target: the new target state
1321 */
1322static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
1323 struct acpi_processor_cx *target)
1324{
1325 if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
1326 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
1327 pr->flags.bm_rld_set = 0;
1328 }
1329
1330 if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
1331 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
1332 pr->flags.bm_rld_set = 1;
1333 }
1334}
1335
1336/**
1337 * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
1338 * @cx: cstate data
1339 */
1340static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
1341{
1342 if (cx->space_id == ACPI_CSTATE_FFH) {
1343 /* Call into architectural FFH based C-state */
1344 acpi_processor_ffh_cstate_enter(cx);
1345 } else {
1346 int unused;
1347 /* IO port based C-state */
1348 inb(cx->address);
1349 /* Dummy wait op - must do something useless after P_LVL2 read
1350 because chipsets cannot guarantee that STPCLK# signal
1351 gets asserted in time to freeze execution properly. */
1352 unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
1353 }
1354}
1355
1356/**
1357 * acpi_idle_enter_c1 - enters an ACPI C1 state-type
1358 * @dev: the target CPU
1359 * @state: the state data
1360 *
1361 * This is equivalent to the HALT instruction.
1362 */
1363static int acpi_idle_enter_c1(struct cpuidle_device *dev,
1364 struct cpuidle_state *state)
1365{
1366 struct acpi_processor *pr;
1367 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
1368 pr = processors[smp_processor_id()];
1369
1370 if (unlikely(!pr))
1371 return 0;
1372
1373 if (pr->flags.bm_check)
1374 acpi_idle_update_bm_rld(pr, cx);
1375
1376 current_thread_info()->status &= ~TS_POLLING;
1377 /*
1378 * TS_POLLING-cleared state must be visible before we test
1379 * NEED_RESCHED:
1380 */
1381 smp_mb();
1382 if (!need_resched())
1383 safe_halt();
1384 current_thread_info()->status |= TS_POLLING;
1385
1386 cx->usage++;
1387
1388 return 0;
1389}
1390
1391/**
1392 * acpi_idle_enter_simple - enters an ACPI state without BM handling
1393 * @dev: the target CPU
1394 * @state: the state data
1395 */
1396static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1397 struct cpuidle_state *state)
1398{
1399 struct acpi_processor *pr;
1400 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
1401 u32 t1, t2;
1402 pr = processors[smp_processor_id()];
1403
1404 if (unlikely(!pr))
1405 return 0;
1406
1407 if (acpi_idle_suspend)
1408 return(acpi_idle_enter_c1(dev, state));
1409
1410 if (pr->flags.bm_check)
1411 acpi_idle_update_bm_rld(pr, cx);
1412
1413 local_irq_disable();
1414 current_thread_info()->status &= ~TS_POLLING;
1415 /*
1416 * TS_POLLING-cleared state must be visible before we test
1417 * NEED_RESCHED:
1418 */
1419 smp_mb();
1420
1421 if (unlikely(need_resched())) {
1422 current_thread_info()->status |= TS_POLLING;
1423 local_irq_enable();
1424 return 0;
1425 }
1426
1427 if (cx->type == ACPI_STATE_C3)
1428 ACPI_FLUSH_CPU_CACHE();
1429
1430 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1431 acpi_state_timer_broadcast(pr, cx, 1);
1432 acpi_idle_do_entry(cx);
1433 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1434
1435#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1436 /* TSC could halt in idle, so notify users */
1437 mark_tsc_unstable("TSC halts in idle");;
1438#endif
1439
1440 local_irq_enable();
1441 current_thread_info()->status |= TS_POLLING;
1442
1443 cx->usage++;
1444
1445 acpi_state_timer_broadcast(pr, cx, 0);
1446 cx->time += ticks_elapsed(t1, t2);
1447 return ticks_elapsed_in_us(t1, t2);
1448}
1449
1450static int c3_cpu_count;
1451static DEFINE_SPINLOCK(c3_lock);
1452
1453/**
1454 * acpi_idle_enter_bm - enters C3 with proper BM handling
1455 * @dev: the target CPU
1456 * @state: the state data
1457 *
1458 * If BM is detected, the deepest non-C3 idle state is entered instead.
1459 */
1460static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1461 struct cpuidle_state *state)
1462{
1463 struct acpi_processor *pr;
1464 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
1465 u32 t1, t2;
1466 pr = processors[smp_processor_id()];
1467
1468 if (unlikely(!pr))
1469 return 0;
1470
1471 if (acpi_idle_suspend)
1472 return(acpi_idle_enter_c1(dev, state));
1473
1474 local_irq_disable();
1475 current_thread_info()->status &= ~TS_POLLING;
1476 /*
1477 * TS_POLLING-cleared state must be visible before we test
1478 * NEED_RESCHED:
1479 */
1480 smp_mb();
1481
1482 if (unlikely(need_resched())) {
1483 current_thread_info()->status |= TS_POLLING;
1484 local_irq_enable();
1485 return 0;
1486 }
1487
1488 /*
1489 * Must be done before busmaster disable as we might need to
1490 * access HPET !
1491 */
1492 acpi_state_timer_broadcast(pr, cx, 1);
1493
1494 if (acpi_idle_bm_check()) {
1495 cx = pr->power.bm_state;
1496
1497 acpi_idle_update_bm_rld(pr, cx);
1498
1499 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1500 acpi_idle_do_entry(cx);
1501 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1502 } else {
1503 acpi_idle_update_bm_rld(pr, cx);
1504
1505 spin_lock(&c3_lock);
1506 c3_cpu_count++;
1507 /* Disable bus master arbitration when all CPUs are in C3 */
1508 if (c3_cpu_count == num_online_cpus())
1509 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
1510 spin_unlock(&c3_lock);
1511
1512 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1513 acpi_idle_do_entry(cx);
1514 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1515
1516 spin_lock(&c3_lock);
1517 /* Re-enable bus master arbitration */
1518 if (c3_cpu_count == num_online_cpus())
1519 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
1520 c3_cpu_count--;
1521 spin_unlock(&c3_lock);
1522 }
1523
1524#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1525 /* TSC could halt in idle, so notify users */
1526 mark_tsc_unstable("TSC halts in idle");
1527#endif
1528
1529 local_irq_enable();
1530 current_thread_info()->status |= TS_POLLING;
1531
1532 cx->usage++;
1533
1534 acpi_state_timer_broadcast(pr, cx, 0);
1535 cx->time += ticks_elapsed(t1, t2);
1536 return ticks_elapsed_in_us(t1, t2);
1537}
1538
1539struct cpuidle_driver acpi_idle_driver = {
1540 .name = "acpi_idle",
1541 .owner = THIS_MODULE,
1542};
1543
1544/**
1545 * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
1546 * @pr: the ACPI processor
1547 */
1548static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1549{
1550 int i, count = 0;
1551 struct acpi_processor_cx *cx;
1552 struct cpuidle_state *state;
1553 struct cpuidle_device *dev = &pr->power.dev;
1554
1555 if (!pr->flags.power_setup_done)
1556 return -EINVAL;
1557
1558 if (pr->flags.power == 0) {
1559 return -EINVAL;
1560 }
1561
1562 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
1563 cx = &pr->power.states[i];
1564 state = &dev->states[count];
1565
1566 if (!cx->valid)
1567 continue;
1568
1569#ifdef CONFIG_HOTPLUG_CPU
1570 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
1571 !pr->flags.has_cst &&
1572 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
1573 continue;
1252#endif 1574#endif
1575 cpuidle_set_statedata(state, cx);
1576
1577 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
1578 state->exit_latency = cx->latency;
1579 state->target_residency = cx->latency * 6;
1580 state->power_usage = cx->power;
1581
1582 state->flags = 0;
1583 switch (cx->type) {
1584 case ACPI_STATE_C1:
1585 state->flags |= CPUIDLE_FLAG_SHALLOW;
1586 state->enter = acpi_idle_enter_c1;
1587 break;
1588
1589 case ACPI_STATE_C2:
1590 state->flags |= CPUIDLE_FLAG_BALANCED;
1591 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1592 state->enter = acpi_idle_enter_simple;
1593 break;
1594
1595 case ACPI_STATE_C3:
1596 state->flags |= CPUIDLE_FLAG_DEEP;
1597 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1598 state->flags |= CPUIDLE_FLAG_CHECK_BM;
1599 state->enter = pr->flags.bm_check ?
1600 acpi_idle_enter_bm :
1601 acpi_idle_enter_simple;
1602 break;
1603 }
1604
1605 count++;
1606 }
1607
1608 dev->state_count = count;
1609
1610 if (!count)
1611 return -EINVAL;
1612
1613 /* find the deepest state that can handle active BM */
1614 if (pr->flags.bm_check) {
1615 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
1616 if (pr->power.states[i].type == ACPI_STATE_C3)
1617 break;
1618 pr->power.bm_state = &pr->power.states[i-1];
1619 }
1620
1621 return 0;
1622}
1623
1624int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1625{
1626 int ret;
1627
1628 if (!pr)
1629 return -EINVAL;
1630
1631 if (nocst) {
1632 return -ENODEV;
1633 }
1634
1635 if (!pr->flags.power_setup_done)
1636 return -ENODEV;
1637
1638 cpuidle_pause_and_lock();
1639 cpuidle_disable_device(&pr->power.dev);
1640 acpi_processor_get_power_info(pr);
1641 acpi_processor_setup_cpuidle(pr);
1642 ret = cpuidle_enable_device(&pr->power.dev);
1643 cpuidle_resume_and_unlock();
1644
1645 return ret;
1646}
1647
1648#endif /* CONFIG_CPU_IDLE */
1253 1649
1254int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, 1650int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1255 struct acpi_device *device) 1651 struct acpi_device *device)
@@ -1267,7 +1663,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1267 "ACPI: processor limited to max C-state %d\n", 1663 "ACPI: processor limited to max C-state %d\n",
1268 max_cstate); 1664 max_cstate);
1269 first_run++; 1665 first_run++;
1270#ifdef CONFIG_SMP 1666#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP)
1271 register_latency_notifier(&acpi_processor_latency_notifier); 1667 register_latency_notifier(&acpi_processor_latency_notifier);
1272#endif 1668#endif
1273 } 1669 }
@@ -1285,6 +1681,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1285 } 1681 }
1286 1682
1287 acpi_processor_get_power_info(pr); 1683 acpi_processor_get_power_info(pr);
1684 pr->flags.power_setup_done = 1;
1288 1685
1289 /* 1686 /*
1290 * Install the idle handler if processor power management is supported. 1687 * Install the idle handler if processor power management is supported.
@@ -1292,6 +1689,13 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1292 * platforms that only support C1. 1689 * platforms that only support C1.
1293 */ 1690 */
1294 if ((pr->flags.power) && (!boot_option_idle_override)) { 1691 if ((pr->flags.power) && (!boot_option_idle_override)) {
1692#ifdef CONFIG_CPU_IDLE
1693 acpi_processor_setup_cpuidle(pr);
1694 pr->power.dev.cpu = pr->id;
1695 if (cpuidle_register_device(&pr->power.dev))
1696 return -EIO;
1697#endif
1698
1295 printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); 1699 printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
1296 for (i = 1; i <= pr->power.count; i++) 1700 for (i = 1; i <= pr->power.count; i++)
1297 if (pr->power.states[i].valid) 1701 if (pr->power.states[i].valid)
@@ -1299,10 +1703,12 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1299 pr->power.states[i].type); 1703 pr->power.states[i].type);
1300 printk(")\n"); 1704 printk(")\n");
1301 1705
1706#ifndef CONFIG_CPU_IDLE
1302 if (pr->id == 0) { 1707 if (pr->id == 0) {
1303 pm_idle_save = pm_idle; 1708 pm_idle_save = pm_idle;
1304 pm_idle = acpi_processor_idle; 1709 pm_idle = acpi_processor_idle;
1305 } 1710 }
1711#endif
1306 } 1712 }
1307 1713
1308 /* 'power' [R] */ 1714 /* 'power' [R] */
@@ -1316,21 +1722,24 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1316 entry->owner = THIS_MODULE; 1722 entry->owner = THIS_MODULE;
1317 } 1723 }
1318 1724
1319 pr->flags.power_setup_done = 1;
1320
1321 return 0; 1725 return 0;
1322} 1726}
1323 1727
1324int acpi_processor_power_exit(struct acpi_processor *pr, 1728int acpi_processor_power_exit(struct acpi_processor *pr,
1325 struct acpi_device *device) 1729 struct acpi_device *device)
1326{ 1730{
1327 1731#ifdef CONFIG_CPU_IDLE
1732 if ((pr->flags.power) && (!boot_option_idle_override))
1733 cpuidle_unregister_device(&pr->power.dev);
1734#endif
1328 pr->flags.power_setup_done = 0; 1735 pr->flags.power_setup_done = 0;
1329 1736
1330 if (acpi_device_dir(device)) 1737 if (acpi_device_dir(device))
1331 remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, 1738 remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
1332 acpi_device_dir(device)); 1739 acpi_device_dir(device));
1333 1740
1741#ifndef CONFIG_CPU_IDLE
1742
1334 /* Unregister the idle handler when processor #0 is removed. */ 1743 /* Unregister the idle handler when processor #0 is removed. */
1335 if (pr->id == 0) { 1744 if (pr->id == 0) {
1336 pm_idle = pm_idle_save; 1745 pm_idle = pm_idle_save;
@@ -1345,6 +1754,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1345 unregister_latency_notifier(&acpi_processor_latency_notifier); 1754 unregister_latency_notifier(&acpi_processor_latency_notifier);
1346#endif 1755#endif
1347 } 1756 }
1757#endif
1348 1758
1349 return 0; 1759 return 0;
1350} 1760}
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index a578986e3214..90fd09c65f95 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $) 2 * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
3 * 3 *
4 * Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
5 * Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
4 * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu> 6 * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
5 * 7 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -26,15 +28,22 @@
26#include <linux/module.h> 28#include <linux/module.h>
27#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
28#include <linux/kernel.h> 30#include <linux/kernel.h>
31
32#ifdef CONFIG_ACPI_PROCFS
29#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
30#include <linux/seq_file.h> 34#include <linux/seq_file.h>
31#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#endif
37
32#include <linux/acpi.h> 38#include <linux/acpi.h>
33#include <linux/timer.h> 39#include <linux/timer.h>
34#include <linux/jiffies.h> 40#include <linux/jiffies.h>
35#include <linux/delay.h> 41#include <linux/delay.h>
36 42
37#define ACPI_SBS_COMPONENT 0x00080000 43#include <linux/power_supply.h>
44
45#include "sbshc.h"
46
38#define ACPI_SBS_CLASS "sbs" 47#define ACPI_SBS_CLASS "sbs"
39#define ACPI_AC_CLASS "ac_adapter" 48#define ACPI_AC_CLASS "ac_adapter"
40#define ACPI_BATTERY_CLASS "battery" 49#define ACPI_BATTERY_CLASS "battery"
@@ -44,836 +53,436 @@
44#define ACPI_SBS_FILE_ALARM "alarm" 53#define ACPI_SBS_FILE_ALARM "alarm"
45#define ACPI_BATTERY_DIR_NAME "BAT%i" 54#define ACPI_BATTERY_DIR_NAME "BAT%i"
46#define ACPI_AC_DIR_NAME "AC0" 55#define ACPI_AC_DIR_NAME "AC0"
47#define ACPI_SBC_SMBUS_ADDR 0x9
48#define ACPI_SBSM_SMBUS_ADDR 0xa
49#define ACPI_SB_SMBUS_ADDR 0xb
50#define ACPI_SBS_AC_NOTIFY_STATUS 0x80
51#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
52#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
53 56
54#define _COMPONENT ACPI_SBS_COMPONENT 57enum acpi_sbs_device_addr {
58 ACPI_SBS_CHARGER = 0x9,
59 ACPI_SBS_MANAGER = 0xa,
60 ACPI_SBS_BATTERY = 0xb,
61};
55 62
56ACPI_MODULE_NAME("sbs"); 63#define ACPI_SBS_NOTIFY_STATUS 0x80
64#define ACPI_SBS_NOTIFY_INFO 0x81
57 65
58MODULE_AUTHOR("Rich Townsend"); 66MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
59MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); 67MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
60MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
61 69
62#define xmsleep(t) msleep(t) 70static unsigned int cache_time = 1000;
63 71module_param(cache_time, uint, 0644);
64#define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */ 72MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
65
66#define ACPI_EC_SMB_STS 0x01 /* status */
67#define ACPI_EC_SMB_ADDR 0x02 /* address */
68#define ACPI_EC_SMB_CMD 0x03 /* command */
69#define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */
70#define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */
71
72#define ACPI_EC_SMB_STS_DONE 0x80
73#define ACPI_EC_SMB_STS_STATUS 0x1f
74
75#define ACPI_EC_SMB_PRTCL_WRITE 0x00
76#define ACPI_EC_SMB_PRTCL_READ 0x01
77#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08
78#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a
79
80#define ACPI_EC_SMB_TRANSACTION_SLEEP 1
81#define ACPI_EC_SMB_ACCESS_SLEEP1 1
82#define ACPI_EC_SMB_ACCESS_SLEEP2 10
83
84#define DEF_CAPACITY_UNIT 3
85#define MAH_CAPACITY_UNIT 1
86#define MWH_CAPACITY_UNIT 2
87#define CAPACITY_UNIT DEF_CAPACITY_UNIT
88
89#define REQUEST_UPDATE_MODE 1
90#define QUEUE_UPDATE_MODE 2
91
92#define DATA_TYPE_COMMON 0
93#define DATA_TYPE_INFO 1
94#define DATA_TYPE_STATE 2
95#define DATA_TYPE_ALARM 3
96#define DATA_TYPE_AC_STATE 4
97 73
98extern struct proc_dir_entry *acpi_lock_ac_dir(void); 74extern struct proc_dir_entry *acpi_lock_ac_dir(void);
99extern struct proc_dir_entry *acpi_lock_battery_dir(void); 75extern struct proc_dir_entry *acpi_lock_battery_dir(void);
100extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); 76extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
101extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 77extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
102 78
103#define MAX_SBS_BAT 4 79#define MAX_SBS_BAT 4
104#define ACPI_SBS_BLOCK_MAX 32 80#define ACPI_SBS_BLOCK_MAX 32
105 81
106#define ACPI_SBS_SMBUS_READ 1
107#define ACPI_SBS_SMBUS_WRITE 2
108
109#define ACPI_SBS_WORD_DATA 1
110#define ACPI_SBS_BLOCK_DATA 2
111
112#define UPDATE_DELAY 10
113
114/* 0 - every time, > 0 - by update_time */
115static unsigned int update_time = 120;
116
117static unsigned int capacity_mode = CAPACITY_UNIT;
118
119module_param(update_time, uint, 0644);
120module_param(capacity_mode, uint, 0444);
121
122static int acpi_sbs_add(struct acpi_device *device);
123static int acpi_sbs_remove(struct acpi_device *device, int type);
124static int acpi_sbs_resume(struct acpi_device *device);
125
126static const struct acpi_device_id sbs_device_ids[] = { 82static const struct acpi_device_id sbs_device_ids[] = {
127 {"ACPI0001", 0}, 83 {"ACPI0002", 0},
128 {"ACPI0005", 0},
129 {"", 0}, 84 {"", 0},
130}; 85};
131MODULE_DEVICE_TABLE(acpi, sbs_device_ids); 86MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
132 87
133static struct acpi_driver acpi_sbs_driver = {
134 .name = "sbs",
135 .class = ACPI_SBS_CLASS,
136 .ids = sbs_device_ids,
137 .ops = {
138 .add = acpi_sbs_add,
139 .remove = acpi_sbs_remove,
140 .resume = acpi_sbs_resume,
141 },
142};
143
144struct acpi_ac {
145 int ac_present;
146};
147
148struct acpi_battery_info {
149 int capacity_mode;
150 s16 full_charge_capacity;
151 s16 design_capacity;
152 s16 design_voltage;
153 int vscale;
154 int ipscale;
155 s16 serial_number;
156 char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
157 char device_name[ACPI_SBS_BLOCK_MAX + 3];
158 char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
159};
160
161struct acpi_battery_state {
162 s16 voltage;
163 s16 amperage;
164 s16 remaining_capacity;
165 s16 battery_state;
166};
167
168struct acpi_battery_alarm {
169 s16 remaining_capacity;
170};
171
172struct acpi_battery { 88struct acpi_battery {
173 int alive; 89 struct power_supply bat;
174 int id;
175 int init_state;
176 int battery_present;
177 struct acpi_sbs *sbs; 90 struct acpi_sbs *sbs;
178 struct acpi_battery_info info; 91#ifdef CONFIG_ACPI_PROCFS
179 struct acpi_battery_state state; 92 struct proc_dir_entry *proc_entry;
180 struct acpi_battery_alarm alarm; 93#endif
181 struct proc_dir_entry *battery_entry; 94 unsigned long update_time;
95 char name[8];
96 char manufacturer_name[ACPI_SBS_BLOCK_MAX];
97 char device_name[ACPI_SBS_BLOCK_MAX];
98 char device_chemistry[ACPI_SBS_BLOCK_MAX];
99 u16 alarm_capacity;
100 u16 full_charge_capacity;
101 u16 design_capacity;
102 u16 design_voltage;
103 u16 serial_number;
104 u16 cycle_count;
105 u16 temp_now;
106 u16 voltage_now;
107 s16 current_now;
108 s16 current_avg;
109 u16 capacity_now;
110 u16 state_of_charge;
111 u16 state;
112 u16 mode;
113 u16 spec;
114 u8 id;
115 u8 present:1;
182}; 116};
183 117
118#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
119
184struct acpi_sbs { 120struct acpi_sbs {
185 int base; 121 struct power_supply charger;
186 struct acpi_device *device; 122 struct acpi_device *device;
187 struct mutex mutex; 123 struct acpi_smb_hc *hc;
188 int sbsm_present; 124 struct mutex lock;
189 int sbsm_batteries_supported; 125#ifdef CONFIG_ACPI_PROCFS
190 struct proc_dir_entry *ac_entry; 126 struct proc_dir_entry *charger_entry;
191 struct acpi_ac ac; 127#endif
192 struct acpi_battery battery[MAX_SBS_BAT]; 128 struct acpi_battery battery[MAX_SBS_BAT];
193 int zombie; 129 u8 batteries_supported:4;
194 struct timer_list update_timer; 130 u8 manager_present:1;
195 int run_cnt; 131 u8 charger_present:1;
196 int update_proc_flg;
197}; 132};
198 133
199static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type); 134#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
200static void acpi_sbs_update_time(void *data);
201 135
202union sbs_rw_data { 136static inline int battery_scale(int log)
203 u16 word;
204 u8 block[ACPI_SBS_BLOCK_MAX + 2];
205};
206
207static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
208 char read_write, u8 command, int size,
209 union sbs_rw_data *data);
210
211/* --------------------------------------------------------------------------
212 SMBus Communication
213 -------------------------------------------------------------------------- */
214
215static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
216{ 137{
217 u8 val; 138 int scale = 1;
218 int err; 139 while (log--)
219 140 scale *= 10;
220 err = ec_read(sbs->base + address, &val); 141 return scale;
221 if (!err) {
222 *data = val;
223 }
224 xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
225 return (err);
226}
227
228static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
229{
230 int err;
231
232 err = ec_write(sbs->base + address, data);
233 return (err);
234}
235
236static int
237acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
238 char read_write, u8 command, int size,
239 union sbs_rw_data *data)
240{
241 unsigned char protocol, len = 0, temp[2] = { 0, 0 };
242 int i;
243
244 if (read_write == ACPI_SBS_SMBUS_READ) {
245 protocol = ACPI_EC_SMB_PRTCL_READ;
246 } else {
247 protocol = ACPI_EC_SMB_PRTCL_WRITE;
248 }
249
250 switch (size) {
251
252 case ACPI_SBS_WORD_DATA:
253 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
254 if (read_write == ACPI_SBS_SMBUS_WRITE) {
255 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
256 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
257 data->word >> 8);
258 }
259 protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
260 break;
261 case ACPI_SBS_BLOCK_DATA:
262 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
263 if (read_write == ACPI_SBS_SMBUS_WRITE) {
264 len = min_t(u8, data->block[0], 32);
265 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
266 for (i = 0; i < len; i++)
267 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
268 data->block[i + 1]);
269 }
270 protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
271 break;
272 default:
273 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
274 "unsupported transaction %d", size));
275 return (-1);
276 }
277
278 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
279 acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
280
281 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
282
283 if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
284 xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
285 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
286 }
287 if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
288 xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
289 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
290 }
291 if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
292 || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
293 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
294 "transaction %d error", size));
295 return (-1);
296 }
297
298 if (read_write == ACPI_SBS_SMBUS_WRITE) {
299 return (0);
300 }
301
302 switch (size) {
303
304 case ACPI_SBS_WORD_DATA:
305 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
306 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
307 data->word = (temp[1] << 8) | temp[0];
308 break;
309
310 case ACPI_SBS_BLOCK_DATA:
311 len = 0;
312 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
313 len = min_t(u8, len, 32);
314 for (i = 0; i < len; i++)
315 acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
316 data->block + i + 1);
317 data->block[0] = len;
318 break;
319 default:
320 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
321 "unsupported transaction %d", size));
322 return (-1);
323 }
324
325 return (0);
326} 142}
327 143
328static int 144static inline int acpi_battery_vscale(struct acpi_battery *battery)
329acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
330{ 145{
331 union sbs_rw_data data; 146 return battery_scale((battery->spec & 0x0f00) >> 8);
332 int result = 0;
333
334 result = acpi_ec_sbs_access(sbs, addr,
335 ACPI_SBS_SMBUS_READ, func,
336 ACPI_SBS_WORD_DATA, &data);
337 if (result) {
338 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
339 "acpi_ec_sbs_access() failed"));
340 } else {
341 *word = data.word;
342 }
343
344 return result;
345} 147}
346 148
347static int 149static inline int acpi_battery_ipscale(struct acpi_battery *battery)
348acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
349{ 150{
350 union sbs_rw_data data; 151 return battery_scale((battery->spec & 0xf000) >> 12);
351 int result = 0;
352
353 result = acpi_ec_sbs_access(sbs, addr,
354 ACPI_SBS_SMBUS_READ, func,
355 ACPI_SBS_BLOCK_DATA, &data);
356 if (result) {
357 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
358 "acpi_ec_sbs_access() failed"));
359 } else {
360 strncpy(str, (const char *)data.block + 1, data.block[0]);
361 str[data.block[0]] = 0;
362 }
363
364 return result;
365} 152}
366 153
367static int 154static inline int acpi_battery_mode(struct acpi_battery *battery)
368acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
369{ 155{
370 union sbs_rw_data data; 156 return (battery->mode & 0x8000);
371 int result = 0;
372
373 data.word = word;
374
375 result = acpi_ec_sbs_access(sbs, addr,
376 ACPI_SBS_SMBUS_WRITE, func,
377 ACPI_SBS_WORD_DATA, &data);
378 if (result) {
379 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
380 "acpi_ec_sbs_access() failed"));
381 }
382
383 return result;
384} 157}
385 158
386static int sbs_zombie(struct acpi_sbs *sbs) 159static inline int acpi_battery_scale(struct acpi_battery *battery)
387{ 160{
388 return (sbs->zombie); 161 return (acpi_battery_mode(battery) ? 10 : 1) *
162 acpi_battery_ipscale(battery);
389} 163}
390 164
391static int sbs_mutex_lock(struct acpi_sbs *sbs) 165static int sbs_get_ac_property(struct power_supply *psy,
166 enum power_supply_property psp,
167 union power_supply_propval *val)
392{ 168{
393 if (sbs_zombie(sbs)) { 169 struct acpi_sbs *sbs = to_acpi_sbs(psy);
394 return -ENODEV; 170 switch (psp) {
171 case POWER_SUPPLY_PROP_ONLINE:
172 val->intval = sbs->charger_present;
173 break;
174 default:
175 return -EINVAL;
395 } 176 }
396 mutex_lock(&sbs->mutex);
397 return 0; 177 return 0;
398} 178}
399 179
400static void sbs_mutex_unlock(struct acpi_sbs *sbs) 180static int acpi_battery_technology(struct acpi_battery *battery)
401{ 181{
402 mutex_unlock(&sbs->mutex); 182 if (!strcasecmp("NiCd", battery->device_chemistry))
183 return POWER_SUPPLY_TECHNOLOGY_NiCd;
184 if (!strcasecmp("NiMH", battery->device_chemistry))
185 return POWER_SUPPLY_TECHNOLOGY_NiMH;
186 if (!strcasecmp("LION", battery->device_chemistry))
187 return POWER_SUPPLY_TECHNOLOGY_LION;
188 if (!strcasecmp("LiP", battery->device_chemistry))
189 return POWER_SUPPLY_TECHNOLOGY_LIPO;
190 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
403} 191}
404 192
405/* -------------------------------------------------------------------------- 193static int acpi_sbs_battery_get_property(struct power_supply *psy,
406 Smart Battery System Management 194 enum power_supply_property psp,
407 -------------------------------------------------------------------------- */ 195 union power_supply_propval *val)
408
409static int acpi_check_update_proc(struct acpi_sbs *sbs)
410{ 196{
411 acpi_status status = AE_OK; 197 struct acpi_battery *battery = to_acpi_battery(psy);
412 198
413 if (update_time == 0) { 199 if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
414 sbs->update_proc_flg = 0; 200 return -ENODEV;
415 return 0; 201 switch (psp) {
416 } 202 case POWER_SUPPLY_PROP_STATUS:
417 if (sbs->update_proc_flg == 0) { 203 if (battery->current_now < 0)
418 status = acpi_os_execute(OSL_GPE_HANDLER, 204 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
419 acpi_sbs_update_time, sbs); 205 else if (battery->current_now > 0)
420 if (status != AE_OK) { 206 val->intval = POWER_SUPPLY_STATUS_CHARGING;
421 ACPI_EXCEPTION((AE_INFO, status, 207 else
422 "acpi_os_execute() failed")); 208 val->intval = POWER_SUPPLY_STATUS_FULL;
423 return 1; 209 break;
424 } 210 case POWER_SUPPLY_PROP_PRESENT:
425 sbs->update_proc_flg = 1; 211 val->intval = battery->present;
212 break;
213 case POWER_SUPPLY_PROP_TECHNOLOGY:
214 val->intval = acpi_battery_technology(battery);
215 break;
216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
217 val->intval = battery->design_voltage *
218 acpi_battery_vscale(battery) * 1000;
219 break;
220 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
221 val->intval = battery->voltage_now *
222 acpi_battery_vscale(battery) * 1000;
223 break;
224 case POWER_SUPPLY_PROP_CURRENT_NOW:
225 val->intval = abs(battery->current_now) *
226 acpi_battery_ipscale(battery) * 1000;
227 break;
228 case POWER_SUPPLY_PROP_CURRENT_AVG:
229 val->intval = abs(battery->current_avg) *
230 acpi_battery_ipscale(battery) * 1000;
231 break;
232 case POWER_SUPPLY_PROP_CAPACITY:
233 val->intval = battery->state_of_charge;
234 break;
235 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
236 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
237 val->intval = battery->design_capacity *
238 acpi_battery_scale(battery) * 1000;
239 break;
240 case POWER_SUPPLY_PROP_CHARGE_FULL:
241 case POWER_SUPPLY_PROP_ENERGY_FULL:
242 val->intval = battery->full_charge_capacity *
243 acpi_battery_scale(battery) * 1000;
244 break;
245 case POWER_SUPPLY_PROP_CHARGE_NOW:
246 case POWER_SUPPLY_PROP_ENERGY_NOW:
247 val->intval = battery->capacity_now *
248 acpi_battery_scale(battery) * 1000;
249 break;
250 case POWER_SUPPLY_PROP_TEMP:
251 val->intval = battery->temp_now - 2730; // dK -> dC
252 break;
253 case POWER_SUPPLY_PROP_MODEL_NAME:
254 val->strval = battery->device_name;
255 break;
256 case POWER_SUPPLY_PROP_MANUFACTURER:
257 val->strval = battery->manufacturer_name;
258 break;
259 default:
260 return -EINVAL;
426 } 261 }
427 return 0; 262 return 0;
428} 263}
429 264
430static int acpi_sbs_generate_event(struct acpi_device *device, 265static enum power_supply_property sbs_ac_props[] = {
431 int event, int state, char *bid, char *class) 266 POWER_SUPPLY_PROP_ONLINE,
432{ 267};
433 char bid_saved[5];
434 char class_saved[20];
435 int result = 0;
436
437 strcpy(bid_saved, acpi_device_bid(device));
438 strcpy(class_saved, acpi_device_class(device));
439
440 strcpy(acpi_device_bid(device), bid);
441 strcpy(acpi_device_class(device), class);
442
443 result = acpi_bus_generate_proc_event(device, event, state);
444
445 strcpy(acpi_device_bid(device), bid_saved);
446 strcpy(acpi_device_class(device), class_saved);
447
448 acpi_bus_generate_netlink_event(class, bid, event, state);
449 return result;
450}
451
452static int acpi_battery_get_present(struct acpi_battery *battery)
453{
454 s16 state;
455 int result = 0;
456 int is_present = 0;
457
458 result = acpi_sbs_read_word(battery->sbs,
459 ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
460 if (result) {
461 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
462 "acpi_sbs_read_word() failed"));
463 }
464 if (!result) {
465 is_present = (state & 0x000f) & (1 << battery->id);
466 }
467 battery->battery_present = is_present;
468
469 return result;
470}
471 268
472static int acpi_battery_select(struct acpi_battery *battery) 269static enum power_supply_property sbs_charge_battery_props[] = {
473{ 270 POWER_SUPPLY_PROP_STATUS,
474 struct acpi_sbs *sbs = battery->sbs; 271 POWER_SUPPLY_PROP_PRESENT,
475 int result = 0; 272 POWER_SUPPLY_PROP_TECHNOLOGY,
476 s16 state; 273 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
477 int foo; 274 POWER_SUPPLY_PROP_VOLTAGE_NOW,
275 POWER_SUPPLY_PROP_CURRENT_NOW,
276 POWER_SUPPLY_PROP_CURRENT_AVG,
277 POWER_SUPPLY_PROP_CAPACITY,
278 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
279 POWER_SUPPLY_PROP_CHARGE_FULL,
280 POWER_SUPPLY_PROP_CHARGE_NOW,
281 POWER_SUPPLY_PROP_TEMP,
282 POWER_SUPPLY_PROP_MODEL_NAME,
283 POWER_SUPPLY_PROP_MANUFACTURER,
284};
478 285
479 if (sbs->sbsm_present) { 286static enum power_supply_property sbs_energy_battery_props[] = {
287 POWER_SUPPLY_PROP_STATUS,
288 POWER_SUPPLY_PROP_PRESENT,
289 POWER_SUPPLY_PROP_TECHNOLOGY,
290 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
291 POWER_SUPPLY_PROP_VOLTAGE_NOW,
292 POWER_SUPPLY_PROP_CURRENT_NOW,
293 POWER_SUPPLY_PROP_CURRENT_AVG,
294 POWER_SUPPLY_PROP_CAPACITY,
295 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
296 POWER_SUPPLY_PROP_ENERGY_FULL,
297 POWER_SUPPLY_PROP_ENERGY_NOW,
298 POWER_SUPPLY_PROP_TEMP,
299 POWER_SUPPLY_PROP_MODEL_NAME,
300 POWER_SUPPLY_PROP_MANUFACTURER,
301};
480 302
481 /* Take special care not to knobble other nibbles of 303/* --------------------------------------------------------------------------
482 * state (aka selector_state), since 304 Smart Battery System Management
483 * it causes charging to halt on SBSELs */ 305 -------------------------------------------------------------------------- */
484 306
485 result = 307struct acpi_battery_reader {
486 acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state); 308 u8 command; /* command for battery */
487 if (result) { 309 u8 mode; /* word or block? */
488 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 310 size_t offset; /* offset inside struct acpi_sbs_battery */
489 "acpi_sbs_read_word() failed")); 311};
490 goto end;
491 }
492 312
493 foo = (state & 0x0fff) | (1 << (battery->id + 12)); 313static struct acpi_battery_reader info_readers[] = {
494 result = 314 {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
495 acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo); 315 {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
496 if (result) { 316 {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
497 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 317 {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
498 "acpi_sbs_write_word() failed")); 318 {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
499 goto end; 319 {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
500 } 320 {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
501 } 321 {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
322 {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
323 {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
324 {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
325};
502 326
503 end: 327static struct acpi_battery_reader state_readers[] = {
504 return result; 328 {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
505} 329 {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
330 {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
331 {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
332 {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
333 {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
334 {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
335};
506 336
507static int acpi_sbsm_get_info(struct acpi_sbs *sbs) 337static int acpi_manager_get_info(struct acpi_sbs *sbs)
508{ 338{
509 int result = 0; 339 int result = 0;
510 s16 battery_system_info; 340 u16 battery_system_info;
511
512 result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
513 &battery_system_info);
514 if (result) {
515 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
516 "acpi_sbs_read_word() failed"));
517 goto end;
518 }
519 sbs->sbsm_present = 1;
520 sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
521
522 end:
523 341
342 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
343 0x04, (u8 *)&battery_system_info);
344 if (!result)
345 sbs->batteries_supported = battery_system_info & 0x000f;
524 return result; 346 return result;
525} 347}
526 348
527static int acpi_battery_get_info(struct acpi_battery *battery) 349static int acpi_battery_get_info(struct acpi_battery *battery)
528{ 350{
529 struct acpi_sbs *sbs = battery->sbs; 351 int i, result = 0;
530 int result = 0; 352
531 s16 battery_mode; 353 for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
532 s16 specification_info; 354 result = acpi_smbus_read(battery->sbs->hc,
533 355 info_readers[i].mode,
534 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, 356 ACPI_SBS_BATTERY,
535 &battery_mode); 357 info_readers[i].command,
536 if (result) { 358 (u8 *) battery +
537 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 359 info_readers[i].offset);
538 "acpi_sbs_read_word() failed")); 360 if (result)
539 goto end; 361 break;
540 }
541 battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
542
543 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
544 &battery->info.full_charge_capacity);
545 if (result) {
546 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
547 "acpi_sbs_read_word() failed"));
548 goto end;
549 }
550
551 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
552 &battery->info.design_capacity);
553
554 if (result) {
555 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
556 "acpi_sbs_read_word() failed"));
557 goto end;
558 }
559
560 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
561 &battery->info.design_voltage);
562 if (result) {
563 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
564 "acpi_sbs_read_word() failed"));
565 goto end;
566 } 362 }
567
568 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
569 &specification_info);
570 if (result) {
571 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
572 "acpi_sbs_read_word() failed"));
573 goto end;
574 }
575
576 switch ((specification_info & 0x0f00) >> 8) {
577 case 1:
578 battery->info.vscale = 10;
579 break;
580 case 2:
581 battery->info.vscale = 100;
582 break;
583 case 3:
584 battery->info.vscale = 1000;
585 break;
586 default:
587 battery->info.vscale = 1;
588 }
589
590 switch ((specification_info & 0xf000) >> 12) {
591 case 1:
592 battery->info.ipscale = 10;
593 break;
594 case 2:
595 battery->info.ipscale = 100;
596 break;
597 case 3:
598 battery->info.ipscale = 1000;
599 break;
600 default:
601 battery->info.ipscale = 1;
602 }
603
604 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
605 &battery->info.serial_number);
606 if (result) {
607 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
608 "acpi_sbs_read_word() failed"));
609 goto end;
610 }
611
612 result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
613 battery->info.manufacturer_name);
614 if (result) {
615 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
616 "acpi_sbs_read_str() failed"));
617 goto end;
618 }
619
620 result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
621 battery->info.device_name);
622 if (result) {
623 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
624 "acpi_sbs_read_str() failed"));
625 goto end;
626 }
627
628 result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
629 battery->info.device_chemistry);
630 if (result) {
631 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
632 "acpi_sbs_read_str() failed"));
633 goto end;
634 }
635
636 end:
637 return result; 363 return result;
638} 364}
639 365
640static int acpi_battery_get_state(struct acpi_battery *battery) 366static int acpi_battery_get_state(struct acpi_battery *battery)
641{ 367{
642 struct acpi_sbs *sbs = battery->sbs; 368 int i, result = 0;
643 int result = 0;
644 369
645 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09, 370 if (battery->update_time &&
646 &battery->state.voltage); 371 time_before(jiffies, battery->update_time +
647 if (result) { 372 msecs_to_jiffies(cache_time)))
648 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 373 return 0;
649 "acpi_sbs_read_word() failed")); 374 for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
650 goto end; 375 result = acpi_smbus_read(battery->sbs->hc,
651 } 376 state_readers[i].mode,
652 377 ACPI_SBS_BATTERY,
653 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a, 378 state_readers[i].command,
654 &battery->state.amperage); 379 (u8 *)battery +
655 if (result) { 380 state_readers[i].offset);
656 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 381 if (result)
657 "acpi_sbs_read_word() failed")); 382 goto end;
658 goto end;
659 }
660
661 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
662 &battery->state.remaining_capacity);
663 if (result) {
664 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
665 "acpi_sbs_read_word() failed"));
666 goto end;
667 }
668
669 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
670 &battery->state.battery_state);
671 if (result) {
672 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
673 "acpi_sbs_read_word() failed"));
674 goto end;
675 } 383 }
676
677 end: 384 end:
385 battery->update_time = jiffies;
678 return result; 386 return result;
679} 387}
680 388
681static int acpi_battery_get_alarm(struct acpi_battery *battery) 389static int acpi_battery_get_alarm(struct acpi_battery *battery)
682{ 390{
683 struct acpi_sbs *sbs = battery->sbs; 391 return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
684 int result = 0; 392 ACPI_SBS_BATTERY, 0x01,
685 393 (u8 *)&battery->alarm_capacity);
686 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
687 &battery->alarm.remaining_capacity);
688 if (result) {
689 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
690 "acpi_sbs_read_word() failed"));
691 goto end;
692 }
693
694 end:
695
696 return result;
697} 394}
698 395
699static int acpi_battery_set_alarm(struct acpi_battery *battery, 396static int acpi_battery_set_alarm(struct acpi_battery *battery)
700 unsigned long alarm)
701{ 397{
702 struct acpi_sbs *sbs = battery->sbs; 398 struct acpi_sbs *sbs = battery->sbs;
703 int result = 0; 399 u16 value, sel = 1 << (battery->id + 12);
704 s16 battery_mode;
705 int foo;
706 400
707 result = acpi_battery_select(battery); 401 int ret;
708 if (result) {
709 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
710 "acpi_battery_select() failed"));
711 goto end;
712 }
713 402
714 /* If necessary, enable the alarm */
715 403
716 if (alarm > 0) { 404 if (sbs->manager_present) {
717 result = 405 ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
718 acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, 406 0x01, (u8 *)&value);
719 &battery_mode); 407 if (ret)
720 if (result) {
721 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
722 "acpi_sbs_read_word() failed"));
723 goto end; 408 goto end;
724 } 409 if ((value & 0xf000) != sel) {
725 410 value &= 0x0fff;
726 result = 411 value |= sel;
727 acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, 412 ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
728 battery_mode & 0xbfff); 413 ACPI_SBS_MANAGER,
729 if (result) { 414 0x01, (u8 *)&value, 2);
730 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 415 if (ret)
731 "acpi_sbs_write_word() failed"));
732 goto end; 416 goto end;
733 } 417 }
734 } 418 }
735 419 ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
736 foo = alarm / (battery->info.capacity_mode ? 10 : 1); 420 0x01, (u8 *)&battery->alarm_capacity, 2);
737 result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
738 if (result) {
739 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
740 "acpi_sbs_write_word() failed"));
741 goto end;
742 }
743
744 end: 421 end:
745 422 return ret;
746 return result;
747} 423}
748 424
749static int acpi_battery_set_mode(struct acpi_battery *battery) 425static int acpi_ac_get_present(struct acpi_sbs *sbs)
750{ 426{
751 struct acpi_sbs *sbs = battery->sbs; 427 int result;
752 int result = 0; 428 u16 status;
753 s16 battery_mode;
754
755 if (capacity_mode == DEF_CAPACITY_UNIT) {
756 goto end;
757 }
758
759 result = acpi_sbs_read_word(sbs,
760 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
761 if (result) {
762 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
763 "acpi_sbs_read_word() failed"));
764 goto end;
765 }
766
767 if (capacity_mode == MAH_CAPACITY_UNIT) {
768 battery_mode &= 0x7fff;
769 } else {
770 battery_mode |= 0x8000;
771 }
772 result = acpi_sbs_write_word(sbs,
773 ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
774 if (result) {
775 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
776 "acpi_sbs_write_word() failed"));
777 goto end;
778 }
779
780 result = acpi_sbs_read_word(sbs,
781 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
782 if (result) {
783 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
784 "acpi_sbs_read_word() failed"));
785 goto end;
786 }
787 429
788 end: 430 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
431 0x13, (u8 *) & status);
432 if (!result)
433 sbs->charger_present = (status >> 15) & 0x1;
789 return result; 434 return result;
790} 435}
791 436
792static int acpi_battery_init(struct acpi_battery *battery) 437static ssize_t acpi_battery_alarm_show(struct device *dev,
438 struct device_attribute *attr,
439 char *buf)
793{ 440{
794 int result = 0; 441 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
795 442 acpi_battery_get_alarm(battery);
796 result = acpi_battery_select(battery); 443 return sprintf(buf, "%d\n", battery->alarm_capacity *
797 if (result) { 444 acpi_battery_scale(battery) * 1000);
798 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
799 "acpi_battery_select() failed"));
800 goto end;
801 }
802
803 result = acpi_battery_set_mode(battery);
804 if (result) {
805 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
806 "acpi_battery_set_mode() failed"));
807 goto end;
808 }
809
810 result = acpi_battery_get_info(battery);
811 if (result) {
812 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
813 "acpi_battery_get_info() failed"));
814 goto end;
815 }
816
817 result = acpi_battery_get_state(battery);
818 if (result) {
819 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
820 "acpi_battery_get_state() failed"));
821 goto end;
822 }
823
824 result = acpi_battery_get_alarm(battery);
825 if (result) {
826 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
827 "acpi_battery_get_alarm() failed"));
828 goto end;
829 }
830
831 end:
832 return result;
833} 445}
834 446
835static int acpi_ac_get_present(struct acpi_sbs *sbs) 447static ssize_t acpi_battery_alarm_store(struct device *dev,
448 struct device_attribute *attr,
449 const char *buf, size_t count)
836{ 450{
837 int result = 0; 451 unsigned long x;
838 s16 charger_status; 452 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
839 453 if (sscanf(buf, "%ld\n", &x) == 1)
840 result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13, 454 battery->alarm_capacity = x /
841 &charger_status); 455 (1000 * acpi_battery_scale(battery));
842 456 if (battery->present)
843 if (result) { 457 acpi_battery_set_alarm(battery);
844 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 458 return count;
845 "acpi_sbs_read_word() failed"));
846 goto end;
847 }
848
849 sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
850
851 end:
852
853 return result;
854} 459}
855 460
461static struct device_attribute alarm_attr = {
462 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
463 .show = acpi_battery_alarm_show,
464 .store = acpi_battery_alarm_store,
465};
466
856/* -------------------------------------------------------------------------- 467/* --------------------------------------------------------------------------
857 FS Interface (/proc/acpi) 468 FS Interface (/proc/acpi)
858 -------------------------------------------------------------------------- */ 469 -------------------------------------------------------------------------- */
859 470
471#ifdef CONFIG_ACPI_PROCFS
860/* Generic Routines */ 472/* Generic Routines */
861
862static int 473static int
863acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, 474acpi_sbs_add_fs(struct proc_dir_entry **dir,
864 struct proc_dir_entry *parent_dir, 475 struct proc_dir_entry *parent_dir,
865 char *dir_name, 476 char *dir_name,
866 struct file_operations *info_fops, 477 struct file_operations *info_fops,
867 struct file_operations *state_fops, 478 struct file_operations *state_fops,
868 struct file_operations *alarm_fops, void *data) 479 struct file_operations *alarm_fops, void *data)
869{ 480{
870 struct proc_dir_entry *entry = NULL; 481 struct proc_dir_entry *entry = NULL;
871 482
872 if (!*dir) { 483 if (!*dir) {
873 *dir = proc_mkdir(dir_name, parent_dir); 484 *dir = proc_mkdir(dir_name, parent_dir);
874 if (!*dir) { 485 if (!*dir) {
875 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
876 "proc_mkdir() failed"));
877 return -ENODEV; 486 return -ENODEV;
878 } 487 }
879 (*dir)->owner = THIS_MODULE; 488 (*dir)->owner = THIS_MODULE;
@@ -882,10 +491,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
882 /* 'info' [R] */ 491 /* 'info' [R] */
883 if (info_fops) { 492 if (info_fops) {
884 entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir); 493 entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
885 if (!entry) { 494 if (entry) {
886 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
887 "create_proc_entry() failed"));
888 } else {
889 entry->proc_fops = info_fops; 495 entry->proc_fops = info_fops;
890 entry->data = data; 496 entry->data = data;
891 entry->owner = THIS_MODULE; 497 entry->owner = THIS_MODULE;
@@ -895,10 +501,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
895 /* 'state' [R] */ 501 /* 'state' [R] */
896 if (state_fops) { 502 if (state_fops) {
897 entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir); 503 entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
898 if (!entry) { 504 if (entry) {
899 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
900 "create_proc_entry() failed"));
901 } else {
902 entry->proc_fops = state_fops; 505 entry->proc_fops = state_fops;
903 entry->data = data; 506 entry->data = data;
904 entry->owner = THIS_MODULE; 507 entry->owner = THIS_MODULE;
@@ -908,24 +511,19 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
908 /* 'alarm' [R/W] */ 511 /* 'alarm' [R/W] */
909 if (alarm_fops) { 512 if (alarm_fops) {
910 entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir); 513 entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
911 if (!entry) { 514 if (entry) {
912 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
913 "create_proc_entry() failed"));
914 } else {
915 entry->proc_fops = alarm_fops; 515 entry->proc_fops = alarm_fops;
916 entry->data = data; 516 entry->data = data;
917 entry->owner = THIS_MODULE; 517 entry->owner = THIS_MODULE;
918 } 518 }
919 } 519 }
920
921 return 0; 520 return 0;
922} 521}
923 522
924static void 523static void
925acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir, 524acpi_sbs_remove_fs(struct proc_dir_entry **dir,
926 struct proc_dir_entry *parent_dir) 525 struct proc_dir_entry *parent_dir)
927{ 526{
928
929 if (*dir) { 527 if (*dir) {
930 remove_proc_entry(ACPI_SBS_FILE_INFO, *dir); 528 remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
931 remove_proc_entry(ACPI_SBS_FILE_STATE, *dir); 529 remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -933,82 +531,52 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
933 remove_proc_entry((*dir)->name, parent_dir); 531 remove_proc_entry((*dir)->name, parent_dir);
934 *dir = NULL; 532 *dir = NULL;
935 } 533 }
936
937} 534}
938 535
939/* Smart Battery Interface */ 536/* Smart Battery Interface */
940
941static struct proc_dir_entry *acpi_battery_dir = NULL; 537static struct proc_dir_entry *acpi_battery_dir = NULL;
942 538
539static inline char *acpi_battery_units(struct acpi_battery *battery)
540{
541 return acpi_battery_mode(battery) ? " mWh" : " mAh";
542}
543
544
943static int acpi_battery_read_info(struct seq_file *seq, void *offset) 545static int acpi_battery_read_info(struct seq_file *seq, void *offset)
944{ 546{
945 struct acpi_battery *battery = seq->private; 547 struct acpi_battery *battery = seq->private;
946 struct acpi_sbs *sbs = battery->sbs; 548 struct acpi_sbs *sbs = battery->sbs;
947 int cscale;
948 int result = 0; 549 int result = 0;
949 550
950 if (sbs_mutex_lock(sbs)) { 551 mutex_lock(&sbs->lock);
951 return -ENODEV;
952 }
953
954 result = acpi_check_update_proc(sbs);
955 if (result)
956 goto end;
957
958 if (update_time == 0) {
959 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
960 if (result) {
961 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
962 "acpi_sbs_update_run() failed"));
963 }
964 }
965 552
966 if (battery->battery_present) { 553 seq_printf(seq, "present: %s\n",
967 seq_printf(seq, "present: yes\n"); 554 (battery->present) ? "yes" : "no");
968 } else { 555 if (!battery->present)
969 seq_printf(seq, "present: no\n");
970 goto end; 556 goto end;
971 }
972 557
973 if (battery->info.capacity_mode) {
974 cscale = battery->info.vscale * battery->info.ipscale;
975 } else {
976 cscale = battery->info.ipscale;
977 }
978 seq_printf(seq, "design capacity: %i%s\n", 558 seq_printf(seq, "design capacity: %i%s\n",
979 battery->info.design_capacity * cscale, 559 battery->design_capacity * acpi_battery_scale(battery),
980 battery->info.capacity_mode ? "0 mWh" : " mAh"); 560 acpi_battery_units(battery));
981
982 seq_printf(seq, "last full capacity: %i%s\n", 561 seq_printf(seq, "last full capacity: %i%s\n",
983 battery->info.full_charge_capacity * cscale, 562 battery->full_charge_capacity * acpi_battery_scale(battery),
984 battery->info.capacity_mode ? "0 mWh" : " mAh"); 563 acpi_battery_units(battery));
985
986 seq_printf(seq, "battery technology: rechargeable\n"); 564 seq_printf(seq, "battery technology: rechargeable\n");
987
988 seq_printf(seq, "design voltage: %i mV\n", 565 seq_printf(seq, "design voltage: %i mV\n",
989 battery->info.design_voltage * battery->info.vscale); 566 battery->design_voltage * acpi_battery_vscale(battery));
990
991 seq_printf(seq, "design capacity warning: unknown\n"); 567 seq_printf(seq, "design capacity warning: unknown\n");
992 seq_printf(seq, "design capacity low: unknown\n"); 568 seq_printf(seq, "design capacity low: unknown\n");
993 seq_printf(seq, "capacity granularity 1: unknown\n"); 569 seq_printf(seq, "capacity granularity 1: unknown\n");
994 seq_printf(seq, "capacity granularity 2: unknown\n"); 570 seq_printf(seq, "capacity granularity 2: unknown\n");
995 571 seq_printf(seq, "model number: %s\n", battery->device_name);
996 seq_printf(seq, "model number: %s\n",
997 battery->info.device_name);
998
999 seq_printf(seq, "serial number: %i\n", 572 seq_printf(seq, "serial number: %i\n",
1000 battery->info.serial_number); 573 battery->serial_number);
1001
1002 seq_printf(seq, "battery type: %s\n", 574 seq_printf(seq, "battery type: %s\n",
1003 battery->info.device_chemistry); 575 battery->device_chemistry);
1004
1005 seq_printf(seq, "OEM info: %s\n", 576 seq_printf(seq, "OEM info: %s\n",
1006 battery->info.manufacturer_name); 577 battery->manufacturer_name);
1007
1008 end: 578 end:
1009 579 mutex_unlock(&sbs->lock);
1010 sbs_mutex_unlock(sbs);
1011
1012 return result; 580 return result;
1013} 581}
1014 582
@@ -1022,73 +590,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1022 struct acpi_battery *battery = seq->private; 590 struct acpi_battery *battery = seq->private;
1023 struct acpi_sbs *sbs = battery->sbs; 591 struct acpi_sbs *sbs = battery->sbs;
1024 int result = 0; 592 int result = 0;
1025 int cscale;
1026 int foo;
1027
1028 if (sbs_mutex_lock(sbs)) {
1029 return -ENODEV;
1030 }
1031 593
1032 result = acpi_check_update_proc(sbs); 594 mutex_lock(&sbs->lock);
1033 if (result) 595 seq_printf(seq, "present: %s\n",
596 (battery->present) ? "yes" : "no");
597 if (!battery->present)
1034 goto end; 598 goto end;
1035 599
1036 if (update_time == 0) { 600 acpi_battery_get_state(battery);
1037 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE); 601 seq_printf(seq, "capacity state: %s\n",
1038 if (result) { 602 (battery->state & 0x0010) ? "critical" : "ok");
1039 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 603 seq_printf(seq, "charging state: %s\n",
1040 "acpi_sbs_update_run() failed")); 604 (battery->current_now < 0) ? "discharging" :
1041 } 605 ((battery->current_now > 0) ? "charging" : "charged"));
1042 } 606 seq_printf(seq, "present rate: %d mA\n",
1043 607 abs(battery->current_now) * acpi_battery_ipscale(battery));
1044 if (battery->battery_present) {
1045 seq_printf(seq, "present: yes\n");
1046 } else {
1047 seq_printf(seq, "present: no\n");
1048 goto end;
1049 }
1050
1051 if (battery->info.capacity_mode) {
1052 cscale = battery->info.vscale * battery->info.ipscale;
1053 } else {
1054 cscale = battery->info.ipscale;
1055 }
1056
1057 if (battery->state.battery_state & 0x0010) {
1058 seq_printf(seq, "capacity state: critical\n");
1059 } else {
1060 seq_printf(seq, "capacity state: ok\n");
1061 }
1062
1063 foo = (s16) battery->state.amperage * battery->info.ipscale;
1064 if (battery->info.capacity_mode) {
1065 foo = foo * battery->info.design_voltage / 1000;
1066 }
1067 if (battery->state.amperage < 0) {
1068 seq_printf(seq, "charging state: discharging\n");
1069 seq_printf(seq, "present rate: %d %s\n",
1070 -foo, battery->info.capacity_mode ? "mW" : "mA");
1071 } else if (battery->state.amperage > 0) {
1072 seq_printf(seq, "charging state: charging\n");
1073 seq_printf(seq, "present rate: %d %s\n",
1074 foo, battery->info.capacity_mode ? "mW" : "mA");
1075 } else {
1076 seq_printf(seq, "charging state: charged\n");
1077 seq_printf(seq, "present rate: 0 %s\n",
1078 battery->info.capacity_mode ? "mW" : "mA");
1079 }
1080
1081 seq_printf(seq, "remaining capacity: %i%s\n", 608 seq_printf(seq, "remaining capacity: %i%s\n",
1082 battery->state.remaining_capacity * cscale, 609 battery->capacity_now * acpi_battery_scale(battery),
1083 battery->info.capacity_mode ? "0 mWh" : " mAh"); 610 acpi_battery_units(battery));
1084
1085 seq_printf(seq, "present voltage: %i mV\n", 611 seq_printf(seq, "present voltage: %i mV\n",
1086 battery->state.voltage * battery->info.vscale); 612 battery->voltage_now * acpi_battery_vscale(battery));
1087 613
1088 end: 614 end:
1089 615 mutex_unlock(&sbs->lock);
1090 sbs_mutex_unlock(sbs);
1091
1092 return result; 616 return result;
1093} 617}
1094 618
@@ -1102,48 +626,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
1102 struct acpi_battery *battery = seq->private; 626 struct acpi_battery *battery = seq->private;
1103 struct acpi_sbs *sbs = battery->sbs; 627 struct acpi_sbs *sbs = battery->sbs;
1104 int result = 0; 628 int result = 0;
1105 int cscale;
1106
1107 if (sbs_mutex_lock(sbs)) {
1108 return -ENODEV;
1109 }
1110
1111 result = acpi_check_update_proc(sbs);
1112 if (result)
1113 goto end;
1114 629
1115 if (update_time == 0) { 630 mutex_lock(&sbs->lock);
1116 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
1117 if (result) {
1118 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1119 "acpi_sbs_update_run() failed"));
1120 }
1121 }
1122 631
1123 if (!battery->battery_present) { 632 if (!battery->present) {
1124 seq_printf(seq, "present: no\n"); 633 seq_printf(seq, "present: no\n");
1125 goto end; 634 goto end;
1126 } 635 }
1127 636
1128 if (battery->info.capacity_mode) { 637 acpi_battery_get_alarm(battery);
1129 cscale = battery->info.vscale * battery->info.ipscale;
1130 } else {
1131 cscale = battery->info.ipscale;
1132 }
1133
1134 seq_printf(seq, "alarm: "); 638 seq_printf(seq, "alarm: ");
1135 if (battery->alarm.remaining_capacity) { 639 if (battery->alarm_capacity)
1136 seq_printf(seq, "%i%s\n", 640 seq_printf(seq, "%i%s\n",
1137 battery->alarm.remaining_capacity * cscale, 641 battery->alarm_capacity *
1138 battery->info.capacity_mode ? "0 mWh" : " mAh"); 642 acpi_battery_scale(battery),
1139 } else { 643 acpi_battery_units(battery));
644 else
1140 seq_printf(seq, "disabled\n"); 645 seq_printf(seq, "disabled\n");
1141 }
1142
1143 end: 646 end:
1144 647 mutex_unlock(&sbs->lock);
1145 sbs_mutex_unlock(sbs);
1146
1147 return result; 648 return result;
1148} 649}
1149 650
@@ -1155,59 +656,29 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1155 struct acpi_battery *battery = seq->private; 656 struct acpi_battery *battery = seq->private;
1156 struct acpi_sbs *sbs = battery->sbs; 657 struct acpi_sbs *sbs = battery->sbs;
1157 char alarm_string[12] = { '\0' }; 658 char alarm_string[12] = { '\0' };
1158 int result, old_alarm, new_alarm; 659 int result = 0;
1159 660 mutex_lock(&sbs->lock);
1160 if (sbs_mutex_lock(sbs)) { 661 if (!battery->present) {
1161 return -ENODEV;
1162 }
1163
1164 result = acpi_check_update_proc(sbs);
1165 if (result)
1166 goto end;
1167
1168 if (!battery->battery_present) {
1169 result = -ENODEV; 662 result = -ENODEV;
1170 goto end; 663 goto end;
1171 } 664 }
1172
1173 if (count > sizeof(alarm_string) - 1) { 665 if (count > sizeof(alarm_string) - 1) {
1174 result = -EINVAL; 666 result = -EINVAL;
1175 goto end; 667 goto end;
1176 } 668 }
1177
1178 if (copy_from_user(alarm_string, buffer, count)) { 669 if (copy_from_user(alarm_string, buffer, count)) {
1179 result = -EFAULT; 670 result = -EFAULT;
1180 goto end; 671 goto end;
1181 } 672 }
1182
1183 alarm_string[count] = 0; 673 alarm_string[count] = 0;
1184 674 battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
1185 old_alarm = battery->alarm.remaining_capacity; 675 acpi_battery_scale(battery);
1186 new_alarm = simple_strtoul(alarm_string, NULL, 0); 676 acpi_battery_set_alarm(battery);
1187
1188 result = acpi_battery_set_alarm(battery, new_alarm);
1189 if (result) {
1190 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1191 "acpi_battery_set_alarm() failed"));
1192 acpi_battery_set_alarm(battery, old_alarm);
1193 goto end;
1194 }
1195 result = acpi_battery_get_alarm(battery);
1196 if (result) {
1197 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1198 "acpi_battery_get_alarm() failed"));
1199 acpi_battery_set_alarm(battery, old_alarm);
1200 goto end;
1201 }
1202
1203 end: 677 end:
1204 sbs_mutex_unlock(sbs); 678 mutex_unlock(&sbs->lock);
1205 679 if (result)
1206 if (result) {
1207 return result; 680 return result;
1208 } else { 681 return count;
1209 return count;
1210 }
1211} 682}
1212 683
1213static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 684static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -1246,26 +717,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
1246 717
1247static int acpi_ac_read_state(struct seq_file *seq, void *offset) 718static int acpi_ac_read_state(struct seq_file *seq, void *offset)
1248{ 719{
1249 struct acpi_sbs *sbs = seq->private;
1250 int result;
1251 720
1252 if (sbs_mutex_lock(sbs)) { 721 struct acpi_sbs *sbs = seq->private;
1253 return -ENODEV;
1254 }
1255 722
1256 if (update_time == 0) { 723 mutex_lock(&sbs->lock);
1257 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
1258 if (result) {
1259 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1260 "acpi_sbs_update_run() failed"));
1261 }
1262 }
1263 724
1264 seq_printf(seq, "state: %s\n", 725 seq_printf(seq, "state: %s\n",
1265 sbs->ac.ac_present ? "on-line" : "off-line"); 726 sbs->charger_present ? "on-line" : "off-line");
1266
1267 sbs_mutex_unlock(sbs);
1268 727
728 mutex_unlock(&sbs->lock);
1269 return 0; 729 return 0;
1270} 730}
1271 731
@@ -1282,429 +742,203 @@ static struct file_operations acpi_ac_state_fops = {
1282 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
1283}; 743};
1284 744
745#endif
746
1285/* -------------------------------------------------------------------------- 747/* --------------------------------------------------------------------------
1286 Driver Interface 748 Driver Interface
1287 -------------------------------------------------------------------------- */ 749 -------------------------------------------------------------------------- */
750static int acpi_battery_read(struct acpi_battery *battery)
751{
752 int result = 0, saved_present = battery->present;
753 u16 state;
754
755 if (battery->sbs->manager_present) {
756 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
757 ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
758 if (!result)
759 battery->present = state & (1 << battery->id);
760 state &= 0x0fff;
761 state |= 1 << (battery->id + 12);
762 acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
763 ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
764 } else if (battery->id == 0)
765 battery->present = 1;
766 if (result || !battery->present)
767 return result;
1288 768
1289/* Smart Battery */ 769 if (saved_present != battery->present) {
770 battery->update_time = 0;
771 result = acpi_battery_get_info(battery);
772 if (result)
773 return result;
774 }
775 result = acpi_battery_get_state(battery);
776 return result;
777}
1290 778
779/* Smart Battery */
1291static int acpi_battery_add(struct acpi_sbs *sbs, int id) 780static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1292{ 781{
1293 int is_present; 782 struct acpi_battery *battery = &sbs->battery[id];
1294 int result; 783 int result;
1295 char dir_name[32];
1296 struct acpi_battery *battery;
1297
1298 battery = &sbs->battery[id];
1299
1300 battery->alive = 0;
1301 784
1302 battery->init_state = 0;
1303 battery->id = id; 785 battery->id = id;
1304 battery->sbs = sbs; 786 battery->sbs = sbs;
787 result = acpi_battery_read(battery);
788 if (result)
789 return result;
1305 790
1306 result = acpi_battery_select(battery); 791 sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
1307 if (result) { 792#ifdef CONFIG_ACPI_PROCFS
1308 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 793 acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
1309 "acpi_battery_select() failed")); 794 battery->name, &acpi_battery_info_fops,
1310 goto end; 795 &acpi_battery_state_fops, &acpi_battery_alarm_fops,
1311 } 796 battery);
1312 797#endif
1313 result = acpi_battery_get_present(battery); 798 battery->bat.name = battery->name;
1314 if (result) { 799 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
1315 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 800 if (!acpi_battery_mode(battery)) {
1316 "acpi_battery_get_present() failed")); 801 battery->bat.properties = sbs_charge_battery_props;
1317 goto end; 802 battery->bat.num_properties =
1318 } 803 ARRAY_SIZE(sbs_charge_battery_props);
1319 804 } else {
1320 is_present = battery->battery_present; 805 battery->bat.properties = sbs_energy_battery_props;
1321 806 battery->bat.num_properties =
1322 if (is_present) { 807 ARRAY_SIZE(sbs_energy_battery_props);
1323 result = acpi_battery_init(battery);
1324 if (result) {
1325 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1326 "acpi_battery_init() failed"));
1327 goto end;
1328 }
1329 battery->init_state = 1;
1330 }
1331
1332 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1333
1334 result = acpi_sbs_generic_add_fs(&battery->battery_entry,
1335 acpi_battery_dir,
1336 dir_name,
1337 &acpi_battery_info_fops,
1338 &acpi_battery_state_fops,
1339 &acpi_battery_alarm_fops, battery);
1340 if (result) {
1341 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1342 "acpi_sbs_generic_add_fs() failed"));
1343 goto end;
1344 } 808 }
1345 battery->alive = 1; 809 battery->bat.get_property = acpi_sbs_battery_get_property;
1346 810 result = power_supply_register(&sbs->device->dev, &battery->bat);
811 device_create_file(battery->bat.dev, &alarm_attr);
1347 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", 812 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
1348 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name, 813 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
1349 sbs->battery->battery_present ? "present" : "absent"); 814 battery->name, sbs->battery->present ? "present" : "absent");
1350
1351 end:
1352 return result; 815 return result;
1353} 816}
1354 817
1355static void acpi_battery_remove(struct acpi_sbs *sbs, int id) 818static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
1356{ 819{
1357 820 if (sbs->battery[id].bat.dev)
1358 if (sbs->battery[id].battery_entry) { 821 device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
1359 acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry), 822 power_supply_unregister(&sbs->battery[id].bat);
1360 acpi_battery_dir); 823#ifdef CONFIG_ACPI_PROCFS
1361 } 824 if (sbs->battery[id].proc_entry) {
825 acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
826 acpi_battery_dir);
827 }
828#endif
1362} 829}
1363 830
1364static int acpi_ac_add(struct acpi_sbs *sbs) 831static int acpi_charger_add(struct acpi_sbs *sbs)
1365{ 832{
1366 int result; 833 int result;
1367 834
1368 result = acpi_ac_get_present(sbs); 835 result = acpi_ac_get_present(sbs);
1369 if (result) { 836 if (result)
1370 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1371 "acpi_ac_get_present() failed"));
1372 goto end; 837 goto end;
1373 } 838#ifdef CONFIG_ACPI_PROCFS
1374 839 result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
1375 result = acpi_sbs_generic_add_fs(&sbs->ac_entry, 840 ACPI_AC_DIR_NAME, NULL,
1376 acpi_ac_dir, 841 &acpi_ac_state_fops, NULL, sbs);
1377 ACPI_AC_DIR_NAME, 842 if (result)
1378 NULL, &acpi_ac_state_fops, NULL, sbs);
1379 if (result) {
1380 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1381 "acpi_sbs_generic_add_fs() failed"));
1382 goto end; 843 goto end;
1383 } 844#endif
1384 845 sbs->charger.name = "sbs-charger";
846 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
847 sbs->charger.properties = sbs_ac_props;
848 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
849 sbs->charger.get_property = sbs_get_ac_property;
850 power_supply_register(&sbs->device->dev, &sbs->charger);
1385 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", 851 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
1386 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 852 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
1387 ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line"); 853 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
1388
1389 end: 854 end:
1390
1391 return result; 855 return result;
1392} 856}
1393 857
1394static void acpi_ac_remove(struct acpi_sbs *sbs) 858static void acpi_charger_remove(struct acpi_sbs *sbs)
1395{ 859{
1396 860 if (sbs->charger.dev)
1397 if (sbs->ac_entry) { 861 power_supply_unregister(&sbs->charger);
1398 acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir); 862#ifdef CONFIG_ACPI_PROCFS
1399 } 863 if (sbs->charger_entry)
864 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
865#endif
1400} 866}
1401 867
1402static void acpi_sbs_update_time_run(unsigned long data) 868void acpi_sbs_callback(void *context)
1403{ 869{
1404 acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data); 870 int id;
1405} 871 struct acpi_sbs *sbs = context;
1406 872 struct acpi_battery *bat;
1407static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) 873 u8 saved_charger_state = sbs->charger_present;
1408{ 874 u8 saved_battery_state;
1409 struct acpi_battery *battery; 875 acpi_ac_get_present(sbs);
1410 int result = 0, cnt; 876 if (sbs->charger_present != saved_charger_state) {
1411 int old_ac_present = -1; 877#ifdef CONFIG_ACPI_PROC_EVENT
1412 int old_battery_present = -1; 878 acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
1413 int new_ac_present = -1; 879 ACPI_SBS_NOTIFY_STATUS,
1414 int new_battery_present = -1; 880 sbs->charger_present);
1415 int id_min = 0, id_max = MAX_SBS_BAT - 1; 881#endif
1416 char dir_name[32]; 882 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
1417 int do_battery_init = 0, do_ac_init = 0; 883 }
1418 int old_remaining_capacity = 0; 884 if (sbs->manager_present) {
1419 int update_battery = 1; 885 for (id = 0; id < MAX_SBS_BAT; ++id) {
1420 int up_tm = update_time; 886 if (!(sbs->batteries_supported & (1 << id)))
1421 887 continue;
1422 if (sbs_zombie(sbs)) { 888 bat = &sbs->battery[id];
1423 goto end; 889 saved_battery_state = bat->present;
1424 } 890 acpi_battery_read(bat);
1425 891 if (saved_battery_state == bat->present)
1426 if (id >= 0) { 892 continue;
1427 id_min = id_max = id; 893#ifdef CONFIG_ACPI_PROC_EVENT
1428 } 894 acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
1429 895 bat->name,
1430 if (data_type == DATA_TYPE_COMMON && up_tm > 0) { 896 ACPI_SBS_NOTIFY_STATUS,
1431 cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm); 897 bat->present);
1432 if (sbs->run_cnt % cnt != 0) { 898#endif
1433 update_battery = 0; 899 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
1434 }
1435 }
1436
1437 sbs->run_cnt++;
1438
1439 old_ac_present = sbs->ac.ac_present;
1440
1441 result = acpi_ac_get_present(sbs);
1442 if (result) {
1443 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1444 "acpi_ac_get_present() failed"));
1445 }
1446
1447 new_ac_present = sbs->ac.ac_present;
1448
1449 do_ac_init = (old_ac_present != new_ac_present);
1450 if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
1451 do_ac_init = 1;
1452 }
1453
1454 if (do_ac_init) {
1455 result = acpi_sbs_generate_event(sbs->device,
1456 ACPI_SBS_AC_NOTIFY_STATUS,
1457 new_ac_present,
1458 ACPI_AC_DIR_NAME,
1459 ACPI_AC_CLASS);
1460 if (result) {
1461 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1462 "acpi_sbs_generate_event() failed"));
1463 }
1464 }
1465
1466 if (data_type == DATA_TYPE_COMMON) {
1467 if (!do_ac_init && !update_battery) {
1468 goto end;
1469 }
1470 }
1471
1472 if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
1473 goto end;
1474 }
1475
1476 for (id = id_min; id <= id_max; id++) {
1477 battery = &sbs->battery[id];
1478 if (battery->alive == 0) {
1479 continue;
1480 }
1481
1482 old_remaining_capacity = battery->state.remaining_capacity;
1483
1484 old_battery_present = battery->battery_present;
1485
1486 result = acpi_battery_select(battery);
1487 if (result) {
1488 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1489 "acpi_battery_select() failed"));
1490 }
1491
1492 result = acpi_battery_get_present(battery);
1493 if (result) {
1494 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1495 "acpi_battery_get_present() failed"));
1496 }
1497
1498 new_battery_present = battery->battery_present;
1499
1500 do_battery_init = ((old_battery_present != new_battery_present)
1501 && new_battery_present);
1502 if (!new_battery_present)
1503 goto event;
1504 if (do_ac_init || do_battery_init) {
1505 result = acpi_battery_init(battery);
1506 if (result) {
1507 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1508 "acpi_battery_init() "
1509 "failed"));
1510 }
1511 }
1512 if (sbs_zombie(sbs)) {
1513 goto end;
1514 }
1515
1516 if ((data_type == DATA_TYPE_COMMON
1517 || data_type == DATA_TYPE_INFO)
1518 && new_battery_present) {
1519 result = acpi_battery_get_info(battery);
1520 if (result) {
1521 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1522 "acpi_battery_get_info() failed"));
1523 }
1524 }
1525 if (data_type == DATA_TYPE_INFO) {
1526 continue;
1527 }
1528 if (sbs_zombie(sbs)) {
1529 goto end;
1530 }
1531
1532 if ((data_type == DATA_TYPE_COMMON
1533 || data_type == DATA_TYPE_STATE)
1534 && new_battery_present) {
1535 result = acpi_battery_get_state(battery);
1536 if (result) {
1537 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1538 "acpi_battery_get_state() failed"));
1539 }
1540 }
1541 if (data_type == DATA_TYPE_STATE) {
1542 goto event;
1543 }
1544 if (sbs_zombie(sbs)) {
1545 goto end;
1546 }
1547
1548 if ((data_type == DATA_TYPE_COMMON
1549 || data_type == DATA_TYPE_ALARM)
1550 && new_battery_present) {
1551 result = acpi_battery_get_alarm(battery);
1552 if (result) {
1553 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1554 "acpi_battery_get_alarm() "
1555 "failed"));
1556 }
1557 }
1558 if (data_type == DATA_TYPE_ALARM) {
1559 continue;
1560 }
1561 if (sbs_zombie(sbs)) {
1562 goto end;
1563 }
1564
1565 event:
1566
1567 if (old_battery_present != new_battery_present || do_ac_init ||
1568 old_remaining_capacity !=
1569 battery->state.remaining_capacity) {
1570 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1571 result = acpi_sbs_generate_event(sbs->device,
1572 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1573 new_battery_present,
1574 dir_name,
1575 ACPI_BATTERY_CLASS);
1576 if (result) {
1577 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1578 "acpi_sbs_generate_event() "
1579 "failed"));
1580 }
1581 } 900 }
1582 } 901 }
1583
1584 end:
1585
1586 return result;
1587} 902}
1588 903
1589static void acpi_sbs_update_time(void *data) 904static int acpi_sbs_remove(struct acpi_device *device, int type);
1590{
1591 struct acpi_sbs *sbs = data;
1592 unsigned long delay = -1;
1593 int result;
1594 unsigned int up_tm = update_time;
1595
1596 if (sbs_mutex_lock(sbs))
1597 return;
1598
1599 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
1600 if (result) {
1601 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1602 "acpi_sbs_update_run() failed"));
1603 }
1604
1605 if (sbs_zombie(sbs)) {
1606 goto end;
1607 }
1608
1609 if (!up_tm) {
1610 if (timer_pending(&sbs->update_timer))
1611 del_timer(&sbs->update_timer);
1612 } else {
1613 delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
1614 delay = jiffies + HZ * delay;
1615 if (timer_pending(&sbs->update_timer)) {
1616 mod_timer(&sbs->update_timer, delay);
1617 } else {
1618 sbs->update_timer.data = (unsigned long)data;
1619 sbs->update_timer.function = acpi_sbs_update_time_run;
1620 sbs->update_timer.expires = delay;
1621 add_timer(&sbs->update_timer);
1622 }
1623 }
1624
1625 end:
1626
1627 sbs_mutex_unlock(sbs);
1628}
1629 905
1630static int acpi_sbs_add(struct acpi_device *device) 906static int acpi_sbs_add(struct acpi_device *device)
1631{ 907{
1632 struct acpi_sbs *sbs = NULL; 908 struct acpi_sbs *sbs;
1633 int result = 0, remove_result = 0; 909 int result = 0;
1634 int id; 910 int id;
1635 acpi_status status = AE_OK;
1636 unsigned long val;
1637
1638 status =
1639 acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
1640 if (ACPI_FAILURE(status)) {
1641 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
1642 return -EIO;
1643 }
1644 911
1645 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); 912 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
1646 if (!sbs) { 913 if (!sbs) {
1647 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
1648 result = -ENOMEM; 914 result = -ENOMEM;
1649 goto end; 915 goto end;
1650 } 916 }
1651 917
1652 mutex_init(&sbs->mutex); 918 mutex_init(&sbs->lock);
1653
1654 sbs_mutex_lock(sbs);
1655 919
1656 sbs->base = 0xff & (val >> 8); 920 sbs->hc = acpi_driver_data(device->parent);
1657 sbs->device = device; 921 sbs->device = device;
1658
1659 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); 922 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
1660 strcpy(acpi_device_class(device), ACPI_SBS_CLASS); 923 strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
1661 acpi_driver_data(device) = sbs; 924 acpi_driver_data(device) = sbs;
1662 925
1663 result = acpi_ac_add(sbs); 926 result = acpi_charger_add(sbs);
1664 if (result) {
1665 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
1666 goto end;
1667 }
1668
1669 acpi_sbsm_get_info(sbs);
1670
1671 if (!sbs->sbsm_present) {
1672 result = acpi_battery_add(sbs, 0);
1673 if (result) {
1674 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1675 "acpi_battery_add() failed"));
1676 goto end;
1677 }
1678 } else {
1679 for (id = 0; id < MAX_SBS_BAT; id++) {
1680 if ((sbs->sbsm_batteries_supported & (1 << id))) {
1681 result = acpi_battery_add(sbs, id);
1682 if (result) {
1683 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1684 "acpi_battery_add() failed"));
1685 goto end;
1686 }
1687 }
1688 }
1689 }
1690
1691 init_timer(&sbs->update_timer);
1692 result = acpi_check_update_proc(sbs);
1693 if (result) 927 if (result)
1694 goto end; 928 goto end;
1695 929
930 result = acpi_manager_get_info(sbs);
931 if (!result) {
932 sbs->manager_present = 1;
933 for (id = 0; id < MAX_SBS_BAT; ++id)
934 if ((sbs->batteries_supported & (1 << id)))
935 acpi_battery_add(sbs, id);
936 } else
937 acpi_battery_add(sbs, 0);
938 acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
1696 end: 939 end:
1697 940 if (result)
1698 sbs_mutex_unlock(sbs); 941 acpi_sbs_remove(device, 0);
1699
1700 if (result) {
1701 remove_result = acpi_sbs_remove(device, 0);
1702 if (remove_result) {
1703 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1704 "acpi_sbs_remove() failed"));
1705 }
1706 }
1707
1708 return result; 942 return result;
1709} 943}
1710 944
@@ -1713,39 +947,25 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
1713 struct acpi_sbs *sbs; 947 struct acpi_sbs *sbs;
1714 int id; 948 int id;
1715 949
1716 if (!device) { 950 if (!device)
1717 return -EINVAL; 951 return -EINVAL;
1718 }
1719
1720 sbs = acpi_driver_data(device); 952 sbs = acpi_driver_data(device);
1721 if (!sbs) { 953 if (!sbs)
1722 return -EINVAL; 954 return -EINVAL;
1723 } 955 mutex_lock(&sbs->lock);
1724 956 acpi_smbus_unregister_callback(sbs->hc);
1725 sbs_mutex_lock(sbs); 957 for (id = 0; id < MAX_SBS_BAT; ++id)
1726
1727 sbs->zombie = 1;
1728 del_timer_sync(&sbs->update_timer);
1729 acpi_os_wait_events_complete(NULL);
1730 del_timer_sync(&sbs->update_timer);
1731
1732 for (id = 0; id < MAX_SBS_BAT; id++) {
1733 acpi_battery_remove(sbs, id); 958 acpi_battery_remove(sbs, id);
1734 } 959 acpi_charger_remove(sbs);
1735 960 mutex_unlock(&sbs->lock);
1736 acpi_ac_remove(sbs); 961 mutex_destroy(&sbs->lock);
1737
1738 sbs_mutex_unlock(sbs);
1739
1740 mutex_destroy(&sbs->mutex);
1741
1742 kfree(sbs); 962 kfree(sbs);
1743
1744 return 0; 963 return 0;
1745} 964}
1746 965
1747static void acpi_sbs_rmdirs(void) 966static void acpi_sbs_rmdirs(void)
1748{ 967{
968#ifdef CONFIG_ACPI_PROCFS
1749 if (acpi_ac_dir) { 969 if (acpi_ac_dir) {
1750 acpi_unlock_ac_dir(acpi_ac_dir); 970 acpi_unlock_ac_dir(acpi_ac_dir);
1751 acpi_ac_dir = NULL; 971 acpi_ac_dir = NULL;
@@ -1754,69 +974,58 @@ static void acpi_sbs_rmdirs(void)
1754 acpi_unlock_battery_dir(acpi_battery_dir); 974 acpi_unlock_battery_dir(acpi_battery_dir);
1755 acpi_battery_dir = NULL; 975 acpi_battery_dir = NULL;
1756 } 976 }
977#endif
1757} 978}
1758 979
1759static int acpi_sbs_resume(struct acpi_device *device) 980static int acpi_sbs_resume(struct acpi_device *device)
1760{ 981{
1761 struct acpi_sbs *sbs; 982 struct acpi_sbs *sbs;
1762
1763 if (!device) 983 if (!device)
1764 return -EINVAL; 984 return -EINVAL;
1765
1766 sbs = device->driver_data; 985 sbs = device->driver_data;
1767 986 acpi_sbs_callback(sbs);
1768 sbs->run_cnt = 0;
1769
1770 return 0; 987 return 0;
1771} 988}
1772 989
990static struct acpi_driver acpi_sbs_driver = {
991 .name = "sbs",
992 .class = ACPI_SBS_CLASS,
993 .ids = sbs_device_ids,
994 .ops = {
995 .add = acpi_sbs_add,
996 .remove = acpi_sbs_remove,
997 .resume = acpi_sbs_resume,
998 },
999};
1000
1773static int __init acpi_sbs_init(void) 1001static int __init acpi_sbs_init(void)
1774{ 1002{
1775 int result = 0; 1003 int result = 0;
1776 1004
1777 if (acpi_disabled) 1005 if (acpi_disabled)
1778 return -ENODEV; 1006 return -ENODEV;
1779 1007#ifdef CONFIG_ACPI_PROCFS
1780 if (capacity_mode != DEF_CAPACITY_UNIT
1781 && capacity_mode != MAH_CAPACITY_UNIT
1782 && capacity_mode != MWH_CAPACITY_UNIT) {
1783 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1784 "invalid capacity_mode = %d", capacity_mode));
1785 return -EINVAL;
1786 }
1787
1788 acpi_ac_dir = acpi_lock_ac_dir(); 1008 acpi_ac_dir = acpi_lock_ac_dir();
1789 if (!acpi_ac_dir) { 1009 if (!acpi_ac_dir)
1790 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1791 "acpi_lock_ac_dir() failed"));
1792 return -ENODEV; 1010 return -ENODEV;
1793 }
1794
1795 acpi_battery_dir = acpi_lock_battery_dir(); 1011 acpi_battery_dir = acpi_lock_battery_dir();
1796 if (!acpi_battery_dir) { 1012 if (!acpi_battery_dir) {
1797 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1798 "acpi_lock_battery_dir() failed"));
1799 acpi_sbs_rmdirs(); 1013 acpi_sbs_rmdirs();
1800 return -ENODEV; 1014 return -ENODEV;
1801 } 1015 }
1802 1016#endif
1803 result = acpi_bus_register_driver(&acpi_sbs_driver); 1017 result = acpi_bus_register_driver(&acpi_sbs_driver);
1804 if (result < 0) { 1018 if (result < 0) {
1805 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1806 "acpi_bus_register_driver() failed"));
1807 acpi_sbs_rmdirs(); 1019 acpi_sbs_rmdirs();
1808 return -ENODEV; 1020 return -ENODEV;
1809 } 1021 }
1810
1811 return 0; 1022 return 0;
1812} 1023}
1813 1024
1814static void __exit acpi_sbs_exit(void) 1025static void __exit acpi_sbs_exit(void)
1815{ 1026{
1816 acpi_bus_unregister_driver(&acpi_sbs_driver); 1027 acpi_bus_unregister_driver(&acpi_sbs_driver);
1817
1818 acpi_sbs_rmdirs(); 1028 acpi_sbs_rmdirs();
1819
1820 return; 1029 return;
1821} 1030}
1822 1031
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
new file mode 100644
index 000000000000..046d7c3ed356
--- /dev/null
+++ b/drivers/acpi/sbshc.c
@@ -0,0 +1,309 @@
1/*
2 * SMBus driver for ACPI Embedded Controller (v0.1)
3 *
4 * Copyright (c) 2007 Alexey Starikovskiy
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation version 2.
9 */
10
11#include <acpi/acpi_bus.h>
12#include <acpi/acpi_drivers.h>
13#include <acpi/actypes.h>
14#include <linux/wait.h>
15#include <linux/delay.h>
16#include <linux/interrupt.h>
17#include "sbshc.h"
18
19#define ACPI_SMB_HC_CLASS "smbus_host_controller"
20#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
21
22struct acpi_smb_hc {
23 struct acpi_ec *ec;
24 struct mutex lock;
25 wait_queue_head_t wait;
26 u8 offset;
27 u8 query_bit;
28 smbus_alarm_callback callback;
29 void *context;
30};
31
32static int acpi_smbus_hc_add(struct acpi_device *device);
33static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
34
35static const struct acpi_device_id sbs_device_ids[] = {
36 {"ACPI0001", 0},
37 {"ACPI0005", 0},
38 {"", 0},
39};
40
41MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
42
43static struct acpi_driver acpi_smb_hc_driver = {
44 .name = "smbus_hc",
45 .class = ACPI_SMB_HC_CLASS,
46 .ids = sbs_device_ids,
47 .ops = {
48 .add = acpi_smbus_hc_add,
49 .remove = acpi_smbus_hc_remove,
50 },
51};
52
53union acpi_smb_status {
54 u8 raw;
55 struct {
56 u8 status:5;
57 u8 reserved:1;
58 u8 alarm:1;
59 u8 done:1;
60 } fields;
61};
62
63enum acpi_smb_status_codes {
64 SMBUS_OK = 0,
65 SMBUS_UNKNOWN_FAILURE = 0x07,
66 SMBUS_DEVICE_ADDRESS_NACK = 0x10,
67 SMBUS_DEVICE_ERROR = 0x11,
68 SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
69 SMBUS_UNKNOWN_ERROR = 0x13,
70 SMBUS_DEVICE_ACCESS_DENIED = 0x17,
71 SMBUS_TIMEOUT = 0x18,
72 SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
73 SMBUS_BUSY = 0x1a,
74 SMBUS_PEC_ERROR = 0x1f,
75};
76
77enum acpi_smb_offset {
78 ACPI_SMB_PROTOCOL = 0, /* protocol, PEC */
79 ACPI_SMB_STATUS = 1, /* status */
80 ACPI_SMB_ADDRESS = 2, /* address */
81 ACPI_SMB_COMMAND = 3, /* command */
82 ACPI_SMB_DATA = 4, /* 32 data registers */
83 ACPI_SMB_BLOCK_COUNT = 0x24, /* number of data bytes */
84 ACPI_SMB_ALARM_ADDRESS = 0x25, /* alarm address */
85 ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
86};
87
88static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
89{
90 return ec_read(hc->offset + address, data);
91}
92
93static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
94{
95 return ec_write(hc->offset + address, data);
96}
97
98static inline int smb_check_done(struct acpi_smb_hc *hc)
99{
100 union acpi_smb_status status = {.raw = 0};
101 smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
102 return status.fields.done && (status.fields.status == SMBUS_OK);
103}
104
105static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
106{
107 if (wait_event_timeout(hc->wait, smb_check_done(hc),
108 msecs_to_jiffies(timeout)))
109 return 0;
110 else
111 return -ETIME;
112}
113
114int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
115 u8 command, u8 *data, u8 length)
116{
117 int ret = -EFAULT, i;
118 u8 temp, sz = 0;
119
120 mutex_lock(&hc->lock);
121 if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
122 goto end;
123 if (temp) {
124 ret = -EBUSY;
125 goto end;
126 }
127 smb_hc_write(hc, ACPI_SMB_COMMAND, command);
128 smb_hc_write(hc, ACPI_SMB_COMMAND, command);
129 if (!(protocol & 0x01)) {
130 smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
131 for (i = 0; i < length; ++i)
132 smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
133 }
134 smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
135 smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
136 /*
137 * Wait for completion. Save the status code, data size,
138 * and data into the return package (if required by the protocol).
139 */
140 ret = wait_transaction_complete(hc, 1000);
141 if (ret || !(protocol & 0x01))
142 goto end;
143 switch (protocol) {
144 case SMBUS_RECEIVE_BYTE:
145 case SMBUS_READ_BYTE:
146 sz = 1;
147 break;
148 case SMBUS_READ_WORD:
149 sz = 2;
150 break;
151 case SMBUS_READ_BLOCK:
152 if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
153 ret = -EFAULT;
154 goto end;
155 }
156 sz &= 0x1f;
157 break;
158 }
159 for (i = 0; i < sz; ++i)
160 smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
161 end:
162 mutex_unlock(&hc->lock);
163 return ret;
164}
165
166int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
167 u8 command, u8 *data)
168{
169 return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
170}
171
172EXPORT_SYMBOL_GPL(acpi_smbus_read);
173
174int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
175 u8 command, u8 *data, u8 length)
176{
177 return acpi_smbus_transaction(hc, protocol, address, command, data, length);
178}
179
180EXPORT_SYMBOL_GPL(acpi_smbus_write);
181
182int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
183 smbus_alarm_callback callback, void *context)
184{
185 mutex_lock(&hc->lock);
186 hc->callback = callback;
187 hc->context = context;
188 mutex_unlock(&hc->lock);
189 return 0;
190}
191
192EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
193
194int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
195{
196 mutex_lock(&hc->lock);
197 hc->callback = NULL;
198 hc->context = NULL;
199 mutex_unlock(&hc->lock);
200 return 0;
201}
202
203EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
204
205static void acpi_smbus_callback(void *context)
206{
207 struct acpi_smb_hc *hc = context;
208
209 if (hc->callback)
210 hc->callback(hc->context);
211}
212
213static int smbus_alarm(void *context)
214{
215 struct acpi_smb_hc *hc = context;
216 union acpi_smb_status status;
217 if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
218 return 0;
219 /* Check if it is only a completion notify */
220 if (status.fields.done)
221 wake_up(&hc->wait);
222 if (!status.fields.alarm)
223 return 0;
224 mutex_lock(&hc->lock);
225 smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
226 if (hc->callback)
227 acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
228 mutex_unlock(&hc->lock);
229 return 0;
230}
231
232typedef int (*acpi_ec_query_func) (void *data);
233
234extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
235 acpi_handle handle, acpi_ec_query_func func,
236 void *data);
237
238static int acpi_smbus_hc_add(struct acpi_device *device)
239{
240 int status;
241 unsigned long val;
242 struct acpi_smb_hc *hc;
243
244 if (!device)
245 return -EINVAL;
246
247 status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
248 if (ACPI_FAILURE(status)) {
249 printk(KERN_ERR PREFIX "error obtaining _EC.\n");
250 return -EIO;
251 }
252
253 strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
254 strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
255
256 hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
257 if (!hc)
258 return -ENOMEM;
259 mutex_init(&hc->lock);
260 init_waitqueue_head(&hc->wait);
261
262 hc->ec = acpi_driver_data(device->parent);
263 hc->offset = (val >> 8) & 0xff;
264 hc->query_bit = val & 0xff;
265 acpi_driver_data(device) = hc;
266
267 acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
268 printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
269 hc->ec, hc->offset, hc->query_bit);
270
271 return 0;
272}
273
274extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
275
276static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
277{
278 struct acpi_smb_hc *hc;
279
280 if (!device)
281 return -EINVAL;
282
283 hc = acpi_driver_data(device);
284 acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
285 kfree(hc);
286 return 0;
287}
288
289static int __init acpi_smb_hc_init(void)
290{
291 int result;
292
293 result = acpi_bus_register_driver(&acpi_smb_hc_driver);
294 if (result < 0)
295 return -ENODEV;
296 return 0;
297}
298
299static void __exit acpi_smb_hc_exit(void)
300{
301 acpi_bus_unregister_driver(&acpi_smb_hc_driver);
302}
303
304module_init(acpi_smb_hc_init);
305module_exit(acpi_smb_hc_exit);
306
307MODULE_LICENSE("GPL");
308MODULE_AUTHOR("Alexey Starikovskiy");
309MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/drivers/acpi/sbshc.h b/drivers/acpi/sbshc.h
new file mode 100644
index 000000000000..3bda3491a97b
--- /dev/null
+++ b/drivers/acpi/sbshc.h
@@ -0,0 +1,27 @@
1struct acpi_smb_hc;
2enum acpi_smb_protocol {
3 SMBUS_WRITE_QUICK = 2,
4 SMBUS_READ_QUICK = 3,
5 SMBUS_SEND_BYTE = 4,
6 SMBUS_RECEIVE_BYTE = 5,
7 SMBUS_WRITE_BYTE = 6,
8 SMBUS_READ_BYTE = 7,
9 SMBUS_WRITE_WORD = 8,
10 SMBUS_READ_WORD = 9,
11 SMBUS_WRITE_BLOCK = 0xa,
12 SMBUS_READ_BLOCK = 0xb,
13 SMBUS_PROCESS_CALL = 0xc,
14 SMBUS_BLOCK_PROCESS_CALL = 0xd,
15};
16
17static const u8 SMBUS_PEC = 0x80;
18
19typedef void (*smbus_alarm_callback)(void *context);
20
21extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
22 u8 command, u8 * data);
23extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
24 u8 command, u8 * data, u8 length);
25extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
26 smbus_alarm_callback callback, void *context);
27extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 048295ec3707..f3d3867303ec 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -44,7 +44,6 @@ int acpi_sleep_prepare(u32 acpi_state)
44 ACPI_FLUSH_CPU_CACHE(); 44 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state); 45 acpi_enable_wakeup_device_prep(acpi_state);
46#endif 46#endif
47 acpi_gpe_sleep_prepare(acpi_state);
48 acpi_enter_sleep_state_prep(acpi_state); 47 acpi_enter_sleep_state_prep(acpi_state);
49 return 0; 48 return 0;
50} 49}
@@ -268,6 +267,11 @@ static void acpi_hibernation_leave(void)
268 267
269static void acpi_hibernation_finish(void) 268static void acpi_hibernation_finish(void)
270{ 269{
270 /*
271 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
272 * enable it here.
273 */
274 acpi_enable();
271 acpi_leave_sleep_state(ACPI_STATE_S4); 275 acpi_leave_sleep_state(ACPI_STATE_S4);
272 acpi_disable_wakeup_device(ACPI_STATE_S4); 276 acpi_disable_wakeup_device(ACPI_STATE_S4);
273 277
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index ff1f8504f497..a2ea125ae2d0 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,6 +5,5 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8extern void acpi_gpe_sleep_prepare(u32 sleep_state);
9 8
10extern int acpi_sleep_prepare(u32 acpi_state); 9extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 97c27ddb144d..ed8e41becf0c 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -64,36 +64,29 @@ void acpi_enable_wakeup_device(u8 sleep_state)
64 ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device"); 64 ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
65 spin_lock(&acpi_device_lock); 65 spin_lock(&acpi_device_lock);
66 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 66 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
67 struct acpi_device *dev = container_of(node, 67 struct acpi_device *dev =
68 struct acpi_device, 68 container_of(node, struct acpi_device, wakeup_list);
69 wakeup_list); 69 if (!dev->wakeup.flags.valid)
70 70 continue;
71 /* If users want to disable run-wake GPE, 71 /* If users want to disable run-wake GPE,
72 * we only disable it for wake and leave it for runtime 72 * we only disable it for wake and leave it for runtime
73 */ 73 */
74 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 74 if (!dev->wakeup.state.enabled ||
75 spin_unlock(&acpi_device_lock); 75 sleep_state > (u32) dev->wakeup.sleep_state) {
76 acpi_set_gpe_type(dev->wakeup.gpe_device, 76 if (dev->wakeup.flags.run_wake) {
77 dev->wakeup.gpe_number, 77 spin_unlock(&acpi_device_lock);
78 ACPI_GPE_TYPE_RUNTIME); 78 /* set_gpe_type will disable GPE, leave it like that */
79 /* Re-enable it, since set_gpe_type will disable it */ 79 acpi_set_gpe_type(dev->wakeup.gpe_device,
80 acpi_enable_gpe(dev->wakeup.gpe_device, 80 dev->wakeup.gpe_number,
81 dev->wakeup.gpe_number, ACPI_ISR); 81 ACPI_GPE_TYPE_RUNTIME);
82 spin_lock(&acpi_device_lock); 82 spin_lock(&acpi_device_lock);
83 }
83 continue; 84 continue;
84 } 85 }
85
86 if (!dev->wakeup.flags.valid ||
87 !dev->wakeup.state.enabled ||
88 (sleep_state > (u32) dev->wakeup.sleep_state))
89 continue;
90
91 spin_unlock(&acpi_device_lock); 86 spin_unlock(&acpi_device_lock);
92 /* run-wake GPE has been enabled */
93 if (!dev->wakeup.flags.run_wake) 87 if (!dev->wakeup.flags.run_wake)
94 acpi_enable_gpe(dev->wakeup.gpe_device, 88 acpi_enable_gpe(dev->wakeup.gpe_device,
95 dev->wakeup.gpe_number, ACPI_ISR); 89 dev->wakeup.gpe_number, ACPI_ISR);
96 dev->wakeup.state.active = 1;
97 spin_lock(&acpi_device_lock); 90 spin_lock(&acpi_device_lock);
98 } 91 }
99 spin_unlock(&acpi_device_lock); 92 spin_unlock(&acpi_device_lock);
@@ -112,26 +105,25 @@ void acpi_disable_wakeup_device(u8 sleep_state)
112 105
113 spin_lock(&acpi_device_lock); 106 spin_lock(&acpi_device_lock);
114 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 107 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
115 struct acpi_device *dev = container_of(node, 108 struct acpi_device *dev =
116 struct acpi_device, 109 container_of(node, struct acpi_device, wakeup_list);
117 wakeup_list);
118 110
119 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 111 if (!dev->wakeup.flags.valid)
120 spin_unlock(&acpi_device_lock);
121 acpi_set_gpe_type(dev->wakeup.gpe_device,
122 dev->wakeup.gpe_number,
123 ACPI_GPE_TYPE_WAKE_RUN);
124 /* Re-enable it, since set_gpe_type will disable it */
125 acpi_enable_gpe(dev->wakeup.gpe_device,
126 dev->wakeup.gpe_number, ACPI_NOT_ISR);
127 spin_lock(&acpi_device_lock);
128 continue; 112 continue;
129 } 113 if (!dev->wakeup.state.enabled ||
130 114 sleep_state > (u32) dev->wakeup.sleep_state) {
131 if (!dev->wakeup.flags.valid || 115 if (dev->wakeup.flags.run_wake) {
132 !dev->wakeup.state.active || 116 spin_unlock(&acpi_device_lock);
133 (sleep_state > (u32) dev->wakeup.sleep_state)) 117 acpi_set_gpe_type(dev->wakeup.gpe_device,
118 dev->wakeup.gpe_number,
119 ACPI_GPE_TYPE_WAKE_RUN);
120 /* Re-enable it, since set_gpe_type will disable it */
121 acpi_enable_gpe(dev->wakeup.gpe_device,
122 dev->wakeup.gpe_number, ACPI_NOT_ISR);
123 spin_lock(&acpi_device_lock);
124 }
134 continue; 125 continue;
126 }
135 127
136 spin_unlock(&acpi_device_lock); 128 spin_unlock(&acpi_device_lock);
137 acpi_disable_wakeup_device_power(dev); 129 acpi_disable_wakeup_device_power(dev);
@@ -142,7 +134,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
142 acpi_clear_gpe(dev->wakeup.gpe_device, 134 acpi_clear_gpe(dev->wakeup.gpe_device,
143 dev->wakeup.gpe_number, ACPI_NOT_ISR); 135 dev->wakeup.gpe_number, ACPI_NOT_ISR);
144 } 136 }
145 dev->wakeup.state.active = 0;
146 spin_lock(&acpi_device_lock); 137 spin_lock(&acpi_device_lock);
147 } 138 }
148 spin_unlock(&acpi_device_lock); 139 spin_unlock(&acpi_device_lock);
@@ -160,48 +151,20 @@ static int __init acpi_wakeup_device_init(void)
160 struct acpi_device *dev = container_of(node, 151 struct acpi_device *dev = container_of(node,
161 struct acpi_device, 152 struct acpi_device,
162 wakeup_list); 153 wakeup_list);
163
164 /* In case user doesn't load button driver */ 154 /* In case user doesn't load button driver */
165 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 155 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
166 spin_unlock(&acpi_device_lock); 156 continue;
167 acpi_set_gpe_type(dev->wakeup.gpe_device, 157 spin_unlock(&acpi_device_lock);
168 dev->wakeup.gpe_number, 158 acpi_set_gpe_type(dev->wakeup.gpe_device,
169 ACPI_GPE_TYPE_WAKE_RUN); 159 dev->wakeup.gpe_number,
170 acpi_enable_gpe(dev->wakeup.gpe_device, 160 ACPI_GPE_TYPE_WAKE_RUN);
171 dev->wakeup.gpe_number, ACPI_NOT_ISR); 161 acpi_enable_gpe(dev->wakeup.gpe_device,
172 dev->wakeup.state.enabled = 1; 162 dev->wakeup.gpe_number, ACPI_NOT_ISR);
173 spin_lock(&acpi_device_lock); 163 dev->wakeup.state.enabled = 1;
174 } 164 spin_lock(&acpi_device_lock);
175 } 165 }
176 spin_unlock(&acpi_device_lock); 166 spin_unlock(&acpi_device_lock);
177
178 return 0; 167 return 0;
179} 168}
180 169
181late_initcall(acpi_wakeup_device_init); 170late_initcall(acpi_wakeup_device_init);
182
183/*
184 * Disable all wakeup GPEs before entering requested sleep state.
185 * @sleep_state: ACPI state
186 * Since acpi_enter_sleep_state() will disable all
187 * RUNTIME GPEs, we simply mark all GPES that
188 * are not enabled for wakeup from requested state as RUNTIME.
189 */
190void acpi_gpe_sleep_prepare(u32 sleep_state)
191{
192 struct list_head *node, *next;
193
194 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
195 struct acpi_device *dev = container_of(node,
196 struct acpi_device,
197 wakeup_list);
198
199 /* The GPE can wakeup system from this state, don't touch it */
200 if ((u32) dev->wakeup.sleep_state >= sleep_state)
201 continue;
202 /* acpi_set_gpe_type will automatically disable GPE */
203 acpi_set_gpe_type(dev->wakeup.gpe_device,
204 dev->wakeup.gpe_number,
205 ACPI_GPE_TYPE_RUNTIME);
206 }
207}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 8cc9492ffbf2..5f1d85f2ffe4 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
400 u32 table_count; 400 u32 table_count;
401 struct acpi_table_header *table; 401 struct acpi_table_header *table;
402 acpi_physical_address address; 402 acpi_physical_address address;
403 acpi_physical_address rsdt_address; 403 acpi_physical_address uninitialized_var(rsdt_address);
404 u32 length; 404 u32 length;
405 u8 *table_entry; 405 u8 *table_entry;
406 acpi_status status; 406 acpi_status status;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index ad898e10c1a9..5f79b4451212 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -195,6 +195,7 @@ struct acpi_thermal {
195 struct acpi_thermal_trips trips; 195 struct acpi_thermal_trips trips;
196 struct acpi_handle_list devices; 196 struct acpi_handle_list devices;
197 struct timer_list timer; 197 struct timer_list timer;
198 struct mutex lock;
198}; 199};
199 200
200static const struct file_operations acpi_thermal_state_fops = { 201static const struct file_operations acpi_thermal_state_fops = {
@@ -711,6 +712,7 @@ static void acpi_thermal_check(void *data)
711 int result = 0; 712 int result = 0;
712 struct acpi_thermal *tz = data; 713 struct acpi_thermal *tz = data;
713 unsigned long sleep_time = 0; 714 unsigned long sleep_time = 0;
715 unsigned long timeout_jiffies = 0;
714 int i = 0; 716 int i = 0;
715 struct acpi_thermal_state state; 717 struct acpi_thermal_state state;
716 718
@@ -720,11 +722,15 @@ static void acpi_thermal_check(void *data)
720 return; 722 return;
721 } 723 }
722 724
725 /* Check if someone else is already running */
726 if (!mutex_trylock(&tz->lock))
727 return;
728
723 state = tz->state; 729 state = tz->state;
724 730
725 result = acpi_thermal_get_temperature(tz); 731 result = acpi_thermal_get_temperature(tz);
726 if (result) 732 if (result)
727 return; 733 goto unlock;
728 734
729 memset(&tz->state, 0, sizeof(tz->state)); 735 memset(&tz->state, 0, sizeof(tz->state));
730 736
@@ -787,10 +793,13 @@ static void acpi_thermal_check(void *data)
787 * a thermal event occurs). Note that _TSP and _TZD values are 793 * a thermal event occurs). Note that _TSP and _TZD values are
788 * given in 1/10th seconds (we must covert to milliseconds). 794 * given in 1/10th seconds (we must covert to milliseconds).
789 */ 795 */
790 if (tz->state.passive) 796 if (tz->state.passive) {
791 sleep_time = tz->trips.passive.tsp * 100; 797 sleep_time = tz->trips.passive.tsp * 100;
792 else if (tz->polling_frequency > 0) 798 timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
799 } else if (tz->polling_frequency > 0) {
793 sleep_time = tz->polling_frequency * 100; 800 sleep_time = tz->polling_frequency * 100;
801 timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
802 }
794 803
795 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 804 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
796 tz->name, tz->temperature, sleep_time)); 805 tz->name, tz->temperature, sleep_time));
@@ -804,17 +813,16 @@ static void acpi_thermal_check(void *data)
804 del_timer(&(tz->timer)); 813 del_timer(&(tz->timer));
805 } else { 814 } else {
806 if (timer_pending(&(tz->timer))) 815 if (timer_pending(&(tz->timer)))
807 mod_timer(&(tz->timer), 816 mod_timer(&(tz->timer), timeout_jiffies);
808 jiffies + (HZ * sleep_time) / 1000);
809 else { 817 else {
810 tz->timer.data = (unsigned long)tz; 818 tz->timer.data = (unsigned long)tz;
811 tz->timer.function = acpi_thermal_run; 819 tz->timer.function = acpi_thermal_run;
812 tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; 820 tz->timer.expires = timeout_jiffies;
813 add_timer(&(tz->timer)); 821 add_timer(&(tz->timer));
814 } 822 }
815 } 823 }
816 824 unlock:
817 return; 825 mutex_unlock(&tz->lock);
818} 826}
819 827
820/* -------------------------------------------------------------------------- 828/* --------------------------------------------------------------------------
@@ -1251,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device)
1251 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1259 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1252 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1260 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1253 acpi_driver_data(device) = tz; 1261 acpi_driver_data(device) = tz;
1254 1262 mutex_init(&tz->lock);
1255 result = acpi_thermal_get_info(tz); 1263 result = acpi_thermal_get_info(tz);
1256 if (result) 1264 if (result)
1257 goto end; 1265 goto end;
@@ -1321,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1321 } 1329 }
1322 1330
1323 acpi_thermal_remove_fs(device); 1331 acpi_thermal_remove_fs(device);
1324 1332 mutex_destroy(&tz->lock);
1325 kfree(tz); 1333 kfree(tz);
1326 return 0; 1334 return 0;
1327} 1335}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index b8a2095cb5ee..bac956b30c57 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -409,14 +409,17 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
409static int 409static int
410acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) 410acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
411{ 411{
412 int status; 412 int status = AE_OK;
413 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 413 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
414 struct acpi_object_list args = { 1, &arg0 }; 414 struct acpi_object_list args = { 1, &arg0 };
415 415
416 416
417 arg0.integer.value = level; 417 arg0.integer.value = level;
418 status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
419 418
419 if (device->cap._BCM)
420 status = acpi_evaluate_object(device->dev->handle, "_BCM",
421 &args, NULL);
422 device->brightness->curr = level;
420 return status; 423 return status;
421} 424}
422 425
@@ -424,11 +427,11 @@ static int
424acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 427acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
425 unsigned long *level) 428 unsigned long *level)
426{ 429{
427 int status; 430 if (device->cap._BQC)
428 431 return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
429 status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level); 432 level);
430 433 *level = device->brightness->curr;
431 return status; 434 return AE_OK;
432} 435}
433 436
434static int 437static int
@@ -1633,9 +1636,20 @@ static int
1633acpi_video_get_next_level(struct acpi_video_device *device, 1636acpi_video_get_next_level(struct acpi_video_device *device,
1634 u32 level_current, u32 event) 1637 u32 level_current, u32 event)
1635{ 1638{
1636 int min, max, min_above, max_below, i, l; 1639 int min, max, min_above, max_below, i, l, delta = 255;
1637 max = max_below = 0; 1640 max = max_below = 0;
1638 min = min_above = 255; 1641 min = min_above = 255;
1642 /* Find closest level to level_current */
1643 for (i = 0; i < device->brightness->count; i++) {
1644 l = device->brightness->levels[i];
1645 if (abs(l - level_current) < abs(delta)) {
1646 delta = l - level_current;
1647 if (!delta)
1648 break;
1649 }
1650 }
1651 /* Ajust level_current to closest available level */
1652 level_current += delta;
1639 for (i = 0; i < device->brightness->count; i++) { 1653 for (i = 0; i < device->brightness->count; i++) {
1640 l = device->brightness->levels[i]; 1654 l = device->brightness->levels[i];
1641 if (l < min) 1655 if (l < min)