aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r--drivers/acpi/glue.c127
1 files changed, 6 insertions, 121 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 0f2dd81736bd..24649ada08df 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -146,8 +146,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
146 acpi_status status; 146 acpi_status status;
147 147
148 if (dev->archdata.acpi_handle) { 148 if (dev->archdata.acpi_handle) {
149 printk(KERN_WARNING PREFIX 149 dev_warn(dev, "Drivers changed 'acpi_handle'\n");
150 "Drivers changed 'acpi_handle' for %s\n", dev->bus_id);
151 return -EINVAL; 150 return -EINVAL;
152 } 151 }
153 get_device(dev); 152 get_device(dev);
@@ -166,8 +165,11 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
166 "firmware_node"); 165 "firmware_node");
167 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 166 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
168 "physical_node"); 167 "physical_node");
169 if (acpi_dev->wakeup.flags.valid) 168 if (acpi_dev->wakeup.flags.valid) {
170 device_set_wakeup_capable(dev, true); 169 device_set_wakeup_capable(dev, true);
170 device_set_wakeup_enable(dev,
171 acpi_dev->wakeup.state.enabled);
172 }
171 } 173 }
172 174
173 return 0; 175 return 0;
@@ -195,8 +197,7 @@ static int acpi_unbind_one(struct device *dev)
195 /* acpi_bind_one increase refcnt by one */ 197 /* acpi_bind_one increase refcnt by one */
196 put_device(dev); 198 put_device(dev);
197 } else { 199 } else {
198 printk(KERN_ERR PREFIX 200 dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
199 "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id);
200 } 201 }
201 return 0; 202 return 0;
202} 203}
@@ -259,119 +260,3 @@ static int __init init_acpi_device_notify(void)
259} 260}
260 261
261arch_initcall(init_acpi_device_notify); 262arch_initcall(init_acpi_device_notify);
262
263
264#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
265
266#ifdef CONFIG_PM
267static u32 rtc_handler(void *context)
268{
269 acpi_clear_event(ACPI_EVENT_RTC);
270 acpi_disable_event(ACPI_EVENT_RTC, 0);
271 return ACPI_INTERRUPT_HANDLED;
272}
273
274static inline void rtc_wake_setup(void)
275{
276 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
277 /*
278 * After the RTC handler is installed, the Fixed_RTC event should
279 * be disabled. Only when the RTC alarm is set will it be enabled.
280 */
281 acpi_clear_event(ACPI_EVENT_RTC);
282 acpi_disable_event(ACPI_EVENT_RTC, 0);
283}
284
285static void rtc_wake_on(struct device *dev)
286{
287 acpi_clear_event(ACPI_EVENT_RTC);
288 acpi_enable_event(ACPI_EVENT_RTC, 0);
289}
290
291static void rtc_wake_off(struct device *dev)
292{
293 acpi_disable_event(ACPI_EVENT_RTC, 0);
294}
295#else
296#define rtc_wake_setup() do{}while(0)
297#define rtc_wake_on NULL
298#define rtc_wake_off NULL
299#endif
300
301/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
302 * its device node and pass extra config data. This helps its driver use
303 * capabilities that the now-obsolete mc146818 didn't have, and informs it
304 * that this board's RTC is wakeup-capable (per ACPI spec).
305 */
306#include <linux/mc146818rtc.h>
307
308static struct cmos_rtc_board_info rtc_info;
309
310
311/* PNP devices are registered in a subsys_initcall();
312 * ACPI specifies the PNP IDs to use.
313 */
314#include <linux/pnp.h>
315
316static int __init pnp_match(struct device *dev, void *data)
317{
318 static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
319 struct pnp_dev *pnp = to_pnp_dev(dev);
320 int i;
321
322 for (i = 0; i < ARRAY_SIZE(ids); i++) {
323 if (compare_pnp_id(pnp->id, ids[i]) != 0)
324 return 1;
325 }
326 return 0;
327}
328
329static struct device *__init get_rtc_dev(void)
330{
331 return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
332}
333
334static int __init acpi_rtc_init(void)
335{
336 struct device *dev = get_rtc_dev();
337
338 if (acpi_disabled)
339 return 0;
340
341 if (acpi_disabled)
342 return 0;
343
344 if (dev) {
345 rtc_wake_setup();
346 rtc_info.wake_on = rtc_wake_on;
347 rtc_info.wake_off = rtc_wake_off;
348
349 /* workaround bug in some ACPI tables */
350 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
351 DBG("bogus FADT month_alarm\n");
352 acpi_gbl_FADT.month_alarm = 0;
353 }
354
355 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
356 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
357 rtc_info.rtc_century = acpi_gbl_FADT.century;
358
359 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
360 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
361 printk(PREFIX "RTC can wake from S4\n");
362
363
364 dev->platform_data = &rtc_info;
365
366 /* RTC always wakes from S1/S2/S3, and often S4/STD */
367 device_init_wakeup(dev, 1);
368
369 put_device(dev);
370 } else
371 DBG("RTC unavailable?\n");
372 return 0;
373}
374/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
375fs_initcall(acpi_rtc_init);
376
377#endif