[RFC PATCH 08/23] at91: Make SPI device common

Ryan Mallon ryan at bluewatersys.com
Tue Apr 19 21:10:12 EDT 2011


Replace the individual SPI code for each at91 variant with a single
implementation in devices.c

Signed-off-by: Ryan Mallon <ryan at bluewatersys.com>
---
 arch/arm/mach-at91/at572d940hf_devices.c |  122 +++++-------------------------
 arch/arm/mach-at91/at91cap9_devices.c    |  122 +++++-------------------------
 arch/arm/mach-at91/at91rm9200_devices.c  |   69 ++---------------
 arch/arm/mach-at91/at91sam9260_devices.c |  122 +++++-------------------------
 arch/arm/mach-at91/at91sam9261_devices.c |  122 +++++-------------------------
 arch/arm/mach-at91/at91sam9263_devices.c |  122 +++++-------------------------
 arch/arm/mach-at91/at91sam9g45_devices.c |  122 +++++-------------------------
 arch/arm/mach-at91/at91sam9rl_devices.c  |   67 ++--------------
 arch/arm/mach-at91/devices.c             |  103 +++++++++++++++++++++++++
 arch/arm/mach-at91/devices.h             |   11 +++
 10 files changed, 252 insertions(+), 730 deletions(-)

diff --git a/arch/arm/mach-at91/at572d940hf_devices.c b/arch/arm/mach-at91/at572d940hf_devices.c
index f8ea398..5df2d13 100644
--- a/arch/arm/mach-at91/at572d940hf_devices.c
+++ b/arch/arm/mach-at91/at572d940hf_devices.c
@@ -142,114 +142,30 @@ static struct __initdata at91_dev_table_twi device_twi1 = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT572D940HF_BASE_SPI0,
-		.end	= AT572D940HF_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT572D940HF_ID_SPI0,
-		.end	= AT572D940HF_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at572d940hf_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT572D940HF_BASE_SPI0,
+	.irq			= AT572D940HF_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT572D940HF_BASE_SPI1,
-		.end	= AT572D940HF_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT572D940HF_ID_SPI1,
-		.end	= AT572D940HF_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT572D940HF_BASE_SPI1,
+	.irq			= AT572D940HF_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6,
 	},
