From: Tomasz Figa <t.figa@samsung.com>
To: Chanwoo Choi <cw00.choi@samsung.com>,
myungjoo.ham@samsung.com, kyungmin.park@samsung.com
Cc: rafael.j.wysocki@intel.com, nm@ti.com, b.zolnierkie@samsaung.com,
pawel.moll@arm.com, mark.rutland@arm.com, swarren@wwwdotorg.org,
ijc+devicetree@hellion.org.uk, linux-pm@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org
Subject: Re: [PATCHv2 3/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control
Date: Fri, 14 Mar 2014 18:42:16 +0100 [thread overview]
Message-ID: <53233F78.8020500@samsung.com> (raw)
In-Reply-To: <1394698649-20996-4-git-send-email-cw00.choi@samsung.com>
Hi Chanwoo,
On 13.03.2014 09:17, Chanwoo Choi wrote:
> There are not the clock controller of ppmudmc0/1. This patch control the clock
> of ppmudmc0/1 which is used for monitoring memory bus utilization.
>
> Also, this patch code clean about regulator control and free resource
> when calling exit/remove function.
>
> For example,
> busfreq@106A0000 {
> compatible = "samsung,exynos4x12-busfreq";
>
> /* Clock for PPMUDMC0/1 */
> clocks = <&clock CLK_PPMUDMC0>, <&clock CLK_PPMUDMC1>;
> clock-names = "ppmudmc0", "ppmudmc1";
>
> /* Regulator for MIF/INT block */
> vdd_mif-supply = <&buck1_reg>;
> vdd_int-supply = <&buck3_reg>;
> };
>
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
> drivers/devfreq/exynos/exynos4_bus.c | 114 ++++++++++++++++++++++++++++++-----
> 1 file changed, 100 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
> index 1a0effa..a2a3a47 100644
> --- a/drivers/devfreq/exynos/exynos4_bus.c
> +++ b/drivers/devfreq/exynos/exynos4_bus.c
> @@ -62,6 +62,11 @@ enum exynos_ppmu_idx {
> PPMU_END,
> };
>
> +static const char *exynos_ppmu_clk_name[] = {
> + [PPMU_DMC0] = "ppmudmc0",
> + [PPMU_DMC1] = "ppmudmc1",
> +};
> +
> #define EX4210_LV_MAX LV_2
> #define EX4x12_LV_MAX LV_4
> #define EX4210_LV_NUM (LV_2 + 1)
> @@ -86,6 +91,7 @@ struct busfreq_data {
> struct regulator *vdd_mif; /* Exynos4412/4212 only */
> struct busfreq_opp_info curr_oppinfo;
> struct exynos_ppmu ppmu[PPMU_END];
> + struct clk *clk_ppmu[PPMU_END];
>
> struct notifier_block pm_notifier;
> struct mutex lock;
> @@ -722,8 +728,26 @@ static int exynos4_bus_get_dev_status(struct device *dev,
> static void exynos4_bus_exit(struct device *dev)
> {
> struct busfreq_data *data = dev_get_drvdata(dev);
> + int i;
> +
> + /*
> + * Un-map memory map and disable regulator/clocks
> + * to prevent power leakage.
> + */
> + regulator_disable(data->vdd_int);
> + if (data->type == TYPE_BUSF_EXYNOS4x12)
> + regulator_disable(data->vdd_mif);
> +
> + for (i = 0; i < PPMU_END; i++) {
> + if (data->clk_ppmu[i])
This check is invalid. Clock pointers must be checked for validity using
the IS_ERR() macro, because NULL is a valid clock pointer value
indicating a dummy clock.
> + clk_disable_unprepare(data->clk_ppmu[i]);
> + }
>
> - devfreq_unregister_opp_notifier(dev, data->devfreq);
> + for (i = 0; i < PPMU_END; i++) {
> + if (data->ppmu[i].hw_base)
Can this even happen? Is there a PPMU without registers?
> + iounmap(data->ppmu[i].hw_base);
> +
> + }
> }
>
> static struct devfreq_dev_profile exynos4_devfreq_profile = {
> @@ -987,6 +1011,7 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data)
> {
> struct device *dev = data->dev;
> struct device_node *np = dev->of_node;
> + const char **clk_name = exynos_ppmu_clk_name;
> int i, ret;
>
> if (!np) {
> @@ -1005,8 +1030,70 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data)
> }
> }
>
> + /*
> + * Get PPMU's clocks to control them. But, if PPMU's clocks
> + * is default 'pass' state, this driver don't need control
> + * PPMU's clock.
> + */
> + for (i = 0; i < PPMU_END; i++) {
> + data->clk_ppmu[i] = devm_clk_get(dev, clk_name[i]);
> + if (IS_ERR_OR_NULL(data->clk_ppmu[i])) {
Again, this check is invalid. Only IS_ERR() is the correct way to check
whether returned clock pointer is valid.
> + dev_warn(dev, "Cannot get %s clock\n", clk_name[i]);
> + data->clk_ppmu[i] = NULL;
This assignment is wrong. To allow further checking whether the clock
was found the value returned from devm_clk_get() must be retained and
then IS_ERR() used in further code.
However, I believe it should be an error if a clock is not provided. The
driver must make sure that PPMU clocks are ungated before trying to
access them, otherwise the system might hang.
> + }
> +
> + ret = clk_prepare_enable(data->clk_ppmu[i]);
The code above allows the clock to be skipped, but this line doesn't
check whether it is valid. Still, I think the clock should be always
required.
> + if (ret < 0) {
> + dev_warn(dev, "Cannot enable %s clock\n", clk_name[i]);
> + data->clk_ppmu[i] = NULL;
> + goto err_clocks;
> + }
> + }
> +
> + /* Get regulator to control voltage of int block */
> + data->vdd_int = devm_regulator_get(dev, "vdd_int");
> + if (IS_ERR(data->vdd_int)) {
> + dev_err(dev, "Failed to get the regulator of vdd_int\n");
> + ret = PTR_ERR(data->vdd_int);
> + goto err_clocks;
> + }
> + ret = regulator_enable(data->vdd_int);
> + if (ret < 0) {
> + dev_err(dev, "Failed to enable regulator of vdd_int\n");
> + goto err_clocks;
> + }
> +
> + switch (data->type) {
> + case TYPE_BUSF_EXYNOS4210:
> + break;
> + case TYPE_BUSF_EXYNOS4x12:
> + /* Get regulator to control voltage of mif blk if Exynos4x12 */
> + data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
> + if (IS_ERR(data->vdd_mif)) {
> + dev_err(dev, "Failed to get the regulator vdd_mif\n");
> + ret = PTR_ERR(data->vdd_mif);
> + goto err_regulator;
> + }
> + ret = regulator_enable(data->vdd_mif);
> + if (ret < 0) {
> + dev_err(dev, "Failed to enable regulator of vdd_mif\n");
> + goto err_regulator;
> + }
> + break;
> + default:
> + dev_err(dev, "Unknown device type : %d\n", data->type);
> + return -EINVAL;
> + };
> +
> return 0;
>
> +err_regulator:
> + regulator_disable(data->vdd_int);
> +err_clocks:
> + for (i = 0; i < PPMU_END; i++) {
> + if (data->clk_ppmu[i])
Invalid check.
Best regards,
Tomasz
next prev parent reply other threads:[~2014-03-14 17:42 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-13 8:17 [PATCHv2 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 1/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 2/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 3/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control Chanwoo Choi
2014-03-14 17:42 ` Tomasz Figa [this message]
2014-03-17 2:51 ` Chanwoo Choi
2014-03-17 5:35 ` Chanwoo Choi
2014-03-17 5:59 ` Chanwoo Choi
2014-03-18 11:13 ` Tomasz Figa
2014-03-19 2:44 ` Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 4/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe() Chanwoo Choi
2014-03-14 17:49 ` Tomasz Figa
2014-03-17 5:05 ` Chanwoo Choi
2014-03-18 12:18 ` Tomasz Figa
2014-03-19 2:46 ` Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state Chanwoo Choi
2014-03-14 17:52 ` Tomasz Figa
2014-03-17 2:58 ` Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail Chanwoo Choi
2014-03-13 8:17 ` [PATCHv2 8/8] devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12 Chanwoo Choi
2014-03-13 16:50 ` Bartlomiej Zolnierkiewicz
2014-03-13 17:53 ` Mark Rutland
2014-03-14 7:14 ` Chanwoo Choi
2014-03-14 10:35 ` Mark Rutland
2014-03-14 10:56 ` Chanwoo Choi
2014-03-14 17:35 ` Tomasz Figa
2014-03-15 11:36 ` Kyungmin Park
2014-03-15 12:41 ` Tomasz Figa
2014-03-17 5:19 ` Chanwoo Choi
2014-03-18 15:46 ` Tomasz Figa
[not found] ` <53286A6C.5090108-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2014-03-19 9:47 ` Chanwoo Choi
2014-03-19 9:47 ` Chanwoo Choi
2014-03-19 10:23 ` Tomasz Figa
2014-03-13 16:43 ` [PATCHv2 0/8] devfreq: exynos4: Support dt and use common ppmu driver Bartlomiej Zolnierkiewicz
2014-03-14 3:14 ` Chanwoo Choi
2014-03-14 10:47 ` Bartlomiej Zolnierkiewicz
2014-03-17 1:56 ` Chanwoo Choi
2014-03-14 17:58 ` Tomasz Figa
2014-03-17 1:58 ` Chanwoo Choi
2014-03-18 15:47 ` Tomasz Figa
2014-07-09 13:06 ` Tomeu Vizoso
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=53233F78.8020500@samsung.com \
--to=t.figa@samsung.com \
--cc=b.zolnierkie@samsaung.com \
--cc=cw00.choi@samsung.com \
--cc=devicetree@vger.kernel.org \
--cc=ijc+devicetree@hellion.org.uk \
--cc=kyungmin.park@samsung.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=myungjoo.ham@samsung.com \
--cc=nm@ti.com \
--cc=pawel.moll@arm.com \
--cc=rafael.j.wysocki@intel.com \
--cc=swarren@wwwdotorg.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.