Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1438281 > unrolled thread

[GIT PULL] clockevents for 4.8

Started byDaniel Lezcano <daniel.lezcano@linaro.org>
First post2016-07-07 10:10 +0200
Last post2016-07-07 11:00 +0200
Articles 11 on this page of 71 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [GIT PULL] clockevents for 4.8 Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 30/93] clocksource/drivers/h8300_timer8: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 04/93] clocksource/drivers/samsung_pwm: Fix typo in Kconfig Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 18/93] clocksource/drivers/st_lpc: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 42/93] clocksource/drivers/tango_xtal: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 57/93] clocksource/drivers/stm32: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 11/93] of: Add a new macro to declare_of for one parameter function returning a value Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 27/93] clocksource/drivers/arm_arch_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 59/93] clocksource/drivers/ti-32k: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 54/93] clocksource/drivers/integrator-ap: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 58/93] clocksource/drivers/sun5i: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 19/93] clocksource/drivers/dw_apb_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
    [PATCH 01/93] clocksource/drivers/armada-370-xp: Make syscore_ops static Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:10 +0200
      [PATCH 69/93] clocksource/drivers/nps: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 71/93] clocksource/drivers/oxnas-rps: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 51/93] clocksource/drivers/atmel-st: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 55/93] clocksource/drivers/keystone: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 73/93] clk: Add missing clk_get_sys() stub Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 52/93] clocksource/drivers/prima2: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 56/93] clocksource/drivers/sp804: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 53/93] clocksource/drivers/imx-gpt: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 70/93] clocksource/drivers/arc: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 50/93] clocksource/drivers/atmel-pit: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:20 +0200
      [PATCH 44/93] clocksource/drivers/time-armada-370-xp: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 45/93] clocksource/drivers/time-efm32: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 40/93] clocksource/drivers/samsung_pwm: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 43/93] clocksource/drivers/tegra20: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 65/93] clocksource/drivers/microblaze: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 48/93] clocksource/drivers/pistachio: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 39/93] clocksource/drivers/qcom: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 34/93] clocksource/drivers/moxart: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 60/93] clocksource/drivers/u300: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 64/93] clocksource/drivers/zevio: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 63/93] clocksource/drivers/vt8500: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 49/93] clocksource/drivers/atlas7: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 66/93] clocksource/drivers/ralink: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 61/93] clocksource/drivers/versatile: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 67/93] clocksource/drivers/nios2: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 62/93] clocksource/drivers/vf_pit_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 47/93] clocksource/drivers/orion: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 68/93] clocksource/drivers/smp_twd: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 36/93] clocksource/drivers/mxs: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 46/93] clocksource/drivers/time-lpc32xx: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 41/93] clocksource/drivers/sun4i: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:30 +0200
      [PATCH 35/93] clocksource/drivers/mps2-timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 31/93] clocksource/drivers/h8300_tpu: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 22/93] clocksource/drivers/armv7m_systick: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 24/93] clocksource/drivers/bcm_kona: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 15/93] clocksource/drivers/exynos_mct: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 21/93] clocksource/drivers/digicolor: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 32/93] clocksource/drivers/meson6_timer.c: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 28/93] clocksource/drivers/arm_global_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 20/93] clocksource/drivers/clps711x: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 25/93] clocksource/drivers/clksrc-dbx500: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 26/93] clocksource/drivers/fsl_ftm_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 29/93] clocksource/drivers/h8300_timer16: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 23/93] clocksource/drivers/bcm2835_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 33/93] clocksource/drivers/mips-gic-timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:40 +0200
      [PATCH 17/93] clocksource/drivers/cadence_ttc: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:50 +0200
      [PATCH 14/93] clocksource/drivers/mtk_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:50 +0200
      [PATCH 16/93] clocksource/drivers/asm9260: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:50 +0200
      [PATCH 07/93] clocksource/drivers/rockchip: Add support for the rk3399 SoC Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 10:50 +0200
      [PATCH 03/93] clocksource/drivers/samsung_pwm_timer: Fix endian accessors Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 05/93] dt-bindings: Document rk3399 rk-timer bindings Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 10/93] dt-bindings: clocksource: Add Oxford Semiconductor RPS Timer bindings Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 02/93] clocksource/drivers/digicolor: Fix warning of non-static function Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 13/93] clocksource/drivers/rockchip_timer: Convert init function to return error Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 12/93] clocksource/drivers/clksrc-probe: Introduce init functions with return code Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 06/93] clocksource/drivers/rockchip: Add the dynamic irq flag to the timer Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 08/93] arm64: dts: rockchip: Add rktimer device node for rk3399 Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200
      [PATCH 09/93] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-07-07 11:00 +0200

Page 4 of 4 — ← Prev page 1 2 3 [4]


#1438378 — [PATCH 16/93] clocksource/drivers/asm9260: Convert init function to return error

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 10:50 +0200
Subject[PATCH 16/93] clocksource/drivers/asm9260: Convert init function to return error
Message-ID<rSdap-4y2-11@gated-at.bofh.it>
In reply to#1438299
The init functions do not return any error. They behave as the following:

 - panic, thus leading to a kernel crash while another timer may work and
   make the system boot up correctly

 or

 - print an error and let the caller unaware if the state of the system

