From patchwork Tue Apr 24 23:10:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Prakash, Prashanth" X-Patchwork-Id: 10361195 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 91B77601BE for ; Tue, 24 Apr 2018 23:10:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80FAF28E86 for ; Tue, 24 Apr 2018 23:10:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 75A9C28E8D; Tue, 24 Apr 2018 23:10:29 +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=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 C295128E86 for ; Tue, 24 Apr 2018 23:10:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751265AbeDXXK1 (ORCPT ); Tue, 24 Apr 2018 19:10:27 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45912 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751027AbeDXXK1 (ORCPT ); Tue, 24 Apr 2018 19:10:27 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 8ECF9607E1; Tue, 24 Apr 2018 23:10:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1524611426; bh=xPmHnMPGmCfJIenntOOZI6RkfSbk12JS4KjQcoEJE9g=; h=From:To:Cc:Subject:Date:From; b=T71kUPBmETUivhgNf4s2uzdpENO/J1c54tFp6jpXfwZQC/BYtmiFILkvb60N0FVYQ jD0RDV1MPTBygkMzEEnVZ46RB8W6PvY7eGhu+25JZlT7UML3DtsBmvrTHVW117iGCh 0YqFrBk1+NKHyxmpjFPVrtmpKlcUrpgyOGGgv7FU= Received: from pprakash-lnx.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: pprakash@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id BFC0360264; Tue, 24 Apr 2018 23:10:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1524611426; bh=xPmHnMPGmCfJIenntOOZI6RkfSbk12JS4KjQcoEJE9g=; h=From:To:Cc:Subject:Date:From; b=T71kUPBmETUivhgNf4s2uzdpENO/J1c54tFp6jpXfwZQC/BYtmiFILkvb60N0FVYQ jD0RDV1MPTBygkMzEEnVZ46RB8W6PvY7eGhu+25JZlT7UML3DtsBmvrTHVW117iGCh 0YqFrBk1+NKHyxmpjFPVrtmpKlcUrpgyOGGgv7FU= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org BFC0360264 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=pprakash@codeaurora.org From: Prashanth Prakash To: linux-acpi@vger.kernel.org Cc: rjw@rjwysocki.net, Prashanth Prakash Subject: [PATCH] ACPI/ CPPC: Fix invalid PCC channel status errors Date: Tue, 24 Apr 2018 17:10:02 -0600 Message-Id: <1524611402-20016-1-git-send-email-pprakash@codeaurora.org> X-Mailer: git-send-email 1.9.1 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 Replace the faulty PCC status register polling code with a iopoll.h macro to fix incorrect reporting of PCC check errors("PCC check channel failed"). There were potential codepaths where we could incorrectly return PCC channel status as busy even without checking the PCC status register once or not checking the status register before breaking out of the polling loop. For example, if the thread polling PCC status register was preempted and scheduled back after we have crossed the deadline then we can report that the channel is busy even without checking the status register. Signed-off-by: Prashanth Prakash Cc: Rafael J. Wysocki --- drivers/acpi/cppc_acpi.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 735c74a..4683dbb 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -49,7 +50,7 @@ struct cppc_pcc_data { struct mbox_chan *pcc_channel; void __iomem *pcc_comm_addr; bool pcc_channel_acquired; - ktime_t deadline; + unsigned int deadline_us; unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ @@ -193,42 +194,31 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj, static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) { - int ret = -EIO, status = 0; + int ret, status; struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_ss_data->pcc_comm_addr; - ktime_t next_deadline = ktime_add(ktime_get(), - pcc_ss_data->deadline); if (!pcc_ss_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)) { - /* - * Per spec, prior to boot the PCC space wil be initialized by - * platform and should have set the command completion bit when - * PCC can be used by OSPM - */ - 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; - } - /* - * Reducing the bus traffic in case this loop takes longer than - * a few retries. - */ - udelay(3); - } + /* + * Poll PCC status register every 3us(delay_us) for maximum of + * deadline_us(timeout_us) until PCC command complete bit is set(cond) + */ + ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status, + status & PCC_CMD_COMPLETE_MASK, 3, + pcc_ss_data->deadline_us); - if (likely(!ret)) + if (likely(!ret)) { pcc_ss_data->platform_owns_pcc = false; - else - pr_err("PCC check channel failed for ss: %d. Status=%x\n", - pcc_ss_id, status); + if (chk_err_bit && (status & PCC_ERROR_MASK)) + ret = -EIO; + } + + if (unlikely(ret)) + pr_err("PCC check channel failed for ss: %d. ret=%d\n", + pcc_ss_id, ret); return ret; } @@ -580,7 +570,7 @@ static int register_pcc_channel(int pcc_ss_idx) * So add an arbitrary amount of wait on top of Nominal. */ usecs_lat = NUM_RETRIES * cppc_ss->latency; - pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); + pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency;