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.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 4334c208841a..41427a41f620 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify);
245 245
246#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 246#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
247 247
248#ifdef CONFIG_PM
249static u32 rtc_handler(void *context)
250{
251 acpi_clear_event(ACPI_EVENT_RTC);
252 acpi_disable_event(ACPI_EVENT_RTC, 0);
253 return ACPI_INTERRUPT_HANDLED;
254}
255
256static inline void rtc_wake_setup(void)
257{
258 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
259}
260
261static void rtc_wake_on(struct device *dev)
262{
263 acpi_clear_event(ACPI_EVENT_RTC);
264 acpi_enable_event(ACPI_EVENT_RTC, 0);
265}
266
267static void rtc_wake_off(struct device *dev)
268{
269 acpi_disable_event(ACPI_EVENT_RTC, 0);
270}
271#else
272#define rtc_wake_setup() do{}while(0)
273#define rtc_wake_on NULL
274#define rtc_wake_off NULL
275#endif
276
248/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find 277/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
249 * its device node and pass extra config data. This helps its driver use 278 * its device node and pass extra config data. This helps its driver use
250 * capabilities that the now-obsolete mc146818 didn't have, and informs it 279 * capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -283,11 +312,24 @@ static int __init acpi_rtc_init(void)
283 struct device *dev = get_rtc_dev(); 312 struct device *dev = get_rtc_dev();
284 313
285 if (dev) { 314 if (dev) {
315 rtc_wake_setup();
316 rtc_info.wake_on = rtc_wake_on;
317 rtc_info.wake_off = rtc_wake_off;
318
319 /* workaround bug in some ACPI tables */
320 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
321 DBG("bogus FADT month_alarm\n");
322 acpi_gbl_FADT.month_alarm = 0;
323 }
324
286 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; 325 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
287 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; 326 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
288 rtc_info.rtc_century = acpi_gbl_FADT.century; 327 rtc_info.rtc_century = acpi_gbl_FADT.century;
289 328
290 /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ 329 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
330 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
331 printk(PREFIX "RTC can wake from S4\n");
332
291 333
292 dev->platform_data = &rtc_info; 334 dev->platform_data = &rtc_info;
293 335
@@ -296,7 +338,7 @@ static int __init acpi_rtc_init(void)
296 338
297 put_device(dev); 339 put_device(dev);
298 } else 340 } else
299 pr_debug("ACPI: RTC unavailable?\n"); 341 DBG("RTC unavailable?\n");
300 return 0; 342 return 0;
301} 343}
302/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ 344/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */