From patchwork Tue Jun 9 10:21:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 6571081 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6855D9F3D1 for ; Tue, 9 Jun 2015 10:26:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7AE8B2027D for ; Tue, 9 Jun 2015 10:26:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9CEAA20306 for ; Tue, 9 Jun 2015 10:25:59 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z2GhO-0007NE-PO; Tue, 09 Jun 2015 10:24:02 +0000 Received: from asav22.altibox.net ([109.247.116.9]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z2Ggu-0007Ar-Ih; Tue, 09 Jun 2015 10:23:34 +0000 Received: from localhost (localhost [127.0.0.1]) by asav22.altibox.net (Postfix) with ESMTP id 3C5C5201F2; Tue, 9 Jun 2015 12:23:12 +0200 (CEST) Received: from asav22.altibox.net ([127.0.0.1]) by localhost (asav22.lysetele.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id exXl1nyjIjqn; Tue, 9 Jun 2015 12:23:11 +0200 (CEST) Received: from localhost.localdomain (48.81-166-104.customer.lyse.net [81.166.104.48]) by asav22.altibox.net (Postfix) with ESMTP id 8A01A201A3; Tue, 9 Jun 2015 12:23:11 +0200 (CEST) From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/3] watchdog: bcm2835: Add poweroff code for the Raspberry Pi Date: Tue, 9 Jun 2015 12:21:44 +0200 Message-Id: <1433845305-17329-2-git-send-email-noralf@tronnes.org> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1433845305-17329-1-git-send-email-noralf@tronnes.org> References: <1433845305-17329-1-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150609_032333_057662_6F2E1B91 X-CRM114-Status: GOOD ( 15.11 ) X-Spam-Score: 0.0 (/) Cc: devicetree@vger.kernel.org, =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , linux-watchdog@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rpi-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, 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 This adds a new poweroff function to the watchdog driver for the Raspberry Pi. Currently poweroff/halt results in a reboot. The Raspberry Pi firmware uses the RSTS register to know which partiton to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10. Partiton 63 is a special partition used by the firmware to indicate halt. The firmware made this change in 19 Aug 2013 and was matched by the downstream commit: Changes for new NOOBS multi partition booting from gsh Signed-off-by: Noralf Trønnes Acked-by: Guenter Roeck --- drivers/watchdog/bcm2835_wdt.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index 7116968..fdf0d7d 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -36,6 +36,13 @@ #define PM_RSTC_WRCFG_FULL_RESET 0x00000020 #define PM_RSTC_RESET 0x00000102 +/* + * The Raspberry Pi firmware uses the RSTS register to know which partiton + * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10. + * Partiton 63 is a special partition used by the firmware to indicate halt. + */ +#define PM_RSTS_RASPBERRYPI_HALT 0x555 + #define SECS_TO_WDOG_TICKS(x) ((x) << 16) #define WDOG_TICKS_TO_SECS(x) ((x) >> 16) @@ -159,6 +166,24 @@ static void bcm2835_power_off(void) bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL); } +static void rpi_power_off(void) +{ + struct device_node *np = + of_find_compatible_node(NULL, NULL, "brcm,raspberrypi-pm-wdt"); + struct platform_device *pdev = of_find_device_by_node(np); + struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); + u32 val; + + val = readl_relaxed(wdt->base + PM_RSTS); + val |= PM_PASSWORD | PM_RSTS_RASPBERRYPI_HALT; + writel_relaxed(val, wdt->base + PM_RSTS); + + /* Continue with normal reset mechanism */ + bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL); +} + +static const struct of_device_id bcm2835_wdt_of_match[]; + static int bcm2835_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -192,8 +217,12 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) wdt->restart_handler.notifier_call = bcm2835_restart; wdt->restart_handler.priority = 128; register_restart_handler(&wdt->restart_handler); - if (pm_power_off == NULL) - pm_power_off = bcm2835_power_off; + if (!pm_power_off) { + const struct of_device_id *match; + + match = of_match_node(bcm2835_wdt_of_match, pdev->dev.of_node); + pm_power_off = match->data; + } dev_info(dev, "Broadcom BCM2835 watchdog timer"); return 0; @@ -204,7 +233,7 @@ static int bcm2835_wdt_remove(struct platform_device *pdev) struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); unregister_restart_handler(&wdt->restart_handler); - if (pm_power_off == bcm2835_power_off) + if (pm_power_off == bcm2835_power_off || pm_power_off == rpi_power_off) pm_power_off = NULL; watchdog_unregister_device(&bcm2835_wdt_wdd); iounmap(wdt->base); @@ -218,7 +247,8 @@ static void bcm2835_wdt_shutdown(struct platform_device *pdev) } static const struct of_device_id bcm2835_wdt_of_match[] = { - { .compatible = "brcm,bcm2835-pm-wdt", }, + { .compatible = "brcm,bcm2835-pm-wdt", .data = bcm2835_power_off }, + { .compatible = "brcm,raspberrypi-pm-wdt", .data = rpi_power_off }, {}, }; MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match);