summaryrefslogtreecommitdiffstats
path: root/drivers/mfd/syscon.c
diff options
context:
space:
mode:
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 = {
40 .reg_stride = 4, 40 .reg_stride = 4,
41}; 41};
42 42
43static struct syscon *of_syscon_register(struct device_node *np) 43static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
44{ 44{
45 struct clk *clk; 45 struct clk *clk;
46 struct syscon *syscon; 46 struct syscon *syscon;
@@ -51,9 +51,6 @@ static struct syscon *of_syscon_register(struct device_node *np)
51 struct regmap_config syscon_config = syscon_regmap_config; 51 struct regmap_config syscon_config = syscon_regmap_config;
52 struct resource res; 52 struct resource res;
53 53
54 if (!of_device_is_compatible(np, "syscon"))
55 return ERR_PTR(-EINVAL);
56
57 syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); 54 syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
58 if (!syscon) 55 if (!syscon)
59 return ERR_PTR(-ENOMEM); 56 return ERR_PTR(-ENOMEM);
@@ -117,16 +114,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
117 goto err_regmap; 114 goto err_regmap;
118 } 115 }
119 116
120 clk = of_clk_get(np, 0); 117 if (check_clk) {
121 if (IS_ERR(clk)) { 118 clk = of_clk_get(np, 0);
122 ret = PTR_ERR(clk); 119 if (IS_ERR(clk)) {
123 /* clock is optional */ 120 ret = PTR_ERR(clk);
124 if (ret != -ENOENT) 121 /* clock is optional */
125 goto err_clk; 122 if (ret != -ENOENT)
126 } else { 123 goto err_clk;
127 ret = regmap_mmio_attach_clk(regmap, clk); 124 } else {
128 if (ret) 125 ret = regmap_mmio_attach_clk(regmap, clk);
129 goto err_attach; 126 if (ret)
127 goto err_attach;
128 }
130 } 129 }
131 130
132 syscon->regmap = regmap; 131 syscon->regmap = regmap;
@@ -150,7 +149,8 @@ err_map:
150 return ERR_PTR(ret); 149 return ERR_PTR(ret);
151} 150}
152 151
153struct regmap *syscon_node_to_regmap(struct device_node *np) 152static struct regmap *device_node_get_regmap(struct device_node *np,
153 bool check_clk)
154{ 154{
155 struct syscon *entry, *syscon = NULL; 155 struct syscon *entry, *syscon = NULL;
156 156
@@ -165,13 +165,27 @@ struct regmap *syscon_node_to_regmap(struct device_node *np)
165 spin_unlock(&syscon_list_slock); 165 spin_unlock(&syscon_list_slock);
166 166
167 if (!syscon) 167 if (!syscon)
168 syscon = of_syscon_register(np); 168 syscon = of_syscon_register(np, check_clk);
169 169
170 if (IS_ERR(syscon)) 170 if (IS_ERR(syscon))
171 return ERR_CAST(syscon); 171 return ERR_CAST(syscon);
172 172
173 return syscon->regmap; 173 return syscon->regmap;
174} 174}
175
176struct regmap *device_node_to_regmap(struct device_node *np)
177{
178 return device_node_get_regmap(np, false);
179}
180EXPORT_SYMBOL_GPL(device_node_to_regmap);
181
182struct regmap *syscon_node_to_regmap(struct device_node *np)
183{
184 if (!of_device_is_compatible(np, "syscon"))
185 return ERR_PTR(-EINVAL);
186
187 return device_node_get_regmap(np, true);
188}
175EXPORT_SYMBOL_GPL(syscon_node_to_regmap); 189EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
176 190
177struct regmap *syscon_regmap_lookup_by_compatible(const char *s) 191struct regmap *syscon_regmap_lookup_by_compatible(const char *s)