All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/5] pinctrl: SPEAr Updates
@ 2012-05-08  3:40 Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 1/5] pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable Viresh Kumar
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

This patchset mainly focuses on providing support to configure SPEAr pads as
gpios. For this i have added a gpiolib based driver and few changes in other
SPEAr pinctrl drivers.

It also contains minor fixes.

V2->V3:
- Created Macros for spear_gpio_pingroups as suggested by Linus and Arnd.
- Included Acked-by from Linus

V1->V2:
- Passing gpio node via DT. Patch for this support in gpiolib is
  gpiolib: Add of_get_gpio_chip_by_phandle() helper
- Other minor fixes

Viresh Kumar (5):
  pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable
  pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res
  pinctrl: SPEAr: Add plgpio driver
  pinctrl: SPEAr: Add gpio ranges support
  SPEAr: Add plgpio node in device tree dtsi files

 arch/arm/boot/dts/spear1310-evb.dts       |    4 +
 arch/arm/boot/dts/spear1310.dtsi          |   22 +
 arch/arm/boot/dts/spear1340-evb.dts       |    4 +
 arch/arm/boot/dts/spear1340.dtsi          |   21 +
 arch/arm/boot/dts/spear310-evb.dts        |    4 +
 arch/arm/boot/dts/spear310.dtsi           |   15 +
 arch/arm/boot/dts/spear320-evb.dts        |    4 +
 arch/arm/boot/dts/spear320.dtsi           |   16 +
 drivers/pinctrl/spear/Kconfig             |   11 +
 drivers/pinctrl/spear/Makefile            |    1 +
 drivers/pinctrl/spear/pinctrl-plgpio.c    |  738 +++++++++++++++++++++++++++++
 drivers/pinctrl/spear/pinctrl-spear.c     |  110 ++++-
 drivers/pinctrl/spear/pinctrl-spear.h     |   26 +
 drivers/pinctrl/spear/pinctrl-spear1310.c |  182 +++++++-
 drivers/pinctrl/spear/pinctrl-spear1340.c |    8 +
 drivers/pinctrl/spear/pinctrl-spear300.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear310.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear320.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear3xx.c  |   29 ++
 19 files changed, 1188 insertions(+), 13 deletions(-)
 create mode 100644 drivers/pinctrl/spear/pinctrl-plgpio.c

-- 
1.7.9

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH V3 1/5] pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
@ 2012-05-08  3:40 ` Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 2/5] pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res Viresh Kumar
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/spear/pinctrl-spear.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 5ae50aa..8653569 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
 			else
 				temp = ~muxreg->val;
 
-			val |= temp;
+			val |= muxreg->mask & temp;
 			pmx_writel(pmx, val, muxreg->reg);
 		}
 	}
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V3 2/5] pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 1/5] pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable Viresh Kumar
@ 2012-05-08  3:40 ` Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 3/5] pinctrl: SPEAr: Add plgpio driver Viresh Kumar
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/spear/pinctrl-spear1310.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index 12b094d..fff168b 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -437,7 +437,7 @@ static struct spear_pingroup clcd_pingroup = {
 };
 
 static const unsigned clcd_high_res_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37,
