linux-samsung-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-samsung-soc <linux-samsung-soc@vger.kernel.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	Inki Dae <inki.dae@samsung.com>,
	Chanwoo Choi <cw00.choi@samsung.com>,
	Sylwester Nawrocki <s.nawrocki@samsung.com>,
	linux-clk <linux-clk@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v5 3/4] clk: samsung: exynos5433: Add runtime PM support
Date: Wed, 22 Mar 2017 09:26:09 +0100	[thread overview]
Message-ID: <68edccfb-c86d-3412-82f4-2a5183f4a16c@samsung.com> (raw)
In-Reply-To: <CAPDyKFotSo5qcJPt9w99Rf3i_kvQnBZE36iBbfDfuBkiKhsoTw@mail.gmail.com>

Hi Ulf,

On 2017-03-13 14:31, Ulf Hansson wrote:
> On 25 January 2017 at 12:53, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Add runtime pm support for all clock controller units (CMU), which belongs
>> to power domains and require special handling during on/off operations.
>> Typically special values has to be written to MUX registers to change
>> internal clocks parents to OSC clock before turning power off. During such
>> operation all clocks, which enters CMU has to be enabled to let MUX to
>> stabilize. Also for each CMU there is one special parent clock, which has
>> to be enabled all the time when any access to CMU registers is done.
>>
>> This patch solves most of the mysterious external abort and freeze issues
>> caused by a lack of proper parent CMU clock enabled or incorrect turn off
>> procedure.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---

Thanks for your review!

> [...]
>> --- a/drivers/clk/samsung/clk-exynos5433.c
>> +++ b/drivers/clk/samsung/clk-exynos5433.c
>> @@ -9,9 +9,14 @@
>>    * Common Clock Framework support for Exynos5443 SoC.
>>    */
>>
>> +#include <linux/clk.h>
>>   #include <linux/clk-provider.h>
>>   #include <linux/of.h>
>>   #include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/slab.h>
>>
>>   #include <dt-bindings/clock/exynos5433.h>
>>
> [...]
>
>> +struct exynos5433_cmu_data {
>> +       struct samsung_clk_provider ctx;
>> +
>> +       struct samsung_clk_reg_dump *clk_save;
>> +       unsigned int nr_clk_save;
>> +       const struct samsung_clk_reg_dump *clk_suspend;
>> +       unsigned int nr_clk_suspend;
>> +
>> +       struct clk *clk;
>> +       struct clk **pclks;
>> +       int nr_pclks;
>> +};
>> +
>> +static int exynos5433_cmu_suspend(struct device *dev)
>> +{
>> +       struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
>> +       int i;
>> +
>> +       samsung_clk_save(data->ctx.reg_base, data->clk_save,
>> +                        data->nr_clk_save);
>> +
>> +       for (i = 0; i < data->nr_pclks; i++)
>> +               clk_enable(data->pclks[i]);
>> +
>> +       samsung_clk_restore(data->ctx.reg_base, data->clk_suspend,
>> +                           data->nr_clk_suspend);
>> +
>> +       for (i = 0; i < data->nr_pclks; i++)
>> +               clk_disable(data->pclks[i]);
>> +
>> +       clk_disable(data->clk);
>> +
>> +       return 0;
>> +}
>> +
>> +static int exynos5433_cmu_resume(struct device *dev)
>> +{
>> +       struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
>> +       int i;
>> +
>> +       clk_enable(data->clk);
>> +
>> +       for (i = 0; i < data->nr_pclks; i++)
>> +               clk_enable(data->pclks[i]);
>> +
>> +       samsung_clk_restore(data->ctx.reg_base, data->clk_save,
>> +                           data->nr_clk_save);
>> +
>> +       for (i = 0; i < data->nr_pclks; i++)
>> +               clk_disable(data->pclks[i]);
>> +
>> +       return 0;
>> +}
>> +
>> +static int __init exynos5433_cmu_probe(struct platform_device *pdev)
>> +{
>> +       const struct samsung_cmu_info *info;
>> +       struct exynos5433_cmu_data *data;
>> +       struct samsung_clk_provider *ctx;
>> +       struct device *dev = &pdev->dev;
>> +       struct resource *res;
>> +       void __iomem *reg_base;
>> +       struct clk **clk_table;
>> +       int i;
>> +
>> +       info = of_device_get_match_data(dev);
>> +
>> +       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>> +       if (!data)
>> +               return -ENOMEM;
>> +       ctx = &data->ctx;
>> +
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       reg_base = devm_ioremap_resource(dev, res);
>> +       if (!reg_base) {
>> +               dev_err(dev, "failed to map registers\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       clk_table = devm_kcalloc(dev, info->nr_clk_ids, sizeof(struct clk *),
>> +                                GFP_KERNEL);
>> +       if (!clk_table)
>> +               return -ENOMEM;
>> +
>> +       for (i = 0; i < info->nr_clk_ids; ++i)
>> +               clk_table[i] = ERR_PTR(-ENOENT);
>> +
>> +       ctx->clk_data.clks = clk_table;
>> +       ctx->clk_data.clk_num = info->nr_clk_ids;
>> +       ctx->reg_base = reg_base;
>> +       ctx->dev = dev;
>> +       spin_lock_init(&ctx->lock);
>> +
>> +       data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
>> +                                                   info->nr_clk_regs);
>> +       data->nr_clk_save = info->nr_clk_regs;
>> +       data->clk_suspend = info->suspend_regs;
>> +       data->nr_clk_suspend = info->nr_suspend_regs;
>> +       data->nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks",
>> +                                                   "#clock-cells");
>> +       if (data->nr_pclks > 0) {
>> +               data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
>> +                                          data->nr_pclks, GFP_KERNEL);
>> +
>> +               for (i = 0; i < data->nr_pclks; i++) {
>> +                       struct clk *clk = of_clk_get(dev->of_node, i);
>> +
>> +                       if (IS_ERR(clk))
>> +                               return PTR_ERR(clk);
>> +                       data->pclks[i] = clk;
>> +               }
>> +       }
>> +
>> +       /*
>> +        * Prepare all parent clocks here to avoid potential deadlock caused
>> +        * by global clock "prepare lock" grabbed by runtime pm callbacks
>> +        * from pm workers.
>> +        */
> I don't understand why this potentially could cause a deadlock. Can
> you please elaborate.

