Skip to content

Commit

Permalink
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6
Browse files Browse the repository at this point in the history
Pull GPIO changes for v3.4 from Grant Likely:
 "Primarily gpio device driver changes with some minor side effects
  under arch/arm and arch/x86.  Also includes a few core changes such as
  explicitly supporting (electrical) open source and open drain outputs
  and some help for parsing gpio devicetree properties."

Fix up context conflict due to Laxman Dewangan adding sleep control for
the tps65910 driver separately for gpio's and regulators.

* tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits)
  gpio/ep93xx: Remove unused inline function and useless pr_err message
  gpio/sodaville: Mark broken due to core irqdomain migration
  gpio/omap: fix redundant decoding of gpio offset
  gpio/omap: fix incorrect update to context.irqenable1
  gpio/omap: fix incorrect context restore logic in omap_gpio_runtime_*
  gpio/omap: fix missing dataout context save in _set_gpio_dataout_reg
  gpio/omap: fix _set_gpio_irqenable implementation
  gpio/omap: fix trigger type to unsigned
  gpio/omap: fix wakeup_en register update in _set_gpio_wakeup()
  gpio: tegra: tegra_gpio_config shouldn't be __init
  gpio/davinci: fix enabling unbanked GPIO IRQs
  gpio/davinci: fix oops on unbanked gpio irq request
  gpio/omap: Fix section warning for omap_mpuio_alloc_gc()
  ARM: tegra: export tegra_gpio_{en,dis}able
  gpio/gpio-stmpe: Fix the value returned by _get_value routine
  Documentation/gpio.txt: Explain expected pinctrl interaction
  GPIO: LPC32xx: Add output reading to GPO P3
  GPIO: LPC32xx: Fix missing bit selection mask
  gpio/omap: fix wakeups on level-triggered GPIOs
  gpio/omap: Fix IRQ handling for SPARSE_IRQ
  ...
  • Loading branch information
Linus Torvalds committed Mar 28, 2012
2 parents 30304e5 + c77c8a6 commit 7bf97e1
Show file tree
Hide file tree
Showing 23 changed files with 1,017 additions and 146 deletions.
36 changes: 36 additions & 0 deletions Documentation/devicetree/bindings/gpio/gpio-omap.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
OMAP GPIO controller bindings

Required properties:
- compatible:
- "ti,omap2-gpio" for OMAP2 controllers
- "ti,omap3-gpio" for OMAP3 controllers
- "ti,omap4-gpio" for OMAP4 controllers
- #gpio-cells : Should be two.
- first cell is the pin number
- second cell is used to specify optional parameters (unused)
- gpio-controller : Marks the device node as a GPIO controller.
- #interrupt-cells : Should be 2.
- interrupt-controller: Mark the device node as an interrupt controller
The first cell is the GPIO number.
The second cell is used to specify flags:
bits[3:0] trigger type and level flags:
1 = low-to-high edge triggered.
2 = high-to-low edge triggered.
4 = active high level-sensitive.
8 = active low level-sensitive.

OMAP specific properties:
- ti,hwmods: Name of the hwmod associated to the GPIO:
"gpio<X>", <X> being the 1-based instance number from the HW spec


Example:

gpio4: gpio4 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio4";
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
};
48 changes: 48 additions & 0 deletions Documentation/devicetree/bindings/gpio/sodaville.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
GPIO controller on CE4100 / Sodaville SoCs
==========================================

The bindings for CE4100's GPIO controller match the generic description
which is covered by the gpio.txt file in this folder.

The only additional property is the intel,muxctl property which holds the
value which is written into the MUXCNTL register.

There is no compatible property for now because the driver is probed via
PCI id (vendor 0x8086 device 0x2e67).

The interrupt specifier consists of two cells encoded as follows:
- <1st cell>: The interrupt-number that identifies the interrupt source.
- <2nd cell>: The level-sense information, encoded as follows:
4 - active high level-sensitive
8 - active low level-sensitive

Example of the GPIO device and one user:

pcigpio: gpio@b,1 {
/* two cells for GPIO and interrupt */
#gpio-cells = <2>;
#interrupt-cells = <2>;
compatible = "pci8086,2e67.2",
"pci8086,2e67",
"pciclassff0000",
"pciclassff00";

reg = <0x15900 0x0 0x0 0x0 0x0>;
/* Interrupt line of the gpio device */
interrupts = <15 1>;
/* It is an interrupt and GPIO controller itself */
interrupt-controller;
gpio-controller;
intel,muxctl = <0>;
};

testuser@20 {
compatible = "example,testuser";
/* User the 11th GPIO line as an active high triggered
* level interrupt
*/
interrupts = <11 8>;
interrupt-parent = <&pcigpio>;
/* Use this GPIO also with the gpio functions */
gpios = <&pcigpio 11 0>;
};
40 changes: 35 additions & 5 deletions Documentation/gpio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,26 @@ Some platforms may also use knowledge about what GPIOs are active for
power management, such as by powering down unused chip sectors and, more
easily, gating off unused clocks.

