summaryrefslogtreecommitdiffstats
path: root/runtime_pm_fixups.patch
blob: 1be6149d6401b1fb3230d0ba0696e6b4cffa9f4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 141d0d01ab292d4ea3a6d5e96b4048e10e68c1d3 Mon Sep 17 00:00:00 2001
From: Kyle McMartin <kyle@mcmartin.ca>
Date: Mon, 24 Jan 2011 13:01:57 -0500
Subject: [PATCH] runtime_pm_fixups

---
 drivers/acpi/bus.c      |    3 ++-
 drivers/acpi/pci_bind.c |    6 ++++++
 drivers/acpi/power.c    |    5 ++++-
 drivers/acpi/sleep.c    |    2 +-
 drivers/acpi/wakeup.c   |    2 +-
 drivers/pci/pci-acpi.c  |    2 +-
 include/acpi/acpi_bus.h |    2 +-
 7 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 7ced61f..e4e0114 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -256,7 +256,8 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state)
 	 * a lower-powered state.
 	 */
 	if (state < device->power.state) {
-		if (device->power.flags.power_resources) {
+		if (device->power.flags.power_resources &&
+		    !device->wakeup.run_wake_count) {
 			result = acpi_power_transition(device, state);
 			if (result)
 				goto end;
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 2ef0409..4b0bb68 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -32,6 +32,8 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_bind");
 
@@ -65,6 +67,7 @@ static int acpi_pci_bind(struct acpi_device *device)
 	acpi_handle handle;
 	struct pci_bus *bus;
 	struct pci_dev *dev;
+	int state;
 
 	dev = acpi_get_pci_dev(device->handle);
 	if (!dev)
@@ -87,6 +90,9 @@ static int acpi_pci_bind(struct acpi_device *device)
 		device->ops.unbind = acpi_pci_unbind;
 	}
 
+	acpi_power_get_inferred_state(device, &state);
+	acpi_power_transition(device, state);
+
 	/*
 	 * Evaluate and parse _PRT, if exists.  This code allows parsing of
 	 * _PRT objects within the scope of non-bridge devices.  Note that
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 9ac2a9f..cd6a8df 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -412,7 +412,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
  *    State Wake) for the device, if present
  * 2. Shutdown down the power resources
  */
-int acpi_disable_wakeup_device_power(struct acpi_device *dev)
+int acpi_disable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 {
 	int i, err = 0;
 
@@ -435,6 +435,9 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
 	if (err)
 		goto out;
 
+	if (sleep_state == ACPI_STATE_S0)
+		goto out;
+
 	/* Close power resource */
 	for (i = 0; i < dev->wakeup.resources.count; i++) {
 		int ret = acpi_power_off(dev->wakeup.resources.handles[i]);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index d6a8cd1..5d68dc0 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -697,7 +697,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 
 	error = enable ?
 		acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
-		acpi_disable_wakeup_device_power(adev);
+		acpi_disable_wakeup_device_power(adev, acpi_target_sleep_state);
 	if (!error)
 		dev_info(dev, "wake-up capability %s by ACPI\n",
 				enable ? "enabled" : "disabled");
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index ed65014..a0cabc3 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -73,7 +73,7 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
 				ACPI_GPE_DISABLE);
 
 		if (device_may_wakeup(&dev->dev))
-			acpi_disable_wakeup_device_power(dev);
+			acpi_disable_wakeup_device_power(dev, sleep_state);
 	}
 }
 
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 6fe0772..819fa7a 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -302,7 +302,7 @@ static int acpi_dev_run_wake(struct device *phys_dev, bool enable)
 		if (!--dev->wakeup.run_wake_count) {
 			acpi_disable_gpe(dev->wakeup.gpe_device,
 					 dev->wakeup.gpe_number);
-			acpi_disable_wakeup_device_power(dev);
+			acpi_disable_wakeup_device_power(dev, ACPI_STATE_S0);
 		}
 	} else {
 		error = -EALREADY;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 78ca429..92d6e86 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -379,7 +379,7 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
 
 int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
-int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev, int state);
 
 #ifdef CONFIG_PM_OPS
 int acpi_pm_device_sleep_state(struct device *, int *);
-- 
1.7.3.5