Change that by converting the init functions to return an error conforming
to the CLOCKSOURCE_OF_RET prototype.

Proper error handling (rollback, errno value) will be changed later case
by case, thus this change just return back an error or success in the init
function.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/asm9260_timer.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c
index 217438d..d113c02 100644
--- a/drivers/clocksource/asm9260_timer.c
+++ b/drivers/clocksource/asm9260_timer.c
@@ -184,7 +184,7 @@ static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id)
  * Timer initialization
  * ---------------------------------------------------------------------------
  */
-static void __init asm9260_timer_init(struct device_node *np)
+static int __init asm9260_timer_init(struct device_node *np)
 {
 	int irq;
 	struct clk *clk;
@@ -192,20 +192,26 @@ static void __init asm9260_timer_init(struct device_node *np)
 	unsigned long rate;
 
 	priv.base = of_io_request_and_map(np, 0, np->name);
-	if (IS_ERR(priv.base))
-		panic("%s: unable to map resource", np->name);
+	if (IS_ERR(priv.base)) {
+		pr_err("%s: unable to map resource", np->name);
+		return PTR_ERR(priv.base);
+	}
 
 	clk = of_clk_get(np, 0);
 
 	ret = clk_prepare_enable(clk);
-	if (ret)
-		panic("Failed to enable clk!\n");
+	if (ret) {
+		pr_err("Failed to enable clk!\n");
+		return ret;
+	}
 
 	irq = irq_of_parse_and_map(np, 0);
 	ret = request_irq(irq, asm9260_timer_interrupt, IRQF_TIMER,
 			DRIVER_NAME, &event_dev);
-	if (ret)
-		panic("Failed to setup irq!\n");
+	if (ret) {
+		pr_err("Failed to setup irq!\n");
+		return ret;
+	}
 
 	/* set all timers for count-up */
 	writel_relaxed(BM_DIR_DEFAULT, priv.base + HW_DIR);
@@ -229,6 +235,8 @@ static void __init asm9260_timer_init(struct device_node *np)
 	priv.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
 	event_dev.cpumask = cpumask_of(0);
 	clockevents_config_and_register(&event_dev, rate, 0x2c00, 0xfffffffe);
+
+	return 0;
 }
-CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer",
+CLOCKSOURCE_OF_DECLARE_RET(asm9260_timer, "alphascale,asm9260-timer",
 		asm9260_timer_init);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438388 — [PATCH 07/93] clocksource/drivers/rockchip: Add support for the rk3399 SoC

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 10:50 +0200
Subject[PATCH 07/93] clocksource/drivers/rockchip: Add support for the rk3399 SoC
Message-ID<rSdaq-4y2-47@gated-at.bofh.it>
In reply to#1438299
From: "Huang, Tao" <huangtao@rock-chips.com>

The only difference between the rk3399 SoC and the other ones is the control
register offset which is different.

Add a new field to store the control register address depending on the SoC
and use it instead of the <base> + <control offset>.

Signed-off-by: Huang Tao <huangtao@rock-chips.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Heiko Stuebner <heiko@sntech.de>
Tested-by: Jianqun Xu <jay.xu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/rockchip_timer.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index b510863..a3f22b0 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -19,7 +19,8 @@
 
 #define TIMER_LOAD_COUNT0	0x00
 #define TIMER_LOAD_COUNT1	0x04
-#define TIMER_CONTROL_REG	0x10
+#define TIMER_CONTROL_REG3288	0x10
+#define TIMER_CONTROL_REG3399	0x1c
 #define TIMER_INT_STATUS	0x18
 
 #define TIMER_DISABLE		0x0
@@ -31,6 +32,7 @@
 struct bc_timer {
 	struct clock_event_device ce;
 	void __iomem *base;
+	void __iomem *ctrl;
 	u32 freq;
 };
 
@@ -46,15 +48,20 @@ static inline void __iomem *rk_base(struct clock_event_device *ce)
 	return rk_timer(ce)->base;
 }
 
