diff options
author | Len Brown <len.brown@intel.com> | 2009-09-19 02:05:34 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-09-19 02:05:34 -0400 |
commit | 762caf0baafc657c410b9c04f4a95d4e3aa4dda1 (patch) | |
tree | 67f40220c61c2ad5ad7b1f063337942157c33027 /drivers/acpi/ec.c | |
parent | 3b87bb640e77023c97cf209e3dd85887a1113ad0 (diff) | |
parent | f25752e67d9d9ee7562ae9944314dd8c057d3fa2 (diff) |
Merge branch 'ec' into release
Conflicts:
drivers/acpi/ec.c
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 150 |
1 files changed, 50 insertions, 100 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f28619d658f7..08b8cf79946b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -67,15 +67,13 @@ enum ec_command { | |||
67 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 67 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
68 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 68 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
69 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 69 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
70 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
70 | 71 | ||
71 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
72 | per one transaction */ | 73 | per one transaction */ |
73 | 74 | ||
74 | enum { | 75 | enum { |
75 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
76 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent | ||
77 | * for status change */ | ||
78 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | ||
79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 77 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
80 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 78 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
81 | * OpReg are installed */ | 79 | * OpReg are installed */ |
@@ -169,7 +167,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
169 | acpi_ec_write_cmd(ec, ec->curr->command); | 167 | acpi_ec_write_cmd(ec, ec->curr->command); |
170 | } | 168 | } |
171 | 169 | ||
172 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 170 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
173 | { | 171 | { |
174 | unsigned long flags; | 172 | unsigned long flags; |
175 | spin_lock_irqsave(&ec->curr_lock, flags); | 173 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -200,29 +198,6 @@ unlock: | |||
200 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 198 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
201 | } | 199 | } |
202 | 200 | ||
203 | static int acpi_ec_wait(struct acpi_ec *ec) | ||
204 | { | ||
205 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
206 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
207 | return 0; | ||
208 | /* try restart command if we get any false interrupts */ | ||
209 | if (ec->curr->irq_count && | ||
210 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
211 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
212 | start_transaction(ec); | ||
213 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
214 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
215 | return 0; | ||
216 | } | ||
217 | /* missing GPEs, switch back to poll mode */ | ||
218 | if (printk_ratelimit()) | ||
219 | pr_info(PREFIX "missing confirmations, " | ||
220 | "switch off interrupt mode.\n"); | ||
221 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
222 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
223 | return 1; | ||
224 | } | ||
225 | |||
226 | static void acpi_ec_gpe_query(void *ec_cxt); | 201 | static void acpi_ec_gpe_query(void *ec_cxt); |
227 | 202 | ||
228 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 203 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -235,43 +210,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
235 | return 0; | 210 | return 0; |
236 | } | 211 | } |
237 | 212 | ||
238 | static void ec_delay(void) | ||
239 | { | ||
240 | /* EC in MSI notebooks don't tolerate delays other than 550 usec */ | ||
241 | if (EC_FLAGS_MSI) | ||
242 | udelay(ACPI_EC_DELAY); | ||
243 | else | ||
244 | /* Use shortest sleep available */ | ||
245 | msleep(1); | ||
246 | } | ||
247 | |||
248 | static int ec_poll(struct acpi_ec *ec) | 213 | static int ec_poll(struct acpi_ec *ec) |
249 | { | 214 | { |
250 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 215 | unsigned long flags; |
251 | udelay(ACPI_EC_CDELAY); | 216 | int repeat = 2; /* number of command restarts */ |
252 | while (time_before(jiffies, delay)) { | 217 | while (repeat--) { |
253 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 218 | unsigned long delay = jiffies + |
254 | ec_delay(); | 219 | msecs_to_jiffies(ACPI_EC_DELAY); |
255 | if (ec_transaction_done(ec)) | 220 | do { |
256 | return 0; | 221 | /* don't sleep with disabled interrupts */ |
222 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
223 | udelay(ACPI_EC_MSI_UDELAY); | ||
224 | if (ec_transaction_done(ec)) | ||
225 | return 0; | ||
226 | } else { | ||
227 | if (wait_event_timeout(ec->wait, | ||
228 | ec_transaction_done(ec), | ||
229 | msecs_to_jiffies(1))) | ||
230 | return 0; | ||
231 | } | ||
232 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
233 | } while (time_before(jiffies, delay)); | ||
234 | if (!ec->curr->irq_count || | ||
235 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
236 | break; | ||
237 | /* try restart command if we get any false interrupts */ | ||
238 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
239 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
240 | start_transaction(ec); | ||
241 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
257 | } | 242 | } |
258 | return -ETIME; | 243 | return -ETIME; |
259 | } | 244 | } |
260 | 245 | ||
261 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 246 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
262 | struct transaction *t, | 247 | struct transaction *t) |
263 | int force_poll) | ||
264 | { | 248 | { |
265 | unsigned long tmp; | 249 | unsigned long tmp; |
266 | int ret = 0; | 250 | int ret = 0; |
267 | pr_debug(PREFIX "transaction start\n"); | 251 | pr_debug(PREFIX "transaction start\n"); |
268 | /* disable GPE during transaction if storm is detected */ | 252 | /* disable GPE during transaction if storm is detected */ |
269 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 253 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
270 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
271 | acpi_disable_gpe(NULL, ec->gpe); | 254 | acpi_disable_gpe(NULL, ec->gpe); |
272 | } | 255 | } |
273 | if (EC_FLAGS_MSI) | 256 | if (EC_FLAGS_MSI) |
274 | udelay(ACPI_EC_DELAY); | 257 | udelay(ACPI_EC_MSI_UDELAY); |
275 | /* start transaction */ | 258 | /* start transaction */ |
276 | spin_lock_irqsave(&ec->curr_lock, tmp); | 259 | spin_lock_irqsave(&ec->curr_lock, tmp); |
277 | /* following two actions should be kept atomic */ | 260 | /* following two actions should be kept atomic */ |
@@ -280,11 +263,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
280 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 263 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
281 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 264 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
282 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 265 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
283 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 266 | ret = ec_poll(ec); |
284 | if (force_poll || | ||
285 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || | ||
286 | acpi_ec_wait(ec)) | ||
287 | ret = ec_poll(ec); | ||
288 | pr_debug(PREFIX "transaction end\n"); | 267 | pr_debug(PREFIX "transaction end\n"); |
289 | spin_lock_irqsave(&ec->curr_lock, tmp); | 268 | spin_lock_irqsave(&ec->curr_lock, tmp); |
290 | ec->curr = NULL; | 269 | ec->curr = NULL; |
@@ -294,8 +273,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
294 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 273 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
295 | /* it is safe to enable GPE outside of transaction */ | 274 | /* it is safe to enable GPE outside of transaction */ |
296 | acpi_enable_gpe(NULL, ec->gpe); | 275 | acpi_enable_gpe(NULL, ec->gpe); |
297 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 276 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
298 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
299 | pr_info(PREFIX "GPE storm detected, " | 277 | pr_info(PREFIX "GPE storm detected, " |
300 | "transactions will use polling mode\n"); | 278 | "transactions will use polling mode\n"); |
301 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 279 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -313,16 +291,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
313 | { | 291 | { |
314 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 292 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
315 | /* interrupt wait manually if GPE mode is not active */ | 293 | /* interrupt wait manually if GPE mode is not active */ |
316 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
317 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
318 | while (time_before(jiffies, delay)) | 294 | while (time_before(jiffies, delay)) |
319 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 295 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
296 | msecs_to_jiffies(1))) | ||
320 | return 0; | 297 | return 0; |
321 | return -ETIME; | 298 | return -ETIME; |
322 | } | 299 | } |
323 | 300 | ||
324 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 301 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
325 | int force_poll) | ||
326 | { | 302 | { |
327 | int status; | 303 | int status; |
328 | u32 glk; | 304 | u32 glk; |
@@ -344,7 +320,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
344 | status = -ETIME; | 320 | status = -ETIME; |
345 | goto end; | 321 | goto end; |
346 | } | 322 | } |
347 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 323 | status = acpi_ec_transaction_unlocked(ec, t); |
348 | end: | 324 | end: |
349 | if (ec->global_lock) | 325 | if (ec->global_lock) |
350 | acpi_release_global_lock(glk); | 326 | acpi_release_global_lock(glk); |
@@ -353,10 +329,6 @@ unlock: | |||
353 | return status; | 329 | return status; |
354 | } | 330 | } |
355 | 331 | ||
356 | /* | ||
357 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
358 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
359 | */ | ||
360 | static int acpi_ec_burst_enable(struct acpi_ec *ec) | 332 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
361 | { | 333 | { |
362 | u8 d; | 334 | u8 d; |
@@ -364,7 +336,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
364 | .wdata = NULL, .rdata = &d, | 336 | .wdata = NULL, .rdata = &d, |
365 | .wlen = 0, .rlen = 1}; | 337 | .wlen = 0, .rlen = 1}; |
366 | 338 | ||
367 | return acpi_ec_transaction(ec, &t, 0); | 339 | return acpi_ec_transaction(ec, &t); |
368 | } | 340 | } |
369 | 341 | ||
370 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 342 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -374,7 +346,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
374 | .wlen = 0, .rlen = 0}; | 346 | .wlen = 0, .rlen = 0}; |
375 | 347 | ||
376 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 348 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
377 | acpi_ec_transaction(ec, &t, 0) : 0; | 349 | acpi_ec_transaction(ec, &t) : 0; |
378 | } | 350 | } |
379 | 351 | ||
380 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 352 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -385,7 +357,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
385 | .wdata = &address, .rdata = &d, | 357 | .wdata = &address, .rdata = &d, |
386 | .wlen = 1, .rlen = 1}; | 358 | .wlen = 1, .rlen = 1}; |
387 | 359 | ||
388 | result = acpi_ec_transaction(ec, &t, 0); | 360 | result = acpi_ec_transaction(ec, &t); |
389 | *data = d; | 361 | *data = d; |
390 | return result; | 362 | return result; |
391 | } | 363 | } |
@@ -397,7 +369,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
397 | .wdata = wdata, .rdata = NULL, | 369 | .wdata = wdata, .rdata = NULL, |
398 | .wlen = 2, .rlen = 0}; | 370 | .wlen = 2, .rlen = 0}; |
399 | 371 | ||
400 | return acpi_ec_transaction(ec, &t, 0); | 372 | return acpi_ec_transaction(ec, &t); |
401 | } | 373 | } |
402 | 374 | ||
403 | /* | 375 | /* |
@@ -465,7 +437,7 @@ int ec_transaction(u8 command, | |||
465 | if (!first_ec) | 437 | if (!first_ec) |
466 | return -ENODEV; | 438 | return -ENODEV; |
467 | 439 | ||
468 | return acpi_ec_transaction(first_ec, &t, force_poll); | 440 | return acpi_ec_transaction(first_ec, &t); |
469 | } | 441 | } |
470 | 442 | ||
471 | EXPORT_SYMBOL(ec_transaction); | 443 | EXPORT_SYMBOL(ec_transaction); |
@@ -486,7 +458,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
486 | * bit to be cleared (and thus clearing the interrupt source). | 458 | * bit to be cleared (and thus clearing the interrupt source). |
487 | */ | 459 | */ |
488 | 460 | ||
489 | result = acpi_ec_transaction(ec, &t, 0); | 461 | result = acpi_ec_transaction(ec, &t); |
490 | if (result) | 462 | if (result) |
491 | return result; | 463 | return result; |
492 | 464 | ||
@@ -569,28 +541,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
569 | pr_debug(PREFIX "~~~> interrupt\n"); | 541 | pr_debug(PREFIX "~~~> interrupt\n"); |
570 | status = acpi_ec_read_status(ec); | 542 | status = acpi_ec_read_status(ec); |
571 | 543 | ||
572 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 544 | advance_transaction(ec, status); |
573 | gpe_transaction(ec, status); | 545 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
574 | if (ec_transaction_done(ec) && | 546 | wake_up(&ec->wait); |
575 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
576 | wake_up(&ec->wait); | ||
577 | } | ||
578 | |||
579 | ec_check_sci(ec, status); | 547 | ec_check_sci(ec, status); |
580 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
581 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | ||
582 | /* this is non-query, must be confirmation */ | ||
583 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
584 | if (printk_ratelimit()) | ||
585 | pr_info(PREFIX "non-query interrupt received," | ||
586 | " switching to interrupt mode\n"); | ||
587 | } else { | ||
588 | /* hush, STORM switches the mode every transaction */ | ||
589 | pr_debug(PREFIX "non-query interrupt received," | ||
590 | " switching to interrupt mode\n"); | ||
591 | } | ||
592 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
593 | } | ||
594 | return ACPI_INTERRUPT_HANDLED; | 548 | return ACPI_INTERRUPT_HANDLED; |
595 | } | 549 | } |
596 | 550 | ||
@@ -616,7 +570,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
616 | if (bits != 8 && acpi_strict) | 570 | if (bits != 8 && acpi_strict) |
617 | return AE_BAD_PARAMETER; | 571 | return AE_BAD_PARAMETER; |
618 | 572 | ||
619 | acpi_ec_burst_enable(ec); | 573 | if (EC_FLAGS_MSI) |
574 | acpi_ec_burst_enable(ec); | ||
620 | 575 | ||
621 | if (function == ACPI_READ) { | 576 | if (function == ACPI_READ) { |
622 | result = acpi_ec_read(ec, address, &temp); | 577 | result = acpi_ec_read(ec, address, &temp); |
@@ -637,7 +592,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
637 | } | 592 | } |
638 | } | 593 | } |
639 | 594 | ||
640 | acpi_ec_burst_disable(ec); | 595 | if (EC_FLAGS_MSI) |
596 | acpi_ec_burst_disable(ec); | ||
641 | 597 | ||
642 | switch (result) { | 598 | switch (result) { |
643 | case -EINVAL: | 599 | case -EINVAL: |
@@ -871,8 +827,6 @@ static int acpi_ec_add(struct acpi_device *device) | |||
871 | acpi_ec_add_fs(device); | 827 | acpi_ec_add_fs(device); |
872 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 828 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
873 | ec->gpe, ec->command_addr, ec->data_addr); | 829 | ec->gpe, ec->command_addr, ec->data_addr); |
874 | pr_info(PREFIX "driver started in %s mode\n", | ||
875 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | ||
876 | 830 | ||
877 | ret = ec_install_handlers(ec); | 831 | ret = ec_install_handlers(ec); |
878 | 832 | ||
@@ -1025,8 +979,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1025 | { | 979 | { |
1026 | struct acpi_ec *ec = acpi_driver_data(device); | 980 | struct acpi_ec *ec = acpi_driver_data(device); |
1027 | /* Stop using GPE */ | 981 | /* Stop using GPE */ |
1028 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1029 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1030 | acpi_disable_gpe(NULL, ec->gpe); | 982 | acpi_disable_gpe(NULL, ec->gpe); |
1031 | return 0; | 983 | return 0; |
1032 | } | 984 | } |
@@ -1035,8 +987,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1035 | { | 987 | { |
1036 | struct acpi_ec *ec = acpi_driver_data(device); | 988 | struct acpi_ec *ec = acpi_driver_data(device); |
1037 | /* Enable use of GPE back */ | 989 | /* Enable use of GPE back */ |
1038 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1039 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1040 | acpi_enable_gpe(NULL, ec->gpe); | 990 | acpi_enable_gpe(NULL, ec->gpe); |
1041 | return 0; | 991 | return 0; |
1042 | } | 992 | } |