diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-25 17:39:25 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-25 17:39:25 -0400 |
commit | 17e8d03c485931b198fd24b69d19247053f58626 (patch) | |
tree | e8d02dd022fae645e1d1d71d8f93e742b62a22e3 | |
parent | e37f14a5fb85522f3bbf88ece6134c4e610ed598 (diff) | |
parent | 5e2be4e0edff4a1021b6743ca6859129cd8e7067 (diff) |
Merge back earlier 'acpi-assorted' material.
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 2 | ||||
-rw-r--r-- | drivers/acpi/ac.c | 256 | ||||
-rw-r--r-- | drivers/acpi/acpi_lpss.c | 12 | ||||
-rw-r--r-- | drivers/acpi/acpi_platform.c | 7 | ||||
-rw-r--r-- | drivers/acpi/button.c | 9 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 49 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 4 | ||||
-rw-r--r-- | drivers/acpi/sysfs.c | 9 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 43 | ||||
-rw-r--r-- | drivers/acpi/utils.c | 17 | ||||
-rw-r--r-- | drivers/platform/x86/ideapad-laptop.c | 344 |
11 files changed, 335 insertions, 417 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 40c76604199f..d00db60a5e04 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -745,7 +745,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table) | |||
745 | #ifdef CONFIG_HPET_TIMER | 745 | #ifdef CONFIG_HPET_TIMER |
746 | #include <asm/hpet.h> | 746 | #include <asm/hpet.h> |
747 | 747 | ||
748 | static struct __initdata resource *hpet_res; | 748 | static struct resource *hpet_res __initdata; |
749 | 749 | ||
750 | static int __init acpi_parse_hpet(struct acpi_table_header *table) | 750 | static int __init acpi_parse_hpet(struct acpi_table_header *table) |
751 | { | 751 | { |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index f37beaa32750..b9f0d5f4bba5 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -30,10 +30,7 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #ifdef CONFIG_ACPI_PROCFS_POWER | 33 | #include <linux/platform_device.h> |
34 | #include <linux/proc_fs.h> | ||
35 | #include <linux/seq_file.h> | ||
36 | #endif | ||
37 | #include <linux/power_supply.h> | 34 | #include <linux/power_supply.h> |
38 | #include <acpi/acpi_bus.h> | 35 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 36 | #include <acpi/acpi_drivers.h> |
@@ -55,75 +52,30 @@ MODULE_AUTHOR("Paul Diefenbaugh"); | |||
55 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); | 52 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); |
56 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
57 | 54 | ||
58 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
59 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | ||
60 | extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | ||
61 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); | ||
62 | #endif | ||
63 | |||
64 | static int acpi_ac_add(struct acpi_device *device); | ||
65 | static int acpi_ac_remove(struct acpi_device *device); | ||
66 | static void acpi_ac_notify(struct acpi_device *device, u32 event); | ||
67 | |||
68 | static const struct acpi_device_id ac_device_ids[] = { | ||
69 | {"ACPI0003", 0}, | ||
70 | {"", 0}, | ||
71 | }; | ||
72 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); | ||
73 | |||
74 | #ifdef CONFIG_PM_SLEEP | ||
75 | static int acpi_ac_resume(struct device *dev); | ||
76 | #endif | ||
77 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | ||
78 | |||
79 | static int ac_sleep_before_get_state_ms; | 55 | static int ac_sleep_before_get_state_ms; |
80 | 56 | ||
81 | static struct acpi_driver acpi_ac_driver = { | ||
82 | .name = "ac", | ||
83 | .class = ACPI_AC_CLASS, | ||
84 | .ids = ac_device_ids, | ||
85 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
86 | .ops = { | ||
87 | .add = acpi_ac_add, | ||
88 | .remove = acpi_ac_remove, | ||
89 | .notify = acpi_ac_notify, | ||
90 | }, | ||
91 | .drv.pm = &acpi_ac_pm, | ||
92 | }; | ||
93 | |||
94 | struct acpi_ac { | 57 | struct acpi_ac { |
95 | struct power_supply charger; | 58 | struct power_supply charger; |
96 | struct acpi_device * device; | 59 | struct acpi_device *adev; |
60 | struct platform_device *pdev; | ||
97 | unsigned long long state; | 61 | unsigned long long state; |
98 | }; | 62 | }; |
99 | 63 | ||
100 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) | 64 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) |
101 | 65 | ||
102 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
103 | static const struct file_operations acpi_ac_fops = { | ||
104 | .owner = THIS_MODULE, | ||
105 | .open = acpi_ac_open_fs, | ||
106 | .read = seq_read, | ||
107 | .llseek = seq_lseek, | ||
108 | .release = single_release, | ||
109 | }; | ||
110 | #endif | ||
111 | |||
112 | /* -------------------------------------------------------------------------- | 66 | /* -------------------------------------------------------------------------- |
113 | AC Adapter Management | 67 | AC Adapter Management |
114 | -------------------------------------------------------------------------- */ | 68 | -------------------------------------------------------------------------- */ |
115 | 69 | ||
116 | static int acpi_ac_get_state(struct acpi_ac *ac) | 70 | static int acpi_ac_get_state(struct acpi_ac *ac) |
117 | { | 71 | { |
118 | acpi_status status = AE_OK; | 72 | acpi_status status; |
119 | |||
120 | |||
121 | if (!ac) | ||
122 | return -EINVAL; | ||
123 | 73 | ||
124 | status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); | 74 | status = acpi_evaluate_integer(ac->adev->handle, "_PSR", NULL, |
75 | &ac->state); | ||
125 | if (ACPI_FAILURE(status)) { | 76 | if (ACPI_FAILURE(status)) { |
126 | ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); | 77 | ACPI_EXCEPTION((AE_INFO, status, |
78 | "Error reading AC Adapter state")); | ||
127 | ac->state = ACPI_AC_STATUS_UNKNOWN; | 79 | ac->state = ACPI_AC_STATUS_UNKNOWN; |
128 | return -ENODEV; | 80 | return -ENODEV; |
129 | } | 81 | } |
@@ -160,91 +112,13 @@ static enum power_supply_property ac_props[] = { | |||
160 | POWER_SUPPLY_PROP_ONLINE, | 112 | POWER_SUPPLY_PROP_ONLINE, |
161 | }; | 113 | }; |
162 | 114 | ||
163 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
164 | /* -------------------------------------------------------------------------- | ||
165 | FS Interface (/proc) | ||
166 | -------------------------------------------------------------------------- */ | ||
167 | |||
168 | static struct proc_dir_entry *acpi_ac_dir; | ||
169 | |||
170 | static int acpi_ac_seq_show(struct seq_file *seq, void *offset) | ||
171 | { | ||
172 | struct acpi_ac *ac = seq->private; | ||
173 | |||
174 | |||
175 | if (!ac) | ||
176 | return 0; | ||
177 | |||
178 | if (acpi_ac_get_state(ac)) { | ||
179 | seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | seq_puts(seq, "state: "); | ||
184 | switch (ac->state) { | ||
185 | case ACPI_AC_STATUS_OFFLINE: | ||
186 | seq_puts(seq, "off-line\n"); | ||
187 | break; | ||
188 | case ACPI_AC_STATUS_ONLINE: | ||
189 | seq_puts(seq, "on-line\n"); | ||
190 | break; | ||
191 | default: | ||
192 | seq_puts(seq, "unknown\n"); | ||
193 | break; | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int acpi_ac_open_fs(struct inode *inode, struct file *file) | ||
200 | { | ||
201 | return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); | ||
202 | } | ||
203 | |||
204 | static int acpi_ac_add_fs(struct acpi_device *device) | ||
205 | { | ||
206 | struct proc_dir_entry *entry = NULL; | ||
207 | |||
208 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," | ||
209 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
210 | if (!acpi_device_dir(device)) { | ||
211 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
212 | acpi_ac_dir); | ||
213 | if (!acpi_device_dir(device)) | ||
214 | return -ENODEV; | ||
215 | } | ||
216 | |||
217 | /* 'state' [R] */ | ||
218 | entry = proc_create_data(ACPI_AC_FILE_STATE, | ||
219 | S_IRUGO, acpi_device_dir(device), | ||
220 | &acpi_ac_fops, acpi_driver_data(device)); | ||
221 | if (!entry) | ||
222 | return -ENODEV; | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int acpi_ac_remove_fs(struct acpi_device *device) | ||
227 | { | ||
228 | |||
229 | if (acpi_device_dir(device)) { | ||
230 | remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); | ||
231 | |||
232 | remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); | ||
233 | acpi_device_dir(device) = NULL; | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | /* -------------------------------------------------------------------------- | 115 | /* -------------------------------------------------------------------------- |
241 | Driver Model | 116 | Driver Model |
242 | -------------------------------------------------------------------------- */ | 117 | -------------------------------------------------------------------------- */ |
243 | 118 | ||
244 | static void acpi_ac_notify(struct acpi_device *device, u32 event) | 119 | static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) |
245 | { | 120 | { |
246 | struct acpi_ac *ac = acpi_driver_data(device); | 121 | struct acpi_ac *ac = data; |
247 | |||
248 | 122 | ||
249 | if (!ac) | 123 | if (!ac) |
250 | return; | 124 | return; |
@@ -267,10 +141,10 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
267 | msleep(ac_sleep_before_get_state_ms); | 141 | msleep(ac_sleep_before_get_state_ms); |
268 | 142 | ||
269 | acpi_ac_get_state(ac); | 143 | acpi_ac_get_state(ac); |
270 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 144 | acpi_bus_generate_netlink_event(ac->adev->pnp.device_class, |
271 | dev_name(&device->dev), event, | 145 | dev_name(&ac->pdev->dev), |
272 | (u32) ac->state); | 146 | event, (u32) ac->state); |
273 | acpi_notifier_call_chain(device, event, (u32) ac->state); | 147 | acpi_notifier_call_chain(ac->adev, event, (u32) ac->state); |
274 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 148 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
275 | } | 149 | } |
276 | 150 | ||
@@ -295,53 +169,55 @@ static struct dmi_system_id ac_dmi_table[] = { | |||
295 | {}, | 169 | {}, |
296 | }; | 170 | }; |
297 | 171 | ||
298 | static int acpi_ac_add(struct acpi_device *device) | 172 | static int acpi_ac_probe(struct platform_device *pdev) |
299 | { | 173 | { |
300 | int result = 0; | 174 | int result = 0; |
301 | struct acpi_ac *ac = NULL; | 175 | struct acpi_ac *ac = NULL; |
176 | struct acpi_device *adev; | ||
302 | 177 | ||
303 | 178 | if (!pdev) | |
304 | if (!device) | ||
305 | return -EINVAL; | 179 | return -EINVAL; |
306 | 180 | ||
181 | result = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); | ||
182 | if (result) | ||
183 | return -ENODEV; | ||
184 | |||
307 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); | 185 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); |
308 | if (!ac) | 186 | if (!ac) |
309 | return -ENOMEM; | 187 | return -ENOMEM; |
310 | 188 | ||
311 | ac->device = device; | 189 | strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); |
312 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | 190 | strcpy(acpi_device_class(adev), ACPI_AC_CLASS); |
313 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); | 191 | ac->adev = adev; |
314 | device->driver_data = ac; | 192 | ac->pdev = pdev; |
193 | platform_set_drvdata(pdev, ac); | ||
315 | 194 | ||
316 | result = acpi_ac_get_state(ac); | 195 | result = acpi_ac_get_state(ac); |
317 | if (result) | 196 | if (result) |
318 | goto end; | 197 | goto end; |
319 | 198 | ||
320 | #ifdef CONFIG_ACPI_PROCFS_POWER | 199 | ac->charger.name = acpi_device_bid(adev); |
321 | result = acpi_ac_add_fs(device); | ||
322 | #endif | ||
323 | if (result) | ||
324 | goto end; | ||
325 | ac->charger.name = acpi_device_bid(device); | ||
326 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; | 200 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; |
327 | ac->charger.properties = ac_props; | 201 | ac->charger.properties = ac_props; |
328 | ac->charger.num_properties = ARRAY_SIZE(ac_props); | 202 | ac->charger.num_properties = ARRAY_SIZE(ac_props); |
329 | ac->charger.get_property = get_ac_property; | 203 | ac->charger.get_property = get_ac_property; |
330 | result = power_supply_register(&ac->device->dev, &ac->charger); | 204 | result = power_supply_register(&pdev->dev, &ac->charger); |
331 | if (result) | 205 | if (result) |
332 | goto end; | 206 | goto end; |
333 | 207 | ||
208 | result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), | ||
209 | ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler, ac); | ||
210 | if (result) { | ||
211 | power_supply_unregister(&ac->charger); | ||
212 | goto end; | ||
213 | } | ||
334 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 214 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
335 | acpi_device_name(device), acpi_device_bid(device), | 215 | acpi_device_name(adev), acpi_device_bid(adev), |
336 | ac->state ? "on-line" : "off-line"); | 216 | ac->state ? "on-line" : "off-line"); |
337 | 217 | ||
338 | end: | 218 | end: |
339 | if (result) { | 219 | if (result) |
340 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
341 | acpi_ac_remove_fs(device); | ||
342 | #endif | ||
343 | kfree(ac); | 220 | kfree(ac); |
344 | } | ||
345 | 221 | ||
346 | dmi_check_system(ac_dmi_table); | 222 | dmi_check_system(ac_dmi_table); |
347 | return result; | 223 | return result; |
@@ -356,7 +232,7 @@ static int acpi_ac_resume(struct device *dev) | |||
356 | if (!dev) | 232 | if (!dev) |
357 | return -EINVAL; | 233 | return -EINVAL; |
358 | 234 | ||
359 | ac = acpi_driver_data(to_acpi_device(dev)); | 235 | ac = platform_get_drvdata(to_platform_device(dev)); |
360 | if (!ac) | 236 | if (!ac) |
361 | return -EINVAL; | 237 | return -EINVAL; |
362 | 238 | ||
@@ -368,28 +244,44 @@ static int acpi_ac_resume(struct device *dev) | |||
368 | return 0; | 244 | return 0; |
369 | } | 245 | } |
370 | #endif | 246 | #endif |
247 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | ||
371 | 248 | ||
372 | static int acpi_ac_remove(struct acpi_device *device) | 249 | static int acpi_ac_remove(struct platform_device *pdev) |
373 | { | 250 | { |
374 | struct acpi_ac *ac = NULL; | 251 | struct acpi_ac *ac; |
375 | |||
376 | 252 | ||
377 | if (!device || !acpi_driver_data(device)) | 253 | if (!pdev) |
378 | return -EINVAL; | 254 | return -EINVAL; |
379 | 255 | ||
380 | ac = acpi_driver_data(device); | 256 | acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), |
257 | ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler); | ||
381 | 258 | ||
259 | ac = platform_get_drvdata(pdev); | ||
382 | if (ac->charger.dev) | 260 | if (ac->charger.dev) |
383 | power_supply_unregister(&ac->charger); | 261 | power_supply_unregister(&ac->charger); |
384 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
385 | acpi_ac_remove_fs(device); | ||
386 | #endif | ||
387 | 262 | ||
388 | kfree(ac); | 263 | kfree(ac); |
389 | 264 | ||
390 | return 0; | 265 | return 0; |
391 | } | 266 | } |
392 | 267 | ||
268 | static const struct acpi_device_id acpi_ac_match[] = { | ||
269 | { "ACPI0003", 0 }, | ||
270 | { } | ||
271 | }; | ||
272 | MODULE_DEVICE_TABLE(acpi, acpi_ac_match); | ||
273 | |||
274 | static struct platform_driver acpi_ac_driver = { | ||
275 | .probe = acpi_ac_probe, | ||
276 | .remove = acpi_ac_remove, | ||
277 | .driver = { | ||
278 | .name = "acpi-ac", | ||
279 | .owner = THIS_MODULE, | ||
280 | .pm = &acpi_ac_pm_ops, | ||
281 | .acpi_match_table = ACPI_PTR(acpi_ac_match), | ||
282 | }, | ||
283 | }; | ||
284 | |||
393 | static int __init acpi_ac_init(void) | 285 | static int __init acpi_ac_init(void) |
394 | { | 286 | { |
395 | int result; | 287 | int result; |
@@ -397,34 +289,16 @@ static int __init acpi_ac_init(void) | |||
397 | if (acpi_disabled) | 289 | if (acpi_disabled) |
398 | return -ENODEV; | 290 | return -ENODEV; |
399 | 291 | ||
400 | #ifdef CONFIG_ACPI_PROCFS_POWER | 292 | result = platform_driver_register(&acpi_ac_driver); |
401 | acpi_ac_dir = acpi_lock_ac_dir(); | 293 | if (result < 0) |
402 | if (!acpi_ac_dir) | ||
403 | return -ENODEV; | 294 | return -ENODEV; |
404 | #endif | ||
405 | |||
406 | result = acpi_bus_register_driver(&acpi_ac_driver); | ||
407 | if (result < 0) { | ||
408 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
409 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
410 | #endif | ||
411 | return -ENODEV; | ||
412 | } | ||
413 | 295 | ||
414 | return 0; | 296 | return 0; |
415 | } | 297 | } |
416 | 298 | ||
417 | static void __exit acpi_ac_exit(void) | 299 | static void __exit acpi_ac_exit(void) |
418 | { | 300 | { |
419 | 301 | platform_driver_unregister(&acpi_ac_driver); | |
420 | acpi_bus_unregister_driver(&acpi_ac_driver); | ||
421 | |||
422 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
423 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
424 | #endif | ||
425 | |||
426 | return; | ||
427 | } | 302 | } |
428 | |||
429 | module_init(acpi_ac_init); | 303 | module_init(acpi_ac_init); |
430 | module_exit(acpi_ac_exit); | 304 | module_exit(acpi_ac_exit); |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index fb78bb9ad8f6..d3961014aad7 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -30,6 +30,7 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
30 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ | 30 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ |
31 | #define LPSS_GENERAL 0x08 | 31 | #define LPSS_GENERAL 0x08 |
32 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) | 32 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) |
33 | #define LPSS_GENERAL_UART_RTS_OVRD BIT(3) | ||
33 | #define LPSS_SW_LTR 0x10 | 34 | #define LPSS_SW_LTR 0x10 |
34 | #define LPSS_AUTO_LTR 0x14 | 35 | #define LPSS_AUTO_LTR 0x14 |
35 | #define LPSS_TX_INT 0x20 | 36 | #define LPSS_TX_INT 0x20 |
@@ -68,11 +69,16 @@ struct lpss_private_data { | |||
68 | 69 | ||
69 | static void lpss_uart_setup(struct lpss_private_data *pdata) | 70 | static void lpss_uart_setup(struct lpss_private_data *pdata) |
70 | { | 71 | { |
71 | unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; | 72 | unsigned int offset; |
72 | u32 reg; | 73 | u32 reg; |
73 | 74 | ||
74 | reg = readl(pdata->mmio_base + tx_int_offset); | 75 | offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; |
75 | writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset); | 76 | reg = readl(pdata->mmio_base + offset); |
77 | writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + offset); | ||
78 | |||
79 | offset = pdata->dev_desc->prv_offset + LPSS_GENERAL; | ||
80 | reg = readl(pdata->mmio_base + offset); | ||
81 | writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset); | ||
76 | } | 82 | } |
77 | 83 | ||
78 | static struct lpss_device_desc lpt_dev_desc = { | 84 | static struct lpss_device_desc lpt_dev_desc = { |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1bde12708f9e..8a4cfc7e71f0 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -29,6 +29,13 @@ ACPI_MODULE_NAME("platform"); | |||
29 | static const struct acpi_device_id acpi_platform_device_ids[] = { | 29 | static const struct acpi_device_id acpi_platform_device_ids[] = { |
30 | 30 | ||
31 | { "PNP0D40" }, | 31 | { "PNP0D40" }, |
32 | { "ACPI0003" }, | ||
33 | { "VPC2004" }, | ||
34 | { "BCM4752" }, | ||
35 | |||
36 | /* Intel Smart Sound Technology */ | ||
37 | { "INT33C8" }, | ||
38 | { "80860F28" }, | ||
32 | 39 | ||
33 | { } | 40 | { } |
34 | }; | 41 | }; |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index a55773801c5f..c971929d75c2 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -383,18 +383,15 @@ static int acpi_button_add(struct acpi_device *device) | |||
383 | 383 | ||
384 | switch (button->type) { | 384 | switch (button->type) { |
385 | case ACPI_BUTTON_TYPE_POWER: | 385 | case ACPI_BUTTON_TYPE_POWER: |
386 | input->evbit[0] = BIT_MASK(EV_KEY); | 386 | input_set_capability(input, EV_KEY, KEY_POWER); |
387 | set_bit(KEY_POWER, input->keybit); | ||
388 | break; | 387 | break; |
389 | 388 | ||
390 | case ACPI_BUTTON_TYPE_SLEEP: | 389 | case ACPI_BUTTON_TYPE_SLEEP: |
391 | input->evbit[0] = BIT_MASK(EV_KEY); | 390 | input_set_capability(input, EV_KEY, KEY_SLEEP); |
392 | set_bit(KEY_SLEEP, input->keybit); | ||
393 | break; | 391 | break; |
394 | 392 | ||
395 | case ACPI_BUTTON_TYPE_LID: | 393 | case ACPI_BUTTON_TYPE_LID: |
396 | input->evbit[0] = BIT_MASK(EV_SW); | 394 | input_set_capability(input, EV_SW, SW_LID); |
397 | set_bit(SW_LID, input->swbit); | ||
398 | break; | 395 | break; |
399 | } | 396 | } |
400 | 397 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a06d98374705..d5309fd49458 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | /* Uncomment next line to get verbose printout */ | 29 | /* Uncomment next line to get verbose printout */ |
30 | /* #define DEBUG */ | 30 | /* #define DEBUG */ |
31 | #define pr_fmt(fmt) "ACPI : EC: " fmt | ||
31 | 32 | ||
32 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -49,9 +50,6 @@ | |||
49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 50 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
50 | #define ACPI_EC_FILE_INFO "info" | 51 | #define ACPI_EC_FILE_INFO "info" |
51 | 52 | ||
52 | #undef PREFIX | ||
53 | #define PREFIX "ACPI: EC: " | ||
54 | |||
55 | /* EC status register */ | 53 | /* EC status register */ |
56 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 54 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
57 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 55 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
@@ -131,26 +129,26 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | |||
131 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 129 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
132 | { | 130 | { |
133 | u8 x = inb(ec->command_addr); | 131 | u8 x = inb(ec->command_addr); |
134 | pr_debug(PREFIX "---> status = 0x%2.2x\n", x); | 132 | pr_debug("---> status = 0x%2.2x\n", x); |
135 | return x; | 133 | return x; |
136 | } | 134 | } |
137 | 135 | ||
138 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | 136 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
139 | { | 137 | { |
140 | u8 x = inb(ec->data_addr); | 138 | u8 x = inb(ec->data_addr); |
141 | pr_debug(PREFIX "---> data = 0x%2.2x\n", x); | 139 | pr_debug("---> data = 0x%2.2x\n", x); |
142 | return x; | 140 | return x; |
143 | } | 141 | } |
144 | 142 | ||
145 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 143 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
146 | { | 144 | { |
147 | pr_debug(PREFIX "<--- command = 0x%2.2x\n", command); | 145 | pr_debug("<--- command = 0x%2.2x\n", command); |
148 | outb(command, ec->command_addr); | 146 | outb(command, ec->command_addr); |
149 | } | 147 | } |
150 | 148 | ||
151 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 149 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
152 | { | 150 | { |
153 | pr_debug(PREFIX "<--- data = 0x%2.2x\n", data); | 151 | pr_debug("<--- data = 0x%2.2x\n", data); |
154 | outb(data, ec->data_addr); | 152 | outb(data, ec->data_addr); |
155 | } | 153 | } |
156 | 154 | ||
@@ -241,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec) | |||
241 | } | 239 | } |
242 | advance_transaction(ec, acpi_ec_read_status(ec)); | 240 | advance_transaction(ec, acpi_ec_read_status(ec)); |
243 | } while (time_before(jiffies, delay)); | 241 | } while (time_before(jiffies, delay)); |
244 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 242 | pr_debug("controller reset, restart transaction\n"); |
245 | spin_lock_irqsave(&ec->lock, flags); | 243 | spin_lock_irqsave(&ec->lock, flags); |
246 | start_transaction(ec); | 244 | start_transaction(ec); |
247 | spin_unlock_irqrestore(&ec->lock, flags); | 245 | spin_unlock_irqrestore(&ec->lock, flags); |
@@ -309,12 +307,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
309 | } | 307 | } |
310 | } | 308 | } |
311 | if (ec_wait_ibf0(ec)) { | 309 | if (ec_wait_ibf0(ec)) { |
312 | pr_err(PREFIX "input buffer is not empty, " | 310 | pr_err("input buffer is not empty, " |
313 | "aborting transaction\n"); | 311 | "aborting transaction\n"); |
314 | status = -ETIME; | 312 | status = -ETIME; |
315 | goto end; | 313 | goto end; |
316 | } | 314 | } |
317 | pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n", | 315 | pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", |
318 | t->command, t->wdata ? t->wdata[0] : 0); | 316 | t->command, t->wdata ? t->wdata[0] : 0); |
319 | /* disable GPE during transaction if storm is detected */ | 317 | /* disable GPE during transaction if storm is detected */ |
320 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 318 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
@@ -331,12 +329,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
331 | /* It is safe to enable the GPE outside of the transaction. */ | 329 | /* It is safe to enable the GPE outside of the transaction. */ |
332 | acpi_enable_gpe(NULL, ec->gpe); | 330 | acpi_enable_gpe(NULL, ec->gpe); |
333 | } else if (t->irq_count > ec_storm_threshold) { | 331 | } else if (t->irq_count > ec_storm_threshold) { |
334 | pr_info(PREFIX "GPE storm detected(%d GPEs), " | 332 | pr_info("GPE storm detected(%d GPEs), " |
335 | "transactions will use polling mode\n", | 333 | "transactions will use polling mode\n", |
336 | t->irq_count); | 334 | t->irq_count); |
337 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 335 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
338 | } | 336 | } |
339 | pr_debug(PREFIX "transaction end\n"); | 337 | pr_debug("transaction end\n"); |
340 | end: | 338 | end: |
341 | if (ec->global_lock) | 339 | if (ec->global_lock) |
342 | acpi_release_global_lock(glk); | 340 | acpi_release_global_lock(glk); |
@@ -570,12 +568,12 @@ static void acpi_ec_run(void *cxt) | |||
570 | struct acpi_ec_query_handler *handler = cxt; | 568 | struct acpi_ec_query_handler *handler = cxt; |
571 | if (!handler) | 569 | if (!handler) |
572 | return; | 570 | return; |
573 | pr_debug(PREFIX "start query execution\n"); | 571 | pr_debug("start query execution\n"); |
574 | if (handler->func) | 572 | if (handler->func) |
575 | handler->func(handler->data); | 573 | handler->func(handler->data); |
576 | else if (handler->handle) | 574 | else if (handler->handle) |
577 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 575 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
578 | pr_debug(PREFIX "stop query execution\n"); | 576 | pr_debug("stop query execution\n"); |
579 | kfree(handler); | 577 | kfree(handler); |
580 | } | 578 | } |
581 | 579 | ||
@@ -593,7 +591,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec) | |||
593 | if (!copy) | 591 | if (!copy) |
594 | return -ENOMEM; | 592 | return -ENOMEM; |
595 | memcpy(copy, handler, sizeof(*copy)); | 593 | memcpy(copy, handler, sizeof(*copy)); |
596 | pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value); | 594 | pr_debug("push query execution (0x%2x) on queue\n", |
595 | value); | ||
597 | return acpi_os_execute((copy->func) ? | 596 | return acpi_os_execute((copy->func) ? |
598 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 597 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
599 | acpi_ec_run, copy); | 598 | acpi_ec_run, copy); |
@@ -616,7 +615,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
616 | { | 615 | { |
617 | if (state & ACPI_EC_FLAG_SCI) { | 616 | if (state & ACPI_EC_FLAG_SCI) { |
618 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 617 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
619 | pr_debug(PREFIX "push gpe query to the queue\n"); | 618 | pr_debug("push gpe query to the queue\n"); |
620 | return acpi_os_execute(OSL_NOTIFY_HANDLER, | 619 | return acpi_os_execute(OSL_NOTIFY_HANDLER, |
621 | acpi_ec_gpe_query, ec); | 620 | acpi_ec_gpe_query, ec); |
622 | } | 621 | } |
@@ -630,7 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | |||
630 | struct acpi_ec *ec = data; | 629 | struct acpi_ec *ec = data; |
631 | u8 status = acpi_ec_read_status(ec); | 630 | u8 status = acpi_ec_read_status(ec); |
632 | 631 | ||
633 | pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status); | 632 | pr_debug("~~~> interrupt, status:0x%02x\n", status); |
634 | 633 | ||
635 | advance_transaction(ec, status); | 634 | advance_transaction(ec, status); |
636 | if (ec_transaction_done(ec) && | 635 | if (ec_transaction_done(ec) && |
@@ -776,7 +775,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
776 | * The AE_NOT_FOUND error will be ignored and OS | 775 | * The AE_NOT_FOUND error will be ignored and OS |
777 | * continue to initialize EC. | 776 | * continue to initialize EC. |
778 | */ | 777 | */ |
779 | printk(KERN_ERR "Fail in evaluating the _REG object" | 778 | pr_err("Fail in evaluating the _REG object" |
780 | " of EC device. Broken bios is suspected.\n"); | 779 | " of EC device. Broken bios is suspected.\n"); |
781 | } else { | 780 | } else { |
782 | acpi_remove_gpe_handler(NULL, ec->gpe, | 781 | acpi_remove_gpe_handler(NULL, ec->gpe, |
@@ -795,10 +794,10 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
795 | acpi_disable_gpe(NULL, ec->gpe); | 794 | acpi_disable_gpe(NULL, ec->gpe); |
796 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 795 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
797 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 796 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
798 | pr_err(PREFIX "failed to remove space handler\n"); | 797 | pr_err("failed to remove space handler\n"); |
799 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, | 798 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
800 | &acpi_ec_gpe_handler))) | 799 | &acpi_ec_gpe_handler))) |
801 | pr_err(PREFIX "failed to remove gpe handler\n"); | 800 | pr_err("failed to remove gpe handler\n"); |
802 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | 801 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
803 | } | 802 | } |
804 | 803 | ||
@@ -840,7 +839,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
840 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); | 839 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); |
841 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); | 840 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); |
842 | 841 | ||
843 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 842 | pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
844 | ec->gpe, ec->command_addr, ec->data_addr); | 843 | ec->gpe, ec->command_addr, ec->data_addr); |
845 | 844 | ||
846 | ret = ec_install_handlers(ec); | 845 | ret = ec_install_handlers(ec); |
@@ -931,7 +930,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) | |||
931 | /* MSI EC needs special treatment, enable it */ | 930 | /* MSI EC needs special treatment, enable it */ |
932 | static int ec_flag_msi(const struct dmi_system_id *id) | 931 | static int ec_flag_msi(const struct dmi_system_id *id) |
933 | { | 932 | { |
934 | printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n"); | 933 | pr_debug("Detected MSI hardware, enabling workarounds.\n"); |
935 | EC_FLAGS_MSI = 1; | 934 | EC_FLAGS_MSI = 1; |
936 | EC_FLAGS_VALIDATE_ECDT = 1; | 935 | EC_FLAGS_VALIDATE_ECDT = 1; |
937 | return 0; | 936 | return 0; |
@@ -1010,7 +1009,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1010 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 1009 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
1011 | (struct acpi_table_header **)&ecdt_ptr); | 1010 | (struct acpi_table_header **)&ecdt_ptr); |
1012 | if (ACPI_SUCCESS(status)) { | 1011 | if (ACPI_SUCCESS(status)) { |
1013 | pr_info(PREFIX "EC description table is found, configuring boot EC\n"); | 1012 | pr_info("EC description table is found, configuring boot EC\n"); |
1014 | boot_ec->command_addr = ecdt_ptr->control.address; | 1013 | boot_ec->command_addr = ecdt_ptr->control.address; |
1015 | boot_ec->data_addr = ecdt_ptr->data.address; | 1014 | boot_ec->data_addr = ecdt_ptr->data.address; |
1016 | boot_ec->gpe = ecdt_ptr->gpe; | 1015 | boot_ec->gpe = ecdt_ptr->gpe; |
@@ -1030,7 +1029,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1030 | 1029 | ||
1031 | /* This workaround is needed only on some broken machines, | 1030 | /* This workaround is needed only on some broken machines, |
1032 | * which require early EC, but fail to provide ECDT */ | 1031 | * which require early EC, but fail to provide ECDT */ |
1033 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 1032 | pr_debug("Look up EC in DSDT\n"); |
1034 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | 1033 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, |
1035 | boot_ec, NULL); | 1034 | boot_ec, NULL); |
1036 | /* Check that acpi_get_devices actually find something */ | 1035 | /* Check that acpi_get_devices actually find something */ |
@@ -1042,7 +1041,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1042 | saved_ec->data_addr != boot_ec->data_addr || | 1041 | saved_ec->data_addr != boot_ec->data_addr || |
1043 | saved_ec->gpe != boot_ec->gpe || | 1042 | saved_ec->gpe != boot_ec->gpe || |
1044 | saved_ec->handle != boot_ec->handle) | 1043 | saved_ec->handle != boot_ec->handle) |
1045 | pr_info(PREFIX "ASUSTek keeps feeding us with broken " | 1044 | pr_info("ASUSTek keeps feeding us with broken " |
1046 | "ECDT tables, which are very hard to workaround. " | 1045 | "ECDT tables, which are very hard to workaround. " |
1047 | "Trying to use DSDT EC info instead. Please send " | 1046 | "Trying to use DSDT EC info instead. Please send " |
1048 | "output of acpidump to linux-acpi@vger.kernel.org\n"); | 1047 | "output of acpidump to linux-acpi@vger.kernel.org\n"); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..4923dd4232b3 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -820,7 +820,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) | |||
820 | 820 | ||
821 | void acpi_os_sleep(u64 ms) | 821 | void acpi_os_sleep(u64 ms) |
822 | { | 822 | { |
823 | schedule_timeout_interruptible(msecs_to_jiffies(ms)); | 823 | msleep(ms); |
824 | } | 824 | } |
825 | 825 | ||
826 | void acpi_os_stall(u32 us) | 826 | void acpi_os_stall(u32 us) |
@@ -1335,7 +1335,7 @@ static int __init acpi_os_name_setup(char *str) | |||
1335 | if (!str || !*str) | 1335 | if (!str || !*str) |
1336 | return 0; | 1336 | return 0; |
1337 | 1337 | ||
1338 | for (; count-- && str && *str; str++) { | 1338 | for (; count-- && *str; str++) { |
1339 | if (isalnum(*str) || *str == ' ' || *str == ':') | 1339 | if (isalnum(*str) || *str == ' ' || *str == ':') |
1340 | *p++ = *str; | 1340 | *p++ = *str; |
1341 | else if (*str == '\'' || *str == '"') | 1341 | else if (*str == '\'' || *str == '"') |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 05306a59aedc..b55778704444 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -564,6 +564,7 @@ static ssize_t counter_set(struct kobject *kobj, | |||
564 | acpi_event_status status; | 564 | acpi_event_status status; |
565 | acpi_handle handle; | 565 | acpi_handle handle; |
566 | int result = 0; | 566 | int result = 0; |
567 | unsigned long tmp; | ||
567 | 568 | ||
568 | if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { | 569 | if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { |
569 | int i; | 570 | int i; |
@@ -596,8 +597,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
596 | else if (!strcmp(buf, "clear\n") && | 597 | else if (!strcmp(buf, "clear\n") && |
597 | (status & ACPI_EVENT_FLAG_SET)) | 598 | (status & ACPI_EVENT_FLAG_SET)) |
598 | result = acpi_clear_gpe(handle, index); | 599 | result = acpi_clear_gpe(handle, index); |
600 | else if (!kstrtoul(buf, 0, &tmp)) | ||
601 | all_counters[index].count = tmp; | ||
599 | else | 602 | else |
600 | all_counters[index].count = strtoul(buf, NULL, 0); | 603 | result = -EINVAL; |
601 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { | 604 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { |
602 | int event = index - num_gpes; | 605 | int event = index - num_gpes; |
603 | if (!strcmp(buf, "disable\n") && | 606 | if (!strcmp(buf, "disable\n") && |
@@ -609,8 +612,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
609 | else if (!strcmp(buf, "clear\n") && | 612 | else if (!strcmp(buf, "clear\n") && |
610 | (status & ACPI_EVENT_FLAG_SET)) | 613 | (status & ACPI_EVENT_FLAG_SET)) |
611 | result = acpi_clear_event(event); | 614 | result = acpi_clear_event(event); |
615 | else if (!kstrtoul(buf, 0, &tmp)) | ||
616 | all_counters[index].count = tmp; | ||
612 | else | 617 | else |
613 | all_counters[index].count = strtoul(buf, NULL, 0); | 618 | result = -EINVAL; |
614 | } else | 619 | } else |
615 | all_counters[index].count = strtoul(buf, NULL, 0); | 620 | all_counters[index].count = strtoul(buf, NULL, 0); |
616 | 621 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6a0329340b42..e600b5dbfcb6 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -299,8 +299,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
300 | "No critical threshold\n")); | 300 | "No critical threshold\n")); |
301 | } else if (tmp <= 2732) { | 301 | } else if (tmp <= 2732) { |
302 | printk(KERN_WARNING FW_BUG "Invalid critical threshold " | 302 | pr_warn(FW_BUG "Invalid critical threshold (%llu)\n", |
303 | "(%llu)\n", tmp); | 303 | tmp); |
304 | tz->trips.critical.flags.valid = 0; | 304 | tz->trips.critical.flags.valid = 0; |
305 | } else { | 305 | } else { |
306 | tz->trips.critical.flags.valid = 1; | 306 | tz->trips.critical.flags.valid = 1; |
@@ -317,8 +317,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
317 | * Allow override critical threshold | 317 | * Allow override critical threshold |
318 | */ | 318 | */ |
319 | if (crt_k > tz->trips.critical.temperature) | 319 | if (crt_k > tz->trips.critical.temperature) |
320 | printk(KERN_WARNING PREFIX | 320 | pr_warn(PREFIX "Critical threshold %d C\n", |
321 | "Critical threshold %d C\n", crt); | 321 | crt); |
322 | tz->trips.critical.temperature = crt_k; | 322 | tz->trips.critical.temperature = crt_k; |
323 | } | 323 | } |
324 | } | 324 | } |
@@ -390,8 +390,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
390 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", | 390 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", |
391 | NULL, &devices); | 391 | NULL, &devices); |
392 | if (ACPI_FAILURE(status)) { | 392 | if (ACPI_FAILURE(status)) { |
393 | printk(KERN_WARNING PREFIX | 393 | pr_warn(PREFIX "Invalid passive threshold\n"); |
394 | "Invalid passive threshold\n"); | ||
395 | tz->trips.passive.flags.valid = 0; | 394 | tz->trips.passive.flags.valid = 0; |
396 | } | 395 | } |
397 | else | 396 | else |
@@ -453,8 +452,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
453 | status = acpi_evaluate_reference(tz->device->handle, | 452 | status = acpi_evaluate_reference(tz->device->handle, |
454 | name, NULL, &devices); | 453 | name, NULL, &devices); |
455 | if (ACPI_FAILURE(status)) { | 454 | if (ACPI_FAILURE(status)) { |
456 | printk(KERN_WARNING PREFIX | 455 | pr_warn(PREFIX "Invalid active%d threshold\n", |
457 | "Invalid active%d threshold\n", i); | 456 | i); |
458 | tz->trips.active[i].flags.valid = 0; | 457 | tz->trips.active[i].flags.valid = 0; |
459 | } | 458 | } |
460 | else | 459 | else |
@@ -505,7 +504,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
505 | valid |= tz->trips.active[i].flags.valid; | 504 | valid |= tz->trips.active[i].flags.valid; |
506 | 505 | ||
507 | if (!valid) { | 506 | if (!valid) { |
508 | printk(KERN_WARNING FW_BUG "No valid trip found\n"); | 507 | pr_warn(FW_BUG "No valid trip found\n"); |
509 | return -ENODEV; | 508 | return -ENODEV; |
510 | } | 509 | } |
511 | return 0; | 510 | return 0; |
@@ -923,8 +922,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
923 | acpi_bus_private_data_handler, | 922 | acpi_bus_private_data_handler, |
924 | tz->thermal_zone); | 923 | tz->thermal_zone); |
925 | if (ACPI_FAILURE(status)) { | 924 | if (ACPI_FAILURE(status)) { |
926 | printk(KERN_ERR PREFIX | 925 | pr_err(PREFIX "Error attaching device data\n"); |
927 | "Error attaching device data\n"); | ||
928 | return -ENODEV; | 926 | return -ENODEV; |
929 | } | 927 | } |
930 | 928 | ||
@@ -1094,9 +1092,8 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1094 | if (result) | 1092 | if (result) |
1095 | goto free_memory; | 1093 | goto free_memory; |
1096 | 1094 | ||
1097 | printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", | 1095 | pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), |
1098 | acpi_device_name(device), acpi_device_bid(device), | 1096 | acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); |
1099 | KELVIN_TO_CELSIUS(tz->temperature)); | ||
1100 | goto end; | 1097 | goto end; |
1101 | 1098 | ||
1102 | free_memory: | 1099 | free_memory: |
@@ -1159,24 +1156,24 @@ static int acpi_thermal_resume(struct device *dev) | |||
1159 | static int thermal_act(const struct dmi_system_id *d) { | 1156 | static int thermal_act(const struct dmi_system_id *d) { |
1160 | 1157 | ||
1161 | if (act == 0) { | 1158 | if (act == 0) { |
1162 | printk(KERN_NOTICE "ACPI: %s detected: " | 1159 | pr_notice(PREFIX "%s detected: " |
1163 | "disabling all active thermal trip points\n", d->ident); | 1160 | "disabling all active thermal trip points\n", d->ident); |
1164 | act = -1; | 1161 | act = -1; |
1165 | } | 1162 | } |
1166 | return 0; | 1163 | return 0; |
1167 | } | 1164 | } |
1168 | static int thermal_nocrt(const struct dmi_system_id *d) { | 1165 | static int thermal_nocrt(const struct dmi_system_id *d) { |
1169 | 1166 | ||
1170 | printk(KERN_NOTICE "ACPI: %s detected: " | 1167 | pr_notice(PREFIX "%s detected: " |
1171 | "disabling all critical thermal trip point actions.\n", d->ident); | 1168 | "disabling all critical thermal trip point actions.\n", d->ident); |
1172 | nocrt = 1; | 1169 | nocrt = 1; |
1173 | return 0; | 1170 | return 0; |
1174 | } | 1171 | } |
1175 | static int thermal_tzp(const struct dmi_system_id *d) { | 1172 | static int thermal_tzp(const struct dmi_system_id *d) { |
1176 | 1173 | ||
1177 | if (tzp == 0) { | 1174 | if (tzp == 0) { |
1178 | printk(KERN_NOTICE "ACPI: %s detected: " | 1175 | pr_notice(PREFIX "%s detected: " |
1179 | "enabling thermal zone polling\n", d->ident); | 1176 | "enabling thermal zone polling\n", d->ident); |
1180 | tzp = 300; /* 300 dS = 30 Seconds */ | 1177 | tzp = 300; /* 300 dS = 30 Seconds */ |
1181 | } | 1178 | } |
1182 | return 0; | 1179 | return 0; |
@@ -1184,8 +1181,8 @@ static int thermal_tzp(const struct dmi_system_id *d) { | |||
1184 | static int thermal_psv(const struct dmi_system_id *d) { | 1181 | static int thermal_psv(const struct dmi_system_id *d) { |
1185 | 1182 | ||
1186 | if (psv == 0) { | 1183 | if (psv == 0) { |
1187 | printk(KERN_NOTICE "ACPI: %s detected: " | 1184 | pr_notice(PREFIX "%s detected: " |
1188 | "disabling all passive thermal trip points\n", d->ident); | 1185 | "disabling all passive thermal trip points\n", d->ident); |
1189 | psv = -1; | 1186 | psv = -1; |
1190 | } | 1187 | } |
1191 | return 0; | 1188 | return 0; |
@@ -1238,7 +1235,7 @@ static int __init acpi_thermal_init(void) | |||
1238 | dmi_check_system(thermal_dmi_table); | 1235 | dmi_check_system(thermal_dmi_table); |
1239 | 1236 | ||
1240 | if (off) { | 1237 | if (off) { |
1241 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); | 1238 | pr_notice(PREFIX "thermal control disabled\n"); |
1242 | return -ENODEV; | 1239 | return -ENODEV; |
1243 | } | 1240 | } |
1244 | 1241 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 552248b0005b..fc2cd3284080 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -169,11 +169,20 @@ acpi_extract_package(union acpi_object *package, | |||
169 | /* | 169 | /* |
170 | * Validate output buffer. | 170 | * Validate output buffer. |
171 | */ | 171 | */ |
172 | if (buffer->length < size_required) { | 172 | if (buffer->length == ACPI_ALLOCATE_BUFFER) { |
173 | buffer->pointer = ACPI_ALLOCATE(size_required); | ||
174 | if (!buffer->pointer) | ||
175 | return AE_NO_MEMORY; | ||
173 | buffer->length = size_required; | 176 | buffer->length = size_required; |
174 | return AE_BUFFER_OVERFLOW; | 177 | memset(buffer->pointer, 0, size_required); |
175 | } else if (buffer->length != size_required || !buffer->pointer) { | 178 | } else { |
176 | return AE_BAD_PARAMETER; | 179 | if (buffer->length < size_required) { |
180 | buffer->length = size_required; | ||
181 | return AE_BUFFER_OVERFLOW; | ||
182 | } else if (buffer->length != size_required || | ||
183 | !buffer->pointer) { | ||
184 | return AE_BAD_PARAMETER; | ||
185 | } | ||
177 | } | 186 | } |
178 | 187 | ||
179 | head = buffer->pointer; | 188 | head = buffer->pointer; |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 89c4519d48ac..6788acc22ab9 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -72,8 +72,15 @@ enum { | |||
72 | VPCCMD_W_BL_POWER = 0x33, | 72 | VPCCMD_W_BL_POWER = 0x33, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | struct ideapad_rfk_priv { | ||
76 | int dev; | ||
77 | struct ideapad_private *priv; | ||
78 | }; | ||
79 | |||
75 | struct ideapad_private { | 80 | struct ideapad_private { |
81 | struct acpi_device *adev; | ||
76 | struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; | 82 | struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; |
83 | struct ideapad_rfk_priv rfk_priv[IDEAPAD_RFKILL_DEV_NUM]; | ||
77 | struct platform_device *platform_device; | 84 | struct platform_device *platform_device; |
78 | struct input_dev *inputdev; | 85 | struct input_dev *inputdev; |
79 | struct backlight_device *blightdev; | 86 | struct backlight_device *blightdev; |
@@ -81,8 +88,6 @@ struct ideapad_private { | |||
81 | unsigned long cfg; | 88 | unsigned long cfg; |
82 | }; | 89 | }; |
83 | 90 | ||
84 | static acpi_handle ideapad_handle; | ||
85 | static struct ideapad_private *ideapad_priv; | ||
86 | static bool no_bt_rfkill; | 91 | static bool no_bt_rfkill; |
87 | module_param(no_bt_rfkill, bool, 0444); | 92 | module_param(no_bt_rfkill, bool, 0444); |
88 | MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); | 93 | MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); |
@@ -200,34 +205,38 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) | |||
200 | */ | 205 | */ |
201 | static int debugfs_status_show(struct seq_file *s, void *data) | 206 | static int debugfs_status_show(struct seq_file *s, void *data) |
202 | { | 207 | { |
208 | struct ideapad_private *priv = s->private; | ||
203 | unsigned long value; | 209 | unsigned long value; |
204 | 210 | ||
205 | if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value)) | 211 | if (!priv) |
212 | return -EINVAL; | ||
213 | |||
214 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) | ||
206 | seq_printf(s, "Backlight max:\t%lu\n", value); | 215 | seq_printf(s, "Backlight max:\t%lu\n", value); |
207 | if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value)) | 216 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) |
208 | seq_printf(s, "Backlight now:\t%lu\n", value); | 217 | seq_printf(s, "Backlight now:\t%lu\n", value); |
209 | if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value)) | 218 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) |
210 | seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); | 219 | seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); |
211 | seq_printf(s, "=====================\n"); | 220 | seq_printf(s, "=====================\n"); |
212 | 221 | ||
213 | if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value)) | 222 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) |
214 | seq_printf(s, "Radio status:\t%s(%lu)\n", | 223 | seq_printf(s, "Radio status:\t%s(%lu)\n", |
215 | value ? "On" : "Off", value); | 224 | value ? "On" : "Off", value); |
216 | if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value)) | 225 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) |
217 | seq_printf(s, "Wifi status:\t%s(%lu)\n", | 226 | seq_printf(s, "Wifi status:\t%s(%lu)\n", |
218 | value ? "On" : "Off", value); | 227 | value ? "On" : "Off", value); |
219 | if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value)) | 228 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) |
220 | seq_printf(s, "BT status:\t%s(%lu)\n", | 229 | seq_printf(s, "BT status:\t%s(%lu)\n", |
221 | value ? "On" : "Off", value); | 230 | value ? "On" : "Off", value); |
222 | if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value)) | 231 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) |
223 | seq_printf(s, "3G status:\t%s(%lu)\n", | 232 | seq_printf(s, "3G status:\t%s(%lu)\n", |
224 | value ? "On" : "Off", value); | 233 | value ? "On" : "Off", value); |
225 | seq_printf(s, "=====================\n"); | 234 | seq_printf(s, "=====================\n"); |
226 | 235 | ||
227 | if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value)) | 236 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) |
228 | seq_printf(s, "Touchpad status:%s(%lu)\n", | 237 | seq_printf(s, "Touchpad status:%s(%lu)\n", |
229 | value ? "On" : "Off", value); | 238 | value ? "On" : "Off", value); |
230 | if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value)) | 239 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) |
231 | seq_printf(s, "Camera status:\t%s(%lu)\n", | 240 | seq_printf(s, "Camera status:\t%s(%lu)\n", |
232 | value ? "On" : "Off", value); | 241 | value ? "On" : "Off", value); |
233 | 242 | ||
@@ -236,7 +245,7 @@ static int debugfs_status_show(struct seq_file *s, void *data) | |||
236 | 245 | ||
237 | static int debugfs_status_open(struct inode *inode, struct file *file) | 246 | static int debugfs_status_open(struct inode *inode, struct file *file) |
238 | { | 247 | { |
239 | return single_open(file, debugfs_status_show, NULL); | 248 | return single_open(file, debugfs_status_show, inode->i_private); |
240 | } | 249 | } |
241 | 250 | ||
242 | static const struct file_operations debugfs_status_fops = { | 251 | static const struct file_operations debugfs_status_fops = { |
@@ -249,21 +258,23 @@ static const struct file_operations debugfs_status_fops = { | |||
249 | 258 | ||
250 | static int debugfs_cfg_show(struct seq_file *s, void *data) | 259 | static int debugfs_cfg_show(struct seq_file *s, void *data) |
251 | { | 260 | { |
252 | if (!ideapad_priv) { | 261 | struct ideapad_private *priv = s->private; |
262 | |||
263 | if (!priv) { | ||
253 | seq_printf(s, "cfg: N/A\n"); | 264 | seq_printf(s, "cfg: N/A\n"); |
254 | } else { | 265 | } else { |
255 | seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", | 266 | seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", |
256 | ideapad_priv->cfg); | 267 | priv->cfg); |
257 | if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg)) | 268 | if (test_bit(CFG_BT_BIT, &priv->cfg)) |
258 | seq_printf(s, "Bluetooth "); | 269 | seq_printf(s, "Bluetooth "); |
259 | if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg)) | 270 | if (test_bit(CFG_3G_BIT, &priv->cfg)) |
260 | seq_printf(s, "3G "); | 271 | seq_printf(s, "3G "); |
261 | if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg)) | 272 | if (test_bit(CFG_WIFI_BIT, &priv->cfg)) |
262 | seq_printf(s, "Wireless "); | 273 | seq_printf(s, "Wireless "); |
263 | if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg)) | 274 | if (test_bit(CFG_CAMERA_BIT, &priv->cfg)) |
264 | seq_printf(s, "Camera "); | 275 | seq_printf(s, "Camera "); |
265 | seq_printf(s, "\nGraphic: "); | 276 | seq_printf(s, "\nGraphic: "); |
266 | switch ((ideapad_priv->cfg)&0x700) { | 277 | switch ((priv->cfg)&0x700) { |
267 | case 0x100: | 278 | case 0x100: |
268 | seq_printf(s, "Intel"); | 279 | seq_printf(s, "Intel"); |
269 | break; | 280 | break; |
@@ -287,7 +298,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data) | |||
287 | 298 | ||
288 | static int debugfs_cfg_open(struct inode *inode, struct file *file) | 299 | static int debugfs_cfg_open(struct inode *inode, struct file *file) |
289 | { | 300 | { |
290 | return single_open(file, debugfs_cfg_show, NULL); | 301 | return single_open(file, debugfs_cfg_show, inode->i_private); |
291 | } | 302 | } |
292 | 303 | ||
293 | static const struct file_operations debugfs_cfg_fops = { | 304 | static const struct file_operations debugfs_cfg_fops = { |
@@ -308,14 +319,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv) | |||
308 | goto errout; | 319 | goto errout; |
309 | } | 320 | } |
310 | 321 | ||
311 | node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL, | 322 | node = debugfs_create_file("cfg", S_IRUGO, priv->debug, priv, |
312 | &debugfs_cfg_fops); | 323 | &debugfs_cfg_fops); |
313 | if (!node) { | 324 | if (!node) { |
314 | pr_err("failed to create cfg in debugfs"); | 325 | pr_err("failed to create cfg in debugfs"); |
315 | goto errout; | 326 | goto errout; |
316 | } | 327 | } |
317 | 328 | ||
318 | node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL, | 329 | node = debugfs_create_file("status", S_IRUGO, priv->debug, priv, |
319 | &debugfs_status_fops); | 330 | &debugfs_status_fops); |
320 | if (!node) { | 331 | if (!node) { |
321 | pr_err("failed to create status in debugfs"); | 332 | pr_err("failed to create status in debugfs"); |
@@ -342,8 +353,9 @@ static ssize_t show_ideapad_cam(struct device *dev, | |||
342 | char *buf) | 353 | char *buf) |
343 | { | 354 | { |
344 | unsigned long result; | 355 | unsigned long result; |
356 | struct ideapad_private *priv = dev_get_drvdata(dev); | ||
345 | 357 | ||
346 | if (read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &result)) | 358 | if (read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result)) |
347 | return sprintf(buf, "-1\n"); | 359 | return sprintf(buf, "-1\n"); |
348 | return sprintf(buf, "%lu\n", result); | 360 | return sprintf(buf, "%lu\n", result); |
349 | } | 361 | } |
@@ -353,12 +365,13 @@ static ssize_t store_ideapad_cam(struct device *dev, | |||
353 | const char *buf, size_t count) | 365 | const char *buf, size_t count) |
354 | { | 366 | { |
355 | int ret, state; | 367 | int ret, state; |
368 | struct ideapad_private *priv = dev_get_drvdata(dev); | ||
356 | 369 | ||
357 | if (!count) | 370 | if (!count) |
358 | return 0; | 371 | return 0; |
359 | if (sscanf(buf, "%i", &state) != 1) | 372 | if (sscanf(buf, "%i", &state) != 1) |
360 | return -EINVAL; | 373 | return -EINVAL; |
361 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); | 374 | ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state); |
362 | if (ret < 0) | 375 | if (ret < 0) |
363 | return -EIO; | 376 | return -EIO; |
364 | return count; | 377 | return count; |
@@ -371,8 +384,9 @@ static ssize_t show_ideapad_fan(struct device *dev, | |||
371 | char *buf) | 384 | char *buf) |
372 | { | 385 | { |
373 | unsigned long result; | 386 | unsigned long result; |
387 | struct ideapad_private *priv = dev_get_drvdata(dev); | ||
374 | 388 | ||
375 | if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) | 389 | if (read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result)) |
376 | return sprintf(buf, "-1\n"); | 390 | return sprintf(buf, "-1\n"); |
377 | return sprintf(buf, "%lu\n", result); | 391 | return sprintf(buf, "%lu\n", result); |
378 | } | 392 | } |
@@ -382,6 +396,7 @@ static ssize_t store_ideapad_fan(struct device *dev, | |||
382 | const char *buf, size_t count) | 396 | const char *buf, size_t count) |
383 | { | 397 | { |
384 | int ret, state; | 398 | int ret, state; |
399 | struct ideapad_private *priv = dev_get_drvdata(dev); | ||
385 | 400 | ||
386 | if (!count) | 401 | if (!count) |
387 | return 0; | 402 | return 0; |
@@ -389,7 +404,7 @@ static ssize_t store_ideapad_fan(struct device *dev, | |||
389 | return -EINVAL; | 404 | return -EINVAL; |
390 | if (state < 0 || state > 4 || state == 3) | 405 | if (state < 0 || state > 4 || state == 3) |
391 | return -EINVAL; | 406 | return -EINVAL; |
392 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); | 407 | ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state); |
393 | if (ret < 0) | 408 | if (ret < 0) |
394 | return -EIO; | 409 | return -EIO; |
395 | return count; | 410 | return count; |
@@ -415,7 +430,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj, | |||
415 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); | 430 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); |
416 | else if (attr == &dev_attr_fan_mode.attr) { | 431 | else if (attr == &dev_attr_fan_mode.attr) { |
417 | unsigned long value; | 432 | unsigned long value; |
418 | supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); | 433 | supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN, |
434 | &value); | ||
419 | } else | 435 | } else |
420 | supported = true; | 436 | supported = true; |
421 | 437 | ||
@@ -445,9 +461,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = { | |||
445 | 461 | ||
446 | static int ideapad_rfk_set(void *data, bool blocked) | 462 | static int ideapad_rfk_set(void *data, bool blocked) |
447 | { | 463 | { |
448 | unsigned long opcode = (unsigned long)data; | 464 | struct ideapad_rfk_priv *priv = data; |
449 | 465 | ||
450 | return write_ec_cmd(ideapad_handle, opcode, !blocked); | 466 | return write_ec_cmd(priv->priv->adev->handle, priv->dev, !blocked); |
451 | } | 467 | } |
452 | 468 | ||
453 | static struct rfkill_ops ideapad_rfk_ops = { | 469 | static struct rfkill_ops ideapad_rfk_ops = { |
@@ -459,7 +475,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) | |||
459 | unsigned long hw_blocked; | 475 | unsigned long hw_blocked; |
460 | int i; | 476 | int i; |
461 | 477 | ||
462 | if (read_ec_data(ideapad_handle, VPCCMD_R_RF, &hw_blocked)) | 478 | if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) |
463 | return; | 479 | return; |
464 | hw_blocked = !hw_blocked; | 480 | hw_blocked = !hw_blocked; |
465 | 481 | ||
@@ -468,27 +484,30 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) | |||
468 | rfkill_set_hw_state(priv->rfk[i], hw_blocked); | 484 | rfkill_set_hw_state(priv->rfk[i], hw_blocked); |
469 | } | 485 | } |
470 | 486 | ||
471 | static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) | 487 | static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) |
472 | { | 488 | { |
473 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
474 | int ret; | 489 | int ret; |
475 | unsigned long sw_blocked; | 490 | unsigned long sw_blocked; |
476 | 491 | ||
477 | if (no_bt_rfkill && | 492 | if (no_bt_rfkill && |
478 | (ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) { | 493 | (ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) { |
479 | /* Force to enable bluetooth when no_bt_rfkill=1 */ | 494 | /* Force to enable bluetooth when no_bt_rfkill=1 */ |
480 | write_ec_cmd(ideapad_handle, | 495 | write_ec_cmd(priv->adev->handle, |
481 | ideapad_rfk_data[dev].opcode, 1); | 496 | ideapad_rfk_data[dev].opcode, 1); |
482 | return 0; | 497 | return 0; |
483 | } | 498 | } |
484 | 499 | priv->rfk_priv[dev].dev = dev; | |
485 | priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adevice->dev, | 500 | priv->rfk_priv[dev].priv = priv; |
486 | ideapad_rfk_data[dev].type, &ideapad_rfk_ops, | 501 | |
487 | (void *)(long)dev); | 502 | priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, |
503 | &priv->platform_device->dev, | ||
504 | ideapad_rfk_data[dev].type, | ||
505 | &ideapad_rfk_ops, | ||
506 | &priv->rfk_priv[dev]); | ||
488 | if (!priv->rfk[dev]) | 507 | if (!priv->rfk[dev]) |
489 | return -ENOMEM; | 508 | return -ENOMEM; |
490 | 509 | ||
491 | if (read_ec_data(ideapad_handle, ideapad_rfk_data[dev].opcode-1, | 510 | if (read_ec_data(priv->adev->handle, ideapad_rfk_data[dev].opcode-1, |
492 | &sw_blocked)) { | 511 | &sw_blocked)) { |
493 | rfkill_init_sw_state(priv->rfk[dev], 0); | 512 | rfkill_init_sw_state(priv->rfk[dev], 0); |
494 | } else { | 513 | } else { |
@@ -504,10 +523,8 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) | |||
504 | return 0; | 523 | return 0; |
505 | } | 524 | } |
506 | 525 | ||
507 | static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) | 526 | static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) |
508 | { | 527 | { |
509 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
510 | |||
511 | if (!priv->rfk[dev]) | 528 | if (!priv->rfk[dev]) |
512 | return; | 529 | return; |
513 | 530 | ||
@@ -518,37 +535,16 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) | |||
518 | /* | 535 | /* |
519 | * Platform device | 536 | * Platform device |
520 | */ | 537 | */ |
521 | static int ideapad_platform_init(struct ideapad_private *priv) | 538 | static int ideapad_sysfs_init(struct ideapad_private *priv) |
522 | { | 539 | { |
523 | int result; | 540 | return sysfs_create_group(&priv->platform_device->dev.kobj, |
524 | |||
525 | priv->platform_device = platform_device_alloc("ideapad", -1); | ||
526 | if (!priv->platform_device) | ||
527 | return -ENOMEM; | ||
528 | platform_set_drvdata(priv->platform_device, priv); | ||
529 | |||
530 | result = platform_device_add(priv->platform_device); | ||
531 | if (result) | ||
532 | goto fail_platform_device; | ||
533 | |||
534 | result = sysfs_create_group(&priv->platform_device->dev.kobj, | ||
535 | &ideapad_attribute_group); | 541 | &ideapad_attribute_group); |
536 | if (result) | ||
537 | goto fail_sysfs; | ||
538 | return 0; | ||
539 | |||
540 | fail_sysfs: | ||
541 | platform_device_del(priv->platform_device); | ||
542 | fail_platform_device: | ||
543 | platform_device_put(priv->platform_device); | ||
544 | return result; | ||
545 | } | 542 | } |
546 | 543 | ||
547 | static void ideapad_platform_exit(struct ideapad_private *priv) | 544 | static void ideapad_sysfs_exit(struct ideapad_private *priv) |
548 | { | 545 | { |
549 | sysfs_remove_group(&priv->platform_device->dev.kobj, | 546 | sysfs_remove_group(&priv->platform_device->dev.kobj, |
550 | &ideapad_attribute_group); | 547 | &ideapad_attribute_group); |
551 | platform_device_unregister(priv->platform_device); | ||
552 | } | 548 | } |
553 | 549 | ||
554 | /* | 550 | /* |
@@ -623,7 +619,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv) | |||
623 | { | 619 | { |
624 | unsigned long long_pressed; | 620 | unsigned long long_pressed; |
625 | 621 | ||
626 | if (read_ec_data(ideapad_handle, VPCCMD_R_NOVO, &long_pressed)) | 622 | if (read_ec_data(priv->adev->handle, VPCCMD_R_NOVO, &long_pressed)) |
627 | return; | 623 | return; |
628 | if (long_pressed) | 624 | if (long_pressed) |
629 | ideapad_input_report(priv, 17); | 625 | ideapad_input_report(priv, 17); |
@@ -635,7 +631,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) | |||
635 | { | 631 | { |
636 | unsigned long bit, value; | 632 | unsigned long bit, value; |
637 | 633 | ||
638 | read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); | 634 | read_ec_data(priv->adev->handle, VPCCMD_R_SPECIAL_BUTTONS, &value); |
639 | 635 | ||
640 | for (bit = 0; bit < 16; bit++) { | 636 | for (bit = 0; bit < 16; bit++) { |
641 | if (test_bit(bit, &value)) { | 637 | if (test_bit(bit, &value)) { |
@@ -662,19 +658,28 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) | |||
662 | */ | 658 | */ |
663 | static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) | 659 | static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) |
664 | { | 660 | { |
661 | struct ideapad_private *priv = bl_get_data(blightdev); | ||
665 | unsigned long now; | 662 | unsigned long now; |
666 | 663 | ||
667 | if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) | 664 | if (!priv) |
665 | return -EINVAL; | ||
666 | |||
667 | if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) | ||
668 | return -EIO; | 668 | return -EIO; |
669 | return now; | 669 | return now; |
670 | } | 670 | } |
671 | 671 | ||
672 | static int ideapad_backlight_update_status(struct backlight_device *blightdev) | 672 | static int ideapad_backlight_update_status(struct backlight_device *blightdev) |
673 | { | 673 | { |
674 | if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL, | 674 | struct ideapad_private *priv = bl_get_data(blightdev); |
675 | |||
676 | if (!priv) | ||
677 | return -EINVAL; | ||
678 | |||
679 | if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL, | ||
675 | blightdev->props.brightness)) | 680 | blightdev->props.brightness)) |
676 | return -EIO; | 681 | return -EIO; |
677 | if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL_POWER, | 682 | if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL_POWER, |
678 | blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) | 683 | blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) |
679 | return -EIO; | 684 | return -EIO; |
680 | 685 | ||
@@ -692,11 +697,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv) | |||
692 | struct backlight_properties props; | 697 | struct backlight_properties props; |
693 | unsigned long max, now, power; | 698 | unsigned long max, now, power; |
694 | 699 | ||
695 | if (read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &max)) | 700 | if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &max)) |
696 | return -EIO; | 701 | return -EIO; |
697 | if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) | 702 | if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) |
698 | return -EIO; | 703 | return -EIO; |
699 | if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) | 704 | if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) |
700 | return -EIO; | 705 | return -EIO; |
701 | 706 | ||
702 | memset(&props, 0, sizeof(struct backlight_properties)); | 707 | memset(&props, 0, sizeof(struct backlight_properties)); |
@@ -734,7 +739,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv) | |||
734 | 739 | ||
735 | if (!blightdev) | 740 | if (!blightdev) |
736 | return; | 741 | return; |
737 | if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) | 742 | if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) |
738 | return; | 743 | return; |
739 | blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; | 744 | blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; |
740 | } | 745 | } |
@@ -745,7 +750,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) | |||
745 | 750 | ||
746 | /* if we control brightness via acpi video driver */ | 751 | /* if we control brightness via acpi video driver */ |
747 | if (priv->blightdev == NULL) { | 752 | if (priv->blightdev == NULL) { |
748 | read_ec_data(ideapad_handle, VPCCMD_R_BL, &now); | 753 | read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now); |
749 | return; | 754 | return; |
750 | } | 755 | } |
751 | 756 | ||
@@ -755,19 +760,12 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) | |||
755 | /* | 760 | /* |
756 | * module init/exit | 761 | * module init/exit |
757 | */ | 762 | */ |
758 | static const struct acpi_device_id ideapad_device_ids[] = { | 763 | static void ideapad_sync_touchpad_state(struct ideapad_private *priv) |
759 | { "VPC2004", 0}, | ||
760 | { "", 0}, | ||
761 | }; | ||
762 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); | ||
763 | |||
764 | static void ideapad_sync_touchpad_state(struct acpi_device *adevice) | ||
765 | { | 764 | { |
766 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
767 | unsigned long value; | 765 | unsigned long value; |
768 | 766 | ||
769 | /* Without reading from EC touchpad LED doesn't switch state */ | 767 | /* Without reading from EC touchpad LED doesn't switch state */ |
770 | if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { | 768 | if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { |
771 | /* Some IdeaPads don't really turn off touchpad - they only | 769 | /* Some IdeaPads don't really turn off touchpad - they only |
772 | * switch the LED state. We (de)activate KBC AUX port to turn | 770 | * switch the LED state. We (de)activate KBC AUX port to turn |
773 | * touchpad off and on. We send KEY_TOUCHPAD_OFF and | 771 | * touchpad off and on. We send KEY_TOUCHPAD_OFF and |
@@ -779,26 +777,77 @@ static void ideapad_sync_touchpad_state(struct acpi_device *adevice) | |||
779 | } | 777 | } |
780 | } | 778 | } |
781 | 779 | ||
782 | static int ideapad_acpi_add(struct acpi_device *adevice) | 780 | static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) |
781 | { | ||
782 | struct ideapad_private *priv = data; | ||
783 | unsigned long vpc1, vpc2, vpc_bit; | ||
784 | |||
785 | if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) | ||
786 | return; | ||
787 | if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) | ||
788 | return; | ||
789 | |||
790 | vpc1 = (vpc2 << 8) | vpc1; | ||
791 | for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { | ||
792 | if (test_bit(vpc_bit, &vpc1)) { | ||
793 | switch (vpc_bit) { | ||
794 | case 9: | ||
795 | ideapad_sync_rfk_state(priv); | ||
796 | break; | ||
797 | case 13: | ||
798 | case 11: | ||
799 | case 7: | ||
800 | case 6: | ||
801 | ideapad_input_report(priv, vpc_bit); | ||
802 | break; | ||
803 | case 5: | ||
804 | ideapad_sync_touchpad_state(priv); | ||
805 | break; | ||
806 | case 4: | ||
807 | ideapad_backlight_notify_brightness(priv); | ||
808 | break; | ||
809 | case 3: | ||
810 | ideapad_input_novokey(priv); | ||
811 | break; | ||
812 | case 2: | ||
813 | ideapad_backlight_notify_power(priv); | ||
814 | break; | ||
815 | case 0: | ||
816 | ideapad_check_special_buttons(priv); | ||
817 | break; | ||
818 | default: | ||
819 | pr_info("Unknown event: %lu\n", vpc_bit); | ||
820 | } | ||
821 | } | ||
822 | } | ||
823 | } | ||
824 | |||
825 | static int ideapad_acpi_add(struct platform_device *pdev) | ||
783 | { | 826 | { |
784 | int ret, i; | 827 | int ret, i; |
785 | int cfg; | 828 | int cfg; |
786 | struct ideapad_private *priv; | 829 | struct ideapad_private *priv; |
830 | struct acpi_device *adev; | ||
831 | |||
832 | ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); | ||
833 | if (ret) | ||
834 | return -ENODEV; | ||
787 | 835 | ||
788 | if (read_method_int(adevice->handle, "_CFG", &cfg)) | 836 | if (read_method_int(adev->handle, "_CFG", &cfg)) |
789 | return -ENODEV; | 837 | return -ENODEV; |
790 | 838 | ||
791 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 839 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
792 | if (!priv) | 840 | if (!priv) |
793 | return -ENOMEM; | 841 | return -ENOMEM; |
794 | dev_set_drvdata(&adevice->dev, priv); | 842 | |
795 | ideapad_priv = priv; | 843 | dev_set_drvdata(&pdev->dev, priv); |
796 | ideapad_handle = adevice->handle; | ||
797 | priv->cfg = cfg; | 844 | priv->cfg = cfg; |
845 | priv->adev = adev; | ||
846 | priv->platform_device = pdev; | ||
798 | 847 | ||
799 | ret = ideapad_platform_init(priv); | 848 | ret = ideapad_sysfs_init(priv); |
800 | if (ret) | 849 | if (ret) |
801 | goto platform_failed; | 850 | goto sysfs_failed; |
802 | 851 | ||
803 | ret = ideapad_debugfs_init(priv); | 852 | ret = ideapad_debugfs_init(priv); |
804 | if (ret) | 853 | if (ret) |
@@ -810,117 +859,92 @@ static int ideapad_acpi_add(struct acpi_device *adevice) | |||
810 | 859 | ||
811 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { | 860 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { |
812 | if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) | 861 | if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) |
813 | ideapad_register_rfkill(adevice, i); | 862 | ideapad_register_rfkill(priv, i); |
814 | else | 863 | else |
815 | priv->rfk[i] = NULL; | 864 | priv->rfk[i] = NULL; |
816 | } | 865 | } |
817 | ideapad_sync_rfk_state(priv); | 866 | ideapad_sync_rfk_state(priv); |
818 | ideapad_sync_touchpad_state(adevice); | 867 | ideapad_sync_touchpad_state(priv); |
819 | 868 | ||
820 | if (!acpi_video_backlight_support()) { | 869 | if (!acpi_video_backlight_support()) { |
821 | ret = ideapad_backlight_init(priv); | 870 | ret = ideapad_backlight_init(priv); |
822 | if (ret && ret != -ENODEV) | 871 | if (ret && ret != -ENODEV) |
823 | goto backlight_failed; | 872 | goto backlight_failed; |
824 | } | 873 | } |
874 | ret = acpi_install_notify_handler(adev->handle, | ||
875 | ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv); | ||
876 | if (ret) | ||
877 | goto notification_failed; | ||
825 | 878 | ||
826 | return 0; | 879 | return 0; |
827 | 880 | notification_failed: | |
881 | ideapad_backlight_exit(priv); | ||
828 | backlight_failed: | 882 | backlight_failed: |
829 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) | 883 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) |
830 | ideapad_unregister_rfkill(adevice, i); | 884 | ideapad_unregister_rfkill(priv, i); |
831 | ideapad_input_exit(priv); | 885 | ideapad_input_exit(priv); |
832 | input_failed: | 886 | input_failed: |
833 | ideapad_debugfs_exit(priv); | 887 | ideapad_debugfs_exit(priv); |
834 | debugfs_failed: | 888 | debugfs_failed: |
835 | ideapad_platform_exit(priv); | 889 | ideapad_sysfs_exit(priv); |
836 | platform_failed: | 890 | sysfs_failed: |
837 | kfree(priv); | 891 | kfree(priv); |
838 | return ret; | 892 | return ret; |
839 | } | 893 | } |
840 | 894 | ||
841 | static int ideapad_acpi_remove(struct acpi_device *adevice) | 895 | static int ideapad_acpi_remove(struct platform_device *pdev) |
842 | { | 896 | { |
843 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | 897 | struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); |
844 | int i; | 898 | int i; |
845 | 899 | ||
900 | acpi_remove_notify_handler(priv->adev->handle, | ||
901 | ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); | ||
846 | ideapad_backlight_exit(priv); | 902 | ideapad_backlight_exit(priv); |
847 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) | 903 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) |
848 | ideapad_unregister_rfkill(adevice, i); | 904 | ideapad_unregister_rfkill(priv, i); |
849 | ideapad_input_exit(priv); | 905 | ideapad_input_exit(priv); |
850 | ideapad_debugfs_exit(priv); | 906 | ideapad_debugfs_exit(priv); |
851 | ideapad_platform_exit(priv); | 907 | ideapad_sysfs_exit(priv); |
852 | dev_set_drvdata(&adevice->dev, NULL); | 908 | dev_set_drvdata(&pdev->dev, NULL); |
853 | kfree(priv); | 909 | kfree(priv); |
854 | 910 | ||
855 | return 0; | 911 | return 0; |
856 | } | 912 | } |
857 | 913 | ||
858 | static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | 914 | #ifdef CONFIG_PM_SLEEP |
915 | static int ideapad_acpi_resume(struct device *device) | ||
859 | { | 916 | { |
860 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | 917 | struct ideapad_private *priv; |
861 | acpi_handle handle = adevice->handle; | ||
862 | unsigned long vpc1, vpc2, vpc_bit; | ||
863 | |||
864 | if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) | ||
865 | return; | ||
866 | if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) | ||
867 | return; | ||
868 | 918 | ||
869 | vpc1 = (vpc2 << 8) | vpc1; | 919 | if (!device) |
870 | for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { | 920 | return -EINVAL; |
871 | if (test_bit(vpc_bit, &vpc1)) { | 921 | priv = dev_get_drvdata(device); |
872 | switch (vpc_bit) { | ||
873 | case 9: | ||
874 | ideapad_sync_rfk_state(priv); | ||
875 | break; | ||
876 | case 13: | ||
877 | case 11: | ||
878 | case 7: | ||
879 | case 6: | ||
880 | ideapad_input_report(priv, vpc_bit); | ||
881 | break; | ||
882 | case 5: | ||
883 | ideapad_sync_touchpad_state(adevice); | ||
884 | break; | ||
885 | case 4: | ||
886 | ideapad_backlight_notify_brightness(priv); | ||
887 | break; | ||
888 | case 3: | ||
889 | ideapad_input_novokey(priv); | ||
890 | break; | ||
891 | case 2: | ||
892 | ideapad_backlight_notify_power(priv); | ||
893 | break; | ||
894 | case 0: | ||
895 | ideapad_check_special_buttons(priv); | ||
896 | break; | ||
897 | default: | ||
898 | pr_info("Unknown event: %lu\n", vpc_bit); | ||
899 | } | ||
900 | } | ||
901 | } | ||
902 | } | ||
903 | 922 | ||
904 | static int ideapad_acpi_resume(struct device *device) | 923 | ideapad_sync_rfk_state(priv); |
905 | { | 924 | ideapad_sync_touchpad_state(priv); |
906 | ideapad_sync_rfk_state(ideapad_priv); | ||
907 | ideapad_sync_touchpad_state(to_acpi_device(device)); | ||
908 | return 0; | 925 | return 0; |
909 | } | 926 | } |
910 | 927 | #endif | |
911 | static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); | 928 | static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); |
912 | 929 | ||
913 | static struct acpi_driver ideapad_acpi_driver = { | 930 | static const struct acpi_device_id ideapad_device_ids[] = { |
914 | .name = "ideapad_acpi", | 931 | { "VPC2004", 0}, |
915 | .class = "IdeaPad", | 932 | { "", 0}, |
916 | .ids = ideapad_device_ids, | ||
917 | .ops.add = ideapad_acpi_add, | ||
918 | .ops.remove = ideapad_acpi_remove, | ||
919 | .ops.notify = ideapad_acpi_notify, | ||
920 | .drv.pm = &ideapad_pm, | ||
921 | .owner = THIS_MODULE, | ||
922 | }; | 933 | }; |
923 | module_acpi_driver(ideapad_acpi_driver); | 934 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); |
935 | |||
936 | static struct platform_driver ideapad_acpi_driver = { | ||
937 | .probe = ideapad_acpi_add, | ||
938 | .remove = ideapad_acpi_remove, | ||
939 | .driver = { | ||
940 | .name = "ideapad_acpi", | ||
941 | .owner = THIS_MODULE, | ||
942 | .pm = &ideapad_pm, | ||
943 | .acpi_match_table = ACPI_PTR(ideapad_device_ids), | ||
944 | }, | ||
945 | }; | ||
946 | |||
947 | module_platform_driver(ideapad_acpi_driver); | ||
924 | 948 | ||
925 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | 949 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
926 | MODULE_DESCRIPTION("IdeaPad ACPI Extras"); | 950 | MODULE_DESCRIPTION("IdeaPad ACPI Extras"); |