diff options
-rw-r--r-- | drivers/acpi/ec.c | 140 |
1 files changed, 46 insertions, 94 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 391f331674c7..839b542d5087 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -68,15 +68,13 @@ enum ec_command { | |||
68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
71 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
71 | 72 | ||
72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
73 | per one transaction */ | 74 | per one transaction */ |
74 | 75 | ||
75 | enum { | 76 | enum { |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
77 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent | ||
78 | * for status change */ | ||
79 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | ||
80 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
82 | * OpReg are installed */ | 80 | * OpReg are installed */ |
@@ -170,7 +168,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
170 | acpi_ec_write_cmd(ec, ec->curr->command); | 168 | acpi_ec_write_cmd(ec, ec->curr->command); |
171 | } | 169 | } |
172 | 170 | ||
173 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 171 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
174 | { | 172 | { |
175 | unsigned long flags; | 173 | unsigned long flags; |
176 | spin_lock_irqsave(&ec->curr_lock, flags); | 174 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -201,29 +199,6 @@ unlock: | |||
201 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 199 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
202 | } | 200 | } |
203 | 201 | ||
204 | static int acpi_ec_wait(struct acpi_ec *ec) | ||
205 | { | ||
206 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
207 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
208 | return 0; | ||
209 | /* try restart command if we get any false interrupts */ | ||
210 | if (ec->curr->irq_count && | ||
211 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
212 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
213 | start_transaction(ec); | ||
214 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
215 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
216 | return 0; | ||
217 | } | ||
218 | /* missing GPEs, switch back to poll mode */ | ||
219 | if (printk_ratelimit()) | ||
220 | pr_info(PREFIX "missing confirmations, " | ||
221 | "switch off interrupt mode.\n"); | ||
222 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
223 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | static void acpi_ec_gpe_query(void *ec_cxt); | 202 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | 203 | ||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 204 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -236,43 +211,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
236 | return 0; | 211 | return 0; |
237 | } | 212 | } |
238 | 213 | ||
239 | static void ec_delay(void) | ||
240 | { | ||
241 | /* EC in MSI notebooks don't tolerate delays other than 550 usec */ | ||
242 | if (EC_FLAGS_MSI) | ||
243 | udelay(ACPI_EC_DELAY); | ||
244 | else | ||
245 | /* Use shortest sleep available */ | ||
246 | msleep(1); | ||
247 | } | ||
248 | |||
249 | static int ec_poll(struct acpi_ec *ec) | 214 | static int ec_poll(struct acpi_ec *ec) |
250 | { | 215 | { |
251 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 216 | unsigned long flags; |
252 | udelay(ACPI_EC_CDELAY); | 217 | int repeat = 2; /* number of command restarts */ |
253 | while (time_before(jiffies, delay)) { | 218 | while (repeat--) { |
254 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 219 | unsigned long delay = jiffies + |
255 | ec_delay(); | 220 | msecs_to_jiffies(ACPI_EC_DELAY); |
256 | if (ec_transaction_done(ec)) | 221 | do { |
257 | return 0; | 222 | /* don't sleep with disabled interrupts */ |
223 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
224 | udelay(ACPI_EC_MSI_UDELAY); | ||
225 | if (ec_transaction_done(ec)) | ||
226 | return 0; | ||
227 | } else { | ||
228 | if (wait_event_timeout(ec->wait, | ||
229 | ec_transaction_done(ec), | ||
230 | msecs_to_jiffies(1))) | ||
231 | return 0; | ||
232 | } | ||
233 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
234 | } while (time_before(jiffies, delay)); | ||
235 | if (!ec->curr->irq_count || | ||
236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
237 | break; | ||
238 | /* try restart command if we get any false interrupts */ | ||
239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
240 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
241 | start_transaction(ec); | ||
242 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
258 | } | 243 | } |
259 | return -ETIME; | 244 | return -ETIME; |
260 | } | 245 | } |
261 | 246 | ||
262 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 247 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
263 | struct transaction *t, | 248 | struct transaction *t) |
264 | int force_poll) | ||
265 | { | 249 | { |
266 | unsigned long tmp; | 250 | unsigned long tmp; |
267 | int ret = 0; | 251 | int ret = 0; |
268 | pr_debug(PREFIX "transaction start\n"); | 252 | pr_debug(PREFIX "transaction start\n"); |
269 | /* disable GPE during transaction if storm is detected */ | 253 | /* disable GPE during transaction if storm is detected */ |
270 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 254 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
271 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
272 | acpi_disable_gpe(NULL, ec->gpe); | 255 | acpi_disable_gpe(NULL, ec->gpe); |
273 | } | 256 | } |
274 | if (EC_FLAGS_MSI) | 257 | if (EC_FLAGS_MSI) |
275 | udelay(ACPI_EC_DELAY); | 258 | udelay(ACPI_EC_MSI_UDELAY); |
276 | /* start transaction */ | 259 | /* start transaction */ |
277 | spin_lock_irqsave(&ec->curr_lock, tmp); | 260 | spin_lock_irqsave(&ec->curr_lock, tmp); |
278 | /* following two actions should be kept atomic */ | 261 | /* following two actions should be kept atomic */ |
@@ -281,11 +264,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
281 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 264 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
282 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 265 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
283 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 266 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
284 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 267 | ret = ec_poll(ec); |
285 | if (force_poll || | ||
286 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || | ||
287 | acpi_ec_wait(ec)) | ||
288 | ret = ec_poll(ec); | ||
289 | pr_debug(PREFIX "transaction end\n"); | 268 | pr_debug(PREFIX "transaction end\n"); |
290 | spin_lock_irqsave(&ec->curr_lock, tmp); | 269 | spin_lock_irqsave(&ec->curr_lock, tmp); |
291 | ec->curr = NULL; | 270 | ec->curr = NULL; |
@@ -295,8 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
295 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 274 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
296 | /* it is safe to enable GPE outside of transaction */ | 275 | /* it is safe to enable GPE outside of transaction */ |
297 | acpi_enable_gpe(NULL, ec->gpe); | 276 | acpi_enable_gpe(NULL, ec->gpe); |
298 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 277 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
299 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
300 | pr_info(PREFIX "GPE storm detected, " | 278 | pr_info(PREFIX "GPE storm detected, " |
301 | "transactions will use polling mode\n"); | 279 | "transactions will use polling mode\n"); |
302 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 280 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -314,16 +292,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
314 | { | 292 | { |
315 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 293 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
316 | /* interrupt wait manually if GPE mode is not active */ | 294 | /* interrupt wait manually if GPE mode is not active */ |
317 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
318 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
319 | while (time_before(jiffies, delay)) | 295 | while (time_before(jiffies, delay)) |
320 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 296 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
297 | msecs_to_jiffies(1))) | ||
321 | return 0; | 298 | return 0; |
322 | return -ETIME; | 299 | return -ETIME; |
323 | } | 300 | } |
324 | 301 | ||
325 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 302 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
326 | int force_poll) | ||
327 | { | 303 | { |
328 | int status; | 304 | int status; |
329 | u32 glk; | 305 | u32 glk; |
@@ -345,7 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
345 | status = -ETIME; | 321 | status = -ETIME; |
346 | goto end; | 322 | goto end; |
347 | } | 323 | } |
348 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 324 | status = acpi_ec_transaction_unlocked(ec, t); |
349 | end: | 325 | end: |
350 | if (ec->global_lock) | 326 | if (ec->global_lock) |
351 | acpi_release_global_lock(glk); | 327 | acpi_release_global_lock(glk); |
@@ -365,7 +341,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
365 | .wdata = NULL, .rdata = &d, | 341 | .wdata = NULL, .rdata = &d, |
366 | .wlen = 0, .rlen = 1}; | 342 | .wlen = 0, .rlen = 1}; |
367 | 343 | ||
368 | return acpi_ec_transaction(ec, &t, 0); | 344 | return acpi_ec_transaction(ec, &t); |
369 | } | 345 | } |
370 | 346 | ||
371 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 347 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -375,7 +351,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
375 | .wlen = 0, .rlen = 0}; | 351 | .wlen = 0, .rlen = 0}; |
376 | 352 | ||
377 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 353 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
378 | acpi_ec_transaction(ec, &t, 0) : 0; | 354 | acpi_ec_transaction(ec, &t) : 0; |
379 | } | 355 | } |
380 | 356 | ||
381 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 357 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -386,7 +362,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
386 | .wdata = &address, .rdata = &d, | 362 | .wdata = &address, .rdata = &d, |
387 | .wlen = 1, .rlen = 1}; | 363 | .wlen = 1, .rlen = 1}; |
388 | 364 | ||
389 | result = acpi_ec_transaction(ec, &t, 0); | 365 | result = acpi_ec_transaction(ec, &t); |
390 | *data = d; | 366 | *data = d; |
391 | return result; | 367 | return result; |
392 | } | 368 | } |
@@ -398,7 +374,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
398 | .wdata = wdata, .rdata = NULL, | 374 | .wdata = wdata, .rdata = NULL, |
399 | .wlen = 2, .rlen = 0}; | 375 | .wlen = 2, .rlen = 0}; |
400 | 376 | ||
401 | return acpi_ec_transaction(ec, &t, 0); | 377 | return acpi_ec_transaction(ec, &t); |
402 | } | 378 | } |
403 | 379 | ||
404 | /* | 380 | /* |
@@ -466,7 +442,7 @@ int ec_transaction(u8 command, | |||
466 | if (!first_ec) | 442 | if (!first_ec) |
467 | return -ENODEV; | 443 | return -ENODEV; |
468 | 444 | ||
469 | return acpi_ec_transaction(first_ec, &t, force_poll); | 445 | return acpi_ec_transaction(first_ec, &t); |
470 | } | 446 | } |
471 | 447 | ||
472 | EXPORT_SYMBOL(ec_transaction); | 448 | EXPORT_SYMBOL(ec_transaction); |
@@ -487,7 +463,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
487 | * bit to be cleared (and thus clearing the interrupt source). | 463 | * bit to be cleared (and thus clearing the interrupt source). |
488 | */ | 464 | */ |
489 | 465 | ||
490 | result = acpi_ec_transaction(ec, &t, 0); | 466 | result = acpi_ec_transaction(ec, &t); |
491 | if (result) | 467 | if (result) |
492 | return result; | 468 | return result; |
493 | 469 | ||
@@ -570,28 +546,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
570 | pr_debug(PREFIX "~~~> interrupt\n"); | 546 | pr_debug(PREFIX "~~~> interrupt\n"); |
571 | status = acpi_ec_read_status(ec); | 547 | status = acpi_ec_read_status(ec); |
572 | 548 | ||
573 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 549 | advance_transaction(ec, status); |
574 | gpe_transaction(ec, status); | 550 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
575 | if (ec_transaction_done(ec) && | 551 | wake_up(&ec->wait); |
576 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
577 | wake_up(&ec->wait); | ||
578 | } | ||
579 | |||
580 | ec_check_sci(ec, status); | 552 | ec_check_sci(ec, status); |
581 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
582 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | ||
583 | /* this is non-query, must be confirmation */ | ||
584 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
585 | if (printk_ratelimit()) | ||
586 | pr_info(PREFIX "non-query interrupt received," | ||
587 | " switching to interrupt mode\n"); | ||
588 | } else { | ||
589 | /* hush, STORM switches the mode every transaction */ | ||
590 | pr_debug(PREFIX "non-query interrupt received," | ||
591 | " switching to interrupt mode\n"); | ||
592 | } | ||
593 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
594 | } | ||
595 | return ACPI_INTERRUPT_HANDLED; | 553 | return ACPI_INTERRUPT_HANDLED; |
596 | } | 554 | } |
597 | 555 | ||
@@ -837,8 +795,6 @@ static int acpi_ec_add(struct acpi_device *device) | |||
837 | acpi_ec_add_fs(device); | 795 | acpi_ec_add_fs(device); |
838 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 796 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
839 | ec->gpe, ec->command_addr, ec->data_addr); | 797 | ec->gpe, ec->command_addr, ec->data_addr); |
840 | pr_info(PREFIX "driver started in %s mode\n", | ||
841 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | ||
842 | return 0; | 798 | return 0; |
843 | } | 799 | } |
844 | 800 | ||
@@ -1054,8 +1010,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1054 | { | 1010 | { |
1055 | struct acpi_ec *ec = acpi_driver_data(device); | 1011 | struct acpi_ec *ec = acpi_driver_data(device); |
1056 | /* Stop using GPE */ | 1012 | /* Stop using GPE */ |
1057 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1058 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1059 | acpi_disable_gpe(NULL, ec->gpe); | 1013 | acpi_disable_gpe(NULL, ec->gpe); |
1060 | return 0; | 1014 | return 0; |
1061 | } | 1015 | } |
@@ -1064,8 +1018,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1064 | { | 1018 | { |
1065 | struct acpi_ec *ec = acpi_driver_data(device); | 1019 | struct acpi_ec *ec = acpi_driver_data(device); |
1066 | /* Enable use of GPE back */ | 1020 | /* Enable use of GPE back */ |
1067 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1068 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1069 | acpi_enable_gpe(NULL, ec->gpe); | 1021 | acpi_enable_gpe(NULL, ec->gpe); |
1070 | return 0; | 1022 | return 0; |
1071 | } | 1023 | } |