Note that requesting a GPIO does NOT cause it to be configured in any
way; it just marks that GPIO as in use. Separate code must handle any
pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
For GPIOs that use pins known to the pinctrl subsystem, that subsystem should
be informed of their use; a gpiolib driver's .request() operation may call
pinctrl_request_gpio(), and a gpiolib driver's .free() operation may call
pinctrl_free_gpio(). The pinctrl subsystem allows a pinctrl_request_gpio()
to succeed concurrently with a pin or pingroup being "owned" by a device for
pin multiplexing.

Any programming of pin multiplexing hardware that is needed to route the
GPIO signal to the appropriate pin should occur within a GPIO driver's
.direction_input() or .direction_output() operations, and occur after any
setup of an output GPIO's value. This allows a glitch-free migration from a
pin's special function to GPIO. This is sometimes required when using a GPIO
to implement a workaround on signals typically driven by a non-GPIO HW block.

Some platforms allow some or all GPIO signals to be routed to different pins.
Similarly, other aspects of the GPIO or pin may need to be configured, such as
pullup/pulldown. Platform software should arrange that any such details are
configured prior to gpio_request() being called for those GPIOs, e.g. using
the pinctrl subsystem's mapping table, so that GPIO users need not be aware
of these details.

Also note that it's your responsibility to have stopped using a GPIO
before you free it.
Expand Down Expand Up @@ -302,6 +319,8 @@ where 'flags' is currently defined to specify the following properties:

* GPIOF_INIT_LOW - as output, set initial level to LOW
* GPIOF_INIT_HIGH - as output, set initial level to HIGH
* GPIOF_OPEN_DRAIN - gpio pin is open drain type.
* GPIOF_OPEN_SOURCE - gpio pin is open source type.

since GPIOF_INIT_* are only valid when configured as output, so group valid
combinations as:
Expand All @@ -310,8 +329,19 @@ combinations as:
* GPIOF_OUT_INIT_LOW - configured as output, initial level LOW
* GPIOF_OUT_INIT_HIGH - configured as output, initial level HIGH

In the future, these flags can be extended to support more properties such
as open-drain status.
When setting the flag as GPIOF_OPEN_DRAIN then it will assume that pins is
open drain type. Such pins will not be driven to 1 in output mode. It is
require to connect pull-up on such pins. By enabling this flag, gpio lib will
make the direction to input when it is asked to set value of 1 in output mode
to make the pin HIGH. The pin is make to LOW by driving value 0 in output mode.

When setting the flag as GPIOF_OPEN_SOURCE then it will assume that pins is
open source type. Such pins will not be driven to 0 in output mode. It is
require to connect pull-down on such pin. By enabling this flag, gpio lib will
make the direction to input when it is asked to set value of 0 in output mode
to make the pin LOW. The pin is make to HIGH by driving value 1 in output mode.

In the future, these flags can be extended to support more properties.

Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
introduced to encapsulate all three fields as:
Expand Down
22 changes: 3 additions & 19 deletions arch/arm/plat-omap/include/plat/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,30 +218,14 @@ extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
/*-------------------------------------------------------------------------*/

/* Wrappers for "new style" GPIO calls, using the new infrastructure
/*
* Wrappers for "new style" GPIO calls, using the new infrastructure
* which lets us plug in FPGA, I2C, and other implementations.
* *
*
* The original OMAP-specific calls should eventually be removed.
*/

#include <linux/errno.h>
#include <asm-generic/gpio.h>

static inline int irq_to_gpio(unsigned irq)
{
int tmp;

/* omap1 SOC mpuio */
if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;

/* SOC gpio */
tmp = irq - IH_GPIO_BASE;
if (tmp < OMAP_MAX_GPIO_LINES)
return tmp;

/* we don't supply reverse mappings for non-SOC gpios */
return -EIO;
}

#endif
7 changes: 5 additions & 2 deletions arch/x86/platform/ce4100/falconfalls.dts
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,19 @@
interrupts = <14 1>;
};

gpio@b,1 {
pcigpio: gpio@b,1 {
#gpio-cells = <2>;
#interrupt-cells = <2>;
compatible = "pci8086,2e67.2",
"pci8086,2e67",
"pciclassff0000",
"pciclassff00";

#gpio-cells = <2>;
reg = <0x15900 0x0 0x0 0x0 0x0>;
interrupts = <15 1>;
interrupt-controller;
gpio-controller;
intel,muxctl = <0>;
};

i2c-controller@b,2 {
Expand Down
14 changes: 14 additions & 0 deletions drivers/gpio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ config GPIO_MAX732X_IRQ
Say yes here to enable the max732x to be used as an interrupt
controller. It requires the driver to be built in the kernel.

config GPIO_MC9S08DZ60
bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
depends on I2C && MACH_MX35_3DS
help
Select this to enable the MC9S08DZ60 GPIO driver

config GPIO_PCA953X
tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports"
depends on I2C
Expand Down Expand Up @@ -422,6 +428,14 @@ config GPIO_ML_IOH
Hub) which is for IVI(In-Vehicle Infotainment) use.
This driver can access the IOH's GPIO device.

config GPIO_SODAVILLE
bool "Intel Sodaville GPIO support"
depends on X86 && PCI && OF && BROKEN
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
help
Say Y here to support Intel Sodaville GPIO.

config GPIO_TIMBERDALE
bool "Support for timberdale GPIO IP"
depends on MFD_TIMBERDALE && HAS_IOMEM
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
Expand All @@ -46,6 +47,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
Expand Down
26 changes: 16 additions & 10 deletions drivers/gpio/gpio-davinci.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,16 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
return -ENODEV;
}

