12744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* 22744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Core driver for the pin muxing portions of the pin control subsystem 32744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 42744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Copyright (C) 2011 ST-Ericsson SA 52744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Written on behalf of Linaro for ST-Ericsson 62744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Based on bits of regulator core, gpio core and clk core 72744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 82744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Author: Linus Walleij <linus.walleij@linaro.org> 92744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * License terms: GNU General Public License (GPL) version 2 112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#define pr_fmt(fmt) "pinmux core: " fmt 132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/kernel.h> 152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/module.h> 162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/init.h> 172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/device.h> 182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/slab.h> 192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/radix-tree.h> 202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/err.h> 212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/list.h> 222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/mutex.h> 232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/spinlock.h> 2497607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij#include <linux/string.h> 252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/sysfs.h> 262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/debugfs.h> 272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/seq_file.h> 282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/pinctrl/machine.h> 292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/pinctrl/pinmux.h> 302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include "core.h" 312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* List of pinmuxes */ 332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic DEFINE_MUTEX(pinmux_list_mutex); 342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic LIST_HEAD(pinmux_list); 352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3659b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij/* Global pinmux maps */ 3797607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleijstatic struct pinmux_map *pinmux_maps; 382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic unsigned pinmux_maps_num; 392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * struct pinmux_group - group list item for pinmux groups 422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @node: pinmux group list node 432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @group_selector: the group selector for this group 442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinmux_group { 462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head node; 472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned group_selector; 482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * struct pinmux - per-device pinmux state holder 522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @node: global list node 532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @dev: the device using this pinmux 542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @usecount: the number of active users of this mux setting, used to keep 552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * track of nested use cases 562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin control device handling this pinmux 572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @func_selector: the function selector for the pinmux device handling 582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * this pinmux 592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @groups: the group selectors for the pinmux device and 602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * selector combination handling this pinmux, this is a list that 612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * will be traversed on all pinmux operations such as 622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * get/put/enable/disable 632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @mutex: a lock for the pinmux state holder 642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinmux { 662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head node; 672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct device *dev; 682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned usecount; 692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev; 702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned func_selector; 712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head groups; 722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct mutex mutex; 732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * struct pinmux_hog - a list item to stash mux hogs 772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @node: pinmux hog list node 782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @map: map entry responsible for this hogging 792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pmx: the pinmux hogged by this item 802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinmux_hog { 822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head node; 832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map; 842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux *pmx; 852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pin_request() - request a single pin to be muxed in, typically for GPIO 892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pin: the pin number in the global pin space 902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @function: a functional name to give to this pin, passed to the driver 912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * so it knows what function to mux in, e.g. the string "gpioNN" 922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * means that you want to mux in the pin for use as GPIO number NN 932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @gpio_range: the range matching the GPIO pin if this is a request for a 942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * single GPIO pin 952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pin_request(struct pinctrl_dev *pctldev, 973712a3c488987849613a4ad74129e67e40b12b38Stephen Warren int pin, const char *function, 982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *gpio_range) 992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 1002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *desc; 1012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *ops = pctldev->desc->pmxops; 1022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int status = -EINVAL; 1032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10451cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, function); 1052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc = pin_desc_get(pctldev, pin); 1072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (desc == NULL) { 10851cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 1092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "pin is not registered so it cannot be requested\n"); 1102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij goto out; 1112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 113d2f6a1c6fb0e510a24ccac066eefbcfd0c932858Marek Belisko if (!function) { 11451cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, "no function name given\n"); 115d2f6a1c6fb0e510a24ccac066eefbcfd0c932858Marek Belisko return -EINVAL; 116d2f6a1c6fb0e510a24ccac066eefbcfd0c932858Marek Belisko } 117d2f6a1c6fb0e510a24ccac066eefbcfd0c932858Marek Belisko 1182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock(&desc->lock); 1195d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren if (desc->mux_function) { 1202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&desc->lock); 12151cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 1222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "pin already requested\n"); 1232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij goto out; 1242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1255d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren desc->mux_function = function; 1262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&desc->lock); 1272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Let each pin increase references to this module */ 1292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!try_module_get(pctldev->owner)) { 13051cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 1312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "could not increase module refcount for pin %d\n", 1322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pin); 1332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij status = -EINVAL; 1342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij goto out_free_pin; 1352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 1382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * If there is no kind of request function for the pin we just assume 1392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * we got it by default and proceed. 1402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 1413712a3c488987849613a4ad74129e67e40b12b38Stephen Warren if (gpio_range && ops->gpio_request_enable) 1422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* This requests and enables a single GPIO pin */ 1432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij status = ops->gpio_request_enable(pctldev, gpio_range, pin); 1442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else if (ops->request) 1452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij status = ops->request(pctldev, pin); 1462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else 1472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij status = 0; 1482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (status) 150f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", 1512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldev->desc->name, pin); 1522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijout_free_pin: 1532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (status) { 1542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock(&desc->lock); 1555d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren desc->mux_function = NULL; 1562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&desc->lock); 1572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijout: 1592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (status) 16051cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, "pin-%d (%s) status %d\n", 1612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pin, function ? : "?", status); 1622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return status; 1642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 1652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 1672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pin_free() - release a single muxed in pin so something else can be muxed 1682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin controller device handling this pin 1692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pin: the pin to free 1703712a3c488987849613a4ad74129e67e40b12b38Stephen Warren * @gpio_range: the range matching the GPIO pin if this is a request for a 1713712a3c488987849613a4ad74129e67e40b12b38Stephen Warren * single GPIO pin 172336cdba09a5df706402628fb20b7660d186aff6cLinus Walleij * 173336cdba09a5df706402628fb20b7660d186aff6cLinus Walleij * This function returns a pointer to the function name in use. This is used 174336cdba09a5df706402628fb20b7660d186aff6cLinus Walleij * for callers that dynamically allocate a function name so it can be freed 175336cdba09a5df706402628fb20b7660d186aff6cLinus Walleij * once the pin is free. This is done for GPIO request functions. 1762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 1773712a3c488987849613a4ad74129e67e40b12b38Stephen Warrenstatic const char *pin_free(struct pinctrl_dev *pctldev, int pin, 1783712a3c488987849613a4ad74129e67e40b12b38Stephen Warren struct pinctrl_gpio_range *gpio_range) 1792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 1802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *ops = pctldev->desc->pmxops; 1812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *desc; 1823712a3c488987849613a4ad74129e67e40b12b38Stephen Warren const char *func; 1832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc = pin_desc_get(pctldev, pin); 1852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (desc == NULL) { 18651cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 1872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "pin is not registered so it cannot be freed\n"); 1883712a3c488987849613a4ad74129e67e40b12b38Stephen Warren return NULL; 1892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1913712a3c488987849613a4ad74129e67e40b12b38Stephen Warren /* 1923712a3c488987849613a4ad74129e67e40b12b38Stephen Warren * If there is no kind of request function for the pin we just assume 1933712a3c488987849613a4ad74129e67e40b12b38Stephen Warren * we got it by default and proceed. 1943712a3c488987849613a4ad74129e67e40b12b38Stephen Warren */ 1953712a3c488987849613a4ad74129e67e40b12b38Stephen Warren if (gpio_range && ops->gpio_disable_free) 1963712a3c488987849613a4ad74129e67e40b12b38Stephen Warren ops->gpio_disable_free(pctldev, gpio_range, pin); 1973712a3c488987849613a4ad74129e67e40b12b38Stephen Warren else if (ops->free) 1982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ops->free(pctldev, pin); 1992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock(&desc->lock); 2013712a3c488987849613a4ad74129e67e40b12b38Stephen Warren func = desc->mux_function; 2025d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren desc->mux_function = NULL; 2032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&desc->lock); 2042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij module_put(pctldev->owner); 2053712a3c488987849613a4ad74129e67e40b12b38Stephen Warren 2063712a3c488987849613a4ad74129e67e40b12b38Stephen Warren return func; 2072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 2102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_request_gpio() - request a single pin to be muxed in as GPIO 2112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @gpio: the GPIO pin number from the GPIO subsystem number space 212542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * 213542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * This function should *ONLY* be used from gpiolib-based GPIO drivers, 214542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * as part of their gpio_request() semantics, platforms and individual drivers 215542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * shall *NOT* request GPIO pins to be muxed in. 2162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 2172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijint pinmux_request_gpio(unsigned gpio) 2182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij char gpiostr[16]; 2205d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren const char *function; 2212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev; 2222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range; 2232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 2242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int pin; 2252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); 2272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 2282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 2292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Convert to the pin controllers number space */ 2313c739ad0df5eb41cd7adad879eda6aa09879eb76Chanho Park pin = gpio - range->base + range->pin_base; 2322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Conjure some name stating what chip and pin this is taken by */ 2342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij snprintf(gpiostr, 15, "%s:%d", range->name, gpio); 2352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2365d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren function = kstrdup(gpiostr, GFP_KERNEL); 2375d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren if (!function) 2385d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren return -EINVAL; 2395d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren 2403712a3c488987849613a4ad74129e67e40b12b38Stephen Warren ret = pin_request(pctldev, pin, function, range); 2415d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren if (ret < 0) 2425d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren kfree(function); 2435d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren 2445d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren return ret; 2452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2462744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_request_gpio); 2472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 2492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_free_gpio() - free a single pin, currently used as GPIO 2502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @gpio: the GPIO pin number from the GPIO subsystem number space 251542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * 252542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * This function should *ONLY* be used from gpiolib-based GPIO drivers, 253542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * as part of their gpio_free() semantics, platforms and individual drivers 254542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * shall *NOT* request GPIO pins to be muxed out. 2552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 2562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_free_gpio(unsigned gpio) 2572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev; 2592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range; 2602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 2612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int pin; 2623712a3c488987849613a4ad74129e67e40b12b38Stephen Warren const char *func; 2632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); 2652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 2662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 2672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Convert to the pin controllers number space */ 2693c739ad0df5eb41cd7adad879eda6aa09879eb76Chanho Park pin = gpio - range->base + range->pin_base; 2702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2713712a3c488987849613a4ad74129e67e40b12b38Stephen Warren func = pin_free(pctldev, pin, range); 2723712a3c488987849613a4ad74129e67e40b12b38Stephen Warren kfree(func); 2732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2742744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_free_gpio); 2752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 276542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleijstatic int pinmux_gpio_direction(unsigned gpio, bool input) 277542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij{ 278542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij struct pinctrl_dev *pctldev; 279542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij struct pinctrl_gpio_range *range; 280542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij const struct pinmux_ops *ops; 281542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij int ret; 282542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij int pin; 283542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 284542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); 285542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij if (ret) 286542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij return ret; 287542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 288542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij ops = pctldev->desc->pmxops; 289542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 290542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij /* Convert to the pin controllers number space */ 291542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij pin = gpio - range->base + range->pin_base; 292542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 293542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij if (ops->gpio_set_direction) 294542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij ret = ops->gpio_set_direction(pctldev, range, pin, input); 295542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij else 296542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij ret = 0; 297542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 298542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij return ret; 299542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij} 300542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 301542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij/** 302542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode 303542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * @gpio: the GPIO pin number from the GPIO subsystem number space 304542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * 305542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * This function should *ONLY* be used from gpiolib-based GPIO drivers, 306542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * as part of their gpio_direction_input() semantics, platforms and individual 307542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * drivers shall *NOT* touch pinmux GPIO calls. 308542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij */ 309542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleijint pinmux_gpio_direction_input(unsigned gpio) 310542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij{ 311542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij return pinmux_gpio_direction(gpio, true); 312542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij} 313542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus WalleijEXPORT_SYMBOL_GPL(pinmux_gpio_direction_input); 314542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 315542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij/** 316542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode 317542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * @gpio: the GPIO pin number from the GPIO subsystem number space 318542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * 319542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * This function should *ONLY* be used from gpiolib-based GPIO drivers, 320542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * as part of their gpio_direction_output() semantics, platforms and individual 321542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij * drivers shall *NOT* touch pinmux GPIO calls. 322542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij */ 323542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleijint pinmux_gpio_direction_output(unsigned gpio) 324542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij{ 325542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij return pinmux_gpio_direction(gpio, false); 326542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij} 327542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus WalleijEXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); 328542e704f3ffee1dc4539c9e8191e4dc215220f5eLinus Walleij 3292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 3302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_register_mappings() - register a set of pinmux mappings 33197607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij * @maps: the pinmux mappings table to register, this should be marked with 33297607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij * __initdata so it can be discarded after boot, this function will 33397607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij * perform a shallow copy for the mapping entries. 3342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @num_maps: the number of maps in the mapping table 3352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 3362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Only call this once during initialization of your machine, the function is 3372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * tagged as __init and won't be callable after init has completed. The map 3382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * passed into this function will be owned by the pinmux core and cannot be 339e6337c3c96a7ee5cfd5e7afed825f894d4576f58Dong Aisheng * freed. 3402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 3412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijint __init pinmux_register_mappings(struct pinmux_map const *maps, 3422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_maps) 3432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 34459b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij void *tmp_maps; 3452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 3462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("add %d pinmux maps\n", num_maps); 34897607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij 34959b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij /* First sanity check the new mapping */ 3502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_maps; i++) { 3512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!maps[i].name) { 352f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pr_err("failed to register map %d: no map name given\n", 353f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König i); 35459b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij return -EINVAL; 3552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 35697607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij 3572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { 358f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pr_err("failed to register map %s (%d): no pin control device given\n", 3592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij maps[i].name, i); 36059b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij return -EINVAL; 3612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 36297607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij 3632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!maps[i].function) { 364f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pr_err("failed to register map %s (%d): no function ID given\n", 365f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König maps[i].name, i); 36659b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij return -EINVAL; 3672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 3682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!maps[i].dev && !maps[i].dev_name) 3702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("add system map %s function %s with no device\n", 3712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij maps[i].name, 3722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij maps[i].function); 3732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else 3742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("register map %s, function %s\n", 3752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij maps[i].name, 3762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij maps[i].function); 37759b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij } 3782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 37959b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij /* 38059b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij * Make a copy of the map array - string pointers will end up in the 38159b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij * kernel const section anyway so these do not need to be deep copied. 38259b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij */ 38359b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij if (!pinmux_maps_num) { 38459b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij /* On first call, just copy them */ 38559b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij tmp_maps = kmemdup(maps, 38659b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij sizeof(struct pinmux_map) * num_maps, 38759b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij GFP_KERNEL); 38859b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij if (!tmp_maps) 38959b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij return -ENOMEM; 39059b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij } else { 39159b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij /* Subsequent calls, reallocate array to new size */ 39259b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num; 39359b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij size_t newsize = sizeof(struct pinmux_map) * num_maps; 39459b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij 39559b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL); 39659b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij if (!tmp_maps) 39759b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij return -ENOMEM; 39859b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij memcpy((tmp_maps + oldsize), maps, newsize); 39997607d157c133ab18dfcd77fa836e37fa950a44aLinus Walleij } 4002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 40159b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij pinmux_maps = tmp_maps; 40259b099b04981917ee7fbd88b6f50eeaffc9f33cdLinus Walleij pinmux_maps_num += num_maps; 4032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 4042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 407de849eecd0addaa6bf60f2f7be36b30abf9ff2aeTony Lindgren * acquire_pins() - acquire all the pins for a certain function on a pinmux 4082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: the device to take the pins on 4092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @func_selector: the function selector to acquire the pins for 4102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @group_selector: the group selector containing the pins to acquire 4112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 4122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int acquire_pins(struct pinctrl_dev *pctldev, 4132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned func_selector, 4142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned group_selector) 4152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 4172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *pmxops = pctldev->desc->pmxops; 4182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *func = pmxops->get_function_name(pctldev, 4192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij func_selector); 420a5818a8bd095a08cfb1871b63af9c8bed103e4b9Stephen Warren const unsigned *pins; 4212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_pins; 4222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 4232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 4242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pctlops->get_group_pins(pctldev, group_selector, 4262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &pins, &num_pins); 4272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 4282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 4292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 43051cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n", 4312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij num_pins, group_selector); 4322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Try to allocate all pins in this group, one by one */ 4342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_pins; i++) { 4353712a3c488987849613a4ad74129e67e40b12b38Stephen Warren ret = pin_request(pctldev, pins[i], func, NULL); 4362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 43751cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 438f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König "could not get pin %d for function %s on device %s - conflicting mux mappings?\n", 4392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pins[i], func ? : "(undefined)", 4402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_dev_get_name(pctldev)); 4412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* On error release all taken pins */ 4422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij i--; /* this pin just failed */ 4432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (; i >= 0; i--) 4443712a3c488987849613a4ad74129e67e40b12b38Stephen Warren pin_free(pctldev, pins[i], NULL); 4452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -ENODEV; 4462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 4492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 4522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * release_pins() - release pins taken by earlier acquirement 453de849eecd0addaa6bf60f2f7be36b30abf9ff2aeTony Lindgren * @pctldev: the device to free the pins on 4542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @group_selector: the group selector containing the pins to free 4552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 4562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void release_pins(struct pinctrl_dev *pctldev, 4572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned group_selector) 4582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 460a5818a8bd095a08cfb1871b63af9c8bed103e4b9Stephen Warren const unsigned *pins; 4612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_pins; 4622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 4632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 4642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pctlops->get_group_pins(pctldev, group_selector, 4662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &pins, &num_pins); 4672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 468f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", 4692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij group_selector); 4702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 4712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_pins; i++) 4733712a3c488987849613a4ad74129e67e40b12b38Stephen Warren pin_free(pctldev, pins[i], NULL); 4742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 4772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_check_pin_group() - check function and pin group combo 4782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: device to check the pin group vs function for 4792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @func_selector: the function selector to check the pin group for, we have 4802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * already looked this up in the calling function 4812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pin_group: the pin group to match to the function 4822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 4832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * This function will check that the pinmux driver can supply the 4842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * selected pin group for a certain function, returns the group selector if 4852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * the group and function selector will work fine together, else returns 4862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * negative 4872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 4882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_check_pin_group(struct pinctrl_dev *pctldev, 4892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned func_selector, 4902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *pin_group) 4912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *pmxops = pctldev->desc->pmxops; 4932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 4942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 4952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 4972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * If the driver does not support different pin groups for the 4982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * functions, we only support group 0, and assume this exists. 4992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 5002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!pctlops || !pctlops->list_groups) 5012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 5022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 5042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Passing NULL (no specific group) will select the first and 5052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * hopefully only group of pins available for this function. 5062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 5072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!pin_group) { 5082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij char const * const *groups; 5092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_groups; 5102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pmxops->get_function_groups(pctldev, func_selector, 5122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &groups, &num_groups); 5132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 5142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 5152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (num_groups < 1) 5162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 5177afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij ret = pinctrl_get_group_selector(pctldev, groups[0]); 5182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret < 0) { 51951cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 520f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König "function %s wants group %s but the pin controller does not seem to have that group\n", 5212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmxops->get_function_name(pctldev, func_selector), 5222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij groups[0]); 5232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 5242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (num_groups > 1) 52751cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, 528f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König "function %s support more than one group, default-selecting first group %s (%d)\n", 5292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmxops->get_function_name(pctldev, func_selector), 5302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij groups[0], 5312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret); 5322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 5342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 53651cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, 5372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "check if we have pin group %s on controller %s\n", 5382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pin_group, pinctrl_dev_get_name(pctldev)); 5392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5407afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij ret = pinctrl_get_group_selector(pctldev, pin_group); 5412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret < 0) { 54251cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, 5432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "%s does not support pin group %s with function %s\n", 5442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_dev_get_name(pctldev), 5452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pin_group, 5462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmxops->get_function_name(pctldev, func_selector)); 5472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 5492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 5522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_search_function() - check pin control driver for a certain function 5532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: device to check for function and position 5542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @map: function map containing the function and position to look for 5552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @func_selector: returns the applicable function selector if found 5562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @group_selector: returns the applicable group selector if found 5572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 5582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * This will search the pinmux driver for an applicable 5592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * function with a specific pin group, returns 0 if these can be mapped 5602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * negative otherwise 5612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 5622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_search_function(struct pinctrl_dev *pctldev, 5632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map, 5642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned *func_selector, 5652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned *group_selector) 5662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *ops = pctldev->desc->pmxops; 5682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned selector = 0; 5692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* See if this pctldev has this function */ 5712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij while (ops->list_functions(pctldev, selector) >= 0) { 5722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *fname = ops->get_function_name(pctldev, 5732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij selector); 5742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 5752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!strcmp(map->function, fname)) { 5772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Found the function, check pin group */ 5782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinmux_check_pin_group(pctldev, selector, 5792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->group); 5802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret < 0) 5812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 5822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* This function and group selector can be used */ 5842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij *func_selector = selector; 5852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij *group_selector = ret; 5862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 5872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij selector++; 5902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_err("%s does not support function %s\n", 5932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_dev_get_name(pctldev), map->function); 5942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 5952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 5982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_enable_muxmap() - enable a map entry for a certain pinmux 5992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 6002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, 6012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux *pmx, 6022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct device *dev, 6032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *devname, 6042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map) 6052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 6062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned func_selector; 6072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned group_selector; 6082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_group *grp; 6092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 6102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 6122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Note that we're not locking the pinmux mutex here, because 6132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * this is only called at pinmux initialization time when it 6142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * has not been added to any list and thus is not reachable 6152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * by anyone else. 6162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 6172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx->pctldev && pmx->pctldev != pctldev) { 61951cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 620f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König "different pin control devices given for device %s, function %s\n", 621f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König devname, map->function); 6222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 6232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->dev = dev; 6252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->pctldev = pctldev; 6262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Now go into the driver and try to match a function and group */ 6282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinmux_search_function(pctldev, map, &func_selector, 6292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &group_selector); 6302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret < 0) 6312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 6322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 6342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * If the function selector is already set, it needs to be identical, 6352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * we support several groups with one function but not several 6362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * functions with one or several groups in the same pinmux. 6372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 6382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx->func_selector != UINT_MAX && 6392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->func_selector != func_selector) { 64051cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 6412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "dual function defines in the map for device %s\n", 6422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname); 6432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 6442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->func_selector = func_selector; 6462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Now add this group selector, we may have many of them */ 6482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL); 6492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!grp) 6502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -ENOMEM; 6512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij grp->group_selector = group_selector; 6522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = acquire_pins(pctldev, func_selector, group_selector); 6532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 6542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(grp); 6552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 6562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_add(&grp->node, &pmx->groups); 6582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 6602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 6612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinmux_free_groups(struct pinmux *pmx) 6632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 6642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head *node, *tmp; 6652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_safe(node, tmp, &pmx->groups) { 6672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_group *grp = 6682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_entry(node, struct pinmux_group, node); 6692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Release all pins taken by this group */ 6702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij release_pins(pmx->pctldev, grp->group_selector); 6712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_del(node); 6722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(grp); 6732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 6752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 6772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_get() - retrieves the pinmux for a certain device 6782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @dev: the device to get the pinmux for 6792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @name: an optional specific mux mapping name or NULL, the name is only 6802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * needed if you want to have more than one mapping per device, or if you 6812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * need an anonymous pinmux (not tied to any specific device) 6822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 6832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinmux *pinmux_get(struct device *dev, const char *name) 6842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 6852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map = NULL; 6862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = NULL; 6872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *devname = NULL; 6882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux *pmx; 6892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij bool found_map; 6902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_maps = 0; 6912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret = -ENODEV; 6922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 6932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* We must have dev or ID or both */ 6952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!dev && !name) 6962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ERR_PTR(-EINVAL); 6972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (dev) 6992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname = dev_name(dev); 7002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("get mux %s for device %s\n", name, 7022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname ? devname : "(none)"); 7032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 7052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * create the state cookie holder struct pinmux for each 7062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * mapping, this is what consumers will get when requesting 7072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * a pinmux handle with pinmux_get() 7082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 7092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL); 7102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx == NULL) 7112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ERR_PTR(-ENOMEM); 7122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_init(&pmx->mutex); 7132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->func_selector = UINT_MAX; 7142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij INIT_LIST_HEAD(&pmx->groups); 7152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Iterate over the pinmux maps to locate the right ones */ 7172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < pinmux_maps_num; i++) { 7182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map = &pinmux_maps[i]; 7192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij found_map = false; 7202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 7222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * First, try to find the pctldev given in the map 7232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 7242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev, 7252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->ctrl_dev_name); 7262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!pctldev) { 7272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *devname = NULL; 7282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (map->ctrl_dev) 7302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname = dev_name(map->ctrl_dev); 7312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else if (map->ctrl_dev_name) 7322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname = map->ctrl_dev_name; 7332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 734f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", 7352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->function); 7362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_warning("given pinctrl device name: %s", 7372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname ? devname : "UNDEFINED"); 7382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Continue to check the other mappings anyway... */ 7402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 7412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("in map, found pctldev %s to handle function %s", 74451cd24ee625c348654114032499914d0311e5832Stephen Warren dev_name(pctldev->dev), map->function); 7452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 7482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * If we're looking for a specific named map, this must match, 7492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * else we loop and look for the next. 7502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 7512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (name != NULL) { 7522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (map->name == NULL) 7532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 7542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (strcmp(map->name, name)) 7552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 7562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 7592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * This is for the case where no device name is given, we 7602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * already know that the function name matches from above 7612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * code. 7622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 7632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!map->dev_name && (name != NULL)) 7642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij found_map = true; 7652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* If the mapping has a device set up it must match */ 7672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (map->dev_name && 7682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij (!devname || !strcmp(map->dev_name, devname))) 7692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* MATCH! */ 7702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij found_map = true; 7712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* If this map is applicable, then apply it */ 7732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (found_map) { 7742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinmux_enable_muxmap(pctldev, pmx, dev, 7752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname, map); 7762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 7772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_free_groups(pmx); 7782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(pmx); 7792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ERR_PTR(ret); 7802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij num_maps++; 7822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* We should have atleast one map, right */ 7872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!num_maps) { 7882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_err("could not find any mux maps for device %s, ID %s\n", 7892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname ? devname : "(anonymous)", 7902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij name ? name : "(undefined)"); 7912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(pmx); 7922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ERR_PTR(-EINVAL); 7932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 7942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 7952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("found %u mux maps for device %s, UD %s\n", 7962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij num_maps, 7972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devname ? devname : "(anonymous)", 7982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij name ? name : "(undefined)"); 7992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Add the pinmux to the global list */ 8012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinmux_list_mutex); 8022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_add(&pmx->node, &pinmux_list); 8032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinmux_list_mutex); 8042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return pmx; 8062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 8072744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_get); 8082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 8102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_put() - release a previously claimed pinmux 8112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pmx: a pinmux previously claimed by pinmux_get() 8122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 8132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_put(struct pinmux *pmx) 8142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 8152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx == NULL) 8162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 8172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pmx->mutex); 8192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx->usecount) 8202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_warn("releasing pinmux with active users!\n"); 8212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Free the groups and all acquired pins */ 8222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_free_groups(pmx); 8232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pmx->mutex); 8242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Remove from list */ 8262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinmux_list_mutex); 8272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_del(&pmx->node); 8282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinmux_list_mutex); 8292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(pmx); 8312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 8322744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_put); 8332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 8352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_enable() - enable a certain pinmux setting 8362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pmx: the pinmux to enable, previously claimed by pinmux_get() 8372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 8382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijint pinmux_enable(struct pinmux *pmx) 8392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 8402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret = 0; 8412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx == NULL) 8432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 8442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pmx->mutex); 8452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx->usecount++ == 0) { 8462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = pmx->pctldev; 8472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *ops = pctldev->desc->pmxops; 8482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_group *grp; 8492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(grp, &pmx->groups, node) { 8512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = ops->enable(pctldev, pmx->func_selector, 8522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij grp->group_selector); 8532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 8542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 8552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * TODO: call disable() on all groups we called 8562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * enable() on to this point? 8572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 8582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->usecount--; 8592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij break; 8602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 8612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 8622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 8632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pmx->mutex); 8642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 8652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 8662744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_enable); 8672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 8692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_disable() - disable a certain pinmux setting 8702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pmx: the pinmux to disable, previously claimed by pinmux_get() 8712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 8722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_disable(struct pinmux *pmx) 8732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 8742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pmx == NULL) 8752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 8762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pmx->mutex); 8782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (--pmx->usecount == 0) { 8792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = pmx->pctldev; 8802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *ops = pctldev->desc->pmxops; 8812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_group *grp; 8822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(grp, &pmx->groups, node) { 8842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ops->disable(pctldev, pmx->func_selector, 8852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij grp->group_selector); 8862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 8872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 8882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pmx->mutex); 8892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 8902744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinmux_disable); 8912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 892b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgrenint pinmux_check_ops(struct pinctrl_dev *pctldev) 8932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 894b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren const struct pinmux_ops *ops = pctldev->desc->pmxops; 895b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren unsigned selector = 0; 896b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren 8972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Check that we implement required operations */ 8982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!ops->list_functions || 8992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij !ops->get_function_name || 9002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij !ops->get_function_groups || 9012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij !ops->enable || 9022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij !ops->disable) 9032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 9042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 905b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren /* Check that all functions registered have names */ 906b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren while (ops->list_functions(pctldev, selector) >= 0) { 907b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren const char *fname = ops->get_function_name(pctldev, 908b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren selector); 909b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren if (!fname) { 910b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pr_err("pinmux ops has no name for function%u\n", 911b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren selector); 912b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren return -EINVAL; 913b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren } 914b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren selector++; 915b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren } 916b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren 9172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 9182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 9192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* Hog a single map entry and add to the hoglist */ 9212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_hog_map(struct pinctrl_dev *pctldev, 9222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map) 9232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 9242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_hog *hog; 9252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux *pmx; 9262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 9272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (map->dev || map->dev_name) { 9292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* 9302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * TODO: the day we have device tree support, we can 9312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * traverse the device tree and hog to specific device nodes 9322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * without any problems, so then we can hog pinmuxes for 9332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * all devices that just want a static pin mux at this point. 9342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 935f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", 936f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König map->name); 9372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 9382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 9392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij hog = kzalloc(sizeof(struct pinmux_hog), GFP_KERNEL); 9412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!hog) 9422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -ENOMEM; 9432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx = pinmux_get(NULL, map->name); 9452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (IS_ERR(pmx)) { 9462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(hog); 94751cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 9482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "could not get the %s pinmux mapping for hogging\n", 9492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->name); 9502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return PTR_ERR(pmx); 9512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 9522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinmux_enable(pmx); 9542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 9552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_put(pmx); 9562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(hog); 95751cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, 9582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "could not enable the %s pinmux mapping for hogging\n", 9592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->name); 9602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 9612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 9622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij hog->map = map; 9642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij hog->pmx = pmx; 9652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 96651cd24ee625c348654114032499914d0311e5832Stephen Warren dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, 9672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->function); 9682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->pinmux_hogs_lock); 9692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_add(&hog->node, &pctldev->pinmux_hogs); 9702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->pinmux_hogs_lock); 9712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 9732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 9742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 9762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinmux_hog_maps() - hog specific map entries on controller device 9772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: the pin control device to hog entries on 9782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 9792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * When the pin controllers are registered, there may be some specific pinmux 9802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * map entries that need to be hogged, i.e. get+enabled until the system shuts 9812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * down. 9822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 9832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijint pinmux_hog_maps(struct pinctrl_dev *pctldev) 9842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 98551cd24ee625c348654114032499914d0311e5832Stephen Warren struct device *dev = pctldev->dev; 9862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *devname = dev_name(dev); 9872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 9882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 9892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij INIT_LIST_HEAD(&pctldev->pinmux_hogs); 9912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_init(&pctldev->pinmux_hogs_lock); 9922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < pinmux_maps_num; i++) { 9942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map = &pinmux_maps[i]; 9952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 9969e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren if (!map->hog_on_boot) 9979e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren continue; 9989e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren 9999e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren if ((map->ctrl_dev == dev) || 10009e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren (map->ctrl_dev_name && 10019e2551e10b5c7ba550849bd9ed519e498cc30e68Tony Lindgren !strcmp(map->ctrl_dev_name, devname))) { 10022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* OK time to hog! */ 10032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinmux_hog_map(pctldev, map); 10042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 10052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 10062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 10072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 10082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 10092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 10102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 1012336cdba09a5df706402628fb20b7660d186aff6cLinus Walleij * pinmux_unhog_maps() - unhog specific map entries on controller device 10132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: the pin control device to unhog entries on 10142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 10152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_unhog_maps(struct pinctrl_dev *pctldev) 10162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 10172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct list_head *node, *tmp; 10182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->pinmux_hogs_lock); 10202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_safe(node, tmp, &pctldev->pinmux_hogs) { 10212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_hog *hog = 10222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_entry(node, struct pinmux_hog, node); 10232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_disable(hog->pmx); 10242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_put(hog->pmx); 10252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_del(node); 10262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(hog); 10272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 10282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->pinmux_hogs_lock); 10292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 10302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#ifdef CONFIG_DEBUG_FS 10322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* Called from pincontrol core */ 10342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_functions_show(struct seq_file *s, void *what) 10352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 10362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 10372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *pmxops = pctldev->desc->pmxops; 10382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned func_selector = 0; 10392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij while (pmxops->list_functions(pctldev, func_selector) >= 0) { 10412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *func = pmxops->get_function_name(pctldev, 10422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij func_selector); 10432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char * const *groups; 10442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_groups; 10452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 10462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 10472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pmxops->get_function_groups(pctldev, func_selector, 10492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &groups, &num_groups); 10502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 10512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "function %s: COULD NOT GET GROUPS\n", 10522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij func); 10532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "function: %s, groups = [ ", func); 10552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_groups; i++) 10562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%s ", groups[i]); 10572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "]\n"); 10582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij func_selector++; 10602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 10622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 10642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 10652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_pins_show(struct seq_file *s, void *what) 10672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 10682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 1069706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park unsigned i, pin; 10702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "Pinmux settings per pin\n"); 10722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "Format: pin (name): pinmuxfunction\n"); 10732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1074706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park /* The pin number can be retrived from the pin controller descriptor */ 1075706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park for (i = 0; i < pctldev->desc->npins; i++) { 10762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *desc; 10782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1079706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park pin = pctldev->desc->pins[i].number; 10802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc = pin_desc_get(pctldev, pin); 1081706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park /* Skip if we cannot search the pin */ 10822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (desc == NULL) 10832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 10842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "pin %d (%s): %s\n", pin, 10862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc->name ? desc->name : "unnamed", 10875d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren desc->mux_function ? desc->mux_function 10885d2eaf8090874f8e65388e82f7e91f9cef74885eStephen Warren : "UNCLAIMED"); 10892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 10902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 10922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 10932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_hogs_show(struct seq_file *s, void *what) 10952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 10962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 10972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_hog *hog; 10982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 10992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "Pinmux map hogs held by device\n"); 11002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(hog, &pctldev->pinmux_hogs, node) 11022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%s\n", hog->map->name); 11032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 11052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_show(struct seq_file *s, void *what) 11082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux *pmx; 11102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "Requested pinmuxes and their maps:\n"); 11122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(pmx, &pinmux_list, node) { 11132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = pmx->pctldev; 11142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinmux_ops *pmxops; 11152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *pctlops; 11162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_group *grp; 11172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!pctldev) { 11192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); 11202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 11212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 11222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmxops = pctldev->desc->pmxops; 11242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctlops = pctldev->desc->pctlops; 11252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "device: %s function: %s (%u),", 11272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_dev_get_name(pmx->pctldev), 1128f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pmxops->get_function_name(pctldev, 1129f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pmx->func_selector), 11302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->func_selector); 11312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " groups: ["); 11332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(grp, &pmx->groups, node) { 11342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " %s (%u)", 1135f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König pctlops->get_group_name(pctldev, 1136f9d41d7cb5a3a4fe9585d47e518d779d2aef8c94Uwe Kleine-König grp->group_selector), 11372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij grp->group_selector); 11382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 11392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " ]"); 11402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " users: %u map-> %s\n", 11422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->usecount, 11432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pmx->dev ? dev_name(pmx->dev) : "(system)"); 11442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 11452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 11472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_maps_show(struct seq_file *s, void *what) 11502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 11522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "Pinmux maps:\n"); 11542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < pinmux_maps_num; i++) { 11562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinmux_map const *map = &pinmux_maps[i]; 11572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%s:\n", map->name); 11592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (map->dev || map->dev_name) 11602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " device: %s\n", 11612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->dev ? dev_name(map->dev) : 11622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->dev_name); 11632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else 11642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " SYSTEM MUX\n"); 11652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " controlling device %s\n", 11662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->ctrl_dev ? dev_name(map->ctrl_dev) : 11672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij map->ctrl_dev_name); 11682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " function: %s\n", map->function); 11692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, " group: %s\n", map->group ? map->group : 11702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij "(default)"); 11712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 11722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 11732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_functions_open(struct inode *inode, struct file *file) 11762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinmux_functions_show, inode->i_private); 11782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_pins_open(struct inode *inode, struct file *file) 11812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinmux_pins_show, inode->i_private); 11832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_hogs_open(struct inode *inode, struct file *file) 11862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinmux_hogs_show, inode->i_private); 11882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_open(struct inode *inode, struct file *file) 11912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinmux_show, NULL); 11932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 11952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinmux_maps_open(struct inode *inode, struct file *file) 11962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 11972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinmux_maps_show, NULL); 11982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 11992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinmux_functions_ops = { 12012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinmux_functions_open, 12022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 12032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 12042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 12052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 12062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinmux_pins_ops = { 12082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinmux_pins_open, 12092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 12102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 12112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 12122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 12132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinmux_hogs_ops = { 12152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinmux_hogs_open, 12162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 12172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 12182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 12192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 12202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinmux_ops = { 12222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinmux_open, 12232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 12242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 12252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 12262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 12272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinmux_maps_ops = { 12292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinmux_maps_open, 12302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 12312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 12322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 12332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 12342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_init_device_debugfs(struct dentry *devroot, 12362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev) 12372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 12382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinmux-functions", S_IFREG | S_IRUGO, 12392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devroot, pctldev, &pinmux_functions_ops); 12402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, 12412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devroot, pctldev, &pinmux_pins_ops); 12422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, 12432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij devroot, pctldev, &pinmux_hogs_ops); 12442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 12452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinmux_init_debugfs(struct dentry *subsys_root) 12472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 12482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO, 12492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij subsys_root, NULL, &pinmux_ops); 12502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinmux-maps", S_IFREG | S_IRUGO, 12512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij subsys_root, NULL, &pinmux_maps_ops); 12522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 12532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 12542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#endif /* CONFIG_DEBUG_FS */ 1255