All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
@ 2013-02-03 10:15 Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
                   ` (10 more replies)
  0 siblings, 11 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:

v2:
* Fix the build issue without CONFIG_OF
* Append to check PINCTRL_SINGLE because of arch pxa not moved to DT
* Use bool for inverted, ed_mask, gafr variable

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

* [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 02/10] gpio: pxa: avoid to use global irq base Haojian Zhuang
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid to judge whether edge mask register exists by CPU. Use platform
data to identify it instead. The gpio edge mask register exists in MMP
series SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-mmp/aspenite.c      |    7 +++++++
 arch/arm/mach-mmp/avengers_lite.c |    7 +++++++
 arch/arm/mach-mmp/brownstone.c    |    7 +++++++
 arch/arm/mach-mmp/flint.c         |    7 +++++++
 arch/arm/mach-mmp/gplugd.c        |    7 +++++++
 arch/arm/mach-mmp/tavorevb.c      |    7 +++++++
 arch/arm/mach-mmp/teton_bga.c     |    7 +++++++
 arch/arm/mach-mmp/ttc_dkb.c       |    7 +++++++
 drivers/gpio/gpio-pxa.c           |   10 +++++++++-
 include/linux/gpio-pxa.h          |    1 +
 10 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 9f64d56..36f5781 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -9,6 +9,7 @@
  *  publishhed by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -110,6 +111,10 @@ static unsigned long common_pin_config[] __initdata = {
 	GPIO121_KP_MKIN4,
 };
 
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct smc91x_platdata smc91x_info = {
 	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
 };
@@ -248,6 +253,8 @@ static void __init common_init(void)
 	pxa168_add_nand(&aspenite_nand_info);
 	pxa168_add_fb(&aspenite_lcd_info);
 	pxa168_add_keypad(&aspenite_keypad_info);
+	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&pxa168_device_gpio);
 
 	/* off-chip devices */
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 1f94957..b8fe447 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gpio-pxa.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach-types.h>
@@ -32,12 +33,18 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
 	GPIO89_UART2_RXD,
 };
 
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static void __init avengers_lite_init(void)
 {
 	mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
 
 	/* on-chip devices */
 	pxa168_add_uart(2);
+	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&pxa168_device_gpio);
 }
 
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 2358011..d6ea5c4 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/gpio-pxa.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/max8649.h>
 #include <linux/regulator/fixed.h>
@@ -104,6 +105,10 @@ static unsigned long brownstone_pin_config[] __initdata = {
 	GPIO89_GPIO,
 };
 
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct regulator_consumer_supply max8649_supply[] = {
 	REGULATOR_SUPPLY("vcc_core", NULL),
 };
@@ -202,6 +207,8 @@ static void __init brownstone_init(void)
 	/* on-chip devices */
 	mmp2_add_uart(1);
 	mmp2_add_uart(3);
+	platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&mmp2_device_gpio);
 	mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
 	mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 754c352..0955f44 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -16,6 +16,7 @@
 #include <linux/smc91x.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 #include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
@@ -77,6 +78,10 @@ static unsigned long flint_pin_config[] __initdata = {
 	GPIO160_ND_RDY1,
 };
 
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct smc91x_platdata flint_smc91x_info = {
 	.flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
 };
@@ -111,6 +116,8 @@ static void __init flint_init(void)
 	/* on-chip devices */
 	mmp2_add_uart(1);
 	mmp2_add_uart(2);
+	platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&mmp2_device_gpio);
 
 	/* off-chip devices */
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index d1e2d59..2315cce 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -10,6 +10,7 @@
 
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
@@ -127,6 +128,10 @@ static unsigned long gplugd_pin_config[] __initdata = {
 	GPIO116_I2S_TXD
 };
 
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct i2c_board_info gplugd_i2c_board_info[] = {
 	{
 		.type = "isl1208",
@@ -185,6 +190,8 @@ static void __init gplugd_init(void)
 	pxa168_add_uart(3);
 	pxa168_add_ssp(1);
 	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&pxa168_device_gpio);
 
 	pxa168_add_eth(&gplugd_eth_platform_data);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 4c127d2..eaec649 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -8,6 +8,7 @@
  *  publishhed by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -60,6 +61,10 @@ static unsigned long tavorevb_pin_config[] __initdata = {
 	DF_RDY0_DF_RDY0,
 };
 
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct smc91x_platdata tavorevb_smc91x_info = {
 	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
 };
@@ -93,6 +98,8 @@ static void __init tavorevb_init(void)
 
 	/* on-chip devices */
 	pxa910_add_uart(1);
+	platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&pxa910_device_gpio);
 
 	/* off-chip devices */
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 8609967..6682100 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 #include <linux/input.h>
 #include <linux/platform_data/keypad-pxa27x.h>
 #include <linux/i2c.h>
@@ -49,6 +50,10 @@ static unsigned long teton_bga_pin_config[] __initdata = {
 	GPIO78_GPIO,
 };
 
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static unsigned int teton_bga_matrix_key_map[] = {
 	KEY(0, 6, KEY_ESC),
 	KEY(0, 7, KEY_ENTER),
@@ -79,6 +84,8 @@ static void __init teton_bga_init(void)
 	pxa168_add_uart(1);
 	pxa168_add_keypad(&teton_bga_keypad_info);
 	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_device_register(&pxa168_device_gpio);
 }
 
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 6e47490..984d902 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
 #include <linux/mfd/88pm860x.h>
 #include <linux/platform_data/mv_usb.h>
 
@@ -73,6 +74,10 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
 	DF_RDY0_DF_RDY0,
 };
 
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.ed_mask	= true,
+};
+
 static struct mtd_partition ttc_dkb_onenand_partitions[] = {
 	{
 		.name		= "bootloader",
@@ -196,6 +201,8 @@ static void __init ttc_dkb_init(void)
 
 	/* off-chip devices */
 	pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
+	platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+				 sizeof(struct pxa_gpio_platform_data));
 	platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
 
 #ifdef CONFIG_USB_MV_UDC
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 9cc108d..a4c6687 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -493,6 +493,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
 	int ret, nr_banks, nr_gpios;
+	struct pxa_gpio_platform_data *pdata;
 	struct device_node *prev, *next, *np = pdev->dev.of_node;
 	const struct of_device_id *of_id =
 				of_match_device(pxa_gpio_dt_ids, &pdev->dev);
@@ -501,6 +502,13 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to find gpio controller\n");
 		return -EFAULT;
 	}
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+	if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
+		pdata->ed_mask = true;
+	/* set the platform data */
+	pdev->dev.platform_data = pdata;
 	gpio_type = (int)of_id->data;
 
 	next = of_get_next_child(np, NULL);
@@ -604,7 +612,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 		writel_relaxed(0, c->regbase + GRER_OFFSET);
 		writel_relaxed(~0,c->regbase + GEDR_OFFSET);
 		/* unmask GPIO edge detect for AP side */
-		if (gpio_is_mmp_type(gpio_type))
+		if (info->ed_mask)
 			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
 	}
 
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index d755b28..bc5cae5 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -14,6 +14,7 @@ extern int pxa_last_gpio;
 extern int pxa_irq_to_gpio(int irq);
 
 struct pxa_gpio_platform_data {
+	bool ed_mask;	/* true means that ed_mask reg is available */
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-13 14:18   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
MMP_GPIO_TO_IRQ().

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-pxa/pxa25x.c |    2 +-
 arch/arm/mach-pxa/pxa27x.c |    2 +-
 drivers/gpio/Kconfig       |    1 +
 drivers/gpio/gpio-pxa.c    |  156 ++++++++++++++++++++++----------------------
 include/linux/gpio-pxa.h   |    4 +-
 5 files changed, 85 insertions(+), 80 deletions(-)

diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 3f5171e..f4c293a 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -289,7 +289,7 @@ static inline void pxa25x_init_pm(void) {}
 
 static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	uint32_t mask = 0;
 
 	if (gpio >= 0 && gpio < 85)
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 69985b06..67f5fd2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -364,7 +364,7 @@ static inline void pxa27x_init_pm(void) {}
  */
 static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	uint32_t mask;
 
 	if (gpio >= 0 && gpio < 128)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 176fb3d..b8c0da8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -201,6 +201,7 @@ config GPIO_PL061
 config GPIO_PXA
 	bool "PXA GPIO support"
 	depends on ARCH_PXA || ARCH_MMP
+	select IRQ_DOMAIN
 	help
 	  Say yes here to support the PXA GPIO device
 
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index a4c6687..2310665 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -13,6 +13,7 @@
  */
 #include <linux/module.h>
 #include <linux/clk.h>
+#include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/gpio-pxa.h>
@@ -61,16 +62,15 @@
 #define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
 
 int pxa_last_gpio;
-static int irq_base;
 
 #ifdef CONFIG_OF
-static struct irq_domain *domain;
 static struct device_node *pxa_gpio_of_node;
 #endif
 
 struct pxa_gpio_chip {
 	struct gpio_chip chip;
 	void __iomem	*regbase;
+	unsigned int	irq_base;
 	char label[10];
 
 	unsigned long	irq_mask;
@@ -170,14 +170,22 @@ static inline int __gpio_is_occupied(unsigned gpio)
 	return ret;
 }
 
-static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 {
-	return chip->base + offset + irq_base;
+	struct pxa_gpio_chip *chip = NULL;
+
+	chip = container_of(gc, struct pxa_gpio_chip, chip);
+	return chip->irq_base + offset;
 }
 
-int pxa_irq_to_gpio(int irq)
+int pxa_irq_to_gpio(struct irq_data *d)
 {
-	return irq - irq_base;
+	struct pxa_gpio_chip *chip;
+	int gpio;
+
+	chip = (struct pxa_gpio_chip *)d->domain->host_data;
+	gpio = d->irq - chip->irq_base + chip->chip.base;
+	return gpio;
 }
 
 static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -250,47 +258,6 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
 }
 #endif
 
-static int pxa_init_gpio_chip(int gpio_end,
-					int (*set_wake)(unsigned int, unsigned int))
-{
-	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
-	struct pxa_gpio_chip *chips;
-
-	chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
-	if (chips == NULL) {
-		pr_err("%s: failed to allocate GPIO chips\n", __func__);
-		return -ENOMEM;
-	}
-
-	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
-		struct gpio_chip *c = &chips[i].chip;
-
-		sprintf(chips[i].label, "gpio-%d", i);
-		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
-		chips[i].set_wake = set_wake;
-
-		c->base  = gpio;
-		c->label = chips[i].label;
-
-		c->direction_input  = pxa_gpio_direction_input;
-		c->direction_output = pxa_gpio_direction_output;
-		c->get = pxa_gpio_get;
-		c->set = pxa_gpio_set;
-		c->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
-		c->of_node = pxa_gpio_of_node;
-		c->of_xlate = pxa_gpio_of_xlate;
-		c->of_gpio_n_cells = 2;
-#endif
-
-		/* number of GPIOs on last bank may be less than 32 */
-		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
-		gpiochip_add(c);
-	}
-	pxa_gpio_chips = chips;
-	return 0;
-}
-
 /* Update only those GRERx and GFERx edge detection register bits if those
  * bits are set in c->irq_mask
  */
@@ -309,7 +276,7 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
 static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
 	struct pxa_gpio_chip *c;
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	unsigned long gpdr, mask = GPIO_bit(gpio);
 
 	c = gpio_to_pxachip(gpio);
@@ -383,7 +350,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 
 static void pxa_ack_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 
 	writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
@@ -391,7 +358,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d)
 
 static void pxa_mask_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 	uint32_t grer, gfer;
 
@@ -405,7 +372,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
 
 static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 
 	if (c->set_wake)
@@ -416,7 +383,7 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 
 static void pxa_unmask_muxed_gpio(struct irq_data *d)
 {
-	int gpio = pxa_irq_to_gpio(d->irq);
+	int gpio = pxa_irq_to_gpio(d);
 	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 
 	c->irq_mask |= GPIO_bit(gpio);
@@ -469,13 +436,6 @@ static int pxa_gpio_nums(void)
 	return count;
 }
 
-#ifdef CONFIG_OF
-static struct of_device_id pxa_gpio_dt_ids[] = {
-	{ .compatible = "mrvl,pxa-gpio" },
-	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
-	{}
-};
-
 static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
@@ -485,11 +445,18 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
 	return 0;
 }
 
-const struct irq_domain_ops pxa_irq_domain_ops = {
+static const struct irq_domain_ops pxa_irq_domain_ops = {
 	.map	= pxa_irq_domain_map,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
+#ifdef CONFIG_OF
+static struct of_device_id pxa_gpio_dt_ids[] = {
+	{ .compatible = "mrvl,pxa-gpio" },
+	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+	{}
+};
+
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
 	int ret, nr_banks, nr_gpios;
@@ -528,14 +495,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	nr_gpios = nr_banks << 5;
 	pxa_last_gpio = nr_gpios - 1;
 
-	irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
-	if (irq_base < 0) {
-		dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
-		goto err;
-	}
-	domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
-				       &pxa_irq_domain_ops, NULL);
-	pxa_gpio_of_node = np;
 	return 0;
 err:
 	iounmap(gpio_reg_base);
@@ -545,6 +504,56 @@ err:
 #define pxa_gpio_probe_dt(pdev)		(-1)
 #endif
 
+static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
+			      int (*set_wake)(unsigned int, unsigned int))
+{
+	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+	struct pxa_gpio_chip *chips;
+
+	chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
+	if (chips == NULL) {
+		pr_err("%s: failed to allocate GPIO chips\n", __func__);
+		return -ENOMEM;
+	}
+
+	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
+		struct gpio_chip *c = &chips[i].chip;
+
+		sprintf(chips[i].label, "gpio-%d", i);
+		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
+		chips[i].set_wake = set_wake;
+
+		c->base  = gpio;
+		c->label = chips[i].label;
+
+		c->direction_input  = pxa_gpio_direction_input;
+		c->direction_output = pxa_gpio_direction_output;
+		c->get = pxa_gpio_get;
+		c->set = pxa_gpio_set;
+		c->to_irq = pxa_gpio_to_irq;
+#ifdef CONFIG_OF_GPIO
+		c->of_node = pxa_gpio_of_node;
+		c->of_xlate = pxa_gpio_of_xlate;
+		c->of_gpio_n_cells = 2;
+#endif
+
+		/* number of GPIOs on last bank may be less than 32 */
+		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+
+		chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
+		if (chips[i].irq_base < 0)
+			return -EINVAL;
+		if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
+					   chips[i].irq_base, 0,
+					   &pxa_irq_domain_ops, &chips[i]))
+			return -ENODEV;
+
+		gpiochip_add(c);
+	}
+	pxa_gpio_chips = chips;
+	return 0;
+}
+
 static int pxa_gpio_probe(struct platform_device *pdev)
 {
 	struct pxa_gpio_chip *c;
@@ -557,14 +566,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 	ret = pxa_gpio_probe_dt(pdev);
 	if (ret < 0) {
 		pxa_last_gpio = pxa_gpio_nums();
-#ifdef CONFIG_ARCH_PXA
-		if (gpio_is_pxa_type(gpio_type))
-			irq_base = PXA_GPIO_TO_IRQ(0);
-#endif
-#ifdef CONFIG_ARCH_MMP
-		if (gpio_is_mmp_type(gpio_type))
-			irq_base = MMP_GPIO_TO_IRQ(0);
-#endif
 	} else {
 		use_of = 1;
 	}
@@ -604,7 +605,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 
 	/* Initialize GPIO chips */
 	info = dev_get_platdata(&pdev->dev);
-	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
+	pxa_init_gpio_chip(pdev, pxa_last_gpio,
+			   info ? info->gpio_set_wake : NULL);
 
 	/* clear all GPIO edge detects */
 	for_each_gpio_chip(gpio, c) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index bc5cae5..49120b8 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -1,6 +1,8 @@
 #ifndef __GPIO_PXA_H
 #define __GPIO_PXA_H
 
+#include <linux/irq.h>
+
 #define GPIO_bit(x)	(1 << ((x) & 0x1f))
 
 #define gpio_to_bank(gpio)	((gpio) >> 5)
@@ -11,7 +13,7 @@
  */
 extern int pxa_last_gpio;
 
-extern int pxa_irq_to_gpio(int irq);
+extern int pxa_irq_to_gpio(struct irq_data *d);
 
 struct pxa_gpio_platform_data {
 	bool ed_mask;	/* true means that ed_mask reg is available */
-- 
1.7.10.4

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

* [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 02/10] gpio: pxa: avoid to use global irq base Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 04/10] gpio: pxa: remove gpio_type Haojian Zhuang
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid to judge whether gpio is inverted by identifying cpu in gpio
driver. Move this into platform data of gpio driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-pxa/pxa25x.c |    3 +++
 drivers/gpio/gpio-pxa.c    |   40 +++++++++++++++++++++++++---------------
 include/linux/gpio-pxa.h   |    1 +
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f4c293a..66dafb7 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -340,6 +340,9 @@ void __init pxa25x_map_io(void)
 }
 
 static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
+#ifdef CONFIG_CPU_PXA26x
+	.inverted = true,
+#endif
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 2310665..1f8dfc8 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -71,6 +71,7 @@ struct pxa_gpio_chip {
 	struct gpio_chip chip;
 	void __iomem	*regbase;
 	unsigned int	irq_base;
+	bool		inverted;
 	char label[10];
 
 	unsigned long	irq_mask;
@@ -126,9 +127,9 @@ static inline int gpio_is_mmp_type(int type)
 /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
  * as well as their Alternate Function value being '1' for GPIO in GAFRx.
  */
-static inline int __gpio_is_inverted(int gpio)
+static inline int __gpio_is_inverted(struct pxa_gpio_chip *chip, int gpio)
 {
-	if ((gpio_type == PXA26X_GPIO) && (gpio > 85))
+	if ((chip->inverted) && (gpio > 85))
 		return 1;
 	return 0;
 }
@@ -139,15 +140,13 @@ static inline int __gpio_is_inverted(int gpio)
  * is attributed as "occupied" here (I know this terminology isn't
  * accurate, you are welcome to propose a better one :-)
  */
-static inline int __gpio_is_occupied(unsigned gpio)
+static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
 {
-	struct pxa_gpio_chip *pxachip;
 	void __iomem *base;
 	unsigned long gafr = 0, gpdr = 0;
 	int ret, af = 0, dir = 0;
 
-	pxachip = gpio_to_pxachip(gpio);
-	base = gpio_chip_base(&pxachip->chip);
+	base = gpio_chip_base(&chip->chip);
 	gpdr = readl_relaxed(base + GPDR_OFFSET);
 
 	switch (gpio_type) {
@@ -158,7 +157,7 @@ static inline int __gpio_is_occupied(unsigned gpio)
 		af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
 		dir = gpdr & GPIO_bit(gpio);
 
-		if (__gpio_is_inverted(gpio))
+		if (__gpio_is_inverted(chip, gpio))
 			ret = (af != 1) || (dir == 0);
 		else
 			ret = (af != 0) || (dir != 0);
@@ -188,16 +187,19 @@ int pxa_irq_to_gpio(struct irq_data *d)
 	return gpio;
 }
 
-static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
 {
-	void __iomem *base = gpio_chip_base(chip);
+	struct pxa_gpio_chip *chip = NULL;
+	void __iomem *base = gpio_chip_base(gc);
 	uint32_t value, mask = 1 << offset;
 	unsigned long flags;
 
+	chip = container_of(gc, struct pxa_gpio_chip, chip);
+
 	spin_lock_irqsave(&gpio_lock, flags);
 
 	value = readl_relaxed(base + GPDR_OFFSET);
-	if (__gpio_is_inverted(chip->base + offset))
+	if (__gpio_is_inverted(chip, gc->base + offset))
 		value |= mask;
 	else
 		value &= ~mask;
@@ -207,19 +209,22 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 	return 0;
 }
 
-static int pxa_gpio_direction_output(struct gpio_chip *chip,
+static int pxa_gpio_direction_output(struct gpio_chip *gc,
 				     unsigned offset, int value)
 {
-	void __iomem *base = gpio_chip_base(chip);
+	struct pxa_gpio_chip *chip = NULL;
+	void __iomem *base = gpio_chip_base(gc);
 	uint32_t tmp, mask = 1 << offset;
 	unsigned long flags;
 
+	chip = container_of(gc, struct pxa_gpio_chip, chip);
+
 	writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
 
 	spin_lock_irqsave(&gpio_lock, flags);
 
 	tmp = readl_relaxed(base + GPDR_OFFSET);
-	if (__gpio_is_inverted(chip->base + offset))
+	if (__gpio_is_inverted(chip, gc->base + offset))
 		tmp &= ~mask;
 	else
 		tmp |= mask;
@@ -288,7 +293,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 		if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
 			return 0;
 
-		if (__gpio_is_occupied(gpio))
+		if (__gpio_is_occupied(c, gpio))
 			return 0;
 
 		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
@@ -296,7 +301,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 
 	gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
 
-	if (__gpio_is_inverted(gpio))
+	if (__gpio_is_inverted(c, gpio))
 		writel_relaxed(gpdr | mask,  c->regbase + GPDR_OFFSET);
 	else
 		writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
@@ -474,6 +479,9 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		return -ENOMEM;
 	if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
 		pdata->ed_mask = true;
+	/* It's only valid for PXA26x */
+	if (of_find_property(np, "marvell,gpio-inverted", NULL))
+		pdata->inverted = true;
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
 	gpio_type = (int)of_id->data;
@@ -616,6 +624,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 		/* unmask GPIO edge detect for AP side */
 		if (info->ed_mask)
 			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
+		/* update for gpio inverted */
+		c->inverted = info->inverted;
 	}
 
 	if (!use_of) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 49120b8..0c212a1 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -17,6 +17,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
 
 struct pxa_gpio_platform_data {
 	bool ed_mask;	/* true means that ed_mask reg is available */
+	bool inverted;	/* only valid for PXA26x */
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

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

* [PATCH v2 04/10] gpio: pxa: remove gpio_type
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (2 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data Haojian Zhuang
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Since gpio_type is used to check whether gafr register is valid. So
move it into platform data.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-pxa/pxa25x.c |    1 +
 arch/arm/mach-pxa/pxa27x.c |    1 +
 drivers/gpio/gpio-pxa.c    |   43 ++++++-------------------------------------
 include/linux/gpio-pxa.h   |    1 +
 4 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 66dafb7..3460de1 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -343,6 +343,7 @@ static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
 #ifdef CONFIG_CPU_PXA26x
 	.inverted = true,
 #endif
+	.gafr = true,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 67f5fd2..999d681 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -430,6 +430,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 }
 
 static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
+	.gafr = true,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 1f8dfc8..6c6e21c 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -72,6 +72,7 @@ struct pxa_gpio_chip {
 	void __iomem	*regbase;
 	unsigned int	irq_base;
 	bool		inverted;
+	bool		gafr;
 	char label[10];
 
 	unsigned long	irq_mask;
@@ -87,18 +88,8 @@ struct pxa_gpio_chip {
 #endif
 };
 
-enum {
-	PXA25X_GPIO = 0,
-	PXA26X_GPIO,
-	PXA27X_GPIO,
-	PXA3XX_GPIO,
-	PXA93X_GPIO,
-	MMP_GPIO = 0x10,
-};
-
 static DEFINE_SPINLOCK(gpio_lock);
 static struct pxa_gpio_chip *pxa_gpio_chips;
-static int gpio_type;
 static void __iomem *gpio_reg_base;
 
 #define for_each_gpio_chip(i, c)			\
@@ -114,16 +105,6 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
 	return &pxa_gpio_chips[gpio_to_bank(gpio)];
 }
 
-static inline int gpio_is_pxa_type(int type)
-{
-	return (type & MMP_GPIO) == 0;
-}
-
-static inline int gpio_is_mmp_type(int type)
-{
-	return (type & MMP_GPIO) != 0;
-}
-
 /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
  * as well as their Alternate Function value being '1' for GPIO in GAFRx.
  */
@@ -149,10 +130,7 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
 	base = gpio_chip_base(&chip->chip);
 	gpdr = readl_relaxed(base + GPDR_OFFSET);
 
-	switch (gpio_type) {
-	case PXA25X_GPIO:
-	case PXA26X_GPIO:
-	case PXA27X_GPIO:
+	if (chip->gafr) {
 		gafr = readl_relaxed(base + GAFR_OFFSET);
 		af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
 		dir = gpdr & GPIO_bit(gpio);
@@ -161,10 +139,8 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
 			ret = (af != 1) || (dir == 0);
 		else
 			ret = (af != 0) || (dir != 0);
-		break;
-	default:
+	} else {
 		ret = gpdr & GPIO_bit(gpio);
-		break;
 	}
 	return ret;
 }
@@ -412,30 +388,23 @@ static int pxa_gpio_nums(void)
 	if (cpu_is_pxa25x()) {
 #ifdef CONFIG_CPU_PXA26x
 		count = 89;
-		gpio_type = PXA26X_GPIO;
 #elif defined(CONFIG_PXA25x)
 		count = 84;
-		gpio_type = PXA26X_GPIO;
 #endif /* CONFIG_CPU_PXA26x */
 	} else if (cpu_is_pxa27x()) {
 		count = 120;
-		gpio_type = PXA27X_GPIO;
 	} else if (cpu_is_pxa93x()) {
 		count = 191;
-		gpio_type = PXA93X_GPIO;
 	} else if (cpu_is_pxa3xx()) {
 		count = 127;
-		gpio_type = PXA3XX_GPIO;
 	}
 #endif /* CONFIG_ARCH_PXA */
 
 #ifdef CONFIG_ARCH_MMP
 	if (cpu_is_pxa168() || cpu_is_pxa910()) {
 		count = 127;
-		gpio_type = MMP_GPIO;
 	} else if (cpu_is_mmp2()) {
 		count = 191;
-		gpio_type = MMP_GPIO;
 	}
 #endif /* CONFIG_ARCH_MMP */
 	return count;
@@ -458,7 +427,7 @@ static const struct irq_domain_ops pxa_irq_domain_ops = {
 #ifdef CONFIG_OF
 static struct of_device_id pxa_gpio_dt_ids[] = {
 	{ .compatible = "mrvl,pxa-gpio" },
-	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+	{ .compatible = "mrvl,mmp-gpio" },
 	{}
 };
 
@@ -484,7 +453,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		pdata->inverted = true;
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
-	gpio_type = (int)of_id->data;
 
 	next = of_get_next_child(np, NULL);
 	prev = next;
@@ -624,8 +592,9 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 		/* unmask GPIO edge detect for AP side */
 		if (info->ed_mask)
 			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
-		/* update for gpio inverted */
+		/* update for gpio inverted & gafr */
 		c->inverted = info->inverted;
+		c->gafr = info->gafr;
 	}
 
 	if (!use_of) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 0c212a1..80e0322 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -18,6 +18,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
 struct pxa_gpio_platform_data {
 	bool ed_mask;	/* true means that ed_mask reg is available */
 	bool inverted;	/* only valid for PXA26x */
+	bool gafr;	/* only valid for PXA25x/PXA26x/PXA27x */
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

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

* [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (3 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 04/10] gpio: pxa: remove gpio_type Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-03 13:18   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 06/10] gpio: pxa: clean code for compatible name Haojian Zhuang
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid to define gpio numbers in gpio driver. Define it in platform data
instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-mmp/aspenite.c      |    1 +
 arch/arm/mach-mmp/avengers_lite.c |    1 +
 arch/arm/mach-mmp/brownstone.c    |    1 +
 arch/arm/mach-mmp/flint.c         |    1 +
 arch/arm/mach-mmp/gplugd.c        |    1 +
 arch/arm/mach-mmp/tavorevb.c      |    1 +
 arch/arm/mach-mmp/teton_bga.c     |    1 +
 arch/arm/mach-mmp/ttc_dkb.c       |    1 +
 arch/arm/mach-pxa/pxa25x.c        |    3 +++
 arch/arm/mach-pxa/pxa27x.c        |    1 +
 arch/arm/mach-pxa/pxa3xx.c        |   15 +++++++++++-
 drivers/gpio/gpio-pxa.c           |   48 +++++++------------------------------
 include/linux/gpio-pxa.h          |    1 +
 13 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 36f5781..a3e42dc 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -112,6 +112,7 @@ static unsigned long common_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index b8fe447..1ea6502 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -34,6 +34,7 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index d6ea5c4..a32156f 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -106,6 +106,7 @@ static unsigned long brownstone_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.nr_gpios	= 192,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 0955f44..3f301b5 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -79,6 +79,7 @@ static unsigned long flint_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.nr_gpios	= 192,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 2315cce..019b178 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -129,6 +129,7 @@ static unsigned long gplugd_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index eaec649..6e8cf80 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -62,6 +62,7 @@ static unsigned long tavorevb_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 6682100..b5146bb 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -51,6 +51,7 @@ static unsigned long teton_bga_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 984d902..123a0bf 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -75,6 +75,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 3460de1..ff91660 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -342,6 +342,9 @@ void __init pxa25x_map_io(void)
 static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
 #ifdef CONFIG_CPU_PXA26x
 	.inverted = true,
+	.nr_gpios = 90,
+#else
+	.nr_gpios = 85,
 #endif
 	.gafr = true,
 	.gpio_set_wake = gpio_set_wake,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 999d681..4de9572 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -431,6 +431,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 
 static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
 	.gafr = true,
+	.nr_gpios = 121,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 656a1bb..a0cc797 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -435,6 +435,10 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 	pxa_register_device(&pxa3xx_device_i2c_power, info);
 }
 
+static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
+	.nr_gpios = 128,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&pxa_device_gpio,
 	&pxa27x_device_udc,
@@ -482,8 +486,17 @@ static int __init pxa3xx_init(void)
 		register_syscore_ops(&pxa3xx_mfp_syscore_ops);
 		register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
-		if (!of_have_populated_dt())
+		if (!of_have_populated_dt()) {
+			if (cpu_is_pxa93x())
+				pxa3xx_gpio_info.nr_gpios = 192;
+			ret = platform_device_add_data(&pxa_device_gpio,
+					&pxa3xx_gpio_info,
+					sizeof(struct pxa_gpio_platform_data);
+			if (ret < 0)
+				break;
+
 			ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+		}
 	}
 
 	return ret;
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 6c6e21c..8fbf4c6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -380,36 +380,6 @@ static struct irq_chip pxa_muxed_gpio_chip = {
 	.irq_set_wake	= pxa_gpio_set_wake,
 };
 
-static int pxa_gpio_nums(void)
-{
-	int count = 0;
-
-#ifdef CONFIG_ARCH_PXA
-	if (cpu_is_pxa25x()) {
-#ifdef CONFIG_CPU_PXA26x
-		count = 89;
-#elif defined(CONFIG_PXA25x)
-		count = 84;
-#endif /* CONFIG_CPU_PXA26x */
-	} else if (cpu_is_pxa27x()) {
-		count = 120;
-	} else if (cpu_is_pxa93x()) {
-		count = 191;
-	} else if (cpu_is_pxa3xx()) {
-		count = 127;
-	}
-#endif /* CONFIG_ARCH_PXA */
-
-#ifdef CONFIG_ARCH_MMP
-	if (cpu_is_pxa168() || cpu_is_pxa910()) {
-		count = 127;
-	} else if (cpu_is_mmp2()) {
-		count = 191;
-	}
-#endif /* CONFIG_ARCH_MMP */
-	return count;
-}
-
 static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
@@ -433,7 +403,7 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
 
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
-	int ret, nr_banks, nr_gpios;
+	int ret, nr_banks;
 	struct pxa_gpio_platform_data *pdata;
 	struct device_node *prev, *next, *np = pdev->dev.of_node;
 	const struct of_device_id *of_id =
@@ -451,6 +421,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	/* It's only valid for PXA26x */
 	if (of_find_property(np, "marvell,gpio-inverted", NULL))
 		pdata->inverted = true;
+	ret = of_property_read_u32(np, "marvell,nr-gpios", &pdata->nr_gpios);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "nr-gpios isn't specified\n");
+		return -ENOTSUPP;
+	}
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
 
@@ -468,8 +443,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		prev = next;
 	}
 	of_node_put(prev);
-	nr_gpios = nr_banks << 5;
-	pxa_last_gpio = nr_gpios - 1;
 
 	return 0;
 err:
@@ -540,14 +513,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
 	ret = pxa_gpio_probe_dt(pdev);
-	if (ret < 0) {
-		pxa_last_gpio = pxa_gpio_nums();
-	} else {
+	if (!ret)
 		use_of = 1;
-	}
-
-	if (!pxa_last_gpio)
-		return -EINVAL;
 
 	irq0 = platform_get_irq_byname(pdev, "gpio0");
 	irq1 = platform_get_irq_byname(pdev, "gpio1");
@@ -581,6 +548,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 
 	/* Initialize GPIO chips */
 	info = dev_get_platdata(&pdev->dev);
+	pxa_last_gpio = info->nr_gpios - 1;
 	pxa_init_gpio_chip(pdev, pxa_last_gpio,
 			   info ? info->gpio_set_wake : NULL);
 
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 80e0322..b357fdc 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
 	bool ed_mask;	/* true means that ed_mask reg is available */
 	bool inverted;	/* only valid for PXA26x */
 	bool gafr;	/* only valid for PXA25x/PXA26x/PXA27x */
+	unsigned nr_gpios;
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

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

* [PATCH v2 06/10] gpio: pxa: clean code for compatible name
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (4 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 07/10] gpio: pxa: remove arch related macro Haojian Zhuang
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Use compatible variable name in gpio pxa driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 drivers/gpio/gpio-pxa.c |  194 ++++++++++++++++++++++++-----------------------
 1 file changed, 98 insertions(+), 96 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 8fbf4c6..95561d6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -95,9 +95,9 @@ static void __iomem *gpio_reg_base;
 #define for_each_gpio_chip(i, c)			\
 	for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
 
-static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
+static inline void __iomem *gpio_chip_base(struct gpio_chip *gc)
 {
-	return container_of(c, struct pxa_gpio_chip, chip)->regbase;
+	return container_of(gc, struct pxa_gpio_chip, chip)->regbase;
 }
 
 static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
@@ -210,14 +210,14 @@ static int pxa_gpio_direction_output(struct gpio_chip *gc,
 	return 0;
 }
 
-static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
-	return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
+	return readl_relaxed(gpio_chip_base(gc) + GPLR_OFFSET) & (1 << offset);
 }
 
-static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static void pxa_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
-	writel_relaxed(1 << offset, gpio_chip_base(chip) +
+	writel_relaxed(1 << offset, gpio_chip_base(gc) +
 				(value ? GPSR_OFFSET : GPCR_OFFSET));
 }
 
@@ -242,57 +242,58 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
 /* Update only those GRERx and GFERx edge detection register bits if those
  * bits are set in c->irq_mask
  */
-static inline void update_edge_detect(struct pxa_gpio_chip *c)
+static inline void update_edge_detect(struct pxa_gpio_chip *chip)
 {
 	uint32_t grer, gfer;
 
-	grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask;
-	gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask;
-	grer |= c->irq_edge_rise & c->irq_mask;
-	gfer |= c->irq_edge_fall & c->irq_mask;
-	writel_relaxed(grer, c->regbase + GRER_OFFSET);
-	writel_relaxed(gfer, c->regbase + GFER_OFFSET);
+	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~chip->irq_mask;
+	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~chip->irq_mask;
+	grer |= chip->irq_edge_rise & chip->irq_mask;
+	gfer |= chip->irq_edge_fall & chip->irq_mask;
+	writel_relaxed(grer, chip->regbase + GRER_OFFSET);
+	writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
 }
 
 static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
-	struct pxa_gpio_chip *c;
+	struct pxa_gpio_chip *chip;
 	int gpio = pxa_irq_to_gpio(d);
 	unsigned long gpdr, mask = GPIO_bit(gpio);
 
-	c = gpio_to_pxachip(gpio);
+	chip = gpio_to_pxachip(gpio);
 
 	if (type == IRQ_TYPE_PROBE) {
 		/* Don't mess with enabled GPIOs using preconfigured edges or
 		 * GPIOs set to alternate function or to output during probe
 		 */
-		if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
+		if ((chip->irq_edge_rise | chip->irq_edge_fall)
+			& GPIO_bit(gpio))
 			return 0;
 
-		if (__gpio_is_occupied(c, gpio))
+		if (__gpio_is_occupied(chip, gpio))
 			return 0;
 
 		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
 	}
 
-	gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
+	gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
 
-	if (__gpio_is_inverted(c, gpio))
-		writel_relaxed(gpdr | mask,  c->regbase + GPDR_OFFSET);
+	if (__gpio_is_inverted(chip, gpio))
+		writel_relaxed(gpdr | mask,  chip->regbase + GPDR_OFFSET);
 	else
-		writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
+		writel_relaxed(gpdr & ~mask, chip->regbase + GPDR_OFFSET);
 
 	if (type & IRQ_TYPE_EDGE_RISING)
-		c->irq_edge_rise |= mask;
+		chip->irq_edge_rise |= mask;
 	else
-		c->irq_edge_rise &= ~mask;
+		chip->irq_edge_rise &= ~mask;
 
 	if (type & IRQ_TYPE_EDGE_FALLING)
-		c->irq_edge_fall |= mask;
+		chip->irq_edge_fall |= mask;
 	else
-		c->irq_edge_fall &= ~mask;
+		chip->irq_edge_fall &= ~mask;
 
-	update_edge_detect(c);
+	update_edge_detect(chip);
 
 	pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio,
 		((type & IRQ_TYPE_EDGE_RISING)  ? " rising"  : ""),
@@ -302,21 +303,21 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
 
 static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct pxa_gpio_chip *c;
+	struct pxa_gpio_chip *chip;
 	int loop, gpio, gpio_base, n;
 	unsigned long gedr;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct irq_chip *ic = irq_desc_get_chip(desc);
 
-	chained_irq_enter(chip, desc);
+	chained_irq_enter(ic, desc);
 
 	do {
 		loop = 0;
-		for_each_gpio_chip(gpio, c) {
-			gpio_base = c->chip.base;
+		for_each_gpio_chip(gpio, chip) {
+			gpio_base = chip->chip.base;
 
-			gedr = readl_relaxed(c->regbase + GEDR_OFFSET);
-			gedr = gedr & c->irq_mask;
-			writel_relaxed(gedr, c->regbase + GEDR_OFFSET);
+			gedr = readl_relaxed(chip->regbase + GEDR_OFFSET);
+			gedr = gedr & chip->irq_mask;
+			writel_relaxed(gedr, chip->regbase + GEDR_OFFSET);
 
 			for_each_set_bit(n, &gedr, BITS_PER_LONG) {
 				loop = 1;
@@ -326,38 +327,38 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	} while (loop);
 
-	chained_irq_exit(chip, desc);
+	chained_irq_exit(ic, desc);
 }
 
 static void pxa_ack_muxed_gpio(struct irq_data *d)
 {
 	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
 
-	writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
+	writel_relaxed(GPIO_bit(gpio), chip->regbase + GEDR_OFFSET);
 }
 
 static void pxa_mask_muxed_gpio(struct irq_data *d)
 {
 	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
 	uint32_t grer, gfer;
 
-	c->irq_mask &= ~GPIO_bit(gpio);
+	chip->irq_mask &= ~GPIO_bit(gpio);
 
-	grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
-	gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
-	writel_relaxed(grer, c->regbase + GRER_OFFSET);
-	writel_relaxed(gfer, c->regbase + GFER_OFFSET);
+	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
+	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+	writel_relaxed(grer, chip->regbase + GRER_OFFSET);
+	writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
 }
 
 static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 {
 	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
 
-	if (c->set_wake)
-		return c->set_wake(gpio, on);
+	if (chip->set_wake)
+		return chip->set_wake(gpio, on);
 	else
 		return 0;
 }
@@ -365,10 +366,10 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
 static void pxa_unmask_muxed_gpio(struct irq_data *d)
 {
 	int gpio = pxa_irq_to_gpio(d);
-	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
 
-	c->irq_mask |= GPIO_bit(gpio);
-	update_edge_detect(c);
+	chip->irq_mask |= GPIO_bit(gpio);
+	update_edge_detect(chip);
 }
 
 static struct irq_chip pxa_muxed_gpio_chip = {
@@ -466,38 +467,37 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 	}
 
 	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
-		struct gpio_chip *c = &chips[i].chip;
+		struct gpio_chip *gc = &chips[i].chip;
 
 		sprintf(chips[i].label, "gpio-%d", i);
 		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
 		chips[i].set_wake = set_wake;
 
-		c->base  = gpio;
-		c->label = chips[i].label;
-
-		c->direction_input  = pxa_gpio_direction_input;
-		c->direction_output = pxa_gpio_direction_output;
-		c->get = pxa_gpio_get;
-		c->set = pxa_gpio_set;
-		c->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
-		c->of_node = pxa_gpio_of_node;
-		c->of_xlate = pxa_gpio_of_xlate;
-		c->of_gpio_n_cells = 2;
-#endif
-
 		/* number of GPIOs on last bank may be less than 32 */
-		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+		gc->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
 
-		chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
+		chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
 		if (chips[i].irq_base < 0)
 			return -EINVAL;
-		if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
+		if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
 					   chips[i].irq_base, 0,
 					   &pxa_irq_domain_ops, &chips[i]))
 			return -ENODEV;
 
-		gpiochip_add(c);
+		gc->base  = gpio;
+		gc->label = chips[i].label;
+
+		gc->direction_input  = pxa_gpio_direction_input;
+		gc->direction_output = pxa_gpio_direction_output;
+		gc->get = pxa_gpio_get;
+		gc->set = pxa_gpio_set;
+		gc->to_irq = pxa_gpio_to_irq;
+#ifdef CONFIG_OF_GPIO
+		gc->of_node = pxa_gpio_of_node;
+		gc->of_xlate = pxa_gpio_of_xlate;
+		gc->of_gpio_n_cells = 2;
+#endif
+		gpiochip_add(gc);
 	}
 	pxa_gpio_chips = chips;
 	return 0;
@@ -505,10 +505,10 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 
 static int pxa_gpio_probe(struct platform_device *pdev)
 {
-	struct pxa_gpio_chip *c;
+	struct pxa_gpio_chip *chip;
 	struct resource *res;
 	struct clk *clk;
-	struct pxa_gpio_platform_data *info;
+	struct pxa_gpio_platform_data *pdata;
 	int gpio, irq, ret, use_of = 0;
 	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
@@ -547,22 +547,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 	}
 
 	/* Initialize GPIO chips */
-	info = dev_get_platdata(&pdev->dev);
-	pxa_last_gpio = info->nr_gpios - 1;
-	pxa_init_gpio_chip(pdev, pxa_last_gpio,
-			   info ? info->gpio_set_wake : NULL);
+	pdata = dev_get_platdata(&pdev->dev);
+	pxa_last_gpio = pdata->nr_gpios - 1;
+	ret = pxa_init_gpio_chip(pdev, pxa_last_gpio,
+				 pdata ? pdata->gpio_set_wake : NULL);
+	if (ret < 0)
+		return ret;
 
 	/* clear all GPIO edge detects */
-	for_each_gpio_chip(gpio, c) {
-		writel_relaxed(0, c->regbase + GFER_OFFSET);
-		writel_relaxed(0, c->regbase + GRER_OFFSET);
-		writel_relaxed(~0,c->regbase + GEDR_OFFSET);
+	for_each_gpio_chip(gpio, chip) {
+		writel_relaxed(0, chip->regbase + GFER_OFFSET);
+		writel_relaxed(0, chip->regbase + GRER_OFFSET);
+		writel_relaxed(~0,chip->regbase + GEDR_OFFSET);
 		/* unmask GPIO edge detect for AP side */
-		if (info->ed_mask)
-			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
+		if (pdata->ed_mask)
+			writel_relaxed(~0, chip->regbase + ED_MASK_OFFSET);
 		/* update for gpio inverted & gafr */
-		c->inverted = info->inverted;
-		c->gafr = info->gafr;
+		chip->inverted = pdata->inverted;
+		chip->gafr = pdata->gafr;
 	}
 
 	if (!use_of) {
@@ -604,34 +606,34 @@ module_platform_driver(pxa_gpio_driver);
 #ifdef CONFIG_PM
 static int pxa_gpio_suspend(void)
 {
-	struct pxa_gpio_chip *c;
+	struct pxa_gpio_chip *chip;
 	int gpio;
 
-	for_each_gpio_chip(gpio, c) {
-		c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET);
-		c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
-		c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET);
-		c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET);
+	for_each_gpio_chip(gpio, chip) {
+		chip->saved_gplr = readl_relaxed(chip->regbase + GPLR_OFFSET);
+		chip->saved_gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
+		chip->saved_grer = readl_relaxed(chip->regbase + GRER_OFFSET);
+		chip->saved_gfer = readl_relaxed(chip->regbase + GFER_OFFSET);
 
 		/* Clear GPIO transition detect bits */
-		writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET);
+		writel_relaxed(~0, chip->regbase + GEDR_OFFSET);
 	}
 	return 0;
 }
 
 static void pxa_gpio_resume(void)
 {
-	struct pxa_gpio_chip *c;
+	struct pxa_gpio_chip *chip;
 	int gpio;
 
-	for_each_gpio_chip(gpio, c) {
+	for_each_gpio_chip(gpio, chip) {
 		/* restore level with set/clear */
-		writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET);
-		writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET);
+		writel_relaxed( chip->saved_gplr, chip->regbase + GPSR_OFFSET);
+		writel_relaxed(~chip->saved_gplr, chip->regbase + GPCR_OFFSET);
 
-		writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET);
-		writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET);
-		writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET);
+		writel_relaxed(chip->saved_grer, chip->regbase + GRER_OFFSET);
+		writel_relaxed(chip->saved_gfer, chip->regbase + GFER_OFFSET);
+		writel_relaxed(chip->saved_gpdr, chip->regbase + GPDR_OFFSET);
 	}
 }
 #else
-- 
1.7.10.4

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

* [PATCH v2 07/10] gpio: pxa: remove arch related macro
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (5 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 06/10] gpio: pxa: clean code for compatible name Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 08/10] gpio: pxa: move gpio properties into child node Haojian Zhuang
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Remove macro CONFIG_ARCH_PXA.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 drivers/gpio/gpio-pxa.c |   30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 95561d6..8130e3b 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -568,21 +568,21 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 	}
 
 	if (!use_of) {
-#ifdef CONFIG_ARCH_PXA
-		irq = gpio_to_irq(0);
-		irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-					 handle_edge_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
-
-		irq = gpio_to_irq(1);
-		irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
-					 handle_edge_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
-#endif
-
-		for (irq  = gpio_to_irq(gpio_offset);
+		if (irq0 > 0) {
+			irq = gpio_to_irq(0);
+			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+						 handle_edge_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+			irq_set_chained_handler(irq0, pxa_gpio_demux_handler);
+		}
+		if (irq1 > 0) {
+			irq = gpio_to_irq(1);
+			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+						 handle_edge_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+			irq_set_chained_handler(irq1, pxa_gpio_demux_handler);
+		}
+		for (irq = gpio_to_irq(gpio_offset);
 			irq <= gpio_to_irq(pxa_last_gpio); irq++) {
 			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
 						 handle_edge_irq);
-- 
1.7.10.4

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

* [PATCH v2 08/10] gpio: pxa: move gpio properties into child node
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (6 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 07/10] gpio: pxa: remove arch related macro Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-03 10:15 ` [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request Haojian Zhuang
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Move gpio properties into child node. So pinctrl driver could binds to
each gpio chip with gpio range.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 drivers/gpio/gpio-pxa.c |   45 +++++++++++++++++----------------------------
 1 file changed, 17 insertions(+), 28 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 8130e3b..5c39db3 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -63,10 +63,6 @@
 
 int pxa_last_gpio;
 
-#ifdef CONFIG_OF
-static struct device_node *pxa_gpio_of_node;
-#endif
-
 struct pxa_gpio_chip {
 	struct gpio_chip chip;
 	void __iomem	*regbase;
@@ -404,9 +400,9 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
 
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
-	int ret, nr_banks;
+	int ret;
 	struct pxa_gpio_platform_data *pdata;
-	struct device_node *prev, *next, *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *of_id =
 				of_match_device(pxa_gpio_dt_ids, &pdev->dev);
 
@@ -430,25 +426,7 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
 
-	next = of_get_next_child(np, NULL);
-	prev = next;
-	if (!next) {
-		dev_err(&pdev->dev, "Failed to find child gpio node\n");
-		ret = -EINVAL;
-		goto err;
-	}
-	for (nr_banks = 1; ; nr_banks++) {
-		next = of_get_next_child(np, prev);
-		if (!next)
-			break;
-		prev = next;
-	}
-	of_node_put(prev);
-
 	return 0;
-err:
-	iounmap(gpio_reg_base);
-	return ret;
 }
 #else
 #define pxa_gpio_probe_dt(pdev)		(-1)
@@ -459,6 +437,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 {
 	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
 	struct pxa_gpio_chip *chips;
+	struct device_node *next = NULL, *np = NULL;
 
 	chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
 	if (chips == NULL) {
@@ -466,6 +445,11 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		return -ENOMEM;
 	}
 
+	np = pdev->dev.of_node;
+#ifdef CONFIG_OF
+	if (np)
+		next = of_get_next_child(np, NULL);
+#endif
 	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
 		struct gpio_chip *gc = &chips[i].chip;
 
@@ -492,13 +476,18 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		gc->get = pxa_gpio_get;
 		gc->set = pxa_gpio_set;
 		gc->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
-		gc->of_node = pxa_gpio_of_node;
-		gc->of_xlate = pxa_gpio_of_xlate;
-		gc->of_gpio_n_cells = 2;
+#ifdef CONFIG_OF
+		if (np) {
+			gc->of_node = next;
+			next = of_get_next_child(np, next);
+
+			gc->of_xlate = pxa_gpio_of_xlate;
+			gc->of_gpio_n_cells = 2;
+		}
 #endif
 		gpiochip_add(gc);
 	}
+	of_node_put(next);
 	pxa_gpio_chips = chips;
 	return 0;
 }
-- 
1.7.10.4

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

* [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (7 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 08/10] gpio: pxa: move gpio properties into child node Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-06 14:11   ` Igor Grinberg
  2013-02-07 15:17   ` Igor Grinberg
  2013-02-03 10:15 ` [PATCH v2 10/10] ARM: dts: support pinmux in pxa910 Haojian Zhuang
  2013-02-05 16:44 ` [PATCH v2 00/10] rework pxa gpio driver for pinctrl Linus Walleij
  10 siblings, 2 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

While gpio pins is requested, request the pin of pinctrl driver first.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 drivers/gpio/gpio-pxa.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 5c39db3..c9cc636 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
 #include <linux/slab.h>
@@ -159,6 +160,23 @@ int pxa_irq_to_gpio(struct irq_data *d)
 	return gpio;
 }
 
+static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
+{
+	/*
+	 * Map back to global GPIO space and request muxing, the direction
+	 * parameter does not matter for this controller.
+	 */
+	int gpio = gc->base + offset;
+
+	/*
+	 * Platforms in ARCH_PXA doesn't move to device tree yet,
+	 * and PINCTRL_SINGLE is depend on device tree.
+	 */ 
+	if (IS_ENABLED(CONFIG_PINCTRL_SINGLE))
+		return pinctrl_request_gpio(gpio);
+	return 0;
+}
+
 static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
 {
 	struct pxa_gpio_chip *chip = NULL;
@@ -471,6 +489,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		gc->base  = gpio;
 		gc->label = chips[i].label;
 
+		gc->request = pxa_gpio_request;
 		gc->direction_input  = pxa_gpio_direction_input;
 		gc->direction_output = pxa_gpio_direction_output;
 		gc->get = pxa_gpio_get;
-- 
1.7.10.4

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

* [PATCH v2 10/10] ARM: dts: support pinmux in pxa910
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (8 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request Haojian Zhuang
@ 2013-02-03 10:15 ` Haojian Zhuang
  2013-02-06 14:12   ` Igor Grinberg
  2013-02-05 16:44 ` [PATCH v2 00/10] rework pxa gpio driver for pinctrl Linus Walleij
  10 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio range, pinmux settings in pxa910 dkb DTS file.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/boot/dts/pxa910-dkb.dts |  264 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/pxa910.dtsi    |   29 ++++-
 2 files changed, 291 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..72eb6bc 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -170,6 +170,270 @@
 			rtc: rtc at d4010000 {
 				status = "okay";
 			};
+			gpio-keys {
+				compatible = "gpio-keys";
+
+				/* in6, out3, out4 */
+				right {
+					label = "right";
+					gpios = <&gcb0 12 0>;
+					linux,code = <106>;	/* KEY_RIGHT */
+				};
+				num5 {
+					label = "5";
+					gpios = <&gcb0 4 0>;
+					linux,code = <6>;	/* KEY_5 */
+				};
+			};
+			gpio at d4019000 {
+				status = "okay";
+
+				/*
+				 * In theorical, some gpios could be routed to
+				 * multiple pins. So define the gpio-ranges in
+				 * board file, not silicon file.
+				 */
+				gcb0: gpio at d4019000 {
+					/* <gpio_offset, pin_offset, nr_pins> */
+					gpio-ranges = <&pmx 0 55 32>;
+				};
+				gcb1: gpio at d4019004 {
+					/* <gpio_offset, pin_offset, nr_pins> */
+					gpio-ranges = <&pmx 0 87 23 &pmx 23 188 9>;
+				};
+				gcb2: gpio at d4019008 {
+					/* <gpio_offset, pin_offset, nr_pins> */
+					gpio-ranges = <&pmx 0 197 3 &pmx 3 110 29>;
+				};
+				gcb3: gpio at d4019100 {
+					/* <gpio_offset, pin_offset, nr_pins> */
+					gpio-ranges = < &pmx 0 139 14 &pmx 14 166 7
+							&pmx 21 45 4 &pmx 25 203 1
+							&pmx 26 50 4 &pmx 30 27 2>;
+				};
+			};
+			pmx: pinmux at d401e000 {
+				/* pin base, nr pins & gpio function */
+				pinctrl-single,gpio-range = <
+					/*
+					 * GPIO number is hardcoded for range@here.
+					 * In gpio chip, GPIO number is not hardcoded for range.
+					 * Since one gpio pin may be routed to multiple pins,
+					 * define these gpio range in pxa910-dkb.dts not pxa910.dtsi.
+					 */
+						&range 55 55 0	/* GPIO0 ~ GPIO54 */
+						&range 188 5 1	/* GPIO55 ~ GPIO59 */ 
+						&range 193 7 0	/* GPIO60 ~ GPIO66 */
+						&range 110 43 0	/* GPIO67 ~ GPIO109 */
+						&range 166 7 0	/* GPIO110 ~ GPIO116 */
+						&range 45 4 0	/* GPIO117 ~ GPIO120 */
+						&range 50 2 1	/* GPIO122 ~ GPIO123 */
+						&range 203 1 0	/* GPIO121 */
+						&range 52 1 0	/* GPIO124 */
+						&range 53 1 1	/* GPIO125 */
+						&range 27 2 0	/* GPIO126 ~ GPIO127 */
+					>;
+
+				pinctrl-names = "default";
+				pinctrl-0 = <&keypad_pmx_func>;
+
+				uart1_pmx_func: pinmux_uart1_pins at 0 {
+					pinctrl-single,pins = <
+						0x198 0x6	/* GPIO47_UART1_RXD */
+						0x19c 0x6	/* GPIO48_UART1_TXD */
+					>;
+					/* slew rate set value, mask */
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					/* bias set value, match, mask */
+					pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x4000 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					/* input schmitt set value, mask */
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					/* input schmitt disable value, match, mask */
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				uart2_pmx_func: pinmux_uart2_pins at 0 {
+					pinctrl-single,pins = <
+						0x150 0x4	/* GPIO29_UART2_CTS */
+						0x154 0x4	/* GPIO30_UART2_RTS */
+						0x158 0x4	/* GPIO31_UART2_TXD */
+						0x15c 0x4	/* GPIO32_UART2_RXD */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				uart3_pmx_func: pinmux_uart3_pins at 0 {
+					pinctrl-single,pins = <
+						0x188 0x7	/* GPIO43_UART3_RXD */
+						0x18c 0x7	/* GPIO44_UART3_TXD */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				twsi1_pmx_func: pinmux_twsi1_pins at 0 {
+					pinctrl-single,pins = <
+						0x1b0 0x2	/* GPIO53_TWSI_SCL */
+						0x1b4 0x2	/* GPIO54_TWSI_SDA */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				nand_pmx_func: pinmux_nand_pins at 0 {
+					pinctrl-single,pins = <
+						0x040 0x0	/* ND_IO0 */
+						0x03c 0x0	/* ND_IO1 */
+						0x038 0x0	/* ND_IO2 */
+						0x034 0x0	/* ND_IO3 */
+						0x030 0x0	/* ND_IO4 */
+						0x02c 0x0	/* ND_IO5 */
+						0x028 0x0	/* ND_IO6 */
+						0x024 0x0	/* ND_IO7 */
+						0x020 0x0	/* ND_IO8 */
+						0x01c 0x0	/* ND_IO9 */
+						0x018 0x0	/* ND_IO10 */
+						0x014 0x0	/* ND_IO11 */
+						0x010 0x0	/* ND_IO12 */
+						0x00c 0x0	/* ND_IO13 */
+						0x008 0x0	/* ND_IO14 */
+						0x004 0x0	/* ND_IO15 */
+						0x044 0x0	/* ND_nCS0 */
+						0x060 0x1	/* ND_ALE */
+						0x05c 0x0	/* ND_CLE */
+						0x054 0x1	/* ND_nWE */
+						0x058 0x1	/* ND_nRE */
+						0x068 0x0	/* ND_RDY0 */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				mmc1_pmx_func1: pinmux_mmc1_pins at 0 {
+					pinctrl-single,pins = <
+						0x0a0 0x0	/* MMC1_DATA0 */
+						0x09c 0x0	/* MMC1_DATA1 */
+						0x098 0x0	/* MMC1_DATA2 */
+						0x094 0x0	/* MMC1_DATA3 */
+						0x090 0x0	/* MMC1_DATA4 */
+						0x08c 0x0	/* MMC1_DATA5 */
+						0x088 0x0	/* MMC1_DATA6 */
+						0x084 0x0	/* MMC1_DATA7 */
+						0x0a4 0x0	/* MMC1_CMD */
+						0x0a8 0x0	/* MMC1_CLK */
+					>;
+					pinctrl-single,slew-rate = <0x1800 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				mmc1_pmx_func2: pinmux_mmc1_pins at 1 {
+					pinctrl-single,pins = <
+						0x0ac 0x0	/* MMC1_CD */
+						0x0b0 0x0	/* MMC1_WP */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				mmc2_pmx_func: pinmux_mmc2_pins at 0 {
+					pinctrl-single,pins = <
+						0x180 0x1	/* MMC2_CMD */
+						0x184 0x1	/* MMC2_CLK */
+						0x17c 0x1	/* MMC2_DATA0 */
+						0x178 0x1	/* MMC2_DATA1 */
+						0x174 0x1	/* MMC2_DATA2 */
+						0x170 0x1	/* MMC2_DATA3 */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				ssp1_pmx_func: pinmux_ssp1_pins at 0 {
+					pinctrl-single,pins = <
+						0x130 0x1	/* GPIO21_SSP1_SCLK */
+						0x134 0x1	/* GPIO22_SSP1_FRM */
+						0x138 0x1	/* GPIO23_SSP1_TXD */
+						0x13c 0x1	/* GPIO24_SSP1_RXD */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				keypad_pmx_func: pinmux_keypad_pins at 0 {
+					pinctrl-single,pins = <
+						0x0dc 0x1	/* GPIO0_MKIN0 */
+						0x0e0 0x1	/* GPIO1_MKOUT0 */
+						0x0e4 0x1	/* GPIO2_MKIN1 */
+						0x0e8 0x1	/* GPIO3_MKOUT1 */
+						0x0ec 0x1	/* GPIO4_MKIN2 */
+						0x0f0 0x1	/* GPIO5_MKOUT2 */
+						0x0f4 0x1	/* GPIO6_MKIN3 */
+						0x0f8 0x1	/* GPIO7_MKOUT3 */
+						0x0fc 0x1	/* GPIO8_MKIN4 */
+						0x100 0x1	/* GPIO9_MKOUT4 */
+						0x10c 0x1	/* GPIO12_MKIN6 */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x2000 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				nfc_pmx_func: pinmux_nfc_pins at 0 {
+					pinctrl-single,pins = <
+						0x120 0x0	/* GPIO17 */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+				wlan_pmx_func: pinmux_wlan_pins at 0 {
+					pinctrl-single,pins = <
+						0x114 0x0	/* GPIO14 */
+						0x12c 0x0	/* GPIO20 */
+						0x160 0x0	/* GPIO33 */
+						0x164 0x0	/* GPIO34 */
+						0x168 0x0	/* GPIO35 */
+						0x16c 0x0	/* GPIO36 */
+					>;
+					pinctrl-single,slew-rate = <0x1000 0x1800>;
+					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+					pinctrl-single,input-schmitt = <0x40 0x70>;
+					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+				};
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 825aaca..20a3418 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -93,28 +93,37 @@
 				#address-cells = <1>;
 				#size-cells = <1>;
 				reg = <0xd4019000 0x1000>;
-				gpio-controller;
-				#gpio-cells = <2>;
+				marvell,gpio-ed-mask = <1>;
+				marvell,nr-gpios = <128>;
 				interrupts = <49>;
 				interrupt-names = "gpio_mux";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+				status = "disabled";
 				ranges;
 
 				gcb0: gpio at d4019000 {
 					reg = <0xd4019000 0x4>;
+					gpio-controller;
+					#gpio-cells = <2>;
 				};
 
 				gcb1: gpio at d4019004 {
 					reg = <0xd4019004 0x4>;
+					gpio-controller;
+					#gpio-cells = <2>;
 				};
 
 				gcb2: gpio at d4019008 {
 					reg = <0xd4019008 0x4>;
+					gpio-controller;
+					#gpio-cells = <2>;
 				};
 
 				gcb3: gpio at d4019100 {
 					reg = <0xd4019100 0x4>;
+					gpio-controller;
+					#gpio-cells = <2>;
 				};
 			};
 
@@ -144,6 +153,22 @@
 				interrupt-names = "rtc 1Hz", "rtc alarm";
 				status = "disabled";
 			};
+
+			pmx: pinmux at d401e000 {
+				compatible = "pinconf-single";
+				reg = <0xd401e000 0x330>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				#gpio-range-cells = <3>;
+				ranges;
+
+				pinctrl-single,register-width = <32>;
+				pinctrl-single,function-mask = <7>;
+
+				range: gpio-range {
+					#pinctrl-single,gpio-range-cells = <3>;
+				};
+			};
 		};
 	};
 };
-- 
1.7.10.4

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

* [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data
  2013-02-03 10:15 ` [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data Haojian Zhuang
@ 2013-02-03 13:18   ` Igor Grinberg
  2013-02-03 15:00     ` [PATCH v2 05/11] " Haojian Zhuang
  2013-02-03 15:03     ` [PATCH v2 05/10] " Haojian Zhuang
  0 siblings, 2 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-03 13:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

On 02/03/13 12:15, Haojian Zhuang wrote:
> Avoid to define gpio numbers in gpio driver. Define it in platform data
> instead.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Same comments as for previous version...

> ---
>  arch/arm/mach-mmp/aspenite.c      |    1 +
>  arch/arm/mach-mmp/avengers_lite.c |    1 +
>  arch/arm/mach-mmp/brownstone.c    |    1 +
>  arch/arm/mach-mmp/flint.c         |    1 +
>  arch/arm/mach-mmp/gplugd.c        |    1 +
>  arch/arm/mach-mmp/tavorevb.c      |    1 +
>  arch/arm/mach-mmp/teton_bga.c     |    1 +
>  arch/arm/mach-mmp/ttc_dkb.c       |    1 +
>  arch/arm/mach-pxa/pxa25x.c        |    3 +++
>  arch/arm/mach-pxa/pxa27x.c        |    1 +
>  arch/arm/mach-pxa/pxa3xx.c        |   15 +++++++++++-
>  drivers/gpio/gpio-pxa.c           |   48 +++++++------------------------------
>  include/linux/gpio-pxa.h          |    1 +
>  13 files changed, 35 insertions(+), 41 deletions(-)

[...]

> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
> index 656a1bb..a0cc797 100644
> --- a/arch/arm/mach-pxa/pxa3xx.c
> +++ b/arch/arm/mach-pxa/pxa3xx.c
> @@ -435,6 +435,10 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
>  	pxa_register_device(&pxa3xx_device_i2c_power, info);
>  }
>  
> +static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
> +	.nr_gpios = 128,
> +};
> +

missing 
#include <linux/gpio-pxa.h>

>  static struct platform_device *devices[] __initdata = {
>  	&pxa_device_gpio,
>  	&pxa27x_device_udc,
> @@ -482,8 +486,17 @@ static int __init pxa3xx_init(void)
>  		register_syscore_ops(&pxa3xx_mfp_syscore_ops);
>  		register_syscore_ops(&pxa3xx_clock_syscore_ops);
>  
> -		if (!of_have_populated_dt())
> +		if (!of_have_populated_dt()) {
> +			if (cpu_is_pxa93x())
> +				pxa3xx_gpio_info.nr_gpios = 192;
> +			ret = platform_device_add_data(&pxa_device_gpio,
> +					&pxa3xx_gpio_info,
> +					sizeof(struct pxa_gpio_platform_data);

Closing parenthesis is missing...

> +			if (ret < 0)
> +				break;
> +
>  			ret = platform_add_devices(devices, ARRAY_SIZE(devices));
> +		}
>  	}
>  
>  	return ret;

[...]


-- 
Regards,
Igor.

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

* [PATCH v2 05/11] gpio: pxa: define nr gpios in platform data
  2013-02-03 13:18   ` Igor Grinberg
@ 2013-02-03 15:00     ` Haojian Zhuang
  2013-02-07 15:17       ` Igor Grinberg
  2013-02-03 15:03     ` [PATCH v2 05/10] " Haojian Zhuang
  1 sibling, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

Avoid to define gpio numbers in gpio driver. Define it in platform data
instead.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-mmp/aspenite.c      |    1 +
 arch/arm/mach-mmp/avengers_lite.c |    1 +
 arch/arm/mach-mmp/brownstone.c    |    1 +
 arch/arm/mach-mmp/flint.c         |    1 +
 arch/arm/mach-mmp/gplugd.c        |    1 +
 arch/arm/mach-mmp/tavorevb.c      |    1 +
 arch/arm/mach-mmp/teton_bga.c     |    1 +
 arch/arm/mach-mmp/ttc_dkb.c       |    1 +
 arch/arm/mach-pxa/pxa25x.c        |    3 +++
 arch/arm/mach-pxa/pxa27x.c        |    1 +
 arch/arm/mach-pxa/pxa3xx.c        |   17 +++++++++++--
 drivers/gpio/gpio-pxa.c           |   48 +++++++------------------------------
 include/linux/gpio-pxa.h          |    1 +
 13 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 36f5781..a3e42dc 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -112,6 +112,7 @@ static unsigned long common_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index b8fe447..1ea6502 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -34,6 +34,7 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index d6ea5c4..a32156f 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -106,6 +106,7 @@ static unsigned long brownstone_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.nr_gpios	= 192,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 0955f44..3f301b5 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -79,6 +79,7 @@ static unsigned long flint_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+	.nr_gpios	= 192,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 2315cce..019b178 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -129,6 +129,7 @@ static unsigned long gplugd_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index eaec649..6e8cf80 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -62,6 +62,7 @@ static unsigned long tavorevb_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 6682100..b5146bb 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -51,6 +51,7 @@ static unsigned long teton_bga_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 984d902..123a0bf 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -75,6 +75,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
 };
 
 static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+	.nr_gpios	= 128,
 	.ed_mask	= true,
 };
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 3460de1..ff91660 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -342,6 +342,9 @@ void __init pxa25x_map_io(void)
 static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
 #ifdef CONFIG_CPU_PXA26x
 	.inverted = true,
+	.nr_gpios = 90,
+#else
+	.nr_gpios = 85,
 #endif
 	.gafr = true,
 	.gpio_set_wake = gpio_set_wake,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 999d681..4de9572 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -431,6 +431,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 
 static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
 	.gafr = true,
+	.nr_gpios = 121,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 656a1bb..f6bff16 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/gpio-pxa.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
@@ -435,6 +436,10 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 	pxa_register_device(&pxa3xx_device_i2c_power, info);
 }
 
+static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
+	.nr_gpios = 128,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&pxa_device_gpio,
 	&pxa27x_device_udc,
@@ -482,8 +487,16 @@ static int __init pxa3xx_init(void)
 		register_syscore_ops(&pxa3xx_mfp_syscore_ops);
 		register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
-		if (!of_have_populated_dt())
-			ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+		if (!of_have_populated_dt()) {
+			if (cpu_is_pxa93x())
+				pxa3xx_gpio_info.nr_gpios = 192;
+			ret = platform_device_add_data(&pxa_device_gpio,
+					&pxa3xx_gpio_info,
+					sizeof(struct pxa_gpio_platform_data));
+			if (!ret)
+				ret = platform_add_devices(devices,
+							   ARRAY_SIZE(devices));
+		}
 	}
 
 	return ret;
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 6c6e21c..8fbf4c6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -380,36 +380,6 @@ static struct irq_chip pxa_muxed_gpio_chip = {
 	.irq_set_wake	= pxa_gpio_set_wake,
 };
 
-static int pxa_gpio_nums(void)
-{
-	int count = 0;
-
-#ifdef CONFIG_ARCH_PXA
-	if (cpu_is_pxa25x()) {
-#ifdef CONFIG_CPU_PXA26x
-		count = 89;
-#elif defined(CONFIG_PXA25x)
-		count = 84;
-#endif /* CONFIG_CPU_PXA26x */
-	} else if (cpu_is_pxa27x()) {
-		count = 120;
-	} else if (cpu_is_pxa93x()) {
-		count = 191;
-	} else if (cpu_is_pxa3xx()) {
-		count = 127;
-	}
-#endif /* CONFIG_ARCH_PXA */
-
-#ifdef CONFIG_ARCH_MMP
-	if (cpu_is_pxa168() || cpu_is_pxa910()) {
-		count = 127;
-	} else if (cpu_is_mmp2()) {
-		count = 191;
-	}
-#endif /* CONFIG_ARCH_MMP */
-	return count;
-}
-
 static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
@@ -433,7 +403,7 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
 
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
-	int ret, nr_banks, nr_gpios;
+	int ret, nr_banks;
 	struct pxa_gpio_platform_data *pdata;
 	struct device_node *prev, *next, *np = pdev->dev.of_node;
 	const struct of_device_id *of_id =
@@ -451,6 +421,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	/* It's only valid for PXA26x */
 	if (of_find_property(np, "marvell,gpio-inverted", NULL))
 		pdata->inverted = true;
+	ret = of_property_read_u32(np, "marvell,nr-gpios", &pdata->nr_gpios);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "nr-gpios isn't specified\n");
+		return -ENOTSUPP;
+	}
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
 
@@ -468,8 +443,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		prev = next;
 	}
 	of_node_put(prev);
-	nr_gpios = nr_banks << 5;
-	pxa_last_gpio = nr_gpios - 1;
 
 	return 0;
 err:
@@ -540,14 +513,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
 	ret = pxa_gpio_probe_dt(pdev);
-	if (ret < 0) {
-		pxa_last_gpio = pxa_gpio_nums();
-	} else {
+	if (!ret)
 		use_of = 1;
-	}
-
-	if (!pxa_last_gpio)
-		return -EINVAL;
 
 	irq0 = platform_get_irq_byname(pdev, "gpio0");
 	irq1 = platform_get_irq_byname(pdev, "gpio1");
@@ -581,6 +548,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
 
 	/* Initialize GPIO chips */
 	info = dev_get_platdata(&pdev->dev);
+	pxa_last_gpio = info->nr_gpios - 1;
 	pxa_init_gpio_chip(pdev, pxa_last_gpio,
 			   info ? info->gpio_set_wake : NULL);
 
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 80e0322..b357fdc 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
 	bool ed_mask;	/* true means that ed_mask reg is available */
 	bool inverted;	/* only valid for PXA26x */
 	bool gafr;	/* only valid for PXA25x/PXA26x/PXA27x */
+	unsigned nr_gpios;
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

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

* [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data
  2013-02-03 13:18   ` Igor Grinberg
  2013-02-03 15:00     ` [PATCH v2 05/11] " Haojian Zhuang
@ 2013-02-03 15:03     ` Haojian Zhuang
  1 sibling, 0 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-03 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 February 2013 21:18, Igor Grinberg <grinberg@compulab.co.il> wrote:
> Hi Haojian,
>
> On 02/03/13 12:15, Haojian Zhuang wrote:
>> Avoid to define gpio numbers in gpio driver. Define it in platform data
>> instead.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> Same comments as for previous version...
>

Thank you for your checking. Now I fix this issue.

Best Regards
Haojian

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

* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
  2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
                   ` (9 preceding siblings ...)
  2013-02-03 10:15 ` [PATCH v2 10/10] ARM: dts: support pinmux in pxa910 Haojian Zhuang
@ 2013-02-05 16:44 ` Linus Walleij
  2013-02-06  2:08   ` Haojian Zhuang
  10 siblings, 1 reply; 34+ messages in thread
From: Linus Walleij @ 2013-02-05 16:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 3, 2013 at 11:15 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> v2:
> * Fix the build issue without CONFIG_OF
> * Append to check PINCTRL_SINGLE because of arch pxa not moved to DT
> * Use bool for inverted, ed_mask, gafr variable

Haojian, does this series depend on the changes for DT in pinctrl-single,
or can I merge it on its own?

The amount of patches makes me confused you know ... :-)

Yours,
Linus Walleij

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

* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
  2013-02-05 16:44 ` [PATCH v2 00/10] rework pxa gpio driver for pinctrl Linus Walleij
@ 2013-02-06  2:08   ` Haojian Zhuang
  2013-02-07 15:32     ` Igor Grinberg
  0 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-06  2:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 6 February 2013 00:44, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Sun, Feb 3, 2013 at 11:15 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> v2:
>> * Fix the build issue without CONFIG_OF
>> * Append to check PINCTRL_SINGLE because of arch pxa not moved to DT
>> * Use bool for inverted, ed_mask, gafr variable
>
> Haojian, does this series depend on the changes for DT in pinctrl-single,
> or can I merge it on its own?
>
> The amount of patches makes me confused you know ... :-)
>
> Yours,
> Linus Walleij

I'm waiting for Igor's test on PXA.
This patch series is used to support DT better. And the driver still works
without DT support since there's no DT in PXA chips.

Only the 9th & 10th patches are related to pinctrl-single driver. You could
skip them and I can move them into the pinctrl-single patch series.

Yes, these patches make people confusing. :) I'm sorry on inconvenience.

Regards
Haojian

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

* [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request
  2013-02-03 10:15 ` [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request Haojian Zhuang
@ 2013-02-06 14:11   ` Igor Grinberg
  2013-02-07 15:17   ` Igor Grinberg
  1 sibling, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-06 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/03/13 12:15, Haojian Zhuang wrote:
> While gpio pins is requested, request the pin of pinctrl driver first.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  drivers/gpio/gpio-pxa.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 5c39db3..c9cc636 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -23,6 +23,7 @@
>  #include <linux/io.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
>  #include <linux/syscore_ops.h>
>  #include <linux/slab.h>
> @@ -159,6 +160,23 @@ int pxa_irq_to_gpio(struct irq_data *d)
>  	return gpio;
>  }
>  
> +static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
> +{
> +	/*
> +	 * Map back to global GPIO space and request muxing, the direction
> +	 * parameter does not matter for this controller.
> +	 */
> +	int gpio = gc->base + offset;
> +
> +	/*
> +	 * Platforms in ARCH_PXA doesn't move to device tree yet,
> +	 * and PINCTRL_SINGLE is depend on device tree.
> +	 */ 

If this is interesting, git am says:
patch:32: trailing whitespace.
         */ 
warning: 1 line adds whitespace errors.

> +	if (IS_ENABLED(CONFIG_PINCTRL_SINGLE))
> +		return pinctrl_request_gpio(gpio);
> +	return 0;
> +}
> +
>  static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
>  {
>  	struct pxa_gpio_chip *chip = NULL;
> @@ -471,6 +489,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
>  		gc->base  = gpio;
>  		gc->label = chips[i].label;
>  
> +		gc->request = pxa_gpio_request;
>  		gc->direction_input  = pxa_gpio_direction_input;
>  		gc->direction_output = pxa_gpio_direction_output;
>  		gc->get = pxa_gpio_get;
> 

-- 
Regards,
Igor.

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

* [PATCH v2 10/10] ARM: dts: support pinmux in pxa910
  2013-02-03 10:15 ` [PATCH v2 10/10] ARM: dts: support pinmux in pxa910 Haojian Zhuang
@ 2013-02-06 14:12   ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-06 14:12 UTC (permalink / raw)
  To: linux-arm-kernel


On 02/03/13 12:15, Haojian Zhuang wrote:
> Add gpio range, pinmux settings in pxa910 dkb DTS file.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  arch/arm/boot/dts/pxa910-dkb.dts |  264 ++++++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/pxa910.dtsi    |   29 ++++-
>  2 files changed, 291 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
> index 595492a..72eb6bc 100644
> --- a/arch/arm/boot/dts/pxa910-dkb.dts
> +++ b/arch/arm/boot/dts/pxa910-dkb.dts
> @@ -170,6 +170,270 @@

[...]

> +			pmx: pinmux at d401e000 {
> +				/* pin base, nr pins & gpio function */
> +				pinctrl-single,gpio-range = <
> +					/*
> +					 * GPIO number is hardcoded for range at here.
> +					 * In gpio chip, GPIO number is not hardcoded for range.
> +					 * Since one gpio pin may be routed to multiple pins,
> +					 * define these gpio range in pxa910-dkb.dts not pxa910.dtsi.
> +					 */
> +						&range 55 55 0	/* GPIO0 ~ GPIO54 */
> +						&range 188 5 1	/* GPIO55 ~ GPIO59 */ 

If this is interesting git am says:
patch:66: trailing whitespace.
                                                &range 188 5 1  /* GPIO55 ~ GPIO59 */ 
warning: 1 line adds whitespace errors.

> +						&range 193 7 0	/* GPIO60 ~ GPIO66 */
> +						&range 110 43 0	/* GPIO67 ~ GPIO109 */
> +						&range 166 7 0	/* GPIO110 ~ GPIO116 */
> +						&range 45 4 0	/* GPIO117 ~ GPIO120 */
> +						&range 50 2 1	/* GPIO122 ~ GPIO123 */
> +						&range 203 1 0	/* GPIO121 */
> +						&range 52 1 0	/* GPIO124 */
> +						&range 53 1 1	/* GPIO125 */
> +						&range 27 2 0	/* GPIO126 ~ GPIO127 */
> +					>;
> +
> +				pinctrl-names = "default";
> +				pinctrl-0 = <&keypad_pmx_func>;
> +
> +				uart1_pmx_func: pinmux_uart1_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x198 0x6	/* GPIO47_UART1_RXD */
> +						0x19c 0x6	/* GPIO48_UART1_TXD */
> +					>;
> +					/* slew rate set value, mask */
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					/* bias set value, match, mask */
> +					pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x4000 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					/* input schmitt set value, mask */
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					/* input schmitt disable value, match, mask */
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				uart2_pmx_func: pinmux_uart2_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x150 0x4	/* GPIO29_UART2_CTS */
> +						0x154 0x4	/* GPIO30_UART2_RTS */
> +						0x158 0x4	/* GPIO31_UART2_TXD */
> +						0x15c 0x4	/* GPIO32_UART2_RXD */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				uart3_pmx_func: pinmux_uart3_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x188 0x7	/* GPIO43_UART3_RXD */
> +						0x18c 0x7	/* GPIO44_UART3_TXD */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				twsi1_pmx_func: pinmux_twsi1_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x1b0 0x2	/* GPIO53_TWSI_SCL */
> +						0x1b4 0x2	/* GPIO54_TWSI_SDA */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				nand_pmx_func: pinmux_nand_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x040 0x0	/* ND_IO0 */
> +						0x03c 0x0	/* ND_IO1 */
> +						0x038 0x0	/* ND_IO2 */
> +						0x034 0x0	/* ND_IO3 */
> +						0x030 0x0	/* ND_IO4 */
> +						0x02c 0x0	/* ND_IO5 */
> +						0x028 0x0	/* ND_IO6 */
> +						0x024 0x0	/* ND_IO7 */
> +						0x020 0x0	/* ND_IO8 */
> +						0x01c 0x0	/* ND_IO9 */
> +						0x018 0x0	/* ND_IO10 */
> +						0x014 0x0	/* ND_IO11 */
> +						0x010 0x0	/* ND_IO12 */
> +						0x00c 0x0	/* ND_IO13 */
> +						0x008 0x0	/* ND_IO14 */
> +						0x004 0x0	/* ND_IO15 */
> +						0x044 0x0	/* ND_nCS0 */
> +						0x060 0x1	/* ND_ALE */
> +						0x05c 0x0	/* ND_CLE */
> +						0x054 0x1	/* ND_nWE */
> +						0x058 0x1	/* ND_nRE */
> +						0x068 0x0	/* ND_RDY0 */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				mmc1_pmx_func1: pinmux_mmc1_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x0a0 0x0	/* MMC1_DATA0 */
> +						0x09c 0x0	/* MMC1_DATA1 */
> +						0x098 0x0	/* MMC1_DATA2 */
> +						0x094 0x0	/* MMC1_DATA3 */
> +						0x090 0x0	/* MMC1_DATA4 */
> +						0x08c 0x0	/* MMC1_DATA5 */
> +						0x088 0x0	/* MMC1_DATA6 */
> +						0x084 0x0	/* MMC1_DATA7 */
> +						0x0a4 0x0	/* MMC1_CMD */
> +						0x0a8 0x0	/* MMC1_CLK */
> +					>;
> +					pinctrl-single,slew-rate = <0x1800 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				mmc1_pmx_func2: pinmux_mmc1_pins at 1 {
> +					pinctrl-single,pins = <
> +						0x0ac 0x0	/* MMC1_CD */
> +						0x0b0 0x0	/* MMC1_WP */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				mmc2_pmx_func: pinmux_mmc2_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x180 0x1	/* MMC2_CMD */
> +						0x184 0x1	/* MMC2_CLK */
> +						0x17c 0x1	/* MMC2_DATA0 */
> +						0x178 0x1	/* MMC2_DATA1 */
> +						0x174 0x1	/* MMC2_DATA2 */
> +						0x170 0x1	/* MMC2_DATA3 */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				ssp1_pmx_func: pinmux_ssp1_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x130 0x1	/* GPIO21_SSP1_SCLK */
> +						0x134 0x1	/* GPIO22_SSP1_FRM */
> +						0x138 0x1	/* GPIO23_SSP1_TXD */
> +						0x13c 0x1	/* GPIO24_SSP1_RXD */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				keypad_pmx_func: pinmux_keypad_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x0dc 0x1	/* GPIO0_MKIN0 */
> +						0x0e0 0x1	/* GPIO1_MKOUT0 */
> +						0x0e4 0x1	/* GPIO2_MKIN1 */
> +						0x0e8 0x1	/* GPIO3_MKOUT1 */
> +						0x0ec 0x1	/* GPIO4_MKIN2 */
> +						0x0f0 0x1	/* GPIO5_MKOUT2 */
> +						0x0f4 0x1	/* GPIO6_MKIN3 */
> +						0x0f8 0x1	/* GPIO7_MKOUT3 */
> +						0x0fc 0x1	/* GPIO8_MKIN4 */
> +						0x100 0x1	/* GPIO9_MKOUT4 */
> +						0x10c 0x1	/* GPIO12_MKIN6 */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x2000 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				nfc_pmx_func: pinmux_nfc_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x120 0x0	/* GPIO17 */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +				wlan_pmx_func: pinmux_wlan_pins at 0 {
> +					pinctrl-single,pins = <
> +						0x114 0x0	/* GPIO14 */
> +						0x12c 0x0	/* GPIO20 */
> +						0x160 0x0	/* GPIO33 */
> +						0x164 0x0	/* GPIO34 */
> +						0x168 0x0	/* GPIO35 */
> +						0x16c 0x0	/* GPIO36 */
> +					>;
> +					pinctrl-single,slew-rate = <0x1000 0x1800>;
> +					pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
> +					pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
> +					pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
> +					pinctrl-single,input-schmitt = <0x40 0x70>;
> +					pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
> +				};
> +			};
>  		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
> index 825aaca..20a3418 100644
> --- a/arch/arm/boot/dts/pxa910.dtsi
> +++ b/arch/arm/boot/dts/pxa910.dtsi
> @@ -93,28 +93,37 @@
>  				#address-cells = <1>;
>  				#size-cells = <1>;
>  				reg = <0xd4019000 0x1000>;
> -				gpio-controller;
> -				#gpio-cells = <2>;
> +				marvell,gpio-ed-mask = <1>;
> +				marvell,nr-gpios = <128>;
>  				interrupts = <49>;
>  				interrupt-names = "gpio_mux";
>  				interrupt-controller;
>  				#interrupt-cells = <1>;
> +				status = "disabled";
>  				ranges;
>  
>  				gcb0: gpio at d4019000 {
>  					reg = <0xd4019000 0x4>;
> +					gpio-controller;
> +					#gpio-cells = <2>;
>  				};
>  
>  				gcb1: gpio at d4019004 {
>  					reg = <0xd4019004 0x4>;
> +					gpio-controller;
> +					#gpio-cells = <2>;
>  				};
>  
>  				gcb2: gpio at d4019008 {
>  					reg = <0xd4019008 0x4>;
> +					gpio-controller;
> +					#gpio-cells = <2>;
>  				};
>  
>  				gcb3: gpio at d4019100 {
>  					reg = <0xd4019100 0x4>;
> +					gpio-controller;
> +					#gpio-cells = <2>;
>  				};
>  			};
>  
> @@ -144,6 +153,22 @@
>  				interrupt-names = "rtc 1Hz", "rtc alarm";
>  				status = "disabled";
>  			};
> +
> +			pmx: pinmux at d401e000 {
> +				compatible = "pinconf-single";
> +				reg = <0xd401e000 0x330>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				#gpio-range-cells = <3>;
> +				ranges;
> +
> +				pinctrl-single,register-width = <32>;
> +				pinctrl-single,function-mask = <7>;
> +
> +				range: gpio-range {
> +					#pinctrl-single,gpio-range-cells = <3>;
> +				};
> +			};
>  		};
>  	};
>  };
> 

-- 
Regards,
Igor.

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-03 10:15 ` [PATCH v2 02/10] gpio: pxa: avoid to use global irq base Haojian Zhuang
@ 2013-02-07 15:17   ` Igor Grinberg
  2013-02-13 14:18   ` Igor Grinberg
  1 sibling, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/03/13 12:15, Haojian Zhuang wrote:
> Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
> pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
> MMP_GPIO_TO_IRQ().
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  arch/arm/mach-pxa/pxa25x.c |    2 +-
>  arch/arm/mach-pxa/pxa27x.c |    2 +-
>  drivers/gpio/Kconfig       |    1 +
>  drivers/gpio/gpio-pxa.c    |  156 ++++++++++++++++++++++----------------------
>  include/linux/gpio-pxa.h   |    4 +-
>  5 files changed, 85 insertions(+), 80 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index 3f5171e..f4c293a 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -289,7 +289,7 @@ static inline void pxa25x_init_pm(void) {}
>  
>  static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	uint32_t mask = 0;
>  
>  	if (gpio >= 0 && gpio < 85)
> diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
> index 69985b06..67f5fd2 100644
> --- a/arch/arm/mach-pxa/pxa27x.c
> +++ b/arch/arm/mach-pxa/pxa27x.c
> @@ -364,7 +364,7 @@ static inline void pxa27x_init_pm(void) {}
>   */
>  static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	uint32_t mask;
>  
>  	if (gpio >= 0 && gpio < 128)
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 176fb3d..b8c0da8 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -201,6 +201,7 @@ config GPIO_PL061
>  config GPIO_PXA
>  	bool "PXA GPIO support"
>  	depends on ARCH_PXA || ARCH_MMP
> +	select IRQ_DOMAIN
>  	help
>  	  Say yes here to support the PXA GPIO device
>  
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index a4c6687..2310665 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -13,6 +13,7 @@
>   */
>  #include <linux/module.h>
>  #include <linux/clk.h>
> +#include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/gpio.h>
>  #include <linux/gpio-pxa.h>
> @@ -61,16 +62,15 @@
>  #define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
>  
>  int pxa_last_gpio;
> -static int irq_base;
>  
>  #ifdef CONFIG_OF
> -static struct irq_domain *domain;
>  static struct device_node *pxa_gpio_of_node;
>  #endif
>  
>  struct pxa_gpio_chip {
>  	struct gpio_chip chip;
>  	void __iomem	*regbase;
> +	unsigned int	irq_base;
>  	char label[10];
>  
>  	unsigned long	irq_mask;
> @@ -170,14 +170,22 @@ static inline int __gpio_is_occupied(unsigned gpio)
>  	return ret;
>  }
>  
> -static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> +static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>  {
> -	return chip->base + offset + irq_base;
> +	struct pxa_gpio_chip *chip = NULL;
> +
> +	chip = container_of(gc, struct pxa_gpio_chip, chip);
> +	return chip->irq_base + offset;
>  }
>  
> -int pxa_irq_to_gpio(int irq)
> +int pxa_irq_to_gpio(struct irq_data *d)
>  {
> -	return irq - irq_base;
> +	struct pxa_gpio_chip *chip;
> +	int gpio;
> +
> +	chip = (struct pxa_gpio_chip *)d->domain->host_data;
> +	gpio = d->irq - chip->irq_base + chip->chip.base;
> +	return gpio;
>  }
>  
>  static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> @@ -250,47 +258,6 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
>  }
>  #endif
>  
> -static int pxa_init_gpio_chip(int gpio_end,
> -					int (*set_wake)(unsigned int, unsigned int))
> -{
> -	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
> -	struct pxa_gpio_chip *chips;
> -
> -	chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
> -	if (chips == NULL) {
> -		pr_err("%s: failed to allocate GPIO chips\n", __func__);
> -		return -ENOMEM;
> -	}
> -
> -	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> -		struct gpio_chip *c = &chips[i].chip;
> -
> -		sprintf(chips[i].label, "gpio-%d", i);
> -		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
> -		chips[i].set_wake = set_wake;
> -
> -		c->base  = gpio;
> -		c->label = chips[i].label;
> -
> -		c->direction_input  = pxa_gpio_direction_input;
> -		c->direction_output = pxa_gpio_direction_output;
> -		c->get = pxa_gpio_get;
> -		c->set = pxa_gpio_set;
> -		c->to_irq = pxa_gpio_to_irq;
> -#ifdef CONFIG_OF_GPIO
> -		c->of_node = pxa_gpio_of_node;
> -		c->of_xlate = pxa_gpio_of_xlate;
> -		c->of_gpio_n_cells = 2;
> -#endif
> -
> -		/* number of GPIOs on last bank may be less than 32 */
> -		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> -		gpiochip_add(c);
> -	}
> -	pxa_gpio_chips = chips;
> -	return 0;
> -}
> -
>  /* Update only those GRERx and GFERx edge detection register bits if those
>   * bits are set in c->irq_mask
>   */
> @@ -309,7 +276,7 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
>  static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  {
>  	struct pxa_gpio_chip *c;
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	unsigned long gpdr, mask = GPIO_bit(gpio);
>  
>  	c = gpio_to_pxachip(gpio);
> @@ -383,7 +350,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
>  
>  static void pxa_ack_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
> @@ -391,7 +358,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d)
>  
>  static void pxa_mask_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  	uint32_t grer, gfer;
>  
> @@ -405,7 +372,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
>  
>  static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	if (c->set_wake)
> @@ -416,7 +383,7 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  
>  static void pxa_unmask_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	c->irq_mask |= GPIO_bit(gpio);
> @@ -469,13 +436,6 @@ static int pxa_gpio_nums(void)
>  	return count;
>  }
>  
> -#ifdef CONFIG_OF
> -static struct of_device_id pxa_gpio_dt_ids[] = {
> -	{ .compatible = "mrvl,pxa-gpio" },
> -	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> -	{}
> -};
> -
>  static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  			      irq_hw_number_t hw)
>  {
> @@ -485,11 +445,18 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  	return 0;
>  }
>  
> -const struct irq_domain_ops pxa_irq_domain_ops = {
> +static const struct irq_domain_ops pxa_irq_domain_ops = {
>  	.map	= pxa_irq_domain_map,
>  	.xlate	= irq_domain_xlate_twocell,
>  };
>  
> +#ifdef CONFIG_OF
> +static struct of_device_id pxa_gpio_dt_ids[] = {
> +	{ .compatible = "mrvl,pxa-gpio" },
> +	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> +	{}
> +};
> +
>  static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  {
>  	int ret, nr_banks, nr_gpios;
> @@ -528,14 +495,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  	nr_gpios = nr_banks << 5;
>  	pxa_last_gpio = nr_gpios - 1;
>  
> -	irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
> -	if (irq_base < 0) {
> -		dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
> -		goto err;
> -	}
> -	domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
> -				       &pxa_irq_domain_ops, NULL);
> -	pxa_gpio_of_node = np;
>  	return 0;
>  err:
>  	iounmap(gpio_reg_base);
> @@ -545,6 +504,56 @@ err:
>  #define pxa_gpio_probe_dt(pdev)		(-1)
>  #endif
>  
> +static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
> +			      int (*set_wake)(unsigned int, unsigned int))
> +{
> +	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
> +	struct pxa_gpio_chip *chips;
> +
> +	chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
> +	if (chips == NULL) {
> +		pr_err("%s: failed to allocate GPIO chips\n", __func__);
> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> +		struct gpio_chip *c = &chips[i].chip;
> +
> +		sprintf(chips[i].label, "gpio-%d", i);
> +		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
> +		chips[i].set_wake = set_wake;
> +
> +		c->base  = gpio;
> +		c->label = chips[i].label;
> +
> +		c->direction_input  = pxa_gpio_direction_input;
> +		c->direction_output = pxa_gpio_direction_output;
> +		c->get = pxa_gpio_get;
> +		c->set = pxa_gpio_set;
> +		c->to_irq = pxa_gpio_to_irq;
> +#ifdef CONFIG_OF_GPIO
> +		c->of_node = pxa_gpio_of_node;
> +		c->of_xlate = pxa_gpio_of_xlate;
> +		c->of_gpio_n_cells = 2;
> +#endif
> +
> +		/* number of GPIOs on last bank may be less than 32 */
> +		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> +
> +		chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
> +		if (chips[i].irq_base < 0)
> +			return -EINVAL;
> +		if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
> +					   chips[i].irq_base, 0,
> +					   &pxa_irq_domain_ops, &chips[i]))
> +			return -ENODEV;
> +
> +		gpiochip_add(c);
> +	}
> +	pxa_gpio_chips = chips;
> +	return 0;
> +}
> +
>  static int pxa_gpio_probe(struct platform_device *pdev)
>  {
>  	struct pxa_gpio_chip *c;
> @@ -557,14 +566,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  	ret = pxa_gpio_probe_dt(pdev);
>  	if (ret < 0) {
>  		pxa_last_gpio = pxa_gpio_nums();
> -#ifdef CONFIG_ARCH_PXA
> -		if (gpio_is_pxa_type(gpio_type))
> -			irq_base = PXA_GPIO_TO_IRQ(0);
> -#endif
> -#ifdef CONFIG_ARCH_MMP
> -		if (gpio_is_mmp_type(gpio_type))
> -			irq_base = MMP_GPIO_TO_IRQ(0);
> -#endif
>  	} else {
>  		use_of = 1;
>  	}
> @@ -604,7 +605,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  
>  	/* Initialize GPIO chips */
>  	info = dev_get_platdata(&pdev->dev);
> -	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
> +	pxa_init_gpio_chip(pdev, pxa_last_gpio,
> +			   info ? info->gpio_set_wake : NULL);
>  
>  	/* clear all GPIO edge detects */
>  	for_each_gpio_chip(gpio, c) {
> diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
> index bc5cae5..49120b8 100644
> --- a/include/linux/gpio-pxa.h
> +++ b/include/linux/gpio-pxa.h
> @@ -1,6 +1,8 @@
>  #ifndef __GPIO_PXA_H
>  #define __GPIO_PXA_H
>  
> +#include <linux/irq.h>
> +
>  #define GPIO_bit(x)	(1 << ((x) & 0x1f))
>  
>  #define gpio_to_bank(gpio)	((gpio) >> 5)
> @@ -11,7 +13,7 @@
>   */
>  extern int pxa_last_gpio;
>  
> -extern int pxa_irq_to_gpio(int irq);
> +extern int pxa_irq_to_gpio(struct irq_data *d);
>  
>  struct pxa_gpio_platform_data {
>  	bool ed_mask;	/* true means that ed_mask reg is available */
> 

-- 
Regards,
Igor.

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

* [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted
  2013-02-03 10:15 ` [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
@ 2013-02-07 15:17   ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 12:15, Haojian Zhuang wrote:
> Avoid to judge whether gpio is inverted by identifying cpu in gpio
> driver. Move this into platform data of gpio driver.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  arch/arm/mach-pxa/pxa25x.c |    3 +++
>  drivers/gpio/gpio-pxa.c    |   40 +++++++++++++++++++++++++---------------
>  include/linux/gpio-pxa.h   |    1 +
>  3 files changed, 29 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index f4c293a..66dafb7 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -340,6 +340,9 @@ void __init pxa25x_map_io(void)
>  }
>  
>  static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
> +#ifdef CONFIG_CPU_PXA26x
> +	.inverted = true,
> +#endif
>  	.gpio_set_wake = gpio_set_wake,
>  };
>  
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 2310665..1f8dfc8 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -71,6 +71,7 @@ struct pxa_gpio_chip {
>  	struct gpio_chip chip;
>  	void __iomem	*regbase;
>  	unsigned int	irq_base;
> +	bool		inverted;
>  	char label[10];
>  
>  	unsigned long	irq_mask;
> @@ -126,9 +127,9 @@ static inline int gpio_is_mmp_type(int type)
>  /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
>   * as well as their Alternate Function value being '1' for GPIO in GAFRx.
>   */
> -static inline int __gpio_is_inverted(int gpio)
> +static inline int __gpio_is_inverted(struct pxa_gpio_chip *chip, int gpio)
>  {
> -	if ((gpio_type == PXA26X_GPIO) && (gpio > 85))
> +	if ((chip->inverted) && (gpio > 85))
>  		return 1;
>  	return 0;
>  }
> @@ -139,15 +140,13 @@ static inline int __gpio_is_inverted(int gpio)
>   * is attributed as "occupied" here (I know this terminology isn't
>   * accurate, you are welcome to propose a better one :-)
>   */
> -static inline int __gpio_is_occupied(unsigned gpio)
> +static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
>  {
> -	struct pxa_gpio_chip *pxachip;
>  	void __iomem *base;
>  	unsigned long gafr = 0, gpdr = 0;
>  	int ret, af = 0, dir = 0;
>  
> -	pxachip = gpio_to_pxachip(gpio);
> -	base = gpio_chip_base(&pxachip->chip);
> +	base = gpio_chip_base(&chip->chip);
>  	gpdr = readl_relaxed(base + GPDR_OFFSET);
>  
>  	switch (gpio_type) {
> @@ -158,7 +157,7 @@ static inline int __gpio_is_occupied(unsigned gpio)
>  		af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
>  		dir = gpdr & GPIO_bit(gpio);
>  
> -		if (__gpio_is_inverted(gpio))
> +		if (__gpio_is_inverted(chip, gpio))
>  			ret = (af != 1) || (dir == 0);
>  		else
>  			ret = (af != 0) || (dir != 0);
> @@ -188,16 +187,19 @@ int pxa_irq_to_gpio(struct irq_data *d)
>  	return gpio;
>  }
>  
> -static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> +static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
>  {
> -	void __iomem *base = gpio_chip_base(chip);
> +	struct pxa_gpio_chip *chip = NULL;
> +	void __iomem *base = gpio_chip_base(gc);
>  	uint32_t value, mask = 1 << offset;
>  	unsigned long flags;
>  
> +	chip = container_of(gc, struct pxa_gpio_chip, chip);
> +
>  	spin_lock_irqsave(&gpio_lock, flags);
>  
>  	value = readl_relaxed(base + GPDR_OFFSET);
> -	if (__gpio_is_inverted(chip->base + offset))
> +	if (__gpio_is_inverted(chip, gc->base + offset))
>  		value |= mask;
>  	else
>  		value &= ~mask;
> @@ -207,19 +209,22 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
>  	return 0;
>  }
>  
> -static int pxa_gpio_direction_output(struct gpio_chip *chip,
> +static int pxa_gpio_direction_output(struct gpio_chip *gc,
>  				     unsigned offset, int value)
>  {
> -	void __iomem *base = gpio_chip_base(chip);
> +	struct pxa_gpio_chip *chip = NULL;
> +	void __iomem *base = gpio_chip_base(gc);
>  	uint32_t tmp, mask = 1 << offset;
>  	unsigned long flags;
>  
> +	chip = container_of(gc, struct pxa_gpio_chip, chip);
> +
>  	writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
>  
>  	spin_lock_irqsave(&gpio_lock, flags);
>  
>  	tmp = readl_relaxed(base + GPDR_OFFSET);
> -	if (__gpio_is_inverted(chip->base + offset))
> +	if (__gpio_is_inverted(chip, gc->base + offset))
>  		tmp &= ~mask;
>  	else
>  		tmp |= mask;
> @@ -288,7 +293,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  		if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
>  			return 0;
>  
> -		if (__gpio_is_occupied(gpio))
> +		if (__gpio_is_occupied(c, gpio))
>  			return 0;
>  
>  		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
> @@ -296,7 +301,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  
>  	gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
>  
> -	if (__gpio_is_inverted(gpio))
> +	if (__gpio_is_inverted(c, gpio))
>  		writel_relaxed(gpdr | mask,  c->regbase + GPDR_OFFSET);
>  	else
>  		writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
> @@ -474,6 +479,9 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  		return -ENOMEM;
>  	if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
>  		pdata->ed_mask = true;
> +	/* It's only valid for PXA26x */
> +	if (of_find_property(np, "marvell,gpio-inverted", NULL))
> +		pdata->inverted = true;
>  	/* set the platform data */
>  	pdev->dev.platform_data = pdata;
>  	gpio_type = (int)of_id->data;
> @@ -616,6 +624,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  		/* unmask GPIO edge detect for AP side */
>  		if (info->ed_mask)
>  			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
> +		/* update for gpio inverted */
> +		c->inverted = info->inverted;
>  	}
>  
>  	if (!use_of) {
> diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
> index 49120b8..0c212a1 100644
> --- a/include/linux/gpio-pxa.h
> +++ b/include/linux/gpio-pxa.h
> @@ -17,6 +17,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
>  
>  struct pxa_gpio_platform_data {
>  	bool ed_mask;	/* true means that ed_mask reg is available */
> +	bool inverted;	/* only valid for PXA26x */
>  	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
>  };
>  
> 

-- 
Regards,
Igor.

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

* [PATCH v2 04/10] gpio: pxa: remove gpio_type
  2013-02-03 10:15 ` [PATCH v2 04/10] gpio: pxa: remove gpio_type Haojian Zhuang
@ 2013-02-07 15:17   ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 12:15, Haojian Zhuang wrote:
> Since gpio_type is used to check whether gafr register is valid. So
> move it into platform data.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  arch/arm/mach-pxa/pxa25x.c |    1 +
>  arch/arm/mach-pxa/pxa27x.c |    1 +
>  drivers/gpio/gpio-pxa.c    |   43 ++++++-------------------------------------
>  include/linux/gpio-pxa.h   |    1 +
>  4 files changed, 9 insertions(+), 37 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index 66dafb7..3460de1 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -343,6 +343,7 @@ static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
>  #ifdef CONFIG_CPU_PXA26x
>  	.inverted = true,
>  #endif
> +	.gafr = true,
>  	.gpio_set_wake = gpio_set_wake,
>  };
>  
> diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
> index 67f5fd2..999d681 100644
> --- a/arch/arm/mach-pxa/pxa27x.c
> +++ b/arch/arm/mach-pxa/pxa27x.c
> @@ -430,6 +430,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
>  }
>  
>  static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
> +	.gafr = true,
>  	.gpio_set_wake = gpio_set_wake,
>  };
>  
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 1f8dfc8..6c6e21c 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -72,6 +72,7 @@ struct pxa_gpio_chip {
>  	void __iomem	*regbase;
>  	unsigned int	irq_base;
>  	bool		inverted;
> +	bool		gafr;
>  	char label[10];
>  
>  	unsigned long	irq_mask;
> @@ -87,18 +88,8 @@ struct pxa_gpio_chip {
>  #endif
>  };
>  
> -enum {
> -	PXA25X_GPIO = 0,
> -	PXA26X_GPIO,
> -	PXA27X_GPIO,
> -	PXA3XX_GPIO,
> -	PXA93X_GPIO,
> -	MMP_GPIO = 0x10,
> -};
> -
>  static DEFINE_SPINLOCK(gpio_lock);
>  static struct pxa_gpio_chip *pxa_gpio_chips;
> -static int gpio_type;
>  static void __iomem *gpio_reg_base;
>  
>  #define for_each_gpio_chip(i, c)			\
> @@ -114,16 +105,6 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
>  	return &pxa_gpio_chips[gpio_to_bank(gpio)];
>  }
>  
> -static inline int gpio_is_pxa_type(int type)
> -{
> -	return (type & MMP_GPIO) == 0;
> -}
> -
> -static inline int gpio_is_mmp_type(int type)
> -{
> -	return (type & MMP_GPIO) != 0;
> -}
> -
>  /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
>   * as well as their Alternate Function value being '1' for GPIO in GAFRx.
>   */
> @@ -149,10 +130,7 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
>  	base = gpio_chip_base(&chip->chip);
>  	gpdr = readl_relaxed(base + GPDR_OFFSET);
>  
> -	switch (gpio_type) {
> -	case PXA25X_GPIO:
> -	case PXA26X_GPIO:
> -	case PXA27X_GPIO:
> +	if (chip->gafr) {
>  		gafr = readl_relaxed(base + GAFR_OFFSET);
>  		af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
>  		dir = gpdr & GPIO_bit(gpio);
> @@ -161,10 +139,8 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
>  			ret = (af != 1) || (dir == 0);
>  		else
>  			ret = (af != 0) || (dir != 0);
> -		break;
> -	default:
> +	} else {
>  		ret = gpdr & GPIO_bit(gpio);
> -		break;
>  	}
>  	return ret;
>  }
> @@ -412,30 +388,23 @@ static int pxa_gpio_nums(void)
>  	if (cpu_is_pxa25x()) {
>  #ifdef CONFIG_CPU_PXA26x
>  		count = 89;
> -		gpio_type = PXA26X_GPIO;
>  #elif defined(CONFIG_PXA25x)
>  		count = 84;
> -		gpio_type = PXA26X_GPIO;
>  #endif /* CONFIG_CPU_PXA26x */
>  	} else if (cpu_is_pxa27x()) {
>  		count = 120;
> -		gpio_type = PXA27X_GPIO;
>  	} else if (cpu_is_pxa93x()) {
>  		count = 191;
> -		gpio_type = PXA93X_GPIO;
>  	} else if (cpu_is_pxa3xx()) {
>  		count = 127;
> -		gpio_type = PXA3XX_GPIO;
>  	}
>  #endif /* CONFIG_ARCH_PXA */
>  
>  #ifdef CONFIG_ARCH_MMP
>  	if (cpu_is_pxa168() || cpu_is_pxa910()) {
>  		count = 127;
> -		gpio_type = MMP_GPIO;
>  	} else if (cpu_is_mmp2()) {
>  		count = 191;
> -		gpio_type = MMP_GPIO;
>  	}
>  #endif /* CONFIG_ARCH_MMP */
>  	return count;
> @@ -458,7 +427,7 @@ static const struct irq_domain_ops pxa_irq_domain_ops = {
>  #ifdef CONFIG_OF
>  static struct of_device_id pxa_gpio_dt_ids[] = {
>  	{ .compatible = "mrvl,pxa-gpio" },
> -	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> +	{ .compatible = "mrvl,mmp-gpio" },
>  	{}
>  };
>  
> @@ -484,7 +453,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  		pdata->inverted = true;
>  	/* set the platform data */
>  	pdev->dev.platform_data = pdata;
> -	gpio_type = (int)of_id->data;
>  
>  	next = of_get_next_child(np, NULL);
>  	prev = next;
> @@ -624,8 +592,9 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  		/* unmask GPIO edge detect for AP side */
>  		if (info->ed_mask)
>  			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
> -		/* update for gpio inverted */
> +		/* update for gpio inverted & gafr */
>  		c->inverted = info->inverted;
> +		c->gafr = info->gafr;
>  	}
>  
>  	if (!use_of) {
> diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
> index 0c212a1..80e0322 100644
> --- a/include/linux/gpio-pxa.h
> +++ b/include/linux/gpio-pxa.h
> @@ -18,6 +18,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
>  struct pxa_gpio_platform_data {
>  	bool ed_mask;	/* true means that ed_mask reg is available */
>  	bool inverted;	/* only valid for PXA26x */
> +	bool gafr;	/* only valid for PXA25x/PXA26x/PXA27x */
>  	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
>  };
>  
> 

-- 
Regards,
Igor.

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

* [PATCH v2 05/11] gpio: pxa: define nr gpios in platform data
  2013-02-03 15:00     ` [PATCH v2 05/11] " Haojian Zhuang
@ 2013-02-07 15:17       ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 17:00, Haojian Zhuang wrote:
> Avoid to define gpio numbers in gpio driver. Define it in platform data
> instead.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  arch/arm/mach-mmp/aspenite.c      |    1 +
>  arch/arm/mach-mmp/avengers_lite.c |    1 +
>  arch/arm/mach-mmp/brownstone.c    |    1 +
>  arch/arm/mach-mmp/flint.c         |    1 +
>  arch/arm/mach-mmp/gplugd.c        |    1 +
>  arch/arm/mach-mmp/tavorevb.c      |    1 +
>  arch/arm/mach-mmp/teton_bga.c     |    1 +
>  arch/arm/mach-mmp/ttc_dkb.c       |    1 +
>  arch/arm/mach-pxa/pxa25x.c        |    3 +++
>  arch/arm/mach-pxa/pxa27x.c        |    1 +
>  arch/arm/mach-pxa/pxa3xx.c        |   17 +++++++++++--
>  drivers/gpio/gpio-pxa.c           |   48 +++++++------------------------------
>  include/linux/gpio-pxa.h          |    1 +
>  13 files changed, 36 insertions(+), 42 deletions(-)
> 
> diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
> index 36f5781..a3e42dc 100644
> --- a/arch/arm/mach-mmp/aspenite.c
> +++ b/arch/arm/mach-mmp/aspenite.c
> @@ -112,6 +112,7 @@ static unsigned long common_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
> index b8fe447..1ea6502 100644
> --- a/arch/arm/mach-mmp/avengers_lite.c
> +++ b/arch/arm/mach-mmp/avengers_lite.c
> @@ -34,6 +34,7 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
> index d6ea5c4..a32156f 100644
> --- a/arch/arm/mach-mmp/brownstone.c
> +++ b/arch/arm/mach-mmp/brownstone.c
> @@ -106,6 +106,7 @@ static unsigned long brownstone_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
> +	.nr_gpios	= 192,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
> index 0955f44..3f301b5 100644
> --- a/arch/arm/mach-mmp/flint.c
> +++ b/arch/arm/mach-mmp/flint.c
> @@ -79,6 +79,7 @@ static unsigned long flint_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
> +	.nr_gpios	= 192,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
> index 2315cce..019b178 100644
> --- a/arch/arm/mach-mmp/gplugd.c
> +++ b/arch/arm/mach-mmp/gplugd.c
> @@ -129,6 +129,7 @@ static unsigned long gplugd_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
> index eaec649..6e8cf80 100644
> --- a/arch/arm/mach-mmp/tavorevb.c
> +++ b/arch/arm/mach-mmp/tavorevb.c
> @@ -62,6 +62,7 @@ static unsigned long tavorevb_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
> index 6682100..b5146bb 100644
> --- a/arch/arm/mach-mmp/teton_bga.c
> +++ b/arch/arm/mach-mmp/teton_bga.c
> @@ -51,6 +51,7 @@ static unsigned long teton_bga_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
> index 984d902..123a0bf 100644
> --- a/arch/arm/mach-mmp/ttc_dkb.c
> +++ b/arch/arm/mach-mmp/ttc_dkb.c
> @@ -75,6 +75,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
>  };
>  
>  static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
> +	.nr_gpios	= 128,
>  	.ed_mask	= true,
>  };
>  
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index 3460de1..ff91660 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -342,6 +342,9 @@ void __init pxa25x_map_io(void)
>  static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
>  #ifdef CONFIG_CPU_PXA26x
>  	.inverted = true,
> +	.nr_gpios = 90,
> +#else
> +	.nr_gpios = 85,
>  #endif
>  	.gafr = true,
>  	.gpio_set_wake = gpio_set_wake,
> diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
> index 999d681..4de9572 100644
> --- a/arch/arm/mach-pxa/pxa27x.c
> +++ b/arch/arm/mach-pxa/pxa27x.c
> @@ -431,6 +431,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
>  
>  static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
>  	.gafr = true,
> +	.nr_gpios = 121,
>  	.gpio_set_wake = gpio_set_wake,
>  };
>  
> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
> index 656a1bb..f6bff16 100644
> --- a/arch/arm/mach-pxa/pxa3xx.c
> +++ b/arch/arm/mach-pxa/pxa3xx.c
> @@ -15,6 +15,7 @@
>  #include <linux/module.h>
>  #include <linux/kernel.h>
>  #include <linux/init.h>
> +#include <linux/gpio-pxa.h>
>  #include <linux/pm.h>
>  #include <linux/platform_device.h>
>  #include <linux/irq.h>
> @@ -435,6 +436,10 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
>  	pxa_register_device(&pxa3xx_device_i2c_power, info);
>  }
>  
> +static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
> +	.nr_gpios = 128,
> +};
> +
>  static struct platform_device *devices[] __initdata = {
>  	&pxa_device_gpio,
>  	&pxa27x_device_udc,
> @@ -482,8 +487,16 @@ static int __init pxa3xx_init(void)
>  		register_syscore_ops(&pxa3xx_mfp_syscore_ops);
>  		register_syscore_ops(&pxa3xx_clock_syscore_ops);
>  
> -		if (!of_have_populated_dt())
> -			ret = platform_add_devices(devices, ARRAY_SIZE(devices));
> +		if (!of_have_populated_dt()) {
> +			if (cpu_is_pxa93x())
> +				pxa3xx_gpio_info.nr_gpios = 192;
> +			ret = platform_device_add_data(&pxa_device_gpio,
> +					&pxa3xx_gpio_info,
> +					sizeof(struct pxa_gpio_platform_data));
> +			if (!ret)
> +				ret = platform_add_devices(devices,
> +							   ARRAY_SIZE(devices));
> +		}
>  	}
>  
>  	return ret;
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 6c6e21c..8fbf4c6 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -380,36 +380,6 @@ static struct irq_chip pxa_muxed_gpio_chip = {
>  	.irq_set_wake	= pxa_gpio_set_wake,
>  };
>  
> -static int pxa_gpio_nums(void)
> -{
> -	int count = 0;
> -
> -#ifdef CONFIG_ARCH_PXA
> -	if (cpu_is_pxa25x()) {
> -#ifdef CONFIG_CPU_PXA26x
> -		count = 89;
> -#elif defined(CONFIG_PXA25x)
> -		count = 84;
> -#endif /* CONFIG_CPU_PXA26x */
> -	} else if (cpu_is_pxa27x()) {
> -		count = 120;
> -	} else if (cpu_is_pxa93x()) {
> -		count = 191;
> -	} else if (cpu_is_pxa3xx()) {
> -		count = 127;
> -	}
> -#endif /* CONFIG_ARCH_PXA */
> -
> -#ifdef CONFIG_ARCH_MMP
> -	if (cpu_is_pxa168() || cpu_is_pxa910()) {
> -		count = 127;
> -	} else if (cpu_is_mmp2()) {
> -		count = 191;
> -	}
> -#endif /* CONFIG_ARCH_MMP */
> -	return count;
> -}
> -
>  static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  			      irq_hw_number_t hw)
>  {
> @@ -433,7 +403,7 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
>  
>  static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  {
> -	int ret, nr_banks, nr_gpios;
> +	int ret, nr_banks;
>  	struct pxa_gpio_platform_data *pdata;
>  	struct device_node *prev, *next, *np = pdev->dev.of_node;
>  	const struct of_device_id *of_id =
> @@ -451,6 +421,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  	/* It's only valid for PXA26x */
>  	if (of_find_property(np, "marvell,gpio-inverted", NULL))
>  		pdata->inverted = true;
> +	ret = of_property_read_u32(np, "marvell,nr-gpios", &pdata->nr_gpios);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "nr-gpios isn't specified\n");
> +		return -ENOTSUPP;
> +	}
>  	/* set the platform data */
>  	pdev->dev.platform_data = pdata;
>  
> @@ -468,8 +443,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  		prev = next;
>  	}
>  	of_node_put(prev);
> -	nr_gpios = nr_banks << 5;
> -	pxa_last_gpio = nr_gpios - 1;
>  
>  	return 0;
>  err:
> @@ -540,14 +513,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
>  
>  	ret = pxa_gpio_probe_dt(pdev);
> -	if (ret < 0) {
> -		pxa_last_gpio = pxa_gpio_nums();
> -	} else {
> +	if (!ret)
>  		use_of = 1;
> -	}
> -
> -	if (!pxa_last_gpio)
> -		return -EINVAL;
>  
>  	irq0 = platform_get_irq_byname(pdev, "gpio0");
>  	irq1 = platform_get_irq_byname(pdev, "gpio1");
> @@ -581,6 +548,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  
>  	/* Initialize GPIO chips */
>  	info = dev_get_platdata(&pdev->dev);
> +	pxa_last_gpio = info->nr_gpios - 1;
>  	pxa_init_gpio_chip(pdev, pxa_last_gpio,
>  			   info ? info->gpio_set_wake : NULL);
>  
> diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
> index 80e0322..b357fdc 100644
> --- a/include/linux/gpio-pxa.h
> +++ b/include/linux/gpio-pxa.h
> @@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
>  	bool ed_mask;	/* true means that ed_mask reg is available */
>  	bool inverted;	/* only valid for PXA26x */
>  	bool gafr;	/* only valid for PXA25x/PXA26x/PXA27x */
> +	unsigned nr_gpios;
>  	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
>  };
>  
> 

-- 
Regards,
Igor.

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

* [PATCH v2 06/10] gpio: pxa: clean code for compatible name
  2013-02-03 10:15 ` [PATCH v2 06/10] gpio: pxa: clean code for compatible name Haojian Zhuang
@ 2013-02-07 15:17   ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 12:15, Haojian Zhuang wrote:
> Use compatible variable name in gpio pxa driver.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  drivers/gpio/gpio-pxa.c |  194 ++++++++++++++++++++++++-----------------------
>  1 file changed, 98 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 8fbf4c6..95561d6 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -95,9 +95,9 @@ static void __iomem *gpio_reg_base;
>  #define for_each_gpio_chip(i, c)			\
>  	for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
>  
> -static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
> +static inline void __iomem *gpio_chip_base(struct gpio_chip *gc)
>  {
> -	return container_of(c, struct pxa_gpio_chip, chip)->regbase;
> +	return container_of(gc, struct pxa_gpio_chip, chip)->regbase;
>  }
>  
>  static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
> @@ -210,14 +210,14 @@ static int pxa_gpio_direction_output(struct gpio_chip *gc,
>  	return 0;
>  }
>  
> -static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
> +static int pxa_gpio_get(struct gpio_chip *gc, unsigned offset)
>  {
> -	return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
> +	return readl_relaxed(gpio_chip_base(gc) + GPLR_OFFSET) & (1 << offset);
>  }
>  
> -static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> +static void pxa_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
>  {
> -	writel_relaxed(1 << offset, gpio_chip_base(chip) +
> +	writel_relaxed(1 << offset, gpio_chip_base(gc) +
>  				(value ? GPSR_OFFSET : GPCR_OFFSET));
>  }
>  
> @@ -242,57 +242,58 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
>  /* Update only those GRERx and GFERx edge detection register bits if those
>   * bits are set in c->irq_mask
>   */
> -static inline void update_edge_detect(struct pxa_gpio_chip *c)
> +static inline void update_edge_detect(struct pxa_gpio_chip *chip)
>  {
>  	uint32_t grer, gfer;
>  
> -	grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask;
> -	gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask;
> -	grer |= c->irq_edge_rise & c->irq_mask;
> -	gfer |= c->irq_edge_fall & c->irq_mask;
> -	writel_relaxed(grer, c->regbase + GRER_OFFSET);
> -	writel_relaxed(gfer, c->regbase + GFER_OFFSET);
> +	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~chip->irq_mask;
> +	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~chip->irq_mask;
> +	grer |= chip->irq_edge_rise & chip->irq_mask;
> +	gfer |= chip->irq_edge_fall & chip->irq_mask;
> +	writel_relaxed(grer, chip->regbase + GRER_OFFSET);
> +	writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
>  }
>  
>  static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  {
> -	struct pxa_gpio_chip *c;
> +	struct pxa_gpio_chip *chip;
>  	int gpio = pxa_irq_to_gpio(d);
>  	unsigned long gpdr, mask = GPIO_bit(gpio);
>  
> -	c = gpio_to_pxachip(gpio);
> +	chip = gpio_to_pxachip(gpio);
>  
>  	if (type == IRQ_TYPE_PROBE) {
>  		/* Don't mess with enabled GPIOs using preconfigured edges or
>  		 * GPIOs set to alternate function or to output during probe
>  		 */
> -		if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
> +		if ((chip->irq_edge_rise | chip->irq_edge_fall)
> +			& GPIO_bit(gpio))
>  			return 0;
>  
> -		if (__gpio_is_occupied(c, gpio))
> +		if (__gpio_is_occupied(chip, gpio))
>  			return 0;
>  
>  		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
>  	}
>  
> -	gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
> +	gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
>  
> -	if (__gpio_is_inverted(c, gpio))
> -		writel_relaxed(gpdr | mask,  c->regbase + GPDR_OFFSET);
> +	if (__gpio_is_inverted(chip, gpio))
> +		writel_relaxed(gpdr | mask,  chip->regbase + GPDR_OFFSET);
>  	else
> -		writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
> +		writel_relaxed(gpdr & ~mask, chip->regbase + GPDR_OFFSET);
>  
>  	if (type & IRQ_TYPE_EDGE_RISING)
> -		c->irq_edge_rise |= mask;
> +		chip->irq_edge_rise |= mask;
>  	else
> -		c->irq_edge_rise &= ~mask;
> +		chip->irq_edge_rise &= ~mask;
>  
>  	if (type & IRQ_TYPE_EDGE_FALLING)
> -		c->irq_edge_fall |= mask;
> +		chip->irq_edge_fall |= mask;
>  	else
> -		c->irq_edge_fall &= ~mask;
> +		chip->irq_edge_fall &= ~mask;
>  
> -	update_edge_detect(c);
> +	update_edge_detect(chip);
>  
>  	pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio,
>  		((type & IRQ_TYPE_EDGE_RISING)  ? " rising"  : ""),
> @@ -302,21 +303,21 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  
>  static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
>  {
> -	struct pxa_gpio_chip *c;
> +	struct pxa_gpio_chip *chip;
>  	int loop, gpio, gpio_base, n;
>  	unsigned long gedr;
> -	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct irq_chip *ic = irq_desc_get_chip(desc);
>  
> -	chained_irq_enter(chip, desc);
> +	chained_irq_enter(ic, desc);
>  
>  	do {
>  		loop = 0;
> -		for_each_gpio_chip(gpio, c) {
> -			gpio_base = c->chip.base;
> +		for_each_gpio_chip(gpio, chip) {
> +			gpio_base = chip->chip.base;
>  
> -			gedr = readl_relaxed(c->regbase + GEDR_OFFSET);
> -			gedr = gedr & c->irq_mask;
> -			writel_relaxed(gedr, c->regbase + GEDR_OFFSET);
> +			gedr = readl_relaxed(chip->regbase + GEDR_OFFSET);
> +			gedr = gedr & chip->irq_mask;
> +			writel_relaxed(gedr, chip->regbase + GEDR_OFFSET);
>  
>  			for_each_set_bit(n, &gedr, BITS_PER_LONG) {
>  				loop = 1;
> @@ -326,38 +327,38 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
>  		}
>  	} while (loop);
>  
> -	chained_irq_exit(chip, desc);
> +	chained_irq_exit(ic, desc);
>  }
>  
>  static void pxa_ack_muxed_gpio(struct irq_data *d)
>  {
>  	int gpio = pxa_irq_to_gpio(d);
> -	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
> +	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
>  
> -	writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
> +	writel_relaxed(GPIO_bit(gpio), chip->regbase + GEDR_OFFSET);
>  }
>  
>  static void pxa_mask_muxed_gpio(struct irq_data *d)
>  {
>  	int gpio = pxa_irq_to_gpio(d);
> -	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
> +	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
>  	uint32_t grer, gfer;
>  
> -	c->irq_mask &= ~GPIO_bit(gpio);
> +	chip->irq_mask &= ~GPIO_bit(gpio);
>  
> -	grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
> -	gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
> -	writel_relaxed(grer, c->regbase + GRER_OFFSET);
> -	writel_relaxed(gfer, c->regbase + GFER_OFFSET);
> +	grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
> +	gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
> +	writel_relaxed(grer, chip->regbase + GRER_OFFSET);
> +	writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
>  }
>  
>  static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  {
>  	int gpio = pxa_irq_to_gpio(d);
> -	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
> +	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
>  
> -	if (c->set_wake)
> -		return c->set_wake(gpio, on);
> +	if (chip->set_wake)
> +		return chip->set_wake(gpio, on);
>  	else
>  		return 0;
>  }
> @@ -365,10 +366,10 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  static void pxa_unmask_muxed_gpio(struct irq_data *d)
>  {
>  	int gpio = pxa_irq_to_gpio(d);
> -	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
> +	struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
>  
> -	c->irq_mask |= GPIO_bit(gpio);
> -	update_edge_detect(c);
> +	chip->irq_mask |= GPIO_bit(gpio);
> +	update_edge_detect(chip);
>  }
>  
>  static struct irq_chip pxa_muxed_gpio_chip = {
> @@ -466,38 +467,37 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
>  	}
>  
>  	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> -		struct gpio_chip *c = &chips[i].chip;
> +		struct gpio_chip *gc = &chips[i].chip;
>  
>  		sprintf(chips[i].label, "gpio-%d", i);
>  		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
>  		chips[i].set_wake = set_wake;
>  
> -		c->base  = gpio;
> -		c->label = chips[i].label;
> -
> -		c->direction_input  = pxa_gpio_direction_input;
> -		c->direction_output = pxa_gpio_direction_output;
> -		c->get = pxa_gpio_get;
> -		c->set = pxa_gpio_set;
> -		c->to_irq = pxa_gpio_to_irq;
> -#ifdef CONFIG_OF_GPIO
> -		c->of_node = pxa_gpio_of_node;
> -		c->of_xlate = pxa_gpio_of_xlate;
> -		c->of_gpio_n_cells = 2;
> -#endif
> -
>  		/* number of GPIOs on last bank may be less than 32 */
> -		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> +		gc->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
>  
> -		chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
> +		chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
>  		if (chips[i].irq_base < 0)
>  			return -EINVAL;
> -		if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
> +		if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
>  					   chips[i].irq_base, 0,
>  					   &pxa_irq_domain_ops, &chips[i]))
>  			return -ENODEV;
>  
> -		gpiochip_add(c);
> +		gc->base  = gpio;
> +		gc->label = chips[i].label;
> +
> +		gc->direction_input  = pxa_gpio_direction_input;
> +		gc->direction_output = pxa_gpio_direction_output;
> +		gc->get = pxa_gpio_get;
> +		gc->set = pxa_gpio_set;
> +		gc->to_irq = pxa_gpio_to_irq;
> +#ifdef CONFIG_OF_GPIO
> +		gc->of_node = pxa_gpio_of_node;
> +		gc->of_xlate = pxa_gpio_of_xlate;
> +		gc->of_gpio_n_cells = 2;
> +#endif
> +		gpiochip_add(gc);
>  	}
>  	pxa_gpio_chips = chips;
>  	return 0;
> @@ -505,10 +505,10 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
>  
>  static int pxa_gpio_probe(struct platform_device *pdev)
>  {
> -	struct pxa_gpio_chip *c;
> +	struct pxa_gpio_chip *chip;
>  	struct resource *res;
>  	struct clk *clk;
> -	struct pxa_gpio_platform_data *info;
> +	struct pxa_gpio_platform_data *pdata;
>  	int gpio, irq, ret, use_of = 0;
>  	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
>  
> @@ -547,22 +547,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Initialize GPIO chips */
> -	info = dev_get_platdata(&pdev->dev);
> -	pxa_last_gpio = info->nr_gpios - 1;
> -	pxa_init_gpio_chip(pdev, pxa_last_gpio,
> -			   info ? info->gpio_set_wake : NULL);
> +	pdata = dev_get_platdata(&pdev->dev);
> +	pxa_last_gpio = pdata->nr_gpios - 1;
> +	ret = pxa_init_gpio_chip(pdev, pxa_last_gpio,
> +				 pdata ? pdata->gpio_set_wake : NULL);
> +	if (ret < 0)
> +		return ret;
>  
>  	/* clear all GPIO edge detects */
> -	for_each_gpio_chip(gpio, c) {
> -		writel_relaxed(0, c->regbase + GFER_OFFSET);
> -		writel_relaxed(0, c->regbase + GRER_OFFSET);
> -		writel_relaxed(~0,c->regbase + GEDR_OFFSET);
> +	for_each_gpio_chip(gpio, chip) {
> +		writel_relaxed(0, chip->regbase + GFER_OFFSET);
> +		writel_relaxed(0, chip->regbase + GRER_OFFSET);
> +		writel_relaxed(~0,chip->regbase + GEDR_OFFSET);
>  		/* unmask GPIO edge detect for AP side */
> -		if (info->ed_mask)
> -			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
> +		if (pdata->ed_mask)
> +			writel_relaxed(~0, chip->regbase + ED_MASK_OFFSET);
>  		/* update for gpio inverted & gafr */
> -		c->inverted = info->inverted;
> -		c->gafr = info->gafr;
> +		chip->inverted = pdata->inverted;
> +		chip->gafr = pdata->gafr;
>  	}
>  
>  	if (!use_of) {
> @@ -604,34 +606,34 @@ module_platform_driver(pxa_gpio_driver);
>  #ifdef CONFIG_PM
>  static int pxa_gpio_suspend(void)
>  {
> -	struct pxa_gpio_chip *c;
> +	struct pxa_gpio_chip *chip;
>  	int gpio;
>  
> -	for_each_gpio_chip(gpio, c) {
> -		c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET);
> -		c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
> -		c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET);
> -		c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET);
> +	for_each_gpio_chip(gpio, chip) {
> +		chip->saved_gplr = readl_relaxed(chip->regbase + GPLR_OFFSET);
> +		chip->saved_gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
> +		chip->saved_grer = readl_relaxed(chip->regbase + GRER_OFFSET);
> +		chip->saved_gfer = readl_relaxed(chip->regbase + GFER_OFFSET);
>  
>  		/* Clear GPIO transition detect bits */
> -		writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET);
> +		writel_relaxed(~0, chip->regbase + GEDR_OFFSET);
>  	}
>  	return 0;
>  }
>  
>  static void pxa_gpio_resume(void)
>  {
> -	struct pxa_gpio_chip *c;
> +	struct pxa_gpio_chip *chip;
>  	int gpio;
>  
> -	for_each_gpio_chip(gpio, c) {
> +	for_each_gpio_chip(gpio, chip) {
>  		/* restore level with set/clear */
> -		writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET);
> -		writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET);
> +		writel_relaxed( chip->saved_gplr, chip->regbase + GPSR_OFFSET);
> +		writel_relaxed(~chip->saved_gplr, chip->regbase + GPCR_OFFSET);
>  
> -		writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET);
> -		writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET);
> -		writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET);
> +		writel_relaxed(chip->saved_grer, chip->regbase + GRER_OFFSET);
> +		writel_relaxed(chip->saved_gfer, chip->regbase + GFER_OFFSET);
> +		writel_relaxed(chip->saved_gpdr, chip->regbase + GPDR_OFFSET);
>  	}
>  }
>  #else
> 