-	38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 };
+	38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
 static struct spear_muxreg clcd_high_res_muxreg[] = {
 	{
 		.reg = PAD_FUNCTION_EN_1,
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V3 3/5] pinctrl: SPEAr: Add plgpio driver
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 1/5] pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 2/5] pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res Viresh Kumar
@ 2012-05-08  3:40 ` Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 4/5] pinctrl: SPEAr: Add gpio ranges support Viresh Kumar
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Most of SPEAr SoCs, which support pinctrl, can configure & use pads as gpio.
This patch adds plgpio driver for configuring these pads as gpio.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/spear/Kconfig          |    7 +
 drivers/pinctrl/spear/Makefile         |    1 +
 drivers/pinctrl/spear/pinctrl-plgpio.c |  738 ++++++++++++++++++++++++++++++++
 3 files changed, 746 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pinctrl/spear/pinctrl-plgpio.c

diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 91558791..6f9a1e8 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -41,4 +41,11 @@ config PINCTRL_SPEAR1340
 	depends on MACH_SPEAR1340
 	select PINCTRL_SPEAR
 
+config PINCTRL_SPEAR_PLGPIO
+	bool "SPEAr SoC PLGPIO Controller"
+	depends on GPIOLIB && PINCTRL_SPEAR
+	help
+	  Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
+	  SoCs.
+
 endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
index b28a7ba..0e400eb 100644
--- a/drivers/pinctrl/spear/Makefile
+++ b/drivers/pinctrl/spear/Makefile
@@ -1,5 +1,6 @@
 # SPEAr pinmux support
 
+obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO)	+= pinctrl-plgpio.o
 obj-$(CONFIG_PINCTRL_SPEAR)	+= pinctrl-spear.o
 obj-$(CONFIG_PINCTRL_SPEAR3XX)	+= pinctrl-spear3xx.o
 obj-$(CONFIG_PINCTRL_SPEAR300)	+= pinctrl-spear300.o
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
new file mode 100644
index 0000000..f016e14
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -0,0 +1,738 @@
+/*
+ * SPEAr platform PLGPIO driver
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spinlock.h>
+#include <asm/mach/irq.h>
+
+#define MAX_GPIO_PER_REG		32
+#define PIN_OFFSET(pin)			(pin % MAX_GPIO_PER_REG)
+#define REG_OFFSET(base, reg, pin)	(base + reg + (pin / MAX_GPIO_PER_REG) \
+							* sizeof(int *))
+
+/*
+ * plgpio pins in all machines are not one to one mapped, bitwise with registers
+ * bits. These set of macros define register masks for which below functions
+ * (pin_to_offset and offset_to_pin) are required to be called.
+ */
+#define PTO_ENB_REG		0x001
+#define PTO_WDATA_REG		0x002
+#define PTO_DIR_REG		0x004
+#define PTO_IE_REG		0x008
+#define PTO_RDATA_REG		0x010
+#define PTO_MIS_REG		0x020
+
+struct plgpio_regs {
+	u32 enb;		/* enable register */
+	u32 wdata;		/* write data register */
+	u32 dir;		/* direction set register */
+	u32 rdata;		/* read data register */
+	u32 ie;			/* interrupt enable register */
+	u32 mis;		/* mask interrupt status register */
+	u32 eit;		/* edge interrupt type */
+};
+
+/*
+ * struct plgpio: plgpio driver specific structure
+ *
+ * lock: lock for guarding gpio registers
+ * base: base address of plgpio block
+ * irq_base: irq number of plgpio0
+ * chip: gpio framework specific chip information structure
+ * p2o: function ptr for pin to offset conversion. This is required only for
+ *	machines where mapping b/w pin and offset is not 1-to-1.
+ * o2p: function ptr for offset to pin conversion. This is required only for
+ *	machines where mapping b/w pin and offset is not 1-to-1.
+ * p2o_regs: mask of registers for which p2o and o2p are applicable
+ * regs: register offsets
+ * csave_regs: context save registers for standby/sleep/hibernate cases
+ */
+struct plgpio {
+	spinlock_t		lock;
+	void __iomem		*base;
+	struct clk		*clk;
+	unsigned		irq_base;
+	struct gpio_chip	chip;
+	int			(*p2o)(int pin);	/* pin_to_offset */
+	int			(*o2p)(int offset);	/* offset_to_pin */
+	u32			p2o_regs;
+	struct plgpio_regs	regs;
+#ifdef CONFIG_PM
+	struct plgpio_regs	*csave_regs;
+#endif
+};
+
+/* register manipulation inline functions */
+static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl_relaxed(reg_off);
+
+	return !!(val & (1 << offset));
+}
+
+static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl_relaxed(reg_off);
+
+	writel_relaxed(val | (1 << offset), reg_off);
+}
+
+static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl_relaxed(reg_off);
+
+	writel_relaxed(val & ~(1 << offset), reg_off);
+}
+
+/* gpio framework specific routines */
+static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return -EINVAL;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+	return 0;
+}
+
+static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+	unsigned dir_offset = offset, wdata_offset = offset, tmp;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) {
+		tmp = plgpio->p2o(offset);
+		if (tmp == -1)
+			return -EINVAL;
+
+		if (plgpio->p2o_regs & PTO_DIR_REG)
+			dir_offset = tmp;
+		if (plgpio->p2o_regs & PTO_WDATA_REG)
+			wdata_offset = tmp;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	if (value)
+		plgpio_reg_set(plgpio->base, wdata_offset,
+				plgpio->regs.wdata);
+	else
+		plgpio_reg_reset(plgpio->base, wdata_offset,
+				plgpio->regs.wdata);
+
+	plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+	return 0;
+}
+
+static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return -EINVAL;
+	}
+
+	return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata);
+}
+
+static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (offset >= chip->ngpio)
+		return;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	if (value)
+		plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata);
+	else
+		plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata);
+}
+
+static int plgpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	int gpio = chip->base + offset;
+	unsigned long flags;
+	int ret = 0;
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	ret = pinctrl_request_gpio(gpio);
+	if (ret)
+		return ret;
+
+	if (!IS_ERR(plgpio->clk)) {
+		ret = clk_prepare_enable(plgpio->clk);
+		if (ret)
+			goto err0;
+	}
+
+	if (plgpio->regs.enb == -1)
+		return 0;
+
+	/*
+	 * put gpio in IN mode before enabling it. This make enabling gpio safe
+	 */
+	ret = plgpio_direction_input(chip, offset);
+	if (ret)
+		goto err1;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1) {
+			ret = -EINVAL;
+			goto err1;
+		}
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+	return 0;
+
+err1:
+	clk_disable_unprepare(plgpio->clk);
+err0:
+	pinctrl_free_gpio(gpio);
+	return ret;
+}
+
+static void plgpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	int gpio = chip->base + offset;
+	unsigned long flags;
+
+	if (offset >= chip->ngpio)
+		return;
+
+	if (plgpio->regs.enb == -1)
+		goto disable_clk;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+disable_clk:
+	if (!IS_ERR(plgpio->clk))
+		clk_disable_unprepare(plgpio->clk);
+
+	pinctrl_free_gpio(gpio);
+}
+
+static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (plgpio->irq_base < 0)
+		return -EINVAL;
+
+	return plgpio->irq_base + offset;
+}
+
+/* PLGPIO IRQ */
+static void plgpio_irq_disable(struct irq_data *d)
+{
+	struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+	int offset = d->irq - plgpio->irq_base;
+	unsigned long flags;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static void plgpio_irq_enable(struct irq_data *d)
+{
+	struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+	int offset = d->irq - plgpio->irq_base;
+	unsigned long flags;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
+{
+	struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+	int offset = d->irq - plgpio->irq_base;
+	void __iomem *reg_off;
+	unsigned int supported_type = 0, val;
+
+	if (offset >= plgpio->chip.ngpio)
+		return -EINVAL;
+
+	if (plgpio->regs.eit == -1)
+		supported_type = IRQ_TYPE_LEVEL_HIGH;
+	else
+		supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+	if (!(trigger & supported_type))
+		return -EINVAL;
+
+	if (plgpio->regs.eit == -1)
+		return 0;
+
+	reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset);
+	val = readl_relaxed(reg_off);
+
+	offset = PIN_OFFSET(offset);
+	if (trigger & IRQ_TYPE_EDGE_RISING)
+		writel_relaxed(val | (1 << offset), reg_off);
+	else
+		writel_relaxed(val & ~(1 << offset), reg_off);
+
+	return 0;
+}
+
+static struct irq_chip plgpio_irqchip = {
+	.name		= "PLGPIO",
+	.irq_enable	= plgpio_irq_enable,
+	.irq_disable	= plgpio_irq_disable,
+	.irq_set_type	= plgpio_irq_set_type,
+};
+
+static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct plgpio *plgpio = irq_get_handler_data(irq);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	int regs_count, count, pin, offset, i = 0;
+	unsigned long pending;
+
+	count = plgpio->chip.ngpio;
+	regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG);
+
+	chained_irq_enter(irqchip, desc);
+	/* check all plgpio MIS registers for a possible interrupt */
+	for (; i < regs_count; i++) {
+		pending = readl_relaxed(plgpio->base + plgpio->regs.mis +
+				i * sizeof(int *));
+		if (!pending)
+			continue;
+
+		/* clear interrupts */
+		writel_relaxed(~pending, plgpio->base + plgpio->regs.mis +
+				i * sizeof(int *));
+		/*
+		 * clear extra bits in last register having gpios < MAX/REG
+		 * ex: Suppose there are max 102 plgpios. then last register
+		 * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits
+		 * so, we must not take other 28 bits into consideration for
+		 * checking interrupt. so clear those bits.
+		 */
+		count = count - i * MAX_GPIO_PER_REG;
+		if (count < MAX_GPIO_PER_REG)
+			pending &= (1 << count) - 1;
+
+		for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) {
+			/* get correct pin for "offset" */
+			if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) {
+				pin = plgpio->o2p(offset);
+				if (pin == -1)
+					continue;
+			} else
+				pin = offset;
+
+			/* get correct irq line number */
+			pin = i * MAX_GPIO_PER_REG + pin;
+			generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+		}
+	}
+	chained_irq_exit(irqchip, desc);
+}
+
+/*
+ * pin to offset and offset to pin converter functions
+ *
+ * In spear310 there is inconsistency among bit positions in plgpio regiseters,
+ * for different plgpio pins. For example: for pin 27, bit offset is 23, pin
+ * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
+ */
+static int spear310_p2o(int pin)
+{
+	int offset = pin;
+
+	if (pin <= 27)
+		offset += 4;
+	else if (pin <= 33)
+		offset = -1;
+	else if (pin <= 97)
+		offset -= 2;
+	else if (pin <= 101)
+		offset = 101 - pin;
+	else
+		offset = -1;
+
+	return offset;
+}
+
+int spear310_o2p(int offset)
+{
+	if (offset <= 3)
+		return 101 - offset;
+	else if (offset <= 31)
+		return offset - 4;
+	else
+		return offset + 2;
+}
+
+static int __devinit plgpio_probe_dt(struct platform_device *pdev,
+		struct plgpio *plgpio)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret = -EINVAL;
+	u32 val;
+
+	if (of_machine_is_compatible("st,spear310")) {
+		plgpio->p2o = spear310_p2o;
+		plgpio->o2p = spear310_o2p;
+		plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG |
+			PTO_RDATA_REG | PTO_MIS_REG;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) {
+		plgpio->chip.ngpio = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid ngpio field\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val))
+		plgpio->regs.enb = val;
+	else
+		plgpio->regs.enb = -1;
+
+	if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) {
+		plgpio->regs.wdata = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid wdata reg\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) {
+		plgpio->regs.dir = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid dir reg\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) {
+		plgpio->regs.ie = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid ie reg\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) {
+		plgpio->regs.rdata = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid rdata reg\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) {
+		plgpio->regs.mis = val;
+	} else {
+		dev_err(&pdev->dev, "DT: Invalid mis reg\n");
+		goto end;
+	}
+
+	if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val))
+		plgpio->regs.eit = val;
+	else
+		plgpio->regs.eit = -1;
+
+	if (!of_property_read_u32(np, "st-plgpio,irq_base", &val))
+		plgpio->irq_base = val;
+	else
+		plgpio->irq_base = -1;
+
+	return 0;
+
+end:
+	return ret;
+}
+static int __devinit plgpio_probe(struct platform_device *pdev)
+{
+	struct plgpio *plgpio;
+	struct resource *res;
+	int ret, irq, i;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
+		return -EBUSY;
+	}
+
+	plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
+	if (!plgpio) {
+		dev_err(&pdev->dev, "memory allocation fail\n");
+		return -ENOMEM;
+	}
+
+	plgpio->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!plgpio->base) {
+		dev_err(&pdev->dev, "request and ioremap fail\n");
+		return -ENOMEM;
+	}
+
+	plgpio->irq_base = 0;
+	ret = plgpio_probe_dt(pdev, plgpio);
+	if (ret) {
+		dev_err(&pdev->dev, "DT probe failed\n");
+		return ret;
+	}
+
+	plgpio->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(plgpio->clk))
+		dev_warn(&pdev->dev, "clk_get() failed, work without it\n");
+
+#ifdef CONFIG_PM
+	plgpio->csave_regs = devm_kzalloc(&pdev->dev,
+			sizeof(*plgpio->csave_regs) *
+			DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG),
+			GFP_KERNEL);
+	if (!plgpio->csave_regs) {
+		dev_err(&pdev->dev, "csave registers memory allocation fail\n");
+		return -ENOMEM;
+	}
+#endif
+
+	platform_set_drvdata(pdev, plgpio);
+	spin_lock_init(&plgpio->lock);
+
+	plgpio->chip.base = -1;
+	plgpio->chip.request = plgpio_request;
+	plgpio->chip.free = plgpio_free;
+	plgpio->chip.direction_input = plgpio_direction_input;
+	plgpio->chip.direction_output = plgpio_direction_output;
+	plgpio->chip.get = plgpio_get_value;
+	plgpio->chip.set = plgpio_set_value;
+	plgpio->chip.to_irq = plgpio_to_irq;
+	plgpio->chip.label = dev_name(&pdev->dev);
+	plgpio->chip.dev = &pdev->dev;
+	plgpio->chip.owner = THIS_MODULE;
+
+	ret = gpiochip_add(&plgpio->chip);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to add gpio chip\n");
+		return ret;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "irqs not supported\n");
+		return 0;
+	}
+
+	/* irq_chip support */
+	if (plgpio->irq_base < 0) {
+		dev_info(&pdev->dev, "Error: invalid irqbase passed\n");
+		goto remove_gpiochip;
+	}
+
+	irq_set_chained_handler(irq, plgpio_irq_handler);
+	for (i = 0; i < plgpio->chip.ngpio; i++) {
+		irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
+				handle_simple_irq);
+		set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
+		irq_set_chip_data(i + plgpio->irq_base, plgpio);
+	}
+
+	irq_set_handler_data(irq, plgpio);
+	dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
+
+	return 0;
+
+remove_gpiochip:
+	dev_info(&pdev->dev, "Remove gpiochip\n");
+	if (gpiochip_remove(&plgpio->chip))
+		dev_err(&pdev->dev, "unable to remove gpiochip\n");
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int plgpio_suspend(struct device *dev)
+{
+	struct plgpio *plgpio = dev_get_drvdata(dev);
+	int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+	void __iomem *off;
+
+	for (i = 0; i < reg_count; i++) {
+		off = plgpio->base + i * sizeof(int *);
+
+		if (plgpio->regs.enb != -1)
+			plgpio->csave_regs[i].enb =
+				readl_relaxed(plgpio->regs.enb + off);
+		if (plgpio->regs.eit != -1)
+			plgpio->csave_regs[i].eit =
+				readl_relaxed(plgpio->regs.eit + off);
+		plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata +
+				off);
+		plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir +
+				off);
+		plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off);
+	}
+
+	return 0;
+}
+
+/*
+ * This is used to correct the values in end registers. End registers contain
+ * extra bits that might be used for other purpose in platform. So, we shouldn't
+ * overwrite these bits. This macro, reads given register again, preserves other
+ * bit values (non-plgpio bits), and retain captured value (plgpio bits).
+ */
+#define plgpio_prepare_reg(__reg, _off, _mask, _tmp)		\
+{								\
+	_tmp = readl_relaxed(plgpio->regs.__reg + _off);		\
+	_tmp &= ~_mask;						\
+	plgpio->csave_regs[i].__reg =				\
+		_tmp | (plgpio->csave_regs[i].__reg & _mask);	\
+}
+
+static int plgpio_resume(struct device *dev)
+{
+	struct plgpio *plgpio = dev_get_drvdata(dev);
+	int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+	void __iomem *off;
+	u32 mask, tmp;
+
+	for (i = 0; i < reg_count; i++) {
+		off = plgpio->base + i * sizeof(int *);
+
+		if (i == reg_count - 1) {
+			mask = (1 << (plgpio->chip.ngpio - i *
+						MAX_GPIO_PER_REG)) - 1;
+
+			if (plgpio->regs.enb != -1)
+				plgpio_prepare_reg(enb, off, mask, tmp);
+
+			if (plgpio->regs.eit != -1)
+				plgpio_prepare_reg(eit, off, mask, tmp);
+
+			plgpio_prepare_reg(wdata, off, mask, tmp);
+			plgpio_prepare_reg(dir, off, mask, tmp);
+			plgpio_prepare_reg(ie, off, mask, tmp);
+		}
+
+		writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata +
+				off);
+		writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir +
+				off);
+
+		if (plgpio->regs.eit != -1)
+			writel_relaxed(plgpio->csave_regs[i].eit,
+					plgpio->regs.eit + off);
+
+		writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off);
+
+		if (plgpio->regs.enb != -1)
+			writel_relaxed(plgpio->csave_regs[i].enb,
+					plgpio->regs.enb + off);
+	}
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume);
+
+static const struct of_device_id plgpio_of_match[] = {
+	{ .compatible = "st,spear-plgpio" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, plgpio_of_match);
+
+static struct platform_driver plgpio_driver = {
+	.probe = plgpio_probe,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "spear-plgpio",
+		.pm = &plgpio_dev_pm_ops,
+		.of_match_table = of_match_ptr(plgpio_of_match),
+	},
+};
+
+static int __init plgpio_init(void)
+{
+	return platform_driver_register(&plgpio_driver);
+}
+arch_initcall(plgpio_init);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver");
+MODULE_LICENSE("GPL");
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V3 4/5] pinctrl: SPEAr: Add gpio ranges support
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
                   ` (2 preceding siblings ...)
  2012-05-08  3:40 ` [PATCH V3 3/5] pinctrl: SPEAr: Add plgpio driver Viresh Kumar
@ 2012-05-08  3:40 ` Viresh Kumar
  2012-05-08  3:40 ` [PATCH V3 5/5] SPEAr: Add plgpio node in device tree dtsi files Viresh Kumar
  2012-05-09 12:56 ` [PATCH V3 0/5] pinctrl: SPEAr Updates Linus Walleij
  5 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Most of SPEAr SoCs, which support pinctrl, can configure & use pads as gpio.
