From patchwork Tue Aug 16 20:39:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Prakash, Prashanth" X-Patchwork-Id: 9284709 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5A9DD60574 for ; Tue, 16 Aug 2016 20:40:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C55C2863B for ; Tue, 16 Aug 2016 20:40:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 40628286B2; Tue, 16 Aug 2016 20:40:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D5D02863B for ; Tue, 16 Aug 2016 20:40:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753671AbcHPUkH (ORCPT ); Tue, 16 Aug 2016 16:40:07 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:54931 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753569AbcHPUkA (ORCPT ); Tue, 16 Aug 2016 16:40:00 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 9F31D61DA2; Tue, 16 Aug 2016 20:39:59 +0000 (UTC) Received: from pprakash-lnx.qualcomm.com (unknown [129.46.15.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: pprakash@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 9637561D7A; Tue, 16 Aug 2016 20:39:56 +0000 (UTC) From: Prashanth Prakash To: linux-acpi@vger.kernel.org Cc: rjw@rjwysocki.net, alexey.klimov@arm.com, hotran@apm.com, cov@codeaurora.org, Prashanth Prakash Subject: [PATCH V3 7/7] ACPI/CPPC: check for error bit in PCC status field Date: Tue, 16 Aug 2016 14:39:44 -0600 Message-Id: <1471379984-15712-8-git-send-email-pprakash@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1471379984-15712-1-git-send-email-pprakash@codeaurora.org> References: <1471379984-15712-1-git-send-email-pprakash@codeaurora.org> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP PCC status field exposes an error bit(2) to indicate any errors during the execution of last comamnd. This patch checks the error bit before notifying success/failure to the cpufreq driver. Cc: "Rafael J. Wysocki" Signed-off-by: Prashanth Prakash --- drivers/acpi/cppc_acpi.c | 66 +++++++++++++++++++++++------------------------- include/acpi/cppc_acpi.h | 4 ++- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 80c123f..ed58883 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -54,6 +54,7 @@ struct cppc_pcc_data { unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ + bool platform_owns_pcc; /* Ownership of PCC subspace */ unsigned int pcc_write_cnt; /* Running count of PCC write commands */ /* @@ -79,6 +80,7 @@ struct cppc_pcc_data { /* Structure to represent the single PCC channel */ static struct cppc_pcc_data pcc_data = { .pcc_subspace_idx = -1, + .platform_owns_pcc = true, }; /* @@ -181,12 +183,15 @@ static struct kobj_type cppc_ktype = { .default_attrs = cppc_attrs, }; -static int check_pcc_chan(void) +static int check_pcc_chan(bool chk_err_bit) { - int ret = -EIO; + int ret = -EIO, status = 0; struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); + if (!pcc_data.platform_owns_pcc) + return 0; + /* Retry in case the remote processor was too slow to catch up. */ while (!ktime_after(ktime_get(), next_deadline)) { /* @@ -194,8 +199,11 @@ static int check_pcc_chan(void) * platform and should have set the command completion bit when * PCC can be used by OSPM */ - if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { + status = readw_relaxed(&generic_comm_base->status); + if (status & PCC_CMD_COMPLETE_MASK) { ret = 0; + if (chk_err_bit && (status & PCC_ERROR_MASK)) + ret = -EIO; break; } /* @@ -205,6 +213,11 @@ static int check_pcc_chan(void) udelay(3); } + if (likely(!ret)) + pcc_data.platform_owns_pcc = false; + else + pr_err("PCC check channel failed. Status=%x\n", status); + return ret; } @@ -234,7 +247,7 @@ static int send_pcc_cmd(u16 cmd) if (pcc_data.pending_pcc_write_cmd) send_pcc_cmd(CMD_WRITE); - ret = check_pcc_chan(); + ret = check_pcc_chan(false); if (ret) goto end; } else /* CMD_WRITE */ @@ -282,6 +295,8 @@ static int send_pcc_cmd(u16 cmd) /* Flip CMD COMPLETE bit */ writew_relaxed(0, &generic_comm_base->status); + pcc_data.platform_owns_pcc = true; + /* Ring doorbell */ ret = mbox_send_message(pcc_data.pcc_channel, &cmd); if (ret < 0) { @@ -290,23 +305,11 @@ static int send_pcc_cmd(u16 cmd) goto end; } - /* - * For READs we need to ensure the cmd completed to ensure - * the ensuing read()s can proceed. For WRITEs we dont care - * because the actual write()s are done before coming here - * and the next READ or WRITE will check if the channel - * is busy/free at the entry of this call. - * - * If Minimum Request Turnaround Time is non-zero, we need - * to record the completion time of both READ and WRITE - * command for proper handling of MRTT, so we need to check - * for pcc_mrtt in addition to CMD_READ - */ - if (cmd == CMD_READ || pcc_data.pcc_mrtt) { - ret = check_pcc_chan(); - if (pcc_data.pcc_mrtt) - last_cmd_cmpl_time = ktime_get(); - } + /* wait for completion and check for PCC errro bit */ + ret = check_pcc_chan(true); + + if (pcc_data.pcc_mrtt) + last_cmd_cmpl_time = ktime_get(); mbox_client_txdone(pcc_data.pcc_channel, ret); @@ -1059,25 +1062,18 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) */ if (CPC_IN_PCC(desired_reg)) { down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */ - /* - * If there are pending write commands i.e pending_pcc_write_cmd - * is TRUE, then we know OSPM owns the channel as another CPU - * has already checked for command completion bit and updated - * the corresponding CPC registers - */ - if (!pcc_data.pending_pcc_write_cmd) { - ret = check_pcc_chan(); + if (pcc_data.platform_owns_pcc) { + ret = check_pcc_chan(false); if (ret) { up_read(&pcc_data.pcc_lock); return ret; } - /* - * Update the pending_write to make sure a PCC CMD_READ - * will not arrive and steal the channel during the - * transition to write lock - */ - pcc_data.pending_pcc_write_cmd = TRUE; } + /* + * Update the pending_write to make sure a PCC CMD_READ will not + * arrive and steal the channel during the switch to write lock + */ + pcc_data.pending_pcc_write_cmd = true; cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt; cpc_desc->write_cmd_status = 0; } diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index f50b533..0e83cc3 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -24,7 +24,9 @@ #define CPPC_NUM_ENT 21 #define CPPC_REV 2 -#define PCC_CMD_COMPLETE 1 +#define PCC_CMD_COMPLETE_MASK (1 << 0) +#define PCC_ERROR_MASK (1 << 2) + #define MAX_CPC_REG_ENT 19 /* CPPC specific PCC commands. */