Merge branch 'acpi-ec'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 13 Feb 2015 20:38:20 +0000 (21:38 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 13 Feb 2015 20:38:20 +0000 (21:38 +0100)
* acpi-ec:
  Revert "ACPI / EC: Add query flushing support"
  Revert "ACPI / EC: Add GPE reference counting debugging messages"

drivers/acpi/ec.c

index 14d0c89ada2a0ce8010b67f54ca4befa023a5e50..982b67faaaf32c0de360aa35449a699075a6550a 100644 (file)
@@ -31,7 +31,6 @@
 
 /* Uncomment next line to get verbose printout */
 /* #define DEBUG */
-#define DEBUG_REF 0
 #define pr_fmt(fmt) "ACPI : EC: " fmt
 
 #include <linux/kernel.h>
@@ -77,9 +76,7 @@ enum ec_command {
                                         * when trying to clear the EC */
 
 enum {
-       EC_FLAGS_EVENT_ENABLED,         /* Event is enabled */
-       EC_FLAGS_EVENT_PENDING,         /* Event is pending */
-       EC_FLAGS_EVENT_DETECTED,        /* Event is detected */
+       EC_FLAGS_QUERY_PENDING,         /* Query is pending */
        EC_FLAGS_HANDLERS_INSTALLED,    /* Handlers for GPE and
                                         * OpReg are installed */
        EC_FLAGS_STARTED,               /* Driver is started */
@@ -91,13 +88,6 @@ enum {
 #define ACPI_EC_COMMAND_POLL           0x01 /* Available for command byte */
 #define ACPI_EC_COMMAND_COMPLETE       0x02 /* Completed last byte */
 
-#define ec_debug_ref(ec, fmt, ...)                                     \
-       do {                                                            \
-               if (DEBUG_REF)                                          \
-                       pr_debug("%lu: " fmt, ec->reference_count,      \
-                                ## __VA_ARGS__);                       \
-       } while (0)
-
 /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
 static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
 module_param(ec_delay, uint, 0644);
@@ -161,12 +151,6 @@ static bool acpi_ec_flushed(struct acpi_ec *ec)
        return ec->reference_count == 1;
 }
 
-static bool acpi_ec_has_pending_event(struct acpi_ec *ec)
-{
-       return test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) ||
-              test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags);
-}
-
 /* --------------------------------------------------------------------------
  *                           EC Registers
  * -------------------------------------------------------------------------- */
@@ -334,97 +318,34 @@ static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag)
  *                                      the flush operation is not in
  *                                      progress
  * @ec: the EC device
- * @allow_event: whether event should be handled
  *
  * This function must be used before taking a new action that should hold
  * the reference count.  If this function returns false, then the action
  * must be discarded or it will prevent the flush operation from being
  * completed.
- *
- * During flushing, QR_EC command need to pass this check when there is a
- * pending event, so that the reference count held for the pending event
- * can be decreased by the completion of the QR_EC command.
  */
-static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec,
-                                            bool allow_event)
+static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec)
 {
-       if (!acpi_ec_started(ec)) {
-               if (!allow_event || !acpi_ec_has_pending_event(ec))
-                       return false;
-       }
+       if (!acpi_ec_started(ec))
+               return false;
        acpi_ec_submit_request(ec);
        return true;
 }
 
-static void acpi_ec_submit_event(struct acpi_ec *ec)
+static void acpi_ec_submit_query(struct acpi_ec *ec)
 {
-       if (!test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) ||
-           !test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags))
-               return;
-       /* Hold reference for pending event */
-       if (!acpi_ec_submit_flushable_request(ec, true))
-               return;
-       ec_debug_ref(ec, "Increase event\n");
-       if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) {
-               pr_debug("***** Event query started *****\n");
+       if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+               pr_debug("***** Event started *****\n");
                schedule_work(&ec->work);
-               return;
        }
-       acpi_ec_complete_request(ec);
-       ec_debug_ref(ec, "Decrease event\n");
 }
 
-static void acpi_ec_complete_event(struct acpi_ec *ec)
+static void acpi_ec_complete_query(struct acpi_ec *ec)
 {
        if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
-               clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags);
-               pr_debug("***** Event query stopped *****\n");
-               /* Unhold reference for pending event */
-               acpi_ec_complete_request(ec);
-               ec_debug_ref(ec, "Decrease event\n");
-               /* Check if there is another SCI_EVT detected */
-               acpi_ec_submit_event(ec);
-       }
-}
-
-static void acpi_ec_submit_detection(struct acpi_ec *ec)
-{
-       /* Hold reference for query submission */
-       if (!acpi_ec_submit_flushable_request(ec, false))
-               return;
-       ec_debug_ref(ec, "Increase query\n");
-       if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) {
-               pr_debug("***** Event detection blocked *****\n");
-               acpi_ec_submit_event(ec);
-               return;
+               clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+               pr_debug("***** Event stopped *****\n");
        }
-       acpi_ec_complete_request(ec);
-       ec_debug_ref(ec, "Decrease query\n");
-}
-
-static void acpi_ec_complete_detection(struct acpi_ec *ec)
-{
-       if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
-               clear_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags);
-               pr_debug("***** Event detetion unblocked *****\n");
-               /* Unhold reference for query submission */
-               acpi_ec_complete_request(ec);
-               ec_debug_ref(ec, "Decrease query\n");
-       }
-}
-
-static void acpi_ec_enable_event(struct acpi_ec *ec)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ec->lock, flags);
-       set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags);
-       /*
-        * An event may be pending even with SCI_EVT=0, so QR_EC should
-        * always be issued right after started.
-        */
-       acpi_ec_submit_detection(ec);
-       spin_unlock_irqrestore(&ec->lock, flags);
 }
 
 static int ec_transaction_completed(struct acpi_ec *ec)
