Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 04/10] gpio: pxa: use platform data for gpio inverted
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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    |   41 ++++++++++++++++++++++++++---------------
 include/linux/gpio-pxa.h   |    1 +
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f4c293a..8d77090 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 = 1,
+#endif
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index da6e7fd..6d61a69 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;
+	unsigned int	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);
@@ -475,6 +480,10 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	ret = of_find_property(np, "marvell,gpio-ed-mask", NULL);
 	if (ret)
 		pdata->ed_mask = 1;
+	/* It's only valid for PXA26x */
+	ret = of_find_property(np, "marvell,gpio-inverted", NULL);
+	if (ret)
+		pdata->inverted = 1;
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
 	gpio_type = (int)of_id->data;
@@ -617,6 +626,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 bdee118..c8d07be5 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 {
 	unsigned ed_mask;	/* not 0 means ed_mask reg is available */
+	unsigned inverted;	/* only valid for PXA26x */
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 05/10] gpio: pxa: remove gpio_type
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 8d77090..90415a6 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 = 1,
 #endif
+	.gafr = 1,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 257d936..91ac5d9 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -422,6 +422,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 = 1,
 	.gpio_set_wake = gpio_set_wake,
 };
 
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 6d61a69..8b3edc7 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;
 	unsigned int	inverted;
+	unsigned int	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;
@@ -444,7 +413,7 @@ static int pxa_gpio_nums(void)
 #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" },
 	{}
 };
 
@@ -486,7 +455,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 		pdata->inverted = 1;
 	/* set the platform data */
 	pdev->dev.platform_data = pdata;
-	gpio_type = (int)of_id->data;
 
 	next = of_get_next_child(np, NULL);
 	prev = next;
@@ -626,8 +594,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 c8d07be5..5a9e003 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 {
 	unsigned ed_mask;	/* not 0 means ed_mask reg is available */
+	unsigned gafr;		/* only valid for PXA25x/PXA26x/PXA27x */
 	unsigned inverted;	/* only valid for PXA26x */
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 06/10] gpio: pxa: define nr gpios in platform data
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 ee1fb62..f5aea07 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 8b4b1ae..2f93f8f 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 0454488..7f07cc5 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 7ec873c..bf37d97 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index d592041..47808e1 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index a855e69..dd4a22b 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 9f64f37..b3e7bf9 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	= 1,
 };
 
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 74081cd..597268c 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	= 1,
 };
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 90415a6..eb82ece 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 = 1,
+	.nr_gpios = 90,
+#else
+	.nr_gpios = 85,
 #endif
 	.gafr = 1,
 	.gpio_set_wake = gpio_set_wake,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 91ac5d9..8e6b164 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -423,6 +423,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 = 1,
+	.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 8b3edc7..67be225 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;
-}
-
 #ifdef CONFIG_OF
 static struct of_device_id pxa_gpio_dt_ids[] = {
 	{ .compatible = "mrvl,pxa-gpio" },
@@ -433,7 +403,7 @@ static 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;
+	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 =
@@ -453,6 +423,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
 	ret = of_find_property(np, "marvell,gpio-inverted", NULL);
 	if (ret)
 		pdata->inverted = 1;
+	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;
 
@@ -470,8 +445,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:
@@ -542,14 +515,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");
@@ -583,6 +550,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 5a9e003..cf17f4c 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
 	unsigned ed_mask;	/* not 0 means ed_mask reg is available */
 	unsigned gafr;		/* only valid for PXA25x/PXA26x/PXA27x */
 	unsigned inverted;	/* only valid for PXA26x */
+	unsigned nr_gpios;
 	int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
 };
 
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 07/10] gpio: pxa: clean code for compatible name
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 67be225..5870944 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 = {
@@ -468,38 +469,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;
@@ -507,10 +507,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;
 
@@ -549,22 +549,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) {
@@ -606,34 +608,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

* [PATCH 08/10] gpio: pxa: remove arch related macro
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 5870944..21cf8fd 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -570,21 +570,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

* [PATCH 09/10] gpio: pxa: move gpio properties into child node
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 |   33 ++++++++-------------------------
 1 file changed, 8 insertions(+), 25 deletions(-)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 21cf8fd..528f742 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 const struct irq_domain_ops pxa_irq_domain_ops = {
 
 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);
 
@@ -432,25 +428,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)
@@ -460,6 +438,7 @@ 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 device_node *next, *np = pdev->dev.of_node;
 	struct pxa_gpio_chip *chips;
 
 	chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
@@ -468,6 +447,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		return -ENOMEM;
 	}
 
+	next = of_get_next_child(np, NULL);
 	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
 		struct gpio_chip *gc = &chips[i].chip;
 
@@ -495,7 +475,10 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
 		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_node = next;
+		next = of_get_next_child(np, next);
+		of_node_put(gc->of_node);
+
 		gc->of_xlate = pxa_gpio_of_xlate;
 		gc->of_gpio_n_cells = 2;
 #endif
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 10/10] gpio: pxa: bind to pinctrl by request
From: Haojian Zhuang @ 2013-01-23  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>

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 |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 528f742..d64ec8c 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,17 @@ 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;
+
+	return pinctrl_request_gpio(gpio);
+}
+
 static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
 {
 	struct pxa_gpio_chip *chip = NULL;
@@ -469,6 +481,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

* [PATCH v2] Dove: activate GPIO interrupts in DT
From: Jean-Francois Moine @ 2013-01-23  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

In a DT, the interrupts of an interrupt-controller are not usable when
#interrupt-cells is missing.

This patch activates the interrupts of the GPIOs 0 and 1 for the Marvell
Dove SoC.

Signed-off-by: Jean-Fran?ois Moine <moinejf@free.fr>
---
v2
- gpio-mvebu asks for 2 cells
---
 arch/arm/boot/dts/dove.dtsi |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 42eac1f..740630f 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -93,6 +93,7 @@
 			reg = <0xd0400 0x20>;
 			ngpios = <32>;
 			interrupt-controller;
+			#interrupt-cells = <2>;
 			interrupts = <12>, <13>, <14>, <60>;
 		};
 
@@ -103,6 +104,7 @@
 			reg = <0xd0420 0x20>;
 			ngpios = <32>;
 			interrupt-controller;
+			#interrupt-cells = <2>;
 			interrupts = <61>;
 		};
 
 
-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply related

* [PATCH V5] drivers/pinctrl: grab default handles from device core
From: Linus Walleij @ 2013-01-23  8:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358877374-1279-1-git-send-email-swarren@wwwdotorg.org>

OK!

This modified version of the patch is way more beautiful, stupid
me for not realizing it could be written like that.

And I can sure live with the removed doc piece ... we can discuss
that separately if need be, I have some argument for it but it's
a separate issue.

I've dubbed this version the v5 variant and applied it, and included
the changelog (so I remember how it came about).

Greg/Mark: are you still confident with your ACK/Reviewed-by
tags being added on this version?

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH] ARM: PXA3xx: program the CSMSADRCFG register
From: Haojian Zhuang @ 2013-01-23  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMPhdO8LfzvjoE1Re9G44pAZh+-9U7aj5gUWj2xeUyV1ihyRSg@mail.gmail.com>

On Tue, Jan 15, 2013 at 11:01 AM, Eric Miao <eric.y.miao@gmail.com> wrote:
>
> On Sun, Jan 13, 2013 at 7:49 PM, Igor Grinberg <grinberg@compulab.co.il> wrote:
> > The Chip Select Configuration Register must be programmed to 0x2 in
> > order to achieve the correct behavior of the Static Memory Controller.
> >
> > Without this patch devices wired to DFI and accessed through SMC cannot
> > be accessed after resume from S2.
> >
> > Do not rely on the boot loader to program the CSMSADRCFG register by
> > programming it in the kernel smemc module.
> >
>
> Looks good to me. Acked-by: Eric Miao <eric.y.miao@gmail.com>
>

Appled.

Thanks.
Haojian

^ permalink raw reply

* [[PATCH v2]] OMAP: omap4-panda: add WiLink shared transport power functions
From: Peter Ujfalusi @ 2013-01-23  8:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130118174910.GF15361@atomide.com>

Hi Tony,

On 01/18/2013 06:49 PM, Tony Lindgren wrote:
> Currently it seems that we need the following working with DT to have panda
> and blaze usable:
> 
> 1. MMC (done)
> 2. USB (patches pending for EHCI and MUSB)
> 3. Ethernet (done for blaze, needs USB for panda)
> 4. DSS (various drivers pending, probably still needs some platform init code)
> 5. WLAN (no binding, needs platform init until done)
> 6. Audio (done?)

Yes, audio is ready. We are covering OMAP2/3/4/5 (adding OMAP1 should not be a
big issue either) with SoC IPs in DT support. We have dmaengine for all OMAP
audio stuff. Codec drivers I maintain in upstream are also works with DT. We
have ASoC machine drivers to cover most of the upstream boards (OMAP3/4/5). So
audio is pretty much done in DT context, we are waiting for the DMA bindings
only AFAIK.

-- 
P?ter

^ permalink raw reply

* [PATCH] [ARM] spitz/pxa: Minor naming fixes in spitz.c
From: Haojian Zhuang @ 2013-01-23  8:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1355254812-14500-1-git-send-email-dromede@gmail.com>

On Wed, Dec 12, 2012 at 3:40 AM,  <dromede@gmail.com> wrote:
> From: Marko Katic <dromede.gmail.com>
>
> The NAND init section was erroneously named "Framebuffer".
> Gpio expander section should really be called "I2C devices"
> since it contains all i2c init code.
>
> Signed-off-by: Marko Katic <dromede@gmail.com>
> ---
>  arch/arm/mach-pxa/spitz.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
Applied.

Thanks
Haojian

^ permalink raw reply

* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Santosh Shilimkar @ 2013-01-23  8:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOesGMgtaCkiv285TU_vbAokN5M2MrANQ9piDcyXu5YMmbQq3A@mail.gmail.com>

