Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp933272ybh; Thu, 12 Mar 2020 13:50:34 -0700 (PDT) X-Google-Smtp-Source: ADFU+vuGN4oi3zbOk+f1bk3gdonIKk0YuMzL2uUwdns16yoc+ykKZSMvS3KNYymx+sEgDAv2ooLY X-Received: by 2002:a9d:1d67:: with SMTP id m94mr7878531otm.140.1584046234043; Thu, 12 Mar 2020 13:50:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584046234; cv=none; d=google.com; s=arc-20160816; b=KBXhfccSJtCS8qLbbfSvX93fOHdU3iuThglUxtsHMtkHDqLiosgd/t65vi0srjMHLp SP3eWzIugjy4Wxu5Q2Fk/iuELD+KAYyg8WT27KdnB8RAAPV3wRz2KaiO19mWWb1Fju8H NEqFLsHH57CJoxX2hEeIqM0ZeDTfpXOJ4s6SA9FkdkSZRBtoEMjKQhiHAX9pRHnjKpXo YfbWwtWkEDW4yIDUqNKbNEILiqmZqQvj+0UTZDI/dlhZw3nrH9PMEesOnNGzZcS9MdDH EJyElhCsfcup8sZhHG+j2QNQrMH/t6+4eaKTc1gG4YLdHK/Hjz03hyzNJOAu6Z8cu5PF /6lQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=8tdcN4NnkMfqmyh0gTGOOia172RsAybBpYZntXd7Nqs=; b=uH4rRlpDET3R/xJJjqZwMu5XwckWUHg06aCn0MF7gnGT3UOGy30iF8BkZ7Bh5FlF54 hCcTQp2Je+g1ZhXqw6tMDWBsROBGi60JNIzrDLnri08Jznn9gkGbb3IZ0oSdc+19FXZO TneIBbbmRcr+1hQqYu9KJW5sz1NZ42krnxQ4YZwMqBIvDsDMndCnqH/qv8Z7ODegncn/ ZvDoHMiCnUvAF2zJ8hcnOavdXYDFFry+5zevTTORM9TVBN643pT99xSNQvj9+oeh9pTg yjFebaEHDoyFtiVOOqxARGhdX66s2v5mh9XJswhZ99YuJ6bXI4zHrDOZSH3AWZGaXITP r9VQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ga8j1Iur; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q10si25344otg.171.2020.03.12.13.50.20; Thu, 12 Mar 2020 13:50:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ga8j1Iur; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727059AbgCLUtj (ORCPT + 99 others); Thu, 12 Mar 2020 16:49:39 -0400 Received: from mail-pj1-f65.google.com ([209.85.216.65]:53390 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726892AbgCLUtj (ORCPT ); Thu, 12 Mar 2020 16:49:39 -0400 Received: by mail-pj1-f65.google.com with SMTP id l36so3035734pjb.3 for ; Thu, 12 Mar 2020 13:49:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=8tdcN4NnkMfqmyh0gTGOOia172RsAybBpYZntXd7Nqs=; b=ga8j1IurUn1zgapYDjTowi9NOYHdzZj9RRmRWOE7h2G2c2CRKoHTXvBqyZh7LdiPKb GHmulodPZSbKh3RZU2Tg352u4qZgLHlewGIVPz1LcAMjeUZUjNhZBRH53pa3QNDdZxO1 1uWchComPc/4QwdOjNoIO9PbIYVKYFLPTZyEU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=8tdcN4NnkMfqmyh0gTGOOia172RsAybBpYZntXd7Nqs=; b=scLnnXbVePcwktrWOUXbSFMvkJ4QaAMdVwqsq+rbjZ6LAPnrTGjnVjNuWqUliiRsAM ZlmNB+alZQSxEtblfAjky0h4h1vVBF0alLQKXDhiduHYnAruxBFvpQ3F2GXqDHPt7/tq ut6wDnBzulp5QxC0Z34jGm9MMQjNWfnpcUTzmZpN/TUFOJYhkRZpJ4hGjlTKz1nRZJv4 eNUWs3M0J7I2MjiUCtWMDDn1SoB9M7XQwWjLcVkYTpK+FVIsuy51xQfMI76fVfhA3CIE Ul9eMThOqMs40dOI2CRf2V4a6Q+oARIVosU8xYE1EA2dimgnYNfWGhfNS/CU4BBEy0RA JI5A== X-Gm-Message-State: ANhLgQ1JWWZjIJa0H//IbTrjuyYnYS3vQ87WHPVkRiHYcS9DqDFkUPpq mNTZoaxxmp7Q+Lj2zg0uOgSeYg== X-Received: by 2002:a17:902:6504:: with SMTP id b4mr9569558plk.291.1584046177701; Thu, 12 Mar 2020 13:49:37 -0700 (PDT) Received: from localhost ([2620:15c:202:1:4fff:7a6b:a335:8fde]) by smtp.gmail.com with ESMTPSA id b2sm2179084pjc.6.2020.03.12.13.49.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 12 Mar 2020 13:49:36 -0700 (PDT) Date: Thu, 12 Mar 2020 13:49:35 -0700 From: Matthias Kaehlcke To: Pradeep P V K Cc: bjorn.andersson@linaro.org, adrian.hunter@intel.com, robh+dt@kernel.org, ulf.hansson@linaro.org, asutoshd@codeaurora.org, stummala@codeaurora.org, sayalil@codeaurora.org, rampraka@codeaurora.org, vbadigan@codeaurora.org, sboyd@kernel.org, georgi.djakov@linaro.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, agross@kernel.org, linux-mmc-owner@vger.kernel.org, Subhash Jadavani Subject: Re: [RFC v5 1/2] mmc: sdhci-msm: Add interconnect bus bandwidth scaling support Message-ID: <20200312204935.GF144492@google.com> References: <1583992911-12001-1-git-send-email-ppvk@codeaurora.org> <1583992911-12001-2-git-send-email-ppvk@codeaurora.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <1583992911-12001-2-git-send-email-ppvk@codeaurora.org> User-Agent: Mutt/1.12.2 (2019-09-21) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Pradeep, On Thu, Mar 12, 2020 at 11:31:50AM +0530, Pradeep P V K wrote: > Add interconnect bandwidths for SDHC driver using OPP framework that > is required by SDHC driver based on the clock frequency and bus width > of the card. Otherwise, the system clocks may run at minimum clock > speed and thus affecting the performance. > > This change is based on > [RFC] mmc: host: sdhci-msm: Use the interconnect API > (https://lkml.org/lkml/2018/10/11/499) and > > [PATCH v6] Introduce Bandwidth OPPs for interconnects > (https://lkml.org/lkml/2019/12/6/740) > > Co-developed-by: Sahitya Tummala > Signed-off-by: Sahitya Tummala > Co-developed-by: Subhash Jadavani > Signed-off-by: Subhash Jadavani > Co-developed-by: Veerabhadrarao Badiganti > Signed-off-by: Veerabhadrarao Badiganti > Co-developed-by: Pradeep P V K > Signed-off-by: Pradeep P V K > --- > > RFC v4 -> v5: > - Rewrote the icc interconnect get handlers and its error handling > and allocated vote data after handling all icc get handler errors. > - Removed explicit error check on ICC handlers. > - Addressed minor code style comments. > > drivers/mmc/host/sdhci-msm.c | 231 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 227 insertions(+), 4 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c > index 09ff731..5fe8fad 100644 > --- a/drivers/mmc/host/sdhci-msm.c > +++ b/drivers/mmc/host/sdhci-msm.c > > ... > > +/* > + * This function sets the interconnect bus bandwidth > + * vote based on bw (bandwidth) argument. > + */ > +#define BUS_INTERCONNECT_PATHS 2 /* 1. sdhc -> ddr 2. cpu -> sdhc */ > +static void sdhci_msm_bus_set_vote(struct sdhci_host *host, > + unsigned int bw) > +{ > + int i, err; > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); > + struct sdhci_msm_bus_vote_data *vote_data = msm_host->bus_vote_data; > + struct device *dev = &msm_host->pdev->dev; > + struct dev_pm_opp *opp; > + unsigned long freq = bw; > + unsigned long peak_bw[BUS_INTERCONNECT_PATHS] = {0}; > + unsigned long avg_bw[BUS_INTERCONNECT_PATHS] = {0}; > + > + if (bw == vote_data->curr_freq) > + return; > + > + for (i = 0; i < BUS_INTERCONNECT_PATHS; i++) { > + opp = sdhci_msm_find_opp_for_freq(msm_host, freq); > + if (opp) { > + avg_bw[i] = dev_pm_opp_get_bw(opp, &peak_bw[i]); > + freq += 1; /* Next bandwidth vote */ > + dev_pm_opp_put(opp); > + } > + } > + pr_debug("%s: freq:%d sdhc_to_ddr avg_bw:%lu peak_bw:%lu cpu_to_sdhc avg_bw:%lu peak_bw:%lu\n", > + mmc_hostname(host->mmc), bw, avg_bw[0], peak_bw[0], > + avg_bw[1], peak_bw[1]); > + err = icc_set_bw(vote_data->sdhc_to_ddr, 0, peak_bw[0]); > + if (err) { > + dev_err(dev, "icc_set() failed for 'sdhc-ddr' path err:%d\n", > + err); nit: the alignment is odd, either align with 'dev' or a tab after 'dev_err' > + return; > + } > + err = icc_set_bw(vote_data->cpu_to_sdhc, 0, peak_bw[1]); > + if (err) { > + dev_err(dev, "icc_set() failed for 'cpu-sdhc' path err:%d\n", > + err); ditto > + return; > + } > + vote_data->curr_freq = bw; > +} > + > +/* > + * Helper function to register for OPP and interconnect > + * frameworks. > + */ > +static struct sdhci_msm_bus_vote_data > + *sdhci_msm_bus_register(struct sdhci_msm_host *host, > + struct platform_device *pdev) > +{ > + struct sdhci_msm_bus_vote_data *vote_data; > + struct device *dev = &pdev->dev; > + int ret, i, err; nit: you can get rid of 'ret' and use 'err' instead. > + struct icc_path *icc_paths[BUS_INTERCONNECT_PATHS]; > + const char *path_names[] = { > + "sdhc-ddr", > + "cpu-sdhc", > + }; > + > + for (i = 0; i < BUS_INTERCONNECT_PATHS; i++) > + icc_paths[i] = of_icc_get(&pdev->dev, path_names[i]); > + > + if (!icc_paths[0] && !icc_paths[1]) { > + dev_info(&pdev->dev, "ICC DT property is missing.Skip vote!!\n"); > + return NULL; > + } > + > + for (i = 0; i < BUS_INTERCONNECT_PATHS; i++) { > + if (!icc_paths[i]) { > + dev_err(&pdev->dev, "interconnect path '%s' is not configured\n", > + path_names[i]); > + err = -EINVAL; > + goto handle_err; > + } > + if (IS_ERR(icc_paths[i])) { > + err = PTR_ERR(icc_paths[i]); > + > + if (err != -EPROBE_DEFER) > + dev_err(&pdev->dev, "interconnect path '%s' is invalid:%d\n", > + path_names[i], err); > + goto handle_err; > + } > + } > + > + ret = dev_pm_opp_of_add_table(dev); > + if (ret) { > + if (ret == -ENODEV || ret == -ENODATA) > + dev_err(dev, "OPP dt properties missing:%d\n", ret); > + else > + dev_err(dev, "OPP registration failed:%d\n", ret); need to call icc_put() for the two paths? > + return ERR_PTR(ret); > + } > + > + vote_data = devm_kzalloc(dev, sizeof(*vote_data), GFP_KERNEL); > + if (!vote_data) ditto probably you want to do this with a jump to an error handler below. > + return ERR_PTR(-ENOMEM); > + > + vote_data->sdhc_to_ddr = icc_paths[0]; > + vote_data->cpu_to_sdhc = icc_paths[1]; > + return vote_data; nit: add empty line > +handle_err: > + if (err) { > + int other = (i == 0) ? 1 : 0; > + > + if (!IS_ERR_OR_NULL(icc_paths[other])) > + icc_put(icc_paths[other]); > + } doing this at the end (as opposed to my suggestion from https://patchwork.kernel.org/patch/11388409/#23165321) has the advantage of keeping the above loop cleaner from error handling cruft, on the downside it is probably easier to understand right away in the context of the loop. I guess you can do it either way. It might get a bit more messy if you also handle the case where both paths are valid. If that gets too involved I'd suggest to hnadle the above case inside the loop. > + return ERR_PTR(err); > +} > + > +static void sdhci_msm_bus_unregister(struct device *dev, > + struct sdhci_msm_host *host) > +{ > + struct sdhci_msm_bus_vote_data *vote_data = host->bus_vote_data; > + > + if (IS_ERR_OR_NULL(vote_data)) I think 'if (!vote_data)' would be sufficient, since _probe() aborts in case of an error. > + return; > + > + icc_put(vote_data->sdhc_to_ddr); > + icc_put(vote_data->cpu_to_sdhc); > +} > + > +static void sdhci_msm_bus_voting(struct sdhci_host *host, bool enable) > +{ > + struct mmc_ios *ios = &host->mmc->ios; > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); > + unsigned int bw; > + > + if (IS_ERR_OR_NULL(msm_host->bus_vote_data)) > + return; ditto