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 updates from Grant Likely:
 "GPIO follow up patch and type change for v3.5 merge window

  Primarily device driver additions, features and bug fixes.  Not much
  touching gpio common subsystem support.  Should not be scary."

* tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits)
  gpio: Provide the STMPE GPIO driver with its own IRQ Domain
  gpio: add TS-5500 DIO blocks support
  gpio: pcf857x: use client->irq for gpio_to_irq()
  gpio: stmpe: Add DT support for stmpe gpio
  gpio: pl061 depends on ARM
  gpio/pl061: remove old comment
  gpio: SPEAr: add spi chipselect control driver
  gpio: gpio-max710x: Support device tree probing
  gpio: twl4030: Use only TWL4030_MODULE_LED for LED configuration
  gpio: tegra: read output value when gpio is set in direction_out
  gpio: pca953x: Add compatible strings to gpio-pca953x driver
  gpio: pca953x: Register an IRQ domain
  gpio: mvebu: Set free callback for gpio_chip
  gpio: tegra: Drop exporting static functions
  gpio: tegra: Staticize non-exported symbols
  gpio: tegra: fix suspend/resume apis
  gpio-pch: Set parent dev for gpio chip
  gpio: em: Fix build errors
  GPIO: clps711x: use platform_device_unregister in gpio_clps711x_init()
  gpio/tc3589x: convert to use the simple irqdomain
  ...
  • Loading branch information
torvalds committed Dec 11, 2012
2 parents bad73c5 + fc13d5a commit b0885d0
Show file tree
Hide file tree
Showing 29 changed files with 1,522 additions and 243 deletions.
18 changes: 18 additions & 0 deletions Documentation/devicetree/bindings/gpio/gpio-stmpe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
STMPE gpio
----------

Required properties:
- compatible: "st,stmpe-gpio"

Optional properties:
- st,norequest-mask: bitmask specifying which GPIOs should _not_ be requestable
due to different usage (e.g. touch, keypad)

Node name must be stmpe_gpio and should be child node of stmpe node to which it
belongs.

Example:
stmpe_gpio {
compatible = "st,stmpe-gpio";
st,norequest-mask = <0x20>; //gpio 5 can't be used
};
50 changes: 50 additions & 0 deletions Documentation/devicetree/bindings/gpio/spear_spics.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
=== ST Microelectronics SPEAr SPI CS Driver ===

SPEAr platform provides a provision to control chipselects of ARM PL022 Prime
Cell spi controller through its system registers, which otherwise remains under
PL022 control. If chipselect remain under PL022 control then they would be
released as soon as transfer is over and TxFIFO becomes empty. This is not
desired by some of the device protocols above spi which expect (multiple)
transfers without releasing their chipselects.

Chipselects can be controlled by software by turning them as GPIOs. SPEAr
provides another interface through system registers through which software can
directly control each PL022 chipselect. Hence, it is natural for SPEAr to export
the control of this interface as gpio.

Required properties:

* compatible: should be defined as "st,spear-spics-gpio"
* reg: mentioning address range of spics controller
* st-spics,peripcfg-reg: peripheral configuration register offset
* st-spics,sw-enable-bit: bit offset to enable sw control
* st-spics,cs-value-bit: bit offset to drive chipselect low or high
* st-spics,cs-enable-mask: chip select number bit mask
* st-spics,cs-enable-shift: chip select number program offset
* gpio-controller: Marks the device node as gpio controller
* #gpio-cells: should be 1 and will mention chip select number

All the above bit offsets are within peripcfg register.

Example:
-------
spics: spics@e0700000{
compatible = "st,spear-spics-gpio";
reg = <0xe0700000 0x1000>;
st-spics,peripcfg-reg = <0x3b0>;
st-spics,sw-enable-bit = <12>;
st-spics,cs-value-bit = <11>;
st-spics,cs-enable-mask = <3>;
st-spics,cs-enable-shift = <8>;
gpio-controller;
#gpio-cells = <2>;
};


spi0: spi@e0100000 {
status = "okay";
num-cs = <3>;
cs-gpios = <&gpio1 7 0>, <&spics 0>,
<&spics 1>;
...
}
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ config ARCH_CNS3XXX

