Skip to contentSkip to conversation

clockevents for 4.1

GIT PULL In review Daniel Lezcano 4 participants 23 messages Mar 30, 2015 – Mar 31, 2015

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

Hi Thomas, Ingo,

this pull request contains the following changes for 4.1:

- Made IO endian agnostic for at91 and dw apb timers (Ben Dooks)

- Maintained tegra endianess (Dmitry Osipenko)

- Enabled the sun4i / sun5i timer for sched_clock, all others winner
boards have the arch arm timer which is more accurate (Hans de Goede)

- Renamed the arch arm timer function name to reflect better its
purpose (Laurent Pinchart)

- Cleaned up the sun5i timer code, replaced the setup_irq by the
request_irq function and handled the parent clock frequency change with the frequency notifiers (Maxime Ripard)

- Fixed features declaration for the efm32 timer (Viresh Kumar)

Thanks !

-- Daniel

The following changes since commit 2557d215a36d18c8bbaa35f65749349ac603360b:

Merge branch 'timers/urgent' into timers/core, to pick up fixes
before applying new changes (2015-03-17 11:11:24 +0100)

are available in the git repository at:

http://git.linaro.org/people/daniel.lezcano/linux.git clockevents/4.1

for you to fetch changes up to 0bb4ef6f7c56cdf606a5e501cf1597f40c9028eb

clocksource: efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features
(2015-03-30 15:27:24 +0200)

----------------------------------------------------------------
Ben Dooks (2):
clocksource: at91: Make IO endian agnostic
clocksource: dw_apb_timer_of: Make IO endian agnostic

Dmitry Osipenko (1):
clocksource: tegra: Maintain CPU endianness

Hans de Goede (1):
clocksource: sun4i-timer: Only register a sched_clock on sun4i
and sun5i

Laurent Pinchart (1):
clocksource: arm_arch_timer: Rename arch_timer_probed to reflect
behaviour

Maxime Ripard (5):
clocksource: sun5i: Switch to request_irq
clocksource: sun5i: Use of_io_request_and_map
clocksource: sun5i: Remove sched_clock
clocksource: sun5i: Refactor the current code
clocksource: sun5i: Add clock notifiers

Viresh Kumar (1):
clocksource: efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features

  drivers/clocksource/arm_arch_timer.c  |  13 +++++-----
  drivers/clocksource/dw_apb_timer_of.c |   2 +-
  drivers/clocksource/sun4i_timer.c     |  10 +++++++-
  drivers/clocksource/tegra20_timer.c   |   4 ++--
  drivers/clocksource/time-efm32.c      |   2 +-
  drivers/clocksource/timer-atmel-pit.c |   4 ++--
  drivers/clocksource/timer-sun5i.c     | 302 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------
  7 files changed, 250 insertions(+), 87 deletions(-)
Signature · 5 lines
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#1 lore raw

PATCH 1/11 clocksource: arm_arch_timer: Rename arch_timer_probed to reflect behaviour

From: Laurent Pinchart <[email protected]>

The arch_timer_probed function returns whether the given time doesn't need to be probed. This can be the case when the timer has been probed already, but also when it has no corresponding enabled node in DT.

Rename the function to arch_timer_need_probe and invert its return value to better reflect the function's purpose and behaviour.

---
 drivers/clocksource/arm_arch_timer.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/clocksource/arm_arch_timer.c +7 -6
index a3025e7..50bb7f2 100644
@@ -661,17 +661,17 @@ static const struct of_device_id arch_timer_mem_of_match[] __initconst = {
 };
 
 static bool __init
-arch_timer_probed(int type, const struct of_device_id *matches)
+arch_timer_need_probe(int type, const struct of_device_id *matches)
 {
 	struct device_node *dn;
-	bool probed = true;
+	bool need_probe = false;
 
 	dn = of_find_matching_node(NULL, matches);
 	if (dn && of_device_is_available(dn) && !(arch_timers_present & type))
-		probed = false;
+		need_probe = true;
 	of_node_put(dn);
 
-	return probed;
+	return need_probe;
 }
 
 static void __init arch_timer_common_init(void)
@@ -680,9 +680,10 @@ static void __init arch_timer_common_init(void)
 
 	/* Wait until both nodes are probed if we have two timers */
 	if ((arch_timers_present & mask) != mask) {
-		if (!arch_timer_probed(ARCH_MEM_TIMER, arch_timer_mem_of_match))
+		if (arch_timer_need_probe(ARCH_MEM_TIMER,
+					  arch_timer_mem_of_match))
 			return;
-		if (!arch_timer_probed(ARCH_CP15_TIMER, arch_timer_of_match))
+		if (arch_timer_need_probe(ARCH_CP15_TIMER, arch_timer_of_match))
 			return;
 	}
 
Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/11 clocksource: sun5i: Switch to request_irq

From: Maxime Ripard <[email protected]>

The current code uses setup_irq, while it could perfectly use the much simpler request_irq. Switch to that.

---
 drivers/clocksource/timer-sun5i.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/clocksource/timer-sun5i.c +2 -8
index 5dcbf90..5320846 100644
@@ -130,13 +130,6 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static struct irqaction sun5i_timer_irq = {
-	.name = "sun5i_timer0",
-	.flags = IRQF_TIMER | IRQF_IRQPOLL,
-	.handler = sun5i_timer_interrupt,
-	.dev_id = &sun5i_clockevent,
-};
-
 static u64 sun5i_timer_sched_read(void)
 {
 	return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
@@ -188,7 +181,8 @@ static void __init sun5i_timer_init(struct device_node *node)
 	clockevents_config_and_register(&sun5i_clockevent, rate,
 					TIMER_SYNC_TICKS, 0xffffffff);
 
-	ret = setup_irq(irq, &sun5i_timer_irq);
+	ret = request_irq(irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
+			  "sun5i_timer0", &sun5i_clockevent);
 	if (ret)
 		pr_warn("failed to setup irq %d\n", irq);
 }
Signature · 1 line
1.9.1
#3 lore raw

PATCH 3/11 clocksource: sun5i: Use of_io_request_and_map

In reply to Daniel Lezcano

From: Maxime Ripard <[email protected]>

of_iomap doesn't do a request_mem_region on the memory area defined in the DT it maps. Switch to of_io_request_and_map to make sure we're the only users.

---
 drivers/clocksource/timer-sun5i.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clocksource/timer-sun5i.c +2 -1
index 5320846..6b08694 100644
@@ -143,7 +143,8 @@ static void __init sun5i_timer_init(struct device_node *node)
 	int ret, irq;
 	u32 val;
 
-	timer_base = of_iomap(node, 0);
+	timer_base = of_io_request_and_map(node, 0,
+					   of_node_full_name(node));
 	if (!timer_base)
 		panic("Can't map registers");
 
Signature · 1 line
1.9.1
#4 lore raw

PATCH 4/11 clocksource: sun5i: Remove sched_clock

In reply to Daniel Lezcano

From: Maxime Ripard <[email protected]>

It's not possible to remove a sched_clock once it has been added, nor is it possible to change its rate.

Since we will need to support a rate change, and that we have other sched_clocks in the system anyway, remove it.

---
 drivers/clocksource/timer-sun5i.c | 6 ------
 1 file changed, 6 deletions(-)
drivers/clocksource/timer-sun5i.c +0 -6
index 6b08694..623ff9e 100644
@@ -130,11 +130,6 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static u64 sun5i_timer_sched_read(void)
-{
-	return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
-}
-
 static void __init sun5i_timer_init(struct device_node *node)
 {
 	struct reset_control *rstc;
@@ -166,7 +161,6 @@ static void __init sun5i_timer_init(struct device_node *node)
 	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
 	       timer_base + TIMER_CTL_REG(1));
 
-	sched_clock_register(sun5i_timer_sched_read, 32, rate);
 	clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
 			      rate, 340, 32, clocksource_mmio_readl_down);
 
Signature · 1 line
1.9.1
#5 lore raw

PATCH 5/11 clocksource: sun5i: Refactor the current code

In reply to Daniel Lezcano

From: Maxime Ripard <[email protected]>

Refactor the code in order to remove the global variables and split the clock source and clock events registration in order to ease the addition of the clock notifiers needed to handle the parent clock rate changes.

[dlezcano] : Fixed conflict with commit 1096be084ac59927158ce80ff1d31c33eed0e565

---
 drivers/clocksource/timer-sun5i.c | 231 +++++++++++++++++++++++++++-----------
 1 file changed, 166 insertions(+), 65 deletions(-)
drivers/clocksource/timer-sun5i.c +166 -65
index 623ff9e..824ce2d 100644
@@ -18,6 +18,7 @@
 #include <linux/irqreturn.h>
 #include <linux/reset.h>
 #include <linux/sched_clock.h>
+#include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
@@ -37,8 +38,27 @@
 
 #define TIMER_SYNC_TICKS	3
 
-static void __iomem *timer_base;
-static u32 ticks_per_jiffy;
+struct sun5i_timer {
+	void __iomem		*base;
+	struct clk		*clk;
+	u32			ticks_per_jiffy;
+};
+
+struct sun5i_timer_clksrc {
+	struct sun5i_timer	timer;
+	struct clocksource	clksrc;
+};
+
+#define to_sun5i_timer_clksrc(x) \
+	container_of(x, struct sun5i_timer_clksrc, clksrc)
+
+struct sun5i_timer_clkevt {
+	struct sun5i_timer		timer;
+	struct clock_event_device	clkevt;
+};
+
+#define to_sun5i_timer_clkevt(x) \
+	container_of(x, struct sun5i_timer_clkevt, clkevt)
 
 /*
  * When we disable a timer, we need to wait at least for 2 cycles of
@@ -46,30 +66,30 @@ static u32 ticks_per_jiffy;
  * that is already setup and runs at the same frequency than the other
  * timers, and we never will be disabled.
  */
-static void sun5i_clkevt_sync(void)
+static void sun5i_clkevt_sync(struct sun5i_timer_clkevt *ce)
 {
-	u32 old = readl(timer_base + TIMER_CNTVAL_LO_REG(1));
+	u32 old = readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1));
 
