1517 lines · 36.2 KB · C
RawDownload
/* * Core driver for the pin control subsystem * * Copyright (C) 2011-2012 ST-Ericsson SA * Written on behalf of Linaro for ST-Ericsson * Based on bits of regulator core, gpio core and clk core * * Author: Linus Walleij <linus.walleij@linaro.org> * * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. * * License terms: GNU General Public License (GPL) version 2 */#define pr_fmt(fmt) "pinctrl core: " fmt #include <linux/kernel.h>#include <linux/export.h>#include <linux/init.h>#include <linux/device.h>#include <linux/slab.h>#include <linux/err.h>#include <linux/list.h>#include <linux/sysfs.h>#include <linux/debugfs.h>#include <linux/seq_file.h>#include <linux/pinctrl/consumer.h>#include <linux/pinctrl/pinctrl.h>#include <linux/pinctrl/machine.h>#include "core.h"#include "devicetree.h"#include "pinmux.h"#include "pinconf.h" /** * struct pinctrl_maps - a list item containing part of the mapping table * @node: mapping table list node * @maps: array of mapping table entries * @num_maps: the number of entries in @maps */struct pinctrl_maps {	struct list_head node;	struct pinctrl_map const *maps;	unsigned num_maps;}; static bool pinctrl_dummy_state; /* Mutex taken by all entry points */DEFINE_MUTEX(pinctrl_mutex); /* Global list of pin control devices (struct pinctrl_dev) */LIST_HEAD(pinctrldev_list); /* List of pin controller handles (struct pinctrl) */static LIST_HEAD(pinctrl_list); /* List of pinctrl maps (struct pinctrl_maps) */static LIST_HEAD(pinctrl_maps); #define for_each_maps(_maps_node_, _i_, _map_) \	list_for_each_entry(_maps_node_, &pinctrl_maps, node) \		for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \			_i_ < _maps_node_->num_maps; \			i++, _map_ = &_maps_node_->maps[_i_]) /** * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support * * Usually this function is called by platforms without pinctrl driver support * but run with some shared drivers using pinctrl APIs. * After calling this function, the pinctrl core will return successfully * with creating a dummy state for the driver to keep going smoothly. */void pinctrl_provide_dummies(void){	pinctrl_dummy_state = true;} const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev){	/* We're not allowed to register devices without name */	return pctldev->desc->name;}EXPORT_SYMBOL_GPL(pinctrl_dev_get_name); void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev){	return pctldev->driver_data;}EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); /** * get_pinctrl_dev_from_devname() - look up pin controller device * @devname: the name of a device instance, as returned by dev_name() * * Looks up a pin control device matching a certain device name or pure device * pointer, the pure device pointer will take precedence. */struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname){	struct pinctrl_dev *pctldev = NULL;	bool found = false; 	if (!devname)		return NULL; 	list_for_each_entry(pctldev, &pinctrldev_list, node) {		if (!strcmp(dev_name(pctldev->dev), devname)) {			/* Matched on device name */			found = true;			break;		}	} 	return found ? pctldev : NULL;} /** * pin_get_from_name() - look up a pin number from a name * @pctldev: the pin control device to lookup the pin on * @name: the name of the pin to look up */int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name){	unsigned i, pin; 	/* The pin number can be retrived from the pin controller descriptor */	for (i = 0; i < pctldev->desc->npins; i++) {		struct pin_desc *desc; 		pin = pctldev->desc->pins[i].number;		desc = pin_desc_get(pctldev, pin);		/* Pin space may be sparse */		if (desc == NULL)			continue;		if (desc->name && !strcmp(name, desc->name))			return pin;	} 	return -EINVAL;} /** * pin_get_name_from_id() - look up a pin name from a pin id * @pctldev: the pin control device to lookup the pin on * @name: the name of the pin to look up */const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin){	const struct pin_desc *desc; 	desc = pin_desc_get(pctldev, pin);	if (desc == NULL) {		dev_err(pctldev->dev, "failed to get pin(%d) name\n",			pin);		return NULL;	} 	return desc->name;} /** * pin_is_valid() - check if pin exists on controller * @pctldev: the pin control device to check the pin on * @pin: pin to check, use the local pin controller index number * * This tells us whether a certain pin exist on a certain pin controller or * not. Pin lists may be sparse, so some pins may not exist. */bool pin_is_valid(struct pinctrl_dev *pctldev, int pin){	struct pin_desc *pindesc; 	if (pin < 0)		return false; 	mutex_lock(&pinctrl_mutex);	pindesc = pin_desc_get(pctldev, pin);	mutex_unlock(&pinctrl_mutex); 	return pindesc != NULL;}EXPORT_SYMBOL_GPL(pin_is_valid); /* Deletes a range of pin descriptors */static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,				  const struct pinctrl_pin_desc *pins,				  unsigned num_pins){	int i; 	for (i = 0; i < num_pins; i++) {		struct pin_desc *pindesc; 		pindesc = radix_tree_lookup(&pctldev->pin_desc_tree,					    pins[i].number);		if (pindesc != NULL) {			radix_tree_delete(&pctldev->pin_desc_tree,					  pins[i].number);			if (pindesc->dynamic_name)				kfree(pindesc->name);		}		kfree(pindesc);	}} static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,				    unsigned number, const char *name){	struct pin_desc *pindesc; 	pindesc = pin_desc_get(pctldev, number);	if (pindesc != NULL) {		pr_err("pin %d already registered on %s\n", number,		       pctldev->desc->name);		return -EINVAL;	} 	pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL);	if (pindesc == NULL) {		dev_err(pctldev->dev, "failed to alloc struct pin_desc\n");		return -ENOMEM;	} 	/* Set owner */	pindesc->pctldev = pctldev; 	/* Copy basic pin info */	if (name) {		pindesc->name = name;	} else {		pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);		if (pindesc->name == NULL)			return -ENOMEM;		pindesc->dynamic_name = true;	} 	radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);	pr_debug("registered pin %d (%s) on %s\n",		 number, pindesc->name, pctldev->desc->name);	return 0;} static int pinctrl_register_pins(struct pinctrl_dev *pctldev,				 struct pinctrl_pin_desc const *pins,				 unsigned num_descs){	unsigned i;	int ret = 0; 	for (i = 0; i < num_descs; i++) {		ret = pinctrl_register_one_pin(pctldev,					       pins[i].number, pins[i].name);		if (ret)			return ret;	} 	return 0;} /** * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range * @pctldev: pin controller device to check * @gpio: gpio pin to check taken from the global GPIO pin space * * Tries to match a GPIO pin number to the ranges handled by a certain pin * controller, return the range or NULL */static struct pinctrl_gpio_range *pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio){	struct pinctrl_gpio_range *range = NULL; 	/* Loop over the ranges */	list_for_each_entry(range, &pctldev->gpio_ranges, node) {		/* Check if we're in the valid range */		if (gpio >= range->base &&		    gpio < range->base + range->npins) {			return range;		}	} 	return NULL;} /** * pinctrl_get_device_gpio_range() - find device for GPIO range * @gpio: the pin to locate the pin controller for * @outdev: the pin control device if found * @outrange: the GPIO range if found * * Find the pin controller handling a certain GPIO pin from the pinspace of * the GPIO subsystem, return the device and the matching GPIO range. Returns * -EPROBE_DEFER if the GPIO range could not be found in any device since it * may still have not been registered. */static int pinctrl_get_device_gpio_range(unsigned gpio,					 struct pinctrl_dev **outdev,					 struct pinctrl_gpio_range **outrange){	struct pinctrl_dev *pctldev = NULL; 	/* Loop over the pin controllers */	list_for_each_entry(pctldev, &pinctrldev_list, node) {		struct pinctrl_gpio_range *range; 		range = pinctrl_match_gpio_range(pctldev, gpio);		if (range != NULL) {			*outdev = pctldev;			*outrange = range;			return 0;		}	} 	return -EPROBE_DEFER;} /** * pinctrl_add_gpio_range() - register a GPIO range for a controller * @pctldev: pin controller device to add the range to * @range: the GPIO range to add * * This adds a range of GPIOs to be handled by a certain pin controller. Call * this to register handled ranges after registering your pin controller. */void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,			    struct pinctrl_gpio_range *range){	mutex_lock(&pinctrl_mutex);	list_add_tail(&range->node, &pctldev->gpio_ranges);	mutex_unlock(&pinctrl_mutex);}EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); /** * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller * @pctldev: pin controller device to remove the range from * @range: the GPIO range to remove */void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,			       struct pinctrl_gpio_range *range){	mutex_lock(&pinctrl_mutex);	list_del(&range->node);	mutex_unlock(&pinctrl_mutex);}EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); /** * pinctrl_get_group_selector() - returns the group selector for a group * @pctldev: the pin controller handling the group * @pin_group: the pin group to look up */int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,			       const char *pin_group){	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;	unsigned ngroups = pctlops->get_groups_count(pctldev);	unsigned group_selector = 0; 	while (group_selector < ngroups) {		const char *gname = pctlops->get_group_name(pctldev,							    group_selector);		if (!strcmp(gname, pin_group)) {			dev_dbg(pctldev->dev,				"found group selector %u for %s\n",				group_selector,				pin_group);			return group_selector;		} 		group_selector++;	} 	dev_err(pctldev->dev, "does not have pin group %s\n",		pin_group); 	return -EINVAL;} /** * pinctrl_request_gpio() - request a single pin to be used in as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_request() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed in. */int pinctrl_request_gpio(unsigned gpio){	struct pinctrl_dev *pctldev;	struct pinctrl_gpio_range *range;	int ret;	int pin; 	mutex_lock(&pinctrl_mutex); 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);	if (ret) {		mutex_unlock(&pinctrl_mutex);		return ret;	} 	/* Convert to the pin controllers number space */	pin = gpio - range->base + range->pin_base; 	ret = pinmux_request_gpio(pctldev, range, pin, gpio); 	mutex_unlock(&pinctrl_mutex);	return ret;}EXPORT_SYMBOL_GPL(pinctrl_request_gpio); /** * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_free() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed out. */void pinctrl_free_gpio(unsigned gpio){	struct pinctrl_dev *pctldev;	struct pinctrl_gpio_range *range;	int ret;	int pin; 	mutex_lock(&pinctrl_mutex); 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);	if (ret) {		mutex_unlock(&pinctrl_mutex);		return;	} 	/* Convert to the pin controllers number space */	pin = gpio - range->base + range->pin_base; 	pinmux_free_gpio(pctldev, pin, range); 	mutex_unlock(&pinctrl_mutex);}EXPORT_SYMBOL_GPL(pinctrl_free_gpio); static int pinctrl_gpio_direction(unsigned gpio, bool input){	struct pinctrl_dev *pctldev;	struct pinctrl_gpio_range *range;	int ret;	int pin; 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);	if (ret)		return ret; 	/* Convert to the pin controllers number space */	pin = gpio - range->base + range->pin_base; 	return pinmux_gpio_direction(pctldev, range, pin, input);} /** * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_input() semantics, platforms and individual * drivers shall *NOT* touch pin control GPIO calls. */int pinctrl_gpio_direction_input(unsigned gpio){	int ret;	mutex_lock(&pinctrl_mutex);	ret = pinctrl_gpio_direction(gpio, true);	mutex_unlock(&pinctrl_mutex);	return ret;}EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); /** * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_output() semantics, platforms and individual * drivers shall *NOT* touch pin control GPIO calls. */int pinctrl_gpio_direction_output(unsigned gpio){	int ret;	mutex_lock(&pinctrl_mutex);	ret = pinctrl_gpio_direction(gpio, false);	mutex_unlock(&pinctrl_mutex);	return ret;}EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); static struct pinctrl_state *find_state(struct pinctrl *p,					const char *name)

Lines 1–500 of 1517.