From patchwork Tue Jun 6 12:44:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 103159 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp1398850qgd; Tue, 6 Jun 2017 05:44:39 -0700 (PDT) X-Received: by 10.98.36.72 with SMTP id r69mr19342141pfj.86.1496753079530; Tue, 06 Jun 2017 05:44:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496753079; cv=none; d=google.com; s=arc-20160816; b=jz6HVoaGVPtb3dZ5LbggiblYdzjpjaLlsljmF8bzvmuR1M20jrSlsXWIKWdMgt22LL +/jGTsPwxPOgzqDVcZj2LI6+PRJH9zb026uaP8u2yv0FQvsy8OfeNoqXQ9tlzuZW4fPC yUtGPqTr/xYpqhY+2FkrKI/byaB5l15jyy0jhNlBhEJKOrBzypkh5JfYPD/BbemjVpIm kogdYAueRz08XMulOO5BPxnesl0v3jfi4JtmuL3uq6jpmEpYVB2EL7qzlb3eDnHBDywY uH5HF/pJAPrqtePOnWjnBmMXjo+5N5NRKLp6k6uuPH1fyoeJFSvEmqCOVyrU66n6b1Ds Ldcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=IFxoaK/Yo+GxT+ttfNK+jYrxqYTC99oaKr52zByheqo=; b=Cl1kxTek0OlMibqkKsPXzEu2QQMOCsUyhvR6Ya5LipWHvKjxNX97xhVpfQNSD4uIa+ H8kl6Z1fU+YwvQe1sTplOo95Enogs9hPLgqh3+cSNUyIrZyGPDGk4otSF9qUBCSOKv98 CjtbIPC//6x06htipjHq60+dfUhfacnGTn4osvAAmP5Hz1kNgpA6paCMGJ1xKH0BDGuS BIvRBUgSlAPpM+2qNmOP5BmTYNRk/dIMK04S9kxtrVKTGVItRPzy1h6ERohgo/IzAVuS p3PL6R0tPXkj+gADe6cGP2x2uuBoZuSZ+rmzef/26YbxAH4zhE6h5FlAG+qj75OApT9x wZ7w== ARC-Authentication-Results: i=1; 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 sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y62si2885312pff.159.2017.06.06.05.44.39; Tue, 06 Jun 2017 05:44:39 -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 sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751492AbdFFMo3 (ORCPT + 25 others); Tue, 6 Jun 2017 08:44:29 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:36085 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751305AbdFFMo2 (ORCPT ); Tue, 6 Jun 2017 08:44:28 -0400 Received: by mail-wm0-f44.google.com with SMTP id 7so96705540wmo.1 for ; Tue, 06 Jun 2017 05:44:27 -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; bh=IFxoaK/Yo+GxT+ttfNK+jYrxqYTC99oaKr52zByheqo=; b=R+Czt7YTyGCufyRvB4FWIBNp8fKBPJihR7hPVRb17eCeiH7tBIJyBWNRteSXxBgNsT /WytyEF1Iw2WYa3W3TmnbmDdrrXGFD2Ifjr67SV69N9VNLsNefh5FdJCz6iK+1OLtYLe k05FOk7DNVrJKHdezcccj174D6Lf6gNtjXniU= 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; bh=IFxoaK/Yo+GxT+ttfNK+jYrxqYTC99oaKr52zByheqo=; b=XtHL1mUo1PZd43yg6ulz7XbF6Vpc4IuQFzBPjrkGVsXT8LCCfLSCSPmnJ2JBBtuKue aQGzIaDwNckYdpDlVj5U/RZ62s/CMs+rH8wCMiTZy3xPg3KMc2oQ/Kn/TpniNn8VRdzt ouyvfe+UPYjxvaRVXYaaKvrrZ5xUXHT1q23Tb6zuys2URu47miuqP0z4AOSstw5KXirz 6wiT+Q4KFgXnWfx9Ws1EuHaryl3eShacqpXh+9JUMD7GENrFxE3BU6HzQH78F6e1umJX FKLofvTLBifB9Am6bFmpEFZvHMsDpT5m+kqOhpeSAQsten7WyMNWmFI8GReIPMg3iYvZ Zz2w== X-Gm-Message-State: AODbwcBnzVJZuesf0KhnNTA5uVGQPPifCkMsxXzTuD6/4fhHNMlLf7XM a56bD/dRp4fHmlXo X-Received: by 10.28.27.76 with SMTP id b73mr9078183wmb.120.1496753066376; Tue, 06 Jun 2017 05:44:26 -0700 (PDT) Received: from localhost.localdomain ([2001:41d0:fe90:b800:3f16:bcf7:601c:a13b]) by smtp.gmail.com with ESMTPSA id w17sm6277827wra.34.2017.06.06.05.44.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Jun 2017 05:44:25 -0700 (PDT) From: Daniel Lezcano To: tglx@linutronix.de Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] clocksource/drivers: Add timer-of common init routine Date: Tue, 6 Jun 2017 14:44:11 +0200 Message-Id: <1496753054-7489-1-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The different drivers are all using the same pattern when initializing. 1. Get the base address 2. Get the irq number 3. Get the clock 4. Prepare and enable the clock 5. Get the rate 6. Request an interrupt Instead of repeating again and again these steps in all the drivers, let's provide a common init routine to give the opportunity to factor all of them out. We can expect a significant kernel size improvement when the common routine will be used in all the drivers. Signed-off-by: Daniel Lezcano --- drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-of.c | 168 +++++++++++++++++++++++++++++++++++++++++ drivers/clocksource/timer-of.h | 67 ++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 drivers/clocksource/timer-of.c create mode 100644 drivers/clocksource/timer-of.h -- 2.7.4 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index ec55921..72bfd00 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_TIMER_OF) += timer-of.o obj-$(CONFIG_TIMER_PROBE) += timer-probe.o obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c new file mode 100644 index 0000000..f25dc72 --- /dev/null +++ b/drivers/clocksource/timer-of.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2017, Linaro Ltd. All rights reserved. + * + * Author: Daniel Lezcano + * + * 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 . + */ +#include +#include +#include +#include +#include +#include + +#include "timer-of.h" + +static __init void timer_irq_exit(struct of_timer_irq *of_irq) +{ + struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); + + struct clock_event_device *clkevt = &to->clkevt; + + of_irq->percpu ? free_percpu_irq(of_irq->irq, clkevt) : + free_irq(of_irq->irq, clkevt); +} + +static __init int timer_irq_init(struct device_node *np, + struct of_timer_irq *of_irq) +{ + int ret; + struct timer_of *to = container_of(of_irq, struct timer_of, of_irq); + struct clock_event_device *clkevt = &to->clkevt; + + of_irq->irq = of_irq->name ? of_irq_get_byname(np, of_irq->name): + irq_of_parse_and_map(np, of_irq->index); + if (!of_irq->irq) { + pr_err("Failed to map interrupt for %s\n", np->full_name); + return -EINVAL; + } + + ret = of_irq->percpu ? + request_percpu_irq(of_irq->irq, of_irq->handler, + np->full_name, clkevt) : + request_irq(of_irq->irq, of_irq->handler, IRQF_TIMER, + np->full_name, clkevt); + if (ret) { + pr_err("Failed to request irq %d for %s\n", of_irq->irq, + np->full_name); + return ret; + } + + clkevt->irq = of_irq->irq; + + return 0; +} + +static __init void timer_clk_exit(struct of_timer_clk *of_clk) +{ + of_clk->rate = 0; + clk_disable_unprepare(of_clk->clk); + clk_put(of_clk->clk); +} + +static __init int timer_clk_init(struct device_node *np, + struct of_timer_clk *of_clk) +{ + int ret; + + of_clk->clk = of_clk->name ? of_clk_get_by_name(np, of_clk->name) : + of_clk_get(np, of_clk->index); + if (IS_ERR(of_clk->clk)) { + pr_err("Failed to get clock for %s\n", np->full_name); + return PTR_ERR(of_clk->clk); + } + + ret = clk_prepare_enable(of_clk->clk); + if (ret) { + pr_err("Failed for enable clock for %s\n", np->full_name); + goto out_clk_put; + } + + of_clk->rate = clk_get_rate(of_clk->clk); + if (!of_clk->rate) { + ret = -EINVAL; + pr_err("Failed to get clock rate for %s\n", np->full_name); + goto out_clk_disable; + } + + of_clk->period = DIV_ROUND_UP(of_clk->rate, HZ); +out: + return ret; + +out_clk_disable: + clk_disable_unprepare(of_clk->clk); +out_clk_put: + clk_put(of_clk->clk); + + goto out; +} + +static __init void timer_base_exit(struct of_timer_base *of_base) +{ + iounmap(of_base->base); +} + +static __init int timer_base_init(struct device_node *np, + struct of_timer_base *of_base) +{ + const char *name = of_base->name ? of_base->name : np->full_name; + + of_base->base = of_io_request_and_map(np, of_base->index, name); + if (of_base->base) { + pr_err("Failed to iomap (%s)\n", name); + return -ENXIO; + } + + return 0; +} + +int __init timer_of_init(struct device_node *np, struct timer_of *to) +{ + int ret; + int flags = 0; + + if (to->flags & TIMER_OF_BASE) { + ret = timer_base_init(np, &to->of_base); + if (ret) + goto out_fail; + flags |= TIMER_OF_BASE; + } + + if (to->flags & TIMER_OF_CLOCK) { + ret = timer_clk_init(np, &to->of_clk); + if (ret) + goto out_fail; + flags |= TIMER_OF_CLOCK; + } + + if (to->flags & TIMER_OF_IRQ) { + ret = timer_irq_init(np, &to->of_irq); + if (ret) + goto out_fail; + flags |= TIMER_OF_IRQ; + } +out: + return ret; + +out_fail: + if (flags & TIMER_OF_IRQ) + timer_irq_exit(&to->of_irq); + + if (flags & TIMER_OF_CLOCK) + timer_clk_exit(&to->of_clk); + + if (flags & TIMER_OF_BASE) + timer_base_exit(&to->of_base); + goto out; +} diff --git a/drivers/clocksource/timer-of.h b/drivers/clocksource/timer-of.h new file mode 100644 index 0000000..70b55aee --- /dev/null +++ b/drivers/clocksource/timer-of.h @@ -0,0 +1,67 @@ +#ifndef __TIMER_OF_H__ +#define __TIMER_OF_H__ + +#include + +#define TIMER_OF_BASE 0x1 +#define TIMER_OF_CLOCK 0x2 +#define TIMER_OF_IRQ 0x4 + +struct of_timer_irq { + int irq; + int index; + int percpu; + const char *name; + irq_handler_t handler; +}; + +struct of_timer_base { + void __iomem *base; + const char *name; + int index; +}; + +struct of_timer_clk { + struct clk *clk; + const char *name; + int index; + unsigned long rate; + unsigned long period; +}; + +struct timer_of { + unsigned int flags; + struct clock_event_device clkevt; + struct of_timer_base of_base; + struct of_timer_irq of_irq; + struct of_timer_clk of_clk; +}; + +static inline struct timer_of *to_timer_of(struct clock_event_device *clkevt) +{ + return container_of(clkevt, struct timer_of, clkevt); +} + +static inline void __iomem *timer_of_base(struct timer_of *to) +{ + return to->of_base.base; +} + +static inline int timer_of_irq(struct timer_of *to) +{ + return to->of_irq.irq; +} + +static inline unsigned long timer_of_rate(struct timer_of *to) +{ + return to->of_clk.rate; +} + +static inline unsigned long timer_of_period(struct timer_of *to) +{ + return to->of_clk.period; +} + +extern int __init timer_of_init(struct device_node *np, + struct timer_of *to); +#endif From patchwork Tue Jun 6 12:44:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 103160 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp1398857qgd; Tue, 6 Jun 2017 05:44:40 -0700 (PDT) X-Received: by 10.84.133.132 with SMTP id f4mr20906988plf.94.1496753079979; Tue, 06 Jun 2017 05:44:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496753079; cv=none; d=google.com; s=arc-20160816; b=DGyMV+W3woEhxpZ4ehOqObTK09XmQhs1UPDGWVNvUtsOkPgWF0REybdHgkhmLi4rhj NXLpFg08DPENb8sSD6y0TLHTH2fII9Jct5JqRvwhRwjbFZhzpl592IcA16yjN+ws7Lea qbclOoJESwGIaETppD5+0FBfvYtd8/3KlMORkV3poRDv1qFpSLyVMmEO/tMIknMWpq9y H7gbnGjQ9b1DsE5KPrNAGK1600AWP4joL6vFHoJJgqoorJGTCOyoVC22pFKqlLM6nXFB 2eZV4BLgmYRl9ujLvEMUxAoMKnQZz0SmhMsWzXiDEQgRo9zz3C40aQmz4LA3S1CMVXMr y2FA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=lFGaAGzZYzKbX5d1R1FHW0G3UYMy2E11PyIUW1V1gAQ=; b=yi69n3vJFKE2ohHewtY+G/G5hAuDUeXa4zTB3mIr7DfVVrIX3DvAfR4Z5SdeT3k2uD UkY75w8eSGq9Yv5u6Br11E4UhFxW8zpuAe8zzDeqYm+bsIIq6huTm3ghpktnh2oAmbMM 67dWHJsPYW7an4T2J/CfHtBBOgsOwgxoLSE25+rD1xFignFh0UkjwCdj7/9sCYUZfYlj 4L/ljv4OJWV4utAZ4owBoOkkTqEPc9MCGL5DoKmnRxKgv/yAL3urxB9e/X7q5G5U+Caz 5PvbaJuY/VCQi4MgbLS/CK8ZQYDaYhe1JdjemmuAh2BQk8vO2cPp2qSlqj8ItUGaIzGu Xpiw== ARC-Authentication-Results: i=1; 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 sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y62si2885312pff.159.2017.06.06.05.44.39; Tue, 06 Jun 2017 05:44:39 -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 sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751552AbdFFMob (ORCPT + 25 others); Tue, 6 Jun 2017 08:44:31 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:36953 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751431AbdFFMo3 (ORCPT ); Tue, 6 Jun 2017 08:44:29 -0400 Received: by mail-wm0-f43.google.com with SMTP id d73so48026392wma.0 for ; Tue, 06 Jun 2017 05:44:28 -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=lFGaAGzZYzKbX5d1R1FHW0G3UYMy2E11PyIUW1V1gAQ=; b=K0LQ1MgP3p1ncpvLJ79bZ0MuV9IEXJac6uw7HL+eU4WoRjxruekM4nvRY6j1ONHxJC O5D4A12tpwTIwiyHSmCqoJ9Omi4oNKNvDInAe0TkiH69cU04eW9kgQG8H/mrYyhSf3N6 5lIyBkef38ifB7SuU/V0YyUSQvRScX/TYqdic= 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=lFGaAGzZYzKbX5d1R1FHW0G3UYMy2E11PyIUW1V1gAQ=; b=Ea9QK97WWCShjNVbFBXm/5o9zIYDreViH7EhENjhdmeuBhBmqWKJPynShiJbkIaqD6 ZdbxldPWXBqVWnDRtdqinwkDaR3ABY711IwMwGtcO7/ov+uJC4knkcwtUZRMkH5P3xGq +C8XKqYiy7NH2Cgkkqtr9cfmNya/ceoOAu5YPLYSkuZTYIt3SQBG3IGdEfcDl14r7m0v mF5ouBqS1qYCtYJtn75LxyZB/eJtW82mx4LEyp9rHlVIqgZ84ip4FQgAfWsIC3W8a5C6 skO6EpsIWV2SrNbfLhsBXzYLx28pXPbmaxLtV3oAjI2mJQA+ZdOG0riubv8ObpBXJgFk g5VA== X-Gm-Message-State: AODbwcBbA3KO2QFI2BD8i9dTsDCEFxfIG2sw4Bv1oi1t2kmMLDBtrq/8 ssiyB/IRKlR9KQFm X-Received: by 10.28.28.146 with SMTP id c140mr12135101wmc.122.1496753068109; Tue, 06 Jun 2017 05:44:28 -0700 (PDT) Received: from localhost.localdomain ([2001:41d0:fe90:b800:3f16:bcf7:601c:a13b]) by smtp.gmail.com with ESMTPSA id w17sm6277827wra.34.2017.06.06.05.44.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Jun 2017 05:44:27 -0700 (PDT) From: Daniel Lezcano To: tglx@linutronix.de Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Santosh Shilimkar Subject: [PATCH 2/2] clocksource/drivers/keystone: Use the timer-of common routine Date: Tue, 6 Jun 2017 14:44:12 +0200 Message-Id: <1496753054-7489-2-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1496753054-7489-1-git-send-email-daniel.lezcano@linaro.org> References: <1496753054-7489-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 The previous patch provided a common init routine for the OF drivers. The keystone driver is given as example on the improvement and usage of the common initialization routine. Signed-off-by: Daniel Lezcano --- drivers/clocksource/Kconfig | 1 + drivers/clocksource/timer-keystone.c | 117 +++++++++++++---------------------- 2 files changed, 44 insertions(+), 74 deletions(-) -- 2.7.4 diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 4ba230d..f1ed520 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -216,6 +216,7 @@ config KEYSTONE_TIMER depends on GENERIC_CLOCKEVENTS depends on ARM || ARM64 select CLKSRC_MMIO + select TIMER_OF help Enables support for the Keystone timer. diff --git a/drivers/clocksource/timer-keystone.c b/drivers/clocksource/timer-keystone.c index 0eee032..84b2523 100644 --- a/drivers/clocksource/timer-keystone.c +++ b/drivers/clocksource/timer-keystone.c @@ -18,6 +18,8 @@ #include #include +#include "timer-of.h" + #define TIMER_NAME "timer-keystone" /* Timer register offsets */ @@ -37,26 +39,16 @@ #define TGCR_TIM_UNRESET_MASK 0x03 #define INTCTLSTAT_ENINT_MASK 0x01 -/** - * struct keystone_timer: holds timer's data - * @base: timer memory base address - * @hz_period: cycles per HZ period - * @event_dev: event device based on timer - */ -static struct keystone_timer { - void __iomem *base; - unsigned long hz_period; - struct clock_event_device event_dev; -} timer; +static struct timer_of to; static inline u32 keystone_timer_readl(unsigned long rg) { - return readl_relaxed(timer.base + rg); + return readl_relaxed(timer_of_base(&to) + rg); } static inline void keystone_timer_writel(u32 val, unsigned long rg) { - writel_relaxed(val, timer.base + rg); + writel_relaxed(val, timer_of_base(&to) + rg); } /** @@ -123,6 +115,7 @@ static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id) struct clock_event_device *evt = dev_id; evt->event_handler(evt); + return IRQ_HANDLED; } @@ -140,43 +133,42 @@ static int keystone_shutdown(struct clock_event_device *evt) static int keystone_set_periodic(struct clock_event_device *evt) { - keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK); + struct timer_of *to = to_timer_of(evt); + + keystone_timer_config(timer_of_period(to), TCR_ENAMODE_PERIODIC_MASK); + return 0; } +static struct timer_of to = { + .flags = TIMER_OF_IRQ | + TIMER_OF_CLOCK | + TIMER_OF_BASE, + + .clkevt = { + .features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = keystone_set_next_event, + .set_state_shutdown = keystone_shutdown, + .set_state_periodic = keystone_set_periodic, + .set_state_oneshot = keystone_shutdown, + .cpumask = cpu_all_mask, + .owner = THIS_MODULE, + .name = TIMER_NAME, + }, + + .of_irq = { + .handler = keystone_timer_interrupt, + }, +}; + static int __init keystone_timer_init(struct device_node *np) { - struct clock_event_device *event_dev = &timer.event_dev; - unsigned long rate; - struct clk *clk; - int irq, error; - - irq = irq_of_parse_and_map(np, 0); - if (!irq) { - pr_err("%s: failed to map interrupts\n", __func__); - return -EINVAL; - } - - timer.base = of_iomap(np, 0); - if (!timer.base) { - pr_err("%s: failed to map registers\n", __func__); - return -ENXIO; - } - - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) { - pr_err("%s: failed to get clock\n", __func__); - iounmap(timer.base); - return PTR_ERR(clk); - } - - error = clk_prepare_enable(clk); - if (error) { - pr_err("%s: failed to enable clock\n", __func__); - goto err; - } - - rate = clk_get_rate(clk); + int ret; + + ret = timer_of_init(np, &to); + if (ret) + return ret; /* disable, use internal clock source */ keystone_timer_writel(0, TCR); @@ -193,38 +185,15 @@ static int __init keystone_timer_init(struct device_node *np) keystone_timer_writel(0, TIM12); keystone_timer_writel(0, TIM34); - timer.hz_period = DIV_ROUND_UP(rate, HZ); - /* enable timer interrupts */ keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT); - error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER, - TIMER_NAME, event_dev); - if (error) { - pr_err("%s: failed to setup irq\n", __func__); - goto err; - } - - /* setup clockevent */ - event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - event_dev->set_next_event = keystone_set_next_event; - event_dev->set_state_shutdown = keystone_shutdown; - event_dev->set_state_periodic = keystone_set_periodic; - event_dev->set_state_oneshot = keystone_shutdown; - event_dev->cpumask = cpu_all_mask; - event_dev->owner = THIS_MODULE; - event_dev->name = TIMER_NAME; - event_dev->irq = irq; - - clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX); - - pr_info("keystone timer clock @%lu Hz\n", rate); + clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), + 1, ULONG_MAX); + + pr_info("keystone timer clock @%lu Hz\n", timer_of_rate(&to)); + return 0; -err: - clk_put(clk); - iounmap(timer.base); - return error; } -TIMER_OF_DECLARE(keystone_timer, "ti,keystone-timer", - keystone_timer_init); +TIMER_OF_DECLARE(keystone_timer, "ti,keystone-timer", keystone_timer_init);