Re: [PATCH v4] clk: x86: Add system specific quirk to mark clocks as critical

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 8, 2019 at 4:34 PM David Müller <dave.mueller@xxxxxx> wrote:
>
> Since commit 648e921888ad ("clk: x86: Stop marking clocks as
> CLK_IS_CRITICAL"), the pmc_plt_clocks of the Bay Trail SoC are
> unconditionally gated off. Unfortunately this will break systems where these
> clocks are used for external purposes beyond the kernel's knowledge. Fix it
> by implementing a system specific quirk to mark the necessary pmc_plt_clks as
> critical.
>

Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>

supposed to go via CLK tree.

> Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL")
> Signed-off-by: David Müller <dave.mueller@xxxxxx>
> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> ---
> Changes in v4:
> - add '.' to comments / rename field as suggested by Andy Shevchenko
> Changes in v3:
> - add missing sentinel entry to critclk_systems table
> Changes in v2:
> - restore previous clk detection logic as suggested by Hans de Goede
>
>  drivers/clk/x86/clk-pmc-atom.c                | 14 ++++++++++---
>  drivers/platform/x86/pmc_atom.c               | 21 +++++++++++++++++++
>  .../linux/platform_data/x86/clk-pmc-atom.h    |  3 +++
>  3 files changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
> index d977193842df..19174835693b 100644
> --- a/drivers/clk/x86/clk-pmc-atom.c
> +++ b/drivers/clk/x86/clk-pmc-atom.c
> @@ -165,7 +165,7 @@ static const struct clk_ops plt_clk_ops = {
>  };
>
>  static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
> -                                       void __iomem *base,
> +                                       const struct pmc_clk_data *pmc_data,
>                                         const char **parent_names,
>                                         int num_parents)
>  {
> @@ -184,9 +184,17 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
>         init.num_parents = num_parents;
>
>         pclk->hw.init = &init;
> -       pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
> +       pclk->reg = pmc_data->base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
>         spin_lock_init(&pclk->lock);
>
> +       /*
> +        * On some systems, the pmc_plt_clocks already enabled by the
> +        * firmware are being marked as critical to avoid them being
> +        * gated by the clock framework.
> +        */
> +       if (pmc_data->critical && plt_clk_is_enabled(&pclk->hw))
> +               init.flags |= CLK_IS_CRITICAL;
> +
>         ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
>         if (ret) {
>                 pclk = ERR_PTR(ret);
> @@ -332,7 +340,7 @@ static int plt_clk_probe(struct platform_device *pdev)
>                 return PTR_ERR(parent_names);
>
>         for (i = 0; i < PMC_CLK_NUM; i++) {
> -               data->clks[i] = plt_clk_register(pdev, i, pmc_data->base,
> +               data->clks[i] = plt_clk_register(pdev, i, pmc_data,
>                                                  parent_names, data->nparents);
>                 if (IS_ERR(data->clks[i])) {
>                         err = PTR_ERR(data->clks[i]);
> diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
> index 8f018b3f3cd4..eaec2d306481 100644
> --- a/drivers/platform/x86/pmc_atom.c
> +++ b/drivers/platform/x86/pmc_atom.c
> @@ -17,6 +17,7 @@
>
>  #include <linux/debugfs.h>
>  #include <linux/device.h>
> +#include <linux/dmi.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
>  #include <linux/platform_data/x86/clk-pmc-atom.h>
> @@ -391,11 +392,27 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
>  }
>  #endif /* CONFIG_DEBUG_FS */
>
> +/*
> + * Some systems need one or more of their pmc_plt_clks to be
> + * marked as critical.
> + */
> +static const struct dmi_system_id critclk_systems[] __initconst = {
> +       {
> +               .ident = "MPL CEC1x",
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "MPL AG"),
> +                       DMI_MATCH(DMI_PRODUCT_NAME, "CEC10 Family"),
> +               },
> +       },
> +       { /*sentinel*/ }
> +};
> +
>  static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
>                           const struct pmc_data *pmc_data)
>  {
>         struct platform_device *clkdev;
>         struct pmc_clk_data *clk_data;
> +       const struct dmi_system_id *d = dmi_first_match(critclk_systems);
>
>         clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>         if (!clk_data)
> @@ -403,6 +420,10 @@ static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
>
>         clk_data->base = pmc_regmap; /* offset is added by client */
>         clk_data->clks = pmc_data->clks;
> +       if (d) {
> +               clk_data->critical = true;
> +               pr_info("%s critclks quirk enabled\n", d->ident);
> +       }
>
>         clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom",
>                                                PLATFORM_DEVID_NONE,
> diff --git a/include/linux/platform_data/x86/clk-pmc-atom.h b/include/linux/platform_data/x86/clk-pmc-atom.h
> index 3ab892208343..7a37ac27d0fb 100644
> --- a/include/linux/platform_data/x86/clk-pmc-atom.h
> +++ b/include/linux/platform_data/x86/clk-pmc-atom.h
> @@ -35,10 +35,13 @@ struct pmc_clk {
>   *
>   * @base:      PMC clock register base offset
>   * @clks:      pointer to set of registered clocks, typically 0..5
> + * @critical:  flag to indicate if firmware enabled pmc_plt_clks
> + *             should be marked as critial or not
>   */
>  struct pmc_clk_data {
>         void __iomem *base;
>         const struct pmc_clk *clks;
> +       bool critical;
>  };
>
>  #endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */
> --
> 2.20.1
>


-- 
With Best Regards,
Andy Shevchenko




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux