Merge branches 'acpi-watchdog', 'acpi-button' and 'acpi-video'
* acpi-watchdog: ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70 * acpi-button: ACPI / button: make module loadable when booted in non-ACPI mode * acpi-video: ACPI / video: Only default only_lcd to true on Win8-ready _desktops_
This commit is contained in:
commit
bd6dff55de
|
@ -2123,6 +2123,25 @@ static int __init intel_opregion_present(void)
|
||||||
return opregion;
|
return opregion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool dmi_is_desktop(void)
|
||||||
|
{
|
||||||
|
const char *chassis_type;
|
||||||
|
|
||||||
|
chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
|
||||||
|
if (!chassis_type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!strcmp(chassis_type, "3") || /* 3: Desktop */
|
||||||
|
!strcmp(chassis_type, "4") || /* 4: Low Profile Desktop */
|
||||||
|
!strcmp(chassis_type, "5") || /* 5: Pizza Box */
|
||||||
|
!strcmp(chassis_type, "6") || /* 6: Mini Tower */
|
||||||
|
!strcmp(chassis_type, "7") || /* 7: Tower */
|
||||||
|
!strcmp(chassis_type, "11")) /* 11: Main Server Chassis */
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int acpi_video_register(void)
|
int acpi_video_register(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -2143,8 +2162,12 @@ int acpi_video_register(void)
|
||||||
* win8 ready (where we also prefer the native backlight driver, so
|
* win8 ready (where we also prefer the native backlight driver, so
|
||||||
* normally the acpi_video code should not register there anyways).
|
* normally the acpi_video code should not register there anyways).
|
||||||
*/
|
*/
|
||||||
if (only_lcd == -1)
|
if (only_lcd == -1) {
|
||||||
only_lcd = acpi_osi_is_win8();
|
if (dmi_is_desktop() && acpi_osi_is_win8())
|
||||||
|
only_lcd = true;
|
||||||
|
else
|
||||||
|
only_lcd = false;
|
||||||
|
}
|
||||||
|
|
||||||
dmi_check_system(video_dmi_table);
|
dmi_check_system(video_dmi_table);
|
||||||
|
|
||||||
|
|
|
@ -12,23 +12,64 @@
|
||||||
#define pr_fmt(fmt) "ACPI: watchdog: " fmt
|
#define pr_fmt(fmt) "ACPI: watchdog: " fmt
|
||||||
|
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
static const struct dmi_system_id acpi_watchdog_skip[] = {
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* On Lenovo Z50-70 there are two issues with the WDAT
|
||||||
|
* table. First some of the instructions use RTC SRAM
|
||||||
|
* to store persistent information. This does not work well
|
||||||
|
* with Linux RTC driver. Second, more important thing is
|
||||||
|
* that the instructions do not actually reset the system.
|
||||||
|
*
|
||||||
|
* On this particular system iTCO_wdt seems to work just
|
||||||
|
* fine so we prefer that over WDAT for now.
|
||||||
|
*
|
||||||
|
* See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
|
||||||
|
*/
|
||||||
|
.ident = "Lenovo Z50-70",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
|
||||||
|
{
|
||||||
|
const struct acpi_table_wdat *wdat = NULL;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
if (acpi_disabled)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (dmi_check_system(acpi_watchdog_skip))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
status = acpi_get_table(ACPI_SIG_WDAT, 0,
|
||||||
|
(struct acpi_table_header **)&wdat);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
/* It is fine if there is no WDAT */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wdat;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this system should prefer ACPI based watchdog instead of
|
* Returns true if this system should prefer ACPI based watchdog instead of
|
||||||
* the native one (which are typically the same hardware).
|
* the native one (which are typically the same hardware).
|
||||||
*/
|
*/
|
||||||
bool acpi_has_watchdog(void)
|
bool acpi_has_watchdog(void)
|
||||||
{
|
{
|
||||||
struct acpi_table_header hdr;
|
return !!acpi_watchdog_get_wdat();
|
||||||
|
|
||||||
if (acpi_disabled)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr));
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_has_watchdog);
|
EXPORT_SYMBOL_GPL(acpi_has_watchdog);
|
||||||
|
|
||||||
|
@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void)
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct resource *resources;
|
struct resource *resources;
|
||||||
size_t nresources = 0;
|
size_t nresources = 0;
|
||||||
acpi_status status;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
status = acpi_get_table(ACPI_SIG_WDAT, 0,
|
wdat = acpi_watchdog_get_wdat();
|
||||||
(struct acpi_table_header **)&wdat);
|
if (!wdat) {
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
/* It is fine if there is no WDAT */
|
/* It is fine if there is no WDAT */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,4 +635,26 @@ module_param_call(lid_init_state,
|
||||||
NULL, 0644);
|
NULL, 0644);
|
||||||
MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
|
MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
|
||||||
|
|
||||||
module_acpi_driver(acpi_button_driver);
|
static int acpi_button_register_driver(struct acpi_driver *driver)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Modules such as nouveau.ko and i915.ko have a link time dependency
|
||||||
|
* on acpi_lid_open(), and would therefore not be loadable on ACPI
|
||||||
|
* capable kernels booted in non-ACPI mode if the return value of
|
||||||
|
* acpi_bus_register_driver() is returned from here with ACPI disabled
|
||||||
|
* when this driver is built as a module.
|
||||||
|
*/
|
||||||
|
if (acpi_disabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return acpi_bus_register_driver(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acpi_button_unregister_driver(struct acpi_driver *driver)
|
||||||
|
{
|
||||||
|
if (!acpi_disabled)
|
||||||
|
acpi_bus_unregister_driver(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_driver(acpi_button_driver, acpi_button_register_driver,
|
||||||
|
acpi_button_unregister_driver);
|
||||||
|
|
Loading…
Reference in New Issue