alarmtimers: Return -ENOTSUPP if no RTC device is present
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>
This commit is contained in:
parent
c008ba58af
commit
1c6b39ad3f
|
@ -107,6 +107,9 @@ static struct rtc_device *alarmtimer_get_rtcdev(void)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define alarmtimer_get_rtcdev() (0)
|
||||||
|
#define rtcdev (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,7 +234,7 @@ static int alarmtimer_suspend(struct device *dev)
|
||||||
freezer_delta = ktime_set(0, 0);
|
freezer_delta = ktime_set(0, 0);
|
||||||
spin_unlock_irqrestore(&freezer_delta_lock, flags);
|
spin_unlock_irqrestore(&freezer_delta_lock, flags);
|
||||||
|
|
||||||
rtc = alarmtimer_get_rtcdev();
|
rtc = rtcdev;
|
||||||
/* If we have no rtcdev, just return */
|
/* If we have no rtcdev, just return */
|
||||||
if (!rtc)
|
if (!rtc)
|
||||||
return 0;
|
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;
|
clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid;
|
||||||
|
|
||||||
|
if (!alarmtimer_get_rtcdev())
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
return hrtimer_get_res(baseid, tp);
|
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)];
|
struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];
|
||||||
|
|
||||||
|
if (!alarmtimer_get_rtcdev())
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
*tp = ktime_to_timespec(base->gettime());
|
*tp = ktime_to_timespec(base->gettime());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -410,6 +419,9 @@ static int alarm_timer_create(struct k_itimer *new_timer)
|
||||||
enum alarmtimer_type type;
|
enum alarmtimer_type type;
|
||||||
struct alarm_base *base;
|
struct alarm_base *base;
|
||||||
|
|
||||||
|
if (!alarmtimer_get_rtcdev())
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
if (!capable(CAP_WAKE_ALARM))
|
if (!capable(CAP_WAKE_ALARM))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
@ -444,6 +456,9 @@ static void alarm_timer_get(struct k_itimer *timr,
|
||||||
*/
|
*/
|
||||||
static int alarm_timer_del(struct k_itimer *timr)
|
static int alarm_timer_del(struct k_itimer *timr)
|
||||||
{
|
{
|
||||||
|
if (!rtcdev)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
alarm_cancel(&timr->it.alarmtimer);
|
alarm_cancel(&timr->it.alarmtimer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -461,6 +476,9 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
|
||||||
struct itimerspec *new_setting,
|
struct itimerspec *new_setting,
|
||||||
struct itimerspec *old_setting)
|
struct itimerspec *old_setting)
|
||||||
{
|
{
|
||||||
|
if (!rtcdev)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
/* Save old values */
|
/* Save old values */
|
||||||
old_setting->it_interval =
|
old_setting->it_interval =
|
||||||
ktime_to_timespec(timr->it.alarmtimer.period);
|
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;
|
int ret = 0;
|
||||||
struct restart_block *restart;
|
struct restart_block *restart;
|
||||||
|
|
||||||
|
if (!alarmtimer_get_rtcdev())
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
if (!capable(CAP_WAKE_ALARM))
|
if (!capable(CAP_WAKE_ALARM))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue