power.c 25.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
L
Linus Torvalds 已提交
2
/*
3
 * drivers/acpi/power.c - ACPI Power Resources management.
L
Linus Torvalds 已提交
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>
L
Linus Torvalds 已提交
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.
L
Linus Torvalds 已提交
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.
 *
L
Linus Torvalds 已提交
20 21 22 23 24 25 26 27
 * A device may rely on multiple power resources, and a power resource
 * may be shared by multiple devices.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
28
#include <linux/slab.h>
29
#include <linux/pm_runtime.h>
30
#include <linux/sysfs.h>
31
#include <linux/acpi.h>
32
#include "sleep.h"
33
#include "internal.h"
34

35
#define _COMPONENT			ACPI_POWER_COMPONENT
36
ACPI_MODULE_NAME("power");
L
Linus Torvalds 已提交
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;
};

L
Len Brown 已提交
48
struct acpi_power_resource {
49
	struct acpi_device device;
50
	struct list_head list_node;
51
	char *name;
L
Len Brown 已提交
52 53
	u32 system_level;
	u32 order;
54
	unsigned int ref_count;
55
	bool wakeup_enabled;
56
	struct mutex resource_lock;
57
	struct list_head dependents;
L
Linus Torvalds 已提交
58 59
};

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

65 66
static LIST_HEAD(acpi_power_resource_list);
static DEFINE_MUTEX(power_resource_list_lock);
L
Linus Torvalds 已提交
67 68 69 70 71

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

72 73 74 75 76 77
static inline
struct acpi_power_resource *to_power_resource(struct acpi_device *device)
{
	return container_of(device, struct acpi_power_resource, device);
}

78
static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
L
Linus Torvalds 已提交
79
{
80
	struct acpi_device *device;
L
Linus Torvalds 已提交
81

82 83
	if (acpi_bus_get_device(handle, &device))
		return NULL;
L
Linus Torvalds 已提交
84

85
	return to_power_resource(device);
L
Linus Torvalds 已提交
86 87
}

88 89
static int acpi_power_resources_list_add(acpi_handle handle,
					 struct list_head *list)
90 91 92 93 94
{
	struct acpi_power_resource *resource = acpi_power_get_context(handle);
	struct acpi_power_resource_entry *entry;

	if (!resource || !list)
95
		return -EINVAL;
96 97 98

	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
99
		return -ENOMEM;
100 101 102 103 104 105 106 107

	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);
108
				return 0;
109 110 111
			}
	}
	list_add_tail(&entry->node, list);
112
	return 0;
113 114 115 116 117 118 119 120 121 122 123 124
}

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);
	}
}

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
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;
}

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

	for (i = start; i < package->package.count; i++) {
		union acpi_object *element = &package->package.elements[i];
		acpi_handle rhandle;

		if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
153
			err = -ENODATA;
154 155 156 157
			break;
		}
		rhandle = element->reference.handle;
		if (!rhandle) {
158
			err = -ENODEV;
159 160
			break;
		}
161 162 163 164 165

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

166 167 168 169 170 171 172
		err = acpi_add_power_resource(rhandle);
		if (err)
			break;

		err = acpi_power_resources_list_add(rhandle, list);
		if (err)
			break;
173
	}
174
	if (err)
175 176
		acpi_power_resources_list_free(list);

177
	return err;
178 179
}

180
static int acpi_power_get_state(acpi_handle handle, int *state)
L
Linus Torvalds 已提交
181
{
L
Len Brown 已提交
182
	acpi_status status = AE_OK;
183
	unsigned long long sta = 0;
184 185
	char node_name[5];
	struct acpi_buffer buffer = { sizeof(node_name), node_name };
L
Linus Torvalds 已提交
186 187


188
	if (!handle || !state)
189
		return -EINVAL;
L
Linus Torvalds 已提交
190

191
	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
L
Linus Torvalds 已提交
192
	if (ACPI_FAILURE(status))
193
		return -ENODEV;
L
Linus Torvalds 已提交
194

195 196
	*state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
			      ACPI_POWER_RESOURCE_STATE_OFF;
L
Linus Torvalds 已提交
197

198 199
	acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);

L
Linus Torvalds 已提交
200
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
201
			  node_name,
202
				*state ? "on" : "off"));
L
Linus Torvalds 已提交
203

204
	return 0;
L
Linus Torvalds 已提交
205 206
}

207
static int acpi_power_get_list_state(struct list_head *list, int *state)
L
Linus Torvalds 已提交
208
{
209
	struct acpi_power_resource_entry *entry;
210
	int cur_state;
L
Linus Torvalds 已提交
211 212

	if (!list || !state)
213
		return -EINVAL;
L
Linus Torvalds 已提交
214 215

	/* The state of the list is 'on' IFF all resources are 'on'. */
