Skip to content

Commit ec612fc

Browse files
committed
Merge branch 'd3' into release
Conflicts: drivers/acpi/sleep.c This was a text conflict between a2ef5c4 (ACPI: Move module parameter gts and bfs to sleep.c) which added #include <linux/module.h> and b24e509 (ACPI, PCI: Move acpi_dev_run_wake() to ACPI core) which added #include <linux/pm_runtime.h> The resolution was to take them both. Signed-off-by: Len Brown <[email protected]>
2 parents 73f0533 + b24e509 commit ec612fc

File tree

5 files changed

+216
-39
lines changed

5 files changed

+216
-39
lines changed

drivers/acpi/power.c

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040
#include <linux/init.h>
4141
#include <linux/types.h>
4242
#include <linux/slab.h>
43+
#include <linux/pm_runtime.h>
4344
#include <acpi/acpi_bus.h>
4445
#include <acpi/acpi_drivers.h>
4546
#include "sleep.h"
47+
#include "internal.h"
4648

4749
#define PREFIX "ACPI: "
4850

@@ -77,13 +79,30 @@ static struct acpi_driver acpi_power_driver = {
7779
},
7880
};
7981

82+
/*
83+
* A power managed device
84+
* A device may rely on multiple power resources.
85+
* */
86+
struct acpi_power_managed_device {
87+
struct device *dev; /* The physical device */
88+
acpi_handle *handle;
89+
};
90+
91+
struct acpi_power_resource_device {
92+
struct acpi_power_managed_device *device;
93+
struct acpi_power_resource_device *next;
94+
};
95+
8096
struct acpi_power_resource {
8197
struct acpi_device * device;
8298
acpi_bus_id name;
8399
u32 system_level;
84100
u32 order;
85101
unsigned int ref_count;
86102
struct mutex resource_lock;
103+
104+
/* List of devices relying on this power resource */
105+
struct acpi_power_resource_device *devices;
87106
};
88107

89108
static struct list_head acpi_power_resource_list;
@@ -183,8 +202,26 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
183202
return 0;
184203
}
185204

205+
/* Resume the device when all power resources in _PR0 are on */
206+
static void acpi_power_on_device(struct acpi_power_managed_device *device)
207+
{
208+
struct acpi_device *acpi_dev;
209+
acpi_handle handle = device->handle;
210+
int state;
211+
212+
if (acpi_bus_get_device(handle, &acpi_dev))
213+
return;
214+
215+
if(acpi_power_get_inferred_state(acpi_dev, &state))
216+
return;
217+
218+
if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev))
219+
pm_request_resume(device->dev);
220+
}
221+
186222
static int __acpi_power_on(struct acpi_power_resource *resource)
187223
{
224+
struct acpi_power_resource_device *device_list = resource->devices;
188225
acpi_status status = AE_OK;
189226

190227
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
@@ -197,6 +234,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
197234
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
198235
resource->name));
199236

237+
while (device_list) {
238+
acpi_power_on_device(device_list->device);
239+
240+
device_list = device_list->next;
241+
}
242+
200243
return 0;
201244
}
202245

@@ -299,6 +342,125 @@ static int acpi_power_on_list(struct acpi_handle_list *list)
299342
return result;
300343
}
301344