This patch gpio enable support for SPEAr pinctrl drivers.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/spear/Kconfig             |    4 +
 drivers/pinctrl/spear/pinctrl-spear.c     |  110 ++++++++++++++++--
 drivers/pinctrl/spear/pinctrl-spear.h     |   26 ++++
 drivers/pinctrl/spear/pinctrl-spear1310.c |  180 +++++++++++++++++++++++++++++
 drivers/pinctrl/spear/pinctrl-spear1340.c |    8 ++
 drivers/pinctrl/spear/pinctrl-spear300.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear310.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear320.c  |    2 +
 drivers/pinctrl/spear/pinctrl-spear3xx.c  |   29 +++++
 9 files changed, 351 insertions(+), 12 deletions(-)

diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 6f9a1e8..04d93e6 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -25,21 +25,25 @@ config PINCTRL_SPEAR310
 	bool "ST Microelectronics SPEAr310 SoC pin controller driver"
 	depends on MACH_SPEAR310
 	select PINCTRL_SPEAR3XX
+	select PINCTRL_SPEAR_PLGPIO
 
 config PINCTRL_SPEAR320
 	bool "ST Microelectronics SPEAr320 SoC pin controller driver"
 	depends on MACH_SPEAR320
 	select PINCTRL_SPEAR3XX
