power.c 26.1 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds's avatar
Linus Torvalds committed
2
/*
3
 * drivers/acpi/power.c - ACPI Power Resources management.
Linus Torvalds's avatar
Linus Torvalds committed
4
 *
5 6 7 8
 * Copyright (C) 2001 - 2015 Intel Corp.
 * Author: Andy Grover <andrew.grover@intel.com>
 * Author: Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Linus Torvalds's avatar
Linus Torvalds committed
9 10 11 12 13 14
 */

/*
 * ACPI power-managed devices may be controlled in two ways:
 * 1. via "Device Specific (D-State) Control"
 * 2. via "Power Resource Control".
15
 * The code below deals with ACPI Power Resources control.
16
 *
17 18 19
 * An ACPI "power resource object" represents a software controllable power
 * plane, clock plane, or other resource depended on by a device.
 *
Linus Torvalds's avatar
Linus Torvalds committed
20 21 22 23
 * A device may rely on multiple power resources, and a power resource
 * may be shared by multiple devices.
 */

24 25
#define pr_fmt(fmt) "ACPI: PM: " fmt

Linus Torvalds's avatar
Linus Torvalds committed
26 27 28 29
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
30
#include <linux/slab.h>
31
#include <linux/pm_runtime.h>
32
#include <linux/sysfs.h>
33
#include <linux/acpi.h>
34
#include "sleep.h"
35
#include "internal.h"
36

Linus Torvalds's avatar
Linus Torvalds committed
37 38 39 40 41
#define ACPI_POWER_CLASS		"power_resource"
#define ACPI_POWER_DEVICE_NAME		"Power Resource"
#define ACPI_POWER_RESOURCE_STATE_OFF	0x00
#define ACPI_POWER_RESOURCE_STATE_ON	0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
42

43 44 45 46 47
struct acpi_power_dependent_device {
	struct device *dev;
	struct list_head node;
};

Len Brown's avatar
Len Brown committed
48
struct acpi_power_resource {
49
	struct acpi_device device;
50
	struct list_head list_node;
Len Brown's avatar
Len Brown committed
51 52
	u32 system_level;
	u32 order;
53
	unsigned int ref_count;
54
	u8 state;
55
	struct mutex resource_lock;
56
	struct list_head dependents;
Linus Torvalds's avatar
Linus Torvalds committed
57 58
};

59 60 61 62 63
struct acpi_power_resource_entry {
	struct list_head node;
	struct acpi_power_resource *resource;
};

64 65
static LIST_HEAD(acpi_power_resource_list);
static DEFINE_MUTEX(power_resource_list_lock);
Linus Torvalds's avatar
Linus Torvalds committed
66 67 68 69 70

/* --------------------------------------------------------------------------
                             Power Resource Management
   -------------------------------------------------------------------------- */

71 72 73 74 75
static inline const char *resource_dev_name(struct acpi_power_resource *pr)
{
	return dev_name(&pr->device.dev);
}

76 77 78 79 80 81
static inline
struct acpi_power_resource *to_power_resource(struct acpi_device *device)
{
	return container_of(device, struct acpi_power_resource, device);
}

82
static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
Linus Torvalds's avatar
Linus Torvalds committed
83
{
84
	struct acpi_device *device = acpi_fetch_acpi_dev(handle);
Linus Torvalds's avatar
Linus Torvalds committed
85

86
	if (!device)
87
		return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
88

89
	return to_power_resource(device);
Linus Torvalds's avatar
Linus Torvalds committed
90 91
}

92 93
static int acpi_power_resources_list_add(acpi_handle handle,
					 struct list_head *list)
94 95 96 97 98
{
	struct acpi_power_resource *resource = acpi_power_get_context(handle);
	struct acpi_power_resource_entry *entry;

	if (!resource || !list)
99
		return -EINVAL;
100 101 102

	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
103
		return -ENOMEM;
104 105 106 107 108 109 110 111

	entry->resource = resource;
	if (!list_empty(list)) {
		struct acpi_power_resource_entry *e;

		list_for_each_entry(e, list, node)
			if (e->resource->order > resource->order) {
				list_add_tail(&entry->node, &e->node);
112
				return 0;
113 114 115
			}
	}
	list_add_tail(&entry->node, list);
116
	return 0;
117 118 119 120 121 122 123 124 125 126 127 128
}

void acpi_power_resources_list_free(struct list_head *list)
{
	struct acpi_power_resource_entry *entry, *e;

	list_for_each_entry_safe(entry, e, list, node) {
		list_del(&entry->node);
		kfree(entry);
	}
}

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
static bool acpi_power_resource_is_dup(union acpi_object *package,
				       unsigned int start, unsigned int i)
{
	acpi_handle rhandle, dup;
	unsigned int j;

	/* The caller is expected to check the package element types */
	rhandle = package->package.elements[i].reference.handle;
	for (j = start; j < i; j++) {
		dup = package->package.elements[j].reference.handle;
		if (dup == rhandle)
			return true;
	}

	return false;
}

146 147
int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
				 struct list_head *list)
148 149
{
	unsigned int i;
150
	int err = 0;
151 152 153

	for (i = start; i < package->package.count; i++) {
		union acpi_object *element = &package->package.elements[i];
154
		struct acpi_device *rdev;
155 156 157
		acpi_handle rhandle;

		if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
158
			err = -ENODATA;
159 160 161 162
			break;
		}
		rhandle = element->reference.handle;
		if (!rhandle) {
163
			err = -ENODEV;
164 165
			break;
		}
166 167 168 169 170

		/* Some ACPI tables contain duplicate power resource references */
		if (acpi_power_resource_is_dup(package, start, i))
			continue;

171 172 173
		rdev = acpi_add_power_resource(rhandle);
		if (!rdev) {
			err = -ENODEV;
174
			break;
175
		}
176 177 178
		err = acpi_power_resources_list_add(rhandle, list);
		if (err)
			break;
179
	}
180
	if (err)
181 182
		acpi_power_resources_list_free(list);

183
	return err;
184 185
}

186
static int __get_state(acpi_handle handle, u8 *state)
Linus Torvalds's avatar
Linus Torvalds committed
187
{
Len Brown's avatar
Len Brown committed
188
	acpi_status status = AE_OK;
189
	unsigned long long sta = 0;
190
	u8 cur_state;
Linus Torvalds's avatar
Linus Torvalds committed
191

192
	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
Linus Torvalds's avatar
Linus Torvalds committed
193
	if (ACPI_FAILURE(status))
194
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
195

196
	cur_state = sta & ACPI_POWER_RESOURCE_STATE_ON;
Linus Torvalds's avatar
Linus Torvalds committed
197

198
	acpi_handle_debug(handle, "Power resource is %s\n",
199
			  cur_state ? "on" : "off");
Linus Torvalds's avatar
Linus Torvalds committed
200

201
	*state = cur_state;
202
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
203 204
}

205 206 207 208 209 210 211 212 213 214 215 216 217 218
static int acpi_power_get_state(struct acpi_power_resource *resource, u8 *state)
{
	if (resource->state == ACPI_POWER_RESOURCE_STATE_UNKNOWN) {
		int ret;

		ret = __get_state(resource->device.handle, &resource->state);
		if (ret)
			return ret;
	}

	*state = resource->state;
	return 0;
}

219
static int acpi_power_get_list_state(struct list_head *list, u8 *state)
Linus Torvalds's avatar
Linus Torvalds committed
220
{
221
	struct acpi_power_resource_entry *entry;
222
	u8 cur_state = ACPI_POWER_RESOURCE_STATE_OFF;
Linus Torvalds's avatar
Linus Torvalds committed
223 224

	if (!list || !state)
225
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
226 227

	/* The state of the list is 'on' IFF all resources are 'on'. */
228 229
	list_for_each_entry(entry, list, node) {
		struct acpi_power_resource *resource = entry->resource;
230 231 232
		int result;

		mutex_lock(&resource->resource_lock);
233
		result = acpi_power_get_state(resource, &cur_state);
234 235 236 237 238
		mutex_unlock(&resource->resource_lock);
		if (result)
			return result;

		if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
Linus Torvalds's avatar
Linus Torvalds committed
239 240 241
			break;
	}

242
	pr_debug("Power resource list is %s\n", cur_state ? "on" : "off");
Linus Torvalds's avatar
Linus Torvalds committed
243

244 245
	*state = cur_state;
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
246 247
}

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
static int
acpi_power_resource_add_dependent(struct acpi_power_resource *resource,
				  struct device *dev)
{
	struct acpi_power_dependent_device *dep;
	int ret = 0;

	mutex_lock(&resource->resource_lock);
	list_for_each_entry(dep, &resource->dependents, node) {
		/* Only add it once */
		if (dep->dev == dev)
			goto unlock;
	}

	dep = kzalloc(sizeof(*dep), GFP_KERNEL);
	if (!dep) {
		ret = -ENOMEM;
		goto unlock;
	}

