aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-08-06 09:12:34 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-08-14 15:00:41 -0400
commite81c8f18afc4fdd6e34d8c83814b8b5134dbb30f (patch)
tree59435df0785247baed2bfe63bbd10a32c3769e60
parent1eb207a9ecaafb980704d8bc055a9a0269f62f8e (diff)
pinctrl: pinconf-generic: add generic APIs for mapping pinctrl node
Add generic APIs to map the DT node and its sub node in pinconf generic driver. These APIs can be used from driver to parse the DT node who uses the pinconf generic APIs for defining their nodes. Changes from V1: - Add generic property for pins and functions in pinconf-generic. - Add APIs to map the DT and subnode. - Move common utils APIs to the pinctrl-utils from this file. - Update the binding document accordingly. Changes from V2: - Rebased the pinctrl binding doc on top of Stephen's cleanup. - Rename properties "pinctrl-pins" and "pinctrl-function" to "pins" and "function". Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinconf-generic.c96
-rw-r--r--include/linux/pinctrl/pinconf-generic.h6
2 files changed, 102 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index 8594f033ac21..d9536caa9c41 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include "core.h" 25#include "core.h"
26#include "pinconf.h" 26#include "pinconf.h"
27#include "pinctrl-utils.h"
27 28
28#ifdef CONFIG_DEBUG_FS 29#ifdef CONFIG_DEBUG_FS
29 30
@@ -236,4 +237,99 @@ out:
236 kfree(cfg); 237 kfree(cfg);
237 return ret; 238 return ret;
238} 239}
240
241int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
242 struct device_node *np, struct pinctrl_map **map,
243 unsigned *reserved_maps, unsigned *num_maps)
244{
245 int ret;
246 const char *function;
247 struct device *dev = pctldev->dev;
248 unsigned long *configs = NULL;
249 unsigned num_configs = 0;
250 unsigned reserve;
251 struct property *prop;
252 const char *group;
253
254 ret = of_property_read_string(np, "function", &function);
255 if (ret < 0) {
256 /* EINVAL=missing, which is fine since it's optional */
257 if (ret != -EINVAL)
258 dev_err(dev,
259 "could not parse property ti,function\n");
260 function = NULL;
261 }
262
263 ret = pinconf_generic_parse_dt_config(np, &configs, &num_configs);
264 if (ret < 0) {
265 dev_err(dev, "could not parse node property\n");
266 return ret;
267 }
268
269 reserve = 0;
270 if (function != NULL)
271 reserve++;
272 if (num_configs)
273 reserve++;
274 ret = of_property_count_strings(np, "pins");
275 if (ret < 0) {
276 dev_err(dev, "could not parse property ti,pins\n");
277 goto exit;
278 }
279 reserve *= ret;
280
281 ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps,
282 num_maps, reserve);
283 if (ret < 0)
284 goto exit;
285
286 of_property_for_each_string(np, "pins", prop, group) {
287 if (function) {
288 ret = pinctrl_utils_add_map_mux(pctldev, map,
289 reserved_maps, num_maps, group,
290 function);
291 if (ret < 0)
292 goto exit;
293 }
294
295 if (num_configs) {
296 ret = pinctrl_utils_add_map_configs(pctldev, map,
297 reserved_maps, num_maps, group, configs,
298 num_configs, PIN_MAP_TYPE_CONFIGS_PIN);
299 if (ret < 0)
300 goto exit;
301 }
302 }
303 ret = 0;
304
305exit:
306 kfree(configs);
307 return ret;
308}
309EXPORT_SYMBOL_GPL(pinconf_generic_dt_subnode_to_map);
310
311int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
312 struct device_node *np_config, struct pinctrl_map **map,
313 unsigned *num_maps)
314{
315 unsigned reserved_maps;
316 struct device_node *np;
317 int ret;
318
319 reserved_maps = 0;
320 *map = NULL;
321 *num_maps = 0;
322
323 for_each_child_of_node(np_config, np) {
324 ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
325 &reserved_maps, num_maps);
326 if (ret < 0) {
327 pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
328 return ret;
329 }
330 }
331 return 0;
332}
333EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);
334
239#endif 335#endif
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index bf7e989abcb5..a472b93292a3 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -137,6 +137,12 @@ static inline unsigned long pinconf_to_config_packed(enum pin_config_param param
137 return PIN_CONF_PACKED(param, argument); 137 return PIN_CONF_PACKED(param, argument);
138} 138}
139 139
140int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
141 struct device_node *np, struct pinctrl_map **map,
142 unsigned *reserved_maps, unsigned *num_maps);
143int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
144 struct device_node *np_config, struct pinctrl_map **map,
145 unsigned *num_maps);
140#endif /* CONFIG_GENERIC_PINCONF */ 146#endif /* CONFIG_GENERIC_PINCONF */
141 147
142#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */ 148#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */