diff options
Diffstat (limited to 'drivers/mfd/syscon.c')
-rw-r--r-- | drivers/mfd/syscon.c | 46 |
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 | ||
43 | static struct syscon *of_syscon_register(struct device_node *np) | 43 | static 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 | ||
153 | struct regmap *syscon_node_to_regmap(struct device_node *np) | 152 | static 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 | |||
176 | struct regmap *device_node_to_regmap(struct device_node *np) | ||
177 | { | ||
178 | return device_node_get_regmap(np, false); | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(device_node_to_regmap); | ||
181 | |||
182 | struct 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 | } | ||
175 | EXPORT_SYMBOL_GPL(syscon_node_to_regmap); | 189 | EXPORT_SYMBOL_GPL(syscon_node_to_regmap); |
176 | 190 | ||
177 | struct regmap *syscon_regmap_lookup_by_compatible(const char *s) | 191 | struct regmap *syscon_regmap_lookup_by_compatible(const char *s) |