-- 
Regards,
Igor.

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

* [PATCH v2 07/10] gpio: pxa: remove arch related macro
  2013-02-03 10:15 ` [PATCH v2 07/10] gpio: pxa: remove arch related macro Haojian Zhuang
@ 2013-02-07 15:17   ` Igor Grinberg
  0 siblings, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 12:15, Haojian Zhuang wrote:
> Remove macro CONFIG_ARCH_PXA.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  drivers/gpio/gpio-pxa.c |   30 +++++++++++++++---------------
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 95561d6..8130e3b 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -568,21 +568,21 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  	}
>  
>  	if (!use_of) {
> -#ifdef CONFIG_ARCH_PXA
> -		irq = gpio_to_irq(0);
> -		irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> -					 handle_edge_irq);
> -		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> -		irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
> -
> -		irq = gpio_to_irq(1);
> -		irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> -					 handle_edge_irq);
> -		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> -		irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
> -#endif
> -
> -		for (irq  = gpio_to_irq(gpio_offset);
> +		if (irq0 > 0) {
> +			irq = gpio_to_irq(0);
> +			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> +						 handle_edge_irq);
> +			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +			irq_set_chained_handler(irq0, pxa_gpio_demux_handler);
> +		}
> +		if (irq1 > 0) {
> +			irq = gpio_to_irq(1);
> +			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> +						 handle_edge_irq);
> +			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +			irq_set_chained_handler(irq1, pxa_gpio_demux_handler);
> +		}
> +		for (irq = gpio_to_irq(gpio_offset);
>  			irq <= gpio_to_irq(pxa_last_gpio); irq++) {
>  			irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
>  						 handle_edge_irq);
> 

