From patchwork Tue Mar 12 17:08:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 2257441 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 5A1B43FCF6 for ; Tue, 12 Mar 2013 17:14:53 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UFShq-00054B-Nz; Tue, 12 Mar 2013 17:09:42 +0000 Received: from mail-ie0-x22d.google.com ([2607:f8b0:4001:c03::22d]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UFShE-0004uQ-EZ for linux-arm-kernel@lists.infradead.org; Tue, 12 Mar 2013 17:09:07 +0000 Received: by mail-ie0-f173.google.com with SMTP id 9so104244iec.18 for ; Tue, 12 Mar 2013 10:09:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=FcKhuh3jNbXiQOA2qFMrhxIwOAA4uNQXH72GK6oDay0=; b=DeRx1sR8c/WDoOTaFN97DrbnwEakwkJiF6WYqMVWcHF4nRuUflcDr7vj+P5sj1JuX/ rGpTv4ZUyMNjv5zDe2Oq2O/5A3nIL5qMTjbaxGF8zNPlINgg6A05gdatv/C361/Zjl+V UNh1h44e+K0JumHAltwP/6TrwgEG6g5kNV1d6CASZDTulM4Lv/RCwUyge++6H82oODZY xtGj2ZSGdZjoE9xxrKdMxFhySJnzhaa33H2MC0BcIGj99bjN0gPsFZtIFnunvWmyzyhZ 2cJTKdhr4JtCwRLO56J67ac5xNAKkzOeBMLltFxkqZQ5eeUCKCufU3kjeVt/nu/bnjrI RZ0A== X-Received: by 10.43.118.2 with SMTP id fo2mr12968006icc.41.1363108143567; Tue, 12 Mar 2013 10:09:03 -0700 (PDT) Received: from localhost.localdomain ([140.206.155.72]) by mx.google.com with ESMTPS id xc3sm20593825igb.10.2013.03.12.10.08.59 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Mar 2013 10:09:03 -0700 (PDT) From: Haojian Zhuang To: linux@arm.linux.org.uk, linus.walleij@linaro.org, arnd@arndb.de, olof@lixom.net, rob.herring@calxeda.com, linux-arm-kernel@lists.infradead.org, pawel.moll@arm.com, swarren@nvidia.com, john.stultz@linaro.org, tglx@linutronix.de, mturquette@linaro.org Subject: [PATCH v2 02/14] clocksource: sp804: add device tree support Date: Wed, 13 Mar 2013 01:08:31 +0800 Message-Id: <1363108124-17484-3-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1363108124-17484-1-git-send-email-haojian.zhuang@linaro.org> References: <1363108124-17484-1-git-send-email-haojian.zhuang@linaro.org> X-Gm-Message-State: ALoCoQkwKWyOZx2uJWOuJb6H+hhnx2FCvysjA5YMmqQQDn2IJwJSkNVADLSqebAxvFchoQhnCqm4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130312_130904_791626_43348BF1 X-CRM114-Status: GOOD ( 15.69 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Haojian Zhuang , patches@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Parse clock & irq from device tree for sp804. Signed-off-by: Haojian Zhuang --- drivers/clocksource/timer-sp.c | 105 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/drivers/clocksource/timer-sp.c b/drivers/clocksource/timer-sp.c index a7f2510..f8c2c54 100644 --- a/drivers/clocksource/timer-sp.c +++ b/drivers/clocksource/timer-sp.c @@ -19,16 +19,23 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include #include #include #include +#include +#include #include +#include #include +#define SP804_CLKSRC "sp804 source" +#define SP804_CLKEVT "sp804 event" + static long __init sp804_get_clock_rate(const char *name) { struct clk *clk; @@ -189,3 +196,101 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); } + +static struct device_node *from = NULL; + +static struct of_device_id sp804_timer_match[] __initdata = { + { .compatible = "arm,sp804", }, + {} +}; + +static struct clk __init *sp804_dt_init_clk(struct device_node *np, int i, + const char *name) +{ + struct clk_lookup *lookup = NULL; + struct clk *clk; + + clk = of_clk_get(np, i); + if (IS_ERR(clk)) + return clk; + lookup = clkdev_alloc(clk, name, "sp804"); + if (!lookup) { + clk_put(clk); + return ERR_PTR(-EINVAL); + } + clkdev_add(lookup); + return clk; +} + +static void __init sp804_dt_init(void) +{ + struct device_node *np = NULL; + struct clk *clksrc = NULL, *clkevt = NULL; + void __iomem *base; + int retsrc, retevt, i = 0, irq = 0; + u32 srcoffs = 0, evtoffs = 0; + + np = of_find_matching_node(from, sp804_timer_match); + WARN_ON(!np); + if (!np) { + pr_err("Failed to find sp804 timer\n"); + return; + } + from = np; + /* check whether timer node is available */ + if (!of_device_is_available(np)) + return; + + base = of_iomap(np, 0); + WARN_ON(!base); + if (!base) + return; + + retsrc = of_property_read_u32(np, "arm,sp804-clocksource", &srcoffs); + retevt = of_property_read_u32(np, "arm,sp804-clockevent", &evtoffs); + if (retsrc < 0 && retevt < 0) + goto err; + + if (!retsrc) { + if (srcoffs) { + /* TIMER2 is clock source */ + i = 1; + srcoffs = TIMER_2_BASE; + } else { + /* TIMER1 is clock source */ + i = 0; + srcoffs = TIMER_1_BASE; + } + clksrc = sp804_dt_init_clk(np, i, SP804_CLKSRC); + if (IS_ERR(clksrc)) + goto err; + sp804_clocksource_and_sched_clock_init(base + srcoffs, + SP804_CLKSRC); + } + if (!retevt) { + if (evtoffs) { + /* TIMER2 is clock event */ + i = 1; + evtoffs = TIMER_2_BASE; + } else { + /* TIMER1 is clock event */ + i = 0; + evtoffs = TIMER_1_BASE; + } + irq = irq_of_parse_and_map(np, i); + if (irq < 0) + goto err_evt; + clkevt = sp804_dt_init_clk(np, i, SP804_CLKEVT); + if (IS_ERR(clkevt)) + goto err_evt; + sp804_clockevents_init(base + evtoffs, irq, SP804_CLKEVT); + } + + return; +err_evt: + if (clksrc) + clk_put(clksrc); +err: + iounmap(base); +} +CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_dt_init);