Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 340128
b: refs/heads/master
c: a623f57
h: refs/heads/master
v: v3
  • Loading branch information
Olof Johansson committed Nov 23, 2012
1 parent b31918b commit c258512
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e9f6d13513ea9fd33b0184db8fc33cf51baa584b
refs/heads/master: a623f57c38eecb4069f61ea523bdc2641cd56124
50 changes: 50 additions & 0 deletions trunk/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 trunk/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
7 changes: 7 additions & 0 deletions trunk/drivers/gpio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,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 Down
1 change: 1 addition & 0 deletions trunk/drivers/gpio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,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 Down
6 changes: 3 additions & 3 deletions trunk/drivers/gpio/gpio-em.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ static int __devinit em_gio_probe(struct platform_device *pdev)
p->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
pdata->number_of_pins,
&em_gio_irq_domain_ops, p);
if (!p->irq_domain)
err = -ENXIO;
if (!p->irq_domain) {
ret = -ENXIO;
dev_err(&pdev->dev, "cannot initialize irq domain\n");
goto err3;
}
Expand Down Expand Up @@ -358,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev)

free_irq(irq[1]->start, pdev);
free_irq(irq[0]->start, pdev);
em_gio_irq_domain_cleanup(p);
irq_domain_remove(p->irq_domain);
iounmap(p->base1);
iounmap(p->base0);
kfree(p);
Expand Down
12 changes: 6 additions & 6 deletions trunk/drivers/gpio/gpio-max730x.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,26 +167,26 @@ int __devinit __max730x_probe(struct max7301 *ts)
int i, ret;

pdata = dev->platform_data;
if (!pdata || !pdata->base) {
dev_err(dev, "incorrect or missing platform data\n");
return -EINVAL;
}

mutex_init(&ts->lock);
dev_set_drvdata(dev, ts);

/* Power up the chip and disable IRQ output */
ts->write(dev, 0x04, 0x01);

ts->input_pullup_active = pdata->input_pullup_active;
if (pdata) {
ts->input_pullup_active = pdata->input_pullup_active;
ts->chip.base = pdata->base;
} else {
ts->chip.base = -1;
}
ts->chip.label = dev->driver->name;

ts->chip.direction_input = max7301_direction_input;
ts->chip.get = max7301_get;
ts->chip.direction_output = max7301_direction_output;
ts->chip.set = max7301_set;

ts->chip.base = pdata->base;
ts->chip.ngpio = PIN_NUMBER;
ts->chip.can_sleep = 1;
ts->chip.dev = dev;
Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/gpio/gpio-mvebu.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
* Functions implementing the gpio_chip methods
*/

int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
{
return pinctrl_request_gpio(chip->base + pin);
}

void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
{
pinctrl_free_gpio(chip->base + pin);
}
Expand Down Expand Up @@ -523,6 +523,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
mvchip->chip.request = mvebu_gpio_request;
mvchip->chip.free = mvebu_gpio_free;
mvchip->chip.direction_input = mvebu_gpio_direction_input;
mvchip->chip.get = mvebu_gpio_get;
mvchip->chip.direction_output = mvebu_gpio_direction_output;
Expand Down
55 changes: 49 additions & 6 deletions trunk/drivers/gpio/gpio-pca953x.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -83,6 +84,7 @@ struct pca953x_chip {
u32 irq_trig_raise;
u32 irq_trig_fall;
int irq_base;
struct irq_domain *domain;
#endif

struct i2c_client *client;
Expand Down Expand Up @@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);

chip->irq_mask &= ~(1 << (d->irq - chip->irq_base));
chip->irq_mask &= ~(1 << d->hwirq);
}

static void pca953x_irq_unmask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);

chip->irq_mask |= 1 << (d->irq - chip->irq_base);
chip->irq_mask |= 1 << d->hwirq;
}

static void pca953x_irq_bus_lock(struct irq_data *d)
Expand Down Expand Up @@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
u32 level = d->irq - chip->irq_base;
u32 mask = 1 << level;
u32 mask = 1 << d->hwirq;

if (!(type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
Expand Down Expand Up @@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)

do {
level = __ffs(pending);
handle_nested_irq(level + chip->irq_base);
handle_nested_irq(irq_find_mapping(chip->domain, level));

pending &= ~(1 << level);
} while (pending);
Expand Down Expand Up @@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
if (chip->irq_base < 0)
goto out_failed;

chip->domain = irq_domain_add_legacy(client->dev.of_node,
chip->gpio_chip.ngpio,
chip->irq_base,
0,
&irq_domain_simple_ops,
NULL);
if (!chip->domain) {
ret = -ENODEV;
goto out_irqdesc_free;
}

for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
int irq = lvl + chip->irq_base;

Expand All @@ -521,14 +533,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
if (ret) {
dev_err(&client->dev, "failed to request irq %d\n",
client->irq);
goto out_failed;
goto out_irqdesc_free;
}

chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
}

return 0;

out_irqdesc_free:
irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
out_failed:
chip->irq_base = -1;
return ret;
Expand Down Expand Up @@ -751,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client)
return 0;
}

static const struct of_device_id pca953x_dt_ids[] = {
{ .compatible = "nxp,pca9534", },
{ .compatible = "nxp,pca9535", },
{ .compatible = "nxp,pca9536", },
{ .compatible = "nxp,pca9537", },
{ .compatible = "nxp,pca9538", },
{ .compatible = "nxp,pca9539", },
{ .compatible = "nxp,pca9554", },
{ .compatible = "nxp,pca9555", },
{ .compatible = "nxp,pca9556", },
{ .compatible = "nxp,pca9557", },
{ .compatible = "nxp,pca9574", },
{ .compatible = "nxp,pca9575", },

{ .compatible = "maxim,max7310", },
{ .compatible = "maxim,max7312", },
{ .compatible = "maxim,max7313", },
{ .compatible = "maxim,max7315", },

{ .compatible = "ti,pca6107", },
{ .compatible = "ti,tca6408", },
{ .compatible = "ti,tca6416", },
{ .compatible = "ti,tca6424", },
{ }
};

MODULE_DEVICE_TABLE(of, pca953x_dt_ids);

static struct i2c_driver pca953x_driver = {
.driver = {
.name = "pca953x",
.of_match_table = pca953x_dt_ids,
},
.probe = pca953x_probe,
.remove = pca953x_remove,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/gpio/gpio-pch.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ static void pch_gpio_setup(struct pch_gpio *chip)
struct gpio_chip *gpio = &chip->gpio;

gpio->label = dev_name(chip->dev);
gpio->dev = chip->dev;
gpio->owner = THIS_MODULE;
gpio->direction_input = pch_gpio_direction_input;
gpio->get = pch_gpio_get;
Expand Down
Loading

0 comments on commit c258512

Please sign in to comment.