[PATCH 07/14] at91: switch gpio to early platfrom device
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Mon Apr 25 14:31:17 EDT 2011
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
Cc: Patrice Vilchez <patrice.vilchez at atmel.com>
---
need patch
clkdev: add support to lookup for early platform device
Best Regards,
J.
arch/arm/mach-at91/at572d940hf.c | 30 ++++++------
arch/arm/mach-at91/at91cap9.c | 34 +++++++-------
arch/arm/mach-at91/at91rm9200.c | 43 +++++++++--------
arch/arm/mach-at91/at91sam9260.c | 30 ++++++------
arch/arm/mach-at91/at91sam9261.c | 30 ++++++------
arch/arm/mach-at91/at91sam9263.c | 42 ++++++++---------
arch/arm/mach-at91/at91sam9g45.c | 43 ++++++++---------
arch/arm/mach-at91/at91sam9rl.c | 37 +++++++--------
arch/arm/mach-at91/clock.h | 6 ++
arch/arm/mach-at91/devices.c | 15 ++++++
arch/arm/mach-at91/devices.h | 55 +++++++++++++++++++++
arch/arm/mach-at91/generic.h | 6 --
arch/arm/mach-at91/gpio.c | 78 +++++++++++++++++++-----------
arch/arm/mach-at91/soc.c | 97 ++++++++++++++++++++++++++++++++++++++
arch/arm/mach-at91/soc.h | 4 ++
15 files changed, 365 insertions(+), 185 deletions(-)
create mode 100644 arch/arm/mach-at91/devices.c
create mode 100644 arch/arm/mach-at91/devices.h
diff --git a/arch/arm/mach-at91/at572d940hf.c b/arch/arm/mach-at91/at572d940hf.c
index b9c48d5..b788861 100644
--- a/arch/arm/mach-at91/at572d940hf.c
+++ b/arch/arm/mach-at91/at572d940hf.c
@@ -202,9 +202,9 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
CLKDEV_CON_ID("macb_clk", &macb_clk),
CLKDEV_CON_ID("mci_clk", &mmc_clk),
CLKDEV_CON_ID("udc_clk", &udc_clk),
@@ -336,19 +336,16 @@ struct clk* __init at572d940hf_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at572d940hf_gpio[] = {
+static struct at91_dev_resource at572d940hf_pios[] __initdata = {
{
- .id = AT572D940HF_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT572D940HF_ID_PIOA,
}, {
- .id = AT572D940HF_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT572D940HF_ID_PIOB,
}, {
- .id = AT572D940HF_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT572D940HF_ID_PIOC,
}
};
@@ -376,9 +373,6 @@ static void __init at572d940hf_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at572d940hf_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at572d940hf_gpio, 3);
}
/* --------------------------------------------------------------------
@@ -427,4 +421,8 @@ struct at91_soc __initdata at572d940hf_soc = {
.name = "at572d940hf",
.default_irq_priority = at572d940hf_default_irq_priority,
.init = at572d940hf_initialize,
+ .gpio = {
+ .resource = at572d940hf_pios,
+ .num_resources = ARRAY_SIZE(at572d940hf_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index 1ba614a1..f60ec74 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -219,7 +219,10 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioABCD_clk", &pioABCD_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioABCD_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioABCD_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioABCD_clk),
+ CLKDEV_DEV_ID("at91_gpio.3", &pioABCD_clk),
CLKDEV_CON_ID("mpb0_clk", &mpb0_clk),
CLKDEV_CON_ID("mpb1_clk", &mpb1_clk),
CLKDEV_CON_ID("mpb2_clk", &mpb2_clk),
@@ -322,23 +325,19 @@ struct clk* __init at91cap9_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91cap9_gpio[] = {
+static struct at91_dev_resource at91cap9_pios[] __initdata = {
{
- .id = AT91CAP9_ID_PIOABCD,
- .offset = AT91_PIOA,
- .clock = &pioABCD_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91CAP9_ID_PIOABCD,
}, {
- .id = AT91CAP9_ID_PIOABCD,
- .offset = AT91_PIOB,
- .clock = &pioABCD_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91CAP9_ID_PIOABCD,
}, {
- .id = AT91CAP9_ID_PIOABCD,
- .offset = AT91_PIOC,
- .clock = &pioABCD_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91CAP9_ID_PIOABCD,
}, {
- .id = AT91CAP9_ID_PIOABCD,
- .offset = AT91_PIOD,
- .clock = &pioABCD_clk,
+ .mmio_base = AT91_PIOD,
+ .irq = AT91CAP9_ID_PIOABCD,
}
};
@@ -372,9 +371,6 @@ static void __init at91cap9_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91cap9_register_clocks();
- /* Register GPIO subsystem */
- at91_gpio_init(at91cap9_gpio, 4);
-
/* Remember the silicon revision */
if (cpu_is_at91cap9_revB())
system_rev = 0xB;
@@ -428,4 +424,8 @@ struct at91_soc __initdata at91cap9_soc = {
.name = "at91cap9",
.default_irq_priority = at91cap9_default_irq_priority,
.init = at91cap9_initialize,
+ .gpio = {
+ .resource = at91cap9_pios,
+ .num_resources = ARRAY_SIZE(at91cap9_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 29a2a8a..e80d544 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -189,16 +189,16 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.3", &pioD_clk),
CLKDEV_CON_ID("udc_clk", &udc_clk),
CLKDEV_CON_ID("ohci_clk", &ohci_clk),
CLKDEV_CON_ID("ether_clk", ðer_clk),
CLKDEV_CON_ID("mci_clk", &mmc_clk),
CLKDEV_CON_ID("twi_clk", &twi_clk),
CLKDEV_CON_ID("spi_clk", &spi_clk),
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
- CLKDEV_CON_ID("pioD_clk", &pioD_clk),
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
@@ -284,23 +284,19 @@ struct clk* __init at91rm9200_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91rm9200_gpio[] = {
+static struct at91_dev_resource at91rm9200_pios[] __initdata = {
{
- .id = AT91RM9200_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91RM9200_ID_PIOA,
}, {
- .id = AT91RM9200_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91RM9200_ID_PIOB,
}, {
- .id = AT91RM9200_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91RM9200_ID_PIOC,
}, {
- .id = AT91RM9200_ID_PIOD,
- .offset = AT91_PIOD,
- .clock = &pioD_clk,
+ .mmio_base = AT91_PIOD,
+ .irq = AT91RM9200_ID_PIOD,
}
};
@@ -318,6 +314,11 @@ static void at91rm9200_reset(void)
* -------------------------------------------------------------------- */
static void __init at91rm9200_initialize(unsigned long main_clock)
{
+ if (cpu_is_at91rm9200_bga())
+ at91rm9200_soc.gpio.num_resources = AT91RM9200_BGA;
+ else
+ at91rm9200_soc.gpio.num_resources = AT91RM9200_PQFP;
+
/* Map peripherals */
iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
@@ -332,10 +333,6 @@ static void __init at91rm9200_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91rm9200_register_clocks();
-
- /* Initialize GPIO subsystem */
- at91_gpio_init(at91rm9200_gpio,
- cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP);
}
@@ -385,4 +382,8 @@ struct at91_soc __initdata at91rm9200_soc = {
.name = "at91rm9200",
.default_irq_priority = at91rm9200_default_irq_priority,
.init = at91rm9200_initialize,
+ .gpio = {
+ .resource = at91rm9200_pios,
+ .num_resources = ARRAY_SIZE(at91rm9200_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 8c7de1e..4859231 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -215,9 +215,9 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
CLKDEV_CON_ID("adc_clk", &adc_clk),
CLKDEV_CON_ID("mci_clk", &mmc_clk),
CLKDEV_CON_ID("udc_clk", &udc_clk),
@@ -300,19 +300,16 @@ struct clk* __init at91sam9260_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91sam9260_gpio[] = {
+static struct at91_dev_resource at91sam9260_pios[] __initdata = {
{
- .id = AT91SAM9260_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91SAM9260_ID_PIOA,
}, {
- .id = AT91SAM9260_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91SAM9260_ID_PIOB,
}, {
- .id = AT91SAM9260_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91SAM9260_ID_PIOC,
}
};
@@ -368,9 +365,6 @@ static void __init at91sam9260_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91sam9260_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91sam9260_gpio, 3);
}
/* --------------------------------------------------------------------
@@ -419,4 +413,8 @@ struct at91_soc __initdata at91sam9260_soc = {
.name = "at91sam9260",
.default_irq_priority = at91sam9260_default_irq_priority,
.init = at91sam9260_initialize,
+ .gpio = {
+ .resource = at91sam9260_pios,
+ .num_resources = ARRAY_SIZE(at91sam9260_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index bf28740..5a3f68b 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -171,9 +171,9 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
CLKDEV_CON_ID("mci_clk", &mmc_clk),
CLKDEV_CON_ID("udc_clk", &udc_clk),
CLKDEV_CON_ID("twi_clk", &twi_clk),
@@ -288,19 +288,16 @@ struct clk* __init at91sam9261_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91sam9261_gpio[] = {
+static struct at91_dev_resource at91sam9261_pios[] __initdata = {
{
- .id = AT91SAM9261_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91SAM9261_ID_PIOA,
}, {
- .id = AT91SAM9261_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91SAM9261_ID_PIOB,
}, {
- .id = AT91SAM9261_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91SAM9261_ID_PIOC,
}
};
@@ -334,9 +331,6 @@ static void __init at91sam9261_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91sam9261_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91sam9261_gpio, 3);
}
/* --------------------------------------------------------------------
@@ -385,4 +379,8 @@ struct at91_soc __initdata at91sam9261_soc = {
.name = "at91sam9261",
.default_irq_priority = at91sam9261_default_irq_priority,
.init = at91sam9261_initialize,
+ .gpio = {
+ .resource = at91sam9261_pios,
+ .num_resources = ARRAY_SIZE(at91sam9261_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 763170b..9a0b3b4 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -196,9 +196,11 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioCDE_clk", &pioCDE_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioCDE_clk),
+ CLKDEV_DEV_ID("at91_gpio.3", &pioCDE_clk),
+ CLKDEV_DEV_ID("at91_gpio.4", &pioCDE_clk),
CLKDEV_CON_ID("can_clk", &can_clk),
CLKDEV_CON_ID("twi_clk", &twi_clk),
CLKDEV_CON_ID("ac97_clk", &ac97_clk),
@@ -295,27 +297,22 @@ struct clk* __init at91sam9263_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91sam9263_gpio[] = {
+static struct at91_dev_resource at91sam9263_pios[] __initdata = {
{
- .id = AT91SAM9263_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91SAM9263_ID_PIOA,
}, {
- .id = AT91SAM9263_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91SAM9263_ID_PIOB,
}, {
- .id = AT91SAM9263_ID_PIOCDE,
- .offset = AT91_PIOC,
- .clock = &pioCDE_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91SAM9263_ID_PIOCDE,
}, {
- .id = AT91SAM9263_ID_PIOCDE,
- .offset = AT91_PIOD,
- .clock = &pioCDE_clk,
+ .mmio_base = AT91_PIOD,
+ .irq = AT91SAM9263_ID_PIOCDE,
}, {
- .id = AT91SAM9263_ID_PIOCDE,
- .offset = AT91_PIOE,
- .clock = &pioCDE_clk,
+ .mmio_base = AT91_PIOE,
+ .irq = AT91SAM9263_ID_PIOCDE,
}
};
@@ -343,9 +340,6 @@ static void __init at91sam9263_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91sam9263_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91sam9263_gpio, 5);
}
/* --------------------------------------------------------------------
@@ -394,4 +388,8 @@ struct at91_soc __initdata at91sam9263_soc = {
.name = "at91sam9263",
.default_irq_priority = at91sam9263_default_irq_priority,
.init = at91sam9263_initialize,
+ .gpio = {
+ .resource = at91sam9263_pios,
+ .num_resources = ARRAY_SIZE(at91sam9263_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index a1561d4..0fee23f 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -211,10 +211,11 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
- CLKDEV_CON_ID("pioDE_clk", &pioDE_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.3", &pioDE_clk),
+ CLKDEV_DEV_ID("at91_gpio.4", &pioDE_clk),
CLKDEV_CON_ID("twi0_clk", &twi0_clk),
CLKDEV_CON_ID("twi1_clk", &twi1_clk),
CLKDEV_CON_ID("pwm_clk", &pwm_clk),
@@ -309,27 +310,22 @@ struct clk* __init at91sam9g45_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91sam9g45_gpio[] = {
+static struct at91_dev_resource at91sam9g45_pios[] __initdata = {
{
- .id = AT91SAM9G45_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91SAM9G45_ID_PIOA,
}, {
- .id = AT91SAM9G45_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91SAM9G45_ID_PIOB,
}, {
- .id = AT91SAM9G45_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91SAM9G45_ID_PIOC,
}, {
- .id = AT91SAM9G45_ID_PIODE,
- .offset = AT91_PIOD,
- .clock = &pioDE_clk,
+ .mmio_base = AT91_PIOD,
+ .irq = AT91SAM9G45_ID_PIODE,
}, {
- .id = AT91SAM9G45_ID_PIODE,
- .offset = AT91_PIOE,
- .clock = &pioDE_clk,
+ .mmio_base = AT91_PIOE,
+ .irq = AT91SAM9G45_ID_PIODE,
}
};
@@ -362,9 +358,6 @@ static void __init at91sam9g45_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91sam9g45_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91sam9g45_gpio, 5);
}
/* --------------------------------------------------------------------
@@ -413,4 +406,8 @@ struct at91_soc __initdata at91sam9g45_soc = {
.name = "at91sam9g45",
.default_irq_priority = at91sam9g45_default_irq_priority,
.init = at91sam9g45_initialize,
+ .gpio = {
+ .resource = at91sam9g45_pios,
+ .num_resources = ARRAY_SIZE(at91sam9g45_pios),
+ },
};
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 80acd8f..ec62ca01 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -184,10 +184,10 @@ static struct clk *periph_clocks[] __initdata = {
};
static struct clk_lookup periph_clocks_lookups[] = {
- CLKDEV_CON_ID("pioA_clk", &pioA_clk),
- CLKDEV_CON_ID("pioB_clk", &pioB_clk),
- CLKDEV_CON_ID("pioC_clk", &pioC_clk),
- CLKDEV_CON_ID("pioD_clk", &pioD_clk),
+ CLKDEV_DEV_ID("at91_gpio.0", &pioA_clk),
+ CLKDEV_DEV_ID("at91_gpio.1", &pioB_clk),
+ CLKDEV_DEV_ID("at91_gpio.2", &pioC_clk),
+ CLKDEV_DEV_ID("at91_gpio.3", &pioD_clk),
CLKDEV_CON_ID("mci_clk", &mmc_clk),
CLKDEV_CON_ID("twi0_clk", &twi0_clk),
CLKDEV_CON_ID("twi1_clk", &twi1_clk),
@@ -266,23 +266,19 @@ struct clk* __init at91sam9rl_get_uart_clock(int id)
* GPIO
* -------------------------------------------------------------------- */
-static struct at91_gpio_bank at91sam9rl_gpio[] = {
+static struct at91_dev_resource at91sam9rl_pios[] __initdata = {
{
- .id = AT91SAM9RL_ID_PIOA,
- .offset = AT91_PIOA,
- .clock = &pioA_clk,
+ .mmio_base = AT91_PIOA,
+ .irq = AT91SAM9RL_ID_PIOA,
}, {
- .id = AT91SAM9RL_ID_PIOB,
- .offset = AT91_PIOB,
- .clock = &pioB_clk,
+ .mmio_base = AT91_PIOB,
+ .irq = AT91SAM9RL_ID_PIOB,
}, {
- .id = AT91SAM9RL_ID_PIOC,
- .offset = AT91_PIOC,
- .clock = &pioC_clk,
+ .mmio_base = AT91_PIOC,
+ .irq = AT91SAM9RL_ID_PIOC,
}, {
- .id = AT91SAM9RL_ID_PIOD,
- .offset = AT91_PIOD,
- .clock = &pioD_clk,
+ .mmio_base = AT91_PIOD,
+ .irq = AT91SAM9RL_ID_PIOD,
}
};
@@ -328,9 +324,6 @@ static void __init at91sam9rl_initialize(unsigned long main_clock)
/* Register the processor-specific clocks */
at91sam9rl_register_clocks();
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91sam9rl_gpio, 4);
}
/* --------------------------------------------------------------------
@@ -379,4 +372,8 @@ struct at91_soc __initdata at91sam9rl_soc = {
.name = "at91sam9rl",
.default_irq_priority = at91sam9rl_default_irq_priority,
.init = at91sam9rl_initialize,
+ .gpio = {
+ .resource = at91sam9rl_pios,
+ .num_resources = ARRAY_SIZE(at91sam9rl_pios),
+ },
};
diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h
index f0d8776..3e40da2 100644
--- a/arch/arm/mach-at91/clock.h
+++ b/arch/arm/mach-at91/clock.h
@@ -32,6 +32,12 @@ extern int __init clk_register(struct clk *clk);
extern struct clk mck;
extern struct clk utmi_clk;
+#define CLKDEV_DEV_ID(_id, _clk) \
+ { \
+ .dev_id = _id, \
+ .clk = _clk, \
+ }
+
#define CLKDEV_CON_ID(_id, _clk) \
{ \
.con_id = _id, \
diff --git a/arch/arm/mach-at91/devices.c b/arch/arm/mach-at91/devices.c
new file mode 100644
index 0000000..03ded48
--- /dev/null
+++ b/arch/arm/mach-at91/devices.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2007 Stelian Pop <stelian.pop at leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2007-2011 Atmel Corporation.
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
+ *
+ * Under GPLv2
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include "devices.h"
+
+
diff --git a/arch/arm/mach-at91/devices.h b/arch/arm/mach-at91/devices.h
new file mode 100644
index 0000000..4d39f9b
--- /dev/null
+++ b/arch/arm/mach-at91/devices.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-at91/devices.h
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
+ *
+ * Under GPLv2
+ *
+ */
+
+#ifndef _AT91_DEVICES_H
+#define _AT91_DEVICES_H
+
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#define RES_MEM(size) \
+ { \
+ .end = size - 1, \
+ .flags = IORESOURCE_MEM, \
+ }
+
+#define RES_IRQ() \
+ { \
+ .flags = IORESOURCE_IRQ, \
+ }
+
+
+static inline void set_resource_mem(struct resource *res, resource_size_t mmio_base)
+{
+ BUG_ON(res->flags != IORESOURCE_MEM);
+ res->start = mmio_base;
+ res->end += mmio_base;
+}
+
+static inline void set_resource_irq(struct resource *res, int irq)
+{
+ if (!irq)
+ return;
+
+ BUG_ON(res->flags != IORESOURCE_IRQ);
+ res->start = irq;
+ res->end = irq;
+}
+
+struct at91_dev_resource {
+ resource_size_t mmio_base;
+ int irq;
+};
+
+struct at91_dev_resource_array {
+ struct at91_dev_resource *resource;
+ int num_resources;
+};
+
+#endif /* _AT91_DEVICES_H */
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index a039726..b2c7c3a 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -50,12 +50,6 @@ extern void at91sam9_alt_reset(void);
#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */
#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
-struct at91_gpio_bank {
- unsigned short id; /* peripheral ID */
- unsigned long offset; /* offset from system peripheral base */
- struct clk *clock; /* associated clock */
-};
-extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
extern void __init at91_gpio_irq_setup(void);
extern void (*at91_arch_reset)(void);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 4615528..dd05512 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -26,12 +27,11 @@
#include <asm/gpio.h>
-#include "generic.h"
-
struct at91_gpio_chip {
struct gpio_chip chip;
+ unsigned short id; /* peripheral ID */
+ struct clk *clock; /* associated clock */
struct at91_gpio_chip *next; /* Bank sharing same clock */
- struct at91_gpio_bank *bank; /* Bank definition */
void __iomem *regbase; /* Base of register bank */
};
@@ -287,7 +287,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
else
wakeups[bank] &= ~mask;
- irq_set_irq_wake(gpio_chip[bank].bank->id, state);
+ irq_set_irq_wake(gpio_chip[bank].id, state);
return 0;
}
@@ -304,7 +304,7 @@ void at91_gpio_suspend(void)
__raw_writel(wakeups[i], pio + PIO_IER);
if (!wakeups[i])
- clk_disable(gpio_chip[i].bank->clock);
+ clk_disable(gpio_chip[i].clock);
else {
#ifdef CONFIG_PM_DEBUG
printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
@@ -321,7 +321,7 @@ void at91_gpio_resume(void)
void __iomem *pio = gpio_chip[i].regbase;
if (!wakeups[i])
- clk_enable(gpio_chip[i].bank->clock);
+ clk_enable(gpio_chip[i].clock);
__raw_writel(wakeups[i], pio + PIO_IDR);
__raw_writel(backups[i], pio + PIO_IER);
@@ -499,7 +499,7 @@ void __init at91_gpio_irq_setup(void)
for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
pioc++ < gpio_banks;
prev = this, this++) {
- unsigned id = this->bank->id;
+ unsigned id = this->id;
unsigned i;
__raw_writel(~0, this->regbase + PIO_IDR);
@@ -599,34 +599,56 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
}
}
-/*
- * Called from the processor-specific init to enable GPIO pin support.
- */
-void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
+static int __devinit at91_gpio_probe(struct platform_device *pdev)
{
- unsigned i;
- struct at91_gpio_chip *at91_gpio, *last = NULL;
+ int id = pdev->id;
+ struct at91_gpio_chip *at91_gpio;
- BUG_ON(nr_banks > MAX_GPIO_BANKS);
+ if (!is_early_platform_device(pdev)) {
+ pr_info("at91_gpio.%d: call via non early plaform\n", id);
+ return 0;
+ }
- gpio_banks = nr_banks;
+ BUG_ON(id > MAX_GPIO_BANKS);
- for (i = 0; i < nr_banks; i++) {
- at91_gpio = &gpio_chip[i];
+ gpio_banks = max(gpio_banks, id + 1);
- at91_gpio->bank = &data[i];
- at91_gpio->chip.base = PIN_BASE + i * 32;
- at91_gpio->regbase = at91_gpio->bank->offset +
+ at91_gpio = &gpio_chip[id];
+ at91_gpio->id = platform_get_irq(pdev, 0);
+ at91_gpio->chip.base = PIN_BASE + id * 32;
+ at91_gpio->regbase = pdev->resource[0].start +
(void __iomem *)AT91_VA_BASE_SYS;
- /* enable PIO controller's clock */
- clk_enable(at91_gpio->bank->clock);
+ at91_gpio->clock = clk_get_pdev(pdev, NULL);
- /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
- if (last && last->bank->id == at91_gpio->bank->id)
- last->next = at91_gpio;
- last = at91_gpio;
+ /* enable PIO controller's clock */
+ clk_enable(at91_gpio->clock);
- gpiochip_add(&at91_gpio->chip);
- }
+ /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
+ if (id > 0 && gpio_chip[id - 1].id == at91_gpio->id)
+ gpio_chip[id - 1].next = at91_gpio;
+
+ gpiochip_add(&at91_gpio->chip);
+
+ pr_debug("at91_gpio.%d: offset = 0x%x, clk = 0x%p, irq = %d\n",
+ id, pdev->resource[0].start, at91_gpio->clock,
+ at91_gpio->id);
+
+ return 0;
+}
+
+static int __devexit at91_gpio_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
}
+
+static struct platform_driver at91_gpio_driver = {
+ .probe = at91_gpio_probe,
+ .remove = __devexit_p(at91_gpio_remove),
+ .driver = {
+ .name = "at91_gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+early_platform_init("early_at91_gpio", &at91_gpio_driver);
diff --git a/arch/arm/mach-at91/soc.c b/arch/arm/mach-at91/soc.c
index 6fe205f2..0e8604c 100644
--- a/arch/arm/mach-at91/soc.c
+++ b/arch/arm/mach-at91/soc.c
@@ -20,6 +20,7 @@
#include "generic.h"
static struct at91_soc __initdata current_soc;
+static void __init at91_add_gpio(void);
struct at91_cpu_id cpu_id;
EXPORT_SYMBOL(cpu_id);
@@ -114,4 +115,100 @@ void __init at91_initialize(unsigned long main_clock)
pr_info("AT91: detected soc: %s\n", current_soc.name);
current_soc.init(main_clock);
+
+ /* Register GPIO subsystem */
+ at91_add_gpio();
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct resource pioa_resources[] = {
+ [0] = RES_MEM(SZ_512),
+ [1] = RES_IRQ(),
+};
+
+static struct platform_device at91_pioa_device = {
+ .name = "at91_gpio",
+ .id = 0,
+ .resource = pioa_resources,
+ .num_resources = ARRAY_SIZE(pioa_resources),
+};
+
+static struct resource piob_resources[] = {
+ [0] = RES_MEM(SZ_512),
+ [1] = RES_IRQ(),
+};
+
+static struct platform_device at91_piob_device = {
+ .name = "at91_gpio",
+ .id = 1,
+ .resource = piob_resources,
+ .num_resources = ARRAY_SIZE(piob_resources),
+};
+
+static struct resource pioc_resources[] = {
+ [0] = RES_MEM(SZ_512),
+ [1] = RES_IRQ(),
+};
+
+static struct platform_device at91_pioc_device = {
+ .name = "at91_gpio",
+ .id = 2,
+ .resource = pioc_resources,
+ .num_resources = ARRAY_SIZE(pioc_resources),
+};
+
+static struct resource piod_resources[] = {
+ [0] = RES_MEM(SZ_512),
+ [1] = RES_IRQ(),
+};
+
+static struct platform_device at91_piod_device = {
+ .name = "at91_gpio",
+ .id = 3,
+ .resource = piod_resources,
+ .num_resources = ARRAY_SIZE(piod_resources),
+};
+
+static struct resource pioe_resources[] = {
+ [0] = RES_MEM(SZ_512),
+ [1] = RES_IRQ(),
+};
+
+static struct platform_device at91_pioe_device = {
+ .name = "at91_gpio",
+ .id = 4,
+ .resource = pioe_resources,
+ .num_resources = ARRAY_SIZE(pioe_resources),
+};
+
+static struct platform_device *at91_pio_devices[] __initdata = {
+ &at91_pioa_device,
+ &at91_piob_device,
+ &at91_pioc_device,
+ &at91_piod_device,
+ &at91_pioe_device,
+};
+
+static void __init at91_add_gpio(void)
+{
+ struct at91_dev_resource *gpios = current_soc.gpio.resource;
+ int nb = current_soc.gpio.num_resources;
+
+ int i;
+ struct resource *r;
+
+ BUG_ON(!gpios || nb < 0 || nb > ARRAY_SIZE(at91_pio_devices));
+
+ for (i = 0; i < nb; i++) {
+ r = at91_pio_devices[i]->resource;
+ set_resource_mem(&r[0], gpios[i].mmio_base);
+ set_resource_irq(&r[1], gpios[i].irq);
+ }
+
+ early_platform_add_devices(at91_pio_devices, nb);
+ early_platform_driver_register_all("early_at91_gpio");
+ early_platform_driver_probe("early_at91_gpio", nb , 0);
}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index a097032..bf90d48 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -6,10 +6,14 @@
*
*/
+#include "devices.h"
+
struct at91_soc {
char *name;
unsigned int *default_irq_priority;
+ struct at91_dev_resource_array gpio;
+
void (*init)(unsigned long main_clock);
};
--
1.7.4.1
More information about the linux-arm-kernel
mailing list