+	select PINCTRL_SPEAR_PLGPIO
 
 config PINCTRL_SPEAR1310
 	bool "ST Microelectronics SPEAr1310 SoC pin controller driver"
 	depends on MACH_SPEAR1310
 	select PINCTRL_SPEAR
+	select PINCTRL_SPEAR_PLGPIO
 
 config PINCTRL_SPEAR1340
 	bool "ST Microelectronics SPEAr1340 SoC pin controller driver"
 	depends on MACH_SPEAR1340
 	select PINCTRL_SPEAR
+	select PINCTRL_SPEAR_PLGPIO
 
 config PINCTRL_SPEAR_PLGPIO
 	bool "SPEAr SoC PLGPIO Controller"
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 8653569..c0c3b28 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_gpio.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
@@ -38,6 +39,23 @@ static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
 	writel_relaxed(val, pmx->vbase + reg);
 }
 
+static void muxreg_endisable(struct spear_pmx *pmx, struct spear_muxreg *muxreg,
+		bool enable)
+{
+	u32 val, temp;
+
+	val = pmx_readl(pmx, muxreg->reg);
+	val &= ~muxreg->mask;
+
+	if (enable)
+		temp = muxreg->val;
+	else
+		temp = ~muxreg->val;
+
+	val |= muxreg->mask & temp;
+	pmx_writel(pmx, val, muxreg->reg);
+}
+
 static int set_mode(struct spear_pmx *pmx, int mode)
 {
 	struct spear_pmx_mode *pmx_mode = NULL;
@@ -70,6 +88,16 @@ static int set_mode(struct spear_pmx *pmx, int mode)
 	return 0;
 }
 
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+		unsigned count, u16 reg)
+{
+	int i = 0;
+
+	for (; i < count; i++)
+		gpio_pingroup[i].muxreg.reg = reg;
+}
+
 void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
 {
 	struct spear_pingroup *pgroup;
@@ -217,7 +245,6 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
 	const struct spear_pingroup *pgroup;
 	const struct spear_modemux *modemux;
 	struct spear_muxreg *muxreg;
-	u32 val, temp;
 	int i, j;
 	bool found = false;
 
@@ -235,17 +262,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
 		found = true;
 		for (j = 0; j < modemux->nmuxregs; j++) {
 			muxreg = &modemux->muxregs[j];
-
-			val = pmx_readl(pmx, muxreg->reg);
-			val &= ~muxreg->mask;
-
-			if (enable)
-				temp = muxreg->val;
-			else
-				temp = ~muxreg->val;
-
-			val |= muxreg->mask & temp;
-			pmx_writel(pmx, val, muxreg->reg);
+			muxreg_endisable(pmx, muxreg, enable);
 		}
 	}
 
@@ -270,12 +287,68 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
 	spear_pinctrl_endisable(pctldev, function, group, false);
 }
 
+/* gpio with pinmux */
+static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
+		unsigned pin)
+{
+	struct spear_gpio_pingroup *gpio_pingroup;
+	int i = 0, j;
+
+	if (!pmx->machdata->gpio_pingroups)
+		return NULL;
+
+	for (; i < pmx->machdata->ngpio_pingroups; i++) {
+		gpio_pingroup = &pmx->machdata->gpio_pingroups[i];
+
+		for (j = 0; j < gpio_pingroup->npins; j++) {
+			if (gpio_pingroup->pins[j] == pin)
+				return gpio_pingroup;
+		}
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int gpio_request_endisable(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset, bool enable)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	struct spear_gpio_pingroup *gpio_pingroup;
+
+	gpio_pingroup = get_gpio_pingroup(pmx, offset);
+	if (IS_ERR(gpio_pingroup))
+		return PTR_ERR(gpio_pingroup);
+
+	if (gpio_pingroup) {
+		struct spear_muxreg *muxreg;
+
+		muxreg = &gpio_pingroup->muxreg;
+		muxreg_endisable(pmx, muxreg, enable);
+	}
+
+	return 0;
+}
+
+static int gpio_request_enable(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset)
+{
+	return gpio_request_endisable(pctldev, range, offset, true);
+}
+
+static void gpio_disable_free(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset)
+{
+	gpio_request_endisable(pctldev, range, offset, false);
+}
+
 static struct pinmux_ops spear_pinmux_ops = {
 	.get_functions_count = spear_pinctrl_get_funcs_count,
 	.get_function_name = spear_pinctrl_get_func_name,
 	.get_function_groups = spear_pinctrl_get_func_groups,
 	.enable = spear_pinctrl_enable,
 	.disable = spear_pinctrl_disable,
+	.gpio_request_enable = gpio_request_enable,
+	.gpio_disable_free = gpio_disable_free,
 };
 
 static struct pinctrl_desc spear_pinctrl_desc = {
@@ -291,6 +364,7 @@ int __devinit spear_pinctrl_probe(struct platform_device *pdev,
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *res;
 	struct spear_pmx *pmx;
+	struct gpio_chip *gc;
 
 	if (!machdata)
 		return -ENODEV;
@@ -341,6 +415,18 @@ int __devinit spear_pinctrl_probe(struct platform_device *pdev,
 		return PTR_ERR(pmx->pctl);
 	}
 
+	gc = of_get_gpio_chip_by_phandle(np);
+	if (!gc) {
+		dev_err(&pdev->dev, "Couldn't find gpiochip, no gpio ranges registered\n");
+		return 0;
+	}
+
+	dev_info(&pdev->dev, "gpiochip bound with pinctrl is %s with base %d\n",
+			dev_name(gc->dev), gc->base);
+
+	machdata->ranges->base = gc->base;
+	pinctrl_add_gpio_range(pmx->pctl, machdata->ranges);
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
index 9155783..11d23ad 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.h
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -46,6 +46,23 @@ struct spear_muxreg {
 	u32 val;
 };
 
+struct spear_gpio_pingroup {
+	const unsigned *pins;
+	unsigned npins;
+	struct spear_muxreg muxreg;
+};
+
+#define GPIO_PINGROUP(__pins, __reg, __mask, __set_to_enb)	\
+	{							\
+		.pins = __pins,					\
+		.npins = ARRAY_SIZE(__pins),			\
+		.muxreg = {					\
+			.reg = __reg,				\
+			.mask = __mask,				\
+			.val = __set_to_enb ? __mask : 0,	\
+		},						\
+	}
+
 /**
  * struct spear_modemux - SPEAr mode mux configuration
  * @modes: mode ids supported by this group of muxregs
@@ -100,6 +117,9 @@ struct spear_function {
  * @nfunctions: The numbmer of entries in @functions.
  * @groups: An array describing all pin groups the pin SoC supports.
  * @ngroups: The numbmer of entries in @groups.
+ * @ranges: PLGPIO ranges for the machine
+ * @gpio_pingroups: gpio pingroups
+ * @ngpio_pingroups: gpio pingroups count
  *
  * @modes_supported: Does SoC support modes
  * @mode: mode configured from probe
@@ -113,6 +133,9 @@ struct spear_pinctrl_machdata {
 	unsigned nfunctions;
 	struct spear_pingroup **groups;
 	unsigned ngroups;
+	struct pinctrl_gpio_range *ranges;
+	struct spear_gpio_pingroup *gpio_pingroups;
+	unsigned ngpio_pingroups;
 
 	bool modes_supported;
 	u16 mode;
@@ -136,6 +159,9 @@ struct spear_pmx {
 
 /* exported routines */
 void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+		unsigned count, u16 reg);
 int __devinit spear_pinctrl_probe(struct platform_device *pdev,
 		struct spear_pinctrl_machdata *machdata);
 int __devexit spear_pinctrl_remove(struct platform_device *pdev);
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index fff168b..1ae9842 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -2143,6 +2143,183 @@ static struct spear_function *spear1310_functions[] = {
 	&gpt64_function,
 };
 
+static struct pinctrl_gpio_range spear1310_plgpio_range = {
+	.name		= "SPEAr1310 PLGPIO",
+	.id		= 0,
+	.pin_base	= 0,
+	.npins		= ARRAY_SIZE(spear1310_pins),
+};
+
+static const unsigned pin18[] = { 18, };
+static const unsigned pin19[] = { 19, };
+static const unsigned pin20[] = { 20, };
+static const unsigned pin21[] = { 21, };
+static const unsigned pin22[] = { 22, };
+static const unsigned pin23[] = { 23, };
+static const unsigned pin54[] = { 54, };
+static const unsigned pin55[] = { 55, };
+static const unsigned pin56[] = { 56, };
+static const unsigned pin57[] = { 57, };
+static const unsigned pin58[] = { 58, };
+static const unsigned pin59[] = { 59, };
+static const unsigned pin60[] = { 60, };
+static const unsigned pin61[] = { 61, };
+static const unsigned pin62[] = { 62, };
+static const unsigned pin63[] = { 63, };
+static const unsigned pin143[] = { 143, };
+static const unsigned pin144[] = { 144, };
+static const unsigned pin145[] = { 145, };
+static const unsigned pin146[] = { 146, };
+static const unsigned pin147[] = { 147, };
+static const unsigned pin148[] = { 148, };
+static const unsigned pin149[] = { 149, };
+static const unsigned pin150[] = { 150, };
+static const unsigned pin151[] = { 151, };
+static const unsigned pin152[] = { 152, };
+static const unsigned pin205[] = { 205, };
+static const unsigned pin206[] = { 206, };
+static const unsigned pin211[] = { 211, };
+static const unsigned pin212[] = { 212, };
+static const unsigned pin213[] = { 213, };
+static const unsigned pin214[] = { 214, };
+static const unsigned pin215[] = { 215, };
+static const unsigned pin216[] = { 216, };
+static const unsigned pin217[] = { 217, };
+static const unsigned pin218[] = { 218, };
+static const unsigned pin219[] = { 219, };
+static const unsigned pin220[] = { 220, };
+static const unsigned pin221[] = { 221, };
+static const unsigned pin222[] = { 222, };
+static const unsigned pin223[] = { 223, };
+static const unsigned pin224[] = { 224, };
+static const unsigned pin225[] = { 225, };
+static const unsigned pin226[] = { 226, };
+static const unsigned pin227[] = { 227, };
+static const unsigned pin228[] = { 228, };
+static const unsigned pin229[] = { 229, };
+static const unsigned pin230[] = { 230, };
+static const unsigned pin231[] = { 231, };
+static const unsigned pin232[] = { 232, };
+static const unsigned pin233[] = { 233, };
+static const unsigned pin234[] = { 234, };
+static const unsigned pin235[] = { 235, };
+static const unsigned pin236[] = { 236, };
+static const unsigned pin237[] = { 237, };
+static const unsigned pin238[] = { 238, };
+static const unsigned pin239[] = { 239, };
+static const unsigned pin240[] = { 240, };
+static const unsigned pin241[] = { 241, };
+static const unsigned pin242[] = { 242, };
+static const unsigned pin243[] = { 243, };
+static const unsigned pin244[] = { 244, };
+static const unsigned pin245[] = { 245, };
+
+static const unsigned pin_grp0[] = { 173, 174, };
+static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, };
+static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189,
+	190, 191, 192, };
+static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, };
+static const unsigned pin_grp4[] = { 199, 200, };
+static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+	75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, };
+static const unsigned pin_grp7[] = { 98, 99, };
+static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165,
+	166, 167, 168, 169, 170, 171, 172, };
+
+static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = {
+	GPIO_PINGROUP(i2c0_pins, PAD_FUNCTION_EN_0, PMX_I2C0_MASK, 0),
+	GPIO_PINGROUP(ssp0_pins, PAD_FUNCTION_EN_0, PMX_SSP0_MASK, 0),
+	GPIO_PINGROUP(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PMX_SSP0_CS0_MASK, 0),
+	GPIO_PINGROUP(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PMX_SSP0_CS1_2_MASK, 0),
+	GPIO_PINGROUP(i2s0_pins, PAD_FUNCTION_EN_0, PMX_I2S0_MASK, 0),
+	GPIO_PINGROUP(i2s1_pins, PAD_FUNCTION_EN_1, PMX_I2S1_MASK, 0),
+	GPIO_PINGROUP(clcd_pins, PAD_FUNCTION_EN_0, PMX_CLCD1_MASK, 0),
+	GPIO_PINGROUP(clcd_high_res_pins, PAD_FUNCTION_EN_1, PMX_CLCD2_MASK, 0),
+	GPIO_PINGROUP(pin18, PAD_FUNCTION_EN_0, PMX_EGPIO15_MASK, 0),
+	GPIO_PINGROUP(pin19, PAD_FUNCTION_EN_0, PMX_EGPIO14_MASK, 0),
+	GPIO_PINGROUP(pin20, PAD_FUNCTION_EN_0, PMX_EGPIO13_MASK, 0),
+	GPIO_PINGROUP(pin21, PAD_FUNCTION_EN_0, PMX_EGPIO12_MASK, 0),
+	GPIO_PINGROUP(pin22, PAD_FUNCTION_EN_0, PMX_EGPIO11_MASK, 0),
+	GPIO_PINGROUP(pin23, PAD_FUNCTION_EN_0, PMX_EGPIO10_MASK, 0),
+	GPIO_PINGROUP(pin143, PAD_FUNCTION_EN_0, PMX_EGPIO00_MASK, 0),
+	GPIO_PINGROUP(pin144, PAD_FUNCTION_EN_0, PMX_EGPIO01_MASK, 0),
+	GPIO_PINGROUP(pin145, PAD_FUNCTION_EN_0, PMX_EGPIO02_MASK, 0),
+	GPIO_PINGROUP(pin146, PAD_FUNCTION_EN_0, PMX_EGPIO03_MASK, 0),
+	GPIO_PINGROUP(pin147, PAD_FUNCTION_EN_0, PMX_EGPIO04_MASK, 0),
+	GPIO_PINGROUP(pin148, PAD_FUNCTION_EN_0, PMX_EGPIO05_MASK, 0),
+	GPIO_PINGROUP(pin149, PAD_FUNCTION_EN_0, PMX_EGPIO06_MASK, 0),
+	GPIO_PINGROUP(pin150, PAD_FUNCTION_EN_0, PMX_EGPIO07_MASK, 0),
+	GPIO_PINGROUP(pin151, PAD_FUNCTION_EN_0, PMX_EGPIO08_MASK, 0),
+	GPIO_PINGROUP(pin152, PAD_FUNCTION_EN_0, PMX_EGPIO09_MASK, 0),
+	GPIO_PINGROUP(smi_2_chips_pins, PAD_FUNCTION_EN_0, PMX_SMI_MASK, 0),
+	GPIO_PINGROUP(pin54, PAD_FUNCTION_EN_1, PMX_SMINCS3_MASK, 0),
+	GPIO_PINGROUP(pin55, PAD_FUNCTION_EN_1, PMX_SMINCS2_MASK, 0),
+	GPIO_PINGROUP(pin56, PAD_FUNCTION_EN_1, PMX_NFRSTPWDWN3_MASK, 0),
+	GPIO_PINGROUP(pin57, PAD_FUNCTION_EN_0, PMX_NFRSTPWDWN2_MASK, 0),
+	GPIO_PINGROUP(pin58, PAD_FUNCTION_EN_0, PMX_NFRSTPWDWN1_MASK, 0),
+	GPIO_PINGROUP(pin59, PAD_FUNCTION_EN_0, PMX_NFRSTPWDWN0_MASK, 0),
+	GPIO_PINGROUP(pin60, PAD_FUNCTION_EN_0, PMX_NFWPRT3_MASK, 0),
+	GPIO_PINGROUP(pin61, PAD_FUNCTION_EN_0, PMX_NFCE3_MASK, 0),
+	GPIO_PINGROUP(pin62, PAD_FUNCTION_EN_0, PMX_NFAD25_MASK, 0),
+	GPIO_PINGROUP(pin63, PAD_FUNCTION_EN_0, PMX_NFAD24_MASK, 0),
+	GPIO_PINGROUP(pin_grp0, PAD_FUNCTION_EN_0, PMX_GMIICLK_MASK, 0),
+	GPIO_PINGROUP(pin_grp1, PAD_FUNCTION_EN_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0),
+	GPIO_PINGROUP(pin_grp2, PAD_FUNCTION_EN_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0),
+	GPIO_PINGROUP(pin_grp3, PAD_FUNCTION_EN_0, PMX_GMIID47_MASK, 0),
+	GPIO_PINGROUP(pin_grp4, PAD_FUNCTION_EN_0, PMX_MDC_MDIO_MASK, 0),
+	GPIO_PINGROUP(pin_grp5, PAD_FUNCTION_EN_0, PMX_NFAD23_MASK, 0),
+	GPIO_PINGROUP(pin_grp6, PAD_FUNCTION_EN_0, PMX_MCI_DATA8_15_MASK, 0),
+	GPIO_PINGROUP(pin_grp7, PAD_FUNCTION_EN_1, PMX_NFCE2_MASK, 0),
+	GPIO_PINGROUP(pin_grp8, PAD_FUNCTION_EN_1, PMX_NAND8_MASK, 0),
+	GPIO_PINGROUP(nand_16bit_pins, PAD_FUNCTION_EN_1, PMX_NAND16BIT_1_MASK, 0),
+	GPIO_PINGROUP(pin205, PAD_FUNCTION_EN_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0),
+	GPIO_PINGROUP(pin206, PAD_FUNCTION_EN_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0),
+	GPIO_PINGROUP(pin211, PAD_FUNCTION_EN_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0),
+	GPIO_PINGROUP(pin212, PAD_FUNCTION_EN_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0),
+	GPIO_PINGROUP(pin213, PAD_FUNCTION_EN_1, PMX_MCIDATA0_MASK, 0),
+	GPIO_PINGROUP(pin214, PAD_FUNCTION_EN_1, PMX_MCIDATA1_MASK, 0),
+	GPIO_PINGROUP(pin215, PAD_FUNCTION_EN_1, PMX_MCIDATA2_MASK, 0),
+	GPIO_PINGROUP(pin216, PAD_FUNCTION_EN_1, PMX_MCIDATA3_MASK, 0),
+	GPIO_PINGROUP(pin217, PAD_FUNCTION_EN_1, PMX_MCIDATA4_MASK, 0),
+	GPIO_PINGROUP(pin218, PAD_FUNCTION_EN_2, PMX_MCIDATA5_MASK, 0),
+	GPIO_PINGROUP(pin219, PAD_FUNCTION_EN_2, PMX_MCIDATA6_MASK, 0),
+	GPIO_PINGROUP(pin220, PAD_FUNCTION_EN_2, PMX_MCIDATA7_MASK, 0),
+	GPIO_PINGROUP(pin221, PAD_FUNCTION_EN_2, PMX_MCIDATA1SD_MASK, 0),
+	GPIO_PINGROUP(pin222, PAD_FUNCTION_EN_2, PMX_MCIDATA2SD_MASK, 0),
+	GPIO_PINGROUP(pin223, PAD_FUNCTION_EN_2, PMX_MCIDATA3SD_MASK, 0),
+	GPIO_PINGROUP(pin224, PAD_FUNCTION_EN_2, PMX_MCIADDR0ALE_MASK, 0),
+	GPIO_PINGROUP(pin225, PAD_FUNCTION_EN_2, PMX_MCIADDR1CLECLK_MASK, 0),
+	GPIO_PINGROUP(pin226, PAD_FUNCTION_EN_2, PMX_MCIADDR2_MASK, 0),
+	GPIO_PINGROUP(pin227, PAD_FUNCTION_EN_2, PMX_MCICECF_MASK, 0),
+	GPIO_PINGROUP(pin228, PAD_FUNCTION_EN_2, PMX_MCICEXD_MASK, 0),
+	GPIO_PINGROUP(pin229, PAD_FUNCTION_EN_2, PMX_MCICESDMMC_MASK, 0),
+	GPIO_PINGROUP(pin230, PAD_FUNCTION_EN_2, PMX_MCICDCF1_MASK, 0),
+	GPIO_PINGROUP(pin231, PAD_FUNCTION_EN_2, PMX_MCICDCF2_MASK, 0),
+	GPIO_PINGROUP(pin232, PAD_FUNCTION_EN_2, PMX_MCICDXD_MASK, 0),
+	GPIO_PINGROUP(pin233, PAD_FUNCTION_EN_2, PMX_MCICDSDMMC_MASK, 0),
+	GPIO_PINGROUP(pin234, PAD_FUNCTION_EN_2, PMX_MCIDATADIR_MASK, 0),
+	GPIO_PINGROUP(pin235, PAD_FUNCTION_EN_2, PMX_MCIDMARQWP_MASK, 0),
+	GPIO_PINGROUP(pin236, PAD_FUNCTION_EN_2, PMX_MCIIORDRE_MASK, 0),
+	GPIO_PINGROUP(pin237, PAD_FUNCTION_EN_2, PMX_MCIIOWRWE_MASK, 0),
+	GPIO_PINGROUP(pin238, PAD_FUNCTION_EN_2, PMX_MCIRESETCF_MASK, 0),
+	GPIO_PINGROUP(pin239, PAD_FUNCTION_EN_2, PMX_MCICS0CE_MASK, 0),
+	GPIO_PINGROUP(pin240, PAD_FUNCTION_EN_2, PMX_MCICFINTR_MASK, 0),
+	GPIO_PINGROUP(pin241, PAD_FUNCTION_EN_2, PMX_MCIIORDY_MASK, 0),
+	GPIO_PINGROUP(pin242, PAD_FUNCTION_EN_2, PMX_MCICS1_MASK, 0),
+	GPIO_PINGROUP(pin243, PAD_FUNCTION_EN_2, PMX_MCIDMAACK_MASK, 0),
+	GPIO_PINGROUP(pin244, PAD_FUNCTION_EN_2, PMX_MCISDCMD_MASK, 0),
+	GPIO_PINGROUP(pin245, PAD_FUNCTION_EN_2, PMX_MCILEDS_MASK, 0),
+	GPIO_PINGROUP(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PMX_KBD_ROWCOL68_MASK, 0),
+	GPIO_PINGROUP(uart0_pins, PAD_FUNCTION_EN_0, PMX_UART0_MASK, 0),
+	GPIO_PINGROUP(uart0_modem_pins, PAD_FUNCTION_EN_1, PMX_UART0_MODEM_MASK, 0),
+	GPIO_PINGROUP(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PMX_GPT0_TMR0_MASK, 0),
+	GPIO_PINGROUP(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PMX_GPT0_TMR1_MASK, 0),
+	GPIO_PINGROUP(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PMX_GPT1_TMR0_MASK, 0),
+	GPIO_PINGROUP(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PMX_GPT1_TMR1_MASK, 0),
+	GPIO_PINGROUP(touch_xy_pins, PAD_FUNCTION_EN_1, PMX_TOUCH_XY_MASK, 0),
+};
+
 static struct spear_pinctrl_machdata spear1310_machdata = {
 	.pins = spear1310_pins,
 	.npins = ARRAY_SIZE(spear1310_pins),
@@ -2150,6 +2327,9 @@ static struct spear_pinctrl_machdata spear1310_machdata = {
 	.ngroups = ARRAY_SIZE(spear1310_pingroups),
 	.functions = spear1310_functions,
 	.nfunctions = ARRAY_SIZE(spear1310_functions),
+	.ranges = &spear1310_plgpio_range,
+	.gpio_pingroups = spear1310_gpio_pingroup,
+	.ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup),
 	.modes_supported = false,
 };
 
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index a8ab2a6..9380507 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -1934,6 +1934,13 @@ static struct spear_function *spear1340_functions[] = {
 	&sata_function,
 };
 
+static struct pinctrl_gpio_range spear1340_plgpio_range = {
+	.name		= "SPEAr1340 PLGPIO",
+	.id		= 0,
+	.pin_base	= 0,
+	.npins		= ARRAY_SIZE(spear1340_pins),
+};
+
 static struct spear_pinctrl_machdata spear1340_machdata = {
 	.pins = spear1340_pins,
 	.npins = ARRAY_SIZE(spear1340_pins),
@@ -1941,6 +1948,7 @@ static struct spear_pinctrl_machdata spear1340_machdata = {
 	.ngroups = ARRAY_SIZE(spear1340_pingroups),
 	.functions = spear1340_functions,
 	.nfunctions = ARRAY_SIZE(spear1340_functions),
+	.ranges = &spear1340_plgpio_range,
 	.modes_supported = false,
 };
 
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
index 9c82a35..faa9169 100644
--- a/drivers/pinctrl/spear/pinctrl-spear300.c
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
 	spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
 	spear3xx_machdata.functions = spear300_functions;
 	spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+	spear3xx_machdata.gpio_pingroups = NULL;
+	spear3xx_machdata.ngpio_pingroups = 0;
 
 	spear3xx_machdata.modes_supported = true;
 	spear3xx_machdata.pmx_modes = spear300_pmx_modes;
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
index 1a97076..f393639 100644
--- a/drivers/pinctrl/spear/pinctrl-spear310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
 	spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
 
 	pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+	pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+			spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
 
 	spear3xx_machdata.modes_supported = false;
 
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
index de726e6..e8c2d65 100644
--- a/drivers/pinctrl/spear/pinctrl-spear320.c
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -3427,6 +3427,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
 	spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
 
 	pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+	pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+			spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
 
 	ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
 	if (ret)
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
index 91c883b..dfd90aa 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.c
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c
@@ -481,7 +481,36 @@ struct spear_function spear3xx_timer_2_3_function = {
 	.ngroups = ARRAY_SIZE(timer_2_3_grps),
 };
 
+/* plgpio */
+static struct pinctrl_gpio_range spear3xx_plgpio_range = {
+	.name		= "SPEAr3xx PLGPIO",
+	.id		= 0,
+	.pin_base	= 0,
+	.npins		= ARRAY_SIZE(spear3xx_pins),
+};
+
+static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = {
+	GPIO_PINGROUP(firda_pins, 0, PMX_FIRDA_MASK, 1),
+	GPIO_PINGROUP(i2c_pins, 0, PMX_I2C_MASK, 1),
+	GPIO_PINGROUP(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 1),
+	GPIO_PINGROUP(ssp_pins, 0, PMX_SSP_MASK, 1),
+	GPIO_PINGROUP(mii_pins, 0, PMX_MII_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 1),
+	GPIO_PINGROUP(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 1),
+	GPIO_PINGROUP(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 1),
+	GPIO_PINGROUP(uart0_pins, 0, PMX_UART0_MASK, 1),
+	GPIO_PINGROUP(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 1),
+	GPIO_PINGROUP(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 1),
+};
+
 struct spear_pinctrl_machdata spear3xx_machdata = {
 	.pins = spear3xx_pins,
 	.npins = ARRAY_SIZE(spear3xx_pins),
+	.ranges = &spear3xx_plgpio_range,
+	.gpio_pingroups = spear3xx_gpio_pingroup,
+	.ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup),
 };
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V3 5/5] SPEAr: Add plgpio node in device tree dtsi files
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
                   ` (3 preceding siblings ...)
  2012-05-08  3:40 ` [PATCH V3 4/5] pinctrl: SPEAr: Add gpio ranges support Viresh Kumar