This deadlock was caused by using pm_runtime_put() in the clk core, but
after switching to pm_runtime_put_sync() it's gone. While tracking this
issue I also found another possible deadlock related to device_links.
I will send a separate patch for it.

> To me, I think you should be fine doing clk_prepare_enable() and
> clk_disable_unprepare() from exynos5433_cmu_suspend|resume(), but I
> may be missing something.
>
>> +       for (i = 0; i < data->nr_pclks; i++)
>> +               clk_prepare(data->pclks[i]);
>> +
>> +       if (info->clk_name)
>> +               data->clk = clk_get(dev, info->clk_name);
>> +       clk_prepare_enable(data->clk);
>> +
>> +       platform_set_drvdata(pdev, data);
>> +
>> +       /*
>> +        * Enable runtime pm here, so clock core with use runtime pm for all
>> +        * registered clocks. Additionally call pm_runtime_get_sync to ensure
>> +        * that clock core will not runtime suspend our clock controller in
>> +        * the middle of clock registration (clock core might call runtime pm
>> +        * on newly registered clocks, for example to recalculate clock rate).
>> +        */
> Instead of the rather confusing comment about the call to
> pm_runtime_get_sync(), let's instead state that we increase the
> runtime PM usage count during the clock registration, to avoid the
> clock core from runtime suspending the device.
>
> In other words, before calling pm_runtime_set_active(), add a call
> pm_runtime_get_noresume() and then remove the latter call to
> pm_runtime_get_sync().

Thanks for the hint!

>> +       pm_runtime_set_active(dev);
>> +       pm_runtime_enable(dev);
>> +       pm_runtime_get_sync(dev);
>> +
>> +       if (info->pll_clks)
>> +               samsung_clk_register_pll(ctx, info->pll_clks, info->nr_pll_clks,
>> +                                        reg_base);
>> +       if (info->mux_clks)
>> +               samsung_clk_register_mux(ctx, info->mux_clks,
>> +                                        info->nr_mux_clks);
>> +       if (info->div_clks)
>> +               samsung_clk_register_div(ctx, info->div_clks,
>> +                                        info->nr_div_clks);
>> +       if (info->gate_clks)
>> +               samsung_clk_register_gate(ctx, info->gate_clks,
>> +                                         info->nr_gate_clks);
>> +       if (info->fixed_clks)
>> +               samsung_clk_register_fixed_rate(ctx, info->fixed_clks,
>> +                                               info->nr_fixed_clks);
>> +       if (info->fixed_factor_clks)
>> +               samsung_clk_register_fixed_factor(ctx, info->fixed_factor_clks,
>> +                                                 info->nr_fixed_factor_clks);
>> +
>> +       samsung_clk_of_add_provider(dev->of_node, ctx);
>> +       pm_runtime_put(dev);
>> +
>> +       return 0;
>> +}
>>
> [...]
>
> Kind regards
> Uffe
>
>
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

  reply	other threads:[~2017-03-22  8:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20170125115327eucas1p172866fa87417f59f1dea60185d6d8b60@eucas1p1.samsung.com>
2017-01-25 11:53 ` [PATCH v5 0/4] Add runtime PM support for clocks (on Exynos SoC example) Marek Szyprowski
     [not found]   ` <CGME20170125115328eucas1p1d97fac29286805b58039f8aec2b9bfe6@eucas1p1.samsung.com>
2017-01-25 11:53     ` [PATCH v5 1/4] clk: Add support for runtime PM Marek Szyprowski
2017-03-13 12:20       ` Ulf Hansson
     [not found]   ` <CGME20170125115329eucas1p1fc59d9be3421bc763d16aa331375b9f6@eucas1p1.samsung.com>
2017-01-25 11:53     ` [PATCH v5 2/4] clk: samsung: " Marek Szyprowski
2017-03-13 13:34       ` Ulf Hansson
     [not found]   ` <CGME20170125115329eucas1p1f42bbb54d5973b6192e964dc8b3a8081@eucas1p1.samsung.com>
2017-01-25 11:53     ` [PATCH v5 3/4] clk: samsung: exynos5433: Add runtime PM support Marek Szyprowski
2017-03-13 13:31       ` Ulf Hansson
2017-03-22  8:26         ` Marek Szyprowski [this message]
     [not found]   ` <CGME20170125115330eucas1p16f9de097e0966bc9d9901bc27caa085c@eucas1p1.samsung.com>
2017-01-25 11:53     ` [PATCH v5 4/4] clk: samsung: exynos-audss: Use runtime PM Marek Szyprowski
2017-01-26  1:28       ` kbuild test robot

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=68edccfb-c86d-3412-82f4-2a5183f4a16c@samsung.com \
    --to=m.szyprowski@samsung.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=cw00.choi@samsung.com \
    --cc=inki.dae@samsung.com \
    --cc=krzk@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=s.nawrocki@samsung.com \
    --cc=sboyd@codeaurora.org \
    --cc=ulf.hansson@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).