@@ -468,7 +389,6 @@ static void advance_transaction(struct acpi_ec *ec)
                                t->rdata[t->ri++] = acpi_ec_read_data(ec);
                                if (t->rlen == t->ri) {
                                        t->flags |= ACPI_EC_COMMAND_COMPLETE;
-                                       acpi_ec_complete_event(ec);
                                        if (t->command == ACPI_EC_COMMAND_QUERY)
                                                pr_debug("***** Command(%s) hardware completion *****\n",
                                                         acpi_ec_cmd_string(t->command));
@@ -479,7 +399,6 @@ static void advance_transaction(struct acpi_ec *ec)
                } else if (t->wlen == t->wi &&
                           (status & ACPI_EC_FLAG_IBF) == 0) {
                        t->flags |= ACPI_EC_COMMAND_COMPLETE;
-                       acpi_ec_complete_event(ec);
                        wakeup = true;
                }
                goto out;
@@ -488,17 +407,16 @@ static void advance_transaction(struct acpi_ec *ec)
                    !(status & ACPI_EC_FLAG_SCI) &&
                    (t->command == ACPI_EC_COMMAND_QUERY)) {
                        t->flags |= ACPI_EC_COMMAND_POLL;
-                       acpi_ec_complete_detection(ec);
+                       acpi_ec_complete_query(ec);
                        t->rdata[t->ri++] = 0x00;
                        t->flags |= ACPI_EC_COMMAND_COMPLETE;
-                       acpi_ec_complete_event(ec);
                        pr_debug("***** Command(%s) software completion *****\n",
                                 acpi_ec_cmd_string(t->command));
                        wakeup = true;
                } else if ((status & ACPI_EC_FLAG_IBF) == 0) {
                        acpi_ec_write_cmd(ec, t->command);
                        t->flags |= ACPI_EC_COMMAND_POLL;
-                       acpi_ec_complete_detection(ec);
+                       acpi_ec_complete_query(ec);
                } else
                        goto err;
                goto out;
@@ -519,7 +437,7 @@ err:
        }
 out:
        if (status & ACPI_EC_FLAG_SCI)
-               acpi_ec_submit_detection(ec);
+               acpi_ec_submit_query(ec);
        if (wakeup && in_interrupt())
                wake_up(&ec->wait);
 }
@@ -580,11 +498,10 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
        /* start transaction */
        spin_lock_irqsave(&ec->lock, tmp);
        /* Enable GPE for command processing (IBF=0/OBF=1) */
-       if (!acpi_ec_submit_flushable_request(ec, true)) {
+       if (!acpi_ec_submit_flushable_request(ec)) {
                ret = -EINVAL;
                goto unlock;
        }
-       ec_debug_ref(ec, "Increase command\n");
        /* following two actions should be kept atomic */
        ec->curr = t;
        pr_debug("***** Command(%s) started *****\n",
@@ -600,7 +517,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
        ec->curr = NULL;
        /* Disable GPE for command processing (IBF=0/OBF=1) */
        acpi_ec_complete_request(ec);
-       ec_debug_ref(ec, "Decrease command\n");
 unlock:
        spin_unlock_irqrestore(&ec->lock, tmp);
        return ret;
@@ -762,10 +678,8 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
        if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) {
                pr_debug("+++++ Starting EC +++++\n");
                /* Enable GPE for event processing (SCI_EVT=1) */
-               if (!resuming) {
+               if (!resuming)
                        acpi_ec_submit_request(ec);
-                       ec_debug_ref(ec, "Increase driver\n");
-               }
                pr_info("+++++ EC started +++++\n");
        }
        spin_unlock_irqrestore(&ec->lock, flags);
@@ -794,10 +708,8 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
                wait_event(ec->wait, acpi_ec_stopped(ec));
                spin_lock_irqsave(&ec->lock, flags);
                /* Disable GPE for event processing (SCI_EVT=1) */
-               if (!suspending) {
+               if (!suspending)
                        acpi_ec_complete_request(ec);
-                       ec_debug_ref(ec, "Decrease driver\n");
-               }
                clear_bit(EC_FLAGS_STARTED, &ec->flags);
                clear_bit(EC_FLAGS_STOPPED, &ec->flags);
                pr_info("+++++ EC stopped +++++\n");
@@ -967,9 +879,7 @@ static void acpi_ec_gpe_poller(struct work_struct *work)
 {
        struct acpi_ec *ec = container_of(work, struct acpi_ec, work);
 
-       pr_debug("***** Event poller started *****\n");
        acpi_ec_query(ec, NULL);
-       pr_debug("***** Event poller stopped *****\n");
 }
 
 static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
@@ -1039,6 +949,7 @@ static struct acpi_ec *make_acpi_ec(void)
 
        if (!ec)
                return NULL;
+       ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
        mutex_init(&ec->mutex);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
@@ -1189,7 +1100,7 @@ static int acpi_ec_add(struct acpi_device *device)
        ret = ec_install_handlers(ec);
 
        /* EC is fully operational, allow queries */
-       acpi_ec_enable_event(ec);
+       clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 
        /* Clear stale _Q events if hardware might require that */
        if (EC_FLAGS_CLEAR_ON_RESUME)