config ARCH_CLPS711X
bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
select CLKDEV_LOOKUP
select COMMON_CLK
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-shmobile/board-kzm9g.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,6 @@ static struct platform_device fsi_ak4648_device = {
/* I2C */
static struct pcf857x_platform_data pcf8575_pdata = {
.gpio_base = GPIO_PCF8575_BASE,
.irq = intcs_evt2irq(0x3260), /* IRQ19 */
};

static struct i2c_board_info i2c0_devices[] = {
Expand All @@ -570,6 +569,7 @@ static struct i2c_board_info i2c1_devices[] = {
static struct i2c_board_info i2c3_devices[] = {
{
I2C_BOARD_INFO("pcf8575", 0x20),
.irq = intcs_evt2irq(0x3260), /* IRQ19 */
.platform_data = &pcf8575_pdata,
},
};
Expand Down
1 change: 1 addition & 0 deletions arch/arm/plat-spear/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ config ARCH_SPEAR13XX
bool "ST SPEAr13xx with Device Tree"
select ARM_GIC
select CPU_V7
select GPIO_SPEAR_SPICS
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select PINCTRL
Expand Down
32 changes: 31 additions & 1 deletion drivers/gpio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,26 @@ config GPIO_DA9052
help
Say yes here to enable the GPIO driver for the DA9052 chip.

config GPIO_DA9055
tristate "Dialog Semiconductor DA9055 GPIO"
depends on MFD_DA9055
help
Say yes here to enable the GPIO driver for the DA9055 chip.

The Dialog DA9055 PMIC chip has 3 GPIO pins that can be
be controller by this driver.

If driver is built as a module it will be called gpio-da9055.

config GPIO_MAX730X
tristate

comment "Memory mapped GPIO drivers:"

config GPIO_CLPS711X
def_bool y
depends on ARCH_CLPS711X

config GPIO_GENERIC_PLATFORM
tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
select GPIO_GENERIC
Expand Down Expand Up @@ -174,7 +189,7 @@ config GPIO_MXS

config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
depends on ARM && ARM_AMBA
select GENERIC_IRQ_CHIP
help
Say yes here to support the PrimeCell PL061 GPIO device
Expand All @@ -185,6 +200,13 @@ config GPIO_PXA
help
Say yes here to support the PXA GPIO device

config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
select GENERIC_IRQ_CHIP
help
Say yes here to support ST SPEAr SPI Chip Select as GPIO device

config GPIO_STA2X11
bool "STA2x11/ConneXt GPIO support"
depends on MFD_STA2X11
Expand All @@ -193,6 +215,14 @@ config GPIO_STA2X11
Say yes here to support the STA2x11/ConneXt GPIO device.
The GPIO module has 128 GPIO pins with alternate functions.

config GPIO_TS5500
tristate "TS-5500 DIO blocks and compatibles"
help
This driver supports Digital I/O exposed by pin blocks found on some
Technologic Systems platforms. It includes, but is not limited to, 3
blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
LCD port.

config GPIO_VT8500
bool "VIA/Wondermedia SoC GPIO Support"
depends on ARCH_VT8500
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
Expand Down Expand Up @@ -58,6 +60,7 @@ 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_SPEAR_SPICS) += gpio-spear-spics.o
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o
Expand All @@ -69,6 +72,7 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
Expand Down
199 changes: 199 additions & 0 deletions drivers/gpio/gpio-clps711x.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* CLPS711X GPIO driver
*
* Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/

#include <linux/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>

#include <mach/hardware.h>

#define CLPS711X_GPIO_PORTS 5
#define CLPS711X_GPIO_NAME "gpio-clps711x"

struct clps711x_gpio {
struct gpio_chip chip[CLPS711X_GPIO_PORTS];
spinlock_t lock;
};

static void __iomem *clps711x_ports[] = {
CLPS711X_VIRT_BASE + PADR,
CLPS711X_VIRT_BASE + PBDR,
CLPS711X_VIRT_BASE + PCDR,
CLPS711X_VIRT_BASE + PDDR,
CLPS711X_VIRT_BASE + PEDR,
};

static void __iomem *clps711x_pdirs[] = {
CLPS711X_VIRT_BASE + PADDR,
CLPS711X_VIRT_BASE + PBDDR,
CLPS711X_VIRT_BASE + PCDDR,
CLPS711X_VIRT_BASE + PDDDR,
CLPS711X_VIRT_BASE + PEDDR,
};

#define clps711x_port(x) clps711x_ports[x->base / 8]
#define clps711x_pdir(x) clps711x_pdirs[x->base / 8]

static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset)
{
return !!(readb(clps711x_port(chip)) & (1 << offset));
}

static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
int value)
{
int tmp;
unsigned long flags;
struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);

