All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/2] clocksource: Conexant CX92755 timers support
@ 2015-01-26 18:35 ` Baruch Siach
  0 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner
  Cc: linux-kernel, linux-arm-kernel, Baruch Siach

This short series adds support for the Conexant CX92755 SoC timers. This SoC is
part of the Conexant Digicolor series of SoCs.

v6:
   * Use a dedicated config symbol, CONFIG_DIGICOLOR_TIMER, to enable the 
	 driver (Daniel Lezcano)

v5:
   http://thread.gmane.org/gmane.linux.kernel/1874237

   * Switch back to use of_iomap (not of_io_request_and_map), as the watchdog 
	 driver also needs access to the same registers; add a comment clarifying 
	 this

   Address more review comments by Daniel Lezcano:

   * Properly encapsulate the static objects for the clock_event code

   * Use dc_timer_{disable,enable,set_count} accessors to make the code clearer

v4:
   http://thread.gmane.org/gmane.linux.kernel/1874017

   Address review comments by Daniel Lezcano:

   * Use macros for register configuration values

   * Encapsulate static objects in a struct

   * Use of_io_request_and_map to exclusively map registers

   * Use UINT_MAX instead of ~0

   * Use request_irq instead of setup_irq, obviating the need for a separate 
     irqaction struct

v3:
   http://article.gmane.org/gmane.linux.kernel/1870628
   http://article.gmane.org/gmane.linux.kernel/1870627

   * Split into a separate clocksource series

v2:
   http://article.gmane.org/gmane.linux.kernel/1861850
   http://article.gmane.org/gmane.linux.kernel/1861853

   * Change the timer dt binding, so that the 'reg' property points to the
     first "Agent Communication" register. This should improve the chance of
     reusing this binding for other SoCs in this series.

   * Add the CONTROL() and COUNT() macros to the timer driver to make the code
     clearer.

   * Move arch/arm Kconfig changes from the clocksource driver patch to the
     base arch support patch to reduce dependency between them

v1:
   http://article.gmane.org/gmane.linux.kernel/1855028
   http://article.gmane.org/gmane.linux.kernel/1855025

Baruch Siach (2):
  clocksource: devicetree: document Conexant Digicolor timer binding
  clocksource: driver for Conexant Digicolor SoC timer

 .../devicetree/bindings/timer/digicolor-timer.txt  |  18 ++
 drivers/clocksource/Kconfig                        |   3 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/timer-digicolor.c              | 199 +++++++++++++++++++++
 4 files changed, 221 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt
 create mode 100644 drivers/clocksource/timer-digicolor.c

-- 
2.1.4


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v6 0/2] clocksource: Conexant CX92755 timers support
@ 2015-01-26 18:35 ` Baruch Siach
  0 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

This short series adds support for the Conexant CX92755 SoC timers. This SoC is
part of the Conexant Digicolor series of SoCs.

v6:
   * Use a dedicated config symbol, CONFIG_DIGICOLOR_TIMER, to enable the 
	 driver (Daniel Lezcano)

v5:
   http://thread.gmane.org/gmane.linux.kernel/1874237

   * Switch back to use of_iomap (not of_io_request_and_map), as the watchdog 
	 driver also needs access to the same registers; add a comment clarifying 
	 this

   Address more review comments by Daniel Lezcano:

   * Properly encapsulate the static objects for the clock_event code

   * Use dc_timer_{disable,enable,set_count} accessors to make the code clearer

v4:
   http://thread.gmane.org/gmane.linux.kernel/1874017

   Address review comments by Daniel Lezcano:

   * Use macros for register configuration values

   * Encapsulate static objects in a struct

   * Use of_io_request_and_map to exclusively map registers

   * Use UINT_MAX instead of ~0

   * Use request_irq instead of setup_irq, obviating the need for a separate 
     irqaction struct

v3:
   http://article.gmane.org/gmane.linux.kernel/1870628
   http://article.gmane.org/gmane.linux.kernel/1870627

   * Split into a separate clocksource series

v2:
   http://article.gmane.org/gmane.linux.kernel/1861850
   http://article.gmane.org/gmane.linux.kernel/1861853

   * Change the timer dt binding, so that the 'reg' property points to the
     first "Agent Communication" register. This should improve the chance of
     reusing this binding for other SoCs in this series.

   * Add the CONTROL() and COUNT() macros to the timer driver to make the code
     clearer.

   * Move arch/arm Kconfig changes from the clocksource driver patch to the
     base arch support patch to reduce dependency between them