@ 2012-05-08  3:40 ` Viresh Kumar
  2012-05-09 12:56 ` [PATCH V3 0/5] pinctrl: SPEAr Updates Linus Walleij
  5 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2012-05-08  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/boot/dts/spear1310-evb.dts |    4 ++++
 arch/arm/boot/dts/spear1310.dtsi    |   22 ++++++++++++++++++++++
 arch/arm/boot/dts/spear1340-evb.dts |    4 ++++
 arch/arm/boot/dts/spear1340.dtsi    |   21 +++++++++++++++++++++
 arch/arm/boot/dts/spear310-evb.dts  |    4 ++++
 arch/arm/boot/dts/spear310.dtsi     |   15 +++++++++++++++
 arch/arm/boot/dts/spear320-evb.dts  |    4 ++++
 arch/arm/boot/dts/spear320.dtsi     |   16 ++++++++++++++++
 8 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index 1ffc46c..12cce81 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -156,6 +156,10 @@
 			       status = "okay";
 			};
 
+			gpio at d8400000 {
+			       status = "okay";
+			};
+
 			i2c0: i2c at e0280000 {
 			       status = "okay";
 			};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 9e61da4..c63bba2 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -70,6 +70,12 @@
 			status = "disabled";
 		};
 
+		pinmux at e0700000 {
+			compatible = "st,spear1310-pinmux";
+			reg = <0xe0700000 0x1000>;
+			gpio-phandle = <&gpiopinctrl>;
+		};
+
 		spi1: spi at 5d400000 {
 			compatible = "arm,pl022", "arm,primecell";
 			reg = <0x5d400000 0x1000>;
@@ -179,6 +185,22 @@
 			thermal at e07008c4 {
 				st,thermal-flags = <0x7000>;
 			};
+
+			gpiopinctrl: gpio at d8400000 {
+				compatible = "st,spear-plgpio";
+				reg = <0xd8400000 0x1000>;
+				interrupts = <0 132 0x4>;
+				status = "disabled";
+
+				st-plgpio,ngpio = <246>;
+				st-plgpio,enb-reg = <0xd0>;
+				st-plgpio,wdata-reg = <0x90>;
+				st-plgpio,dir-reg = <0xb0>;
+				st-plgpio,ie-reg = <0x30>;
+				st-plgpio,rdata-reg = <0x70>;
+				st-plgpio,mis-reg = <0x10>;
+				st-plgpio,eit-reg = <0x50>;
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index 0813597..e52b23f 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -168,6 +168,10 @@
 			       status = "okay";
 			};
 
+			gpio at e2800000 {
+			       status = "okay";
+			};
+
 			i2c0: i2c at e0280000 {
 			       status = "okay";
 			};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index a26fc47..e5d4e05 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -24,6 +24,12 @@
 			status = "disabled";
 		};
 
