157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren/*
257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * Device tree integration for the pin control subsystem
357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren *
457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren *
657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * This program is free software; you can redistribute it and/or modify it
757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * under the terms and conditions of the GNU General Public License,
857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * version 2, as published by the Free Software Foundation.
957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren *
1057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * This program is distributed in the hope it will be useful, but WITHOUT
1157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * more details.
1457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren *
1557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * You should have received a copy of the GNU General Public License
1657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren */
1857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
1957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include <linux/device.h>
2057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include <linux/of.h>
2157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include <linux/pinctrl/pinctrl.h>
2257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include <linux/slab.h>
2357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
2457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include "core.h"
2557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren#include "devicetree.h"
2657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
2757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren/**
2857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * struct pinctrl_dt_map - mapping table chunk parsed from device tree
2957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * @node: list node for struct pinctrl's @dt_maps field
3057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * @pctldev: the pin controller that allocated this struct, and will free it
3157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren * @maps: the mapping table entries
3257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren */
3357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenstruct pinctrl_dt_map {
3457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct list_head node;
3557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_dev *pctldev;
3657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_map *map;
3757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	unsigned num_maps;
3857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren};
3957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
4057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenstatic void dt_free_map(struct pinctrl_dev *pctldev,
4157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		     struct pinctrl_map *map, unsigned num_maps)
4257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
4357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (pctldev) {
44022ab148d28e8466e45d28552224e3029f1cccd8Laurent Pinchart		const struct pinctrl_ops *ops = pctldev->desc->pctlops;
4557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		ops->dt_free_map(pctldev, map, num_maps);
4657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	} else {
4757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
4857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		kfree(map);
4957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
5057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
5157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
5257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenvoid pinctrl_dt_free_maps(struct pinctrl *p)
5357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
5457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_dt_map *dt_map, *n1;
5557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
5657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) {
5757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		pinctrl_unregister_map(dt_map->map);
5857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		list_del(&dt_map->node);
5957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		dt_free_map(dt_map->pctldev, dt_map->map,
6057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			    dt_map->num_maps);
6157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		kfree(dt_map);
6257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
6357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
6457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	of_node_put(p->dev->of_node);
6557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
6657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
6757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenstatic int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
6857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				   struct pinctrl_dev *pctldev,
6957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				   struct pinctrl_map *map, unsigned num_maps)
7057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
7157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	int i;
7257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_dt_map *dt_map;
7357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
7457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* Initialize common mapping table entry fields */
7557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	for (i = 0; i < num_maps; i++) {
7657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		map[i].dev_name = dev_name(p->dev);
7757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		map[i].name = statename;
7857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (pctldev)
7957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			map[i].ctrl_dev_name = dev_name(pctldev->dev);
8057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
8157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
8257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* Remember the converted mapping table entries */
8357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
8457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (!dt_map) {
8557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		dev_err(p->dev, "failed to alloc struct pinctrl_dt_map\n");
8657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		dt_free_map(pctldev, map, num_maps);
8757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		return -ENOMEM;
8857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
8957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
9057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	dt_map->pctldev = pctldev;
9157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	dt_map->map = map;
9257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	dt_map->num_maps = num_maps;
9357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	list_add_tail(&dt_map->node, &p->dt_maps);
9457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
9557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	return pinctrl_register_map(map, num_maps, false, true);
9657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
9757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
981e63d7b9363f0c57d00991f9f2e0af374dfc591aLinus Walleijstruct pinctrl_dev *of_pinctrl_get(struct device_node *np)
99f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim{
100f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim	struct pinctrl_dev *pctldev;
101f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim
10242fed7ba44e4e8c1fb27b28ad14490cb1daff3c7Patrice Chotard	pctldev = get_pinctrl_dev_from_of_node(np);
103f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim	if (!pctldev)
104f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim		return NULL;
105f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim
106f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim	return pctldev;
107f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim}
108f23f1516b6757c326cc638bed8c402c77e2a596eShiraz Hashim
10957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenstatic int dt_to_map_one_config(struct pinctrl *p, const char *statename,
11057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				struct device_node *np_config)
11157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
11257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct device_node *np_pctldev;
11357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_dev *pctldev;
114022ab148d28e8466e45d28552224e3029f1cccd8Laurent Pinchart	const struct pinctrl_ops *ops;
11557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	int ret;
11657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_map *map;
11757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	unsigned num_maps;
11857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
11957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* Find the pin controller containing np_config */
12057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	np_pctldev = of_node_get(np_config);
12157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	for (;;) {
12257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		np_pctldev = of_get_next_parent(np_pctldev);
12357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (!np_pctldev || of_node_is_root(np_pctldev)) {
124c05127c4e2c6e7d9949347a76fd05c337bcd5e84Linus Walleij			dev_info(p->dev, "could not find pctldev for node %s, deferring probe\n",
12557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				np_config->full_name);
12657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			of_node_put(np_pctldev);
127c05127c4e2c6e7d9949347a76fd05c337bcd5e84Linus Walleij			/* OK let's just assume this will appear later then */
128c05127c4e2c6e7d9949347a76fd05c337bcd5e84Linus Walleij			return -EPROBE_DEFER;
12957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		}
13042fed7ba44e4e8c1fb27b28ad14490cb1daff3c7Patrice Chotard		pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
13157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (pctldev)
13257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			break;
133b2083062a3b4035e85349120b426ecef2b6d155fLinus Walleij		/* Do not defer probing of hogs (circular loop) */
134b2083062a3b4035e85349120b426ecef2b6d155fLinus Walleij		if (np_pctldev == p->dev->of_node) {
135b2083062a3b4035e85349120b426ecef2b6d155fLinus Walleij			of_node_put(np_pctldev);
136b2083062a3b4035e85349120b426ecef2b6d155fLinus Walleij			return -ENODEV;
137b2083062a3b4035e85349120b426ecef2b6d155fLinus Walleij		}
13857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
13957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	of_node_put(np_pctldev);
14057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
14157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/*
14257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	 * Call pinctrl driver to parse device tree node, and
14357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	 * generate mapping table entries
14457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	 */
14557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	ops = pctldev->desc->pctlops;
14657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (!ops->dt_node_to_map) {
14757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		dev_err(p->dev, "pctldev %s doesn't support DT\n",
14857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			dev_name(pctldev->dev));
14957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		return -ENODEV;
15057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
15157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
15257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (ret < 0)
15357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		return ret;
15457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
15557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* Stash the mapping table chunk away for later use */
15657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	return dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
15757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
15857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
15957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenstatic int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
16057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
16157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct pinctrl_map *map;
16257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
16357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	map = kzalloc(sizeof(*map), GFP_KERNEL);
16457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (!map) {
16557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		dev_err(p->dev, "failed to alloc struct pinctrl_map\n");
16657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		return -ENOMEM;
16757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
16857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
16957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
17057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	map->type = PIN_MAP_TYPE_DUMMY_STATE;
17157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
17257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	return dt_remember_or_free_map(p, statename, NULL, map, 1);
17357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
17457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
17557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenint pinctrl_dt_to_map(struct pinctrl *p)
17657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren{
17757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct device_node *np = p->dev->of_node;
17857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	int state, ret;
17957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	char *propname;
18057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct property *prop;
18157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	const char *statename;
18257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	const __be32 *list;
18357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	int size, config;
18457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	phandle phandle;
18557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	struct device_node *np_config;
18657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
18757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* CONFIG_OF enabled, p->dev not instantiated from DT */
18857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	if (!np) {
1895d88dceac736a779fdf6208bbd0a06e81fe25300Mark Brown		if (of_have_populated_dt())
1905d88dceac736a779fdf6208bbd0a06e81fe25300Mark Brown			dev_dbg(p->dev,
1915d88dceac736a779fdf6208bbd0a06e81fe25300Mark Brown				"no of_node; not parsing pinctrl DT\n");
19257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		return 0;
19357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
19457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
19557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* We may store pointers to property names within the node */
19657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	of_node_get(np);
19757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
19857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	/* For each defined state ID */
19957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	for (state = 0; ; state++) {
20057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/* Retrieve the pinctrl-* property */
20157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
20257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		prop = of_find_property(np, propname, &size);
20357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		kfree(propname);
20457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (!prop)
20557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			break;
20657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		list = prop->value;
20757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		size /= sizeof(*list);
20857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
20957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/* Determine whether pinctrl-names property names the state */
21057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		ret = of_property_read_string_index(np, "pinctrl-names",
21157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren						    state, &statename);
21257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/*
21357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		 * If not, statename is just the integer state ID. But rather
21457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		 * than dynamically allocate it and have to free it later,
21557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		 * just point part way into the property name for the string.
21657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		 */
21757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (ret < 0) {
21857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			/* strlen("pinctrl-") == 8 */
21957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			statename = prop->name + 8;
22057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		}
22157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
22257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/* For every referenced pin configuration node in it */
22357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		for (config = 0; config < size; config++) {
22457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			phandle = be32_to_cpup(list++);
22557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
22657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			/* Look up the pin configuration node */
22757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			np_config = of_find_node_by_phandle(phandle);
22857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			if (!np_config) {
22957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				dev_err(p->dev,
23057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren					"prop %s index %i invalid phandle\n",
23157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren					prop->name, config);
23257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				ret = -EINVAL;
23357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				goto err;
23457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			}
23557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
23657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			/* Parse the node */
23757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			ret = dt_to_map_one_config(p, statename, np_config);
23857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			of_node_put(np_config);
23957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			if (ret < 0)
24057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				goto err;
24157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		}
24257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
24357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		/* No entries in DT? Generate a dummy state table entry */
24457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		if (!size) {
24557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			ret = dt_remember_dummy_state(p, statename);
24657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren			if (ret < 0)
24757291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren				goto err;
24857291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren		}
24957291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	}
25057291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
25157291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	return 0;
25257291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren
25357291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warrenerr:
25457291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	pinctrl_dt_free_maps(p);
25557291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren	return ret;
25657291ce295c0aca738dd284c4a9c591c09ebee71Stephen Warren}
257