提交 7fc86a79 编写于 作者: L Linus Torvalds

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

Pull pinctrl updates for v3.4 from Linus Walleij (*):
 - Switches the PXA 168, 910 and MMP over to use pinctrl
 - Locking revamped
 - Massive refactorings...
 - Reform the driver API to use multiple states
 - Support pin config in the mapping tables
 - Pinctrl drivers for the nVidia Tegra series
 - Generic pin config support lib for simple pin controllers
 - Implement pin config for the U300

* tag 'pinctrl-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (48 commits)
  ARM: u300: configure some pins as an example
  pinctrl: support pinconfig on the U300
  pinctrl/coh901: use generic pinconf enums and parameters
  pinctrl: introduce generic pin config
  pinctrl: fix error path in pinconf_map_to_setting()
  pinctrl: allow concurrent gpio and mux function ownership of pins
  pinctrl: forward-declare struct device
  pinctrl: split pincontrol states into its own header
  pinctrl: include machine header to core.h
  ARM: tegra: Select PINCTRL Kconfig variables
  pinctrl: add a driver for NVIDIA Tegra
  pinctrl: Show selected function and group in pinmux-pins debugfs
  pinctrl: enhance mapping table to support pin config operations
  pinctrl: API changes to support multiple states per device
  pinctrl: add usecount to pins for muxing
  pinctrl: refactor struct pinctrl handling in core.c vs pinmux.c
  pinctrl: fix and simplify locking
  pinctrl: fix the pin descriptor kerneldoc
  pinctrl: assume map table entries can't have a NULL name field
  pinctrl: introduce PINCTRL_STATE_DEFAULT, define hogs as that state
  ...

(*) What is it with all these Linuses these days? There's a Linus at
    google too.  Some day I will get myself my own broadsword, and run
    around screaming "There can be only one".

    I used to be _special_ dammit. Snif.
