From patchwork Mon Jan 9 09:50:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 9504261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 89E9D60710 for ; Mon, 9 Jan 2017 09:52:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E33128442 for ; Mon, 9 Jan 2017 09:52:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7FBF22845F; Mon, 9 Jan 2017 09:52:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0B00128442 for ; Mon, 9 Jan 2017 09:52:10 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cQWcY-0004R3-Jj; Mon, 09 Jan 2017 09:52:06 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cQWc3-0003OK-1Y for linux-arm-kernel@lists.infradead.org; Mon, 09 Jan 2017 09:51:38 +0000 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1cQWbF-0006Mz-Pk; Mon, 09 Jan 2017 10:50:45 +0100 Received: from ukl by dude.hi.pengutronix.de with local (Exim 4.88) (envelope-from ) id 1cQWbC-000382-8B; Mon, 09 Jan 2017 10:50:42 +0100 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= To: Vladimir Zapolskiy , Shawn Guo , Wim Van Sebroeck , Guenter Roeck , Fabio Estevam Subject: [PATCH 1/3] watchdog: imx2: Only i.MX35 and later have a WMCR register Date: Mon, 9 Jan 2017 10:50:37 +0100 Message-Id: <20170109095039.11979-2-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170109095039.11979-1-u.kleine-koenig@pengutronix.de> References: <20170109095039.11979-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170109_015135_269452_EA1C193C X-CRM114-Status: GOOD ( 18.40 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, Magnus Lilja , linux-watchdog@vger.kernel.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Commit 5fe65ce7ccbb ("watchdog: imx2_wdt: Disable power down counter on boot") introduced a write to the WMCR register that doesn't exist on i.MX21, i.MX27 and i.MX31 and so makes the SoC hang during probe. So teach the driver to differentiate between these two types. Note that this effectively undoes commit 5fe65ce7ccbb for machines using dt until their dtb is updated accordingly. This is critical iff the bootloader doesn't disable the power down counter and the #WDOG signal actually does something to the machine. Signed-off-by: Uwe Kleine-König Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/devices/devices-common.h | 1 + arch/arm/mach-imx/devices/platform-imx2-wdt.c | 13 +++--- drivers/watchdog/imx2_wdt.c | 59 +++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h index 6920e356f4e5..946cca627018 100644 --- a/arch/arm/mach-imx/devices/devices-common.h +++ b/arch/arm/mach-imx/devices/devices-common.h @@ -92,6 +92,7 @@ struct platform_device *__init imx_add_imx27_coda( struct imx_imx2_wdt_data { int id; + const char *devname; resource_size_t iobase; resource_size_t iosize; }; diff --git a/arch/arm/mach-imx/devices/platform-imx2-wdt.c b/arch/arm/mach-imx/devices/platform-imx2-wdt.c index 8c134c8d7500..d8d3dd58fcfe 100644 --- a/arch/arm/mach-imx/devices/platform-imx2-wdt.c +++ b/arch/arm/mach-imx/devices/platform-imx2-wdt.c @@ -11,9 +11,10 @@ #include "../hardware.h" #include "devices-common.h" -#define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) \ +#define imx_imx2_wdt_data_entry_single(soc, _id, _devname, _hwid, _size)\ { \ .id = _id, \ + .devname = _devname, \ .iobase = soc ## _WDOG ## _hwid ## _BASE_ADDR, \ .iosize = _size, \ } @@ -22,22 +23,22 @@ #ifdef CONFIG_SOC_IMX21 const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K); + imx_imx2_wdt_data_entry_single(MX21, 0, "imx21-wdt", , SZ_4K); #endif /* ifdef CONFIG_SOC_IMX21 */ #ifdef CONFIG_SOC_IMX27 const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K); + imx_imx2_wdt_data_entry_single(MX27, 0, "imx21-wdt", , SZ_4K); #endif /* ifdef CONFIG_SOC_IMX27 */ #ifdef CONFIG_SOC_IMX31 const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX31, 0, , SZ_16K); + imx_imx2_wdt_data_entry_single(MX31, 0, "imx21-wdt", , SZ_16K); #endif /* ifdef CONFIG_SOC_IMX31 */ #ifdef CONFIG_SOC_IMX35 const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX35, 0, , SZ_16K); + imx_imx2_wdt_data_entry_single(MX35, 0, "imx35-wdt", , SZ_16K); #endif /* ifdef CONFIG_SOC_IMX35 */ struct platform_device *__init imx_add_imx2_wdt( @@ -50,6 +51,6 @@ struct platform_device *__init imx_add_imx2_wdt( .flags = IORESOURCE_MEM, }, }; - return imx_add_platform_device("imx2-wdt", data->id, + return imx_add_platform_device(data->devname, data->id, res, ARRAY_SIZE(res), NULL, 0); } diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 4874b0f18650..509b2fedb112 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,18 @@ #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8) +struct imx2_wdt_type { + bool has_WMCR; +}; + +static const struct imx2_wdt_type imx2_wdt_type_imx21 = { + .has_WMCR = false, +}; + +static const struct imx2_wdt_type imx2_wdt_type_imx35 = { + .has_WMCR = true, +}; + struct imx2_wdt_device { struct clk *clk; struct regmap *regmap; @@ -248,6 +261,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) void __iomem *base; int ret; u32 val; + const struct imx2_wdt_type *type; wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) @@ -309,12 +323,21 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) set_bit(WDOG_HW_RUNNING, &wdog->status); } - /* - * Disable the watchdog power down counter at boot. Otherwise the power - * down counter will pull down the #WDOG interrupt line for one clock - * cycle. - */ - regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); + type = of_device_get_match_data(&pdev->dev); + if (!type) + type = (void *)pdev->id_entry->driver_data; + + if (type) { + if (type->has_WMCR) + /* + * Disable the watchdog power down counter at boot. + * Otherwise the power down counter will pull down the + * #WDOG interrupt line for one clock cycle. + */ + regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); + } else { + dev_warn(&pdev->dev, "Cannot determine if WMCR is present\n"); + } ret = watchdog_register_device(wdog); if (ret) { @@ -411,9 +434,29 @@ static int imx2_wdt_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, imx2_wdt_resume); +static const struct platform_device_id imx2_wdt_devtype[] = { + { + .name = "imx21-wdt", + .driver_data = (kernel_ulong_t) &imx2_wdt_type_imx21, + }, { + .name = "imx35-wdt", + .driver_data = (kernel_ulong_t) &imx2_wdt_type_imx35, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, imx2_wdt_devtype); + static const struct of_device_id imx2_wdt_dt_ids[] = { - { .compatible = "fsl,imx21-wdt", }, - { /* sentinel */ } + { + .compatible = "fsl,imx21-wdt", + .data = &imx2_wdt_type_imx21, + }, { + .compatible = "fsl,imx35-wdt", + .data = &imx2_wdt_type_imx35, + }, { + /* sentinel */ + } }; MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);