From patchwork Tue Apr 7 23:50:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 189707 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90EE3C2BB54 for ; Tue, 7 Apr 2020 23:50:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 652AD20719 for ; Tue, 7 Apr 2020 23:50:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="TbW/TRy4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726437AbgDGXu6 (ORCPT ); Tue, 7 Apr 2020 19:50:58 -0400 Received: from mail-pj1-f67.google.com ([209.85.216.67]:50329 "EHLO mail-pj1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726407AbgDGXu5 (ORCPT ); Tue, 7 Apr 2020 19:50:57 -0400 Received: by mail-pj1-f67.google.com with SMTP id b7so286374pju.0 for ; Tue, 07 Apr 2020 16:50:57 -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=31rj24m3X17PSEbUwC15en+C3wJXpiCj3YBFX5nStr0=; b=TbW/TRy4ANNKKWudxkfhBucJ4xL+Fdi5v8Mo+7DB7BBnQDGE+OgJICZAZc4JQA43Tp OMFN3zq8v7oWTmxXZF+Pi1ymZ/Xq9Xvhar2Jm2gAne+3CwTaVa7K3VG6F3qTSqufmAMG JgIIQoQGAWPX4dfnzg/acPEa8j6aGAzenr9c4= 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=31rj24m3X17PSEbUwC15en+C3wJXpiCj3YBFX5nStr0=; b=ZxochBToO/LeU0P0ZKr2HFfe2ujosrXJHGN3M+y+KDvOcTeIvAyftW4pOpVid9xUaw xow/UMC56unyStMd31KiaT9IZPRA1NRZAtFdemaylM/2zDprBWHAdj12LnJrcFyzWnj/ 3TaiLLTWZb6OYW2tduzJbkDweWRc5xlWimKxcXUhekdD/7lvIOuaPU/sXzBeU0LRyvg9 Fq7DZlDSosZFbXuh4PWwvGvutfflfertWWyHZc6Np/9bRr1yYaNdMc92pWHOQJT92OaJ rB9DQzvMUINKZH4uWkfCCVFzwzyF2i9E5kgvlxRqvqWvjsJy50byhknwnBYBG5iDpkxX HC8w== X-Gm-Message-State: AGi0Pub0j4VIVDGEceJ6WbmU6on3iz07BFS0cwcO+2QyXXhOtVZRsLXM v8QVs7mRCITCINhGsWh0NTYAvmKdEaSedg== X-Google-Smtp-Source: APiQypLOQrDPqBz3TL/1fx/TZxlRaUpgmLYmCaFCTC3+YFsxeD17UsRD/hpVcFJQYI9/nBhHHZV3Ww== X-Received: by 2002:a17:90a:c085:: with SMTP id o5mr1878124pjs.85.1586303456983; Tue, 07 Apr 2020 16:50:56 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id s27sm14467165pgn.90.2020.04.07.16.50.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 16:50:56 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Lina Iyer , Rajendra Nayak , swboyd@chromium.org, evgreen@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 01/10] drivers: qcom: rpmh-rsc: Clean code reading/writing TCS regs/cmds Date: Tue, 7 Apr 2020 16:50:15 -0700 Message-Id: <20200407164915.v3.1.I1b754137e8089e46cf33fc2ea270734ec3847ec4@changeid> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog In-Reply-To: <20200407235024.260460-1-dianders@chromium.org> References: <20200407235024.260460-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 v3: - Add "TCS" in title (Maulik). - Rebased atop v16 ('Invoke rpmh_flush...') series. Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 34b0e14c2f33..7d9e2c2f0e27 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -67,28 +67,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)) @@ -100,7 +105,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) @@ -207,7 +212,7 @@ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) * 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; @@ -226,7 +231,7 @@ static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) { u32 data; - data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, 0); + data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0); if (enable) data |= BIT(tcs_id); else @@ -245,7 +250,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); @@ -259,7 +264,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))) { @@ -313,7 +318,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]; @@ -329,7 +334,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); } @@ -345,10 +350,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 Tue Apr 7 23:50:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 189703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1B7FC2D0EC for ; Tue, 7 Apr 2020 23:51:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7023620747 for ; Tue, 7 Apr 2020 23:51:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="fikP9pwn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726513AbgDGXvA (ORCPT ); Tue, 7 Apr 2020 19:51:00 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:41705 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726510AbgDGXvA (ORCPT ); Tue, 7 Apr 2020 19:51:00 -0400 Received: by mail-pl1-f193.google.com with SMTP id d24so1832778pll.8 for ; Tue, 07 Apr 2020 16:50:59 -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=WC7KT0pNRGqubghsLpqhU2AyP/TQtFiX3YW33bK8+tI=; b=fikP9pwnOKADqBxBp6Df8qFyXJbZ76/yDzRTxlPbEVuwcFBa9Ei7Jr/I/5rNnBOk15 9pdZBMzxFK3BfIz15xQFFhvyhaCBXDxtfrn0QjK8ffDM8t52m1JiTPdYSxR7Fh8CF45X aVVfCxai+xqCiTD5zYRJkfkB7ZtqR7kj3Emns= 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=WC7KT0pNRGqubghsLpqhU2AyP/TQtFiX3YW33bK8+tI=; b=azYwlWYhYyfro5uZ5AWbXrCEo4u/h5MFYkXZABwyg4zljfY2eH/aWcfHWWJBhkOsEU qqVpWTYyM3xlvAyEuNP0DD7AQyuzFX0EJLXhJVnF13RkCBtZRcVEPsnOMxZiR3VqRXik FoosO0lpXCmhGxJIBRyz6Zb99rL8Co0rKjSvVJS9M7c1G3XyHSI9QD+zytkGG8cOrVAr vkD6h7+smwg8Lb50hbWWOVAglRd+6rjMmobswdwOdMLB5iepds0SnaC3pQTm2Px7MRt9 msu0FCN2rPg41g6/jVUZSWPPiCiBfOT8PZsRirHkdpTfOn5abJ+gfPjJixANVjpcQ3GP N/9A== X-Gm-Message-State: AGi0PuZxOST72ZXU++QFJ0wVS6Kip2NTbn1UwbFxM0FWdOgC6Ou6tAe3 LAik8GcSpXQ+khrv6y4ziQ03jg== X-Google-Smtp-Source: APiQypIrWS1flrwcKiadKIyXre2kng3sWUWISf/o7P+SWHRdrX2RTHhTJrRyakO4f92FAblSxbF7xQ== X-Received: by 2002:a17:902:b183:: with SMTP id s3mr4638431plr.33.1586303459290; Tue, 07 Apr 2020 16:50:59 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id s27sm14467165pgn.90.2020.04.07.16.50.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 16:50:58 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Lina Iyer , Rajendra Nayak , swboyd@chromium.org, evgreen@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 03/10] drivers: qcom: rpmh-rsc: Fold tcs_ctrl_write() into its single caller Date: Tue, 7 Apr 2020 16:50:17 -0700 Message-Id: <20200407164915.v3.3.Ie88ce5ccfc0c6055903ccca5286ae28ed3b85ed3@changeid> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog In-Reply-To: <20200407235024.260460-1-dianders@chromium.org> References: <20200407235024.260460-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 v3: None 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 46455b1d93f1..e361b2331993 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -587,27 +587,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 * @@ -618,6 +597,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"); @@ -628,7 +612,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; } /** From patchwork Tue Apr 7 23:50:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 189704 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35D5DC2D0EC for ; Tue, 7 Apr 2020 23:51:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0DF2E207FF for ; Tue, 7 Apr 2020 23:51:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Xfz8/K/O" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726613AbgDGXvF (ORCPT ); Tue, 7 Apr 2020 19:51:05 -0400 Received: from mail-pf1-f195.google.com ([209.85.210.195]:37558 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726598AbgDGXvE (ORCPT ); Tue, 7 Apr 2020 19:51:04 -0400 Received: by mail-pf1-f195.google.com with SMTP id u65so1548208pfb.4 for ; Tue, 07 Apr 2020 16:51:00 -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=ufwFZH8Vw5ajOnZdRGjiXkdZy2lJZCO7ZDz2z9bRXZw=; b=Xfz8/K/ONOudrnmWuEl2zxnwM62SiiPUWtjfC+y+P1fZQG0BH32YLlNo3A1ZI8V3Df gdx8CNfeyk97RQOSrMgH44tNDOcqMn6rtA2Fhhlobcy38D79h80x65Lcidk5lhgozxj1 1m5lB/CqpnZnfnrdWFXCx/AdewXMnEskgXnNI= 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=ufwFZH8Vw5ajOnZdRGjiXkdZy2lJZCO7ZDz2z9bRXZw=; b=GssbEQLY9y38aufqW95i7EmX1flspIdo8F+yVrnk1ej9GT7U6N8/xt/u/9axGqNnCQ V4j4uQ4mYk2dvOexw9pNeP0zHhQS9ocNWOFe+lsY2JeJP7BFSn1AqzGgCOSNK1fys1cF Qtq50AaArwnrgrmP4vr7SIwlUmHGVOpix9PzeQAjiRrzeKs7naK4LJYfYb1eHAWHF0b+ dZhOTMytZkfBSgNjmY/PG0ClUoj0lLJn3gXAksCoNytZovldBD73ir9g04m2WH2VMk76 K1JADPBPNm8OofqIH7OvUh9FoW7VkfrG+iuATlblp02eJbj/85vuFYXbXmQTf1Br69k0 BOCA== X-Gm-Message-State: AGi0PubK/aIz5wgh85cV/+xIp4AmbyL59SSBY7MIe6I5o0sTQQ+SVKsm Qyi9m68J5dU96etuEdR6LCr+l/FFqL9Qxw== X-Google-Smtp-Source: APiQypLXra4GbXuZzgL7voQ+20vFCu370yQ+rEI3mnaNboOs0lSKk0dSYt2+bQf+hxYkB15jHP5xaw== X-Received: by 2002:aa7:9150:: with SMTP id 16mr5126173pfi.209.1586303460412; Tue, 07 Apr 2020 16:51:00 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id s27sm14467165pgn.90.2020.04.07.16.50.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 16:50:59 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Lina Iyer , Rajendra Nayak , swboyd@chromium.org, evgreen@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 04/10] drivers: qcom: rpmh-rsc: Remove get_tcs_of_type() abstraction Date: Tue, 7 Apr 2020 16:50:18 -0700 Message-Id: <20200407164915.v3.4.Ia348ade7c6ed1d0d952ff2245bc854e5834c8d9a@changeid> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog In-Reply-To: <20200407235024.260460-1-dianders@chromium.org> References: <20200407235024.260460-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 v3: - Rebased atop v16 ('Invoke rpmh_flush...') series. Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index e361b2331993..855a1dab7718 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -177,17 +177,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)) { @@ -250,9 +243,9 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, * dedicated TCS for active state use, then re-purpose a wake TCS to * send active votes. */ - 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]; return tcs; } @@ -643,7 +636,7 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv) { int m; - struct tcs_group *tcs = get_tcs_of_type(drv, ACTIVE_TCS); + struct tcs_group *tcs = &drv->tcs[ACTIVE_TCS]; /* * If we made an active request on a RSC that does not have a @@ -654,7 +647,7 @@ static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv) * lock before checking tcs_is_free(). */ if (!tcs->num_tcs) - tcs = get_tcs_of_type(drv, WAKE_TCS); + tcs = &drv->tcs[WAKE_TCS]; for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { if (!tcs_is_free(drv, m)) From patchwork Tue Apr 7 23:50:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 189706 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC5F3C2BB1D for ; Tue, 7 Apr 2020 23:51:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A9CCE20719 for ; Tue, 7 Apr 2020 23:51:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="fJxPc50u" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726622AbgDGXvG (ORCPT ); Tue, 7 Apr 2020 19:51:06 -0400 Received: from mail-pl1-f169.google.com ([209.85.214.169]:44158 "EHLO mail-pl1-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726582AbgDGXvF (ORCPT ); Tue, 7 Apr 2020 19:51:05 -0400 Received: by mail-pl1-f169.google.com with SMTP id h11so1824422plr.11 for ; Tue, 07 Apr 2020 16:51:03 -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=DMtIkbSrj/ZJCThjFP22N8JJpPD0QLzqj6pPoOZrB/U=; b=fJxPc50uI1Dv8M53JChgWGbY1FrDhD0NWSLXQ5489g8yXTatqMxY2ad6iI07tLM4Oe cVROkELZplCCMTKn31y71IB4Dxdm4SOaFw9THGcu7p6kUh639LLZVJt93AJaWQW/nVoB 021cRjX95G6xJgfgWiYhCfqfjqRhXHKEnfebY= 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=DMtIkbSrj/ZJCThjFP22N8JJpPD0QLzqj6pPoOZrB/U=; b=lwoxdSd8CJDIgMaqqNAUbXAr7rZb6kQozPjEI49XcTR99hElXfJQSYcu8EEQHsEjGh JsTCnbabW7K5oUqjaYYNiYx8PjjPJSsQ2ataJ38PypLTJuu7xG9cACV/NJUeyd0mNMtr 1ac8qTxdyFEAjt04GdNMmjOD8Desb3HINUts4mHV5j5HGyc8i50X31/Ti3e5GMARx5fC jq2aoZrDpz1GDAZK71baePDFjRgD7MZwwxSCdlSBJDMYlNkv6S6qSZmzGO8dGLSIw+Zr NSs/YDCtxZTyp1/Ag9TqQFgGAShYMAoEM69uUsf8gfD6bKpUmTG0uL8GSCGM+eOMJKQ4 yStg== X-Gm-Message-State: AGi0PuZsNfrjBX4bN4mqU69VfmJxATxyROROLufoLiiwpyu3ltnQtlt3 sIx+JRgg0QWf6fHFDEoNr6daXw== X-Google-Smtp-Source: APiQypIo8WCuEG8Y4zN8g7crCwkEn2oftGaP0RCx7E7kMK0qthbwWvUMwIliQYN15kmb+5g2ySwSXA== X-Received: by 2002:a17:902:8e84:: with SMTP id bg4mr4384780plb.50.1586303462702; Tue, 07 Apr 2020 16:51:02 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id s27sm14467165pgn.90.2020.04.07.16.51.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 16:51:02 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Lina Iyer , Rajendra Nayak , swboyd@chromium.org, evgreen@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 06/10] drivers: qcom: rpmh-rsc: A lot of comments Date: Tue, 7 Apr 2020 16:50:20 -0700 Message-Id: <20200407164915.v3.6.I52653eb85d7dc8981ee0dafcd0b6cc0f273e9425@changeid> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog In-Reply-To: <20200407235024.260460-1-dianders@chromium.org> References: <20200407235024.260460-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. Any comments I adjusted I also tried to make match kernel-doc better. Specifically: - kernel-doc says do not leave a blank line between the function description and the arguments - kernel-doc examples always have things starting w/ a capital and ending with a period. This should be a no-op. It's just comment changes. Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah --- Changes in v3: - Adjusted comments for rpmh_rsc_write_ctrl_data(). - Comments for new enable_tcs_irq() function. - Comments for new rpmh_rsc_cpu_pm_callback() function. - Mention in message that I also fixed up kernel-doc stuff. - Moved comments patch after ("Kill cmd_cache and find_match..."). - One space after a period now (Maulik). - Plural of TCS fixed to TCSes following Maulik's example. - Re-added comment in tcs_write() about checking for same address. - Rebased atop v16 ('Invoke rpmh_flush...') series. - __tcs_set_trigger() comments adjusted now that it can set or unset. - get_tcs_for_msg() documents why it's safe to borrow the wake TCS. - get_tcs_for_msg() no longer returns -EAGAIN. Changes in v2: - Document bug of tcs_write() not handling -EAGAIN. - Document get_tcs_for_msg() => -EAGAIN only for ACTIVE_ONLY. - Document locks for updating "tcs_in_use" more. - Document tcs_is_free() without drv->lock OK for tcs_invalidate(). - Document that rpmh_rsc_send_data() can be an implicit invalidate. - Document two get_tcs_for_msg() issues if zero-active TCS. - Fixed documentation of "tcs" param in find_slots(). - More clear that active-only xfers can happen on wake TCS sometimes. - Reword tcs_write() doc a bit. drivers/soc/qcom/rpmh-internal.h | 62 ++++++--- drivers/soc/qcom/rpmh-rsc.c | 221 ++++++++++++++++++++++++++++--- 2 files changed, 246 insertions(+), 37 deletions(-) diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index 6a6d776ccca9..f06350cbc9a2 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -22,15 +22,24 @@ 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 - * @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 + * @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; @@ -82,19 +91,28 @@ 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 - * @rsc_pm: CPU PM notifier for controller - * Used when solver mode is not present - * @cpus_entered_pm: CPU mask for cpus in idle power collapse - * Used when solver mode is not present - * @tcs: TCS groups - * @tcs_in_use: S/W state of the TCS - * @lock: Synchronize state of the controller - * @pm_lock: Synchronize during PM notifications - * Used when solver mode is not present + * @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. + * @rsc_pm: CPU PM notifier for controller. + * Used when solver mode is not present. + * @cpus_entered_pm: CPU mask for cpus in idle power collapse. + * Used when solver mode is not present. + * @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 + * (aka the drv->lock) 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. + * @pm_lock: Synchronize during PM notifications. + * Used when solver mode is not present. * @client: Handle to the DRV's client. */ struct rsc_drv { diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index da1045c92b38..84ae3e514eee 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -171,12 +171,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 TCSes 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; @@ -203,9 +229,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) { @@ -218,6 +246,18 @@ 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 TCSes. + * + * Called without drv->lock held and with no tcs_lock locks held. + * + * Return: A pointer to a tcs_group or an ERR_PTR. + */ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, const struct tcs_request *msg) { @@ -241,7 +281,9 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, /* * If we are making an active request on a RSC that does not have a * dedicated TCS for active state use, then re-purpose a wake TCS to - * send active votes. + * send active votes. This is safe because we ensure any active-only + * transfers have finished before we use it (maybe by running from + * the last CPU in PM code). */ tcs = &drv->tcs[type]; if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) @@ -250,6 +292,22 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, 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) { @@ -265,6 +323,23 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, return NULL; } +/** + * __tcs_set_trigger() - Start xfer on a TCS or unset trigger on a borrowed TCS + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @trigger: If true then untrigger/retrigger. If false then just untrigger. + * + * In the normal case we only ever call with "trigger=true" to start a + * transfer. That will un-trigger/disable the TCS from the last transfer + * then trigger/enable for this transfer. + * + * If we borrowed a wake TCS for an active-only transfer we'll also call + * this function with "trigger=false" to just do the un-trigger/disable + * before using the TCS for wake purposes again. + * + * Note that the AP is only in charge of triggering active-only transfers. + * The AP never triggers sleep/wake values using this function. + */ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) { u32 enable; @@ -289,6 +364,15 @@ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) } } +/** + * enable_tcs_irq() - Enable or disable interrupts on the given TCS. + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @enable: If true then enable; if false then disable + * + * We only ever call this when we borrow a wake TCS for an active-only + * transfer. For active-only TCSes interrupts are always left enabled. + */ static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) { u32 data; @@ -302,7 +386,14 @@ static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) } /** - * 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 transfers (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) { @@ -367,6 +458,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 transfers (active, sleep, and wake). + */ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, const struct tcs_request *msg) { @@ -400,6 +501,26 @@ 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); } +/** + * 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). + * + * This will walk through the TCSes 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. + * + * Only for use for active-only transfers. + * + * 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) { @@ -426,6 +547,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. + * @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; @@ -438,6 +568,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 TCSes for ACTIVE_ONLY transfers 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; @@ -491,14 +635,26 @@ 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. * * 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) { @@ -522,13 +678,30 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) return ret; } +/** + * 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 TCSes since those are the only ones we maintain + * tcs->slots 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) { int slot, offset; int i = 0; - /* 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); @@ -547,12 +720,14 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, } /** - * rpmh_rsc_write_ctrl_data: Write request 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. * - * @drv: the controller - * @msg: the data to be written to the controller + * This should only be called for for sleep/wake state, never active-only + * state. * - * 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) { @@ -587,7 +762,6 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg) /** * rpmh_rsc_ctrlr_is_busy() - Check if any of the AMCs are busy. - * * @drv: The controller * * Checks if any of the AMCs are busy in handling ACTIVE sets. @@ -623,6 +797,23 @@ static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv) return false; } +/** + * rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy. + * @nfb: Pointer to the notifier block in struct rsc_drv. + * @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT. + * @v: Unused + * + * This function is given to cpu_pm_register_notifier so we can be informed + * about when CPUs go down. When all CPUs go down we know no more active + * transfers will be started so we write sleep/wake sets. This function gets + * called from cpuidle code paths and also at system suspend time. + * + * If its last CPU going down and AMCs are not busy then writes cached sleep + * and wake messages to TCSes. The firmware then takes care of triggering + * them when entering deepest low power modes. + * + * Return: See cpu_pm_register_notifier. + */ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb, unsigned long action, void *v) { From patchwork Tue Apr 7 23:50:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 189705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EE6BC2D0EC for ; Tue, 7 Apr 2020 23:51:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7B0BF207FF for ; Tue, 7 Apr 2020 23:51:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="OT/L+d2s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726648AbgDGXvJ (ORCPT ); Tue, 7 Apr 2020 19:51:09 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:45762 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726636AbgDGXvI (ORCPT ); Tue, 7 Apr 2020 19:51:08 -0400 Received: by mail-pf1-f194.google.com with SMTP id r14so1534718pfl.12 for ; Tue, 07 Apr 2020 16:51:07 -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=KvEJzMH6Rxi8JFDstC273KQ0bdGB37YijaATrtjA+Oo=; b=OT/L+d2sOkBze7u7kCa/ul9nbt7FBPk4UFbvoXf7evUw860Zm7kdOTvn+/o1kPqp4C 1Y0MaFQ01GRIGs3AAZfSuNfnwO66ph7dkS6vDmTcUTZl5i6jIw+1+KFcO9KXV1wjqlrZ PPO7T+JbzB1wgA8vitRJDvxObqOOuYYVZDiYo= 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=KvEJzMH6Rxi8JFDstC273KQ0bdGB37YijaATrtjA+Oo=; b=ol5mtBnXZOz9LjDnQj2MHSwT2EACBH6kSLAV52G3VXokzSB/K0avTzec/GZTNUKGSA 4D1v07FYjwUjyRGJGSJW5pfIE+WLkDhsCwuH5hdtNqJDEJWOmqvV6Adobvqw+EsnhoTf N1qbYDu5ar7r4RheaVqq5ttzRsRIOLYegT39x0nJX3DFD9Vr87eaoi58TJBoxTZrWDGu DiR/EVP8Ee0JHoTCe3LSsNPu9xD9RDH1kypRDIGa3rsxTsna3izJHn3edtmECCMrNAj+ TvKCHJU8vyKD09BS59YjMUWv3PbsJmUIerWXavG5xAYuByCYaOByNjztzYutkVn5FZIb QEcA== X-Gm-Message-State: AGi0Pua0Wa7jgUMMu1giF48B/kgm/29KPhFV/iCn7GM9Tma1PKwzc10n py4nboaSNNRamcEehcoCJfBfRg== X-Google-Smtp-Source: APiQypJMr4oUHM0Ta88xT7+6ntyKOqf33TdlrkpIUfBkSR/NP5bMYzT+8z/Iix1PO7MN42gvKmsSlg== X-Received: by 2002:aa7:8d90:: with SMTP id i16mr3456900pfr.126.1586303467414; Tue, 07 Apr 2020 16:51:07 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id s27sm14467165pgn.90.2020.04.07.16.51.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 16:51:06 -0700 (PDT) From: Douglas Anderson To: Andy Gross , Bjorn Andersson , Maulik Shah Cc: mka@chromium.org, Lina Iyer , Rajendra Nayak , swboyd@chromium.org, evgreen@chromium.org, Douglas Anderson , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 10/10] drivers: qcom: rpmh-rsc: read_tcs_reg()/write_tcs_reg() are not for IRQ Date: Tue, 7 Apr 2020 16:50:24 -0700 Message-Id: <20200407164915.v3.10.I2adf93809c692d0b673e1a86ea97c45644aa8d97@changeid> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog In-Reply-To: <20200407235024.260460-1-dianders@chromium.org> References: <20200407235024.260460-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 RSC_DRV_IRQ_ENABLE, RSC_DRV_IRQ_STATUS, and RSC_DRV_IRQ_CLEAR registers are not part of TCS 0. Let's not pretend that they are by using read_tcs_reg() and write_tcs_reg() and passing a bogus tcs_id of 0. We could introduce a new wrapper for these registers but it wouldn't buy us much. Let's just read/write directly. Signed-off-by: Douglas Anderson --- Changes in v3: - ("...are not for IRQ") is new for v3. Changes in v2: None drivers/soc/qcom/rpmh-rsc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index a3b015196f15..31a998e6f2e9 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -363,12 +363,12 @@ static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) { u32 data; - data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0); + data = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_ENABLE); if (enable) data |= BIT(tcs_id); else data &= ~BIT(tcs_id); - write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, data); + writel_relaxed(data, drv->tcs_base + RSC_DRV_IRQ_ENABLE); } /** @@ -389,7 +389,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); + irq_status = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_STATUS); for_each_set_bit(i, &irq_status, BITS_PER_LONG) { req = get_req_from_tcs(drv, i); @@ -426,7 +426,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p) /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0); - write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i)); + writel_relaxed(BIT(i), drv->tcs_base + RSC_DRV_IRQ_CLEAR); spin_lock(&drv->lock); clear_bit(i, drv->tcs_in_use); /* @@ -969,7 +969,8 @@ static int rpmh_rsc_probe(struct platform_device *pdev) } /* Enable the active TCS to send requests immediately */ - write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, drv->tcs[ACTIVE_TCS].mask); + writel_relaxed(drv->tcs[ACTIVE_TCS].mask, + drv->tcs_base + RSC_DRV_IRQ_ENABLE); spin_lock_init(&drv->client.cache_lock); INIT_LIST_HEAD(&drv->client.cache);