	dep->dev = dev;
	list_add_tail(&dep->node, &resource->dependents);
270 271
	dev_dbg(dev, "added power dependency to [%s]\n",
		resource_dev_name(resource));
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

unlock:
	mutex_unlock(&resource->resource_lock);
	return ret;
}

static void
acpi_power_resource_remove_dependent(struct acpi_power_resource *resource,
				     struct device *dev)
{
	struct acpi_power_dependent_device *dep;

	mutex_lock(&resource->resource_lock);
	list_for_each_entry(dep, &resource->dependents, node) {
		if (dep->dev == dev) {
			list_del(&dep->node);
			kfree(dep);
			dev_dbg(dev, "removed power dependency to [%s]\n",
290
				resource_dev_name(resource));
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
			break;
		}
	}
	mutex_unlock(&resource->resource_lock);
}

/**
 * acpi_device_power_add_dependent - Add dependent device of this ACPI device
 * @adev: ACPI device pointer
 * @dev: Dependent device
 *
 * If @adev has non-empty _PR0 the @dev is added as dependent device to all
 * power resources returned by it. This means that whenever these power
 * resources are turned _ON the dependent devices get runtime resumed. This
 * is needed for devices such as PCI to allow its driver to re-initialize
 * it after it went to D0uninitialized.
 *
 * If @adev does not have _PR0 this does nothing.
 *
 * Returns %0 in case of success and negative errno otherwise.
 */
int acpi_device_power_add_dependent(struct acpi_device *adev,
				    struct device *dev)
{
	struct acpi_power_resource_entry *entry;
	struct list_head *resources;
	int ret;

	if (!adev->flags.power_manageable)
		return 0;

	resources = &adev->power.states[ACPI_STATE_D0].resources;
	list_for_each_entry(entry, resources, node) {
		ret = acpi_power_resource_add_dependent(entry->resource, dev);
		if (ret)
			goto err;
	}

	return 0;

err:
	list_for_each_entry(entry, resources, node)
		acpi_power_resource_remove_dependent(entry->resource, dev);

	return ret;
}

/**
 * acpi_device_power_remove_dependent - Remove dependent device
 * @adev: ACPI device pointer
 * @dev: Dependent device
 *
 * Does the opposite of acpi_device_power_add_dependent() and removes the
 * dependent device if it is found. Can be called to @adev that does not
 * have _PR0 as well.
 */
void acpi_device_power_remove_dependent(struct acpi_device *adev,
					struct device *dev)
{
	struct acpi_power_resource_entry *entry;
	struct list_head *resources;

	if (!adev->flags.power_manageable)
		return;

	resources = &adev->power.states[ACPI_STATE_D0].resources;
	list_for_each_entry_reverse(entry, resources, node)
		acpi_power_resource_remove_dependent(entry->resource, dev);
}

361
static int __acpi_power_on(struct acpi_power_resource *resource)
Linus Torvalds's avatar
Linus Torvalds committed
362
{
363
	acpi_handle handle = resource->device.handle;
364
	struct acpi_power_dependent_device *dep;
Len Brown's avatar
Len Brown committed
365
	acpi_status status = AE_OK;
Linus Torvalds's avatar
Linus Torvalds committed
366

367
	status = acpi_evaluate_object(handle, "_ON", NULL, NULL);
368 369
	if (ACPI_FAILURE(status)) {
		resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
370
		return -ENODEV;
371 372 373
	}

	resource->state = ACPI_POWER_RESOURCE_STATE_ON;
374

375
	acpi_handle_debug(handle, "Power resource turned on\n");
376

377 378 379 380 381 382 383 384 385 386 387
	/*
	 * If there are other dependents on this power resource we need to
	 * resume them now so that their drivers can re-initialize the
	 * hardware properly after it went back to D0.
	 */
	if (list_empty(&resource->dependents) ||
	    list_is_singular(&resource->dependents))
		return 0;

	list_for_each_entry(dep, &resource->dependents, node) {
		dev_dbg(dep->dev, "runtime resuming because [%s] turned on\n",
388
			resource_dev_name(resource));
389 390 391
		pm_request_resume(dep->dev);
	}

392 393 394
	return 0;
}

395
static int acpi_power_on_unlocked(struct acpi_power_resource *resource)
396
{
397
	int result = 0;
398

399
	if (resource->ref_count++) {
400 401
		acpi_handle_debug(resource->device.handle,
				  "Power resource already on\n");
402 403
	} else {
		result = __acpi_power_on(resource);
404
		if (result)
405
			resource->ref_count--;
406
	}
407 408
	return result;
}
409

