From patchwork Thu Oct 31 06:27:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Domenico Andreoli X-Patchwork-Id: 3118941 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B5A93BF924 for ; Thu, 31 Oct 2013 06:33:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CBE46203E6 for ; Thu, 31 Oct 2013 06:33:58 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6902C203DF for ; Thu, 31 Oct 2013 06:33:57 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VblnR-0005HS-Iw; Thu, 31 Oct 2013 06:31:59 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vblmu-0008Jc-2r; Thu, 31 Oct 2013 06:31:24 +0000 Received: from mail-ee0-x236.google.com ([2a00:1450:4013:c00::236]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vblm0-0008CF-3r for linux-arm-kernel@lists.infradead.org; Thu, 31 Oct 2013 06:30:38 +0000 Received: by mail-ee0-f54.google.com with SMTP id c50so457153eek.27 for ; Wed, 30 Oct 2013 23:30:10 -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=FWJTGuVJT3zvw7VOR2R+ZzF8gF851WqME9r9H7/5AVY=; b=JRldE9qLQ6m/a8XMZPynZL/65avZppRWPXD9Y+JP9bATLH4vVRqQ3aHgE/yDeGuH1/ Y1piOmnkrNG96kQsQHkV5A7lgg/WDxQgyv4FjK8XZDaPooSRgyyueA8zfOPXqaAXHpvI cLnKW/i97TO45jQDRtUtgKpzlJkdhvdsrr9XOmM7p6IMXsJyB7fOjgwNxAeq/psM/P6e 9Y9yG2gXkPyINlvBRF4zm1rABYSkjGba8dtnAl/P896WhV3DkGxPnS7Ue/+YHL0wkT1u 4nxld6CsRfq38ljhl5mwf4hJ29nWQ+3BG+JLh5MZO97+qa/lIEOZwlq+UFzCUaehmtiP iA6Q== X-Received: by 10.15.22.69 with SMTP id e45mr304048eeu.137.1383201010541; Wed, 30 Oct 2013 23:30:10 -0700 (PDT) Received: from shock.dandreoli.com (j115181.upc-j.chello.nl. [24.132.115.181]) by mx.google.com with ESMTPSA id a1sm4505888eem.1.2013.10.30.23.30.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Oct 2013 23:30:09 -0700 (PDT) Received: by shock.dandreoli.com (Postfix, from userid 1000) id 4988734032C; Thu, 31 Oct 2013 07:30:01 +0100 (CET) Message-Id: <20131031063001.088351233@linux.com> User-Agent: quilt/0.60-1 Date: Thu, 31 Oct 2013 07:27:19 +0100 From: Domenico Andreoli To: linux-arch@vger.kernel.org Subject: [PATCH 11/11] ARM: sp805: use the common machine reset handling References: <20131031062708.520968323@linux.com> Content-Disposition: inline; filename=sp805-machine-reset.patch X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131031_023028_394477_4E9684DF X-CRM114-Status: GOOD ( 16.35 ) X-Spam-Score: -1.9 (-) Cc: Russell King , Arnd Bergmann , Ralf Baechle , Domenico Andreoli , Wim Van Sebroeck , linux-mips@lvger.kernel.org, Olof Johansson , linux-arm-kernel@lists.infradead.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 X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Domenico Andreoli Proof of concept: sp805 as provider of reset hooks. Cc: Russell King Cc: Arnd Bergmann Cc: Olof Johansson Cc: Wim Van Sebroeck Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Domenico Andreoli --- drivers/watchdog/Kconfig | 9 ++++++++ drivers/watchdog/sp805_wdt.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) Index: b/drivers/watchdog/Kconfig =================================================================== --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -110,11 +110,20 @@ config WM8350_WATCHDOG config ARM_SP805_WATCHDOG tristate "ARM SP805 Watchdog" depends on ARM && ARM_AMBA + select MACHINE_RESET select WATCHDOG_CORE help ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached. +config ARM_SP805_WATCHDOG_RESTART_HOOK + bool "ARM SP805 system restart hook" + depends on ARM_SP805_WATCHDOG + help + Register hook to reboot the system based on the SP805 Watchdog. + + This can be overriden with cmdline option restart_hook=0. + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on ARCH_AT91RM9200 Index: b/drivers/watchdog/sp805_wdt.c =================================================================== --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include /* default timeout in seconds */ #define DEFAULT_TIMEOUT 60 @@ -77,6 +79,11 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Set to 1 to keep watchdog running after device release"); +static bool restart_hook = IS_ENABLED(CONFIG_ARM_SP805_WATCHDOG_RESTART_HOOK); +module_param(restart_hook, bool, 0); +MODULE_PARM_DESC(restart_hook, + "Set to 1 to install a machine restart handler based on this watchdog"); + /* This routine finds load value that will reset system in required timout */ static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) { @@ -189,6 +196,33 @@ static int wdt_disable(struct watchdog_d return 0; } +/* trigger watchdog timer */ +static void wdt_atomic_trigger(struct watchdog_device *wdd) +{ + struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); + + spin_lock(&wdt->lock); + + writel_relaxed(UNLOCK, wdt->base + WDTLOCK); + writel_relaxed(0, wdt->base + WDTCONTROL); + udelay(20); + writel_relaxed(INT_MASK, wdt->base + WDTINTCLR); + udelay(20); + + /* Expire after 5 cycles */ + writel_relaxed(5, wdt->base + WDTLOAD); + + writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL); + writel_relaxed(LOCK, wdt->base + WDTLOCK); + + /* Flush posted writes. */ + readl_relaxed(wdt->base + WDTLOCK); + spin_unlock(&wdt->lock); + + /* Wait the bite */ + udelay(400); +} + static const struct watchdog_info wdt_info = { .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = MODULE_NAME, @@ -201,8 +235,15 @@ static const struct watchdog_ops wdt_ops .ping = wdt_ping, .set_timeout = wdt_setload, .get_timeleft = wdt_timeleft, +/* .atomic_trigger = wdt_atomic_trigger, */ }; +static void sp805_wdt_machine_restart(void *wdd, enum reboot_mode mode, + const char *cmd) +{ + wdt_atomic_trigger(wdd); +} + static int sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) { @@ -247,6 +288,13 @@ sp805_wdt_probe(struct amba_device *adev watchdog_set_drvdata(&wdt->wdd, wdt); wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT); + if (restart_hook) { + struct reset_hook hook; + reset_hook_init(&hook); + hook.restart = sp805_wdt_machine_restart; + set_machine_reset(RESET_RESTART, &hook, &wdt->wdd); + } + ret = watchdog_register_device(&wdt->wdd); if (ret) { dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",