Loading kernel/time/alarmtimer.c +47 −7 Original line number Diff line number Diff line Loading @@ -53,6 +53,17 @@ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; static DEFINE_SPINLOCK(rtcdev_lock); static void alarmtimer_triggered_func(void *p) { struct rtc_device *rtc = rtcdev; if (!(rtc->irq_data & RTC_AF)) return; __pm_wakeup_event(ws, 2 * MSEC_PER_SEC); } static struct rtc_task alarmtimer_rtc_task = { .func = alarmtimer_triggered_func }; /** * alarmtimer_get_rtcdev - Return selected rtcdevice * Loading @@ -63,7 +74,7 @@ static DEFINE_SPINLOCK(rtcdev_lock); struct rtc_device *alarmtimer_get_rtcdev(void) { unsigned long flags; struct rtc_device *ret; struct rtc_device *ret = NULL; spin_lock_irqsave(&rtcdev_lock, flags); ret = rtcdev; Loading @@ -72,29 +83,40 @@ struct rtc_device *alarmtimer_get_rtcdev(void) return ret; } static int alarmtimer_rtc_add_device(struct device *dev, struct class_interface *class_intf) { unsigned long flags; int err = 0; struct rtc_device *rtc = to_rtc_device(dev); if (rtcdev) return -EBUSY; if (!rtc->ops->set_alarm) return -1; if (!device_may_wakeup(rtc->dev.parent)) return -1; spin_lock_irqsave(&rtcdev_lock, flags); if (!rtcdev) { err = rtc_irq_register(rtc, &alarmtimer_rtc_task); if (err) goto rtc_irq_reg_err; rtcdev = rtc; /* hold a reference so it doesn't go away */ get_device(dev); } rtc_irq_reg_err: spin_unlock_irqrestore(&rtcdev_lock, flags); return 0; return err; } static void alarmtimer_rtc_remove_device(struct device *dev, struct class_interface *class_intf) { if (rtcdev && dev == &rtcdev->dev) { rtc_irq_unregister(rtcdev, &alarmtimer_rtc_task); rtcdev = NULL; } } static inline void alarmtimer_rtc_timer_init(void) Loading @@ -104,6 +126,7 @@ static inline void alarmtimer_rtc_timer_init(void) static struct class_interface alarmtimer_rtc_interface = { .add_dev = &alarmtimer_rtc_add_device, .remove_dev = &alarmtimer_rtc_remove_device, }; static int alarmtimer_rtc_interface_setup(void) Loading Loading @@ -270,11 +293,27 @@ static int alarmtimer_suspend(struct device *dev) __pm_wakeup_event(ws, MSEC_PER_SEC); return ret; } static int alarmtimer_resume(struct device *dev) { struct rtc_device *rtc; rtc = alarmtimer_get_rtcdev(); /* If we have no rtcdev, just return */ if (!rtc) return 0; rtc_timer_cancel(rtc, &rtctimer); return 0; } #else static int alarmtimer_suspend(struct device *dev) { return 0; } static int alarmtimer_resume(struct device *dev) { return 0; } #endif static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) Loading Loading @@ -767,6 +806,7 @@ out: /* Suspend hook structures */ static const struct dev_pm_ops alarmtimer_pm_ops = { .suspend = alarmtimer_suspend, .resume = alarmtimer_resume, }; static struct platform_driver alarmtimer_driver = { Loading Loading
kernel/time/alarmtimer.c +47 −7 Original line number Diff line number Diff line Loading @@ -53,6 +53,17 @@ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; static DEFINE_SPINLOCK(rtcdev_lock); static void alarmtimer_triggered_func(void *p) { struct rtc_device *rtc = rtcdev; if (!(rtc->irq_data & RTC_AF)) return; __pm_wakeup_event(ws, 2 * MSEC_PER_SEC); } static struct rtc_task alarmtimer_rtc_task = { .func = alarmtimer_triggered_func }; /** * alarmtimer_get_rtcdev - Return selected rtcdevice * Loading @@ -63,7 +74,7 @@ static DEFINE_SPINLOCK(rtcdev_lock); struct rtc_device *alarmtimer_get_rtcdev(void) { unsigned long flags; struct rtc_device *ret; struct rtc_device *ret = NULL; spin_lock_irqsave(&rtcdev_lock, flags); ret = rtcdev; Loading @@ -72,29 +83,40 @@ struct rtc_device *alarmtimer_get_rtcdev(void) return ret; } static int alarmtimer_rtc_add_device(struct device *dev, struct class_interface *class_intf) { unsigned long flags; int err = 0; struct rtc_device *rtc = to_rtc_device(dev); if (rtcdev) return -EBUSY; if (!rtc->ops->set_alarm) return -1; if (!device_may_wakeup(rtc->dev.parent)) return -1; spin_lock_irqsave(&rtcdev_lock, flags); if (!rtcdev) { err = rtc_irq_register(rtc, &alarmtimer_rtc_task); if (err) goto rtc_irq_reg_err; rtcdev = rtc; /* hold a reference so it doesn't go away */ get_device(dev); } rtc_irq_reg_err: spin_unlock_irqrestore(&rtcdev_lock, flags); return 0; return err; } static void alarmtimer_rtc_remove_device(struct device *dev, struct class_interface *class_intf) { if (rtcdev && dev == &rtcdev->dev) { rtc_irq_unregister(rtcdev, &alarmtimer_rtc_task); rtcdev = NULL; } } static inline void alarmtimer_rtc_timer_init(void) Loading @@ -104,6 +126,7 @@ static inline void alarmtimer_rtc_timer_init(void) static struct class_interface alarmtimer_rtc_interface = { .add_dev = &alarmtimer_rtc_add_device, .remove_dev = &alarmtimer_rtc_remove_device, }; static int alarmtimer_rtc_interface_setup(void) Loading Loading @@ -270,11 +293,27 @@ static int alarmtimer_suspend(struct device *dev) __pm_wakeup_event(ws, MSEC_PER_SEC); return ret; } static int alarmtimer_resume(struct device *dev) { struct rtc_device *rtc; rtc = alarmtimer_get_rtcdev(); /* If we have no rtcdev, just return */ if (!rtc) return 0; rtc_timer_cancel(rtc, &rtctimer); return 0; } #else static int alarmtimer_suspend(struct device *dev) { return 0; } static int alarmtimer_resume(struct device *dev) { return 0; } #endif static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) Loading Loading @@ -767,6 +806,7 @@ out: /* Suspend hook structures */ static const struct dev_pm_ops alarmtimer_pm_ops = { .suspend = alarmtimer_suspend, .resume = alarmtimer_resume, }; static struct platform_driver alarmtimer_driver = { Loading