+static inline void __iomem *rk_ctrl(struct clock_event_device *ce)
+{
+	return rk_timer(ce)->ctrl;
+}
+
 static inline void rk_timer_disable(struct clock_event_device *ce)
 {
-	writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG);
+	writel_relaxed(TIMER_DISABLE, rk_ctrl(ce));
 }
 
 static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
 {
 	writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
-		       rk_base(ce) + TIMER_CONTROL_REG);
+		       rk_ctrl(ce));
 }
 
 static void rk_timer_update_counter(unsigned long cycles,
@@ -106,7 +113,7 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void __init rk_timer_init(struct device_node *np)
+static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
 {
 	struct clock_event_device *ce = &bc_timer.ce;
 	struct clk *timer_clk;
@@ -118,6 +125,7 @@ static void __init rk_timer_init(struct device_node *np)
 		pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
 		return;
 	}
+	bc_timer.ctrl = bc_timer.base + ctrl_reg;
 
 	pclk = of_clk_get_by_name(np, "pclk");
 	if (IS_ERR(pclk)) {
@@ -180,4 +188,17 @@ out_unmap:
 	iounmap(bc_timer.base);
 }
 
-CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init);
+static void __init rk3288_timer_init(struct device_node *np)
+{
+	rk_timer_init(np, TIMER_CONTROL_REG3288);
+}
+
+static void __init rk3399_timer_init(struct device_node *np)
+{
+	rk_timer_init(np, TIMER_CONTROL_REG3399);
+}
+
+CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer",
+		       rk3288_timer_init);
+CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer",
+		       rk3399_timer_init);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438397 — [PATCH 03/93] clocksource/drivers/samsung_pwm_timer: Fix endian accessors

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 03/93] clocksource/drivers/samsung_pwm_timer: Fix endian accessors
Message-ID<rSdk6-4BD-3@gated-at.bofh.it>
In reply to#1438299
From: Matthew Leach <matthew@mattleach.net>

Fix the Samsung pwm timer access code to deal with kernels built for big
endian operation.

Signed-off-by: Matthew Leach <matthew@mattleach.net>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 9502bc4..47e0515 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -130,9 +130,9 @@ static void samsung_time_stop(unsigned int channel)
 
 	spin_lock_irqsave(&samsung_pwm_lock, flags);
 
-	tcon = __raw_readl(pwm.base + REG_TCON);
+	tcon = readl_relaxed(pwm.base + REG_TCON);
 	tcon &= ~TCON_START(channel);
-	__raw_writel(tcon, pwm.base + REG_TCON);
+	writel_relaxed(tcon, pwm.base + REG_TCON);
 
 	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
 }
@@ -148,14 +148,14 @@ static void samsung_time_setup(unsigned int channel, unsigned long tcnt)
 
 	spin_lock_irqsave(&samsung_pwm_lock, flags);
 
-	tcon = __raw_readl(pwm.base + REG_TCON);
+	tcon = readl_relaxed(pwm.base + REG_TCON);
 
 	tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan));
 	tcon |= TCON_MANUALUPDATE(tcon_chan);
 
-	__raw_writel(tcnt, pwm.base + REG_TCNTB(channel));
-	__raw_writel(tcnt, pwm.base + REG_TCMPB(channel));
-	__raw_writel(tcon, pwm.base + REG_TCON);
+	writel_relaxed(tcnt, pwm.base + REG_TCNTB(channel));
+	writel_relaxed(tcnt, pwm.base + REG_TCMPB(channel));
+	writel_relaxed(tcon, pwm.base + REG_TCON);
 
 	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
 }
@@ -170,7 +170,7 @@ static void samsung_time_start(unsigned int channel, bool periodic)
 
 	spin_lock_irqsave(&samsung_pwm_lock, flags);
 
-	tcon = __raw_readl(pwm.base + REG_TCON);
+	tcon = readl_relaxed(pwm.base + REG_TCON);
 
 	tcon &= ~TCON_MANUALUPDATE(channel);
 	tcon |= TCON_START(channel);
@@ -180,7 +180,7 @@ static void samsung_time_start(unsigned int channel, bool periodic)
 	else
 		tcon &= ~TCON_AUTORELOAD(channel);
 
-	__raw_writel(tcon, pwm.base + REG_TCON);
+	writel_relaxed(tcon, pwm.base + REG_TCON);
 
 	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
 }
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438398 — [PATCH 05/93] dt-bindings: Document rk3399 rk-timer bindings

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 05/93] dt-bindings: Document rk3399 rk-timer bindings
Message-ID<rSdk6-4BD-5@gated-at.bofh.it>
In reply to#1438299
From: Huang Tao <huangtao@rock-chips.com>

Add a compatible string for rk3399 SoC because the timer is slightly different
from the older SoCs. So rename the file name from rockchip,rk3288-timer.txt to
rockchip,rk-timer.txt and clarify rockchip,rk3288-timer supported SoCs.

Signed-off-by: Huang Tao <huangtao@rock-chips.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 .../devicetree/bindings/timer/rockchip,rk-timer.txt  | 20 ++++++++++++++++++++
 .../bindings/timer/rockchip,rk3288-timer.txt         | 18 ------------------
 2 files changed, 20 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
 delete mode 100644 Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
new file mode 100644
index 0000000..a41b184
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
@@ -0,0 +1,20 @@
+Rockchip rk timer
+
+Required properties:
+- compatible: shall be one of:
+  "rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368
+  "rockchip,rk3399-timer" - for rk3399
+- reg: base address of the timer register starting with TIMERS CONTROL register
+- interrupts: should contain the interrupts for Timer0
+- clocks : must contain an entry for each entry in clock-names
+- clock-names : must include the following entries:
+  "timer", "pclk"
+
+Example:
+	timer: timer@ff810000 {
+		compatible = "rockchip,rk3288-timer";
+		reg = <0xff810000 0x20>;
+		interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&xin24m>, <&cru PCLK_TIMER>;
+		clock-names = "timer", "pclk";
+	};
diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt
deleted file mode 100644
index 87f0b00..0000000
--- a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Rockchip rk3288 timer
-
-Required properties:
-- compatible: shall be "rockchip,rk3288-timer"
-- reg: base address of the timer register starting with TIMERS CONTROL register
-- interrupts: should contain the interrupts for Timer0
-- clocks : must contain an entry for each entry in clock-names
-- clock-names : must include the following entries:
-  "timer", "pclk"
-
-Example:
-	timer: timer@ff810000 {
-		compatible = "rockchip,rk3288-timer";
-		reg = <0xff810000 0x20>;
-		interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&xin24m>, <&cru PCLK_TIMER>;
-		clock-names = "timer", "pclk";
-	};
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438399 — [PATCH 10/93] dt-bindings: clocksource: Add Oxford Semiconductor RPS Timer bindings

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 10/93] dt-bindings: clocksource: Add Oxford Semiconductor RPS Timer bindings
Message-ID<rSdk6-4BD-17@gated-at.bofh.it>
In reply to#1438299
From: Neil Armstrong <narmstrong@baylibre.com>

Add DT bindings for the Oxford Semiconductor RPS dual Timer.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/timer/oxsemi,rps-timer.txt      | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt
new file mode 100644
index 0000000..3ca89cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt
@@ -0,0 +1,17 @@
+Oxford Semiconductor OXNAS SoCs Family RPS Timer
+================================================
+
+Required properties:
+- compatible: Should be "oxsemi,ox810se-rps-timer"
+- reg : Specifies base physical address and size of the registers.
+- interrupts : The interrupts of the two timers
+- clocks : The phandle of the timer clock source
+
+example:
+
+timer0: timer@200 {
+	compatible = "oxsemi,ox810se-rps-timer";
+	reg = <0x200 0x40>;
+	clocks = <&rpsclk>;
+	interrupts = <4 5>;
+};
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438401 — [PATCH 02/93] clocksource/drivers/digicolor: Fix warning of non-static function

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 02/93] clocksource/drivers/digicolor: Fix warning of non-static function
Message-ID<rSdk6-4BD-13@gated-at.bofh.it>
In reply to#1438299
From: Ben Dooks <ben.dooks@codethink.co.uk>

Change the dc_timer function to be static as it is not used outside
this driver. This fixes the following warning:

drivers/clocksource/timer-digicolor.c:66:24: warning: symbol 'dc_timer' was not declared. Should it be static?

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/clocksource/timer-digicolor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
index a536eeb..96bb222 100644
--- a/drivers/clocksource/timer-digicolor.c
+++ b/drivers/clocksource/timer-digicolor.c
@@ -63,7 +63,7 @@ struct digicolor_timer {
 	int timer_id; /* one of TIMER_* */
 };
 
-struct digicolor_timer *dc_timer(struct clock_event_device *ce)
+static struct digicolor_timer *dc_timer(struct clock_event_device *ce)
 {
 	return container_of(ce, struct digicolor_timer, ce);
 }
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438406 — [PATCH 13/93] clocksource/drivers/rockchip_timer: Convert init function to return error

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 13/93] clocksource/drivers/rockchip_timer: Convert init function to return error
Message-ID<rSdk6-4BD-27@gated-at.bofh.it>
In reply to#1438299
The init functions do not return any error. They behave as the following:

 - panic, thus leading to a kernel crash while another timer may work and
   make the system boot up correctly

 or

 - print an error and let the caller unaware if the state of the system

Change that by converting the init functions to return an error conforming
to the CLOCKSOURCE_OF_RET prototype.

Proper error handling (rollback, errno value) will be changed later case
by case, thus this change just return back an error or success in the init
function.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>

on a rk3399-evb
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clocksource/rockchip_timer.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index a3f22b0..85aee69 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -113,38 +113,42 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
+static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
 {
 	struct clock_event_device *ce = &bc_timer.ce;
 	struct clk *timer_clk;
 	struct clk *pclk;
-	int ret, irq;
+	int ret = -EINVAL, irq;
 
 	bc_timer.base = of_iomap(np, 0);
 	if (!bc_timer.base) {
 		pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
-		return;
+		return -ENXIO;
 	}
 	bc_timer.ctrl = bc_timer.base + ctrl_reg;
 
 	pclk = of_clk_get_by_name(np, "pclk");
 	if (IS_ERR(pclk)) {
+		ret = PTR_ERR(pclk);
 		pr_err("Failed to get pclk for '%s'\n", TIMER_NAME);
 		goto out_unmap;
 	}
 
-	if (clk_prepare_enable(pclk)) {
+	ret = clk_prepare_enable(pclk);
+	if (ret) {
 		pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME);
 		goto out_unmap;
 	}
 
 	timer_clk = of_clk_get_by_name(np, "timer");
 	if (IS_ERR(timer_clk)) {
+		ret = PTR_ERR(timer_clk);
 		pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME);
 		goto out_timer_clk;
 	}
 
