// SPDX-License-Identifier: GPL-2.0-only
/*
 * Device tree integration for the pin control subsystem
 *
 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
 */

#include <linux/device.h>
#include <linux/of.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>

#include "core.h"
#include "devicetree.h"

/**
 * struct pinctrl_dt_map - mapping table chunk parsed from device tree
 * @node: list node for struct pinctrl's @dt_maps field
 * @pctldev: the pin controller that allocated this struct, and will free it
 * @map: the mapping table entries
 * @num_maps: number of mapping table entries
 */
struct pinctrl_dt_map {
	struct list_head node;
	struct pinctrl_dev *pctldev;
	struct pinctrl_map *map;
	unsigned int num_maps;
};

static void dt_free_map(struct pinctrl_dev *pctldev,
			struct pinctrl_map *map, unsigned int 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)
			ops->dt_free_map(pctldev, map, num_maps);
	} else {
		/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
		kfree(map);
	}
}

void pinctrl_dt_free_maps(struct pinctrl *p)
{
	struct pinctrl_dt_map *dt_map, *n1;

	list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) {
		pinctrl_unregister_mappings(dt_map->map);
		list_del(&dt_map->node);
		dt_free_map(dt_map->pctldev, dt_map->map,
			    dt_map->num_maps);
		kfree(dt_map);
	}

	of_node_put(p->dev->of_node);
}

static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
				   struct pinctrl_dev *pctldev,
				   struct pinctrl_map *map, unsigned int num_maps)
{
	int i;
	struct pinctrl_dt_map *dt_map;

	/* Initialize common mapping table entry fields */
	for (i = 0; i < num_maps; i++) {
		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);
	}

	/* Remember the converted mapping table entries */
	dt_map = kzalloc_obj(*dt_map);
	if (!dt_map)
		goto err_free_map;

	dt_map->pctldev = pctldev;
	dt_map->map = map;
	dt_map->num_maps = num_maps;
	list_add_tail(&dt_map->node, &p->dt_maps);

	return pinctrl_register_mappings(map, num_maps);

err_free_map:
	dt_free_map(pctldev, map, num_maps);
	return -ENOMEM;
}

struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
{
	return get_pinctrl_dev_from_of_node(np);
}
EXPORT_SYMBOL_GPL(of_pinctrl_get);

static int dt_to_map_one_config(struct pinctrl *p,
				struct pinctrl_dev *hog_pctldev,
				const char *statename,
				struct device_node *np_config)
{
	struct pinctrl_dev *pctldev = NULL;
	struct device_node *np_pctldev;
	const struct pinctrl_ops *ops;
	int ret;
	struct pinctrl_map *map;
	unsigned int num_maps;
	bool allow_default = false;

	/* Find the pin controller containing np_config */
	np_pctldev = of_node_get(np_config);
	for (;;) {
		if (!allow_default)
			allow_default = of_property_read_bool(np_pctldev,
							      "pinctrl-use-default");

		np_pctldev = of_get_next_parent(np_pctldev);
		if (!np_pctldev || of_node_is_root(np_pctldev)) {
			of_node_put(np_pctldev);
			ret = -ENODEV;
			/* keep deferring if modules are enabled */
			if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret < 0)
				ret = -EPROBE_DEFER;
			return ret;
		}
		/* If we're creating a hog we can use the passed pctldev */
		if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
			pctldev = hog_pctldev;
			break;
		}
		pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
		if (pctldev)
			break;
		/*
		 * Do not defer probing of hogs (circular loop)
		 *
		 * Return 1 to let the caller catch the case.
		 */
		if (np_pctldev == p->dev->of_node) {
			of_node_put(np_pctldev);
			return 1;
		}
	}
	of_node_put(np_pctldev);

	/*
	 * Call pinctrl driver to parse device tree node, and
	 * generate mapping table entries
	 */
	ops = pctldev->desc->pctlops;
	if (!ops->dt_node_to_map) {
		dev_err(p->dev, "pctldev %s doesn't support DT\n",
			dev_name(pctldev->dev));
		return -ENODEV;
	}
	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 are no 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);
}

static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
{
	struct pinctrl_map *map;

	map = kzalloc_obj(*map);
	if (!map)
		return -ENOMEM;

	/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
	map->type = PIN_MAP_TYPE_DUMMY_STATE;

	return dt_remember_or_free_map(p, statename, NULL, map, 1);
}

