aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/ec.c26
-rw-r--r--drivers/acpi/fan.c40
-rw-r--r--drivers/acpi/processor_throttling.c4
4 files changed, 61 insertions, 11 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index d7a115c362d1..f4487c38d9f2 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -200,7 +200,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
200 * Get device's current power state 200 * Get device's current power state
201 */ 201 */
202 acpi_bus_get_power(device->handle, &device->power.state); 202 acpi_bus_get_power(device->handle, &device->power.state);
203 if (state == device->power.state) { 203 if ((state == device->power.state) && !device->flags.force_power_state) {
204 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 204 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
205 state)); 205 state));
206 return 0; 206 return 0;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 97dc16155a55..987b967c7467 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -26,6 +26,9 @@
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */ 27 */
28 28
29/* Uncomment next line to get verbose print outs*/
30/* #define DEBUG */
31
29#include <linux/kernel.h> 32#include <linux/kernel.h>
30#include <linux/module.h> 33#include <linux/module.h>
31#include <linux/init.h> 34#include <linux/init.h>
@@ -47,9 +50,6 @@
47#undef PREFIX 50#undef PREFIX
48#define PREFIX "ACPI: EC: " 51#define PREFIX "ACPI: EC: "
49 52
50/* Uncomment next line to get verbose print outs*/
51/* #define DEBUG */
52
53/* EC status register */ 53/* EC status register */
54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
@@ -82,6 +82,7 @@ enum {
82 EC_FLAGS_ADDRESS, /* Address is being written */ 82 EC_FLAGS_ADDRESS, /* Address is being written */
83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ 83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
84 EC_FLAGS_WDATA, /* Data is being written */ 84 EC_FLAGS_WDATA, /* Data is being written */
85 EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */
85}; 86};
86 87
87static int acpi_ec_remove(struct acpi_device *device, int type); 88static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -138,26 +139,26 @@ static struct acpi_ec {
138static inline u8 acpi_ec_read_status(struct acpi_ec *ec) 139static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
139{ 140{
140 u8 x = inb(ec->command_addr); 141 u8 x = inb(ec->command_addr);
141 pr_debug(PREFIX "---> status = 0x%2x\n", x); 142 pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
142 return x; 143 return x;
143} 144}
144 145
145static inline u8 acpi_ec_read_data(struct acpi_ec *ec) 146static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
146{ 147{
147 u8 x = inb(ec->data_addr); 148 u8 x = inb(ec->data_addr);
148 pr_debug(PREFIX "---> data = 0x%2x\n", x); 149 pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
149 return inb(ec->data_addr); 150 return inb(ec->data_addr);
150} 151}
151 152
152static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) 153static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
153{ 154{
154 pr_debug(PREFIX "<--- command = 0x%2x\n", command); 155 pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
155 outb(command, ec->command_addr); 156 outb(command, ec->command_addr);
156} 157}
157 158
158static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) 159static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
159{ 160{
160 pr_debug(PREFIX "<--- data = 0x%2x\n", data); 161 pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
161 outb(data, ec->data_addr); 162 outb(data, ec->data_addr);
162} 163}
163 164
@@ -179,6 +180,10 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
179static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) 180static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
180{ 181{
181 int ret = 0; 182 int ret = 0;
183
184 if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
185 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
186 force_poll = 1;
182 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && 187 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
183 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) 188 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
184 force_poll = 1; 189 force_poll = 1;
@@ -192,7 +197,12 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
192 goto end; 197 goto end;
193 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 198 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
194 if (acpi_ec_check_status(ec, event)) { 199 if (acpi_ec_check_status(ec, event)) {
195 if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { 200 if (event == ACPI_EC_EVENT_OBF_1) {
201 /* miss OBF_1 GPE, don't expect it */
202 pr_info(PREFIX "missing OBF confirmation, "
203 "don't expect it any longer.\n");
204 set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
205 } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
196 /* miss address GPE, don't expect it anymore */ 206 /* miss address GPE, don't expect it anymore */
197 pr_info(PREFIX "missing address confirmation, " 207 pr_info(PREFIX "missing address confirmation, "
198 "don't expect it any longer.\n"); 208 "don't expect it any longer.\n");
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index a5a5532db268..a6e149d692cb 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -47,6 +47,8 @@ MODULE_LICENSE("GPL");
47 47
48static int acpi_fan_add(struct acpi_device *device); 48static int acpi_fan_add(struct acpi_device *device);
49static int acpi_fan_remove(struct acpi_device *device, int type); 49static int acpi_fan_remove(struct acpi_device *device, int type);
50static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
51static int acpi_fan_resume(struct acpi_device *device);
50 52
51static const struct acpi_device_id fan_device_ids[] = { 53static const struct acpi_device_id fan_device_ids[] = {
52 {"PNP0C0B", 0}, 54 {"PNP0C0B", 0},
@@ -61,6 +63,8 @@ static struct acpi_driver acpi_fan_driver = {
61 .ops = { 63 .ops = {
62 .add = acpi_fan_add, 64 .add = acpi_fan_add,
63 .remove = acpi_fan_remove, 65 .remove = acpi_fan_remove,
66 .suspend = acpi_fan_suspend,
67 .resume = acpi_fan_resume,
64 }, 68 },
65}; 69};
66 70
@@ -191,6 +195,10 @@ static int acpi_fan_add(struct acpi_device *device)
191 goto end; 195 goto end;
192 } 196 }
193 197
198 device->flags.force_power_state = 1;
199 acpi_bus_set_power(device->handle, state);
200 device->flags.force_power_state = 0;
201
194 result = acpi_fan_add_fs(device); 202 result = acpi_fan_add_fs(device);
195 if (result) 203 if (result)
196 goto end; 204 goto end;
@@ -216,6 +224,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
216 return 0; 224 return 0;
217} 225}
218 226
227static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
228{
229 if (!device)
230 return -EINVAL;
231
232 acpi_bus_set_power(device->handle, ACPI_STATE_D0);
233
234 return AE_OK;
235}
236
237static int acpi_fan_resume(struct acpi_device *device)
238{
239 int result = 0;
240 int power_state = 0;
241
242 if (!device)
243 return -EINVAL;
244
245 result = acpi_bus_get_power(device->handle, &power_state);
246 if (result) {
247 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
248 "Error reading fan power state\n"));
249 return result;
250 }
251
252 device->flags.force_power_state = 1;
253 acpi_bus_set_power(device->handle, power_state);
254 device->flags.force_power_state = 0;
255
256 return result;
257}
258
219static int __init acpi_fan_init(void) 259static int __init acpi_fan_init(void)
220{ 260{
221 int result = 0; 261 int result = 0;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 6742d7bc4777..1685b40abda7 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -775,12 +775,12 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
775 acpi_processor_get_throttling_states(pr) || 775 acpi_processor_get_throttling_states(pr) ||
776 acpi_processor_get_platform_limit(pr)) 776 acpi_processor_get_platform_limit(pr))
777 { 777 {
778 if (acpi_processor_get_fadt_info(pr))
779 return 0;
780 pr->throttling.acpi_processor_get_throttling = 778 pr->throttling.acpi_processor_get_throttling =
781 &acpi_processor_get_throttling_fadt; 779 &acpi_processor_get_throttling_fadt;
782 pr->throttling.acpi_processor_set_throttling = 780 pr->throttling.acpi_processor_set_throttling =
783 &acpi_processor_set_throttling_fadt; 781 &acpi_processor_set_throttling_fadt;
782 if (acpi_processor_get_fadt_info(pr))
783 return 0;
784 } else { 784 } else {
785 pr->throttling.acpi_processor_get_throttling = 785 pr->throttling.acpi_processor_get_throttling =
786 &acpi_processor_get_throttling_ptc; 786 &acpi_processor_get_throttling_ptc;