ACPI and power management fixes for 3.15-rc6
- ACPICA fix for a stale pointer access introduced by a recent
    commit in the XSDT validation code from Lv Zheng.
 
  - ACPICA fix for the default value of the command line switch
    to favor 32-bit FADT addresses (in case there's a conflict
    between a 64-bit and a 32-bit address).  The previous default
    was that the 32-bit version would take precedence and we tried
    to change it to the other way around and it didn't work.
    From Lv Zheng.
 
  - A TPM commit related to ACPI _DSM in 3.14 caused the driver to
    refuse to load if a specific _DSM was missing and that broke
    resume from system suspend on Chromebooks that require the TPM
    hardware to be restored to a working state during resume by the
    OS.  Restore the old behavior to load the driver if the _DSM
    in question is not present, but prevent it from using the
    feature the _DSM is for.
 
  - ACPI AC driver conversion in 3.13 broke thermal management on
    at least one machine and has to be reverted.  From Guenter Roeck.
 
  - Two reverts of 3.13 commits that attempted to remove the old ACPI
    battery interface in /proc, but turned out to break some utilities
    still using that interface.  From Lan Tianyu.
 
  - ACPI processor driver fix to prevent acpi_processor_add() from
    modifying the CPU device's .offline field which leads to breakage
    if the initial online of the CPU fails.  From Igor Mammedov.
 
  - Two intel_pstate fixes, one to take a BayTrail documentation update
    into account and one to avoid forcing the maximum P-state on init
    which causes CPU PM trouble on systems with P-states coordination
    when one of the CPU cores is initialized after an offline/online
    cycle triggered by user space.  Both stable candidates, from
    Dirk Brandewie.
 
  - Fix for the ACPI video DMI blacklist entry for Dell Inspiron 7520
    from Aaron Lu.
 
  - Two new ACPI video blacklist entries for machines shipping with
    Win8 that need to use native backlight so that it can be controlled
    in a usual way (which doesn't work otherwise due bugs in the ACPI
    tables) from Hans de Goede.
 
  - Two ACPI _OSI quirks for systems that need them to work correctly
    with Linux from Edward Lin and Hans de Goede.
 
 /
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABCAAGBQJTdow6AAoJEILEb/54YlRxUWcP/0nczFCxZ7C1c7l7Ya8r9iRZ
 HXT+AAbakanPs6Ms4VRxao65v1AcdlruWHPhJ6JiEoiO60yKxIIzy7f3mO5gVesr
 tcaxaFaCTNdUDFdRDhyN6y+RzO/ohYSKdOJng2tcz2IvcsRD93hXk+095BlVzfJV
 EFycqXPb3nmP6oZo1KjPebk4cmlC8Sw9aWcBxK0O1aRoIrAdObf3+rCXfc2/FvC0
 vAquOI2OaJ0bwNl7QhGHMLMnvoDvq+/y2mDQ+BvxPERbtDBDS66tkhjsxEx89kpi
 ow6WKX1vgfsWYGa5tCxFDZvYIYP5x4+YWPwvYfOFmCO520PUIojT81qT+P6hLHMy
 jf2G7QWvL/3qn89qKsR26YNE/fadNDZq0IHh3KD8kOaKtXBV30fIh2rLG3XZfB8q
 lhWAcx5ot2ZoQy5ppAuKNG+zA6MniWbN/a5acUIS6zsvVRFkGeZE5ORyEUgkWMjk
 QiiL3kcx/Fe528A1cMVXR2fb4kzKBpnVXxWQlzptKCX/3JAOxe6ElZqHMDff983b
 LHJjMfVUX9m1yGUZHqbH6CiK9kuQv2fQXSESLrkUDItVs9VFskYQb6AZE5Ow+k+A
 QKnDg7n81YlYiau997g0+yA7EqwQmQZx+EwfVtOIfppOlp4LFbCKC6Ytu9pcgbZB
 GuYsd/bPvEVswylJMu6U
 =v+oA
 -----END PGP SIGNATURE-----
