From patchwork Wed Jan 14 11:28:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lv Zheng X-Patchwork-Id: 5625721 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D63A4C058D for ; Wed, 14 Jan 2015 03:28:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EAF342018E for ; Wed, 14 Jan 2015 03:28:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CD1A72013D for ; Wed, 14 Jan 2015 03:28:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751204AbbAND24 (ORCPT ); Tue, 13 Jan 2015 22:28:56 -0500 Received: from mga11.intel.com ([192.55.52.93]:34787 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751028AbbAND2z (ORCPT ); Tue, 13 Jan 2015 22:28:55 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 13 Jan 2015 19:28:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,753,1413270000"; d="scan'208";a="669513984" Received: from lvzheng-z530.sh.intel.com ([10.239.159.120]) by orsmga002.jf.intel.com with ESMTP; 13 Jan 2015 19:28:54 -0800 From: Lv Zheng To: "Rafael J. Wysocki" , Len Brown Cc: Lv Zheng , Lv Zheng , linux-acpi@vger.kernel.org Subject: [PATCH 6/6] ACPI/EC: Cleanup QR_EC related code Date: Wed, 14 Jan 2015 19:28:53 +0800 Message-Id: <6ad483d819ef1f2d5516512056968a0df2b2cf77.1421234254.git.lv.zheng@intel.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: References: Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The QR_EC related code pieces have redundants, this patch merges them into acpi_ec_query() which invokes acpi_ec_transaction() where EC mutex and the global lock are already held. After doing so, query handler traversal still need to be locked by EC mutex after invoking acpi_ec_transaction(). Note that EC event handling is sequential. We fetch one event from firmware event queue and process it until 0x00 or error returned. So we don't need to hold mutex for whole acpi_ec_clear() process to determine whether we should continue to drain. And for the same reason, we don't need to hold mutex for the whole procedure from the QR_EC transaction to the query handler traversal. Signed-off-by: Lv Zheng --- drivers/acpi/ec.c | 70 +++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 50 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 89e89b2..c385606 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -120,7 +120,7 @@ struct transaction { u8 flags; }; -static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); +static int acpi_ec_query(struct acpi_ec *ec, u8 *data); struct acpi_ec *boot_ec, *first_ec; EXPORT_SYMBOL(first_ec); @@ -508,7 +508,7 @@ static void acpi_ec_clear(struct acpi_ec *ec) u8 value = 0; for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { - status = acpi_ec_sync_query(ec, &value); + status = acpi_ec_query(ec, &value); if (status || !value) break; } @@ -539,14 +539,11 @@ void acpi_ec_unblock_transactions(void) if (!ec) return; - mutex_lock(&ec->mutex); /* Allow transactions to be carried out again */ clear_bit(EC_FLAGS_BLOCKED, &ec->flags); if (EC_FLAGS_CLEAR_ON_RESUME) acpi_ec_clear(ec); - - mutex_unlock(&ec->mutex); } void acpi_ec_unblock_transactions_early(void) @@ -559,30 +556,6 @@ void acpi_ec_unblock_transactions_early(void) clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); } -static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) -{ - int result; - u8 d; - struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, - .wdata = NULL, .rdata = &d, - .wlen = 0, .rlen = 1}; - - if (!ec || !data) - return -EINVAL; - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ - result = acpi_ec_transaction_unlocked(ec, &t); - if (result) - return result; - if (!d) - return -ENODATA; - *data = d; - return 0; -} - /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ @@ -662,19 +635,30 @@ static void acpi_ec_run(void *cxt) acpi_ec_put_query_handler(handler); } -static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) +static int acpi_ec_query(struct acpi_ec *ec, u8 *data) { u8 value = 0; int result; acpi_status status; struct acpi_ec_query_handler *handler; + struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, + .wdata = NULL, .rdata = &value, + .wlen = 0, .rlen = 1}; - result = acpi_ec_query_unlocked(ec, &value); - if (data) - *data = value; + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ + result = acpi_ec_transaction(ec, &t); if (result) return result; + if (data) + *data = value; + if (!value) + return -ENODATA; + mutex_lock(&ec->mutex); list_for_each_entry(handler, &ec->list, node) { if (value == handler->query_bit) { /* have custom handler for this bit */ @@ -689,26 +673,15 @@ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) break; } } + mutex_unlock(&ec->mutex); return result; } static void acpi_ec_gpe_poller(struct work_struct *work) { - acpi_status status; - u32 glk; struct acpi_ec *ec = container_of(work, struct acpi_ec, work); - mutex_lock(&ec->mutex); - if (ec->global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - goto unlock; - } - acpi_ec_sync_query(ec, NULL); - if (ec->global_lock) - acpi_release_global_lock(glk); -unlock: - mutex_unlock(&ec->mutex); + acpi_ec_query(ec, NULL); } static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, @@ -932,11 +905,8 @@ static int acpi_ec_add(struct acpi_device *device) clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); /* Clear stale _Q events if hardware might require that */ - if (EC_FLAGS_CLEAR_ON_RESUME) { - mutex_lock(&ec->mutex); + if (EC_FLAGS_CLEAR_ON_RESUME) acpi_ec_clear(ec); - mutex_unlock(&ec->mutex); - } return ret; }