On Tuesday 22 January 2013 10:34 PM, Olof Johansson wrote:
> On Tue, Jan 22, 2013 at 8:57 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 01/21/2013 11:07 PM, Santosh Shilimkar wrote:
>>> On Tuesday 22 January 2013 11:22 AM, Hiroshi Doyu wrote:
>>>> Skip scu_enable(scu_base) if CPU is not Cortex A9 with SCU.
>>>>
>>>> Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
>>>> ---
>>> Looks fine. I will also update OMAP code with the new
>>> interface. Thanks.
>>
>> OK, so patch 1/2 at least needs to get into a stable arm-soc branch
>> then. Unless there are violent objections, I'll forward patch 1/2 to
>> arm-soc and request it be added into a branch so that Tegra and OMAP can
>> both merge it into their branches as a dependency. I guess patch 2/2
>> could also be included; I don't think it has any complex dependencies
>> that'd prevent that, and would help to show how patch 1/2 gets used.
>>
>> Hiroshi, is this series the only dependency you need for your Tegra114
>> series? So, I could merge your Tegra114 series once this series is applied?
>
> For something like this, it might make more sense for us to just apply
> the patches for OMAP on top, i.e. we'll pull the short branch from
> you, and then we can just apply patches (with maintainer acks) on top,
> instead of doing a bunch of single-patch pulls.
>
In case you decide to apply patches, you can use patch in the end
of the email for OMAP. Attached the same in case mailer damages it.

Btw, I noticed the build error with patch 1/1. Since I wasn't using
the first interface in OMAP code, I just bypassed it for testing.
I might be missing some dependent patch which added
read_cpuid_part_number().

---------------
In file included from arch/arm/kernel/smp_scu.c:15:0:
linux-2.6/arch/arm/include/asm/smp_scu.h: In function 'scu_a9_has_base':
linux-2.6/arch/arm/include/asm/smp_scu.h:14:2: error: implicit 
declaration of function 'read_cpuid_part_number' 
[-Werror=implicit-function-declaration]
linux-2.6/arch/arm/include/asm/smp_scu.h:14:37: error: 
'ARM_CPU_PART_CORTEX_A9' undeclared (first use in this function)
linux-2.6/arch/arm/include/asm/smp_scu.h:14:37: note: each undeclared 
identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
make[1]: *** [arch/arm/kernel/smp_scu.o] Error 1
make: *** [arch/arm/kernel] Error 2
---------------------------------

Regards
Santosh

 From 9760cd0ed93b48ec22584e89979cd4a8ec65b938 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Wed, 23 Jan 2013 13:56:19 +0530
Subject: [PATCH] ARM: OMAP: Make use of available scu_a9_get_base() 
interface

Drop the define and make use of scu_a9_get_base() which reads
the physical address of SCU from CP15 register.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
  arch/arm/mach-omap2/omap-smp.c |    2 +-
  arch/arm/mach-omap2/omap44xx.h |    1 -
  2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index cd42d92..e683d0d 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -215,7 +215,7 @@ static void __init omap4_smp_init_cpus(void)
  		 * Currently we can't call ioremap here because
  		 * SoC detection won't work until after init_early.
  		 */
-		scu_base =  OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE);
+		scu_base =  OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
  		BUG_ON(!scu_base);
  		ncores = scu_get_core_count(scu_base);
  	} else if (cpu_id == CPU_CORTEX_A15) {
diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h
index 43b927b..8a515bb 100644
--- a/arch/arm/mach-omap2/omap44xx.h
+++ b/arch/arm/mach-omap2/omap44xx.h
@@ -40,7 +40,6 @@
  #define OMAP44XX_GIC_DIST_BASE		0x48241000
  #define OMAP44XX_GIC_CPU_BASE		0x48240100
  #define OMAP44XX_IRQ_GIC_START		32
-#define OMAP44XX_SCU_BASE		0x48240000
  #define OMAP44XX_LOCAL_TWD_BASE		0x48240600
  #define OMAP44XX_L2CACHE_BASE		0x48242000
  #define OMAP44XX_WKUPGEN_BASE		0x48281000
-- 
1.7.9.5


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-OMAP-Make-use-of-available-scu_a9_get_base-inter.patch
Type: text/x-patch
Size: 1627 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130123/2bd872f7/attachment.bin>

^ permalink raw reply related

* [PATCH] [ARM] spitz/pxa: Refactor i2c init code in spitz.c
From: Haojian Zhuang @ 2013-01-23  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1355257645-27888-1-git-send-email-dromede@gmail.com>

On Wed, Dec 12, 2012 at 4:27 AM,  <dromede@gmail.com> wrote:
> From: Marko Katic <dromede.gmail.com>
>
> This patch changes the way i2c devices are defined
> and registered.
>
> I2c devices that are present in all spitz
> variants are always defined and registered while the max7310
> gpio expander specific to the akita variant is defined
> and registered only when building the kernel for akita variants.
>
> spitz_i2c_init() is simplified and is now more readable.
>
> Signed-off-by: Marko Katic <dromede@gmail.com>
> ---
>  arch/arm/mach-pxa/spitz.c |   38 ++++++++++++++++++--------------------
>  1 file changed, 18 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
> index 0cc9dc7..1c7dc2b 100644
> --- a/arch/arm/mach-pxa/spitz.c
> +++ b/arch/arm/mach-pxa/spitz.c
> @@ -865,17 +865,6 @@ static struct pca953x_platform_data akita_pca953x_pdata = {
>         .gpio_base              = AKITA_IOEXP_GPIO_BASE,
>  };
>
> -static struct i2c_board_info spitz_i2c_devs[] = {
> -       {
> -               .type           = "wm8750",
> -               .addr           = 0x1b,
> -       }, {
> -               .type           = "max7310",
> -               .addr           = 0x18,
> -               .platform_data  = &akita_pca953x_pdata,
> -       },
> -};
> -
>  static struct regulator_consumer_supply isl6271a_consumers[] = {
>         REGULATOR_SUPPLY("vcc_core", NULL),
>  };
> @@ -894,26 +883,35 @@ static struct regulator_init_data isl6271a_info[] = {
>         }
>  };
>
> -static struct i2c_board_info spitz_pi2c_devs[] = {
> +static struct i2c_board_info spitz_i2c_devs[2] = {
>         {
> +               .type           = "wm8750",
> +               .addr           = 0x1b,
> +       }, {
>                 .type           = "isl6271a",
>                 .addr           = 0x0c,
>                 .platform_data  = &isl6271a_info,
>         },
>  };
>
spitz_i2c_devs[] are in i2c0 bus. spitz_pi2c_devs[] are in i2c1 bus.
Why do you move wm8750 from i2c0 bus to i2c1 bus?

> +#ifdef CONFIG_MACH_AKITA
> +static struct i2c_board_info akita_i2c_max7310 = {
> +               .type           = "max7310",
> +               .addr           = 0x18,
> +               .platform_data  = &akita_pca953x_pdata,
> +};
> +#endif
> +
>  static void __init spitz_i2c_init(void)
>  {
> -       int size = ARRAY_SIZE(spitz_i2c_devs);
> -
> -       /* Only Akita has the max7310 chip */
> -       if (!machine_is_akita())
> -               size--;
> -
>         pxa_set_i2c_info(NULL);
>         pxa27x_set_i2c_power_info(NULL);
> -       i2c_register_board_info(0, spitz_i2c_devs, size);
> -       i2c_register_board_info(1, ARRAY_AND_SIZE(spitz_pi2c_devs));
> +
> +       i2c_register_board_info(0, &spitz_i2c_devs[0], 1);
> +       i2c_register_board_info(1, &spitz_i2c_devs[1], 1);
> +
> +       if (machine_is_akita())
> +               i2c_register_board_info(0, &akita_i2c_max7310, 1);
>  }
>  #else
>  static inline void spitz_i2c_init(void) {}
> --
> 1.7.10.4
>

^ permalink raw reply

* [PATCH v3 1/2] mtd: Add a common JEDEC flash device table
From: Matthieu CASTET @ 2013-01-23  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358928068-12417-2-git-send-email-linux@prisktech.co.nz>

Tony Prisk a ?crit :
> This patch adds a common JEDEC flash device table which can be
> expanded on as more features are required.
> 
> A simple match function is also included to query the table for
> a match based on the JEDEC id.

Why don't you use id from include/linux/mtd/cfi.h that is used by flash driver
like drivers/mtd/devices/m25p80.c ?


#define CFI_MFR_AMD     0x0001
#define CFI_MFR_AMIC        0x0037
#define CFI_MFR_ATMEL       0x001F
#define CFI_MFR_EON     0x001C
#define CFI_MFR_FUJITSU     0x0004
#define CFI_MFR_HYUNDAI     0x00AD
#define CFI_MFR_INTEL       0x0089
#define CFI_MFR_MACRONIX    0x00C2
#define CFI_MFR_NEC     0x0010
#define CFI_MFR_PMC     0x009D
#define CFI_MFR_SAMSUNG     0x00EC
#define CFI_MFR_SHARP       0x00B0
#define CFI_MFR_SST     0x00BF
#define CFI_MFR_ST      0x0020 /* STMicroelectronics */
#define CFI_MFR_TOSHIBA     0x0098
#define CFI_MFR_WINBOND     0x00DA


> 
> Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
> ---
>  drivers/mtd/devices/flash_jedec.c |   96 +++++++++++++++++++++++++++++++++++++
>  drivers/mtd/devices/flash_jedec.h |   30 ++++++++++++
>  2 files changed, 126 insertions(+)
>  create mode 100644 drivers/mtd/devices/flash_jedec.c
>  create mode 100644 drivers/mtd/devices/flash_jedec.h
> 
> diff --git a/drivers/mtd/devices/flash_jedec.c b/drivers/mtd/devices/flash_jedec.c
> new file mode 100644
> index 0000000..c0b2272
> --- /dev/null
> +++ b/drivers/mtd/devices/flash_jedec.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright Tony Prisk <linux@prisktech.co.nz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +
> +#include "flash_jedec.h"
> +
> +/*
> + * Device Manufacturer IDs
> + * Please keep sorted by manufacturer ID
> + */
> +#define MFR_SPANSION		0X01
> +#define MFR_EON			0X1C
> +#define MFR_ATMEL		0X1F
> +#define MFR_MICRON		0X20	/* Also Numonyx & STM */
> +#define MFR_INTEL		0x89
> +#define MFR_FUDAN		0XA1
> +#define MFR_SST			0XBF
> +#define MFR_MXIC		0XC2
> +#define MFR_WINBOND		0XEF
> +
> +#define _ID(m, d)	((m << 16) | d)
> +
> +/*
> + * Flash device information
> + * Please keep sorted by manufacturer id, then device id
> + */
> +static struct flash_device_info flash_devices[] = {
> +	/* Spansion */
> +	{ "s25fl016", _ID(MFR_SPANSION, 0x0214), 2048 },
> +	{ "s25fl064", _ID(MFR_SPANSION, 0x0216), 8192 },
> +	/* EON */
> +	{ "en25p16", _ID(MFR_EON, 0x2015), 2048 },
> +	{ "en25p64", _ID(MFR_EON, 0x2017), 8192 },
> +	{ "en25f40", _ID(MFR_EON, 0x3113),  512 },
> +	{ "en25f16", _ID(MFR_EON, 0x3115), 2048 },
> +	/* ATMEL */
> +	{ "at25df041a", _ID(MFR_ATMEL, 0x4401), 512 },
> +	/* Micron, STM & Numonyx */
> +	{ "stm25p16", _ID(MFR_MICRON, 0x2015), 2048 },
> +	{ "stm25p64", _ID(MFR_MICRON, 0x2017), 8192 },
> +	/* Fudan */
> +	{ "fm25f04", _ID(MFR_FUDAN, 0x3113), 512 },
> +	/* SST */
> +	{ "sst25vf016b", _ID(MFR_SST, 0x2541), 2048 },
> +	/* Macronix - MXIC */
> +	{ "mx25l512",   _ID(MFR_MXIC, 0x2010),    64 },
> +	{ "mx25l4005",  _ID(MFR_MXIC, 0x2013),   512 },
> +	{ "mx25l1605",  _ID(MFR_MXIC, 0x2015),  2048 },
> +	{ "mx25l3205",  _ID(MFR_MXIC, 0x2016),  4096 },
> +	{ "mx25l6405",  _ID(MFR_MXIC, 0x2017),  8192 },
> +	{ "mx25l12805", _ID(MFR_MXIC, 0x2018), 16384 },
> +	{ "mx25l1635",  _ID(MFR_MXIC, 0x2415),  2048 },
> +	{ "mx25l3235",  _ID(MFR_MXIC, 0x5E16),  4096 },
> +	/* Winbond */
> +	{ "w25x40", _ID(MFR_WINBOND, 0x3013),   512 },
> +	{ "w25x16", _ID(MFR_WINBOND, 0x3015),  2048 },
> +	{ "w25x32", _ID(MFR_WINBOND, 0x3016),  4096 },
> +	{ "w25x64", _ID(MFR_WINBOND, 0x3017),  8192 },
> +};
> +
> +/*
> + * jedec_match_device - match a jedec id against the flash_devices table
> + * @jedecid: JEDEC formatted id to match
> + *	bits 16..24: manufacturer id
> + *	bits  0..15: device id
> + * Returns a valid flash_device_info* or ERR_PTR(-ENODEV) if an entry is
> + * not found
> + */
> +struct flash_device_info *jedec_match_device(u32 jedec_id)
> +{
> +	int i;
> +	for (i = 0; i < ARRAY_SIZE(flash_devices); i++)
> +		if (flash_devices[i].jedec_id == jedec_id)
> +			return &flash_devices[i];
> +
> +	return ERR_PTR(-ENODEV);
> +}
> diff --git a/drivers/mtd/devices/flash_jedec.h b/drivers/mtd/devices/flash_jedec.h
> new file mode 100644
> index 0000000..27b978a
> --- /dev/null
> +++ b/drivers/mtd/devices/flash_jedec.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright Tony Prisk <linux@prisktech.co.nz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#ifndef __MTD_FLASH_JEDEC
> +#define __MTD_FLASH_JEDEC
> +
> +struct flash_device_info {
> +	const char	*name;
> +	u32		jedec_id;
> +	u32		size_kb;
> +};
> +
> +extern struct flash_device_info *jedec_match_device(u32 jedec_id);
> +
> +#endif


-- 
Matthieu Castet
Ing?nieur D?veloppement Logiciel
Parrot SA
174 Quai de Jemmapes
75010 Paris, France

T?l: +33 (0) 1 48 03 74 78
Fax: +33 (0) 1 48 03 06 66
Email: matthieu.castet at parrot.fr
http://www.parrot.biz

^ permalink raw reply

* [PATCH] ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock
From: Haojian Zhuang @ 2013-01-23  9:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87ehjh3man.fsf@free.fr>

On Sun, Nov 25, 2012 at 8:21 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

Applied.

Thanks
Haojian

^ permalink raw reply

* [GIT PULL][for 3.8] request from armsoc/fix branch in pxa git tree
From: Haojian Zhuang @ 2013-01-23  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd & Olof,

Please help to pull armsoc/fix branch in pxa git tree.

Regards
Haojian

The following changes since commit 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619:

  Linux 3.8-rc4 (2013-01-17 19:25:45 -0800)

are available in the git repository at:

  git://github.com/hzhuang1/linux.git armsoc/fix

for you to fetch changes up to eea6e39b916dd282c7fa4629be8934b5ad60e62b:

  ARM: pxa: Minor naming fixes in spitz.c (2013-01-23 17:13:07 +0800)

----------------------------------------------------------------
Igor Grinberg (1):
      ARM: PXA3xx: program the CSMSADRCFG register

Marko Katic (1):
      ARM: pxa: Minor naming fixes in spitz.c

Mike Dunn (2):
      ARM: palmtreo: fix lcd initilialization on treo680
      ARM: palmtreo: fix #ifdefs for leds-gpio device

 arch/arm/mach-pxa/include/mach/palmtreo.h |    5 +++--
 arch/arm/mach-pxa/include/mach/smemc.h    |    1 +
 arch/arm/mach-pxa/palmtreo.c              |   70
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 arch/arm/mach-pxa/smemc.c                 |   15 ++++++++++++++-
 arch/arm/mach-pxa/spitz.c                 |    4 ++--
 5 files changed, 80 insertions(+), 15 deletions(-)

^ permalink raw reply

* [GIT PULL][for 3.9] request from pxa git tree on armsoc/board branch
From: Haojian Zhuang @ 2013-01-23  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd & Olof,

Please help to merge armsoc/board branch from pxa git tree.

Regards
Haojian

The following changes since commit 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619:

  Linux 3.8-rc4 (2013-01-17 19:25:45 -0800)

are available in the git repository at:

  git://github.com/hzhuang1/linux.git armsoc/board

for you to fetch changes up to 495b21dc0e488b784ab1d4007d00db1ca2a95c98:

  ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock (2013-01-23 17:05:08 +0800)

----------------------------------------------------------------
Andrea Adami (1):
      ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock

Mike Dunn (2):
      ARM: palmtreo: add docg4 device initialization
      ARM: palmtreo: replace #if defined with IF_ENABLED

 arch/arm/mach-pxa/palmtreo.c |   35 +++++++++++++++++++++++++++++++++--
 arch/arm/mach-pxa/pxa27x.c   |    1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

^ permalink raw reply

* arm: Kernel failures when several memory banks are used with starting address above 128MB
From: Russell King - ARM Linux @ 2013-01-23  9:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHTX3dJZxuoz_0Eaa7QcoK9bF4LdLuWcDcwK3OUKc6qY_0PeuQ@mail.gmail.com>

On Tue, Jan 22, 2013 at 08:18:13PM +0100, Michal Simek wrote:
> I have a question regarding to the case where DTS specify one memory bank
> for example <0x0 0x40000000> with CONFIG_ARM_PATCH_PHYS_VIRT=y
> where the kernel can be loaded at a 16MB boundary.

That's where you're going wrong.  We assume that the kernel is loaded
within the 16MB of memory _always_.  Can't get around this on a
multiplatform kernel.

^ permalink raw reply

* [PATCH 0/4] LOW power sleep support for OMAP nand driver
From: Philip Avinash @ 2013-01-23  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds low power transition support for OMAP NAND driver.
This includes low power transition support of
- GPMC module
- ELM module
- OMAP2 NAND driver

Low power transition support tested on am335x-evm with NAND flash support.
This patch series based on [1] and depends on [2] and is available [2]

1. ARM: OMAP2+: AM33XX: Add suspend-resume support
   http://comments.gmane.org/gmane.linux.ports.arm.omap/91405
2. https://github.com/avinashphilip/am335x_linux/commits/NAND_supend_resume_support

Philip Avinash (4):
  arch: arm: gpmc: gpmc migration support
  mtd: devices: elm: Low power transition support
  arm: gpmc: Low power transition support
  mtd: nand: omap2: Low power transition support

 arch/arm/mach-omap2/gpmc.c   |   22 ++++++++++++++++++++--
 arch/arm/mach-omap2/pm34xx.c |    5 -----
 drivers/mtd/devices/elm.c    |   40 ++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/omap2.c     |   19 +++++++++++++++++++
 4 files changed, 79 insertions(+), 7 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH 1/4] arch: arm: gpmc: gpmc migration support