Merge tag 'pm+acpi-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki:
 "Still fixing regressions (partly by reverting commits that broke
  things for people), fixing other stable-candidate bugs and adding some
  blacklist entries for ACPI video and _OSI.
  Two ACPICA regression fixes (one recent and one for a 3.14 commit), a
  fix for an ACPI-related regression in TPM (introduced in 3.14), a
  revert of the ACPI AC driver conversion in 3.13 that went wrong for an
  unknown reason, two reverts of commits that attempted to remove an old
  user space interface in /proc and broke some utilities, in 3.13 too, a
  fix for a CPU hotplug bug in the ACPI processor driver (stable
  material), two (stable candidate) fixes for intel_pstate and a few new
  blacklist entries, mostly for systems that shipped with Windows 8.
  Specifics:
   - ACPICA fix for a stale pointer access introduced by a recent commit
     in the XSDT validation code from Lv Zheng.
   - ACPICA fix for the default value of the command line switch to
     favor 32-bit FADT addresses (in case there's a conflict between a
     64-bit and a 32-bit address).  The previous default was that the
     32-bit version would take precedence and we tried to change it to
     the other way around and it didn't work.  From Lv Zheng.
   - A TPM commit related to ACPI _DSM in 3.14 caused the driver to
     refuse to load if a specific _DSM was missing and that broke resume
     from system suspend on Chromebooks that require the TPM hardware to
     be restored to a working state during resume by the OS.  Restore
     the old behavior to load the driver if the _DSM in question is not
     present, but prevent it from using the feature the _DSM is for.
   - ACPI AC driver conversion in 3.13 broke thermal management on at
     least one machine and has to be reverted.  From Guenter Roeck.
   - Two reverts of 3.13 commits that attempted to remove the old ACPI
     battery interface in /proc, but turned out to break some utilities
     still using that interface.  From Lan Tianyu.
   - ACPI processor driver fix to prevent acpi_processor_add() from
     modifying the CPU device's .offline field which leads to breakage
     if the initial online of the CPU fails.  From Igor Mammedov.
   - Two intel_pstate fixes, one to take a BayTrail documentation update
     into account and one to avoid forcing the maximum P-state on init
     which causes CPU PM trouble on systems with P-states coordination
     when one of the CPU cores is initialized after an offline/online
     cycle triggered by user space.  Both stable candidates, from Dirk
     Brandewie.
   - Fix for the ACPI video DMI blacklist entry for Dell Inspiron 7520
     from Aaron Lu.
   - Two new ACPI video blacklist entries for machines shipping with
     Win8 that need to use native backlight so that it can be controlled
     in a usual way (which doesn't work otherwise due bugs in the ACPI
     tables) from Hans de Goede.
   - Two ACPI _OSI quirks for systems that need them to work correctly
     with Linux from Edward Lin and Hans de Goede"
* tag 'pm+acpi-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / video: Revert native brightness quirk for ThinkPad T530
  intel_pstate: remove setting P state to MAX on init
  ACPICA: Tables: Restore old behavor to favor 32-bit FADT addresses.
  ACPI / video: correct DMI tag for Dell Inspiron 7520
  intel_pstate: Set turbo VID for BayTrail
  ACPI / TPM: Fix resume regression on Chromebooks
  ACPI / proc: Do not say when /proc interfaces will be deleted in Kconfig
  ACPI / processor: do not mark present at boot but not onlined CPU as onlined
  ACPI: Revert "ACPI / AC: convert ACPI ac driver to platform bus"
  ACPI / blacklist: Add dmi_enable_osi_linux quirk for Asus EEE PC 1015PX
  ACPI: blacklist win8 OSI for Dell Inspiron 7737
  ACPI / video: Add use_native_backlight quirks for more systems
  ACPI: Revert "ACPI / Battery: Remove battery's proc directory"
  ACPI: Revert "ACPI: Remove CONFIG_ACPI_PROCFS_POWER and cm_sbsc.c"
  ACPICA: Tables: Fix invalid pointer accesses in acpi_tb_parse_root_table().
	
	
This commit is contained in:
		
				commit
				
					
						478c7cf7a8
					
				
			
		
					 13 changed files with 568 additions and 93 deletions
				
			
		| 
						 | 
					@ -47,6 +47,23 @@ config ACPI_SLEEP
 | 
				
			||||||
	depends on SUSPEND || HIBERNATION
 | 
						depends on SUSPEND || HIBERNATION
 | 
				
			||||||
	default y
 | 
						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
 | 
					config ACPI_EC_DEBUGFS
 | 
				
			||||||
	tristate "EC read/write access through /sys/kernel/debug/ec"
 | 
						tristate "EC read/write access through /sys/kernel/debug/ec"
 | 
				
			||||||
	default n
 | 
						default n
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ acpi-y				+= sysfs.o
 | 
				
			||||||
acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 | 
					acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 | 
				
			||||||
acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 | 
					acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 | 
				
			||||||
acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 | 
					acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 | 
				
			||||||
 | 
					acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 | 
				
			||||||
ifdef CONFIG_ACPI_VIDEO
 | 
					ifdef CONFIG_ACPI_VIDEO
 | 
				
			||||||
acpi-y				+= video_detect.o
 | 
					acpi-y				+= video_detect.o
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,11 +52,39 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 | 
				
			||||||
MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 | 
					MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					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 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 acpi_ac {
 | 
				
			||||||
	struct power_supply charger;
 | 
						struct power_supply charger;
 | 
				
			||||||
	struct platform_device *pdev;
 | 
						struct acpi_device * device;
 | 
				
			||||||
	unsigned long long state;
 | 
						unsigned long long state;
 | 
				
			||||||
	struct notifier_block battery_nb;
 | 
						struct notifier_block battery_nb;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -69,10 +97,12 @@ struct acpi_ac {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int acpi_ac_get_state(struct acpi_ac *ac)
 | 
					static int acpi_ac_get_state(struct acpi_ac *ac)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	acpi_status status;
 | 
						acpi_status status = AE_OK;
 | 
				
			||||||
	acpi_handle handle = ACPI_HANDLE(&ac->pdev->dev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = acpi_evaluate_integer(handle, "_PSR", NULL,
 | 
						if (!ac)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,
 | 
				
			||||||
				       &ac->state);
 | 
									       &ac->state);
 | 
				
			||||||
	if (ACPI_FAILURE(status)) {
 | 
						if (ACPI_FAILURE(status)) {
 | 
				
			||||||
		ACPI_EXCEPTION((AE_INFO, status,
 | 
							ACPI_EXCEPTION((AE_INFO, status,
 | 
				
			||||||
| 
						 | 
					@ -117,10 +147,9 @@ static enum power_supply_property ac_props[] = {
 | 
				
			||||||
                                   Driver Model
 | 
					                                   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_ac *ac = acpi_driver_data(device);
 | 
				
			||||||
	struct acpi_device *adev;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ac)
 | 
						if (!ac)
 | 
				
			||||||
		return;
 | 
							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);
 | 
								msleep(ac_sleep_before_get_state_ms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		acpi_ac_get_state(ac);
 | 
							acpi_ac_get_state(ac);
 | 
				
			||||||
		adev = ACPI_COMPANION(&ac->pdev->dev);
 | 
							acpi_bus_generate_netlink_event(device->pnp.device_class,
 | 
				
			||||||
		acpi_bus_generate_netlink_event(adev->pnp.device_class,
 | 
											  dev_name(&device->dev), event,
 | 
				
			||||||
						dev_name(&ac->pdev->dev),
 | 
											  (u32) ac->state);
 | 
				
			||||||
						event, (u32) ac->state);
 | 
							acpi_notifier_call_chain(device, event, (u32) ac->state);
 | 
				
			||||||
		acpi_notifier_call_chain(adev, event, (u32) ac->state);
 | 
					 | 
				
			||||||
		kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
 | 
							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;
 | 
						int result = 0;
 | 
				
			||||||
	struct acpi_ac *ac = NULL;
 | 
						struct acpi_ac *ac = NULL;
 | 
				
			||||||
	struct acpi_device *adev;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pdev)
 | 
					
 | 
				
			||||||
 | 
						if (!device)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adev = ACPI_COMPANION(&pdev->dev);
 | 
					 | 
				
			||||||
	if (!adev)
 | 
					 | 
				
			||||||
		return -ENODEV;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
 | 
						ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
 | 
				
			||||||
	if (!ac)
 | 
						if (!ac)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
 | 
						ac->device = device;
 | 
				
			||||||
	strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
 | 
						strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
 | 
				
			||||||
	ac->pdev = pdev;
 | 
						strcpy(acpi_device_class(device), ACPI_AC_CLASS);
 | 
				
			||||||
	platform_set_drvdata(pdev, ac);
 | 
						device->driver_data = ac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = acpi_ac_get_state(ac);
 | 
						result = acpi_ac_get_state(ac);
 | 
				
			||||||
	if (result)
 | 
						if (result)
 | 
				
			||||||
		goto end;
 | 
							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.type = POWER_SUPPLY_TYPE_MAINS;
 | 
				
			||||||
	ac->charger.properties = ac_props;
 | 
						ac->charger.properties = ac_props;
 | 
				
			||||||
	ac->charger.num_properties = ARRAY_SIZE(ac_props);
 | 
						ac->charger.num_properties = ARRAY_SIZE(ac_props);
 | 
				
			||||||
	ac->charger.get_property = get_ac_property;
 | 
						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)
 | 
						if (result)
 | 
				
			||||||
		goto end;
 | 
							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",
 | 
						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->state ? "on-line" : "off-line");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac->battery_nb.notifier_call = acpi_ac_battery_notify;
 | 
						ac->battery_nb.notifier_call = acpi_ac_battery_notify;
 | 
				
			||||||
| 
						 | 
					@ -256,7 +274,7 @@ static int acpi_ac_resume(struct device *dev)
 | 
				
			||||||
	if (!dev)
 | 
						if (!dev)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac = platform_get_drvdata(to_platform_device(dev));
 | 
						ac = acpi_driver_data(to_acpi_device(dev));
 | 
				
			||||||
	if (!ac)
 | 
						if (!ac)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,19 +288,17 @@ static int acpi_ac_resume(struct device *dev)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define acpi_ac_resume NULL
 | 
					#define acpi_ac_resume NULL
 | 
				
			||||||
#endif
 | 
					#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;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev),
 | 
						ac = acpi_driver_data(device);
 | 
				
			||||||
			ACPI_ALL_NOTIFY, acpi_ac_notify_handler);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac = platform_get_drvdata(pdev);
 | 
					 | 
				
			||||||
	if (ac->charger.dev)
 | 
						if (ac->charger.dev)
 | 
				
			||||||
		power_supply_unregister(&ac->charger);
 | 
							power_supply_unregister(&ac->charger);
 | 
				
			||||||
	unregister_acpi_notifier(&ac->battery_nb);
 | 
						unregister_acpi_notifier(&ac->battery_nb);
 | 
				
			||||||
| 
						 | 
					@ -292,23 +308,6 @@ static int acpi_ac_remove(struct platform_device *pdev)
 | 
				
			||||||
	return 0;
 | 
						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)
 | 
					static int __init acpi_ac_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int result;
 | 
						int result;
 | 
				
			||||||
| 
						 | 
					@ -316,7 +315,7 @@ static int __init acpi_ac_init(void)
 | 
				
			||||||
	if (acpi_disabled)
 | 
						if (acpi_disabled)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = platform_driver_register(&acpi_ac_driver);
 | 
						result = acpi_bus_register_driver(&acpi_ac_driver);
 | 
				
			||||||
	if (result < 0)
 | 
						if (result < 0)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -325,7 +324,7 @@ static int __init acpi_ac_init(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __exit acpi_ac_exit(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_init(acpi_ac_init);
 | 
				
			||||||
module_exit(acpi_ac_exit);
 | 
					module_exit(acpi_ac_exit);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,6 @@ ACPI_MODULE_NAME("platform");
 | 
				
			||||||
static const struct acpi_device_id acpi_platform_device_ids[] = {
 | 
					static const struct acpi_device_id acpi_platform_device_ids[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ "PNP0D40" },
 | 
						{ "PNP0D40" },
 | 
				
			||||||
	{ "ACPI0003" },
 | 
					 | 
				
			||||||
	{ "VPC2004" },
 | 
						{ "VPC2004" },
 | 
				
			||||||
	{ "BCM4752" },
 | 
						{ "BCM4752" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,7 +405,6 @@ static int acpi_processor_add(struct acpi_device *device,
 | 
				
			||||||
		goto err;
 | 
							goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr->dev = dev;
 | 
						pr->dev = dev;
 | 
				
			||||||
	dev->offline = pr->flags.need_hotplug_init;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Trigger the processor driver's .probe() if present. */
 | 
						/* Trigger the processor driver's .probe() if present. */
 | 
				
			||||||
	if (device_attach(dev) >= 0)
 | 
						if (device_attach(dev) >= 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,9 +141,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
 | 
				
			||||||
 * address. Although ACPICA adheres to the ACPI specification which
 | 
					 * address. Although ACPICA adheres to the ACPI specification which
 | 
				
			||||||
 * requires the use of the corresponding 64-bit address if it is non-zero,
 | 
					 * 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
 | 
					 * 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
 | 
					 * Optionally truncate I/O addresses to 16 bits. Provides compatibility
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -461,6 +461,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
 | 
				
			||||||
	u32 table_count;
 | 
						u32 table_count;
 | 
				
			||||||
	struct acpi_table_header *table;
 | 
						struct acpi_table_header *table;
 | 
				
			||||||
	acpi_physical_address address;
 | 
						acpi_physical_address address;
 | 
				
			||||||
 | 
						acpi_physical_address rsdt_address;
 | 
				
			||||||
	u32 length;
 | 
						u32 length;
 | 
				
			||||||
	u8 *table_entry;
 | 
						u8 *table_entry;
 | 
				
			||||||
	acpi_status status;
 | 
						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.
 | 
							 * as per the ACPI specification.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		address = (acpi_physical_address) rsdp->xsdt_physical_address;
 | 
							address = (acpi_physical_address) rsdp->xsdt_physical_address;
 | 
				
			||||||
 | 
							rsdt_address =
 | 
				
			||||||
 | 
							    (acpi_physical_address) rsdp->rsdt_physical_address;
 | 
				
			||||||
		table_entry_size = ACPI_XSDT_ENTRY_SIZE;
 | 
							table_entry_size = ACPI_XSDT_ENTRY_SIZE;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Root table is an RSDT (32-bit physical addresses) */
 | 
							/* Root table is an RSDT (32-bit physical addresses) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		address = (acpi_physical_address) rsdp->rsdt_physical_address;
 | 
							address = (acpi_physical_address) rsdp->rsdt_physical_address;
 | 
				
			||||||
 | 
							rsdt_address = address;
 | 
				
			||||||
		table_entry_size = ACPI_RSDT_ENTRY_SIZE;
 | 
							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 */
 | 
								/* Fall back to the RSDT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			address =
 | 
								address = rsdt_address;
 | 
				
			||||||
			    (acpi_physical_address) rsdp->rsdt_physical_address;
 | 
					 | 
				
			||||||
			table_entry_size = ACPI_RSDT_ENTRY_SIZE;
 | 
								table_entry_size = ACPI_RSDT_ENTRY_SIZE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,12 @@
 | 
				
			||||||
#include <linux/suspend.h>
 | 
					#include <linux/suspend.h>
 | 
				
			||||||
#include <asm/unaligned.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/acpi.h>
 | 
				
			||||||
#include <linux/power_supply.h>
 | 
					#include <linux/power_supply.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +70,19 @@ static unsigned int cache_time = 1000;
 | 
				
			||||||
module_param(cache_time, uint, 0644);
 | 
					module_param(cache_time, uint, 0644);
 | 
				
			||||||
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 | 
					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[] = {
 | 
					static const struct acpi_device_id battery_device_ids[] = {
 | 
				
			||||||
	{"PNP0C0A", 0},
 | 
						{"PNP0C0A", 0},
 | 
				
			||||||
	{"", 0},
 | 
						{"", 0},
 | 
				
			||||||
| 
						 | 
					@ -299,6 +318,14 @@ static enum power_supply_property energy_battery_props[] = {
 | 
				
			||||||
	POWER_SUPPLY_PROP_SERIAL_NUMBER,
 | 
						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
 | 
					                               Battery Management
 | 
				
			||||||
   -------------------------------------------------------------------------- */
 | 
					   -------------------------------------------------------------------------- */
 | 
				
			||||||
| 
						 | 
					@ -716,6 +743,279 @@ static void acpi_battery_refresh(struct acpi_battery *battery)
 | 
				
			||||||
	sysfs_add_battery(battery);
 | 
						sysfs_add_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
 | 
					                                 Driver Interface
 | 
				
			||||||
   -------------------------------------------------------------------------- */
 | 
					   -------------------------------------------------------------------------- */
 | 
				
			||||||
| 
						 | 
					@ -790,6 +1090,15 @@ static int acpi_battery_add(struct acpi_device *device)
 | 
				
			||||||
	result = acpi_battery_update(battery);
 | 
						result = acpi_battery_update(battery);
 | 
				
			||||||
	if (result)
 | 
						if (result)
 | 
				
			||||||
		goto fail;
 | 
							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",
 | 
						printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
 | 
				
			||||||
		ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
 | 
							ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
 | 
				
			||||||
| 
						 | 
					@ -816,6 +1125,9 @@ static int acpi_battery_remove(struct acpi_device *device)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	battery = acpi_driver_data(device);
 | 
						battery = acpi_driver_data(device);
 | 
				
			||||||
	unregister_pm_notifier(&battery->pm_nb);
 | 
						unregister_pm_notifier(&battery->pm_nb);
 | 
				
			||||||
 | 
					#ifdef CONFIG_ACPI_PROCFS_POWER
 | 
				
			||||||
 | 
						acpi_battery_remove_fs(device);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	sysfs_remove_battery(battery);
 | 
						sysfs_remove_battery(battery);
 | 
				
			||||||
	mutex_destroy(&battery->lock);
 | 
						mutex_destroy(&battery->lock);
 | 
				
			||||||
	mutex_destroy(&battery->sysfs_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))
 | 
						if (dmi_check_system(bat_dmi_table))
 | 
				
			||||||
		battery_bix_broken_package = 1;
 | 
							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)
 | 
					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)
 | 
					static void __exit acpi_battery_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	acpi_bus_unregister_driver(&acpi_battery_driver);
 | 
						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);
 | 
					module_init(acpi_battery_init);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -314,6 +314,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
 | 
				
			||||||
		     DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
 | 
							     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.
 | 
						 * 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"),
 | 
							     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"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										105
									
								
								drivers/acpi/cm_sbs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								drivers/acpi/cm_sbs.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					@ -457,10 +457,10 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	 .callback = video_set_use_native_backlight,
 | 
						 .callback = video_set_use_native_backlight,
 | 
				
			||||||
	 .ident = "ThinkPad T430s",
 | 
						 .ident = "ThinkPad T430 and T430s",
 | 
				
			||||||
	 .matches = {
 | 
						 .matches = {
 | 
				
			||||||
		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 | 
							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",
 | 
						.ident = "ThinkPad X1 Carbon",
 | 
				
			||||||
	.matches = {
 | 
						.matches = {
 | 
				
			||||||
		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 | 
							DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 | 
				
			||||||
| 
						 | 
					@ -500,7 +500,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
 | 
				
			||||||
	 .ident = "Dell Inspiron 7520",
 | 
						 .ident = "Dell Inspiron 7520",
 | 
				
			||||||
	 .matches = {
 | 
						 .matches = {
 | 
				
			||||||
		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 | 
							DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 | 
				
			||||||
		DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"),
 | 
							DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -511,6 +511,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
 | 
				
			||||||
		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"),
 | 
							DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						 .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,
 | 
						 .callback = video_set_use_native_backlight,
 | 
				
			||||||
	 .ident = "Acer Aspire V5-431",
 | 
						 .ident = "Acer Aspire V5-431",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,13 +328,11 @@ int tpm_add_ppi(struct kobject *parent)
 | 
				
			||||||
	/* Cache TPM ACPI handle and version string */
 | 
						/* Cache TPM ACPI handle and version string */
 | 
				
			||||||
	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 | 
						acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 | 
				
			||||||
			    ppi_callback, NULL, NULL, &tpm_ppi_handle);
 | 
								    ppi_callback, NULL, NULL, &tpm_ppi_handle);
 | 
				
			||||||
	if (tpm_ppi_handle == NULL)
 | 
						return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0;
 | 
				
			||||||
		return -ENODEV;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sysfs_create_group(parent, &ppi_attr_grp);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void tpm_remove_ppi(struct kobject *parent)
 | 
					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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#define BYT_RATIOS		0x66a
 | 
					#define BYT_RATIOS		0x66a
 | 
				
			||||||
#define BYT_VIDS		0x66b
 | 
					#define BYT_VIDS		0x66b
 | 
				
			||||||
#define BYT_TURBO_RATIOS	0x66c
 | 
					#define BYT_TURBO_RATIOS	0x66c
 | 
				
			||||||
 | 
					#define BYT_TURBO_VIDS		0x66d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FRAC_BITS 6
 | 
					#define FRAC_BITS 6
 | 
				
			||||||
| 
						 | 
					@ -70,8 +71,9 @@ struct pstate_data {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct vid_data {
 | 
					struct vid_data {
 | 
				
			||||||
	int32_t min;
 | 
						int min;
 | 
				
			||||||
	int32_t max;
 | 
						int max;
 | 
				
			||||||
 | 
						int turbo;
 | 
				
			||||||
	int32_t ratio;
 | 
						int32_t ratio;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,14 +361,14 @@ static int byt_get_min_pstate(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 value;
 | 
						u64 value;
 | 
				
			||||||
	rdmsrl(BYT_RATIOS, value);
 | 
						rdmsrl(BYT_RATIOS, value);
 | 
				
			||||||
	return (value >> 8) & 0xFF;
 | 
						return (value >> 8) & 0x3F;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int byt_get_max_pstate(void)
 | 
					static int byt_get_max_pstate(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 value;
 | 
						u64 value;
 | 
				
			||||||
	rdmsrl(BYT_RATIOS, value);
 | 
						rdmsrl(BYT_RATIOS, value);
 | 
				
			||||||
	return (value >> 16) & 0xFF;
 | 
						return (value >> 16) & 0x3F;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int byt_get_turbo_pstate(void)
 | 
					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 = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
 | 
				
			||||||
	vid = fp_toint(vid_fp);
 | 
						vid = fp_toint(vid_fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pstate > cpudata->pstate.max_pstate)
 | 
				
			||||||
 | 
							vid = cpudata->vid.turbo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val |= vid;
 | 
						val |= vid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wrmsrl(MSR_IA32_PERF_CTL, val);
 | 
						wrmsrl(MSR_IA32_PERF_CTL, val);
 | 
				
			||||||
| 
						 | 
					@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 value;
 | 
						u64 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rdmsrl(BYT_VIDS, value);
 | 
						rdmsrl(BYT_VIDS, value);
 | 
				
			||||||
	cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
 | 
						cpudata->vid.min = int_tofp((value >> 8) & 0x3f);
 | 
				
			||||||
	cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
 | 
						cpudata->vid.max = int_tofp((value >> 16) & 0x3f);
 | 
				
			||||||
	cpudata->vid.ratio = div_fp(
 | 
						cpudata->vid.ratio = div_fp(
 | 
				
			||||||
		cpudata->vid.max - cpudata->vid.min,
 | 
							cpudata->vid.max - cpudata->vid.min,
 | 
				
			||||||
		int_tofp(cpudata->pstate.max_pstate -
 | 
							int_tofp(cpudata->pstate.max_pstate -
 | 
				
			||||||
			cpudata->pstate.min_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)
 | 
						if (pstate_funcs.get_vid)
 | 
				
			||||||
		pstate_funcs.get_vid(cpu);
 | 
							pstate_funcs.get_vid(cpu);
 | 
				
			||||||
 | 
						intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * 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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void intel_pstate_calc_busy(struct cpudata *cpu,
 | 
					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];
 | 
						cpu = all_cpu_data[cpunum];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	intel_pstate_get_cpu_pstates(cpu);
 | 
						intel_pstate_get_cpu_pstates(cpu);
 | 
				
			||||||
	if (!cpu->pstate.current_pstate) {
 | 
					 | 
				
			||||||
		all_cpu_data[cpunum] = NULL;
 | 
					 | 
				
			||||||
		kfree(cpu);
 | 
					 | 
				
			||||||
		return -ENODATA;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cpu->cpu = cpunum;
 | 
						cpu->cpu = cpunum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
 | 
				
			||||||
	cpu->timer.expires = jiffies + HZ/100;
 | 
						cpu->timer.expires = jiffies + HZ/100;
 | 
				
			||||||
	intel_pstate_busy_pid_reset(cpu);
 | 
						intel_pstate_busy_pid_reset(cpu);
 | 
				
			||||||
	intel_pstate_sample(cpu);
 | 
						intel_pstate_sample(cpu);
 | 
				
			||||||
	intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	add_timer_on(&cpu->timer, cpunum);
 | 
						add_timer_on(&cpu->timer, cpunum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue