diff options
Diffstat (limited to 'drivers/acpi/osl.c')
| -rw-r--r-- | drivers/acpi/osl.c | 113 | 
1 files changed, 77 insertions, 36 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1..055d7b701ff 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -110,9 +110,6 @@ struct acpi_ioremap {  static LIST_HEAD(acpi_ioremaps);  static DEFINE_SPINLOCK(acpi_ioremap_lock); -#define	OSI_STRING_LENGTH_MAX 64	/* arbitrary */ -static char osi_setup_string[OSI_STRING_LENGTH_MAX]; -  static void __init acpi_osi_setup_late(void);  /* @@ -152,8 +149,7 @@ static struct osi_linux {  	unsigned int	enable:1;  	unsigned int	dmi:1;  	unsigned int	cmdline:1; -	unsigned int	known:1; -} osi_linux = { 0, 0, 0, 0}; +} osi_linux = {0, 0, 0};  static u32 acpi_osi_handler(acpi_string interface, u32 supported)  { @@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)  __setup("acpi_os_name=", acpi_os_name_setup); +#define	OSI_STRING_LENGTH_MAX 64	/* arbitrary */ +#define	OSI_STRING_ENTRIES_MAX 16	/* arbitrary */ + +struct osi_setup_entry { +	char string[OSI_STRING_LENGTH_MAX]; +	bool enable; +}; + +static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; + +void __init acpi_osi_setup(char *str) +{ +	struct osi_setup_entry *osi; +	bool enable = true; +	int i; + +	if (!acpi_gbl_create_osi_method) +		return; + +	if (str == NULL || *str == '\0') { +		printk(KERN_INFO PREFIX "_OSI method disabled\n"); +		acpi_gbl_create_osi_method = FALSE; +		return; +	} + +	if (*str == '!') { +		str++; +		enable = false; +	} + +	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { +		osi = &osi_setup_entries[i]; +		if (!strcmp(osi->string, str)) { +			osi->enable = enable; +			break; +		} else if (osi->string[0] == '\0') { +			osi->enable = enable; +			strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); +			break; +		} +	} +} +  static void __init set_osi_linux(unsigned int enable)  { -	if (osi_linux.enable != enable) { +	if (osi_linux.enable != enable)  		osi_linux.enable = enable; -		printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", -			enable ? "Add": "Delet"); -	}  	if (osi_linux.enable)  		acpi_osi_setup("Linux"); @@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)  static void __init acpi_cmdline_osi_linux(unsigned int enable)  { -	osi_linux.cmdline = 1;	/* cmdline set the default */ +	osi_linux.cmdline = 1;	/* cmdline set the default and override DMI */ +	osi_linux.dmi = 0;  	set_osi_linux(enable);  	return; @@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)  void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)  { -	osi_linux.dmi = 1;	/* DMI knows that this box asks OSI(Linux) */ -  	printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);  	if (enable == -1)  		return; -	osi_linux.known = 1;	/* DMI knows which OSI(Linux) default needed */ - +	osi_linux.dmi = 1;	/* DMI knows that this box asks OSI(Linux) */  	set_osi_linux(enable);  	return; @@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)   */  static void __init acpi_osi_setup_late(void)  { -	char *str = osi_setup_string; +	struct osi_setup_entry *osi; +	char *str; +	int i; +	acpi_status status; -	if (*str == '\0') -		return; +	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { +		osi = &osi_setup_entries[i]; +		str = osi->string; -	if (!strcmp("!Linux", str)) { -		acpi_cmdline_osi_linux(0);	/* !enable */ -	} else if (*str == '!') { -		if (acpi_remove_interface(++str) == AE_OK) -			printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); -	} else if (!strcmp("Linux", str)) { -		acpi_cmdline_osi_linux(1);	/* enable */ -	} else { -		if (acpi_install_interface(str) == AE_OK) -			printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); +		if (*str == '\0') +			break; +		if (osi->enable) { +			status = acpi_install_interface(str); + +			if (ACPI_SUCCESS(status)) +				printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); +		} else { +			status = acpi_remove_interface(str); + +			if (ACPI_SUCCESS(status)) +				printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); +		}  	}  } -int __init acpi_osi_setup(char *str) +static int __init osi_setup(char *str)  { -	if (str == NULL || *str == '\0') { -		printk(KERN_INFO PREFIX "_OSI method disabled\n"); -		acpi_gbl_create_osi_method = FALSE; -	} else { -		strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); -	} +	if (str && !strcmp("Linux", str)) +		acpi_cmdline_osi_linux(1); +	else if (str && !strcmp("!Linux", str)) +		acpi_cmdline_osi_linux(0); +	else +		acpi_osi_setup(str);  	return 1;  } -__setup("acpi_osi=", acpi_osi_setup); +__setup("acpi_osi=", osi_setup);  /* enable serialization to combat AE_ALREADY_EXISTS errors */  static int __init acpi_serialize_setup(char *str) @@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)  	return AE_OK;  } -acpi_status acpi_os_initialize1(void) +acpi_status __init acpi_os_initialize1(void)  {  	kacpid_wq = create_workqueue("kacpid");  	kacpi_notify_wq = create_workqueue("kacpi_notify");  |