From: Philip Avinash @ 2013-01-23  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358933176-12409-1-git-send-email-avinashphilip@ti.com>

With recent GPMC driver conversion, usage of gpmc_save/restore_context
can done from gpmc driver itself. Hence removes the usage from pm34xx.c.
Also removes the conditional compilation primitives ARCH_OMAP3 for
gpmc_save/restore_context.

Signed-off-by: Philip Avinash <avinashphilip@ti.com>
---
 arch/arm/mach-omap2/gpmc.c   |    2 --
 arch/arm/mach-omap2/pm34xx.c |    5 -----
 2 files changed, 7 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index cbf4e0d..aed958a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1426,7 +1426,6 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_ARCH_OMAP3
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
@@ -1491,4 +1490,3 @@ void omap3_gpmc_restore_context(void)
 		}
 	}
 }
-#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 60fbf0a..cab4c5d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -43,7 +43,6 @@
 #include "common.h"
 #include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
-#include "gpmc.h"
 #include "prm-regbits-34xx.h"
 #include "prm3xxx.h"
 #include "pm.h"
@@ -84,8 +83,6 @@ static void omap3_core_save_context(void)
 
 	/* Save the Interrupt controller context */
 	omap_intc_save_context();
-	/* Save the GPMC context */
-	omap3_gpmc_save_context();
 	/* Save the system control module context, padconf already save above*/
 	omap3_control_save_context();
 	omap_dma_global_context_save();
