From patchwork Wed Oct 18 12:58:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 10014653 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 64BFE60215 for ; Wed, 18 Oct 2017 13:00:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F7C728B3C for ; Wed, 18 Oct 2017 13:00:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4281C28B40; Wed, 18 Oct 2017 13:00:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B163228B3C for ; Wed, 18 Oct 2017 13:00:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=3zSdruZvxZMuaNXHa8AZNYh5FMQ8M+Zf+OtzjhEHhaI=; b=nAYntKKkzHF8hhjcCyR5I4qu8N h7gEbliQ5vTmsylCCkVFWZ3F4o6of0+gi9NmM7/pMmm+yjGurmQE3pxlr4C8+w8LvhnfVBDl4Ag/q CrvmKT9FoUCUT7T4AOXICyRFOcW060vLnUOCO8w2YKsNhbunFgJBjtxvc4VHh0NjEejqFRUD7fP/D 4un8OSb8L0XSAnDSa12hgYYHvve0Fg8XTdHboFf57dwOdXAr6nS8Sg4t0+Y9a/17nM2uV24EeQAX5 msMwPsEGBK6tPQI70UeqtZ97b1c5N108fuw+ziooSRas7SL1PqPy/+g6Gur+55W/+/AUlXwYC+sc6 VIraKVYw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e4nx8-0006ae-Jv; Wed, 18 Oct 2017 13:00:06 +0000 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e4nw4-0005SI-Gw for linux-arm-kernel@lists.infradead.org; Wed, 18 Oct 2017 12:59:08 +0000 Received: by mail-wr0-x241.google.com with SMTP id y44so4923086wry.10 for ; Wed, 18 Oct 2017 05:58:40 -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=dz0D++f5CTxWW+vKs5vINIqQ5xCBJX7Tlg618+Xjh+8=; b=jpb0nWAMxBtnn7P4UjtnE9Mc+sP1S8AVvd0hzJxjg0W7LI4MvyJLoeSi2xJeCxYxZ5 4EkyL2BYFtQpjn8YbYAHJ+UTpkA5T1mQjxeRN2xbefWWRkFzjd7dc5XZqc0E93qdmPl0 a9z4SsDp7DbwEHGZQ7JykvEFKrUH02AceXsLI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dz0D++f5CTxWW+vKs5vINIqQ5xCBJX7Tlg618+Xjh+8=; b=Du6QPFaSCHPAqx7EN+we4XscxTOo80WDmuk2DzjhUczI/AZYJCylYxxbJd0lRWgXyu QGGvfXPHhHr5Um6Hc1/0fnQB7UI7BByfgYY3o/Y7IsIaODsl+0GL2S9ZTw4egsghQ6hX PXQkk1G9B7KtXnBB9KOQJ51Uh6TP+b6PUZAjmpHspwef4gPtQ3FkKjCbC4epX4ycrpGd NOj7C/IfKK1IZG6VLI0kO7XcHAy66WExD7xIBhwVGDtAQV9dFNVr4vaP2ydyazw0HJDA l0m/pBZrYlFsRaA2x3J1kX19oVrw1zGxKGrYgvXQ14FnSc3wYmsGv8twL847U8R7dE5r erdQ== X-Gm-Message-State: AMCzsaXiR9DGTOZ6SFh+qY9FSqp1QOHAhMVtCiYSYm7vMi6mMqmA5NiD YOBVQelVcRtjR6xcrjwy+FsPxw== X-Google-Smtp-Source: ABhQp+TctQGmSosa0XDtPZTOBXXmvgWLtqZHpSIPrW9W359aVC53jYoSzSK8hixgRI05u7MZcXAvdg== X-Received: by 10.223.154.180 with SMTP id a49mr1463040wrc.96.1508331519087; Wed, 18 Oct 2017 05:58:39 -0700 (PDT) Received: from lmecxl0911.lme.st.com ([80.215.70.168]) by smtp.gmail.com with ESMTPSA id m23sm14169908wrm.75.2017.10.18.05.58.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 18 Oct 2017 05:58:38 -0700 (PDT) From: Benjamin Gaignard To: robh+dt@kernel.org, mark.rutland@arm.com, linux@armlinux.org.uk, mcoquelin.stm32@gmail.com, alexandre.torgue@st.com, daniel.lezcano@linaro.org, tglx@linutronix.de, ludovic.barre@st.com, julien.thierry@arm.com Subject: [PATCH v6 2/5] clocksource: stm32: convert driver to timer_of Date: Wed, 18 Oct 2017 14:58:23 +0200 Message-Id: <1508331506-23782-3-git-send-email-benjamin.gaignard@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508331506-23782-1-git-send-email-benjamin.gaignard@linaro.org> References: <1508331506-23782-1-git-send-email-benjamin.gaignard@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171018_055901_125269_4239E8A8 X-CRM114-Status: GOOD ( 18.20 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Benjamin Gaignard , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.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-Virus-Scanned: ClamAV using ClamSMTP Convert driver to use timer_of helpers. This allow to remove custom proprietary structure. Increase min delta value because if it is too small it could generate too much interrupts and the system will not be able to catch them all. Signed-off-by: Benjamin Gaignard --- drivers/clocksource/Kconfig | 1 + drivers/clocksource/timer-stm32.c | 160 ++++++++++++++------------------------ 2 files changed, 58 insertions(+), 103 deletions(-) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc60620..755c0cc 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -289,6 +289,7 @@ config CLKSRC_STM32 bool "Clocksource for STM32 SoCs" if !ARCH_STM32 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST) select CLKSRC_MMIO + select TIMER_OF config CLKSRC_MPS2 bool "Clocksource for MPS2 SoCs" if COMPILE_TEST diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index 8f24237..67dcf48 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c @@ -17,6 +17,8 @@ #include #include +#include "timer-of.h" + #define TIM_CR1 0x00 #define TIM_DIER 0x0c #define TIM_SR 0x10 @@ -34,117 +36,84 @@ #define TIM_EGR_UG BIT(0) -struct stm32_clock_event_ddata { - struct clock_event_device evtdev; - unsigned periodic_top; - void __iomem *base; -}; - -static int stm32_clock_event_shutdown(struct clock_event_device *evtdev) +static int stm32_clock_event_shutdown(struct clock_event_device *evt) { - struct stm32_clock_event_ddata *data = - container_of(evtdev, struct stm32_clock_event_ddata, evtdev); - void *base = data->base; + struct timer_of *to = to_timer_of(evt); - writel_relaxed(0, base + TIM_CR1); + writel_relaxed(0, timer_of_base(to) + TIM_CR1); return 0; } -static int stm32_clock_event_set_periodic(struct clock_event_device *evtdev) +static int stm32_clock_event_set_periodic(struct clock_event_device *evt) { - struct stm32_clock_event_ddata *data = - container_of(evtdev, struct stm32_clock_event_ddata, evtdev); - void *base = data->base; + struct timer_of *to = to_timer_of(evt); + + writel_relaxed(timer_of_period(to), timer_of_base(to) + TIM_ARR); + writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1); - writel_relaxed(data->periodic_top, base + TIM_ARR); - writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1); return 0; } static int stm32_clock_event_set_next_event(unsigned long evt, - struct clock_event_device *evtdev) + struct clock_event_device *clkevt) { - struct stm32_clock_event_ddata *data = - container_of(evtdev, struct stm32_clock_event_ddata, evtdev); + struct timer_of *to = to_timer_of(clkevt); - writel_relaxed(evt, data->base + TIM_ARR); + writel_relaxed(evt, timer_of_base(to) + TIM_ARR); writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN, - data->base + TIM_CR1); + timer_of_base(to) + TIM_CR1); return 0; } static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id) { - struct stm32_clock_event_ddata *data = dev_id; + struct clock_event_device *evt = (struct clock_event_device *)dev_id; + struct timer_of *to = to_timer_of(evt); - writel_relaxed(0, data->base + TIM_SR); + writel_relaxed(0, timer_of_base(to) + TIM_SR); - data->evtdev.event_handler(&data->evtdev); + evt->event_handler(evt); return IRQ_HANDLED; } -static struct stm32_clock_event_ddata clock_event_ddata = { - .evtdev = { - .name = "stm32 clockevent", - .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, - .set_state_shutdown = stm32_clock_event_shutdown, - .set_state_periodic = stm32_clock_event_set_periodic, - .set_state_oneshot = stm32_clock_event_shutdown, - .tick_resume = stm32_clock_event_shutdown, - .set_next_event = stm32_clock_event_set_next_event, - .rating = 200, - }, -}; - -static int __init stm32_clockevent_init(struct device_node *np) +static int __init stm32_clockevent_init(struct device_node *node) { - struct stm32_clock_event_ddata *data = &clock_event_ddata; - struct clk *clk; struct reset_control *rstc; - unsigned long rate, max_delta; - int irq, ret, bits, prescaler = 1; - - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - pr_err("failed to get clock for clockevent (%d)\n", ret); - goto err_clk_get; - } - - ret = clk_prepare_enable(clk); - if (ret) { - pr_err("failed to enable timer clock for clockevent (%d)\n", - ret); - goto err_clk_enable; - } - - rate = clk_get_rate(clk); - - rstc = of_reset_control_get(np, NULL); + unsigned long max_delta; + int ret, bits, prescaler = 1; + struct timer_of *to; + + to = kzalloc(sizeof(*to), GFP_KERNEL); + if (!to) + return -ENOMEM; + + to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE; + to->clkevt.name = "stm32_clockevent"; + to->clkevt.rating = 200; + to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC; + to->clkevt.set_state_shutdown = stm32_clock_event_shutdown; + to->clkevt.set_state_periodic = stm32_clock_event_set_periodic; + to->clkevt.set_state_oneshot = stm32_clock_event_shutdown; + to->clkevt.tick_resume = stm32_clock_event_shutdown; + to->clkevt.set_next_event = stm32_clock_event_set_next_event; + + to->of_irq.handler = stm32_clock_event_handler; + + ret = timer_of_init(node, to); + if (ret) + goto err; + + rstc = of_reset_control_get(node, NULL); if (!IS_ERR(rstc)) { reset_control_assert(rstc); reset_control_deassert(rstc); } - data->base = of_iomap(np, 0); - if (!data->base) { - ret = -ENXIO; - pr_err("failed to map registers for clockevent\n"); - goto err_iomap; - } - - irq = irq_of_parse_and_map(np, 0); - if (!irq) { - ret = -EINVAL; - pr_err("%pOF: failed to get irq.\n", np); - goto err_get_irq; - } - /* Detect whether the timer is 16 or 32 bits */ - writel_relaxed(~0U, data->base + TIM_ARR); - max_delta = readl_relaxed(data->base + TIM_ARR); + writel_relaxed(~0U, timer_of_base(to) + TIM_ARR); + max_delta = readl_relaxed(timer_of_base(to) + TIM_ARR); if (max_delta == ~0U) { prescaler = 1; bits = 32; @@ -152,38 +121,23 @@ static int __init stm32_clockevent_init(struct device_node *np) prescaler = 1024; bits = 16; } - writel_relaxed(0, data->base + TIM_ARR); - - writel_relaxed(prescaler - 1, data->base + TIM_PSC); - writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR); - writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER); - writel_relaxed(0, data->base + TIM_SR); + writel_relaxed(0, timer_of_base(to) + TIM_ARR); - data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ); + writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC); + writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR); + writel_relaxed(TIM_DIER_UIE, timer_of_base(to) + TIM_DIER); + writel_relaxed(0, timer_of_base(to) + TIM_SR); - clockevents_config_and_register(&data->evtdev, - DIV_ROUND_CLOSEST(rate, prescaler), - 0x1, max_delta); - - ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER, - "stm32 clockevent", data); - if (ret) { - pr_err("%pOF: failed to request irq.\n", np); - goto err_get_irq; - } + clockevents_config_and_register(&to->clkevt, + timer_of_period(to), 0x60, max_delta); pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n", - np, bits); + node, bits); - return ret; + return 0; -err_get_irq: - iounmap(data->base); -err_iomap: - clk_disable_unprepare(clk); -err_clk_enable: - clk_put(clk); -err_clk_get: +err: + kfree(to); return ret; }