All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] clk: x86: Add system specific quirk to mark clocks as critical
@ 2019-03-28 12:49 David Müller
  2019-03-28 14:05 ` Andy Shevchenko
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: David Müller @ 2019-03-28 12:49 UTC (permalink / raw)
  To: linux-clk
  Cc: platform-driver-x86, Michael Turquette, Stephen Boyd,
	Darren Hart, Andy Shevchenko, Hans de Goede

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.

Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL")
Signed-off-by: David Müller <dave.mueller@gmx.ch>
---
 drivers/clk/x86/clk-pmc-atom.c                |  9 +++++---
 drivers/platform/x86/pmc_atom.c               | 22 +++++++++++++++++++
 .../linux/platform_data/x86/clk-pmc-atom.h    |  2 ++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
index d977193842df..882ea0c4c050 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)
 {
@@ -183,8 +183,11 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
 	init.parent_names = parent_names;
 	init.num_parents = num_parents;

+	if (test_bit(id, &pmc_data->critclk))
+		init.flags |= CLK_IS_CRITICAL;
+
 	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);

 	ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
@@ -332,7 +335,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..d25b2423afe0 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,28 @@ 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"),
+		},
+		/* on this platform, pmc_plt_clk_0 is a critical clock */
+		.driver_data = (void *)BIT(0),
+	},
+};
+
 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 +421,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->critclk = (uintptr_t)d->driver_data;
+		pr_info("%s critclk 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..8d00b6bd83b4 100644
--- a/include/linux/platform_data/x86/clk-pmc-atom.h
+++ b/include/linux/platform_data/x86/clk-pmc-atom.h
@@ -35,10 +35,12 @@ struct pmc_clk {
  *
  * @base:	PMC clock register base offset
  * @clks:	pointer to set of registered clocks, typically 0..5
+ * @clkcrit:	bit mask of pmc_plt_clks which are to be marked as critical
  */
 struct pmc_clk_data {
 	void __iomem *base;
 	const struct pmc_clk *clks;
+	unsigned long critclk;
 };

 #endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */
--
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2019-04-08 16:49 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-28 12:49 [PATCH] clk: x86: Add system specific quirk to mark clocks as critical David Müller
2019-03-28 14:05 ` Andy Shevchenko
2019-03-28 14:53 ` Hans de Goede
2019-03-28 15:41   ` David Müller
2019-03-28 15:42     ` Hans de Goede
2019-03-28 15:44       ` Andy Shevchenko
2019-04-03 14:08 ` [PATCH v2] " David Müller
2019-04-03 15:30   ` Hans de Goede
2019-04-03 15:36     ` Andy Shevchenko
2019-04-03 15:38       ` Hans de Goede
2019-04-04  8:00         ` David Müller
2019-04-04  8:02           ` Hans de Goede
2019-04-04  8:00     ` David Müller
2019-04-04 14:13 ` [PATCH v3] " David Müller
2019-04-04 14:41   ` Hans de Goede
2019-04-05 15:19   ` Andy Shevchenko
2019-04-05 17:19     ` David Müller
2019-04-08 13:33 ` [PATCH v4] " David Müller
2019-04-08 16:49   ` Andy Shevchenko

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.