-	while ((old - readl(timer_base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
+	while ((old - readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
 		cpu_relax();
 }
 
-static void sun5i_clkevt_time_stop(u8 timer)
+static void sun5i_clkevt_time_stop(struct sun5i_timer_clkevt *ce, u8 timer)
 {
-	u32 val = readl(timer_base + TIMER_CTL_REG(timer));
-	writel(val & ~TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(timer));
+	u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
+	writel(val & ~TIMER_CTL_ENABLE, ce->timer.base + TIMER_CTL_REG(timer));
 
-	sun5i_clkevt_sync();
+	sun5i_clkevt_sync(ce);
 }
 
-static void sun5i_clkevt_time_setup(u8 timer, u32 delay)
+static void sun5i_clkevt_time_setup(struct sun5i_timer_clkevt *ce, u8 timer, u32 delay)
 {
-	writel(delay, timer_base + TIMER_INTVAL_LO_REG(timer));
+	writel(delay, ce->timer.base + TIMER_INTVAL_LO_REG(timer));
 }
 
-static void sun5i_clkevt_time_start(u8 timer, bool periodic)
+static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, bool periodic)
 {
-	u32 val = readl(timer_base + TIMER_CTL_REG(timer));
+	u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
 
 	if (periodic)
 		val &= ~TIMER_CTL_ONESHOT;
@@ -77,66 +97,170 @@ static void sun5i_clkevt_time_start(u8 timer, bool periodic)
 		val |= TIMER_CTL_ONESHOT;
 
 	writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
-	       timer_base + TIMER_CTL_REG(timer));
+	       ce->timer.base + TIMER_CTL_REG(timer));
 }
 
 static void sun5i_clkevt_mode(enum clock_event_mode mode,
-			      struct clock_event_device *clk)
+			      struct clock_event_device *clkevt)
 {
+	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
+
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		sun5i_clkevt_time_stop(0);
-		sun5i_clkevt_time_setup(0, ticks_per_jiffy);
-		sun5i_clkevt_time_start(0, true);
+		sun5i_clkevt_time_stop(ce, 0);
+		sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
+		sun5i_clkevt_time_start(ce, 0, true);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		sun5i_clkevt_time_stop(0);
-		sun5i_clkevt_time_start(0, false);
+		sun5i_clkevt_time_stop(ce, 0);
+		sun5i_clkevt_time_start(ce, 0, false);
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	default:
-		sun5i_clkevt_time_stop(0);
+		sun5i_clkevt_time_stop(ce, 0);
 		break;
 	}
 }
 
 static int sun5i_clkevt_next_event(unsigned long evt,
-				   struct clock_event_device *unused)
+				   struct clock_event_device *clkevt)
 {
-	sun5i_clkevt_time_stop(0);
-	sun5i_clkevt_time_setup(0, evt - TIMER_SYNC_TICKS);
-	sun5i_clkevt_time_start(0, false);
+	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
+
+	sun5i_clkevt_time_stop(ce, 0);
+	sun5i_clkevt_time_setup(ce, 0, evt - TIMER_SYNC_TICKS);
+	sun5i_clkevt_time_start(ce, 0, false);
 
 	return 0;
 }
 
-static struct clock_event_device sun5i_clockevent = {
-	.name = "sun5i_tick",
-	.rating = 340,
-	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = sun5i_clkevt_mode,
-	.set_next_event = sun5i_clkevt_next_event,
-};
-
-
 static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+	struct sun5i_timer_clkevt *ce = (struct sun5i_timer_clkevt *)dev_id;
 
-	writel(0x1, timer_base + TIMER_IRQ_ST_REG);
-	evt->event_handler(evt);
+	writel(0x1, ce->timer.base + TIMER_IRQ_ST_REG);
+	ce->clkevt.event_handler(&ce->clkevt);
 
 	return IRQ_HANDLED;
 }
 
+static cycle_t sun5i_clksrc_read(struct clocksource *clksrc)
+{
+	struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
+
+	return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
+}
+
+static int __init sun5i_setup_clocksource(struct device_node *node,
+					  void __iomem *base,
+					  struct clk *clk, int irq)
+{
+	struct sun5i_timer_clksrc *cs;
+	unsigned long rate;
+	int ret;
+
+	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
+	if (!cs)
+		return -ENOMEM;
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("Couldn't enable parent clock\n");
+		goto err_free;
+	}
+
+	rate = clk_get_rate(clk);
+
+	cs->timer.base = base;
+	cs->timer.clk = clk;
+
+	writel(~0, base + TIMER_INTVAL_LO_REG(1));
+	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
+	       base + TIMER_CTL_REG(1));
+
+	cs->clksrc.name = node->name;
+	cs->clksrc.rating = 340;
+	cs->clksrc.read = sun5i_clksrc_read;
+	cs->clksrc.mask = CLOCKSOURCE_MASK(32);
+	cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+	ret = clocksource_register_hz(&cs->clksrc, rate);
+	if (ret) {
+		pr_err("Couldn't register clock source.\n");
+		goto err_disable_clk;
+	}
+
+	return 0;
+
+err_disable_clk:
+	clk_disable_unprepare(clk);
+err_free:
+	kfree(cs);
+	return ret;
+}
+
+static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem *base,
+					 struct clk *clk, int irq)
+{
+	struct sun5i_timer_clkevt *ce;
+	unsigned long rate;
+	int ret;
+	u32 val;
+
+	ce = kzalloc(sizeof(*ce), GFP_KERNEL);
+	if (!ce)
+		return -ENOMEM;
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("Couldn't enable parent clock\n");
+		goto err_free;
+	}
+
+	rate = clk_get_rate(clk);
+
+	ce->timer.base = base;
+	ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+	ce->timer.clk = clk;
+
+	ce->clkevt.name = node->name;
+	ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	ce->clkevt.set_next_event = sun5i_clkevt_next_event;
+	ce->clkevt.set_mode = sun5i_clkevt_mode;
+	ce->clkevt.rating = 340;
+	ce->clkevt.irq = irq;
+	ce->clkevt.cpumask = cpu_possible_mask;
+
+	/* Enable timer0 interrupt */
+	val = readl(base + TIMER_IRQ_EN_REG);
+	writel(val | TIMER_IRQ_EN(0), base + TIMER_IRQ_EN_REG);
+
+	clockevents_config_and_register(&ce->clkevt, rate,
+					TIMER_SYNC_TICKS, 0xffffffff);
+
+	ret = request_irq(irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
+			  "sun5i_timer0", ce);
+	if (ret) {
+		pr_err("Unable to register interrupt\n");
+		goto err_disable_clk;
+	}
+
+	return 0;
+
+err_disable_clk:
+	clk_disable_unprepare(clk);
+err_free:
+	kfree(ce);
+	return ret;
+}
+
 static void __init sun5i_timer_init(struct device_node *node)
 {
 	struct reset_control *rstc;
-	unsigned long rate;
+	void __iomem *timer_base;
 	struct clk *clk;
-	int ret, irq;
-	u32 val;
+	int irq;
 
 	timer_base = of_io_request_and_map(node, 0,
 					   of_node_full_name(node));
@@ -150,36 +274,13 @@ static void __init sun5i_timer_init(struct device_node *node)
 	clk = of_clk_get(node, 0);
 	if (IS_ERR(clk))
 		panic("Can't get timer clock");
-	clk_prepare_enable(clk);
-	rate = clk_get_rate(clk);
 
 	rstc = of_reset_control_get(node, NULL);
 	if (!IS_ERR(rstc))
 		reset_control_deassert(rstc);
 
-	writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
-	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
-	       timer_base + TIMER_CTL_REG(1));
-
-	clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
-			      rate, 340, 32, clocksource_mmio_readl_down);
-
-	ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
-
-	/* Enable timer0 interrupt */
-	val = readl(timer_base + TIMER_IRQ_EN_REG);
-	writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
-
-	sun5i_clockevent.cpumask = cpu_possible_mask;
-	sun5i_clockevent.irq = irq;
-
-	clockevents_config_and_register(&sun5i_clockevent, rate,
-					TIMER_SYNC_TICKS, 0xffffffff);
-
-	ret = request_irq(irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
-			  "sun5i_timer0", &sun5i_clockevent);
-	if (ret)
-		pr_warn("failed to setup irq %d\n", irq);
+	sun5i_setup_clocksource(node, timer_base, clk, irq);
+	sun5i_setup_clockevent(node, timer_base, clk, irq);
 }
 CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
 		       sun5i_timer_init);