216
	cur_state = 0;
217 218 219
	list_for_each_entry(entry, list, node) {
		struct acpi_power_resource *resource = entry->resource;
		acpi_handle handle = resource->device.handle;
220 221 222 223 224 225 226 227 228
		int result;

		mutex_lock(&resource->resource_lock);
		result = acpi_power_get_state(handle, &cur_state);
		mutex_unlock(&resource->resource_lock);
		if (result)
			return result;

		if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
L
Linus Torvalds 已提交
229 230 231 232
			break;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
233
			  cur_state ? "on" : "off"));
L
Linus Torvalds 已提交
234

235 236
	*state = cur_state;
	return 0;
L
Linus Torvalds 已提交
237 238
}

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 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
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);
	dev_dbg(dev, "added power dependency to [%s]\n", resource->name);

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",
				resource->name);
			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);
}

351
static int __acpi_power_on(struct acpi_power_resource *resource)
L
Linus Torvalds 已提交
352
{
353
	struct acpi_power_dependent_device *dep;
L
Len Brown 已提交
354
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
355

356
	status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL);
357 358 359 360 361 362
	if (ACPI_FAILURE(status))
		return -ENODEV;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
			  resource->name));

363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
	/*
	 * 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",
			resource->name);
		pm_request_resume(dep->dev);
	}

378 379 380
	return 0;
}

381
static int acpi_power_on_unlocked(struct acpi_power_resource *resource)
382
{
383
	int result = 0;
384

385 386
	if (resource->ref_count++) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
387
				  "Power resource [%s] already on\n",
388 389 390
				  resource->name));
	} else {
		result = __acpi_power_on(resource);
391
		if (result)
392
			resource->ref_count--;
393
	}
394 395
	return result;
}
396

397 398 399
static int acpi_power_on(struct acpi_power_resource *resource)
{
	int result;
400

401 402 403
	mutex_lock(&resource->resource_lock);
	result = acpi_power_on_unlocked(resource);
	mutex_unlock(&resource->resource_lock);
404
	return result;
L
Linus Torvalds 已提交
405 406
}

407 408 409 410 411 412 413 414 415 416 417 418 419 420
static int __acpi_power_off(struct acpi_power_resource *resource)
{
	acpi_status status;

	status = acpi_evaluate_object(resource->device.handle, "_OFF",
				      NULL, NULL);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned off\n",
			  resource->name));
	return 0;
}

421
static int acpi_power_off_unlocked(struct acpi_power_resource *resource)
L
Linus Torvalds 已提交
422
{
423
	int result = 0;
L
Linus Torvalds 已提交
424

425 426
	if (!resource->ref_count) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
427
				  "Power resource [%s] already off\n",
428
				  resource->name));
429
		return 0;
430
	}
L
Linus Torvalds 已提交
431

432 433 434 435
	if (--resource->ref_count) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Power resource [%s] still in use\n",
				  resource->name));
436 437 438 439
	} else {
		result = __acpi_power_off(resource);
		if (result)
			resource->ref_count++;
L
Linus Torvalds 已提交
440
	}
441 442
	return result;
}
L
Linus Torvalds 已提交
443

444 445 446
static int acpi_power_off(struct acpi_power_resource *resource)
{
	int result;
L
Linus Torvalds 已提交
447

448 449 450
	mutex_lock(&resource->resource_lock);
	result = acpi_power_off_unlocked(resource);
	mutex_unlock(&resource->resource_lock);
451
	return result;
L
Linus Torvalds 已提交
452 453
}

454
static int acpi_power_off_list(struct list_head *list)
455
{
456 457
	struct acpi_power_resource_entry *entry;
	int result = 0;
458

459 460 461 462 463 464
	list_for_each_entry_reverse(entry, list, node) {
		result = acpi_power_off(entry->resource);
		if (result)
			goto err;
	}
	return 0;
465

466 467 468 469 470
 err:
	list_for_each_entry_continue(entry, list, node)
		acpi_power_on(entry->resource);

	return result;
471 472
}

473
static int acpi_power_on_list(struct list_head *list)
474
{
475
	struct acpi_power_resource_entry *entry;
476 477
	int result = 0;

478 479 480 481
	list_for_each_entry(entry, list, node) {
		result = acpi_power_on(entry->resource);
		if (result)
			goto err;
482
	}
483 484 485 486 487
	return 0;

 err:
	list_for_each_entry_continue_reverse(entry, list, node)
		acpi_power_off(entry->resource);
488 489 490 491

	return result;
}

492 493 494 495
static struct attribute *attrs[] = {
	NULL,
};

496
static const struct attribute_group attr_groups[] = {
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
	[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,
	},
};

515
static const struct attribute_group wakeup_attr_group = {
516 517 518 519 520 521
	.name = "power_resources_wakeup",
	.attrs = attrs,
};

static void acpi_power_hide_list(struct acpi_device *adev,
				 struct list_head *resources,
522
				 const struct attribute_group *attr_group)
523 524 525
{
	struct acpi_power_resource_entry *entry;

526
	if (list_empty(resources))
527 528
		return;

529
	list_for_each_entry_reverse(entry, resources, node) {
530 531 532
		struct acpi_device *res_dev = &entry->resource->device;

		sysfs_remove_link_from_group(&adev->dev.kobj,
533
					     attr_group->name,
534 535
					     dev_name(&res_dev->dev));
	}
536
	sysfs_remove_group(&adev->dev.kobj, attr_group);
537 538
}

539 540
static void acpi_power_expose_list(struct acpi_device *adev,
				   struct list_head *resources,
541
				   const struct attribute_group *attr_group)
542
{
543 544 545
	struct acpi_power_resource_entry *entry;
	int ret;

546
	if (list_empty(resources))
547 548
		return;

549
	ret = sysfs_create_group(&adev->dev.kobj, attr_group);
550 551 552
	if (ret)
		return;

553
	list_for_each_entry(entry, resources, node) {
554 555 556
		struct acpi_device *res_dev = &entry->resource->device;

		ret = sysfs_add_link_to_group(&adev->dev.kobj,
557
					      attr_group->name,
558 559 560
					      &res_dev->dev.kobj,
					      dev_name(&res_dev->dev));
		if (ret) {
561
			acpi_power_hide_list(adev, resources, attr_group);
562
			break;
563 564 565
		}
	}
}
566

567 568
static void acpi_power_expose_hide(struct acpi_device *adev,
				   struct list_head *resources,
569
				   const struct attribute_group *attr_group,
570 571 572 573 574 575 576 577
				   bool expose)
{
	if (expose)
		acpi_power_expose_list(adev, resources, attr_group);
	else
		acpi_power_hide_list(adev, resources, attr_group);
}

578 579 580 581
void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
{
	int state;

582 583 584 585
	if (adev->wakeup.flags.valid)
		acpi_power_expose_hide(adev, &adev->wakeup.resources,
				       &wakeup_attr_group, add);

586 587 588
	if (!adev->power.flags.power_resources)
		return;

589 590 591 592
	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);
593 594
}

595
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
596 597 598 599 600 601
{
	struct acpi_power_resource_entry *entry;
	int system_level = 5;

	list_for_each_entry(entry, list, node) {
		struct acpi_power_resource *resource = entry->resource;
602 603 604
		acpi_handle handle = resource->device.handle;
		int result;
		int state;
605

606 607 608 609 610 611 612 613 614 615 616
		mutex_lock(&resource->resource_lock);

		result = acpi_power_get_state(handle, &state);
		if (result) {
			mutex_unlock(&resource->resource_lock);
			return result;
		}
		if (state == ACPI_POWER_RESOURCE_STATE_ON) {
			resource->ref_count++;
			resource->wakeup_enabled = true;
		}
617 618
		if (system_level > resource->system_level)
			system_level = resource->system_level;
619 620

		mutex_unlock(&resource->resource_lock);
621
	}
622 623
	*system_level_p = system_level;
	return 0;
624 625
}

626 627 628
/* --------------------------------------------------------------------------
                             Device Power Management
   -------------------------------------------------------------------------- */