int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
{
	struct device_node *np = p->dev->of_node;
	int state, ret;
	char *propname;
	struct property *prop;
	const char *statename;
	const __be32 *list;
	int size, config;
	phandle phandle;
	struct device_node *np_config;

	/* CONFIG_OF enabled, p->dev not instantiated from DT */
	if (!np) {
		if (of_have_populated_dt())
			dev_dbg(p->dev,
				"no of_node; not parsing pinctrl DT\n");
		return 0;
	}

	/* We may store pointers to property names within the node */
	of_node_get(np);

	/* For each defined state ID */
	for (state = 0; ; state++) {
		/* Retrieve the pinctrl-* property */
		propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
		if (!propname) {
			ret = -ENOMEM;
			goto err;
		}
		prop = of_find_property(np, propname, &size);
		kfree(propname);
		if (!prop) {
			if (state == 0) {
				ret = -ENODEV;
				goto err;
			}
			break;
		}
		list = prop->value;
		size /= sizeof(*list);

		/* Determine whether pinctrl-names property names the state */
		ret = of_property_read_string_index(np, "pinctrl-names",
						    state, &statename);
		/*
		 * If not, statename is just the integer state ID. But rather
		 * than dynamically allocate it and have to free it later,
		 * just point part way into the property name for the string.
		 */
		if (ret < 0)
			statename = prop->name + strlen("pinctrl-");

		/* For every referenced pin configuration node in it */
		for (config = 0; config < size; config++) {
			phandle = be32_to_cpup(list++);

			/* Look up the pin configuration node */
			np_config = of_find_node_by_phandle(phandle);
			if (!np_config) {
				dev_err(p->dev,
					"prop %s index %i invalid phandle\n",
					prop->name, config);
				ret = -EINVAL;
				goto err;
			}

			/* Parse the node */
			ret = dt_to_map_one_config(p, pctldev, statename,
						   np_config);
			of_node_put(np_config);
			if (ret == 1)
				continue;
			if (ret < 0)
				goto err;
		}

		/* No entries in DT? Generate a dummy state table entry */
		if (!size) {
			ret = dt_remember_dummy_state(p, statename);
			if (ret < 0)
				goto err;
		}
	}

	return 0;

err:
	pinctrl_dt_free_maps(p);
	return ret;
}

/*
 * For pinctrl binding, typically #pinctrl-cells is for the pin controller
 * device, so either parent or grandparent. See pinctrl-bindings.txt.
 */
static int pinctrl_find_cells_size(const struct device_node *np)
{
	const char *cells_name = "#pinctrl-cells";
	int cells_size, error;

	error = of_property_read_u32(np->parent, cells_name, &cells_size);
	if (error) {
		error = of_property_read_u32(np->parent->parent,
					     cells_name, &cells_size);
		if (error)
			return -ENOENT;
	}

	return cells_size;
}

/**
 * pinctrl_get_list_and_count - Gets the list and it's cell size and number
 * @np: pointer to device node with the property
 * @list_name: property that contains the list
 * @list: pointer for the list found
 * @cells_size: pointer for the cell size found
 * @nr_elements: pointer for the number of elements found
 *
 * Typically np is a single pinctrl entry containing the list.
 */
static int pinctrl_get_list_and_count(const struct device_node *np,
				      const char *list_name,
				      const __be32 **list,
				      int *cells_size,
				      int *nr_elements)
{
	int size;

	*cells_size = 0;
	*nr_elements = 0;

	*list = of_get_property(np, list_name, &size);
	if (!*list)
		return -ENOENT;

	*cells_size = pinctrl_find_cells_size(np);
	if (*cells_size < 0)
		return -ENOENT;

	/* First element is always the index within the pinctrl device */
	*nr_elements = (size / sizeof(**list)) / (*cells_size + 1);

	return 0;
}

/**
 * pinctrl_count_index_with_args - Count number of elements in a pinctrl entry
 * @np: pointer to device node with the property
 * @list_name: property that contains the list
 *
 * Counts the number of elements in a pinctrl array consisting of an index
 * within the controller and a number of u32 entries specified for each
 * entry. Note that device_node is always for the parent pin controller device.
 */
int pinctrl_count_index_with_args(const struct device_node *np,
				  const char *list_name)
{
	const __be32 *list;
	int size, nr_cells, error;

	error = pinctrl_get_list_and_count(np, list_name, &list,
					   &nr_cells, &size);
	if (error)
		return error;

	return size;
}
EXPORT_SYMBOL_GPL(pinctrl_count_index_with_args);

/**
 * pinctrl_copy_args - Populates of_phandle_args based on index
 * @np: pointer to device node with the property
 * @list: pointer to a list with the elements
 * @index: entry within the list of elements
 * @nr_cells: number of cells in the list
 * @nr_elem: number of elements for each entry in the list
 * @out_args: returned values
 *
 * Populates the of_phandle_args based on the index in the list.
 */
static int pinctrl_copy_args(const struct device_node *np,
			     const __be32 *list,
			     int index, int nr_cells, int nr_elem,
			     struct of_phandle_args *out_args)
{
	int i;

	memset(out_args, 0, sizeof(*out_args));
	out_args->np = (struct device_node *)np;
	out_args->args_count = nr_cells + 1;

	if (index >= nr_elem)
		return -EINVAL;

	list += index * (nr_cells + 1);

	for (i = 0; i < nr_cells + 1; i++)
		out_args->args[i] = be32_to_cpup(list++);

	return 0;
}

/**
 * pinctrl_parse_index_with_args - Find a node pointed by index in a list
 * @np: pointer to device node with the property
 * @list_name: property that contains the list
 * @index: index within the list
 * @out_args: entries in the list pointed by index
 *
 * Finds the selected element in a pinctrl array consisting of an index
 * within the controller and a number of u32 entries specified for each
 * entry. Note that device_node is always for the parent pin controller device.
 */
int pinctrl_parse_index_with_args(const struct device_node *np,
				  const char *list_name, int index,
				  struct of_phandle_args *out_args)
{
	const __be32 *list;
	int nr_elem, nr_cells, error;

	error = pinctrl_get_list_and_count(np, list_name, &list,
					   &nr_cells, &nr_elem);
	if (error || !nr_cells)
		return error;

	error = pinctrl_copy_args(np, list, index, nr_cells, nr_elem,
				  out_args);
	if (error)
		return error;

	return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_parse_index_with_args);
