From patchwork Wed Mar 11 23:13:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433061 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C7D4714E5 for ; Wed, 11 Mar 2020 23:14:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6DDF520752 for ; Wed, 11 Mar 2020 23:14:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="LPNhui0z" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731448AbgCKXOO (ORCPT ); Wed, 11 Mar 2020 19:14:14 -0400 Received: from mail-pj1-f66.google.com ([209.85.216.66]:53934 "EHLO mail-pj1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731338AbgCKXON (ORCPT ); Wed, 11 Mar 2020 19:14:13 -0400 Received: by mail-pj1-f66.google.com with SMTP id l36so1706777pjb.3 for ; Wed, 11 Mar 2020 16:14:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PV3+rsqW3G7K5hlkhIrJBc69bnftS3pQw9KwpyvMaqE=; b=LPNhui0z7fgOHv5VmaKW8Q3oPQibJt17I4z7uvFu3ortliSvgBwYPXf2hbqMvgwA3r kUBL7zN9EcbyRr8IPmVce235Q1MlVSTl1n9ioc5ZK8Y+2ZpL8tgbLHalS3apy8Sh6Qi/ xdGnQFWD7k10rP0OG7mb5il/kktLXrrmT8fdo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PV3+rsqW3G7K5hlkhIrJBc69bnftS3pQw9KwpyvMaqE=; b=CWZzrF2fmFuWv5wddER8eZUhw9PGLlu6jP2fE9J+LHFvJrwRpGV8/2RLtWQsQ1+G3U ld8UsweGquedrOKMzBA1hWbLrUPQ3QcL+4yXB0EN+X7nzBzLl8ztx0PzPkJzPjlRrFYb hPiBpf4bBOeCDXZGkg7MMPcUsMAsdWSGZZUhXr+JP+vOPuUs7wC0wx5dmqSjjagGup+p NSPi9hedIJ9NRji1otgTWwRDO9xvAhcrH1ewJIPPlepfXRAG3oHPYjrM8IeuWgz7hYK9 McZLOWM+7fQ5k8UNKZBUzEz5/WfNCVD20WI1K+uc7DjwDrLYCWM+f7oXe/heBocKAcDi AXPw== X-Gm-Message-State: ANhLgQ0qxBI9sRp/sFKlk+nfjR9jSTl9+BV4JA/kpaFrha9pIYlM0hN1 Zxj22f2LfCw56f3hV28kVapsdw== X-Google-Smtp-Source: ADFU+vu3sQ368RVO6S1ZZTgdPc6p7c3SQuo0BBPWkU8Q2oKfhElVFwRi5HIEq6h1lYkvmms8xq7JBg== X-Received: by 2002:a17:90b:19ca:: with SMTP id nm10mr1029173pjb.157.1583968452725; Wed, 11 Mar 2020 16:14:12 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:12 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 01/10] drivers: qcom: rpmh-rsc: Clean code reading/writing regs/cmds Date: Wed, 11 Mar 2020 16:13:39 -0700 Message-Id: <20200311161104.RFT.v2.1.I1b754137e8089e46cf33fc2ea270734ec3847ec4@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This patch makes two changes, both of which should be no-ops: 1. Make read_tcs_reg() / read_tcs_cmd() symmetric to write_tcs_reg() / write_tcs_cmd(). 2. Change the order of operations in the above functions to make it more obvious to me what the math is doing. Specifically first you want to find the right TCS, then the right register, and then multiply by the command ID if necessary. Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah --- Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index b71822131f59..b87b79f0347d 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -61,28 +61,33 @@ #define CMD_STATUS_ISSUED BIT(8) #define CMD_STATUS_COMPL BIT(16) -static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +static u32 read_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) { - return readl_relaxed(drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id + + return readl_relaxed(drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg + RSC_DRV_CMD_OFFSET * cmd_id); } +static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id) +{ + return readl_relaxed(drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg); +} + static void write_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id, u32 data) { - writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id + + writel_relaxed(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg + RSC_DRV_CMD_OFFSET * cmd_id); } static void write_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, u32 data) { - writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id); + writel_relaxed(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg); } static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, u32 data) { - writel(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id); + writel(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg); for (;;) { if (data == readl(drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id)) @@ -94,7 +99,7 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) { return !test_bit(tcs_id, drv->tcs_in_use) && - read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id, 0); + read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id); } static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type) @@ -212,7 +217,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p) const struct tcs_request *req; struct tcs_cmd *cmd; - irq_status = read_tcs_reg(drv, RSC_DRV_IRQ_STATUS, 0, 0); + irq_status = read_tcs_reg(drv, RSC_DRV_IRQ_STATUS, 0); for_each_set_bit(i, &irq_status, BITS_PER_LONG) { req = get_req_from_tcs(drv, i); @@ -226,7 +231,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p) u32 sts; cmd = &req->cmds[j]; - sts = read_tcs_reg(drv, RSC_DRV_CMD_STATUS, i, j); + sts = read_tcs_cmd(drv, RSC_DRV_CMD_STATUS, i, j); if (!(sts & CMD_STATUS_ISSUED) || ((req->wait_for_compl || cmd->wait) && !(sts & CMD_STATUS_COMPL))) { @@ -265,7 +270,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0; cmd_msgid |= CMD_MSGID_WRITE; - cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0); + cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id); for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) { cmd = &msg->cmds[i]; @@ -281,7 +286,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, } write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete); - cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0); + cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id); write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable); } @@ -294,7 +299,7 @@ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id) * While clearing ensure that the AMC mode trigger is cleared * and then the mode enable is cleared. */ - enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0); + enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id); enable &= ~TCS_AMC_MODE_TRIGGER; write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); enable &= ~TCS_AMC_MODE_ENABLE; @@ -319,10 +324,10 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, if (tcs_is_free(drv, tcs_id)) continue; - curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0); + curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id); for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) { - addr = read_tcs_reg(drv, RSC_DRV_CMD_ADDR, tcs_id, j); + addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j); for (k = 0; k < msg->num_cmds; k++) { if (addr == msg->cmds[k].addr) return -EBUSY; From patchwork Wed Mar 11 23:13:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433057 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F0E0513B1 for ; Wed, 11 Mar 2020 23:14:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 958DC20752 for ; Wed, 11 Mar 2020 23:14:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ZXDsY4AA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731481AbgCKXOQ (ORCPT ); Wed, 11 Mar 2020 19:14:16 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:41406 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731456AbgCKXOP (ORCPT ); Wed, 11 Mar 2020 19:14:15 -0400 Received: by mail-pl1-f194.google.com with SMTP id t14so1816928plr.8 for ; Wed, 11 Mar 2020 16:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=M5YJLKJcxwEPId9+i+O/beL+j/9lm96wUEn1DNYymac=; b=ZXDsY4AAGMrW8ORBp2CoIvZNFzwrJQ0+R9NPUeFJwxmDBONJr4Nian5wotzxXzjFO2 vuXyKTotxNlzQqS8XQjkp5wlUQ15yNgJkXKuyumC7KlRrPMed3ayY/XCjLcDiRS5R1F4 G19dsHJAEUZedOT0ZLQmA+7u6OVHR0xQuBrVU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=M5YJLKJcxwEPId9+i+O/beL+j/9lm96wUEn1DNYymac=; b=Z/HBeZI6OVg6Mb9QSImSJtDxIYURLvvRCOgA/TmobZAIl7bj0I3PallrQb2gHKTI5E a1e1OKpoKi3Eh4haHHA3WWIYOaqgzC9gvDRLiX0nrQ6on4BnFcp6eVL4BpeYbYvYyo9J dRp1/uTXzZli+aJRaX6FSNfARr4fJlADShV9PT21BIGbV9cdwJjcmxE8b4J4gScw2V1W ZHKZ3WyxU3Ygli6BDQgd8aOkkrALWC1di9Luleyi7gupnmZsczN01D+mF33zg3OzU5hJ Mc7yilELKjB4ZFUCA6Oqw0xMFQHyG61m9WQYv4wRcI429VKuzwFoGN2vr6PeLHupN6Ks D7EQ== X-Gm-Message-State: ANhLgQ3bjrLIkyFh4S5wwCOygTCItHtexh9TBk5LVMY5Z/tIgSHY6tZi rXvAp0voRCh363u9hvmdreG9ng== X-Google-Smtp-Source: ADFU+vt15BF/iHu6Jo59dmAQcWMKOAgo8Zm7TY1fXqWSkm1ezuyQB2gDubvfPczCT8mAEGbBp7Zh5g== X-Received: by 2002:a17:90a:357:: with SMTP id 23mr1091055pjf.192.1583968454151; Wed, 11 Mar 2020 16:14:14 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:13 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 02/10] drivers: qcom: rpmh-rsc: Document the register layout better Date: Wed, 11 Mar 2020 16:13:40 -0700 Message-Id: <20200311161104.RFT.v2.2.Iaddc29b72772e6ea381238a0ee85b82d3903e5f2@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Perhaps it's just me, it took a really long time to understand what the register layout of rpmh-rsc was just from the #defines. Let's add a bunch of comments describing which blocks are part of other blocks. Signed-off-by: Douglas Anderson --- Changes in v2: - Now prose in comments instead of struct definitions. - Pretty ASCII art from Stephen. drivers/soc/qcom/rpmh-rsc.c | 78 ++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index b87b79f0347d..02c8e0ffbbe4 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -37,14 +37,24 @@ #define DRV_NCPT_MASK 0x1F #define DRV_NCPT_SHIFT 27 -/* Register offsets */ +/* + * Register offsets within a TCS. + * + * TCSs are stored one after another; multiply tcs_id by RSC_DRV_TCS_OFFSET + * to find a given TCS and add one of the below to find a register. + */ #define RSC_DRV_IRQ_ENABLE 0x00 #define RSC_DRV_IRQ_STATUS 0x04 -#define RSC_DRV_IRQ_CLEAR 0x08 -#define RSC_DRV_CMD_WAIT_FOR_CMPL 0x10 +#define RSC_DRV_IRQ_CLEAR 0x08 /* w/o; write 1 to clear */ +#define RSC_DRV_CMD_WAIT_FOR_CMPL 0x10 /* 1 bit per command */ #define RSC_DRV_CONTROL 0x14 -#define RSC_DRV_STATUS 0x18 -#define RSC_DRV_CMD_ENABLE 0x1C +#define RSC_DRV_STATUS 0x18 /* zero if tcs is busy */ +#define RSC_DRV_CMD_ENABLE 0x1C /* 1 bit per command */ + +/* + * Commands (up to 16) start at 0x30 in a TCS; multiply command index + * by RSC_DRV_CMD_OFFSET and add one of the below to find a register. + */ #define RSC_DRV_CMD_MSGID 0x30 #define RSC_DRV_CMD_ADDR 0x34 #define RSC_DRV_CMD_DATA 0x38 @@ -61,6 +71,64 @@ #define CMD_STATUS_ISSUED BIT(8) #define CMD_STATUS_COMPL BIT(16) +/* + * Here's a high level overview of how all the registers in RPMH work + * together: + * + * - The main rpmh-rsc address is the base of a register space that can + * be used to find overall configuration of the hardware + * (DRV_PRNT_CHLD_CONFIG). Also found within the rpmh-rsc register + * space are all the TCS blocks. The offset of the TCS blocks is + * specified in the device tree by "qcom,tcs-offset" and used to + * compute tcs_base. + * - TCS blocks come one after another. Type, count, and order are + * specified by the device tree as "qcom,tcs-config". + * - Each TCS block has some registers, then space for up to 16 commands. + * Note that though address space is reserved for 16 commands, fewer + * might be present. See ncpt (num cmds per TCS). + * - The first TCS block is special in that it has registers to control + * interrupts (RSC_DRV_IRQ_XXX). Space for these registers is reserved + * in all TCS blocks to make the math easier, but only the first one + * matters. + * + * Here's a picture: + * + * +---------------------------------------------------+ + * |RSC | + * | ctrl | + * | | + * | Drvs: | + * | +-----------------------------------------------+ | + * | |DRV0 | | + * | | ctrl | | + * | | | | + * | | TCSs: | | + * | | +------------------------------------------+ | | + * | | |TCS0 | | | | | | | | | | | | | | | + * | | | IRQ | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | ctrl | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | +------------------------------------------+ | | + * | | |TCS1 | | | | | | | | | | | | | | | + * | | | | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | ctrl | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | +------------------------------------------+ | | + * | | |TCS2 | | | | | | | | | | | | | | | + * | | | | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | ctrl | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | ...... | | + * | +-----------------------------------------------+ | + * | +-----------------------------------------------+ | + * | |DRV1 | | + * | | (same as DRV0) | | + * | +-----------------------------------------------+ | + * | ...... | + * +---------------------------------------------------+ + */ + + static u32 read_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) { return readl_relaxed(drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg + From patchwork Wed Mar 11 23:13:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433043 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6323313B1 for ; Wed, 11 Mar 2020 23:14:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 07B4120751 for ; Wed, 11 Mar 2020 23:14:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="jSndEF9A" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731483AbgCKXOR (ORCPT ); Wed, 11 Mar 2020 19:14:17 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:41013 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731446AbgCKXOQ (ORCPT ); Wed, 11 Mar 2020 19:14:16 -0400 Received: by mail-pf1-f194.google.com with SMTP id z65so2206152pfz.8 for ; Wed, 11 Mar 2020 16:14:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pz+R6/bajFiKzuDg21R/p73E7Dnb/exoWqB7bjIzotw=; b=jSndEF9AasufRC8A5cwEtAu5taaitC5tcTcTjAKzjbTOxXxNypnb1Rg3xMWdy37RS0 8iiZD5NEjCF03LnN64o4uY/Y71JVnxTuCWxxjs2hYDK3QT1w00LSO6HlBi7YRBd6eAvj Glo0pEBnllScOhYw0fKkSCvSp1JVRzHvZx5tQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pz+R6/bajFiKzuDg21R/p73E7Dnb/exoWqB7bjIzotw=; b=Udo4HKfgd7/PijAo9A2vMwBtKuKWuC0Rd2Hmxn1k7g3gxpmo1oxjx/BWEW10PiDmMb QnNDfHW4MF/F+F9hwQSSw9abmwO/br+cWWsdBx3gWpeqfaw/gmrls9zro50oK7s+Ifsm hcbyVwzObpFU3AjgqNX+nKuPqisY8NkEivR9F/hkH/hqqr5CVGIICSsSGLmh6/IYzMLk k3q2neDZPYwCg3tJthX1DNTRkrjtNUHeU27ROGyzaIu6yUTWkB/B4MHzD2LNLSIPh3NS pINrKhVs4PcSkeXlT1yvtDHTls0GfZn168hiivAJBgZn+u4bJO8g5a4iKDyB+bFc+4J4 r9lw== X-Gm-Message-State: ANhLgQ3uXg0Xr2lL6N5I9y60IMk0E2Nl0r2YZfD8EVZ5fn/stnSlALbz qygaH0KvQ+6uVW8kHNqTb8xlzA== X-Google-Smtp-Source: ADFU+vu3hctvPwyWe4hOmGeRglVH3FlBt2UmhtU0gyCwNzZZICUwyFSB2Itc1xN7oobQquYNQgeR4Q== X-Received: by 2002:aa7:8711:: with SMTP id b17mr2845654pfo.315.1583968455549; Wed, 11 Mar 2020 16:14:15 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:15 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 03/10] drivers: qcom: rpmh-rsc: Fold tcs_ctrl_write() into its single caller Date: Wed, 11 Mar 2020 16:13:41 -0700 Message-Id: <20200311161104.RFT.v2.3.Ie88ce5ccfc0c6055903ccca5286ae28ed3b85ed3@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org I was trying to write documentation for the functions in rpmh-rsc and I got to tcs_ctrl_write(). The documentation for the function would have been: "This is the core of rpmh_rsc_write_ctrl_data(); all the caller does is error-check and then call this". Having the error checks in a separate function doesn't help for anything since: - There are no other callers that need to bypass the error checks. - It's less documenting. When I read tcs_ctrl_write() I kept wondering if I need to handle cases other than ACTIVE_ONLY or cases with more commands than could fit in a TCS. This is obvious when the error checks and code are together. - The function just isn't that long, so there's no problem understanding the combined function. Things were even more confusing because the two functions names didn't make obvious (at least to me) their relationship. Simplify by folding one function into the other. Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah --- Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 39 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 02c8e0ffbbe4..799847b08038 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -550,27 +550,6 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, return 0; } -static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg) -{ - struct tcs_group *tcs; - int tcs_id = 0, cmd_id = 0; - unsigned long flags; - int ret; - - tcs = get_tcs_for_msg(drv, msg); - if (IS_ERR(tcs)) - return PTR_ERR(tcs); - - spin_lock_irqsave(&tcs->lock, flags); - /* find the TCS id and the command in the TCS to write to */ - ret = find_slots(tcs, msg, &tcs_id, &cmd_id); - if (!ret) - __tcs_buffer_write(drv, tcs_id, cmd_id, msg); - spin_unlock_irqrestore(&tcs->lock, flags); - - return ret; -} - /** * rpmh_rsc_write_ctrl_data: Write request to the controller * @@ -581,6 +560,11 @@ static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg) */ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) { + struct tcs_group *tcs; + int tcs_id = 0, cmd_id = 0; + unsigned long flags; + int ret; + if (!msg || !msg->cmds || !msg->num_cmds || msg->num_cmds > MAX_RPMH_PAYLOAD) { pr_err("Payload error\n"); @@ -591,7 +575,18 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) if (msg->state == RPMH_ACTIVE_ONLY_STATE) return -EINVAL; - return tcs_ctrl_write(drv, msg); + tcs = get_tcs_for_msg(drv, msg); + if (IS_ERR(tcs)) + return PTR_ERR(tcs); + + spin_lock_irqsave(&tcs->lock, flags); + /* find the TCS id and the command in the TCS to write to */ + ret = find_slots(tcs, msg, &tcs_id, &cmd_id); + if (!ret) + __tcs_buffer_write(drv, tcs_id, cmd_id, msg); + spin_unlock_irqrestore(&tcs->lock, flags); + + return ret; } static int rpmh_probe_tcs_config(struct platform_device *pdev, From patchwork Wed Mar 11 23:13:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433045 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C602314B4 for ; Wed, 11 Mar 2020 23:14:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 74C642074E for ; Wed, 11 Mar 2020 23:14:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="LguTebpO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731491AbgCKXOT (ORCPT ); Wed, 11 Mar 2020 19:14:19 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:34600 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731488AbgCKXOS (ORCPT ); Wed, 11 Mar 2020 19:14:18 -0400 Received: by mail-pg1-f196.google.com with SMTP id t3so2032135pgn.1 for ; Wed, 11 Mar 2020 16:14:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UWBjFQXkSBNRsjQ6miPhHt5bde1mFApW8A9hXCEPvFI=; b=LguTebpOgMY1OHVxiVcNye4AXrA527VpjMXtXNfeo1dOVyA4+iLfLEzY8FsMnsBAsc E6BeIn78I+gQO162VXEyatPZ5hSVUz1sCr0Q9juzHnJPv97xSLNAMDMGN/fK/sWmkyW1 hKK+VbVYaIOIcGVe1tHh1Avo40fMjblj7/SZc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UWBjFQXkSBNRsjQ6miPhHt5bde1mFApW8A9hXCEPvFI=; b=P4502aAdeqb5c70yWXbw7MYV+vylYtWyZETi68ts0Y7etuRjOWefADk5tE6xjYj6X6 ajUCAk9oF2ChHEpKJW5nSvKfCIxJ3fqM0E5mVwGjcsaJ4+pZHFxkK/g6ceU4Uno+XIg8 24vHfKTCIO68B5X/8C+Wlw7AhfNutVFNb1fCBzTasle0rp56ArnlGmsu2w9o408sGbH5 2gXscKoo8q1O7SeWA+DeZBEg5obNd5tFbo2efBTW991k0HXR2nUEeIuKRBaKdaGYqnjg m9Ve8tA3igjLBBD9JTRLirpI7GoVBZj12nAx8W1xPXTlIKB1eFaDDDwdZVvevT2WUh9k Q6uA== X-Gm-Message-State: ANhLgQ3LW+ET478II+tMW3T6I0UBAZ69VoY+gtcRRGXTotdbvl9uJunU CKMp3XdyiSNJs1JBcNZveqATqQ== X-Google-Smtp-Source: ADFU+vv6X0UnzkEj2YlvXDq+eSZJYrQxXPKGUCKJLjK8g3CuKDN5rYk+n8oeLbdWPp3hb9WK391FZg== X-Received: by 2002:a65:43cb:: with SMTP id n11mr4796908pgp.65.1583968456977; Wed, 11 Mar 2020 16:14:16 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:16 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 04/10] drivers: qcom: rpmh-rsc: Remove get_tcs_of_type() abstraction Date: Wed, 11 Mar 2020 16:13:42 -0700 Message-Id: <20200311161104.RFT.v2.4.Ia348ade7c6ed1d0d952ff2245bc854e5834c8d9a@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The get_tcs_of_type() function doesn't provide any value. It's not conceptually difficult to access a value in an array, even if that value is in a structure and we want a pointer to the value. Having the function in there makes me feel like it's doing something fancier like looping or searching. Remove it. Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah --- Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 799847b08038..c9f29cbd5ee5 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -170,17 +170,10 @@ static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id); } -static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type) -{ - return &drv->tcs[type]; -} - static int tcs_invalidate(struct rsc_drv *drv, int type) { int m; - struct tcs_group *tcs; - - tcs = get_tcs_of_type(drv, type); + struct tcs_group *tcs = &drv->tcs[type]; spin_lock(&tcs->lock); if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) { @@ -246,9 +239,9 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, * dedicated AMC, and therefore would invalidate the sleep and wake * TCSes before making an active state request. */ - tcs = get_tcs_of_type(drv, type); + tcs = &drv->tcs[type]; if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) { - tcs = get_tcs_of_type(drv, WAKE_TCS); + tcs = &drv->tcs[WAKE_TCS]; if (tcs->num_tcs) { ret = rpmh_rsc_invalidate(drv); if (ret) From patchwork Wed Mar 11 23:13:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433055 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E0D013B1 for ; Wed, 11 Mar 2020 23:14:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0674420751 for ; Wed, 11 Mar 2020 23:14:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="OuQIIP/D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731502AbgCKXOo (ORCPT ); Wed, 11 Mar 2020 19:14:44 -0400 Received: from mail-pg1-f174.google.com ([209.85.215.174]:44881 "EHLO mail-pg1-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731488AbgCKXOV (ORCPT ); Wed, 11 Mar 2020 19:14:21 -0400 Received: by mail-pg1-f174.google.com with SMTP id 37so2012697pgm.11 for ; Wed, 11 Mar 2020 16:14:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NaNAdzL2XEfcvjYu5mo/uVEx+JASRSRpLwar1oYdQ5M=; b=OuQIIP/Dm1fv4rd0kw0c5G9svnZZ1Th9xVsAoLnt/knYbLg8d12TIZTSIU6bvGTMX1 Y7dkbg+ujvEFSItl8RiRCbcZjuv0OYvM4vYogod7Uq9kGIk6cLWmB/UZJRgO5kbPQQnw QPQdb/XMNYRa/slyYDP1xedZJE8v/RRwZiMYM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NaNAdzL2XEfcvjYu5mo/uVEx+JASRSRpLwar1oYdQ5M=; b=LByqz8f/C3q1ib0f/3k+y+S3263VpP3xU5pTqlG43TD484MqNFx4wkZPnksxwxKzYg gk7Gha307FjgY5BY7dSmYTNZWAgzjTklWc8yDiUImKfm+4dCwdvv8dXmnc3J7lfuuUrS 8sgkbuos3P7sim02/jzhKCjQgulI19hYj6/GZ/cT4qDBPIPULCWSXOcpnt6XXxCH2ntv CIK2wHL7Ta4zVNAR3Y3/gR1qgkWZAOLP2II9zdO/3SRnsMLgpU6CFsKsnggeH3IiWZQp Ci0wZAbBwOiYw1CTVj3wcbvDB3OXTV934LXFfACXngPGDn3dgO2oTqEB2tiPDKUxuCbC t4Og== X-Gm-Message-State: ANhLgQ1q6UeAw5Sfs/XUTq1bF5oC6vC5JB5+fLzy/rwMQAGGa8Y2+Kcd bV7xvZQCACUWa8w53Rj2Zf7lvA== X-Google-Smtp-Source: ADFU+vuAZaEjcG8pGAg04HxVBKzMuundPylxaarEWc/ti/6gjDutaCHrApU/XeNcmVrg0CxEvQt3gA== X-Received: by 2002:a63:b949:: with SMTP id v9mr4801566pgo.336.1583968458318; Wed, 11 Mar 2020 16:14:18 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:17 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 05/10] drivers: qcom: rpmh-rsc: A lot of comments Date: Wed, 11 Mar 2020 16:13:43 -0700 Message-Id: <20200311161104.RFT.v2.5.I52653eb85d7dc8981ee0dafcd0b6cc0f273e9425@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org I've been pouring through the rpmh-rsc code and trying to understand it. Document everything to the best of my ability. All documentation here is strictly from code analysis--no actual knowledge of the hardware was used. If something is wrong in here I either misunderstood the code, had a typo, or the code has a bug in it leading to my incorrect understanding. In a few places here I have documented things that don't make tons of sense. A future patch will try to address this. While this means I'm adding comments / todos and then later fixing them in the series, it seemed more urgent to get things documented first so that people could understand the later patches. This should be a no-op. It's just comment changes. Signed-off-by: Douglas Anderson --- Changes in v2: - More clear that active-only xfers can happen on wake TCS sometimes. - Document locks for updating "tcs_in_use" more. - Document tcs_is_free() without drv->lock OK for tcs_invalidate(). - Document bug of tcs_write() not handling -EAGAIN. - Document get_tcs_for_msg() => -EAGAIN only for ACTIVE_ONLY. - Reword tcs_write() doc a bit. - Document two get_tcs_for_msg() issues if zero-active TCS. - Document that rpmh_rsc_send_data() can be an implicit invalidate. - Fixed documentation of "tcs" param in find_slots(). drivers/soc/qcom/rpmh-internal.h | 52 +++--- drivers/soc/qcom/rpmh-rsc.c | 264 +++++++++++++++++++++++++++++-- 2 files changed, 281 insertions(+), 35 deletions(-) diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index 6eec32b97f83..b756d3036e96 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -22,16 +22,25 @@ struct rsc_drv; * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests * to the controller * - * @drv: the controller - * @type: type of the TCS in this group - active, sleep, wake - * @mask: mask of the TCSes relative to all the TCSes in the RSC - * @offset: start of the TCS group relative to the TCSes in the RSC - * @num_tcs: number of TCSes in this type - * @ncpt: number of commands in each TCS - * @lock: lock for synchronizing this TCS writes - * @req: requests that are sent from the TCS - * @cmd_cache: flattened cache of cmds in sleep/wake TCS - * @slots: indicates which of @cmd_addr are occupied + * @drv: The controller. + * @type: Type of the TCS in this group - active, sleep, wake. + * @mask: Mask of the TCSes relative to all the TCSes in the RSC. + * @offset: Start of the TCS group relative to the TCSes in the RSC. + * @num_tcs: Number of TCSes in this type. + * @ncpt: Number of commands in each TCS. + * @lock: Lock for synchronizing this TCS writes. + * @req: Requests that are sent from the TCS; only used for ACTIVE_ONLY + * transfers (could be on a wake/sleep TCS if we are borrowing for + * an ACTIVE_ONLY transfer). + * Start: grab drv->lock, set req, set tcs_in_use, drop drv->lock, + * trigger + * End: get irq, access req, + * grab drv->lock, clear tcs_in_use, drop drv->lock + * @cmd_cache: Flattened cache of cmds in sleep/wake TCS; num_tcs * ncpt big. + * @slots: Indicates which of @cmd_addr are occupied; only used for + * SLEEP / WAKE TCSs. Things are tightly packed in the + * case that (ncpt < MAX_CMDS_PER_TCS). That is if ncpt = 2 and + * MAX_CMDS_PER_TCS = 16 then bit[2] = the first bit in 2nd TCS. */ struct tcs_group { struct rsc_drv *drv; @@ -84,14 +93,21 @@ struct rpmh_ctrlr { * struct rsc_drv: the Direct Resource Voter (DRV) of the * Resource State Coordinator controller (RSC) * - * @name: controller identifier - * @tcs_base: start address of the TCS registers in this controller - * @id: instance id in the controller (Direct Resource Voter) - * @num_tcs: number of TCSes in this DRV - * @tcs: TCS groups - * @tcs_in_use: s/w state of the TCS - * @lock: synchronize state of the controller - * @client: handle to the DRV's client. + * @name: Controller identifier. + * @tcs_base: Start address of the TCS registers in this controller. + * @id: Instance id in the controller (Direct Resource Voter). + * @num_tcs: Number of TCSes in this DRV. + * @tcs: TCS groups. + * @tcs_in_use: s/w state of the TCS; only set for ACTIVE_ONLY transfers, but + * might show a sleep/wake TCS in use if it was borrowed for an + * active_only transfer. You must hold both the lock in this + * struct and the tcs_lock for the TCS in order to mark a TCS as + * in-use, but you only need the lock in this structure to mark + * one freed. + * @lock: Synchronize state of the controller. If you will be grabbing + * this lock and a tcs_lock at the same time, grab the tcs_lock + * first so we always have a consistent lock ordering. + * @client: Handle to the DRV's client. */ struct rsc_drv { const char *name; diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index c9f29cbd5ee5..9d2669cbd994 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -164,12 +164,38 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, } } +/** + * tcs_is_free() - Return if a TCS is totally free. + * @drv: The RSC controller. + * @tcs_id: The global ID of this TCS. + * + * Returns true if nobody has claimed this TCS (by setting tcs_in_use). + * If the TCS looks free, checks that the hardware agrees. + * + * Must be called with the drv->lock held or the tcs_lock for the TCS being + * tested. If only the tcs_lock is held then it is possible that this + * function will return that a tcs is still busy when it has been recently + * been freed but it will never return free when a TCS is actually in use. + * + * Return: true if the given TCS is free. + */ static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) { return !test_bit(tcs_id, drv->tcs_in_use) && read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id); } +/** + * tcs_invalidate() - Invalidate all TCSs of the given type (sleep or wake). + * @drv: The RSC controller. + * @type: SLEEP_TCS or WAKE_TCS + * + * This will clear the "slots" variable of the given tcs_group and also + * tell the hardware to forget about all entries. + * + * Return: 0 if no problem, or -EAGAIN if the caller should try again in a + * bit. Caller should make sure to enable interrupts between tries. + */ static int tcs_invalidate(struct rsc_drv *drv, int type) { int m; @@ -196,9 +222,11 @@ static int tcs_invalidate(struct rsc_drv *drv, int type) } /** - * rpmh_rsc_invalidate - Invalidate sleep and wake TCSes + * rpmh_rsc_invalidate() - Invalidate sleep and wake TCSes. + * @drv: The RSC controller. * - * @drv: the RSC controller + * Return: 0 if no problem, or -EAGAIN if the caller should try again in a + * bit. Caller should make sure to enable interrupts between tries. */ int rpmh_rsc_invalidate(struct rsc_drv *drv) { @@ -211,6 +239,20 @@ int rpmh_rsc_invalidate(struct rsc_drv *drv) return ret; } +/** + * get_tcs_for_msg() - Get the tcs_group used to send the given message. + * @drv: The RSC controller. + * @msg: The message we want to send. + * + * This is normally pretty straightforward except if we are trying to send + * an ACTIVE_ONLY message but don't have any active_only TCSs. + * + * Called without drv->lock held and with no tcs_lock locks held. + * + * Return: 0 if no problem, or -EAGAIN if the caller should try again in a bit. + * Caller should make sure to enable interrupts between tries. + * Only ever returns -EAGAIN for ACTIVE_ONLY transfers. + */ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, const struct tcs_request *msg) { @@ -246,12 +288,35 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, ret = rpmh_rsc_invalidate(drv); if (ret) return ERR_PTR(ret); + + /* + * TODO: + * - Temporarily enable IRQs on the wake tcs. + * - Make sure nobody else race with us and re-write + * to this TCS; document how this works. + */ } } return tcs; } +/** + * get_req_from_tcs() - Get a stashed request that was xfering on the given tcs. + * @drv: The RSC controller. + * @tcs_id: The global ID of this TCS. + * + * For ACTIVE_ONLY transfers we want to call back into the client when the + * transfer finishes. To do this we need the "request" that the client + * originally provided us. This function grabs the request that we stashed + * when we started the transfer. + * + * This only makes sense for ACTIVE_ONLY transfers since those are the only + * ones we track sending (the only ones we enable interrupts for and the only + * ones we call back to the client for). + * + * Return: The stashed request. + */ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, int tcs_id) { @@ -268,7 +333,14 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, } /** - * tcs_tx_done: TX Done interrupt handler + * tcs_tx_done() - TX Done interrupt handler. + * @irq: The IRQ number (ignored). + * @p: Pointer to "struct rsc_drv". + * + * Called for ACTIVE_ONLY TCSs (those are the only ones we enable the IRQ for) + * when a transfer is done. + * + * Return: IRQ_HANDLED */ static irqreturn_t tcs_tx_done(int irq, void *p) { @@ -278,6 +350,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p) const struct tcs_request *req; struct tcs_cmd *cmd; + /* NOTE: interrupt status for all TCSs are found in TCS 0 */ irq_status = read_tcs_reg(drv, RSC_DRV_IRQ_STATUS, 0); for_each_set_bit(i, &irq_status, BITS_PER_LONG) { @@ -318,6 +391,16 @@ static irqreturn_t tcs_tx_done(int irq, void *p) return IRQ_HANDLED; } +/** + * __tcs_buffer_write() - Write to TCS hardware from a request; don't trigger. + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @cmd_id: The index within the TCS to start writing. + * @msg: The message we want to send, which will contain several addr/data + * pairs to program (but few enough that they all fit in one TCS). + * + * This is used for all types of TCSs (active, sleep, and wake). + */ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, const struct tcs_request *msg) { @@ -351,6 +434,15 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable); } +/** + * __tcs_trigger() - Start transferring on the given TCS. + * + * The TCS given is probably the active-only one, but could be a wake one + * that we borrowed if there are zero active-only TCSs. + * + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + */ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id) { u32 enable; @@ -373,6 +465,27 @@ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id) write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); } +/** + * check_for_req_inflight() - Look to see if conflicting cmds are in flight. + * @drv: The controller. + * @tcs: A pointer to the tcs_group used for ACTIVE_ONLY transfers. + * @msg: The message we want to send, which will contain several addr/data + * pairs to program (but few enough that they all fit in one TCS). + * + * Only for use for ACTIVE_ONLY tcs_group, since those are the only ones + * that might be actively sending. + * + * This will walk through the TCSs in the group and check if any of them + * appear to be sending to addresses referenced in the message. If it finds + * one it'll return -EBUSY. + * + * Must be called with the drv->lock held since that protects tcs_in_use. + * + * Return: 0 if nothing in flight or -EBUSY if we should try again later. + * The caller must re-enable interrupts between tries since that's + * the only way tcs_is_free() will ever return true and the only way + * RSC_DRV_CMD_ENABLE will ever be cleared. + */ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, const struct tcs_request *msg) { @@ -399,6 +512,15 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, return 0; } +/** + * find_free_tcs() - Find free tcs in the given tcs_group; only for ACTIVE_ONLY. + * @tcs: A pointer to the ACTIVE_ONLY tcs_group (or the wake tcs_group if + * we borrowed it because there are zero active-only ones). + * + * Must be called with the drv->lock held since that protects tcs_in_use. + * + * Return: The first tcs that's free. + */ static int find_free_tcs(struct tcs_group *tcs) { int i; @@ -411,6 +533,20 @@ static int find_free_tcs(struct tcs_group *tcs) return -EBUSY; } +/** + * tcs_write() - Store messages into a TCS right now, or return -EBUSY. + * @drv: The controller. + * @msg: The data to be sent. + * + * Grabs a TCS for ACTIVE_ONLY transfers and writes the messages to it. + * + * If there are no free ACTIVE_ONLY TCSs or if a command for the same address + * is already transferring returns -EBUSY which means the client should retry + * shortly. + * + * Return: 0 on success, -EBUSY if client should retry, or an error. + * Client should have interrupts enabled for a bit before retrying. + */ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) { struct tcs_group *tcs; @@ -418,16 +554,14 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) unsigned long flags; int ret; + /* TODO: get_tcs_for_msg() can return -EAGAIN and nobody handles */ tcs = get_tcs_for_msg(drv, msg); if (IS_ERR(tcs)) return PTR_ERR(tcs); spin_lock_irqsave(&tcs->lock, flags); + spin_lock(&drv->lock); - /* - * The h/w does not like if we send a request to the same address, - * when one is already in-flight or being processed. - */ ret = check_for_req_inflight(drv, tcs, msg); if (ret) { spin_unlock(&drv->lock); @@ -454,14 +588,30 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) } /** - * rpmh_rsc_send_data: Validate the incoming message and write to the - * appropriate TCS block. + * rpmh_rsc_send_data() - Validate the incoming message + write to TCS block. + * @drv: The controller. + * @msg: The data to be sent. * - * @drv: the controller - * @msg: the data to be sent + * NOTES: + * - This is only used for "ACTIVE_ONLY" since the limitations of this + * function don't make sense for sleep/wake cases. + * - To do the transfer, we will grab a whole TCS for ourselves--we don't + * try to share. If there are none available we'll wait indefinitely + * for a free one. + * - This function will not wait for the commands to be finished, only for + * data to be programmed into the RPMh. See rpmh_tx_done() which will + * be called when the transfer is fully complete. + * - This function must be called with interrupts enabled. If the hardware + * is busy doing someone else's transfer we need that transfer to fully + * finish so that we can have the hardware, and to fully finish it needs + * the interrupt handler to run. If the interrupts is set to run on the + * active CPU this can never happen if interrupts are disabled. + * - If there are no active TCS calling this function can cause an implicit + * call to rpmh_rsc_invalidate(). Unless you know for sure that you have + * an active TCS you should assume that you need to re-write sleep/wake + * values after calling this function. * * Return: 0 on success, -EINVAL on error. - * Note: This call blocks until a valid data is written to the TCS. */ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) { @@ -485,6 +635,63 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) return ret; } +/** + * find_match() - Find if the cmd sequence is in the tcs_group + * @tcs: The tcs_group to search. Either sleep or wake. + * @cmd: The command sequence to search for; only addr is looked at. + * @len: The number of commands in the sequence. + * + * Searches through the given tcs_group to see if a given command sequence + * is in there. + * + * Two sequences are matches if they modify the same set of addresses in + * the same order. The value of the data is not considered when deciding if + * two things are matches. + * + * How this function works is best understood by example. For our example, + * we'll imagine our tcs group contains these (cmd, data) tuples: + * [(a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H)] + * ...in other words it has an element where (addr=a, data=A), etc. + * ...we'll assume that there is one TCS in the group that can store 8 commands. + * + * - find_match([(a, X)]) => 0 + * - find_match([(c, X), (d, X)]) => 2 + * - find_match([(c, X), (d, X), (e, X)]) => 2 + * - find_match([(z, X)]) => -ENODATA + * - find_match([(a, X), (y, X)]) => -EINVAL (and warning printed) + * - find_match([(g, X), (h, X), (i, X)]) => -EINVAL (and warning printed) + * - find_match([(y, X), (a, X)]) => -ENODATA + * + * NOTE: This function overall seems like it has questionable value. + * - It can be used to update a message in the TCS with new data, but I + * don't believe we actually do that--we always fully invalidate and + * re-write everything. Specifically it would be too limiting to force + * someone not to change the set of addresses written to each time. + * - This function could be attempting to avoid writing different data to + * the same address twice in a tcs_group. If that's the goal, it doesn't + * do a great job since find_match([(y, X), (a, X)]) return -ENODATA in my + * above example. + * - If you originally wrote [(a, A), (b, B), (c, C)] and later tried to + * write [(a, A), (b, B)] it'd look like a match and we wouldn't consider + * it an error that the size got shorter. + * - If two clients wrote sequences that happened to be placed in slots next + * to each other then a later check could match a sequence that was the + * size of both together. + * + * TODO: in light of the above, prehaps we can just remove this function? + * If we later come up with fancy algorithms for updating everything without + * full invalidations we can come up with something then. + * + * Only for use on sleep/wake TCSs since those are the only ones we maintain + * tcs->slots and tcs->cmd_cache for. + * + * Must be called with the tcs_lock for the group held. + * + * Return: If the given command sequence wasn't in the tcs_group: -ENODATA. + * If the given command sequence was in the tcs_group: the index of + * the slot in the tcs_group where the first command is. + * In some error cases (see above), -EINVAL. + */ static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd, int len) { @@ -497,6 +704,11 @@ static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd, if (i + len >= tcs->num_tcs * tcs->ncpt) goto seq_err; for (j = 0; j < len; j++) { + /* + * TODO: it's actually not valid to look at + * "cmd_cache[x]" if "slots[x]" doesn't have a bit + * set. Should add a check. + */ if (tcs->cmd_cache[i + j] != cmd[j].addr) goto seq_err; } @@ -510,6 +722,23 @@ static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd, return -EINVAL; } +/** + * find_slots() - Find a place to write the given message. + * @tcs: The tcs group to search. + * @msg: The message we want to find room for. + * @tcs_id: If we return 0 from the function, we return the global ID of the + * TCS to write to here. + * @cmd_id: If we return 0 from the function, we return the index of + * the command array of the returned TCS where the client should + * start writing the message. + * + * Only for use on sleep/wake TCSs since those are the only ones we maintain + * tcs->slots and tcs->cmd_cache for. + * + * Must be called with the tcs_lock for the group held. + * + * Return: -ENOMEM if there was no room, else 0. + */ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, int *tcs_id, int *cmd_id) { @@ -521,7 +750,7 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, if (slot >= 0) goto copy_data; - /* Do over, until we can fit the full payload in a TCS */ + /* Do over, until we can fit the full payload in a single TCS */ do { slot = bitmap_find_next_zero_area(tcs->slots, MAX_TCS_SLOTS, i, msg->num_cmds, 0); @@ -544,12 +773,13 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, } /** - * rpmh_rsc_write_ctrl_data: Write request to the controller - * - * @drv: the controller - * @msg: the data to be written to the controller + * rpmh_rsc_write_ctrl_data() - Write request to controller but don't trigger. + * @drv: The controller. + * @msg: The data to be written to the controller. * * There is no response returned for writing the request to the controller. + * + * Return: 0 if no error; else -error. */ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) { From patchwork Wed Mar 11 23:13:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433059 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 27CEC92A for ; Wed, 11 Mar 2020 23:14:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CA36C20752 for ; Wed, 11 Mar 2020 23:14:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ClKgrdpC" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731492AbgCKXOs (ORCPT ); Wed, 11 Mar 2020 19:14:48 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:39783 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731494AbgCKXOU (ORCPT ); Wed, 11 Mar 2020 19:14:20 -0400 Received: by mail-pf1-f196.google.com with SMTP id w65so2208589pfb.6 for ; Wed, 11 Mar 2020 16:14:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kG1+YVl0s8o9smr2trKOZ7NbvC55EDPcXtr8oUkRgXE=; b=ClKgrdpCmsvoy2gfXgwaLyaAM1AihCtYKyvZqzuy05EGgTbYcUN7uJ0SPLSwc4/4cw aR5se+RbOXCoyHSA33S+YdUlP0iiAd58cRs0M6QOrypjdzfoVRRp2d0QynUiBGxMZtd1 54mJCAn4YFUnZWaGt34SJYmeqmweS894Ge5Uw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kG1+YVl0s8o9smr2trKOZ7NbvC55EDPcXtr8oUkRgXE=; b=td7+GjO5rJgQ7qIIekVFJlQCI4wJ6IFGkTyTJ4/Kmp9Kkrabll4uTmk8Pok254d7XO vBbAzU6/RShVrrlU0ThC6neeEcz0DJuov8DJxGHQl47l6zVDR6zXrJl7jgKAMwpsnsGt aqJx7u+hKe/MYVlt351RnYkRv+Lkf41PcIJmqisdDD1aj8N8N75vJWZZqSWCCW7S9rgY iPSaSoQyBN1Zi9/Jau2ecXIdvDuKuoFtFSyxSsdmMtE1QROVqbYGm9ylQRbeUkuwphG3 t7C4TyYOxc/B+8O+tRghVeUwx6Cwux7Tvi16W1ntI2fPsQOwKGjs2W92FWliOkAPnh0t rwhg== X-Gm-Message-State: ANhLgQ3wZDnlSr36xJ35b4qA+F7LpzQmgleY+3uYxVjbz9KggxdYI8Dm 8m+VscsrUsdy/Spxzg4Ri4oamw== X-Google-Smtp-Source: ADFU+vs/ReMVEIKJdAieZwzQ6Ome0PIMgPnHEZ2NECjwaMVYEiKRDwr2hM+QvF7yG/PvY4YndTe9tw== X-Received: by 2002:a63:58a:: with SMTP id 132mr5025730pgf.216.1583968459378; Wed, 11 Mar 2020 16:14:19 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:18 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 06/10] drivers: qcom: rpmh-rsc: Comment tcs_is_free() + warn if state mismatch Date: Wed, 11 Mar 2020 16:13:44 -0700 Message-Id: <20200311161104.RFT.v2.6.Icf2213131ea652087f100129359052c83601f8b0@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org tcs_is_free() had two checks in it: does the software think that the TCS is free and does the hardware think that the TCS is free. Let's comment this and also add a warning in the case that software and hardware disagree, at least for ACTIVE_ONLY TCS. Signed-off-by: Douglas Anderson --- Changes in v2: - Comment tcs_is_free() new for v2; replaces old patch 6. drivers/soc/qcom/rpmh-rsc.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 9d2669cbd994..93f5d1fb71ca 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -181,8 +181,27 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id, */ static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) { - return !test_bit(tcs_id, drv->tcs_in_use) && - read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id); + /* If software thinks it's in use then it's definitely in use */ + if (test_bit(tcs_id, drv->tcs_in_use)) + return false; + + /* If hardware agrees it's free then it's definitely free */ + if (read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id) != 0) + return true; + + /* + * If we're here then software and hardware disagree about whether + * the TCS is free. Software thinks it is free and hardware thinks + * it is not. + * + * Maybe this should be a warning in all cases, but it's almost + * certainly a warning for the ACTIVE_TCS where nobody else should + * be doing anything else behind our backs. For now we'll just + * warn there and then still return that we're in use. + */ + WARN(drv->tcs[tcs_id].type == ACTIVE_TCS, + "Driver thought TCS was free but HW reported busy\n"); + return false; } /** From patchwork Wed Mar 11 23:13:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433053 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 959F692A for ; Wed, 11 Mar 2020 23:14:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4497A2074F for ; Wed, 11 Mar 2020 23:14:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="jRtnocXH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731493AbgCKXOn (ORCPT ); Wed, 11 Mar 2020 19:14:43 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:34605 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731502AbgCKXOV (ORCPT ); Wed, 11 Mar 2020 19:14:21 -0400 Received: by mail-pg1-f196.google.com with SMTP id t3so2032206pgn.1 for ; Wed, 11 Mar 2020 16:14:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mCMQ2OChqTGNObRkFX9H0wPC+5YSQubFFV/J730ew5s=; b=jRtnocXHHMUP3D+7tOmcprsy5ijnwFjDJ2i50lUH6gswsfBQnvJKVqfR5jpnGxFwWA ce1P1tv5x9Mli/4UNjaB5lE2ae20TKIRXhYPr4twa0iJ1ggbqNqpwjBcmQ2OG/7ZBSjR 1y1aCxYUhYpaVcihAXvzY+Ycp2e/5Am4O665o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mCMQ2OChqTGNObRkFX9H0wPC+5YSQubFFV/J730ew5s=; b=mwnWr0kJiHFYETREtvmWWZgQYRonNsqDD3wtWc+fWGvGUUvG/lbH9K5Ibl+BRx49Wg YTVE+N1QsYtKMSfoyvDRS9wwOeCRdYyGoIeXE78CkevKFizaShhoZo9UAxrADDUw2Xph FxHWZx2+B7TuzyFOPKFXgQnKCLo9XQ7g3sCYYD7ew60Rg0OF2nrM7ShdJ9EY95aJ1/v/ D05OK9pf5ZAfCQLiy4gkLIxX66qnzDRLKlzwD3+YrAeUD+hPkNYov62/J3EA2zp/XHFw Ej+UKyGDpD9inpAgEAJe8/Rk0gBtIX/SkTIF6DslwXN2AK62iwKXZc88kWXJAYghSFwc cJaQ== X-Gm-Message-State: ANhLgQ0+UzQANQk2NHpDDlXx8nzZSTPw871d/stL4318C52gXvVqT93S QWAmIW1DvD/y610kdbi5q4mYXA== X-Google-Smtp-Source: ADFU+vtMFl8p/co8i8x5gkeIQK2jVDPcbsl/SIL1NLHshjUeTo67wxI9RgvSkAVSGhGTpySbG2k2Tg== X-Received: by 2002:a63:4555:: with SMTP id u21mr4952213pgk.66.1583968460689; Wed, 11 Mar 2020 16:14:20 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:20 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 07/10] drivers: qcom: rpmh-rsc: Warning if tcs_write() used for non-active Date: Wed, 11 Mar 2020 16:13:45 -0700 Message-Id: <20200311161104.RFT.v2.7.I8e187cdfb7a31f5bb7724f1f937f2862ee464a35@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org tcs_write() is documented to only be useful for writing RPMH_ACTIVE_ONLY_STATE. Let's be loud if someone messes up. Signed-off-by: Douglas Anderson --- Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 93f5d1fb71ca..ba489d18c20e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -573,6 +573,12 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) unsigned long flags; int ret; + /* + * It only makes sense to grab a whole TCS for ourselves if we're + * triggering right away, which we only do for ACTIVE_ONLY. + */ + WARN_ON(msg->state != RPMH_ACTIVE_ONLY_STATE); + /* TODO: get_tcs_for_msg() can return -EAGAIN and nobody handles */ tcs = get_tcs_for_msg(drv, msg); if (IS_ERR(tcs)) From patchwork Wed Mar 11 23:13:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433051 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0DD4792A for ; Wed, 11 Mar 2020 23:14:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B15CC20752 for ; Wed, 11 Mar 2020 23:14:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="B7/KZHMf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731520AbgCKXOX (ORCPT ); Wed, 11 Mar 2020 19:14:23 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:37889 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731513AbgCKXOX (ORCPT ); Wed, 11 Mar 2020 19:14:23 -0400 Received: by mail-pl1-f194.google.com with SMTP id w3so1824928plz.5 for ; Wed, 11 Mar 2020 16:14:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3xshg7ExKoZEQ1cmRMbwPGjLTkGkDqXFoENhWmw2kvw=; b=B7/KZHMfx/pmxw43ZXgtosczRo5w1B5pV4DwD4I7ocTJtH/KHnLq5kPOgKQIwkyF2W eAYNB5zzBdc1/Ow+NeqHY/wrbNlnUfUt4OLrGRyGiCDBdwW/SzD8W6WKyk6ADh36204z KoRbmp5/BFJPsG3fxhNoK/HnTXDX3Cve4EjkU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3xshg7ExKoZEQ1cmRMbwPGjLTkGkDqXFoENhWmw2kvw=; b=ueZMKQyVjSm/N1h+KOXF+t/BhOMNBYm3qx0w72p28cn2DUCvsGpCqIaKiwvgdL2Dji ZTnjhRbVI+hmreavLkenG7cNh5SLul+6yXJ5RMQYRwyZoEHIxLGb1UqoD1DOB5KfL5df jFimqwfCYn3PYAtMH0wEfXH7ViLjYSlOyY49+JjYCDqv6kN9GzeevtABLHQHdAoSDJzn 7jZd9ufGYRsV+Fk6zHVegDQJCtSmf1dCwBFcLXxbPKWOlZv5uz9CvFF6JCzJVytcF7JA zPwZo7aBYEJ3CK2aP++2osNqAQv0sCCQpcTDG7XzpjuHvhyIov+wn/Py9u0dBMtcmwDr 7aew== X-Gm-Message-State: ANhLgQ1DzNoScsFyu4Sdg7xHy55G54qiaeysK/Y1ITyFmQaLXzkIjXw8 y7cUcB8S25skE9uHPJnlkjBW+A== X-Google-Smtp-Source: ADFU+vtJPb7raHtNVcBlj/4DXcl6eXZsrwxmV0Q1tUcIzYLc0r3sj7CGDQOd1wc55wtMz5uc24ug5Q== X-Received: by 2002:a17:90a:de16:: with SMTP id m22mr1086840pjv.142.1583968461826; Wed, 11 Mar 2020 16:14:21 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:21 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 08/10] drivers: qcom: rpmh-rsc: spin_lock_irqsave() for tcs_invalidate() Date: Wed, 11 Mar 2020 16:13:46 -0700 Message-Id: <20200311161104.RFT.v2.8.I07c1f70e0e8f2dc0004bd38970b4e258acdc773e@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Auditing tcs_invalidate() made me worried. Specifically I saw that it used spin_lock(), not spin_lock_irqsave(). That always worries me. As I understand it, using spin_lock() is only valid in these situations: a) You know you are running in the interrupt handler (and all other users of the lock use the "irqsave" variant). b) You know that nobody using the lock is ever running in the interrupt handler. c) You know that someone else has always disabled interrupts before your code runs and thus the "irqsave" variant is pointless. From auditing the driver we look OK. ...except that there is one further corner case. If sometimes your code is called with IRQs disabled and sometimes it's not you will get in trouble if someone ever boots your board with "nosmp" (AKA in uniprocessor mode). In such a case if someone else has the lock (without disabling interrupts) and they get swapped out then your code (with interrupts disabled) might loop forever waiting for the spinlock. It's just safer to use the irqsave version, so let's do that. In future patches I believe tcs_invalidate() will always be called with interrupts off anyway. Signed-off-by: Douglas Anderson --- Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index ba489d18c20e..c82c734788b1 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -218,9 +218,10 @@ static bool tcs_is_free(struct rsc_drv *drv, int tcs_id) static int tcs_invalidate(struct rsc_drv *drv, int type) { int m; + unsigned long flags; struct tcs_group *tcs = &drv->tcs[type]; - spin_lock(&tcs->lock); + spin_lock_irqsave(&tcs->lock, flags); if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) { spin_unlock(&tcs->lock); return 0; @@ -235,7 +236,7 @@ static int tcs_invalidate(struct rsc_drv *drv, int type) write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, m, 0); } bitmap_zero(tcs->slots, MAX_TCS_SLOTS); - spin_unlock(&tcs->lock); + spin_unlock_irqrestore(&tcs->lock, flags); return 0; } From patchwork Wed Mar 11 23:13:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433047 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 862F313B1 for ; Wed, 11 Mar 2020 23:14:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2331D20751 for ; Wed, 11 Mar 2020 23:14:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="PdRmyWqo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731473AbgCKXOY (ORCPT ); Wed, 11 Mar 2020 19:14:24 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:37022 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731521AbgCKXOY (ORCPT ); Wed, 11 Mar 2020 19:14:24 -0400 Received: by mail-pl1-f196.google.com with SMTP id f16so1827236plj.4 for ; Wed, 11 Mar 2020 16:14:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8SlVRwnK5lBUi1cuRxYdtVjS355vj5dPhf2DZCPlIWI=; b=PdRmyWqoKxh2+6SHbS0YNAHaIPPP4fcj27uyWtCJO7py7qLAa8Le7xvHv+FdxIIjIU NIe4YApf2dLBSRxcS133Zva9N5UAgAKS4HBtWDS2iui/bA0qXlZycVV41VUx3lIXY+kv CvXpAW5txMPoWpkExNV+I1ksL/XNNyIAUYMq4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8SlVRwnK5lBUi1cuRxYdtVjS355vj5dPhf2DZCPlIWI=; b=t9UyBgQaKqm8iFdpmJuZjbNgmAk/youBoQVQnAcGqYueH4JluNVaa/TpXz+JbqN+5e cv0CeE/KCyLviW4JVxOND9MO0+qyZ0mObgF4n/X0SiaLXwEHwXU0rbxtRBUdHnbnuB9D Dyjj/sZSqMZamCD4x9rekwtjkfOaogG4OUZ3fkbsZTjEUZeBUR0Z+oPtk8HMYdGOzipT guGFgrl/W5qKs0WXBfw+XGdF1p5KOBm1rR5NSzhxbfKltTa7DVkJv8anmaTJq7VWM8rP M5dUgLwqP/Zm83JhCsVxPwx/0c0UbDlMPdszkInxVQX+bndAPyPXKW9pzDUHIv48kDTT 8Fdg== X-Gm-Message-State: ANhLgQ1otiWoy+kk9qJo51QKPeocTRUjxOPbWTZcuCymzQNoXKbTdK6Y dVmCxUQLRgA6dyarbALSB6ZGVw== X-Google-Smtp-Source: ADFU+vvEnKH2A9yQKt9DtLS0LD9vxkoCVLECwf36CkzLff6JhV6fc9/pbWUSTLRDW36SOFQKD8pJfQ== X-Received: by 2002:a17:90a:f0cd:: with SMTP id fa13mr1028894pjb.129.1583968462952; Wed, 11 Mar 2020 16:14:22 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:22 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 09/10] drivers: qcom: rpmh-rsc: Kill cmd_cache and find_match() with fire Date: Wed, 11 Mar 2020 16:13:47 -0700 Message-Id: <20200311161104.RFT.v2.9.I6d3d0a3ec810dc72ff1df3cbf97deefdcdeb8eef@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org As talked about in the comments introduced by the patch ("drivers: qcom: rpmh-rsc: A lot of comments"), the find_match() function() didn't seem very sensible. Remove it and the cmd_cache array that it needed. Nothing should stop us from exploring some fancy ways to avoid fully invalidating the whole sleep/wake TCSs all the time in the future, but find_match() doesn't seem well enough thought out to keep while we wait for something better to arrive. This patch isn't quite a no-op. Specifically: * It should be a slight performance boost of not searching through so many arrays. * There is slightly less self-checking of commands written to the sleep/wake sets. If it truly is an error to write to the same address more than once in a tcs_group then some cases (but not all) would have been caught before. [1] https://lore.kernel.org/r/1583428023-19559-1-git-send-email-mkshah@codeaurora.org Signed-off-by: Douglas Anderson --- It's possible that this might need the latest version of Maulik's rpmh.c patches to work properly so we can really be sure that we always invalidate before we flush. Changes in v2: - Got rid of useless "if (x) continue" at end of for loop. drivers/soc/qcom/rpmh-internal.h | 2 - drivers/soc/qcom/rpmh-rsc.c | 111 +------------------------------ 2 files changed, 1 insertion(+), 112 deletions(-) diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index b756d3036e96..07dfa393bb34 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -36,7 +36,6 @@ struct rsc_drv; * trigger * End: get irq, access req, * grab drv->lock, clear tcs_in_use, drop drv->lock - * @cmd_cache: Flattened cache of cmds in sleep/wake TCS; num_tcs * ncpt big. * @slots: Indicates which of @cmd_addr are occupied; only used for * SLEEP / WAKE TCSs. Things are tightly packed in the * case that (ncpt < MAX_CMDS_PER_TCS). That is if ncpt = 2 and @@ -51,7 +50,6 @@ struct tcs_group { int ncpt; spinlock_t lock; const struct tcs_request *req[MAX_TCS_PER_TYPE]; - u32 *cmd_cache; DECLARE_BITMAP(slots, MAX_TCS_SLOTS); }; diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index c82c734788b1..abbd8b158a63 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -661,93 +661,6 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) return ret; } -/** - * find_match() - Find if the cmd sequence is in the tcs_group - * @tcs: The tcs_group to search. Either sleep or wake. - * @cmd: The command sequence to search for; only addr is looked at. - * @len: The number of commands in the sequence. - * - * Searches through the given tcs_group to see if a given command sequence - * is in there. - * - * Two sequences are matches if they modify the same set of addresses in - * the same order. The value of the data is not considered when deciding if - * two things are matches. - * - * How this function works is best understood by example. For our example, - * we'll imagine our tcs group contains these (cmd, data) tuples: - * [(a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H)] - * ...in other words it has an element where (addr=a, data=A), etc. - * ...we'll assume that there is one TCS in the group that can store 8 commands. - * - * - find_match([(a, X)]) => 0 - * - find_match([(c, X), (d, X)]) => 2 - * - find_match([(c, X), (d, X), (e, X)]) => 2 - * - find_match([(z, X)]) => -ENODATA - * - find_match([(a, X), (y, X)]) => -EINVAL (and warning printed) - * - find_match([(g, X), (h, X), (i, X)]) => -EINVAL (and warning printed) - * - find_match([(y, X), (a, X)]) => -ENODATA - * - * NOTE: This function overall seems like it has questionable value. - * - It can be used to update a message in the TCS with new data, but I - * don't believe we actually do that--we always fully invalidate and - * re-write everything. Specifically it would be too limiting to force - * someone not to change the set of addresses written to each time. - * - This function could be attempting to avoid writing different data to - * the same address twice in a tcs_group. If that's the goal, it doesn't - * do a great job since find_match([(y, X), (a, X)]) return -ENODATA in my - * above example. - * - If you originally wrote [(a, A), (b, B), (c, C)] and later tried to - * write [(a, A), (b, B)] it'd look like a match and we wouldn't consider - * it an error that the size got shorter. - * - If two clients wrote sequences that happened to be placed in slots next - * to each other then a later check could match a sequence that was the - * size of both together. - * - * TODO: in light of the above, prehaps we can just remove this function? - * If we later come up with fancy algorithms for updating everything without - * full invalidations we can come up with something then. - * - * Only for use on sleep/wake TCSs since those are the only ones we maintain - * tcs->slots and tcs->cmd_cache for. - * - * Must be called with the tcs_lock for the group held. - * - * Return: If the given command sequence wasn't in the tcs_group: -ENODATA. - * If the given command sequence was in the tcs_group: the index of - * the slot in the tcs_group where the first command is. - * In some error cases (see above), -EINVAL. - */ -static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd, - int len) -{ - int i, j; - - /* Check for already cached commands */ - for_each_set_bit(i, tcs->slots, MAX_TCS_SLOTS) { - if (tcs->cmd_cache[i] != cmd[0].addr) - continue; - if (i + len >= tcs->num_tcs * tcs->ncpt) - goto seq_err; - for (j = 0; j < len; j++) { - /* - * TODO: it's actually not valid to look at - * "cmd_cache[x]" if "slots[x]" doesn't have a bit - * set. Should add a check. - */ - if (tcs->cmd_cache[i + j] != cmd[j].addr) - goto seq_err; - } - return i; - } - - return -ENODATA; - -seq_err: - WARN(1, "Message does not match previous sequence.\n"); - return -EINVAL; -} - /** * find_slots() - Find a place to write the given message. * @tcs: The tcs group to search. @@ -759,7 +672,7 @@ static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd, * start writing the message. * * Only for use on sleep/wake TCSs since those are the only ones we maintain - * tcs->slots and tcs->cmd_cache for. + * tcs->slots for. * * Must be called with the tcs_lock for the group held. * @@ -771,11 +684,6 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, int slot, offset; int i = 0; - /* Find if we already have the msg in our TCS */ - slot = find_match(tcs, msg->cmds, msg->num_cmds); - if (slot >= 0) - goto copy_data; - /* Do over, until we can fit the full payload in a single TCS */ do { slot = bitmap_find_next_zero_area(tcs->slots, MAX_TCS_SLOTS, @@ -785,11 +693,7 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, i += tcs->ncpt; } while (slot + msg->num_cmds - 1 >= i); -copy_data: bitmap_set(tcs->slots, slot, msg->num_cmds); - /* Copy the addresses of the resources over to the slots */ - for (i = 0; i < msg->num_cmds; i++) - tcs->cmd_cache[slot + i] = msg->cmds[i].addr; offset = slot / tcs->ncpt; *tcs_id = offset + tcs->offset; @@ -913,19 +817,6 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev, tcs->mask = ((1 << tcs->num_tcs) - 1) << st; tcs->offset = st; st += tcs->num_tcs; - - /* - * Allocate memory to cache sleep and wake requests to - * avoid reading TCS register memory. - */ - if (tcs->type == ACTIVE_TCS) - continue; - - tcs->cmd_cache = devm_kcalloc(&pdev->dev, - tcs->num_tcs * ncpt, sizeof(u32), - GFP_KERNEL); - if (!tcs->cmd_cache) - return -ENOMEM; } drv->num_tcs = st; From patchwork Wed Mar 11 23:13:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 11433049 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE8F614E5 for ; Wed, 11 Mar 2020 23:14:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E89620752 for ; Wed, 11 Mar 2020 23:14:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="gZsLsQ90" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731535AbgCKXOl (ORCPT ); Wed, 11 Mar 2020 19:14:41 -0400 Received: from mail-pj1-f65.google.com ([209.85.216.65]:37351 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731493AbgCKXO1 (ORCPT ); Wed, 11 Mar 2020 19:14:27 -0400 Received: by mail-pj1-f65.google.com with SMTP id ca13so1780178pjb.2 for ; Wed, 11 Mar 2020 16:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+l8HEEp5z/NJMl2lmZaebCPqD2oTwZcZODCagAmwBoI=; b=gZsLsQ905xELdiFXDuvhCY948QmOeq8hgf7WRNwFQYggf7QXDlIrRdkt6RRbcRjNRw wCDMWcAZnWj75TZ4WmkroiHz3XAAsw/OTa+lAVRAp2o5sCdGCFOAvvSDqJKeZEUCpmBb BpstVVFKwXnMIPEHqdjum/DfKDyUB92ghvYrg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+l8HEEp5z/NJMl2lmZaebCPqD2oTwZcZODCagAmwBoI=; b=NQAqEkRFvxE11Ssr8X5bKnN3I6rP1t5M8jrPhbWe8AQAU9ehdJTISnad9FCn3guOeh +q7QigPI/5vyB+qXOGqol/UjNkGE6r9ptaTsUeNwj8ZQyjoj1BEwdV0kIJj3Y4bzSoxo ztaIUXBkTEgDNschcgOlouA4KCuTQWA4mwS3UfURnwbv1rAA18MRAxaJNkI+oY4DS7uo +j3aMAqnKgq6merpoYWmw+7XT+ud3hkMAvkWLY0rzg0p4iUe8hMsmxmsC9RgAUWhh3za Wep6+XNUI9YwoqgStGhxzI3Zn3p8TJk9wuW5pQjUS8ddTE7uKd61fd6aSO0NFs5yrcgU mY5w== X-Gm-Message-State: ANhLgQ1z7YnVeF+76S3Rw4bI5e1RugLFejoxnau3jWTMrh4i8gsc6HG6 y8aCm1XW5Zc2im64wOJS+Qj3KQ== X-Google-Smtp-Source: ADFU+vuyyhI1HC2LBNYvyyv/D6HXeGMLu7hKQzSZUyP6NZso3KnmgOeJay5KNjXVk2vcBMokDpLLZw== X-Received: by 2002:a17:90a:b90a:: with SMTP id p10mr1029934pjr.81.1583968464591; Wed, 11 Mar 2020 16:14:24 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id g75sm2606334pje.37.2020.03.11.16.14.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Mar 2020 16:14:23 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Rajendra Nayak , evgreen@chromium.org, Lina Iyer , swboyd@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFT PATCH v2 10/10] drivers: qcom: rpmh-rsc: Always use -EAGAIN, never -EBUSY Date: Wed, 11 Mar 2020 16:13:48 -0700 Message-Id: <20200311161104.RFT.v2.10.I537337af59c51c72aac2c1625760a60519c66387@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200311231348.129254-1-dianders@chromium.org> References: <20200311231348.129254-1-dianders@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Some parts of rpmh-rsc returned -EAGAIN when the controller was busy and you should try again. Other parts returned -EBUSY when the controller was busy and you should try again. Typically -EAGAIN was used when dealing with sleep/wake TCSs and -EBUSY was used when dealing with the active TCS. Let's standardize and just have one return code. If we don't do this then the crossover case where we need to use a sleep/wake TCS for an active only transfer (when there are zero active TCSs) we need to either adapt one code to the other test for both. Signed-off-by: Douglas Anderson --- Changes in v2: - ("Always use -EAGAIN, never -EBUSY") new for v2. drivers/soc/qcom/rpmh-rsc.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index abbd8b158a63..8b59d07ef94e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -497,11 +497,11 @@ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id) * * This will walk through the TCSs in the group and check if any of them * appear to be sending to addresses referenced in the message. If it finds - * one it'll return -EBUSY. + * one it'll return -EAGAIN. * * Must be called with the drv->lock held since that protects tcs_in_use. * - * Return: 0 if nothing in flight or -EBUSY if we should try again later. + * Return: 0 if nothing in flight or -EAGAIN if we should try again later. * The caller must re-enable interrupts between tries since that's * the only way tcs_is_free() will ever return true and the only way * RSC_DRV_CMD_ENABLE will ever be cleared. @@ -524,7 +524,7 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j); for (k = 0; k < msg->num_cmds; k++) { if (addr == msg->cmds[k].addr) - return -EBUSY; + return -EAGAIN; } } } @@ -550,21 +550,21 @@ static int find_free_tcs(struct tcs_group *tcs) return tcs->offset + i; } - return -EBUSY; + return -EAGAIN; } /** - * tcs_write() - Store messages into a TCS right now, or return -EBUSY. + * tcs_write() - Store messages into a TCS right now, or return -EAGAIN. * @drv: The controller. * @msg: The data to be sent. * * Grabs a TCS for ACTIVE_ONLY transfers and writes the messages to it. * * If there are no free ACTIVE_ONLY TCSs or if a command for the same address - * is already transferring returns -EBUSY which means the client should retry + * is already transferring returns -EAGAIN which means the client should retry * shortly. * - * Return: 0 on success, -EBUSY if client should retry, or an error. + * Return: 0 on success, -EAGAIN if client should retry, or an error. * Client should have interrupts enabled for a bit before retrying. */ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) @@ -580,7 +580,6 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) */ WARN_ON(msg->state != RPMH_ACTIVE_ONLY_STATE); - /* TODO: get_tcs_for_msg() can return -EAGAIN and nobody handles */ tcs = get_tcs_for_msg(drv, msg); if (IS_ERR(tcs)) return PTR_ERR(tcs); @@ -651,12 +650,12 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) do { ret = tcs_write(drv, msg); - if (ret == -EBUSY) { + if (ret == -EAGAIN) { pr_info_ratelimited("TCS Busy, retrying RPMH message send: addr=%#x\n", msg->cmds[0].addr); udelay(10); } - } while (ret == -EBUSY); + } while (ret == -EAGAIN); return ret; }