-	if (clk_prepare_enable(timer_clk)) {
+	ret = clk_prepare_enable(timer_clk);
+	if (ret) {
 		pr_err("Failed to enable timer clock\n");
 		goto out_timer_clk;
 	}
@@ -153,6 +157,7 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
 
 	irq = irq_of_parse_and_map(np, 0);
 	if (!irq) {
+		ret = -EINVAL;
 		pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
 		goto out_irq;
 	}
@@ -178,7 +183,7 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
 
 	clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);
 
-	return;
+	return 0;
 
 out_irq:
 	clk_disable_unprepare(timer_clk);
@@ -186,19 +191,21 @@ out_timer_clk:
 	clk_disable_unprepare(pclk);
 out_unmap:
 	iounmap(bc_timer.base);
+
+	return ret;
 }
 
-static void __init rk3288_timer_init(struct device_node *np)
+static int __init rk3288_timer_init(struct device_node *np)
 {
-	rk_timer_init(np, TIMER_CONTROL_REG3288);
+	return rk_timer_init(np, TIMER_CONTROL_REG3288);
 }
 
-static void __init rk3399_timer_init(struct device_node *np)
+static int __init rk3399_timer_init(struct device_node *np)
 {
-	rk_timer_init(np, TIMER_CONTROL_REG3399);
+	return rk_timer_init(np, TIMER_CONTROL_REG3399);
 }
 
-CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer",
-		       rk3288_timer_init);
-CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer",
-		       rk3399_timer_init);
+CLOCKSOURCE_OF_DECLARE_RET(rk3288_timer, "rockchip,rk3288-timer",
+			   rk3288_timer_init);
+CLOCKSOURCE_OF_DECLARE_RET(rk3399_timer, "rockchip,rk3399-timer",
+			   rk3399_timer_init);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438408 — [PATCH 12/93] clocksource/drivers/clksrc-probe: Introduce init functions with return code

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 12/93] clocksource/drivers/clksrc-probe: Introduce init functions with return code
Message-ID<rSdk7-4BD-31@gated-at.bofh.it>
In reply to#1438299
Currently, the clksrc-probe is not able to handle any error from the init
functions. There are different issues with the current code:
 - the code is duplicated in the init functions by writing error
 - every driver tends to panic in its own init function
 - counting the number of clocksources is not reliable

This patch adds another table to store the functions returning an error.
The table is temporary while we convert all the drivers to return an error
and will disappear.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/clksrc-probe.c | 22 ++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h  |  2 ++
 include/linux/clocksource.h        |  3 +++
 3 files changed, 27 insertions(+)

diff --git a/drivers/clocksource/clksrc-probe.c b/drivers/clocksource/clksrc-probe.c
index 7cb6c92..5fa6a55 100644
--- a/drivers/clocksource/clksrc-probe.c
+++ b/drivers/clocksource/clksrc-probe.c
@@ -20,16 +20,22 @@
 #include <linux/clocksource.h>
 
 extern struct of_device_id __clksrc_of_table[];
+extern struct of_device_id __clksrc_ret_of_table[];
 
 static const struct of_device_id __clksrc_of_table_sentinel
 	__used __section(__clksrc_of_table_end);
 
+static const struct of_device_id __clksrc_ret_of_table_sentinel
+	__used __section(__clksrc_ret_of_table_end);
+
 void __init clocksource_probe(void)
 {
 	struct device_node *np;
 	const struct of_device_id *match;
 	of_init_fn_1 init_func;
+	of_init_fn_1_ret init_func_ret;
 	unsigned clocksources = 0;
+	int ret;
 
 	for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
 		if (!of_device_is_available(np))
@@ -40,6 +46,22 @@ void __init clocksource_probe(void)
 		clocksources++;
 	}
 
+	for_each_matching_node_and_match(np, __clksrc_ret_of_table, &match) {
+		if (!of_device_is_available(np))
+			continue;
+
+		init_func_ret = match->data;
+
+		ret = init_func_ret(np);
+		if (ret) {
+			pr_err("Failed to initialize '%s': %d",
+			       of_node_full_name(np), ret);
+			continue;
+		}
+
+		clocksources++;
+	}
+
 	clocksources += acpi_probe_device_table(clksrc);
 
 	if (!clocksources)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6a67ab9..8c6c626 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -173,6 +173,7 @@
 	*(__##name##_of_table_end)
 
 #define CLKSRC_OF_TABLES()	OF_TABLE(CONFIG_CLKSRC_OF, clksrc)
+#define CLKSRC_RET_OF_TABLES()	OF_TABLE(CONFIG_CLKSRC_OF, clksrc_ret)
 #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
 #define CLK_OF_TABLES()		OF_TABLE(CONFIG_COMMON_CLK, clk)
 #define IOMMU_OF_TABLES()	OF_TABLE(CONFIG_OF_IOMMU, iommu)
@@ -531,6 +532,7 @@
 	CLK_OF_TABLES()							\
 	RESERVEDMEM_OF_TABLES()						\
 	CLKSRC_OF_TABLES()						\
+	CLKSRC_RET_OF_TABLES()						\
 	IOMMU_OF_TABLES()						\
 	CPU_METHOD_OF_TABLES()						\
 	CPUIDLE_METHOD_OF_TABLES()					\
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 44a1aff..15c3839 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -246,6 +246,9 @@ extern int clocksource_i8253_init(void);
 #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \
 	OF_DECLARE_1(clksrc, name, compat, fn)
 
+#define CLOCKSOURCE_OF_DECLARE_RET(name, compat, fn) \
+	OF_DECLARE_1_RET(clksrc_ret, name, compat, fn)
+
 #ifdef CONFIG_CLKSRC_PROBE
 extern void clocksource_probe(void);
 #else
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438411 — [PATCH 06/93] clocksource/drivers/rockchip: Add the dynamic irq flag to the timer

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 06/93] clocksource/drivers/rockchip: Add the dynamic irq flag to the timer
Message-ID<rSdk7-4BD-39@gated-at.bofh.it>
In reply to#1438299
From: "Huang, Tao" <huangtao@rock-chips.com>

The rockchip timer is a broadcast timer. Add the CLOCK_EVT_FEAT_DYNIRQ flag
and set the cpumask to all possible cpus to save power by avoiding
unnecessary wakeups and IPIs.

Signed-off-by: Huang Tao <huangtao@rock-chips.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Heiko Stuebner <heiko@sntech.de>
Tested-by: Jianqun Xu <jay.xu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/rockchip_timer.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index b991b28..b510863 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -150,12 +150,13 @@ static void __init rk_timer_init(struct device_node *np)
 	}
 
 	ce->name = TIMER_NAME;
-	ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
+		       CLOCK_EVT_FEAT_DYNIRQ;
 	ce->set_next_event = rk_timer_set_next_event;
 	ce->set_state_shutdown = rk_timer_shutdown;
 	ce->set_state_periodic = rk_timer_set_periodic;
 	ce->irq = irq;
-	ce->cpumask = cpumask_of(0);
+	ce->cpumask = cpu_possible_mask;
 	ce->rating = 250;
 
 	rk_timer_interrupt_clear(ce);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438412 — [PATCH 08/93] arm64: dts: rockchip: Add rktimer device node for rk3399

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 08/93] arm64: dts: rockchip: Add rktimer device node for rk3399
Message-ID<rSdk7-4BD-41@gated-at.bofh.it>
In reply to#1438299
From: Huang Tao <huangtao@rock-chips.com>

Add a 'rktimer' node in the device treee for the ARM64 rk3399 SoC.

