From patchwork Mon Sep 12 09:15:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 75974 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp751757qgf; Mon, 12 Sep 2016 02:16:20 -0700 (PDT) X-Received: by 10.66.126.131 with SMTP id my3mr31994680pab.115.1473671780529; Mon, 12 Sep 2016 02:16:20 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w8si20826193paj.25.2016.09.12.02.16.20; Mon, 12 Sep 2016 02:16:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757414AbcILJQL (ORCPT + 27 others); Mon, 12 Sep 2016 05:16:11 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:34356 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752742AbcILJQF (ORCPT ); Mon, 12 Sep 2016 05:16:05 -0400 Received: by mail-wm0-f49.google.com with SMTP id a6so2799386wmc.1 for ; Mon, 12 Sep 2016 02:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eYLI4tExrgHfdu8MHymSIlnmG4DxrGSD5mCJB4ID3AU=; b=huWg7kI/fs9tofUrljYRlffuw9JhmUEkHVa06tFXs73Cf3yFcpvuVjpz0j2cn8Io2x jXDyjGVrX9Lu04KxdmzYcLR3oG92CGasFx/WeCPgZGoqLkA6I9CzHAToDq3wIH2EWFXJ b2pwgDCXZmg8S/1z+Tq+WVXuRGdDcFScozNPk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eYLI4tExrgHfdu8MHymSIlnmG4DxrGSD5mCJB4ID3AU=; b=lq74cCb06QpatrRx5D09E1KnDQTkXust5HHmnNBoF14AbYPR7o4VLDOP0cAxLiyRtC s10O/IwvOSNrbABrbESWlCp+U8jq8rQ3X20wjvBb8dudSv/kjH0Pezw/C57+xqqOt8TN vNEahAdX2Buq3U8f2CMhK1q97mXd+TYzgO0xkudNHW6AZMCKP/Rw6SzRSgepeR5j/3ry wS2HVNC4r99VOJZEJ8b9dQimPV3Xcv8Wf3ZHExXmYPAVYKe/WN3KtT8WoBP1eZg6m7WZ r4Msn/PGzUC1h0XhdI+yifv1vrL1MbxjQgEBNmZE9QYcgjoB1WoBUhpC+VVDAZp+Ocfm U0ww== X-Gm-Message-State: AE9vXwMLZqWJNK6YrcQ5u/YUUcWcWKqq9Y3kSk0lBKCoBuxKt5KdNGAQkQezvVR+MEmSAoQa X-Received: by 10.194.29.7 with SMTP id f7mr13302160wjh.99.1473671763387; Mon, 12 Sep 2016 02:16:03 -0700 (PDT) Received: from localhost.localdomain ([2a01:e35:879a:6cd0:e089:f01a:f419:f17e]) by smtp.gmail.com with ESMTPSA id va3sm16939362wjb.18.2016.09.12.02.16.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Sep 2016 02:16:02 -0700 (PDT) From: Daniel Lezcano To: tglx@linutronix.de Cc: mingo@kernel.org, linux-kernel@vger.kernel.org, Joel Stanley Subject: [PATCH 2/9] clocksource/drivers/moxart: Use struct to hold state Date: Mon, 12 Sep 2016 11:15:40 +0200 Message-Id: <1473671747-9400-2-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1473671747-9400-1-git-send-email-daniel.lezcano@linaro.org> References: <1473671747-9400-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joel Stanley Add a struct moxart_timer to hold the driver state, including the irqaction and struct clock_event_device. Most importantly this holds values for enabling and disabling the timer, so future support can be added for devices that use different bits for enable/disable. In preparation for future hardware support we add a MOXART prefix to the existing values. Signed-off-by: Joel Stanley Signed-off-by: Daniel Lezcano --- drivers/clocksource/moxart_timer.c | 147 ++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 61 deletions(-) -- 2.7.4 diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index a3aaa56..cb0b347 100644 --- a/drivers/clocksource/moxart_timer.c +++ b/drivers/clocksource/moxart_timer.c @@ -21,6 +21,7 @@ #include #include #include +#include #define TIMER1_BASE 0x00 #define TIMER2_BASE 0x10 @@ -36,36 +37,51 @@ #define TIMER_INTR_MASK 0x38 /* - * TIMER_CR flags: + * Moxart TIMER_CR flags: * - * TIMEREG_CR_*_CLOCK 0: PCLK, 1: EXT1CLK - * TIMEREG_CR_*_INT overflow interrupt enable bit + * MOXART_CR_*_CLOCK 0: PCLK, 1: EXT1CLK + * MOXART_CR_*_INT overflow interrupt enable bit */ -#define TIMEREG_CR_1_ENABLE BIT(0) -#define TIMEREG_CR_1_CLOCK BIT(1) -#define TIMEREG_CR_1_INT BIT(2) -#define TIMEREG_CR_2_ENABLE BIT(3) -#define TIMEREG_CR_2_CLOCK BIT(4) -#define TIMEREG_CR_2_INT BIT(5) -#define TIMEREG_CR_3_ENABLE BIT(6) -#define TIMEREG_CR_3_CLOCK BIT(7) -#define TIMEREG_CR_3_INT BIT(8) -#define TIMEREG_CR_COUNT_UP BIT(9) - -#define TIMER1_ENABLE (TIMEREG_CR_2_ENABLE | TIMEREG_CR_1_ENABLE) -#define TIMER1_DISABLE (TIMEREG_CR_2_ENABLE) - -static void __iomem *base; -static unsigned int clock_count_per_tick; +#define MOXART_CR_1_ENABLE BIT(0) +#define MOXART_CR_1_CLOCK BIT(1) +#define MOXART_CR_1_INT BIT(2) +#define MOXART_CR_2_ENABLE BIT(3) +#define MOXART_CR_2_CLOCK BIT(4) +#define MOXART_CR_2_INT BIT(5) +#define MOXART_CR_3_ENABLE BIT(6) +#define MOXART_CR_3_CLOCK BIT(7) +#define MOXART_CR_3_INT BIT(8) +#define MOXART_CR_COUNT_UP BIT(9) + +#define MOXART_TIMER1_ENABLE (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE) +#define MOXART_TIMER1_DISABLE (MOXART_CR_2_ENABLE) + +struct moxart_timer { + void __iomem *base; + unsigned int t1_disable_val; + unsigned int t1_enable_val; + unsigned int count_per_tick; + struct clock_event_device clkevt; + struct irqaction act; +}; + +static inline struct moxart_timer *to_moxart(struct clock_event_device *evt) +{ + return container_of(evt, struct moxart_timer, clkevt); +} static inline void moxart_disable(struct clock_event_device *evt) { - writel(TIMER1_DISABLE, base + TIMER_CR); + struct moxart_timer *timer = to_moxart(evt); + + writel(timer->t1_disable_val, timer->base + TIMER_CR); } static inline void moxart_enable(struct clock_event_device *evt) { - writel(TIMER1_ENABLE, base + TIMER_CR); + struct moxart_timer *timer = to_moxart(evt); + + writel(timer->t1_enable_val, timer->base + TIMER_CR); } static int moxart_shutdown(struct clock_event_device *evt) @@ -77,13 +93,17 @@ static int moxart_shutdown(struct clock_event_device *evt) static int moxart_set_oneshot(struct clock_event_device *evt) { moxart_disable(evt); - writel(~0, base + TIMER1_BASE + REG_LOAD); + writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD); return 0; } static int moxart_set_periodic(struct clock_event_device *evt) { - writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD); + struct moxart_timer *timer = to_moxart(evt); + + moxart_disable(evt); + writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD); + writel(0, timer->base + TIMER1_BASE + REG_MATCH1); moxart_enable(evt); return 0; } @@ -91,30 +111,19 @@ static int moxart_set_periodic(struct clock_event_device *evt) static int moxart_clkevt_next_event(unsigned long cycles, struct clock_event_device *evt) { + struct moxart_timer *timer = to_moxart(evt); u32 u; moxart_disable(evt); - u = readl(base + TIMER1_BASE + REG_COUNT) - cycles; - writel(u, base + TIMER1_BASE + REG_MATCH1); + u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles; + writel(u, timer->base + TIMER1_BASE + REG_MATCH1); moxart_enable(evt); return 0; } -static struct clock_event_device moxart_clockevent = { - .name = "moxart_timer", - .rating = 200, - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_state_shutdown = moxart_shutdown, - .set_state_periodic = moxart_set_periodic, - .set_state_oneshot = moxart_set_oneshot, - .tick_resume = moxart_set_oneshot, - .set_next_event = moxart_clkevt_next_event, -}; - static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; @@ -122,21 +131,19 @@ static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction moxart_timer_irq = { - .name = "moxart-timer", - .flags = IRQF_TIMER, - .handler = moxart_timer_interrupt, - .dev_id = &moxart_clockevent, -}; - static int __init moxart_timer_init(struct device_node *node) { int ret, irq; unsigned long pclk; struct clk *clk; + struct moxart_timer *timer; - base = of_iomap(node, 0); - if (!base) { + timer = kzalloc(sizeof(*timer), GFP_KERNEL); + if (!timer) + return -ENOMEM; + + timer->base = of_iomap(node, 0); + if (!timer->base) { pr_err("%s: of_iomap failed\n", node->full_name); return -ENXIO; } @@ -147,12 +154,6 @@ static int __init moxart_timer_init(struct device_node *node) return -EINVAL; } - ret = setup_irq(irq, &moxart_timer_irq); - if (ret) { - pr_err("%s: setup_irq failed\n", node->full_name); - return ret; - } - clk = of_clk_get(node, 0); if (IS_ERR(clk)) { pr_err("%s: of_clk_get failed\n", node->full_name); @@ -161,7 +162,31 @@ static int __init moxart_timer_init(struct device_node *node) pclk = clk_get_rate(clk); - ret = clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT, + if (of_device_is_compatible(node, "moxa,moxart-timer")) { + timer->t1_enable_val = MOXART_TIMER1_ENABLE; + timer->t1_disable_val = MOXART_TIMER1_DISABLE; + } else + panic("%s: unknown platform\n", node->full_name); + + timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); + + timer->clkevt.name = node->name; + timer->clkevt.rating = 200; + timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT; + timer->clkevt.set_state_shutdown = moxart_shutdown; + timer->clkevt.set_state_periodic = moxart_set_periodic; + timer->clkevt.set_state_oneshot = moxart_set_oneshot; + timer->clkevt.tick_resume = moxart_set_oneshot; + timer->clkevt.set_next_event = moxart_clkevt_next_event; + timer->clkevt.cpumask = cpumask_of(0); + timer->clkevt.irq = irq; + timer->act.name = node->name; + timer->act.flags = IRQF_TIMER; + timer->act.handler = moxart_timer_interrupt; + timer->act.dev_id = &timer->clkevt; + + ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT, "moxart_timer", pclk, 200, 32, clocksource_mmio_readl_down); if (ret) { @@ -169,13 +194,14 @@ static int __init moxart_timer_init(struct device_node *node) return ret; } - clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); - - writel(~0, base + TIMER2_BASE + REG_LOAD); - writel(TIMEREG_CR_2_ENABLE, base + TIMER_CR); + ret = setup_irq(irq, &timer->act); + if (ret) { + pr_err("%s: setup_irq failed\n", node->full_name); + return ret; + } - moxart_clockevent.cpumask = cpumask_of(0); - moxart_clockevent.irq = irq; + writel(~0, timer->base + TIMER2_BASE + REG_LOAD); + writel(timer->t1_disable_val, timer->base + TIMER_CR); /* * documentation is not publicly available: @@ -183,8 +209,7 @@ static int __init moxart_timer_init(struct device_node *node) * max_delta 0xfffffffe should be ok because count * register size is u32 */ - clockevents_config_and_register(&moxart_clockevent, pclk, - 0x4, 0xfffffffe); + clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe); return 0; }