12744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* 22744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Core driver for 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) "pinctrl core: " fmt 132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/kernel.h> 15a5a697cdefd8b577b237662eb5d70f1ff75bf74fStephen Rothwell#include <linux/export.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> 242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/sysfs.h> 252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/debugfs.h> 262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/seq_file.h> 272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/pinctrl/pinctrl.h> 282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include <linux/pinctrl/machine.h> 292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include "core.h" 302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#include "pinmux.h" 31ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij#include "pinconf.h" 322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* Global list of pin control devices */ 342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic DEFINE_MUTEX(pinctrldev_list_mutex); 352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic LIST_HEAD(pinctrldev_list); 362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijconst char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) 382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* We're not allowed to register devices without name */ 402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return pctldev->desc->name; 412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 422744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinctrl_dev_get_name); 432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) 452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return pctldev->driver_data; 472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 482744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); 492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * get_pinctrl_dev_from_dev() - look up pin controller device 522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @dev: a device pointer, this may be NULL but then devname needs to be 532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * defined instead 542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @devname: the name of a device instance, as returned by dev_name(), this 552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * may be NULL but then dev needs to be defined instead 562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Looks up a pin control device matching a certain device name or pure device 582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pointer, the pure device pointer will take precedence. 592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, 612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *devname) 622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = NULL; 642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij bool found = false; 652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinctrldev_list_mutex); 672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(pctldev, &pinctrldev_list, node) { 6851cd24ee625c348654114032499914d0311e5832Stephen Warren if (dev && pctldev->dev == dev) { 692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Matched on device pointer */ 702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij found = true; 712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij break; 722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (devname && 7551cd24ee625c348654114032499914d0311e5832Stephen Warren !strcmp(dev_name(pctldev->dev), devname)) { 762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Matched on device name */ 772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij found = true; 782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij break; 792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return found ? pctldev : NULL; 842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 8633d58949adee5086478e140751e4a7263bd7e207Marek Beliskostruct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin) 872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *pindesc; 892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned long flags; 902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock_irqsave(&pctldev->pin_desc_tree_lock, flags); 922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc = radix_tree_lookup(&pctldev->pin_desc_tree, pin); 932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock_irqrestore(&pctldev->pin_desc_tree_lock, flags); 942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return pindesc; 962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 99ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij * pin_get_from_name() - look up a pin number from a name 100ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij * @pctldev: the pin control device to lookup the pin on 101ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij * @name: the name of the pin to look up 102ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij */ 103ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleijint pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) 104ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij{ 105706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park unsigned i, pin; 106ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 107706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park /* The pin number can be retrived from the pin controller descriptor */ 108706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park for (i = 0; i < pctldev->desc->npins; i++) { 109ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij struct pin_desc *desc; 110ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 111706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park pin = pctldev->desc->pins[i].number; 112ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij desc = pin_desc_get(pctldev, pin); 113ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij /* Pin space may be sparse */ 114ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij if (desc == NULL) 115ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij continue; 116ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij if (desc->name && !strcmp(name, desc->name)) 117ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij return pin; 118ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij } 119ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 120ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij return -EINVAL; 121ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij} 122ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 123ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij/** 1242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pin_is_valid() - check if pin exists on controller 1252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: the pin control device to check the pin on 1262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pin: pin to check, use the local pin controller index number 1272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 1282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * This tells us whether a certain pin exist on a certain pin controller or 1292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * not. Pin lists may be sparse, so some pins may not exist. 1302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 1312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijbool pin_is_valid(struct pinctrl_dev *pctldev, int pin) 1322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 1332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *pindesc; 1342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pin < 0) 1362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return false; 1372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc = pin_desc_get(pctldev, pin); 1392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pindesc == NULL) 1402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return false; 1412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return true; 1432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 1442744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pin_is_valid); 1452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* Deletes a range of pin descriptors */ 1472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, 1482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_pin_desc *pins, 1492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_pins) 1502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 1512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 1522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock(&pctldev->pin_desc_tree_lock); 1542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_pins; i++) { 1552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *pindesc; 1562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc = radix_tree_lookup(&pctldev->pin_desc_tree, 1582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pins[i].number); 1592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pindesc != NULL) { 1602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij radix_tree_delete(&pctldev->pin_desc_tree, 1612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pins[i].number); 162ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij if (pindesc->dynamic_name) 163ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij kfree(pindesc->name); 1642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij kfree(pindesc); 1662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&pctldev->pin_desc_tree_lock); 1682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 1692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, 1712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned number, const char *name) 1722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 1732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *pindesc; 1742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc = pin_desc_get(pctldev, number); 1762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pindesc != NULL) { 1772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_err("pin %d already registered on %s\n", number, 1782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldev->desc->name); 1792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 1802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 1812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); 1832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pindesc == NULL) 1842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -ENOMEM; 185ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 1862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock_init(&pindesc->lock); 1872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Set owner */ 1892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pindesc->pctldev = pctldev; 1902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 1919af1e44fb4a4c62a90bff9b095eb001764d91b65Stephen Warren /* Copy basic pin info */ 1928dc6ae4d448758a30cf5fa822d6fe6f4e15a04c6Linus Walleij if (name) { 193ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij pindesc->name = name; 194ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij } else { 195ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); 196ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij if (pindesc->name == NULL) 197ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij return -ENOMEM; 198ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij pindesc->dynamic_name = true; 199ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij } 2002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_lock(&pctldev->pin_desc_tree_lock); 2022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); 2032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij spin_unlock(&pctldev->pin_desc_tree_lock); 2042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("registered pin %d (%s) on %s\n", 205ca53c5f1ca5c936777caca46b7c716a40682ce83Linus Walleij number, pindesc->name, pctldev->desc->name); 2062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 2072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_register_pins(struct pinctrl_dev *pctldev, 2102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_pin_desc const *pins, 2112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_descs) 2122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned i; 2142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret = 0; 2152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_descs; i++) { 2172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinctrl_register_one_pin(pctldev, 2182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pins[i].number, pins[i].name); 2192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 2202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return ret; 2212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 2222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 2242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 2272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range 2282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin controller device to check 2292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @gpio: gpio pin to check taken from the global GPIO pin space 2302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 2312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Tries to match a GPIO pin number to the ranges handled by a certain pin 2322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * controller, return the range or NULL 2332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 2342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic struct pinctrl_gpio_range * 2352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijpinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) 2362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range = NULL; 2382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Loop over the ranges */ 2402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->gpio_ranges_lock); 2412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(range, &pctldev->gpio_ranges, node) { 2422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Check if we're in the valid range */ 2432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (gpio >= range->base && 2442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij gpio < range->base + range->npins) { 2452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->gpio_ranges_lock); 2462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return range; 2472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 2482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 2492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->gpio_ranges_lock); 2502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return NULL; 2522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 2552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_get_device_gpio_range() - find device for GPIO range 2562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @gpio: the pin to locate the pin controller for 2572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @outdev: the pin control device if found 2582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @outrange: the GPIO range if found 2592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 2602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Find the pin controller handling a certain GPIO pin from the pinspace of 2612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * the GPIO subsystem, return the device and the matching GPIO range. Returns 2622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * negative if the GPIO range could not be found in any device. 2632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 2642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijint pinctrl_get_device_gpio_range(unsigned gpio, 2652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev **outdev, 2662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range **outrange) 2672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = NULL; 2692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Loop over the pin controllers */ 2712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinctrldev_list_mutex); 2722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(pctldev, &pinctrldev_list, node) { 2732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range; 2742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij range = pinctrl_match_gpio_range(pctldev, gpio); 2762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (range != NULL) { 2772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij *outdev = pctldev; 2782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij *outrange = range; 2792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 2802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 2812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 2822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 2832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 2842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return -EINVAL; 2862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 2872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 2882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 2892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_add_gpio_range() - register a GPIO range for a controller 2902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin controller device to add the range to 2912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @range: the GPIO range to add 2922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 2932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * This adds a range of GPIOs to be handled by a certain pin controller. Call 2942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * this to register handled ranges after registering your pin controller. 2952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 2962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, 2972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range) 2982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 2992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->gpio_ranges_lock); 3002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_add(&range->node, &pctldev->gpio_ranges); 3012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->gpio_ranges_lock); 3022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 3032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 3052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller 3062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin controller device to remove the range from 3072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @range: the GPIO range to remove 3082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 3092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, 3102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range) 3112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 3122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->gpio_ranges_lock); 3132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_del(&range->node); 3142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->gpio_ranges_lock); 3152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 3162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3177afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij/** 3187afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij * pinctrl_get_group_selector() - returns the group selector for a group 3197afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij * @pctldev: the pin controller handling the group 3207afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij * @pin_group: the pin group to look up 3217afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij */ 3227afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleijint pinctrl_get_group_selector(struct pinctrl_dev *pctldev, 3237afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij const char *pin_group) 3247afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij{ 3257afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 3267afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij unsigned group_selector = 0; 3277afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij 3287afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij while (pctlops->list_groups(pctldev, group_selector) >= 0) { 3297afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij const char *gname = pctlops->get_group_name(pctldev, 3307afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij group_selector); 3317afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij if (!strcmp(gname, pin_group)) { 33251cd24ee625c348654114032499914d0311e5832Stephen Warren dev_dbg(pctldev->dev, 3337afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij "found group selector %u for %s\n", 3347afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij group_selector, 3357afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij pin_group); 3367afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij return group_selector; 3377afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij } 3387afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij 3397afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij group_selector++; 3407afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij } 3417afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij 34251cd24ee625c348654114032499914d0311e5832Stephen Warren dev_err(pctldev->dev, "does not have pin group %s\n", 3437afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij pin_group); 3447afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij 3457afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij return -EINVAL; 3467afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij} 3477afde8baa83b9ac409a6db86f27a41878aa6b33fLinus Walleij 3482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#ifdef CONFIG_DEBUG_FS 3492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_pins_show(struct seq_file *s, void *what) 3512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 3522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 3532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *ops = pctldev->desc->pctlops; 354706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park unsigned i, pin; 3552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); 3572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 358706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park /* The pin number can be retrived from the pin controller descriptor */ 359706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park for (i = 0; i < pctldev->desc->npins; i++) { 3602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pin_desc *desc; 3612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 362706e8520e8450a631ca6f798f8c811faf56f0a59Chanho Park pin = pctldev->desc->pins[i].number; 3632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc = pin_desc_get(pctldev, pin); 3642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Pin space may be sparse */ 3652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (desc == NULL) 3662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij continue; 3672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "pin %d (%s) ", pin, 3692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij desc->name ? desc->name : "unnamed"); 3702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Driver-specific info per pin */ 3722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ops->pin_dbg_show) 3732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ops->pin_dbg_show(pctldev, s, pin); 3742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "\n"); 3762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 3772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 3792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 3802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_groups_show(struct seq_file *s, void *what) 3822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 3832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 3842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const struct pinctrl_ops *ops = pctldev->desc->pctlops; 3852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned selector = 0; 3862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* No grouping */ 3882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (!ops) 3892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 3902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "registered pin groups:\n"); 3922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij while (ops->list_groups(pctldev, selector) >= 0) { 393a5818a8bd095a08cfb1871b63af9c8bed103e4b9Stephen Warren const unsigned *pins; 3942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij unsigned num_pins; 3952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij const char *gname = ops->get_group_name(pctldev, selector); 3962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 3972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int i; 3982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 3992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = ops->get_group_pins(pctldev, selector, 4002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij &pins, &num_pins); 4012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) 4022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%s [ERROR GETTING PINS]\n", 4032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij gname); 4042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else { 4052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "group: %s, pins = [ ", gname); 4062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij for (i = 0; i < num_pins; i++) 4072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%d ", pins[i]); 4082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "]\n"); 4092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij selector++; 4112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4132744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 4152744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4172744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_gpioranges_show(struct seq_file *s, void *what) 4182744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev = s->private; 4202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_gpio_range *range = NULL; 4212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "GPIO ranges handled:\n"); 4232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Loop over the ranges */ 4252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pctldev->gpio_ranges_lock); 4262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(range, &pctldev->gpio_ranges, node) { 42775d6642a3ee1dfe2552028997cdcc2c4207bec8fLinus Walleij seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", 42875d6642a3ee1dfe2552028997cdcc2c4207bec8fLinus Walleij range->id, range->name, 42975d6642a3ee1dfe2552028997cdcc2c4207bec8fLinus Walleij range->base, (range->base + range->npins - 1), 43075d6642a3ee1dfe2552028997cdcc2c4207bec8fLinus Walleij range->pin_base, 43175d6642a3ee1dfe2552028997cdcc2c4207bec8fLinus Walleij (range->pin_base + range->npins - 1)); 4322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pctldev->gpio_ranges_lock); 4342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 4362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4382744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_devices_show(struct seq_file *s, void *what) 4392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev; 4412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 442ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij seq_puts(s, "name [pinmux] [pinconf]\n"); 4432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinctrldev_list_mutex); 4442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_for_each_entry(pctldev, &pinctrldev_list, node) { 4452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_printf(s, "%s ", pctldev->desc->name); 4462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pctldev->desc->pmxops) 447ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij seq_puts(s, "yes "); 448ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij else 449ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij seq_puts(s, "no "); 450ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij if (pctldev->desc->confops) 4512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "yes"); 4522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij else 4532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "no"); 4542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij seq_puts(s, "\n"); 4552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 4562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 4572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 4592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_pins_open(struct inode *inode, struct file *file) 4622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinctrl_pins_show, inode->i_private); 4642744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4662744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_groups_open(struct inode *inode, struct file *file) 4672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinctrl_groups_show, inode->i_private); 4692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_gpioranges_open(struct inode *inode, struct file *file) 4722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinctrl_gpioranges_show, inode->i_private); 4742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int pinctrl_devices_open(struct inode *inode, struct file *file) 4772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 4782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return single_open(file, pinctrl_devices_show, NULL); 4792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 4802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinctrl_pins_ops = { 4822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinctrl_pins_open, 4832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 4842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 4852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 4862744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 4872744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4882744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinctrl_groups_ops = { 4892744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinctrl_groups_open, 4902744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 4912744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 4922744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 4932744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 4942744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 4952744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinctrl_gpioranges_ops = { 4962744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinctrl_gpioranges_open, 4972744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 4982744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 4992744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 5002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 5012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5022744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic const struct file_operations pinctrl_devices_ops = { 5032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .open = pinctrl_devices_open, 5042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .read = seq_read, 5052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .llseek = seq_lseek, 5062744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij .release = single_release, 5072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij}; 5082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic struct dentry *debugfs_root; 5102744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5112744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) 5122744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5130215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren struct dentry *device_root; 5142744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 51551cd24ee625c348654114032499914d0311e5832Stephen Warren device_root = debugfs_create_dir(dev_name(pctldev->dev), 5162744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_root); 5170215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren pctldev->device_root = device_root; 5180215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren 5192744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (IS_ERR(device_root) || !device_root) { 5202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_warn("failed to create debugfs directory for %s\n", 52151cd24ee625c348654114032499914d0311e5832Stephen Warren dev_name(pctldev->dev)); 5222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 5232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pins", S_IFREG | S_IRUGO, 5252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij device_root, pctldev, &pinctrl_pins_ops); 5262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pingroups", S_IFREG | S_IRUGO, 5272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij device_root, pctldev, &pinctrl_groups_ops); 5282744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, 5292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij device_root, pctldev, &pinctrl_gpioranges_ops); 5302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_init_device_debugfs(device_root, pctldev); 531ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij pinconf_init_device_debugfs(device_root, pctldev); 5322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5340215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgrenstatic void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) 5350215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren{ 5360215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren debugfs_remove_recursive(pctldev->device_root); 5370215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren} 5380215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren 5392744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinctrl_init_debugfs(void) 5402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_root = debugfs_create_dir("pinctrl", NULL); 5422744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (IS_ERR(debugfs_root) || !debugfs_root) { 5432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_warn("failed to create debugfs directory\n"); 5442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_root = NULL; 5452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 5462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 5472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, 5492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij debugfs_root, NULL, &pinctrl_devices_ops); 5502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_init_debugfs(debugfs_root); 5512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#else /* CONFIG_DEBUG_FS */ 5542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5552744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) 5562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic void pinctrl_init_debugfs(void) 5602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 5622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5630215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgrenstatic void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) 5640215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren{ 5650215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren} 5660215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren 5672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij#endif 5682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 5702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_register() - register a pin controller device 5712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldesc: descriptor for this pin controller 5722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @dev: parent device for this pin controller 5732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @driver_data: private pin controller data for this pin controller 5742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 5752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstruct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, 5762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct device *dev, void *driver_data) 5772744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 5782744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij struct pinctrl_dev *pctldev; 5792744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij int ret; 5802744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 5812744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pctldesc == NULL) 5822744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return NULL; 5832744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pctldesc->name == NULL) 5842744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return NULL; 5852744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 586b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); 587b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren if (pctldev == NULL) 588b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren return NULL; 589b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren 590b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren /* Initialize pin control device struct */ 591b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pctldev->owner = pctldesc->owner; 592b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pctldev->desc = pctldesc; 593b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pctldev->driver_data = driver_data; 594b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); 595b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren spin_lock_init(&pctldev->pin_desc_tree_lock); 596b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren INIT_LIST_HEAD(&pctldev->gpio_ranges); 597b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren mutex_init(&pctldev->gpio_ranges_lock); 598b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren pctldev->dev = dev; 599b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren 6002744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* If we're implementing pinmuxing, check the ops for sanity */ 6012744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pctldesc->pmxops) { 602b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren ret = pinmux_check_ops(pctldev); 6032744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 6042744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_err("%s pinmux ops lacks necessary functions\n", 6052744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldesc->name); 606b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren goto out_err; 6072744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6082744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6092744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 610ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij /* If we're implementing pinconfig, check the ops for sanity */ 611ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij if (pctldesc->confops) { 612b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren ret = pinconf_check_ops(pctldev); 613ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij if (ret) { 614ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij pr_err("%s pin config ops lacks necessary functions\n", 615ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij pctldesc->name); 616b9130b776ee481acbc27a7e56d98df75680de369Tony Lindgren goto out_err; 617ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij } 618ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij } 619ae6b4d8588f4fc95520b0e62c4b1f474c82191a9Linus Walleij 6202744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Register all the pins */ 6212744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_debug("try to register %d pins on %s...\n", 6222744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldesc->npins, pctldesc->name); 6232744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins); 6242744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (ret) { 6252744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_err("error during pin registration\n"); 6262744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_free_pindescs(pctldev, pctldesc->pins, 6272744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldesc->npins); 62851cd24ee625c348654114032499914d0311e5832Stephen Warren goto out_err; 6292744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij } 6302744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6312744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_init_device_debugfs(pctldev); 6322744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinctrldev_list_mutex); 6332744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_add(&pctldev->node, &pinctrldev_list); 6342744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 6352744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_hog_maps(pctldev); 6362744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return pctldev; 6372744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 63851cd24ee625c348654114032499914d0311e5832Stephen Warrenout_err: 63951cd24ee625c348654114032499914d0311e5832Stephen Warren kfree(pctldev); 6402744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return NULL; 6412744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 6422744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinctrl_register); 6432744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6442744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/** 6452744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * pinctrl_unregister() - unregister pinmux 6462744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * @pctldev: pin controller to unregister 6472744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * 6482744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij * Called by pinmux drivers to unregister a pinmux. 6492744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij */ 6502744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijvoid pinctrl_unregister(struct pinctrl_dev *pctldev) 6512744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 6522744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij if (pctldev == NULL) 6532744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return; 6542744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6550215716083cac67ff7ea3e3efdc9943bdb462274Tony Lindgren pinctrl_remove_device_debugfs(pctldev); 6562744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinmux_unhog_maps(pctldev); 6572744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* TODO: check that no pinmuxes are still active? */ 6582744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_lock(&pinctrldev_list_mutex); 6592744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij list_del(&pctldev->node); 6602744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij mutex_unlock(&pinctrldev_list_mutex); 6612744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij /* Destroy descriptor tree */ 6622744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_free_pindescs(pctldev, pctldev->desc->pins, 6632744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pctldev->desc->npins); 66451cd24ee625c348654114032499914d0311e5832Stephen Warren kfree(pctldev); 6652744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 6662744e8afb3b76343e7eb8197e8b3e085036010a5Linus WalleijEXPORT_SYMBOL_GPL(pinctrl_unregister); 6672744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6682744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijstatic int __init pinctrl_init(void) 6692744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij{ 6702744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pr_info("initialized pinctrl subsystem\n"); 6712744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij pinctrl_init_debugfs(); 6722744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij return 0; 6732744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij} 6742744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij 6752744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleij/* init early since many drivers really need to initialized pinmux early */ 6762744e8afb3b76343e7eb8197e8b3e085036010a5Linus Walleijcore_initcall(pinctrl_init); 677