410 411 412
static int acpi_power_on(struct acpi_power_resource *resource)
{
	int result;
413

414 415 416
	mutex_lock(&resource->resource_lock);
	result = acpi_power_on_unlocked(resource);
	mutex_unlock(&resource->resource_lock);
417
	return result;
Linus Torvalds's avatar
Linus Torvalds committed
418 419
}

420 421
static int __acpi_power_off(struct acpi_power_resource *resource)
{
422
	acpi_handle handle = resource->device.handle;
423 424
	acpi_status status;

425
	status = acpi_evaluate_object(handle, "_OFF", NULL, NULL);
426 427
	if (ACPI_FAILURE(status)) {
		resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
428
		return -ENODEV;
429 430 431
	}

	resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
432

433
	acpi_handle_debug(handle, "Power resource turned off\n");
434

435 436 437
	return 0;
}

438
static int acpi_power_off_unlocked(struct acpi_power_resource *resource)
Linus Torvalds's avatar
Linus Torvalds committed
439
{
440
	int result = 0;
Linus Torvalds's avatar
Linus Torvalds committed
441

442
	if (!resource->ref_count) {
443 444
		acpi_handle_debug(resource->device.handle,
				  "Power resource already off\n");
445
		return 0;
446
	}
Linus Torvalds's avatar
Linus Torvalds committed
447

448
	if (--resource->ref_count) {
449 450
		acpi_handle_debug(resource->device.handle,
				  "Power resource still in use\n");
451 452 453 454
	} else {
		result = __acpi_power_off(resource);
		if (result)
			resource->ref_count++;
Linus Torvalds's avatar
Linus Torvalds committed
455
	}
456 457
	return result;
}
Linus Torvalds's avatar
Linus Torvalds committed
458

459 460 461
static int acpi_power_off(struct acpi_power_resource *resource)
{
	int result;
Linus Torvalds's avatar
Linus Torvalds committed
462

463 464 465
	mutex_lock(&resource->resource_lock);
	result = acpi_power_off_unlocked(resource);
	mutex_unlock(&resource->resource_lock);
466
	return result;
Linus Torvalds's avatar
Linus Torvalds committed
467 468
}

469
static int acpi_power_off_list(struct list_head *list)
470
{
471 472
	struct acpi_power_resource_entry *entry;
	int result = 0;
473

474 475 476 477 478 479
	list_for_each_entry_reverse(entry, list, node) {
		result = acpi_power_off(entry->resource);
		if (result)
			goto err;
	}
	return 0;
480

481 482 483 484 485
 err:
	list_for_each_entry_continue(entry, list, node)
		acpi_power_on(entry->resource);

	return result;
486 487
}

488
static int acpi_power_on_list(struct list_head *list)
489
{
490
	struct acpi_power_resource_entry *entry;
491 492
	int result = 0;

493 494 495 496
	list_for_each_entry(entry, list, node) {
		result = acpi_power_on(entry->resource);
		if (result)
			goto err;
497
	}
498 499 500 501 502
	return 0;

 err:
	list_for_each_entry_continue_reverse(entry, list, node)
		acpi_power_off(entry->resource);
503 504 505 506

	return result;
}

507 508 509 510
static struct attribute *attrs[] = {
	NULL,
};

511
static const struct attribute_group attr_groups[] = {
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
	[ACPI_STATE_D0] = {
		.name = "power_resources_D0",
		.attrs = attrs,
	},
	[ACPI_STATE_D1] = {
		.name = "power_resources_D1",
		.attrs = attrs,
	},
	[ACPI_STATE_D2] = {
		.name = "power_resources_D2",
		.attrs = attrs,
	},
	[ACPI_STATE_D3_HOT] = {
		.name = "power_resources_D3hot",
		.attrs = attrs,
	},
};

530
static const struct attribute_group wakeup_attr_group = {
531 532 533 534 535 536
	.name = "power_resources_wakeup",
	.attrs = attrs,
};

static void acpi_power_hide_list(struct acpi_device *adev,
				 struct list_head *resources,
537
				 const struct attribute_group *attr_group)
538 539 540
{
	struct acpi_power_resource_entry *entry;

541
	if (list_empty(resources))
542 543
		return;

544
	list_for_each_entry_reverse(entry, resources, node) {
545 546 547
		struct acpi_device *res_dev = &entry->resource->device;

		sysfs_remove_link_from_group(&adev->dev.kobj,
548
					     attr_group->name,
549 550
					     dev_name(&res_dev->dev));
	}
551
	sysfs_remove_group(&adev->dev.kobj, attr_group);
552 553
}