Signature · 1 line
1.9.1
#6 lore raw

PATCH 6/11 clocksource: sun5i: Add clock notifiers

In reply to Daniel Lezcano

From: Maxime Ripard <[email protected]>

The parent clock of the sun5i timer is the AHB clock, which rate might change because of other devices requirements.

This is for example the case on the Allwinner A31, where the DMA controller needs a minimum rate higher than the default, that is enforced after the timer driver has probed.

Add clock notifiers to make sure we reflect the clock rate changes in the timer rates.

---
 drivers/clocksource/timer-sun5i.c | 68 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)
drivers/clocksource/timer-sun5i.c +66 -2
index 824ce2d..b3840f6 100644
@@ -41,9 +41,13 @@
 struct sun5i_timer {
 	void __iomem		*base;
 	struct clk		*clk;
+	struct notifier_block	clk_rate_cb;
 	u32			ticks_per_jiffy;
 };
 
+#define to_sun5i_timer(x) \
+	container_of(x, struct sun5i_timer, clk_rate_cb)
+
 struct sun5i_timer_clksrc {
 	struct sun5i_timer	timer;
 	struct clocksource	clksrc;
@@ -152,6 +156,30 @@ static cycle_t sun5i_clksrc_read(struct clocksource *clksrc)
 	return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
 }
 
+static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
+				unsigned long event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct sun5i_timer *timer = to_sun5i_timer(nb);
+	struct sun5i_timer_clksrc *cs = container_of(timer,
+						     struct sun5i_timer_clksrc, timer);
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		clocksource_unregister(&cs->clksrc);
+		break;
+
+	case POST_RATE_CHANGE:
+		clocksource_register_hz(&cs->clksrc, ndata->new_rate);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
 static int __init sun5i_setup_clocksource(struct device_node *node,
 					  void __iomem *base,
 					  struct clk *clk, int irq)
@@ -174,6 +202,14 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
 
 	cs->timer.base = base;
 	cs->timer.clk = clk;
+	cs->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clksrc;
+	cs->timer.clk_rate_cb.next = NULL;
+
+	ret = clk_notifier_register(clk, &cs->timer.clk_rate_cb);
+	if (ret) {
+		pr_err("Unable to register clock notifier.\n");
+		goto err_disable_clk;
+	}
 
 	writel(~0, base + TIMER_INTVAL_LO_REG(1));
 	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
@@ -188,11 +224,13 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
 	ret = clocksource_register_hz(&cs->clksrc, rate);
 	if (ret) {
 		pr_err("Couldn't register clock source.\n");
-		goto err_disable_clk;
+		goto err_remove_notifier;
 	}
 
 	return 0;
 
+err_remove_notifier:
+	clk_notifier_unregister(clk, &cs->timer.clk_rate_cb);
 err_disable_clk:
 	clk_disable_unprepare(clk);
 err_free:
@@ -200,6 +238,22 @@ err_free:
 	return ret;
 }
 