v1:
   http://article.gmane.org/gmane.linux.kernel/1855028
   http://article.gmane.org/gmane.linux.kernel/1855025

Baruch Siach (2):
  clocksource: devicetree: document Conexant Digicolor timer binding
  clocksource: driver for Conexant Digicolor SoC timer

 .../devicetree/bindings/timer/digicolor-timer.txt  |  18 ++
 drivers/clocksource/Kconfig                        |   3 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/timer-digicolor.c              | 199 +++++++++++++++++++++
 4 files changed, 221 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt
 create mode 100644 drivers/clocksource/timer-digicolor.c

-- 
2.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v6 1/2] clocksource: devicetree: document Conexant Digicolor timer binding
  2015-01-26 18:35 ` Baruch Siach
@ 2015-01-26 18:35   ` Baruch Siach
  -1 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner
  Cc: linux-kernel, linux-arm-kernel, Baruch Siach

The Conexant CX92755 SoC provides 8 32-bit timers as part of its so called
"Agent Communication" block. Timers can be configures either as free running or
one shot. Each timer has a dedicated interrupt source in the CX92755 interrupts
controller. The first timer (Timer A) can also be configured as watchdog.

This commit adds devicetree binding definition of this hardware module. The
binding defined here should be reusable for other SoCs in the Digicolor series.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 .../devicetree/bindings/timer/digicolor-timer.txt      | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/digicolor-timer.txt b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
new file mode 100644
index 000000000000..d1b659bbc29f
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
@@ -0,0 +1,18 @@
+Conexant Digicolor SoCs Timer Controller
+
+Required properties:
+
+- compatible : should be "cnxt,cx92755-timer"
+- reg : Specifies base physical address and size of the "Agent Communication"
+  timer registers
+- interrupts : Contains 8 interrupts, one for each timer
+- clocks: phandle to the main clock
+
+Example:
+
+	timer@f0000fc0 {
+		compatible = "cnxt,cx92755-timer";
+		reg = <0xf0000fc0 0x40>;
+		interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>;
+		clocks = <&main_clk>;
+	};
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 1/2] clocksource: devicetree: document Conexant Digicolor timer binding
@ 2015-01-26 18:35   ` Baruch Siach
  0 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

The Conexant CX92755 SoC provides 8 32-bit timers as part of its so called
"Agent Communication" block. Timers can be configures either as free running or
one shot. Each timer has a dedicated interrupt source in the CX92755 interrupts
controller. The first timer (Timer A) can also be configured as watchdog.

This commit adds devicetree binding definition of this hardware module. The
binding defined here should be reusable for other SoCs in the Digicolor series.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 .../devicetree/bindings/timer/digicolor-timer.txt      | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/digicolor-timer.txt b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
new file mode 100644
index 000000000000..d1b659bbc29f
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
@@ -0,0 +1,18 @@
+Conexant Digicolor SoCs Timer Controller
+
+Required properties:
+
+- compatible : should be "cnxt,cx92755-timer"
+- reg : Specifies base physical address and size of the "Agent Communication"
+  timer registers
+- interrupts : Contains 8 interrupts, one for each timer
+- clocks: phandle to the main clock
+
+Example:
+
+	timer at f0000fc0 {
+		compatible = "cnxt,cx92755-timer";
+		reg = <0xf0000fc0 0x40>;
+		interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>;
+		clocks = <&main_clk>;
+	};
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 2/2] clocksource: driver for Conexant Digicolor SoC timer
  2015-01-26 18:35 ` Baruch Siach