无相关合并请求
......@@ -206,12 +206,21 @@ 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:
Pin configuration can be programmed either using the explicit APIs described
immediately below, or by adding configuration entries into the mapping table;
see section "Board/machine configuration" below.
For example, a platform may do the following to pull up a pin to VDD:
#include <linux/pinctrl/consumer.h>
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:
The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
above, is entirely defined by the pin controller driver.
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>
......@@ -492,14 +501,10 @@ Definitions:
{"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0}
}
Every map must be assigned a symbolic name, pin controller and function.
The group is not compulsory - if it is omitted the first group presented by
the driver as applicable for the function will be selected, which is
useful for simple cases.
The device name is present in map entries tied to specific devices. Maps
without device names are referred to as SYSTEM pinmuxes, such as can be taken
by the machine implementation on boot and not tied to any specific device.
Every map must be assigned a state name, pin controller, device and
function. The group is not compulsory - if it is omitted the first group
presented by the driver as applicable for the function will be selected,
which is useful for simple cases.
It is possible to map several groups to the same combination of device,
pin controller and function. This is for cases where a certain function on
......@@ -726,19 +731,19 @@ same time.
All the above functions are mandatory to implement for a pinmux driver.
Pinmux interaction with the GPIO subsystem
==========================================
Pin control 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
The public pinmux API contains two functions named pinctrl_request_gpio()
and pinctrl_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]
gpio_free() semantics. Likewise the pinctrl_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.
controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have
that driver request proper muxing and other control for its pins.
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
......@@ -747,7 +752,7 @@ the approach to define every pin as a function.
In this case, the function array would become 64 entries for each GPIO
setting and then the device functions.
For this reason there are two functions a pinmux driver can implement
For this reason there are two functions a pin control driver can implement
to enable only GPIO on an individual pin: .gpio_request_enable() and
.gpio_disable_free().
......@@ -762,12 +767,12 @@ 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
named functions for each GPIO pin, the pinctrl_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
Board/machine configuration
==================================
Boards and machines define how a certain complete running system is put
......@@ -775,27 +780,33 @@ together, including how GPIOs and devices are muxed, how regulators are
constrained and how the clock tree looks. Of course pinmux settings are also
part of this.
A pinmux config for a machine looks pretty much like a simple regulator
configuration, so for the example array above we want to enable i2c and
spi on the second function mapping:
A pin controller configuration for a machine looks pretty much like a simple
regulator configuration, so for the example array above we want to enable i2c
and spi on the second function mapping:
#include <linux/pinctrl/machine.h>
static const struct pinmux_map __initdata pmx_mapping[] = {
static const struct pinctrl_map __initdata mapping[] = {
{
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.dev_name = "foo-spi.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "spi0",
},
{
.ctrl_dev_name = "pinctrl-foo",
.function = "i2c0",
.dev_name = "foo-i2c.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "i2c0",
},
{
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.dev_name = "foo-mmc.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "mmc0",
},
};
......@@ -805,21 +816,51 @@ must match a function provided by the pinmux driver handling this pin range.
As you can see we may have several pin controllers on the system and thus
we need to specify which one of them that contain the functions we wish
to map. The map can also use struct device * directly, so there is no
inherent need to use strings to specify .dev_name or .ctrl_dev_name, these
are for the situation where you do not have a handle to the struct device *,
for example if they are not yet instantiated or cumbersome to obtain.
to map.
You register this pinmux mapping to the pinmux subsystem by simply:
ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping));
ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping));
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-foo and position
0 for mapping, for example:
static struct pinmux_map __initdata pmx_mapping[] = {
PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, "pinctrl-foo", NULL, "i2c0"),
};
The mapping table may also contain pin configuration entries. It's common for
each pin/group to have a number of configuration entries that affect it, so
the table entries for configuration reference an array of config parameters
and values. An example using the convenience macros is shown below:
static unsigned long i2c_grp_configs[] = {
FOO_PIN_DRIVEN,
FOO_PIN_PULLUP,
};
static unsigned long i2c_pin_configs[] = {
FOO_OPEN_COLLECTOR,
FOO_SLEW_RATE_SLOW,
};
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"),
PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs),
PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs),
PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs),
};
Finally, some devices expect the mapping table to contain certain specific
named states. When running on hardware that doesn't need any pin controller
configuration, the mapping table must still contain those named states, in
order to explicitly indicate that the states were provided and intended to
be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining
a named state without causing any pin controller to be programmed:
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT),
};
......@@ -831,81 +872,96 @@ As it is possible to map a function to different groups of pins an optional
...
{
.dev_name = "foo-spi.0",
.name = "spi0-pos-A",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_0_grp",
.dev_name = "foo-spi.0",
},
{
.dev_name = "foo-spi.0",
.name = "spi0-pos-B",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_1_grp",
.dev_name = "foo-spi.0",
},
...
This example mapping is used to switch between two positions for spi0 at
runtime, as described further below under the heading "Runtime pinmuxing".
Further it is possible to match several groups of pins to the same function
for a single device, say for example in the mmc0 example above, where you can
Further it is possible for one named state to affect the muxing of several
groups of pins, say for example in the mmc0 example above, where you can
additively expand the mmc0 bus from 2 to 4 to 8 pins. If we want to use all
three groups for a total of 2+2+4 = 8 pins (for an 8-bit MMC bus as is the
case), we define a mapping like this:
...
{
.dev_name = "foo-mmc.0",
.name = "2bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_3_grp",
.dev_name = "foo-mmc.0",
},
...
The result of grabbing this mapping from the device with something like
this (see next paragraph):
pmx = pinmux_get(&device, "8bit");
p = pinctrl_get(dev);
s = pinctrl_lookup_state(p, "8bit");
ret = pinctrl_select_state(p, s);
or more simply:
p = pinctrl_get_select(dev, "8bit");
Will be that you activate all the three bottom records in the mapping at
once. Since they share the same name, pin controller device, funcion and
once. Since they share the same name, pin controller device, function and
device, and since we allow multiple groups to match to a single device, they
all get selected, and they all get enabled and disable simultaneously by the
pinmux core.
......@@ -914,97 +970,111 @@ pinmux core.
Pinmux requests from drivers
============================
Generally it is discouraged to let individual drivers get and enable pinmuxes.
So if possible, handle the pinmuxes in platform code or some other place where
you have access to all the affected struct device * pointers. In some cases
where a driver needs to switch between different mux mappings at runtime
this is not possible.
Generally it is discouraged to let individual drivers get and enable pin
control. So if possible, handle the pin control in platform code or some other
place where you have access to all the affected struct device * pointers. In
some cases where a driver needs to e.g. switch between different mux mappings
at runtime this is not possible.
A driver may request a certain mux to be activated, usually just the default
mux like this:
A driver may request a certain control state to be activated, usually just the
default state like this:
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
struct foo_state {
struct pinmux *pmx;
struct pinctrl *p;
struct pinctrl_state *s;
...
};
foo_probe()
{
/* Allocate a state holder named "state" etc */
struct pinmux pmx;
/* Allocate a state holder named "foo" etc */
struct foo_state *foo = ...;
foo->p = pinctrl_get(&device);
if (IS_ERR(foo->p)) {
/* FIXME: clean up "foo" here */
return PTR_ERR(foo->p);
}
pmx = pinmux_get(&device, NULL);
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
if (IS_ERR(foo->s)) {
pinctrl_put(foo->p);
/* FIXME: clean up "foo" here */
return PTR_ERR(s);
}
state->pmx = pmx;
ret = pinctrl_select_state(foo->s);
if (ret < 0) {
pinctrl_put(foo->p);
/* FIXME: clean up "foo" here */
return ret;
}
}
foo_remove()
{
pinmux_disable(state->pmx);
pinmux_put(state->pmx);
pinctrl_put(state->p);
}
If you want to grab a specific mux mapping and not just the first one found for
this device you can specify a specific mapping name, for example in the above
example the second i2c0 setting: pinmux_get(&device, "spi0-pos-B");
This get/enable/disable/put sequence can just as well be handled by bus drivers
This get/lookup/select/put sequence can just as well be handled by bus drivers
if you don't want each and every driver to handle it and you know the
arrangement on your bus.
The semantics of the get/enable respective disable/put is as follows:
The semantics of the pinctrl APIs are:
- pinctrl_get() is called in process context to obtain a handle to all pinctrl
information for a given client device. It will allocate a struct from the
kernel memory to hold the pinmux state. All mapping table parsing or similar
slow operations take place within this API.
- pinmux_get() is called in process context to reserve the pins affected with
a certain mapping and set up the pinmux core and the driver. It will allocate
a struct from the kernel memory to hold the pinmux state.
- pinctrl_lookup_state() is called in process context to obtain a handle to a
specific state for a the client device. This operation may be slow too.
- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath
(irq context) when you quickly want to set up/tear down the hardware muxing
when running a device driver. Usually it will just poke some values into a
register.
- pinctrl_select_state() programs pin controller hardware according to the
definition of the state as given by the mapping table. In theory this is a
fast-path operation, since it only involved blasting some register settings
into hardware. However, note that some pin controllers may have their
registers on a slow/IRQ-based bus, so client devices should not assume they
can call pinctrl_select_state() from non-blocking contexts.
- pinmux_disable() is called in process context to tear down the pin requests
and release the state holder struct for the mux setting.
- pinctrl_put() frees all information associated with a pinctrl handle.
Usually the pinmux core handled the get/put pair and call out to the device
drivers bookkeeping operations, like checking available functions and the
associated pins, whereas the enable/disable pass on to the pin controller
Usually the pin control core handled the get/put pair and call out to the
device drivers bookkeeping operations, like checking available functions and
the associated pins, whereas the enable/disable pass on to the pin controller
driver which takes care of activating and/or deactivating the mux setting by
quickly poking some registers.
The pins are allocated for your device when you issue the pinmux_get() call,
The pins are allocated for your device when you issue the pinctrl_get() call,
after this you should be able to see this in the debugfs listing of all pins.
System pinmux hogging
=====================
System pin control hogging
==========================
A system pinmux map entry, i.e. a pinmux setting that does not have a device
associated with it, can be hogged by the core when the pin controller is
registered. This means that the core will attempt to call pinmux_get() and
pinmux_enable() on it immediately after the pin control device has been
registered.
Pin control map entries can be hogged by the core when the pin controller
is registered. This means that the core will attempt to call pinctrl_get(),
lookup_state() and select_state() on it immediately after the pin control
device has been registered.
This is enabled by simply setting the .hog_on_boot field in the map to true,
like this:
This occurs for mapping table entries where the client device name is equal
to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT.
{
.name = "POWERMAP"
.dev_name = "pinctrl-foo",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "power_func",
.hog_on_boot = true,
},
Since it may be common to request the core to hog a few always-applicable
mux settings on the primary pin controller, there is a convenience macro for
this:
PINMUX_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func")
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, "power_func")
This gives the exact same result as the above construction.
......@@ -1016,32 +1086,47 @@ It is possible to mux a certain function in and out at runtime, say to move
an SPI port from one set of pins to another set of pins. Say for example for
spi0 in the example above, we expose two different groups of pins for the same
function, but with different named in the mapping as described under
"Advanced mapping" above. So we have two mappings named "spi0-pos-A" and
"spi0-pos-B".
"Advanced mapping" above. So that for an SPI device, we have two states named
"pos-A" and "pos-B".
This snippet first muxes the function in the pins defined by group A, enables
it, disables and releases it, and muxes it in on the pins defined by group B:
#include <linux/pinctrl/consumer.h>
foo_switch()
{
struct pinmux *pmx;
struct pinctrl *p;
struct pinctrl_state *s1, *s2;
/* Setup */
p = pinctrl_get(&device);
if (IS_ERR(p))
...
s1 = pinctrl_lookup_state(foo->p, "pos-A");
if (IS_ERR(s1))
...
s2 = pinctrl_lookup_state(foo->p, "pos-B");
if (IS_ERR(s2))
...
/* Enable on position A */
pmx = pinmux_get(&device, "spi0-pos-A");
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
ret = pinctrl_select_state(s1);
if (ret < 0)
...
/* This releases the pins again */
pinmux_disable(pmx);
pinmux_put(pmx);
...
/* Enable on position B */
pmx = pinmux_get(&device, "spi0-pos-B");
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
ret = pinctrl_select_state(s2);
if (ret < 0)
...
...
pinctrl_put(p);
}
The above has to be done from process context.
......@@ -7,6 +7,8 @@ config ARCH_TEGRA_2x_SOC
select CPU_V7
select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA20
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT
......@@ -19,6 +21,8 @@ config ARCH_TEGRA_3x_SOC
select CPU_V7
select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA30
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT
......
/*
* pinctrl configuration definitions for the NVIDIA Tegra pinmux
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __PINCONF_TEGRA_H__
#define __PINCONF_TEGRA_H__
enum tegra_pinconf_param {
/* argument: tegra_pinconf_pull */
TEGRA_PINCONF_PARAM_PULL,
/* argument: tegra_pinconf_tristate */
TEGRA_PINCONF_PARAM_TRISTATE,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_ENABLE_INPUT,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_OPEN_DRAIN,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_LOCK,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_IORESET,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_SCHMITT,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_LOW_POWER_MODE,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_SLEW_RATE_RISING,
};
enum tegra_pinconf_pull {
TEGRA_PINCONFIG_PULL_NONE,
TEGRA_PINCONFIG_PULL_DOWN,
TEGRA_PINCONFIG_PULL_UP,
};
enum tegra_pinconf_tristate {
TEGRA_PINCONFIG_DRIVEN,
TEGRA_PINCONFIG_TRISTATE,
};
#define TEGRA_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_))
#define TEGRA_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
#define TEGRA_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
#endif
......@@ -26,7 +26,8 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/dma-mapping.h>
#include <asm/types.h>
......@@ -1477,7 +1478,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};
static struct resource pinmux_resources[] = {
static struct resource pinctrl_resources[] = {
{
.start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1,
......@@ -1506,6 +1507,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources,
};
static struct platform_device pinctrl_device = {
.name = "pinctrl-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinctrl_resources),
.resource = pinctrl_resources,
};
/*
* The different variants have a few different versions of the
* GPIO block, with different number of ports.
......@@ -1525,6 +1533,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif
.gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE,
.pinctrl_device = &pinctrl_device,
};
static struct platform_device gpio_device = {
......@@ -1597,71 +1606,67 @@ static struct platform_device dma_device = {
},
};
static struct platform_device pinmux_device = {
.name = "pinmux-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinmux_resources),
.resource = pinmux_resources,
static unsigned long pin_pullup_conf[] = {
PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
};
/* Pinmux settings */
static struct pinmux_map __initdata u300_pinmux_map[] = {
static unsigned long pin_highz_conf[] = {
PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
};
/* Pin control settings */
static struct pinctrl_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */
PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
/* per-device maps for MMC/SD, SPI and UART */
PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
/* This pin is used for clock return rather than GPIO */
PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
pin_pullup_conf),
/* This pin is used for card detect */
PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
pin_highz_conf),
};
struct u300_mux_hog {
const char *name;
struct device *dev;
struct pinmux *pmx;
struct pinctrl *p;
};
static struct u300_mux_hog u300_mux_hogs[] = {
{
.name = "uart0",
.dev = &uart0_device.dev,
},
{
.name = "spi0",
.dev = &pl022_device.dev,
},
{
.name = "mmc0",
.dev = &mmcsd_device.dev,
},
};
static int __init u300_pinmux_fetch(void)
static int __init u300_pinctrl_fetch(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
struct pinmux *pmx;
int ret;
struct pinctrl *p;
pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
if (IS_ERR(pmx)) {
pr_err("u300: could not get pinmux hog %s\n",
u300_mux_hogs[i].name);
continue;
}
ret = pinmux_enable(pmx);
if (ret) {
pr_err("u300: could enable pinmux hog %s\n",
u300_mux_hogs[i].name);
p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
if (IS_ERR(p)) {
pr_err("u300: could not get pinmux hog for dev %s\n",
dev_name(u300_mux_hogs[i].dev));
continue;
}
u300_mux_hogs[i].pmx = pmx;
u300_mux_hogs[i].p = p;
}
return 0;
}
subsys_initcall(u300_pinmux_fetch);
subsys_initcall(u300_pinctrl_fetch);
/*
* Notice that AMBA devices are initialized before platform devices.
......@@ -1676,7 +1681,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
&pinmux_device,
};
/*
......@@ -1861,8 +1865,8 @@ void __init u300_init_devices(void)
u300_assign_physmem();
/* Initialize pinmuxing */
pinmux_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));
pinctrl_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));
/* Register subdevices on the I2C buses */
u300_i2c_register_board_devices();
......
......@@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range)
* @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
* @pinctrl_device: pin control device to spawn as child
*/
struct u300_gpio_platform {
enum u300_gpio_variant variant;
u8 ports;
int gpio_base;
int gpio_irq_base;
struct platform_device *pinctrl_device;
};
#endif /* __MACH_U300_GPIO_U300_H */
......@@ -17,21 +17,63 @@ config PINMUX
config PINCONF
bool "Support pin configuration controllers"
config GENERIC_PINCONF
bool
select PINCONF
config DEBUG_PINCTRL
bool "Debug PINCTRL calls"
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINCTRL_PXA3xx
bool
select PINMUX
config PINCTRL_MMP2
bool "MMP2 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_PXA168
bool "PXA168 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_PXA910
bool "PXA910 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_SIRF
bool "CSR SiRFprimaII pin controller driver"
depends on ARCH_PRIMA2
select PINMUX
config PINCTRL_TEGRA
bool
config PINCTRL_TEGRA20
bool
select PINMUX
select PINCONF
select PINCTRL_TEGRA
config PINCTRL_TEGRA30
bool
select PINMUX
select PINCONF
select PINCTRL_TEGRA
config PINCTRL_U300
bool "U300 pin controller driver"
depends on ARCH_U300
select PINMUX
select GENERIC_PINCONF
config PINCTRL_COH901
bool "ST-Ericsson U300 COH 901 335/571 GPIO"
......
......@@ -5,6 +5,14 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
此差异已折叠。
......@@ -9,7 +9,10 @@
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
struct pinctrl_gpio_range;
......@@ -20,34 +23,94 @@ struct pinctrl_gpio_range;
* controller
* @pin_desc_tree: each pin descriptor for this pin controller is stored in
* this radix tree
* @pin_desc_tree_lock: lock for the descriptor tree
* @gpio_ranges: a list of GPIO ranges that is handled by this pin controller,
* ranges are added to this list at runtime
* @gpio_ranges_lock: lock for the GPIO ranges list
* @dev: the device entry for this pin controller
* @owner: module providing the pin controller, used for refcounting
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
* @pinmux_hogs_lock: lock for the pinmux hog list
* @pinmux_hogs: list of pinmux maps hogged by this device
* @p: result of pinctrl_get() for this device
* @device_root: debugfs root for this device
*/
struct pinctrl_dev {
struct list_head node;
struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree;
spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges;
struct mutex gpio_ranges_lock;
struct device *dev;
struct module *owner;
void *driver_data;
struct pinctrl *p;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
#ifdef CONFIG_PINMUX
struct mutex pinmux_hogs_lock;
struct list_head pinmux_hogs;
#endif
};
/**
* struct pinctrl - per-device pin control state holder
* @node: global list node
* @dev: the device using this pin control handle
* @states: a list of states for this device
* @state: the current state
*/
struct pinctrl {
struct list_head node;
struct device *dev;
struct list_head states;
struct pinctrl_state *state;
};
/**
* struct pinctrl_state - a pinctrl state for a device
* @node: list not for struct pinctrl's @states field
* @name: the name of this state
* @settings: a list of settings for this state
*/
struct pinctrl_state {
struct list_head node;
const char *name;
struct list_head settings;
};
/**
* struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP
* @group: the group selector to program
* @func: the function selector to program
*/
struct pinctrl_setting_mux {
unsigned group;
unsigned func;
};
/**
* struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_*
* @group_or_pin: the group selector or pin ID to program
* @configs: a pointer to an array of config parameters/values to program into
* hardware. Each individual pin controller defines the format and meaning
* of config parameters.
* @num_configs: the number of entries in array @configs
*/
struct pinctrl_setting_configs {
unsigned group_or_pin;
unsigned long *configs;
unsigned num_configs;
};
/**
* struct pinctrl_setting - an individual mux or config setting
* @node: list node for struct pinctrl_settings's @settings field
* @type: the type of setting
* @pctldev: pin control device handling to be programmed
* @data: Data specific to the setting type
*/
struct pinctrl_setting {
struct list_head node;
enum pinctrl_map_type type;
struct pinctrl_dev *pctldev;
union {
struct pinctrl_setting_mux mux;
struct pinctrl_setting_configs configs;
} data;
};
/**
......@@ -56,28 +119,38 @@ struct pinctrl_dev {
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated
* @lock: a lock to protect the descriptor structure
* @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
* subdrivers and shown in debugfs etc
* @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
* If non-zero, this pin is claimed by @owner. This field is an integer
* rather than a boolean, since pinctrl_get() might process multiple
* mapping table entries that refer to, and hence claim, the same group
* or pin, and each of these will increment the @usecount.
* @mux_owner: The name of device that called pinctrl_get().
* @mux_setting: The most recent selected mux setting for this pin, if any.
* @gpio_owner: If pinctrl_request_gpio() was called for this pin, this is
* the name of the GPIO that "owns" this pin.
*/
struct pin_desc {
struct pinctrl_dev *pctldev;
const char *name;
bool dynamic_name;
spinlock_t lock;
/* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX
const char *mux_function;
unsigned mux_usecount;
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
#endif
};
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
const char *dev_name);
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange);
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group);
static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
unsigned int pin)
{
return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
}
extern struct mutex pinctrl_mutex;
/*
* Core driver for the generic 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) "generic pinconfig core: " fmt
#include <linux/kernel.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/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "pinconf.h"
#ifdef CONFIG_DEBUG_FS
struct pin_config_item {
const enum pin_config_param param;
const char * const display;
const char * const format;
};
#define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c }
struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
};
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int i;
if (!ops->is_generic)
return;
for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
unsigned long config;
int ret;
/* We want to check out this parameter */
config = pinconf_to_config_packed(conf_items[i].param, 0);
ret = pin_config_get_for_pin(pctldev, pin, &config);
/* These are legal errors */
if (ret == -EINVAL || ret == -ENOTSUPP)
continue;
if (ret) {
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
continue;
}
/* Space between multiple configs */
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format &&
pinconf_to_config_argument(config) != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
}
}
void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int i;
if (!ops->is_generic)
return;
for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
unsigned long config;
int ret;
/* We want to check out this parameter */
config = pinconf_to_config_packed(conf_items[i].param, 0);
ret = pin_config_group_get(dev_name(pctldev->dev), gname,
&config);
/* These are legal errors */
if (ret == -EINVAL || ret == -ENOTSUPP)
continue;
if (ret) {
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
continue;
}
/* Space between multiple configs */
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format && config != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
}
}
#endif
......@@ -23,6 +23,37 @@
#include "core.h"
#include "pinconf.h"
int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* 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;
}
int pinconf_validate_map(struct pinctrl_map const *map, int i)
{
if (!map->data.configs.group_or_pin) {
pr_err("failed to register map %s (%d): no group/pin given\n",
map->name, i);
return -EINVAL;
}
if (map->data.configs.num_configs &&
!map->data.configs.configs) {
pr_err("failed to register map %s (%d): no configs ptr given\n",
map->name, i);
return -EINVAL;
}
return 0;
}
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
......@@ -51,19 +82,27 @@ int pin_config_get(const char *dev_name, const char *name,
struct pinctrl_dev *pctldev;
int pin;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
pin = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
goto unlock;
pin = pin_config_get_for_pin(pctldev, pin, config);
return pin_config_get_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return pin;
}
EXPORT_SYMBOL(pin_config_get);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
......@@ -97,17 +136,27 @@ int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
struct pinctrl_dev *pctldev;
int pin;
int pin, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
if (pin < 0) {
ret = pin;
goto unlock;
}
ret = pin_config_set_for_pin(pctldev, pin, config);
return pin_config_set_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_set);
......@@ -116,29 +165,39 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
int selector;
int selector, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
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;
ret = -EINVAL;
goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
if (selector < 0) {
ret = selector;
goto unlock;
}
ret = ops->pin_config_group_get(pctldev, selector, config);
return ops->pin_config_group_get(pctldev, selector, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_group_get);
int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config)
{
......@@ -151,27 +210,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
int ret;
int i;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
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;
ret = -EINVAL;
goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
if (selector < 0) {
ret = selector;
goto unlock;
}
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;
goto unlock;
}
/*
......@@ -185,46 +251,196 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
* pin-by-pin as well, it returns -EAGAIN.
*/
if (ret != -EAGAIN)
return ret;
goto unlock;
}
/*
* If the controller cannot handle entire groups, we configure each pin
* individually.
*/
if (!ops->pin_config_set)
return 0;
if (!ops->pin_config_set) {
ret = 0;
goto unlock;
}
for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0)
return ret;
goto unlock;
}
return 0;
ret = 0;
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_group_set);
int pinconf_check_ops(struct pinctrl_dev *pctldev)
int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
int pin;
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
pin = pin_get_from_name(pctldev,
map->data.configs.group_or_pin);
if (pin < 0) {
dev_err(pctldev->dev, "could not map pin config for \"%s\"",
map->data.configs.group_or_pin);
return pin;
}
setting->data.configs.group_or_pin = pin;
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
pin = pinctrl_get_group_selector(pctldev,
map->data.configs.group_or_pin);
if (pin < 0) {
dev_err(pctldev->dev, "could not map group config for \"%s\"",
map->data.configs.group_or_pin);
return pin;
}
setting->data.configs.group_or_pin = pin;
break;
default:
return -EINVAL;
}
setting->data.configs.num_configs = map->data.configs.num_configs;
setting->data.configs.configs = map->data.configs.configs;
return 0;
}
void pinconf_free_setting(struct pinctrl_setting const *setting)
{
}
int pinconf_apply_setting(struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinconf_ops *ops = pctldev->desc->confops;
int i, ret;
/* We must be able to read out pin status */
if (!ops->pin_config_get && !ops->pin_config_group_get)
if (!ops) {
dev_err(pctldev->dev, "missing confops\n");
return -EINVAL;
/* We have to be able to config the pins in SOME way */
if (!ops->pin_config_set && !ops->pin_config_group_set)
}
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
if (!ops->pin_config_set) {
dev_err(pctldev->dev, "missing pin_config_set op\n");
return -EINVAL;
}
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_set(pctldev,
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
if (ret < 0) {
dev_err(pctldev->dev,
"pin_config_set op failed for pin %d config %08lx\n",
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
return ret;
}
}
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
if (!ops->pin_config_group_set) {
dev_err(pctldev->dev,
"missing pin_config_group_set op\n");
return -EINVAL;
}
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_group_set(pctldev,
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
if (ret < 0) {
dev_err(pctldev->dev,
"pin_config_group_set op failed for group %d config %08lx\n",
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
return ret;
}
}
break;
default:
return -EINVAL;
}
return 0;
}
#ifdef CONFIG_DEBUG_FS
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
{
int i;
switch (map->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
seq_printf(s, "pin ");
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
seq_printf(s, "group ");
break;
default:
break;
}
seq_printf(s, "%s\n", map->data.configs.group_or_pin);
for (i = 0; i < map->data.configs.num_configs; i++)
seq_printf(s, "config %08lx\n", map->data.configs.configs[i]);
}
void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
struct pin_desc *desc;
int i;
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
desc = pin_desc_get(setting->pctldev,
setting->data.configs.group_or_pin);
seq_printf(s, "pin %s (%d)",
desc->name ? desc->name : "unnamed",
setting->data.configs.group_or_pin);
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
seq_printf(s, "group %s (%d)",
pctlops->get_group_name(pctldev,
setting->data.configs.group_or_pin),
setting->data.configs.group_or_pin);
break;
default:
break;
}
/*
* FIXME: We should really get the pin controler to dump the config
* values, so they can be decoded to something meaningful.
*/
for (i = 0; i < setting->data.configs.num_configs; i++)
seq_printf(s, " %08lx", setting->data.configs.configs[i]);
seq_printf(s, "\n");
}
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, int pin)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* no-op when not using generic pin config */
pinconf_generic_dump_pin(pctldev, s, pin);
if (ops && ops->pin_config_dbg_show)
ops->pin_config_dbg_show(pctldev, s, pin);
}
......@@ -237,6 +453,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): pinmux setting array\n");
mutex_lock(&pinctrl_mutex);
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
......@@ -255,6 +473,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_printf(s, "\n");
}
mutex_unlock(&pinctrl_mutex);
return 0;
}
......@@ -264,6 +484,8 @@ static void pinconf_dump_group(struct pinctrl_dev *pctldev,
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* no-op when not using generic pin config */
pinconf_generic_dump_group(pctldev, s, gname);
if (ops && ops->pin_config_group_dbg_show)
ops->pin_config_group_dbg_show(pctldev, s, selector);
}
......@@ -281,14 +503,20 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): pinmux setting array\n");
mutex_lock(&pinctrl_mutex);
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);
seq_printf(s, "\n");
selector++;
}
mutex_unlock(&pinctrl_mutex);
return 0;
}
......
......@@ -14,12 +14,25 @@
#ifdef CONFIG_PINCONF
int pinconf_check_ops(struct pinctrl_dev *pctldev);
int pinconf_validate_map(struct pinctrl_map const *map, int i);
int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting);
void pinconf_free_setting(struct pinctrl_setting const *setting);
int pinconf_apply_setting(struct pinctrl_setting const *setting);
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map);
void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting);
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
/*
* You will only be interested in these if you're using PINCONF
* so don't supply any stubs for these.
*/
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);
int pin_config_group_get(const char *dev_name, const char *pin_group,
unsigned long *config);
#else
......@@ -28,9 +41,70 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
return 0;
}
static inline int pinconf_validate_map(struct pinctrl_map const *map, int i)
{
return 0;
}
static inline int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting)
{
return 0;
}
static inline void pinconf_free_setting(struct pinctrl_setting const *setting)
{
}
static inline int pinconf_apply_setting(struct pinctrl_setting const *setting)
{
return 0;
}
static inline void pinconf_show_map(struct seq_file *s,
struct pinctrl_map const *map)
{
}
static inline void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting)
{
}
static inline void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
}
#endif
/*
* The following functions are available if the driver uses the generic
* pin config.
*/
#ifdef CONFIG_GENERIC_PINCONF
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin);
void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname);
#else
static inline void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned pin)
{
return;
}
static inline void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s,
const char *gname)
{
return;
}
#endif
......@@ -22,38 +22,10 @@
#include <linux/gpio.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <mach/gpio-u300.h>
/*
* Bias modes for U300 GPIOs
*
* GPIO_U300_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us
* GPIO_U300_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state
* is not controlled by software
* GPIO_U300_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high
* impedance to VDD)
*/
#define GPIO_U300_CONFIG_BIAS_UNKNOWN 0x1000
#define GPIO_U300_CONFIG_BIAS_FLOAT 0x1001
#define GPIO_U300_CONFIG_BIAS_PULL_UP 0x1002
/*
* Drive modes for U300 GPIOs (output)
*
* GPIO_U300_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and
* low, this is the most typical case and is typically achieved with two
* active transistors on the output
* GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain
* (open collector) which means it is usually wired with other output
* ports which are then pulled up with an external resistor
* GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain
* (open emitter) which is the same as open drain mutatis mutandis but
* pulled to ground
*/
#define GPIO_U300_CONFIG_DRIVE_PUSH_PULL 0x2000
#define GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN 0x2001
#define GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE 0x2002
#include "pinctrl-coh901.h"
/*
* Register definitions for COH 901 335 variant
......@@ -181,12 +153,12 @@ struct u300_gpio_confdata {
#define BS365_GPIO_NUM_PORTS 5
#define U300_FLOATING_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \
.bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \
.output = false, \
}
#define U300_PULL_UP_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \
.bias_mode = PIN_CONFIG_BIAS_PULL_UP, \
.output = false, \
}
......@@ -360,14 +332,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
*/
int gpio = chip->base + offset;
return pinmux_request_gpio(gpio);
return pinctrl_request_gpio(gpio);
}
static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
pinmux_free_gpio(gpio);
pinctrl_free_gpio(gpio);
}
static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
......@@ -448,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return retirq;
}
static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
u16 param, unsigned long *data)
/* Returning -EINVAL means "supported but not available" */
int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
enum pin_config_param param = (enum pin_config_param) *config;
bool biasmode;
u32 drmode;
/* One bit per pin, clamp to bool range */
biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset));
/* Mask out the two bits for this pin and shift to bits 0,1 */
drmode = readl(U300_PIN_REG(offset, pcr));
drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1));
drmode >>= ((offset & 0x07) << 1);
switch(param) {
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
*config = 0;
if (biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
*config = 0;
if (!biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE)
return 0;
else
return -EINVAL;
break;
default:
break;
}
return -ENOTSUPP;
}
int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
unsigned long flags;
......@@ -457,16 +489,16 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
local_irq_save(flags);
switch (param) {
case GPIO_U300_CONFIG_BIAS_UNKNOWN:
case GPIO_U300_CONFIG_BIAS_FLOAT:
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
val = readl(U300_PIN_REG(offset, per));
writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break;
case GPIO_U300_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_UP:
val = readl(U300_PIN_REG(offset, per));
writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break;
case GPIO_U300_CONFIG_DRIVE_PUSH_PULL:
case PIN_CONFIG_DRIVE_PUSH_PULL:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
......@@ -474,7 +506,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr));
break;
case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN:
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
......@@ -482,7 +514,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr));
break;
case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE:
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
......@@ -650,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_direction_output(&gpio->chip, offset, conf->outval);
/* Deactivate bias mode for output */
u300_gpio_config(&gpio->chip, offset,
GPIO_U300_CONFIG_BIAS_FLOAT,
NULL);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE);
/* Set drive mode for output */
u300_gpio_config(&gpio->chip, offset,
GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_DRIVE_PUSH_PULL);
dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
offset, conf->outval);
......@@ -667,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_set(&gpio->chip, offset, 0);
/* Set bias mode for input */
u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL);
u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode);
dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n",
offset, conf->bias_mode);
......@@ -705,7 +736,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
free_irq(port->irq, port);
kfree(port);
}
}
......@@ -861,10 +891,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip;
}
/* Spawn pin controller device as child of the GPIO, pass gpio chip */
plat->pinctrl_device->dev.platform_data = &gpio->chip;
err = platform_device_register(plat->pinctrl_device);
if (err)
goto err_no_pinctrl;
platform_set_drvdata(pdev, gpio);
return 0;
err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip:
err_no_port:
u300_gpio_free_ports(gpio);
......@@ -919,7 +957,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove),
};
static int __init u300_gpio_init(void)
{
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
......
int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config);
int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param);
此差异已折叠。
此差异已折叠。
/*
* linux/drivers/pinctrl/pinctrl-pxa3xx.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "pinctrl-pxa3xx.h"
static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
.name = "PXA3xx GPIO",
.id = 0,
.base = 0,
.pin_base = 0,
};
static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return -EINVAL;
return 0;
}
static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
unsigned selector)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return NULL;
return info->grps[selector].name;
}
static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
unsigned selector,
const unsigned **pins,
unsigned *num_pins)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return -EINVAL;
*pins = info->grps[selector].pins;
*num_pins = info->grps[selector].npins;
return 0;
}
static struct pinctrl_ops pxa3xx_pctrl_ops = {
.list_groups = pxa3xx_list_groups,
.get_group_name = pxa3xx_get_group_name,
.get_group_pins = pxa3xx_get_group_pins,
};
static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (func >= info->num_funcs)
return -EINVAL;
return 0;
}
static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
unsigned func)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
return info->funcs[func].name;
}
static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
const char * const **groups,
unsigned * const num_groups)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
*groups = info->funcs[func].groups;
*num_groups = info->funcs[func].num_groups;
return 0;
}
/* Return function number. If failure, return negative value. */
static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
{
int i;
for (i = 0; i < PXA3xx_MAX_MUX; i++) {
if (mfp->func[i] == mux)
break;
}
if (i >= PXA3xx_MAX_MUX)
return -EINVAL;
return i;
}
/* check whether current pin configuration is valid. Negative for failure */
static int match_group_mux(struct pxa3xx_pin_group *grp,
struct pxa3xx_pinmux_info *info,
unsigned mux)
{
int i, pin, ret = 0;
for (i = 0; i < grp->npins; i++) {
pin = grp->pins[i];
ret = match_mux(&info->mfp[pin], mux);
if (ret < 0) {
dev_err(info->dev, "Can't find mux %d on pin%d\n",
mux, pin);
break;
}
}
return ret;
}
static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
unsigned group)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
struct pxa3xx_pin_group *pin_grp = &info->grps[group];
unsigned int data;
int i, mfpr, pin, pin_func;
if (!pin_grp->npins ||
(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
dev_err(info->dev, "Failed to set the pin group: %d\n", group);
return -EINVAL;
}
for (i = 0; i < pin_grp->npins; i++) {
pin = pin_grp->pins[i];
pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
mfpr = info->mfp[pin].mfpr;
data = readl_relaxed(info->virt_base + mfpr);
data &= ~MFPR_FUNC_MASK;
data |= pin_func;
writel_relaxed(data, info->virt_base + mfpr);
}
return 0;
}
static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
unsigned group)
{
}
static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
struct pinctrl_gpio_range *range,
unsigned pin)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
unsigned int data;
int pin_func, mfpr;
pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
if (pin_func < 0) {
dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
pin, info->pads[pin].name);
return -EINVAL;
}
mfpr = info->mfp[pin].mfpr;
/* write gpio function into mfpr register */
data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
data |= pin_func;
writel_relaxed(data, info->virt_base + mfpr);
return 0;
}
static struct pinmux_ops pxa3xx_pmx_ops = {
.list_functions = pxa3xx_pmx_list_func,
.get_function_name = pxa3xx_pmx_get_func_name,
.get_function_groups = pxa3xx_pmx_get_groups,
.enable = pxa3xx_pmx_enable,
.disable = pxa3xx_pmx_disable,
.gpio_request_enable = pxa3xx_pmx_request_gpio,
};
int pxa3xx_pinctrl_register(struct platform_device *pdev,
struct pxa3xx_pinmux_info *info)
{
struct pinctrl_desc *desc;
struct resource *res;
int ret = 0;
if (!info || !info->cputype)
return -EINVAL;
desc = info->desc;
desc->pins = info->pads;
desc->npins = info->num_pads;
desc->pctlops = &pxa3xx_pctrl_ops;
desc->pmxops = &pxa3xx_pmx_ops;
info->dev = &pdev->dev;
pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
info->phy_base = res->start;
info->phy_size = resource_size(res);
info->virt_base = ioremap(info->phy_base, info->phy_size);
if (!info->virt_base)
return -ENOMEM;
info->pctrl = pinctrl_register(desc, &pdev->dev, info);
if (!info->pctrl) {
dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
ret = -EINVAL;
goto err;
}
pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
platform_set_drvdata(pdev, info);
return 0;
err:
iounmap(info->virt_base);
return ret;
}
int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
{
struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
pinctrl_unregister(info->pctrl);
iounmap(info->virt_base);
platform_set_drvdata(pdev, NULL);
return 0;
}
static int __init pxa3xx_pinctrl_init(void)
{
pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
return 0;
}
core_initcall_sync(pxa3xx_pinctrl_init);
static void __exit pxa3xx_pinctrl_exit(void)
{
}
module_exit(pxa3xx_pinctrl_exit);
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("PXA3xx pin control driver");
MODULE_LICENSE("GPL v2");
/*
* linux/drivers/pinctrl/pinctrl-pxa3xx.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#ifndef __PINCTRL_PXA3XX_H
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
#define PXA3xx_MUX_GPIO 0
#define PXA3xx_MAX_MUX 8
#define MFPR_FUNC_MASK 0x7
enum pxa_cpu_type {
PINCTRL_INVALID = 0,
PINCTRL_PXA300,
PINCTRL_PXA310,
PINCTRL_PXA320,
PINCTRL_PXA168,
PINCTRL_PXA910,
PINCTRL_PXA930,
PINCTRL_PXA955,
PINCTRL_MMP2,
PINCTRL_MAX,
};
struct pxa3xx_mfp_pin {
const char *name;
const unsigned int pin;
const unsigned int mfpr; /* register offset */
const unsigned short func[8];
};
struct pxa3xx_pin_group {
const char *name;
const unsigned mux;
const unsigned *pins;
const unsigned npins;
};
struct pxa3xx_pmx_func {
const char *name;
const char * const * groups;
const unsigned num_groups;
};
struct pxa3xx_pinmux_info {
struct device *dev;
struct pinctrl_dev *pctrl;
enum pxa_cpu_type cputype;
unsigned int phy_base;
unsigned int phy_size;
void __iomem *virt_base;
struct pxa3xx_mfp_pin *mfp;
unsigned int num_mfp;
struct pxa3xx_pin_group *grps;
unsigned int num_grps;
struct pxa3xx_pmx_func *funcs;
unsigned int num_funcs;
unsigned int num_gpio;
struct pinctrl_desc *desc;
struct pinctrl_pin_desc *pads;
unsigned int num_pads;
unsigned ds_mask; /* drive strength mask */
unsigned ds_shift; /* drive strength shift */
unsigned slp_mask; /* sleep mask */
unsigned slp_input_low;
unsigned slp_input_high;
unsigned slp_output_low;
unsigned slp_output_high;
unsigned slp_float;
};
enum pxa3xx_pin_list {
GPIO0 = 0,
GPIO1,
GPIO2,
GPIO3,
GPIO4,
GPIO5,
GPIO6,
GPIO7,
GPIO8,
GPIO9,
GPIO10, /* 10 */
GPIO11,
GPIO12,
GPIO13,
GPIO14,
GPIO15,
GPIO16,
GPIO17,
GPIO18,
GPIO19,
GPIO20, /* 20 */
GPIO21,
GPIO22,
GPIO23,
GPIO24,
GPIO25,
GPIO26,
GPIO27,
GPIO28,
GPIO29,
GPIO30, /* 30 */
GPIO31,
GPIO32,
GPIO33,
GPIO34,
GPIO35,
GPIO36,
GPIO37,
GPIO38,
GPIO39,
GPIO40, /* 40 */
GPIO41,
GPIO42,
GPIO43,
GPIO44,
GPIO45,
GPIO46,
GPIO47,
GPIO48,
GPIO49,
GPIO50, /* 50 */
GPIO51,
GPIO52,
GPIO53,
GPIO54,
GPIO55,
GPIO56,
GPIO57,
GPIO58,
GPIO59,
GPIO60, /* 60 */
GPIO61,
GPIO62,
GPIO63,
GPIO64,
GPIO65,
GPIO66,
GPIO67,
GPIO68,
GPIO69,
GPIO70, /* 70 */
GPIO71,
GPIO72,
GPIO73,
GPIO74,
GPIO75,
GPIO76,
GPIO77,
GPIO78,
GPIO79,
GPIO80, /* 80 */
GPIO81,
GPIO82,
GPIO83,
GPIO84,
GPIO85,
GPIO86,
GPIO87,
GPIO88,
GPIO89,
GPIO90, /* 90 */
GPIO91,
GPIO92,
GPIO93,
GPIO94,
GPIO95,
GPIO96,
GPIO97,
GPIO98,
GPIO99,
GPIO100, /* 100 */
GPIO101,
GPIO102,
GPIO103,
GPIO104,
GPIO105,
GPIO106,
GPIO107,
GPIO108,
GPIO109,
GPIO110, /* 110 */
GPIO111,
GPIO112,
GPIO113,
GPIO114,
GPIO115,
GPIO116,
GPIO117,
GPIO118,
GPIO119,
GPIO120, /* 120 */
GPIO121,
GPIO122,
GPIO123,
GPIO124,
GPIO125,
GPIO126,
GPIO127,
GPIO128,
GPIO129,
GPIO130, /* 130 */
GPIO131,
GPIO132,
GPIO133,
GPIO134,
GPIO135,
GPIO136,
GPIO137,
GPIO138,
GPIO139,
GPIO140, /* 140 */
GPIO141,
GPIO142,
GPIO143,
GPIO144,
GPIO145,
GPIO146,
GPIO147,
GPIO148,
GPIO149,
GPIO150, /* 150 */
GPIO151,
GPIO152,
GPIO153,
GPIO154,
GPIO155,
GPIO156,
GPIO157,
GPIO158,
GPIO159,
GPIO160, /* 160 */
GPIO161,
GPIO162,
GPIO163,
GPIO164,
GPIO165,
GPIO166,
GPIO167,
GPIO168,
GPIO169,
};
extern int pxa3xx_pinctrl_register(struct platform_device *pdev,
struct pxa3xx_pinmux_info *info);
extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev);
#endif /* __PINCTRL_PXA3XX_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -19,6 +19,9 @@
#include <linux/err.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "pinctrl-coh901.h"
/*
* Register definitions for the U300 Padmux control registers in the
......@@ -162,7 +165,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200
#define DRIVER_NAME "pinmux-u300"
#define DRIVER_NAME "pinctrl-u300"
/*
* The DB3350 has 467 pads, I have enumerated the pads clockwise around the
......@@ -1044,22 +1047,82 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
U300_GPIO_RANGE(25, 181, 1),
};
static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
{
int i;
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
struct pinctrl_gpio_range *range;
range = &u300_gpio_ranges[i];
if (pin >= range->pin_base &&
pin <= (range->pin_base + range->npins - 1))
return range;
}
return NULL;
}
int u300_pin_config_get(struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long *config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
/* We get config for those pins we CAN get it for and that's it */
if (!range)
return -ENOTSUPP;
return u300_gpio_config_get(range->gc,
(pin - range->pin_base + range->base),
config);
}
int u300_pin_config_set(struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
int ret;
if (!range)
return -EINVAL;
/* Note: none of these configurations take any argument */
ret = u300_gpio_config_set(range->gc,
(pin - range->pin_base + range->base),
pinconf_to_config_param(config));
if (ret)
return ret;
return 0;
}
static struct pinconf_ops u300_pconf_ops = {
.is_generic = true,
.pin_config_get = u300_pin_config_get,
.pin_config_set = u300_pin_config_set,
};
static struct pinctrl_desc u300_pmx_desc = {
.name = DRIVER_NAME,
.pins = u300_pads,
.npins = ARRAY_SIZE(u300_pads),
.pctlops = &u300_pctrl_ops,
.pmxops = &u300_pmx_ops,
.confops = &u300_pconf_ops,
.owner = THIS_MODULE,
};
static int __init u300_pmx_probe(struct platform_device *pdev)
static int __devinit u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret;
int i;
pr_err("U300 PMX PROBE\n");
/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx)
......@@ -1095,12 +1158,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
}
/* We will handle a range of GPIO pins */
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
u300_gpio_ranges[i].gc = gpio_chip;
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
}
platform_set_drvdata(pdev, upmx);
dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
dev_info(&pdev->dev, "initialized U300 pin control driver\n");
return 0;
......@@ -1115,7 +1180,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
return ret;
}
static int __exit u300_pmx_remove(struct platform_device *pdev)
static int __devexit u300_pmx_remove(struct platform_device *pdev)
{
struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i;
......@@ -1136,12 +1201,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.remove = __exit_p(u300_pmx_remove),
.probe = u300_pmx_probe,
.remove = __devexit_p(u300_pmx_remove),
};
static int __init u300_pmx_init(void)
{
return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
return platform_driver_register(&u300_pmx_driver);
}
arch_initcall(u300_pmx_init);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -162,7 +162,7 @@ struct sirfsoc_uart_port {
unsigned char ms_enabled;
struct uart_port port;
struct pinmux *pmx;
struct pinctrl *p;
};
/* Hardware Flow Control */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部