diff options
| -rw-r--r-- | drivers/acpi/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
| -rw-r--r-- | drivers/acpi/ac.c | 117 | ||||
| -rw-r--r-- | drivers/acpi/acpi_platform.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/acpi_processor.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/acpica/acglobal.h | 4 | ||||
| -rw-r--r-- | drivers/acpi/acpica/tbutils.c | 7 | ||||
| -rw-r--r-- | drivers/acpi/battery.c | 329 | ||||
| -rw-r--r-- | drivers/acpi/blacklist.c | 21 | ||||
| -rw-r--r-- | drivers/acpi/cm_sbs.c | 105 | ||||
| -rw-r--r-- | drivers/acpi/video.c | 16 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_ppi.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 34 | 
13 files changed, 568 insertions, 93 deletions
| diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ab686b310100..a34a22841002 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -47,6 +47,23 @@ config ACPI_SLEEP  	depends on SUSPEND || HIBERNATION  	default y +config ACPI_PROCFS_POWER +	bool "Deprecated power /proc/acpi directories" +	depends on PROC_FS +	help +	  For backwards compatibility, this option allows +          deprecated power /proc/acpi/ directories to exist, even when +          they have been replaced by functions in /sys. +          The deprecated directories (and their replacements) include: +	  /proc/acpi/battery/* (/sys/class/power_supply/*) +	  /proc/acpi/ac_adapter/* (sys/class/power_supply/*) +	  This option has no effect on /proc/acpi/ directories +	  and functions, which do not yet exist in /sys +	  This option, together with the proc directories, will be +	  deleted in the future. + +	  Say N to delete power /proc/acpi/ directories that have moved to /sys/ +  config ACPI_EC_DEBUGFS  	tristate "EC read/write access through /sys/kernel/debug/ec"  	default n diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 0331f91d56e6..bce34afadcd0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -47,6 +47,7 @@ acpi-y				+= sysfs.o  acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o  acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o  acpi-$(CONFIG_ACPI_NUMA)	+= numa.o +acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o  ifdef CONFIG_ACPI_VIDEO  acpi-y				+= video_detect.o  endif diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 2c01c1da29ce..c67f6f5ad611 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -52,11 +52,39 @@ MODULE_AUTHOR("Paul Diefenbaugh");  MODULE_DESCRIPTION("ACPI AC Adapter Driver");  MODULE_LICENSE("GPL"); +static int acpi_ac_add(struct acpi_device *device); +static int acpi_ac_remove(struct acpi_device *device); +static void acpi_ac_notify(struct acpi_device *device, u32 event); + +static const struct acpi_device_id ac_device_ids[] = { +	{"ACPI0003", 0}, +	{"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, ac_device_ids); + +#ifdef CONFIG_PM_SLEEP +static int acpi_ac_resume(struct device *dev); +#endif +static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); +  static int ac_sleep_before_get_state_ms; +static struct acpi_driver acpi_ac_driver = { +	.name = "ac", +	.class = ACPI_AC_CLASS, +	.ids = ac_device_ids, +	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, +	.ops = { +		.add = acpi_ac_add, +		.remove = acpi_ac_remove, +		.notify = acpi_ac_notify, +		}, +	.drv.pm = &acpi_ac_pm, +}; +  struct acpi_ac {  	struct power_supply charger; -	struct platform_device *pdev; +	struct acpi_device * device;  	unsigned long long state;  	struct notifier_block battery_nb;  }; @@ -69,10 +97,12 @@ struct acpi_ac {  static int acpi_ac_get_state(struct acpi_ac *ac)  { -	acpi_status status; -	acpi_handle handle = ACPI_HANDLE(&ac->pdev->dev); +	acpi_status status = AE_OK; + +	if (!ac) +		return -EINVAL; -	status = acpi_evaluate_integer(handle, "_PSR", NULL, +	status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,  				       &ac->state);  	if (ACPI_FAILURE(status)) {  		ACPI_EXCEPTION((AE_INFO, status, @@ -117,10 +147,9 @@ static enum power_supply_property ac_props[] = {                                     Driver Model     -------------------------------------------------------------------------- */ -static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) +static void acpi_ac_notify(struct acpi_device *device, u32 event)  { -	struct acpi_ac *ac = data; -	struct acpi_device *adev; +	struct acpi_ac *ac = acpi_driver_data(device);  	if (!ac)  		return; @@ -143,11 +172,10 @@ static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data)  			msleep(ac_sleep_before_get_state_ms);  		acpi_ac_get_state(ac); -		adev = ACPI_COMPANION(&ac->pdev->dev); -		acpi_bus_generate_netlink_event(adev->pnp.device_class, -						dev_name(&ac->pdev->dev), -						event, (u32) ac->state); -		acpi_notifier_call_chain(adev, event, (u32) ac->state); +		acpi_bus_generate_netlink_event(device->pnp.device_class, +						  dev_name(&device->dev), event, +						  (u32) ac->state); +		acpi_notifier_call_chain(device, event, (u32) ac->state);  		kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);  	} @@ -192,49 +220,39 @@ static struct dmi_system_id ac_dmi_table[] = {  	{},  }; -static int acpi_ac_probe(struct platform_device *pdev) +static int acpi_ac_add(struct acpi_device *device)  {  	int result = 0;  	struct acpi_ac *ac = NULL; -	struct acpi_device *adev; -	if (!pdev) -		return -EINVAL; -	adev = ACPI_COMPANION(&pdev->dev); -	if (!adev) -		return -ENODEV; +	if (!device) +		return -EINVAL;  	ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);  	if (!ac)  		return -ENOMEM; -	strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); -	strcpy(acpi_device_class(adev), ACPI_AC_CLASS); -	ac->pdev = pdev; -	platform_set_drvdata(pdev, ac); +	ac->device = device; +	strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); +	strcpy(acpi_device_class(device), ACPI_AC_CLASS); +	device->driver_data = ac;  	result = acpi_ac_get_state(ac);  	if (result)  		goto end; -	ac->charger.name = acpi_device_bid(adev); +	ac->charger.name = acpi_device_bid(device);  	ac->charger.type = POWER_SUPPLY_TYPE_MAINS;  	ac->charger.properties = ac_props;  	ac->charger.num_properties = ARRAY_SIZE(ac_props);  	ac->charger.get_property = get_ac_property; -	result = power_supply_register(&pdev->dev, &ac->charger); +	result = power_supply_register(&ac->device->dev, &ac->charger);  	if (result)  		goto end; -	result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), -			ACPI_ALL_NOTIFY, acpi_ac_notify_handler, ac); -	if (result) { -		power_supply_unregister(&ac->charger); -		goto end; -	}  	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", -	       acpi_device_name(adev), acpi_device_bid(adev), +	       acpi_device_name(device), acpi_device_bid(device),  	       ac->state ? "on-line" : "off-line");  	ac->battery_nb.notifier_call = acpi_ac_battery_notify; @@ -256,7 +274,7 @@ static int acpi_ac_resume(struct device *dev)  	if (!dev)  		return -EINVAL; -	ac = platform_get_drvdata(to_platform_device(dev)); +	ac = acpi_driver_data(to_acpi_device(dev));  	if (!ac)  		return -EINVAL; @@ -270,19 +288,17 @@ static int acpi_ac_resume(struct device *dev)  #else  #define acpi_ac_resume NULL  #endif -static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); -static int acpi_ac_remove(struct platform_device *pdev) +static int acpi_ac_remove(struct acpi_device *device)  { -	struct acpi_ac *ac; +	struct acpi_ac *ac = NULL; + -	if (!pdev) +	if (!device || !acpi_driver_data(device))  		return -EINVAL; -	acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), -			ACPI_ALL_NOTIFY, acpi_ac_notify_handler); +	ac = acpi_driver_data(device); -	ac = platform_get_drvdata(pdev);  	if (ac->charger.dev)  		power_supply_unregister(&ac->charger);  	unregister_acpi_notifier(&ac->battery_nb); @@ -292,23 +308,6 @@ static int acpi_ac_remove(struct platform_device *pdev)  	return 0;  } -static const struct acpi_device_id acpi_ac_match[] = { -	{ "ACPI0003", 0 }, -	{ } -}; -MODULE_DEVICE_TABLE(acpi, acpi_ac_match); - -static struct platform_driver acpi_ac_driver = { -	.probe          = acpi_ac_probe, -	.remove         = acpi_ac_remove, -	.driver         = { -		.name   = "acpi-ac", -		.owner  = THIS_MODULE, -		.pm     = &acpi_ac_pm_ops, -		.acpi_match_table = ACPI_PTR(acpi_ac_match), -	}, -}; -  static int __init acpi_ac_init(void)  {  	int result; @@ -316,7 +315,7 @@ static int __init acpi_ac_init(void)  	if (acpi_disabled)  		return -ENODEV; -	result = platform_driver_register(&acpi_ac_driver); +	result = acpi_bus_register_driver(&acpi_ac_driver);  	if (result < 0)  		return -ENODEV; @@ -325,7 +324,7 @@ static int __init acpi_ac_init(void)  static void __exit acpi_ac_exit(void)  { -	platform_driver_unregister(&acpi_ac_driver); +	acpi_bus_unregister_driver(&acpi_ac_driver);  }  module_init(acpi_ac_init);  module_exit(acpi_ac_exit); diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index dbfe49e5fd63..1d4950388fa1 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -29,7 +29,6 @@ ACPI_MODULE_NAME("platform");  static const struct acpi_device_id acpi_platform_device_ids[] = {  	{ "PNP0D40" }, -	{ "ACPI0003" },  	{ "VPC2004" },  	{ "BCM4752" }, diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b06f5f55ada9..52c81c49cc7d 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -405,7 +405,6 @@ static int acpi_processor_add(struct acpi_device *device,  		goto err;  	pr->dev = dev; -	dev->offline = pr->flags.need_hotplug_init;  	/* Trigger the processor driver's .probe() if present. */  	if (device_attach(dev) >= 0) diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 49bbc71fad54..a08a448068dd 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -141,9 +141,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);   * address. Although ACPICA adheres to the ACPI specification which   * requires the use of the corresponding 64-bit address if it is non-zero,   * some machines have been found to have a corrupted non-zero 64-bit - * address. Default is FALSE, do not favor the 32-bit addresses. + * address. Default is TRUE, favor the 32-bit addresses.   */ -ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE);  /*   * Optionally truncate I/O addresses to 16 bits. Provides compatibility diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index a4702eee91a8..9fb85f38de90 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -461,6 +461,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)  	u32 table_count;  	struct acpi_table_header *table;  	acpi_physical_address address; +	acpi_physical_address rsdt_address;  	u32 length;  	u8 *table_entry;  	acpi_status status; @@ -488,11 +489,14 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)  		 * as per the ACPI specification.  		 */  		address = (acpi_physical_address) rsdp->xsdt_physical_address; +		rsdt_address = +		    (acpi_physical_address) rsdp->rsdt_physical_address;  		table_entry_size = ACPI_XSDT_ENTRY_SIZE;  	} else {  		/* Root table is an RSDT (32-bit physical addresses) */  		address = (acpi_physical_address) rsdp->rsdt_physical_address; +		rsdt_address = address;  		table_entry_size = ACPI_RSDT_ENTRY_SIZE;  	} @@ -515,8 +519,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)  			/* Fall back to the RSDT */ -			address = -			    (acpi_physical_address) rsdp->rsdt_physical_address; +			address = rsdt_address;  			table_entry_size = ACPI_RSDT_ENTRY_SIZE;  		}  	} diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9a2c63b20050..6e7b2a12860d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -36,6 +36,12 @@  #include <linux/suspend.h>  #include <asm/unaligned.h> +#ifdef CONFIG_ACPI_PROCFS_POWER +#include <linux/proc_fs.h> +#include <linux/seq_file.h> +#include <asm/uaccess.h> +#endif +  #include <linux/acpi.h>  #include <linux/power_supply.h> @@ -64,6 +70,19 @@ static unsigned int cache_time = 1000;  module_param(cache_time, uint, 0644);  MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); +#ifdef CONFIG_ACPI_PROCFS_POWER +extern struct proc_dir_entry *acpi_lock_battery_dir(void); +extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); + +enum acpi_battery_files { +	info_tag = 0, +	state_tag, +	alarm_tag, +	ACPI_BATTERY_NUMFILES, +}; + +#endif +  static const struct acpi_device_id battery_device_ids[] = {  	{"PNP0C0A", 0},  	{"", 0}, @@ -299,6 +318,14 @@ static enum power_supply_property energy_battery_props[] = {  	POWER_SUPPLY_PROP_SERIAL_NUMBER,  }; +#ifdef CONFIG_ACPI_PROCFS_POWER +inline char *acpi_battery_units(struct acpi_battery *battery) +{ +	return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? +		"mA" : "mW"; +} +#endif +  /* --------------------------------------------------------------------------                                 Battery Management     -------------------------------------------------------------------------- */ @@ -717,6 +744,279 @@ static void acpi_battery_refresh(struct acpi_battery *battery)  }  /* -------------------------------------------------------------------------- +                              FS Interface (/proc) +   -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_PROCFS_POWER +static struct proc_dir_entry *acpi_battery_dir; + +static int acpi_battery_print_info(struct seq_file *seq, int result) +{ +	struct acpi_battery *battery = seq->private; + +	if (result) +		goto end; + +	seq_printf(seq, "present:                 %s\n", +		   acpi_battery_present(battery) ? "yes" : "no"); +	if (!acpi_battery_present(battery)) +		goto end; +	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "design capacity:         unknown\n"); +	else +		seq_printf(seq, "design capacity:         %d %sh\n", +			   battery->design_capacity, +			   acpi_battery_units(battery)); + +	if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "last full capacity:      unknown\n"); +	else +		seq_printf(seq, "last full capacity:      %d %sh\n", +			   battery->full_charge_capacity, +			   acpi_battery_units(battery)); + +	seq_printf(seq, "battery technology:      %srechargeable\n", +		   (!battery->technology)?"non-":""); + +	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "design voltage:          unknown\n"); +	else +		seq_printf(seq, "design voltage:          %d mV\n", +			   battery->design_voltage); +	seq_printf(seq, "design capacity warning: %d %sh\n", +		   battery->design_capacity_warning, +		   acpi_battery_units(battery)); +	seq_printf(seq, "design capacity low:     %d %sh\n", +		   battery->design_capacity_low, +		   acpi_battery_units(battery)); +	seq_printf(seq, "cycle count:		  %i\n", battery->cycle_count); +	seq_printf(seq, "capacity granularity 1:  %d %sh\n", +		   battery->capacity_granularity_1, +		   acpi_battery_units(battery)); +	seq_printf(seq, "capacity granularity 2:  %d %sh\n", +		   battery->capacity_granularity_2, +		   acpi_battery_units(battery)); +	seq_printf(seq, "model number:            %s\n", battery->model_number); +	seq_printf(seq, "serial number:           %s\n", battery->serial_number); +	seq_printf(seq, "battery type:            %s\n", battery->type); +	seq_printf(seq, "OEM info:                %s\n", battery->oem_info); +      end: +	if (result) +		seq_printf(seq, "ERROR: Unable to read battery info\n"); +	return result; +} + +static int acpi_battery_print_state(struct seq_file *seq, int result) +{ +	struct acpi_battery *battery = seq->private; + +	if (result) +		goto end; + +	seq_printf(seq, "present:                 %s\n", +		   acpi_battery_present(battery) ? "yes" : "no"); +	if (!acpi_battery_present(battery)) +		goto end; + +	seq_printf(seq, "capacity state:          %s\n", +			(battery->state & 0x04) ? "critical" : "ok"); +	if ((battery->state & 0x01) && (battery->state & 0x02)) +		seq_printf(seq, +			   "charging state:          charging/discharging\n"); +	else if (battery->state & 0x01) +		seq_printf(seq, "charging state:          discharging\n"); +	else if (battery->state & 0x02) +		seq_printf(seq, "charging state:          charging\n"); +	else +		seq_printf(seq, "charging state:          charged\n"); + +	if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "present rate:            unknown\n"); +	else +		seq_printf(seq, "present rate:            %d %s\n", +			   battery->rate_now, acpi_battery_units(battery)); + +	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "remaining capacity:      unknown\n"); +	else +		seq_printf(seq, "remaining capacity:      %d %sh\n", +			   battery->capacity_now, acpi_battery_units(battery)); +	if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) +		seq_printf(seq, "present voltage:         unknown\n"); +	else +		seq_printf(seq, "present voltage:         %d mV\n", +			   battery->voltage_now); +      end: +	if (result) +		seq_printf(seq, "ERROR: Unable to read battery state\n"); + +	return result; +} + +static int acpi_battery_print_alarm(struct seq_file *seq, int result) +{ +	struct acpi_battery *battery = seq->private; + +	if (result) +		goto end; + +	if (!acpi_battery_present(battery)) { +		seq_printf(seq, "present:                 no\n"); +		goto end; +	} +	seq_printf(seq, "alarm:                   "); +	if (!battery->alarm) +		seq_printf(seq, "unsupported\n"); +	else +		seq_printf(seq, "%u %sh\n", battery->alarm, +				acpi_battery_units(battery)); +      end: +	if (result) +		seq_printf(seq, "ERROR: Unable to read battery alarm\n"); +	return result; +} + +static ssize_t acpi_battery_write_alarm(struct file *file, +					const char __user * buffer, +					size_t count, loff_t * ppos) +{ +	int result = 0; +	char alarm_string[12] = { '\0' }; +	struct seq_file *m = file->private_data; +	struct acpi_battery *battery = m->private; + +	if (!battery || (count > sizeof(alarm_string) - 1)) +		return -EINVAL; +	if (!acpi_battery_present(battery)) { +		result = -ENODEV; +		goto end; +	} +	if (copy_from_user(alarm_string, buffer, count)) { +		result = -EFAULT; +		goto end; +	} +	alarm_string[count] = '\0'; +	battery->alarm = simple_strtol(alarm_string, NULL, 0); +	result = acpi_battery_set_alarm(battery); +      end: +	if (!result) +		return count; +	return result; +} + +typedef int(*print_func)(struct seq_file *seq, int result); + +static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { +	acpi_battery_print_info, +	acpi_battery_print_state, +	acpi_battery_print_alarm, +}; + +static int acpi_battery_read(int fid, struct seq_file *seq) +{ +	struct acpi_battery *battery = seq->private; +	int result = acpi_battery_update(battery); +	return acpi_print_funcs[fid](seq, result); +} + +#define DECLARE_FILE_FUNCTIONS(_name) \ +static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ +{ \ +	return acpi_battery_read(_name##_tag, seq); \ +} \ +static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ +{ \ +	return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ +} + +DECLARE_FILE_FUNCTIONS(info); +DECLARE_FILE_FUNCTIONS(state); +DECLARE_FILE_FUNCTIONS(alarm); + +#undef DECLARE_FILE_FUNCTIONS + +#define FILE_DESCRIPTION_RO(_name) \ +	{ \ +	.name = __stringify(_name), \ +	.mode = S_IRUGO, \ +	.ops = { \ +		.open = acpi_battery_##_name##_open_fs, \ +		.read = seq_read, \ +		.llseek = seq_lseek, \ +		.release = single_release, \ +		.owner = THIS_MODULE, \ +		}, \ +	} + +#define FILE_DESCRIPTION_RW(_name) \ +	{ \ +	.name = __stringify(_name), \ +	.mode = S_IFREG | S_IRUGO | S_IWUSR, \ +	.ops = { \ +		.open = acpi_battery_##_name##_open_fs, \ +		.read = seq_read, \ +		.llseek = seq_lseek, \ +		.write = acpi_battery_write_##_name, \ +		.release = single_release, \ +		.owner = THIS_MODULE, \ +		}, \ +	} + +static const struct battery_file { +	struct file_operations ops; +	umode_t mode; +	const char *name; +} acpi_battery_file[] = { +	FILE_DESCRIPTION_RO(info), +	FILE_DESCRIPTION_RO(state), +	FILE_DESCRIPTION_RW(alarm), +}; + +#undef FILE_DESCRIPTION_RO +#undef FILE_DESCRIPTION_RW + +static int acpi_battery_add_fs(struct acpi_device *device) +{ +	struct proc_dir_entry *entry = NULL; +	int i; + +	printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," +			" please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); +	if (!acpi_device_dir(device)) { +		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), +						     acpi_battery_dir); +		if (!acpi_device_dir(device)) +			return -ENODEV; +	} + +	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { +		entry = proc_create_data(acpi_battery_file[i].name, +					 acpi_battery_file[i].mode, +					 acpi_device_dir(device), +					 &acpi_battery_file[i].ops, +					 acpi_driver_data(device)); +		if (!entry) +			return -ENODEV; +	} +	return 0; +} + +static void acpi_battery_remove_fs(struct acpi_device *device) +{ +	int i; +	if (!acpi_device_dir(device)) +		return; +	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) +		remove_proc_entry(acpi_battery_file[i].name, +				  acpi_device_dir(device)); + +	remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); +	acpi_device_dir(device) = NULL; +} + +#endif + +/* --------------------------------------------------------------------------                                   Driver Interface     -------------------------------------------------------------------------- */ @@ -790,6 +1090,15 @@ static int acpi_battery_add(struct acpi_device *device)  	result = acpi_battery_update(battery);  	if (result)  		goto fail; +#ifdef CONFIG_ACPI_PROCFS_POWER +	result = acpi_battery_add_fs(device); +#endif +	if (result) { +#ifdef CONFIG_ACPI_PROCFS_POWER +		acpi_battery_remove_fs(device); +#endif +		goto fail; +	}  	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",  		ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), @@ -816,6 +1125,9 @@ static int acpi_battery_remove(struct acpi_device *device)  		return -EINVAL;  	battery = acpi_driver_data(device);  	unregister_pm_notifier(&battery->pm_nb); +#ifdef CONFIG_ACPI_PROCFS_POWER +	acpi_battery_remove_fs(device); +#endif  	sysfs_remove_battery(battery);  	mutex_destroy(&battery->lock);  	mutex_destroy(&battery->sysfs_lock); @@ -866,7 +1178,19 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)  	if (dmi_check_system(bat_dmi_table))  		battery_bix_broken_package = 1; -	acpi_bus_register_driver(&acpi_battery_driver); +	 +#ifdef CONFIG_ACPI_PROCFS_POWER +	acpi_battery_dir = acpi_lock_battery_dir(); +	if (!acpi_battery_dir) +		return; +#endif +	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { +#ifdef CONFIG_ACPI_PROCFS_POWER +		acpi_unlock_battery_dir(acpi_battery_dir); +#endif +		return; +	} +	return;  }  static int __init acpi_battery_init(void) @@ -878,6 +1202,9 @@ static int __init acpi_battery_init(void)  static void __exit acpi_battery_exit(void)  {  	acpi_bus_unregister_driver(&acpi_battery_driver); +#ifdef CONFIG_ACPI_PROCFS_POWER +	acpi_unlock_battery_dir(acpi_battery_dir); +#endif  }  module_init(acpi_battery_init); diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index afec4526c48a..3d8413d02a97 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -314,6 +314,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {  		     DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),  		},  	}, +	{ +	.callback = dmi_disable_osi_win8, +	.ident = "Dell Inspiron 7737", +	.matches = { +		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +		    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), +		}, +	},  	/*  	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. @@ -374,6 +382,19 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {  		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),  		},  	}, +	/* +	 * Without this this EEEpc exports a non working WMI interface, with +	 * this it exports a working "good old" eeepc_laptop interface, fixing +	 * both brightness control, and rfkill not working. +	 */ +	{ +	.callback = dmi_enable_osi_linux, +	.ident = "Asus EEE PC 1015PX", +	.matches = { +		     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), +		     DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), +		}, +	},  	{}  }; diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c new file mode 100644 index 000000000000..6c9ee68e46fb --- /dev/null +++ b/drivers/acpi/cm_sbs.c @@ -0,0 +1,105 @@ +/* + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or (at + *  your option) any later version. + * + *  This program is distributed in the hope that it will be useful, but + *  WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *  General Public License for more details. + * + *  You should have received a copy of the GNU General Public License along + *  with this program; if not, write to the Free Software Foundation, Inc., + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/acpi.h> +#include <linux/types.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> +#include <acpi/acpi_bus.h> +#include <acpi/acpi_drivers.h> + +#define PREFIX "ACPI: " + +ACPI_MODULE_NAME("cm_sbs"); +#define ACPI_AC_CLASS		"ac_adapter" +#define ACPI_BATTERY_CLASS	"battery" +#define _COMPONENT		ACPI_SBS_COMPONENT +static struct proc_dir_entry *acpi_ac_dir; +static struct proc_dir_entry *acpi_battery_dir; + +static DEFINE_MUTEX(cm_sbs_mutex); + +static int lock_ac_dir_cnt; +static int lock_battery_dir_cnt; + +struct proc_dir_entry *acpi_lock_ac_dir(void) +{ +	mutex_lock(&cm_sbs_mutex); +	if (!acpi_ac_dir) +		acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); +	if (acpi_ac_dir) { +		lock_ac_dir_cnt++; +	} else { +		printk(KERN_ERR PREFIX +				  "Cannot create %s\n", ACPI_AC_CLASS); +	} +	mutex_unlock(&cm_sbs_mutex); +	return acpi_ac_dir; +} +EXPORT_SYMBOL(acpi_lock_ac_dir); + +void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) +{ +	mutex_lock(&cm_sbs_mutex); +	if (acpi_ac_dir_param) +		lock_ac_dir_cnt--; +	if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { +		remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); +		acpi_ac_dir = NULL; +	} +	mutex_unlock(&cm_sbs_mutex); +} +EXPORT_SYMBOL(acpi_unlock_ac_dir); + +struct proc_dir_entry *acpi_lock_battery_dir(void) +{ +	mutex_lock(&cm_sbs_mutex); +	if (!acpi_battery_dir) { +		acpi_battery_dir = +		    proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); +	} +	if (acpi_battery_dir) { +		lock_battery_dir_cnt++; +	} else { +		printk(KERN_ERR PREFIX +				  "Cannot create %s\n", ACPI_BATTERY_CLASS); +	} +	mutex_unlock(&cm_sbs_mutex); +	return acpi_battery_dir; +} +EXPORT_SYMBOL(acpi_lock_battery_dir); + +void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) +{ +	mutex_lock(&cm_sbs_mutex); +	if (acpi_battery_dir_param) +		lock_battery_dir_cnt--; +	if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param +	    && acpi_battery_dir) { +		remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); +		acpi_battery_dir = NULL; +	} +	mutex_unlock(&cm_sbs_mutex); +	return; +} +EXPORT_SYMBOL(acpi_unlock_battery_dir); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8b6990e417ec..f8bc5a755dda 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -457,10 +457,10 @@ static struct dmi_system_id video_dmi_table[] __initdata = {  	},  	{  	 .callback = video_set_use_native_backlight, -	 .ident = "ThinkPad T430s", +	 .ident = "ThinkPad T430 and T430s",  	 .matches = {  		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), +		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"),  		},  	},  	{ @@ -472,7 +472,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = {  		},  	},  	{ -	.callback = video_set_use_native_backlight, +	 .callback = video_set_use_native_backlight,  	.ident = "ThinkPad X1 Carbon",  	.matches = {  		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), @@ -500,7 +500,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = {  	 .ident = "Dell Inspiron 7520",  	 .matches = {  		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), -		DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"), +		DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),  		},  	},  	{ @@ -513,6 +513,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {  	},  	{  	 .callback = video_set_use_native_backlight, +	 .ident = "Acer Aspire 5742G", +	 .matches = { +		DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5742G"), +		}, +	}, +	{ +	 .callback = video_set_use_native_backlight,  	 .ident = "Acer Aspire V5-431",  	 .matches = {  		DMI_MATCH(DMI_SYS_VENDOR, "Acer"), diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index b3ea223585bd..61dcc8011ec7 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c @@ -328,13 +328,11 @@ int tpm_add_ppi(struct kobject *parent)  	/* Cache TPM ACPI handle and version string */  	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,  			    ppi_callback, NULL, NULL, &tpm_ppi_handle); -	if (tpm_ppi_handle == NULL) -		return -ENODEV; - -	return sysfs_create_group(parent, &ppi_attr_grp); +	return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0;  }  void tpm_remove_ppi(struct kobject *parent)  { -	sysfs_remove_group(parent, &ppi_attr_grp); +	if (tpm_ppi_handle) +		sysfs_remove_group(parent, &ppi_attr_grp);  } diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 099967302bf2..eab8ccfe6beb 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -37,6 +37,7 @@  #define BYT_RATIOS		0x66a  #define BYT_VIDS		0x66b  #define BYT_TURBO_RATIOS	0x66c +#define BYT_TURBO_VIDS		0x66d  #define FRAC_BITS 6 @@ -70,8 +71,9 @@ struct pstate_data {  };  struct vid_data { -	int32_t min; -	int32_t max; +	int min; +	int max; +	int turbo;  	int32_t ratio;  }; @@ -359,14 +361,14 @@ static int byt_get_min_pstate(void)  {  	u64 value;  	rdmsrl(BYT_RATIOS, value); -	return (value >> 8) & 0xFF; +	return (value >> 8) & 0x3F;  }  static int byt_get_max_pstate(void)  {  	u64 value;  	rdmsrl(BYT_RATIOS, value); -	return (value >> 16) & 0xFF; +	return (value >> 16) & 0x3F;  }  static int byt_get_turbo_pstate(void) @@ -393,6 +395,9 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate)  	vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);  	vid = fp_toint(vid_fp); +	if (pstate > cpudata->pstate.max_pstate) +		vid = cpudata->vid.turbo; +  	val |= vid;  	wrmsrl(MSR_IA32_PERF_CTL, val); @@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata)  {  	u64 value; +  	rdmsrl(BYT_VIDS, value); -	cpudata->vid.min = int_tofp((value >> 8) & 0x7f); -	cpudata->vid.max = int_tofp((value >> 16) & 0x7f); +	cpudata->vid.min = int_tofp((value >> 8) & 0x3f); +	cpudata->vid.max = int_tofp((value >> 16) & 0x3f);  	cpudata->vid.ratio = div_fp(  		cpudata->vid.max - cpudata->vid.min,  		int_tofp(cpudata->pstate.max_pstate -  			cpudata->pstate.min_pstate)); + +	rdmsrl(BYT_TURBO_VIDS, value); +	cpudata->vid.turbo = value & 0x7f;  } @@ -545,12 +554,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)  	if (pstate_funcs.get_vid)  		pstate_funcs.get_vid(cpu); - -	/* -	 * goto max pstate so we don't slow up boot if we are built-in if we are -	 * a module we will take care of it during normal operation -	 */ -	intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); +	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);  }  static inline void intel_pstate_calc_busy(struct cpudata *cpu, @@ -695,11 +699,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)  	cpu = all_cpu_data[cpunum];  	intel_pstate_get_cpu_pstates(cpu); -	if (!cpu->pstate.current_pstate) { -		all_cpu_data[cpunum] = NULL; -		kfree(cpu); -		return -ENODATA; -	}  	cpu->cpu = cpunum; @@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)  	cpu->timer.expires = jiffies + HZ/100;  	intel_pstate_busy_pid_reset(cpu);  	intel_pstate_sample(cpu); -	intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);  	add_timer_on(&cpu->timer, cpunum); |