@ 2015-01-26 18:35   ` Baruch Siach
  -1 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner
  Cc: linux-kernel, linux-arm-kernel, Baruch Siach

Add clocksource driver to the Conexant CX92755 SoC, part of the Digicolor SoCs
series. Hardware provides 8 timers, A to H. Timer A is dedicated to a future
watchdog driver so we don't use it here. Use timer B for sched_clock, and timer
C for clock_event.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/clocksource/Kconfig           |   3 +
 drivers/clocksource/Makefile          |   1 +
 drivers/clocksource/timer-digicolor.c | 199 ++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/clocksource/timer-digicolor.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec27d3c8..7e116ce190dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -18,6 +18,9 @@ config CLKBLD_I8253
 config CLKSRC_MMIO
 	bool
 
+config DIGICOLOR_TIMER
+	bool
+
 config DW_APB_TIMER
 	bool
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b24b56b..6b20951fc1e3 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
 obj-$(CONFIG_EM_TIMER_STI)	+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
+obj-$(CONFIG_DIGICOLOR_TIMER)	+= timer-digicolor.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
new file mode 100644
index 000000000000..7f8388cfa810
--- /dev/null
+++ b/drivers/clocksource/timer-digicolor.c
@@ -0,0 +1,199 @@
+/*
+ * Conexant Digicolor timer driver
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * Based on:
+ *	Allwinner SoCs hstimer driver
+ *
+ * Copyright (C) 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * Conexant Digicolor SoCs have 8 configurable timers, named from "Timer A" to
+ * "Timer H". Timer A is the only one with watchdog support, so it is dedicated
+ * to the watchdog driver. This driver uses Timer B for sched_clock(), and
+ * Timer C for clockevents.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+enum {
+	TIMER_A,
+	TIMER_B,
+	TIMER_C,
+	TIMER_D,
+	TIMER_E,
+	TIMER_F,
+	TIMER_G,
+	TIMER_H,
+};
+
+#define CONTROL(t)	((t)*8)
+#define COUNT(t)	((t)*8 + 4)
+
+#define CONTROL_DISABLE		0
+#define CONTROL_ENABLE		BIT(0)
+#define CONTROL_MODE(m)		((m) << 4)
+#define CONTROL_MODE_ONESHOT	CONTROL_MODE(1)
+#define CONTROL_MODE_PERIODIC	CONTROL_MODE(2)
+
+struct digicolor_timer {
+	struct clock_event_device ce;
+	void __iomem *base;
+	u32 ticks_per_jiffy;
+	int timer_id; /* one of TIMER_* */
+};
+
+struct digicolor_timer *dc_timer(struct clock_event_device *ce)
+{
+	return container_of(ce, struct digicolor_timer, ce);
+}
+
+static inline void dc_timer_disable(struct clock_event_device *ce)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writeb(CONTROL_DISABLE, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_enable(struct clock_event_device *ce, u32 mode)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writeb(CONTROL_ENABLE | mode, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_set_count(struct clock_event_device *ce,
+				      unsigned long count)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writel(count, dt->base + COUNT(dt->timer_id));
+}
+
+static void digicolor_clkevt_mode(enum clock_event_mode mode,
+				  struct clock_event_device *ce)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		dc_timer_disable(ce);
+		dc_timer_set_count(ce, dt->ticks_per_jiffy);
+		dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		dc_timer_disable(ce);
+		dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		dc_timer_disable(ce);
+		break;
+	}
+}
+
+static int digicolor_clkevt_next_event(unsigned long evt,
+				       struct clock_event_device *ce)
+{
+	dc_timer_disable(ce);
+	dc_timer_set_count(ce, evt);
+	dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+
+	return 0;
+}
+
+static struct digicolor_timer dc_timer_dev = {
+	.ce = {
+		.name = "digicolor_tick",
+		.rating = 340,
+		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+		.set_mode = digicolor_clkevt_mode,
+		.set_next_event = digicolor_clkevt_next_event,
+	},
+	.timer_id = TIMER_C,
+};
+
+static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static u64 digicolor_timer_sched_read(void)
+{
+	return ~readl(dc_timer_dev.base + COUNT(TIMER_B));
+}
+
+static void __init digicolor_timer_init(struct device_node *node)
+{
+	unsigned long rate;
+	struct clk *clk;
+	int ret, irq;
+
+	/*
+	 * timer registers are shared with the watchdog timer;
+	 * don't map exclusively
+	 */
+	dc_timer_dev.base = of_iomap(node, 0);
+	if (!dc_timer_dev.base) {
+		pr_err("Can't map registers");
+		return;
+	}
+
+	irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id);
+	if (irq <= 0) {
+		pr_err("Can't parse IRQ");
+		return;
+	}
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk)) {
+		pr_err("Can't get timer clock");
+		return;
+	}
+	clk_prepare_enable(clk);
+	rate = clk_get_rate(clk);
+	dc_timer_dev.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+
+	writeb(CONTROL_DISABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+	writel(UINT_MAX, dc_timer_dev.base + COUNT(TIMER_B));
+	writeb(CONTROL_ENABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+
+	sched_clock_register(digicolor_timer_sched_read, 32, rate);
+	clocksource_mmio_init(dc_timer_dev.base + COUNT(TIMER_B), node->name,
+			      rate, 340, 32, clocksource_mmio_readl_down);
+
+	ret = request_irq(irq, digicolor_timer_interrupt,
+			  IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC",
+			  &dc_timer_dev.ce);
+	if (ret)
+		pr_warn("request of timer irq %d failed (%d)\n", irq, ret);
+
+	dc_timer_dev.ce.cpumask = cpu_possible_mask;
+	dc_timer_dev.ce.irq = irq;
+
+	clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff);
+}
+CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer",
+		       digicolor_timer_init);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 2/2] clocksource: driver for Conexant Digicolor SoC timer
@ 2015-01-26 18:35   ` Baruch Siach
  0 siblings, 0 replies; 8+ messages in thread