554 555
static void acpi_power_expose_list(struct acpi_device *adev,
				   struct list_head *resources,
556
				   const struct attribute_group *attr_group)
557
{
558 559 560
	struct acpi_power_resource_entry *entry;
	int ret;

561
	if (list_empty(resources))
562 563
		return;

564
	ret = sysfs_create_group(&adev->dev.kobj, attr_group);
565 566 567
	if (ret)
		return;

568
	list_for_each_entry(entry, resources, node) {
569 570 571
		struct acpi_device *res_dev = &entry->resource->device;

		ret = sysfs_add_link_to_group(&adev->dev.kobj,
572
					      attr_group->name,
573 574 575
					      &res_dev->dev.kobj,
					      dev_name(&res_dev->dev));
		if (ret) {
576
			acpi_power_hide_list(adev, resources, attr_group);
577
			break;
578 579 580
		}
	}
}
581

582 583
static void acpi_power_expose_hide(struct acpi_device *adev,
				   struct list_head *resources,
584
				   const struct attribute_group *attr_group,
585 586 587 588 589 590 591 592
				   bool expose)
{
	if (expose)
		acpi_power_expose_list(adev, resources, attr_group);
	else
		acpi_power_hide_list(adev, resources, attr_group);
}

593 594 595 596
void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
{
	int state;

597 598 599 600
	if (adev->wakeup.flags.valid)
		acpi_power_expose_hide(adev, &adev->wakeup.resources,
				       &wakeup_attr_group, add);

601 602 603
	if (!adev->power.flags.power_resources)
		return;

604 605 606 607
	for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++)
		acpi_power_expose_hide(adev,
				       &adev->power.states[state].resources,
				       &attr_groups[state], add);
608 609
}

610
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
611 612 613 614 615 616
{
	struct acpi_power_resource_entry *entry;
	int system_level = 5;

	list_for_each_entry(entry, list, node) {
		struct acpi_power_resource *resource = entry->resource;
617
		u8 state;
618

619 620
		mutex_lock(&resource->resource_lock);

621 622 623 624 625 626 627 628 629
		/*
		 * Make sure that the power resource state and its reference
		 * counter value are consistent with each other.
		 */
		if (!resource->ref_count &&
		    !acpi_power_get_state(resource, &state) &&
		    state == ACPI_POWER_RESOURCE_STATE_ON)
			__acpi_power_off(resource);

630 631
		if (system_level > resource->system_level)
			system_level = resource->system_level;
632 633

		mutex_unlock(&resource->resource_lock);
634
	}
635 636
	*system_level_p = system_level;
	return 0;
637 638
}

639 640 641
/* --------------------------------------------------------------------------
                             Device Power Management
   -------------------------------------------------------------------------- */
642

643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
/**
 * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
 *                          ACPI 3.0) _PSW (Power State Wake)
 * @dev: Device to handle.
 * @enable: 0 - disable, 1 - enable the wake capabilities of the device.
 * @sleep_state: Target sleep state of the system.
 * @dev_state: Target power state of the device.
 *
 * Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 * State Wake) for the device, if present.  On failure reset the device's
 * wakeup.flags.valid flag.
 *
 * RETURN VALUE:
 * 0 if either _DSW or _PSW has been successfully executed
 * 0 if neither _DSW nor _PSW has been found
 * -ENODEV if the execution of either _DSW or _PSW has failed
 */
int acpi_device_sleep_wake(struct acpi_device *dev,
661
			   int enable, int sleep_state, int dev_state)