+static int sun5i_rate_cb_clkevt(struct notifier_block *nb,
+				unsigned long event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct sun5i_timer *timer = to_sun5i_timer(nb);
+	struct sun5i_timer_clkevt *ce = container_of(timer,
+						     struct sun5i_timer_clkevt, timer);
+
+	if (event == POST_RATE_CHANGE) {
+		clockevents_update_freq(&ce->clkevt, ndata->new_rate);
+		ce->timer.ticks_per_jiffy = DIV_ROUND_UP(ndata->new_rate, HZ);
+	}
+
+	return NOTIFY_DONE;
+}
+
 static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem *base,
 					 struct clk *clk, int irq)
 {
@@ -223,6 +277,14 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
 	ce->timer.base = base;
 	ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
 	ce->timer.clk = clk;
+	ce->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clkevt;
+	ce->timer.clk_rate_cb.next = NULL;
+
+	ret = clk_notifier_register(clk, &ce->timer.clk_rate_cb);
+	if (ret) {
+		pr_err("Unable to register clock notifier.\n");
+		goto err_disable_clk;
+	}
 
 	ce->clkevt.name = node->name;
 	ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
@@ -243,11 +305,13 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
 			  "sun5i_timer0", ce);
 	if (ret) {
 		pr_err("Unable to register interrupt\n");
-		goto err_disable_clk;
+		goto err_remove_notifier;
 	}
 
 	return 0;
 
+err_remove_notifier:
+	clk_notifier_unregister(clk, &ce->timer.clk_rate_cb);
 err_disable_clk:
 	clk_disable_unprepare(clk);
 err_free:
Signature · 1 line
1.9.1
#7 lore raw

PATCH 7/11 clocksource: at91: Make IO endian agnostic

In reply to Daniel Lezcano

From: Ben Dooks <[email protected]>

Fix the use of __raw IO accessor with the readl/writel_relaxed versions to allow the code to be used on a system running in big endian.

Cc Daniel Lezcano <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Linux Kernel <[email protected]>
Cc Linux ARM Kernel <[email protected]>
Cc Andrew Victor <[email protected]>
Cc Nicolas Ferre <[email protected]>
Cc Jean-Christophe Plagniol-Villard <[email protected]>
---
 drivers/clocksource/timer-atmel-pit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/timer-atmel-pit.c +2 -2
index b5b4d45..c0304ff 100644
@@ -61,12 +61,12 @@ static inline struct pit_data *clkevt_to_pit_data(struct clock_event_device *clk
 
 static inline unsigned int pit_read(void __iomem *base, unsigned int reg_offset)
 {
-	return __raw_readl(base + reg_offset);
+	return readl_relaxed(base + reg_offset);
 }
 
 static inline void pit_write(void __iomem *base, unsigned int reg_offset, unsigned long value)
 {
-	__raw_writel(value, base + reg_offset);
+	writel_relaxed(value, base + reg_offset);
 }
 
 /*
Signature · 1 line
1.9.1
#8 lore raw

[tip:timers/core] clocksource/drivers/at91: Fix IO endianness

clocksource/drivers/at91: Fix IO endianness
Commit-ID:  4806c87f017d8a7003ad34886f58c3b9e023df6a
Gitweb:     http://git.kernel.org/tip/4806c87f017d8a7003ad34886f58c3b9e023df6a
Author:     Ben Dooks <[email protected]>
AuthorDate: Mon, 30 Mar 2015 22:17:09 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 31 Mar 2015 09:15:58 +0200

clocksource/drivers/at91: Fix IO endianness

Fix the use of __raw IO accessor with the readl/writel_relaxed() versions to allow the code to be used on a system running in big endian mode.

---
 drivers/clocksource/timer-atmel-pit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/timer-atmel-pit.c +2 -2
index b5b4d45..c0304ff 100644
@@ -61,12 +61,12 @@ static inline struct pit_data *clkevt_to_pit_data(struct clock_event_device *clk
 
 static inline unsigned int pit_read(void __iomem *base, unsigned int reg_offset)
 {
-	return __raw_readl(base + reg_offset);
+	return readl_relaxed(base + reg_offset);
 }
 
 static inline void pit_write(void __iomem *base, unsigned int reg_offset, unsigned long value)
 {
-	__raw_writel(value, base + reg_offset);
+	writel_relaxed(value, base + reg_offset);
 }
 
 /*
#9 lore raw

PATCH 8/11 clocksource: sun4i-timer: Only register a sched_clock on sun4i and sun5i

In reply to Daniel Lezcano

From: Hans de Goede <[email protected]>

sun6i and newer have an arm arch timer which is a better sched_clock source then the sun4i-timer, and sched_clock does not have priorities, so do not register the sun4i-timer sched_clock at all on sun6i and newer.

---
 drivers/clocksource/sun4i_timer.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/clocksource/sun4i_timer.c +9 -1
index f4a9c00..1928a89 100644
@@ -170,7 +170,15 @@ static void __init sun4i_timer_init(struct device_node *node)
 	       TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M),
 	       timer_base + TIMER_CTL_REG(1));
 
-	sched_clock_register(sun4i_timer_sched_read, 32, rate);
+	/*
+	 * sched_clock_register does not have priorities, and on sun6i and
+	 * later there is a better sched_clock registered by arm_arch_timer.c
+	 */
+	if (of_machine_is_compatible("allwinner,sun4i-a10") ||
+	    of_machine_is_compatible("allwinner,sun5i-a13") ||
+	    of_machine_is_compatible("allwinner,sun5i-a10s"))
+		sched_clock_register(sun4i_timer_sched_read, 32, rate);
+
 	clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name,
 			      rate, 350, 32, clocksource_mmio_readl_down);
 
Signature · 1 line
1.9.1
#10 lore raw

[tip:timers/core] clocksource/drivers/sun4i-timer: Only register a sched_clock on sun4i and sun5i

clocksource/drivers/sun4i-timer: Only register a sched_clock on sun4i and sun5i
Commit-ID:  37b8b003c483191a327a740fc32c1993959e7ae9
Gitweb:     http://git.kernel.org/tip/37b8b003c483191a327a740fc32c1993959e7ae9
Author:     Hans de Goede <[email protected]>
AuthorDate: Mon, 30 Mar 2015 22:17:10 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 31 Mar 2015 09:15:58 +0200