From: Baruch Siach @ 2015-01-26 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

Add clocksource driver to the Conexant CX92755 SoC, part of the Digicolor SoCs
series. Hardware provides 8 timers, A to H. Timer A is dedicated to a future
watchdog driver so we don't use it here. Use timer B for sched_clock, and timer
C for clock_event.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/clocksource/Kconfig           |   3 +
 drivers/clocksource/Makefile          |   1 +
 drivers/clocksource/timer-digicolor.c | 199 ++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/clocksource/timer-digicolor.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec27d3c8..7e116ce190dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -18,6 +18,9 @@ config CLKBLD_I8253
 config CLKSRC_MMIO
 	bool
 
+config DIGICOLOR_TIMER
+	bool
+
 config DW_APB_TIMER
 	bool
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b24b56b..6b20951fc1e3 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
 obj-$(CONFIG_EM_TIMER_STI)	+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
+obj-$(CONFIG_DIGICOLOR_TIMER)	+= timer-digicolor.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
new file mode 100644
index 000000000000..7f8388cfa810
--- /dev/null
+++ b/drivers/clocksource/timer-digicolor.c
@@ -0,0 +1,199 @@
+/*
+ * Conexant Digicolor timer driver
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * Based on:
+ *	Allwinner SoCs hstimer driver
+ *
+ * Copyright (C) 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * Conexant Digicolor SoCs have 8 configurable timers, named from "Timer A" to
+ * "Timer H". Timer A is the only one with watchdog support, so it is dedicated
+ * to the watchdog driver. This driver uses Timer B for sched_clock(), and
+ * Timer C for clockevents.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+enum {
+	TIMER_A,
+	TIMER_B,
+	TIMER_C,
+	TIMER_D,
+	TIMER_E,
+	TIMER_F,
+	TIMER_G,
+	TIMER_H,
+};
+
+#define CONTROL(t)	((t)*8)
+#define COUNT(t)	((t)*8 + 4)
+
+#define CONTROL_DISABLE		0
+#define CONTROL_ENABLE		BIT(0)
+#define CONTROL_MODE(m)		((m) << 4)
+#define CONTROL_MODE_ONESHOT	CONTROL_MODE(1)
+#define CONTROL_MODE_PERIODIC	CONTROL_MODE(2)
+
+struct digicolor_timer {
+	struct clock_event_device ce;
+	void __iomem *base;
+	u32 ticks_per_jiffy;
+	int timer_id; /* one of TIMER_* */
+};
+
+struct digicolor_timer *dc_timer(struct clock_event_device *ce)
+{
+	return container_of(ce, struct digicolor_timer, ce);
+}
+
+static inline void dc_timer_disable(struct clock_event_device *ce)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writeb(CONTROL_DISABLE, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_enable(struct clock_event_device *ce, u32 mode)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writeb(CONTROL_ENABLE | mode, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_set_count(struct clock_event_device *ce,
+				      unsigned long count)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+	writel(count, dt->base + COUNT(dt->timer_id));
+}
+
+static void digicolor_clkevt_mode(enum clock_event_mode mode,
+				  struct clock_event_device *ce)
+{
+	struct digicolor_timer *dt = dc_timer(ce);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		dc_timer_disable(ce);
+		dc_timer_set_count(ce, dt->ticks_per_jiffy);
+		dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		dc_timer_disable(ce);
+		dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		dc_timer_disable(ce);
+		break;
+	}
+}
+
+static int digicolor_clkevt_next_event(unsigned long evt,
+				       struct clock_event_device *ce)
+{
+	dc_timer_disable(ce);
+	dc_timer_set_count(ce, evt);
+	dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+
+	return 0;
+}
+
+static struct digicolor_timer dc_timer_dev = {
+	.ce = {
+		.name = "digicolor_tick",
+		.rating = 340,
+		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+		.set_mode = digicolor_clkevt_mode,
+		.set_next_event = digicolor_clkevt_next_event,
+	},
+	.timer_id = TIMER_C,
+};
+
+static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static u64 digicolor_timer_sched_read(void)
+{
+	return ~readl(dc_timer_dev.base + COUNT(TIMER_B));
+}
+
+static void __init digicolor_timer_init(struct device_node *node)
+{
+	unsigned long rate;
+	struct clk *clk;
+	int ret, irq;
+
+	/*
+	 * timer registers are shared with the watchdog timer;
+	 * don't map exclusively
+	 */
+	dc_timer_dev.base = of_iomap(node, 0);
+	if (!dc_timer_dev.base) {
+		pr_err("Can't map registers");
+		return;
+	}
+
+	irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id);
+	if (irq <= 0) {
+		pr_err("Can't parse IRQ");
+		return;
+	}
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk)) {
+		pr_err("Can't get timer clock");
+		return;
+	}
+	clk_prepare_enable(clk);
+	rate = clk_get_rate(clk);
+	dc_timer_dev.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+
+	writeb(CONTROL_DISABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+	writel(UINT_MAX, dc_timer_dev.base + COUNT(TIMER_B));
+	writeb(CONTROL_ENABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+
+	sched_clock_register(digicolor_timer_sched_read, 32, rate);
+	clocksource_mmio_init(dc_timer_dev.base + COUNT(TIMER_B), node->name,
+			      rate, 340, 32, clocksource_mmio_readl_down);
+
+	ret = request_irq(irq, digicolor_timer_interrupt,
+			  IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC",
+			  &dc_timer_dev.ce);
+	if (ret)
+		pr_warn("request of timer irq %d failed (%d)\n", irq, ret);
+
+	dc_timer_dev.ce.cpumask = cpu_possible_mask;
+	dc_timer_dev.ce.irq = irq;
+
+	clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff);
+}
+CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer",
+		       digicolor_timer_init);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v6 0/2] clocksource: Conexant CX92755 timers support
  2015-01-26 18:35 ` Baruch Siach
@ 2015-01-26 21:23   ` Daniel Lezcano
  -1 siblings, 0 replies; 8+ messages in thread
