diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 548 |
1 files changed, 417 insertions, 131 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1b5853f384e2..14d0c89ada2a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * ec.c - ACPI Embedded Controller Driver (v2.2) | 2 | * ec.c - ACPI Embedded Controller Driver (v3) |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2014 Intel Corporation | 4 | * Copyright (C) 2001-2015 Intel Corporation |
5 | * Author: 2014 Lv Zheng <lv.zheng@intel.com> | 5 | * Author: 2014, 2015 Lv Zheng <lv.zheng@intel.com> |
6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> |
7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> | 7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> |
8 | * 2004 Luming Yu <luming.yu@intel.com> | 8 | * 2004 Luming Yu <luming.yu@intel.com> |
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | /* Uncomment next line to get verbose printout */ | 32 | /* Uncomment next line to get verbose printout */ |
33 | /* #define DEBUG */ | 33 | /* #define DEBUG */ |
34 | #define DEBUG_REF 0 | ||
34 | #define pr_fmt(fmt) "ACPI : EC: " fmt | 35 | #define pr_fmt(fmt) "ACPI : EC: " fmt |
35 | 36 | ||
36 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -71,20 +72,32 @@ enum ec_command { | |||
71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 72 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
72 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 73 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 74 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
75 | #define ACPI_EC_UDELAY_POLL 1000 /* Wait 1ms for EC transaction polling */ | ||
74 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query | 76 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query |
75 | * when trying to clear the EC */ | 77 | * when trying to clear the EC */ |
76 | 78 | ||
77 | enum { | 79 | enum { |
78 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 80 | EC_FLAGS_EVENT_ENABLED, /* Event is enabled */ |
79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 81 | EC_FLAGS_EVENT_PENDING, /* Event is pending */ |
82 | EC_FLAGS_EVENT_DETECTED, /* Event is detected */ | ||
80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and | 83 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
81 | * OpReg are installed */ | 84 | * OpReg are installed */ |
82 | EC_FLAGS_BLOCKED, /* Transactions are blocked */ | 85 | EC_FLAGS_STARTED, /* Driver is started */ |
86 | EC_FLAGS_STOPPED, /* Driver is stopped */ | ||
87 | EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the | ||
88 | * current command processing */ | ||
83 | }; | 89 | }; |
84 | 90 | ||
85 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ | 91 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ |
86 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ | 92 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ |
87 | 93 | ||
94 | #define ec_debug_ref(ec, fmt, ...) \ | ||
95 | do { \ | ||
96 | if (DEBUG_REF) \ | ||
97 | pr_debug("%lu: " fmt, ec->reference_count, \ | ||
98 | ## __VA_ARGS__); \ | ||
99 | } while (0) | ||
100 | |||
88 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ | 101 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ |
89 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; | 102 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; |
90 | module_param(ec_delay, uint, 0644); | 103 | module_param(ec_delay, uint, 0644); |
@@ -105,6 +118,7 @@ struct acpi_ec_query_handler { | |||
105 | acpi_handle handle; | 118 | acpi_handle handle; |
106 | void *data; | 119 | void *data; |
107 | u8 query_bit; | 120 | u8 query_bit; |
121 | struct kref kref; | ||
108 | }; | 122 | }; |
109 | 123 | ||
110 | struct transaction { | 124 | struct transaction { |
@@ -117,8 +131,12 @@ struct transaction { | |||
117 | u8 wlen; | 131 | u8 wlen; |
118 | u8 rlen; | 132 | u8 rlen; |
119 | u8 flags; | 133 | u8 flags; |
134 | unsigned long timestamp; | ||
120 | }; | 135 | }; |
121 | 136 | ||
137 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data); | ||
138 | static void advance_transaction(struct acpi_ec *ec); | ||
139 | |||
122 | struct acpi_ec *boot_ec, *first_ec; | 140 | struct acpi_ec *boot_ec, *first_ec; |
123 | EXPORT_SYMBOL(first_ec); | 141 | EXPORT_SYMBOL(first_ec); |
124 | 142 | ||
@@ -129,7 +147,28 @@ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | |||
129 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ | 147 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ |
130 | 148 | ||
131 | /* -------------------------------------------------------------------------- | 149 | /* -------------------------------------------------------------------------- |
132 | * Transaction Management | 150 | * Device Flags |
151 | * -------------------------------------------------------------------------- */ | ||
152 | |||
153 | static bool acpi_ec_started(struct acpi_ec *ec) | ||
154 | { | ||
155 | return test_bit(EC_FLAGS_STARTED, &ec->flags) && | ||
156 | !test_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
157 | } | ||
158 | |||
159 | static bool acpi_ec_flushed(struct acpi_ec *ec) | ||
160 | { | ||
161 | return ec->reference_count == 1; | ||
162 | } | ||
163 | |||
164 | static bool acpi_ec_has_pending_event(struct acpi_ec *ec) | ||
165 | { | ||
166 | return test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | ||
167 | test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | ||
168 | } | ||
169 | |||
170 | /* -------------------------------------------------------------------------- | ||
171 | * EC Registers | ||
133 | * -------------------------------------------------------------------------- */ | 172 | * -------------------------------------------------------------------------- */ |
134 | 173 | ||
135 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 174 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
@@ -151,6 +190,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | |||
151 | { | 190 | { |
152 | u8 x = inb(ec->data_addr); | 191 | u8 x = inb(ec->data_addr); |
153 | 192 | ||
193 | ec->curr->timestamp = jiffies; | ||
154 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); | 194 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); |
155 | return x; | 195 | return x; |
156 | } | 196 | } |
@@ -159,12 +199,14 @@ static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | |||
159 | { | 199 | { |
160 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); | 200 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); |
161 | outb(command, ec->command_addr); | 201 | outb(command, ec->command_addr); |
202 | ec->curr->timestamp = jiffies; | ||
162 | } | 203 | } |
163 | 204 | ||
164 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 205 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
165 | { | 206 | { |
166 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); | 207 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); |
167 | outb(data, ec->data_addr); | 208 | outb(data, ec->data_addr); |
209 | ec->curr->timestamp = jiffies; | ||
168 | } | 210 | } |
169 | 211 | ||
170 | #ifdef DEBUG | 212 | #ifdef DEBUG |
@@ -188,6 +230,203 @@ static const char *acpi_ec_cmd_string(u8 cmd) | |||
188 | #define acpi_ec_cmd_string(cmd) "UNDEF" | 230 | #define acpi_ec_cmd_string(cmd) "UNDEF" |
189 | #endif | 231 | #endif |
190 | 232 | ||
233 | /* -------------------------------------------------------------------------- | ||
234 | * GPE Registers | ||
235 | * -------------------------------------------------------------------------- */ | ||
236 | |||
237 | static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec) | ||
238 | { | ||
239 | acpi_event_status gpe_status = 0; | ||
240 | |||
241 | (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status); | ||
242 | return (gpe_status & ACPI_EVENT_FLAG_SET) ? true : false; | ||
243 | } | ||
244 | |||
245 | static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) | ||
246 | { | ||
247 | if (open) | ||
248 | acpi_enable_gpe(NULL, ec->gpe); | ||
249 | else { | ||
250 | BUG_ON(ec->reference_count < 1); | ||
251 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | ||
252 | } | ||
253 | if (acpi_ec_is_gpe_raised(ec)) { | ||
254 | /* | ||
255 | * On some platforms, EN=1 writes cannot trigger GPE. So | ||
256 | * software need to manually trigger a pseudo GPE event on | ||
257 | * EN=1 writes. | ||
258 | */ | ||
259 | pr_debug("***** Polling quirk *****\n"); | ||
260 | advance_transaction(ec); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close) | ||
265 | { | ||
266 | if (close) | ||
267 | acpi_disable_gpe(NULL, ec->gpe); | ||
268 | else { | ||
269 | BUG_ON(ec->reference_count < 1); | ||
270 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static inline void acpi_ec_clear_gpe(struct acpi_ec *ec) | ||
275 | { | ||
276 | /* | ||
277 | * GPE STS is a W1C register, which means: | ||
278 | * 1. Software can clear it without worrying about clearing other | ||
279 | * GPEs' STS bits when the hardware sets them in parallel. | ||
280 | * 2. As long as software can ensure only clearing it when it is | ||
281 | * set, hardware won't set it in parallel. | ||
282 | * So software can clear GPE in any contexts. | ||
283 | * Warning: do not move the check into advance_transaction() as the | ||
284 | * EC commands will be sent without GPE raised. | ||
285 | */ | ||
286 | if (!acpi_ec_is_gpe_raised(ec)) | ||
287 | return; | ||
288 | acpi_clear_gpe(NULL, ec->gpe); | ||
289 | } | ||
290 | |||
291 | /* -------------------------------------------------------------------------- | ||
292 | * Transaction Management | ||
293 | * -------------------------------------------------------------------------- */ | ||
294 | |||
295 | static void acpi_ec_submit_request(struct acpi_ec *ec) | ||
296 | { | ||
297 | ec->reference_count++; | ||
298 | if (ec->reference_count == 1) | ||
299 | acpi_ec_enable_gpe(ec, true); | ||
300 | } | ||
301 | |||
302 | static void acpi_ec_complete_request(struct acpi_ec *ec) | ||
303 | { | ||
304 | bool flushed = false; | ||
305 | |||
306 | ec->reference_count--; | ||
307 | if (ec->reference_count == 0) | ||
308 | acpi_ec_disable_gpe(ec, true); | ||
309 | flushed = acpi_ec_flushed(ec); | ||
310 | if (flushed) | ||
311 | wake_up(&ec->wait); | ||
312 | } | ||
313 | |||
314 | static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag) | ||
315 | { | ||
316 | if (!test_bit(flag, &ec->flags)) { | ||
317 | acpi_ec_disable_gpe(ec, false); | ||
318 | pr_debug("+++++ Polling enabled +++++\n"); | ||
319 | set_bit(flag, &ec->flags); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) | ||
324 | { | ||
325 | if (test_bit(flag, &ec->flags)) { | ||
326 | clear_bit(flag, &ec->flags); | ||
327 | acpi_ec_enable_gpe(ec, false); | ||
328 | pr_debug("+++++ Polling disabled +++++\n"); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * acpi_ec_submit_flushable_request() - Increase the reference count unless | ||
334 | * the flush operation is not in | ||
335 | * progress | ||
336 | * @ec: the EC device | ||
337 | * @allow_event: whether event should be handled | ||
338 | * | ||
339 | * This function must be used before taking a new action that should hold | ||
340 | * the reference count. If this function returns false, then the action | ||
341 | * must be discarded or it will prevent the flush operation from being | ||
342 | * completed. | ||
343 | * | ||
344 | * During flushing, QR_EC command need to pass this check when there is a | ||
345 | * pending event, so that the reference count held for the pending event | ||
346 | * can be decreased by the completion of the QR_EC command. | ||
347 | */ | ||
348 | static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec, | ||
349 | bool allow_event) | ||
350 | { | ||
351 | if (!acpi_ec_started(ec)) { | ||
352 | if (!allow_event || !acpi_ec_has_pending_event(ec)) | ||
353 | return false; | ||
354 | } | ||
355 | acpi_ec_submit_request(ec); | ||
356 | return true; | ||
357 | } | ||
358 | |||
359 | static void acpi_ec_submit_event(struct acpi_ec *ec) | ||
360 | { | ||
361 | if (!test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | ||
362 | !test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags)) | ||
363 | return; | ||
364 | /* Hold reference for pending event */ | ||
365 | if (!acpi_ec_submit_flushable_request(ec, true)) | ||
366 | return; | ||
367 | ec_debug_ref(ec, "Increase event\n"); | ||
368 | if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { | ||
369 | pr_debug("***** Event query started *****\n"); | ||
370 | schedule_work(&ec->work); | ||
371 | return; | ||
372 | } | ||
373 | acpi_ec_complete_request(ec); | ||
374 | ec_debug_ref(ec, "Decrease event\n"); | ||
375 | } | ||
376 | |||
377 | static void acpi_ec_complete_event(struct acpi_ec *ec) | ||
378 | { | ||
379 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
380 | clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | ||
381 | pr_debug("***** Event query stopped *****\n"); | ||
382 | /* Unhold reference for pending event */ | ||
383 | acpi_ec_complete_request(ec); | ||
384 | ec_debug_ref(ec, "Decrease event\n"); | ||
385 | /* Check if there is another SCI_EVT detected */ | ||
386 | acpi_ec_submit_event(ec); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | static void acpi_ec_submit_detection(struct acpi_ec *ec) | ||
391 | { | ||
392 | /* Hold reference for query submission */ | ||
393 | if (!acpi_ec_submit_flushable_request(ec, false)) | ||
394 | return; | ||
395 | ec_debug_ref(ec, "Increase query\n"); | ||
396 | if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) { | ||
397 | pr_debug("***** Event detection blocked *****\n"); | ||
398 | acpi_ec_submit_event(ec); | ||
399 | return; | ||
400 | } | ||
401 | acpi_ec_complete_request(ec); | ||
402 | ec_debug_ref(ec, "Decrease query\n"); | ||
403 | } | ||
404 | |||
405 | static void acpi_ec_complete_detection(struct acpi_ec *ec) | ||
406 | { | ||
407 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
408 | clear_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags); | ||
409 | pr_debug("***** Event detetion unblocked *****\n"); | ||
410 | /* Unhold reference for query submission */ | ||
411 | acpi_ec_complete_request(ec); | ||
412 | ec_debug_ref(ec, "Decrease query\n"); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static void acpi_ec_enable_event(struct acpi_ec *ec) | ||
417 | { | ||
418 | unsigned long flags; | ||
419 | |||
420 | spin_lock_irqsave(&ec->lock, flags); | ||
421 | set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags); | ||
422 | /* | ||
423 | * An event may be pending even with SCI_EVT=0, so QR_EC should | ||
424 | * always be issued right after started. | ||
425 | */ | ||
426 | acpi_ec_submit_detection(ec); | ||
427 | spin_unlock_irqrestore(&ec->lock, flags); | ||
428 | } | ||
429 | |||
191 | static int ec_transaction_completed(struct acpi_ec *ec) | 430 | static int ec_transaction_completed(struct acpi_ec *ec) |
192 | { | 431 | { |
193 | unsigned long flags; | 432 | unsigned long flags; |
@@ -200,7 +439,7 @@ static int ec_transaction_completed(struct acpi_ec *ec) | |||
200 | return ret; | 439 | return ret; |
201 | } | 440 | } |
202 | 441 | ||
203 | static bool advance_transaction(struct acpi_ec *ec) | 442 | static void advance_transaction(struct acpi_ec *ec) |
204 | { | 443 | { |
205 | struct transaction *t; | 444 | struct transaction *t; |
206 | u8 status; | 445 | u8 status; |
@@ -208,6 +447,12 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
208 | 447 | ||
209 | pr_debug("===== %s (%d) =====\n", | 448 | pr_debug("===== %s (%d) =====\n", |
210 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); | 449 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); |
450 | /* | ||
451 | * By always clearing STS before handling all indications, we can | ||
452 | * ensure a hardware STS 0->1 change after this clearing can always | ||
453 | * trigger a GPE interrupt. | ||
454 | */ | ||
455 | acpi_ec_clear_gpe(ec); | ||
211 | status = acpi_ec_read_status(ec); | 456 | status = acpi_ec_read_status(ec); |
212 | t = ec->curr; | 457 | t = ec->curr; |
213 | if (!t) | 458 | if (!t) |
@@ -223,6 +468,7 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
223 | t->rdata[t->ri++] = acpi_ec_read_data(ec); | 468 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
224 | if (t->rlen == t->ri) { | 469 | if (t->rlen == t->ri) { |
225 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 470 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
471 | acpi_ec_complete_event(ec); | ||
226 | if (t->command == ACPI_EC_COMMAND_QUERY) | 472 | if (t->command == ACPI_EC_COMMAND_QUERY) |
227 | pr_debug("***** Command(%s) hardware completion *****\n", | 473 | pr_debug("***** Command(%s) hardware completion *****\n", |
228 | acpi_ec_cmd_string(t->command)); | 474 | acpi_ec_cmd_string(t->command)); |
@@ -233,25 +479,29 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
233 | } else if (t->wlen == t->wi && | 479 | } else if (t->wlen == t->wi && |
234 | (status & ACPI_EC_FLAG_IBF) == 0) { | 480 | (status & ACPI_EC_FLAG_IBF) == 0) { |
235 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 481 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
482 | acpi_ec_complete_event(ec); | ||
236 | wakeup = true; | 483 | wakeup = true; |
237 | } | 484 | } |
238 | return wakeup; | 485 | goto out; |
239 | } else { | 486 | } else { |
240 | if (EC_FLAGS_QUERY_HANDSHAKE && | 487 | if (EC_FLAGS_QUERY_HANDSHAKE && |
241 | !(status & ACPI_EC_FLAG_SCI) && | 488 | !(status & ACPI_EC_FLAG_SCI) && |
242 | (t->command == ACPI_EC_COMMAND_QUERY)) { | 489 | (t->command == ACPI_EC_COMMAND_QUERY)) { |
243 | t->flags |= ACPI_EC_COMMAND_POLL; | 490 | t->flags |= ACPI_EC_COMMAND_POLL; |
491 | acpi_ec_complete_detection(ec); | ||
244 | t->rdata[t->ri++] = 0x00; | 492 | t->rdata[t->ri++] = 0x00; |
245 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 493 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
494 | acpi_ec_complete_event(ec); | ||
246 | pr_debug("***** Command(%s) software completion *****\n", | 495 | pr_debug("***** Command(%s) software completion *****\n", |
247 | acpi_ec_cmd_string(t->command)); | 496 | acpi_ec_cmd_string(t->command)); |
248 | wakeup = true; | 497 | wakeup = true; |
249 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | 498 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
250 | acpi_ec_write_cmd(ec, t->command); | 499 | acpi_ec_write_cmd(ec, t->command); |
251 | t->flags |= ACPI_EC_COMMAND_POLL; | 500 | t->flags |= ACPI_EC_COMMAND_POLL; |
501 | acpi_ec_complete_detection(ec); | ||
252 | } else | 502 | } else |
253 | goto err; | 503 | goto err; |
254 | return wakeup; | 504 | goto out; |
255 | } | 505 | } |
256 | err: | 506 | err: |
257 | /* | 507 | /* |
@@ -259,28 +509,27 @@ err: | |||
259 | * otherwise will take a not handled IRQ as a false one. | 509 | * otherwise will take a not handled IRQ as a false one. |
260 | */ | 510 | */ |
261 | if (!(status & ACPI_EC_FLAG_SCI)) { | 511 | if (!(status & ACPI_EC_FLAG_SCI)) { |
262 | if (in_interrupt() && t) | 512 | if (in_interrupt() && t) { |
263 | ++t->irq_count; | 513 | if (t->irq_count < ec_storm_threshold) |
514 | ++t->irq_count; | ||
515 | /* Allow triggering on 0 threshold */ | ||
516 | if (t->irq_count == ec_storm_threshold) | ||
517 | acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM); | ||
518 | } | ||
264 | } | 519 | } |
265 | return wakeup; | 520 | out: |
521 | if (status & ACPI_EC_FLAG_SCI) | ||
522 | acpi_ec_submit_detection(ec); | ||
523 | if (wakeup && in_interrupt()) | ||
524 | wake_up(&ec->wait); | ||
266 | } | 525 | } |
267 | 526 | ||
268 | static void start_transaction(struct acpi_ec *ec) | 527 | static void start_transaction(struct acpi_ec *ec) |
269 | { | 528 | { |
270 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; | 529 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; |
271 | ec->curr->flags = 0; | 530 | ec->curr->flags = 0; |
272 | (void)advance_transaction(ec); | 531 | ec->curr->timestamp = jiffies; |
273 | } | 532 | advance_transaction(ec); |
274 | |||
275 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); | ||
276 | |||
277 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) | ||
278 | { | ||
279 | if (state & ACPI_EC_FLAG_SCI) { | ||
280 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | ||
281 | return acpi_ec_sync_query(ec, NULL); | ||
282 | } | ||
283 | return 0; | ||
284 | } | 533 | } |
285 | 534 | ||
286 | static int ec_poll(struct acpi_ec *ec) | 535 | static int ec_poll(struct acpi_ec *ec) |
@@ -291,20 +540,25 @@ static int ec_poll(struct acpi_ec *ec) | |||
291 | while (repeat--) { | 540 | while (repeat--) { |
292 | unsigned long delay = jiffies + | 541 | unsigned long delay = jiffies + |
293 | msecs_to_jiffies(ec_delay); | 542 | msecs_to_jiffies(ec_delay); |
543 | unsigned long usecs = ACPI_EC_UDELAY_POLL; | ||
294 | do { | 544 | do { |
295 | /* don't sleep with disabled interrupts */ | 545 | /* don't sleep with disabled interrupts */ |
296 | if (EC_FLAGS_MSI || irqs_disabled()) { | 546 | if (EC_FLAGS_MSI || irqs_disabled()) { |
297 | udelay(ACPI_EC_MSI_UDELAY); | 547 | usecs = ACPI_EC_MSI_UDELAY; |
548 | udelay(usecs); | ||
298 | if (ec_transaction_completed(ec)) | 549 | if (ec_transaction_completed(ec)) |
299 | return 0; | 550 | return 0; |
300 | } else { | 551 | } else { |
301 | if (wait_event_timeout(ec->wait, | 552 | if (wait_event_timeout(ec->wait, |
302 | ec_transaction_completed(ec), | 553 | ec_transaction_completed(ec), |
303 | msecs_to_jiffies(1))) | 554 | usecs_to_jiffies(usecs))) |
304 | return 0; | 555 | return 0; |
305 | } | 556 | } |
306 | spin_lock_irqsave(&ec->lock, flags); | 557 | spin_lock_irqsave(&ec->lock, flags); |
307 | (void)advance_transaction(ec); | 558 | if (time_after(jiffies, |
559 | ec->curr->timestamp + | ||
560 | usecs_to_jiffies(usecs))) | ||
561 | advance_transaction(ec); | ||
308 | spin_unlock_irqrestore(&ec->lock, flags); | 562 | spin_unlock_irqrestore(&ec->lock, flags); |
309 | } while (time_before(jiffies, delay)); | 563 | } while (time_before(jiffies, delay)); |
310 | pr_debug("controller reset, restart transaction\n"); | 564 | pr_debug("controller reset, restart transaction\n"); |
@@ -325,21 +579,29 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
325 | udelay(ACPI_EC_MSI_UDELAY); | 579 | udelay(ACPI_EC_MSI_UDELAY); |
326 | /* start transaction */ | 580 | /* start transaction */ |
327 | spin_lock_irqsave(&ec->lock, tmp); | 581 | spin_lock_irqsave(&ec->lock, tmp); |
582 | /* Enable GPE for command processing (IBF=0/OBF=1) */ | ||
583 | if (!acpi_ec_submit_flushable_request(ec, true)) { | ||
584 | ret = -EINVAL; | ||
585 | goto unlock; | ||
586 | } | ||
587 | ec_debug_ref(ec, "Increase command\n"); | ||
328 | /* following two actions should be kept atomic */ | 588 | /* following two actions should be kept atomic */ |
329 | ec->curr = t; | 589 | ec->curr = t; |
330 | pr_debug("***** Command(%s) started *****\n", | 590 | pr_debug("***** Command(%s) started *****\n", |
331 | acpi_ec_cmd_string(t->command)); | 591 | acpi_ec_cmd_string(t->command)); |
332 | start_transaction(ec); | 592 | start_transaction(ec); |
333 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
334 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
335 | pr_debug("***** Event stopped *****\n"); | ||
336 | } | ||
337 | spin_unlock_irqrestore(&ec->lock, tmp); | 593 | spin_unlock_irqrestore(&ec->lock, tmp); |
338 | ret = ec_poll(ec); | 594 | ret = ec_poll(ec); |
339 | spin_lock_irqsave(&ec->lock, tmp); | 595 | spin_lock_irqsave(&ec->lock, tmp); |
596 | if (t->irq_count == ec_storm_threshold) | ||
597 | acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); | ||
340 | pr_debug("***** Command(%s) stopped *****\n", | 598 | pr_debug("***** Command(%s) stopped *****\n", |
341 | acpi_ec_cmd_string(t->command)); | 599 | acpi_ec_cmd_string(t->command)); |
342 | ec->curr = NULL; | 600 | ec->curr = NULL; |
601 | /* Disable GPE for command processing (IBF=0/OBF=1) */ | ||
602 | acpi_ec_complete_request(ec); | ||
603 | ec_debug_ref(ec, "Decrease command\n"); | ||
604 | unlock: | ||
343 | spin_unlock_irqrestore(&ec->lock, tmp); | 605 | spin_unlock_irqrestore(&ec->lock, tmp); |
344 | return ret; | 606 | return ret; |
345 | } | 607 | } |
@@ -354,10 +616,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
354 | if (t->rdata) | 616 | if (t->rdata) |
355 | memset(t->rdata, 0, t->rlen); | 617 | memset(t->rdata, 0, t->rlen); |
356 | mutex_lock(&ec->mutex); | 618 | mutex_lock(&ec->mutex); |
357 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { | ||
358 | status = -EINVAL; | ||
359 | goto unlock; | ||
360 | } | ||
361 | if (ec->global_lock) { | 619 | if (ec->global_lock) { |
362 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 620 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
363 | if (ACPI_FAILURE(status)) { | 621 | if (ACPI_FAILURE(status)) { |
@@ -365,26 +623,11 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
365 | goto unlock; | 623 | goto unlock; |
366 | } | 624 | } |
367 | } | 625 | } |
368 | /* disable GPE during transaction if storm is detected */ | ||
369 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
370 | /* It has to be disabled, so that it doesn't trigger. */ | ||
371 | acpi_disable_gpe(NULL, ec->gpe); | ||
372 | } | ||
373 | 626 | ||
374 | status = acpi_ec_transaction_unlocked(ec, t); | 627 | status = acpi_ec_transaction_unlocked(ec, t); |
375 | 628 | ||
376 | /* check if we received SCI during transaction */ | 629 | if (test_bit(EC_FLAGS_COMMAND_STORM, &ec->flags)) |
377 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); | ||
378 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
379 | msleep(1); | 630 | msleep(1); |
380 | /* It is safe to enable the GPE outside of the transaction. */ | ||
381 | acpi_enable_gpe(NULL, ec->gpe); | ||
382 | } else if (t->irq_count > ec_storm_threshold) { | ||
383 | pr_info("GPE storm detected(%d GPEs), " | ||
384 | "transactions will use polling mode\n", | ||
385 | t->irq_count); | ||
386 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | ||
387 | } | ||
388 | if (ec->global_lock) | 631 | if (ec->global_lock) |
389 | acpi_release_global_lock(glk); | 632 | acpi_release_global_lock(glk); |
390 | unlock: | 633 | unlock: |
@@ -500,7 +743,7 @@ static void acpi_ec_clear(struct acpi_ec *ec) | |||
500 | u8 value = 0; | 743 | u8 value = 0; |
501 | 744 | ||
502 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | 745 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { |
503 | status = acpi_ec_sync_query(ec, &value); | 746 | status = acpi_ec_query(ec, &value); |
504 | if (status || !value) | 747 | if (status || !value) |
505 | break; | 748 | break; |
506 | } | 749 | } |
@@ -511,6 +754,57 @@ static void acpi_ec_clear(struct acpi_ec *ec) | |||
511 | pr_info("%d stale EC events cleared\n", i); | 754 | pr_info("%d stale EC events cleared\n", i); |
512 | } | 755 | } |
513 | 756 | ||
757 | static void acpi_ec_start(struct acpi_ec *ec, bool resuming) | ||
758 | { | ||
759 | unsigned long flags; | ||
760 | |||
761 | spin_lock_irqsave(&ec->lock, flags); | ||
762 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { | ||
763 | pr_debug("+++++ Starting EC +++++\n"); | ||
764 | /* Enable GPE for event processing (SCI_EVT=1) */ | ||
765 | if (!resuming) { | ||
766 | acpi_ec_submit_request(ec); | ||
767 | ec_debug_ref(ec, "Increase driver\n"); | ||
768 | } | ||
769 | pr_info("+++++ EC started +++++\n"); | ||
770 | } | ||
771 | spin_unlock_irqrestore(&ec->lock, flags); | ||
772 | } | ||
773 | |||
774 | static bool acpi_ec_stopped(struct acpi_ec *ec) | ||
775 | { | ||
776 | unsigned long flags; | ||
777 | bool flushed; | ||
778 | |||
779 | spin_lock_irqsave(&ec->lock, flags); | ||
780 | flushed = acpi_ec_flushed(ec); | ||
781 | spin_unlock_irqrestore(&ec->lock, flags); | ||
782 | return flushed; | ||
783 | } | ||
784 | |||
785 | static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | ||
786 | { | ||
787 | unsigned long flags; | ||
788 | |||
789 | spin_lock_irqsave(&ec->lock, flags); | ||
790 | if (acpi_ec_started(ec)) { | ||
791 | pr_debug("+++++ Stopping EC +++++\n"); | ||
792 | set_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
793 | spin_unlock_irqrestore(&ec->lock, flags); | ||
794 | wait_event(ec->wait, acpi_ec_stopped(ec)); | ||
795 | spin_lock_irqsave(&ec->lock, flags); | ||
796 | /* Disable GPE for event processing (SCI_EVT=1) */ | ||
797 | if (!suspending) { | ||
798 | acpi_ec_complete_request(ec); | ||
799 | ec_debug_ref(ec, "Decrease driver\n"); | ||
800 | } | ||
801 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | ||
802 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
803 | pr_info("+++++ EC stopped +++++\n"); | ||
804 | } | ||
805 | spin_unlock_irqrestore(&ec->lock, flags); | ||
806 | } | ||
807 | |||
514 | void acpi_ec_block_transactions(void) | 808 | void acpi_ec_block_transactions(void) |
515 | { | 809 | { |
516 | struct acpi_ec *ec = first_ec; | 810 | struct acpi_ec *ec = first_ec; |
@@ -520,7 +814,7 @@ void acpi_ec_block_transactions(void) | |||
520 | 814 | ||
521 | mutex_lock(&ec->mutex); | 815 | mutex_lock(&ec->mutex); |
522 | /* Prevent transactions from being carried out */ | 816 | /* Prevent transactions from being carried out */ |
523 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); | 817 | acpi_ec_stop(ec, true); |
524 | mutex_unlock(&ec->mutex); | 818 | mutex_unlock(&ec->mutex); |
525 | } | 819 | } |
526 | 820 | ||
@@ -531,14 +825,11 @@ void acpi_ec_unblock_transactions(void) | |||
531 | if (!ec) | 825 | if (!ec) |
532 | return; | 826 | return; |
533 | 827 | ||
534 | mutex_lock(&ec->mutex); | ||
535 | /* Allow transactions to be carried out again */ | 828 | /* Allow transactions to be carried out again */ |
536 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | 829 | acpi_ec_start(ec, true); |
537 | 830 | ||
538 | if (EC_FLAGS_CLEAR_ON_RESUME) | 831 | if (EC_FLAGS_CLEAR_ON_RESUME) |
539 | acpi_ec_clear(ec); | 832 | acpi_ec_clear(ec); |
540 | |||
541 | mutex_unlock(&ec->mutex); | ||
542 | } | 833 | } |
543 | 834 | ||
544 | void acpi_ec_unblock_transactions_early(void) | 835 | void acpi_ec_unblock_transactions_early(void) |
@@ -548,36 +839,33 @@ void acpi_ec_unblock_transactions_early(void) | |||
548 | * atomic context during wakeup, so we don't need to acquire the mutex). | 839 | * atomic context during wakeup, so we don't need to acquire the mutex). |
549 | */ | 840 | */ |
550 | if (first_ec) | 841 | if (first_ec) |
551 | clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); | 842 | acpi_ec_start(first_ec, true); |
552 | } | 843 | } |
553 | 844 | ||
554 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) | 845 | /* -------------------------------------------------------------------------- |
846 | Event Management | ||
847 | -------------------------------------------------------------------------- */ | ||
848 | static struct acpi_ec_query_handler * | ||
849 | acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler) | ||
555 | { | 850 | { |
556 | int result; | 851 | if (handler) |
557 | u8 d; | 852 | kref_get(&handler->kref); |
558 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | 853 | return handler; |
559 | .wdata = NULL, .rdata = &d, | 854 | } |
560 | .wlen = 0, .rlen = 1}; | ||
561 | 855 | ||
562 | if (!ec || !data) | 856 | static void acpi_ec_query_handler_release(struct kref *kref) |
563 | return -EINVAL; | 857 | { |
564 | /* | 858 | struct acpi_ec_query_handler *handler = |
565 | * Query the EC to find out which _Qxx method we need to evaluate. | 859 | container_of(kref, struct acpi_ec_query_handler, kref); |
566 | * Note that successful completion of the query causes the ACPI_EC_SCI | 860 | |
567 | * bit to be cleared (and thus clearing the interrupt source). | 861 | kfree(handler); |
568 | */ | 862 | } |
569 | result = acpi_ec_transaction_unlocked(ec, &t); | 863 | |
570 | if (result) | 864 | static void acpi_ec_put_query_handler(struct acpi_ec_query_handler *handler) |
571 | return result; | 865 | { |
572 | if (!d) | 866 | kref_put(&handler->kref, acpi_ec_query_handler_release); |
573 | return -ENODATA; | ||
574 | *data = d; | ||
575 | return 0; | ||
576 | } | 867 | } |
577 | 868 | ||
578 | /* -------------------------------------------------------------------------- | ||
579 | Event Management | ||
580 | -------------------------------------------------------------------------- */ | ||
581 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | 869 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
582 | acpi_handle handle, acpi_ec_query_func func, | 870 | acpi_handle handle, acpi_ec_query_func func, |
583 | void *data) | 871 | void *data) |
@@ -593,6 +881,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
593 | handler->func = func; | 881 | handler->func = func; |
594 | handler->data = data; | 882 | handler->data = data; |
595 | mutex_lock(&ec->mutex); | 883 | mutex_lock(&ec->mutex); |
884 | kref_init(&handler->kref); | ||
596 | list_add(&handler->node, &ec->list); | 885 | list_add(&handler->node, &ec->list); |
597 | mutex_unlock(&ec->mutex); | 886 | mutex_unlock(&ec->mutex); |
598 | return 0; | 887 | return 0; |
@@ -602,15 +891,18 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | |||
602 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | 891 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
603 | { | 892 | { |
604 | struct acpi_ec_query_handler *handler, *tmp; | 893 | struct acpi_ec_query_handler *handler, *tmp; |
894 | LIST_HEAD(free_list); | ||
605 | 895 | ||
606 | mutex_lock(&ec->mutex); | 896 | mutex_lock(&ec->mutex); |
607 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 897 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
608 | if (query_bit == handler->query_bit) { | 898 | if (query_bit == handler->query_bit) { |
609 | list_del(&handler->node); | 899 | list_del_init(&handler->node); |
610 | kfree(handler); | 900 | list_add(&handler->node, &free_list); |
611 | } | 901 | } |
612 | } | 902 | } |
613 | mutex_unlock(&ec->mutex); | 903 | mutex_unlock(&ec->mutex); |
904 | list_for_each_entry(handler, &free_list, node) | ||
905 | acpi_ec_put_query_handler(handler); | ||
614 | } | 906 | } |
615 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | 907 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
616 | 908 | ||
@@ -626,59 +918,58 @@ static void acpi_ec_run(void *cxt) | |||
626 | else if (handler->handle) | 918 | else if (handler->handle) |
627 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 919 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
628 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); | 920 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); |
629 | kfree(handler); | 921 | acpi_ec_put_query_handler(handler); |
630 | } | 922 | } |
631 | 923 | ||
632 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) | 924 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data) |
633 | { | 925 | { |
634 | u8 value = 0; | 926 | u8 value = 0; |
635 | int status; | 927 | int result; |
636 | struct acpi_ec_query_handler *handler, *copy; | 928 | acpi_status status; |
929 | struct acpi_ec_query_handler *handler; | ||
930 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | ||
931 | .wdata = NULL, .rdata = &value, | ||
932 | .wlen = 0, .rlen = 1}; | ||
637 | 933 | ||
638 | status = acpi_ec_query_unlocked(ec, &value); | 934 | /* |
935 | * Query the EC to find out which _Qxx method we need to evaluate. | ||
936 | * Note that successful completion of the query causes the ACPI_EC_SCI | ||
937 | * bit to be cleared (and thus clearing the interrupt source). | ||
938 | */ | ||
939 | result = acpi_ec_transaction(ec, &t); | ||
940 | if (result) | ||
941 | return result; | ||
639 | if (data) | 942 | if (data) |
640 | *data = value; | 943 | *data = value; |
641 | if (status) | 944 | if (!value) |
642 | return status; | 945 | return -ENODATA; |
643 | 946 | ||
947 | mutex_lock(&ec->mutex); | ||
644 | list_for_each_entry(handler, &ec->list, node) { | 948 | list_for_each_entry(handler, &ec->list, node) { |
645 | if (value == handler->query_bit) { | 949 | if (value == handler->query_bit) { |
646 | /* have custom handler for this bit */ | 950 | /* have custom handler for this bit */ |
647 | copy = kmalloc(sizeof(*handler), GFP_KERNEL); | 951 | handler = acpi_ec_get_query_handler(handler); |
648 | if (!copy) | ||
649 | return -ENOMEM; | ||
650 | memcpy(copy, handler, sizeof(*copy)); | ||
651 | pr_debug("##### Query(0x%02x) scheduled #####\n", | 952 | pr_debug("##### Query(0x%02x) scheduled #####\n", |
652 | handler->query_bit); | 953 | handler->query_bit); |
653 | return acpi_os_execute((copy->func) ? | 954 | status = acpi_os_execute((handler->func) ? |
654 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 955 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
655 | acpi_ec_run, copy); | 956 | acpi_ec_run, handler); |
957 | if (ACPI_FAILURE(status)) | ||
958 | result = -EBUSY; | ||
959 | break; | ||
656 | } | 960 | } |
657 | } | 961 | } |
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static void acpi_ec_gpe_query(void *ec_cxt) | ||
662 | { | ||
663 | struct acpi_ec *ec = ec_cxt; | ||
664 | |||
665 | if (!ec) | ||
666 | return; | ||
667 | mutex_lock(&ec->mutex); | ||
668 | acpi_ec_sync_query(ec, NULL); | ||
669 | mutex_unlock(&ec->mutex); | 962 | mutex_unlock(&ec->mutex); |
963 | return result; | ||
670 | } | 964 | } |
671 | 965 | ||
672 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 966 | static void acpi_ec_gpe_poller(struct work_struct *work) |
673 | { | 967 | { |
674 | if (state & ACPI_EC_FLAG_SCI) { | 968 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work); |
675 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 969 | |
676 | pr_debug("***** Event started *****\n"); | 970 | pr_debug("***** Event poller started *****\n"); |
677 | return acpi_os_execute(OSL_NOTIFY_HANDLER, | 971 | acpi_ec_query(ec, NULL); |
678 | acpi_ec_gpe_query, ec); | 972 | pr_debug("***** Event poller stopped *****\n"); |
679 | } | ||
680 | } | ||
681 | return 0; | ||
682 | } | 973 | } |
683 | 974 | ||
684 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | 975 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
@@ -688,11 +979,9 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | |||
688 | struct acpi_ec *ec = data; | 979 | struct acpi_ec *ec = data; |
689 | 980 | ||
690 | spin_lock_irqsave(&ec->lock, flags); | 981 | spin_lock_irqsave(&ec->lock, flags); |
691 | if (advance_transaction(ec)) | 982 | advance_transaction(ec); |
692 | wake_up(&ec->wait); | ||
693 | spin_unlock_irqrestore(&ec->lock, flags); | 983 | spin_unlock_irqrestore(&ec->lock, flags); |
694 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 984 | return ACPI_INTERRUPT_HANDLED; |
695 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; | ||
696 | } | 985 | } |
697 | 986 | ||
698 | /* -------------------------------------------------------------------------- | 987 | /* -------------------------------------------------------------------------- |
@@ -750,11 +1039,11 @@ static struct acpi_ec *make_acpi_ec(void) | |||
750 | 1039 | ||
751 | if (!ec) | 1040 | if (!ec) |
752 | return NULL; | 1041 | return NULL; |
753 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | ||
754 | mutex_init(&ec->mutex); | 1042 | mutex_init(&ec->mutex); |
755 | init_waitqueue_head(&ec->wait); | 1043 | init_waitqueue_head(&ec->wait); |
756 | INIT_LIST_HEAD(&ec->list); | 1044 | INIT_LIST_HEAD(&ec->list); |
757 | spin_lock_init(&ec->lock); | 1045 | spin_lock_init(&ec->lock); |
1046 | INIT_WORK(&ec->work, acpi_ec_gpe_poller); | ||
758 | return ec; | 1047 | return ec; |
759 | } | 1048 | } |
760 | 1049 | ||
@@ -810,13 +1099,13 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
810 | 1099 | ||
811 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | 1100 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
812 | return 0; | 1101 | return 0; |
813 | status = acpi_install_gpe_handler(NULL, ec->gpe, | 1102 | status = acpi_install_gpe_raw_handler(NULL, ec->gpe, |
814 | ACPI_GPE_EDGE_TRIGGERED, | 1103 | ACPI_GPE_EDGE_TRIGGERED, |
815 | &acpi_ec_gpe_handler, ec); | 1104 | &acpi_ec_gpe_handler, ec); |
816 | if (ACPI_FAILURE(status)) | 1105 | if (ACPI_FAILURE(status)) |
817 | return -ENODEV; | 1106 | return -ENODEV; |
818 | 1107 | ||
819 | acpi_enable_gpe(NULL, ec->gpe); | 1108 | acpi_ec_start(ec, false); |
820 | status = acpi_install_address_space_handler(ec->handle, | 1109 | status = acpi_install_address_space_handler(ec->handle, |
821 | ACPI_ADR_SPACE_EC, | 1110 | ACPI_ADR_SPACE_EC, |
822 | &acpi_ec_space_handler, | 1111 | &acpi_ec_space_handler, |
@@ -831,7 +1120,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
831 | pr_err("Fail in evaluating the _REG object" | 1120 | pr_err("Fail in evaluating the _REG object" |
832 | " of EC device. Broken bios is suspected.\n"); | 1121 | " of EC device. Broken bios is suspected.\n"); |
833 | } else { | 1122 | } else { |
834 | acpi_disable_gpe(NULL, ec->gpe); | 1123 | acpi_ec_stop(ec, false); |
835 | acpi_remove_gpe_handler(NULL, ec->gpe, | 1124 | acpi_remove_gpe_handler(NULL, ec->gpe, |
836 | &acpi_ec_gpe_handler); | 1125 | &acpi_ec_gpe_handler); |
837 | return -ENODEV; | 1126 | return -ENODEV; |
@@ -846,7 +1135,7 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
846 | { | 1135 | { |
847 | if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | 1136 | if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
848 | return; | 1137 | return; |
849 | acpi_disable_gpe(NULL, ec->gpe); | 1138 | acpi_ec_stop(ec, false); |
850 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 1139 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
851 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 1140 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
852 | pr_err("failed to remove space handler\n"); | 1141 | pr_err("failed to remove space handler\n"); |
@@ -900,14 +1189,11 @@ static int acpi_ec_add(struct acpi_device *device) | |||
900 | ret = ec_install_handlers(ec); | 1189 | ret = ec_install_handlers(ec); |
901 | 1190 | ||
902 | /* EC is fully operational, allow queries */ | 1191 | /* EC is fully operational, allow queries */ |
903 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 1192 | acpi_ec_enable_event(ec); |
904 | 1193 | ||
905 | /* Clear stale _Q events if hardware might require that */ | 1194 | /* Clear stale _Q events if hardware might require that */ |
906 | if (EC_FLAGS_CLEAR_ON_RESUME) { | 1195 | if (EC_FLAGS_CLEAR_ON_RESUME) |
907 | mutex_lock(&ec->mutex); | ||
908 | acpi_ec_clear(ec); | 1196 | acpi_ec_clear(ec); |
909 | mutex_unlock(&ec->mutex); | ||
910 | } | ||
911 | return ret; | 1197 | return ret; |
912 | } | 1198 | } |
913 | 1199 | ||