From: Alexandre Belloni <alexandre.belloni@free-electrons.com> To: Nicolas Ferre <nicolas.ferre@atmel.com>, Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Boris Brezillon <boris.brezillon@free-electrons.com>, Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>, Wim Van Sebroeck <wim@iguana.be>, Guenter Roeck <linux@roeck-us.net>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-watchdog@vger.kernel.org, Alexandre Belloni <alexandre.belloni@free-electrons.com> Subject: [PATCH v5 08/10] clocksource: atmel-st: use syscon/regmap Date: Thu, 12 Mar 2015 13:07:32 +0100 [thread overview] Message-ID: <1426162054-9987-9-git-send-email-alexandre.belloni@free-electrons.com> (raw) In-Reply-To: <1426162054-9987-1-git-send-email-alexandre.belloni@free-electrons.com> The register range from the system timer is also used by the watchdog driver. Use a regmap to handle concurrent accesses. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> --- drivers/clocksource/timer-atmel-st.c | 94 ++++++++++++++---------------------- 1 file changed, 35 insertions(+), 59 deletions(-) diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c index 7d062ab32674..674ef2519d6b 100644 --- a/drivers/clocksource/timer-atmel-st.c +++ b/drivers/clocksource/timer-atmel-st.c @@ -24,18 +24,19 @@ #include <linux/irq.h> #include <linux/clockchips.h> #include <linux/export.h> -#include <linux/of.h> -#include <linux/of_address.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/atmel-st.h> #include <linux/of_irq.h> +#include <linux/regmap.h> #include <asm/mach/time.h> -#include <mach/at91_st.h> #include <mach/hardware.h> static unsigned long last_crtr; static u32 irqmask; static struct clock_event_device clkevt; +static struct regmap *regmap_st; #define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) @@ -46,11 +47,11 @@ static struct clock_event_device clkevt; */ static inline unsigned long read_CRTR(void) { - unsigned long x1, x2; + unsigned int x1, x2; - x1 = at91_st_read(AT91_ST_CRTR); + regmap_read(regmap_st, AT91_ST_CRTR, &x1); do { - x2 = at91_st_read(AT91_ST_CRTR); + regmap_read(regmap_st, AT91_ST_CRTR, &x2); if (x1 == x2) break; x1 = x2; @@ -63,7 +64,10 @@ static inline unsigned long read_CRTR(void) */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) { - u32 sr = at91_st_read(AT91_ST_SR) & irqmask; + u32 sr; + + regmap_read(regmap_st, AT91_ST_SR, &sr); + sr &= irqmask; /* * irqs should be disabled here, but as the irq is shared they are only @@ -115,23 +119,25 @@ static struct clocksource clk32k = { static void clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) { + unsigned int val; + /* Disable and flush pending timer interrupts */ - at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); - at91_st_read(AT91_ST_SR); + regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + regmap_read(regmap_st, AT91_ST_SR, &val); last_crtr = read_CRTR(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); + regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() * before 32 seconds have passed */ irqmask = AT91_ST_ALMS; - at91_st_write(AT91_ST_RTAR, last_crtr); + regmap_write(regmap_st, AT91_ST_RTAR, last_crtr); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: @@ -139,7 +145,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) irqmask = 0; break; } - at91_st_write(AT91_ST_IER, irqmask); + regmap_write(regmap_st, AT91_ST_IER, irqmask); } static int @@ -147,6 +153,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) { u32 alm; int status = 0; + unsigned int val; BUG_ON(delta < 2); @@ -162,12 +169,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) alm = read_CRTR(); /* Cancel any pending alarm; flush any pending IRQ */ - at91_st_write(AT91_ST_RTAR, alm); - at91_st_read(AT91_ST_SR); + regmap_write(regmap_st, AT91_ST_RTAR, alm); + regmap_read(regmap_st, AT91_ST_SR, &val); /* Schedule alarm by writing RTAR. */ alm += delta; - at91_st_write(AT91_ST_RTAR, alm); + regmap_write(regmap_st, AT91_ST_RTAR, alm); return status; } @@ -180,57 +187,26 @@ static struct clock_event_device clkevt = { .set_mode = clkevt32k_mode, }; -void __iomem *at91_st_base; -EXPORT_SYMBOL_GPL(at91_st_base); - -static const struct of_device_id at91rm9200_st_timer_ids[] = { - { .compatible = "atmel,at91rm9200-st" }, - { /* sentinel */ } -}; - -static int __init of_at91rm9200_st_init(void) -{ - struct device_node *np; - int ret; - - np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); - if (!np) - goto err; - - at91_st_base = of_iomap(np, 0); - if (!at91_st_base) - goto node_err; - - /* Get the interrupts property */ - ret = irq_of_parse_and_map(np, 0); - if (!ret) - goto ioremap_err; - at91rm9200_timer_irq.irq = ret; - - of_node_put(np); - - return 0; - -ioremap_err: - iounmap(at91_st_base); -node_err: - of_node_put(np); -err: - return -EINVAL; -} - /* * ST (system timer) module supports both clockevents and clocksource. */ static void __init atmel_st_timer_init(struct device_node *node) { - /* For device tree enabled device: initialize here */ - of_at91rm9200_st_init(); + unsigned int val; + + regmap_st = syscon_node_to_regmap(node); + if (IS_ERR(regmap_st)) + panic(pr_fmt("Unable to get regmap\n")); /* Disable all timer interrupts, and clear any pending ones */ - at91_st_write(AT91_ST_IDR, + regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); - at91_st_read(AT91_ST_SR); + regmap_read(regmap_st, AT91_ST_SR, &val); + + /* Get the interrupts property */ + at91rm9200_timer_irq.irq = irq_of_parse_and_map(node, 0); + if (!at91rm9200_timer_irq.irq) + panic(pr_fmt("Unable to get IRQ from DT\n")); /* Make IRQs happen for the system timer */ setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); @@ -239,7 +215,7 @@ static void __init atmel_st_timer_init(struct device_node *node) * directly for the clocksource and all clockevents, after adjusting * its prescaler from the 1 Hz default. */ - at91_st_write(AT91_ST_RTMR, 1); + regmap_write(regmap_st, AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ clkevt.cpumask = cpumask_of(0); -- 2.1.0
WARNING: multiple messages have this Message-ID (diff)
From: alexandre.belloni@free-electrons.com (Alexandre Belloni) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v5 08/10] clocksource: atmel-st: use syscon/regmap Date: Thu, 12 Mar 2015 13:07:32 +0100 [thread overview] Message-ID: <1426162054-9987-9-git-send-email-alexandre.belloni@free-electrons.com> (raw) In-Reply-To: <1426162054-9987-1-git-send-email-alexandre.belloni@free-electrons.com> The register range from the system timer is also used by the watchdog driver. Use a regmap to handle concurrent accesses. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> --- drivers/clocksource/timer-atmel-st.c | 94 ++++++++++++++---------------------- 1 file changed, 35 insertions(+), 59 deletions(-) diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c index 7d062ab32674..674ef2519d6b 100644 --- a/drivers/clocksource/timer-atmel-st.c +++ b/drivers/clocksource/timer-atmel-st.c @@ -24,18 +24,19 @@ #include <linux/irq.h> #include <linux/clockchips.h> #include <linux/export.h> -#include <linux/of.h> -#include <linux/of_address.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/atmel-st.h> #include <linux/of_irq.h> +#include <linux/regmap.h> #include <asm/mach/time.h> -#include <mach/at91_st.h> #include <mach/hardware.h> static unsigned long last_crtr; static u32 irqmask; static struct clock_event_device clkevt; +static struct regmap *regmap_st; #define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) @@ -46,11 +47,11 @@ static struct clock_event_device clkevt; */ static inline unsigned long read_CRTR(void) { - unsigned long x1, x2; + unsigned int x1, x2; - x1 = at91_st_read(AT91_ST_CRTR); + regmap_read(regmap_st, AT91_ST_CRTR, &x1); do { - x2 = at91_st_read(AT91_ST_CRTR); + regmap_read(regmap_st, AT91_ST_CRTR, &x2); if (x1 == x2) break; x1 = x2; @@ -63,7 +64,10 @@ static inline unsigned long read_CRTR(void) */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) { - u32 sr = at91_st_read(AT91_ST_SR) & irqmask; + u32 sr; + + regmap_read(regmap_st, AT91_ST_SR, &sr); + sr &= irqmask; /* * irqs should be disabled here, but as the irq is shared they are only @@ -115,23 +119,25 @@ static struct clocksource clk32k = { static void clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) { + unsigned int val; + /* Disable and flush pending timer interrupts */ - at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); - at91_st_read(AT91_ST_SR); + regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + regmap_read(regmap_st, AT91_ST_SR, &val); last_crtr = read_CRTR(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); + regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() * before 32 seconds have passed */ irqmask = AT91_ST_ALMS; - at91_st_write(AT91_ST_RTAR, last_crtr); + regmap_write(regmap_st, AT91_ST_RTAR, last_crtr); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: @@ -139,7 +145,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) irqmask = 0; break; } - at91_st_write(AT91_ST_IER, irqmask); + regmap_write(regmap_st, AT91_ST_IER, irqmask); } static int @@ -147,6 +153,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) { u32 alm; int status = 0; + unsigned int val; BUG_ON(delta < 2); @@ -162,12 +169,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) alm = read_CRTR(); /* Cancel any pending alarm; flush any pending IRQ */ - at91_st_write(AT91_ST_RTAR, alm); - at91_st_read(AT91_ST_SR); + regmap_write(regmap_st, AT91_ST_RTAR, alm); + regmap_read(regmap_st, AT91_ST_SR, &val); /* Schedule alarm by writing RTAR. */ alm += delta; - at91_st_write(AT91_ST_RTAR, alm); + regmap_write(regmap_st, AT91_ST_RTAR, alm); return status; } @@ -180,57 +187,26 @@ static struct clock_event_device clkevt = { .set_mode = clkevt32k_mode, }; -void __iomem *at91_st_base; -EXPORT_SYMBOL_GPL(at91_st_base); - -static const struct of_device_id at91rm9200_st_timer_ids[] = { - { .compatible = "atmel,at91rm9200-st" }, - { /* sentinel */ } -}; - -static int __init of_at91rm9200_st_init(void) -{ - struct device_node *np; - int ret; - - np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); - if (!np) - goto err; - - at91_st_base = of_iomap(np, 0); - if (!at91_st_base) - goto node_err; - - /* Get the interrupts property */ - ret = irq_of_parse_and_map(np, 0); - if (!ret) - goto ioremap_err; - at91rm9200_timer_irq.irq = ret; - - of_node_put(np); - - return 0; - -ioremap_err: - iounmap(at91_st_base); -node_err: - of_node_put(np); -err: - return -EINVAL; -} - /* * ST (system timer) module supports both clockevents and clocksource. */ static void __init atmel_st_timer_init(struct device_node *node) { - /* For device tree enabled device: initialize here */ - of_at91rm9200_st_init(); + unsigned int val; + + regmap_st = syscon_node_to_regmap(node); + if (IS_ERR(regmap_st)) + panic(pr_fmt("Unable to get regmap\n")); /* Disable all timer interrupts, and clear any pending ones */ - at91_st_write(AT91_ST_IDR, + regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); - at91_st_read(AT91_ST_SR); + regmap_read(regmap_st, AT91_ST_SR, &val); + + /* Get the interrupts property */ + at91rm9200_timer_irq.irq = irq_of_parse_and_map(node, 0); + if (!at91rm9200_timer_irq.irq) + panic(pr_fmt("Unable to get IRQ from DT\n")); /* Make IRQs happen for the system timer */ setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); @@ -239,7 +215,7 @@ static void __init atmel_st_timer_init(struct device_node *node) * directly for the clocksource and all clockevents, after adjusting * its prescaler from the 1 Hz default. */ - at91_st_write(AT91_ST_RTMR, 1); + regmap_write(regmap_st, AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ clkevt.cpumask = cpumask_of(0); -- 2.1.0
next prev parent reply other threads:[~2015-03-12 12:09 UTC|newest] Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-03-12 12:07 [PATCH v5 00/10] Atmel System Timer cleanups Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 01/10] ARM: at91/dt: declare atmel,at91rm9200-st as a syscon Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 01/10] ARM: at91/dt: declare atmel, at91rm9200-st " Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 02/10] mfd: syscon: Add atmel system timer registers definition Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-13 8:03 ` Lee Jones 2015-03-13 8:03 ` Lee Jones 2015-03-13 8:03 ` Lee Jones 2015-03-13 10:40 ` Alexandre Belloni 2015-03-13 10:40 ` Alexandre Belloni 2015-03-13 16:52 ` Nicolas Ferre 2015-03-13 16:52 ` Nicolas Ferre 2015-03-13 16:52 ` Nicolas Ferre 2015-03-16 8:17 ` Lee Jones 2015-03-16 8:17 ` Lee Jones 2015-03-16 8:17 ` Lee Jones 2015-03-12 12:07 ` [PATCH v5 03/10] watchdog: at91rm9200: use the system timer syscon Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-12 16:19 ` Guenter Roeck 2015-03-12 16:19 ` Guenter Roeck 2015-03-12 12:07 ` [PATCH v5 04/10] watchdog: at91rm9200: implement restart handler Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-12 16:22 ` Guenter Roeck 2015-03-12 16:22 ` Guenter Roeck 2015-03-12 12:07 ` [PATCH v5 05/10] ARM: at91: at91rm9200: remove deprecated arm_pm_restart Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 06/10] ARM: at91: properly initialize timer Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 07/10] ARM: at91: time: move the system timer driver to drivers/clocksource Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-13 10:14 ` Daniel Lezcano 2015-03-13 10:14 ` Daniel Lezcano 2015-03-13 10:14 ` Daniel Lezcano 2015-03-12 12:07 ` Alexandre Belloni [this message] 2015-03-12 12:07 ` [PATCH v5 08/10] clocksource: atmel-st: use syscon/regmap Alexandre Belloni 2015-03-13 10:17 ` Daniel Lezcano 2015-03-13 10:17 ` Daniel Lezcano 2015-03-13 10:17 ` Daniel Lezcano 2015-03-12 12:07 ` [PATCH v5 09/10] clocksource: atmel-st: remove mach/hardware dependency Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-13 10:21 ` Daniel Lezcano 2015-03-13 10:21 ` Daniel Lezcano 2015-03-13 10:21 ` Daniel Lezcano 2015-03-13 10:44 ` Alexandre Belloni 2015-03-13 10:44 ` Alexandre Belloni 2015-03-13 10:54 ` [PATCH v6 " Alexandre Belloni 2015-03-13 10:54 ` Alexandre Belloni 2015-03-12 12:07 ` [PATCH v5 10/10] ARM: at91: remove useless include Alexandre Belloni 2015-03-12 12:07 ` Alexandre Belloni 2015-03-13 10:22 ` Daniel Lezcano 2015-03-13 10:22 ` Daniel Lezcano 2015-03-13 10:22 ` Daniel Lezcano 2015-03-12 14:04 ` [PATCH v5 00/10] Atmel System Timer cleanups Nicolas Ferre 2015-03-12 14:04 ` Nicolas Ferre 2015-03-12 14:04 ` Nicolas Ferre 2015-03-13 10:23 ` Daniel Lezcano 2015-03-13 10:23 ` Daniel Lezcano 2015-03-13 10:23 ` Daniel Lezcano 2015-03-13 10:33 ` Alexandre Belloni 2015-03-13 10:33 ` Alexandre Belloni 2015-03-13 10:33 ` Daniel Lezcano 2015-03-13 10:33 ` Daniel Lezcano 2015-03-13 10:33 ` Daniel Lezcano 2015-03-13 16:36 ` Nicolas Ferre 2015-03-13 16:36 ` Nicolas Ferre 2015-03-13 16:36 ` Nicolas Ferre
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1426162054-9987-9-git-send-email-alexandre.belloni@free-electrons.com \ --to=alexandre.belloni@free-electrons.com \ --cc=boris.brezillon@free-electrons.com \ --cc=daniel.lezcano@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-watchdog@vger.kernel.org \ --cc=linux@roeck-us.net \ --cc=nicolas.ferre@atmel.com \ --cc=plagnioj@jcrosoft.com \ --cc=wim@iguana.be \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.