diff options
Diffstat (limited to 'drivers/pinctrl/devicetree.c')
| -rw-r--r-- | drivers/pinctrl/devicetree.c | 50 | 
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 5d6d8b1e9062..674920daac26 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -29,6 +29,13 @@ struct pinctrl_dt_map {  static void dt_free_map(struct pinctrl_dev *pctldev,  		     struct pinctrl_map *map, unsigned num_maps)  { +	int i; + +	for (i = 0; i < num_maps; ++i) { +		kfree_const(map[i].dev_name); +		map[i].dev_name = NULL; +	} +  	if (pctldev) {  		const struct pinctrl_ops *ops = pctldev->desc->pctlops;  		if (ops->dt_free_map) @@ -63,7 +70,13 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,  	/* Initialize common mapping table entry fields */  	for (i = 0; i < num_maps; i++) { -		map[i].dev_name = dev_name(p->dev); +		const char *devname; + +		devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL); +		if (!devname) +			goto err_free_map; + +		map[i].dev_name = devname;  		map[i].name = statename;  		if (pctldev)  			map[i].ctrl_dev_name = dev_name(pctldev->dev); @@ -71,10 +84,8 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,  	/* Remember the converted mapping table entries */  	dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL); -	if (!dt_map) { -		dt_free_map(pctldev, map, num_maps); -		return -ENOMEM; -	} +	if (!dt_map) +		goto err_free_map;  	dt_map->pctldev = pctldev;  	dt_map->map = map; @@ -82,6 +93,10 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,  	list_add_tail(&dt_map->node, &p->dt_maps);  	return pinctrl_register_map(map, num_maps, false); + +err_free_map: +	dt_free_map(pctldev, map, num_maps); +	return -ENOMEM;  }  struct pinctrl_dev *of_pinctrl_get(struct device_node *np) @@ -147,6 +162,16 @@ static int dt_to_map_one_config(struct pinctrl *p,  	ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);  	if (ret < 0)  		return ret; +	else if (num_maps == 0) { +		/* +		 * If we have no valid maps (maybe caused by empty pinctrl node +		 * or typing error) ther is no need remember this, so just +		 * return. +		 */ +		dev_info(p->dev, +			 "there is not valid maps for state %s\n", statename); +		return 0; +	}  	/* Stash the mapping table chunk away for later use */  	return dt_remember_or_free_map(p, statename, pctldev, map, num_maps); @@ -166,21 +191,6 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)  	return dt_remember_or_free_map(p, statename, NULL, map, 1);  } -bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev) -{ -	struct device_node *np; -	struct property *prop; -	int size; - -	np = pctldev->dev->of_node; -	if (!np) -		return false; - -	prop = of_find_property(np, "pinctrl-0", &size); - -	return prop ? true : false; -} -  int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)  {  	struct device_node *np = p->dev->of_node;  |