diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/sh-msiof.txt | 19 | ||||
-rw-r--r-- | Documentation/spi/ep93xx_spi | 105 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/edb93xx.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/simone.c | 63 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/vision_ep9307.c | 88 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/spi/spi-armada-3700.c | 25 | ||||
-rw-r--r-- | drivers/spi/spi-ath79.c | 23 | ||||
-rw-r--r-- | drivers/spi/spi-axi-spi-engine.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-bcm-qspi.c | 194 | ||||
-rw-r--r-- | drivers/spi/spi-bcm53xx.c | 18 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mid.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 9 | ||||
-rw-r--r-- | drivers/spi/spi-dw.h | 1 | ||||
-rw-r--r-- | drivers/spi/spi-ep93xx.c | 139 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lpspi.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-spi.c | 17 | ||||
-rw-r--r-- | drivers/spi/spi-mt65xx.c | 37 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-rspi.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi.c | 18 | ||||
-rw-r--r-- | include/linux/platform_data/spi-ep93xx.h | 17 |
25 files changed, 332 insertions, 511 deletions
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index da6614c..dc97506 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -1,17 +1,23 @@ Renesas MSIOF spi controller Required properties: -- compatible : "renesas,msiof-<soctype>" for SoCs, - "renesas,sh-msiof" for SuperH, or - "renesas,sh-mobile-msiof" for SH Mobile series. - Examples with soctypes are: - "renesas,msiof-r8a7790" (R-Car H2) +- compatible : "renesas,msiof-r8a7790" (R-Car H2) "renesas,msiof-r8a7791" (R-Car M2-W) "renesas,msiof-r8a7792" (R-Car V2H) "renesas,msiof-r8a7793" (R-Car M2-N) "renesas,msiof-r8a7794" (R-Car E2) "renesas,msiof-r8a7796" (R-Car M3-W) "renesas,msiof-sh73a0" (SH-Mobile AG5) + "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device) + "renesas,rcar-gen2-msiof" (generic R-Car Gen2 compatible device) + "renesas,rcar-gen3-msiof" (generic R-Car Gen3 compatible device) + "renesas,sh-msiof" (deprecated) + + When compatible with the generic version, nodes + must list the SoC-specific version corresponding + to the platform first followed by the generic + version. + - reg : A list of offsets and lengths of the register sets for the device. If only one register set is present, it is to be used @@ -61,7 +67,8 @@ Documentation/devicetree/bindings/pinctrl/renesas,*. Example: msiof0: spi@e6e20000 { - compatible = "renesas,msiof-r8a7791"; + compatible = "renesas,msiof-r8a7791", + "renesas,rcar-gen2-msiof"; reg = <0 0xe6e20000 0 0x0064>; interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi deleted file mode 100644 index 832ddce..0000000 --- a/Documentation/spi/ep93xx_spi +++ /dev/null @@ -1,105 +0,0 @@ -Cirrus EP93xx SPI controller driver HOWTO -========================================= - -ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip -selects are implemented with GPIO lines. - -NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will -not work correctly (it cannot be controlled by software). Use GPIO lines -instead. - -Sample configuration -==================== - -Typically driver configuration is done in platform board files (the files under -arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through -this driver on TS-7260 board. You can adapt the code to suit your needs. - -This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1 -header on the board). - -You need to select CONFIG_MMC_SPI to use mmc_spi driver. - -arch/arm/mach-ep93xx/ts72xx.c: - -... -#include <linux/gpio.h> -#include <linux/spi/spi.h> - -#include <linux/platform_data/spi-ep93xx.h> - -/* this is our GPIO line used for chip select */ -#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9 - -static int ts72xx_mmc_spi_setup(struct spi_device *spi) -{ - int err; - - err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias); - if (err) - return err; - - gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1); - - return 0; -} - -static void ts72xx_mmc_spi_cleanup(struct spi_device *spi) -{ - gpio_set_value(MMC_CHIP_SELECT_GPIO, 1); - gpio_direction_input(MMC_CHIP_SELECT_GPIO); - gpio_free(MMC_CHIP_SELECT_GPIO); -} - -static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(MMC_CHIP_SELECT_GPIO, value); -} - -static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = { - .setup = ts72xx_mmc_spi_setup, - .cleanup = ts72xx_mmc_spi_cleanup, - .cs_control = ts72xx_mmc_spi_cs_control, -}; - -static struct spi_board_info ts72xx_spi_devices[] __initdata = { - { - .modalias = "mmc_spi", - .controller_data = &ts72xx_mmc_spi_ops, - /* - * We use 10 MHz even though the maximum is 7.4 MHz. The driver - * will limit it automatically to max. frequency. - */ - .max_speed_hz = 10 * 1000 * 1000, - .bus_num = 0, - .chip_select = 0, - .mode = SPI_MODE_0, - }, -}; - -static struct ep93xx_spi_info ts72xx_spi_info = { - .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), -}; - -static void __init ts72xx_init_machine(void) -{ - ... - ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, - ARRAY_SIZE(ts72xx_spi_devices)); -} - -The driver can use DMA for the transfers also. In this case ts72xx_spi_info -becomes: - -static struct ep93xx_spi_info ts72xx_spi_info = { - .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), - .use_dma = true; -}; - -Note that CONFIG_EP93XX_DMA should be enabled as well. - -Thanks to -========= -Martin Guy, H. Hartley Sweeten and others who helped me during development of -the driver. Simplemachines.it donated me a Sim.One board which I used testing -the driver on EP9307. diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index ad92d9f..0ac1763 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -27,7 +27,6 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/gpio.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> #include <linux/spi/spi.h> @@ -106,33 +105,10 @@ static struct cs4271_platform_data edb93xx_cs4271_data = { .gpio_nreset = -EINVAL, /* filled in later */ }; -static int edb93xx_cs4271_hw_setup(struct spi_device *spi) -{ - return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, - GPIOF_OUT_INIT_HIGH, spi->modalias); -} - -static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi) -{ - gpio_free(EP93XX_GPIO_LINE_EGPIO6); -} - -static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); -} - -static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = { - .setup = edb93xx_cs4271_hw_setup, - .cleanup = edb93xx_cs4271_hw_cleanup, - .cs_control = edb93xx_cs4271_hw_cs_control, -}; - static struct spi_board_info edb93xx_spi_board_info[] __initdata = { { .modalias = "cs4271", .platform_data = &edb93xx_cs4271_data, - .controller_data = &edb93xx_cs4271_hw, .max_speed_hz = 6000000, .bus_num = 0, .chip_select = 0, @@ -140,8 +116,13 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { }, }; +static int edb93xx_spi_chipselects[] __initdata = { + EP93XX_GPIO_LINE_EGPIO6, +}; + static struct ep93xx_spi_info edb93xx_spi_info __initdata = { - .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info), + .chipselect = edb93xx_spi_chipselects, + .num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects), }; static void __init edb93xx_register_spi(void) diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 7bb540c4..c7a40f2 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -49,56 +49,6 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 /* - * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes - * low between multi-message command blocks. From v1.4, it uses a GPIO instead. - * v1.3 parts will still work, since the signal on SFRMOUT is automatic. - */ -#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 - -/* - * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, - * you can leave these empty and pass NULL as .controller_data. - */ - -static int simone_mmc_spi_setup(struct spi_device *spi) -{ - unsigned int gpio = MMC_CHIP_SELECT_GPIO; - int err; - - err = gpio_request(gpio, spi->modalias); - if (err) - return err; - - err = gpio_direction_output(gpio, 1); - if (err) { - gpio_free(gpio); - return err; - } - - return 0; -} - -static void simone_mmc_spi_cleanup(struct spi_device *spi) -{ - unsigned int gpio = MMC_CHIP_SELECT_GPIO; - - gpio_set_value(gpio, 1); - gpio_direction_input(gpio); - gpio_free(gpio); -} - -static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(MMC_CHIP_SELECT_GPIO, value); -} - -static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { - .setup = simone_mmc_spi_setup, - .cleanup = simone_mmc_spi_cleanup, - .cs_control = simone_mmc_spi_cs_control, -}; - -/* * MMC card detection GPIO setup. */ @@ -152,7 +102,6 @@ static struct mmc_spi_platform_data simone_mmc_spi_data = { static struct spi_board_info simone_spi_devices[] __initdata = { { .modalias = "mmc_spi", - .controller_data = &simone_mmc_spi_ops, .platform_data = &simone_mmc_spi_data, /* * We use 10 MHz even though the maximum is 3.7 MHz. The driver @@ -165,8 +114,18 @@ static struct spi_board_info simone_spi_devices[] __initdata = { }, }; +/* + * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes + * low between multi-message command blocks. From v1.4, it uses a GPIO instead. + * v1.3 parts will still work, since the signal on SFRMOUT is automatic. + */ +static int simone_spi_chipselects[] __initdata = { + EP93XX_GPIO_LINE_EGPIO1, +}; + static struct ep93xx_spi_info simone_spi_info __initdata = { - .num_chipselect = ARRAY_SIZE(simone_spi_devices), + .chipselect = simone_spi_chipselects, + .num_chipselect = ARRAY_SIZE(simone_spi_chipselects), .use_dma = 1, }; diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 5cced59..1daf944 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -175,33 +175,9 @@ static struct cs4271_platform_data vision_cs4271_data = { .gpio_nreset = EP93XX_GPIO_LINE_H(2), }; -static int vision_cs4271_hw_setup(struct spi_device *spi) -{ - return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, - GPIOF_OUT_INIT_HIGH, spi->modalias); -} - -static void vision_cs4271_hw_cleanup(struct spi_device *spi) -{ - gpio_free(EP93XX_GPIO_LINE_EGPIO6); -} - -static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); -} - -static struct ep93xx_spi_chip_ops vision_cs4271_hw = { - .setup = vision_cs4271_hw_setup, - .cleanup = vision_cs4271_hw_cleanup, - .cs_control = vision_cs4271_hw_cs_control, -}; - /************************************************************************* * SPI Flash *************************************************************************/ -#define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7 - static struct mtd_partition vision_spi_flash_partitions[] = { { .name = "SPI bootstrap", @@ -224,68 +200,20 @@ static struct flash_platform_data vision_spi_flash_data = { .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), }; -static int vision_spi_flash_hw_setup(struct spi_device *spi) -{ - return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH, - spi->modalias); -} - -static void vision_spi_flash_hw_cleanup(struct spi_device *spi) -{ - gpio_free(VISION_SPI_FLASH_CS); -} - -static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(VISION_SPI_FLASH_CS, value); -} - -static struct ep93xx_spi_chip_ops vision_spi_flash_hw = { - .setup = vision_spi_flash_hw_setup, - .cleanup = vision_spi_flash_hw_cleanup, - .cs_control = vision_spi_flash_hw_cs_control, -}; - /************************************************************************* * SPI SD/MMC host *************************************************************************/ -#define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2) -#define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0) -#define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15 - static struct mmc_spi_platform_data vision_spi_mmc_data = { .detect_delay = 100, .powerup_msecs = 100, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, - .cd_gpio = VISION_SPI_MMC_CD, + .cd_gpio = EP93XX_GPIO_LINE_EGPIO15, .cd_debounce = 1, - .ro_gpio = VISION_SPI_MMC_WP, + .ro_gpio = EP93XX_GPIO_LINE_F(0), .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, }; -static int vision_spi_mmc_hw_setup(struct spi_device *spi) -{ - return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH, - spi->modalias); -} - -static void vision_spi_mmc_hw_cleanup(struct spi_device *spi) -{ - gpio_free(VISION_SPI_MMC_CS); -} - -static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value) -{ - gpio_set_value(VISION_SPI_MMC_CS, value); -} - -static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = { - .setup = vision_spi_mmc_hw_setup, - .cleanup = vision_spi_mmc_hw_cleanup, - .cs_control = vision_spi_mmc_hw_cs_control, -}; - /************************************************************************* * SPI Bus *************************************************************************/ @@ -293,7 +221,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { { .modalias = "cs4271", .platform_data = &vision_cs4271_data, - .controller_data = &vision_cs4271_hw, .max_speed_hz = 6000000, .bus_num = 0, .chip_select = 0, @@ -301,7 +228,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { }, { .modalias = "sst25l", .platform_data = &vision_spi_flash_data, - .controller_data = &vision_spi_flash_hw, .max_speed_hz = 20000000, .bus_num = 0, .chip_select = 1, @@ -309,7 +235,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { }, { .modalias = "mmc_spi", .platform_data = &vision_spi_mmc_data, - .controller_data = &vision_spi_mmc_hw, .max_speed_hz = 20000000, .bus_num = 0, .chip_select = 2, @@ -317,8 +242,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { }, }; +static int vision_spi_chipselects[] __initdata = { + EP93XX_GPIO_LINE_EGPIO6, + EP93XX_GPIO_LINE_EGPIO7, + EP93XX_GPIO_LINE_G(2), +}; + static struct ep93xx_spi_info vision_spi_master __initdata = { - .num_chipselect = ARRAY_SIZE(vision_spi_board_info), + .chipselect = vision_spi_chipselects, + .num_chipselect = ARRAY_SIZE(vision_spi_chipselects), .use_dma = 1, }; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e3c2566..7415022 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -162,7 +162,8 @@ config SPI_BCM63XX_HSSPI config SPI_BCM_QSPI tristate "Broadcom BSPI and MSPI controller support" - depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || COMPILE_TEST + depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || \ + BMIPS_GENERIC || COMPILE_TEST default ARCH_BCM_IPROC help Enables support for the Broadcom SPI flash and MSPI controller. @@ -378,6 +379,7 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" select REGMAP_MMIO + depends on HAS_DMA depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST help This enables support for the Freescale DSPI controller in master diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index e89da0a..6c7d7a4 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -170,12 +170,12 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1); switch (pin_mode) { - case 1: + case SPI_NBITS_SINGLE: break; - case 2: + case SPI_NBITS_DUAL: val |= A3700_SPI_DATA_PIN0; break; - case 4: + case SPI_NBITS_QUAD: val |= A3700_SPI_DATA_PIN1; break; default: @@ -340,8 +340,7 @@ static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id) spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause); /* Wake up the transfer */ - if (a3700_spi->wait_mask & cause) - complete(&a3700_spi->done); + complete(&a3700_spi->done); return IRQ_HANDLED; } @@ -421,7 +420,7 @@ static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi, } static void a3700_spi_transfer_setup(struct spi_device *spi, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { struct a3700_spi *a3700_spi; unsigned int byte_len; @@ -562,6 +561,7 @@ static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi) val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG); if (a3700_spi->buf_len >= 4) { u32 data = le32_to_cpu(val); + memcpy(a3700_spi->rx_buf, &data, 4); a3700_spi->buf_len -= 4; @@ -800,7 +800,7 @@ static int a3700_spi_probe(struct platform_device *pdev) struct spi_master *master; struct a3700_spi *spi; u32 num_cs = 0; - int ret = 0; + int irq, ret = 0; master = spi_alloc_master(dev, sizeof(*spi)); if (!master) { @@ -825,7 +825,7 @@ static int a3700_spi_probe(struct platform_device *pdev) master->unprepare_message = a3700_spi_unprepare_message; master->set_cs = a3700_spi_set_cs; master->flags = SPI_MASTER_HALF_DUPLEX; - master->mode_bits |= (SPI_RX_DUAL | SPI_RX_DUAL | + master->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD); platform_set_drvdata(pdev, master); @@ -846,12 +846,13 @@ static int a3700_spi_probe(struct platform_device *pdev) goto error; } - spi->irq = platform_get_irq(pdev, 0); - if (spi->irq < 0) { - dev_err(dev, "could not get irq: %d\n", spi->irq); + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "could not get irq: %d\n", irq); ret = -ENXIO; goto error; } + spi->irq = irq; init_completion(&spi->done); @@ -900,7 +901,6 @@ static int a3700_spi_remove(struct platform_device *pdev) struct a3700_spi *spi = spi_master_get_devdata(master); clk_unprepare(spi->clk); - spi_master_put(master); return 0; } @@ -908,7 +908,6 @@ static int a3700_spi_remove(struct platform_device *pdev) static struct platform_driver a3700_spi_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(a3700_spi_dt_ids), }, .probe = a3700_spi_probe, diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index f369174..b89cee1 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -78,14 +78,16 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active) ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); } - if (spi->chip_select) { + if (gpio_is_valid(spi->cs_gpio)) { /* SPI is normally active-low */ - gpio_set_value(spi->cs_gpio, cs_high); + gpio_set_value_cansleep(spi->cs_gpio, cs_high); } else { + u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select); + if (cs_high) - sp->ioc_base |= AR71XX_SPI_IOC_CS0; + sp->ioc_base |= cs_bit; else - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; + sp->ioc_base &= ~cs_bit; ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); } @@ -118,11 +120,8 @@ static int ath79_spi_setup_cs(struct spi_device *spi) struct ath79_spi *sp = ath79_spidev_to_sp(spi); int status; - if (spi->chip_select && !gpio_is_valid(spi->cs_gpio)) - return -EINVAL; - status = 0; - if (spi->chip_select) { + if (gpio_is_valid(spi->cs_gpio)) { unsigned long flags; flags = GPIOF_DIR_OUT; @@ -134,10 +133,12 @@ static int ath79_spi_setup_cs(struct spi_device *spi) status = gpio_request_one(spi->cs_gpio, flags, dev_name(&spi->dev)); } else { + u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select); + if (spi->mode & SPI_CS_HIGH) - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; + sp->ioc_base &= ~cs_bit; else - sp->ioc_base |= AR71XX_SPI_IOC_CS0; + sp->ioc_base |= cs_bit; ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); } @@ -147,7 +148,7 @@ static int ath79_spi_setup_cs(struct spi_device *spi) static void ath79_spi_cleanup_cs(struct spi_device *spi) { - if (spi->chip_select) { + if (gpio_is_valid(spi->cs_gpio)) { gpio_free(spi->cs_gpio); } } diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 319225d..6ab4c77 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -494,7 +494,8 @@ static int spi_engine_probe(struct platform_device *pdev) SPI_ENGINE_VERSION_MAJOR(version), SPI_ENGINE_VERSION_MINOR(version), SPI_ENGINE_VERSION_PATCH(version)); - return -ENODEV; + ret = -ENODEV; + goto err_put_master; } spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 14f9dea..958fb4e 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -89,7 +89,7 @@ #define BSPI_BPP_MODE_SELECT_MASK BIT(8) #define BSPI_BPP_ADDR_SELECT_MASK BIT(16) -#define BSPI_READ_LENGTH 256 +#define BSPI_READ_LENGTH 512 /* MSPI register offsets */ #define MSPI_SPCR0_LSB 0x000 @@ -192,9 +192,11 @@ struct bcm_qspi_dev_id { void *dev; }; + struct qspi_trans { struct spi_transfer *trans; int byte; + bool mspi_last_trans; }; struct bcm_qspi { @@ -616,6 +618,16 @@ static int bcm_qspi_setup(struct spi_device *spi) return 0; } +static bool bcm_qspi_mspi_transfer_is_last(struct bcm_qspi *qspi, + struct qspi_trans *qt) +{ + if (qt->mspi_last_trans && + spi_transfer_is_last(qspi->master, qt->trans)) + return true; + else + return false; +} + static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, struct qspi_trans *qt, int flags) { @@ -629,7 +641,6 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, if (qt->byte >= qt->trans->len) { /* we're at the end of the spi_transfer */ - /* in TX mode, need to pause for a delay or CS change */ if (qt->trans->delay_usecs && (flags & TRANS_STATUS_BREAK_DELAY)) @@ -641,7 +652,7 @@ static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, goto done; dev_dbg(&qspi->pdev->dev, "advance msg exit\n"); - if (spi_transfer_is_last(qspi->master, qt->trans)) + if (bcm_qspi_mspi_transfer_is_last(qspi, qt)) ret = TRANS_STATUS_BREAK_EOM; else ret = TRANS_STATUS_BREAK_NO_BYTES; @@ -813,7 +824,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, struct spi_flash_read_message *msg) { struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); - u32 addr = 0, len, len_words; + u32 addr = 0, len, rdlen, len_words; int ret = 0; unsigned long timeo = msecs_to_jiffies(100); struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; @@ -826,7 +837,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); /* - * when using flex mode mode we need to send + * when using flex mode we need to send * the upper address byte to bspi */ if (bcm_qspi_bspi_ver_three(qspi) == false) { @@ -840,48 +851,127 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, else addr = msg->from & 0x00ffffff; - /* set BSPI RAF buffer max read length */ - len = msg->len; - if (len > BSPI_READ_LENGTH) - len = BSPI_READ_LENGTH; - if (bcm_qspi_bspi_ver_three(qspi) == true) addr = (addr + 0xc00000) & 0xffffff; - reinit_completion(&qspi->bspi_done); - bcm_qspi_enable_bspi(qspi); - len_words = (len + 3) >> 2; - qspi->bspi_rf_msg = msg; - qspi->bspi_rf_msg_status = 0; + /* + * read into the entire buffer by breaking the reads + * into RAF buffer read lengths + */ + len = msg->len; qspi->bspi_rf_msg_idx = 0; - qspi->bspi_rf_msg_len = len; - dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len); - bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); - bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); - bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); + do { + if (len > BSPI_READ_LENGTH) + rdlen = BSPI_READ_LENGTH; + else + rdlen = len; + + reinit_completion(&qspi->bspi_done); + bcm_qspi_enable_bspi(qspi); + len_words = (rdlen + 3) >> 2; + qspi->bspi_rf_msg = msg; + qspi->bspi_rf_msg_status = 0; + qspi->bspi_rf_msg_len = rdlen; + dev_dbg(&qspi->pdev->dev, + "bspi xfr addr 0x%x len 0x%x", addr, rdlen); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); + if (qspi->soc_intc) { + /* + * clear soc MSPI and BSPI interrupts and enable + * BSPI interrupts. + */ + soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE); + soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true); + } - if (qspi->soc_intc) { - /* - * clear soc MSPI and BSPI interrupts and enable - * BSPI interrupts. - */ - soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE); - soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true); + /* Must flush previous writes before starting BSPI operation */ + mb(); + bcm_qspi_bspi_lr_start(qspi); + if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); + ret = -ETIMEDOUT; + break; + } + + /* set msg return length */ + msg->retlen += rdlen; + addr += rdlen; + len -= rdlen; + } while (len); + + return ret; +} + +static int bcm_qspi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *trans) +{ + struct bcm_qspi *qspi = spi_master_get_devdata(master); + int slots; + unsigned long timeo = msecs_to_jiffies(100); + + bcm_qspi_chip_select(qspi, spi->chip_select); + qspi->trans_pos.trans = trans; + qspi->trans_pos.byte = 0; + + while (qspi->trans_pos.byte < trans->len) { + reinit_completion(&qspi->mspi_done); + + slots = write_to_hw(qspi, spi); + if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); + return -ETIMEDOUT; + } + + read_from_hw(qspi, slots); } - /* Must flush previous writes before starting BSPI operation */ - mb(); + return 0; +} - bcm_qspi_bspi_lr_start(qspi); - if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { - dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); - ret = -ETIMEDOUT; - } else { - /* set the return length for the caller */ - msg->retlen = len; +static int bcm_qspi_mspi_flash_read(struct spi_device *spi, + struct spi_flash_read_message *msg) +{ + struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); + struct spi_transfer t[2]; + u8 cmd[6]; + int ret; + + memset(cmd, 0, sizeof(cmd)); + memset(t, 0, sizeof(t)); + + /* tx */ + /* opcode is in cmd[0] */ + cmd[0] = msg->read_opcode; + cmd[1] = msg->from >> (msg->addr_width * 8 - 8); + cmd[2] = msg->from >> (msg->addr_width * 8 - 16); + cmd[3] = msg->from >> (msg->addr_width * 8 - 24); + cmd[4] = msg->from >> (msg->addr_width * 8 - 32); + t[0].tx_buf = cmd; + t[0].len = msg->addr_width + msg->dummy_bytes + 1; + t[0].bits_per_word = spi->bits_per_word; + t[0].tx_nbits = msg->opcode_nbits; + /* lets mspi know that this is not last transfer */ + qspi->trans_pos.mspi_last_trans = false; + ret = bcm_qspi_transfer_one(spi->master, spi, &t[0]); + + /* rx */ + qspi->trans_pos.mspi_last_trans = true; + if (!ret) { + /* rx */ + t[1].rx_buf = msg->buf; + t[1].len = msg->len; + t[1].rx_nbits = msg->data_nbits; + t[1].bits_per_word = spi->bits_per_word; + ret = bcm_qspi_transfer_one(spi->master, spi, &t[1]); } + if (!ret) + msg->retlen = msg->len; + return ret; } @@ -918,8 +1008,7 @@ static int bcm_qspi_flash_read(struct spi_device *spi, mspi_read = true; if (mspi_read) - /* this will make the m25p80 read to fallback to mspi read */ - return -EAGAIN; + return bcm_qspi_mspi_flash_read(spi, msg); io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; addrlen = msg->addr_width; @@ -931,33 +1020,6 @@ static int bcm_qspi_flash_read(struct spi_device *spi, return ret; } -static int bcm_qspi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *trans) -{ - struct bcm_qspi *qspi = spi_master_get_devdata(master); - int slots; - unsigned long timeo = msecs_to_jiffies(100); - - bcm_qspi_chip_select(qspi, spi->chip_select); - qspi->trans_pos.trans = trans; - qspi->trans_pos.byte = 0; - - while (qspi->trans_pos.byte < trans->len) { - reinit_completion(&qspi->mspi_done); - - slots = write_to_hw(qspi, spi); - if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { - dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); - return -ETIMEDOUT; - } - - read_from_hw(qspi, slots); - } - - return 0; -} - static void bcm_qspi_cleanup(struct spi_device *spi) { struct bcm_qspi_parms *xp = spi_get_ctldata(spi); @@ -1187,6 +1249,7 @@ int bcm_qspi_probe(struct platform_device *pdev, qspi->pdev = pdev; qspi->trans_pos.trans = NULL; qspi->trans_pos.byte = 0; + qspi->trans_pos.mspi_last_trans = true; qspi->master = master; master->bus_num = -1; @@ -1345,7 +1408,6 @@ int bcm_qspi_remove(struct platform_device *pdev) { struct bcm_qspi *qspi = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); bcm_qspi_hw_uninit(qspi); clk_disable_unprepare(qspi->clk); kfree(qspi->dev_ids); diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index afb5169..6e409ea 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c @@ -1,3 +1,11 @@ +/* + * Copyright (C) 2014-2016 Rafał Miłecki <rafal@milecki.pl> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/kernel.h> @@ -275,10 +283,6 @@ static int bcm53xxspi_flash_read(struct spi_device *spi, * BCMA **************************************************/ -static struct spi_board_info bcm53xx_info = { - .modalias = "bcm53xxspiflash", -}; - static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS), {}, @@ -311,6 +315,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) b53spi->bspi = true; bcm53xxspi_disable_bspi(b53spi); + master->dev.of_node = dev->of_node; master->transfer_one = bcm53xxspi_transfer_one; if (b53spi->mmio_base) master->spi_flash_read = bcm53xxspi_flash_read; @@ -324,9 +329,6 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) return err; } - /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ - spi_new_device(master, &bcm53xx_info); - return 0; } @@ -361,4 +363,4 @@ module_exit(bcm53xxspi_module_exit); MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver"); MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index d36c11b..02fb967 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -646,7 +646,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) buf = t->rx_buf; t->rx_dma = dma_map_single(&spi->dev, buf, t->len, DMA_FROM_DEVICE); - if (!t->rx_dma) { + if (dma_mapping_error(&spi->dev, !t->rx_dma)) { ret = -EFAULT; goto err_rx_map; } @@ -660,7 +660,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) buf = (void *)t->tx_buf; t->tx_dma = dma_map_single(&spi->dev, buf, t->len, DMA_TO_DEVICE); - if (!t->tx_dma) { + if (dma_mapping_error(&spi->dev, t->tx_dma)) { ret = -EFAULT; goto err_tx_map; } diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index e31971f9..837cb8d 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -274,11 +274,11 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) static void mid_spi_dma_stop(struct dw_spi *dws) { if (test_bit(TX_BUSY, &dws->dma_chan_busy)) { - dmaengine_terminate_all(dws->txchan); + dmaengine_terminate_sync(dws->txchan); clear_bit(TX_BUSY, &dws->dma_chan_busy); } if (test_bit(RX_BUSY, &dws->dma_chan_busy)) { - dmaengine_terminate_all(dws->rxchan); + dmaengine_terminate_sync(dws->rxchan); clear_bit(RX_BUSY, &dws->dma_chan_busy); } } diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index b715a26..b217c22 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -107,7 +107,10 @@ static const struct file_operations dw_spi_regs_ops = { static int dw_spi_debugfs_init(struct dw_spi *dws) { - dws->debugfs = debugfs_create_dir("dw_spi", NULL); + char name[32]; + + snprintf(name, 32, "dw_spi%d", dws->master->bus_num); + dws->debugfs = debugfs_create_dir(name, NULL); if (!dws->debugfs) return -ENOMEM; @@ -483,9 +486,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) dws->type = SSI_MOTO_SPI; dws->dma_inited = 0; dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); - snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); - ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master); + ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), + master); if (ret < 0) { dev_err(dev, "can not get IRQ\n"); goto err_free_master; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index c21ca02..da5eab6 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -101,7 +101,6 @@ struct dw_spi_dma_ops { struct dw_spi { struct spi_master *master; enum dw_ssi_type type; - char name[16]; void __iomem *regs; unsigned long paddr; diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 17a6387..b5d7660 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -28,6 +28,7 @@ #include <linux/platform_device.h> #include <linux/sched.h> #include <linux/scatterlist.h> +#include <linux/gpio.h> #include <linux/spi/spi.h> #include <linux/platform_data/dma-ep93xx.h> @@ -107,16 +108,6 @@ struct ep93xx_spi { void *zeropage; }; -/** - * struct ep93xx_spi_chip - SPI device hardware settings - * @spi: back pointer to the SPI device - * @ops: private chip operations - */ -struct ep93xx_spi_chip { - const struct spi_device *spi; - struct ep93xx_spi_chip_ops *ops; -}; - /* converts bits per word to CR0.DSS value */ #define bits_per_word_to_dss(bpw) ((bpw) - 1) @@ -229,104 +220,36 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, return -EINVAL; } -static void ep93xx_spi_cs_control(struct spi_device *spi, bool control) -{ - struct ep93xx_spi_chip *chip = spi_get_ctldata(spi); - int value = (spi->mode & SPI_CS_HIGH) ? control : !control; - - if (chip->ops && chip->ops->cs_control) - chip->ops->cs_control(spi, value); -} - -/** - * ep93xx_spi_setup() - setup an SPI device - * @spi: SPI device to setup - * - * This function sets up SPI device mode, speed etc. Can be called multiple - * times for a single device. Returns %0 in case of success, negative error in - * case of failure. When this function returns success, the device is - * deselected. - */ -static int ep93xx_spi_setup(struct spi_device *spi) +static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable) { - struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); - struct ep93xx_spi_chip *chip; + if (spi->mode & SPI_CS_HIGH) + enable = !enable; - chip = spi_get_ctldata(spi); - if (!chip) { - dev_dbg(&espi->pdev->dev, "initial setup for %s\n", - spi->modalias); - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->spi = spi; - chip->ops = spi->controller_data; - - if (chip->ops && chip->ops->setup) { - int ret = chip->ops->setup(spi); - - if (ret) { - kfree(chip); - return ret; - } - } - - spi_set_ctldata(spi, chip); - } - - ep93xx_spi_cs_control(spi, false); - return 0; + if (gpio_is_valid(spi->cs_gpio)) + gpio_set_value(spi->cs_gpio, !enable); } -/** - * ep93xx_spi_cleanup() - cleans up master controller specific state - * @spi: SPI device to cleanup - * - * This function releases master controller specific state for given @spi - * device. - */ -static void ep93xx_spi_cleanup(struct spi_device *spi) -{ - struct ep93xx_spi_chip *chip; - - chip = spi_get_ctldata(spi); - if (chip) { - if (chip->ops && chip->ops->cleanup) - chip->ops->cleanup(spi); - spi_set_ctldata(spi, NULL); - kfree(chip); - } -} - -/** - * ep93xx_spi_chip_setup() - configures hardware according to given @chip - * @espi: ep93xx SPI controller struct - * @chip: chip specific settings - * @speed_hz: transfer speed - * @bits_per_word: transfer bits_per_word - */ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, - const struct ep93xx_spi_chip *chip, - u32 speed_hz, u8 bits_per_word) + struct spi_device *spi, + struct spi_transfer *xfer) { - u8 dss = bits_per_word_to_dss(bits_per_word); + u8 dss = bits_per_word_to_dss(xfer->bits_per_word); u8 div_cpsr = 0; u8 div_scr = 0; u16 cr0; int err; - err = ep93xx_spi_calc_divisors(espi, speed_hz, &div_cpsr, &div_scr); + err = ep93xx_spi_calc_divisors(espi, xfer->speed_hz, + &div_cpsr, &div_scr); if (err) return err; cr0 = div_scr << SSPCR0_SCR_SHIFT; - cr0 |= (chip->spi->mode & (SPI_CPHA|SPI_CPOL)) << SSPCR0_MODE_SHIFT; + cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT; cr0 |= dss; dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", - chip->spi->mode, div_cpsr, div_scr, dss); + spi->mode, div_cpsr, div_scr, dss); dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); @@ -603,12 +526,11 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, struct spi_message *msg, struct spi_transfer *t) { - struct ep93xx_spi_chip *chip = spi_get_ctldata(msg->spi); int err; msg->state = t; - err = ep93xx_spi_chip_setup(espi, chip, t->speed_hz, t->bits_per_word); + err = ep93xx_spi_chip_setup(espi, msg->spi, t); if (err) { dev_err(&espi->pdev->dev, "failed to setup chip for transfer\n"); @@ -863,8 +785,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev) struct resource *res; int irq; int error; + int i; info = dev_get_platdata(&pdev->dev); + if (!info) { + dev_err(&pdev->dev, "missing platform data\n"); + return -EINVAL; + } irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -882,14 +809,36 @@ static int ep93xx_spi_probe(struct platform_device *pdev) if (!master) return -ENOMEM; - master->setup = ep93xx_spi_setup; master->transfer_one_message = ep93xx_spi_transfer_one_message; - master->cleanup = ep93xx_spi_cleanup; master->bus_num = pdev->id; - master->num_chipselect = info->num_chipselect; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); + master->num_chipselect = info->num_chipselect; + master->cs_gpios = devm_kzalloc(&master->dev, + sizeof(int) * master->num_chipselect, + GFP_KERNEL); + if (!master->cs_gpios) { + error = -ENOMEM; + goto fail_release_master; + } + + for (i = 0; i < master->num_chipselect; i++) { + master->cs_gpios[i] = info->chipselect[i]; + + if (!gpio_is_valid(master->cs_gpios[i])) + continue; + + error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i], + GPIOF_OUT_INIT_HIGH, + "ep93xx-spi"); + if (error) { + dev_err(&pdev->dev, "could not request cs gpio %d\n", + master->cs_gpios[i]); + goto fail_release_master; + } + } + platform_set_drvdata(pdev, master); espi = spi_master_get_devdata(master); diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index 52551f6..cb3c730 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -366,7 +366,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master, struct spi_transfer *xfer; bool is_first_xfer = true; u32 temp; - int ret; + int ret = 0; msg->status = 0; msg->actual_length = 0; @@ -512,9 +512,9 @@ static int fsl_lpspi_remove(struct platform_device *pdev) static struct platform_driver fsl_lpspi_driver = { .driver = { - .name = DRIVER_NAME, - .of_match_table = fsl_lpspi_dt_ids, - }, + .name = DRIVER_NAME, + .of_match_table = fsl_lpspi_dt_ids, + }, .probe = fsl_lpspi_probe, .remove = fsl_lpspi_remove, }; diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 8b290d9..0fc3452 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -267,10 +267,9 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, if ((mpc8xxx_spi->spibrg / hz) > 64) { cs->hw_mode |= SPMODE_DIV16; pm = (mpc8xxx_spi->spibrg - 1) / (hz * 64) + 1; - - WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. " - "Will use %d Hz instead.\n", dev_name(&spi->dev), - hz, mpc8xxx_spi->spibrg / 1024); + WARN_ONCE(pm > 16, + "%s: Requested speed is too low: %d Hz. Will use %d Hz instead.\n", + dev_name(&spi->dev), hz, mpc8xxx_spi->spibrg / 1024); if (pm > 16) pm = 16; } else { @@ -727,12 +726,13 @@ static int of_fsl_spi_get_chipselects(struct device *dev) return 0; } - pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL); + pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios), + GFP_KERNEL); if (!pinfo->gpios) return -ENOMEM; memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios)); - pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags), + pinfo->alow_flags = kcalloc(ngpios, sizeof(*pinfo->alow_flags), GFP_KERNEL); if (!pinfo->alow_flags) { ret = -ENOMEM; @@ -762,8 +762,9 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ret = gpio_direction_output(pinfo->gpios[i], pinfo->alow_flags[i]); if (ret) { - dev_err(dev, "can't set output direction for gpio " - "#%d: %d\n", i, ret); + dev_err(dev, + "can't set output direction for gpio #%d: %d\n", + i, ret); goto err_loop; } } diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 899d7a8..278867a 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -73,7 +73,7 @@ #define MTK_SPI_IDLE 0 #define MTK_SPI_PAUSED 1 -#define MTK_SPI_MAX_FIFO_SIZE 32 +#define MTK_SPI_MAX_FIFO_SIZE 32U #define MTK_SPI_PACKET_SIZE 1024 struct mtk_spi_compatible { @@ -333,7 +333,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, struct mtk_spi *mdata = spi_master_get_devdata(master); mdata->cur_transfer = xfer; - mdata->xfer_len = xfer->len; + mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len); mtk_spi_prepare_transfer(master, xfer); mtk_spi_setup_packet(master); @@ -410,7 +410,10 @@ static bool mtk_spi_can_dma(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { - return xfer->len > MTK_SPI_MAX_FIFO_SIZE; + /* Buffers for DMA transactions must be 4-byte aligned */ + return (xfer->len > MTK_SPI_MAX_FIFO_SIZE && + (unsigned long)xfer->tx_buf % 4 == 0 && + (unsigned long)xfer->rx_buf % 4 == 0); } static int mtk_spi_setup(struct spi_device *spi) @@ -451,7 +454,33 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) ®_val, remainder); } } - spi_finalize_current_transfer(master); + + trans->len -= mdata->xfer_len; + if (!trans->len) { + spi_finalize_current_transfer(master); + return IRQ_HANDLED; + } + + if (trans->tx_buf) + trans->tx_buf += mdata->xfer_len; + if (trans->rx_buf) + trans->rx_buf += mdata->xfer_len; + + mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, trans->len); + mtk_spi_setup_packet(master); + + cnt = trans->len / 4; + iowrite32_rep(mdata->base + SPI_TX_DATA_REG, trans->tx_buf, cnt); + + remainder = trans->len % 4; + if (remainder > 0) { + reg_val = 0; + memcpy(®_val, trans->tx_buf + (cnt * 4), remainder); + writel(reg_val, mdata->base + SPI_TX_DATA_REG); + } + + mtk_spi_enable_transfer(master); + return IRQ_HANDLED; } diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index dd7b5b4..3f3751e 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1458,6 +1458,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { { PCI_VDEVICE(INTEL, 0x1ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x1ac4), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x1ac6), LPSS_BXT_SSP }, + /* GLK */ + { PCI_VDEVICE(INTEL, 0x31c2), LPSS_BXT_SSP }, + { PCI_VDEVICE(INTEL, 0x31c4), LPSS_BXT_SSP }, + { PCI_VDEVICE(INTEL, 0x31c6), LPSS_BXT_SSP }, /* APL */ { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, @@ -1690,6 +1694,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) pxa2xx_spi_write(drv_data, SSCR1, tmp); tmp = SSCR0_SCR(2) | SSCR0_Motorola | SSCR0_DataSize(8); pxa2xx_spi_write(drv_data, SSCR0, tmp); + break; default: tmp = SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT); diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 9daf500..bc3c868 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -808,7 +808,7 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) for (i = 0; i < len; i++) rspi_write_data(rspi, *tx++); } else { - ret = rspi_pio_transfer(rspi, tx, NULL, n); + ret = rspi_pio_transfer(rspi, tx, NULL, len); if (ret < 0) return ret; } @@ -845,10 +845,9 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) for (i = 0; i < len; i++) *rx++ = rspi_read_data(rspi); } else { - ret = rspi_pio_transfer(rspi, NULL, rx, n); + ret = rspi_pio_transfer(rspi, NULL, rx, len); if (ret < 0) return ret; - *rx++ = ret; } n -= len; } diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 3c09e94..186342b 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1003,7 +1003,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev) sci->num_cs = temp; } - sci->no_cs = of_property_read_bool(dev->of_node, "broken-cs"); + sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback"); return sci; } diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 0012ad0..1f00eeb 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -973,14 +973,16 @@ static const struct sh_msiof_chipdata r8a779x_data = { }; static const struct of_device_id sh_msiof_match[] = { - { .compatible = "renesas,sh-msiof", .data = &sh_data }, { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, { .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data }, { .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data }, { .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data }, { .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data }, { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data }, + { .compatible = "renesas,rcar-gen2-msiof", .data = &r8a779x_data }, { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data }, + { .compatible = "renesas,rcar-gen3-msiof", .data = &r8a779x_data }, + { .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */ {}, }; MODULE_DEVICE_TABLE(of, sh_msiof_match); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 656dd3e..e709553 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -621,8 +621,10 @@ void spi_unregister_device(struct spi_device *spi) if (!spi) return; - if (spi->dev.of_node) + if (spi->dev.of_node) { of_node_clear_flag(spi->dev.of_node, OF_POPULATED); + of_node_put(spi->dev.of_node); + } if (ACPI_COMPANION(&spi->dev)) acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); device_unregister(&spi->dev); @@ -672,7 +674,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) if (!n) return -EINVAL; - bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); + bi = kcalloc(n, sizeof(*bi), GFP_KERNEL); if (!bi) return -ENOMEM; @@ -805,12 +807,12 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) if (master->dma_tx) tx_dev = master->dma_tx->device->dev; else - tx_dev = &master->dev; + tx_dev = master->dev.parent; if (master->dma_rx) rx_dev = master->dma_rx->device->dev; else - rx_dev = &master->dev; + rx_dev = master->dev.parent; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!master->can_dma(master, msg->spi, xfer)) @@ -852,12 +854,12 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg) if (master->dma_tx) tx_dev = master->dma_tx->device->dev; else - tx_dev = &master->dev; + tx_dev = master->dev.parent; if (master->dma_rx) rx_dev = master->dma_rx->device->dev; else - rx_dev = &master->dev; + rx_dev = master->dev.parent; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!master->can_dma(master, msg->spi, xfer)) @@ -1603,11 +1605,13 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) if (rc) { dev_err(&master->dev, "spi_device register error %s\n", nc->full_name); - goto err_out; + goto err_of_node_put; } return spi; +err_of_node_put: + of_node_put(nc); err_out: spi_dev_put(spi); return ERR_PTR(rc); diff --git a/include/linux/platform_data/spi-ep93xx.h b/include/linux/platform_data/spi-ep93xx.h index 9bb63ac..171a271 100644 --- a/include/linux/platform_data/spi-ep93xx.h +++ b/include/linux/platform_data/spi-ep93xx.h @@ -5,25 +5,14 @@ struct spi_device; /** * struct ep93xx_spi_info - EP93xx specific SPI descriptor - * @num_chipselect: number of chip selects on this board, must be - * at least one + * @chipselect: array of gpio numbers to use as chip selects + * @num_chipselect: ARRAY_SIZE(chipselect) * @use_dma: use DMA for the transfers */ struct ep93xx_spi_info { + int *chipselect; int num_chipselect; bool use_dma; }; -/** - * struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device - * @setup: setup the chip select mechanism - * @cleanup: cleanup the chip select mechanism - * @cs_control: control the device chip select - */ -struct ep93xx_spi_chip_ops { - int (*setup)(struct spi_device *spi); - void (*cleanup)(struct spi_device *spi); - void (*cs_control)(struct spi_device *spi, int value); -}; - #endif /* __ASM_MACH_EP93XX_SPI_H */ |