spi: s6000 spi host driver
Subsystems (2)
PATCH 1/6 spi: s6000 spi host driver
From: Johannes Weiner <[email protected]>
The host controller has a 128 bit buffer which is shared between rx and tx. Filling and reading of this buffer happens in a dedicated workqueue. We always fill it with an integer number of words but don't cross spi_transfer boundaries.
The driver usually uses interrupts but falls back to polling if the transfer is expected to finish within a certain window of time.
--- drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi_s6000.c | 648 +++++++++++++++++++++++++++++++++++++++++ drivers/spi/spi_s6000.h | 26 ++ include/linux/spi/spi_s6000.h | 10 + 5 files changed, 691 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi_s6000.c create mode 100644 drivers/spi/spi_s6000.h create mode 100644 include/linux/spi/spi_s6000.h
drivers/spi/Kconfig +6 -0
@@ -197,6 +197,12 @@ config SPI_S3C24XX_GPIO the inbuilt hardware cannot provide the transfer mode, or where the board is using non hardware connected pins. +config SPI_S6000 + tristate "S6000 SPI master" + depends on SPI_MASTER && XTENSA_VARIANT_S6000 + help + SPI driver for the Stretch S6000 family SoCs. + config SPI_SH_SCI tristate "SuperH SCI SPI controller" depends on SUPERH
drivers/spi/Makefile +1 -0
@@ -27,6 +27,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o +obj-$(CONFIG_SPI_S6000) += spi_s6000.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
drivers/spi/spi_s6000.c new file +648 -0
648 lines not on this page · raw message
drivers/spi/spi_s6000.h new file +26 -0
@@ -0,0 +1,26 @@ +#ifndef __DRIVERS_SPI_SPI_S6000_H +#define __DRIVERS_SPI_SPI_S6000_H + +#define S6_SPI_RX0 0x00 +#define S6_SPI_RX1 0x04 +#define S6_SPI_RX2 0x08 +#define S6_SPI_RX3 0x0C +#define S6_SPI_TX0 0x00 +#define S6_SPI_TX1 0x04 +#define S6_SPI_TX2 0x08 +#define S6_SPI_TX3 0x0C +#define S6_SPI_CTRL 0x10 +#define S6_SPI_CTRL_GO_BSY 0 +#define S6_SPI_CTRL_Rx_NEG 1 +#define S6_SPI_CTRL_Tx_NEG 2 +#define S6_SPI_CTRL_CHAR_LEN 3 +#define S6_SPI_CTRL_LSB 10 +#define S6_SPI_CTRL_IE 11 +#define S6_SPI_CTRL_ASS 12 +#define S6_SPI_CTRL_CPOL 13 +#define S6_SPI_DIVIDER 0x14 +#define S6_SPI_DIVIDER_MAX 0xffff +#define S6_SPI_SS 0x18 +#define S6_SPI_INT_CLR 0x20 + +#endif
include/linux/spi/spi_s6000.h new file +10 -0
@@ -0,0 +1,10 @@ +#ifndef __LINUX_SPI_SPI_S6000_H +#define __LINUX_SPI_SPI_S6000_H + +struct s6_spi_platform_data { +const char *clock; +s16 bus_num; +u8 cs_polarity; +}; + +#endif
Signature · 1 line
1.6.2.107.ge47ee
PATCH 2/6 xtensa: add s6000 spi host to s6105 platform
--- arch/xtensa/platforms/s6105/device.c | 48 ++++++++++++++++++++++++++++++++++ arch/xtensa/platforms/s6105/setup.c | 5 +++- 2 files changed, 52 insertions(+), 1 deletions(-)
arch/xtensa/platforms/s6105/device.c +48 -0
@@ -14,6 +14,8 @@#include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_8250.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi_s6000.h> #include <variant/hardware.h> #include <variant/dmac.h>
@@ -24,6 +26,7 @@#define UART_INTNUM 4#define GMAC_INTNUM 5#define I2C_INTNUM 6 +#define SPI_INTNUM 11static const signed char gpio3_irq_mappings[] = {S6_INTC_GPIO (3 ),
@@ -49,11 +52,17 @@ static const signed char i2c_irq_mappings[] = {-1 }; +static const signed char spi_irq_mappings[] = { +S6_INTC_SPI , +-1 +}; +const signed char *platform_irq_mappings[NR_IRQS ] = { [GPIO3_INTNUM ] = gpio3_irq_mappings, [UART_INTNUM ] = uart_irq_mappings, [GMAC_INTNUM ] = gmac_irq_mappings, [I2C_INTNUM ] = i2c_irq_mappings, + [SPI_INTNUM ] = spi_irq_mappings, };static struct plat_serial8250_port serial_platform_data[] = {
@@ -173,6 +182,36 @@ static struct i2c_board_info __initdata s6_i2c_devices[] = { }, }; +static struct resource s6_spi_resource[] = { + { + .name ="mem" , + .start = (resource_size_t )S6_REG_SPI , + .end = (resource_size_t )S6_REG_SPI +0x1000 -1 , + .flags =IORESOURCE_MEM , + }, + { + .name ="irq" , + .start = (resource_size_t )SPI_INTNUM , + .flags =IORESOURCE_IRQ , + }, +}; + +#define S6_SPI_BUS_NUM 0 + +static __devinitdata struct s6_spi_platform_data s6_spi_pdata = { + .bus_num =S6_SPI_BUS_NUM , + .cs_polarity =0x00 , + .clock ="PCLK" , +}; + +#define S6_SPI_CS_BOOT_FLASH 0 +#define S6_SPI_CS_BACK_PANEL 1 +#define S6_SPI_CS_EXPANSION 3 +#define S6_SPI_CS_MMC_SLOT 4 + +static struct spi_board_info __initdata s6_spi_devices[] = { +}; +static struct platform_device platform_devices[] = { { .name ="serial8250" ,
@@ -195,6 +234,14 @@ static struct platform_device platform_devices[] = { .platform_data = &s6_i2c_pdata, }, }, + { + .name = "spi_s6000", + .resource = s6_spi_resource, + .num_resources = ARRAY_SIZE(s6_spi_resource), + .dev = { + .platform_data = &s6_spi_pdata, + }, + }, };static int __init device_init (void )
@@ -203,6 +250,7 @@ static int __init device_init(void)i2c_register_board_info (S6_I2C_BUS_NUM , s6_i2c_devices,ARRAY_SIZE (s6_i2c_devices)); +spi_register_board_info (s6_spi_devices,ARRAY_SIZE (s6_spi_devices)); s6_gmac_resource[5 ].start =prepare_phy_irq (GPIO_PHY_IRQ );for (i =0 ; i <ARRAY_SIZE (platform_devices); i++)
arch/xtensa/platforms/s6105/setup.c +4 -1
@@ -58,7 +58,10 @@ void __init platform_setup(char **cmdline)void __init platform_init (bp_tag_t *first) { -s6_setup_gpio (0 ); +s6_setup_gpio (1 <<GPIO_SPI_CS0 | +1 <<GPIO_SPI_CS1 | +1 <<GPIO_SPI_CS3 | +1 <<GPIO_SPI_CS4 );gpio_request (GPIO_LED1_NGREEN ,"led1_green" );gpio_request (GPIO_LED1_RED ,"led1_red" );gpio_direction_output (GPIO_LED1_NGREEN ,1 );
Signature · 1 line
1.6.2.107.ge47ee
PATCH 3/6 xtensa: add spi mmc host to s6105 platform
In reply to Daniel Glöckner--- arch/xtensa/platforms/s6105/device.c | 55 ++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-)
arch/xtensa/platforms/s6105/device.c +55 -0
@@ -11,9 +11,11 @@#include <linux/init.h> #include <linux/irq.h> #include <linux/phy.h> +#include <linux/mmc/host.h> #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_8250.h> +#include <linux/spi/mmc_spi.h> #include <linux/spi/spi.h> #include <linux/spi/spi_s6000.h>
@@ -209,7 +211,60 @@ static __devinitdata struct s6_spi_platform_data s6_spi_pdata = {#define S6_SPI_CS_EXPANSION 3#define S6_SPI_CS_MMC_SLOT 4 +static int __devinit s6_init_mmc_host (struct device *spi, +irqreturn_t (*handler)(int ,void *), +void *mmc) +{ +int ret; + ret =gpio_request (GPIO_SD_WP ,"mmc_wp" ); +if (ret <0 ) +return ret; + ret =gpio_request (GPIO_SD_IRQ ,"mmc_irq" ); +if (ret <0 ) +return ret; + ret =gpio_direction_input (GPIO_SD_WP ); +if (ret <0 ) +return ret; + ret =gpio_direction_input (GPIO_SD_IRQ ); +if (ret <0 ) +return ret; + ret =gpio_to_irq (GPIO_SD_IRQ ); +if (ret <0 ) +return ret; + ret =request_irq (ret, handler, +IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING , +"mmc_slot" , mmc); +return ret; +} + +static void __devexit s6_exit_mmc_host(struct device *spi, void *mmc) +{ +free_irq (gpio_to_irq (GPIO_SD_IRQ ), mmc); +gpio_free (GPIO_SD_IRQ ); +gpio_free (GPIO_SD_WP ); +} + +static int s6_mmc_get_ro (struct device *spi) +{ +return gpio_get_value (GPIO_SD_WP ); +} + +static struct mmc_spi_platform_data s6_spi_mmc_pdata = { + .caps =0 , + .ocr_mask =MMC_VDD_32_33 , + .init = s6_init_mmc_host, + .exit =__devexit_p (s6_exit_mmc_host), + .get_ro = s6_mmc_get_ro, +}; +static struct spi_board_info __initdata s6_spi_devices[] = { + { + .modalias ="mmc_spi" , + .platform_data = &s6_spi_mmc_pdata, + .bus_num =S6_SPI_BUS_NUM , + .chip_select =S6_SPI_CS_MMC_SLOT , + .max_speed_hz =50000000 , + }, };static struct platform_device platform_devices[] = {
Signature · 1 line
1.6.2.107.ge47ee
Re: [patch 3/6] xtensa: add spi mmc host to s6105 platform
Quoted 1 line · Daniel Glöckner
Signed-off-by Daniel Glöckner <[email protected]>
Looks OK to me. FWIW I don't expect to ack arch patches that just use public interfaces...
Quoted 85 lines
--- arch/xtensa/platforms/s6105/device.c | 55 ++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-)arch/xtensa/platforms/s6105/device.c +55
-0@@ -11,9 +11,11 @@#include <linux/init.h> #include <linux/irq.h> #include <linux/phy.h> +#include <linux/mmc/host.h> #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_8250.h> +#include <linux/spi/mmc_spi.h> #include <linux/spi/spi.h> #include <linux/spi/spi_s6000.h> @@ -209,7 +211,60 @@ static __devinitdata struct s6_spi_platform_data s6_spi_pdata = {#define S6_SPI_CS_EXPANSION 3#define S6_SPI_CS_MMC_SLOT 4 +static int __devinit s6_init_mmc_host (struct device *spi, +irqreturn_t (*handler)(int ,void *), +void *mmc) +{ +int ret; + ret =gpio_request (GPIO_SD_WP ,"mmc_wp" ); +if (ret <0 ) +return ret; + ret =gpio_request (GPIO_SD_IRQ ,"mmc_irq" ); +if (ret <0 ) +return ret; + ret =gpio_direction_input (GPIO_SD_WP ); +if (ret <0 ) +return ret; + ret =gpio_direction_input (GPIO_SD_IRQ ); +if (ret <0 ) +return ret; + ret =gpio_to_irq (GPIO_SD_IRQ ); +if (ret <0 ) +return ret; + ret =request_irq (ret, handler, +IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING , +"mmc_slot" , mmc); +return ret; +} + +static void __devexit s6_exit_mmc_host(struct device *spi, void *mmc) +{ +free_irq (gpio_to_irq (GPIO_SD_IRQ ), mmc); +gpio_free (GPIO_SD_IRQ ); +gpio_free (GPIO_SD_WP ); +} + +static int s6_mmc_get_ro (struct device *spi) +{ +return gpio_get_value (GPIO_SD_WP ); +} + +static struct mmc_spi_platform_data s6_spi_mmc_pdata = { + .caps =0 , + .ocr_mask =MMC_VDD_32_33 , + .init = s6_init_mmc_host, + .exit =__devexit_p (s6_exit_mmc_host), + .get_ro = s6_mmc_get_ro, +}; +static struct spi_board_info __initdata s6_spi_devices[] = { + { + .modalias ="mmc_spi" , + .platform_data = &s6_spi_mmc_pdata, + .bus_num =S6_SPI_BUS_NUM , + .chip_select =S6_SPI_CS_MMC_SLOT , + .max_speed_hz =50000000 , + }, };static struct platform_device platform_devices[] = {Signature · 1 line
1.6.2.107.ge47ee
Re: [patch 3/6] xtensa: add spi mmc host to s6105 platform
Quoted 2 lines · David Brownell
Looks OK to me. FWIW I don't expect to ack arch patches that just use public interfaces...
Then what do you think of patch 1/6 aka "spi: s6000 spi host driver"?
Daniel
Signature · 6 lines
Dipl.-Math. Daniel Glöckner, emlix GmbH, http://www.emlix.com Fon +49 551 30664-0, Fax -11, Bahnhofsallee 1b, 37081 Göttingen, Germany Geschäftsführung: Dr. Uwe Kracke, Dr. Cord Seele, Ust-IdNr.: DE 205 198 055 Sitz der Gesellschaft: Göttingen, Amtsgericht Göttingen HR B 3160 emlix - your embedded linux partner
PATCH 4/6 xtensa: add m25p80 to s6105 platform
In reply to Daniel GlöcknerThe spi_board_info is enclosed in #ifdef CONFIG_MTD_M25P80 to not interfere with the mmc_spi driver if not used. When mmc_spi is fixed to work on a shared bus, this #ifdef can be removed.
The stage2 partition contains the kernels for all processors in the device. In our case a Linux kernel for the SCP core and maybe a non-Linux kernel for the AUX core. The size of the stage2 partition is not hardcoded in the bootloader. It depends on the first few bytes of that partition. Remaining space up to the boot config can be used for other purposes (f.ex. a filesystem).
The boot configuration is expected at address 0xfff800. The flash chip ignores the upper two address bits. Rounding down to sectors then yields an offset of 0x3f0000 for that partition.
--- arch/xtensa/platforms/s6105/device.c | 47 ++++++++++++++++++++++++++++++++++ 1 files changed, 47 insertions(+), 0 deletions(-)
arch/xtensa/platforms/s6105/device.c +47 -0
@@ -12,9 +12,12 @@#include <linux/irq.h> #include <linux/phy.h> #include <linux/mmc/host.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_8250.h> +#include <linux/spi/flash.h> #include <linux/spi/mmc_spi.h> #include <linux/spi/spi.h> #include <linux/spi/spi_s6000.h>
@@ -211,6 +214,36 @@ static __devinitdata struct s6_spi_platform_data s6_spi_pdata = {#define S6_SPI_CS_EXPANSION 3#define S6_SPI_CS_MMC_SLOT 4 +static struct mtd_partition s6_spi_flash_partitions[] = { + { + .name ="bootloader" , + .size =0x10000 , + .offset =0 , + }, + { + .name ="stage2" , + .size =0x360000 , + .offset =0x10000 , + }, + { + .name ="filesystem" , + .size =0x90000 , + .offset =0x370000 , + }, + {/* actually 0x800 bytes at 0xfff800 */ + .name ="bootconfig" , + .size =0x10000 , + .offset =0x3f0000 , + } +}; + +static struct flash_platform_data s6_spi_flash_pdata = { + .name ="m25p80" , + .parts = s6_spi_flash_partitions, + .nr_parts =ARRAY_SIZE (s6_spi_flash_partitions), + .type ="m25p32" , +}; +static int __devinit s6_init_mmc_host (struct device *spi,irqreturn_t (*handler)(int ,void *),void *mmc)
@@ -258,6 +291,20 @@ static struct mmc_spi_platform_data s6_spi_mmc_pdata = { };static struct spi_board_info __initdata s6_spi_devices[] = { +#ifdef CONFIG_MTD_M25P80 + { + .modalias ="m25p80" , + .platform_data = &s6_spi_flash_pdata, + .bus_num =S6_SPI_BUS_NUM , + .chip_select =S6_SPI_CS_BOOT_FLASH , +#ifdef CONFIG_M25PXX_USE_FAST_READ + .max_speed_hz =50000000 , +#else + .max_speed_hz =33000000 , +#endif + .mode =SPI_MODE_3 + }, +#endif { .modalias ="mmc_spi" , .platform_data = &s6_spi_mmc_pdata,
Signature · 1 line
1.6.2.107.ge47ee
PATCH 5/6 xtensa: enable s6000 spi host in s6105_defconfig
In reply to Daniel Glöckner--- arch/xtensa/configs/s6105_defconfig | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)
arch/xtensa/configs/s6105_defconfig +19 -1
@@ -260,6 +260,7 @@ CONFIG_MISC_DEVICES=y # EEPROM support # CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y
@@ -409,7 +410,22 @@ CONFIG_I2C_S6000=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_S6000=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set
@@ -433,6 +449,8 @@ CONFIG_GPIOLIB=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set
Signature · 1 line
1.6.2.107.ge47ee
Re: [patch 5/6] xtensa: enable s6000 spi host in s6105_defconfig
"
arch/xtensa/configs/s6105_defconfig
Quoted 6 lines · Daniel Glöckner
--- arch/xtensa/configs/s6105_defconfig | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)arch/xtensa/configs/s6105_defconfig +0
-0
Signature · 6 lines
Dipl.-Math. Daniel Glöckner, emlix GmbH, http://www.emlix.com Fon +49 551 30664-0, Fax -11, Bahnhofsallee 1b, 37081 Göttingen, Germany Geschäftsführung: Dr. Uwe Kracke, Dr. Cord Seele, Ust-IdNr.: DE 205 198 055 Sitz der Gesellschaft: Göttingen, Amtsgericht Göttingen HR B 3160 emlix - your embedded linux partner
PATCH 6/6 xtensa: enable spi mmc host in s6105_defconfig
In reply to Daniel Glöckner--- arch/xtensa/configs/s6105_defconfig | 22 +++++++++++++++++++--- 1 files changed, 19 insertions(+), 3 deletions(-)
arch/xtensa/configs/s6105_defconfig +19 -3
@@ -509,7 +509,23 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=y # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set
@@ -646,9 +662,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=y # CONFIG_CRC32 is not set -# CONFIG_CRC7 is not set +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y
Signature · 1 line
1.6.2.107.ge47ee