diff options
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r-- | drivers/acpi/glue.c | 127 |
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 | ||
261 | arch_initcall(init_acpi_device_notify); | 262 | arch_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 | ||
267 | static 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 | |||
274 | static 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 | |||
285 | static 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 | |||
291 | static 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 | |||
308 | static 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 | |||
316 | static 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 | |||
329 | static struct device *__init get_rtc_dev(void) | ||
330 | { | ||
331 | return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); | ||
332 | } | ||
333 | |||
334 | static 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() */ | ||
375 | fs_initcall(acpi_rtc_init); | ||
376 | |||
377 | #endif | ||