]>
Commit | Line | Data |
---|---|---|
ef421410 GKH |
1 | From d5a1c7e3fc38d9c7d629e1e47f32f863acbdec3d Mon Sep 17 00:00:00 2001 |
2 | From: Borislav Petkov <bp@alien8.de> | |
3 | Date: Sat, 20 Jul 2013 19:00:23 +0200 | |
4 | Subject: rtc-cmos: Add an alarm disable quirk | |
5 | ||
6 | From: Borislav Petkov <bp@alien8.de> | |
7 | ||
8 | commit d5a1c7e3fc38d9c7d629e1e47f32f863acbdec3d upstream. | |
9 | ||
10 | 41c7f7424259f ("rtc: Disable the alarm in the hardware (v2)") added the | |
11 | functionality to disable the RTC wake alarm when shutting down the box. | |
12 | ||
13 | However, there are at least two b0rked BIOSes we know about: | |
14 | ||
15 | https://bugzilla.novell.com/show_bug.cgi?id=812592 | |
16 | https://bugzilla.novell.com/show_bug.cgi?id=805740 | |
17 | ||
18 | where, when wakeup alarm is enabled in the BIOS, the machine reboots | |
19 | automatically right after shutdown, regardless of what wakeup time is | |
20 | programmed. | |
21 | ||
22 | Bisecting the issue lead to this patch so disable its functionality with | |
23 | a DMI quirk only for those boxes. | |
24 | ||
25 | Cc: Brecht Machiels <brecht@mos6581.org> | |
26 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
27 | Cc: John Stultz <john.stultz@linaro.org> | |
28 | Cc: Rabin Vincent <rabin.vincent@stericsson.com> | |
29 | Signed-off-by: Borislav Petkov <bp@suse.de> | |
30 | [jstultz: Changed variable name for clarity, added extra dmi entry] | |
31 | Tested-by: Brecht Machiels <brecht@mos6581.org> | |
32 | Tested-by: Borislav Petkov <bp@suse.de> | |
33 | Signed-off-by: John Stultz <john.stultz@linaro.org> | |
34 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
35 | ||
36 | --- | |
37 | drivers/rtc/rtc-cmos.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++- | |
38 | 1 file changed, 51 insertions(+), 1 deletion(-) | |
39 | ||
40 | --- a/drivers/rtc/rtc-cmos.c | |
41 | +++ b/drivers/rtc/rtc-cmos.c | |
42 | @@ -34,11 +34,11 @@ | |
43 | #include <linux/interrupt.h> | |
44 | #include <linux/spinlock.h> | |
45 | #include <linux/platform_device.h> | |
46 | -#include <linux/mod_devicetable.h> | |
47 | #include <linux/log2.h> | |
48 | #include <linux/pm.h> | |
49 | #include <linux/of.h> | |
50 | #include <linux/of_platform.h> | |
51 | +#include <linux/dmi.h> | |
52 | ||
53 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | |
54 | #include <asm-generic/rtc.h> | |
55 | @@ -377,6 +377,51 @@ static int cmos_set_alarm(struct device | |
56 | return 0; | |
57 | } | |
58 | ||
59 | +/* | |
60 | + * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. | |
61 | + */ | |
62 | +static bool alarm_disable_quirk; | |
63 | + | |
64 | +static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) | |
65 | +{ | |
66 | + alarm_disable_quirk = true; | |
67 | + pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); | |
68 | + pr_info("RTC alarms disabled\n"); | |
69 | + return 0; | |
70 | +} | |
71 | + | |
72 | +static const struct dmi_system_id rtc_quirks[] __initconst = { | |
73 | + /* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ | |
74 | + { | |
75 | + .callback = set_alarm_disable_quirk, | |
76 | + .ident = "IBM Truman", | |
77 | + .matches = { | |
78 | + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
79 | + DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), | |
80 | + }, | |
81 | + }, | |
82 | + /* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ | |
83 | + { | |
84 | + .callback = set_alarm_disable_quirk, | |
85 | + .ident = "Gigabyte GA-990XA-UD3", | |
86 | + .matches = { | |
87 | + DMI_MATCH(DMI_SYS_VENDOR, | |
88 | + "Gigabyte Technology Co., Ltd."), | |
89 | + DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), | |
90 | + }, | |
91 | + }, | |
92 | + /* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ | |
93 | + { | |
94 | + .callback = set_alarm_disable_quirk, | |
95 | + .ident = "Toshiba Satellite L300", | |
96 | + .matches = { | |
97 | + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
98 | + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), | |
99 | + }, | |
100 | + }, | |
101 | + {} | |
102 | +}; | |
103 | + | |
104 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) | |
105 | { | |
106 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | |
107 | @@ -385,6 +430,9 @@ static int cmos_alarm_irq_enable(struct | |
108 | if (!is_valid_irq(cmos->irq)) | |
109 | return -EINVAL; | |
110 | ||
111 | + if (alarm_disable_quirk) | |
112 | + return 0; | |
113 | + | |
114 | spin_lock_irqsave(&rtc_lock, flags); | |
115 | ||
116 | if (enabled) | |
117 | @@ -1163,6 +1211,8 @@ static int __init cmos_init(void) | |
118 | platform_driver_registered = true; | |
119 | } | |
120 | ||
121 | + dmi_check_system(rtc_quirks); | |
122 | + | |
123 | if (retval == 0) | |
124 | return 0; | |
125 |