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

Commit 89de77a8 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

Merge branch 'clockevents/3.19' of...

Merge branch 'clockevents/3.19' of http://git.linaro.org/people/daniel.lezcano/linux into timers/core

Daniel Lezcano muttered:

 * Marvell timer updates from Ezequiel Garcia
   - Add missing clock enable calls for armada
   - Change source clock for clocksource and watchdog
 * SIRF timer updates from Yanchang Li
   - Make clock rate configurable
parents cb2aa634 4a22d9c9
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
@@ -293,6 +293,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);
@@ -300,11 +301,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();
}
+41 −1
Original line number Diff line number Diff line
@@ -114,6 +114,46 @@ static int armada370_wdt_clock_init(struct platform_device *pdev,
	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,
				   struct orion_watchdog *dev)
{
@@ -394,7 +434,7 @@ static const struct orion_watchdog_data armada375_data = {
	.rstout_mask_bit = BIT(10),
	.wdt_enable_bit = BIT(8),
	.wdt_counter_offset = 0x34,
	.clock_init = armada370_wdt_clock_init,
	.clock_init = armada375_wdt_clock_init,
	.enabled = armada375_enabled,
	.start = armada375_start,
	.stop = armada375_stop,