summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2018-03-26 16:58:03 +0300
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2018-04-19 19:01:50 +0300
commit36d91a4d401c284ab21213622c85cd855725f10f (patch)
tree5534d27f39b371b19157ceaf234ac9146a35ab59
parentc6d3a278cc1201a93677737db565c25c58b2cfe0 (diff)
downloadlinux-36d91a4d401c284ab21213622c85cd855725f10f.tar.xz
rtc: cmos: introduce quirks to enable use_acpi_alarm mode
Use ACPI for RTC Alarm only for Intel platforms 1. with Low Power S0 support 2. with HPET RTC emulation enabled 3. no earlier than 2015 Note that, during the test, it is found that this patch 1. works in 4.15-rc kernel 2. hangs the platform after suspend-to-idle for 2 or 3 times, in 4.15.0 3. works again in 4.16-rc3 kernel. 4. works in the latest 4.15.12 stable kernel. Thus although this patch breaks 4.15.0 kernel for some unknown reason, still, it is safe for both upstream and backport. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--drivers/rtc/rtc-cmos.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5171bade16f2..cd3a2411bc2f 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -43,6 +43,8 @@
#include <linux/of_platform.h>
#ifdef CONFIG_X86
#include <asm/i8259.h>
+#include <asm/processor.h>
+#include <linux/dmi.h>
#endif
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
@@ -1174,6 +1176,28 @@ static void rtc_wake_off(struct device *dev)
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
+#ifdef CONFIG_X86
+/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
+static void use_acpi_alarm_quirks(void)
+{
+ int year;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+ return;
+
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
+ return;
+
+ if (!is_hpet_enabled())
+ return;
+
+ if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
+ use_acpi_alarm = true;
+}
+#else
+static inline void use_acpi_alarm_quirks(void) { }
+#endif
+
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -1186,6 +1210,8 @@ static void cmos_wake_setup(struct device *dev)
if (acpi_disabled)
return;
+ use_acpi_alarm_quirks();
+
rtc_wake_setup(dev);
acpi_rtc_info.wake_on = rtc_wake_on;
acpi_rtc_info.wake_off = rtc_wake_off;