+		pinmux at e0700000 {
+			compatible = "st,spear1340-pinmux";
+			reg = <0xe0700000 0x1000>;
+			gpio-phandle = <&gpiopinctrl>;
+		};
+
 		spi1: spi at 5d400000 {
 			compatible = "arm,pl022", "arm,primecell";
 			reg = <0x5d400000 0x1000>;
@@ -51,6 +57,21 @@
 			thermal at e07008c4 {
 				st,thermal-flags = <0x2a00>;
 			};
+
+			gpiopinctrl: gpio at e2800000 {
+				compatible = "st,spear-plgpio";
+				reg = <0xe2800000 0x1000>;
+				interrupts = <0 139 0x4>;
+				status = "disabled";
+
+				st-plgpio,ngpio = <250>;
+				st-plgpio,wdata-reg = <0x40>;
+				st-plgpio,dir-reg = <0x00>;
+				st-plgpio,ie-reg = <0x80>;
+				st-plgpio,rdata-reg = <0x20>;
+				st-plgpio,mis-reg = <0xa0>;
+				st-plgpio,eit-reg = <0x60>;
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
index 6d95317..eb9f19e 100644
--- a/arch/arm/boot/dts/spear310-evb.dts
+++ b/arch/arm/boot/dts/spear310-evb.dts
@@ -132,6 +132,10 @@
 			       status = "okay";
 			};
 
+			gpio at b4000000 {
+			       status = "okay";
+			};
+
 			i2c0: i2c at d0180000 {
 			       status = "okay";
 			};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
index e47081c..fddf84c 100644
--- a/arch/arm/boot/dts/spear310.dtsi
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -25,6 +25,7 @@
 		pinmux at b4000000 {
 			compatible = "st,spear310-pinmux";
 			reg = <0xb4000000 0x1000>;
+			gpio-phandle = <&gpiopinctrl>;
 		};
 
 		fsmc: flash at 44000000 {
@@ -75,6 +76,20 @@
 				reg = <0xb2200000 0x1000>;
 				status = "disabled";
 			};
+
+			gpiopinctrl: gpio at b4000000 {
+				compatible = "st,spear-plgpio";
+				reg = <0xb4000000 0x1000>;
+				status = "disabled";
+
+				st-plgpio,ngpio = <102>;
+				st-plgpio,enb-reg = <0x10>;
+				st-plgpio,wdata-reg = <0x20>;
+				st-plgpio,dir-reg = <0x30>;
+				st-plgpio,ie-reg = <0x50>;
+				st-plgpio,rdata-reg = <0x40>;
+				st-plgpio,mis-reg = <0x60>;
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index 0c6463b..96280fe 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -141,6 +141,10 @@
 			       status = "okay";
 			};
 
+			gpio at b3000000 {
+			       status = "okay";
+			};
+
 			i2c0: i2c at d0180000 {
 			       status = "okay";
 			};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
index 5372ca3..9adac5b 100644
--- a/arch/arm/boot/dts/spear320.dtsi
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -24,6 +24,7 @@
 		pinmux at b3000000 {
 			compatible = "st,spear320-pinmux";
 			reg = <0xb3000000 0x1000>;
+			gpio-phandle = <&gpiopinctrl>;
 		};
 
 		clcd at 90000000 {
@@ -90,6 +91,21 @@
 				reg = <0xa4000000 0x1000>;
 				status = "disabled";
 			};
+
+			gpiopinctrl: gpio at b3000000 {
+				compatible = "st,spear-plgpio";
+				reg = <0xb3000000 0x1000>;
+				status = "disabled";
+
+				st-plgpio,ngpio = <102>;
+				st-plgpio,enb-reg = <0x24>;
+				st-plgpio,wdata-reg = <0x34>;
+				st-plgpio,dir-reg = <0x44>;
+				st-plgpio,ie-reg = <0x64>;
+				st-plgpio,rdata-reg = <0x54>;
+				st-plgpio,mis-reg = <0x84>;
+				st-plgpio,eit-reg = <0x94>;
+			};
 		};
 	};
 };
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V3 0/5] pinctrl: SPEAr Updates
  2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
                   ` (4 preceding siblings ...)
  2012-05-08  3:40 ` [PATCH V3 5/5] SPEAr: Add plgpio node in device tree dtsi files Viresh Kumar
@ 2012-05-09 12:56 ` Linus Walleij
  5 siblings, 0 replies; 7+ messages in thread
From: Linus Walleij @ 2012-05-09 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 8, 2012 at 5:40 AM, Viresh Kumar <viresh.kumar@st.com> wrote:

> This patchset mainly focuses on providing support to configure SPEAr pads as
> gpios. For this i have added a gpiolib based driver and few changes in other
> SPEAr pinctrl drivers.

I've already ACK:ed it I think, I guess you will send this as a pull
request to ARM SoC maintainers since that is where the dependent
branch is?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-05-09 12:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-08  3:40 [PATCH V3 0/5] pinctrl: SPEAr Updates Viresh Kumar
2012-05-08  3:40 ` [PATCH V3 1/5] pinctrl: SPEAr: Don't set all non muxreg bits on pinctrl_disable Viresh Kumar
2012-05-08  3:40 ` [PATCH V3 2/5] pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res Viresh Kumar
2012-05-08  3:40 ` [PATCH V3 3/5] pinctrl: SPEAr: Add plgpio driver Viresh Kumar
2012-05-08  3:40 ` [PATCH V3 4/5] pinctrl: SPEAr: Add gpio ranges support Viresh Kumar
2012-05-08  3:40 ` [PATCH V3 5/5] SPEAr: Add plgpio node in device tree dtsi files Viresh Kumar
2012-05-09 12:56 ` [PATCH V3 0/5] pinctrl: SPEAr Updates Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.