* [PATCH v3 0/2] clocksource: npcm: add NPCM7xx timer driver
@ 2017-11-06 16:28 Tomer Maimon
2017-11-06 16:28 ` [PATCH v3 1/2] " Tomer Maimon
2017-11-06 16:28 ` [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings Tomer Maimon
0 siblings, 2 replies; 7+ messages in thread
From: Tomer Maimon @ 2017-11-06 16:28 UTC (permalink / raw)
To: robh+dt, mark.rutland, daniel.lezcano, tglx, avifishman70,
brendanhiggins, raltherr, joel
Cc: devicetree, linux-kernel, openbmc, Tomer Maimon
Addressed comments from:.
- Daniel Lezcano: https://www.spinics.net/lists/devicetree/msg196683.html
- Brendan Higgins: https://www.spinics.net/lists/devicetree/msg201038.html
https://www.spinics.net/lists/devicetree/msg201037.html
Changes since version 2:
- The shutdown function called oneshot function that can cause a crash
in the system.
Modify shutdown call to unique shutdown function to solve it.
- Adding support to resume function
- Using timer-of.c API
- Modify NPCM750 compatible name.
Asked Brendon to modify NPCM7xx device tree entry.
https://lkml.org/lkml/2017/11/6/335
Changes have been tested on the NPCM750 evaluation board.
Tomer Maimon (2):
clocksource: npcm: add NPCM7xx timer driver
dt-binding: timer: document NPCM7xx timer DT bindings
.../bindings/timer/nuvoton,npcm7xx-timer.txt | 25 +++
drivers/clocksource/Kconfig | 8 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/npcm7xx-timer.c | 239 +++++++++++++++++++++
4 files changed, 273 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
create mode 100644 drivers/clocksource/npcm7xx-timer.c
--
2.14.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 1/2] clocksource: npcm: add NPCM7xx timer driver
2017-11-06 16:28 [PATCH v3 0/2] clocksource: npcm: add NPCM7xx timer driver Tomer Maimon
@ 2017-11-06 16:28 ` Tomer Maimon
2017-11-17 19:29 ` Brendan Higgins
2017-11-06 16:28 ` [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings Tomer Maimon
1 sibling, 1 reply; 7+ messages in thread
From: Tomer Maimon @ 2017-11-06 16:28 UTC (permalink / raw)
To: robh+dt, mark.rutland, daniel.lezcano, tglx, avifishman70,
brendanhiggins, raltherr, joel
Cc: devicetree, linux-kernel, openbmc, Tomer Maimon
Add Nuvoton BMC NPCM7xx timer driver.
the clocksource Enable 24-bit TIMER0 and TIMER1 counters,
while TIMER0 serves as clockevent and TIMER1 serves as clocksource.
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
drivers/clocksource/Kconfig | 8 ++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/npcm7xx-timer.c | 239 ++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+)
create mode 100644 drivers/clocksource/npcm7xx-timer.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cc6062049170..46184af75d6c 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,6 +140,14 @@ config VT8500_TIMER
help
Enables support for the VT8500 driver.
+config NPCM7XX_TIMER
+ bool "NPCM7xx timer driver" if COMPILE_TEST
+ depends on HAS_IOMEM
+ select CLKSRC_MMIO
+ help
+ Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx arcithcture,
+ While TIMER0 serves as clockevent and TIMER1 serves as clocksource.
+
config CADENCE_TTC_TIMER
bool "Cadence TTC timer driver" if COMPILE_TEST
depends on COMMON_CLK
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1491e3..ff2b30b75b5b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -54,6 +54,7 @@ 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_OWL_TIMER) += owl-timer.o
+obj-$(CONFIG_NPCM7XX_TIMER) += npcm7xx-timer.o
obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
diff --git a/drivers/clocksource/npcm7xx-timer.c b/drivers/clocksource/npcm7xx-timer.c
new file mode 100644
index 000000000000..b9b468da4560
--- /dev/null
+++ b/drivers/clocksource/npcm7xx-timer.c
@@ -0,0 +1,239 @@
+
+/*
+ * Copyright (c) 2017 Nuvoton Technology corporation.
+ * Copyright 2017 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include "timer-of.h"
+
+/* Timers registers */
+#define NPCM7XX_REG_TCSR0 0x0 /* Timer 0 Control and Status Register */
+#define NPCM7XX_REG_TICR0 0x8 /* Timer 0 Initial Count Register */
+#define NPCM7XX_REG_TCSR1 0x4 /* Timer 1 Control and Status Register */
+#define NPCM7XX_REG_TICR1 0xc /* Timer 1 Initial Count Register */
+#define NPCM7XX_REG_TDR1 0x14 /* Timer 1 Data Register */
+#define NPCM7XX_REG_TISR 0x18 /* Timer Interrupt Status Register */
+
+/* Timers control */
+#define NPCM7XX_Tx_RESETINT 0x1f
+#define NPCM7XX_Tx_PERIOD BIT(27)
+#define NPCM7XX_Tx_INTEN BIT(29)
+#define NPCM7XX_Tx_COUNTEN BIT(30)
+#define NPCM7XX_Tx_ONESHOT 0x0
+#define NPCM7XX_Tx_OPER GENMASK(3, 27)
+#define NPCM7XX_Tx_MIN_PRESCALE 0x1
+#define NPCM7XX_Tx_TDR_MASK_BITS 24
+#define NPCM7XX_Tx_MAX_CNT 0xFFFFFF
+#define NPCM7XX_T0_CLR_INT 0x1
+#define NPCM7XX_Tx_CLR_CSR 0x0
+
+/* Timers operating mode */
+#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
+ NPCM7XX_Tx_INTEN | \
+ NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
+ NPCM7XX_Tx_INTEN | \
+ NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
+ NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)
+
+static int npcm7xx_timer_resume(struct clock_event_device *evt)
+{
+ struct timer_of *to = to_timer_of(evt);
+ u32 val;
+
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val |= NPCM7XX_Tx_COUNTEN;
+ writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+ return 0;
+}
+
+static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
+{
+ struct timer_of *to = to_timer_of(evt);
+ u32 val;
+
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val &= ~NPCM7XX_Tx_COUNTEN;
+ writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+ return 0;
+}
+
+static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
+{
+ struct timer_of *to = to_timer_of(evt);
+ u32 val;
+
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val &= ~NPCM7XX_Tx_OPER;
+
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val |= NPCM7XX_START_ONESHOT_Tx;
+ writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+ return 0;
+}
+
+static int npcm7xx_timer_periodic(struct clock_event_device *evt)
+{
+ struct timer_of *to = to_timer_of(evt);
+ u32 val;
+
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val &= ~NPCM7XX_Tx_OPER;
+
+ writel((timer_of_rate(to) / HZ),
+ timer_of_base(to) + NPCM7XX_REG_TICR0);
+ val |= NPCM7XX_START_PERIODIC_Tx;
+
+ writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+ return 0;
+}
+
+static int npcm7xx_clockevent_setnextevent(unsigned long evt,
+ struct clock_event_device *clk)
+{
+ struct timer_of *to = to_timer_of(clk);
+ u32 val;
+
+ writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
+ val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+ val |= NPCM7XX_START_Tx;
+ writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+ return 0;
+}
+
+static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+ struct timer_of *to = to_timer_of(evt);
+
+ writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct timer_of to_npcm7xx = {
+ .flags = TIMER_OF_IRQ | TIMER_OF_BASE,
+
+ .clkevt = {
+ .name = "npcm7xx-timer0",
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = npcm7xx_clockevent_setnextevent,
+ .set_state_shutdown = npcm7xx_timer_shutdown,
+ .set_state_periodic = npcm7xx_timer_periodic,
+ .set_state_oneshot = npcm7xx_timer_oneshot,
+ .tick_resume = npcm7xx_timer_resume,
+ .rating = 300,
+ },
+
+ .of_irq = {
+ .handler = npcm7xx_timer0_interrupt,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ },
+};
+
+static void __init npcm7xx_clockevents_init(u32 rate)
+{
+ writel(NPCM7XX_DEFAULT_CSR,
+ timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR0);
+
+ writel(NPCM7XX_Tx_RESETINT,
+ timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TISR);
+
+ to_npcm7xx.clkevt.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&to_npcm7xx.clkevt, rate,
+ 0x1, NPCM7XX_Tx_MAX_CNT);
+}
+
+static void __init npcm7xx_clocksource_init(u32 rate)
+{
+ u32 val;
+
+ writel(NPCM7XX_DEFAULT_CSR,
+ timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
+ writel(NPCM7XX_Tx_MAX_CNT,
+ timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TICR1);
+
+ val = readl(timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
+ val |= NPCM7XX_START_Tx;
+ writel(val, timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
+
+ clocksource_mmio_init(timer_of_base(&to_npcm7xx) +
+ NPCM7XX_REG_TDR1,
+ "npcm7xx-timer1", rate,
+ 300, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
+ clocksource_mmio_readl_down);
+}
+
+static int __init npcm7xx_timer_init(struct device_node *np)
+{
+ struct clk *clk;
+ int ret;
+ u32 rate;
+
+ clk = of_clk_get(np, 0);
+
+ if (IS_ERR(clk)) {
+ ret = of_property_read_u32(np, "clock-frequency", &rate);
+ if (ret)
+ return ret;
+ } else {
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+ to_npcm7xx.of_clk.clk = clk;
+ }
+
+ ret = timer_of_init(np, &to_npcm7xx);
+ if (ret)
+ goto err_timer_of_init;
+
+ /* Clock input is divided by PRESCALE + 1 before it is fed */
+ /* to the counter */
+ rate = rate / (NPCM7XX_Tx_MIN_PRESCALE + 1);
+ to_npcm7xx.of_clk.rate = rate;
+
+ npcm7xx_clocksource_init(rate);
+ npcm7xx_clockevents_init(rate);
+
+ pr_info("Enabling NPCM7xx clocksource timer base: %p, IRQ: %d\n",
+ timer_of_base(&to_npcm7xx), timer_of_irq(&to_npcm7xx));
+
+ return 0;
+
+err_timer_of_init:
+ if (!IS_ERR(clk)) {
+ clk_disable_unprepare(clk);
+ clk_put(clk);
+ }
+
+ return ret;
+}
+
+TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);
+
--
2.14.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings
2017-11-06 16:28 [PATCH v3 0/2] clocksource: npcm: add NPCM7xx timer driver Tomer Maimon
2017-11-06 16:28 ` [PATCH v3 1/2] " Tomer Maimon
@ 2017-11-06 16:28 ` Tomer Maimon
2017-11-06 22:39 ` Rob Herring
1 sibling, 1 reply; 7+ messages in thread
From: Tomer Maimon @ 2017-11-06 16:28 UTC (permalink / raw)
To: robh+dt, mark.rutland, daniel.lezcano, tglx, avifishman70,
brendanhiggins, raltherr, joel
Cc: devicetree, linux-kernel, openbmc, Tomer Maimon
Added device tree binding documentation for Nuvoton NPCM7xx timer.
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
.../bindings/timer/nuvoton,npcm7xx-timer.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
new file mode 100644
index 000000000000..c5150522e618
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
@@ -0,0 +1,25 @@
+Nuvoton NPCM7xx timer
+
+Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit
+timer counters.
+
+Required properties:
+- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750.
+- reg : Offset and length of the register set for the device.
+- interrupts : Contain the timer interrupt with flags for
+ falling edge.
+
+Required clocking property, have to be one of:
+- clocks : phandle of timer reference clock.
+- clock-frequency : The frequency in Hz of the clock that drives the NPCM7xx
+ timer (usually 25000000).
+
+Example:
+
+timer@f0008000 {
+ compatible = "nuvoton,npcm750-timer";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf0008000 0x1000>;
+ clocks = <&clk NPCM7XX_CLK_TIMER>;
+};
+
--
2.14.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings
2017-11-06 16:28 ` [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings Tomer Maimon
@ 2017-11-06 22:39 ` Rob Herring
2017-11-17 19:31 ` Brendan Higgins
0 siblings, 1 reply; 7+ messages in thread
From: Rob Herring @ 2017-11-06 22:39 UTC (permalink / raw)
To: Tomer Maimon
Cc: mark.rutland, daniel.lezcano, tglx, avifishman70, brendanhiggins,
raltherr, joel, devicetree, linux-kernel, openbmc
On Mon, Nov 06, 2017 at 06:28:36PM +0200, Tomer Maimon wrote:
> Added device tree binding documentation for Nuvoton NPCM7xx timer.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
> .../bindings/timer/nuvoton,npcm7xx-timer.txt | 25 ++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] clocksource: npcm: add NPCM7xx timer driver
2017-11-06 16:28 ` [PATCH v3 1/2] " Tomer Maimon
@ 2017-11-17 19:29 ` Brendan Higgins
2017-12-07 20:40 ` Brendan Higgins
0 siblings, 1 reply; 7+ messages in thread
From: Brendan Higgins @ 2017-11-17 19:29 UTC (permalink / raw)
To: Tomer Maimon
Cc: Rob Herring, Mark Rutland, Daniel Lezcano, Thomas Gleixner,
Avi Fishman, Rick Altherr, Joel Stanley, devicetree,
Linux Kernel Mailing List, OpenBMC Maillist
On Mon, Nov 6, 2017 at 8:28 AM, Tomer Maimon <tmaimon77@gmail.com> wrote:
> Add Nuvoton BMC NPCM7xx timer driver.
>
> the clocksource Enable 24-bit TIMER0 and TIMER1 counters,
> while TIMER0 serves as clockevent and TIMER1 serves as clocksource.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
> drivers/clocksource/Kconfig | 8 ++
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/npcm7xx-timer.c | 239 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 248 insertions(+)
> create mode 100644 drivers/clocksource/npcm7xx-timer.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index cc6062049170..46184af75d6c 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -140,6 +140,14 @@ config VT8500_TIMER
> help
> Enables support for the VT8500 driver.
>
> +config NPCM7XX_TIMER
> + bool "NPCM7xx timer driver" if COMPILE_TEST
> + depends on HAS_IOMEM
> + select CLKSRC_MMIO
> + help
> + Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx arcithcture,
> + While TIMER0 serves as clockevent and TIMER1 serves as clocksource.
> +
> config CADENCE_TTC_TIMER
> bool "Cadence TTC timer driver" if COMPILE_TEST
> depends on COMMON_CLK
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 72711f1491e3..ff2b30b75b5b 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -54,6 +54,7 @@ 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_OWL_TIMER) += owl-timer.o
> +obj-$(CONFIG_NPCM7XX_TIMER) += npcm7xx-timer.o
>
> obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
> obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
> diff --git a/drivers/clocksource/npcm7xx-timer.c b/drivers/clocksource/npcm7xx-timer.c
> new file mode 100644
> index 000000000000..b9b468da4560
> --- /dev/null
> +++ b/drivers/clocksource/npcm7xx-timer.c
> @@ -0,0 +1,239 @@
> +
> +/*
> + * Copyright (c) 2017 Nuvoton Technology corporation.
> + * Copyright 2017 Google, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation;version 2 of the License.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/clockchips.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +#include "timer-of.h"
> +
> +/* Timers registers */
> +#define NPCM7XX_REG_TCSR0 0x0 /* Timer 0 Control and Status Register */
> +#define NPCM7XX_REG_TICR0 0x8 /* Timer 0 Initial Count Register */
> +#define NPCM7XX_REG_TCSR1 0x4 /* Timer 1 Control and Status Register */
> +#define NPCM7XX_REG_TICR1 0xc /* Timer 1 Initial Count Register */
> +#define NPCM7XX_REG_TDR1 0x14 /* Timer 1 Data Register */
> +#define NPCM7XX_REG_TISR 0x18 /* Timer Interrupt Status Register */
> +
> +/* Timers control */
> +#define NPCM7XX_Tx_RESETINT 0x1f
> +#define NPCM7XX_Tx_PERIOD BIT(27)
> +#define NPCM7XX_Tx_INTEN BIT(29)
> +#define NPCM7XX_Tx_COUNTEN BIT(30)
> +#define NPCM7XX_Tx_ONESHOT 0x0
> +#define NPCM7XX_Tx_OPER GENMASK(3, 27)
> +#define NPCM7XX_Tx_MIN_PRESCALE 0x1
> +#define NPCM7XX_Tx_TDR_MASK_BITS 24
> +#define NPCM7XX_Tx_MAX_CNT 0xFFFFFF
> +#define NPCM7XX_T0_CLR_INT 0x1
> +#define NPCM7XX_Tx_CLR_CSR 0x0
> +
> +/* Timers operating mode */
> +#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
> + NPCM7XX_Tx_INTEN | \
> + NPCM7XX_Tx_MIN_PRESCALE)
> +
> +#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
> + NPCM7XX_Tx_INTEN | \
> + NPCM7XX_Tx_MIN_PRESCALE)
> +
> +#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
> + NPCM7XX_Tx_MIN_PRESCALE)
> +
> +#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)
> +
> +static int npcm7xx_timer_resume(struct clock_event_device *evt)
> +{
> + struct timer_of *to = to_timer_of(evt);
> + u32 val;
> +
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val |= NPCM7XX_Tx_COUNTEN;
> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
> +
> + return 0;
> +}
> +
> +static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
> +{
> + struct timer_of *to = to_timer_of(evt);
> + u32 val;
> +
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val &= ~NPCM7XX_Tx_COUNTEN;
> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
> +
> + return 0;
> +}
> +
> +static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
> +{
> + struct timer_of *to = to_timer_of(evt);
> + u32 val;
> +
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val &= ~NPCM7XX_Tx_OPER;
> +
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val |= NPCM7XX_START_ONESHOT_Tx;
> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
> +
> + return 0;
> +}
> +
> +static int npcm7xx_timer_periodic(struct clock_event_device *evt)
> +{
> + struct timer_of *to = to_timer_of(evt);
> + u32 val;
> +
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val &= ~NPCM7XX_Tx_OPER;
> +
> + writel((timer_of_rate(to) / HZ),
> + timer_of_base(to) + NPCM7XX_REG_TICR0);
> + val |= NPCM7XX_START_PERIODIC_Tx;
> +
> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
> +
> + return 0;
> +}
> +
> +static int npcm7xx_clockevent_setnextevent(unsigned long evt,
> + struct clock_event_device *clk)
> +{
> + struct timer_of *to = to_timer_of(clk);
> + u32 val;
> +
> + writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
> + val |= NPCM7XX_START_Tx;
> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
> +
> + return 0;
> +}
> +
> +static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = (struct clock_event_device *)dev_id;
> + struct timer_of *to = to_timer_of(evt);
> +
> + writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);
> +
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct timer_of to_npcm7xx = {
nit: the prefix should be npcm7xx_*
> + .flags = TIMER_OF_IRQ | TIMER_OF_BASE,
> +
> + .clkevt = {
> + .name = "npcm7xx-timer0",
> + .features = CLOCK_EVT_FEAT_PERIODIC |
> + CLOCK_EVT_FEAT_ONESHOT,
> + .set_next_event = npcm7xx_clockevent_setnextevent,
> + .set_state_shutdown = npcm7xx_timer_shutdown,
> + .set_state_periodic = npcm7xx_timer_periodic,
> + .set_state_oneshot = npcm7xx_timer_oneshot,
> + .tick_resume = npcm7xx_timer_resume,
> + .rating = 300,
> + },
> +
> + .of_irq = {
> + .handler = npcm7xx_timer0_interrupt,
> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
> + },
> +};
> +
> +static void __init npcm7xx_clockevents_init(u32 rate)
> +{
> + writel(NPCM7XX_DEFAULT_CSR,
> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR0);
> +
> + writel(NPCM7XX_Tx_RESETINT,
> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TISR);
> +
> + to_npcm7xx.clkevt.cpumask = cpumask_of(0);
> + clockevents_config_and_register(&to_npcm7xx.clkevt, rate,
> + 0x1, NPCM7XX_Tx_MAX_CNT);
> +}
> +
> +static void __init npcm7xx_clocksource_init(u32 rate)
> +{
> + u32 val;
> +
> + writel(NPCM7XX_DEFAULT_CSR,
> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
> + writel(NPCM7XX_Tx_MAX_CNT,
> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TICR1);
> +
> + val = readl(timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
> + val |= NPCM7XX_START_Tx;
> + writel(val, timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
> +
> + clocksource_mmio_init(timer_of_base(&to_npcm7xx) +
> + NPCM7XX_REG_TDR1,
> + "npcm7xx-timer1", rate,
> + 300, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
> + clocksource_mmio_readl_down);
> +}
> +
> +static int __init npcm7xx_timer_init(struct device_node *np)
> +{
> + struct clk *clk;
> + int ret;
> + u32 rate;
> +
> + clk = of_clk_get(np, 0);
> +
> + if (IS_ERR(clk)) {
> + ret = of_property_read_u32(np, "clock-frequency", &rate);
> + if (ret)
> + return ret;
> + } else {
> + clk_prepare_enable(clk);
> + rate = clk_get_rate(clk);
> + to_npcm7xx.of_clk.clk = clk;
> + }
> +
> + ret = timer_of_init(np, &to_npcm7xx);
> + if (ret)
> + goto err_timer_of_init;
> +
> + /* Clock input is divided by PRESCALE + 1 before it is fed */
> + /* to the counter */
> + rate = rate / (NPCM7XX_Tx_MIN_PRESCALE + 1);
> + to_npcm7xx.of_clk.rate = rate;
> +
> + npcm7xx_clocksource_init(rate);
> + npcm7xx_clockevents_init(rate);
> +
> + pr_info("Enabling NPCM7xx clocksource timer base: %p, IRQ: %d\n",
> + timer_of_base(&to_npcm7xx), timer_of_irq(&to_npcm7xx));
> +
> + return 0;
> +
> +err_timer_of_init:
> + if (!IS_ERR(clk)) {
> + clk_disable_unprepare(clk);
> + clk_put(clk);
> + }
> +
> + return ret;
> +}
> +
> +TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);
> +
> --
> 2.14.1
>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings
2017-11-06 22:39 ` Rob Herring
@ 2017-11-17 19:31 ` Brendan Higgins
0 siblings, 0 replies; 7+ messages in thread
From: Brendan Higgins @ 2017-11-17 19:31 UTC (permalink / raw)
To: Rob Herring
Cc: Tomer Maimon, Mark Rutland, Daniel Lezcano, Thomas Gleixner,
Avi Fishman, Rick Altherr, Joel Stanley, devicetree,
Linux Kernel Mailing List, OpenBMC Maillist
On Mon, Nov 6, 2017 at 2:39 PM, Rob Herring <robh@kernel.org> wrote:
> On Mon, Nov 06, 2017 at 06:28:36PM +0200, Tomer Maimon wrote:
>> Added device tree binding documentation for Nuvoton NPCM7xx timer.
>>
>> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
>> ---
>> .../bindings/timer/nuvoton,npcm7xx-timer.txt | 25 ++++++++++++++++++++++
>> 1 file changed, 25 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
>
> Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] clocksource: npcm: add NPCM7xx timer driver
2017-11-17 19:29 ` Brendan Higgins
@ 2017-12-07 20:40 ` Brendan Higgins
0 siblings, 0 replies; 7+ messages in thread
From: Brendan Higgins @ 2017-12-07 20:40 UTC (permalink / raw)
To: Tomer Maimon
Cc: Rob Herring, Mark Rutland, Daniel Lezcano, Thomas Gleixner,
Avi Fishman, Rick Altherr, Joel Stanley, devicetree,
Linux Kernel Mailing List, OpenBMC Maillist
On Fri, Nov 17, 2017 at 11:29 AM, Brendan Higgins
<brendanhiggins@google.com> wrote:
> On Mon, Nov 6, 2017 at 8:28 AM, Tomer Maimon <tmaimon77@gmail.com> wrote:
>> Add Nuvoton BMC NPCM7xx timer driver.
>>
>> the clocksource Enable 24-bit TIMER0 and TIMER1 counters,
>> while TIMER0 serves as clockevent and TIMER1 serves as clocksource.
>>
>> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
>> ---
>> drivers/clocksource/Kconfig | 8 ++
>> drivers/clocksource/Makefile | 1 +
>> drivers/clocksource/npcm7xx-timer.c | 239 ++++++++++++++++++++++++++++++++++++
>> 3 files changed, 248 insertions(+)
>> create mode 100644 drivers/clocksource/npcm7xx-timer.c
>>
>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> index cc6062049170..46184af75d6c 100644
>> --- a/drivers/clocksource/Kconfig
>> +++ b/drivers/clocksource/Kconfig
>> @@ -140,6 +140,14 @@ config VT8500_TIMER
>> help
>> Enables support for the VT8500 driver.
>>
>> +config NPCM7XX_TIMER
>> + bool "NPCM7xx timer driver" if COMPILE_TEST
>> + depends on HAS_IOMEM
>> + select CLKSRC_MMIO
>> + help
>> + Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx arcithcture,
>> + While TIMER0 serves as clockevent and TIMER1 serves as clocksource.
>> +
>> config CADENCE_TTC_TIMER
>> bool "Cadence TTC timer driver" if COMPILE_TEST
>> depends on COMMON_CLK
>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
>> index 72711f1491e3..ff2b30b75b5b 100644
>> --- a/drivers/clocksource/Makefile
>> +++ b/drivers/clocksource/Makefile
>> @@ -54,6 +54,7 @@ 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_OWL_TIMER) += owl-timer.o
>> +obj-$(CONFIG_NPCM7XX_TIMER) += npcm7xx-timer.o
>>
>> obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
>> obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
>> diff --git a/drivers/clocksource/npcm7xx-timer.c b/drivers/clocksource/npcm7xx-timer.c
>> new file mode 100644
>> index 000000000000..b9b468da4560
>> --- /dev/null
>> +++ b/drivers/clocksource/npcm7xx-timer.c
>> @@ -0,0 +1,239 @@
>> +
>> +/*
>> + * Copyright (c) 2017 Nuvoton Technology corporation.
>> + * Copyright 2017 Google, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation;version 2 of the License.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/sched.h>
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/err.h>
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/clockchips.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/of_address.h>
>> +#include "timer-of.h"
>> +
>> +/* Timers registers */
>> +#define NPCM7XX_REG_TCSR0 0x0 /* Timer 0 Control and Status Register */
>> +#define NPCM7XX_REG_TICR0 0x8 /* Timer 0 Initial Count Register */
>> +#define NPCM7XX_REG_TCSR1 0x4 /* Timer 1 Control and Status Register */
>> +#define NPCM7XX_REG_TICR1 0xc /* Timer 1 Initial Count Register */
>> +#define NPCM7XX_REG_TDR1 0x14 /* Timer 1 Data Register */
>> +#define NPCM7XX_REG_TISR 0x18 /* Timer Interrupt Status Register */
>> +
>> +/* Timers control */
>> +#define NPCM7XX_Tx_RESETINT 0x1f
>> +#define NPCM7XX_Tx_PERIOD BIT(27)
>> +#define NPCM7XX_Tx_INTEN BIT(29)
>> +#define NPCM7XX_Tx_COUNTEN BIT(30)
>> +#define NPCM7XX_Tx_ONESHOT 0x0
>> +#define NPCM7XX_Tx_OPER GENMASK(3, 27)
>> +#define NPCM7XX_Tx_MIN_PRESCALE 0x1
>> +#define NPCM7XX_Tx_TDR_MASK_BITS 24
>> +#define NPCM7XX_Tx_MAX_CNT 0xFFFFFF
>> +#define NPCM7XX_T0_CLR_INT 0x1
>> +#define NPCM7XX_Tx_CLR_CSR 0x0
>> +
>> +/* Timers operating mode */
>> +#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
>> + NPCM7XX_Tx_INTEN | \
>> + NPCM7XX_Tx_MIN_PRESCALE)
>> +
>> +#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
>> + NPCM7XX_Tx_INTEN | \
>> + NPCM7XX_Tx_MIN_PRESCALE)
>> +
>> +#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
>> + NPCM7XX_Tx_MIN_PRESCALE)
>> +
>> +#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)
>> +
>> +static int npcm7xx_timer_resume(struct clock_event_device *evt)
>> +{
>> + struct timer_of *to = to_timer_of(evt);
>> + u32 val;
>> +
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val |= NPCM7XX_Tx_COUNTEN;
>> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> +
>> + return 0;
>> +}
>> +
>> +static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
>> +{
>> + struct timer_of *to = to_timer_of(evt);
>> + u32 val;
>> +
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val &= ~NPCM7XX_Tx_COUNTEN;
>> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> +
>> + return 0;
>> +}
>> +
>> +static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
>> +{
>> + struct timer_of *to = to_timer_of(evt);
>> + u32 val;
>> +
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val &= ~NPCM7XX_Tx_OPER;
>> +
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val |= NPCM7XX_START_ONESHOT_Tx;
>> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> +
>> + return 0;
>> +}
>> +
>> +static int npcm7xx_timer_periodic(struct clock_event_device *evt)
>> +{
>> + struct timer_of *to = to_timer_of(evt);
>> + u32 val;
>> +
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val &= ~NPCM7XX_Tx_OPER;
>> +
>> + writel((timer_of_rate(to) / HZ),
>> + timer_of_base(to) + NPCM7XX_REG_TICR0);
>> + val |= NPCM7XX_START_PERIODIC_Tx;
>> +
>> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> +
>> + return 0;
>> +}
>> +
>> +static int npcm7xx_clockevent_setnextevent(unsigned long evt,
>> + struct clock_event_device *clk)
>> +{
>> + struct timer_of *to = to_timer_of(clk);
>> + u32 val;
>> +
>> + writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
>> + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> + val |= NPCM7XX_START_Tx;
>> + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
>> +
>> + return 0;
>> +}
>> +
>> +static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
>> +{
>> + struct clock_event_device *evt = (struct clock_event_device *)dev_id;
>> + struct timer_of *to = to_timer_of(evt);
>> +
>> + writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);
>> +
>> + evt->event_handler(evt);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static struct timer_of to_npcm7xx = {
>
> nit: the prefix should be npcm7xx_*
>
>> + .flags = TIMER_OF_IRQ | TIMER_OF_BASE,
>> +
>> + .clkevt = {
>> + .name = "npcm7xx-timer0",
>> + .features = CLOCK_EVT_FEAT_PERIODIC |
>> + CLOCK_EVT_FEAT_ONESHOT,
>> + .set_next_event = npcm7xx_clockevent_setnextevent,
>> + .set_state_shutdown = npcm7xx_timer_shutdown,
>> + .set_state_periodic = npcm7xx_timer_periodic,
>> + .set_state_oneshot = npcm7xx_timer_oneshot,
>> + .tick_resume = npcm7xx_timer_resume,
>> + .rating = 300,
>> + },
>> +
>> + .of_irq = {
>> + .handler = npcm7xx_timer0_interrupt,
>> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
>> + },
>> +};
>> +
>> +static void __init npcm7xx_clockevents_init(u32 rate)
>> +{
>> + writel(NPCM7XX_DEFAULT_CSR,
>> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR0);
>> +
>> + writel(NPCM7XX_Tx_RESETINT,
>> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TISR);
>> +
>> + to_npcm7xx.clkevt.cpumask = cpumask_of(0);
>> + clockevents_config_and_register(&to_npcm7xx.clkevt, rate,
>> + 0x1, NPCM7XX_Tx_MAX_CNT);
>> +}
>> +
>> +static void __init npcm7xx_clocksource_init(u32 rate)
>> +{
>> + u32 val;
>> +
>> + writel(NPCM7XX_DEFAULT_CSR,
>> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
>> + writel(NPCM7XX_Tx_MAX_CNT,
>> + timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TICR1);
>> +
>> + val = readl(timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
>> + val |= NPCM7XX_START_Tx;
>> + writel(val, timer_of_base(&to_npcm7xx) + NPCM7XX_REG_TCSR1);
>> +
>> + clocksource_mmio_init(timer_of_base(&to_npcm7xx) +
>> + NPCM7XX_REG_TDR1,
>> + "npcm7xx-timer1", rate,
>> + 300, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
>> + clocksource_mmio_readl_down);
>> +}
>> +
>> +static int __init npcm7xx_timer_init(struct device_node *np)
>> +{
>> + struct clk *clk;
>> + int ret;
>> + u32 rate;
>> +
>> + clk = of_clk_get(np, 0);
>> +
>> + if (IS_ERR(clk)) {
>> + ret = of_property_read_u32(np, "clock-frequency", &rate);
>> + if (ret)
>> + return ret;
>> + } else {
>> + clk_prepare_enable(clk);
>> + rate = clk_get_rate(clk);
>> + to_npcm7xx.of_clk.clk = clk;
>> + }
>> +
>> + ret = timer_of_init(np, &to_npcm7xx);
>> + if (ret)
>> + goto err_timer_of_init;
>> +
>> + /* Clock input is divided by PRESCALE + 1 before it is fed */
>> + /* to the counter */
>> + rate = rate / (NPCM7XX_Tx_MIN_PRESCALE + 1);
>> + to_npcm7xx.of_clk.rate = rate;
>> +
>> + npcm7xx_clocksource_init(rate);
>> + npcm7xx_clockevents_init(rate);
>> +
>> + pr_info("Enabling NPCM7xx clocksource timer base: %p, IRQ: %d\n",
>> + timer_of_base(&to_npcm7xx), timer_of_irq(&to_npcm7xx));
>> +
>> + return 0;
>> +
>> +err_timer_of_init:
>> + if (!IS_ERR(clk)) {
>> + clk_disable_unprepare(clk);
>> + clk_put(clk);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);
>> +
>> --
>> 2.14.1
>>
>
> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Any update on this?
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-12-07 20:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-06 16:28 [PATCH v3 0/2] clocksource: npcm: add NPCM7xx timer driver Tomer Maimon
2017-11-06 16:28 ` [PATCH v3 1/2] " Tomer Maimon
2017-11-17 19:29 ` Brendan Higgins
2017-12-07 20:40 ` Brendan Higgins
2017-11-06 16:28 ` [PATCH v3 2/2] dt-binding: timer: document NPCM7xx timer DT bindings Tomer Maimon
2017-11-06 22:39 ` Rob Herring
2017-11-17 19:31 ` Brendan Higgins
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).