662 663 664 665 666 667 668 669
{
	union acpi_object in_arg[3];
	struct acpi_object_list arg_list = { 3, in_arg };
	acpi_status status = AE_OK;

	/*
	 * Try to execute _DSW first.
	 *
Bjorn Helgaas's avatar
Bjorn Helgaas committed
670
	 * Three arguments are needed for the _DSW object:
671 672 673 674
	 * Argument 0: enable/disable the wake capabilities
	 * Argument 1: target system state
	 * Argument 2: target device state
	 * When _DSW object is called to disable the wake capabilities, maybe
Bjorn Helgaas's avatar
Bjorn Helgaas committed
675
	 * the first argument is filled. The values of the other two arguments
676 677 678 679 680 681 682 683 684 685 686 687
	 * are meaningless.
	 */
	in_arg[0].type = ACPI_TYPE_INTEGER;
	in_arg[0].integer.value = enable;
	in_arg[1].type = ACPI_TYPE_INTEGER;
	in_arg[1].integer.value = sleep_state;
	in_arg[2].type = ACPI_TYPE_INTEGER;
	in_arg[2].integer.value = dev_state;
	status = acpi_evaluate_object(dev->handle, "_DSW", &arg_list, NULL);
	if (ACPI_SUCCESS(status)) {
		return 0;
	} else if (status != AE_NOT_FOUND) {
688
		acpi_handle_info(dev->handle, "_DSW execution failed\n");
689 690 691 692 693
		dev->wakeup.flags.valid = 0;
		return -ENODEV;
	}

	/* Execute _PSW */
694
	status = acpi_execute_simple_method(dev->handle, "_PSW", enable);
695
	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
696
		acpi_handle_info(dev->handle, "_PSW execution failed\n");
697 698 699 700 701 702 703
		dev->wakeup.flags.valid = 0;
		return -ENODEV;
	}

	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
704 705
/*
 * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
706
 * 1. Power on the power resources required for the wakeup device
707 708
 * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 *    State Wake) for the device, if present
Linus Torvalds's avatar
Linus Torvalds committed
709
 */
710
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
Linus Torvalds's avatar
Linus Torvalds committed
711
{
712
	int err = 0;
Linus Torvalds's avatar
Linus Torvalds committed
713 714

	if (!dev || !dev->wakeup.flags.valid)
715
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
716

717 718
	mutex_lock(&acpi_device_lock);

719 720 721
	dev_dbg(&dev->dev, "Enabling wakeup power (count %d)\n",
		dev->wakeup.prepare_count);

722 723
	if (dev->wakeup.prepare_count++)
		goto out;
724

725 726 727 728 729
	err = acpi_power_on_list(&dev->wakeup.resources);
	if (err) {
		dev_err(&dev->dev, "Cannot turn on wakeup power resources\n");
		dev->wakeup.flags.valid = 0;
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
730
	}
731

732 733 734 735 736
	/*
	 * Passing 3 as the third argument below means the device may be
	 * put into arbitrary power state afterward.
	 */
	err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
737 738
	if (err) {
		acpi_power_off_list(&dev->wakeup.resources);
739
		dev->wakeup.prepare_count = 0;
740
		goto out;
741
	}
742

743 744
	dev_dbg(&dev->dev, "Wakeup power enabled\n");

745 746
 out:
	mutex_unlock(&acpi_device_lock);
747
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
748 749 750 751
}

/*
 * Shutdown a wakeup device, counterpart of above method
752 753
 * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 *    State Wake) for the device, if present
Linus Torvalds's avatar
Linus Torvalds committed
754 755
 * 2. Shutdown down the power resources
 */
Len Brown's avatar
Len Brown committed
756
int acpi_disable_wakeup_device_power(struct acpi_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
757
{
758
	struct acpi_power_resource_entry *entry;
759
	int err = 0;
Linus Torvalds's avatar
Linus Torvalds committed
760 761

	if (!dev || !dev->wakeup.flags.valid)
762
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
763

764 765
	mutex_lock(&acpi_device_lock);

766 767 768
	dev_dbg(&dev->dev, "Disabling wakeup power (count %d)\n",
		dev->wakeup.prepare_count);

769 770
	/* Do nothing if wakeup power has not been enabled for this device. */
	if (dev->wakeup.prepare_count <= 0)
771 772
		goto out;

773
	if (--dev->wakeup.prepare_count > 0)
774
		goto out;
775

776 777 778
	err = acpi_device_sleep_wake(dev, 0, 0, 0);
	if (err)
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
779

780 781 782 783
	/*
	 * All of the power resources in the list need to be turned off even if
	 * there are errors.
	 */
784
	list_for_each_entry(entry, &dev->wakeup.resources, node) {
785
		int ret;
786

787 788 789 790 791 792 793
		ret = acpi_power_off(entry->resource);
		if (ret && !err)
			err = ret;
	}
	if (err) {
		dev_err(&dev->dev, "Cannot turn off wakeup power resources\n");
		dev->wakeup.flags.valid = 0;
794
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
795 796
	}

797 798
	dev_dbg(&dev->dev, "Wakeup power disabled\n");

799 800 801
 out:
	mutex_unlock(&acpi_device_lock);
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
802 803
}

804
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
Linus Torvalds's avatar
Linus Torvalds committed
805
{
806
	u8 list_state = ACPI_POWER_RESOURCE_STATE_OFF;
Len Brown's avatar
Len Brown committed
807 808
	int result = 0;
	int i = 0;
Linus Torvalds's avatar
Linus Torvalds committed
809

810
	if (!device || !state)
811
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
812 813 814 815 816

	/*
	 * We know a device's inferred power state when all the resources
	 * required for a given D-state are 'on'.
	 */
817
	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
818 819 820
		struct list_head *list = &device->power.states[i].resources;

		if (list_empty(list))
Linus Torvalds's avatar
Linus Torvalds committed
821 822 823 824
			continue;

		result = acpi_power_get_list_state(list, &list_state);
		if (result)
825
			return result;
Linus Torvalds's avatar
Linus Torvalds committed
826 827

		if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
828
			*state = i;
829
			return 0;
Linus Torvalds's avatar
Linus Torvalds committed
830 831 832
		}
	}

