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: 712533 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3txr6P0XB5z9sDg for ; Mon, 9 Jan 2017 20:52:13 +1100 (AEDT) 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-8g; 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-Spam-Score: -5.1 (-----) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-5.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -3.2 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list 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+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org 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);