+	.pin_miso		= {AT91_PIN_PC0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PC1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PC2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at572d940hf_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_A_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_A_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
-
-		at91_clock_associate("spi0_clk", &at572d940hf_spi0_device.dev, "spi_clk");
-		platform_device_register(&at572d940hf_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PC0, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PC1, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PC2, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at572d940hf_spi1_device.dev, "spi_clk");
-		platform_device_register(&at572d940hf_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  Timer/Counter blocks
  * -------------------------------------------------------------------- */
@@ -661,6 +577,8 @@ static struct at91_device_table __initdata at572d940hf_device_table = {
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi0,
 	.twi[1]		= &device_twi1,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at572d940hf_init_devices(void)
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index a775fcc..1cc0b5b 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -251,114 +251,30 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SPI0,
-		.end	= AT91CAP9_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SPI0,
-		.end	= AT91CAP9_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT91CAP9_BASE_SPI0,
+	.irq			= AT91CAP9_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_B, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_B, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_B, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SPI1,
-		.end	= AT91CAP9_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SPI1,
-		.end	= AT91CAP9_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT91CAP9_BASE_SPI1,
+	.irq			= AT91CAP9_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18,
 	},
+	.pin_miso		= {AT91_PIN_PB12, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PC13, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PC14, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at91cap9_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_B_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
-
-		at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk");
-		platform_device_register(&at91cap9_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB12, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk");
-		platform_device_register(&at91cap9_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  Timer/Counter block
  * -------------------------------------------------------------------- */
@@ -989,6 +905,8 @@ static struct at91_device_table __initdata at91cap9_device_table = {
 	.mmc[1]		= &device_mmc1,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at91cap9_init_devices(void)
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index d3ef09d..a2fec48 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -235,69 +235,17 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi_resources[] = {
-	[0] = {
-		.start	= AT91RM9200_BASE_SPI,
-		.end	= AT91RM9200_BASE_SPI + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91RM9200_ID_SPI,
-		.end	= AT91RM9200_ID_SPI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91rm9200_spi_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi = {
+	.mmio_base		= AT91RM9200_BASE_SPI,
+	.irq			= AT91RM9200_ID_SPI,
+	.standard_cs_pins	= {
+		AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6,
 	},
-	.resource	= spi_resources,
-	.num_resources	= ARRAY_SIZE(spi_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-
-	at91_set_A_periph(AT91_PIN_PA0, 0);	/* MISO */
-	at91_set_A_periph(AT91_PIN_PA1, 0);	/* MOSI */
-	at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPCK */
-
-	/* Enable SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else
-			cs_pin = spi_standard_cs[devices[i].chip_select];
-
-		if (devices[i].chip_select == 0)	/* for CS0 errata */
-			at91_set_A_periph(cs_pin, 0);
-		else
-			at91_set_gpio_output(cs_pin, 1);
-
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-	platform_device_register(&at91rm9200_spi_device);
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  Timer/Counter blocks
  * -------------------------------------------------------------------- */
@@ -899,6 +847,7 @@ static struct at91_device_table __initdata at91rm9200_device_table = {
 	.mmc[0]		= &device_mmc,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi,
 };
 
 void __init at91rm9200_init_devices(void)
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index ffcde0e..f5d264a 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -136,114 +136,30 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91SAM9260_BASE_SPI0,
-		.end	= AT91SAM9260_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9260_ID_SPI0,
-		.end	= AT91SAM9260_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91sam9260_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT91SAM9260_BASE_SPI0,
+	.irq			= AT91SAM9260_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91SAM9260_BASE_SPI1,
-		.end	= AT91SAM9260_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9260_ID_SPI1,
-		.end	= AT91SAM9260_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT91SAM9260_BASE_SPI1,
+	.irq			= AT91SAM9260_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3,
 	},
+	.pin_miso		= {AT91_PIN_PB0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PB1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PB2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at91sam9260_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_A_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_A_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk");
-		platform_device_register(&at91sam9260_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB0, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk");
-		platform_device_register(&at91sam9260_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  Timer/Counter blocks
  * -------------------------------------------------------------------- */
@@ -951,6 +867,8 @@ static struct at91_device_table __initdata at91sam9260_device_table = {
 	.mmc[0]		= &device_mmc,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at91sam9260_init_devices(void)
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index dfcd763..70b1adc 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -99,114 +99,30 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91SAM9261_BASE_SPI0,
-		.end	= AT91SAM9261_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9261_ID_SPI0,
-		.end	= AT91SAM9261_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91sam9261_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT91SAM9261_BASE_SPI0,
+	.irq			= AT91SAM9261_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91SAM9261_BASE_SPI1,
-		.end	= AT91SAM9261_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9261_ID_SPI1,
-		.end	= AT91SAM9261_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT91SAM9261_BASE_SPI1,
+	.irq			= AT91SAM9261_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26,
 	},
+	.pin_miso		= {AT91_PIN_PB30, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PB31, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PB29, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at91sam9261_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_A_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_A_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
-
-		at91_clock_associate("spi0_clk", &at91sam9261_spi0_device.dev, "spi_clk");
-		platform_device_register(&at91sam9261_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB30, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB31, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB29, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk");
-		platform_device_register(&at91sam9261_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  LCD Controller
  * -------------------------------------------------------------------- */
@@ -814,6 +730,8 @@ static struct at91_device_table __initdata at91sam9261_device_table = {
 	.mmc[0]		= &device_mmc,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at91sam9261_init_devices(void)
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 346aa9e..934a756 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -271,114 +271,30 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91SAM9263_BASE_SPI0,
-		.end	= AT91SAM9263_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9263_ID_SPI0,
-		.end	= AT91SAM9263_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91sam9263_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT91SAM9263_BASE_SPI0,
+	.irq			= AT91SAM9263_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PA0, AT91_PIN_PERIPH_B, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA1, AT91_PIN_PERIPH_B, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA2, AT91_PIN_PERIPH_B, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91SAM9263_BASE_SPI1,
-		.end	= AT91SAM9263_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9263_ID_SPI1,
-		.end	= AT91SAM9263_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT91SAM9263_BASE_SPI1,
+	.irq			= AT91SAM9263_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18,
 	},
+	.pin_miso		= {AT91_PIN_PB12, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PB13, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PB14, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at91sam9263_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_B_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
-
-		at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk");
-		platform_device_register(&at91sam9263_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB12, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk");
-		platform_device_register(&at91sam9263_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  AC97
  * -------------------------------------------------------------------- */
@@ -1109,6 +1025,8 @@ static struct at91_device_table __initdata at91sam9263_device_table = {
 	.mmc[1]		= &device_mmc1,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at91sam9263_init_devices(void)
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index a86f08e..f9ba907 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -303,114 +303,30 @@ static struct __initdata at91_dev_table_twi device_twi1 = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91SAM9G45_BASE_SPI0,
-		.end	= AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9G45_ID_SPI0,
-		.end	= AT91SAM9G45_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91sam9g45_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi0 = {
+	.mmio_base		= AT91SAM9G45_BASE_SPI0,
+	.irq			= AT91SAM9G45_ID_SPI0,
+	.clk_asc		= "spi0_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27,
 	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
+	.pin_miso		= {AT91_PIN_PB0, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PB1, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PB2, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91SAM9G45_BASE_SPI1,
-		.end	= AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9G45_ID_SPI1,
-		.end	= AT91SAM9G45_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
+static struct __initdata at91_dev_table_spi device_spi1 = {
+	.mmio_base		= AT91SAM9G45_BASE_SPI1,
+	.irq			= AT91SAM9G45_ID_SPI1,
+	.clk_asc		= "spi1_clk",
+	.standard_cs_pins	= {
+		AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19,
 	},
+	.pin_miso		= {AT91_PIN_PB14, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PB15, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PB16, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static struct platform_device at91sam9g45_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_A_periph(AT91_PIN_PB0, 0);	/* SPI0_MISO */
-		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI0_MOSI */
-		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI0_SPCK */
-
-		at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk");
-		platform_device_register(&at91sam9g45_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB15, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB16, 0);	/* SPI1_SPCK */
-
-		at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk");
-		platform_device_register(&at91sam9g45_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  AC97
  * -------------------------------------------------------------------- */
@@ -1189,6 +1105,8 @@ static struct at91_device_table __initdata at91sam9g45_device_table = {
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi0,
 	.twi[1]		= &device_twi1,
+	.spi[0]		= &device_spi0,
+	.spi[1]		= &device_spi1,
 };
 
 void __init at91sam9g45_init_devices(void)
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index dd8f8c4..5d1aba4 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -212,67 +212,17 @@ static struct __initdata at91_dev_table_twi device_twi = {
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi_resources[] = {
-	[0] = {
-		.start	= AT91SAM9RL_BASE_SPI,
-		.end	= AT91SAM9RL_BASE_SPI + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91SAM9RL_ID_SPI,
-		.end	= AT91SAM9RL_ID_SPI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91sam9rl_spi_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
+static struct __initdata at91_dev_table_spi device_spi = {
+	.mmio_base		= AT91SAM9RL_BASE_SPI,
+	.irq			= AT91SAM9RL_ID_SPI,
+	.standard_cs_pins	= {
+		AT91_PIN_PA28, AT91_PIN_PB7, AT91_PIN_PD8, AT91_PIN_PD9,
 	},
-	.resource	= spi_resources,
-	.num_resources	= ARRAY_SIZE(spi_resources),
+	.pin_miso		= {AT91_PIN_PA25, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_mosi		= {AT91_PIN_PA26, AT91_PIN_PERIPH_A, 0, 0, 0},
+	.pin_spck		= {AT91_PIN_PA27, AT91_PIN_PERIPH_A, 0, 0, 0},
 };
 
-static const unsigned spi_standard_cs[4] = { AT91_PIN_PA28, AT91_PIN_PB7, AT91_PIN_PD8, AT91_PIN_PD9 };
-
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-
-	at91_set_A_periph(AT91_PIN_PA25, 0);	/* MISO */
-	at91_set_A_periph(AT91_PIN_PA26, 0);	/* MOSI */
-	at91_set_A_periph(AT91_PIN_PA27, 0);	/* SPCK */
-
-	/* Enable SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else
-			cs_pin = spi_standard_cs[devices[i].chip_select];
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-	platform_device_register(&at91sam9rl_spi_device);
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
 /* --------------------------------------------------------------------
  *  AC97
  * -------------------------------------------------------------------- */
@@ -1035,6 +985,7 @@ static struct at91_device_table __initdata at91sam9rl_device_table = {
 	.mmc[0]		= &device_mmc,
 	.nand		= &device_nand,
 	.twi[0]		= &device_twi,
+	.spi[0]		= &device_spi,
 };
 
 void __init at91sam9rl_init_devices(void)
diff --git a/arch/arm/mach-at91/devices.c b/arch/arm/mach-at91/devices.c
index 64e02bd..0df4b06 100644
--- a/arch/arm/mach-at91/devices.c
+++ b/arch/arm/mach-at91/devices.c
@@ -729,6 +729,109 @@ void __init at91_add_device_i2c(short i2c_id,
 				int nr_devices) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+	[0] = {
+		.end	= SZ_16K,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_spi0_device = {
+	.name		= "atmel_spi",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static struct resource spi1_resources[] = {
+	[0] = {
+		.end	= SZ_16K,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_spi1_device = {
+	.name		= "atmel_spi",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+
+void __init at91_add_device_spi(struct spi_board_info *spi_devices,
+				int nr_devices)
+{
+	struct at91_dev_table_spi *info;
+	int i;
+	unsigned long cs_pin;
+	short enable_spi0 = 0;
+	short enable_spi1 = 0;
+
+	/* Choose SPI chip-selects */
+	for (i = 0; i < nr_devices; i++) {
+		info = devices->spi[spi_devices[i].bus_num];
+		BUG_ON(!info);
+
+		if (spi_devices[i].controller_data)
+			cs_pin = (unsigned long)spi_devices[i].controller_data;
+		else
+			cs_pin = info->standard_cs_pins[spi_devices[i].chip_select];
+
+		/* enable chip-select pin */
+		at91_set_gpio_output(cs_pin, 1);
+
+		/* pass chip-select pin to driver */
+		spi_devices[i].controller_data = (void *)cs_pin;
+
+		at91_config_pins(&info->pin_miso, 1);
+		at91_config_pins(&info->pin_mosi, 1);
+		at91_config_pins(&info->pin_spck, 1);
+
+		if (spi_devices[i].bus_num == 0) {
+			enable_spi0 = 1;
+			if (info->clk_asc)
+				at91_clock_associate(info->clk_asc,
+						     &at91_spi0_device.dev,
+						     "spi_clk");
+		} else {
+			enable_spi1 = 1;
+			if (info->clk_asc)
+				at91_clock_associate(info->clk_asc,
+						     &at91_spi1_device.dev,
+						     "spi_clk");
+		}
+	}
+
+	spi_register_board_info(spi_devices, nr_devices);
+	if (enable_spi0)
+		platform_device_register(&at91_spi0_device);
+	if (enable_spi1)
+		platform_device_register(&at91_spi1_device);
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *spi_devices, int nr_devices) {}
+#endif
+
 void __init at91_init_devices(struct at91_device_table *device_table)
 {
 	devices = device_table;
diff --git a/arch/arm/mach-at91/devices.h b/arch/arm/mach-at91/devices.h
index 9b99be2..ba85523 100644
--- a/arch/arm/mach-at91/devices.h
+++ b/arch/arm/mach-at91/devices.h
@@ -81,6 +81,16 @@ struct at91_dev_table_twi {
 	int			udelay;		/* For i2c-gpio */
 };
 
+struct at91_dev_table_spi {
+	unsigned		mmio_base;
+	int			irq;
+	const char		*clk_asc;
+	int			standard_cs_pins[4];
+	struct at91_pin_config	pin_miso;
+	struct at91_pin_config	pin_mosi;
+	struct at91_pin_config	pin_spck;
+};
+
 struct at91_device_table {
 	struct at91_dev_table_ethernet		*ethernet;
 	struct at91_dev_table_usb_ohci		*usbh_ohci;
@@ -89,6 +99,7 @@ struct at91_device_table {
 	struct at91_dev_table_mmc		*mmc[2];
 	struct at91_dev_table_nand		*nand;
 	struct at91_dev_table_twi		*twi[2];
+	struct at91_dev_table_spi		*spi[2];
 };
 
 extern void __init at91_init_devices(struct at91_device_table *device_table);
-- 
1.7.0.4




More information about the linux-arm-kernel mailing list