/* * 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. Load more
/* * 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)