345+
static void __acpi_power_resource_unregister_device(struct device *dev,
346+
acpi_handle res_handle)
347+
{
348+
struct acpi_power_resource *resource = NULL;
349+
struct acpi_power_resource_device *prev, *curr;
350+
351+
if (acpi_power_get_context(res_handle, &resource))
352+
return;
353+
354+
mutex_lock(&resource->resource_lock);
355+
prev = NULL;
356+
curr = resource->devices;
357+
while (curr) {
358+
if (curr->device->dev == dev) {
359+
if (!prev)
360+
resource->devices = curr->next;
361+
else
362+
prev->next = curr->next;
363+
364+
kfree(curr);
365+
break;
366+
}
367+
368+
prev = curr;
369+
curr = curr->next;
370+
}
371+
mutex_unlock(&resource->resource_lock);
372+
}
373+
374+
/* Unlink dev from all power resources in _PR0 */
375+
void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle)
376+
{
377+
struct acpi_device *acpi_dev;
378+
struct acpi_handle_list *list;
379+
int i;
380+
381+
if (!dev || !handle)
382+
return;
383+
384+
if (acpi_bus_get_device(handle, &acpi_dev))
385+
return;
386+
387+
list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
388+
389+
for (i = 0; i < list->count; i++)
390+
__acpi_power_resource_unregister_device(dev,
391+
list->handles[i]);
392+
}
393+
394+
static int __acpi_power_resource_register_device(
395+
struct acpi_power_managed_device *powered_device, acpi_handle handle)
396+
{
397+
struct acpi_power_resource *resource = NULL;
398+
struct acpi_power_resource_device *power_resource_device;
399+
int result;
400+
401+
result = acpi_power_get_context(handle, &resource);
402+
if (result)
403+
return result;
404+
405+
power_resource_device = kzalloc(
406+
sizeof(*power_resource_device), GFP_KERNEL);
407+
if (!power_resource_device)
408+
return -ENOMEM;
409+
410+
power_resource_device->device = powered_device;
411+
412+
mutex_lock(&resource->resource_lock);
413+
power_resource_device->next = resource->devices;
414+
resource->devices = power_resource_device;
415+
mutex_unlock(&resource->resource_lock);
416+
417+
return 0;
418+
}
419+
420+
/* Link dev to all power resources in _PR0 */
421+
int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
422+
{
423+
struct acpi_device *acpi_dev;
424+
struct acpi_handle_list *list;
425+
struct acpi_power_managed_device *powered_device;
426+
int i, ret;
427+
428+
if (!dev || !handle)
429+
return -ENODEV;
430+
431+
ret = acpi_bus_get_device(handle, &acpi_dev);
432+
if (ret)
433+
goto no_power_resource;
434+
435+
if (!acpi_dev->power.flags.power_resources)
436+
goto no_power_resource;
437+
438+
powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL);
439+
if (!powered_device)
440+
return -ENOMEM;
441+
442+
powered_device->dev = dev;
443+
powered_device->handle = handle;
444+
445+
list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
446+
447+
for (i = 0; i < list->count; i++) {
448+
ret = __acpi_power_resource_register_device(powered_device,
449+
list->handles[i]);
450+
451+
if (ret) {
452+
acpi_power_resource_unregister_device(dev, handle);
453+
break;
454+
}
455+
}
456+
457+
return ret;
458+
459+
no_power_resource:
460+
printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
461+
return -ENODEV;
462+
}
463+
302464
/**
303465
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
304466
* ACPI 3.0) _PSW (Power State Wake)
@@ -500,14 +662,14 @@ int acpi_power_transition(struct acpi_device *device, int state)
500662
{
501663
int result;
502664

503-
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
665+
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
504666
return -EINVAL;
505667

506668
if (device->power.state == state)
507669
return 0;
508670

509671
if ((device->power.state < ACPI_STATE_D0)
510-
|| (device->power.state > ACPI_STATE_D3))
672+
|| (device->power.state > ACPI_STATE_D3_COLD))
511673
return -ENODEV;
512674

513675
/* TBD: Resources must be ordered. */

drivers/acpi/scan.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
884884
acpi_bus_add_power_resource(ps->resources.handles[j]);
885885
}
886886

887+
/* The exist of _PR3 indicates D3Cold support */
888+
if (i == ACPI_STATE_D3) {
889+
status = acpi_get_handle(device->handle, object_name, &handle);
890+
if (ACPI_SUCCESS(status))
891+
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
892+
}
893+
887894
/* Evaluate "_PSx" to see if we can do explicit sets */
888895
object_name[2] = 'S';
889896
status = acpi_get_handle(device->handle, object_name, &handle);

drivers/acpi/sleep.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/reboot.h>
1919
#include <linux/acpi.h>
2020
#include <linux/module.h>
21+
#include <linux/pm_runtime.h>
2122

2223
#include <asm/io.h>
2324

@@ -752,6 +753,40 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
752753
#endif /* CONFIG_PM */
753754