-- 
Regards,
Igor.

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

* [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request
  2013-02-03 10:15 ` [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request Haojian Zhuang
  2013-02-06 14:11   ` Igor Grinberg
@ 2013-02-07 15:17   ` Igor Grinberg
  1 sibling, 0 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:17 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/03/13 12:15, Haojian Zhuang wrote:
> While gpio pins is requested, request the pin of pinctrl driver first.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Tested-by: Igor Grinberg <grinberg@compulab.co.il>

> ---
>  drivers/gpio/gpio-pxa.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 5c39db3..c9cc636 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -23,6 +23,7 @@
>  #include <linux/io.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
>  #include <linux/syscore_ops.h>
>  #include <linux/slab.h>
> @@ -159,6 +160,23 @@ int pxa_irq_to_gpio(struct irq_data *d)
>  	return gpio;
>  }
>  
> +static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
> +{
> +	/*
> +	 * Map back to global GPIO space and request muxing, the direction
> +	 * parameter does not matter for this controller.
> +	 */
> +	int gpio = gc->base + offset;
> +
> +	/*
> +	 * Platforms in ARCH_PXA doesn't move to device tree yet,
> +	 * and PINCTRL_SINGLE is depend on device tree.
> +	 */ 
> +	if (IS_ENABLED(CONFIG_PINCTRL_SINGLE))
> +		return pinctrl_request_gpio(gpio);
> +	return 0;
> +}
> +
>  static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
>  {
>  	struct pxa_gpio_chip *chip = NULL;
> @@ -471,6 +489,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
>  		gc->base  = gpio;
>  		gc->label = chips[i].label;
>  
> +		gc->request = pxa_gpio_request;
>  		gc->direction_input  = pxa_gpio_direction_input;
>  		gc->direction_output = pxa_gpio_direction_output;
>  		gc->get = pxa_gpio_get;
> 

-- 
Regards,
Igor.

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

* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
  2013-02-06  2:08   ` Haojian Zhuang
@ 2013-02-07 15:32     ` Igor Grinberg
  2013-02-07 15:52       ` Linus Walleij
  0 siblings, 1 reply; 34+ messages in thread
From: Igor Grinberg @ 2013-02-07 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/06/13 04:08, Haojian Zhuang wrote:
> On 6 February 2013 00:44, Linus Walleij <linus.walleij@linaro.org> wrote:
>> On Sun, Feb 3, 2013 at 11:15 AM, Haojian Zhuang
>> <haojian.zhuang@linaro.org> wrote:
>>
>>> v2:
>>> * Fix the build issue without CONFIG_OF
>>> * Append to check PINCTRL_SINGLE because of arch pxa not moved to DT
>>> * Use bool for inverted, ed_mask, gafr variable
>>
>> Haojian, does this series depend on the changes for DT in pinctrl-single,
>> or can I merge it on its own?
>>
>> The amount of patches makes me confused you know ... :-)
>>
>> Yours,
>> Linus Walleij
> 
> I'm waiting for Igor's test on PXA.
> This patch series is used to support DT better. And the driver still works
> without DT support since there's no DT in PXA chips.