From: Daniel Lezcano @ 2015-01-26 21:23 UTC (permalink / raw)
  To: Baruch Siach, Thomas Gleixner; +Cc: linux-kernel, linux-arm-kernel


Hi Baruch,

applied the series for 3.20.

Thanks !
   -- Daniel


On 01/26/2015 07:35 PM, Baruch Siach wrote:
> This short series adds support for the Conexant CX92755 SoC timers. This SoC is
> part of the Conexant Digicolor series of SoCs.
>
> v6:
>     * Use a dedicated config symbol, CONFIG_DIGICOLOR_TIMER, to enable the
> 	 driver (Daniel Lezcano)
>
> v5:
>     http://thread.gmane.org/gmane.linux.kernel/1874237
>
>     * Switch back to use of_iomap (not of_io_request_and_map), as the watchdog
> 	 driver also needs access to the same registers; add a comment clarifying
> 	 this
>
>     Address more review comments by Daniel Lezcano:
>
>     * Properly encapsulate the static objects for the clock_event code
>
>     * Use dc_timer_{disable,enable,set_count} accessors to make the code clearer
>
> v4:
>     http://thread.gmane.org/gmane.linux.kernel/1874017
>
>     Address review comments by Daniel Lezcano:
>
>     * Use macros for register configuration values
>
>     * Encapsulate static objects in a struct
>
>     * Use of_io_request_and_map to exclusively map registers
>
>     * Use UINT_MAX instead of ~0
>
>     * Use request_irq instead of setup_irq, obviating the need for a separate
>       irqaction struct
>
> v3:
>     http://article.gmane.org/gmane.linux.kernel/1870628
>     http://article.gmane.org/gmane.linux.kernel/1870627
>
>     * Split into a separate clocksource series
>
> v2:
>     http://article.gmane.org/gmane.linux.kernel/1861850
>     http://article.gmane.org/gmane.linux.kernel/1861853
>
>     * Change the timer dt binding, so that the 'reg' property points to the
>       first "Agent Communication" register. This should improve the chance of
>       reusing this binding for other SoCs in this series.
>
>     * Add the CONTROL() and COUNT() macros to the timer driver to make the code
>       clearer.
>
>     * Move arch/arm Kconfig changes from the clocksource driver patch to the
>       base arch support patch to reduce dependency between them
>
> v1:
>     http://article.gmane.org/gmane.linux.kernel/1855028
>     http://article.gmane.org/gmane.linux.kernel/1855025
>
> Baruch Siach (2):
>    clocksource: devicetree: document Conexant Digicolor timer binding
>    clocksource: driver for Conexant Digicolor SoC timer
>
>   .../devicetree/bindings/timer/digicolor-timer.txt  |  18 ++
>   drivers/clocksource/Kconfig                        |   3 +
>   drivers/clocksource/Makefile                       |   1 +
>   drivers/clocksource/timer-digicolor.c              | 199 +++++++++++++++++++++
>   4 files changed, 221 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt
>   create mode 100644 drivers/clocksource/timer-digicolor.c
>


