From: Daniel Lezcano <daniel.lezcano@linaro.org> To: daniel.lezcano@linaro.org, tglx@linutronix.de Cc: linux-kernel@vger.kernel.org, Neil Armstrong <narmstrong@baylibre.com>, Ma Haijun <mahaijuns@gmail.com>, linux-arm-kernel@lists.infradead.org Subject: [PATCH 09/92] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer Date: Tue, 28 Jun 2016 12:30:28 +0200 [thread overview] Message-ID: <1467109911-11060-9-git-send-email-daniel.lezcano@linaro.org> (raw) In-Reply-To: <1467109911-11060-1-git-send-email-daniel.lezcano@linaro.org> From: Neil Armstrong <narmstrong@baylibre.com> Add clocksource and clockevent driver from dual RPS timer. The HW provides a dual one-shot or periodic 24bit timers, the drivers set the first one as tick event source and the second as a continuous scheduler clock source. The timer can use 1, 16 or 256 as pre-dividers, thus the clocksource uses 16 by default. CC: Ma Haijun <mahaijuns@gmail.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> --- drivers/clocksource/Kconfig | 8 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-oxnas-rps.c | 290 ++++++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 drivers/clocksource/timer-oxnas-rps.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 6bbd3d8..d4b9e04 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -293,6 +293,14 @@ config VF_PIT_TIMER help Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. +config OXNAS_RPS_TIMER + bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST + depends on GENERIC_CLOCKEVENTS + select CLKSRC_OF + select CLKSRC_MMIO + help + This enables support for the Oxford Semiconductor OXNAS RPS timers. + config SYS_SUPPORTS_SH_CMT bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 473974f..bc66981 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o 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_ARM_ARCH_TIMER) += arm_arch_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c new file mode 100644 index 0000000..c002e99 --- /dev/null +++ b/drivers/clocksource/timer-oxnas-rps.c @@ -0,0 +1,290 @@ +/* + * drivers/clocksource/timer-oxnas-rps.c + * + * Copyright (C) 2009 Oxford Semiconductor Ltd + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/clockchips.h> +#include <linux/sched_clock.h> + +/* TIMER1 used as tick + * TIMER2 used as clocksource + */ + +/* Registers definitions */ + +#define TIMER_LOAD_REG 0x0 +#define TIMER_CURR_REG 0x4 +#define TIMER_CTRL_REG 0x8 +#define TIMER_CLRINT_REG 0xC + +#define TIMER_BITS 24 + +#define TIMER_MAX_VAL (BIT(TIMER_BITS) - 1) + +#define TIMER_PERIODIC BIT(6) +#define TIMER_ENABLE BIT(7) + +#define TIMER_DIV1 (0) +#define TIMER_DIV16 (1 << 2) +#define TIMER_DIV256 (2 << 2) + +#define TIMER1_REG_OFFSET 0 +#define TIMER2_REG_OFFSET 0x20 + +/* Clockevent & Clocksource data */ + +struct oxnas_rps_timer { + struct clock_event_device clkevent; + void __iomem *clksrc_base; + void __iomem *clkevt_base; + unsigned long timer_period; + unsigned int timer_prescaler; + struct clk *clk; + int irq; +}; + +static irqreturn_t oxnas_rps_timer_irq(int irq, void *dev_id) +{ + struct oxnas_rps_timer *rps = dev_id; + + writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); + + rps->clkevent.event_handler(&rps->clkevent); + + return IRQ_HANDLED; +} + +static void oxnas_rps_timer_config(struct oxnas_rps_timer *rps, + unsigned long period, + unsigned int periodic) +{ + uint32_t cfg = rps->timer_prescaler; + + if (period) + cfg |= TIMER_ENABLE; + + if (periodic) + cfg |= TIMER_PERIODIC; + + writel_relaxed(period, rps->clkevt_base + TIMER_LOAD_REG); + writel_relaxed(cfg, rps->clkevt_base + TIMER_CTRL_REG); +} + +static int oxnas_rps_timer_shutdown(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, 0, 0); + + return 0; +} + +static int oxnas_rps_timer_set_periodic(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, rps->timer_period, 1); + + return 0; +} + +static int oxnas_rps_timer_set_oneshot(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, rps->timer_period, 0); + + return 0; +} + +static int oxnas_rps_timer_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, delta, 0); + + return 0; +} + +static int __init oxnas_rps_clockevent_init(struct oxnas_rps_timer *rps) +{ + ulong clk_rate = clk_get_rate(rps->clk); + ulong timer_rate; + + /* Start with prescaler 1 */ + rps->timer_prescaler = TIMER_DIV1; + rps->timer_period = DIV_ROUND_UP(clk_rate, HZ); + timer_rate = clk_rate; + + if (rps->timer_period > TIMER_MAX_VAL) { + rps->timer_prescaler = TIMER_DIV16; + timer_rate = clk_rate / 16; + rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); + } + if (rps->timer_period > TIMER_MAX_VAL) { + rps->timer_prescaler = TIMER_DIV256; + timer_rate = clk_rate / 256; + rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); + } + + rps->clkevent.name = "oxnas-rps"; + rps->clkevent.features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_DYNIRQ; + rps->clkevent.tick_resume = oxnas_rps_timer_shutdown; + rps->clkevent.set_state_shutdown = oxnas_rps_timer_shutdown; + rps->clkevent.set_state_periodic = oxnas_rps_timer_set_periodic; + rps->clkevent.set_state_oneshot = oxnas_rps_timer_set_oneshot; + rps->clkevent.set_next_event = oxnas_rps_timer_next_event; + rps->clkevent.rating = 200; + rps->clkevent.cpumask = cpu_possible_mask; + rps->clkevent.irq = rps->irq; + clockevents_config_and_register(&rps->clkevent, + timer_rate, + 1, + TIMER_MAX_VAL); + + pr_info("Registered clock event rate %luHz prescaler %x period %lu\n", + clk_rate, + rps->timer_prescaler, + rps->timer_period); + + return 0; +} + +/* Clocksource */ + +static void __iomem *timer_sched_base; + +static u64 notrace oxnas_rps_read_sched_clock(void) +{ + return ~readl_relaxed(timer_sched_base); +} + +static int __init oxnas_rps_clocksource_init(struct oxnas_rps_timer *rps) +{ + ulong clk_rate = clk_get_rate(rps->clk); + int ret; + + /* use prescale 16 */ + clk_rate = clk_rate / 16; + + writel_relaxed(TIMER_MAX_VAL, rps->clksrc_base + TIMER_LOAD_REG); + writel_relaxed(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16, + rps->clksrc_base + TIMER_CTRL_REG); + + timer_sched_base = rps->clksrc_base + TIMER_CURR_REG; + sched_clock_register(oxnas_rps_read_sched_clock, + TIMER_BITS, clk_rate); + ret = clocksource_mmio_init(timer_sched_base, + "oxnas_rps_clocksource_timer", + clk_rate, 250, TIMER_BITS, + clocksource_mmio_readl_down); + if (WARN_ON(ret)) { + pr_err("can't register clocksource\n"); + return ret; + } + + pr_info("Registered clocksource rate %luHz\n", clk_rate); + + return 0; +} + +static void __init oxnas_rps_timer_init(struct device_node *np) +{ + struct oxnas_rps_timer *rps; + void __iomem *base; + int ret; + + rps = kzalloc(sizeof(*rps), GFP_KERNEL); + if (!rps) { + pr_err("Failed to allocate rps structure\n"); + return; + } + + rps->clk = of_clk_get(np, 0); + if (WARN_ON(IS_ERR(rps->clk))) + goto err_alloc; + + if (WARN_ON(clk_prepare_enable(rps->clk))) + goto err_clk; + + base = of_iomap(np, 0); + if (WARN_ON(!base)) + goto err_clk_prepare; + + rps->irq = irq_of_parse_and_map(np, 0); + if (WARN_ON(rps->irq < 0)) + goto err_iomap; + + rps->clkevt_base = base + TIMER1_REG_OFFSET; + rps->clksrc_base = base + TIMER2_REG_OFFSET; + + /* Disable timers */ + writel_relaxed(0, rps->clkevt_base + TIMER_CTRL_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_CTRL_REG); + writel_relaxed(0, rps->clkevt_base + TIMER_LOAD_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_LOAD_REG); + writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_CLRINT_REG); + + ret = request_irq(rps->irq, oxnas_rps_timer_irq, + IRQF_TIMER | IRQF_IRQPOLL, + "rps-timer", rps); + if (WARN_ON(ret)) + goto err_iomap; + + ret = oxnas_rps_clocksource_init(rps); + if (ret) + goto err_irqreq; + + ret = oxnas_rps_clockevent_init(rps); + if (ret) + goto err_irqreq; + + return; + +err_irqreq: + free_irq(rps->irq, rps); +err_iomap: + iounmap(base); +err_clk_prepare: + clk_disable_unprepare(rps->clk); +err_clk: + clk_put(rps->clk); +err_alloc: + kfree(rps); +} + +CLOCKSOURCE_OF_DECLARE(ox810se_rps, + "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init); -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: daniel.lezcano@linaro.org (Daniel Lezcano) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 09/92] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer Date: Tue, 28 Jun 2016 12:30:28 +0200 [thread overview] Message-ID: <1467109911-11060-9-git-send-email-daniel.lezcano@linaro.org> (raw) In-Reply-To: <1467109911-11060-1-git-send-email-daniel.lezcano@linaro.org> From: Neil Armstrong <narmstrong@baylibre.com> Add clocksource and clockevent driver from dual RPS timer. The HW provides a dual one-shot or periodic 24bit timers, the drivers set the first one as tick event source and the second as a continuous scheduler clock source. The timer can use 1, 16 or 256 as pre-dividers, thus the clocksource uses 16 by default. CC: Ma Haijun <mahaijuns@gmail.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> --- drivers/clocksource/Kconfig | 8 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-oxnas-rps.c | 290 ++++++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 drivers/clocksource/timer-oxnas-rps.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 6bbd3d8..d4b9e04 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -293,6 +293,14 @@ config VF_PIT_TIMER help Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. +config OXNAS_RPS_TIMER + bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST + depends on GENERIC_CLOCKEVENTS + select CLKSRC_OF + select CLKSRC_MMIO + help + This enables support for the Oxford Semiconductor OXNAS RPS timers. + config SYS_SUPPORTS_SH_CMT bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 473974f..bc66981 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o 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_ARM_ARCH_TIMER) += arm_arch_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c new file mode 100644 index 0000000..c002e99 --- /dev/null +++ b/drivers/clocksource/timer-oxnas-rps.c @@ -0,0 +1,290 @@ +/* + * drivers/clocksource/timer-oxnas-rps.c + * + * Copyright (C) 2009 Oxford Semiconductor Ltd + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/clockchips.h> +#include <linux/sched_clock.h> + +/* TIMER1 used as tick + * TIMER2 used as clocksource + */ + +/* Registers definitions */ + +#define TIMER_LOAD_REG 0x0 +#define TIMER_CURR_REG 0x4 +#define TIMER_CTRL_REG 0x8 +#define TIMER_CLRINT_REG 0xC + +#define TIMER_BITS 24 + +#define TIMER_MAX_VAL (BIT(TIMER_BITS) - 1) + +#define TIMER_PERIODIC BIT(6) +#define TIMER_ENABLE BIT(7) + +#define TIMER_DIV1 (0) +#define TIMER_DIV16 (1 << 2) +#define TIMER_DIV256 (2 << 2) + +#define TIMER1_REG_OFFSET 0 +#define TIMER2_REG_OFFSET 0x20 + +/* Clockevent & Clocksource data */ + +struct oxnas_rps_timer { + struct clock_event_device clkevent; + void __iomem *clksrc_base; + void __iomem *clkevt_base; + unsigned long timer_period; + unsigned int timer_prescaler; + struct clk *clk; + int irq; +}; + +static irqreturn_t oxnas_rps_timer_irq(int irq, void *dev_id) +{ + struct oxnas_rps_timer *rps = dev_id; + + writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); + + rps->clkevent.event_handler(&rps->clkevent); + + return IRQ_HANDLED; +} + +static void oxnas_rps_timer_config(struct oxnas_rps_timer *rps, + unsigned long period, + unsigned int periodic) +{ + uint32_t cfg = rps->timer_prescaler; + + if (period) + cfg |= TIMER_ENABLE; + + if (periodic) + cfg |= TIMER_PERIODIC; + + writel_relaxed(period, rps->clkevt_base + TIMER_LOAD_REG); + writel_relaxed(cfg, rps->clkevt_base + TIMER_CTRL_REG); +} + +static int oxnas_rps_timer_shutdown(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, 0, 0); + + return 0; +} + +static int oxnas_rps_timer_set_periodic(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, rps->timer_period, 1); + + return 0; +} + +static int oxnas_rps_timer_set_oneshot(struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, rps->timer_period, 0); + + return 0; +} + +static int oxnas_rps_timer_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + struct oxnas_rps_timer *rps = + container_of(evt, struct oxnas_rps_timer, clkevent); + + oxnas_rps_timer_config(rps, delta, 0); + + return 0; +} + +static int __init oxnas_rps_clockevent_init(struct oxnas_rps_timer *rps) +{ + ulong clk_rate = clk_get_rate(rps->clk); + ulong timer_rate; + + /* Start with prescaler 1 */ + rps->timer_prescaler = TIMER_DIV1; + rps->timer_period = DIV_ROUND_UP(clk_rate, HZ); + timer_rate = clk_rate; + + if (rps->timer_period > TIMER_MAX_VAL) { + rps->timer_prescaler = TIMER_DIV16; + timer_rate = clk_rate / 16; + rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); + } + if (rps->timer_period > TIMER_MAX_VAL) { + rps->timer_prescaler = TIMER_DIV256; + timer_rate = clk_rate / 256; + rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); + } + + rps->clkevent.name = "oxnas-rps"; + rps->clkevent.features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_DYNIRQ; + rps->clkevent.tick_resume = oxnas_rps_timer_shutdown; + rps->clkevent.set_state_shutdown = oxnas_rps_timer_shutdown; + rps->clkevent.set_state_periodic = oxnas_rps_timer_set_periodic; + rps->clkevent.set_state_oneshot = oxnas_rps_timer_set_oneshot; + rps->clkevent.set_next_event = oxnas_rps_timer_next_event; + rps->clkevent.rating = 200; + rps->clkevent.cpumask = cpu_possible_mask; + rps->clkevent.irq = rps->irq; + clockevents_config_and_register(&rps->clkevent, + timer_rate, + 1, + TIMER_MAX_VAL); + + pr_info("Registered clock event rate %luHz prescaler %x period %lu\n", + clk_rate, + rps->timer_prescaler, + rps->timer_period); + + return 0; +} + +/* Clocksource */ + +static void __iomem *timer_sched_base; + +static u64 notrace oxnas_rps_read_sched_clock(void) +{ + return ~readl_relaxed(timer_sched_base); +} + +static int __init oxnas_rps_clocksource_init(struct oxnas_rps_timer *rps) +{ + ulong clk_rate = clk_get_rate(rps->clk); + int ret; + + /* use prescale 16 */ + clk_rate = clk_rate / 16; + + writel_relaxed(TIMER_MAX_VAL, rps->clksrc_base + TIMER_LOAD_REG); + writel_relaxed(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16, + rps->clksrc_base + TIMER_CTRL_REG); + + timer_sched_base = rps->clksrc_base + TIMER_CURR_REG; + sched_clock_register(oxnas_rps_read_sched_clock, + TIMER_BITS, clk_rate); + ret = clocksource_mmio_init(timer_sched_base, + "oxnas_rps_clocksource_timer", + clk_rate, 250, TIMER_BITS, + clocksource_mmio_readl_down); + if (WARN_ON(ret)) { + pr_err("can't register clocksource\n"); + return ret; + } + + pr_info("Registered clocksource rate %luHz\n", clk_rate); + + return 0; +} + +static void __init oxnas_rps_timer_init(struct device_node *np) +{ + struct oxnas_rps_timer *rps; + void __iomem *base; + int ret; + + rps = kzalloc(sizeof(*rps), GFP_KERNEL); + if (!rps) { + pr_err("Failed to allocate rps structure\n"); + return; + } + + rps->clk = of_clk_get(np, 0); + if (WARN_ON(IS_ERR(rps->clk))) + goto err_alloc; + + if (WARN_ON(clk_prepare_enable(rps->clk))) + goto err_clk; + + base = of_iomap(np, 0); + if (WARN_ON(!base)) + goto err_clk_prepare; + + rps->irq = irq_of_parse_and_map(np, 0); + if (WARN_ON(rps->irq < 0)) + goto err_iomap; + + rps->clkevt_base = base + TIMER1_REG_OFFSET; + rps->clksrc_base = base + TIMER2_REG_OFFSET; + + /* Disable timers */ + writel_relaxed(0, rps->clkevt_base + TIMER_CTRL_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_CTRL_REG); + writel_relaxed(0, rps->clkevt_base + TIMER_LOAD_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_LOAD_REG); + writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); + writel_relaxed(0, rps->clksrc_base + TIMER_CLRINT_REG); + + ret = request_irq(rps->irq, oxnas_rps_timer_irq, + IRQF_TIMER | IRQF_IRQPOLL, + "rps-timer", rps); + if (WARN_ON(ret)) + goto err_iomap; + + ret = oxnas_rps_clocksource_init(rps); + if (ret) + goto err_irqreq; + + ret = oxnas_rps_clockevent_init(rps); + if (ret) + goto err_irqreq; + + return; + +err_irqreq: + free_irq(rps->irq, rps); +err_iomap: + iounmap(base); +err_clk_prepare: + clk_disable_unprepare(rps->clk); +err_clk: + clk_put(rps->clk); +err_alloc: + kfree(rps); +} + +CLOCKSOURCE_OF_DECLARE(ox810se_rps, + "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init); -- 1.9.1
next prev parent reply other threads:[~2016-06-28 11:01 UTC|newest] Thread overview: 153+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <577251A4.7030508@linaro.org> 2016-06-28 10:30 ` [PATCH 01/92] clocksource/drivers/armada-370-xp: Make syscore_ops static Daniel Lezcano 2016-06-28 10:30 ` [PATCH 02/92] clocksource/drivers/digicolor: Fix warning of non-static function Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 03/92] clocksource/drivers/samsung_pwm_timer: Fix endian accessors Daniel Lezcano 2016-06-28 10:30 ` [PATCH 04/92] clocksource/drivers/samsung_pwm: Fix typo in Kconfig Daniel Lezcano 2016-06-28 10:30 ` [PATCH 05/92] dt-bindings: Document rk3399 rk-timer bindings Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 06/92] clocksource/drivers/rockchip: Add the dynamic irq flag to the timer Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 07/92] clocksource/drivers/rockchip: Add support for the rk3399 SoC Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 08/92] arm64: dts: rockchip: Add rktimer device node for rk3399 Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano [this message] 2016-06-28 10:30 ` [PATCH 09/92] clocksource/drivers/oxnas-rps: Add Oxford Semiconductor RPS Dual Timer Daniel Lezcano 2016-06-28 10:30 ` [PATCH 10/92] dt-bindings: clocksource: Add Oxford Semiconductor RPS Timer bindings Daniel Lezcano 2016-06-28 10:30 ` [PATCH 11/92] of: Add a new macro to declare_of for one parameter function returning a value Daniel Lezcano 2016-06-28 10:30 ` [PATCH 12/92] clocksource/drivers/clksrc-probe: Introduce init functions with return code Daniel Lezcano 2016-06-28 10:30 ` [PATCH 13/92] clocksource/drivers/rockchip_timer: Convert init function to return error Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 14/92] clocksource/drivers/mtk_timer: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 15/92] clocksource/drivers/exynos_mct: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 16/92] clocksource/drivers/asm9260: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 17/92] clocksource/drivers/cadence_ttc: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 18/92] clocksource/drivers/st_lpc: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 19/92] clocksource/drivers/dw_apb_timer: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 20/92] clocksource/drivers/clps711x: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 21/92] clocksource/drivers/digicolor: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 22/92] clocksource/drivers/armv7m_systick: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 23/92] clocksource/drivers/bcm2835_timer: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 24/92] clocksource/drivers/bcm_kona: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 25/92] clocksource/drivers/clksrc-dbx500: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 26/92] clocksource/drivers/fsl_ftm_timer: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 27/92] clocksource/drivers/arm_arch_timer: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 28/92] clocksource/drivers/arm_global_timer: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 29/92] clocksource/drivers/h8300_timer16: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 30/92] clocksource/drivers/h8300_timer8: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 31/92] clocksource/drivers/h8300_tpu: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 32/92] clocksource/drivers/meson6_timer.c: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 33/92] clocksource/drivers/mips-gic-timer: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 34/92] clocksource/drivers/moxart: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 35/92] clocksource/drivers/mps2-timer: " Daniel Lezcano 2016-06-28 10:30 ` Daniel Lezcano 2016-06-28 10:30 ` [PATCH 36/92] clocksource/drivers/mxs: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 37/92] clocksource/drivers/nomadik-mtu: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 38/92] clocksource/drivers/pxa: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 39/92] clocksource/drivers/qcom: " Daniel Lezcano 2016-06-28 10:30 ` [PATCH 40/92] clocksource/drivers/samsung_pwm: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 41/92] clocksource/drivers/sun4i: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 42/92] clocksource/drivers/tango_xtal: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 43/92] clocksource/drivers/tegra20: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 44/92] clocksource/drivers/time-armada-370-xp: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 45/92] clocksource/drivers/time-efm32: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 46/92] clocksource/drivers/time-lpc32xx: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 47/92] clocksource/drivers/orion: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 48/92] clocksource/drivers/pistachio: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 49/92] clocksource/drivers/atlas7: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 50/92] clocksource/drivers/atmel-pit: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 51/92] clocksource/drivers/atmel-st: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 52/92] clocksource/drivers/prima2: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 53/92] clocksource/drivers/imx-gpt: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 54/92] clocksource/drivers/integrator-ap: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 55/92] clocksource/drivers/keystone: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 56/92] clocksource/drivers/sp804: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 57/92] clocksource/drivers/stm32: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 58/92] clocksource/drivers/sun5i: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 59/92] clocksource/drivers/ti-32k: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 60/92] clocksource/drivers/u300: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 61/92] clocksource/drivers/versatile: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 62/92] clocksource/drivers/vf_pit_timer: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 63/92] clocksource/drivers/vt8500: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 64/92] clocksource/drivers/zevio: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 65/92] clocksource/drivers/microblaze: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 66/92] clocksource/drivers/ralink: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 67/92] clocksource/drivers/nios2: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 68/92] clocksource/drivers/smp_twd: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 69/92] clocksource/drivers/nps: " Daniel Lezcano 2016-06-28 10:31 ` [PATCH 70/92] clocksource/drivers/arc: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 71/92] clocksource/drivers/oxnas-rps: " Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano [not found] ` <1467109911-11060-1-git-send-email-daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> 2016-06-28 10:31 ` [PATCH 72/92] clocksources: Switch back to the clksrc table Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:31 ` [PATCH 73/92] clk: Add missing clk_get_sys() stub Daniel Lezcano 2016-06-28 10:31 ` [PATCH 74/92] clocksource/drivers/bcm_kona: Remove useless header <asm/mach/time.h> Daniel Lezcano 2016-06-29 5:53 ` Ray Jui 2016-06-28 10:31 ` [PATCH 75/92] clocksource/drivers/bcm2835: Add the COMPILE_TEST option Daniel Lezcano 2016-06-28 10:31 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 76/92] clocksource/drivers/armv7m_systick: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 77/92] clocksource/drivers/bcm_kona: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 78/92] clocksource/drivers/clps_711x: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 79/92] clocksource/drivers/atlas7: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 80/92] clocksource/drivers/moxart: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 81/92] clocksource/drivers/mxs: Remove useless header <asm/mach/time.h> Daniel Lezcano 2016-06-28 10:51 ` [PATCH 82/92] clocksource/drivers/mxs: Add the COMPILE_TEST option Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 83/92] clocksource/drivers/prima2: Remove useless header <asm/mach/time.h> Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 84/92] clocksource/drivers/prima2: Add the COMPILE_TEST option Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 85/92] clocksource/drivers/u300: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 86/92] clocksource/drivers/nspire: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 87/92] clocksource/drivers/keystone: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 88/92] clocksource/drivers/integrator-ap: " Daniel Lezcano 2016-06-28 10:51 ` Daniel Lezcano 2016-06-28 10:51 ` [PATCH 89/92] clocksource/drivers/arm_global_timer: " Daniel Lezcano 2016-06-28 10:51 ` [PATCH 90/92] clocksource/drivers/timer-atmel-st: " Daniel Lezcano 2016-06-28 10:51 ` [PATCH 91/92] clocksource/drivers/versatile: " Daniel Lezcano 2016-06-28 10:51 ` [PATCH 92/92] clocksource/drivers/arm_arch_timer: Control the evtstrm via the cmdline Daniel Lezcano 2016-07-06 10:24 ` [PULL] : clockevents for 4.8 Daniel Lezcano 2016-07-06 10:44 ` Thomas Gleixner 2016-07-06 10:47 ` Thomas Gleixner 2016-07-06 13:21 ` Daniel Lezcano
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=1467109911-11060-9-git-send-email-daniel.lezcano@linaro.org \ --to=daniel.lezcano@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mahaijuns@gmail.com \ --cc=narmstrong@baylibre.com \ --cc=tglx@linutronix.de \ /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.