aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c97
1 files changed, 53 insertions, 44 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a51df9681319..354007d490d1 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -158,10 +158,10 @@ static int ec_transaction_done(struct acpi_ec *ec)
158{ 158{
159 unsigned long flags; 159 unsigned long flags;
160 int ret = 0; 160 int ret = 0;
161 spin_lock_irqsave(&ec->curr_lock, flags); 161 spin_lock_irqsave(&ec->lock, flags);
162 if (!ec->curr || ec->curr->done) 162 if (!ec->curr || ec->curr->done)
163 ret = 1; 163 ret = 1;
164 spin_unlock_irqrestore(&ec->curr_lock, flags); 164 spin_unlock_irqrestore(&ec->lock, flags);
165 return ret; 165 return ret;
166} 166}
167 167
@@ -175,32 +175,38 @@ static void start_transaction(struct acpi_ec *ec)
175static void advance_transaction(struct acpi_ec *ec, u8 status) 175static void advance_transaction(struct acpi_ec *ec, u8 status)
176{ 176{
177 unsigned long flags; 177 unsigned long flags;
178 spin_lock_irqsave(&ec->curr_lock, flags); 178 struct transaction *t = ec->curr;
179 if (!ec->curr) 179
180 spin_lock_irqsave(&ec->lock, flags);
181 if (!t)
180 goto unlock; 182 goto unlock;
181 if (ec->curr->wlen > ec->curr->wi) { 183 if (t->wlen > t->wi) {
182 if ((status & ACPI_EC_FLAG_IBF) == 0) 184 if ((status & ACPI_EC_FLAG_IBF) == 0)
183 acpi_ec_write_data(ec, 185 acpi_ec_write_data(ec,
184 ec->curr->wdata[ec->curr->wi++]); 186 t->wdata[t->wi++]);
185 else 187 else
186 goto err; 188 goto err;
187 } else if (ec->curr->rlen > ec->curr->ri) { 189 } else if (t->rlen > t->ri) {
188 if ((status & ACPI_EC_FLAG_OBF) == 1) { 190 if ((status & ACPI_EC_FLAG_OBF) == 1) {
189 ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); 191 t->rdata[t->ri++] = acpi_ec_read_data(ec);
190 if (ec->curr->rlen == ec->curr->ri) 192 if (t->rlen == t->ri)
191 ec->curr->done = true; 193 t->done = true;
192 } else 194 } else
193 goto err; 195 goto err;
194 } else if (ec->curr->wlen == ec->curr->wi && 196 } else if (t->wlen == t->wi &&
195 (status & ACPI_EC_FLAG_IBF) == 0) 197 (status & ACPI_EC_FLAG_IBF) == 0)
196 ec->curr->done = true; 198 t->done = true;
197 goto unlock; 199 goto unlock;
198err: 200err:
199 /* false interrupt, state didn't change */ 201 /*
200 if (in_interrupt()) 202 * If SCI bit is set, then don't think it's a false IRQ
201 ++ec->curr->irq_count; 203 * otherwise will take a not handled IRQ as a false one.
204 */
205 if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
206 ++t->irq_count;
207
202unlock: 208unlock:
203 spin_unlock_irqrestore(&ec->curr_lock, flags); 209 spin_unlock_irqrestore(&ec->lock, flags);
204} 210}
205 211
206static int acpi_ec_sync_query(struct acpi_ec *ec); 212static int acpi_ec_sync_query(struct acpi_ec *ec);
@@ -238,9 +244,9 @@ static int ec_poll(struct acpi_ec *ec)
238 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) 244 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
239 break; 245 break;
240 pr_debug(PREFIX "controller reset, restart transaction\n"); 246 pr_debug(PREFIX "controller reset, restart transaction\n");
241 spin_lock_irqsave(&ec->curr_lock, flags); 247 spin_lock_irqsave(&ec->lock, flags);
242 start_transaction(ec); 248 start_transaction(ec);
243 spin_unlock_irqrestore(&ec->curr_lock, flags); 249 spin_unlock_irqrestore(&ec->lock, flags);
244 } 250 }
245 return -ETIME; 251 return -ETIME;
246} 252}
@@ -253,17 +259,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
253 if (EC_FLAGS_MSI) 259 if (EC_FLAGS_MSI)
254 udelay(ACPI_EC_MSI_UDELAY); 260 udelay(ACPI_EC_MSI_UDELAY);
255 /* start transaction */ 261 /* start transaction */
256 spin_lock_irqsave(&ec->curr_lock, tmp); 262 spin_lock_irqsave(&ec->lock, tmp);
257 /* following two actions should be kept atomic */ 263 /* following two actions should be kept atomic */
258 ec->curr = t; 264 ec->curr = t;
259 start_transaction(ec); 265 start_transaction(ec);
260 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) 266 if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
261 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); 267 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
262 spin_unlock_irqrestore(&ec->curr_lock, tmp); 268 spin_unlock_irqrestore(&ec->lock, tmp);
263 ret = ec_poll(ec); 269 ret = ec_poll(ec);
264 spin_lock_irqsave(&ec->curr_lock, tmp); 270 spin_lock_irqsave(&ec->lock, tmp);
265 ec->curr = NULL; 271 ec->curr = NULL;
266 spin_unlock_irqrestore(&ec->curr_lock, tmp); 272 spin_unlock_irqrestore(&ec->lock, tmp);
267 return ret; 273 return ret;
268} 274}
269 275
@@ -292,7 +298,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
292 return -EINVAL; 298 return -EINVAL;
293 if (t->rdata) 299 if (t->rdata)
294 memset(t->rdata, 0, t->rlen); 300 memset(t->rdata, 0, t->rlen);
295 mutex_lock(&ec->lock); 301 mutex_lock(&ec->mutex);
296 if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { 302 if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) {
297 status = -EINVAL; 303 status = -EINVAL;
298 goto unlock; 304 goto unlock;
@@ -310,7 +316,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
310 status = -ETIME; 316 status = -ETIME;
311 goto end; 317 goto end;
312 } 318 }
313 pr_debug(PREFIX "transaction start\n"); 319 pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n",
320 t->command, t->wdata ? t->wdata[0] : 0);
314 /* disable GPE during transaction if storm is detected */ 321 /* disable GPE during transaction if storm is detected */
315 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { 322 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
316 /* It has to be disabled, so that it doesn't trigger. */ 323 /* It has to be disabled, so that it doesn't trigger. */
@@ -326,8 +333,9 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
326 /* It is safe to enable the GPE outside of the transaction. */ 333 /* It is safe to enable the GPE outside of the transaction. */
327 acpi_enable_gpe(NULL, ec->gpe); 334 acpi_enable_gpe(NULL, ec->gpe);
328 } else if (t->irq_count > ec_storm_threshold) { 335 } else if (t->irq_count > ec_storm_threshold) {
329 pr_info(PREFIX "GPE storm detected, " 336 pr_info(PREFIX "GPE storm detected(%d GPEs), "
330 "transactions will use polling mode\n"); 337 "transactions will use polling mode\n",
338 t->irq_count);
331 set_bit(EC_FLAGS_GPE_STORM, &ec->flags); 339 set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
332 } 340 }
333 pr_debug(PREFIX "transaction end\n"); 341 pr_debug(PREFIX "transaction end\n");
@@ -335,7 +343,7 @@ end:
335 if (ec->global_lock) 343 if (ec->global_lock)
336 acpi_release_global_lock(glk); 344 acpi_release_global_lock(glk);
337unlock: 345unlock:
338 mutex_unlock(&ec->lock); 346 mutex_unlock(&ec->mutex);
339 return status; 347 return status;
340} 348}
341 349
@@ -403,7 +411,7 @@ int ec_burst_disable(void)
403 411
404EXPORT_SYMBOL(ec_burst_disable); 412EXPORT_SYMBOL(ec_burst_disable);
405 413
406int ec_read(u8 addr, u8 * val) 414int ec_read(u8 addr, u8 *val)
407{ 415{
408 int err; 416 int err;
409 u8 temp_data; 417 u8 temp_data;
@@ -468,10 +476,10 @@ void acpi_ec_block_transactions(void)
468 if (!ec) 476 if (!ec)
469 return; 477 return;
470 478
471 mutex_lock(&ec->lock); 479 mutex_lock(&ec->mutex);
472 /* Prevent transactions from being carried out */ 480 /* Prevent transactions from being carried out */
473 set_bit(EC_FLAGS_BLOCKED, &ec->flags); 481 set_bit(EC_FLAGS_BLOCKED, &ec->flags);
474 mutex_unlock(&ec->lock); 482 mutex_unlock(&ec->mutex);
475} 483}
476 484
477void acpi_ec_unblock_transactions(void) 485void acpi_ec_unblock_transactions(void)
@@ -481,10 +489,10 @@ void acpi_ec_unblock_transactions(void)
481 if (!ec) 489 if (!ec)
482 return; 490 return;
483 491
484 mutex_lock(&ec->lock); 492 mutex_lock(&ec->mutex);
485 /* Allow transactions to be carried out again */ 493 /* Allow transactions to be carried out again */
486 clear_bit(EC_FLAGS_BLOCKED, &ec->flags); 494 clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
487 mutex_unlock(&ec->lock); 495 mutex_unlock(&ec->mutex);
488} 496}
489 497
490void acpi_ec_unblock_transactions_early(void) 498void acpi_ec_unblock_transactions_early(void)
@@ -536,9 +544,9 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
536 handler->handle = handle; 544 handler->handle = handle;
537 handler->func = func; 545 handler->func = func;
538 handler->data = data; 546 handler->data = data;
539 mutex_lock(&ec->lock); 547 mutex_lock(&ec->mutex);
540 list_add(&handler->node, &ec->list); 548 list_add(&handler->node, &ec->list);
541 mutex_unlock(&ec->lock); 549 mutex_unlock(&ec->mutex);
542 return 0; 550 return 0;
543} 551}
544 552
@@ -547,14 +555,14 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
547void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) 555void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
548{ 556{
549 struct acpi_ec_query_handler *handler, *tmp; 557 struct acpi_ec_query_handler *handler, *tmp;
550 mutex_lock(&ec->lock); 558 mutex_lock(&ec->mutex);
551 list_for_each_entry_safe(handler, tmp, &ec->list, node) { 559 list_for_each_entry_safe(handler, tmp, &ec->list, node) {
552 if (query_bit == handler->query_bit) { 560 if (query_bit == handler->query_bit) {
553 list_del(&handler->node); 561 list_del(&handler->node);
554 kfree(handler); 562 kfree(handler);
555 } 563 }
556 } 564 }
557 mutex_unlock(&ec->lock); 565 mutex_unlock(&ec->mutex);
558} 566}
559 567
560EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); 568EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
@@ -601,9 +609,9 @@ static void acpi_ec_gpe_query(void *ec_cxt)
601 struct acpi_ec *ec = ec_cxt; 609 struct acpi_ec *ec = ec_cxt;
602 if (!ec) 610 if (!ec)
603 return; 611 return;
604 mutex_lock(&ec->lock); 612 mutex_lock(&ec->mutex);
605 acpi_ec_sync_query(ec); 613 acpi_ec_sync_query(ec);
606 mutex_unlock(&ec->lock); 614 mutex_unlock(&ec->mutex);
607} 615}
608 616
609static int ec_check_sci(struct acpi_ec *ec, u8 state) 617static int ec_check_sci(struct acpi_ec *ec, u8 state)
@@ -622,10 +630,11 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
622 u32 gpe_number, void *data) 630 u32 gpe_number, void *data)
623{ 631{
624 struct acpi_ec *ec = data; 632 struct acpi_ec *ec = data;
633 u8 status = acpi_ec_read_status(ec);
625 634
626 pr_debug(PREFIX "~~~> interrupt\n"); 635 pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status);
627 636
628 advance_transaction(ec, acpi_ec_read_status(ec)); 637 advance_transaction(ec, status);
629 if (ec_transaction_done(ec) && 638 if (ec_transaction_done(ec) &&
630 (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { 639 (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
631 wake_up(&ec->wait); 640 wake_up(&ec->wait);
@@ -691,10 +700,10 @@ static struct acpi_ec *make_acpi_ec(void)
691 if (!ec) 700 if (!ec)
692 return NULL; 701 return NULL;
693 ec->flags = 1 << EC_FLAGS_QUERY_PENDING; 702 ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
694 mutex_init(&ec->lock); 703 mutex_init(&ec->mutex);
695 init_waitqueue_head(&ec->wait); 704 init_waitqueue_head(&ec->wait);
696 INIT_LIST_HEAD(&ec->list); 705 INIT_LIST_HEAD(&ec->list);
697 spin_lock_init(&ec->curr_lock); 706 spin_lock_init(&ec->lock);
698 return ec; 707 return ec;
699} 708}
700 709
@@ -853,12 +862,12 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
853 862
854 ec = acpi_driver_data(device); 863 ec = acpi_driver_data(device);
855 ec_remove_handlers(ec); 864 ec_remove_handlers(ec);
856 mutex_lock(&ec->lock); 865 mutex_lock(&ec->mutex);
857 list_for_each_entry_safe(handler, tmp, &ec->list, node) { 866 list_for_each_entry_safe(handler, tmp, &ec->list, node) {
858 list_del(&handler->node); 867 list_del(&handler->node);
859 kfree(handler); 868 kfree(handler);
860 } 869 }
861 mutex_unlock(&ec->lock); 870 mutex_unlock(&ec->mutex);
862 release_region(ec->data_addr, 1); 871 release_region(ec->data_addr, 1);
863 release_region(ec->command_addr, 1); 872 release_region(ec->command_addr, 1);
864 device->driver_data = NULL; 873 device->driver_data = NULL;