Wait a moment, I have a problem with NFS root:
IP-Config: Failed to open eth0
on both cm_x300 and em_x270.
Both machines use DM9000 and before the series,
the problem does not exist.
I will look into it tomorrow, but I have a feeling that it is related to
the DM9000 interrupt line.

So, please, wait on merging this!


-- 
Regards,
Igor.

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

* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
  2013-02-07 15:32     ` Igor Grinberg
@ 2013-02-07 15:52       ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2013-02-07 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 7, 2013 at 4:32 PM, Igor Grinberg <grinberg@compulab.co.il> wrote:

> Wait a moment, I have a problem with NFS root:
(...)
> So, please, wait on merging this!

OK holding back this patch set for now.

Yours,
Linus Walleij

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-03 10:15 ` [PATCH v2 02/10] gpio: pxa: avoid to use global irq base Haojian Zhuang
  2013-02-07 15:17   ` Igor Grinberg
@ 2013-02-13 14:18   ` Igor Grinberg
  2013-02-13 14:55     ` Haojian Zhuang
  1 sibling, 1 reply; 34+ messages in thread
From: Igor Grinberg @ 2013-02-13 14:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/03/13 12:15, Haojian Zhuang wrote:
> Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
> pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
> MMP_GPIO_TO_IRQ().
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Ok. This patch breaks the NFS root on my PXA based systems.
I still haven't found the cause of the breakage.

> ---
>  arch/arm/mach-pxa/pxa25x.c |    2 +-
>  arch/arm/mach-pxa/pxa27x.c |    2 +-
>  drivers/gpio/Kconfig       |    1 +
>  drivers/gpio/gpio-pxa.c    |  156 ++++++++++++++++++++++----------------------
>  include/linux/gpio-pxa.h   |    4 +-
>  5 files changed, 85 insertions(+), 80 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index 3f5171e..f4c293a 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -289,7 +289,7 @@ static inline void pxa25x_init_pm(void) {}
>  
>  static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	uint32_t mask = 0;
>  
>  	if (gpio >= 0 && gpio < 85)
> diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
> index 69985b06..67f5fd2 100644
> --- a/arch/arm/mach-pxa/pxa27x.c
> +++ b/arch/arm/mach-pxa/pxa27x.c
> @@ -364,7 +364,7 @@ static inline void pxa27x_init_pm(void) {}
>   */
>  static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	uint32_t mask;
>  
>  	if (gpio >= 0 && gpio < 128)
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 176fb3d..b8c0da8 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -201,6 +201,7 @@ config GPIO_PL061
>  config GPIO_PXA
>  	bool "PXA GPIO support"
>  	depends on ARCH_PXA || ARCH_MMP
> +	select IRQ_DOMAIN
>  	help
>  	  Say yes here to support the PXA GPIO device
>  
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index a4c6687..2310665 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -13,6 +13,7 @@
>   */
>  #include <linux/module.h>
>  #include <linux/clk.h>
> +#include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/gpio.h>
>  #include <linux/gpio-pxa.h>
> @@ -61,16 +62,15 @@
>  #define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
>  
>  int pxa_last_gpio;
> -static int irq_base;
>  
>  #ifdef CONFIG_OF
> -static struct irq_domain *domain;
>  static struct device_node *pxa_gpio_of_node;
>  #endif
>  
>  struct pxa_gpio_chip {
>  	struct gpio_chip chip;
>  	void __iomem	*regbase;
> +	unsigned int	irq_base;
>  	char label[10];
>  
>  	unsigned long	irq_mask;
> @@ -170,14 +170,22 @@ static inline int __gpio_is_occupied(unsigned gpio)
>  	return ret;
>  }
>  
> -static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> +static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>  {
> -	return chip->base + offset + irq_base;
> +	struct pxa_gpio_chip *chip = NULL;
> +
> +	chip = container_of(gc, struct pxa_gpio_chip, chip);
> +	return chip->irq_base + offset;
>  }
>  
> -int pxa_irq_to_gpio(int irq)
> +int pxa_irq_to_gpio(struct irq_data *d)
>  {
> -	return irq - irq_base;
> +	struct pxa_gpio_chip *chip;
> +	int gpio;
> +
> +	chip = (struct pxa_gpio_chip *)d->domain->host_data;
> +	gpio = d->irq - chip->irq_base + chip->chip.base;
> +	return gpio;
>  }
>  
>  static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> @@ -250,47 +258,6 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
>  }
>  #endif
>  
> -static int pxa_init_gpio_chip(int gpio_end,
> -					int (*set_wake)(unsigned int, unsigned int))
> -{
> -	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
> -	struct pxa_gpio_chip *chips;
> -
> -	chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
> -	if (chips == NULL) {
> -		pr_err("%s: failed to allocate GPIO chips\n", __func__);
> -		return -ENOMEM;
> -	}
> -
> -	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> -		struct gpio_chip *c = &chips[i].chip;
> -
> -		sprintf(chips[i].label, "gpio-%d", i);
> -		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
> -		chips[i].set_wake = set_wake;
> -
> -		c->base  = gpio;
> -		c->label = chips[i].label;
> -
> -		c->direction_input  = pxa_gpio_direction_input;
> -		c->direction_output = pxa_gpio_direction_output;
> -		c->get = pxa_gpio_get;
> -		c->set = pxa_gpio_set;
> -		c->to_irq = pxa_gpio_to_irq;
> -#ifdef CONFIG_OF_GPIO
> -		c->of_node = pxa_gpio_of_node;
> -		c->of_xlate = pxa_gpio_of_xlate;
> -		c->of_gpio_n_cells = 2;
> -#endif
> -
> -		/* number of GPIOs on last bank may be less than 32 */
> -		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> -		gpiochip_add(c);
> -	}
> -	pxa_gpio_chips = chips;
> -	return 0;
> -}
> -
>  /* Update only those GRERx and GFERx edge detection register bits if those
>   * bits are set in c->irq_mask
>   */
> @@ -309,7 +276,7 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
>  static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
>  {
>  	struct pxa_gpio_chip *c;
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	unsigned long gpdr, mask = GPIO_bit(gpio);
>  
>  	c = gpio_to_pxachip(gpio);
> @@ -383,7 +350,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
>  
>  static void pxa_ack_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
> @@ -391,7 +358,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d)
>  
>  static void pxa_mask_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  	uint32_t grer, gfer;
>  
> @@ -405,7 +372,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
>  
>  static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	if (c->set_wake)
> @@ -416,7 +383,7 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
>  
>  static void pxa_unmask_muxed_gpio(struct irq_data *d)
>  {
> -	int gpio = pxa_irq_to_gpio(d->irq);
> +	int gpio = pxa_irq_to_gpio(d);
>  	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
>  
>  	c->irq_mask |= GPIO_bit(gpio);
> @@ -469,13 +436,6 @@ static int pxa_gpio_nums(void)
>  	return count;
>  }
>  
> -#ifdef CONFIG_OF
> -static struct of_device_id pxa_gpio_dt_ids[] = {
> -	{ .compatible = "mrvl,pxa-gpio" },
> -	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> -	{}
> -};
> -
>  static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  			      irq_hw_number_t hw)
>  {
> @@ -485,11 +445,18 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  	return 0;
>  }
>  
> -const struct irq_domain_ops pxa_irq_domain_ops = {
> +static const struct irq_domain_ops pxa_irq_domain_ops = {
>  	.map	= pxa_irq_domain_map,
>  	.xlate	= irq_domain_xlate_twocell,
>  };
>  
> +#ifdef CONFIG_OF
> +static struct of_device_id pxa_gpio_dt_ids[] = {
> +	{ .compatible = "mrvl,pxa-gpio" },
> +	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> +	{}
> +};
> +
>  static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  {
>  	int ret, nr_banks, nr_gpios;
> @@ -528,14 +495,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
>  	nr_gpios = nr_banks << 5;
>  	pxa_last_gpio = nr_gpios - 1;
>  
> -	irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
> -	if (irq_base < 0) {
> -		dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
> -		goto err;
> -	}
> -	domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
> -				       &pxa_irq_domain_ops, NULL);
> -	pxa_gpio_of_node = np;
>  	return 0;
>  err:
>  	iounmap(gpio_reg_base);
> @@ -545,6 +504,56 @@ err:
>  #define pxa_gpio_probe_dt(pdev)		(-1)
>  #endif
>  
> +static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
> +			      int (*set_wake)(unsigned int, unsigned int))
> +{
> +	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
> +	struct pxa_gpio_chip *chips;
> +
> +	chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
> +	if (chips == NULL) {
> +		pr_err("%s: failed to allocate GPIO chips\n", __func__);
> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
> +		struct gpio_chip *c = &chips[i].chip;
> +
> +		sprintf(chips[i].label, "gpio-%d", i);
> +		chips[i].regbase = gpio_reg_base + BANK_OFF(i);
> +		chips[i].set_wake = set_wake;
> +
> +		c->base  = gpio;
> +		c->label = chips[i].label;
> +
> +		c->direction_input  = pxa_gpio_direction_input;
> +		c->direction_output = pxa_gpio_direction_output;
> +		c->get = pxa_gpio_get;
> +		c->set = pxa_gpio_set;
> +		c->to_irq = pxa_gpio_to_irq;
> +#ifdef CONFIG_OF_GPIO
> +		c->of_node = pxa_gpio_of_node;
> +		c->of_xlate = pxa_gpio_of_xlate;
> +		c->of_gpio_n_cells = 2;
> +#endif
> +
> +		/* number of GPIOs on last bank may be less than 32 */
> +		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
> +
> +		chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
> +		if (chips[i].irq_base < 0)
> +			return -EINVAL;
> +		if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
> +					   chips[i].irq_base, 0,
> +					   &pxa_irq_domain_ops, &chips[i]))
> +			return -ENODEV;
> +
> +		gpiochip_add(c);
> +	}
> +	pxa_gpio_chips = chips;
> +	return 0;
> +}
> +
>  static int pxa_gpio_probe(struct platform_device *pdev)
>  {
>  	struct pxa_gpio_chip *c;
> @@ -557,14 +566,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  	ret = pxa_gpio_probe_dt(pdev);
>  	if (ret < 0) {
>  		pxa_last_gpio = pxa_gpio_nums();
> -#ifdef CONFIG_ARCH_PXA
> -		if (gpio_is_pxa_type(gpio_type))
> -			irq_base = PXA_GPIO_TO_IRQ(0);
> -#endif
> -#ifdef CONFIG_ARCH_MMP
> -		if (gpio_is_mmp_type(gpio_type))
> -			irq_base = MMP_GPIO_TO_IRQ(0);
> -#endif
>  	} else {
>  		use_of = 1;
>  	}
> @@ -604,7 +605,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
>  
>  	/* Initialize GPIO chips */
>  	info = dev_get_platdata(&pdev->dev);
> -	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
> +	pxa_init_gpio_chip(pdev, pxa_last_gpio,
> +			   info ? info->gpio_set_wake : NULL);
>  
>  	/* clear all GPIO edge detects */
>  	for_each_gpio_chip(gpio, c) {
> diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
> index bc5cae5..49120b8 100644
> --- a/include/linux/gpio-pxa.h
> +++ b/include/linux/gpio-pxa.h
> @@ -1,6 +1,8 @@
>  #ifndef __GPIO_PXA_H
>  #define __GPIO_PXA_H
>  
> +#include <linux/irq.h>
> +
>  #define GPIO_bit(x)	(1 << ((x) & 0x1f))
>  
>  #define gpio_to_bank(gpio)	((gpio) >> 5)
> @@ -11,7 +13,7 @@
>   */
>  extern int pxa_last_gpio;
>  
> -extern int pxa_irq_to_gpio(int irq);
> +extern int pxa_irq_to_gpio(struct irq_data *d);
>  
>  struct pxa_gpio_platform_data {
>  	bool ed_mask;	/* true means that ed_mask reg is available */
> 

-- 
Regards,
Igor.

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-13 14:18   ` Igor Grinberg
@ 2013-02-13 14:55     ` Haojian Zhuang
  2013-02-14  9:27       ` Igor Grinberg
  0 siblings, 1 reply; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-13 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 February 2013 22:18, Igor Grinberg <grinberg@compulab.co.il> wrote:
