aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_video.c27
-rw-r--r--drivers/acpi/acpi_watchdog.c59
-rw-r--r--drivers/acpi/button.c24
3 files changed, 97 insertions, 13 deletions
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 76fb96966f7b..2f2e737be0f8 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2123,6 +2123,25 @@ static int __init intel_opregion_present(void)
2123 return opregion; 2123 return opregion;
2124} 2124}
2125 2125
2126static bool dmi_is_desktop(void)
2127{
2128 const char *chassis_type;
2129
2130 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
2131 if (!chassis_type)
2132 return false;
2133
2134 if (!strcmp(chassis_type, "3") || /* 3: Desktop */
2135 !strcmp(chassis_type, "4") || /* 4: Low Profile Desktop */
2136 !strcmp(chassis_type, "5") || /* 5: Pizza Box */
2137 !strcmp(chassis_type, "6") || /* 6: Mini Tower */
2138 !strcmp(chassis_type, "7") || /* 7: Tower */
2139 !strcmp(chassis_type, "11")) /* 11: Main Server Chassis */
2140 return true;
2141
2142 return false;
2143}
2144
2126int acpi_video_register(void) 2145int acpi_video_register(void)
2127{ 2146{
2128 int ret = 0; 2147 int ret = 0;
@@ -2143,8 +2162,12 @@ int acpi_video_register(void)
2143 * win8 ready (where we also prefer the native backlight driver, so 2162 * win8 ready (where we also prefer the native backlight driver, so
2144 * normally the acpi_video code should not register there anyways). 2163 * normally the acpi_video code should not register there anyways).
2145 */ 2164 */
2146 if (only_lcd == -1) 2165 if (only_lcd == -1) {
2147 only_lcd = acpi_osi_is_win8(); 2166 if (dmi_is_desktop() && acpi_osi_is_win8())
2167 only_lcd = true;
2168 else
2169 only_lcd = false;
2170 }
2148 2171
2149 dmi_check_system(video_dmi_table); 2172 dmi_check_system(video_dmi_table);
2150 2173
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
index ebb626ffb5fa..4bde16fb97d8 100644
--- a/drivers/acpi/acpi_watchdog.c
+++ b/drivers/acpi/acpi_watchdog.c
@@ -12,23 +12,64 @@
12#define pr_fmt(fmt) "ACPI: watchdog: " fmt 12#define pr_fmt(fmt) "ACPI: watchdog: " fmt
13 13
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/dmi.h>
15#include <linux/ioport.h> 16#include <linux/ioport.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17 18
18#include "internal.h" 19#include "internal.h"
19 20
21static const struct dmi_system_id acpi_watchdog_skip[] = {
22 {
23 /*
24 * On Lenovo Z50-70 there are two issues with the WDAT
25 * table. First some of the instructions use RTC SRAM
26 * to store persistent information. This does not work well
27 * with Linux RTC driver. Second, more important thing is
28 * that the instructions do not actually reset the system.
29 *
30 * On this particular system iTCO_wdt seems to work just
31 * fine so we prefer that over WDAT for now.
32 *
33 * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
34 */
35 .ident = "Lenovo Z50-70",
36 .matches = {
37 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
38 DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
39 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
40 },
41 },
42 {}
43};
44
45static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
46{
47 const struct acpi_table_wdat *wdat = NULL;
48 acpi_status status;
49
50 if (acpi_disabled)
51 return NULL;
52
53 if (dmi_check_system(acpi_watchdog_skip))
54 return NULL;
55
56 status = acpi_get_table(ACPI_SIG_WDAT, 0,
57 (struct acpi_table_header **)&wdat);
58 if (ACPI_FAILURE(status)) {
59 /* It is fine if there is no WDAT */
60 return NULL;
61 }
62
63 return wdat;
64}
65
20/** 66/**
21 * Returns true if this system should prefer ACPI based watchdog instead of 67 * Returns true if this system should prefer ACPI based watchdog instead of
22 * the native one (which are typically the same hardware). 68 * the native one (which are typically the same hardware).
23 */ 69 */
24bool acpi_has_watchdog(void) 70bool acpi_has_watchdog(void)
25{ 71{
26 struct acpi_table_header hdr; 72 return !!acpi_watchdog_get_wdat();
27
28 if (acpi_disabled)
29 return false;
30
31 return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr));
32} 73}
33EXPORT_SYMBOL_GPL(acpi_has_watchdog); 74EXPORT_SYMBOL_GPL(acpi_has_watchdog);
34 75
@@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void)
41 struct platform_device *pdev; 82 struct platform_device *pdev;
42 struct resource *resources; 83 struct resource *resources;
43 size_t nresources = 0; 84 size_t nresources = 0;
44 acpi_status status;
45 int i; 85 int i;
46 86
47 status = acpi_get_table(ACPI_SIG_WDAT, 0, 87 wdat = acpi_watchdog_get_wdat();
48 (struct acpi_table_header **)&wdat); 88 if (!wdat) {
49 if (ACPI_FAILURE(status)) {
50 /* It is fine if there is no WDAT */ 89 /* It is fine if there is no WDAT */
51 return; 90 return;
52 } 91 }
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index e1eee7a60fad..f1cc4f9d31cd 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -635,4 +635,26 @@ module_param_call(lid_init_state,
635 NULL, 0644); 635 NULL, 0644);
636MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); 636MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
637 637
638module_acpi_driver(acpi_button_driver); 638static int acpi_button_register_driver(struct acpi_driver *driver)
639{
640 /*
641 * Modules such as nouveau.ko and i915.ko have a link time dependency
642 * on acpi_lid_open(), and would therefore not be loadable on ACPI
643 * capable kernels booted in non-ACPI mode if the return value of
644 * acpi_bus_register_driver() is returned from here with ACPI disabled
645 * when this driver is built as a module.
646 */
647 if (acpi_disabled)
648 return 0;
649
650 return acpi_bus_register_driver(driver);
651}
652
653static void acpi_button_unregister_driver(struct acpi_driver *driver)
654{
655 if (!acpi_disabled)
656 acpi_bus_unregister_driver(driver);
657}
658
659module_driver(acpi_button_driver, acpi_button_register_driver,
660 acpi_button_unregister_driver);