Signed-off-by: Huang Tao <huangtao@rock-chips.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Heiko Stuebner <heiko@sntech.de>
Tested-by: Jianqun Xu <jay.xu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 46f325a..f0c0d76 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -492,6 +492,14 @@
 		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	rktimer: rktimer@ff850000 {
+		compatible = "rockchip,rk3399-timer";
+		reg = <0x0 0xff850000 0x0 0x1000>;
+		interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER00>;
+		clock-names = "pclk", "timer";
+	};
+
 	spdif: spdif@ff870000 {
 		compatible = "rockchip,rk3399-spdif";
 		reg = <0x0 0xff870000 0x0 0x1000>;
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1438413 — [PATCH 09/93] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-07-07 11:00 +0200
Subject[PATCH 09/93] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer
Message-ID<rSdk7-4BD-37@gated-at.bofh.it>
In reply to#1438299
From: Neil Armstrong <narmstrong@baylibre.com>

Add clocksource and clockevent driver from dual RPS timer.
The HW provides a dual one-shot or periodic 24bit timers,
the drivers set the first one as tick event source and the
second as a continuous scheduler clock source.
The timer can use 1, 16 or 256 as pre-dividers, thus the
clocksource uses 16 by default.

CC: Ma Haijun <mahaijuns@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/Kconfig           |   8 +
 drivers/clocksource/Makefile          |   1 +
 drivers/clocksource/timer-oxnas-rps.c | 290 ++++++++++++++++++++++++++++++++++
 3 files changed, 299 insertions(+)
 create mode 100644 drivers/clocksource/timer-oxnas-rps.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6bbd3d8..d4b9e04 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -293,6 +293,14 @@ config VF_PIT_TIMER
 	help
 	  Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
 
+config OXNAS_RPS_TIMER
+	bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST
+	depends on GENERIC_CLOCKEVENTS
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	help
+	  This enables support for the Oxford Semiconductor OXNAS RPS timers.
+
 config SYS_SUPPORTS_SH_CMT
         bool
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 473974f..bc66981 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
 obj-$(CONFIG_CLKSRC_NPS)	+= timer-nps.o
+obj-$(CONFIG_OXNAS_RPS_TIMER)	+= timer-oxnas-rps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c
new file mode 100644
index 0000000..c002e99
--- /dev/null
+++ b/drivers/clocksource/timer-oxnas-rps.c
@@ -0,0 +1,290 @@
+/*
+ * drivers/clocksource/timer-oxnas-rps.c
+ *
+ * Copyright (C) 2009 Oxford Semiconductor Ltd
+ * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/clockchips.h>
+#include <linux/sched_clock.h>
+
+/* TIMER1 used as tick
+ * TIMER2 used as clocksource
+ */
+
+/* Registers definitions */
+
+#define TIMER_LOAD_REG		0x0
+#define TIMER_CURR_REG		0x4
+#define TIMER_CTRL_REG		0x8
+#define TIMER_CLRINT_REG	0xC
+
+#define TIMER_BITS		24
+
+#define TIMER_MAX_VAL		(BIT(TIMER_BITS) - 1)
+
+#define TIMER_PERIODIC		BIT(6)
+#define TIMER_ENABLE		BIT(7)
+
+#define TIMER_DIV1		(0)
+#define TIMER_DIV16		(1 << 2)
+#define TIMER_DIV256		(2 << 2)
+
+#define TIMER1_REG_OFFSET	0
+#define TIMER2_REG_OFFSET	0x20
+
+/* Clockevent & Clocksource data */
+
+struct oxnas_rps_timer {
+	struct clock_event_device clkevent;
+	void __iomem *clksrc_base;
+	void __iomem *clkevt_base;
+	unsigned long timer_period;
+	unsigned int timer_prescaler;
+	struct clk *clk;
+	int irq;
+};
+
+static irqreturn_t oxnas_rps_timer_irq(int irq, void *dev_id)
+{
+	struct oxnas_rps_timer *rps = dev_id;
+
+	writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG);
+
+	rps->clkevent.event_handler(&rps->clkevent);
+
+	return IRQ_HANDLED;
+}
+
+static void oxnas_rps_timer_config(struct oxnas_rps_timer *rps,
+				   unsigned long period,
+				   unsigned int periodic)
+{
+	uint32_t cfg = rps->timer_prescaler;
+
+	if (period)
+		cfg |= TIMER_ENABLE;
+
+	if (periodic)
+		cfg |= TIMER_PERIODIC;
+
+	writel_relaxed(period, rps->clkevt_base + TIMER_LOAD_REG);
+	writel_relaxed(cfg, rps->clkevt_base + TIMER_CTRL_REG);
+}
+
+static int oxnas_rps_timer_shutdown(struct clock_event_device *evt)
+{
+	struct oxnas_rps_timer *rps =
+		container_of(evt, struct oxnas_rps_timer, clkevent);
+
+	oxnas_rps_timer_config(rps, 0, 0);
+
+	return 0;
+}
+
+static int oxnas_rps_timer_set_periodic(struct clock_event_device *evt)
+{
+	struct oxnas_rps_timer *rps =
+		container_of(evt, struct oxnas_rps_timer, clkevent);
+
+	oxnas_rps_timer_config(rps, rps->timer_period, 1);
+
+	return 0;
+}
+
+static int oxnas_rps_timer_set_oneshot(struct clock_event_device *evt)
+{
+	struct oxnas_rps_timer *rps =
+		container_of(evt, struct oxnas_rps_timer, clkevent);
+
+	oxnas_rps_timer_config(rps, rps->timer_period, 0);
+
+	return 0;
+}
+
+static int oxnas_rps_timer_next_event(unsigned long delta,
+				struct clock_event_device *evt)
+{
+	struct oxnas_rps_timer *rps =
+		container_of(evt, struct oxnas_rps_timer, clkevent);
+
+	oxnas_rps_timer_config(rps, delta, 0);
+
+	return 0;
+}
+
+static int __init oxnas_rps_clockevent_init(struct oxnas_rps_timer *rps)
+{
+	ulong clk_rate = clk_get_rate(rps->clk);
+	ulong timer_rate;
+
+	/* Start with prescaler 1 */
+	rps->timer_prescaler = TIMER_DIV1;
+	rps->timer_period = DIV_ROUND_UP(clk_rate, HZ);
+	timer_rate = clk_rate;
+
+	if (rps->timer_period > TIMER_MAX_VAL) {
+		rps->timer_prescaler = TIMER_DIV16;
+		timer_rate = clk_rate / 16;
+		rps->timer_period = DIV_ROUND_UP(timer_rate, HZ);
+	}
+	if (rps->timer_period > TIMER_MAX_VAL) {
+		rps->timer_prescaler = TIMER_DIV256;
+		timer_rate = clk_rate / 256;
+		rps->timer_period = DIV_ROUND_UP(timer_rate, HZ);
+	}
+
+	rps->clkevent.name = "oxnas-rps";
+	rps->clkevent.features = CLOCK_EVT_FEAT_PERIODIC |
+				 CLOCK_EVT_FEAT_ONESHOT |
+				 CLOCK_EVT_FEAT_DYNIRQ;
+	rps->clkevent.tick_resume = oxnas_rps_timer_shutdown;
+	rps->clkevent.set_state_shutdown = oxnas_rps_timer_shutdown;
+	rps->clkevent.set_state_periodic = oxnas_rps_timer_set_periodic;
+	rps->clkevent.set_state_oneshot = oxnas_rps_timer_set_oneshot;
+	rps->clkevent.set_next_event = oxnas_rps_timer_next_event;
+	rps->clkevent.rating = 200;
+	rps->clkevent.cpumask = cpu_possible_mask;
+	rps->clkevent.irq = rps->irq;
+	clockevents_config_and_register(&rps->clkevent,
+					timer_rate,
+					1,
+					TIMER_MAX_VAL);
+
+	pr_info("Registered clock event rate %luHz prescaler %x period %lu\n",
+			clk_rate,
+			rps->timer_prescaler,
+			rps->timer_period);
+
+	return 0;
+}
+
+/* Clocksource */
+
+static void __iomem *timer_sched_base;
+
+static u64 notrace oxnas_rps_read_sched_clock(void)
+{
+	return ~readl_relaxed(timer_sched_base);
+}
+
+static int __init oxnas_rps_clocksource_init(struct oxnas_rps_timer *rps)
+{
+	ulong clk_rate = clk_get_rate(rps->clk);
+	int ret;
+
+	/* use prescale 16 */
+	clk_rate = clk_rate / 16;
+
+	writel_relaxed(TIMER_MAX_VAL, rps->clksrc_base + TIMER_LOAD_REG);
+	writel_relaxed(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16,
+			rps->clksrc_base + TIMER_CTRL_REG);
+
+	timer_sched_base = rps->clksrc_base + TIMER_CURR_REG;
+	sched_clock_register(oxnas_rps_read_sched_clock,
+			     TIMER_BITS, clk_rate);
+	ret = clocksource_mmio_init(timer_sched_base,
+				    "oxnas_rps_clocksource_timer",
+				    clk_rate, 250, TIMER_BITS,
+				    clocksource_mmio_readl_down);
+	if (WARN_ON(ret)) {
+		pr_err("can't register clocksource\n");
+		return ret;
+	}
+
+	pr_info("Registered clocksource rate %luHz\n", clk_rate);
+
+	return 0;
+}
+
+static void __init oxnas_rps_timer_init(struct device_node *np)
+{
+	struct oxnas_rps_timer *rps;
+	void __iomem *base;
+	int ret;
+
+	rps = kzalloc(sizeof(*rps), GFP_KERNEL);
+	if (!rps) {
+		pr_err("Failed to allocate rps structure\n");
+		return;
+	}
+
+	rps->clk = of_clk_get(np, 0);
+	if (WARN_ON(IS_ERR(rps->clk)))
+		goto err_alloc;
+
+	if (WARN_ON(clk_prepare_enable(rps->clk)))
+		goto err_clk;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		goto err_clk_prepare;
+
+	rps->irq = irq_of_parse_and_map(np, 0);
+	if (WARN_ON(rps->irq < 0))
+		goto err_iomap;
+
+	rps->clkevt_base = base + TIMER1_REG_OFFSET;
+	rps->clksrc_base = base + TIMER2_REG_OFFSET;
+
+	/* Disable timers */
+	writel_relaxed(0, rps->clkevt_base + TIMER_CTRL_REG);
+	writel_relaxed(0, rps->clksrc_base + TIMER_CTRL_REG);
+	writel_relaxed(0, rps->clkevt_base + TIMER_LOAD_REG);
+	writel_relaxed(0, rps->clksrc_base + TIMER_LOAD_REG);
+	writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG);
+	writel_relaxed(0, rps->clksrc_base + TIMER_CLRINT_REG);
+
+	ret = request_irq(rps->irq, oxnas_rps_timer_irq,
+			  IRQF_TIMER | IRQF_IRQPOLL,
+			  "rps-timer", rps);
+	if (WARN_ON(ret))
+		goto err_iomap;
+
+	ret = oxnas_rps_clocksource_init(rps);
+	if (ret)
+		goto err_irqreq;
+
+	ret = oxnas_rps_clockevent_init(rps);
+	if (ret)
+		goto err_irqreq;
+
+	return;
+
+err_irqreq:
+	free_irq(rps->irq, rps);
+err_iomap:
+	iounmap(base);
+err_clk_prepare:
+	clk_disable_unprepare(rps->clk);
+err_clk:
+	clk_put(rps->clk);
+err_alloc:
+	kfree(rps);
+}
+
+CLOCKSOURCE_OF_DECLARE(ox810se_rps,
+		       "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init);
-- 
1.9.1

[toc] | [prev] | [standalone]


Page 4 of 4 — ← Prev page 1 2 3 [4]

Back to top | Article view | linux.kernel


csiph-web