754755
#ifdef CONFIG_PM_SLEEP
756+
/**
757+
* acpi_pm_device_run_wake - Enable/disable wake-up for given device.
758+
* @phys_dev: Device to enable/disable the platform to wake-up the system for.
759+
* @enable: Whether enable or disable the wake-up functionality.
760+
*
761+
* Find the ACPI device object corresponding to @pci_dev and try to
762+
* enable/disable the GPE associated with it.
763+
*/
764+
int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
765+
{
766+
struct acpi_device *dev;
767+
acpi_handle handle;
768+
769+
if (!device_run_wake(phys_dev))
770+
return -EINVAL;
771+
772+
handle = DEVICE_ACPI_HANDLE(phys_dev);
773+
if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
774+
dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
775+
__func__);
776+
return -ENODEV;
777+
}
778+
779+
if (enable) {
780+
acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
781+
acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
782+
} else {
783+
acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
784+
acpi_disable_wakeup_device_power(dev);
785+
}
786+
787+
return 0;
788+
}
789+
755790
/**
756791
* acpi_pm_device_sleep_wake - enable or disable the system wake-up
757792
* capability of given device

drivers/pci/pci-acpi.c

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -277,63 +277,29 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
277277
return 0;
278278
}
279279

280-
/**
281-
* acpi_dev_run_wake - Enable/disable wake-up for given device.
282-
* @phys_dev: Device to enable/disable the platform to wake-up the system for.
283-
* @enable: Whether enable or disable the wake-up functionality.
284-
*
285-
* Find the ACPI device object corresponding to @pci_dev and try to
286-
* enable/disable the GPE associated with it.
287-
*/
288-
static int acpi_dev_run_wake(struct device *phys_dev, bool enable)
289-
{
290-
struct acpi_device *dev;
291-
acpi_handle handle;
292-
293-
if (!device_run_wake(phys_dev))
294-
return -EINVAL;
295-
296-
handle = DEVICE_ACPI_HANDLE(phys_dev);
297-
if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
298-
dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
299-
__func__);
300-
return -ENODEV;
301-
}
302-
303-
if (enable) {
304-
acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
305-
acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
306-
} else {
307-
acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
308-
acpi_disable_wakeup_device_power(dev);
309-
}
310-
311-
return 0;
312-
}
313-
314280
static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
315281
{
316282
while (bus->parent) {
317283
struct pci_dev *bridge = bus->self;
318284

319285
if (bridge->pme_interrupt)
320286
return;
321-
if (!acpi_dev_run_wake(&bridge->dev, enable))
287+
if (!acpi_pm_device_run_wake(&bridge->dev, enable))
322288
return;
323289
bus = bus->parent;
324290
}
325291

326292
/* We have reached the root bus. */
327293
if (bus->bridge)
328-
acpi_dev_run_wake(bus->bridge, enable);
294+
acpi_pm_device_run_wake(bus->bridge, enable);
329295
}
330296

331297
static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
332298
{
333299
if (dev->pme_interrupt)
334300
return 0;
335301

336-
if (!acpi_dev_run_wake(&dev->dev, enable))
302+
if (!acpi_pm_device_run_wake(&dev->dev, enable))
337303
return 0;
338304

339305
acpi_pci_propagate_run_wake(dev->bus, enable);

include/acpi/acpi_bus.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ int acpi_bus_set_power(acpi_handle handle, int state);
323323
int acpi_bus_update_power(acpi_handle handle, int *state_p);
324324
bool acpi_bus_power_manageable(acpi_handle handle);
325325
bool acpi_bus_can_wakeup(acpi_handle handle);
326+
int acpi_power_resource_register_device(struct device *dev, acpi_handle handle);
327+
void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle);
326328
#ifdef CONFIG_ACPI_PROC_EVENT
327329
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
328330
int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
@@ -392,8 +394,13 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
392394
#endif
393395

394396
#ifdef CONFIG_PM_SLEEP
397+
int acpi_pm_device_run_wake(struct device *, bool);
395398
int acpi_pm_device_sleep_wake(struct device *, bool);
396399
#else
400+
static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
401+
{
402+
return -ENODEV;
403+
}
397404
static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
398405
{
399406
return -ENODEV;

0 commit comments

Comments
 (0)