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/tip

Pull timer core updates from Thomas Gleixner:
 "The time(r) departement provides:

   - more infrastructure work on the year 2038 issue

   - a few fixes in the Armada SoC timers

   - the usual pile of fixlets and improvements"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource: armada-370-xp: Use the reference clock on A375 SoC
  watchdog: orion: Use the reference clock on Armada 375 SoC
  clocksource: armada-370-xp: Add missing clock enable
  time: Fix sign bug in NTP mult overflow warning
  time: Remove timekeeping_inject_sleeptime()
  rtc: Update suspend/resume timing to use 64bit time
  rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm() replacement
  time: Fixup comments to reflect usage of timespec64
  time: Expose get_monotonic_coarse64() for in-kernel uses
  time: Expose getrawmonotonic64 for in-kernel uses
  time: Provide y2038 safe mktime() replacement
  time: Provide y2038 safe timekeeping_inject_sleeptime() replacement
  time: Provide y2038 safe do_settimeofday() replacement
  time: Complete NTP adjustment threshold judging conditions
  time: Avoid possible NTP adjustment mult overflow.
  time: Rename udelay_test.c to test_udelay.c
  clocksource: sirf: Remove hard-coded clock rate
  • Loading branch information
torvalds committed Dec 10, 2014
2 parents 86c6a2f + 89de77a commit a157508
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ Marvell Armada 370 and Armada XP Timers
---------------------------------------

Required properties:
- compatible: Should be either "marvell,armada-370-timer" or
"marvell,armada-xp-timer" as appropriate.
- compatible: Should be one of the following
"marvell,armada-370-timer",
"marvell,armada-375-timer",
"marvell,armada-xp-timer".
- interrupts: Should contain the list of Global Timer interrupts and
then local timer interrupts
- reg: Should contain location and length for timers register. First
Expand All @@ -13,7 +15,8 @@ Required properties:
Clocks required for compatible = "marvell,armada-370-timer":
- clocks : Must contain a single entry describing the clock input

Clocks required for compatible = "marvell,armada-xp-timer":
Clocks required for compatibles = "marvell,armada-xp-timer",
"marvell,armada-375-timer":
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : Must include the following entries:
"nbclk" (L2/coherency fabric clock),
Expand Down
13 changes: 13 additions & 0 deletions Documentation/devicetree/bindings/watchdog/marvel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ For "marvell,armada-375-wdt" and "marvell,armada-380-wdt":
- reg : A third entry is mandatory and should contain the
shared mask/unmask RSTOUT address.

Clocks required for compatibles = "marvell,orion-wdt",
"marvell,armada-370-wdt":
- clocks : Must contain a single entry describing the clock input

Clocks required for compatibles = "marvell,armada-xp-wdt"
"marvell,armada-375-wdt"
"marvell,armada-380-wdt":
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : Must include the following entries:
"nbclk" (L2/coherency fabric clock),
"fixed" (Reference 25 MHz fixed-clock).

Optional properties:

- interrupts : Contains the IRQ for watchdog expiration
Expand All @@ -30,4 +42,5 @@ Example:
interrupts = <3>;
timeout-sec = <10>;
status = "okay";
clocks = <&gate_clk 7>;
};
30 changes: 30 additions & 0 deletions drivers/clocksource/time-armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,18 +318,48 @@ static void __init armada_xp_timer_init(struct device_node *np)

/* The 25Mhz fixed clock is mandatory, and must always be available */
BUG_ON(IS_ERR(clk));
clk_prepare_enable(clk);
timer_clk = clk_get_rate(clk);

armada_370_xp_timer_common_init(np);
}
CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
armada_xp_timer_init);

static void __init armada_375_timer_init(struct device_node *np)
{
struct clk *clk;

clk = of_clk_get_by_name(np, "fixed");
if (!IS_ERR(clk)) {
clk_prepare_enable(clk);
timer_clk = clk_get_rate(clk);
} else {

/*
* This fallback is required in order to retain proper
* devicetree backwards compatibility.
*/
clk = of_clk_get(np, 0);

/* Must have at least a clock */
BUG_ON(IS_ERR(clk));
clk_prepare_enable(clk);
timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
timer25Mhz = false;
}

armada_370_xp_timer_common_init(np);
}
CLOCKSOURCE_OF_DECLARE(armada_375, "marvell,armada-375-timer",
armada_375_timer_init);