-- 
  <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


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v6 0/2] clocksource: Conexant CX92755 timers support
@ 2015-01-26 21:23   ` Daniel Lezcano
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Lezcano @ 2015-01-26 21:23 UTC (permalink / raw)
  To: linux-arm-kernel


Hi Baruch,

applied the series for 3.20.

Thanks !
   -- Daniel


On 01/26/2015 07:35 PM, Baruch Siach wrote:
> This short series adds support for the Conexant CX92755 SoC timers. This SoC is
> part of the Conexant Digicolor series of SoCs.
>
> v6:
>     * Use a dedicated config symbol, CONFIG_DIGICOLOR_TIMER, to enable the
> 	 driver (Daniel Lezcano)
>
> v5:
>     http://thread.gmane.org/gmane.linux.kernel/1874237
>
>     * Switch back to use of_iomap (not of_io_request_and_map), as the watchdog
> 	 driver also needs access to the same registers; add a comment clarifying
> 	 this
>
>     Address more review comments by Daniel Lezcano:
>
>     * Properly encapsulate the static objects for the clock_event code
>
>     * Use dc_timer_{disable,enable,set_count} accessors to make the code clearer
>
> v4:
>     http://thread.gmane.org/gmane.linux.kernel/1874017
>
>     Address review comments by Daniel Lezcano:
>
>     * Use macros for register configuration values
>
>     * Encapsulate static objects in a struct
>
>     * Use of_io_request_and_map to exclusively map registers
>
>     * Use UINT_MAX instead of ~0
>
>     * Use request_irq instead of setup_irq, obviating the need for a separate
>       irqaction struct
>
> v3:
>     http://article.gmane.org/gmane.linux.kernel/1870628
>     http://article.gmane.org/gmane.linux.kernel/1870627
>
>     * Split into a separate clocksource series
>
> v2:
>     http://article.gmane.org/gmane.linux.kernel/1861850
>     http://article.gmane.org/gmane.linux.kernel/1861853
>
>     * Change the timer dt binding, so that the 'reg' property points to the
>       first "Agent Communication" register. This should improve the chance of
>       reusing this binding for other SoCs in this series.
>
>     * Add the CONTROL() and COUNT() macros to the timer driver to make the code
>       clearer.
>
>     * Move arch/arm Kconfig changes from the clocksource driver patch to the
>       base arch support patch to reduce dependency between them
>
> v1:
>     http://article.gmane.org/gmane.linux.kernel/1855028
>     http://article.gmane.org/gmane.linux.kernel/1855025
>
> Baruch Siach (2):
>    clocksource: devicetree: document Conexant Digicolor timer binding
>    clocksource: driver for Conexant Digicolor SoC timer
>
>   .../devicetree/bindings/timer/digicolor-timer.txt  |  18 ++
>   drivers/clocksource/Kconfig                        |   3 +
>   drivers/clocksource/Makefile                       |   1 +
>   drivers/clocksource/timer-digicolor.c              | 199 +++++++++++++++++++++
>   4 files changed, 221 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/timer/digicolor-timer.txt
>   create mode 100644 drivers/clocksource/timer-digicolor.c
>


-- 
  <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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-01-26 21:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-26 18:35 [PATCH v6 0/2] clocksource: Conexant CX92755 timers support Baruch Siach
2015-01-26 18:35 ` Baruch Siach
2015-01-26 18:35 ` [PATCH v6 1/2] clocksource: devicetree: document Conexant Digicolor timer binding Baruch Siach
2015-01-26 18:35   ` Baruch Siach
2015-01-26 18:35 ` [PATCH v6 2/2] clocksource: driver for Conexant Digicolor SoC timer Baruch Siach
2015-01-26 18:35   ` Baruch Siach
2015-01-26 21:23 ` [PATCH v6 0/2] clocksource: Conexant CX92755 timers support Daniel Lezcano
2015-01-26 21:23   ` Daniel Lezcano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.