* [PATCH 0/2] Alarmtimer fixes for 3.0
@ 2011-06-21 23:52 John Stultz
2011-06-21 23:52 ` [PATCH 1/2] alarmtimers: Handle late rtc module loading John Stultz
2011-06-21 23:52 ` [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present John Stultz
0 siblings, 2 replies; 4+ messages in thread
From: John Stultz @ 2011-06-21 23:52 UTC (permalink / raw)
To: LKML
Cc: John Stultz, Thomas Gleixner, Meelis Roos, Toralf Förster,
Peter Zijlstra
Hey Thomas,
Here are two alarmtimer fixes that should go in for 3.0.
The first is a fix to check for rtc devices on demand, to better
handle late rtc device driver loading. And the second makes sure
we report an error to apps using alarmtiemrs if there is no backing
RTC device.
Let me know if you have any issues with these.
Both of these patches are available in the git repository at:
git://git.linaro.org/people/jstultz/linux.git fortglx/3.0/tip/timers/alarmtimers
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Meelis Roos <mroos@ut.ee>
CC: Toralf Förster <toralf.foerster@gmx.de>
CC: Richard Weinberger <richard@nod.at
CC: Peter Zijlstra <peterz@infradead.org>
John Stultz (2):
alarmtimers: Handle late rtc module loading
alarmtimers: Return -ENOTSUPP if no RTC device is present
kernel/time/alarmtimer.c | 158 +++++++++++++++++++++++++--------------------
1 files changed, 88 insertions(+), 70 deletions(-)
--
1.7.3.2.146.gca209
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] alarmtimers: Handle late rtc module loading
2011-06-21 23:52 [PATCH 0/2] Alarmtimer fixes for 3.0 John Stultz
@ 2011-06-21 23:52 ` John Stultz
2011-06-21 23:52 ` [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present John Stultz
1 sibling, 0 replies; 4+ messages in thread
From: John Stultz @ 2011-06-21 23:52 UTC (permalink / raw)
To: LKML; +Cc: John Stultz, Thomas Gleixner, Meelis Roos
The alarmtimers code currently picks a rtc device to use at
late init time. However, if your rtc driver is loaded as a module,
it may be registered after the alarmtimers late init code, leaving
the alarmtimers nonfunctional.
This patch moves the the rtcdevice selection to when we actually try
to use it, allowing us to make use of rtc modules that may have been
loaded at any point since bootup.
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Meelis Roos <mroos@ut.ee>
Reported-by: Meelis Roos <mroos@ut.ee>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
kernel/time/alarmtimer.c | 137 ++++++++++++++++++++++-----------------------
1 files changed, 67 insertions(+), 70 deletions(-)
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 2d96624..98ecf4e 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -42,15 +42,72 @@ static struct alarm_base {
clockid_t base_clockid;
} alarm_bases[ALARM_NUMTYPE];
+/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */
+static ktime_t freezer_delta;
+static DEFINE_SPINLOCK(freezer_delta_lock);
+
#ifdef CONFIG_RTC_CLASS
/* rtc timer and device for setting alarm wakeups at suspend */
static struct rtc_timer rtctimer;
static struct rtc_device *rtcdev;
-#endif
+static DEFINE_SPINLOCK(rtcdev_lock);
-/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */
-static ktime_t freezer_delta;
-static DEFINE_SPINLOCK(freezer_delta_lock);
+/**
+ * has_wakealarm - check rtc device has wakealarm ability
+ * @dev: current device
+ * @name_ptr: name to be returned
+ *
+ * This helper function checks to see if the rtc device can wake
+ * from suspend.
+ */
+static int has_wakealarm(struct device *dev, void *name_ptr)
+{
+ struct rtc_device *candidate = to_rtc_device(dev);
+
+ if (!candidate->ops->set_alarm)
+ return 0;
+ if (!device_may_wakeup(candidate->dev.parent))
+ return 0;
+
+ *(const char **)name_ptr = dev_name(dev);
+ return 1;
+}
+
+/**
+ * alarmtimer_get_rtcdev - Return selected rtcdevice
+ *
+ * This function returns the rtc device to use for wakealarms.
+ * If one has not already been chosen, it checks to see if a
+ * functional rtc device is available.
+ */
+static struct rtc_device *alarmtimer_get_rtcdev(void)
+{
+ struct device *dev;
+ char *str;
+ unsigned long flags;
+ struct rtc_device *ret;
+
+ spin_lock_irqsave(&rtcdev_lock, flags);
+ if (!rtcdev) {
+ /* Find an rtc device and init the rtc_timer */
+ dev = class_find_device(rtc_class, NULL, &str, has_wakealarm);
+ /* If we have a device then str is valid. See has_wakealarm() */
+ if (dev) {
+ rtcdev = rtc_class_open(str);
+ /*
+ * Drop the reference we got in class_find_device,
+ * rtc_open takes its own.
+ */
+ put_device(dev);
+ rtc_timer_init(&rtctimer, NULL, NULL);
+ }
+ }
+ ret = rtcdev;
+ spin_unlock_irqrestore(&rtcdev_lock, flags);
+
+ return ret;
+}
+#endif
/**
@@ -166,6 +223,7 @@ static int alarmtimer_suspend(struct device *dev)
struct rtc_time tm;
ktime_t min, now;
unsigned long flags;
+ struct rtc_device *rtc;
int i;
spin_lock_irqsave(&freezer_delta_lock, flags);
@@ -173,8 +231,9 @@ static int alarmtimer_suspend(struct device *dev)
freezer_delta = ktime_set(0, 0);
spin_unlock_irqrestore(&freezer_delta_lock, flags);
+ rtc = alarmtimer_get_rtcdev();
/* If we have no rtcdev, just return */
- if (!rtcdev)
+ if (!rtc)
return 0;
/* Find the soonest timer to expire*/
@@ -199,12 +258,12 @@ static int alarmtimer_suspend(struct device *dev)
WARN_ON(min.tv64 < NSEC_PER_SEC);
/* Setup an rtc timer to fire that far in the future */
- rtc_timer_cancel(rtcdev, &rtctimer);
- rtc_read_time(rtcdev, &tm);
+ rtc_timer_cancel(rtc, &rtctimer);
+ rtc_read_time(rtc, &tm);
now = rtc_tm_to_ktime(tm);
now = ktime_add(now, min);
- rtc_timer_start(rtcdev, &rtctimer, now, ktime_set(0, 0));
+ rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
return 0;
}
@@ -638,65 +697,3 @@ static int __init alarmtimer_init(void)
}
device_initcall(alarmtimer_init);
-#ifdef CONFIG_RTC_CLASS
-/**
- * has_wakealarm - check rtc device has wakealarm ability
- * @dev: current device
- * @name_ptr: name to be returned
- *
- * This helper function checks to see if the rtc device can wake
- * from suspend.
- */
-static int __init has_wakealarm(struct device *dev, void *name_ptr)
-{
- struct rtc_device *candidate = to_rtc_device(dev);
-
- if (!candidate->ops->set_alarm)
- return 0;
- if (!device_may_wakeup(candidate->dev.parent))
- return 0;
-
- *(const char **)name_ptr = dev_name(dev);
- return 1;
-}
-
-/**
- * alarmtimer_init_late - Late initializing of alarmtimer code
- *
- * This function locates a rtc device to use for wakealarms.
- * Run as late_initcall to make sure rtc devices have been
- * registered.
- */
-static int __init alarmtimer_init_late(void)
-{
- struct device *dev;
- char *str;
-
- /* Find an rtc device and init the rtc_timer */
- dev = class_find_device(rtc_class, NULL, &str, has_wakealarm);
- /* If we have a device then str is valid. See has_wakealarm() */
- if (dev) {
- rtcdev = rtc_class_open(str);
- /*
- * Drop the reference we got in class_find_device,
- * rtc_open takes its own.
- */
- put_device(dev);
- }
- if (!rtcdev) {
- printk(KERN_WARNING "No RTC device found, ALARM timers will"
- " not wake from suspend");
- }
- rtc_timer_init(&rtctimer, NULL, NULL);
-
- return 0;
-}
-#else
-static int __init alarmtimer_init_late(void)
-{
- printk(KERN_WARNING "Kernel not built with RTC support, ALARM timers"
- " will not wake from suspend");
- return 0;
-}
-#endif
-late_initcall(alarmtimer_init_late);
--
1.7.3.2.146.gca209
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present
2011-06-21 23:52 [PATCH 0/2] Alarmtimer fixes for 3.0 John Stultz
2011-06-21 23:52 ` [PATCH 1/2] alarmtimers: Handle late rtc module loading John Stultz
@ 2011-06-21 23:52 ` John Stultz
2011-06-22 9:19 ` richard -rw- weinberger
1 sibling, 1 reply; 4+ messages in thread
From: John Stultz @ 2011-06-21 23:52 UTC (permalink / raw)
To: LKML; +Cc: John Stultz, Toralf Förster, Peter Zijlstra, Thomas Gleixner
Toralf Förster and Richard Weinberger noted that if there is
no RTC device, the alarm timers core prints out an annoying
"ALARM timers will not wake from suspend" message.
This warning has been removed in a previous patch, however
the issue still remains: The original idea was to support
alarm timers even if there was no rtc device, as long as the
system didn't go into suspend.
However, after further consideration, communicating to the application
that alarmtimers are not fully functional seems like the better
solution.
So this patch makes it so we return -ENOTSUPP to any posix _ALARM
clockid calls if there is no backing RTC device on the system.
Further this changes the behavior where when there is no rtc device
we will check for one on clock_getres, clock_gettime, timer_create,
and timer_nsleep instead of on suspend.
CC: Toralf Förster <toralf.foerster@gmx.de>
CC: Richard Weinberger <richard@nod.at
CC: Peter Zijlstra <peterz@infradead.org>
CC: Thomas Gleixner <tglx@linutronix.de>
Reported-by: Toralf Förster <toralf.foerster@gmx.de>
Reported by: Richard Weinberger <richard@nod.at>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
kernel/time/alarmtimer.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 98ecf4e..59f369f 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -107,6 +107,9 @@ static struct rtc_device *alarmtimer_get_rtcdev(void)
return ret;
}
+#else
+#define alarmtimer_get_rtcdev() (0)
+#define rtcdev (0)
#endif
@@ -231,7 +234,7 @@ static int alarmtimer_suspend(struct device *dev)
freezer_delta = ktime_set(0, 0);
spin_unlock_irqrestore(&freezer_delta_lock, flags);
- rtc = alarmtimer_get_rtcdev();
+ rtc = rtcdev;
/* If we have no rtcdev, just return */
if (!rtc)
return 0;
@@ -381,6 +384,9 @@ static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp)
{
clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid;
+ if (!alarmtimer_get_rtcdev())
+ return -ENOTSUPP;
+
return hrtimer_get_res(baseid, tp);
}
@@ -395,6 +401,9 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp)
{
struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];
+ if (!alarmtimer_get_rtcdev())
+ return -ENOTSUPP;
+
*tp = ktime_to_timespec(base->gettime());
return 0;
}
@@ -410,6 +419,9 @@ static int alarm_timer_create(struct k_itimer *new_timer)
enum alarmtimer_type type;
struct alarm_base *base;
+ if (!alarmtimer_get_rtcdev())
+ return -ENOTSUPP;
+
if (!capable(CAP_WAKE_ALARM))
return -EPERM;
@@ -444,6 +456,9 @@ static void alarm_timer_get(struct k_itimer *timr,
*/
static int alarm_timer_del(struct k_itimer *timr)
{
+ if (!rtcdev)
+ return -ENOTSUPP;
+
alarm_cancel(&timr->it.alarmtimer);
return 0;
}
@@ -461,6 +476,9 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
struct itimerspec *new_setting,
struct itimerspec *old_setting)
{
+ if (!rtcdev)
+ return -ENOTSUPP;
+
/* Save old values */
old_setting->it_interval =
ktime_to_timespec(timr->it.alarmtimer.period);
@@ -600,6 +618,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
int ret = 0;
struct restart_block *restart;
+ if (!alarmtimer_get_rtcdev())
+ return -ENOTSUPP;
+
if (!capable(CAP_WAKE_ALARM))
return -EPERM;
--
1.7.3.2.146.gca209
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present
2011-06-21 23:52 ` [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present John Stultz
@ 2011-06-22 9:19 ` richard -rw- weinberger
0 siblings, 0 replies; 4+ messages in thread
From: richard -rw- weinberger @ 2011-06-22 9:19 UTC (permalink / raw)
To: John Stultz; +Cc: LKML, Toralf Förster, Peter Zijlstra, Thomas Gleixner
2011/6/22 John Stultz <john.stultz@linaro.org>:
> Toralf Förster and Richard Weinberger noted that if there is
> no RTC device, the alarm timers core prints out an annoying
> "ALARM timers will not wake from suspend" message.
>
> This warning has been removed in a previous patch, however
> the issue still remains: The original idea was to support
> alarm timers even if there was no rtc device, as long as the
> system didn't go into suspend.
>
> However, after further consideration, communicating to the application
> that alarmtimers are not fully functional seems like the better
> solution.
>
> So this patch makes it so we return -ENOTSUPP to any posix _ALARM
> clockid calls if there is no backing RTC device on the system.
>
> Further this changes the behavior where when there is no rtc device
> we will check for one on clock_getres, clock_gettime, timer_create,
> and timer_nsleep instead of on suspend.
>
> CC: Toralf Förster <toralf.foerster@gmx.de>
> CC: Richard Weinberger <richard@nod.at
Ahhh, the missing ">" explains why I didn't receive this mail. :-)
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-06-22 9:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-21 23:52 [PATCH 0/2] Alarmtimer fixes for 3.0 John Stultz
2011-06-21 23:52 ` [PATCH 1/2] alarmtimers: Handle late rtc module loading John Stultz
2011-06-21 23:52 ` [PATCH 2/2] alarmtimers: Return -ENOTSUPP if no RTC device is present John Stultz
2011-06-22 9:19 ` richard -rw- weinberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®