Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a157508c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 86c6a2fd 89de77a8
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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
@@ -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),
+13 −0
Original line number Diff line number Diff line
@@ -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
@@ -30,4 +42,5 @@ Example:
		interrupts = <3>;
		timeout-sec = <10>;
		status = "okay";
		clocks = <&gate_clk 7>;
	};
+30 −0
Original line number Diff line number Diff line
@@ -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 */
	BUG_ON(IS_ERR(clk));
	clk_prepare_enable(clk);
	timer_clk = clk_get_rate(clk);

	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",
		       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;

+9 −14
Original line number Diff line number Diff line
@@ -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
@@ -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,
@@ -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);
@@ -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;

@@ -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);
@@ -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();
}
+15 −15
Original line number Diff line number Diff line
@@ -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())
@@ -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);


	/*
@@ -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
@@ -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;
@@ -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())
@@ -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));
@@ -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) {
@@ -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
@@ -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;
}
Loading