[PATCH] watchdog: renesas_wdt: Blacklist early R-Car Gen2 SoCs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On early revisions of some R-Car Gen2 SoCs, and depending on SMP
configuration, the system may fail to restart on watchdog time-out, and
lock up instead.

Specifically:
  - On R-Car H2 ES1.0 and M2-W ES1.0, watchdog restart fails unless
    only the first CPU core is in use (using e.g. the "maxcpus=1" kernel
    commandline option).
  - On R-Car V2H ES1.1, watchdog restart fails unless SMP is disabled
    completely (using CONFIG_SMP=n during build configuration, or using
    the "nosmp" or "maxcpus=0" kernel commandline options).

Prevent using the watchdog in impacted cases by blacklisting the
affected SoCs, using the minimum known working revisions (ES2.0 on R-Car
H2, and ES3.0 on M2-W), and taking the actual SMP software configuration
into account.

Signed-off-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
---
To be folded into Fabrizio Castro's "watchdog: renesas_wdt: Add R-Car
Gen2 support".

Note that I cannot use IS_ENABLED(CONFIG_SMP), as setup_max_cpus does
not exist for CONFIG_SMP=n.

Any reports on R-Car M2-W ES2.0 and V2H ES2.0+ are welcomed!

As the failure is due to an integration issue, and the watchdog itself
is working fine, an alternative solution would be to move the check to
the code that installs the reset trigger ("soc: renesas: rcar-rst:
Enable watchdog as reset trigger for Gen2").
However, doing so would mean that:
  1. The user could enable and seemingly use the watchdog, but watchdog
     timeout would not restart the system,
  2. The same check should be done before installing the new reset
     vector ("ARM: shmobile: rcar-gen2: Add watchdog support"), too,
     else onlining CPU0 would fail once the watchdog has timed out.
---
 drivers/watchdog/renesas_wdt.c | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
index 0f88614797c36022..4c8e8d2600a922a5 100644
--- a/drivers/watchdog/renesas_wdt.c
+++ b/drivers/watchdog/renesas_wdt.c
@@ -16,6 +16,8 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/smp.h>
+#include <linux/sys_soc.h>
 #include <linux/watchdog.h>
 
 #define RWTCNT		0
@@ -131,6 +133,44 @@ static const struct watchdog_ops rwdt_ops = {
 	.restart = rwdt_restart,
 };
 
+#if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP)
+/*
+ * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs
+ */
+static const struct soc_device_attribute rwdt_quirks_match[] = {
+	{
+		.soc_id = "r8a7790",
+		.revision = "ES1.*",
+		.data = (void *)1,	/* needs single CPU */
+	}, {
+		.soc_id = "r8a7791",
+		.revision = "ES[12].*",
+		.data = (void *)1,	/* needs single CPU */
+	}, {
+		.soc_id = "r8a7792",
+		.revision = "*",
+		.data = (void *)0,	/* needs SMP disabled */
+	},
+	{ /* sentinel */ }
+};
+
+static bool rwdt_blacklisted(struct device *dev)
+{
+	const struct soc_device_attribute *attr;
+
+	attr = soc_device_match(rwdt_quirks_match);
+	if (attr && setup_max_cpus > (uintptr_t)attr->data) {
+		dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id,
+			 attr->revision);
+		return true;
+	}
+
+	return false;
+}
+#else /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */
+static inline bool rwdt_blacklisted(struct device *dev) { return false; }
+#endif /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */
+
 static int rwdt_probe(struct platform_device *pdev)
 {
 	struct rwdt_priv *priv;
@@ -139,6 +179,9 @@ static int rwdt_probe(struct platform_device *pdev)
 	unsigned long clks_per_sec;
 	int ret, i;
 
+	if (rwdt_blacklisted(&pdev->dev))
+		return -ENODEV;
+
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
-- 
2.7.4




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux