Commit 39233b7c authored by Paul Cercueil's avatar Paul Cercueil Committed by Paul Burton

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: default avatarPaul Cercueil <paul@crapouillou.net>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarPaul 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>
parent 2e8722a5
...@@ -40,7 +40,7 @@ static const struct regmap_config syscon_regmap_config = { ...@@ -40,7 +40,7 @@ static const struct regmap_config syscon_regmap_config = {
.reg_stride = 4, .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 clk *clk;
struct syscon *syscon; struct syscon *syscon;
...@@ -51,9 +51,6 @@ static struct syscon *of_syscon_register(struct device_node *np) ...@@ -51,9 +51,6 @@ static struct syscon *of_syscon_register(struct device_node *np)
struct regmap_config syscon_config = syscon_regmap_config; struct regmap_config syscon_config = syscon_regmap_config;
struct resource res; struct resource res;
if (!of_device_is_compatible(np, "syscon"))
return ERR_PTR(-EINVAL);
syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
if (!syscon) if (!syscon)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -117,16 +114,18 @@ static struct syscon *of_syscon_register(struct device_node *np) ...@@ -117,16 +114,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
goto err_regmap; goto err_regmap;
} }
clk = of_clk_get(np, 0); if (check_clk) {
if (IS_ERR(clk)) { clk = of_clk_get(np, 0);
ret = PTR_ERR(clk); if (IS_ERR(clk)) {
/* clock is optional */ ret = PTR_ERR(clk);
if (ret != -ENOENT) /* clock is optional */
goto err_clk; if (ret != -ENOENT)
} else { goto err_clk;
ret = regmap_mmio_attach_clk(regmap, clk); } else {
if (ret) ret = regmap_mmio_attach_clk(regmap, clk);
goto err_attach; if (ret)
goto err_attach;
}
} }
syscon->regmap = regmap; syscon->regmap = regmap;
...@@ -150,7 +149,8 @@ static struct syscon *of_syscon_register(struct device_node *np) ...@@ -150,7 +149,8 @@ static struct syscon *of_syscon_register(struct device_node *np)
return ERR_PTR(ret); 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; struct syscon *entry, *syscon = NULL;
...@@ -165,13 +165,27 @@ struct regmap *syscon_node_to_regmap(struct device_node *np) ...@@ -165,13 +165,27 @@ struct regmap *syscon_node_to_regmap(struct device_node *np)
spin_unlock(&syscon_list_slock); spin_unlock(&syscon_list_slock);
if (!syscon) if (!syscon)
syscon = of_syscon_register(np); syscon = of_syscon_register(np, check_clk);
if (IS_ERR(syscon)) if (IS_ERR(syscon))
return ERR_CAST(syscon); return ERR_CAST(syscon);
return syscon->regmap; 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); EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
struct regmap *syscon_regmap_lookup_by_compatible(const char *s) struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
......
...@@ -17,12 +17,18 @@ ...@@ -17,12 +17,18 @@
struct device_node; struct device_node;
#ifdef CONFIG_MFD_SYSCON #ifdef CONFIG_MFD_SYSCON
extern struct regmap *device_node_to_regmap(struct device_node *np);
extern struct regmap *syscon_node_to_regmap(struct device_node *np); extern struct regmap *syscon_node_to_regmap(struct device_node *np);
extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
extern struct regmap *syscon_regmap_lookup_by_phandle( extern struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np, struct device_node *np,
const char *property); const char *property);
#else #else
static inline struct regmap *device_node_to_regmap(struct device_node *np)
{
return ERR_PTR(-ENOTSUPP);
}
static inline struct regmap *syscon_node_to_regmap(struct device_node *np) static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
{ {
return ERR_PTR(-ENOTSUPP); return ERR_PTR(-ENOTSUPP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment