Commit d52739c6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (31 commits)
  pinctrl: remove unnecessary max pin number
  pinctrl: correct a offset while enumerating pins
  pinctrl: some typo fixes
  pinctrl: rename U300 and SIRF pin controllers
  pinctrl: pass name instead of device to pin_config_*
  pinctrl: add "struct seq_file;" to pinconf.h
  pinctrl: conjure names for unnamed pins
  pinctrl: add a group-specific hog macro
  pinctrl: don't create a device for each pin controller
  arm/u300: don't use PINMUX_MAP_PRIMARY*
  pinctrl: implement PINMUX_MAP_SYS_HOG
  pinctrl: add a pin config interface
  pinctrl/coh901: driver to request its pins
  pinctrl: u300-pinmux: register proper GPIO ranges
  pinctrl: move the U300 GPIO driver to pinctrl
  ARM: u300: localize GPIO assignments
  pinctrl: make it possible to add multiple maps
  pinctrl: make a copy of pinmux map
  pinctrl: GPIO direction support for muxing
  pinctrl: print pin range in GPIO range debugs
  ...
parents abce00f9 0d2006bb
...@@ -7,12 +7,9 @@ This subsystem deals with: ...@@ -7,12 +7,9 @@ This subsystem deals with:
- Multiplexing of pins, pads, fingers (etc) see below for details - Multiplexing of pins, pads, fingers (etc) see below for details
The intention is to also deal with: - Configuration of pins, pads, fingers (etc), such as software-controlled
biasing and driving mode specific pins, such as pull-up/down, open drain,
- Software-controlled biasing and driving mode specific pins, such as load capacitance etc.
pull-up/down, open drain etc, load capacitance configuration when controlled
by software, etc.
Top-level interface Top-level interface
=================== ===================
...@@ -32,7 +29,7 @@ Definition of PIN: ...@@ -32,7 +29,7 @@ Definition of PIN:
be sparse - i.e. there may be gaps in the space with numbers where no be sparse - i.e. there may be gaps in the space with numbers where no
pin exists. pin exists.
When a PIN CONTROLLER is instatiated, it will register a descriptor to the When a PIN CONTROLLER is instantiated, it will register a descriptor to the
pin control framework, and this descriptor contains an array of pin descriptors pin control framework, and this descriptor contains an array of pin descriptors
describing the pins handled by this specific pin controller. describing the pins handled by this specific pin controller.
...@@ -61,14 +58,14 @@ this in our driver: ...@@ -61,14 +58,14 @@ this in our driver:
#include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinctrl.h>
const struct pinctrl_pin_desc __refdata foo_pins[] = { const struct pinctrl_pin_desc foo_pins[] = {
PINCTRL_PIN(0, "A1"), PINCTRL_PIN(0, "A8"),
PINCTRL_PIN(1, "A2"), PINCTRL_PIN(1, "B8"),
PINCTRL_PIN(2, "A3"), PINCTRL_PIN(2, "C8"),
... ...
PINCTRL_PIN(61, "H6"), PINCTRL_PIN(61, "F1"),
PINCTRL_PIN(62, "H7"), PINCTRL_PIN(62, "G1"),
PINCTRL_PIN(63, "H8"), PINCTRL_PIN(63, "H1"),
}; };
static struct pinctrl_desc foo_desc = { static struct pinctrl_desc foo_desc = {
...@@ -88,11 +85,16 @@ int __init foo_probe(void) ...@@ -88,11 +85,16 @@ int __init foo_probe(void)
pr_err("could not register foo pin driver\n"); pr_err("could not register foo pin driver\n");
} }
To enable the pinctrl subsystem and the subgroups for PINMUX and PINCONF and
selected drivers, you need to select them from your machine's Kconfig entry,
since these are so tightly integrated with the machines they are used on.
See for example arch/arm/mach-u300/Kconfig for an example.
Pins usually have fancier names than this. You can find these in the dataheet Pins usually have fancier names than this. You can find these in the dataheet
for your chip. Notice that the core pinctrl.h file provides a fancy macro for your chip. Notice that the core pinctrl.h file provides a fancy macro
called PINCTRL_PIN() to create the struct entries. As you can see I enumerated called PINCTRL_PIN() to create the struct entries. As you can see I enumerated
the pins from 0 in the upper left corner to 63 in the lower right corner, the pins from 0 in the upper left corner to 63 in the lower right corner.
this enumeration was arbitrarily chosen, in practice you need to think This enumeration was arbitrarily chosen, in practice you need to think
through your numbering system so that it matches the layout of registers through your numbering system so that it matches the layout of registers
and such things in your driver, or the code may become complicated. You must and such things in your driver, or the code may become complicated. You must
also consider matching of offsets to the GPIO ranges that may be handled by also consider matching of offsets to the GPIO ranges that may be handled by
...@@ -133,8 +135,8 @@ struct foo_group { ...@@ -133,8 +135,8 @@ struct foo_group {
const unsigned num_pins; const unsigned num_pins;
}; };
static unsigned int spi0_pins[] = { 0, 8, 16, 24 }; static const unsigned int spi0_pins[] = { 0, 8, 16, 24 };
static unsigned int i2c0_pins[] = { 24, 25 }; static const unsigned int i2c0_pins[] = { 24, 25 };
static const struct foo_group foo_groups[] = { static const struct foo_group foo_groups[] = {
{ {
...@@ -193,6 +195,88 @@ structure, for example specific register ranges associated with each group ...@@ -193,6 +195,88 @@ structure, for example specific register ranges associated with each group
and so on. and so on.
Pin configuration
=================
Pins can sometimes be software-configured in an various ways, mostly related
to their electronic properties when used as inputs or outputs. For example you
may be able to make an output pin high impedance, or "tristate" meaning it is
effectively disconnected. You may be able to connect an input pin to VDD or GND
using a certain resistor value - pull up and pull down - so that the pin has a
stable value when nothing is driving the rail it is connected to, or when it's
unconnected.
For example, a platform may do this:
ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
To pull up a pin to VDD. The pin configuration driver implements callbacks for
changing pin configuration in the pin controller ops like this:
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include "platform_x_pindefs.h"
static int foo_pin_config_get(struct pinctrl_dev *pctldev,
unsigned offset,
unsigned long *config)
{
struct my_conftype conf;
... Find setting for pin @ offset ...
*config = (unsigned long) conf;
}
static int foo_pin_config_set(struct pinctrl_dev *pctldev,
unsigned offset,
unsigned long config)
{
struct my_conftype *conf = (struct my_conftype *) config;
switch (conf) {
case PLATFORM_X_PULL_UP:
...
}
}
}
static int foo_pin_config_group_get (struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long *config)
{
...
}
static int foo_pin_config_group_set (struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long config)
{
...
}
static struct pinconf_ops foo_pconf_ops = {
.pin_config_get = foo_pin_config_get,
.pin_config_set = foo_pin_config_set,
.pin_config_group_get = foo_pin_config_group_get,
.pin_config_group_set = foo_pin_config_group_set,
};
/* Pin config operations are handled by some pin controller */
static struct pinctrl_desc foo_desc = {
...
.confops = &foo_pconf_ops,
};
Since some controllers have special logic for handling entire groups of pins
they can exploit the special whole-group pin control function. The
pin_config_group_set() callback is allowed to return the error code -EAGAIN,
for groups it does not want to handle, or if it just wants to do some
group-level handling and then fall through to iterate over all pins, in which
case each individual pin will be treated by separate pin_config_set() calls as
well.
Interaction with the GPIO subsystem Interaction with the GPIO subsystem
=================================== ===================================
...@@ -214,19 +298,20 @@ static struct pinctrl_gpio_range gpio_range_a = { ...@@ -214,19 +298,20 @@ static struct pinctrl_gpio_range gpio_range_a = {
.name = "chip a", .name = "chip a",
.id = 0, .id = 0,
.base = 32, .base = 32,
.pin_base = 32,
.npins = 16, .npins = 16,
.gc = &chip_a; .gc = &chip_a;
}; };
static struct pinctrl_gpio_range gpio_range_a = { static struct pinctrl_gpio_range gpio_range_b = {
.name = "chip b", .name = "chip b",
.id = 0, .id = 0,
.base = 48, .base = 48,
.pin_base = 64,
.npins = 8, .npins = 8,
.gc = &chip_b; .gc = &chip_b;
}; };
{ {
struct pinctrl_dev *pctl; struct pinctrl_dev *pctl;
... ...
...@@ -235,42 +320,39 @@ static struct pinctrl_gpio_range gpio_range_a = { ...@@ -235,42 +320,39 @@ static struct pinctrl_gpio_range gpio_range_a = {
} }
So this complex system has one pin controller handling two different So this complex system has one pin controller handling two different
GPIO chips. Chip a has 16 pins and chip b has 8 pins. They are mapped in GPIO chips. "chip a" has 16 pins and "chip b" has 8 pins. The "chip a" and
the global GPIO pin space at: "chip b" have different .pin_base, which means a start pin number of the
GPIO range.
The GPIO range of "chip a" starts from the GPIO base of 32 and actual
pin range also starts from 32. However "chip b" has different starting
offset for the GPIO range and pin range. The GPIO range of "chip b" starts
from GPIO number 48, while the pin range of "chip b" starts from 64.
We can convert a gpio number to actual pin number using this "pin_base".
They are mapped in the global GPIO pin space at:
chip a: [32 .. 47] chip a:
chip b: [48 .. 55] - GPIO range : [32 .. 47]
- pin range : [32 .. 47]
chip b:
- GPIO range : [48 .. 55]
- pin range : [64 .. 71]
When GPIO-specific functions in the pin control subsystem are called, these When GPIO-specific functions in the pin control subsystem are called, these
ranges will be used to look up the apropriate pin controller by inspecting ranges will be used to look up the appropriate pin controller by inspecting
and matching the pin to the pin ranges across all controllers. When a and matching the pin to the pin ranges across all controllers. When a
pin controller handling the matching range is found, GPIO-specific functions pin controller handling the matching range is found, GPIO-specific functions
will be called on that specific pin controller. will be called on that specific pin controller.
For all functionalities dealing with pin biasing, pin muxing etc, the pin For all functionalities dealing with pin biasing, pin muxing etc, the pin
controller subsystem will subtract the range's .base offset from the passed controller subsystem will subtract the range's .base offset from the passed
in gpio pin number, and pass that on to the pin control driver, so the driver in gpio number, and add the ranges's .pin_base offset to retrive a pin number.
will get an offset into its handled number range. Further it is also passed After that, the subsystem passes it on to the pin control driver, so the driver
will get an pin number into its handled number range. Further it is also passed
the range ID value, so that the pin controller knows which range it should the range ID value, so that the pin controller knows which range it should
deal with. deal with.
For example: if a user issues pinctrl_gpio_set_foo(50), the pin control
subsystem will find that the second range on this pin controller matches,
subtract the base 48 and call the
pinctrl_driver_gpio_set_foo(pinctrl, range, 2) where the latter function has
this signature:
int pinctrl_driver_gpio_set_foo(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *rangeid,
unsigned offset);
Now the driver knows that we want to do some GPIO-specific operation on the
second GPIO range handled by "chip b", at offset 2 in that specific range.
(If the GPIO subsystem is ever refactored to use a local per-GPIO controller
pin space, this mapping will need to be augmented accordingly.)
PINMUX interfaces PINMUX interfaces
================= =================
...@@ -438,7 +520,7 @@ you. Define enumerators only for the pins you can control if that makes sense. ...@@ -438,7 +520,7 @@ you. Define enumerators only for the pins you can control if that makes sense.
Assumptions: Assumptions:
We assume that the number possible function maps to pin groups is limited by We assume that the number of possible function maps to pin groups is limited by
the hardware. I.e. we assume that there is no system where any function can be the hardware. I.e. we assume that there is no system where any function can be
mapped to any pin, like in a phone exchange. So the available pins groups for mapped to any pin, like in a phone exchange. So the available pins groups for
a certain function will be limited to a few choices (say up to eight or so), a certain function will be limited to a few choices (say up to eight or so),
...@@ -585,7 +667,7 @@ int foo_list_funcs(struct pinctrl_dev *pctldev, unsigned selector) ...@@ -585,7 +667,7 @@ int foo_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
{ {
return myfuncs[selector].name; return foo_functions[selector].name;
} }
static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector, static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
...@@ -600,16 +682,16 @@ static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -600,16 +682,16 @@ static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
int foo_enable(struct pinctrl_dev *pctldev, unsigned selector, int foo_enable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group) unsigned group)
{ {
u8 regbit = (1 << group); u8 regbit = (1 << selector + group);
writeb((readb(MUX)|regbit), MUX) writeb((readb(MUX)|regbit), MUX)
return 0; return 0;
} }
int foo_disable(struct pinctrl_dev *pctldev, unsigned selector, void foo_disable(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group) unsigned group)
{ {
u8 regbit = (1 << group); u8 regbit = (1 << selector + group);
writeb((readb(MUX) & ~(regbit)), MUX) writeb((readb(MUX) & ~(regbit)), MUX)
return 0; return 0;
...@@ -647,6 +729,17 @@ All the above functions are mandatory to implement for a pinmux driver. ...@@ -647,6 +729,17 @@ All the above functions are mandatory to implement for a pinmux driver.
Pinmux interaction with the GPIO subsystem Pinmux interaction with the GPIO subsystem
========================================== ==========================================
The public pinmux API contains two functions named pinmux_request_gpio()
and pinmux_free_gpio(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and
gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output]
shall only be called from within respective gpio_direction_[input|output]
gpiolib implementation.
NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be
muxed in. Instead, implement a proper gpiolib driver and have that driver
request proper muxing for its pins.
The function list could become long, especially if you can convert every The function list could become long, especially if you can convert every
individual pin into a GPIO pin independent of any other pins, and then try individual pin into a GPIO pin independent of any other pins, and then try
the approach to define every pin as a function. the approach to define every pin as a function.
...@@ -654,19 +747,24 @@ the approach to define every pin as a function. ...@@ -654,19 +747,24 @@ the approach to define every pin as a function.
In this case, the function array would become 64 entries for each GPIO In this case, the function array would become 64 entries for each GPIO
setting and then the device functions. setting and then the device functions.
For this reason there is an additional function a pinmux driver can implement For this reason there are two functions a pinmux driver can implement
to enable only GPIO on an individual pin: .gpio_request_enable(). The same to enable only GPIO on an individual pin: .gpio_request_enable() and
.free() function as for other functions is assumed to be usable also for .gpio_disable_free().
GPIO pins.
This function will pass in the affected GPIO range identified by the pin This function will pass in the affected GPIO range identified by the pin
controller core, so you know which GPIO pins are being affected by the request controller core, so you know which GPIO pins are being affected by the request
operation. operation.
Alternatively it is fully allowed to use named functions for each GPIO If your driver needs to have an indication from the framework of whether the
pin, the pinmux_request_gpio() will attempt to obtain the function "gpioN" GPIO pin shall be used for input or output you can implement the
where "N" is the global GPIO pin number if no special GPIO-handler is .gpio_set_direction() function. As described this shall be called from the
registered. gpiolib driver and the affected GPIO range, pin offset and desired direction
will be passed along to this function.
Alternatively to using these special functions, it is fully allowed to use
named functions for each GPIO pin, the pinmux_request_gpio() will attempt to
obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered.
Pinmux board/machine configuration Pinmux board/machine configuration
...@@ -683,19 +781,19 @@ spi on the second function mapping: ...@@ -683,19 +781,19 @@ spi on the second function mapping:
#include <linux/pinctrl/machine.h> #include <linux/pinctrl/machine.h>
static struct pinmux_map pmx_mapping[] = { static const struct pinmux_map __initdata pmx_mapping[] = {
{ {
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "spi0", .function = "spi0",
.dev_name = "foo-spi.0", .dev_name = "foo-spi.0",
}, },
{ {
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "i2c0", .function = "i2c0",
.dev_name = "foo-i2c.0", .dev_name = "foo-i2c.0",
}, },
{ {
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
...@@ -714,14 +812,14 @@ for example if they are not yet instantiated or cumbersome to obtain. ...@@ -714,14 +812,14 @@ for example if they are not yet instantiated or cumbersome to obtain.
You register this pinmux mapping to the pinmux subsystem by simply: You register this pinmux mapping to the pinmux subsystem by simply:
ret = pinmux_register_mappings(&pmx_mapping, ARRAY_SIZE(pmx_mapping)); ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping));
Since the above construct is pretty common there is a helper macro to make Since the above construct is pretty common there is a helper macro to make
it even more compact which assumes you want to use pinctrl.0 and position it even more compact which assumes you want to use pinctrl-foo and position
0 for mapping, for example: 0 for mapping, for example:
static struct pinmux_map pmx_mapping[] = { static struct pinmux_map __initdata pmx_mapping[] = {
PINMUX_MAP_PRIMARY("I2CMAP", "i2c0", "foo-i2c.0"), PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
}; };
...@@ -734,14 +832,14 @@ As it is possible to map a function to different groups of pins an optional ...@@ -734,14 +832,14 @@ As it is possible to map a function to different groups of pins an optional
... ...
{ {
.name = "spi0-pos-A", .name = "spi0-pos-A",
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "spi0", .function = "spi0",
.group = "spi0_0_grp", .group = "spi0_0_grp",
.dev_name = "foo-spi.0", .dev_name = "foo-spi.0",
}, },
{ {
.name = "spi0-pos-B", .name = "spi0-pos-B",
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "spi0", .function = "spi0",
.group = "spi0_1_grp", .group = "spi0_1_grp",
.dev_name = "foo-spi.0", .dev_name = "foo-spi.0",
...@@ -760,44 +858,44 @@ case), we define a mapping like this: ...@@ -760,44 +858,44 @@ case), we define a mapping like this:
... ...
{ {
.name "2bit" .name "2bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_0_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
{ {
.name "4bit" .name "4bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_0_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
{ {
.name "4bit" .name "4bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_1_grp", .group = "mmc0_2_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
{ {
.name "8bit" .name "8bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_0_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
{ {
.name "8bit" .name "8bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_1_grp", .group = "mmc0_2_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
{ {
.name "8bit" .name "8bit"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_2_grp", .group = "mmc0_3_grp",
.dev_name = "foo-mmc.0", .dev_name = "foo-mmc.0",
}, },
... ...
...@@ -898,7 +996,7 @@ like this: ...@@ -898,7 +996,7 @@ like this:
{ {
.name "POWERMAP" .name "POWERMAP"
.ctrl_dev_name = "pinctrl.0", .ctrl_dev_name = "pinctrl-foo",
.function = "power_func", .function = "power_func",
.hog_on_boot = true, .hog_on_boot = true,
}, },
......
...@@ -5123,7 +5123,7 @@ F: drivers/*/*/picoxcell* ...@@ -5123,7 +5123,7 @@ F: drivers/*/*/picoxcell*
PIN CONTROL SUBSYSTEM PIN CONTROL SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org> M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained S: Maintained
F: drivers/pinmux/ F: drivers/pinctrl/
PKTCDVD DRIVER PKTCDVD DRIVER
M: Peter Osterlund <petero2@telia.com> M: Peter Osterlund <petero2@telia.com>
......
...@@ -7,8 +7,8 @@ comment "ST-Ericsson Mobile Platform Products" ...@@ -7,8 +7,8 @@ comment "ST-Ericsson Mobile Platform Products"
config MACH_U300 config MACH_U300
bool "U300" bool "U300"
select PINCTRL select PINCTRL
select PINMUX_U300 select PINCTRL_U300
select GPIO_U300 select PINCTRL_COH901
comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
......
...@@ -1605,15 +1605,15 @@ static struct platform_device pinmux_device = { ...@@ -1605,15 +1605,15 @@ static struct platform_device pinmux_device = {
}; };
/* Pinmux settings */ /* Pinmux settings */
static struct pinmux_map u300_pinmux_map[] = { static struct pinmux_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */ /* anonymous maps for chip power and EMIFs */
PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"), PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"), PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
PINMUX_MAP_PRIMARY_SYS_HOG("EMIF1", "emif1"), PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
/* per-device maps for MMC/SD, SPI and UART */ /* per-device maps for MMC/SD, SPI and UART */
PINMUX_MAP_PRIMARY("MMCSD", "mmc0", "mmci"), PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
PINMUX_MAP_PRIMARY("SPI", "spi0", "pl022"), PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
PINMUX_MAP_PRIMARY("UART0", "uart0", "uart0"), PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
}; };
struct u300_mux_hog { struct u300_mux_hog {
......
...@@ -9,121 +9,6 @@ ...@@ -9,121 +9,6 @@
#ifndef __MACH_U300_GPIO_U300_H #ifndef __MACH_U300_GPIO_U300_H
#define __MACH_U300_GPIO_U300_H #define __MACH_U300_GPIO_U300_H
/*
* Individual pin assignments for the B26/S26. Notice that the
* actual usage of these pins depends on the PAD MUX settings, that
* is why the same number can potentially appear several times.
* In the reference design each pin is only used for one purpose.
* These were determined by inspecting the B26/S26 schematic:
* 2/1911-ROA 128 1603
*/
#ifdef CONFIG_MACH_U300_BS2X
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
#define U300_GPIO_PIN_CAM_SLEEP 4
#define U300_GPIO_PIN_CAM_REG_EN 5
#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#endif
/*
* Individual pin assignments for the B330/S330 and B365/S365.
* Notice that the actual usage of these pins depends on the
* PAD MUX settings, that is why the same number can potentially
* appear several times. In the reference design each pin is only
* used for one purpose. These were determined by inspecting the
* S365 schematic.
*/
#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
defined(CONFIG_MACH_U300_BS335)
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_UART_CTS 2
#define U300_GPIO_PIN_UART_RTS 3
#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
#ifdef CONFIG_MACH_U300_BS335
#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
#endif
#endif
/** /**
* enum u300_gpio_variant - the type of U300 GPIO employed * enum u300_gpio_variant - the type of U300 GPIO employed
*/ */
......
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
#endif #endif
/* Maximum 8*7 GPIO lines */ /* Maximum 8*7 GPIO lines */
#ifdef CONFIG_GPIO_U300 #ifdef CONFIG_PINCTRL_COH901
#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END) #define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END)
#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56) #define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56)
#else #else
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <mach/coh901318.h> #include <mach/coh901318.h>
#include <mach/dma_channels.h> #include <mach/dma_channels.h>
#include <mach/gpio-u300.h>
#include "u300-gpio.h"
#include "mmc.h" #include "mmc.h"
static struct mmci_platform_data mmc0_plat_data = { static struct mmci_platform_data mmc0_plat_data = {
......
/*
* Individual pin assignments for the B26/S26. Notice that the
* actual usage of these pins depends on the PAD MUX settings, that
* is why the same number can potentially appear several times.
* In the reference design each pin is only used for one purpose.
* These were determined by inspecting the B26/S26 schematic:
* 2/1911-ROA 128 1603
*/
#ifdef CONFIG_MACH_U300_BS2X
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
#define U300_GPIO_PIN_CAM_SLEEP 4
#define U300_GPIO_PIN_CAM_REG_EN 5
#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#endif
/*
* Individual pin assignments for the B330/S330 and B365/S365.
* Notice that the actual usage of these pins depends on the
* PAD MUX settings, that is why the same number can potentially
* appear several times. In the reference design each pin is only
* used for one purpose. These were determined by inspecting the
* S365 schematic.
*/
#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
defined(CONFIG_MACH_U300_BS335)
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_UART_CTS 2
#define U300_GPIO_PIN_UART_RTS 3
#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
#ifdef CONFIG_MACH_U300_BS335
#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
#endif
#endif
...@@ -176,15 +176,6 @@ config GPIO_SCH ...@@ -176,15 +176,6 @@ config GPIO_SCH
The Intel Tunnel Creek processor has 5 GPIOs powered by the The Intel Tunnel Creek processor has 5 GPIOs powered by the
core power rail and 9 from suspend power supply. core power rail and 9 from suspend power supply.
config GPIO_U300
bool "ST-Ericsson U300 COH 901 335/571 GPIO"
depends on GPIOLIB && ARCH_U300
help
Say yes here to support GPIO interface on ST-Ericsson U300.
The names of the two IP block variants supported are
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
config GPIO_VX855 config GPIO_VX855
tristate "VIA VX855/VX875 GPIO" tristate "VIA VX855/VX875 GPIO"
depends on PCI depends on PCI
......
...@@ -54,7 +54,6 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o ...@@ -54,7 +54,6 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_MACH_U300) += gpio-u300.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
......
...@@ -12,7 +12,10 @@ menu "Pin controllers" ...@@ -12,7 +12,10 @@ menu "Pin controllers"
depends on PINCTRL depends on PINCTRL
config PINMUX config PINMUX
bool "Support pinmux controllers" bool "Support pin multiplexing controllers"
config PINCONF
bool "Support pin configuration controllers"
config DEBUG_PINCTRL config DEBUG_PINCTRL
bool "Debug PINCTRL calls" bool "Debug PINCTRL calls"
...@@ -20,16 +23,25 @@ config DEBUG_PINCTRL ...@@ -20,16 +23,25 @@ config DEBUG_PINCTRL
help help
Say Y here to add some extra checks and diagnostics to PINCTRL calls. Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINMUX_SIRF config PINCTRL_SIRF
bool "CSR SiRFprimaII pinmux driver" bool "CSR SiRFprimaII pin controller driver"
depends on ARCH_PRIMA2 depends on ARCH_PRIMA2
select PINMUX select PINMUX
config PINMUX_U300 config PINCTRL_U300
bool "U300 pinmux driver" bool "U300 pin controller driver"
depends on ARCH_U300 depends on ARCH_U300
select PINMUX select PINMUX
config PINCTRL_COH901
bool "ST-Ericsson U300 COH 901 335/571 GPIO"
depends on GPIOLIB && ARCH_U300 && PINMUX_U300
help
Say yes here to support GPIO interface on ST-Ericsson U300.
The names of the two IP block variants supported are
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
endmenu endmenu
endif endif
# generic pinmux support # generic pinmux support
ccflags-$(CONFIG_DEBUG_PINMUX) += -DDEBUG ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_PINMUX_U300) += pinmux-u300.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
...@@ -28,17 +28,12 @@ ...@@ -28,17 +28,12 @@
#include <linux/pinctrl/machine.h> #include <linux/pinctrl/machine.h>
#include "core.h" #include "core.h"
#include "pinmux.h" #include "pinmux.h"
#include "pinconf.h"
/* Global list of pin control devices */ /* Global list of pin control devices */
static DEFINE_MUTEX(pinctrldev_list_mutex); static DEFINE_MUTEX(pinctrldev_list_mutex);
static LIST_HEAD(pinctrldev_list); static LIST_HEAD(pinctrldev_list);
static void pinctrl_dev_release(struct device *dev)
{
struct pinctrl_dev *pctldev = dev_get_drvdata(dev);
kfree(pctldev);
}
const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
{ {
/* We're not allowed to register devices without name */ /* We're not allowed to register devices without name */
...@@ -70,14 +65,14 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, ...@@ -70,14 +65,14 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
mutex_lock(&pinctrldev_list_mutex); mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
if (dev && &pctldev->dev == dev) { if (dev && pctldev->dev == dev) {
/* Matched on device pointer */ /* Matched on device pointer */
found = true; found = true;
break; break;
} }
if (devname && if (devname &&
!strcmp(dev_name(&pctldev->dev), devname)) { !strcmp(dev_name(pctldev->dev), devname)) {
/* Matched on device name */ /* Matched on device name */
found = true; found = true;
break; break;
...@@ -88,7 +83,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, ...@@ -88,7 +83,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
return found ? pctldev : NULL; return found ? pctldev : NULL;
} }
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin) struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin)
{ {
struct pin_desc *pindesc; struct pin_desc *pindesc;
unsigned long flags; unsigned long flags;
...@@ -100,6 +95,31 @@ struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin) ...@@ -100,6 +95,31 @@ struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin)
return pindesc; return pindesc;
} }
/**
* pin_get_from_name() - look up a pin number from a name
* @pctldev: the pin control device to lookup the pin on
* @name: the name of the pin to look up
*/
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name)
{
unsigned i, pin;
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin);
/* Pin space may be sparse */
if (desc == NULL)
continue;
if (desc->name && !strcmp(name, desc->name))
return pin;
}
return -EINVAL;
}
/** /**
* pin_is_valid() - check if pin exists on controller * pin_is_valid() - check if pin exists on controller
* @pctldev: the pin control device to check the pin on * @pctldev: the pin control device to check the pin on
...@@ -139,6 +159,8 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, ...@@ -139,6 +159,8 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
if (pindesc != NULL) { if (pindesc != NULL) {
radix_tree_delete(&pctldev->pin_desc_tree, radix_tree_delete(&pctldev->pin_desc_tree,
pins[i].number); pins[i].number);
if (pindesc->dynamic_name)
kfree(pindesc->name);
} }
kfree(pindesc); kfree(pindesc);
} }
...@@ -160,19 +182,27 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, ...@@ -160,19 +182,27 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL);
if (pindesc == NULL) if (pindesc == NULL)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&pindesc->lock); spin_lock_init(&pindesc->lock);
/* Set owner */ /* Set owner */
pindesc->pctldev = pctldev; pindesc->pctldev = pctldev;
/* Copy basic pin info */ /* Copy basic pin info */
pindesc->name = name; if (pindesc->name) {
pindesc->name = name;
} else {
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);
if (pindesc->name == NULL)
return -ENOMEM;
pindesc->dynamic_name = true;
}
spin_lock(&pctldev->pin_desc_tree_lock); spin_lock(&pctldev->pin_desc_tree_lock);
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);
spin_unlock(&pctldev->pin_desc_tree_lock); spin_unlock(&pctldev->pin_desc_tree_lock);
pr_debug("registered pin %d (%s) on %s\n", pr_debug("registered pin %d (%s) on %s\n",
number, name ? name : "(unnamed)", pctldev->desc->name); number, pindesc->name, pctldev->desc->name);
return 0; return 0;
} }
...@@ -284,21 +314,52 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, ...@@ -284,21 +314,52 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
mutex_unlock(&pctldev->gpio_ranges_lock); mutex_unlock(&pctldev->gpio_ranges_lock);
} }
/**
* pinctrl_get_group_selector() - returns the group selector for a group
* @pctldev: the pin controller handling the group
* @pin_group: the pin group to look up
*/
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group)
{
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
unsigned group_selector = 0;
while (pctlops->list_groups(pctldev, group_selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev,
group_selector);
if (!strcmp(gname, pin_group)) {
dev_dbg(pctldev->dev,
"found group selector %u for %s\n",
group_selector,
pin_group);
return group_selector;
}
group_selector++;
}
dev_err(pctldev->dev, "does not have pin group %s\n",
pin_group);
return -EINVAL;
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what) static int pinctrl_pins_show(struct seq_file *s, void *what)
{ {
struct pinctrl_dev *pctldev = s->private; struct pinctrl_dev *pctldev = s->private;
const struct pinctrl_ops *ops = pctldev->desc->pctlops; const struct pinctrl_ops *ops = pctldev->desc->pctlops;
unsigned pin; unsigned i, pin;
seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); seq_printf(s, "registered pins: %d\n", pctldev->desc->npins);
seq_printf(s, "max pin number: %d\n", pctldev->desc->maxpin);
/* The highest pin number need to be included in the loop, thus <= */ /* The pin number can be retrived from the pin controller descriptor */
for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc; struct pin_desc *desc;
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
/* Pin space may be sparse */ /* Pin space may be sparse */
if (desc == NULL) if (desc == NULL)
...@@ -363,8 +424,11 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) ...@@ -363,8 +424,11 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
/* Loop over the ranges */ /* Loop over the ranges */
mutex_lock(&pctldev->gpio_ranges_lock); mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) { list_for_each_entry(range, &pctldev->gpio_ranges, node) {
seq_printf(s, "%u: %s [%u - %u]\n", range->id, range->name, seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
range->base, (range->base + range->npins - 1)); range->id, range->name,
range->base, (range->base + range->npins - 1),
range->pin_base,
(range->pin_base + range->npins - 1));
} }
mutex_unlock(&pctldev->gpio_ranges_lock); mutex_unlock(&pctldev->gpio_ranges_lock);
...@@ -375,11 +439,15 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) ...@@ -375,11 +439,15 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
{ {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
seq_puts(s, "name [pinmux]\n"); seq_puts(s, "name [pinmux] [pinconf]\n");
mutex_lock(&pinctrldev_list_mutex); mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
seq_printf(s, "%s ", pctldev->desc->name); seq_printf(s, "%s ", pctldev->desc->name);
if (pctldev->desc->pmxops) if (pctldev->desc->pmxops)
seq_puts(s, "yes ");
else
seq_puts(s, "no ");
if (pctldev->desc->confops)
seq_puts(s, "yes"); seq_puts(s, "yes");
else else
seq_puts(s, "no"); seq_puts(s, "no");
...@@ -444,11 +512,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) ...@@ -444,11 +512,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
{ {
static struct dentry *device_root; static struct dentry *device_root;
device_root = debugfs_create_dir(dev_name(&pctldev->dev), device_root = debugfs_create_dir(dev_name(pctldev->dev),
debugfs_root); debugfs_root);
if (IS_ERR(device_root) || !device_root) { if (IS_ERR(device_root) || !device_root) {
pr_warn("failed to create debugfs directory for %s\n", pr_warn("failed to create debugfs directory for %s\n",
dev_name(&pctldev->dev)); dev_name(pctldev->dev));
return; return;
} }
debugfs_create_file("pins", S_IFREG | S_IRUGO, debugfs_create_file("pins", S_IFREG | S_IRUGO,
...@@ -458,6 +526,7 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) ...@@ -458,6 +526,7 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO,
device_root, pctldev, &pinctrl_gpioranges_ops); device_root, pctldev, &pinctrl_gpioranges_ops);
pinmux_init_device_debugfs(device_root, pctldev); pinmux_init_device_debugfs(device_root, pctldev);
pinconf_init_device_debugfs(device_root, pctldev);
} }
static void pinctrl_init_debugfs(void) static void pinctrl_init_debugfs(void)
...@@ -495,7 +564,6 @@ static void pinctrl_init_debugfs(void) ...@@ -495,7 +564,6 @@ static void pinctrl_init_debugfs(void)
struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
struct device *dev, void *driver_data) struct device *dev, void *driver_data)
{ {
static atomic_t pinmux_no = ATOMIC_INIT(0);
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
int ret; int ret;
...@@ -514,6 +582,16 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -514,6 +582,16 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
} }
} }
/* If we're implementing pinconfig, check the ops for sanity */
if (pctldesc->confops) {
ret = pinconf_check_ops(pctldesc->confops);
if (ret) {
pr_err("%s pin config ops lacks necessary functions\n",
pctldesc->name);
return NULL;
}
}
pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
if (pctldev == NULL) if (pctldev == NULL)
return NULL; return NULL;
...@@ -526,18 +604,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -526,18 +604,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
spin_lock_init(&pctldev->pin_desc_tree_lock); spin_lock_init(&pctldev->pin_desc_tree_lock);
INIT_LIST_HEAD(&pctldev->gpio_ranges); INIT_LIST_HEAD(&pctldev->gpio_ranges);
mutex_init(&pctldev->gpio_ranges_lock); mutex_init(&pctldev->gpio_ranges_lock);
pctldev->dev = dev;
/* Register device */
pctldev->dev.parent = dev;
dev_set_name(&pctldev->dev, "pinctrl.%d",
atomic_inc_return(&pinmux_no) - 1);
pctldev->dev.release = pinctrl_dev_release;
ret = device_register(&pctldev->dev);
if (ret != 0) {
pr_err("error in device registration\n");
goto out_reg_dev_err;
}
dev_set_drvdata(&pctldev->dev, pctldev);
/* Register all the pins */ /* Register all the pins */
pr_debug("try to register %d pins on %s...\n", pr_debug("try to register %d pins on %s...\n",
...@@ -547,7 +614,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -547,7 +614,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pr_err("error during pin registration\n"); pr_err("error during pin registration\n");
pinctrl_free_pindescs(pctldev, pctldesc->pins, pinctrl_free_pindescs(pctldev, pctldesc->pins,
pctldesc->npins); pctldesc->npins);
goto out_reg_pins_err; goto out_err;
} }
pinctrl_init_device_debugfs(pctldev); pinctrl_init_device_debugfs(pctldev);
...@@ -557,10 +624,8 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -557,10 +624,8 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pinmux_hog_maps(pctldev); pinmux_hog_maps(pctldev);
return pctldev; return pctldev;
out_reg_pins_err: out_err:
device_del(&pctldev->dev); kfree(pctldev);
out_reg_dev_err:
put_device(&pctldev->dev);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(pinctrl_register); EXPORT_SYMBOL_GPL(pinctrl_register);
...@@ -584,7 +649,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) ...@@ -584,7 +649,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
/* Destroy descriptor tree */ /* Destroy descriptor tree */
pinctrl_free_pindescs(pctldev, pctldev->desc->pins, pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins); pctldev->desc->npins);
device_unregister(&pctldev->dev); kfree(pctldev);
} }
EXPORT_SYMBOL_GPL(pinctrl_unregister); EXPORT_SYMBOL_GPL(pinctrl_unregister);
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
*/ */
#include <linux/pinctrl/pinconf.h>
struct pinctrl_gpio_range;
/** /**
* struct pinctrl_dev - pin control class device * struct pinctrl_dev - pin control class device
* @node: node to include this pin controller in the global pin controller list * @node: node to include this pin controller in the global pin controller list
...@@ -34,7 +38,7 @@ struct pinctrl_dev { ...@@ -34,7 +38,7 @@ struct pinctrl_dev {
spinlock_t pin_desc_tree_lock; spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges; struct list_head gpio_ranges;
struct mutex gpio_ranges_lock; struct mutex gpio_ranges_lock;
struct device dev; struct device *dev;
struct module *owner; struct module *owner;
void *driver_data; void *driver_data;
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
...@@ -48,6 +52,7 @@ struct pinctrl_dev { ...@@ -48,6 +52,7 @@ struct pinctrl_dev {
* @pctldev: corresponding pin control device * @pctldev: corresponding pin control device
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a * @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such * datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated
* @lock: a lock to protect the descriptor structure * @lock: a lock to protect the descriptor structure
* @mux_requested: whether the pin is already requested by pinmux or not * @mux_requested: whether the pin is already requested by pinmux or not
* @mux_function: a named muxing function for the pin that will be passed to * @mux_function: a named muxing function for the pin that will be passed to
...@@ -56,6 +61,7 @@ struct pinctrl_dev { ...@@ -56,6 +61,7 @@ struct pinctrl_dev {
struct pin_desc { struct pin_desc {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
const char *name; const char *name;
bool dynamic_name;
spinlock_t lock; spinlock_t lock;
/* These fields only added when supporting pinmux drivers */ /* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
...@@ -65,7 +71,10 @@ struct pin_desc { ...@@ -65,7 +71,10 @@ struct pin_desc {
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
const char *dev_name); const char *dev_name);
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
int pinctrl_get_device_gpio_range(unsigned gpio, int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev, struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange); struct pinctrl_gpio_range **outrange);
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group);
/*
* Core driver for the pin config portions of the pin control subsystem
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#define pr_fmt(fmt) "pinconfig core: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include "core.h"
#include "pinconf.h"
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_get) {
dev_err(pctldev->dev, "cannot get pin configuration, missing "
"pin_config_get() function in driver\n");
return -EINVAL;
}
return ops->pin_config_get(pctldev, pin, config);
}
/**
* pin_config_get() - get the configuration of a single pin parameter
* @dev_name: name of the pin controller device for this pin
* @name: name of the pin to get the config for
* @config: the config pointed to by this argument will be filled in with the
* current pin state, it can be used directly by drivers as a numeral, or
* it can be dereferenced to any struct.
*/
int pin_config_get(const char *dev_name, const char *name,
unsigned long *config)
{
struct pinctrl_dev *pctldev;
int pin;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
return pin_config_get_for_pin(pctldev, pin, config);
}
EXPORT_SYMBOL(pin_config_get);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int ret;
if (!ops || !ops->pin_config_set) {
dev_err(pctldev->dev, "cannot configure pin, missing "
"config function in driver\n");
return -EINVAL;
}
ret = ops->pin_config_set(pctldev, pin, config);
if (ret) {
dev_err(pctldev->dev,
"unable to set pin configuration on pin %d\n", pin);
return ret;
}
return 0;
}
/**
* pin_config_set() - set the configuration of a single pin parameter
* @dev_name: name of pin controller device for this pin
* @name: name of the pin to set the config for
* @config: the config in this argument will contain the desired pin state, it
* can be used directly by drivers as a numeral, or it can be dereferenced
* to any struct.
*/
int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
struct pinctrl_dev *pctldev;
int pin;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
return pin_config_set_for_pin(pctldev, pin, config);
}
EXPORT_SYMBOL(pin_config_set);
int pin_config_group_get(const char *dev_name, const char *pin_group,
unsigned long *config)
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
int selector;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
return -EINVAL;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
return ops->pin_config_group_get(pctldev, selector, config);
}
EXPORT_SYMBOL(pin_config_group_get);
int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config)
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
const struct pinctrl_ops *pctlops;
int selector;
const unsigned *pins;
unsigned num_pins;
int ret;
int i;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
ops = pctldev->desc->confops;
pctlops = pctldev->desc->pctlops;
if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
dev_err(pctldev->dev, "cannot configure pin group, missing "
"config function in driver\n");
return -EINVAL;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
if (ret) {
dev_err(pctldev->dev, "cannot configure pin group, error "
"getting pins\n");
return ret;
}
/*
* If the pin controller supports handling entire groups we use that
* capability.
*/
if (ops->pin_config_group_set) {
ret = ops->pin_config_group_set(pctldev, selector, config);
/*
* If the pin controller prefer that a certain group be handled
* pin-by-pin as well, it returns -EAGAIN.
*/
if (ret != -EAGAIN)
return ret;
}
/*
* If the controller cannot handle entire groups, we configure each pin
* individually.
*/
if (!ops->pin_config_set)
return 0;
for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0)
return ret;
}
return 0;
}
EXPORT_SYMBOL(pin_config_group_set);
int pinconf_check_ops(const struct pinconf_ops *ops)
{
/* We must be able to read out pin status */
if (!ops->pin_config_get && !ops->pin_config_group_get)
return -EINVAL;
/* We have to be able to config the pins in SOME way */
if (!ops->pin_config_set && !ops->pin_config_group_set)
return -EINVAL;
return 0;
}
#ifdef CONFIG_DEBUG_FS
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, int pin)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
if (ops && ops->pin_config_dbg_show)
ops->pin_config_dbg_show(pctldev, s, pin);
}
static int pinconf_pins_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
unsigned i, pin;
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): pinmux setting array\n");
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; pin < pctldev->desc->npins; i++) {
struct pin_desc *desc;
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin);
/* Skip if we cannot search the pin */
if (desc == NULL)
continue;
seq_printf(s, "pin %d (%s):", pin,
desc->name ? desc->name : "unnamed");
pinconf_dump_pin(pctldev, s, pin);
seq_printf(s, "\n");
}
return 0;
}
static void pinconf_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned selector,
const char *gname)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
if (ops && ops->pin_config_group_dbg_show)
ops->pin_config_group_dbg_show(pctldev, s, selector);
}
static int pinconf_groups_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinconf_ops *ops = pctldev->desc->confops;
unsigned selector = 0;
if (!ops || !ops->pin_config_group_get)
return 0;
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): pinmux setting array\n");
while (pctlops->list_groups(pctldev, selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev, selector);
seq_printf(s, "%u (%s):", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname);
selector++;
}
return 0;
}
static int pinconf_pins_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_pins_show, inode->i_private);
}
static int pinconf_groups_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_groups_show, inode->i_private);
}
static const struct file_operations pinconf_pins_ops = {
.open = pinconf_pins_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations pinconf_groups_ops = {
.open = pinconf_groups_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
devroot, pctldev, &pinconf_pins_ops);
debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
devroot, pctldev, &pinconf_groups_ops);
}
#endif
/*
* Internal interface between the core pin control system and the
* pin config portions
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifdef CONFIG_PINCONF
int pinconf_check_ops(const struct pinconf_ops *ops);
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config);
#else
static inline int pinconf_check_ops(const struct pinconf_ops *ops)
{
return 0;
}
static inline void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
}
#endif
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pinctrl/pinmux.h>
#include <mach/gpio-u300.h> #include <mach/gpio-u300.h>
/* /*
...@@ -351,6 +352,24 @@ static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip) ...@@ -351,6 +352,24 @@ static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip)
return container_of(chip, struct u300_gpio, chip); return container_of(chip, struct u300_gpio, chip);
} }
static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
{
/*
* Map back to global GPIO space and request muxing, the direction
* parameter does not matter for this controller.
*/
int gpio = chip->base + offset;
return pinmux_request_gpio(gpio);
}
static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
pinmux_free_gpio(gpio);
}
static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
{ {
struct u300_gpio *gpio = to_u300_gpio(chip); struct u300_gpio *gpio = to_u300_gpio(chip);
...@@ -483,6 +502,8 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, ...@@ -483,6 +502,8 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
static struct gpio_chip u300_gpio_chip = { static struct gpio_chip u300_gpio_chip = {
.label = "u300-gpio-chip", .label = "u300-gpio-chip",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.request = u300_gpio_request,
.free = u300_gpio_free,
.get = u300_gpio_get, .get = u300_gpio_get,
.set = u300_gpio_set, .set = u300_gpio_set,
.direction_input = u300_gpio_direction_input, .direction_input = u300_gpio_direction_input,
......
...@@ -463,7 +463,7 @@ static const struct sirfsoc_padmux spi1_padmux = { ...@@ -463,7 +463,7 @@ static const struct sirfsoc_padmux spi1_padmux = {
.funcval = BIT(8), .funcval = BIT(8),
}; };
static const unsigned spi1_pins[] = { 33, 34, 35, 36 }; static const unsigned spi1_pins[] = { 43, 44, 45, 46 };
static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { static const struct sirfsoc_muxmask sdmmc1_muxmask[] = {
{ {
...@@ -1067,7 +1067,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, ...@@ -1067,7 +1067,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
spmx = pinctrl_dev_get_drvdata(pmxdev); spmx = pinctrl_dev_get_drvdata(pmxdev);
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
muxval = muxval | (1 << offset); muxval = muxval | (1 << (offset - range->pin_base));
writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
return 0; return 0;
...@@ -1086,7 +1086,6 @@ static struct pinctrl_desc sirfsoc_pinmux_desc = { ...@@ -1086,7 +1086,6 @@ static struct pinctrl_desc sirfsoc_pinmux_desc = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pins = sirfsoc_pads, .pins = sirfsoc_pads,
.npins = ARRAY_SIZE(sirfsoc_pads), .npins = ARRAY_SIZE(sirfsoc_pads),
.maxpin = SIRFSOC_NUM_PADS - 1,
.pctlops = &sirfsoc_pctrl_ops, .pctlops = &sirfsoc_pctrl_ops,
.pmxops = &sirfsoc_pinmux_ops, .pmxops = &sirfsoc_pinmux_ops,
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1100,21 +1099,25 @@ static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = { ...@@ -1100,21 +1099,25 @@ static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = {
.name = "sirfsoc-gpio*", .name = "sirfsoc-gpio*",
.id = 0, .id = 0,
.base = 0, .base = 0,
.pin_base = 0,
.npins = 32, .npins = 32,
}, { }, {
.name = "sirfsoc-gpio*", .name = "sirfsoc-gpio*",
.id = 1, .id = 1,
.base = 32, .base = 32,
.pin_base = 32,
.npins = 32, .npins = 32,
}, { }, {
.name = "sirfsoc-gpio*", .name = "sirfsoc-gpio*",
.id = 2, .id = 2,
.base = 64, .base = 64,
.pin_base = 64,
.npins = 32, .npins = 32,
}, { }, {
.name = "sirfsoc-gpio*", .name = "sirfsoc-gpio*",
.id = 3, .id = 3,
.base = 96, .base = 96,
.pin_base = 96,
.npins = 19, .npins = 19,
}, },
}; };
......
...@@ -940,20 +940,23 @@ static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector, ...@@ -940,20 +940,23 @@ static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector,
{ {
u16 regval, val, mask; u16 regval, val, mask;
int i; int i;
const struct u300_pmx_mask *upmx_mask;
upmx_mask = u300_pmx_functions[selector].mask;
for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) { for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) {
if (enable) if (enable)
val = u300_pmx_functions[selector].mask->bits; val = upmx_mask->bits;
else else
val = 0; val = 0;
mask = u300_pmx_functions[selector].mask->mask; mask = upmx_mask->mask;
if (mask != 0) { if (mask != 0) {
regval = readw(upmx->virtbase + u300_pmx_registers[i]); regval = readw(upmx->virtbase + u300_pmx_registers[i]);
regval &= ~mask; regval &= ~mask;
regval |= val; regval |= val;
writew(regval, upmx->virtbase + u300_pmx_registers[i]); writew(regval, upmx->virtbase + u300_pmx_registers[i]);
} }
upmx_mask++;
} }
} }
...@@ -1016,21 +1019,35 @@ static struct pinmux_ops u300_pmx_ops = { ...@@ -1016,21 +1019,35 @@ static struct pinmux_ops u300_pmx_ops = {
}; };
/* /*
* FIXME: this will be set to sane values as this driver engulfs * GPIO ranges handled by the application-side COH901XXX GPIO controller
* drivers/gpio/gpio-u300.c and we really know this stuff. * Very many pins can be converted into GPIO pins, but we only list those
* that are useful in practice to cut down on tables.
*/ */
static struct pinctrl_gpio_range u300_gpio_range = { #define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \
.name = "COH901*", .pin_base = b, .npins = c }
.id = 0,
.base = 0, static struct pinctrl_gpio_range u300_gpio_ranges[] = {
.npins = 64, U300_GPIO_RANGE(10, 426, 1),
U300_GPIO_RANGE(11, 180, 1),
U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */
U300_GPIO_RANGE(13, 179, 1),
U300_GPIO_RANGE(14, 178, 1),
U300_GPIO_RANGE(16, 194, 1),
U300_GPIO_RANGE(17, 193, 1),
U300_GPIO_RANGE(18, 192, 1),
U300_GPIO_RANGE(19, 191, 1),
U300_GPIO_RANGE(20, 186, 1),
U300_GPIO_RANGE(21, 185, 1),
U300_GPIO_RANGE(22, 184, 1),
U300_GPIO_RANGE(23, 183, 1),
U300_GPIO_RANGE(24, 182, 1),
U300_GPIO_RANGE(25, 181, 1),
}; };
static struct pinctrl_desc u300_pmx_desc = { static struct pinctrl_desc u300_pmx_desc = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pins = u300_pads, .pins = u300_pads,
.npins = ARRAY_SIZE(u300_pads), .npins = ARRAY_SIZE(u300_pads),
.maxpin = U300_NUM_PADS-1,
.pctlops = &u300_pctrl_ops, .pctlops = &u300_pctrl_ops,
.pmxops = &u300_pmx_ops, .pmxops = &u300_pmx_ops,
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1038,9 +1055,10 @@ static struct pinctrl_desc u300_pmx_desc = { ...@@ -1038,9 +1055,10 @@ static struct pinctrl_desc u300_pmx_desc = {
static int __init u300_pmx_probe(struct platform_device *pdev) static int __init u300_pmx_probe(struct platform_device *pdev)
{ {
int ret;
struct u300_pmx *upmx; struct u300_pmx *upmx;
struct resource *res; struct resource *res;
int ret;
int i;
/* Create state holders etc for this driver */ /* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
...@@ -1077,7 +1095,8 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1077,7 +1095,8 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
} }
/* We will handle a range of GPIO pins */ /* We will handle a range of GPIO pins */
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_range); for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
platform_set_drvdata(pdev, upmx); platform_set_drvdata(pdev, upmx);
...@@ -1099,8 +1118,10 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1099,8 +1118,10 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
static int __exit u300_pmx_remove(struct platform_device *pdev) static int __exit u300_pmx_remove(struct platform_device *pdev)
{ {
struct u300_pmx *upmx = platform_get_drvdata(pdev); struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i;
pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_range); for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
pinctrl_unregister(upmx->pctl); pinctrl_unregister(upmx->pctl);
iounmap(upmx->virtbase); iounmap(upmx->virtbase);
release_mem_region(upmx->phybase, upmx->physize); release_mem_region(upmx->phybase, upmx->physize);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -32,12 +33,8 @@ ...@@ -32,12 +33,8 @@
static DEFINE_MUTEX(pinmux_list_mutex); static DEFINE_MUTEX(pinmux_list_mutex);
static LIST_HEAD(pinmux_list); static LIST_HEAD(pinmux_list);
/* List of pinmux hogs */ /* Global pinmux maps */
static DEFINE_MUTEX(pinmux_hoglist_mutex); static struct pinmux_map *pinmux_maps;
static LIST_HEAD(pinmux_hoglist);
/* Global pinmux maps, we allow one set only */
static struct pinmux_map const *pinmux_maps;
static unsigned pinmux_maps_num; static unsigned pinmux_maps_num;
/** /**
...@@ -98,41 +95,35 @@ struct pinmux_hog { ...@@ -98,41 +95,35 @@ struct pinmux_hog {
* @function: a functional name to give to this pin, passed to the driver * @function: a functional name to give to this pin, passed to the driver
* so it knows what function to mux in, e.g. the string "gpioNN" * so it knows what function to mux in, e.g. the string "gpioNN"
* means that you want to mux in the pin for use as GPIO number NN * means that you want to mux in the pin for use as GPIO number NN
* @gpio: if this request concerns a single GPIO pin
* @gpio_range: the range matching the GPIO pin if this is a request for a * @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin * single GPIO pin
*/ */
static int pin_request(struct pinctrl_dev *pctldev, static int pin_request(struct pinctrl_dev *pctldev,
int pin, const char *function, bool gpio, int pin, const char *function,
struct pinctrl_gpio_range *gpio_range) struct pinctrl_gpio_range *gpio_range)
{ {
struct pin_desc *desc; struct pin_desc *desc;
const struct pinmux_ops *ops = pctldev->desc->pmxops; const struct pinmux_ops *ops = pctldev->desc->pmxops;
int status = -EINVAL; int status = -EINVAL;
dev_dbg(&pctldev->dev, "request pin %d for %s\n", pin, function); dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, function);
if (!pin_is_valid(pctldev, pin)) {
dev_err(&pctldev->dev, "pin is invalid\n");
return -EINVAL;
}
if (!function) {
dev_err(&pctldev->dev, "no function name given\n");
return -EINVAL;
}
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
if (desc == NULL) { if (desc == NULL) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"pin is not registered so it cannot be requested\n"); "pin is not registered so it cannot be requested\n");
goto out; goto out;
} }
if (!function) {
dev_err(pctldev->dev, "no function name given\n");
return -EINVAL;
}
spin_lock(&desc->lock); spin_lock(&desc->lock);
if (desc->mux_function) { if (desc->mux_function) {
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"pin already requested\n"); "pin already requested\n");
goto out; goto out;
} }
...@@ -141,7 +132,7 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -141,7 +132,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
/* Let each pin increase references to this module */ /* Let each pin increase references to this module */
if (!try_module_get(pctldev->owner)) { if (!try_module_get(pctldev->owner)) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"could not increase module refcount for pin %d\n", "could not increase module refcount for pin %d\n",
pin); pin);
status = -EINVAL; status = -EINVAL;
...@@ -152,7 +143,7 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -152,7 +143,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
* If there is no kind of request function for the pin we just assume * If there is no kind of request function for the pin we just assume
* we got it by default and proceed. * we got it by default and proceed.
*/ */
if (gpio && ops->gpio_request_enable) if (gpio_range && ops->gpio_request_enable)
/* This requests and enables a single GPIO pin */ /* This requests and enables a single GPIO pin */
status = ops->gpio_request_enable(pctldev, gpio_range, pin); status = ops->gpio_request_enable(pctldev, gpio_range, pin);
else if (ops->request) else if (ops->request)
...@@ -161,7 +152,7 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -161,7 +152,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
status = 0; status = 0;
if (status) if (status)
dev_err(&pctldev->dev, "->request on device %s failed " dev_err(pctldev->dev, "->request on device %s failed "
"for pin %d\n", "for pin %d\n",
pctldev->desc->name, pin); pctldev->desc->name, pin);
out_free_pin: out_free_pin:
...@@ -172,7 +163,7 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -172,7 +163,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
} }
out: out:
if (status) if (status)
dev_err(&pctldev->dev, "pin-%d (%s) status %d\n", dev_err(pctldev->dev, "pin-%d (%s) status %d\n",
pin, function ? : "?", status); pin, function ? : "?", status);
return status; return status;
...@@ -182,34 +173,52 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -182,34 +173,52 @@ static int pin_request(struct pinctrl_dev *pctldev,
* pin_free() - release a single muxed in pin so something else can be muxed * pin_free() - release a single muxed in pin so something else can be muxed
* @pctldev: pin controller device handling this pin * @pctldev: pin controller device handling this pin
* @pin: the pin to free * @pin: the pin to free
* @free_func: whether to free the pin's assigned function name string * @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin
*
* This function returns a pointer to the function name in use. This is used
* for callers that dynamically allocate a function name so it can be freed
* once the pin is free. This is done for GPIO request functions.
*/ */
static void pin_free(struct pinctrl_dev *pctldev, int pin, int free_func) static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
struct pinctrl_gpio_range *gpio_range)
{ {
const struct pinmux_ops *ops = pctldev->desc->pmxops; const struct pinmux_ops *ops = pctldev->desc->pmxops;
struct pin_desc *desc; struct pin_desc *desc;
const char *func;
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
if (desc == NULL) { if (desc == NULL) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"pin is not registered so it cannot be freed\n"); "pin is not registered so it cannot be freed\n");
return; return NULL;
} }
if (ops->free) /*
* If there is no kind of request function for the pin we just assume
* we got it by default and proceed.
*/
if (gpio_range && ops->gpio_disable_free)
ops->gpio_disable_free(pctldev, gpio_range, pin);
else if (ops->free)
ops->free(pctldev, pin); ops->free(pctldev, pin);
spin_lock(&desc->lock); spin_lock(&desc->lock);
if (free_func) func = desc->mux_function;
kfree(desc->mux_function);
desc->mux_function = NULL; desc->mux_function = NULL;
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
module_put(pctldev->owner); module_put(pctldev->owner);
return func;
} }
/** /**
* pinmux_request_gpio() - request a single pin to be muxed in as GPIO * pinmux_request_gpio() - request a single pin to be muxed in as GPIO
* @gpio: the GPIO pin number from the GPIO subsystem number space * @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_request() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed in.
*/ */
int pinmux_request_gpio(unsigned gpio) int pinmux_request_gpio(unsigned gpio)
{ {
...@@ -225,7 +234,7 @@ int pinmux_request_gpio(unsigned gpio) ...@@ -225,7 +234,7 @@ int pinmux_request_gpio(unsigned gpio)
return -EINVAL; return -EINVAL;
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base; pin = gpio - range->base + range->pin_base;
/* Conjure some name stating what chip and pin this is taken by */ /* Conjure some name stating what chip and pin this is taken by */
snprintf(gpiostr, 15, "%s:%d", range->name, gpio); snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
...@@ -234,7 +243,7 @@ int pinmux_request_gpio(unsigned gpio) ...@@ -234,7 +243,7 @@ int pinmux_request_gpio(unsigned gpio)
if (!function) if (!function)
return -EINVAL; return -EINVAL;
ret = pin_request(pctldev, pin, function, true, range); ret = pin_request(pctldev, pin, function, range);
if (ret < 0) if (ret < 0)
kfree(function); kfree(function);
...@@ -245,6 +254,10 @@ EXPORT_SYMBOL_GPL(pinmux_request_gpio); ...@@ -245,6 +254,10 @@ EXPORT_SYMBOL_GPL(pinmux_request_gpio);
/** /**
* pinmux_free_gpio() - free a single pin, currently used as GPIO * pinmux_free_gpio() - free a single pin, currently used as GPIO
* @gpio: the GPIO pin number from the GPIO subsystem number space * @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_free() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed out.
*/ */
void pinmux_free_gpio(unsigned gpio) void pinmux_free_gpio(unsigned gpio)
{ {
...@@ -252,53 +265,108 @@ void pinmux_free_gpio(unsigned gpio) ...@@ -252,53 +265,108 @@ void pinmux_free_gpio(unsigned gpio)
struct pinctrl_gpio_range *range; struct pinctrl_gpio_range *range;
int ret; int ret;
int pin; int pin;
const char *func;
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret) if (ret)
return; return;
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base; pin = gpio - range->base + range->pin_base;
pin_free(pctldev, pin, true); func = pin_free(pctldev, pin, range);
kfree(func);
} }
EXPORT_SYMBOL_GPL(pinmux_free_gpio); EXPORT_SYMBOL_GPL(pinmux_free_gpio);
static int pinmux_gpio_direction(unsigned gpio, bool input)
{
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range;
const struct pinmux_ops *ops;
int ret;
int pin;
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret)
return ret;
ops = pctldev->desc->pmxops;
/* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base;
if (ops->gpio_set_direction)
ret = ops->gpio_set_direction(pctldev, range, pin, input);
else
ret = 0;
return ret;
}
/**
* pinmux_gpio_direction_input() - request a GPIO pin to go into input mode
* @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_direction_input() semantics, platforms and individual
* drivers shall *NOT* touch pinmux GPIO calls.
*/
int pinmux_gpio_direction_input(unsigned gpio)
{
return pinmux_gpio_direction(gpio, true);
}
EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input);
/**
* pinmux_gpio_direction_output() - request a GPIO pin to go into output mode
* @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_direction_output() semantics, platforms and individual
* drivers shall *NOT* touch pinmux GPIO calls.
*/
int pinmux_gpio_direction_output(unsigned gpio)
{
return pinmux_gpio_direction(gpio, false);
}
EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
/** /**
* pinmux_register_mappings() - register a set of pinmux mappings * pinmux_register_mappings() - register a set of pinmux mappings
* @maps: the pinmux mappings table to register * @maps: the pinmux mappings table to register, this should be marked with
* __initdata so it can be discarded after boot, this function will
* perform a shallow copy for the mapping entries.
* @num_maps: the number of maps in the mapping table * @num_maps: the number of maps in the mapping table
* *
* Only call this once during initialization of your machine, the function is * Only call this once during initialization of your machine, the function is
* tagged as __init and won't be callable after init has completed. The map * tagged as __init and won't be callable after init has completed. The map
* passed into this function will be owned by the pinmux core and cannot be * passed into this function will be owned by the pinmux core and cannot be
* free:d. * freed.
*/ */
int __init pinmux_register_mappings(struct pinmux_map const *maps, int __init pinmux_register_mappings(struct pinmux_map const *maps,
unsigned num_maps) unsigned num_maps)
{ {
void *tmp_maps;
int i; int i;
if (pinmux_maps != NULL) {
pr_err("pinmux mappings already registered, you can only "
"register one set of maps\n");
return -EINVAL;
}
pr_debug("add %d pinmux maps\n", num_maps); pr_debug("add %d pinmux maps\n", num_maps);
/* First sanity check the new mapping */
for (i = 0; i < num_maps; i++) { for (i = 0; i < num_maps; i++) {
/* Sanity check the mapping */
if (!maps[i].name) { if (!maps[i].name) {
pr_err("failed to register map %d: " pr_err("failed to register map %d: "
"no map name given\n", i); "no map name given\n", i);
return -EINVAL; return -EINVAL;
} }
if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
pr_err("failed to register map %s (%d): " pr_err("failed to register map %s (%d): "
"no pin control device given\n", "no pin control device given\n",
maps[i].name, i); maps[i].name, i);
return -EINVAL; return -EINVAL;
} }
if (!maps[i].function) { if (!maps[i].function) {
pr_err("failed to register map %s (%d): " pr_err("failed to register map %s (%d): "
"no function ID given\n", maps[i].name, i); "no function ID given\n", maps[i].name, i);
...@@ -315,9 +383,30 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, ...@@ -315,9 +383,30 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
maps[i].function); maps[i].function);
} }
pinmux_maps = maps; /*
pinmux_maps_num = num_maps; * Make a copy of the map array - string pointers will end up in the
* kernel const section anyway so these do not need to be deep copied.
*/
if (!pinmux_maps_num) {
/* On first call, just copy them */
tmp_maps = kmemdup(maps,
sizeof(struct pinmux_map) * num_maps,
GFP_KERNEL);
if (!tmp_maps)
return -ENOMEM;
} else {
/* Subsequent calls, reallocate array to new size */
size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num;
size_t newsize = sizeof(struct pinmux_map) * num_maps;
tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL);
if (!tmp_maps)
return -ENOMEM;
memcpy((tmp_maps + oldsize), maps, newsize);
}
pinmux_maps = tmp_maps;
pinmux_maps_num += num_maps;
return 0; return 0;
} }
...@@ -345,14 +434,14 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ...@@ -345,14 +434,14 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
if (ret) if (ret)
return ret; return ret;
dev_dbg(&pctldev->dev, "requesting the %u pins from group %u\n", dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n",
num_pins, group_selector); num_pins, group_selector);
/* Try to allocate all pins in this group, one by one */ /* Try to allocate all pins in this group, one by one */
for (i = 0; i < num_pins; i++) { for (i = 0; i < num_pins; i++) {
ret = pin_request(pctldev, pins[i], func, false, NULL); ret = pin_request(pctldev, pins[i], func, NULL);
if (ret) { if (ret) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"could not get pin %d for function %s " "could not get pin %d for function %s "
"on device %s - conflicting mux mappings?\n", "on device %s - conflicting mux mappings?\n",
pins[i], func ? : "(undefined)", pins[i], func ? : "(undefined)",
...@@ -360,7 +449,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ...@@ -360,7 +449,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
/* On error release all taken pins */ /* On error release all taken pins */
i--; /* this pin just failed */ i--; /* this pin just failed */
for (; i >= 0; i--) for (; i >= 0; i--)
pin_free(pctldev, pins[i], false); pin_free(pctldev, pins[i], NULL);
return -ENODEV; return -ENODEV;
} }
} }
...@@ -384,44 +473,13 @@ static void release_pins(struct pinctrl_dev *pctldev, ...@@ -384,44 +473,13 @@ static void release_pins(struct pinctrl_dev *pctldev,
ret = pctlops->get_group_pins(pctldev, group_selector, ret = pctlops->get_group_pins(pctldev, group_selector,
&pins, &num_pins); &pins, &num_pins);
if (ret) { if (ret) {
dev_err(&pctldev->dev, "could not get pins to release for " dev_err(pctldev->dev, "could not get pins to release for "
"group selector %d\n", "group selector %d\n",
group_selector); group_selector);
return; return;
} }
for (i = 0; i < num_pins; i++) for (i = 0; i < num_pins; i++)
pin_free(pctldev, pins[i], false); pin_free(pctldev, pins[i], NULL);
}
/**
* pinmux_get_group_selector() - returns the group selector for a group
* @pctldev: the pin controller handling the group
* @pin_group: the pin group to look up
*/
static int pinmux_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group)
{
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
unsigned group_selector = 0;
while (pctlops->list_groups(pctldev, group_selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev,
group_selector);
if (!strcmp(gname, pin_group)) {
dev_dbg(&pctldev->dev,
"found group selector %u for %s\n",
group_selector,
pin_group);
return group_selector;
}
group_selector++;
}
dev_err(&pctldev->dev, "does not have pin group %s\n",
pin_group);
return -EINVAL;
} }
/** /**
...@@ -465,9 +523,9 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, ...@@ -465,9 +523,9 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
return ret; return ret;
if (num_groups < 1) if (num_groups < 1)
return -EINVAL; return -EINVAL;
ret = pinmux_get_group_selector(pctldev, groups[0]); ret = pinctrl_get_group_selector(pctldev, groups[0]);
if (ret < 0) { if (ret < 0) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"function %s wants group %s but the pin " "function %s wants group %s but the pin "
"controller does not seem to have that group\n", "controller does not seem to have that group\n",
pmxops->get_function_name(pctldev, func_selector), pmxops->get_function_name(pctldev, func_selector),
...@@ -476,7 +534,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, ...@@ -476,7 +534,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
} }
if (num_groups > 1) if (num_groups > 1)
dev_dbg(&pctldev->dev, dev_dbg(pctldev->dev,
"function %s support more than one group, " "function %s support more than one group, "
"default-selecting first group %s (%d)\n", "default-selecting first group %s (%d)\n",
pmxops->get_function_name(pctldev, func_selector), pmxops->get_function_name(pctldev, func_selector),
...@@ -486,13 +544,13 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, ...@@ -486,13 +544,13 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
return ret; return ret;
} }
dev_dbg(&pctldev->dev, dev_dbg(pctldev->dev,
"check if we have pin group %s on controller %s\n", "check if we have pin group %s on controller %s\n",
pin_group, pinctrl_dev_get_name(pctldev)); pin_group, pinctrl_dev_get_name(pctldev));
ret = pinmux_get_group_selector(pctldev, pin_group); ret = pinctrl_get_group_selector(pctldev, pin_group);
if (ret < 0) { if (ret < 0) {
dev_dbg(&pctldev->dev, dev_dbg(pctldev->dev,
"%s does not support pin group %s with function %s\n", "%s does not support pin group %s with function %s\n",
pinctrl_dev_get_name(pctldev), pinctrl_dev_get_name(pctldev),
pin_group, pin_group,
...@@ -569,7 +627,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, ...@@ -569,7 +627,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
*/ */
if (pmx->pctldev && pmx->pctldev != pctldev) { if (pmx->pctldev && pmx->pctldev != pctldev) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"different pin control devices given for device %s, " "different pin control devices given for device %s, "
"function %s\n", "function %s\n",
devname, devname,
...@@ -592,7 +650,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, ...@@ -592,7 +650,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
*/ */
if (pmx->func_selector != UINT_MAX && if (pmx->func_selector != UINT_MAX &&
pmx->func_selector != func_selector) { pmx->func_selector != func_selector) {
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"dual function defines in the map for device %s\n", "dual function defines in the map for device %s\n",
devname); devname);
return -EINVAL; return -EINVAL;
...@@ -698,7 +756,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) ...@@ -698,7 +756,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name)
} }
pr_debug("in map, found pctldev %s to handle function %s", pr_debug("in map, found pctldev %s to handle function %s",
dev_name(&pctldev->dev), map->function); dev_name(pctldev->dev), map->function);
/* /*
...@@ -874,7 +932,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, ...@@ -874,7 +932,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
* without any problems, so then we can hog pinmuxes for * without any problems, so then we can hog pinmuxes for
* all devices that just want a static pin mux at this point. * all devices that just want a static pin mux at this point.
*/ */
dev_err(&pctldev->dev, "map %s wants to hog a non-system " dev_err(pctldev->dev, "map %s wants to hog a non-system "
"pinmux, this is not going to work\n", map->name); "pinmux, this is not going to work\n", map->name);
return -EINVAL; return -EINVAL;
} }
...@@ -886,7 +944,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, ...@@ -886,7 +944,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
pmx = pinmux_get(NULL, map->name); pmx = pinmux_get(NULL, map->name);
if (IS_ERR(pmx)) { if (IS_ERR(pmx)) {
kfree(hog); kfree(hog);
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"could not get the %s pinmux mapping for hogging\n", "could not get the %s pinmux mapping for hogging\n",
map->name); map->name);
return PTR_ERR(pmx); return PTR_ERR(pmx);
...@@ -896,7 +954,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, ...@@ -896,7 +954,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
if (ret) { if (ret) {
pinmux_put(pmx); pinmux_put(pmx);
kfree(hog); kfree(hog);
dev_err(&pctldev->dev, dev_err(pctldev->dev,
"could not enable the %s pinmux mapping for hogging\n", "could not enable the %s pinmux mapping for hogging\n",
map->name); map->name);
return ret; return ret;
...@@ -905,7 +963,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, ...@@ -905,7 +963,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
hog->map = map; hog->map = map;
hog->pmx = pmx; hog->pmx = pmx;
dev_info(&pctldev->dev, "hogged map %s, function %s\n", map->name, dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name,
map->function); map->function);
mutex_lock(&pctldev->pinmux_hogs_lock); mutex_lock(&pctldev->pinmux_hogs_lock);
list_add(&hog->node, &pctldev->pinmux_hogs); list_add(&hog->node, &pctldev->pinmux_hogs);
...@@ -924,7 +982,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, ...@@ -924,7 +982,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
*/ */
int pinmux_hog_maps(struct pinctrl_dev *pctldev) int pinmux_hog_maps(struct pinctrl_dev *pctldev)
{ {
struct device *dev = &pctldev->dev; struct device *dev = pctldev->dev;
const char *devname = dev_name(dev); const char *devname = dev_name(dev);
int ret; int ret;
int i; int i;
...@@ -948,7 +1006,7 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) ...@@ -948,7 +1006,7 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev)
} }
/** /**
* pinmux_hog_maps() - unhog specific map entries on controller device * pinmux_unhog_maps() - unhog specific map entries on controller device
* @pctldev: the pin control device to unhog entries on * @pctldev: the pin control device to unhog entries on
*/ */
void pinmux_unhog_maps(struct pinctrl_dev *pctldev) void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
...@@ -1005,18 +1063,19 @@ static int pinmux_functions_show(struct seq_file *s, void *what) ...@@ -1005,18 +1063,19 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
static int pinmux_pins_show(struct seq_file *s, void *what) static int pinmux_pins_show(struct seq_file *s, void *what)
{ {
struct pinctrl_dev *pctldev = s->private; struct pinctrl_dev *pctldev = s->private;
unsigned pin; unsigned i, pin;
seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Pinmux settings per pin\n");
seq_puts(s, "Format: pin (name): pinmuxfunction\n"); seq_puts(s, "Format: pin (name): pinmuxfunction\n");
/* The highest pin number need to be included in the loop, thus <= */ /* The pin number can be retrived from the pin controller descriptor */
for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc; struct pin_desc *desc;
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
/* Pin space may be sparse */ /* Skip if we cannot search the pin */
if (desc == NULL) if (desc == NULL)
continue; continue;
......
...@@ -48,7 +48,7 @@ struct pinmux_map { ...@@ -48,7 +48,7 @@ struct pinmux_map {
const char *group; const char *group;
struct device *dev; struct device *dev;
const char *dev_name; const char *dev_name;
const bool hog_on_boot; bool hog_on_boot;
}; };
/* /*
...@@ -66,30 +66,22 @@ struct pinmux_map { ...@@ -66,30 +66,22 @@ struct pinmux_map {
{ .name = a, .ctrl_dev_name = b, .function = c } { .name = a, .ctrl_dev_name = b, .function = c }
/* /*
* Convenience macro to map a function onto the primary device pinctrl device * Convenience macro to map a system function onto a certain pinctrl device,
* this is especially helpful on systems that have only one pin controller * to be hogged by the pinmux core until the system shuts down.
* or need to set up a lot of mappings on the primary controller.
*/
#define PINMUX_MAP_PRIMARY(a, b, c) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b, \
.dev_name = c }
/*
* Convenience macro to map a system function onto the primary pinctrl device.
* System functions are not assigned to a particular device.
*/ */
#define PINMUX_MAP_PRIMARY_SYS(a, b) \ #define PINMUX_MAP_SYS_HOG(a, b, c) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b } { .name = a, .ctrl_dev_name = b, .function = c, \
.hog_on_boot = true }
/* /*
* Convenience macro to map a system function onto the primary pinctrl device, * Convenience macro to map a system function onto a certain pinctrl device
* to be hogged by the pinmux core until the system shuts down. * using a specified group, to be hogged by the pinmux core until the system
* shuts down.
*/ */
#define PINMUX_MAP_PRIMARY_SYS_HOG(a, b) \ #define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b, \ { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \
.hog_on_boot = true } .hog_on_boot = true }
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
extern int pinmux_register_mappings(struct pinmux_map const *map, extern int pinmux_register_mappings(struct pinmux_map const *map,
......
/*
* Interface the pinconfig portions of the pinctrl subsystem
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* This interface is used in the core to keep track of pins.
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __LINUX_PINCTRL_PINCONF_H
#define __LINUX_PINCTRL_PINCONF_H
#ifdef CONFIG_PINCONF
struct pinctrl_dev;
struct seq_file;
/**
* struct pinconf_ops - pin config operations, to be implemented by
* pin configuration capable drivers.
* @pin_config_get: get the config of a certain pin, if the requested config
* is not available on this controller this should return -ENOTSUPP
* and if it is available but disabled it should return -EINVAL
* @pin_config_get: get the config of a certain pin
* @pin_config_set: configure an individual pin
* @pin_config_group_get: get configurations for an entire pin group
* @pin_config_group_set: configure all pins in a group
* @pin_config_dbg_show: optional debugfs display hook that will provide
* per-device info for a certain pin in debugfs
* @pin_config_group_dbg_show: optional debugfs display hook that will provide
* per-device info for a certain group in debugfs
*/
struct pinconf_ops {
int (*pin_config_get) (struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long *config);
int (*pin_config_set) (struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long config);
int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long *config);
int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long config);
void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned offset);
void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned selector);
};
extern int pin_config_get(const char *dev_name, const char *name,
unsigned long *config);
extern int pin_config_set(const char *dev_name, const char *name,
unsigned long config);
extern int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config);
extern int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config);
#else
static inline int pin_config_get(const char *dev_name, const char *name,
unsigned long *config)
{
return 0;
}
static inline int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
return 0;
}
static inline int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config)
{
return 0;
}
static inline int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config)
{
return 0;
}
#endif
#endif /* __LINUX_PINCTRL_PINCONF_H */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
struct pinctrl_dev; struct pinctrl_dev;
struct pinmux_ops; struct pinmux_ops;
struct pinconf_ops;
struct gpio_chip; struct gpio_chip;
/** /**
...@@ -45,6 +46,7 @@ struct pinctrl_pin_desc { ...@@ -45,6 +46,7 @@ struct pinctrl_pin_desc {
* @name: a name for the chip in this range * @name: a name for the chip in this range
* @id: an ID number for the chip in this range * @id: an ID number for the chip in this range
* @base: base offset of the GPIO range * @base: base offset of the GPIO range
* @pin_base: base pin number of the GPIO range
* @npins: number of pins in the GPIO range, including the base number * @npins: number of pins in the GPIO range, including the base number
* @gc: an optional pointer to a gpio_chip * @gc: an optional pointer to a gpio_chip
*/ */
...@@ -53,6 +55,7 @@ struct pinctrl_gpio_range { ...@@ -53,6 +55,7 @@ struct pinctrl_gpio_range {
const char *name; const char *name;
unsigned int id; unsigned int id;
unsigned int base; unsigned int base;
unsigned int pin_base;
unsigned int npins; unsigned int npins;
struct gpio_chip *gc; struct gpio_chip *gc;
}; };
...@@ -89,22 +92,20 @@ struct pinctrl_ops { ...@@ -89,22 +92,20 @@ struct pinctrl_ops {
* this pin controller * this pin controller
* @npins: number of descriptors in the array, usually just ARRAY_SIZE() * @npins: number of descriptors in the array, usually just ARRAY_SIZE()
* of the pins field above * of the pins field above
* @maxpin: since pin spaces may be sparse, there can he "holes" in the
* pin range, this attribute gives the maximum pin number in the
* total range. This should not be lower than npins for example,
* but may be equal to npins if you have no holes in the pin range.
* @pctlops: pin control operation vtable, to support global concepts like * @pctlops: pin control operation vtable, to support global concepts like
* grouping of pins, this is optional. * grouping of pins, this is optional.
* @pmxops: pinmux operation vtable, if you support pinmuxing in your driver * @pmxops: pinmux operations vtable, if you support pinmuxing in your driver
* @confops: pin config operations vtable, if you support pin configuration in
* your driver
* @owner: module providing the pin controller, used for refcounting * @owner: module providing the pin controller, used for refcounting
*/ */
struct pinctrl_desc { struct pinctrl_desc {
const char *name; const char *name;
struct pinctrl_pin_desc const *pins; struct pinctrl_pin_desc const *pins;
unsigned int npins; unsigned int npins;
unsigned int maxpin;
struct pinctrl_ops *pctlops; struct pinctrl_ops *pctlops;
struct pinmux_ops *pmxops; struct pinmux_ops *pmxops;
struct pinconf_ops *confops;
struct module *owner; struct module *owner;
}; };
...@@ -123,7 +124,7 @@ extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); ...@@ -123,7 +124,7 @@ extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
struct pinctrl_dev; struct pinctrl_dev;
/* Sufficiently stupid default function when pinctrl is not in use */ /* Sufficiently stupid default functions when pinctrl is not in use */
static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
{ {
return pin >= 0; return pin >= 0;
......
...@@ -52,9 +52,15 @@ struct pinctrl_dev; ...@@ -52,9 +52,15 @@ struct pinctrl_dev;
* @disable: disable a certain muxing selector with a certain pin group * @disable: disable a certain muxing selector with a certain pin group
* @gpio_request_enable: requests and enables GPIO on a certain pin. * @gpio_request_enable: requests and enables GPIO on a certain pin.
* Implement this only if you can mux every pin individually as GPIO. The * Implement this only if you can mux every pin individually as GPIO. The
* affected GPIO range is passed along with an offset into that * affected GPIO range is passed along with an offset(pin number) into that
* specific GPIO range - function selectors and pin groups are orthogonal * specific GPIO range - function selectors and pin groups are orthogonal
* to this, the core will however make sure the pins do not collide * to this, the core will however make sure the pins do not collide.
* @gpio_disable_free: free up GPIO muxing on a certain pin, the reverse of
* @gpio_request_enable
* @gpio_set_direction: Since controllers may need different configurations
* depending on whether the GPIO is configured as input or output,
* a direction selector function may be implemented as a backing
* to the GPIO controllers that need pin muxing.
*/ */
struct pinmux_ops { struct pinmux_ops {
int (*request) (struct pinctrl_dev *pctldev, unsigned offset); int (*request) (struct pinctrl_dev *pctldev, unsigned offset);
...@@ -73,11 +79,20 @@ struct pinmux_ops { ...@@ -73,11 +79,20 @@ struct pinmux_ops {
int (*gpio_request_enable) (struct pinctrl_dev *pctldev, int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset); unsigned offset);
void (*gpio_disable_free) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset);
int (*gpio_set_direction) (struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset,
bool input);
}; };
/* External interface to pinmux */ /* External interface to pinmux */
extern int pinmux_request_gpio(unsigned gpio); extern int pinmux_request_gpio(unsigned gpio);
extern void pinmux_free_gpio(unsigned gpio); extern void pinmux_free_gpio(unsigned gpio);
extern int pinmux_gpio_direction_input(unsigned gpio);
extern int pinmux_gpio_direction_output(unsigned gpio);
extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name);
extern void pinmux_put(struct pinmux *pmx); extern void pinmux_put(struct pinmux *pmx);
extern int pinmux_enable(struct pinmux *pmx); extern int pinmux_enable(struct pinmux *pmx);
...@@ -94,6 +109,16 @@ static inline void pinmux_free_gpio(unsigned gpio) ...@@ -94,6 +109,16 @@ static inline void pinmux_free_gpio(unsigned gpio)
{ {
} }
static inline int pinmux_gpio_direction_input(unsigned gpio)
{
return 0;
}
static inline int pinmux_gpio_direction_output(unsigned gpio)
{
return 0;
}
static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name)
{ {
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment