Skip to content

Commit

Permalink
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/linux-2.6-tip

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  hrtimer: Make lookup table const
  RTC: Disable CONFIG_RTC_CLASS from being built as a module
  timers: Fix alarmtimer build issues when CONFIG_RTC_CLASS=n
  timers: Remove delayed irqwork from alarmtimers implementation
  timers: Improve alarmtimer comments and minor fixes
  timers: Posix interface for alarm-timers
  timers: Introduce in-kernel alarm-timer interface
  timers: Add rb_init_node() to allow for stack allocated rb nodes
  time: Add timekeeping_inject_sleeptime
  • Loading branch information
torvalds committed May 20, 2011
2 parents 7e6628e + 942c3c5 commit 78c4def
Showing 12 changed files with 820 additions and 26 deletions.
7 changes: 2 additions & 5 deletions drivers/rtc/Kconfig
Original file line number Diff line number Diff line change
@@ -3,10 +3,10 @@
#

config RTC_LIB
tristate
bool

menuconfig RTC_CLASS
tristate "Real Time Clock"
bool "Real Time Clock"
default n
depends on !S390
select RTC_LIB
@@ -15,9 +15,6 @@ menuconfig RTC_CLASS
be allowed to plug one or more RTCs to your system. You will
probably want to enable one or more of the interfaces below.

This driver can also be built as a module. If so, the module
will be called rtc-core.

if RTC_CLASS

config RTC_HCTOSYS
23 changes: 9 additions & 14 deletions drivers/rtc/class.c
Original file line number Diff line number Diff line change
@@ -41,26 +41,21 @@ static void rtc_device_release(struct device *dev)
* system's wall clock; restore it on resume().
*/

static struct timespec delta;
static time_t oldtime;
static struct timespec oldts;

static int rtc_suspend(struct device *dev, pm_message_t mesg)
{
struct rtc_device *rtc = to_rtc_device(dev);
struct rtc_time tm;
struct timespec ts = current_kernel_time();

if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
return 0;

rtc_read_time(rtc, &tm);
ktime_get_ts(&oldts);
rtc_tm_to_time(&tm, &oldtime);

/* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
set_normalized_timespec(&delta,
ts.tv_sec - oldtime,
ts.tv_nsec - (NSEC_PER_SEC >> 1));

return 0;
}

@@ -70,10 +65,12 @@ static int rtc_resume(struct device *dev)
struct rtc_time tm;
time_t newtime;
struct timespec time;
struct timespec newts;

if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
return 0;

ktime_get_ts(&newts);
rtc_read_time(rtc, &tm);
if (rtc_valid_tm(&tm) != 0) {
pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
@@ -85,15 +82,13 @@ static int rtc_resume(struct device *dev)
pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
return 0;
}
/* calculate the RTC time delta */
set_normalized_timespec(&time, newtime - oldtime, 0);

/* restore wall clock using delta against this RTC;
* adjust again for avg 1/2 second RTC sampling error
*/
set_normalized_timespec(&time,
newtime + delta.tv_sec,
(NSEC_PER_SEC >> 1) + delta.tv_nsec);
do_settimeofday(&time);
/* subtract kernel time between rtc_suspend to rtc_resume */
time = timespec_sub(time, timespec_sub(newts, oldts));

timekeeping_inject_sleeptime(&time);
return 0;
}

40 changes: 40 additions & 0 deletions include/linux/alarmtimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef _LINUX_ALARMTIMER_H
#define _LINUX_ALARMTIMER_H

#include <linux/time.h>
#include <linux/hrtimer.h>
#include <linux/timerqueue.h>
#include <linux/rtc.h>

enum alarmtimer_type {
ALARM_REALTIME,
ALARM_BOOTTIME,

ALARM_NUMTYPE,
};

/**
* struct alarm - Alarm timer structure
* @node: timerqueue node for adding to the event list this value
* also includes the expiration time.
* @period: Period for recuring alarms
* @function: Function pointer to be executed when the timer fires.
* @type: Alarm type (BOOTTIME/REALTIME)
* @enabled: Flag that represents if the alarm is set to fire or not
* @data: Internal data value.
*/
struct alarm {
struct timerqueue_node node;
ktime_t period;
void (*function)(struct alarm *);
enum alarmtimer_type type;
bool enabled;
void *data;
};

void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
void (*function)(struct alarm *));
void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);
void alarm_cancel(struct alarm *alarm);

#endif
7 changes: 6 additions & 1 deletion include/linux/capability.h
Original file line number Diff line number Diff line change
@@ -355,7 +355,12 @@ struct cpu_vfs_cap_data {

#define CAP_SYSLOG 34

#define CAP_LAST_CAP CAP_SYSLOG
/* Allow triggering something that will wake the system */

#define CAP_WAKE_ALARM 35


#define CAP_LAST_CAP CAP_WAKE_ALARM

#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)

2 changes: 2 additions & 0 deletions include/linux/posix-timers.h
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/timex.h>
#include <linux/alarmtimer.h>

union cpu_time_count {
cputime_t cpu;
@@ -80,6 +81,7 @@ struct k_itimer {
unsigned long incr;
unsigned long expires;
} mmtimer;
struct alarm alarmtimer;
} it;
};

8 changes: 8 additions & 0 deletions include/linux/rbtree.h
Original file line number Diff line number Diff line change
@@ -136,6 +136,14 @@ static inline void rb_set_color(struct rb_node *rb, int color)
#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))

static inline void rb_init_node(struct rb_node *rb)
{
rb->rb_parent_color = 0;
rb->rb_right = NULL;
rb->rb_left = NULL;
RB_CLEAR_NODE(rb);
}

extern void rb_insert_color(struct rb_node *, struct rb_root *);
extern void rb_erase(struct rb_node *, struct rb_root *);

3 changes: 3 additions & 0 deletions include/linux/time.h
Original file line number Diff line number Diff line change
@@ -126,6 +126,7 @@ struct timespec __current_kernel_time(void); /* does not take xtime_lock */
struct timespec get_monotonic_coarse(void);
void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
struct timespec *wtom, struct timespec *sleep);
void timekeeping_inject_sleeptime(struct timespec *delta);

#define CURRENT_TIME (current_kernel_time())
#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 })
@@ -294,6 +295,8 @@ struct itimerval {
#define CLOCK_REALTIME_COARSE 5
#define CLOCK_MONOTONIC_COARSE 6
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9

/*
* The IDs of various hardware clocks:
2 changes: 1 addition & 1 deletion include/linux/timerqueue.h
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)

static inline void timerqueue_init(struct timerqueue_node *node)
{
RB_CLEAR_NODE(&node->node);
rb_init_node(&node->node);
}

static inline void timerqueue_init_head(struct timerqueue_head *head)
2 changes: 1 addition & 1 deletion kernel/hrtimer.c
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
}
};

static int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME,
[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC,
[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME,
2 changes: 1 addition & 1 deletion kernel/time/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o
obj-y += timeconv.o posix-clock.o
obj-y += timeconv.o posix-clock.o alarmtimer.o

obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
Loading

0 comments on commit 78c4def

Please sign in to comment.