e293be
centosplus patch bug#15830
e293be
e293be
From c6e2c1e1138fa5cb5bb99381132855bbaf712029 Mon Sep 17 00:00:00 2001
e293be
From: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Date: Thu, 22 Dec 2016 13:17:07 +0300
e293be
Subject: ACPI / watchdog: Print out error number when device creation fails
e293be
e293be
If the platform device creation fails for whichever reason the driver
e293be
prints out something like:
e293be
e293be
  [    0.978837] ACPI: watchdog: Failed to create platform device
e293be
e293be
However, that is quite confusing and does not include any information
e293be
why it failed. To make it more understandable, reword it like:
e293be
e293be
  [    0.978837] ACPI: watchdog: Device creation failed: -16
e293be
e293be
Which tells that we failed to create the watchdog device because some of
e293be
the resources were already reserved (-EBUSY).
e293be
e293be
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
e293be
e293be
Submitted-by: Pablo Greco <pablo@fliagreco.com.ar> 
e293be
Applied-by:   Akemi Yagi <toracat@centos.org>
e293be
---
e293be
 drivers/acpi/acpi_watchdog.c | 2 +-
e293be
 1 file changed, 1 insertion(+), 1 deletion(-)
e293be
e293be
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
e293be
index 13caebd679f5..8c4e0a18460a 100644
e293be
--- a/drivers/acpi/acpi_watchdog.c
e293be
+++ b/drivers/acpi/acpi_watchdog.c
e293be
@@ -114,7 +114,7 @@ void __init acpi_watchdog_init(void)
e293be
 	pdev = platform_device_register_simple("wdat_wdt", PLATFORM_DEVID_NONE,
e293be
 					       resources, nresources);
e293be
 	if (IS_ERR(pdev))
e293be
-		pr_err("Failed to create platform device\n");
e293be
+		pr_err("Device creation failed: %ld\n", PTR_ERR(pdev));
e293be
 
e293be
 	kfree(resources);
e293be
 
e293be
-- 
e293be
cgit 1.2-0.3.lf.el7
e293be
e293be
From 31e86cb99a3af0653f0e317fdd9c05b530c70af8 Mon Sep 17 00:00:00 2001
e293be
From: Ryan Kennedy <ryan5544@gmail.com>
e293be
Date: Sat, 15 Jul 2017 17:48:18 -0400
e293be
Subject: ACPI / watchdog: Fix init failure with overlapping register regions
e293be
e293be
Partially overlapping regions cause platform device creation
e293be
to fail. The latter of two overlapping resources will fail to be
e293be
reserved. Fix this by merging overlapping resource ranges while
e293be
enumerating WDAT table entries.
e293be
e293be
Signed-off-by: Ryan Kennedy <ryan5544@gmail.com>
e293be
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
e293be
---
e293be
 drivers/acpi/acpi_watchdog.c | 7 ++++++-
e293be
 1 file changed, 6 insertions(+), 1 deletion(-)
e293be
e293be
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
e293be
index 8c4e0a18460a..bf22c29d2517 100644
e293be
--- a/drivers/acpi/acpi_watchdog.c
e293be
+++ b/drivers/acpi/acpi_watchdog.c
e293be
@@ -86,7 +86,12 @@ void __init acpi_watchdog_init(void)
e293be
 
e293be
 		found = false;
