From patchwork Mon May 9 12:32:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Stanley X-Patchwork-Id: 9046131 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 98A3F9F30C for ; Mon, 9 May 2016 12:37:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 698902010E for ; Mon, 9 May 2016 12:37:08 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 43B382010B for ; Mon, 9 May 2016 12:37:07 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1azkON-0005A5-T5; Mon, 09 May 2016 12:34:31 +0000 Received: from mail-pa0-x231.google.com ([2607:f8b0:400e:c03::231]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1azkNT-0003oc-K5 for linux-arm-kernel@lists.infradead.org; Mon, 09 May 2016 12:33:53 +0000 Received: by mail-pa0-x231.google.com with SMTP id r5so74177941pag.1 for ; Mon, 09 May 2016 05:33:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jms.id.au; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=es1dXcr3eWqjzcjMotDcsHThinXwikWH128WJqVuy1Y=; b=JXwDvQSCO5WHpFcDJUPduoWkVZCJoWvGtofQkg1er3xM/CifSgFPimGIFXrcyK3GuM A/gdZ1bueH57vq78AdezdFcmDCA7XJdFchimp5pf2Uum82EPkMZSMrmMKHwLZKlQPotn hSDfUhn7WhR3HZKFT2dWMySUI+IeWb7tyGdsY= 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=es1dXcr3eWqjzcjMotDcsHThinXwikWH128WJqVuy1Y=; b=ZIaaLaVi5srApv3pAVE7gQFoAdyyDI4b9PISHJ63o0Tj44FP6S00zX8kE3ZDRYcEUk trefq//ssOc4WmeVp6QAiCWdvIzV76wcA6bjPuhWrwCu6OW9z9510ov+67jAfb8DSLR8 AyIpdOftLr+v0fI1FJ/biKsiLh9cX7DceYgAejLQhIIrV5pcMMIsvS5uUVJi3AFasD6j O3A+SSiNXh7b7DvMFDEXIJNFXwlEt6awfTm0S/uNTsp1d18YEQWbudNNjauJGuwaSsMc m03iatTkSFm/xeF5em4IMSKtLnDCiMGypmf5Jx/lYo0DS+Ullz+VNDQLdcEXEKXpjvD7 Oxeg== X-Gm-Message-State: AOPr4FU62y33ClKIu6sdoatIti4R69p1PqvgPJ0IXqc7G5GRXfFFdAlzXrwWdNgdzYqisA== X-Received: by 10.67.22.129 with SMTP id hs1mr50184058pad.105.1462797195129; Mon, 09 May 2016 05:33:15 -0700 (PDT) Received: from icarus.au.ibm.com ([2403:480:11:10:3400:b218:cbe9:48cb]) by smtp.gmail.com with ESMTPSA id e2sm34452101pfd.20.2016.05.09.05.33.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 May 2016 05:33:14 -0700 (PDT) From: Joel Stanley To: daniel.lezcano@linaro.org, tglx@linutronix.de, jonas.jensen@gmail.com Subject: [PATCH 3/4] drivers/clocksource/moxart: Use struct to hold state Date: Mon, 9 May 2016 22:02:48 +0930 Message-Id: <1462797169-14512-4-git-send-email-joel@jms.id.au> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1462797169-14512-1-git-send-email-joel@jms.id.au> References: <1462797169-14512-1-git-send-email-joel@jms.id.au> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160509_053336_093451_46DD5A73 X-CRM114-Status: GOOD ( 17.69 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, arnd@arndb.de, jk@ozlabs.org, linux-arm-kernel@lists.infradead.org, benh@kernel.crashing.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- drivers/clocksource/moxart_timer.c | 143 ++++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 59 deletions(-) diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index b00b2b21e8b3..d17e3eface87 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,49 +131,66 @@ 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 void __init moxart_timer_init(struct device_node *node) { int ret, irq; unsigned long pclk; struct clk *clk; + struct moxart_timer *timer; + + timer = kzalloc(sizeof(*timer), GFP_KERNEL); + if (!timer) + panic("Can't allocate timer struct\n"); - base = of_iomap(node, 0); - if (!base) + timer->base = of_iomap(node, 0); + if (!timer->base) panic("%s: of_iomap failed\n", node->full_name); irq = irq_of_parse_and_map(node, 0); if (irq <= 0) panic("%s: irq_of_parse_and_map failed\n", node->full_name); - ret = setup_irq(irq, &moxart_timer_irq); - if (ret) - panic("%s: setup_irq failed\n", node->full_name); - clk = of_clk_get(node, 0); if (IS_ERR(clk)) panic("%s: of_clk_get failed\n", node->full_name); pclk = clk_get_rate(clk); - if (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; + + if (clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT, "moxart_timer", pclk, 200, 32, clocksource_mmio_readl_down)) panic("%s: clocksource_mmio_init failed\n", node->full_name); - 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) + panic("%s: setup_irq failed\n", node->full_name); - 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: @@ -172,7 +198,6 @@ static void __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); } CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);