@@ -95,8 +92,6 @@ static void omap3_core_restore_context(void)
 {
 	/* Restore the control module context, padconf restored by h/w */
 	omap3_control_restore_context();
-	/* Restore the GPMC context */
-	omap3_gpmc_restore_context();
 	/* Restore the interrupt controller context */
 	omap_intc_restore_context();
 	omap_dma_global_context_restore();
-- 
1.7.9.5

^ permalink raw reply related

* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Hiroshi Doyu @ 2013-01-23  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123.080457.171573168772211248.hdoyu@nvidia.com>

Hiroshi Doyu <hdoyu@nvidia.com> wrote @ Wed, 23 Jan 2013 08:04:57 +0200 (EET):

> Stephen Warren <swarren@wwwdotorg.org> wrote @ Tue, 22 Jan 2013 17:57:39 +0100:
> 
> > Hiroshi, is this series the only dependency you need for your
> > Tegra114
> 
> Basically yes.
> 
> > series? So, I could merge your Tegra114 series once this series is applied?
> 
> But now "CCF" seems to be in. Then, the HACK(*1) needs to be replaced
> with "Tegra114 CCF". But "Tegra114 CCF" doesn't seem ready yet. I'll check
> if this Tegra114 series would work without "Tegra114 CCF".
> 
> *1: http://patchwork.ozlabs.org/patch/212010/

Stephen,

Verified "Tegra114 series" worked with "for-3.9/soc" branch(inc CCF)
with a little tweak.

I can post Tegra114 series again. If you want them rebased onto
another branch, let me know.

^ permalink raw reply

* [PATCHv2] Add GPIO driver for Allwinner SoCs
From: Maxime Ripard @ 2013-01-23  9:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This patch adds support for the GPIOs for the Allwinner SoCs supported so
far.

It comes on top of my previous pinctrl patchset, and has been tested on a
A13-Olinuxino from Olimex.

Thanks,
Maxime

Changes from v1:
  - Merged the gpio driver with the pinctrl one
  - Now using gpiochip_add_pin_range instead of pinctrl_add_gpio_range
  - Removed the hairy range registration function, and register 1pin ranges
    instead

Maxime Ripard (1):
  ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers

 drivers/pinctrl/pinctrl-sunxi.c |  138 ++++++++++++++++++++++++++++++++++++++-
 drivers/pinctrl/pinctrl-sunxi.h |   23 ++++++-
 2 files changed, 158 insertions(+), 3 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH] ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers
From: Maxime Ripard @ 2013-01-23  9:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358933646-12681-1-git-send-email-maxime.ripard@free-electrons.com>

The IP responsible for the muxing on the Allwinner SoCs are also
handling the GPIOs on the system. This patch adds the needed driver that
relies on the pinctrl driver for most of its operations.

The number of pins available for GPIOs operations are already declared
in the pinctrl driver, we only need to probe a generic driver to handle
the banks available for each SoC.

This driver has been tested on a A13-Olinuxino.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/pinctrl/pinctrl-sunxi.c |  138 ++++++++++++++++++++++++++++++++++++++-
 drivers/pinctrl/pinctrl-sunxi.h |   23 ++++++-
 2 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index 6f02e34..bfca9e1 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -609,11 +610,57 @@ static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
+static int
+sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range,
+			unsigned offset,
+			bool input)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sunxi_desc_function *desc;
+	char *func, *pin_name;
+	u8 bank, pin;
+	int ret;
+
+	bank = (offset) / PINS_PER_BANK;
+	pin = (offset) % PINS_PER_BANK;
+
+	pin_name = kzalloc(5, GFP_KERNEL);
+	if (!pin_name)
+		return -ENOMEM;
+
+	ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
+	if (!ret)
+		goto error;
+
+	if (input)
+		func = "gpio_in";
+	else
+		func = "gpio_out";
+
+	desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
+							pin_name,
+							func);
+	if (!desc) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	sunxi_pmx_set(pctldev, offset, desc->muxval);
+
+	ret = 0;
+
+error:
+	kfree(pin_name);
+	return ret;
+}
+
 static struct pinmux_ops sunxi_pmx_ops = {
 	.get_functions_count	= sunxi_pmx_get_funcs_cnt,
 	.get_function_name	= sunxi_pmx_get_func_name,
 	.get_function_groups	= sunxi_pmx_get_func_groups,
 	.enable			= sunxi_pmx_enable,
+	.gpio_set_direction	= sunxi_pmx_gpio_set_direction,
 };
 
 static struct pinctrl_desc sunxi_pctrl_desc = {
@@ -622,6 +669,60 @@ static struct pinctrl_desc sunxi_pctrl_desc = {
 	.pmxops		= &sunxi_pmx_ops,
 };
 
+static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+
+	u32 reg = sunxi_data_reg(offset);
+	u8 index = sunxi_data_offset(offset);
+	u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
+
+	return val;
+}
+
+static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+	u32 reg = sunxi_data_reg(offset);
+	u8 index = sunxi_data_offset(offset);
+
+	writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
+}
+
+static struct gpio_chip sunxi_pinctrl_gpio_chip __devinitconst = {
+	.owner			= THIS_MODULE,
+	.request		= sunxi_pinctrl_gpio_request,
+	.free			= sunxi_pinctrl_gpio_free,
+	.direction_input	= sunxi_pinctrl_gpio_direction_input,
+	.direction_output	= sunxi_pinctrl_gpio_direction_output,
+	.get			= sunxi_pinctrl_gpio_get,
+	.set			= sunxi_pinctrl_gpio_set,
+	.can_sleep		= 0,
+};
+
 static struct of_device_id sunxi_pinctrl_match[] = {
 	{ .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
 	{}
@@ -737,7 +838,7 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
 	const struct of_device_id *device;
 	struct pinctrl_pin_desc *pins;
 	struct sunxi_pinctrl *pctl;
-	int i, ret;
+	int i, ret, last_pin;
 
 	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 	if (!pctl)
@@ -781,9 +882,42 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	dev_info(&pdev->dev, "initialized sunXi pin control driver\n");
+	pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
+	if (!pctl->chip) {
+		ret = -ENOMEM;
+		goto pinctrl_error;
+	}
+
+	last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+	pctl->chip = &sunxi_pinctrl_gpio_chip;
+	pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
+	pctl->chip->label = dev_name(&pdev->dev);
+	pctl->chip->dev = &pdev->dev;
+	pctl->chip->base = 0;
+
+	ret = gpiochip_add(pctl->chip);
+	if (ret)
+		goto pinctrl_error;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+
+		ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
+					     pin->pin.number,
+					     pin->pin.number, 1);
+		if (ret)
+			goto gpiochip_error;
+	}
+
+	dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 
 	return 0;