629

630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
/**
 * 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,
                           int enable, int sleep_state, int dev_state)
{
	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.
	 *
B
Bjorn Helgaas 已提交
657
	 * Three arguments are needed for the _DSW object:
658 659 660 661
	 * 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
B
Bjorn Helgaas 已提交
662
	 * the first argument is filled. The values of the other two arguments
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
	 * 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) {
		printk(KERN_ERR PREFIX "_DSW execution failed\n");
		dev->wakeup.flags.valid = 0;
		return -ENODEV;
	}

	/* Execute _PSW */
681
	status = acpi_execute_simple_method(dev->handle, "_PSW", enable);
682 683 684 685 686 687 688 689 690
	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
		printk(KERN_ERR PREFIX "_PSW execution failed\n");
		dev->wakeup.flags.valid = 0;
		return -ENODEV;
	}

	return 0;
}

L
Linus Torvalds 已提交
691 692 693
/*
 * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
 * 1. Power on the power resources required for the wakeup device 
694 695
 * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 *    State Wake) for the device, if present
L
Linus Torvalds 已提交
696
 */
697
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
L
Linus Torvalds 已提交
698
{
699
	struct acpi_power_resource_entry *entry;
700
	int err = 0;
L
Linus Torvalds 已提交
701 702

	if (!dev || !dev->wakeup.flags.valid)
703
		return -EINVAL;
L
Linus Torvalds 已提交
704

705 706 707 708
	mutex_lock(&acpi_device_lock);

	if (dev->wakeup.prepare_count++)
		goto out;
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
	list_for_each_entry(entry, &dev->wakeup.resources, node) {
		struct acpi_power_resource *resource = entry->resource;

		mutex_lock(&resource->resource_lock);

		if (!resource->wakeup_enabled) {
			err = acpi_power_on_unlocked(resource);
			if (!err)
				resource->wakeup_enabled = true;
		}

		mutex_unlock(&resource->resource_lock);

		if (err) {
			dev_err(&dev->dev,
				"Cannot turn wakeup power resources on\n");
			dev->wakeup.flags.valid = 0;
			goto out;
		}
L
Linus Torvalds 已提交
729
	}
730 731 732 733 734
	/*
	 * 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);
735 736 737 738 739
	if (err)
		dev->wakeup.prepare_count = 0;

 out:
	mutex_unlock(&acpi_device_lock);
740
	return err;
L
Linus Torvalds 已提交
741 742 743 744
}

/*
 * Shutdown a wakeup device, counterpart of above method
745 746
 * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 *    State Wake) for the device, if present
L
Linus Torvalds 已提交
747 748
 * 2. Shutdown down the power resources
 */
L
Len Brown 已提交
749
int acpi_disable_wakeup_device_power(struct acpi_device *dev)
L
Linus Torvalds 已提交
750
{
751
	struct acpi_power_resource_entry *entry;
752
	int err = 0;
L
Linus Torvalds 已提交
753 754

	if (!dev || !dev->wakeup.flags.valid)
755
		return -EINVAL;
L
Linus Torvalds 已提交
756

757 758 759 760 761
	mutex_lock(&acpi_device_lock);

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

762
	/*
763 764
	 * Executing the code below even if prepare_count is already zero when
	 * the function is called may be useful, for example for initialisation.
765
	 */
766 767
	if (dev->wakeup.prepare_count < 0)
		dev->wakeup.prepare_count = 0;
768

769 770 771
	err = acpi_device_sleep_wake(dev, 0, 0, 0);
	if (err)
		goto out;
L
Linus Torvalds 已提交
772

773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
	list_for_each_entry(entry, &dev->wakeup.resources, node) {
		struct acpi_power_resource *resource = entry->resource;

		mutex_lock(&resource->resource_lock);

		if (resource->wakeup_enabled) {
			err = acpi_power_off_unlocked(resource);
			if (!err)
				resource->wakeup_enabled = false;
		}

		mutex_unlock(&resource->resource_lock);

		if (err) {
			dev_err(&dev->dev,
				"Cannot turn wakeup power resources off\n");
			dev->wakeup.flags.valid = 0;
			break;
		}
L
Linus Torvalds 已提交
792 793
	}

794 795 796
 out:
	mutex_unlock(&acpi_device_lock);
	return err;
L
Linus Torvalds 已提交
797 798
}

799
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
L
Linus Torvalds 已提交
800
{
L
Len Brown 已提交
801 802 803
	int result = 0;
	int list_state = 0;
	int i = 0;
L
Linus Torvalds 已提交
804

805
	if (!device || !state)
806
		return -EINVAL;
L
Linus Torvalds 已提交
807 808 809 810 811

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

		if (list_empty(list))
L
Linus Torvalds 已提交
816 817 818 819
			continue;

		result = acpi_power_get_list_state(list, &list_state);
		if (result)
820
			return result;
L
Linus Torvalds 已提交
821 822

		if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
823
			*state = i;
824
			return 0;
L
Linus Torvalds 已提交
825 826 827
		}
	}

828 829
	*state = device->power.states[ACPI_STATE_D3_COLD].flags.valid ?
		ACPI_STATE_D3_COLD : ACPI_STATE_D3_HOT;
830
	return 0;
L
Linus Torvalds 已提交
831 832
}

833 834
int acpi_power_on_resources(struct acpi_device *device, int state)
{
835
	if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3_HOT)
836 837 838 839 840
		return -EINVAL;

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

L
Len Brown 已提交
841
int acpi_power_transition(struct acpi_device *device, int state)
L
Linus Torvalds 已提交
842
{
843
	int result = 0;
L
Linus Torvalds 已提交
844

845
	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
846
		return -EINVAL;
L
Linus Torvalds 已提交
847

848
	if (device->power.state == state || !device->flags.power_manageable)
849 850
		return 0;

L
Len Brown 已提交
851
	if ((device->power.state < ACPI_STATE_D0)
852
	    || (device->power.state > ACPI_STATE_D3_COLD))
853
		return -ENODEV;
L
Linus Torvalds 已提交
854 855 856

	/*
	 * First we reference all power resources required in the target list
857 858
	 * (e.g. so the device doesn't lose power while transitioning).  Then,
	 * we dereference all power resources used in the current list.
L
Linus Torvalds 已提交
859
	 */
860 861 862 863 864
	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)