static void __init armada_370_timer_init(struct device_node *np)
{
struct clk *clk = of_clk_get(np, 0);

BUG_ON(IS_ERR(clk));
clk_prepare_enable(clk);
timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
timer25Mhz = false;

Expand Down
23 changes: 9 additions & 14 deletions drivers/clocksource/timer-marco.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <linux/of_address.h>
#include <linux/sched_clock.h>

#define MARCO_CLOCK_FREQ 1000000

#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
#define SIRFSOC_TIMER_MATCH_0 0x0018
Expand All @@ -40,6 +38,8 @@

#define SIRFSOC_TIMER_REG_CNT 6

static unsigned long marco_timer_rate;

static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
SIRFSOC_TIMER_WATCHDOG_EN,
SIRFSOC_TIMER_32COUNTER_0_CTRL,
Expand Down Expand Up @@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
ce->rating = 200;
ce->set_mode = sirfsoc_timer_set_mode;
ce->set_next_event = sirfsoc_timer_set_next_event;
clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60);
clockevents_calc_mult_shift(ce, marco_timer_rate, 60);
ce->max_delta_ns = clockevent_delta2ns(-2, ce);
ce->min_delta_ns = clockevent_delta2ns(2, ce);
ce->cpumask = cpumask_of(cpu);
Expand Down Expand Up @@ -257,7 +257,6 @@ static void __init sirfsoc_clockevent_init(void)
/* initialize the kernel jiffy timer source */
static void __init sirfsoc_marco_timer_init(struct device_node *np)
{
unsigned long rate;
u32 timer_div;
struct clk *clk;

Expand All @@ -266,16 +265,12 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)

BUG_ON(clk_prepare_enable(clk));

rate = clk_get_rate(clk);

BUG_ON(rate < MARCO_CLOCK_FREQ);
BUG_ON(rate % MARCO_CLOCK_FREQ);
marco_timer_rate = clk_get_rate(clk);

/* Initialize the timer dividers */
timer_div = rate / MARCO_CLOCK_FREQ - 1;
writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
/* timer dividers: 0, not divided */
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);

/* Initialize timer counters to 0 */
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
Expand All @@ -288,7 +283,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
/* Clear all interrupts */
writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);

BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ));
BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, marco_timer_rate));

sirfsoc_clockevent_init();
}
Expand Down
30 changes: 15 additions & 15 deletions drivers/rtc/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ int rtc_hctosys_ret = -ENODEV;
* system's wall clock; restore it on resume().
*/

static struct timespec old_rtc, old_system, old_delta;
static struct timespec64 old_rtc, old_system, old_delta;


static int rtc_suspend(struct device *dev)
{
struct rtc_device *rtc = to_rtc_device(dev);
struct rtc_time tm;
struct timespec delta, delta_delta;
struct timespec64 delta, delta_delta;
int err;

if (has_persistent_clock())
Expand All @@ -68,8 +68,8 @@ static int rtc_suspend(struct device *dev)
return 0;
}

getnstimeofday(&old_system);
rtc_tm_to_time(&tm, &old_rtc.tv_sec);
getnstimeofday64(&old_system);
old_rtc.tv_sec = rtc_tm_to_time64(&tm);


/*
Expand All @@ -78,8 +78,8 @@ static int rtc_suspend(struct device *dev)
* try to compensate so the difference in system time
* and rtc time stays close to constant.
*/
delta = timespec_sub(old_system, old_rtc);
delta_delta = timespec_sub(delta, old_delta);
delta = timespec64_sub(old_system, old_rtc);
delta_delta = timespec64_sub(delta, old_delta);
if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
/*
* if delta_delta is too large, assume time correction
Expand All @@ -88,7 +88,7 @@ static int rtc_suspend(struct device *dev)
old_delta = delta;
} else {
/* Otherwise try to adjust old_system to compensate */
old_system = timespec_sub(old_system, delta_delta);
old_system = timespec64_sub(old_system, delta_delta);
}

return 0;
Expand All @@ -98,8 +98,8 @@ static int rtc_resume(struct device *dev)
{
struct rtc_device *rtc = to_rtc_device(dev);
struct rtc_time tm;
struct timespec new_system, new_rtc;
struct timespec sleep_time;
struct timespec64 new_system, new_rtc;
struct timespec64 sleep_time;
int err;

if (has_persistent_clock())
Expand All @@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev)
return 0;

