From 54395d7e8ddb888ed9447334a8efc3f35ca14fe5 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Wed, 30 Dec 2015 18:22:54 +0900 Subject: [PATCH] rx: clocksource: Add MTU2 support. Signed-off-by: Yoshinori Sato --- drivers/clocksource/rx_tpu.c | 67 +++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/drivers/clocksource/rx_tpu.c b/drivers/clocksource/rx_tpu.c index fc2bedd578a5..96463bceb5ab 100644 --- a/drivers/clocksource/rx_tpu.c +++ b/drivers/clocksource/rx_tpu.c @@ -1,5 +1,5 @@ /* - * RX TPU Driver + * RX TPU / MTU2 clocksource driver * * Copyright 2015 Yoshinori Sato * @@ -19,12 +19,11 @@ #define TSR 0x5 #define TCNT 0x6 -#define TCFV 0x10 - struct tpu_priv { struct clocksource cs; void __iomem *mapbase1; void __iomem *mapbase2; + void __iomem *tstr; raw_spinlock_t lock; unsigned int cs_enabled; }; @@ -38,25 +37,19 @@ static inline unsigned long read_tcnt32(struct tpu_priv *p) return tcnt; } -static int tpu_get_counter(struct tpu_priv *p, unsigned long long *val) +static void tpu_get_counter(struct tpu_priv *p, unsigned long long *val) { unsigned long v1, v2, v3; - int o1, o2; - - o1 = ioread8(p->mapbase1 + TSR) & TCFV; /* Make sure the timer value is stable. Stolen from acpi_pm.c */ do { - o2 = o1; v1 = read_tcnt32(p); v2 = read_tcnt32(p); v3 = read_tcnt32(p); - o1 = ioread8(p->mapbase1 + TSR) & TCFV; - } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) - || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); + } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) || + (v3 > v1 && v3 < v2))); *val = v2; - return o1; } static inline struct tpu_priv *cs_to_priv(struct clocksource *cs) @@ -71,8 +64,7 @@ static cycle_t tpu_clocksource_read(struct clocksource *cs) unsigned long long value; raw_spin_lock_irqsave(&p->lock, flags); - if (tpu_get_counter(p, &value)) - value += 0x100000000; + tpu_get_counter(p, &value); raw_spin_unlock_irqrestore(&p->lock, flags); return value; @@ -88,6 +80,7 @@ static int tpu_clocksource_enable(struct clocksource *cs) iowrite16(0, p->mapbase2 + TCNT); iowrite8(0x0f, p->mapbase1 + TCR); iowrite8(0x03, p->mapbase2 + TCR); + iowrite8(ioread8(p->tstr) | 0x06, p->tstr); p->cs_enabled = true; return 0; @@ -99,14 +92,12 @@ static void tpu_clocksource_disable(struct clocksource *cs) WARN_ON(!p->cs_enabled); - iowrite8(0, p->mapbase1 + TCR); - iowrite8(0, p->mapbase2 + TCR); + iowrite8(ioread8(p->tstr) & ~0x06, p->tstr); p->cs_enabled = false; } static struct tpu_priv tpu_priv = { .cs = { - .name = "RX_TPU", .rating = 200, .read = tpu_clocksource_read, .enable = tpu_clocksource_enable, @@ -132,10 +123,11 @@ static void __init rx_tpu_init(struct device_node *node) pr_err("failed to map registers for clocksource\n"); goto free_clk; } - + + tpu_priv.cs.name = "rx-tpu"; tpu_priv.mapbase1 = base + 0x20; tpu_priv.mapbase2 = base + 0x30; - iowrite8(ioread8(base) | 0x06, base); + tpu_priv.tstr = base; clocksource_register_hz(&tpu_priv.cs, clk_get_rate(clk) / 64); return; @@ -144,4 +136,41 @@ free_clk: clk_put(clk); } +static void __init rx_mtu_init(struct device_node *node) +{ + void __iomem *chbase, *tstr; + struct clk *clk; + + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_err("failed to get clock for clocksource\n"); + return; + } + + chbase = of_iomap(node, 0); + if (!chbase) { + pr_err("failed to map registers for clocksource\n"); + goto free_clk; + } + + tstr = of_iomap(node, 1); + if (!tstr) { + pr_err("failed to map registers for clocksource\n"); + goto unmap_base; + } + + tpu_priv.cs.name = "rx-mtu2"; + tpu_priv.mapbase1 = chbase; + tpu_priv.mapbase2 = chbase + 0x80; + tpu_priv.tstr = tstr; + clocksource_register_hz(&tpu_priv.cs, clk_get_rate(clk) / 64); + + return; +unmap_base: + iounmap(chbase); +free_clk: + clk_put(clk); +} + CLOCKSOURCE_OF_DECLARE(rx_tpu, "renesas,rx-tpu", rx_tpu_init); +CLOCKSOURCE_OF_DECLARE(rx_mtu, "renesas,rx-mtu2", rx_mtu_init); -- 2.11.0