From patchwork Wed Mar 13 05:05:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 15313 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A0D6823E2E for ; Wed, 13 Mar 2013 05:07:13 +0000 (UTC) Received: from mail-vb0-f52.google.com (mail-vb0-f52.google.com [209.85.212.52]) by fiordland.canonical.com (Postfix) with ESMTP id 4AA86A19283 for ; Wed, 13 Mar 2013 05:07:13 +0000 (UTC) Received: by mail-vb0-f52.google.com with SMTP id fa15so272219vbb.25 for ; Tue, 12 Mar 2013 22:07:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=HyMQvc2YbCqp+NKCt/eGiWrb8kKq5FgXoUYD+MnBxvk=; b=RbSWLCSDPVRmq4J36FPzxQTtI4Ql7q9aiI170pADBTaBRa7gi4vZ/N/meo6yJfZR9X SARLjIMn2LFUf95WH0gxoKPw/g5f2sl45hqKkGCaSKn3W19YBWbGCh2Vb++oKkLwIiw8 v6Cdemi5XbBxGyWLzqn5RIpoWw62kcZPYPupSZUfrXagbQIt6nsYmrV2le2rU0v2hLFy ZlSFijtQJ9/CYNS3ChNqNIXH4Nv/bZ/DeJZsmVacyfZtyx+aCryULEJ8XSMHJKzh16FJ PCMwCQeDbh/TmBHgqPBcD2Y3u/h/2XbkGoNxiveWDy/Ek0xNiHpYlCsJH6v+mO15tHPi 7Y6g== X-Received: by 10.52.88.237 with SMTP id bj13mr6612277vdb.75.1363151232817; Tue, 12 Mar 2013 22:07:12 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.127.98 with SMTP id nf2csp1625veb; Tue, 12 Mar 2013 22:07:12 -0700 (PDT) X-Received: by 10.68.117.104 with SMTP id kd8mr43352211pbb.1.1363151231826; Tue, 12 Mar 2013 22:07:11 -0700 (PDT) Received: from mail-da0-x22c.google.com (mail-da0-x22c.google.com [2607:f8b0:400e:c00::22c]) by mx.google.com with ESMTPS id ot10si33569150pbb.97.2013.03.12.22.07.11 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Mar 2013 22:07:11 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400e:c00::22c is neither permitted nor denied by best guess record for domain of haojian.zhuang@linaro.org) client-ip=2607:f8b0:400e:c00::22c; Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400e:c00::22c is neither permitted nor denied by best guess record for domain of haojian.zhuang@linaro.org) smtp.mail=haojian.zhuang@linaro.org Received: by mail-da0-f44.google.com with SMTP id z20so244186dae.31 for ; Tue, 12 Mar 2013 22:07:11 -0700 (PDT) X-Received: by 10.68.190.195 with SMTP id gs3mr36712173pbc.14.1363151230788; Tue, 12 Mar 2013 22:07:10 -0700 (PDT) Received: from localhost.localdomain ([67.198.145.34]) by mx.google.com with ESMTPS id ab1sm27947630pbd.37.2013.03.12.22.07.06 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Mar 2013 22:07:10 -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 Cc: patches@linaro.org, Haojian Zhuang Subject: [PATCH v3 03/11] clocksource: sp804: add device tree support Date: Wed, 13 Mar 2013 13:05:34 +0800 Message-Id: <1363151142-32162-4-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1363151142-32162-1-git-send-email-haojian.zhuang@linaro.org> References: <1363151142-32162-1-git-send-email-haojian.zhuang@linaro.org> X-Gm-Message-State: ALoCoQmubm8ECvFsHttCtpV7onPaaMRx4w3hNofZTnO50EPrNpylQV5rJWYVr98lykRBEznhTzTc Parse clock & irq from device tree for sp804. Signed-off-by: Haojian Zhuang --- .../devicetree/bindings/timer/arm,sp804.txt | 27 +++++ drivers/clocksource/timer-sp.c | 105 ++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/arm,sp804.txt diff --git a/Documentation/devicetree/bindings/timer/arm,sp804.txt b/Documentation/devicetree/bindings/timer/arm,sp804.txt new file mode 100644 index 0000000..ec1ae45 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/arm,sp804.txt @@ -0,0 +1,27 @@ +ARM sp804 Dual Timers +--------------------------------------- + +Required properties: +- compatible: Should be "arm,sp804" & "arm,primecell" +- interrupts: Should contain the list of Dual Timer interrupts + interrupts = <0 0 4>, <0 1 4>; +- reg: Should contain location and length for dual timer register. +- clocks: clock driving the dual timer hardware + clocks = <&timclk0 &timclk1>; + +Optional properties: +- arm,sp804-clocksource: Should contain the register offset of TIMER1 or + TIMER2 in Dual Timer Controller. + arm,sp804-clocksource = <0x20>; + +Example: + + timer0: timer@fc800000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xfc800000 0x1000>; + /* timer00 & timer01 */ + interrupts = <0 0 4>, <0 1 4>; + clocks = <&timclk0 &timclk1>; + clock-names = "apb_pclk"; + status = "disabled"; + }; diff --git a/drivers/clocksource/timer-sp.c b/drivers/clocksource/timer-sp.c index a7f2510..63f757d 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 __attribute__((__unused__)) __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)