From: andrew-sh.cheng <andrew-sh.cheng@mediatek.com>
To: Chanwoo Choi <cw00.choi@samsung.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
devicetree@vger.kernel.org, srv_heupstream@mediatek.com,
linux-pm@vger.kernel.org, Viresh Kumar <viresh.kumar@linaro.org>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
fan.chen@mediatek.com, Kyungmin Park <kyungmin.park@samsung.com>,
MyungJoo Ham <myungjoo.ham@samsung.com>,
linux-mediatek@lists.infradead.org,
Matthias Brugger <matthias.bgg@gmail.com>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2 4/4] devfreq: add mediatek cci devfreq
Date: Fri, 10 May 2019 17:24:32 +0800 [thread overview]
Message-ID: <1557480272.7664.3.camel@mtksdaap41> (raw)
In-Reply-To: <e9eaa131-5791-c844-a02f-1bdd46719768@samsung.com>
On Tue, 2019-04-16 at 18:05 +0900, Chanwoo Choi wrote:
> Hi Andrew-sh.Cheng,
>
> Please add the dt-binding documentation.
>
> On 19. 3. 29. 오후 3:46, Andrew-sh.Cheng wrote:
> > This adds a devfreq driver for the Cache Coherent Interconnect (CCI)
> > of the Mediatek MT8183.
> >
> > On the MT8183 the CCI is supplied by the same regulator as the LITTLE
> > cores. The driver is notified when the regulator voltage changes
> > (driven by cpufreq) and adjusts the CCI frequency to the maximum
> > possible value.
> >
> > Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
> > ---
> > drivers/devfreq/Kconfig | 10 ++
> > drivers/devfreq/Makefile | 1 +
> > drivers/devfreq/mt8183-cci-devfreq.c | 235 +++++++++++++++++++++++++++++++++++
> > 3 files changed, 246 insertions(+)
> > create mode 100644 drivers/devfreq/mt8183-cci-devfreq.c
> >
> > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> > index 6a172d3..da2f8ec 100644
> > --- a/drivers/devfreq/Kconfig
> > +++ b/drivers/devfreq/Kconfig
> > @@ -91,6 +91,16 @@ config ARM_EXYNOS_BUS_DEVFREQ
> > and adjusts the operating frequencies and voltages with OPP support.
> > This does not yet operate with optimal voltages.
> >
> > +config ARM_MT8183_CCI_DEVFREQ
> > + tristate "MT8183 CCI DEVFREQ Driver"
> > + depends on ARM_MEDIATEK_CPUFREQ
> > + help
> > + This adds a devfreq driver for Cache Coherent Interconnect
> > + of Mediatek MT8183, which is shared the same regulator
> > + with cpu cluster.
> > + It can track buck voltage and update a proper cci frequency.
> > + Use notification to get regulator status.
> > +
> > config ARM_TEGRA_DEVFREQ
> > tristate "Tegra DEVFREQ Driver"
> > depends on ARCH_TEGRA_124_SOC
> > diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
> > index 32b8d4d..817dde7 100644
> > --- a/drivers/devfreq/Makefile
> > +++ b/drivers/devfreq/Makefile
> > @@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o
> >
> > # DEVFREQ Drivers
> > obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
> > +obj-$(CONFIG_ARM_MT8183_CCI_DEVFREQ) += mt8183-cci-devfreq.o
> > obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
> > obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra-devfreq.o
> >
> > diff --git a/drivers/devfreq/mt8183-cci-devfreq.c b/drivers/devfreq/mt8183-cci-devfreq.c
> > new file mode 100644
> > index 0000000..af82d2e
> > --- /dev/null
> > +++ b/drivers/devfreq/mt8183-cci-devfreq.c
> > @@ -0,0 +1,235 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019 MediaTek Inc.
>
> You can add the author information under copyright information.
ok~
>
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/devfreq.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regulator/consumer.h>
> > +
> > +#include "governor.h"
> > +
> > +struct cci_devfreq {
> > + struct devfreq *devfreq;
> > + struct regulator *proc_reg;
> > + unsigned long proc_reg_uV;
> > + struct clk *cci_clk;
> > + struct notifier_block nb;
>
> Just use the space instead of tab as following:
>
> struct devfreq *devfreq;
> struct regulator *proc_reg;
> unsigned long proc_reg_uV;
> struct clk *cci_clk;
> struct notifier_block nb;
>
OK, I will modify at next patch.
> > +};
> > +
> > +static int cci_devfreq_regulator_notifier(struct notifier_block *nb,
> > + unsigned long val, void *data)
> > +{
> > + struct cci_devfreq *cci_df =
> > + container_of(nb, struct cci_devfreq, nb);
> > +
> > + /* deal with reduce frequency */
> > + if (val & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
> > + struct pre_voltage_change_data *pvc_data = data;
> > +
> > + if (pvc_data->min_uV < pvc_data->old_uV) {
> > + cci_df->proc_reg_uV =
> > + (unsigned long)(pvc_data->min_uV);
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
>
> Please handle the return value of update_devfreq() for exception handling.
OK, I will modify at next patch.
>
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > + }
> > +
> > + if ((val & REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE) &&
>
> if -> else if
>
> At the same time, receives only one notification.
> It is not necessary to check the two if statement always, .
OK, I will modify at next patch.
>
>
> > + ((unsigned long)data > cci_df->proc_reg_uV)) {
> > + cci_df->proc_reg_uV = (unsigned long)data;
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
>
> ditto. Please check the return value of update_devfreq.
OK, I will modify at next patch.
>
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > +
> > + /* deal with increase frequency */
> > + if ((val & REGULATOR_EVENT_VOLTAGE_CHANGE) &&
>
> ditto.
> if -> else if
>
> At the same time, receives only one notification.
> It is not necessary to check the two if statement always, .
OK, I will modify at next patch.
>
>
> > + (cci_df->proc_reg_uV < (unsigned long)data)) {
> > + cci_df->proc_reg_uV = (unsigned long)data;
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
>
> ditto. Please check the return value of update_devfreq.
OK, I will modify at next patch.
>
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_cci_governor_get_target(struct devfreq *devfreq,
> > + unsigned long *freq)
> > +{
> > + struct cci_devfreq *cci_df;
> > + struct dev_pm_opp *opp;
> > +
> > + cci_df = dev_get_drvdata(devfreq->dev.parent);
> > +
> > + /* find available frequency */
> > + opp = dev_pm_opp_find_max_freq_by_volt(devfreq->dev.parent,
> > + cci_df->proc_reg_uV);
> > + *freq = dev_pm_opp_get_freq(opp);
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_cci_governor_event_handler(struct devfreq *devfreq,
> > + unsigned int event, void *data)
> > +{
> > + struct cci_devfreq *cci_df;
> > + struct notifier_block *nb;
> > +
> > + cci_df = dev_get_drvdata(devfreq->dev.parent);
> > + nb = &cci_df->nb;
> > +
> > + switch (event) {
> > + case DEVFREQ_GOV_START:
> > + case DEVFREQ_GOV_RESUME:
> > + nb->notifier_call = cci_devfreq_regulator_notifier;
> > + regulator_register_notifier(cci_df->proc_reg,
> > + nb);
>
> Please check the return value of regulator_register_notifier
> in order to handle the exception handling.
OK, I will modify at next patch.
>
>
> > + break;
> > +
> > + case DEVFREQ_GOV_STOP:
> > + case DEVFREQ_GOV_SUSPEND:
> > + regulator_unregister_notifier(cci_df->proc_reg,
> > + nb);
>
> ditto.
>
> > +
>
> Remove unneeded blank line.
OK, I will modify at next patch.
>
> > + break;
> > +
> > + default:
> > + break;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static struct devfreq_governor mtk_cci_devfreq_governor = {
> > + .name = "mtk_cci_vmon",
>
> How about editing the name from mtk_cci_vmon to mediatek_cci_voltage_monitor
> for the readability? Actually, 'mtk' and 'vmon' are not standard expression.
The srting of name is only [16], I'll leave it as mtk_cci_vmon.
>
> > + .get_target_freq = mtk_cci_governor_get_target,
> > + .event_handler = mtk_cci_governor_event_handler,
>
> Please add following code to make it as the immutable
> because the governor for this driver will not be changed
> through sysfs interface.
>
> .immutable = true
OK, I will modify at next patch.
>
> > +};
> > +
> > +static int mtk_cci_devfreq_target(struct device *dev, unsigned long *freq,
> > + u32 flags)
> > +{
> > + struct cci_devfreq *cci_df = dev_get_drvdata(dev);
> > +
> > + if (!cci_df)
> > + return -EINVAL;
> > +
> > + clk_set_rate(cci_df->cci_clk, *freq);
>
> Please check the return value of clk_set_rate().
OK, I will modify at next patch.
>
> > +
> > + return 0;
> > +}
> > +
> > +static struct devfreq_dev_profile cci_devfreq_profile = {
> > + .target = mtk_cci_devfreq_target,
>
> Just use the space instead of tab because cci_devfreq_profile
> only has one record.
>
> .target = mtk_cci_devfreq_target,
OK, I will modify at next patch.
>
> > +};
> > +
> > +static int mtk_cci_devfreq_probe(struct platform_device *pdev)
> > +{
> > + struct device *cci_dev = &pdev->dev;
> > + struct cci_devfreq *cci_df;
> > + int ret;
> > +
> > + cci_df = devm_kzalloc(cci_dev, sizeof(*cci_df), GFP_KERNEL);
> > + if (!cci_df)
> > + return -ENOMEM;
> > +
> > + cci_df->cci_clk = clk_get(cci_dev, "cci_clock");
>
> clk_get -> devm_clk_get()
OK, I will modify at next patch.
>
> > + ret = PTR_ERR_OR_ZERO(cci_df->cci_clk);
> > + if (ret) {
> > + if (ret != -EPROBE_DEFER)
> > + dev_err(cci_dev, "failed to get clock for CCI: %d\n",
> > + ret);
> > +
>
> Remove unneeded blank line.
>
> > + return ret;
> > + }> +
> > + cci_df->proc_reg = regulator_get_optional(cci_dev, "proc");
>
>
> regulator_get_optional -> devm_regulator_get_optional
OK, I will modify at next patch.
>
> > + ret = PTR_ERR_OR_ZERO(cci_df->proc_reg);
> > + if (ret) {
> > + if (ret != -EPROBE_DEFER)
> > + dev_err(cci_dev, "failed to get regulator for CCI: %d\n",
> > + ret);
> > +
>
> Remove unneeded blank line.
>
> > + goto err_put_clk;
>
> If you use devm_clk_get(), just return instead of goto.
OK, I will rewrite these code.
>
> > + }
> > +
> > + ret = dev_pm_opp_of_add_table(&pdev->dev);
> > + if (ret) {
> > + dev_err(cci_dev, "Fail to init CCI OPP table\n");
> > + goto err_put_reg;
> > + }
> > +
> > + platform_set_drvdata(pdev, cci_df);
> > +
> > + cci_df->devfreq = devm_devfreq_add_device(cci_dev,
> > + &cci_devfreq_profile,
> > + "mtk_cci_vmon",
> > + NULL);
> > + if (IS_ERR(cci_df->devfreq)) {
> > + dev_err(cci_dev, "cannot create cci devfreq device\n", ret);
> > + goto err_put_reg;
> > + }
> > +
> > + return 0;
> > +
> > +err_put_reg:
> > + regulator_put(cci_df->proc_reg);
> > +err_put_clk:
> > + clk_put(cci_df->cci_clk);
>
> If you use devm_clk_get()/devm_regulator_get(),
> 'err_put_reg' and 'err_put_clk' are unneeded.
OK, I will rewrite these code.
>
> > +
> > + return ret;
> > +}
> > +
> > +static const struct of_device_id mediatek_cci_devfreq_of_match[] = {
> > + { .compatible = "mediatek,mt8183-cci" },
> > + { },
> > +};
> > +MODULE_DEVICE_TABLE(of, mediatek_cci_devfreq_of_match);
> > +
> > +static struct platform_driver cci_devfreq_driver = {
> > + .probe = mtk_cci_devfreq_probe,
> > + .driver = {
> > + .name = "mediatek-cci-devfreq",
> > + .of_match_table = mediatek_cci_devfreq_of_match,
> > + },
> > +};
> > +
> > +static int __init mtk_cci_devfreq_init(void)
> > +{
> > + int ret;
> > +
> > + ret = devfreq_add_governor(&mtk_cci_devfreq_governor);
> > + if (ret) {
> > + pr_err("%s: failed to add governor: %d\n", __func__, ret);
> > + return ret;
> > + }
> > +
> > + ret = platform_driver_register(&cci_devfreq_driver);
> > + if (ret)
> > + devfreq_remove_governor(&mtk_cci_devfreq_governor);
> > +
> > + return ret;
> > +}
> > +module_init(mtk_cci_devfreq_init)
> > +
> > +static void __exit mtk_cci_devfreq_exit(void)
> > +{
> > + int ret;
> > +
> > + ret = devfreq_remove_governor(&mtk_cci_devfreq_governor);
> > + if (ret)
> > + pr_err("%s: failed to remove governor: %d\n", __func__, ret);
> > +
> > + platform_driver_unregister(&cci_devfreq_driver);
> > +}
> > +module_exit(mtk_cci_devfreq_exit)
> > +
> > +MODULE_DESCRIPTION("Mediatek CCI devfreq driver");
> > +MODULE_AUTHOR("Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>");
> > +MODULE_LICENSE("GPL v2");
> >
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-05-10 9:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-29 6:46 [PATCH v2 0/4] Add cpufreq and cci devfreq for mt8183 Andrew-sh.Cheng
2019-03-29 6:46 ` [PATCH v2 3/4] dt-bindings: devfreq: add compatible for mt8183 cci devfreq Andrew-sh.Cheng
2019-04-16 9:08 ` Chanwoo Choi
[not found] ` <28f2c90a-9588-3afa-193d-2572c9cc9bf5-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2019-05-08 9:27 ` andrew-sh.cheng
[not found] ` <1553841972-19737-1-git-send-email-andrew-sh.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2019-03-29 6:46 ` [PATCH v2 1/4] cpufreq: mediatek: add mt8183 cpufreq support Andrew-sh.Cheng
2019-03-31 0:06 ` Nicolas Boichat
2019-04-13 2:33 ` andrew-sh.cheng
2019-03-29 6:46 ` [PATCH v2 2/4] opp: add API which get max freq by voltage Andrew-sh.Cheng
2019-04-03 4:32 ` Nicolas Boichat
2019-04-13 4:39 ` andrew-sh.cheng
2019-04-10 6:29 ` Viresh Kumar
2022-06-02 6:54 ` Viresh Kumar
2019-03-29 6:46 ` [PATCH v2 4/4] devfreq: add mediatek cci devfreq Andrew-sh.Cheng
2019-04-08 17:22 ` [v2,4/4] " Guenter Roeck
2019-04-13 7:07 ` andrew-sh.cheng
2019-04-16 9:05 ` [PATCH v2 4/4] " Chanwoo Choi
2019-05-10 9:24 ` andrew-sh.cheng [this message]
[not found] ` <CGME20190329064632epcas2p4d10ea099bfea4ad682d7312a75bfbe68@epcms1p8>
2019-04-01 2:30 ` [PATCH v2 2/4] opp: add API which get max freq by voltage MyungJoo Ham
2019-04-13 3:36 ` andrew-sh.cheng
[not found] ` <CGME20190329064636epcas1p13633ae078ef83ceda0b8189df1399753@epcms1p1>
2019-04-01 4:18 ` [PATCH v2 4/4] devfreq: add mediatek cci devfreq MyungJoo Ham
2019-04-13 5:54 ` andrew-sh.cheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1557480272.7664.3.camel@mtksdaap41 \
--to=andrew-sh.cheng@mediatek.com \
--cc=cw00.choi@samsung.com \
--cc=devicetree@vger.kernel.org \
--cc=fan.chen@mediatek.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=matthias.bgg@gmail.com \
--cc=myungjoo.ham@samsung.com \
--cc=rjw@rjwysocki.net \
--cc=robh+dt@kernel.org \
--cc=srv_heupstream@mediatek.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).