833 834
	*state = device->power.states[ACPI_STATE_D3_COLD].flags.valid ?
		ACPI_STATE_D3_COLD : ACPI_STATE_D3_HOT;
835
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
836 837
}

838 839
int acpi_power_on_resources(struct acpi_device *device, int state)
{
840
	if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3_HOT)
841 842 843 844 845
		return -EINVAL;

	return acpi_power_on_list(&device->power.states[state].resources);
}

Len Brown's avatar
Len Brown committed
846
int acpi_power_transition(struct acpi_device *device, int state)
Linus Torvalds's avatar
Linus Torvalds committed
847
{
848
	int result = 0;
Linus Torvalds's avatar
Linus Torvalds committed
849

850
	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
851
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
852

853
	if (device->power.state == state || !device->flags.power_manageable)
854 855
		return 0;

Len Brown's avatar
Len Brown committed
856
	if ((device->power.state < ACPI_STATE_D0)
857
	    || (device->power.state > ACPI_STATE_D3_COLD))
858
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
859 860 861

	/*
	 * First we reference all power resources required in the target list
862 863
	 * (e.g. so the device doesn't lose power while transitioning).  Then,
	 * we dereference all power resources used in the current list.
Linus Torvalds's avatar
Linus Torvalds committed
864
	 */
865 866 867 868 869
	if (state < ACPI_STATE_D3_COLD)
		result = acpi_power_on_list(
			&device->power.states[state].resources);

	if (!result && device->power.state < ACPI_STATE_D3_COLD)
870 871
		acpi_power_off_list(
			&device->power.states[device->power.state].resources);
Linus Torvalds's avatar
Linus Torvalds committed
872

873 874
	/* We shouldn't change the state unless the above operations succeed. */
	device->power.state = result ? ACPI_STATE_UNKNOWN : state;
Linus Torvalds's avatar
Linus Torvalds committed
875

876
	return result;
Linus Torvalds's avatar
Linus Torvalds committed
877 878
}

879 880 881 882 883 884
static void acpi_release_power_resource(struct device *dev)
{
	struct acpi_device *device = to_acpi_device(dev);
	struct acpi_power_resource *resource;

	resource = container_of(device, struct acpi_power_resource, device);
885 886 887 888 889

	mutex_lock(&power_resource_list_lock);
	list_del(&resource->list_node);
	mutex_unlock(&power_resource_list_lock);

890
	acpi_free_pnp_ids(&device->pnp);
891 892
	kfree(resource);
}
Linus Torvalds's avatar
Linus Torvalds committed
893

894 895 896 897
static ssize_t resource_in_use_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
898 899 900 901 902
	struct acpi_power_resource *resource;

	resource = to_power_resource(to_acpi_device(dev));
	return sprintf(buf, "%u\n", !!resource->ref_count);
}
903
static DEVICE_ATTR_RO(resource_in_use);
904 905 906 907 908 909

static void acpi_power_sysfs_remove(struct acpi_device *device)
{
	device_remove_file(&device->dev, &dev_attr_resource_in_use);
}

910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
static void acpi_power_add_resource_to_list(struct acpi_power_resource *resource)
{
	mutex_lock(&power_resource_list_lock);

	if (!list_empty(&acpi_power_resource_list)) {
		struct acpi_power_resource *r;

		list_for_each_entry(r, &acpi_power_resource_list, list_node)
			if (r->order > resource->order) {
				list_add_tail(&resource->list_node, &r->list_node);
				goto out;
			}
	}
	list_add_tail(&resource->list_node, &acpi_power_resource_list);

 out:
	mutex_unlock(&power_resource_list_lock);
}

929
struct acpi_device *acpi_add_power_resource(acpi_handle handle)
Linus Torvalds's avatar
Linus Torvalds committed
930
{
931
	struct acpi_device *device = acpi_fetch_acpi_dev(handle);
932
	struct acpi_power_resource *resource;
Len Brown's avatar
Len Brown committed
933 934
	union acpi_object acpi_object;
	struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
935
	acpi_status status;
936
	u8 state_dummy;
937
	int result;
Linus Torvalds's avatar
Linus Torvalds committed
938

939
	if (device)
940
		return device;
Linus Torvalds's avatar
Linus Torvalds committed
941

942
	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
943
	if (!resource)
944
		return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
945

946
	device = &resource->device;
947 948
	acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER,
				acpi_release_power_resource);
949
	mutex_init(&resource->resource_lock);
950
	INIT_LIST_HEAD(&resource->list_node);
951
	INIT_LIST_HEAD(&resource->dependents);
Linus Torvalds's avatar
Linus Torvalds committed
952 953
	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
954
	device->power.state = ACPI_STATE_UNKNOWN;
955
	device->flags.match_driver = true;
Linus Torvalds's avatar
Linus Torvalds committed
956

957
	/* Evaluate the object to get the system level and resource order. */
958 959
	status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status))
960
		goto err;
961

Linus Torvalds's avatar
Linus Torvalds committed
962 963
	resource->system_level = acpi_object.power_resource.system_level;
	resource->order = acpi_object.power_resource.resource_order;
964
	resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
Linus Torvalds's avatar
Linus Torvalds committed
965

966 967 968 969
	/* Get the initial state or just flip it on if that fails. */
	if (acpi_power_get_state(resource, &state_dummy))
		__acpi_power_on(resource);

970
	pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
Linus Torvalds's avatar
Linus Torvalds committed
971

972 973 974 975
	result = acpi_tie_acpi_dev(device);
	if (result)
		goto err;

976
	result = acpi_device_add(device);
Linus Torvalds's avatar
Linus Torvalds committed
977
	if (result)
978
		goto err;
Len Brown's avatar
Len Brown committed
979

980 981 982
	if (!device_create_file(&device->dev, &dev_attr_resource_in_use))
		device->remove = acpi_power_sysfs_remove;

983
	acpi_power_add_resource_to_list(resource);
984
	acpi_device_add_finalize(device);
985
	return device;
Linus Torvalds's avatar
Linus Torvalds committed
986

987 988
 err:
	acpi_release_power_resource(&device->dev);
989
	return NULL;
990
}
Linus Torvalds's avatar
Linus Torvalds committed
991

992 993
#ifdef CONFIG_ACPI_SLEEP
void acpi_resume_power_resources(void)
994
{
995
	struct acpi_power_resource *resource;
996

997
	mutex_lock(&power_resource_list_lock);
998

999
	list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
1000 1001
		int result;
		u8 state;
1002

1003
		mutex_lock(&resource->resource_lock);
1004

1005 1006
		resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
		result = acpi_power_get_state(resource, &state);
1007 1008
		if (result) {
			mutex_unlock(&resource->resource_lock);
1009
			continue;
1010
		}
1011 1012

		if (state == ACPI_POWER_RESOURCE_STATE_OFF
1013
		    && resource->ref_count) {
1014
			acpi_handle_debug(resource->device.handle, "Turning ON\n");
1015
			__acpi_power_on(resource);
1016 1017 1018 1019
		}

		mutex_unlock(&resource->resource_lock);
	}
1020 1021 1022

	mutex_unlock(&power_resource_list_lock);
}
1023
#endif
1024

1025 1026 1027
/**
 * acpi_turn_off_unused_power_resources - Turn off power resources not in use.
 */
1028
void acpi_turn_off_unused_power_resources(void)
1029 1030 1031 1032 1033
{
	struct acpi_power_resource *resource;

	mutex_lock(&power_resource_list_lock);

1034 1035 1036
	list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
		mutex_lock(&resource->resource_lock);

1037
		if (!resource->ref_count &&
1038
		    resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
1039
			acpi_handle_debug(resource->device.handle, "Turning OFF\n");
1040 1041
			__acpi_power_off(resource);
		}
1042

1043 1044
		mutex_unlock(&resource->resource_lock);
	}
1045

1046
	mutex_unlock(&power_resource_list_lock);
1047
}