diff options
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f14876256a4a..a2325bc5e497 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -34,11 +34,11 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | ||
38 | #include <linux/log2.h> | 37 | #include <linux/log2.h> |
39 | #include <linux/pm.h> | 38 | #include <linux/pm.h> |
40 | #include <linux/of.h> | 39 | #include <linux/of.h> |
41 | #include <linux/of_platform.h> | 40 | #include <linux/of_platform.h> |
41 | #include <linux/dmi.h> | ||
42 | 42 | ||
43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
44 | #include <asm-generic/rtc.h> | 44 | #include <asm-generic/rtc.h> |
@@ -377,6 +377,51 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | 379 | ||
380 | /* | ||
381 | * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. | ||
382 | */ | ||
383 | static bool alarm_disable_quirk; | ||
384 | |||
385 | static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) | ||
386 | { | ||
387 | alarm_disable_quirk = true; | ||
388 | pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); | ||
389 | pr_info("RTC alarms disabled\n"); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static const struct dmi_system_id rtc_quirks[] __initconst = { | ||
394 | /* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ | ||
395 | { | ||
396 | .callback = set_alarm_disable_quirk, | ||
397 | .ident = "IBM Truman", | ||
398 | .matches = { | ||
399 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
400 | DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), | ||
401 | }, | ||
402 | }, | ||
403 | /* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ | ||
404 | { | ||
405 | .callback = set_alarm_disable_quirk, | ||
406 | .ident = "Gigabyte GA-990XA-UD3", | ||
407 | .matches = { | ||
408 | DMI_MATCH(DMI_SYS_VENDOR, | ||
409 | "Gigabyte Technology Co., Ltd."), | ||
410 | DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), | ||
411 | }, | ||
412 | }, | ||
413 | /* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ | ||
414 | { | ||
415 | .callback = set_alarm_disable_quirk, | ||
416 | .ident = "Toshiba Satellite L300", | ||
417 | .matches = { | ||
418 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
419 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), | ||
420 | }, | ||
421 | }, | ||
422 | {} | ||
423 | }; | ||
424 | |||
380 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) | 425 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) |
381 | { | 426 | { |
382 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 427 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
@@ -385,6 +430,9 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
385 | if (!is_valid_irq(cmos->irq)) | 430 | if (!is_valid_irq(cmos->irq)) |
386 | return -EINVAL; | 431 | return -EINVAL; |
387 | 432 | ||
433 | if (alarm_disable_quirk) | ||
434 | return 0; | ||
435 | |||
388 | spin_lock_irqsave(&rtc_lock, flags); | 436 | spin_lock_irqsave(&rtc_lock, flags); |
389 | 437 | ||
390 | if (enabled) | 438 | if (enabled) |
@@ -1157,6 +1205,8 @@ static int __init cmos_init(void) | |||
1157 | platform_driver_registered = true; | 1205 | platform_driver_registered = true; |
1158 | } | 1206 | } |
1159 | 1207 | ||
1208 | dmi_check_system(rtc_quirks); | ||
1209 | |||
1160 | if (retval == 0) | 1210 | if (retval == 0) |
1161 | return 0; | 1211 | return 0; |
1162 | 1212 | ||