#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/delay.h>
+#include <linux/dmi.h>
#include <linux/workqueue.h>
#include <linux/nmi.h>
#include <linux/acpi.h>
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
+static int osi_linux; /* disable _OSI(Linux) by default */
+
+#ifdef CONFIG_DMI
+static struct __initdata dmi_system_id acpi_osl_dmi_table[];
+#endif
+
static void __init acpi_request_region (struct acpi_generic_address *addr,
unsigned int length, char *desc)
{
}
device_initcall(acpi_reserve_resources);
-acpi_status acpi_os_initialize(void)
+acpi_status __init acpi_os_initialize(void)
{
+ dmi_check_system(acpi_osl_dmi_table);
return AE_OK;
}
__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
*
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
+ } else if (!strcmp("!Linux", str)) {
+ enable_osi_linux(0);
} else if (*str == '!') {
if (acpi_osi_invalidate(++str) == AE_OK)
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ } else if (!strcmp("Linux", str)) {
+ enable_osi_linux(1);
} else if (*osi_additional_string == '\0') {
strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
-/*
- * max_cstate is defined in the base kernel so modules can
- * change it w/o depending on the state of the processor module.
- */
-unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
-
-EXPORT_SYMBOL(max_cstate);
-
/*
* Acquire a spinlock.
*
acpi_status
acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
{
- *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL);
+ *cache = kmem_cache_create(name, size, 0, 0, NULL);
if (*cache == NULL)
return AE_ERROR;
else
{
if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
return AE_OK;
+ if (!strcmp("Linux", interface)) {
+ printk(KERN_WARNING PREFIX
+ "System BIOS is requesting _OSI(Linux)\n");
+ printk(KERN_WARNING PREFIX
+ "If \"acpi_osi=Linux\" works better,\n"
+ "Please send dmidecode "
+ "to linux-acpi@vger.kernel.org\n");
+ if(osi_linux)
+ return AE_OK;
+ }
return AE_SUPPORT;
}
return AE_OK;
}
+#ifdef CONFIG_DMI
+static int dmi_osi_linux(struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident);
+ enable_osi_linux(1);
+ return 0;
+}
+
+static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
+ /*
+ * 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 /* CONFIG_DMI */
#endif