Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/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
This commit is contained in:
@ -2,8 +2,10 @@ Marvell Armada 370 and Armada XP Timers
|
|||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Should be either "marvell,armada-370-timer" or
|
- compatible: Should be one of the following
|
||||||
"marvell,armada-xp-timer" as appropriate.
|
"marvell,armada-370-timer",
|
||||||
|
"marvell,armada-375-timer",
|
||||||
|
"marvell,armada-xp-timer".
|
||||||
- interrupts: Should contain the list of Global Timer interrupts and
|
- interrupts: Should contain the list of Global Timer interrupts and
|
||||||
then local timer interrupts
|
then local timer interrupts
|
||||||
- reg: Should contain location and length for timers register. First
|
- reg: Should contain location and length for timers register. First
|
||||||
@ -13,7 +15,8 @@ Required properties:
|
|||||||
Clocks required for compatible = "marvell,armada-370-timer":
|
Clocks required for compatible = "marvell,armada-370-timer":
|
||||||
- clocks : Must contain a single entry describing the clock input
|
- 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.
|
- clocks : Must contain an entry for each entry in clock-names.
|
||||||
- clock-names : Must include the following entries:
|
- clock-names : Must include the following entries:
|
||||||
"nbclk" (L2/coherency fabric clock),
|
"nbclk" (L2/coherency fabric clock),
|
||||||
|
@ -17,6 +17,18 @@ For "marvell,armada-375-wdt" and "marvell,armada-380-wdt":
|
|||||||
- reg : A third entry is mandatory and should contain the
|
- reg : A third entry is mandatory and should contain the
|
||||||
shared mask/unmask RSTOUT address.
|
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:
|
Optional properties:
|
||||||
|
|
||||||
- interrupts : Contains the IRQ for watchdog expiration
|
- interrupts : Contains the IRQ for watchdog expiration
|
||||||
@ -30,4 +42,5 @@ Example:
|
|||||||
interrupts = <3>;
|
interrupts = <3>;
|
||||||
timeout-sec = <10>;
|
timeout-sec = <10>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
clocks = <&gate_clk 7>;
|
||||||
};
|
};
|
||||||
|
@ -318,6 +318,7 @@ static void __init armada_xp_timer_init(struct device_node *np)
|
|||||||
|
|
||||||
/* The 25Mhz fixed clock is mandatory, and must always be available */
|
/* The 25Mhz fixed clock is mandatory, and must always be available */
|
||||||
BUG_ON(IS_ERR(clk));
|
BUG_ON(IS_ERR(clk));
|
||||||
|
clk_prepare_enable(clk);
|
||||||
timer_clk = clk_get_rate(clk);
|
timer_clk = clk_get_rate(clk);
|
||||||
|
|
||||||
armada_370_xp_timer_common_init(np);
|
armada_370_xp_timer_common_init(np);
|
||||||
@ -325,11 +326,40 @@ static void __init armada_xp_timer_init(struct device_node *np)
|
|||||||
CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
|
CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
|
||||||
armada_xp_timer_init);
|
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)
|
static void __init armada_370_timer_init(struct device_node *np)
|
||||||
{
|
{
|
||||||
struct clk *clk = of_clk_get(np, 0);
|
struct clk *clk = of_clk_get(np, 0);
|
||||||
|
|
||||||
BUG_ON(IS_ERR(clk));
|
BUG_ON(IS_ERR(clk));
|
||||||
|
clk_prepare_enable(clk);
|
||||||
timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
|
timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
|
||||||
timer25Mhz = false;
|
timer25Mhz = false;
|
||||||
|
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/sched_clock.h>
|
#include <linux/sched_clock.h>
|
||||||
|
|
||||||
#define MARCO_CLOCK_FREQ 1000000
|
|
||||||
|
|
||||||
#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
|
#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
|
||||||
#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
|
#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
|
||||||
#define SIRFSOC_TIMER_MATCH_0 0x0018
|
#define SIRFSOC_TIMER_MATCH_0 0x0018
|
||||||
@ -40,6 +38,8 @@
|
|||||||
|
|
||||||
#define SIRFSOC_TIMER_REG_CNT 6
|
#define SIRFSOC_TIMER_REG_CNT 6
|
||||||
|
|
||||||
|
static unsigned long marco_timer_rate;
|
||||||
|
|
||||||
static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
|
static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
|
||||||
SIRFSOC_TIMER_WATCHDOG_EN,
|
SIRFSOC_TIMER_WATCHDOG_EN,
|
||||||
SIRFSOC_TIMER_32COUNTER_0_CTRL,
|
SIRFSOC_TIMER_32COUNTER_0_CTRL,
|
||||||
@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
|
|||||||
ce->rating = 200;
|
ce->rating = 200;
|
||||||
ce->set_mode = sirfsoc_timer_set_mode;
|
ce->set_mode = sirfsoc_timer_set_mode;
|
||||||
ce->set_next_event = sirfsoc_timer_set_next_event;
|
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->max_delta_ns = clockevent_delta2ns(-2, ce);
|
||||||
ce->min_delta_ns = clockevent_delta2ns(2, ce);
|
ce->min_delta_ns = clockevent_delta2ns(2, ce);
|
||||||
ce->cpumask = cpumask_of(cpu);
|
ce->cpumask = cpumask_of(cpu);
|
||||||
@ -257,7 +257,6 @@ static void __init sirfsoc_clockevent_init(void)
|
|||||||
/* initialize the kernel jiffy timer source */
|
/* initialize the kernel jiffy timer source */
|
||||||
static void __init sirfsoc_marco_timer_init(struct device_node *np)
|
static void __init sirfsoc_marco_timer_init(struct device_node *np)
|
||||||
{
|
{
|
||||||
unsigned long rate;
|
|
||||||
u32 timer_div;
|
u32 timer_div;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
||||||
@ -266,16 +265,12 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
|
|||||||
|
|
||||||
BUG_ON(clk_prepare_enable(clk));
|
BUG_ON(clk_prepare_enable(clk));
|
||||||
|
|
||||||
rate = clk_get_rate(clk);
|
marco_timer_rate = clk_get_rate(clk);
|
||||||
|
|
||||||
BUG_ON(rate < MARCO_CLOCK_FREQ);
|
/* timer dividers: 0, not divided */
|
||||||
BUG_ON(rate % MARCO_CLOCK_FREQ);
|
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
|
||||||
|
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
|
||||||
/* Initialize the timer dividers */
|
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Initialize timer counters to 0 */
|
/* Initialize timer counters to 0 */
|
||||||
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
|
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
|
||||||
@ -288,7 +283,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
|
|||||||
/* Clear all interrupts */
|
/* Clear all interrupts */
|
||||||
writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
|
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();
|
sirfsoc_clockevent_init();
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,14 @@ int rtc_hctosys_ret = -ENODEV;
|
|||||||
* system's wall clock; restore it on resume().
|
* 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)
|
static int rtc_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rtc_device *rtc = to_rtc_device(dev);
|
struct rtc_device *rtc = to_rtc_device(dev);
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
struct timespec delta, delta_delta;
|
struct timespec64 delta, delta_delta;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (has_persistent_clock())
|
if (has_persistent_clock())
|
||||||
@ -68,8 +68,8 @@ static int rtc_suspend(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getnstimeofday(&old_system);
|
getnstimeofday64(&old_system);
|
||||||
rtc_tm_to_time(&tm, &old_rtc.tv_sec);
|
old_rtc.tv_sec = rtc_tm_to_time64(&tm);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -78,8 +78,8 @@ static int rtc_suspend(struct device *dev)
|
|||||||
* try to compensate so the difference in system time
|
* try to compensate so the difference in system time
|
||||||
* and rtc time stays close to constant.
|
* and rtc time stays close to constant.
|
||||||
*/
|
*/
|
||||||
delta = timespec_sub(old_system, old_rtc);
|
delta = timespec64_sub(old_system, old_rtc);
|
||||||
delta_delta = timespec_sub(delta, old_delta);
|
delta_delta = timespec64_sub(delta, old_delta);
|
||||||
if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
|
if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
|
||||||
/*
|
/*
|
||||||
* if delta_delta is too large, assume time correction
|
* if delta_delta is too large, assume time correction
|
||||||
@ -88,7 +88,7 @@ static int rtc_suspend(struct device *dev)
|
|||||||
old_delta = delta;
|
old_delta = delta;
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise try to adjust old_system to compensate */
|
/* 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;
|
return 0;
|
||||||
@ -98,8 +98,8 @@ static int rtc_resume(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct rtc_device *rtc = to_rtc_device(dev);
|
struct rtc_device *rtc = to_rtc_device(dev);
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
struct timespec new_system, new_rtc;
|
struct timespec64 new_system, new_rtc;
|
||||||
struct timespec sleep_time;
|
struct timespec64 sleep_time;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (has_persistent_clock())
|
if (has_persistent_clock())
|
||||||
@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* snapshot the current rtc and system time at resume */
|
/* snapshot the current rtc and system time at resume */
|
||||||
getnstimeofday(&new_system);
|
getnstimeofday64(&new_system);
|
||||||
err = rtc_read_time(rtc, &tm);
|
err = rtc_read_time(rtc, &tm);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev));
|
pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev));
|
||||||
@ -121,7 +121,7 @@ static int rtc_resume(struct device *dev)
|
|||||||
pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
|
pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
|
||||||
return 0;
|
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;
|
new_rtc.tv_nsec = 0;
|
||||||
|
|
||||||
if (new_rtc.tv_sec < old_rtc.tv_sec) {
|
if (new_rtc.tv_sec < old_rtc.tv_sec) {
|
||||||
@ -130,7 +130,7 @@ static int rtc_resume(struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the RTC time delta (sleep time)*/
|
/* 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
|
* Since these RTC suspend/resume handlers are not called
|
||||||
@ -139,11 +139,11 @@ static int rtc_resume(struct device *dev)
|
|||||||
* so subtract kernel run-time between rtc_suspend to rtc_resume
|
* so subtract kernel run-time between rtc_suspend to rtc_resume
|
||||||
* to keep things accurate.
|
* to keep things accurate.
|
||||||
*/
|
*/
|
||||||
sleep_time = timespec_sub(sleep_time,
|
sleep_time = timespec64_sub(sleep_time,
|
||||||
timespec_sub(new_system, old_system));
|
timespec64_sub(new_system, old_system));
|
||||||
|
|
||||||
if (sleep_time.tv_sec >= 0)
|
if (sleep_time.tv_sec >= 0)
|
||||||
timekeeping_inject_sleeptime(&sleep_time);
|
timekeeping_inject_sleeptime64(&sleep_time);
|
||||||
rtc_hctosys_ret = 0;
|
rtc_hctosys_ret = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,20 @@ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtc_year_days);
|
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.
|
* 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 int month, year;
|
||||||
|
unsigned long secs;
|
||||||
int days;
|
int days;
|
||||||
|
|
||||||
days = time / 86400;
|
/* time must be positive */
|
||||||
time -= (unsigned int) days * 86400;
|
days = div_s64(time, 86400);
|
||||||
|
secs = time - (unsigned int) days * 86400;
|
||||||
|
|
||||||
/* day of the week, 1970-01-01 was a Thursday */
|
/* day of the week, 1970-01-01 was a Thursday */
|
||||||
tm->tm_wday = (days + 4) % 7;
|
tm->tm_wday = (days + 4) % 7;
|
||||||
@ -81,14 +85,14 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
|
|||||||
tm->tm_mon = month;
|
tm->tm_mon = month;
|
||||||
tm->tm_mday = days + 1;
|
tm->tm_mday = days + 1;
|
||||||
|
|
||||||
tm->tm_hour = time / 3600;
|
tm->tm_hour = secs / 3600;
|
||||||
time -= tm->tm_hour * 3600;
|
secs -= tm->tm_hour * 3600;
|
||||||
tm->tm_min = time / 60;
|
tm->tm_min = secs / 60;
|
||||||
tm->tm_sec = time - tm->tm_min * 60;
|
tm->tm_sec = secs - tm->tm_min * 60;
|
||||||
|
|
||||||
tm->tm_isdst = 0;
|
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?
|
* Does the rtc_time represent a valid date/time?
|
||||||
@ -109,24 +113,22 @@ int rtc_valid_tm(struct rtc_time *tm)
|
|||||||
EXPORT_SYMBOL(rtc_valid_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.
|
* 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);
|
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
|
* Convert rtc_time to ktime
|
||||||
*/
|
*/
|
||||||
ktime_t rtc_tm_to_ktime(struct rtc_time tm)
|
ktime_t rtc_tm_to_ktime(struct rtc_time tm)
|
||||||
{
|
{
|
||||||
time_t time;
|
return ktime_set(rtc_tm_to_time64(&tm), 0);
|
||||||
rtc_tm_to_time(&tm, &time);
|
|
||||||
return ktime_set(time, 0);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
|
EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
|
||||||
|
|
||||||
@ -135,14 +137,14 @@ EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
|
|||||||
*/
|
*/
|
||||||
struct rtc_time rtc_ktime_to_tm(ktime_t kt)
|
struct rtc_time rtc_ktime_to_tm(ktime_t kt)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec64 ts;
|
||||||
struct rtc_time ret;
|
struct rtc_time ret;
|
||||||
|
|
||||||
ts = ktime_to_timespec(kt);
|
ts = ktime_to_timespec64(kt);
|
||||||
/* Round up any ns */
|
/* Round up any ns */
|
||||||
if (ts.tv_nsec)
|
if (ts.tv_nsec)
|
||||||
ts.tv_sec++;
|
ts.tv_sec++;
|
||||||
rtc_time_to_tm(ts.tv_sec, &ret);
|
rtc_time64_to_tm(ts.tv_sec, &ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtc_ktime_to_tm);
|
EXPORT_SYMBOL_GPL(rtc_ktime_to_tm);
|
||||||
|
@ -114,6 +114,46 @@ static int armada370_wdt_clock_init(struct platform_device *pdev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int armada375_wdt_clock_init(struct platform_device *pdev,
|
||||||
|
struct orion_watchdog *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
|
||||||
|
if (!IS_ERR(dev->clk)) {
|
||||||
|
ret = clk_prepare_enable(dev->clk);
|
||||||
|
if (ret) {
|
||||||
|
clk_put(dev->clk);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_io_modify(dev->reg + TIMER_CTRL,
|
||||||
|
WDT_AXP_FIXED_ENABLE_BIT,
|
||||||
|
WDT_AXP_FIXED_ENABLE_BIT);
|
||||||
|
dev->clk_rate = clk_get_rate(dev->clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mandatory fallback for proper devicetree backward compatibility */
|
||||||
|
dev->clk = clk_get(&pdev->dev, NULL);
|
||||||
|
if (IS_ERR(dev->clk))
|
||||||
|
return PTR_ERR(dev->clk);
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(dev->clk);
|
||||||
|
if (ret) {
|
||||||
|
clk_put(dev->clk);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_io_modify(dev->reg + TIMER_CTRL,
|
||||||
|
WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
|
||||||
|
WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
|
||||||
|
dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int armadaxp_wdt_clock_init(struct platform_device *pdev,
|
static int armadaxp_wdt_clock_init(struct platform_device *pdev,
|
||||||
struct orion_watchdog *dev)
|
struct orion_watchdog *dev)
|
||||||
{
|
{
|
||||||
@ -394,7 +434,7 @@ static const struct orion_watchdog_data armada375_data = {
|
|||||||
.rstout_mask_bit = BIT(10),
|
.rstout_mask_bit = BIT(10),
|
||||||
.wdt_enable_bit = BIT(8),
|
.wdt_enable_bit = BIT(8),
|
||||||
.wdt_counter_offset = 0x34,
|
.wdt_counter_offset = 0x34,
|
||||||
.clock_init = armada370_wdt_clock_init,
|
.clock_init = armada375_wdt_clock_init,
|
||||||
.enabled = armada375_enabled,
|
.enabled = armada375_enabled,
|
||||||
.start = armada375_start,
|
.start = armada375_start,
|
||||||
.stop = armada375_stop,
|
.stop = armada375_stop,
|
||||||
|
@ -19,11 +19,28 @@
|
|||||||
extern int rtc_month_days(unsigned int month, unsigned int year);
|
extern int rtc_month_days(unsigned int month, unsigned int year);
|
||||||
extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year);
|
extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year);
|
||||||
extern int rtc_valid_tm(struct rtc_time *tm);
|
extern int rtc_valid_tm(struct rtc_time *tm);
|
||||||
extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
|
extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
|
||||||
extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
|
extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
|
||||||
ktime_t rtc_tm_to_ktime(struct rtc_time tm);
|
ktime_t rtc_tm_to_ktime(struct rtc_time tm);
|
||||||
struct rtc_time rtc_ktime_to_tm(ktime_t kt);
|
struct rtc_time rtc_ktime_to_tm(ktime_t kt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated. Use rtc_time64_to_tm().
|
||||||
|
*/
|
||||||
|
static inline void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
rtc_time64_to_tm(time, tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated. Use rtc_tm_to_time64().
|
||||||
|
*/
|
||||||
|
static inline int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
|
||||||
|
{
|
||||||
|
*time = rtc_tm_to_time64(tm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
@ -39,9 +39,20 @@ static inline int timeval_compare(const struct timeval *lhs, const struct timeva
|
|||||||
return lhs->tv_usec - rhs->tv_usec;
|
return lhs->tv_usec - rhs->tv_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned long mktime(const unsigned int year, const unsigned int mon,
|
extern time64_t mktime64(const unsigned int year, const unsigned int mon,
|
||||||
const unsigned int day, const unsigned int hour,
|
const unsigned int day, const unsigned int hour,
|
||||||
const unsigned int min, const unsigned int sec);
|
const unsigned int min, const unsigned int sec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated. Use mktime64().
|
||||||
|
*/
|
||||||
|
static inline unsigned long mktime(const unsigned int year,
|
||||||
|
const unsigned int mon, const unsigned int day,
|
||||||
|
const unsigned int hour, const unsigned int min,
|
||||||
|
const unsigned int sec)
|
||||||
|
{
|
||||||
|
return mktime64(year, mon, day, hour, min, sec);
|
||||||
|
}
|
||||||
|
|
||||||
extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
|
extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ extern int timekeeping_suspended;
|
|||||||
* Get and set timeofday
|
* Get and set timeofday
|
||||||
*/
|
*/
|
||||||
extern void do_gettimeofday(struct timeval *tv);
|
extern void do_gettimeofday(struct timeval *tv);
|
||||||
extern int do_settimeofday(const struct timespec *tv);
|
extern int do_settimeofday64(const struct timespec64 *ts);
|
||||||
extern int do_sys_settimeofday(const struct timespec *tv,
|
extern int do_sys_settimeofday(const struct timespec *tv,
|
||||||
const struct timezone *tz);
|
const struct timezone *tz);
|
||||||
|
|
||||||
@ -25,14 +25,22 @@ struct timespec __current_kernel_time(void);
|
|||||||
/*
|
/*
|
||||||
* timespec based interfaces
|
* timespec based interfaces
|
||||||
*/
|
*/
|
||||||
struct timespec get_monotonic_coarse(void);
|
struct timespec64 get_monotonic_coarse64(void);
|
||||||
extern void getrawmonotonic(struct timespec *ts);
|
extern void getrawmonotonic64(struct timespec64 *ts);
|
||||||
extern void ktime_get_ts64(struct timespec64 *ts);
|
extern void ktime_get_ts64(struct timespec64 *ts);
|
||||||
|
|
||||||
extern int __getnstimeofday64(struct timespec64 *tv);
|
extern int __getnstimeofday64(struct timespec64 *tv);
|
||||||
extern void getnstimeofday64(struct timespec64 *tv);
|
extern void getnstimeofday64(struct timespec64 *tv);
|
||||||
|
|
||||||
#if BITS_PER_LONG == 64
|
#if BITS_PER_LONG == 64
|
||||||
|
/**
|
||||||
|
* Deprecated. Use do_settimeofday64().
|
||||||
|
*/
|
||||||
|
static inline int do_settimeofday(const struct timespec *ts)
|
||||||
|
{
|
||||||
|
return do_settimeofday64(ts);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int __getnstimeofday(struct timespec *ts)
|
static inline int __getnstimeofday(struct timespec *ts)
|
||||||
{
|
{
|
||||||
return __getnstimeofday64(ts);
|
return __getnstimeofday64(ts);
|
||||||
@ -53,7 +61,27 @@ static inline void ktime_get_real_ts(struct timespec *ts)
|
|||||||
getnstimeofday64(ts);
|
getnstimeofday64(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void getrawmonotonic(struct timespec *ts)
|
||||||
|
{
|
||||||
|
getrawmonotonic64(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct timespec get_monotonic_coarse(void)
|
||||||
|
{
|
||||||
|
return get_monotonic_coarse64();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
/**
|
||||||
|
* Deprecated. Use do_settimeofday64().
|
||||||
|
*/
|
||||||
|
static inline int do_settimeofday(const struct timespec *ts)
|
||||||
|
{
|
||||||
|
struct timespec64 ts64;
|
||||||
|
|
||||||
|
ts64 = timespec_to_timespec64(*ts);
|
||||||
|
return do_settimeofday64(&ts64);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int __getnstimeofday(struct timespec *ts)
|
static inline int __getnstimeofday(struct timespec *ts)
|
||||||
{
|
{
|
||||||
struct timespec64 ts64;
|
struct timespec64 ts64;
|
||||||
@ -86,6 +114,19 @@ static inline void ktime_get_real_ts(struct timespec *ts)
|
|||||||
getnstimeofday64(&ts64);
|
getnstimeofday64(&ts64);
|
||||||
*ts = timespec64_to_timespec(ts64);
|
*ts = timespec64_to_timespec(ts64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void getrawmonotonic(struct timespec *ts)
|
||||||
|
{
|
||||||
|
struct timespec64 ts64;
|
||||||
|
|
||||||
|
getrawmonotonic64(&ts64);
|
||||||
|
*ts = timespec64_to_timespec(ts64);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct timespec get_monotonic_coarse(void)
|
||||||
|
{
|
||||||
|
return timespec64_to_timespec(get_monotonic_coarse64());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void getboottime(struct timespec *ts);
|
extern void getboottime(struct timespec *ts);
|
||||||
@ -182,7 +223,7 @@ static inline void timekeeping_clocktai(struct timespec *ts)
|
|||||||
/*
|
/*
|
||||||
* RTC specific
|
* RTC specific
|
||||||
*/
|
*/
|
||||||
extern void timekeeping_inject_sleeptime(struct timespec *delta);
|
extern void timekeeping_inject_sleeptime64(struct timespec64 *delta);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PPS accessor
|
* PPS accessor
|
||||||
|
@ -13,7 +13,7 @@ obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o
|
|||||||
obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o
|
obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o
|
||||||
obj-$(CONFIG_TIMER_STATS) += timer_stats.o
|
obj-$(CONFIG_TIMER_STATS) += timer_stats.o
|
||||||
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
|
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
|
||||||
obj-$(CONFIG_TEST_UDELAY) += udelay_test.o
|
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
|
||||||
|
|
||||||
$(obj)/time.o: $(obj)/timeconst.h
|
$(obj)/time.o: $(obj)/timeconst.h
|
||||||
|
|
||||||
|
@ -304,7 +304,9 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(timespec_trunc);
|
EXPORT_SYMBOL(timespec_trunc);
|
||||||
|
|
||||||
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
/*
|
||||||
|
* mktime64 - Converts date to seconds.
|
||||||
|
* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
||||||
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
||||||
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
||||||
*
|
*
|
||||||
@ -314,15 +316,10 @@ EXPORT_SYMBOL(timespec_trunc);
|
|||||||
* -year/100+year/400 terms, and add 10.]
|
* -year/100+year/400 terms, and add 10.]
|
||||||
*
|
*
|
||||||
* This algorithm was first published by Gauss (I think).
|
* This algorithm was first published by Gauss (I think).
|
||||||
*
|
|
||||||
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
|
|
||||||
* machines where long is 32-bit! (However, as time_t is signed, we
|
|
||||||
* will already get problems at other places on 2038-01-19 03:14:08)
|
|
||||||
*/
|
*/
|
||||||
unsigned long
|
time64_t mktime64(const unsigned int year0, const unsigned int mon0,
|
||||||
mktime(const unsigned int year0, const unsigned int mon0,
|
const unsigned int day, const unsigned int hour,
|
||||||
const unsigned int day, const unsigned int hour,
|
const unsigned int min, const unsigned int sec)
|
||||||
const unsigned int min, const unsigned int sec)
|
|
||||||
{
|
{
|
||||||
unsigned int mon = mon0, year = year0;
|
unsigned int mon = mon0, year = year0;
|
||||||
|
|
||||||
@ -332,15 +329,14 @@ mktime(const unsigned int year0, const unsigned int mon0,
|
|||||||
year -= 1;
|
year -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((((unsigned long)
|
return ((((time64_t)
|
||||||
(year/4 - year/100 + year/400 + 367*mon/12 + day) +
|
(year/4 - year/100 + year/400 + 367*mon/12 + day) +
|
||||||
year*365 - 719499
|
year*365 - 719499
|
||||||
)*24 + hour /* now have hours */
|
)*24 + hour /* now have hours */
|
||||||
)*60 + min /* now have minutes */
|
)*60 + min /* now have minutes */
|
||||||
)*60 + sec; /* finally seconds */
|
)*60 + sec; /* finally seconds */
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(mktime64);
|
||||||
EXPORT_SYMBOL(mktime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_normalized_timespec - set timespec sec and nsec parts and normalize
|
* set_normalized_timespec - set timespec sec and nsec parts and normalize
|
||||||
|
@ -519,9 +519,9 @@ EXPORT_SYMBOL(__getnstimeofday64);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* getnstimeofday64 - Returns the time of day in a timespec64.
|
* getnstimeofday64 - Returns the time of day in a timespec64.
|
||||||
* @ts: pointer to the timespec to be set
|
* @ts: pointer to the timespec64 to be set
|
||||||
*
|
*
|
||||||
* Returns the time of day in a timespec (WARN if suspended).
|
* Returns the time of day in a timespec64 (WARN if suspended).
|
||||||
*/
|
*/
|
||||||
void getnstimeofday64(struct timespec64 *ts)
|
void getnstimeofday64(struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
@ -623,7 +623,7 @@ EXPORT_SYMBOL_GPL(ktime_get_raw);
|
|||||||
*
|
*
|
||||||
* The function calculates the monotonic clock from the realtime
|
* The function calculates the monotonic clock from the realtime
|
||||||
* clock and the wall_to_monotonic offset and stores the result
|
* clock and the wall_to_monotonic offset and stores the result
|
||||||
* in normalized timespec format in the variable pointed to by @ts.
|
* in normalized timespec64 format in the variable pointed to by @ts.
|
||||||
*/
|
*/
|
||||||
void ktime_get_ts64(struct timespec64 *ts)
|
void ktime_get_ts64(struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
@ -703,18 +703,18 @@ void do_gettimeofday(struct timeval *tv)
|
|||||||
EXPORT_SYMBOL(do_gettimeofday);
|
EXPORT_SYMBOL(do_gettimeofday);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do_settimeofday - Sets the time of day
|
* do_settimeofday64 - Sets the time of day.
|
||||||
* @tv: pointer to the timespec variable containing the new time
|
* @ts: pointer to the timespec64 variable containing the new time
|
||||||
*
|
*
|
||||||
* Sets the time of day to the new time and update NTP and notify hrtimers
|
* Sets the time of day to the new time and update NTP and notify hrtimers
|
||||||
*/
|
*/
|
||||||
int do_settimeofday(const struct timespec *tv)
|
int do_settimeofday64(const struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
struct timekeeper *tk = &tk_core.timekeeper;
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
struct timespec64 ts_delta, xt, tmp;
|
struct timespec64 ts_delta, xt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!timespec_valid_strict(tv))
|
if (!timespec64_valid_strict(ts))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&timekeeper_lock, flags);
|
raw_spin_lock_irqsave(&timekeeper_lock, flags);
|
||||||
@ -723,13 +723,12 @@ int do_settimeofday(const struct timespec *tv)
|
|||||||
timekeeping_forward_now(tk);
|
timekeeping_forward_now(tk);
|
||||||
|
|
||||||
xt = tk_xtime(tk);
|
xt = tk_xtime(tk);
|
||||||
ts_delta.tv_sec = tv->tv_sec - xt.tv_sec;
|
ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
|
||||||
ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec;
|
ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
|
||||||
|
|
||||||
tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
|
tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
|
||||||
|
|
||||||
tmp = timespec_to_timespec64(*tv);
|
tk_set_xtime(tk, ts);
|
||||||
tk_set_xtime(tk, &tmp);
|
|
||||||
|
|
||||||
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
|
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
|
||||||
|
|
||||||
@ -741,7 +740,7 @@ int do_settimeofday(const struct timespec *tv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(do_settimeofday);
|
EXPORT_SYMBOL(do_settimeofday64);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* timekeeping_inject_offset - Adds or subtracts from the current time.
|
* timekeeping_inject_offset - Adds or subtracts from the current time.
|
||||||
@ -895,12 +894,12 @@ int timekeeping_notify(struct clocksource *clock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getrawmonotonic - Returns the raw monotonic time in a timespec
|
* getrawmonotonic64 - Returns the raw monotonic time in a timespec
|
||||||
* @ts: pointer to the timespec to be set
|
* @ts: pointer to the timespec64 to be set
|
||||||
*
|
*
|
||||||
* Returns the raw monotonic time (completely un-modified by ntp)
|
* Returns the raw monotonic time (completely un-modified by ntp)
|
||||||
*/
|
*/
|
||||||
void getrawmonotonic(struct timespec *ts)
|
void getrawmonotonic64(struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
struct timekeeper *tk = &tk_core.timekeeper;
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
struct timespec64 ts64;
|
struct timespec64 ts64;
|
||||||
@ -915,9 +914,10 @@ void getrawmonotonic(struct timespec *ts)
|
|||||||
} while (read_seqcount_retry(&tk_core.seq, seq));
|
} while (read_seqcount_retry(&tk_core.seq, seq));
|
||||||
|
|
||||||
timespec64_add_ns(&ts64, nsecs);
|
timespec64_add_ns(&ts64, nsecs);
|
||||||
*ts = timespec64_to_timespec(ts64);
|
*ts = ts64;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(getrawmonotonic);
|
EXPORT_SYMBOL(getrawmonotonic64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
|
* timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
|
||||||
@ -1068,8 +1068,8 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values
|
* timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
|
||||||
* @delta: pointer to a timespec delta value
|
* @delta: pointer to a timespec64 delta value
|
||||||
*
|
*
|
||||||
* This hook is for architectures that cannot support read_persistent_clock
|
* This hook is for architectures that cannot support read_persistent_clock
|
||||||
* because their RTC/persistent clock is only accessible when irqs are enabled.
|
* because their RTC/persistent clock is only accessible when irqs are enabled.
|
||||||
@ -1077,10 +1077,9 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
|
|||||||
* This function should only be called by rtc_resume(), and allows
|
* This function should only be called by rtc_resume(), and allows
|
||||||
* a suspend offset to be injected into the timekeeping values.
|
* a suspend offset to be injected into the timekeeping values.
|
||||||
*/
|
*/
|
||||||
void timekeeping_inject_sleeptime(struct timespec *delta)
|
void timekeeping_inject_sleeptime64(struct timespec64 *delta)
|
||||||
{
|
{
|
||||||
struct timekeeper *tk = &tk_core.timekeeper;
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
struct timespec64 tmp;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1095,8 +1094,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
|
|||||||
|
|
||||||
timekeeping_forward_now(tk);
|
timekeeping_forward_now(tk);
|
||||||
|
|
||||||
tmp = timespec_to_timespec64(*delta);
|
__timekeeping_inject_sleeptime(tk, delta);
|
||||||
__timekeeping_inject_sleeptime(tk, &tmp);
|
|
||||||
|
|
||||||
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
|
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
|
||||||
|
|
||||||
@ -1332,6 +1330,12 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
|
|||||||
*
|
*
|
||||||
* XXX - TODO: Doc ntp_error calculation.
|
* XXX - TODO: Doc ntp_error calculation.
|
||||||
*/
|
*/
|
||||||
|
if ((mult_adj > 0) && (tk->tkr.mult + mult_adj < mult_adj)) {
|
||||||
|
/* NTP adjustment caused clocksource mult overflow */
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tk->tkr.mult += mult_adj;
|
tk->tkr.mult += mult_adj;
|
||||||
tk->xtime_interval += interval;
|
tk->xtime_interval += interval;
|
||||||
tk->tkr.xtime_nsec -= offset;
|
tk->tkr.xtime_nsec -= offset;
|
||||||
@ -1397,7 +1401,8 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(tk->tkr.clock->maxadj &&
|
if (unlikely(tk->tkr.clock->maxadj &&
|
||||||
(tk->tkr.mult > tk->tkr.clock->mult + tk->tkr.clock->maxadj))) {
|
(abs(tk->tkr.mult - tk->tkr.clock->mult)
|
||||||
|
> tk->tkr.clock->maxadj))) {
|
||||||
printk_once(KERN_WARNING
|
printk_once(KERN_WARNING
|
||||||
"Adjusting %s more than 11%% (%ld vs %ld)\n",
|
"Adjusting %s more than 11%% (%ld vs %ld)\n",
|
||||||
tk->tkr.clock->name, (long)tk->tkr.mult,
|
tk->tkr.clock->name, (long)tk->tkr.mult,
|
||||||
@ -1646,7 +1651,7 @@ struct timespec current_kernel_time(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(current_kernel_time);
|
EXPORT_SYMBOL(current_kernel_time);
|
||||||
|
|
||||||
struct timespec get_monotonic_coarse(void)
|
struct timespec64 get_monotonic_coarse64(void)
|
||||||
{
|
{
|
||||||
struct timekeeper *tk = &tk_core.timekeeper;
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
struct timespec64 now, mono;
|
struct timespec64 now, mono;
|
||||||
@ -1662,7 +1667,7 @@ struct timespec get_monotonic_coarse(void)
|
|||||||
set_normalized_timespec64(&now, now.tv_sec + mono.tv_sec,
|
set_normalized_timespec64(&now, now.tv_sec + mono.tv_sec,
|
||||||
now.tv_nsec + mono.tv_nsec);
|
now.tv_nsec + mono.tv_nsec);
|
||||||
|
|
||||||
return timespec64_to_timespec(now);
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user