+
+gpiochip_error:
+	ret = gpiochip_remove(pctl->chip);
+pinctrl_error:
+	pinctrl_unregister(pctl->pctl_dev);
+	return ret;
 }
 
 static struct platform_driver sunxi_pinctrl_driver = {
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
index 0dc3b9d..0416c36 100644
--- a/drivers/pinctrl/pinctrl-sunxi.h
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -256,6 +256,7 @@
 
 #define BANK_MEM_SIZE		0x24
 #define MUX_REGS_OFFSET		0x0
+#define DATA_REGS_OFFSET	0x10
 #define DLEVEL_REGS_OFFSET	0x14
 #define PULL_REGS_OFFSET	0x1c
 
@@ -263,6 +264,9 @@
 #define MUX_PINS_PER_REG	8
 #define MUX_PINS_BITS		4
 #define MUX_PINS_MASK		0x0f
+#define DATA_PINS_PER_REG	32
+#define DATA_PINS_BITS		1
+#define DATA_PINS_MASK		0x01
 #define DLEVEL_PINS_PER_REG	16
 #define DLEVEL_PINS_BITS	2
 #define DLEVEL_PINS_MASK	0x03
@@ -283,6 +287,8 @@ struct sunxi_desc_pin {
 struct sunxi_pinctrl_desc {
 	const struct sunxi_desc_pin	*pins;
 	int				npins;
+	struct pinctrl_gpio_range	*ranges;
+	int				nranges;
 };
 
 struct sunxi_pinctrl_function {
@@ -299,6 +305,7 @@ struct sunxi_pinctrl_group {
 
 struct sunxi_pinctrl {
 	void __iomem			*membase;
+	struct gpio_chip		*chip;
 	struct sunxi_pinctrl_desc	*desc;
 	struct device			*dev;
 	struct sunxi_pinctrl_function	*functions;
@@ -321,7 +328,6 @@ struct sunxi_pinctrl {
 		.muxval = _val,					\
 	}
 
-
 /*
  * The sunXi PIO registers are organized as is:
  * 0x00 - 0x0c	Muxing values.
@@ -354,6 +360,21 @@ static inline u32 sunxi_mux_offset(u16 pin)
 	return pin_num * MUX_PINS_BITS;
 }
 
+static inline u32 sunxi_data_reg(u16 pin)
+{
+	u8 bank = pin / PINS_PER_BANK;
+	u32 offset = bank * BANK_MEM_SIZE;
+	offset += DATA_REGS_OFFSET;
+	offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
+	return round_down(offset, 4);
+}
+
+static inline u32 sunxi_data_offset(u16 pin)
+{
+	u32 pin_num = pin % DATA_PINS_PER_REG;
+	return pin_num * DATA_PINS_BITS;
+}
+
 static inline u32 sunxi_dlevel_reg(u16 pin)
 {
 	u8 bank = pin / PINS_PER_BANK;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/3] ARM: ux500: Add Snowball pin configuration for user LED
From: Linus Walleij @ 2013-01-23  9:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1357725965-27342-3-git-send-email-lee.jones@linaro.org>

On Wed, Jan 9, 2013 at 11:06 AM, Lee Jones <lee.jones@linaro.org> wrote:

> Here we setup the GPIO pin responsible for illuminating the user
> LED on the Snowball low-cost development board.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>

Patch applied to my ux500 tree, branch ux500-pinctrl.

Yours,
Linus Walleij

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox