* [PATCH v3 00/12] enhance DT support on gpio pxa
@ 2013-02-18 5:12 Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
` (11 more replies)
0 siblings, 12 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 UTC (permalink / raw)
To: linux-arm-kernel
Changelog:
v3:
* Fix the gpio irq issue on legacy platform.
* Discard irq_base & use irq domain instead in pxa_gpio_chip structure.
* Update DTS file since it's depend on latest pinctrl single driver.
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] 32+ messages in thread
* [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 18:37 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 02/12] gpio: pxa: avoid to use global irq base Haojian Zhuang
` (10 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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 22a9058..d8df90b 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>
#include <linux/spi/spi.h>
@@ -75,6 +76,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",
@@ -284,6 +289,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] 32+ messages in thread
* [PATCH v3 02/12] gpio: pxa: avoid to use global irq base
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 18:50 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
` (9 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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 3203a9f..4a63b4e 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -365,7 +365,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 93aaadf..7f5e89b 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] 32+ messages in thread
* [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 02/12] gpio: pxa: avoid to use global irq base Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 18:56 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 04/12] gpio: pxa: remove gpio_type Haojian Zhuang
` (8 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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] 32+ messages in thread
* [PATCH v3 04/12] gpio: pxa: remove gpio_type
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (2 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 18:58 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data Haojian Zhuang
` (7 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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 4a63b4e..c2c3120 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,
.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] 32+ messages in thread
* [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (3 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 04/12] gpio: pxa: remove gpio_type Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:01 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 06/12] gpio: pxa: clean code for compatible name Haojian Zhuang
` (6 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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 d8df90b..387e3f8 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -77,6 +77,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 c2c3120..e478ec8 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -432,6 +432,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] 32+ messages in thread
* [PATCH v3 06/12] gpio: pxa: clean code for compatible name
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (4 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:03 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 07/12] gpio: pxa: remove arch related macro Haojian Zhuang
` (5 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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] 32+ messages in thread
* [PATCH v3 07/12] gpio: pxa: remove arch related macro
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (5 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 06/12] gpio: pxa: clean code for compatible name Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:05 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 08/12] gpio: pxa: move gpio properties into child node Haojian Zhuang
` (4 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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] 32+ messages in thread
* [PATCH v3 08/12] gpio: pxa: move gpio properties into child node
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (6 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 07/12] gpio: pxa: remove arch related macro Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:09 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request Haojian Zhuang
` (3 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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] 32+ messages in thread
* [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (7 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 08/12] gpio: pxa: move gpio properties into child node Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:10 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 10/12] gpio: pxa: add irq base in platform data Haojian Zhuang
` (2 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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] 32+ messages in thread
* [PATCH v3 10/12] gpio: pxa: add irq base in platform data
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (8 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:12 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 12/12] ARM: dts: support pinmux in pxa910 Haojian Zhuang
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 UTC (permalink / raw)
To: linux-arm-kernel
Macro PXA_GPIO_TO_IRQ() & MMP_GPIO_TO_IRQ() is used in machine driver
without DT. Although we're allocating irq descriptions dynamically,
it may break machine drivers without DT. Append pdata->irq_base.
If irq_base is valid, allocate irq descriptions from irq_base.
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 | 2 ++
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 | 1 +
arch/arm/mach-pxa/pxa27x.c | 1 +
arch/arm/mach-pxa/pxa3xx.c | 1 +
drivers/gpio/gpio-pxa.c | 15 ++++++++++-----
include/linux/gpio-pxa.h | 1 +
13 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index a3e42dc..a160efc 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -113,6 +113,7 @@ static unsigned long common_pin_config[] __initdata = {
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 1ea6502..5c8c93d 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -35,6 +35,7 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index a32156f..ba9f3a1 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -107,6 +107,7 @@ static unsigned long brownstone_pin_config[] __initdata = {
static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
.nr_gpios = 192,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 3f301b5..544c03a 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -80,6 +80,7 @@ static unsigned long flint_pin_config[] __initdata = {
static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
.nr_gpios = 192,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 019b178..e19eae8 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -130,6 +131,7 @@ static unsigned long gplugd_pin_config[] __initdata = {
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 6e8cf80..37a181a 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -63,6 +63,7 @@ static unsigned long tavorevb_pin_config[] __initdata = {
static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index b5146bb..cace3b5 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -52,6 +52,7 @@ static unsigned long teton_bga_pin_config[] __initdata = {
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 387e3f8..a824285 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -78,6 +78,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
.nr_gpios = 128,
+ .irq_base = IRQ_GPIO_START,
.ed_mask = true,
};
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index ff91660..2646654 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -346,6 +346,7 @@ static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
#else
.nr_gpios = 85,
#endif
+ .irq_base = PXA_GPIO_IRQ_BASE,
.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 e478ec8..9f44c4b 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -433,6 +433,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,
+ .irq_base = PXA_GPIO_IRQ_BASE,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index f6bff16..7506879 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -438,6 +438,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
.nr_gpios = 128,
+ .irq_base = PXA_GPIO_IRQ_BASE,
};
static struct platform_device *devices[] __initdata = {
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index c9cc636..35cdb23 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -451,9 +451,10 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
#endif
static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
- int (*set_wake)(unsigned int, unsigned int))
+ struct pxa_gpio_platform_data *pdata)
{
int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+ int irq_base;
struct pxa_gpio_chip *chips;
struct device_node *next = NULL, *np = NULL;
@@ -473,12 +474,17 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
sprintf(chips[i].label, "gpio-%d", i);
chips[i].regbase = gpio_reg_base + BANK_OFF(i);
- chips[i].set_wake = set_wake;
+ if (pdata->gpio_set_wake)
+ chips[i].set_wake = pdata->gpio_set_wake;
/* number of GPIOs on last bank may be less than 32 */
gc->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
- chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
+ if (pdata->irq_base)
+ irq_base = pdata->irq_base + gpio;
+ else
+ irq_base = -1;
+ chips[i].irq_base = irq_alloc_descs(irq_base, 0, gc->ngpio, 0);
if (chips[i].irq_base < 0)
return -EINVAL;
if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
@@ -557,8 +563,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
/* Initialize GPIO chips */
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);
+ ret = pxa_init_gpio_chip(pdev, pxa_last_gpio, pdata);
if (ret < 0)
return ret;
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index b357fdc..0d5e6db 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -20,6 +20,7 @@ struct pxa_gpio_platform_data {
bool inverted; /* only valid for PXA26x */
bool gafr; /* only valid for PXA25x/PXA26x/PXA27x */
unsigned nr_gpios;
+ int irq_base;
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (9 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 10/12] gpio: pxa: add irq base in platform data Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-18 10:10 ` Igor Grinberg
2013-02-21 19:15 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 12/12] ARM: dts: support pinmux in pxa910 Haojian Zhuang
11 siblings, 2 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 UTC (permalink / raw)
To: linux-arm-kernel
Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 91 +++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 47 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 35cdb23..d45cb57 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -66,8 +66,8 @@ int pxa_last_gpio;
struct pxa_gpio_chip {
struct gpio_chip chip;
+ struct irq_domain *domain;
void __iomem *regbase;
- unsigned int irq_base;
bool inverted;
bool gafr;
char label[10];
@@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
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(struct irq_data *d)
-{
- 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;
+ return irq_create_mapping(chip->domain, offset);
}
static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
@@ -270,18 +260,19 @@ static inline void update_edge_detect(struct pxa_gpio_chip *chip)
static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
{
- struct pxa_gpio_chip *chip;
- int gpio = pxa_irq_to_gpio(d);
- unsigned long gpdr, mask = GPIO_bit(gpio);
+ struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int offset = irqd_to_hwirq(d);
+ int gpio;
+ unsigned long gpdr, mask;
- chip = gpio_to_pxachip(gpio);
+ mask = 1 << offset;
+ gpio = chip->chip.base + offset;
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 ((chip->irq_edge_rise | chip->irq_edge_fall)
- & GPIO_bit(gpio))
+ if ((chip->irq_edge_rise | chip->irq_edge_fall) & mask)
return 0;
if (__gpio_is_occupied(chip, gpio))
@@ -318,16 +309,15 @@ 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 *chip;
- int loop, gpio, gpio_base, n;
- unsigned long gedr;
struct irq_chip *ic = irq_desc_get_chip(desc);
+ int n, gpio, loop;
+ unsigned long gedr;
chained_irq_enter(ic, desc);
do {
loop = 0;
for_each_gpio_chip(gpio, chip) {
- gpio_base = chip->chip.base;
gedr = readl_relaxed(chip->regbase + GEDR_OFFSET);
gedr = gedr & chip->irq_mask;
@@ -335,8 +325,8 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
for_each_set_bit(n, &gedr, BITS_PER_LONG) {
loop = 1;
-
- generic_handle_irq(gpio_to_irq(gpio_base + n));
+ generic_handle_irq(pxa_gpio_to_irq(&chip->chip,
+ n));
}
}
} while (loop);
@@ -346,31 +336,35 @@ 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);
- struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int offset = irqd_to_hwirq(d);
- writel_relaxed(GPIO_bit(gpio), chip->regbase + GEDR_OFFSET);
+ writel_relaxed(1 << offset, 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 *chip = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int offset = irqd_to_hwirq(d);
+ int mask;
uint32_t grer, gfer;
- chip->irq_mask &= ~GPIO_bit(gpio);
+ mask = 1 << offset;
+ chip->irq_mask &= ~mask;
- grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
- gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+ grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~mask;
+ gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~mask;
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 *chip = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int offset = irqd_to_hwirq(d);
+ int gpio;
+ gpio = chip->chip.base + offset;
if (chip->set_wake)
return chip->set_wake(gpio, on);
else
@@ -379,10 +373,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 *chip = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int offset = irqd_to_hwirq(d);
- chip->irq_mask |= GPIO_bit(gpio);
+ chip->irq_mask |= 1 << offset;
update_edge_detect(chip);
}
@@ -395,12 +389,16 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.irq_set_wake = pxa_gpio_set_wake,
};
-static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
+static int pxa_irq_domain_map(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hw)
{
- irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ struct pxa_gpio_chip *chip = d->host_data;
+
+ irq_set_chip_and_handler_name(virq, &pxa_muxed_gpio_chip,
+ handle_edge_irq, "gpio");
+ irq_set_chip_data(virq, chip);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
+ set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
return 0;
}
@@ -483,13 +481,12 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
if (pdata->irq_base)
irq_base = pdata->irq_base + gpio;
else
- irq_base = -1;
- chips[i].irq_base = irq_alloc_descs(irq_base, 0, gc->ngpio, 0);
- if (chips[i].irq_base < 0)
- return -EINVAL;
- if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
- chips[i].irq_base, 0,
- &pxa_irq_domain_ops, &chips[i]))
+ irq_base = 0;
+ chips[i].domain = irq_domain_add_simple(pdev->dev.of_node,
+ gc->ngpio, irq_base,
+ &pxa_irq_domain_ops,
+ &chips[i]);
+ if (!chips[i].domain)
return -ENODEV;
gc->base = gpio;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v3 12/12] ARM: dts: support pinmux in pxa910
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
` (10 preceding siblings ...)
2013-02-18 5:12 ` [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip Haojian Zhuang
@ 2013-02-18 5:12 ` Haojian Zhuang
2013-02-21 19:16 ` Linus Walleij
11 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 5:12 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 | 248 ++++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/pxa910.dtsi | 29 ++++-
2 files changed, 275 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..04db0b6 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -170,6 +170,254 @@
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 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-pullup = <0xc000 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0xa000 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ nfc_pmx_func: pinmux_nfc_pins at 0 {
+ pinctrl-single,pins = <
+ 0x120 0x0 /* GPIO17 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0x0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ 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-pullup = <0 0xc000 0 0xc000>;
+ pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>;
+ pinctrl-single,input-schmitt = <0 0x30>;
+ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>;
+ };
+ };
};
};
};
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] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 5:12 ` [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip Haojian Zhuang
@ 2013-02-18 10:10 ` Igor Grinberg
2013-02-18 12:10 ` Haojian Zhuang
2013-02-21 19:15 ` Linus Walleij
1 sibling, 1 reply; 32+ messages in thread
From: Igor Grinberg @ 2013-02-18 10:10 UTC (permalink / raw)
To: linux-arm-kernel
On 02/18/13 07:12, Haojian Zhuang wrote:
> Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
> drivers/gpio/gpio-pxa.c | 91 +++++++++++++++++++++++------------------------
> 1 file changed, 44 insertions(+), 47 deletions(-)
[...]
>
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index 35cdb23..d45cb57 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -66,8 +66,8 @@ int pxa_last_gpio;
>
> struct pxa_gpio_chip {
> struct gpio_chip chip;
> + struct irq_domain *domain;
> void __iomem *regbase;
> - unsigned int irq_base;
> bool inverted;
> bool gafr;
> char label[10];
> @@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> 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(struct irq_data *d)
> -{
> - 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;
> + return irq_create_mapping(chip->domain, offset);
> }
You remove the pxa_irq_to_gpio() function here, but we still have:
$ grep -nr pxa_irq_to_gpio *
arch/arm/mach-pxa/pxa27x.c:368: int gpio = pxa_irq_to_gpio(d);
arch/arm/mach-pxa/pxa25x.c:292: int gpio = pxa_irq_to_gpio(d);
include/linux/gpio-pxa.h:16:extern int pxa_irq_to_gpio(struct irq_data *d);
And this in turn breaks the compilation for example with error:
arch/arm/mach-pxa/built-in.o: In function `pxa27x_set_wake':
em-x270.c:(.text+0x1298): undefined reference to `pxa_irq_to_gpio'
make[1]: *** [vmlinux] Error 1
make: *** [sub-make] Error 2
--
Regards,
Igor.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 10:10 ` Igor Grinberg
@ 2013-02-18 12:10 ` Haojian Zhuang
2013-02-18 13:39 ` Igor Grinberg
0 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 12:10 UTC (permalink / raw)
To: linux-arm-kernel
On 18 February 2013 18:10, Igor Grinberg <grinberg@compulab.co.il> wrote:
> On 02/18/13 07:12, Haojian Zhuang wrote:
>> Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>> drivers/gpio/gpio-pxa.c | 91 +++++++++++++++++++++++------------------------
>> 1 file changed, 44 insertions(+), 47 deletions(-)
>
> [...]
>
>>
>> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
>> index 35cdb23..d45cb57 100644
>> --- a/drivers/gpio/gpio-pxa.c
>> +++ b/drivers/gpio/gpio-pxa.c
>> @@ -66,8 +66,8 @@ int pxa_last_gpio;
>>
>> struct pxa_gpio_chip {
>> struct gpio_chip chip;
>> + struct irq_domain *domain;
>> void __iomem *regbase;
>> - unsigned int irq_base;
>> bool inverted;
>> bool gafr;
>> char label[10];
>> @@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>> 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(struct irq_data *d)
>> -{
>> - 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;
>> + return irq_create_mapping(chip->domain, offset);
>> }
>
> You remove the pxa_irq_to_gpio() function here, but we still have:
> $ grep -nr pxa_irq_to_gpio *
> arch/arm/mach-pxa/pxa27x.c:368: int gpio = pxa_irq_to_gpio(d);
> arch/arm/mach-pxa/pxa25x.c:292: int gpio = pxa_irq_to_gpio(d);
> include/linux/gpio-pxa.h:16:extern int pxa_irq_to_gpio(struct irq_data *d);
>
> And this in turn breaks the compilation for example with error:
> arch/arm/mach-pxa/built-in.o: In function `pxa27x_set_wake':
> em-x270.c:(.text+0x1298): undefined reference to `pxa_irq_to_gpio'
> make[1]: *** [vmlinux] Error 1
> make: *** [sub-make] Error 2
>
>
> --
> Regards,
> Igor.
Thank you.
Please drop this patch (11/12) for your test. Whatever it's DT or non-DT mode,
gpio driver should work without this patch.
Regards
Haojian
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 12:10 ` Haojian Zhuang
@ 2013-02-18 13:39 ` Igor Grinberg
2013-02-18 14:49 ` Haojian Zhuang
0 siblings, 1 reply; 32+ messages in thread
From: Igor Grinberg @ 2013-02-18 13:39 UTC (permalink / raw)
To: linux-arm-kernel
On 02/18/13 14:10, Haojian Zhuang wrote:
> On 18 February 2013 18:10, Igor Grinberg <grinberg@compulab.co.il> wrote:
>> On 02/18/13 07:12, Haojian Zhuang wrote:
>>> Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
>>>
>>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>>> ---
>>> drivers/gpio/gpio-pxa.c | 91 +++++++++++++++++++++++------------------------
>>> 1 file changed, 44 insertions(+), 47 deletions(-)
>>
>> [...]
>>
>>>
>>> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
>>> index 35cdb23..d45cb57 100644
>>> --- a/drivers/gpio/gpio-pxa.c
>>> +++ b/drivers/gpio/gpio-pxa.c
>>> @@ -66,8 +66,8 @@ int pxa_last_gpio;
>>>
>>> struct pxa_gpio_chip {
>>> struct gpio_chip chip;
>>> + struct irq_domain *domain;
>>> void __iomem *regbase;
>>> - unsigned int irq_base;
>>> bool inverted;
>>> bool gafr;
>>> char label[10];
>>> @@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>>> 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(struct irq_data *d)
>>> -{
>>> - 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;
>>> + return irq_create_mapping(chip->domain, offset);
>>> }
>>
>> You remove the pxa_irq_to_gpio() function here, but we still have:
>> $ grep -nr pxa_irq_to_gpio *
>> arch/arm/mach-pxa/pxa27x.c:368: int gpio = pxa_irq_to_gpio(d);
>> arch/arm/mach-pxa/pxa25x.c:292: int gpio = pxa_irq_to_gpio(d);
>> include/linux/gpio-pxa.h:16:extern int pxa_irq_to_gpio(struct irq_data *d);
>>
>> And this in turn breaks the compilation for example with error:
>> arch/arm/mach-pxa/built-in.o: In function `pxa27x_set_wake':
>> em-x270.c:(.text+0x1298): undefined reference to `pxa_irq_to_gpio'
>> make[1]: *** [vmlinux] Error 1
>> make: *** [sub-make] Error 2
>>
>>
>> --
>> Regards,
>> Igor.
>
> Thank you.
>
> Please drop this patch (11/12) for your test. Whatever it's DT or non-DT mode,
> gpio driver should work without this patch.
Nope... The IRQ is still broken even if I drop this patch.
--
Regards,
Igor.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 13:39 ` Igor Grinberg
@ 2013-02-18 14:49 ` Haojian Zhuang
0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-18 14:49 UTC (permalink / raw)
To: linux-arm-kernel
On 18 February 2013 21:39, Igor Grinberg <grinberg@compulab.co.il> wrote:
>
>
> On 02/18/13 14:10, Haojian Zhuang wrote:
>> On 18 February 2013 18:10, Igor Grinberg <grinberg@compulab.co.il> wrote:
>>> On 02/18/13 07:12, Haojian Zhuang wrote:
>>>> Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
>>>>
>>>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>>>> ---
>>>> drivers/gpio/gpio-pxa.c | 91 +++++++++++++++++++++++------------------------
>>>> 1 file changed, 44 insertions(+), 47 deletions(-)
>>>
>>> [...]
>>>
>>>>
>>>> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
>>>> index 35cdb23..d45cb57 100644
>>>> --- a/drivers/gpio/gpio-pxa.c
>>>> +++ b/drivers/gpio/gpio-pxa.c
>>>> @@ -66,8 +66,8 @@ int pxa_last_gpio;
>>>>
>>>> struct pxa_gpio_chip {
>>>> struct gpio_chip chip;
>>>> + struct irq_domain *domain;
>>>> void __iomem *regbase;
>>>> - unsigned int irq_base;
>>>> bool inverted;
>>>> bool gafr;
>>>> char label[10];
>>>> @@ -147,17 +147,7 @@ static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
>>>> 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(struct irq_data *d)
>>>> -{
>>>> - 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;
>>>> + return irq_create_mapping(chip->domain, offset);
>>>> }
>>>
>>> You remove the pxa_irq_to_gpio() function here, but we still have:
>>> $ grep -nr pxa_irq_to_gpio *
>>> arch/arm/mach-pxa/pxa27x.c:368: int gpio = pxa_irq_to_gpio(d);
>>> arch/arm/mach-pxa/pxa25x.c:292: int gpio = pxa_irq_to_gpio(d);
>>> include/linux/gpio-pxa.h:16:extern int pxa_irq_to_gpio(struct irq_data *d);
>>>
>>> And this in turn breaks the compilation for example with error:
>>> arch/arm/mach-pxa/built-in.o: In function `pxa27x_set_wake':
>>> em-x270.c:(.text+0x1298): undefined reference to `pxa_irq_to_gpio'
>>> make[1]: *** [vmlinux] Error 1
>>> make: *** [sub-make] Error 2
>>>
>>>
>>> --
>>> Regards,
>>> Igor.
>>
>> Thank you.
>>
>> Please drop this patch (11/12) for your test. Whatever it's DT or non-DT mode,
>> gpio driver should work without this patch.
>
> Nope... The IRQ is still broken even if I drop this patch.
>
>
> --
> Regards,
> Igor.
Could you send the full log to me?
Thanks
Haojian
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data
2013-02-18 5:12 ` [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
@ 2013-02-21 18:37 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 18:37 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> 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>
(...)
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + if (!pdata)
> + return -ENOMEM;
> + if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
Should you not use of_property_read_bool()?
Should you not also update some DT binding document for this?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 02/12] gpio: pxa: avoid to use global irq base
2013-02-18 5:12 ` [PATCH v3 02/12] gpio: pxa: avoid to use global irq base Haojian Zhuang
@ 2013-02-21 18:50 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 18:50 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> 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>
(...)
> +++ b/drivers/gpio/gpio-pxa.c
(...)
> -static int irq_base;
Nice!
> #ifdef CONFIG_OF
> -static struct irq_domain *domain;
Nice!
> static struct device_node *pxa_gpio_of_node;
> #endif
>
> struct pxa_gpio_chip {
> struct gpio_chip chip;
> void __iomem *regbase;
> + unsigned int irq_base;
I don't get this.
Just put a struct irq_domain *irqdomain here
instead and let that keep track of the irq_base for you.
> -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;
No. Use return irq_create_mapping(chip->irqdomain, 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;
Just d->hwirq + chip->chip.base;
> +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]))
Don't throw irqdomains away! They are for using.
That is why I ask you to store it in the pxa state struct.
Since you obviously do not care which IRQ descriptors you get
from this, just use irq_domain_add_linear(). The descriptors will
then be allocated dynamically when you call irq_create_mapping().
This is not the first time I see irqdomains being created and then
just thrown away, please don't do this.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted
2013-02-18 5:12 ` [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
@ 2013-02-21 18:56 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 18:56 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> 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>
(...)
> -static inline int __gpio_is_inverted(int gpio)
> +static inline int __gpio_is_inverted(struct pxa_gpio_chip *chip, int gpio)
Take this opportunity to rename the function pxa_gpio_is_inverted().
__notation should be used for other things IMO.
Also, this function should return a bool.
> {
> - if ((gpio_type == PXA26X_GPIO) && (gpio > 85))
> + if ((chip->inverted) && (gpio > 85))
Add a comment explaining why only GPIOs > 85 may be
inverted.
> return 1;
> return 0;
return true or false.
> -static inline int __gpio_is_occupied(unsigned gpio)
> +static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
pxa_gpio_is_occupied()
> - if (__gpio_is_inverted(gpio))
> + if (__gpio_is_inverted(chip, gpio))
So it is obviously used as a bool so make it a bool.
> + chip = container_of(gc, struct pxa_gpio_chip, chip);
> +
Many drivers define a helper macro for this, something
like TO_PXA_GPIO(). But just a hint.
> + /* It's only valid for PXA26x */
> + if (of_find_property(np, "marvell,gpio-inverted", NULL))
> + pdata->inverted = true;
of_property_read_bool()
And add it to the binding document, right?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 04/12] gpio: pxa: remove gpio_type
2013-02-18 5:12 ` [PATCH v3 04/12] gpio: pxa: remove gpio_type Haojian Zhuang
@ 2013-02-21 18:58 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 18:58 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> 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>
Looks clean an nice,
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data
2013-02-18 5:12 ` [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data Haojian Zhuang
@ 2013-02-21 19:01 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:01 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Avoid to define gpio numbers in gpio driver. Define it in platform data
> instead.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Very nice patch overall!
> - 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;
We need to get rid of cpu_is_* and pass this from the machine
instead, but this is OK as a stepping stone.
> -#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;
> -}
This alone warrants ACKing the patch :-)
> + 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;
> + }
Add this to the binding document?
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 06/12] gpio: pxa: clean code for compatible name
2013-02-18 5:12 ` [PATCH v3 06/12] gpio: pxa: clean code for compatible name Haojian Zhuang
@ 2013-02-21 19:03 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:03 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Use compatible variable name in gpio pxa driver.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
OK if you prefer this by all means...
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 07/12] gpio: pxa: remove arch related macro
2013-02-18 5:12 ` [PATCH v3 07/12] gpio: pxa: remove arch related macro Haojian Zhuang
@ 2013-02-21 19:05 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:05 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Remove macro CONFIG_ARCH_PXA.
Do you mean, remove usage of compiler flag CONFIG_ARCH_PXA?
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 08/12] gpio: pxa: move gpio properties into child node
2013-02-18 5:12 ` [PATCH v3 08/12] gpio: pxa: move gpio properties into child node Haojian Zhuang
@ 2013-02-21 19:09 ` Linus Walleij
2013-02-22 1:32 ` Haojian Zhuang
0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:09 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> 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>
(...)
> + np = pdev->dev.of_node;
> +#ifdef CONFIG_OF
> + if (np)
> + next = of_get_next_child(np, NULL);
> +#endif
(...)
> +#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
(...)
> + of_node_put(next);
So if you're #ifdef:in all the other of_* stuff, why are you not
#ifdef:in this?
Is the #ifdef really necessary by the way, or will there be stubs
handling it?
Have you considered using IS_ENABLED() from <linux/kconfig.h>?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request
2013-02-18 5:12 ` [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request Haojian Zhuang
@ 2013-02-21 19:10 ` Linus Walleij
0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:10 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> While gpio pins is requested, request the pin of pinctrl driver first.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Looks correct!
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 10/12] gpio: pxa: add irq base in platform data
2013-02-18 5:12 ` [PATCH v3 10/12] gpio: pxa: add irq base in platform data Haojian Zhuang
@ 2013-02-21 19:12 ` Linus Walleij
2013-02-22 1:34 ` Haojian Zhuang
0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:12 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Macro PXA_GPIO_TO_IRQ() & MMP_GPIO_TO_IRQ() is used in machine driver
> without DT. Although we're allocating irq descriptions dynamically,
> it may break machine drivers without DT. Append pdata->irq_base.
> If irq_base is valid, allocate irq descriptions from irq_base.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
(...)
> - chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
> + if (pdata->irq_base)
> + irq_base = pdata->irq_base + gpio;
> + else
> + irq_base = -1;
> + chips[i].irq_base = irq_alloc_descs(irq_base, 0, gc->ngpio, 0);
> if (chips[i].irq_base < 0)
> return -EINVAL;
> if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
In this case, when you want to pass a base IRQ, use
irq_domain_add_simple().
The descriptor allocation will still be unnecessary.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip
2013-02-18 5:12 ` [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip Haojian Zhuang
2013-02-18 10:10 ` Igor Grinberg
@ 2013-02-21 19:15 ` Linus Walleij
1 sibling, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:15 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Discard irq_base in struct pxa_gpio_chip. Use irq_domain instead.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
(...)
> + irq_base = 0;
> + chips[i].domain = irq_domain_add_simple(pdev->dev.of_node,
> + gc->ngpio, irq_base,
> + &pxa_irq_domain_ops,
> + &chips[i]);
> + if (!chips[i].domain)
Aha... so not at the end you fix it up :-)
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Maybe I can ACK all the others too then, if I know it will end up like
this. But I had a few other review comments.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 12/12] ARM: dts: support pinmux in pxa910
2013-02-18 5:12 ` [PATCH v3 12/12] ARM: dts: support pinmux in pxa910 Haojian Zhuang
@ 2013-02-21 19:16 ` Linus Walleij
2013-02-22 1:35 ` Haojian Zhuang
0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2013-02-21 19:16 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Add gpio range, pinmux settings in pxa910 dkb DTS file.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Same question as earlier:
had the binding document been updated?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 08/12] gpio: pxa: move gpio properties into child node
2013-02-21 19:09 ` Linus Walleij
@ 2013-02-22 1:32 ` Haojian Zhuang
0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-22 1:32 UTC (permalink / raw)
To: linux-arm-kernel
On 22 February 2013 03:09, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> 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>
> (...)
>> + np = pdev->dev.of_node;
>> +#ifdef CONFIG_OF
>> + if (np)
>> + next = of_get_next_child(np, NULL);
>> +#endif
> (...)
>> +#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
> (...)
>> + of_node_put(next);
>
> So if you're #ifdef:in all the other of_* stuff, why are you not
> #ifdef:in this?
>
> Is the #ifdef really necessary by the way, or will there be stubs
> handling it?
>
> Have you considered using IS_ENABLED() from <linux/kconfig.h>?
>
> Yours,
> Linus Walleij
I also like IS_ENABLED() macro. But the problem is that
of_get_next_child() isn't defined if CONFIG_OF isn't selected. So
I don't have the choice to use IS_ENABLED().
Regards
Haojian
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 10/12] gpio: pxa: add irq base in platform data
2013-02-21 19:12 ` Linus Walleij
@ 2013-02-22 1:34 ` Haojian Zhuang
0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-22 1:34 UTC (permalink / raw)
To: linux-arm-kernel
On 22 February 2013 03:12, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> Macro PXA_GPIO_TO_IRQ() & MMP_GPIO_TO_IRQ() is used in machine driver
>> without DT. Although we're allocating irq descriptions dynamically,
>> it may break machine drivers without DT. Append pdata->irq_base.
>> If irq_base is valid, allocate irq descriptions from irq_base.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> (...)
>> - chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
>> + if (pdata->irq_base)
>> + irq_base = pdata->irq_base + gpio;
>> + else
>> + irq_base = -1;
>> + chips[i].irq_base = irq_alloc_descs(irq_base, 0, gc->ngpio, 0);
>> if (chips[i].irq_base < 0)
>> return -EINVAL;
>> if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
>
> In this case, when you want to pass a base IRQ, use
> irq_domain_add_simple().
>
> The descriptor allocation will still be unnecessary.
>
> Yours,
> Linus Walleij
Yes, thank you. Let me clean the irq usage after this patch series.
Regards
Haojian
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v3 12/12] ARM: dts: support pinmux in pxa910
2013-02-21 19:16 ` Linus Walleij
@ 2013-02-22 1:35 ` Haojian Zhuang
0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-02-22 1:35 UTC (permalink / raw)
To: linux-arm-kernel
On 22 February 2013 03:16, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Feb 18, 2013 at 6:12 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> Add gpio range, pinmux settings in pxa910 dkb DTS file.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> Same question as earlier:
> had the binding document been updated?
>
> Yours,
> Linus Walleij
It's mentioned in v4 series.
Regards
Haojian
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2013-02-22 1:35 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-18 5:12 [PATCH v3 00/12] enhance DT support on gpio pxa Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 01/12] gpio: pxa: identify ed mask reg with platform data Haojian Zhuang
2013-02-21 18:37 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 02/12] gpio: pxa: avoid to use global irq base Haojian Zhuang
2013-02-21 18:50 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 03/12] gpio: pxa: use platform data for gpio inverted Haojian Zhuang
2013-02-21 18:56 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 04/12] gpio: pxa: remove gpio_type Haojian Zhuang
2013-02-21 18:58 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 05/12] gpio: pxa: define nr gpios in platform data Haojian Zhuang
2013-02-21 19:01 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 06/12] gpio: pxa: clean code for compatible name Haojian Zhuang
2013-02-21 19:03 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 07/12] gpio: pxa: remove arch related macro Haojian Zhuang
2013-02-21 19:05 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 08/12] gpio: pxa: move gpio properties into child node Haojian Zhuang
2013-02-21 19:09 ` Linus Walleij
2013-02-22 1:32 ` Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 09/12] gpio: pxa: bind to pinctrl by request Haojian Zhuang
2013-02-21 19:10 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 10/12] gpio: pxa: add irq base in platform data Haojian Zhuang
2013-02-21 19:12 ` Linus Walleij
2013-02-22 1:34 ` Haojian Zhuang
2013-02-18 5:12 ` [PATCH v3 11/12] gpio: pxa: discard irq base in pxa_gpio_chip Haojian Zhuang
2013-02-18 10:10 ` Igor Grinberg
2013-02-18 12:10 ` Haojian Zhuang
2013-02-18 13:39 ` Igor Grinberg
2013-02-18 14:49 ` Haojian Zhuang
2013-02-21 19:15 ` Linus Walleij
2013-02-18 5:12 ` [PATCH v3 12/12] ARM: dts: support pinmux in pxa910 Haojian Zhuang
2013-02-21 19:16 ` Linus Walleij
2013-02-22 1:35 ` Haojian Zhuang
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.