spin_lock_irqsave(&gpio->lock, flags);
tmp = readb(clps711x_port(chip)) & ~(1 << offset);
if (value)
tmp |= 1 << offset;
writeb(tmp, clps711x_port(chip));
spin_unlock_irqrestore(&gpio->lock, flags);
}

static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset)
{
int tmp;
unsigned long flags;
struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);

spin_lock_irqsave(&gpio->lock, flags);
tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
writeb(tmp, clps711x_pdir(chip));
spin_unlock_irqrestore(&gpio->lock, flags);

return 0;
}

static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset,
int value)
{
int tmp;
unsigned long flags;
struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);

spin_lock_irqsave(&gpio->lock, flags);
tmp = readb(clps711x_pdir(chip)) | (1 << offset);
writeb(tmp, clps711x_pdir(chip));
tmp = readb(clps711x_port(chip)) & ~(1 << offset);
if (value)
tmp |= 1 << offset;
writeb(tmp, clps711x_port(chip));
spin_unlock_irqrestore(&gpio->lock, flags);

return 0;
}

static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset)
{
int tmp;
unsigned long flags;
struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);

spin_lock_irqsave(&gpio->lock, flags);
tmp = readb(clps711x_pdir(chip)) | (1 << offset);
writeb(tmp, clps711x_pdir(chip));
spin_unlock_irqrestore(&gpio->lock, flags);

return 0;
}

static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset,
int value)
{
int tmp;
unsigned long flags;
struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);

spin_lock_irqsave(&gpio->lock, flags);
tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
writeb(tmp, clps711x_pdir(chip));
tmp = readb(clps711x_port(chip)) & ~(1 << offset);
if (value)
tmp |= 1 << offset;
writeb(tmp, clps711x_port(chip));
spin_unlock_irqrestore(&gpio->lock, flags);

return 0;
}

static struct {
char *name;
int nr;
int inv_dir;
} clps711x_gpio_ports[] __initconst = {
{ "PORTA", 8, 0, },
{ "PORTB", 8, 0, },
{ "PORTC", 8, 0, },
{ "PORTD", 8, 1, },
{ "PORTE", 3, 0, },
};

static int __init gpio_clps711x_init(void)
{
int i;
struct platform_device *pdev;
struct clps711x_gpio *gpio;

pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0);
if (!pdev) {
pr_err("Cannot create platform device: %s\n",
CLPS711X_GPIO_NAME);
return -ENOMEM;
}

platform_device_add(pdev);

gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio),
GFP_KERNEL);
if (!gpio) {
dev_err(&pdev->dev, "GPIO allocating memory error\n");
platform_device_unregister(pdev);
return -ENOMEM;
}

platform_set_drvdata(pdev, gpio);

spin_lock_init(&gpio->lock);

for (i = 0; i < CLPS711X_GPIO_PORTS; i++) {
gpio->chip[i].owner = THIS_MODULE;
gpio->chip[i].dev = &pdev->dev;
gpio->chip[i].label = clps711x_gpio_ports[i].name;
gpio->chip[i].base = i * 8;
gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr;
gpio->chip[i].get = gpio_clps711x_get;
gpio->chip[i].set = gpio_clps711x_set;
if (!clps711x_gpio_ports[i].inv_dir) {
gpio->chip[i].direction_input = gpio_clps711x_dir_in;
gpio->chip[i].direction_output = gpio_clps711x_dir_out;
} else {
gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv;
gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv;
}
WARN_ON(gpiochip_add(&gpio->chip[i]));
}

dev_info(&pdev->dev, "GPIO driver initialized\n");

return 0;
}
arch_initcall(gpio_clps711x_init);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
MODULE_DESCRIPTION("CLPS711X GPIO driver");
Loading

0 comments on commit b0885d0

Please sign in to comment.