|
@@ -33,6 +33,7 @@
|
|
#include <linux/interrupt.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/kmod.h>
|
|
#include <linux/kmod.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/delay.h>
|
|
|
|
+#include <linux/dmi.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/acpi.h>
|
|
#include <linux/acpi.h>
|
|
@@ -76,6 +77,18 @@ static struct workqueue_struct *kacpi_notify_wq;
|
|
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
|
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
|
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
|
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
|
|
|
|
|
|
|
+#define OSI_LINUX_ENABLED
|
|
|
|
+#ifdef OSI_LINUX_ENABLED
|
|
|
|
+int osi_linux = 1; /* enable _OSI(Linux) by default */
|
|
|
|
+#else
|
|
|
|
+int osi_linux; /* disable _OSI(Linux) by default */
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DMI
|
|
|
|
+static struct dmi_system_id acpi_osl_dmi_table[];
|
|
|
|
+#endif
|
|
|
|
+
|
|
static void __init acpi_request_region (struct acpi_generic_address *addr,
|
|
static void __init acpi_request_region (struct acpi_generic_address *addr,
|
|
unsigned int length, char *desc)
|
|
unsigned int length, char *desc)
|
|
{
|
|
{
|
|
@@ -126,6 +139,7 @@ device_initcall(acpi_reserve_resources);
|
|
|
|
|
|
acpi_status acpi_os_initialize(void)
|
|
acpi_status acpi_os_initialize(void)
|
|
{
|
|
{
|
|
|
|
+ dmi_check_system(acpi_osl_dmi_table);
|
|
return AE_OK;
|
|
return AE_OK;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -963,6 +977,16 @@ static int __init acpi_os_name_setup(char *str)
|
|
|
|
|
|
__setup("acpi_os_name=", acpi_os_name_setup);
|
|
__setup("acpi_os_name=", acpi_os_name_setup);
|
|
|
|
|
|
|
|
+static void enable_osi_linux(int enable) {
|
|
|
|
+
|
|
|
|
+ if (osi_linux != enable)
|
|
|
|
+ printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
|
|
|
|
+ enable ? "En": "Dis");
|
|
|
|
+
|
|
|
|
+ osi_linux = enable;
|
|
|
|
+ return;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Modify the list of "OS Interfaces" reported to BIOS via _OSI
|
|
* Modify the list of "OS Interfaces" reported to BIOS via _OSI
|
|
*
|
|
*
|
|
@@ -978,6 +1002,10 @@ static int __init acpi_osi_setup(char *str)
|
|
} else if (*str == '!') {
|
|
} else if (*str == '!') {
|
|
if (acpi_osi_invalidate(++str) == AE_OK)
|
|
if (acpi_osi_invalidate(++str) == AE_OK)
|
|
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
|
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
|
|
|
+ } else if (!strcmp("!Linux", str)) {
|
|
|
|
+ enable_osi_linux(0);
|
|
|
|
+ } else if (!strcmp("Linux", str)) {
|
|
|
|
+ enable_osi_linux(1);
|
|
} else if (*osi_additional_string == '\0') {
|
|
} else if (*osi_additional_string == '\0') {
|
|
strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
|
|
strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
|
|
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
|
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
|
@@ -1152,6 +1180,23 @@ acpi_os_validate_interface (char *interface)
|
|
{
|
|
{
|
|
if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
|
|
if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
|
|
return AE_OK;
|
|
return AE_OK;
|
|
|
|
+ if (!strcmp("Linux", interface)) {
|
|
|
|
+ printk(KERN_WARNING PREFIX
|
|
|
|
+ "System BIOS is requesting _OSI(Linux)\n");
|
|
|
|
+#ifdef OSI_LINUX_ENABLED
|
|
|
|
+ printk(KERN_WARNING PREFIX
|
|
|
|
+ "Please test with \"acpi_osi=!Linux\"\n"
|
|
|
|
+ "Please send dmidecode "
|
|
|
|
+ "to linux-acpi@vger.kernel.org\n");
|
|
|
|
+#else
|
|
|
|
+ printk(KERN_WARNING PREFIX
|
|
|
|
+ "If \"acpi_osi=Linux\" works better,\n"
|
|
|
|
+ "Please send dmidecode "
|
|
|
|
+ "to linux-acpi@vger.kernel.org\n");
|
|
|
|
+#endif
|
|
|
|
+ if(osi_linux)
|
|
|
|
+ return AE_OK;
|
|
|
|
+ }
|
|
return AE_SUPPORT;
|
|
return AE_SUPPORT;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1181,5 +1226,51 @@ acpi_os_validate_address (
|
|
return AE_OK;
|
|
return AE_OK;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_DMI
|
|
|
|
+#ifdef OSI_LINUX_ENABLED
|
|
|
|
+static int dmi_osi_not_linux(struct dmi_system_id *d)
|
|
|
|
+{
|
|
|
|
+ printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
|
|
|
|
+ enable_osi_linux(0);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static int dmi_osi_linux(struct dmi_system_id *d)
|
|
|
|
+{
|
|
|
|
+ printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident);
|
|
|
|
+ enable_osi_linux(1);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static struct dmi_system_id acpi_osl_dmi_table[] = {
|
|
|
|
+#ifdef OSI_LINUX_ENABLED
|
|
|
|
+ /*
|
|
|
|
+ * Boxes that need NOT _OSI(Linux)
|
|
|
|
+ */
|
|
|
|
+ {
|
|
|
|
+ .callback = dmi_osi_not_linux,
|
|
|
|
+ .ident = "Toshiba Satellite P100",
|
|
|
|
+ .matches = {
|
|
|
|
+ DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
|
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+#else
|
|
|
|
+ /*
|
|
|
|
+ * Boxes that need _OSI(Linux)
|
|
|
|
+ */
|
|
|
|
+ {
|
|
|
|
+ .callback = dmi_osi_linux,
|
|
|
|
+ .ident = "Intel Napa CRB",
|
|
|
|
+ .matches = {
|
|
|
|
+ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
|
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+#endif
|
|
|
|
+ {}
|
|
|
|
+};
|
|
|
|
+#endif /* CONFIG_DMI */
|
|
|
|
|
|
#endif
|
|
#endif
|