e293be
 		resource_list_for_each_entry(rentry, &resource_list) {
e293be
-			if (resource_contains(rentry->res, &res)) {
e293be
+			if (rentry->res->flags == res.flags &&
e293be
+			    resource_overlaps(rentry->res, &res)) {
e293be
+				if (res.start < rentry->res->start)
e293be
+					rentry->res->start = res.start;
e293be
+				if (res.end > rentry->res->end)
e293be
+					rentry->res->end = res.end;
e293be
 				found = true;
e293be
 				break;
e293be
 			}
e293be
-- 
e293be
cgit 1.2-0.3.lf.el7
e293be
e293be
From 6ce14f6416c84bd9c81777edf899b57ac5000c87 Mon Sep 17 00:00:00 2001
e293be
From: Arnd Bergmann <arnd@arndb.de>
e293be
Date: Tue, 19 Sep 2017 01:49:02 +0200
e293be
Subject: ACPI / watchdog: properly initialize resources
e293be
e293be
We copy a local resource structure into a list, but only
e293be
initialize some of its members, as pointed out by gcc-4.4:
e293be
e293be
drivers/acpi/acpi_watchdog.c: In function 'acpi_watchdog_init':
e293be
drivers/acpi/acpi_watchdog.c:105: error: 'res.child' may be used uninitialized in this function
e293be
drivers/acpi/acpi_watchdog.c:105: error: 'res.sibling' may be used uninitialized in this function
e293be
drivers/acpi/acpi_watchdog.c:105: error: 'res.parent' may be used uninitialized in this function
e293be
drivers/acpi/acpi_watchdog.c:105: error: 'res.desc' may be used uninitialized in this function
e293be
drivers/acpi/acpi_watchdog.c:105: error: 'res.name' may be used uninitialized in this function
e293be
e293be
Newer compilers can presumably optimize the uninitialized access
e293be
away entirely and don't warn at all, but rely on the kzalloc()
e293be
to zero the structure first. This adds an explicit initialization
e293be
to force consistent behavior.
e293be
e293be
Fixes: 058dfc767008 (ACPI / watchdog: Add support for WDAT hardware watchdog)
e293be
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
e293be
Acked-by: Guenter Roeck <linux@roeck-us.net>
e293be
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
e293be
---
e293be
 drivers/acpi/acpi_watchdog.c | 2 +-
e293be
 1 file changed, 1 insertion(+), 1 deletion(-)
e293be
e293be
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
e293be
index bf22c29d2517..11b113f8e367 100644
e293be
--- a/drivers/acpi/acpi_watchdog.c
e293be
+++ b/drivers/acpi/acpi_watchdog.c
e293be
@@ -66,7 +66,7 @@ void __init acpi_watchdog_init(void)
e293be
 	for (i = 0; i < wdat->entries; i++) {
e293be
 		const struct acpi_generic_address *gas;
e293be
 		struct resource_entry *rentry;
e293be
-		struct resource res;
e293be
+		struct resource res = {};
e293be
 		bool found;
e293be
 
e293be
 		gas = &entries[i].register_region;
e293be
-- 
e293be
cgit 1.2-0.3.lf.el7
e293be
e293be
From a0a37862a4e1844793d39aca9ccb8fecbdcb8659 Mon Sep 17 00:00:00 2001
e293be
From: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Date: Mon, 23 Apr 2018 14:16:03 +0300
e293be
Subject: ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70
e293be
e293be
WDAT table on Lenovo Z50-70 is using RTC SRAM (ports 0x70 and 0x71) to
e293be
store state of the timer. This conflicts with Linux RTC driver
e293be
(rtc-cmos.c) who fails to reserve those ports for itself preventing RTC
e293be
from functioning. In addition the WDAT table seems not to be fully
e293be
functional because it does not reset the system when the watchdog times
e293be
out.
e293be
e293be
On this system iTCO_wdt works just fine so we simply prefer to use it
e293be
instead of WDAT. This makes RTC working again and also results working
e293be
watchdog via iTCO_wdt.
e293be
e293be
Reported-by: Peter Milley <pbmilley@gmail.com>
e293be
Link: https://bugzilla.kernel.org/show_bug.cgi?id=199033
e293be
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
e293be
---
e293be
 drivers/acpi/acpi_watchdog.c | 59 ++++++++++++++++++++++++++++++++++++--------
e293be
 1 file changed, 49 insertions(+), 10 deletions(-)
e293be
e293be
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
e293be
index ebb626ffb5fa..4bde16fb97d8 100644
e293be
--- a/drivers/acpi/acpi_watchdog.c
e293be
+++ b/drivers/acpi/acpi_watchdog.c
e293be
@@ -12,23 +12,64 @@
e293be
 #define pr_fmt(fmt) "ACPI: watchdog: " fmt
e293be
 
e293be
 #include <linux/acpi.h>
e293be
+#include <linux/dmi.h>
e293be
 #include <linux/ioport.h>
e293be
 #include <linux/platform_device.h>
e293be
 
e293be
 #include "internal.h"
e293be
 
e293be
+static const struct dmi_system_id acpi_watchdog_skip[] = {
e293be
+	{
e293be
+		/*
e293be
+		 * On Lenovo Z50-70 there are two issues with the WDAT
e293be
+		 * table. First some of the instructions use RTC SRAM
e293be
+		 * to store persistent information. This does not work well
e293be
+		 * with Linux RTC driver. Second, more important thing is
e293be
+		 * that the instructions do not actually reset the system.
e293be
+		 *
e293be
+		 * On this particular system iTCO_wdt seems to work just
e293be
+		 * fine so we prefer that over WDAT for now.
e293be
+		 *
e293be
+		 * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
e293be
+		 */
e293be
+		.ident = "Lenovo Z50-70",
e293be
+		.matches = {
e293be
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
e293be
+			DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
e293be
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
e293be
+		},
e293be
+	},
e293be
+	{}
e293be
+};
e293be
+
e293be
+static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
e293be
+{
e293be
+	const struct acpi_table_wdat *wdat = NULL;
e293be
+	acpi_status status;
e293be
+
e293be
+	if (acpi_disabled)
e293be
+		return NULL;
e293be
+
e293be
+	if (dmi_check_system(acpi_watchdog_skip))
e293be
+		return NULL;
e293be
+
e293be
+	status = acpi_get_table(ACPI_SIG_WDAT, 0,
e293be
+				(struct acpi_table_header **)&wdat);
e293be
+	if (ACPI_FAILURE(status)) {
e293be
+		/* It is fine if there is no WDAT */
e293be
+		return NULL;
e293be
+	}
e293be
+
e293be
+	return wdat;
e293be
+}
e293be
+
e293be
 /**
e293be
  * Returns true if this system should prefer ACPI based watchdog instead of
e293be
  * the native one (which are typically the same hardware).
e293be
  */
e293be
 bool acpi_has_watchdog(void)
e293be
 {
e293be
-	struct acpi_table_header hdr;
e293be
-
e293be
-	if (acpi_disabled)
e293be
-		return false;
e293be
-
e293be
-	return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr));
e293be
+	return !!acpi_watchdog_get_wdat();
e293be
 }
e293be
 EXPORT_SYMBOL_GPL(acpi_has_watchdog);
e293be
 
e293be
@@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void)
e293be
 	struct platform_device *pdev;
