static u32 rtc_handler(void *context) { struct device *dev = context; pm_wakeup_event(dev, 0); acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); return ACPI_INTERRUPT_HANDLED; }
acpi_status acpi_install_fixed_event_handler ( u32 event, acpi_event_handler handler, void *context) { acpi_status status; ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler"); /* Parameter validation */ if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Don't allow two handlers. */ if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { status = AE_ALREADY_EXISTS; goto cleanup; } /* Install the handler before enabling the event */ acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; status = acpi_clear_event (event); if (ACPI_SUCCESS(status)) status = acpi_enable_event (event, 0); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n")); /* Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; } else { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Enabled fixed event %X, Handler=%p\n", event, handler)); } cleanup: (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (status); }
static inline void rtc_wake_setup(struct device *dev) { acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev); /* * After the RTC handler is installed, the Fixed_RTC event should * be disabled. Only when the RTC alarm is set will it be enabled. */ acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); }
/** * acpi_suspend_enter - Actually enter a sleep state. * @pm_state: ignored * * Flush caches and go to sleep. For STR we have to call arch-specific * assembly, which in turn call acpi_enter_sleep_state(). * It's unfortunate, but it works. Please fix if you're feeling frisky. */ static int acpi_suspend_enter(suspend_state_t pm_state) { acpi_status status = AE_OK; unsigned long flags = 0; u32 acpi_state = acpi_target_sleep_state; ACPI_FLUSH_CPU_CACHE(); /* Do arch specific saving of state. */ if (acpi_state == ACPI_STATE_S3) { int error = acpi_save_state_mem(); if (error) return error; } local_irq_save(flags); acpi_enable_wakeup_device(acpi_state); switch (acpi_state) { case ACPI_STATE_S1: barrier(); status = acpi_enter_sleep_state(acpi_state); break; case ACPI_STATE_S3: do_suspend_lowlevel(); break; } /* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep(acpi_state); /* ACPI 3.0 specs (P62) says that it's the responsibility * of the OSPM to clear the status bit [ implying that the * POWER_BUTTON event should not reach userspace ] */ if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) acpi_clear_event(ACPI_EVENT_POWER_BUTTON); /* * Disable and clear GPE status before interrupt is enabled. Some GPEs * (like wakeup GPE) haven't handler, this can avoid such GPE misfire. * acpi_leave_sleep_state will reenable specific GPEs later */ acpi_hw_disable_all_gpes(); local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); /* restore processor state */ if (acpi_state == ACPI_STATE_S3) acpi_restore_state_mem(); return ACPI_SUCCESS(status) ? 0 : -EFAULT; }
acpi_status acpi_install_fixed_event_handler(u32 event, acpi_event_handler handler, void *context) { acpi_status status; ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { status = AE_ALREADY_EXISTS; goto cleanup; } acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; status = acpi_clear_event(event); if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Could not enable fixed event %X", event)); acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Enabled fixed event %X, Handler=%p\n", event, handler)); } cleanup: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); }
static u32 rtc_handler(void *context) { struct device *dev = context; struct cmos_rtc *cmos = dev_get_drvdata(dev); unsigned char rtc_control = 0; unsigned char rtc_intr; spin_lock_irq(&rtc_lock); if (cmos_rtc.suspend_ctrl) rtc_control = CMOS_READ(RTC_CONTROL); if (rtc_control & RTC_AIE) { cmos_rtc.suspend_ctrl &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_update_irq(cmos->rtc, 1, rtc_intr); } spin_unlock_irq(&rtc_lock); pm_wakeup_event(dev, 0); acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); return ACPI_INTERRUPT_HANDLED; }
static void rtc_wake_on(struct device *dev) { acpi_clear_event(ACPI_EVENT_RTC); acpi_enable_event(ACPI_EVENT_RTC, 0); }
static u32 rtc_handler(void *context) { acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); return ACPI_INTERRUPT_HANDLED; }
static int acpi_pm_enter(suspend_state_t pm_state) { acpi_status status = AE_OK; unsigned long flags = 0; u32 acpi_state = acpi_suspend_states[pm_state]; ACPI_FLUSH_CPU_CACHE(); /* Do arch specific saving of state. */ if (pm_state > PM_SUSPEND_STANDBY) { int error = acpi_save_state_mem(); if (error) return error; } local_irq_save(flags); acpi_enable_wakeup_device(acpi_state); switch (pm_state) { case PM_SUSPEND_STANDBY: barrier(); status = acpi_enter_sleep_state(acpi_state); break; case PM_SUSPEND_MEM: if (unlikely(acpi_simulate_suspend_to_ram)) { printk(KERN_INFO "ACPI: simulating suspend-to-RAM: " "not calling BIOS.\n"); } else { do_suspend_lowlevel(); } break; case PM_SUSPEND_DISK: if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM) status = acpi_enter_sleep_state(acpi_state); break; case PM_SUSPEND_MAX: acpi_power_off(); break; default: return -EINVAL; } /* ACPI 3.0 specs (P62) says that it's the responsabilty * of the OSPM to clear the status bit [ implying that the * POWER_BUTTON event should not reach userspace ] */ if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) acpi_clear_event(ACPI_EVENT_POWER_BUTTON); local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); /* restore processor state * We should only be here if we're coming back from STR or STD. * And, in the case of the latter, the memory image should have already * been loaded from disk. */ if (pm_state > PM_SUSPEND_STANDBY) acpi_restore_state_mem(); return ACPI_SUCCESS(status) ? 0 : -EFAULT; }
static inline void rtc_wake_setup(void) { acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); }