clk: meson: use hhi syscon if available
authorJerome Brunet <jbrunet@baylibre.com>
Mon, 12 Feb 2018 14:58:46 +0000 (15:58 +0100)
committerNeil Armstrong <narmstrong@baylibre.com>
Tue, 13 Mar 2018 09:04:04 +0000 (10:04 +0100)
On gxbb and axg, try to get the hhi regmap from the parent DT node, which
should be the HHI system controller once the necessary changes have been
made in amlogic's DTs

Until then, if getting regmap through the system controller fails, the
clock controller will fall back to the old way, requesting memory region
directly and then registering the regmap itself.

This should allow a smooth transition to syscon

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
drivers/clk/meson/Kconfig
drivers/clk/meson/axg.c
drivers/clk/meson/gxbb.c

index 936afddae406ec2b072b9bfaa46b2c57818b3311..d5cbec522aec65f0e08b034ba1c68f5dc97f1a4a 100644 (file)
@@ -22,6 +22,7 @@ config COMMON_CLK_GXBB
        depends on COMMON_CLK_AMLOGIC
        select RESET_CONTROLLER
        select COMMON_CLK_REGMAP_MESON
+       select MFD_SYSCON
        help
          Support for the clock controller on AmLogic S905 devices, aka gxbb.
          Say Y if you want peripherals and CPU frequency scaling to work.
@@ -31,6 +32,7 @@ config COMMON_CLK_AXG
        depends on COMMON_CLK_AMLOGIC
        select RESET_CONTROLLER
        select COMMON_CLK_REGMAP_MESON
+       select MFD_SYSCON
        help
          Support for the clock controller on AmLogic A113D devices, aka axg.
          Say Y if you want peripherals and CPU frequency scaling to work.
index 6813b632c1a941ae61adcd0c8f7eaff6d0601288..acb63c8e0fd8316f6f40f006a61f6bba91f83083 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -850,25 +851,41 @@ static int axg_clkc_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct resource *res;
-       void __iomem *clk_base;
+       void __iomem *clk_base = NULL;
        struct regmap *map;
        int ret, i;
 
-       /*  Generic clocks and PLLs */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -EINVAL;
+       /* Get the hhi system controller node if available */
+       map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+       if (IS_ERR(map)) {
+               dev_err(dev,
+                       "failed to get HHI regmap - Trying obsolete regs\n");
+
+               /*
+                * FIXME: HHI registers should be accessed through
+                * the appropriate system controller. This is required because
+                * there is more than just clocks in this register space
+                *
+                * This fallback method is only provided temporarily until
+                * all the platform DTs are properly using the syscon node
+                */
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!res)
+                       return -EINVAL;
+
+
+               clk_base = devm_ioremap(dev, res->start, resource_size(res));
+               if (!clk_base) {
+                       dev_err(dev, "Unable to map clk base\n");
+                       return -ENXIO;
+               }
 
-       clk_base = devm_ioremap(dev, res->start, resource_size(res));
-       if (!clk_base) {
-               dev_err(dev, "Unable to map clk base\n");
-               return -ENXIO;
+               map = devm_regmap_init_mmio(dev, clk_base,
+                                           &clkc_regmap_config);
+               if (IS_ERR(map))
+                       return PTR_ERR(map);
        }
 
-       map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
-       if (IS_ERR(map))
-               return PTR_ERR(map);
-
        /* Populate regmap for the regmap backed clocks */
        for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
                axg_clk_regmaps[i]->map = map;
index 5ab8338eb89476c4ffb9badb7264ebcae828845b..bb0b0529ca8178fce0b7bfac397a955966c74e63 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -2045,19 +2046,35 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
        if (!clkc_data)
                return -EINVAL;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -EINVAL;
+       /* Get the hhi system controller node if available */
+       map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+       if (IS_ERR(map)) {
+               dev_err(dev,
+                       "failed to get HHI regmap - Trying obsolete regs\n");
 
-       clk_base = devm_ioremap(dev, res->start, resource_size(res));
-       if (!clk_base) {
-               pr_err("%s: Unable to map clk base\n", __func__);
-               return -ENXIO;
-       }
+               /*
+                * FIXME: HHI registers should be accessed through
+                * the appropriate system controller. This is required because
+                * there is more than just clocks in this register space
+                *
+                * This fallback method is only provided temporarily until
+                * all the platform DTs are properly using the syscon node
+                */
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!res)
+                       return -EINVAL;
+
+               clk_base = devm_ioremap(dev, res->start, resource_size(res));
+               if (!clk_base) {
+                       dev_err(dev, "Unable to map clk base\n");
+                       return -ENXIO;
+               }
 
-       map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
-       if (IS_ERR(map))
-               return PTR_ERR(map);
+               map = devm_regmap_init_mmio(dev, clk_base,
+                                           &clkc_regmap_config);
+               if (IS_ERR(map))
+                       return PTR_ERR(map);
+       }
 
        /* Populate regmap for the common regmap backed clocks */
        for (i = 0; i < ARRAY_SIZE(gx_clk_regmaps); i++)