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