aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ec.c59
-rw-r--r--drivers/acpi/internal.h1
2 files changed, 26 insertions, 34 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3c97122eacd7..89e89b21dd54 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -120,6 +120,8 @@ struct transaction {
120 u8 flags; 120 u8 flags;
121}; 121};
122 122
123static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
124
123struct acpi_ec *boot_ec, *first_ec; 125struct acpi_ec *boot_ec, *first_ec;
124EXPORT_SYMBOL(first_ec); 126EXPORT_SYMBOL(first_ec);
125 127
@@ -189,6 +191,22 @@ static const char *acpi_ec_cmd_string(u8 cmd)
189#define acpi_ec_cmd_string(cmd) "UNDEF" 191#define acpi_ec_cmd_string(cmd) "UNDEF"
190#endif 192#endif
191 193
194static void acpi_ec_submit_query(struct acpi_ec *ec)
195{
196 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
197 pr_debug("***** Event started *****\n");
198 schedule_work(&ec->work);
199 }
200}
201
202static void acpi_ec_complete_query(struct acpi_ec *ec)
203{
204 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
205 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
206 pr_debug("***** Event stopped *****\n");
207 }
208}
209
192static int ec_transaction_completed(struct acpi_ec *ec) 210static int ec_transaction_completed(struct acpi_ec *ec)
193{ 211{
194 unsigned long flags; 212 unsigned long flags;
@@ -242,6 +260,7 @@ static void advance_transaction(struct acpi_ec *ec)
242 !(status & ACPI_EC_FLAG_SCI) && 260 !(status & ACPI_EC_FLAG_SCI) &&
243 (t->command == ACPI_EC_COMMAND_QUERY)) { 261 (t->command == ACPI_EC_COMMAND_QUERY)) {
244 t->flags |= ACPI_EC_COMMAND_POLL; 262 t->flags |= ACPI_EC_COMMAND_POLL;
263 acpi_ec_complete_query(ec);
245 t->rdata[t->ri++] = 0x00; 264 t->rdata[t->ri++] = 0x00;
246 t->flags |= ACPI_EC_COMMAND_COMPLETE; 265 t->flags |= ACPI_EC_COMMAND_COMPLETE;
247 pr_debug("***** Command(%s) software completion *****\n", 266 pr_debug("***** Command(%s) software completion *****\n",
@@ -250,6 +269,7 @@ static void advance_transaction(struct acpi_ec *ec)
250 } else if ((status & ACPI_EC_FLAG_IBF) == 0) { 269 } else if ((status & ACPI_EC_FLAG_IBF) == 0) {
251 acpi_ec_write_cmd(ec, t->command); 270 acpi_ec_write_cmd(ec, t->command);
252 t->flags |= ACPI_EC_COMMAND_POLL; 271 t->flags |= ACPI_EC_COMMAND_POLL;
272 acpi_ec_complete_query(ec);
253 } else 273 } else
254 goto err; 274 goto err;
255 goto out; 275 goto out;
@@ -264,6 +284,8 @@ err:
264 ++t->irq_count; 284 ++t->irq_count;
265 } 285 }
266out: 286out:
287 if (status & ACPI_EC_FLAG_SCI)
288 acpi_ec_submit_query(ec);
267 if (wakeup && in_interrupt()) 289 if (wakeup && in_interrupt())
268 wake_up(&ec->wait); 290 wake_up(&ec->wait);
269} 291}
@@ -275,17 +297,6 @@ static void start_transaction(struct acpi_ec *ec)
275 advance_transaction(ec); 297 advance_transaction(ec);
276} 298}
277 299
278static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
279
280static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
281{
282 if (state & ACPI_EC_FLAG_SCI) {
283 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
284 return acpi_ec_sync_query(ec, NULL);
285 }
286 return 0;
287}
288
289static int ec_poll(struct acpi_ec *ec) 300static int ec_poll(struct acpi_ec *ec)
290{ 301{
291 unsigned long flags; 302 unsigned long flags;
@@ -333,10 +344,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
333 pr_debug("***** Command(%s) started *****\n", 344 pr_debug("***** Command(%s) started *****\n",
334 acpi_ec_cmd_string(t->command)); 345 acpi_ec_cmd_string(t->command));
335 start_transaction(ec); 346 start_transaction(ec);
336 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
337 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
338 pr_debug("***** Event stopped *****\n");
339 }
340 spin_unlock_irqrestore(&ec->lock, tmp); 347 spin_unlock_irqrestore(&ec->lock, tmp);
341 ret = ec_poll(ec); 348 ret = ec_poll(ec);
342 spin_lock_irqsave(&ec->lock, tmp); 349 spin_lock_irqsave(&ec->lock, tmp);
@@ -376,8 +383,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
376 383
377 status = acpi_ec_transaction_unlocked(ec, t); 384 status = acpi_ec_transaction_unlocked(ec, t);
378 385
379 /* check if we received SCI during transaction */
380 ec_check_sci_sync(ec, acpi_ec_read_status(ec));
381 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { 386 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
382 msleep(1); 387 msleep(1);
383 /* It is safe to enable the GPE outside of the transaction. */ 388 /* It is safe to enable the GPE outside of the transaction. */
@@ -687,14 +692,12 @@ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
687 return result; 692 return result;
688} 693}
689 694
690static void acpi_ec_gpe_query(void *ec_cxt) 695static void acpi_ec_gpe_poller(struct work_struct *work)
691{ 696{
692 struct acpi_ec *ec = ec_cxt;
693 acpi_status status; 697 acpi_status status;
694 u32 glk; 698 u32 glk;
699 struct acpi_ec *ec = container_of(work, struct acpi_ec, work);
695 700
696 if (!ec)
697 return;
698 mutex_lock(&ec->mutex); 701 mutex_lock(&ec->mutex);
699 if (ec->global_lock) { 702 if (ec->global_lock) {
700 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 703 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
@@ -708,18 +711,6 @@ unlock:
708 mutex_unlock(&ec->mutex); 711 mutex_unlock(&ec->mutex);
709} 712}
710 713
711static int ec_check_sci(struct acpi_ec *ec, u8 state)
712{
713 if (state & ACPI_EC_FLAG_SCI) {
714 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
715 pr_debug("***** Event started *****\n");
716 return acpi_os_execute(OSL_NOTIFY_HANDLER,
717 acpi_ec_gpe_query, ec);
718 }
719 }
720 return 0;
721}
722
723static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, 714static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
724 u32 gpe_number, void *data) 715 u32 gpe_number, void *data)
725{ 716{
@@ -729,7 +720,6 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
729 spin_lock_irqsave(&ec->lock, flags); 720 spin_lock_irqsave(&ec->lock, flags);
730 advance_transaction(ec); 721 advance_transaction(ec);
731 spin_unlock_irqrestore(&ec->lock, flags); 722 spin_unlock_irqrestore(&ec->lock, flags);
732 ec_check_sci(ec, acpi_ec_read_status(ec));
733 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; 723 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
734} 724}
735 725
@@ -793,6 +783,7 @@ static struct acpi_ec *make_acpi_ec(void)
793 init_waitqueue_head(&ec->wait); 783 init_waitqueue_head(&ec->wait);
794 INIT_LIST_HEAD(&ec->list); 784 INIT_LIST_HEAD(&ec->list);
795 spin_lock_init(&ec->lock); 785 spin_lock_init(&ec->lock);
786 INIT_WORK(&ec->work, acpi_ec_gpe_poller);
796 return ec; 787 return ec;
797} 788}
798 789
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 163e82f536fa..dc420787ffcd 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -127,6 +127,7 @@ struct acpi_ec {
127 struct list_head list; 127 struct list_head list;
128 struct transaction *curr; 128 struct transaction *curr;
129 spinlock_t lock; 129 spinlock_t lock;
130 struct work_struct work;
130}; 131};
131 132
132extern struct acpi_ec *first_ec; 133extern struct acpi_ec *first_ec;