From patchwork Sun Oct 14 22:14:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Domenico Andreoli X-Patchwork-Id: 1591821 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 6EEABE00AD for ; Sun, 14 Oct 2012 22:32:56 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TNWi2-0000au-7o; Sun, 14 Oct 2012 22:30:58 +0000 Received: from mail-we0-f177.google.com ([74.125.82.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TNWha-0000VC-Sc for linux-arm-kernel@lists.infradead.org; Sun, 14 Oct 2012 22:30:33 +0000 Received: by mail-we0-f177.google.com with SMTP id u50so2855544wey.36 for ; Sun, 14 Oct 2012 15:30:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:user-agent:date:from:to:cc:subject:references :content-disposition; bh=yQft41xrMSa06tiLnJIflvqTZl9iob21VnNhpA3GyUo=; b=K40IyTAQUivLgT+GxJjDguWQZCMd5wnh4J2UcGiqyXVubUFlbT1Ihp0nizFkZoEb8y gUGak+syUBNN8slFMrfdg0KNTGs8/j73qdh1de4ryjJz1lGoByUIWxk3Itj4DhdesV2s 6pRD/3YsM0umcyFYCYNFESegYEt1pWdnnh9kt8UolisDFApzkFJnSQKilKIfnMVfugEj Ik6qHnHPtyn2dXX5QNfqP3ayjtqlRORJ2IGQCQ+WzBNeWWN+nG8S1ifWFUmnirC+0WTZ +nt5+GeiIGCCmHyM2auZpOZHSj801WBJduU3zRpUk5r2bxhFHsk6NeR38kcl41I24oix eJhQ== Received: by 10.216.147.4 with SMTP id s4mr6378944wej.9.1350253829839; Sun, 14 Oct 2012 15:30:29 -0700 (PDT) Received: from raptus.dandreoli.com (178-85-163-250.dynamic.upc.nl. [178.85.163.250]) by mx.google.com with ESMTPS id v3sm10890539wiw.7.2012.10.14.15.30.28 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 14 Oct 2012 15:30:29 -0700 (PDT) Received: by raptus.dandreoli.com (Postfix, from userid 1000) id 657683F620C; Mon, 15 Oct 2012 00:30:25 +0200 (CEST) Message-Id: <20121014223025.133094217@gmail.com> User-Agent: quilt/0.60-1 Date: Mon, 15 Oct 2012 00:14:55 +0200 From: Domenico Andreoli To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 5/5] ARM: bcm476x: Add restart hook References: <20121014221450.866288977@gmail.com> Content-Disposition: inline; filename=arm-bcm476x-add-restart-hook.patch X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.177 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (cavokz[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Domenico Andreoli , Olof Johansson X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Domenico Andreoli Restart hook implementation for the BCM476x SoC (uses the watchdog). v2: * bcm476x_setup_restart() now manages correctly the failure of of_iomap() * match DT with the specific product names instead of the generic bcm476x v1: * initial release Signed-off-by: Domenico Andreoli Acked-by: Olof Johansson --- Documentation/devicetree/bindings/watchdog/brcm,bcm476x-pm-wdt.txt | 15 ++ arch/arm/boot/dts/bcm4760.dtsi | 5 + arch/arm/boot/dts/bcm4761.dtsi | 5 + arch/arm/mach-bcm476x/bcm476x.c | 79 ++++++++++ 4 files changed, 104 insertions(+) Index: b/Documentation/devicetree/bindings/watchdog/brcm,bcm476x-pm-wdt.txt =================================================================== --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm476x-pm-wdt.txt @@ -0,0 +1,15 @@ +Broadcom BCM4760 and BCM4761 watchdog timer device tree bindings +---------------------------------------------------------------- + +Required properties: + +- compatible : should be "brcm,bcm4760-pm-wdt" or + "brcm,bcm4761-pm-wdt" +- reg : Specifies base physical address and size of the registers. + +Example: + +watchdog { + compatible = "brcm,bcm4760-pm-wdt"; + reg = <0xbd000 0x1000>; +}; Index: b/arch/arm/boot/dts/bcm4760.dtsi =================================================================== --- a/arch/arm/boot/dts/bcm4760.dtsi +++ b/arch/arm/boot/dts/bcm4760.dtsi @@ -24,6 +24,11 @@ clock-frequency = <32000>; }; + watchdog { + compatible = "brcm,bcm4760-pm-wdt"; + reg = <0xbd000 0x1000>; + }; + vic0: interrupt-controller@80000 { compatible = "brcm,bcm4760-pl192", "arm,pl192-vic", "arm,primecell"; reg = <0x80000 0x1000>; Index: b/arch/arm/boot/dts/bcm4761.dtsi =================================================================== --- a/arch/arm/boot/dts/bcm4761.dtsi +++ b/arch/arm/boot/dts/bcm4761.dtsi @@ -24,6 +24,11 @@ clock-frequency = <32000>; }; + watchdog { + compatible = "brcm,bcm4761-pm-wdt"; + reg = <0xbd000 0x1000>; + }; + vic0: interrupt-controller@80000 { compatible = "brcm,bcm4761-pl192", "arm,pl192-vic", "arm,primecell"; reg = <0x80000 0x1000>; Index: b/arch/arm/mach-bcm476x/bcm476x.c =================================================================== --- a/arch/arm/mach-bcm476x/bcm476x.c +++ b/arch/arm/mach-bcm476x/bcm476x.c @@ -15,7 +15,9 @@ */ #include +#include #include +#include #include #include #include @@ -28,6 +30,17 @@ #define BCM476X_PERIPH_VIRT IOMEM(0xd0080000) #define BCM476X_PERIPH_SIZE SZ_512K +#define BCM476X_WDT_LOAD 0x000 +#define BCM476X_WDT_CTRL 0x008 +#define BCM476X_WDT_INTCLR 0x00c +#define BCM476X_WDT_LOCK 0xc00 + +#define BCM476X_WDT_PASSWORD 0x1acce551 +#define BCM476X_WDT_INTEN BIT(0) +#define BCM476X_WDT_RESEN BIT(1) + +static void __iomem *wdt_regs; + static struct map_desc io_map __initdata = { .virtual = (unsigned long) BCM476X_PERIPH_VIRT, .pfn = __phys_to_pfn(BCM476X_PERIPH_PHYS), @@ -40,10 +53,75 @@ static void __init bcm476x_map_io(void) iotable_init(&io_map, 1); } +static const struct of_device_id bcm476x_pm_wdt_match[] __initconst = { + { .compatible = "brcm,bcm4760-pm-wdt" }, + { .compatible = "brcm,bcm4761-pm-wdt" }, + {} +}; + +/* + * The machine restart method can be called from an atomic context so we won't + * be able to ioremap the regs then. + */ +static void bcm476x_setup_restart(void) +{ + struct device_node *node; + + node = of_find_matching_node(NULL, bcm476x_pm_wdt_match); + if (!node) { + pr_info("No bcm476x watchdog node\n"); + return; + } + + wdt_regs = of_iomap(node, 0); + if (!wdt_regs) { + pr_err("Can't remap watchdog registers\n"); + return; + } + + /* unlock watchdog registers */ + writel(BCM476X_WDT_PASSWORD, wdt_regs + BCM476X_WDT_LOCK); + /* disable watchdog */ + writel(0, wdt_regs + BCM476X_WDT_CTRL); + /* lock watchdog registers */ + writel(1, wdt_regs + BCM476X_WDT_LOCK); +} + +static void bcm476x_restart(char mode, const char *cmd) +{ + if (!wdt_regs) { + pr_err("No restart hook installed. "); + return; + } + + /* unlock watchdog registers */ + writel(BCM476X_WDT_PASSWORD, wdt_regs + BCM476X_WDT_LOCK); + + /* disable watchdog */ + writel(0, wdt_regs + BCM476X_WDT_CTRL); + udelay(20); + + /* clear the irq status */ + writel(1, wdt_regs + BCM476X_WDT_INTCLR); + udelay(20); + + /* expire after 5 cycles (~156us) */ + writel(5, wdt_regs + BCM476X_WDT_LOAD); + /* enable watchdog */ + writel(BCM476X_WDT_INTEN | BCM476X_WDT_RESEN, + wdt_regs + BCM476X_WDT_CTRL); + + /* lock watchdog registers */ + writel(1, wdt_regs + BCM476X_WDT_LOCK); + /* wait the bite */ + udelay(400); +} + static void __init bcm476x_init(void) { int err; + bcm476x_setup_restart(); bcm476x_init_clocks(); err = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); @@ -75,5 +153,6 @@ DT_MACHINE_START(BCM476X, "Broadcom BCM4 .handle_irq = vic_handle_irq, .init_machine = bcm476x_init, .timer = &bcm476x_timer, + .restart = bcm476x_restart, .dt_compat = bcm476x_compat MACHINE_END