e293be
 	struct resource *resources;
e293be
 	size_t nresources = 0;
e293be
-	acpi_status status;
e293be
 	int i;
e293be
 
e293be
-	status = acpi_get_table(ACPI_SIG_WDAT, 0,
e293be
-				(struct acpi_table_header **)&wdat);
e293be
-	if (ACPI_FAILURE(status)) {
e293be
+	wdat = acpi_watchdog_get_wdat();
e293be
+	if (!wdat) {
e293be
 		/* It is fine if there is no WDAT */
e293be
 		return;
e293be
 	}
e293be
-- 
e293be
cgit 1.2-0.3.lf.el7
e293be
e293be
From 5a802a7a285c8877ca872e44eeb0f06afcb5212f Mon Sep 17 00:00:00 2001
e293be
From: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Date: Tue, 22 May 2018 14:16:50 +0300
e293be
Subject: ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM
e293be
e293be
After we added quirk for Lenovo Z50-70 it turns out there are at least
e293be
two more systems where WDAT table includes instructions accessing RTC
e293be
SRAM. Instead of quirking each system separately, look for such
e293be
instructions in the table and automatically prefer iTCO_wdt if found.
e293be
e293be
Link: https://bugzilla.kernel.org/show_bug.cgi?id=199033
e293be
Reported-by: Arnold Guy <aurnoldg@gmail.com>
e293be
Reported-by: Alois Nespor <nespor@fssp.cz>
e293be
Reported-by: Yury Pakin <zxwarior@gmail.com>
e293be
Reported-by: Ihor Chyhin <ihorchyhin@ukr.net>
e293be
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
e293be
Acked-by: Guenter Roeck <linux@roeck-us.net>
e293be
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
e293be
---
e293be
 drivers/acpi/acpi_watchdog.c | 72 +++++++++++++++++++++++++++-----------------
e293be
 1 file changed, 45 insertions(+), 27 deletions(-)
e293be
e293be
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
e293be
index 4bde16fb97d8..95600309ce42 100644
e293be
--- a/drivers/acpi/acpi_watchdog.c
e293be
+++ b/drivers/acpi/acpi_watchdog.c
e293be
@@ -12,35 +12,51 @@
e293be
 #define pr_fmt(fmt) "ACPI: watchdog: " fmt
e293be
 
e293be
 #include <linux/acpi.h>
e293be
-#include <linux/dmi.h>
e293be
 #include <linux/ioport.h>
e293be
 #include <linux/platform_device.h>
e293be
 
e293be
 #include "internal.h"
e293be
 
e293be
-static const struct dmi_system_id acpi_watchdog_skip[] = {
e293be
-	{
e293be
-		/*
e293be
-		 * On Lenovo Z50-70 there are two issues with the WDAT
e293be
-		 * table. First some of the instructions use RTC SRAM
e293be
-		 * to store persistent information. This does not work well
e293be
-		 * with Linux RTC driver. Second, more important thing is
e293be
-		 * that the instructions do not actually reset the system.
e293be
-		 *
e293be
-		 * On this particular system iTCO_wdt seems to work just
e293be
-		 * fine so we prefer that over WDAT for now.
e293be
-		 *
e293be
-		 * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
e293be
-		 */
e293be
-		.ident = "Lenovo Z50-70",
e293be
-		.matches = {
e293be
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
e293be
-			DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
e293be
-			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
e293be
-		},
e293be
-	},
e293be
-	{}
e293be
-};
e293be
+#ifdef CONFIG_RTC_LIB
e293be
+#include <linux/mc146818rtc.h>
e293be
+
e293be
+/*
e293be
+ * There are several systems where the WDAT table is accessing RTC SRAM to
e293be
+ * store persistent information. This does not work well with the Linux RTC
e293be
+ * driver so on those systems we skip WDAT driver and prefer iTCO_wdt
e293be
+ * instead.
e293be
+ *
e293be
+ * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
e293be
+ */
e293be
+static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
e293be
+{
e293be
+	const struct acpi_wdat_entry *entries;
e293be
+	int i;
e293be
+
e293be
+	entries = (struct acpi_wdat_entry *)(wdat + 1);
e293be
+	for (i = 0; i < wdat->entries; i++) {
e293be
+		const struct acpi_generic_address *gas;
e293be
+
e293be
+		gas = &entries[i].register_region;
e293be
+		if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
e293be
+			switch (gas->address) {
e293be
+			case RTC_PORT(0):
e293be
+			case RTC_PORT(1):
e293be
+			case RTC_PORT(2):
e293be
+			case RTC_PORT(3):
e293be
+				return true;
e293be
+			}
e293be
+		}
e293be
+	}
e293be
+
e293be
+	return false;
e293be
+}
e293be
+#else
e293be
+static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
e293be
+{
e293be
+	return false;
e293be
+}
e293be
+#endif
e293be
 
e293be
 static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
e293be
 {
e293be
@@ -50,9 +66,6 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
e293be
 	if (acpi_disabled)
e293be
 		return NULL;
e293be
 
e293be
-	if (dmi_check_system(acpi_watchdog_skip))
e293be
-		return NULL;
e293be
-
e293be
 	status = acpi_get_table(ACPI_SIG_WDAT, 0,
e293be
 				(struct acpi_table_header **)&wdat);
e293be
 	if (ACPI_FAILURE(status)) {
e293be
@@ -60,6 +73,11 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
e293be
 		return NULL;
e293be
 	}
e293be
 
e293be
+	if (acpi_watchdog_uses_rtc(wdat)) {
e293be
+		pr_info("Skipping WDAT on this system because it uses RTC SRAM\n");
e293be
+		return NULL;
e293be
+	}
e293be
+
e293be
 	return wdat;
e293be
 }
e293be
 
e293be
-- 
e293be
cgit 1.2-0.3.lf.el7
e293be