> On 02/03/13 12:15, Haojian Zhuang wrote:
>> Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
>> pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
>> MMP_GPIO_TO_IRQ().
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> Ok. This patch breaks the NFS root on my PXA based systems.
> I still haven't found the cause of the breakage.
>

It's so strange. I tested it OK on pxa910 without DT. Could you help
to check whether your GPIO interrupt still works?

Regards
Haojian

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-13 14:55     ` Haojian Zhuang
@ 2013-02-14  9:27       ` Igor Grinberg
  2013-02-14 12:19         ` Linus Walleij
  0 siblings, 1 reply; 34+ messages in thread
From: Igor Grinberg @ 2013-02-14  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/13/13 16:55, Haojian Zhuang wrote:
> On 13 February 2013 22:18, Igor Grinberg <grinberg@compulab.co.il> wrote:
>> On 02/03/13 12:15, Haojian Zhuang wrote:
>>> Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
>>> pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
>>> MMP_GPIO_TO_IRQ().
>>>
>>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>>
>> Ok. This patch breaks the NFS root on my PXA based systems.
>> I still haven't found the cause of the breakage.
>>
> 
> It's so strange. I tested it OK on pxa910 without DT. Could you help
> to check whether your GPIO interrupt still works?

It looks like I've figured this out...
For em-x270 as an example, if I move the IRQ resource assignment to runtime:

diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 1b64114..178cc0b 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -210,8 +210,6 @@ static struct resource em_x270_dm9000_resource[] = {
 		.flags = IORESOURCE_MEM,
 	},
 	[2] = {
-		.start = EM_X270_ETHIRQ,
-		.end   = EM_X270_ETHIRQ,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
@@ -232,6 +230,9 @@ static struct platform_device em_x270_dm9000 = {
 
 static void __init em_x270_init_dm9000(void)
 {
+	em_x270_dm9000_resource[2].start = gpio_to_irq(GPIO41_ETHIRQ);
+	em_x270_dm9000_resource[2].end = gpio_to_irq(GPIO41_ETHIRQ);
+
 	em_x270_dm9000_platdata.flags |= dm9000_flags;
 	platform_device_register(&em_x270_dm9000);
 }

The Ethernet is alive and NFS root works fine.

So my conclusion, is that we still need to have some work done
before we can switch to using IRQ_DOMAIN.
As you can see from above patch, we at least must deal with the
PXA_GPIO_TO_IRQ macros and alike that have compile time assumptions
which obviously get broken once you switch to the IRQ_DOMAIN.

What do you think?

-- 
Regards,
Igor.

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-14  9:27       ` Igor Grinberg
@ 2013-02-14 12:19         ` Linus Walleij
  2013-02-14 12:45           ` Igor Grinberg
  0 siblings, 1 reply; 34+ messages in thread
From: Linus Walleij @ 2013-02-14 12:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 14, 2013 at 10:27 AM, Igor Grinberg <grinberg@compulab.co.il> wrote:

> It looks like I've figured this out...
> For em-x270 as an example, if I move the IRQ resource assignment to runtime:
>
> diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
> index 1b64114..178cc0b 100644
> --- a/arch/arm/mach-pxa/em-x270.c
> +++ b/arch/arm/mach-pxa/em-x270.c
> @@ -210,8 +210,6 @@ static struct resource em_x270_dm9000_resource[] = {
>                 .flags = IORESOURCE_MEM,
>         },
>         [2] = {
> -               .start = EM_X270_ETHIRQ,
> -               .end   = EM_X270_ETHIRQ,
>                 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
>         }
>  };
> @@ -232,6 +230,9 @@ static struct platform_device em_x270_dm9000 = {
>
>  static void __init em_x270_init_dm9000(void)
>  {
> +       em_x270_dm9000_resource[2].start = gpio_to_irq(GPIO41_ETHIRQ);
> +       em_x270_dm9000_resource[2].end = gpio_to_irq(GPIO41_ETHIRQ);
> +
>         em_x270_dm9000_platdata.flags |= dm9000_flags;
>         platform_device_register(&em_x270_dm9000);
>  }
>
> The Ethernet is alive and NFS root works fine.
>
> So my conclusion, is that we still need to have some work done
> before we can switch to using IRQ_DOMAIN.
> As you can see from above patch, we at least must deal with the
> PXA_GPIO_TO_IRQ macros and alike that have compile time assumptions
> which obviously get broken once you switch to the IRQ_DOMAIN.
>
> What do you think?

I think it seems like you should review all the IRQ assignments in that
former GPIO range. Statically encoding IRQ numbers for GPIO things
is usually not a good idea, it's better to always use gpio_to_irq()
on these and only keep hard-coded GPIO numbers around (atleast
just *one* problem to worry about).

Your,
Linus Walleij

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-14 12:19         ` Linus Walleij
@ 2013-02-14 12:45           ` Igor Grinberg
  2013-02-14 15:34             ` Linus Walleij
  2013-02-17 14:54             ` Haojian Zhuang
  0 siblings, 2 replies; 34+ messages in thread
From: Igor Grinberg @ 2013-02-14 12:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/14/13 14:19, Linus Walleij wrote:
> On Thu, Feb 14, 2013 at 10:27 AM, Igor Grinberg <grinberg@compulab.co.il> wrote:
> 
>> It looks like I've figured this out...
>> For em-x270 as an example, if I move the IRQ resource assignment to runtime:
>>
>> diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
>> index 1b64114..178cc0b 100644
>> --- a/arch/arm/mach-pxa/em-x270.c
>> +++ b/arch/arm/mach-pxa/em-x270.c
>> @@ -210,8 +210,6 @@ static struct resource em_x270_dm9000_resource[] = {
>>                 .flags = IORESOURCE_MEM,
>>         },
>>         [2] = {
>> -               .start = EM_X270_ETHIRQ,
>> -               .end   = EM_X270_ETHIRQ,
>>                 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
>>         }
>>  };
>> @@ -232,6 +230,9 @@ static struct platform_device em_x270_dm9000 = {
>>
>>  static void __init em_x270_init_dm9000(void)
>>  {
>> +       em_x270_dm9000_resource[2].start = gpio_to_irq(GPIO41_ETHIRQ);
>> +       em_x270_dm9000_resource[2].end = gpio_to_irq(GPIO41_ETHIRQ);
>> +
>>         em_x270_dm9000_platdata.flags |= dm9000_flags;
>>         platform_device_register(&em_x270_dm9000);
>>  }
>>
>> The Ethernet is alive and NFS root works fine.
>>
>> So my conclusion, is that we still need to have some work done
>> before we can switch to using IRQ_DOMAIN.
>> As you can see from above patch, we at least must deal with the
>> PXA_GPIO_TO_IRQ macros and alike that have compile time assumptions
>> which obviously get broken once you switch to the IRQ_DOMAIN.
>>
>> What do you think?
> 
> I think it seems like you should review all the IRQ assignments in that
> former GPIO range. Statically encoding IRQ numbers for GPIO things
> is usually not a good idea, it's better to always use gpio_to_irq()
> on these and only keep hard-coded GPIO numbers around (atleast
> just *one* problem to worry about).

Well, it always worked like this...
Now it is clear that we cannot continue doing it
(at least not with current IRQ_DOMAIN).

In order to merge this patch, we need to either remove
the static PXA_GPIO_TO_IRQ macros and alike, or teach the IRQ_DOMAIN
somehow to know about these.
I don't know what from the above is easier to do, as I did not looked
deeper into this.

I might have some time to look into this in two weeks from now,
but I guess it will be too late as Haojian wants this patch set
to go into 3.9.


-- 
Regards,
Igor.

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-14 12:45           ` Igor Grinberg
@ 2013-02-14 15:34             ` Linus Walleij
  2013-02-17 14:54             ` Haojian Zhuang
  1 sibling, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2013-02-14 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 14, 2013 at 1:45 PM, Igor Grinberg <grinberg@compulab.co.il> wrote:

> In order to merge this patch, we need to either remove
> the static PXA_GPIO_TO_IRQ macros and alike, or teach the IRQ_DOMAIN
> somehow to know about these.
> I don't know what from the above is easier to do, as I did not looked
> deeper into this.

I think it's quite easy to get the irqdomain in place and working
correctly. It's intended to solve exactly this kind of thing.

> I might have some time to look into this in two weeks from now,
> but I guess it will be too late as Haojian wants this patch set
> to go into 3.9.

This patch as outlined by me in the previous comments, with a
complete working irqdomain is welcome if you can get it tested.

Yours,
Linus Walleij

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

* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
  2013-02-14 12:45           ` Igor Grinberg
  2013-02-14 15:34             ` Linus Walleij
@ 2013-02-17 14:54             ` Haojian Zhuang
  1 sibling, 0 replies; 34+ messages in thread
From: Haojian Zhuang @ 2013-02-17 14:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 14 February 2013 20:45, Igor Grinberg <grinberg@compulab.co.il> wrote:
> On 02/14/13 14:19, Linus Walleij wrote:
>> On Thu, Feb 14, 2013 at 10:27 AM, Igor Grinberg <grinberg@compulab.co.il> wrote:
>>
>>> It looks like I've figured this out...
>>> For em-x270 as an example, if I move the IRQ resource assignment to runtime:
>>>
>>> diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
>>> index 1b64114..178cc0b 100644
>>> --- a/arch/arm/mach-pxa/em-x270.c
>>> +++ b/arch/arm/mach-pxa/em-x270.c
>>> @@ -210,8 +210,6 @@ static struct resource em_x270_dm9000_resource[] = {
>>>                 .flags = IORESOURCE_MEM,
>>>         },
>>>         [2] = {
>>> -               .start = EM_X270_ETHIRQ,
>>> -               .end   = EM_X270_ETHIRQ,
>>>                 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
>>>         }
>>>  };
>>> @@ -232,6 +230,9 @@ static struct platform_device em_x270_dm9000 = {
>>>
>>>  static void __init em_x270_init_dm9000(void)
>>>  {
>>> +       em_x270_dm9000_resource[2].start = gpio_to_irq(GPIO41_ETHIRQ);
>>> +       em_x270_dm9000_resource[2].end = gpio_to_irq(GPIO41_ETHIRQ);
>>> +
>>>         em_x270_dm9000_platdata.flags |= dm9000_flags;
>>>         platform_device_register(&em_x270_dm9000);
>>>  }
>>>
>>> The Ethernet is alive and NFS root works fine.
>>>
>>> So my conclusion, is that we still need to have some work done
>>> before we can switch to using IRQ_DOMAIN.
>>> As you can see from above patch, we at least must deal with the
>>> PXA_GPIO_TO_IRQ macros and alike that have compile time assumptions
>>> which obviously get broken once you switch to the IRQ_DOMAIN.
>>>
>>> What do you think?
>>
>> I think it seems like you should review all the IRQ assignments in that
>> former GPIO range. Statically encoding IRQ numbers for GPIO things
>> is usually not a good idea, it's better to always use gpio_to_irq()
>> on these and only keep hard-coded GPIO numbers around (atleast
>> just *one* problem to worry about).
>
> Well, it always worked like this...
> Now it is clear that we cannot continue doing it
> (at least not with current IRQ_DOMAIN).
>
> In order to merge this patch, we need to either remove
> the static PXA_GPIO_TO_IRQ macros and alike, or teach the IRQ_DOMAIN
> somehow to know about these.
> I don't know what from the above is easier to do, as I did not looked
> deeper into this.
>
> I might have some time to look into this in two weeks from now,
> but I guess it will be too late as Haojian wants this patch set
> to go into 3.9.
>
>
> --
> Regards,
> Igor.

I can append pdata->irq_base to resolve this issue. While I'm
finished, I'll send it
out.

I don't want to change too much files in pxa directory. If I have enough time, I
would put resource on supporting DT & mutliplatform on pxa. So I'll
fix this issue.

Thanks
Haojian

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

end of thread, other threads:[~2013-02-17 14:54 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-03 10:15 [PATCH v2 00/10] rework pxa gpio driver for pinctrl Haojian Zhuang
2013-02-03 10:15 ` [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
2013-02-03 10:15 ` [PATCH v2 02/10] gpio: pxa: avoid to use global irq base Haojian Zhuang
2013-02-07 15:17   ` Igor Grinberg
2013-02-13 14:18   ` Igor Grinberg
2013-02-13 14:55     ` Haojian Zhuang
2013-02-14  9:27       ` Igor Grinberg
2013-02-14 12:19         ` Linus Walleij
2013-02-14 12:45           ` Igor Grinberg
2013-02-14 15:34             ` Linus Walleij
2013-02-17 14:54             ` Haojian Zhuang
2013-02-03 10:15 ` [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
2013-02-07 15:17   ` Igor Grinberg
2013-02-03 10:15 ` [PATCH v2 04/10] gpio: pxa: remove gpio_type Haojian Zhuang
2013-02-07 15:17   ` Igor Grinberg
2013-02-03 10:15 ` [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data Haojian Zhuang
2013-02-03 13:18   ` Igor Grinberg
2013-02-03 15:00     ` [PATCH v2 05/11] " Haojian Zhuang
2013-02-07 15:17       ` Igor Grinberg
2013-02-03 15:03     ` [PATCH v2 05/10] " Haojian Zhuang
2013-02-03 10:15 ` [PATCH v2 06/10] gpio: pxa: clean code for compatible name Haojian Zhuang
2013-02-07 15:17   ` Igor Grinberg
2013-02-03 10:15 ` [PATCH v2 07/10] gpio: pxa: remove arch related macro Haojian Zhuang
2013-02-07 15:17   ` Igor Grinberg
2013-02-03 10:15 ` [PATCH v2 08/10] gpio: pxa: move gpio properties into child node Haojian Zhuang
2013-02-03 10:15 ` [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request Haojian Zhuang
2013-02-06 14:11   ` Igor Grinberg
2013-02-07 15:17   ` Igor Grinberg
2013-02-03 10:15 ` [PATCH v2 10/10] ARM: dts: support pinmux in pxa910 Haojian Zhuang
2013-02-06 14:12   ` Igor Grinberg
2013-02-05 16:44 ` [PATCH v2 00/10] rework pxa gpio driver for pinctrl Linus Walleij
2013-02-06  2:08   ` Haojian Zhuang
2013-02-07 15:32     ` Igor Grinberg
2013-02-07 15:52       ` 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.