summaryrefslogtreecommitdiffstats
path: root/drivers/mfd/syscon.c
diff options
context:
space:
mode:
authorPaul Cercueil <paul@crapouillou.net>2019-07-24 13:16:06 -0400
committerPaul Burton <paul.burton@mips.com>2019-08-08 15:30:07 -0700
commit39233b7c611248c0d05209b4854bc63e26485655 (patch)
treedeb77504407a952589c45839385b9b5eaf627d20 /drivers/mfd/syscon.c
parent2e8722a5255e6596246c0feee221902f11178ee5 (diff)
downloadlinux-stable-39233b7c611248c0d05209b4854bc63e26485655.tar.gz
linux-stable-39233b7c611248c0d05209b4854bc63e26485655.tar.bz2
linux-stable-39233b7c611248c0d05209b4854bc63e26485655.zip
mfd/syscon: Add device_node_to_regmap()
device_node_to_regmap() is exactly like syscon_node_to_regmap(), but it does not check that the node is compatible with "syscon", and won't attach the first clock it finds to the regmap. The rationale behind this, is that one device node with a standard compatible string "foo,bar" can be covered by multiple drivers sharing a regmap, or by a single driver doing all the job without a regmap, but these are implementation details which shouldn't reflect on the devicetree. Signed-off-by: Paul Cercueil <paul@crapouillou.net> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Paul Burton <paul.burton@mips.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <jhogan@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Lee Jones <lee.jones@linaro.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Stephen Boyd <sboyd@kernel.org> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Rob Herring <robh+dt@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-doc@vger.kernel.org Cc: linux-mips@vger.kernel.org Cc: linux-clk@vger.kernel.org Cc: od@zcrc.me Cc: Mathieu Malaterre <malat@debian.org>
Diffstat (limited to 'drivers/mfd/syscon.c')
-rw-r--r--drivers/mfd/syscon.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index b65e585fc8c6..660723276481 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -40,7 +40,7 @@ static const struct regmap_config syscon_regmap_config = {
.reg_stride = 4,
};
-static struct syscon *of_syscon_register(struct device_node *np)
+static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
{
struct clk *clk;
struct syscon *syscon;
@@ -51,9 +51,6 @@ static struct syscon *of_syscon_register(struct device_node *np)
struct regmap_config syscon_config = syscon_regmap_config;
struct resource res;
- if (!of_device_is_compatible(np, "syscon"))
- return ERR_PTR(-EINVAL);
-
syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
if (!syscon)
return ERR_PTR(-ENOMEM);
@@ -117,16 +114,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
goto err_regmap;
}
- clk = of_clk_get(np, 0);
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- /* clock is optional */
- if (ret != -ENOENT)
- goto err_clk;
- } else {
- ret = regmap_mmio_attach_clk(regmap, clk);
- if (ret)
- goto err_attach;
+ if (check_clk) {
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ /* clock is optional */
+ if (ret != -ENOENT)
+ goto err_clk;
+ } else {
+ ret = regmap_mmio_attach_clk(regmap, clk);
+ if (ret)
+ goto err_attach;
+ }
}
syscon->regmap = regmap;
@@ -150,7 +149,8 @@ err_map:
return ERR_PTR(ret);
}
-struct regmap *syscon_node_to_regmap(struct device_node *np)
+static struct regmap *device_node_get_regmap(struct device_node *np,
+ bool check_clk)
{
struct syscon *entry, *syscon = NULL;
@@ -165,13 +165,27 @@ struct regmap *syscon_node_to_regmap(struct device_node *np)
spin_unlock(&syscon_list_slock);
if (!syscon)
- syscon = of_syscon_register(np);
+ syscon = of_syscon_register(np, check_clk);
if (IS_ERR(syscon))
return ERR_CAST(syscon);
return syscon->regmap;
}
+
+struct regmap *device_node_to_regmap(struct device_node *np)
+{
+ return device_node_get_regmap(np, false);
+}
+EXPORT_SYMBOL_GPL(device_node_to_regmap);
+
+struct regmap *syscon_node_to_regmap(struct device_node *np)
+{
+ if (!of_device_is_compatible(np, "syscon"))
+ return ERR_PTR(-EINVAL);
+
+ return device_node_get_regmap(np, true);
+}
EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
struct regmap *syscon_regmap_lookup_by_compatible(const char *s)