clocksource/drivers/sun4i-timer: Only register a sched_clock on sun4i and sun5i

sun6i and newer have an arm arch timer which is a better sched_clock source then the sun4i-timer, and sched_clock does not have priorities, so do not register the sun4i-timer sched_clock at all on sun6i and newer.

---
 drivers/clocksource/sun4i_timer.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/clocksource/sun4i_timer.c +9 -1
index f4a9c00..1928a89 100644
@@ -170,7 +170,15 @@ static void __init sun4i_timer_init(struct device_node *node)
 	       TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M),
 	       timer_base + TIMER_CTL_REG(1));
 
-	sched_clock_register(sun4i_timer_sched_read, 32, rate);
+	/*
+	 * sched_clock_register does not have priorities, and on sun6i and
+	 * later there is a better sched_clock registered by arm_arch_timer.c
+	 */
+	if (of_machine_is_compatible("allwinner,sun4i-a10") ||
+	    of_machine_is_compatible("allwinner,sun5i-a13") ||
+	    of_machine_is_compatible("allwinner,sun5i-a10s"))
+		sched_clock_register(sun4i_timer_sched_read, 32, rate);
+
 	clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name,
 			      rate, 350, 32, clocksource_mmio_readl_down);
 
#11 lore raw

PATCH 9/11 clocksource: tegra: Maintain CPU endianness

In reply to Daniel Lezcano

From: Dmitry Osipenko <[email protected]>

Support big-endian kernel by using endian-aware register access functions.

---
 drivers/clocksource/tegra20_timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/tegra20_timer.c +2 -2
index d2616ef..d8a3a4e 100644
@@ -57,9 +57,9 @@ static u64 persistent_ms, last_persistent_ms;
 static struct delay_timer tegra_delay_timer;
 
 #define timer_writel(value, reg) \
-	__raw_writel(value, timer_reg_base + (reg))
+	writel_relaxed(value, timer_reg_base + (reg))
 #define timer_readl(reg) \
-	__raw_readl(timer_reg_base + (reg))
+	readl_relaxed(timer_reg_base + (reg))
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 					 struct clock_event_device *evt)
Signature · 1 line
1.9.1
#12 lore raw

[tip:timers/core] clocksource/drivers/tegra: Fix IO endianness

clocksource/drivers/tegra: Fix IO endianness
Commit-ID:  59196bcef5c1034f020fe5bf3579f89767537246
Gitweb:     http://git.kernel.org/tip/59196bcef5c1034f020fe5bf3579f89767537246
Author:     Dmitry Osipenko <[email protected]>
AuthorDate: Mon, 30 Mar 2015 22:17:11 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 31 Mar 2015 09:15:58 +0200

clocksource/drivers/tegra: Fix IO endianness

Support big-endian kernel by using endian-aware register access functions.

---
 drivers/clocksource/tegra20_timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/tegra20_timer.c +2 -2
index d2616ef..d8a3a4e 100644
@@ -57,9 +57,9 @@ static u64 persistent_ms, last_persistent_ms;
 static struct delay_timer tegra_delay_timer;
 
 #define timer_writel(value, reg) \
-	__raw_writel(value, timer_reg_base + (reg))
+	writel_relaxed(value, timer_reg_base + (reg))
 #define timer_readl(reg) \
-	__raw_readl(timer_reg_base + (reg))
+	readl_relaxed(timer_reg_base + (reg))
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 					 struct clock_event_device *evt)
#13 lore raw

PATCH 10/11 clocksource: dw_apb_timer_of: Make IO endian agnostic

In reply to Daniel Lezcano

From: Ben Dooks <[email protected]>

The dw_apb_timer_of timer is using __raw_readl to access the timer register, which is causing issues when the system is running in big endian mode. Fix this by using readl_relaxed() which should account for the endian settings.

This fixes issues where the time jumps around in the dmesg output due to returnling __le32 values.

For an example, these two console lines show time running backwards:

[   49.882572] CPU1: failed to come online
[   43.282457] Brought up 1 CPUs
Cc Daniel Lezcano <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Linux ARM Kernel <[email protected]>
Cc Dinh Nguyen <[email protected]>
---
 drivers/clocksource/dw_apb_timer_of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/dw_apb_timer_of.c +1 -1