865 866
		acpi_power_off_list(
			&device->power.states[device->power.state].resources);
L
Linus Torvalds 已提交
867

868 869
	/* We shouldn't change the state unless the above operations succeed. */
	device->power.state = result ? ACPI_STATE_UNKNOWN : state;
L
Linus Torvalds 已提交
870

871
	return result;
L
Linus Torvalds 已提交
872 873
}

874 875 876 877 878 879
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);
880 881 882 883 884

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

885
	acpi_free_pnp_ids(&device->pnp);
886 887
	kfree(resource);
}
L
Linus Torvalds 已提交
888

889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
static ssize_t acpi_power_in_use_show(struct device *dev,
				      struct device_attribute *attr,
				      char *buf) {
	struct acpi_power_resource *resource;

	resource = to_power_resource(to_acpi_device(dev));
	return sprintf(buf, "%u\n", !!resource->ref_count);
}
static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL);

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

904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
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);
}

923
int acpi_add_power_resource(acpi_handle handle)
L
Linus Torvalds 已提交
924
{
925 926
	struct acpi_power_resource *resource;
	struct acpi_device *device = NULL;
L
Len Brown 已提交
927 928
	union acpi_object acpi_object;
	struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
929 930
	acpi_status status;
	int state, result = -ENODEV;
L
Linus Torvalds 已提交
931

932 933
	acpi_bus_get_device(handle, &device);
	if (device)
934
		return 0;
L
Linus Torvalds 已提交
935

936
	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
L
Linus Torvalds 已提交
937
	if (!resource)
938
		return -ENOMEM;
L
Linus Torvalds 已提交
939

940 941 942
	device = &resource->device;
	acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER,
				ACPI_STA_DEFAULT);
943
	mutex_init(&resource->resource_lock);
944
	INIT_LIST_HEAD(&resource->list_node);
945
	INIT_LIST_HEAD(&resource->dependents);
946
	resource->name = device->pnp.bus_id;
L
Linus Torvalds 已提交
947 948
	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
949
	device->power.state = ACPI_STATE_UNKNOWN;
L
Linus Torvalds 已提交
950 951

	/* Evalute the object to get the system level and resource order. */
952 953
	status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
	if (ACPI_FAILURE(status))
954
		goto err;
955

L
Linus Torvalds 已提交
956 957 958
	resource->system_level = acpi_object.power_resource.system_level;
	resource->order = acpi_object.power_resource.resource_order;

959
	result = acpi_power_get_state(handle, &state);
L
Linus Torvalds 已提交
960
	if (result)
961
		goto err;
L
Linus Torvalds 已提交
962 963

	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
964
	       acpi_device_bid(device), state ? "on" : "off");
L
Linus Torvalds 已提交
965

966
	device->flags.match_driver = true;
967
	result = acpi_device_add(device, acpi_release_power_resource);
L
Linus Torvalds 已提交
968
	if (result)
969
		goto err;
L
Len Brown 已提交
970

971 972 973
	if (!device_create_file(&device->dev, &dev_attr_resource_in_use))
		device->remove = acpi_power_sysfs_remove;

974
	acpi_power_add_resource_to_list(resource);
975
	acpi_device_add_finalize(device);
976
	return 0;
L
Linus Torvalds 已提交
977

978 979
 err:
	acpi_release_power_resource(&device->dev);
980
	return result;
981
}
L
Linus Torvalds 已提交
982

983 984
#ifdef CONFIG_ACPI_SLEEP
void acpi_resume_power_resources(void)
985
{
986
	struct acpi_power_resource *resource;
987

988
	mutex_lock(&power_resource_list_lock);
989

990 991
	list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
		int result, state;
992

993
		mutex_lock(&resource->resource_lock);
994

995
		result = acpi_power_get_state(resource->device.handle, &state);
996 997
		if (result) {
			mutex_unlock(&resource->resource_lock);
998
			continue;
999
		}
1000 1001

		if (state == ACPI_POWER_RESOURCE_STATE_OFF
1002 1003 1004
		    && resource->ref_count) {
			dev_info(&resource->device.dev, "Turning ON\n");
			__acpi_power_on(resource);
1005 1006 1007 1008
		}

		mutex_unlock(&resource->resource_lock);
	}
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018

	mutex_unlock(&power_resource_list_lock);
}

void acpi_turn_off_unused_power_resources(void)
{
	struct acpi_power_resource *resource;

	mutex_lock(&power_resource_list_lock);

1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
	list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
		int result, state;

		mutex_lock(&resource->resource_lock);

		result = acpi_power_get_state(resource->device.handle, &state);
		if (result) {
			mutex_unlock(&resource->resource_lock);
			continue;
		}

		if (state == ACPI_POWER_RESOURCE_STATE_ON
1031 1032 1033
		    && !resource->ref_count) {
			dev_info(&resource->device.dev, "Turning OFF\n");
			__acpi_power_off(resource);
1034
		}
1035

1036 1037
		mutex_unlock(&resource->resource_lock);
	}
1038

1039
	mutex_unlock(&power_resource_list_lock);
1040
}
1041
#endif