/* snapshot the current rtc and system time at resume */
getnstimeofday(&new_system);
getnstimeofday64(&new_system);
err = rtc_read_time(rtc, &tm);
if (err < 0) {
pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev));
Expand All @@ -121,7 +121,7 @@ static int rtc_resume(struct device *dev)
pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
return 0;
}
rtc_tm_to_time(&tm, &new_rtc.tv_sec);
new_rtc.tv_sec = rtc_tm_to_time64(&tm);
new_rtc.tv_nsec = 0;

if (new_rtc.tv_sec < old_rtc.tv_sec) {
Expand All @@ -130,7 +130,7 @@ static int rtc_resume(struct device *dev)
}

/* calculate the RTC time delta (sleep time)*/
sleep_time = timespec_sub(new_rtc, old_rtc);
sleep_time = timespec64_sub(new_rtc, old_rtc);

/*
* Since these RTC suspend/resume handlers are not called
Expand All @@ -139,11 +139,11 @@ static int rtc_resume(struct device *dev)
* so subtract kernel run-time between rtc_suspend to rtc_resume
* to keep things accurate.
*/
sleep_time = timespec_sub(sleep_time,
timespec_sub(new_system, old_system));
sleep_time = timespec64_sub(sleep_time,
timespec64_sub(new_system, old_system));

if (sleep_time.tv_sec >= 0)
timekeeping_inject_sleeptime(&sleep_time);
timekeeping_inject_sleeptime64(&sleep_time);
rtc_hctosys_ret = 0;
return 0;
}
Expand Down
38 changes: 20 additions & 18 deletions drivers/rtc/rtc-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,20 @@ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
}
EXPORT_SYMBOL(rtc_year_days);


/*
* rtc_time_to_tm64 - Converts time64_t to rtc_time.
* Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
*/
void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
{
unsigned int month, year;
unsigned long secs;
int days;

days = time / 86400;
time -= (unsigned int) days * 86400;
/* time must be positive */
days = div_s64(time, 86400);
secs = time - (unsigned int) days * 86400;

/* day of the week, 1970-01-01 was a Thursday */
tm->tm_wday = (days + 4) % 7;
Expand All @@ -81,14 +85,14 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
tm->tm_mon = month;
tm->tm_mday = days + 1;

tm->tm_hour = time / 3600;
time -= tm->tm_hour * 3600;
tm->tm_min = time / 60;
tm->tm_sec = time - tm->tm_min * 60;
tm->tm_hour = secs / 3600;
secs -= tm->tm_hour * 3600;
tm->tm_min = secs / 60;
tm->tm_sec = secs - tm->tm_min * 60;

tm->tm_isdst = 0;
}
EXPORT_SYMBOL(rtc_time_to_tm);
EXPORT_SYMBOL(rtc_time64_to_tm);

/*
* Does the rtc_time represent a valid date/time?
Expand All @@ -109,24 +113,22 @@ int rtc_valid_tm(struct rtc_time *tm)
EXPORT_SYMBOL(rtc_valid_tm);

/*
* rtc_tm_to_time64 - Converts rtc_time to time64_t.
* Convert Gregorian date to seconds since 01-01-1970 00:00:00.
*/
int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
time64_t rtc_tm_to_time64(struct rtc_time *tm)
{
*time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
return mktime64(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0;
}
EXPORT_SYMBOL(rtc_tm_to_time);
EXPORT_SYMBOL(rtc_tm_to_time64);

/*
* Convert rtc_time to ktime
*/
ktime_t rtc_tm_to_ktime(struct rtc_time tm)
{
time_t time;
rtc_tm_to_time(&tm, &time);
return ktime_set(time, 0);
return ktime_set(rtc_tm_to_time64(&tm), 0);
}
EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);

Expand All @@ -135,14 +137,14 @@ EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
*/
struct rtc_time rtc_ktime_to_tm(ktime_t kt)
{
struct timespec ts;
struct timespec64 ts;
struct rtc_time ret;

ts = ktime_to_timespec(kt);
ts = ktime_to_timespec64(kt);
/* Round up any ns */
if (ts.tv_nsec)
ts.tv_sec++;
rtc_time_to_tm(ts.tv_sec, &ret);
rtc_time64_to_tm(ts.tv_sec, &ret);
return ret;
}
EXPORT_SYMBOL_GPL(rtc_ktime_to_tm);
Expand Down
Loading

0 comments on commit a157508

Please sign in to comment.