index d305fb0..a19a3f6 100644
@@ -108,7 +108,7 @@ static void __init add_clocksource(struct device_node *source_timer)
 
 static u64 notrace read_sched_clock(void)
 {
-	return ~__raw_readl(sched_io_base);
+	return ~readl_relaxed(sched_io_base);
 }
 
 static const struct of_device_id sptimer_ids[] __initconst = {
Signature · 1 line
1.9.1
#14 lore raw

[tip:timers/core] clocksource/drivers/dw_apb_timers_of: Fix IO endianness causing time jumps

clocksource/drivers/dw_apb_timers_of: Fix IO endianness causing time jumps
Commit-ID:  3a10013b6a5975346fe5a8db59500a8d176d64e0
Gitweb:     http://git.kernel.org/tip/3a10013b6a5975346fe5a8db59500a8d176d64e0
Author:     Ben Dooks <[email protected]>
AuthorDate: Mon, 30 Mar 2015 22:17:12 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 31 Mar 2015 09:15:57 +0200

clocksource/drivers/dw_apb_timers_of: Fix IO endianness causing time jumps

The dw_apb_timer_of timer is using __raw_readl() to access the timer register, which is causing issues when the system is running in big endian mode. Fix this by using readl_relaxed() which should account for the endian settings.

This fixes issues where the time jumps around in the dmesg output due to returnling __le32 values.

For an example, these two console lines show time running backwards:

[   49.882572] CPU1: failed to come online
[   43.282457] Brought up 1 CPUs
---
 drivers/clocksource/dw_apb_timer_of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/dw_apb_timer_of.c +1 -1
index d305fb0..a19a3f6 100644
@@ -108,7 +108,7 @@ static void __init add_clocksource(struct device_node *source_timer)
 
 static u64 notrace read_sched_clock(void)
 {
-	return ~__raw_readl(sched_io_base);
+	return ~readl_relaxed(sched_io_base);
 }
 
 static const struct of_device_id sptimer_ids[] __initconst = {
#15 lore raw

PATCH 11/11 clocksource: efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features

In reply to Daniel Lezcano

From: Viresh Kumar <[email protected]>

We have used CLOCK_EVT_MODE_PERIODIC instead of CLOCK_EVT_FEAT_PERIODIC while defining features. Fix it.

---
 drivers/clocksource/time-efm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/time-efm32.c +1 -1
index ec57ba2..5b6e3d5 100644
@@ -111,7 +111,7 @@ static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
 static struct efm32_clock_event_ddata clock_event_ddata = {
 	.evtdev = {
 		.name = "efm32 clockevent",
-		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_MODE_PERIODIC,
+		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
 		.set_mode = efm32_clock_event_set_mode,
 		.set_next_event = efm32_clock_event_set_next_event,
 		.rating = 200,
Signature · 1 line
1.9.1
#16 lore raw

[tip:timers/core] clocksource/drivers/efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features

clocksource/drivers/efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features
Commit-ID:  ad834a346853b7ee7c684efa56b1d415a850a710
Gitweb:     http://git.kernel.org/tip/ad834a346853b7ee7c684efa56b1d415a850a710
Author:     Viresh Kumar <[email protected]>
AuthorDate: Mon, 30 Mar 2015 22:17:13 +0200
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 31 Mar 2015 09:15:57 +0200

clocksource/drivers/efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features

We have used CLOCK_EVT_MODE_PERIODIC instead of CLOCK_EVT_FEAT_PERIODIC while defining features. Fix it.

---
 drivers/clocksource/time-efm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/time-efm32.c +1 -1
index ec57ba2..5b6e3d5 100644
@@ -111,7 +111,7 @@ static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
 static struct efm32_clock_event_ddata clock_event_ddata = {
 	.evtdev = {
 		.name = "efm32 clockevent",
-		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_MODE_PERIODIC,
+		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
 		.set_mode = efm32_clock_event_set_mode,
 		.set_next_event = efm32_clock_event_set_next_event,
 		.rating = 200,
#17 lore raw

Re: [PATCH 01/11] clocksource: arm_arch_timer: Rename arch_timer_probed to reflect behaviour

In reply to Daniel Lezcano
Quoted 21 lines · Daniel Lezcano

From: Laurent Pinchart <[email protected]>

The arch_timer_probed function returns whether the given time doesn't need to be probed. This can be the case when the timer has been probed already, but also when it has no corresponding enabled node in DT.

Rename the function to arch_timer_need_probe and invert its return value to better reflect the function's purpose and behaviour.

---
 drivers/clocksource/arm_arch_timer.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/clocksource/arm_arch_timer.c +0 -0
index a3025e7..50bb7f2 100644

drivers/clocksource/arm_arch_timer.c static const struct of_device_id arch_timer_mem_of_match[] __initconst = { · line 664

Quoted 5 lines
drivers/clocksource/arm_arch_timer.c +1 -1
@@ -661,17 +661,17 @@ static const struct of_device_id arch_timer_mem_of_match[] __initconst = {
 };
 
 static bool __init
-arch_timer_probed(int type, const struct of_device_id *matches)
+arch_timer_need_probe(int type, const struct of_device_id *matches)

If we do a rename we might as well use valid English spelling such as 'arch_timer_needs_probing()'?

Thanks,

Ingo

#18 lore raw

Re: [PATCH 01/11] clocksource: arm_arch_timer: Rename arch_timer_probed to reflect behaviour

Hi Ingo,

Quoted 27 lines · On Tuesday 31 March 2015 09:14:52 Ingo Molnar wrote:
Quoted 26 lines · Daniel Lezcano

From: Laurent Pinchart <[email protected]>

The arch_timer_probed function returns whether the given time doesn't need to be probed. This can be the case when the timer has been probed already, but also when it has no corresponding enabled node in DT.

Rename the function to arch_timer_need_probe and invert its return value to better reflect the function's purpose and behaviour.

Signed-off-by Laurent Pinchart

<[email protected]>

---

 drivers/clocksource/arm_arch_timer.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
(quoted diff) +0 -0

b/drivers/clocksource/arm_arch_timer.c index a3025e7..50bb7f2 100644

drivers/clocksource/arm_arch_timer.c +0 -0
@@ -661,17 +661,17 @@ static const struct of_device_id

arch_timer_mem_of_match[] __initconst = {>
};

Quoted 7 lines

drivers/clocksource/arm_arch_timer.c static const struct of_device_id arch_timer_mem_of_match[] __initconst = { · line 664

Quoted 4 lines

static bool __init

drivers/clocksource/arm_arch_timer.c +1 -1
-arch_timer_probed(int type, const struct of_device_id *matches)
+arch_timer_need_probe(int type, const struct of_device_id *matches)

If we do a rename we might as well use valid English spelling such as 'arch_timer_needs_probing()'?

Of course. Should I resend the patch or can you fix that while applying it ?

Signature · 3 lines
Regards,

Laurent Pinchart
#19 lore raw

Re: [PATCH 01/11] clocksource: arm_arch_timer: Rename arch_timer_probed to reflect behaviour

Quoted 32 lines · Laurent Pinchart

Hi Ingo,

Quoted 29 lines · On Tuesday 31 March 2015 09:14:52 Ingo Molnar wrote:
Quoted 28 lines · Daniel Lezcano

From: Laurent Pinchart <[email protected]>

The arch_timer_probed function returns whether the given time doesn't need to be probed. This can be the case when the timer has been probed already, but also when it has no corresponding enabled node in DT.

Rename the function to arch_timer_need_probe and invert its return value to better reflect the function's purpose and behaviour.

Signed-off-by Laurent Pinchart

<[email protected]>

---

 drivers/clocksource/arm_arch_timer.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
(quoted diff) +0 -0

b/drivers/clocksource/arm_arch_timer.c index a3025e7..50bb7f2 100644

drivers/clocksource/arm_arch_timer.c +0 -0
@@ -661,17 +661,17 @@ static const struct of_device_id

arch_timer_mem_of_match[] __initconst = {>
};

static bool __init

Quoted 7 lines
Quoted 5 lines

drivers/clocksource/arm_arch_timer.c static const struct of_device_id arch_timer_mem_of_match[] __initconst = { · line 664

Quoted 2 lines
drivers/clocksource/arm_arch_timer.c +1 -1
-arch_timer_probed(int type, const struct of_device_id *matches)
+arch_timer_need_probe(int type, const struct of_device_id *matches)

If we do a rename we might as well use valid English spelling such as 'arch_timer_needs_probing()'?

Of course. Should I resend the patch or can you fix that while applying it ?

No need to resend, I've done the rename in the patch.

Thanks,

Ingo

#20 lore raw
In reply to Daniel Lezcano
Quoted 15 lines · Daniel Lezcano

Hi Thomas, Ingo,

this pull request contains the following changes for 4.1:

- Made IO endian agnostic for at91 and dw apb timers (Ben Dooks)

- Maintained tegra endianess (Dmitry Osipenko)

- Enabled the sun4i / sun5i timer for sched_clock, all others winner boards
have the arch arm timer which is more accurate (Hans de Goede)

- Renamed the arch arm timer function name to reflect better its purpose
(Laurent Pinchart)

Quoted 7 lines

- Cleaned up the sun5i timer code, replaced the setup_irq by the
request_irq function and handled the parent clock frequency change with the frequency notifiers (Maxime Ripard)

- Fixed features declaration for the efm32 timer (Viresh Kumar)

Thanks !

So I had some comments about one of the patches, and fixes to changelogs, so I've applied all but the sun4/5i patches from email to move things forward.

The sun4/5i patches conflicted - mind reposting those merged on top of the latest tip:timers:core tree?

Thanks!

Ingo

#21 lore raw
Quoted 22 lines · Ingo Molnar
Quoted 19 lines · Daniel Lezcano

Hi Thomas, Ingo,

this pull request contains the following changes for 4.1:

- Made IO endian agnostic for at91 and dw apb timers (Ben Dooks)

- Maintained tegra endianess (Dmitry Osipenko)

- Enabled the sun4i / sun5i timer for sched_clock, all others winner boards
have the arch arm timer which is more accurate (Hans de Goede)

- Renamed the arch arm timer function name to reflect better its purpose
(Laurent Pinchart)

- Cleaned up the sun5i timer code, replaced the setup_irq by the
request_irq function and handled the parent clock frequency change with the frequency notifiers (Maxime Ripard)

Quoted 7 lines
Quoted 3 lines

- Fixed features declaration for the efm32 timer (Viresh Kumar)

Thanks !

So I had some comments about one of the patches, and fixes to changelogs, so I've applied all but the sun4/5i patches from email to move things forward.

The subsystem prefix is now 'clocksource/drivers/<name>' ?

Quoted 2 lines

The sun4/5i patches conflicted - mind reposting those merged on top of the latest tip:timers:core tree?

Yes, sure. No problem.

Thanks !

-- Daniel

Signature · 5 lines
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#22 lore raw
Quoted 25 lines · Daniel Lezcano
Quoted 24 lines · Ingo Molnar
Quoted 21 lines · Daniel Lezcano

Hi Thomas, Ingo,

this pull request contains the following changes for 4.1:

- Made IO endian agnostic for at91 and dw apb timers (Ben Dooks)

- Maintained tegra endianess (Dmitry Osipenko)

- Enabled the sun4i / sun5i timer for sched_clock, all others winner boards
have the arch arm timer which is more accurate (Hans de Goede)

- Renamed the arch arm timer function name to reflect better its purpose
(Laurent Pinchart)

- Cleaned up the sun5i timer code, replaced the setup_irq by the
request_irq function and handled the parent clock frequency change with the frequency notifiers (Maxime Ripard)

- Fixed features declaration for the efm32 timer (Viresh Kumar)

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Thanks !

So I had some comments about one of the patches, and fixes to changelogs, so I've applied all but the sun4/5i patches from email to move things forward.

The subsystem prefix is now 'clocksource/drivers/<name>' ?

At least now that we have a good number of clocksource drivers, for such pure driver changes that's the logical prefix and makes it easier to tell apart clocksource core changes from driver changes.

Quoted 4 lines
Quoted 2 lines

The sun4/5i patches conflicted - mind reposting those merged on top of the latest tip:timers:core tree?

Yes, sure. No problem.

Thanks!

Ingo