static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
{
struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
u32 mask = (u32) irq_data_get_irq_handler_data(d);
struct davinci_gpio_controller *d;
struct davinci_gpio_regs __iomem *g;
struct davinci_soc_info *soc_info = &davinci_soc_info;
u32 mask;

d = (struct davinci_gpio_controller *)data->handler_data;
g = (struct davinci_gpio_regs __iomem *)d->regs;
mask = __gpio_mask(data->irq - soc_info->gpio_irq);

if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
Expand Down Expand Up @@ -380,17 +386,18 @@ static int __init davinci_gpio_irq_setup(void)
* IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
*/
if (soc_info->gpio_unbanked) {
static struct irq_chip gpio_irqchip_unbanked;
static struct irq_chip_type gpio_unbanked;

/* pass "bank 0" GPIO IRQs to AINTC */
chips[0].chip.to_irq = gpio_to_irq_unbanked;
binten = BIT(0);

/* AINTC handles mask/unmask; GPIO handles triggering */
irq = bank_irq;
gpio_irqchip_unbanked = *irq_get_chip(irq);
gpio_irqchip_unbanked.name = "GPIO-AINTC";
gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
gpio_unbanked = *container_of(irq_get_chip(irq),
struct irq_chip_type, chip);
gpio_unbanked.chip.name = "GPIO-AINTC";
gpio_unbanked.chip.irq_set_type = gpio_irq_type_unbanked;

/* default trigger: both edges */
g = gpio2regs(0);
Expand All @@ -399,9 +406,8 @@ static int __init davinci_gpio_irq_setup(void)

/* set the direct IRQs up to use that irqchip */
for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
irq_set_chip(irq, &gpio_irqchip_unbanked);
irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
irq_set_chip_data(irq, (__force void *)g);
irq_set_chip(irq, &gpio_unbanked.chip);
irq_set_handler_data(irq, &chips[gpio / 32]);
irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
}

Expand Down
8 changes: 0 additions & 8 deletions drivers/gpio/gpio-ep93xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
* published by the Free Software Foundation.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
Expand Down Expand Up @@ -65,11 +63,6 @@ static void ep93xx_gpio_update_int_params(unsigned port)
EP93XX_GPIO_REG(int_en_register_offset[port]));
}

static inline void ep93xx_gpio_int_mask(unsigned line)
{
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
}

static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
{
int line = irq_to_gpio(irq);
Expand Down Expand Up @@ -212,7 +205,6 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
handler = handle_edge_irq;
break;
default:
pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
return -EINVAL;
}

Expand Down
19 changes: 18 additions & 1 deletion drivers/gpio/gpio-lpc32xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@
#define GPO3_PIN_TO_BIT(x) (1 << (x))
#define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
#define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x))
#define GPIO3_PIN_IN_SEL(x, y) ((x) >> GPIO3_PIN_IN_SHIFT(y))
#define GPIO3_PIN_IN_SEL(x, y) (((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1)
#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1)
#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
#define GPO3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)

struct gpio_regs {
void __iomem *inp_state;
void __iomem *outp_state;
void __iomem *outp_set;
void __iomem *outp_clr;
void __iomem *dir_set;
Expand Down Expand Up @@ -145,6 +147,7 @@ static struct gpio_regs gpio_grp_regs_p2 = {

static struct gpio_regs gpio_grp_regs_p3 = {
.inp_state = LPC32XX_GPIO_P3_INP_STATE,
.outp_state = LPC32XX_GPIO_P3_OUTP_STATE,
.outp_set = LPC32XX_GPIO_P3_OUTP_SET,
.outp_clr = LPC32XX_GPIO_P3_OUTP_CLR,
.dir_set = LPC32XX_GPIO_P2_DIR_SET,
Expand Down Expand Up @@ -240,6 +243,12 @@ static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
}

static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group,
unsigned pin)
{
return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin);
}

/*
* GENERIC_GPIO primitives.
*/
Expand Down Expand Up @@ -340,6 +349,13 @@ static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
__set_gpo_level_p3(group, pin, value);
}

static int lpc32xx_gpo_get_value(struct gpio_chip *chip, unsigned pin)
{
struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);

return __get_gpo_state_p3(group, pin);
}

static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
{
if (pin < chip->ngpio)
Expand Down Expand Up @@ -427,6 +443,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
.label = "gpo_p3",
.direction_output = lpc32xx_gpio_dir_out_always,
.set = lpc32xx_gpo_set_value,
.get = lpc32xx_gpo_get_value,
.request = lpc32xx_gpio_request,
.base = LPC32XX_GPO_P3_GRP,
.ngpio = LPC32XX_GPO_P3_MAX,
Expand Down
Loading

0 comments on commit 7bf97e1

Please sign in to comment.