]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge remote-tracking branches 'spi/topic/rockchip', 'spi/topic/rspi', 'spi/topic...
authorMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:41:05 +0000 (16:41 +0000)
committerMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:41:05 +0000 (16:41 +0000)
36 files changed:
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/spi-rockchip.txt
Documentation/spi/ep93xx_spi [deleted file]
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-ep93xx/vision_ep9307.c
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/spi-armada-3700.c
drivers/spi/spi-ath79.c
drivers/spi/spi-axi-spi-engine.c
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-bcm53xx.c
drivers/spi/spi-davinci.c
drivers/spi/spi-dw-mid.c
drivers/spi/spi-dw.c
drivers/spi/spi-dw.h
drivers/spi/spi-ep93xx.c
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-imx.c
drivers/spi/spi-lantiq-ssc.c [new file with mode: 0644]
drivers/spi/spi-mpc52xx.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-ppc4xx.c
drivers/spi/spi-pxa2xx-pci.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-rockchip.c
drivers/spi/spi-rspi.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-ti-qspi.c
drivers/spi/spi.c
include/linux/platform_data/spi-ep93xx.h
include/linux/pxa2xx_ssp.h

index da6614c6379604bb209156cea87a4e3b27a7d1b8..dc975064fa273c3600eee7d822c94eb5fea73502 100644 (file)
@@ -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/devicetree/bindings/spi/spi-lantiq-ssc.txt b/Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt
new file mode 100644 (file)
index 0000000..6069b95
--- /dev/null
@@ -0,0 +1,29 @@
+Lantiq Synchronous Serial Controller (SSC) SPI master driver
+
+Required properties:
+- compatible: "lantiq,ase-spi", "lantiq,falcon-spi", "lantiq,xrx100-spi"
+- #address-cells: see spi-bus.txt
+- #size-cells: see spi-bus.txt
+- reg: address and length of the spi master registers
+- interrupts: should contain the "spi_rx", "spi_tx" and "spi_err" interrupt.
+
+
+Optional properties:
+- clocks: spi clock phandle
+- num-cs: see spi-bus.txt, set to 8 if unset
+- base-cs: the number of the first chip select, set to 1 if unset.
+
+Example:
+
+
+spi: spi@E100800 {
+       compatible = "lantiq,xrx200-spi", "lantiq,xrx100-spi";
+       reg = <0xE100800 0x100>;
+       interrupt-parent = <&icu0>;
+       interrupts = <22 23 24>;
+       interrupt-names = "spi_rx", "spi_tx", "spi_err";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       num-cs = <6>;
+       base-cs = <1>;
+};
index d2ca153614f912fcd06cca8e1e65090030eba96e..83da4931d832688f51e19a56aaa03af8482e721a 100644 (file)
@@ -31,6 +31,10 @@ Optional Properties:
 - rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling
                Rx data (may need to be fine tuned for high capacitance lines).
                No delay (0) by default.
+- pinctrl-names: Names for the pin configuration(s); may be "default" or
+               "sleep", where the "sleep" configuration may describe the state
+               the pins should be in during system suspend. See also
+               pinctrl/pinctrl-bindings.txt.
 
 
 Example:
@@ -46,4 +50,7 @@ Example:
                interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
                clock-names = "spiclk", "apb_pclk";
+               pinctrl-0 = <&spi1_pins>;
+               pinctrl-1 = <&spi1_sleep>;
+               pinctrl-names = "default", "sleep";
        };
diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi
deleted file mode 100644 (file)
index 832ddce..0000000
+++ /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.
index ad92d9f7e4df3e09b305bb40520d58c081b27eb4..0ac176386789428be26631ad1c9f75ad343e8951 100644 (file)
@@ -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)
index 7bb540c421ee30314b93eb8c0f5247070b349b19..c7a40f245892885b403621e40bb33b4405111d5d 100644 (file)
@@ -48,56 +48,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,
 };
 
index 5cced5988498f7c7fbe065b42a065e37b8f6b703..1daf9441058c8ded557463daad4f7dcef44381bd 100644 (file)
@@ -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,
 };
 
index ec4aa252d6e8c1c761a47246851ad2645382516e..25ae7f2e44b51717251c068e3a9f85288c614093 100644 (file)
@@ -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.
@@ -263,7 +264,7 @@ config SPI_EP93XX
          mode.
 
 config SPI_FALCON
-       tristate "Falcon SPI controller support"
+       bool "Falcon SPI controller support"
        depends on SOC_FALCON
        help
          The external bus unit (EBU) found on the FALC-ON SoC has SPI
@@ -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
@@ -415,6 +417,14 @@ config SPI_NUC900
        help
          SPI driver for Nuvoton NUC900 series ARM SoCs
 
+config SPI_LANTIQ_SSC
+       tristate "Lantiq SSC SPI controller"
+       depends on LANTIQ || COMPILE_TEST
+       help
+         This driver supports the Lantiq SSC SPI controller in master
+         mode. This controller is found on Intel (former Lantiq) SoCs like
+         the Danube, Falcon, xRX200, xRX300.
+
 config SPI_OC_TINY
        tristate "OpenCores tiny SPI"
        depends on GPIOLIB || COMPILE_TEST
index 7a6b64662c82c71106f3af94a61190ba1f98a218..b375a7a892160b76b5bf62a7f66f86484f300ed1 100644 (file)
@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_FSL_SPI)             += spi-fsl-spi.o
 obj-$(CONFIG_SPI_GPIO)                 += spi-gpio.o
 obj-$(CONFIG_SPI_IMG_SPFI)             += spi-img-spfi.o
 obj-$(CONFIG_SPI_IMX)                  += spi-imx.o
+obj-$(CONFIG_SPI_LANTIQ_SSC)           += spi-lantiq-ssc.o
 obj-$(CONFIG_SPI_JCORE)                        += spi-jcore.o
 obj-$(CONFIG_SPI_LM70_LLP)             += spi-lm70llp.o
 obj-$(CONFIG_SPI_LP8841_RTC)           += spi-lp8841-rtc.o
index e89da0af45d2518ef26670f7bbd50b875692872b..6c7d7a460689917d577973f7bb47a1e408470210 100644 (file)
@@ -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,
index f369174fbd886fbbc09a13af5f9dbce66d498635..b89cee11f41815be61876bb9206e59cb4d6714b1 100644 (file)
@@ -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);
        }
 }
index 319225d7e761b0066a062b017c6e6f2104447859..6ab4c770022882eacc338a31b345c0d80bc1b541 100644 (file)
@@ -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");
index 14f9dea3173fc5fd9298c7188bf836a3a95f383d..958fb4ee972d01914b433e5ce545ea333b319760 100644 (file)
@@ -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);
index afb51699dbb5a6953821189ed03a9bfbfa8d9b7a..6e409eabe1c938224b9907f0fbe3fe86679eeb98 100644 (file)
@@ -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");
index d36c11b73a35ca656ab04e9c5ef0492f96950b32..02fb96797ac8b9ec52f41c8a13f93b290db0fc1c 100644 (file)
@@ -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;
                }
index e31971f91475b1b3d9f1b2011e0b6e4e2ae4697b..837cb8d0bac6c9a1bd9f866192cd96950b13a68b 100644 (file)
@@ -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);
        }
 }
index b715a26a91484fb695088459d9249b367b334fe1..b217c22ff72fe9a2284f59f8c1cd62aca58680aa 100644 (file)
@@ -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;
index c21ca02f8ec5fcb1d6ca74ee15f43028d03044c7..da5eab62df3477dc4ceb66bed98457373bef3fe8 100644 (file)
@@ -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;
index 17a6387e20b5fb0f9cf673cfb4cc8e4322ea9fed..b5d766064b7b59390d50e888ad0832605f47699f 100644 (file)
@@ -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);
index 52551f6d0c7ddf71aaf03ecc18c5caf2f804108b..cb3c73007ca15a79dc4283c8a07d065118cbca24 100644 (file)
@@ -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,
 };
index 8b290d9d7935044640da36688e82fd01e90bf114..0fc3452652aee4fad412d74398ff6dd13f1ceb96 100644 (file)
@@ -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;
                }
        }
index 32ced64a5bb9a012e2edd0d415d8c477ebc0522a..9a7c62f471dc8cb2e62638d2846989da076442ae 100644 (file)
@@ -211,7 +211,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
                         struct spi_transfer *transfer)
 {
        struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
-       unsigned int bpw;
+       unsigned int bpw, i;
 
        if (!master->dma_rx)
                return false;
@@ -228,12 +228,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
        if (bpw != 1 && bpw != 2 && bpw != 4)
                return false;
 
-       if (transfer->len < spi_imx->wml * bpw)
-               return false;
+       for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) {
+               if (!(transfer->len % (i * bpw)))
+                       break;
+       }
 
-       if (transfer->len % (spi_imx->wml * bpw))
+       if (i == 0)
                return false;
 
+       spi_imx->wml = i;
+
        return true;
 }
 
@@ -837,10 +841,6 @@ static int spi_imx_dma_configure(struct spi_master *master,
        struct dma_slave_config rx = {}, tx = {};
        struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
 
-       if (bytes_per_word == spi_imx->bytes_per_word)
-               /* Same as last time */
-               return 0;
-
        switch (bytes_per_word) {
        case 4:
                buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c
new file mode 100644 (file)
index 0000000..8a626f7
--- /dev/null
@@ -0,0 +1,983 @@
+/*
+ * Copyright (C) 2011-2015 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ * Copyright (C) 2016 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+
+#ifdef CONFIG_LANTIQ
+#include <lantiq_soc.h>
+#endif
+
+#define SPI_RX_IRQ_NAME                "spi_rx"
+#define SPI_TX_IRQ_NAME                "spi_tx"
+#define SPI_ERR_IRQ_NAME       "spi_err"
+#define SPI_FRM_IRQ_NAME       "spi_frm"
+
+#define SPI_CLC                        0x00
+#define SPI_PISEL              0x04
+#define SPI_ID                 0x08
+#define SPI_CON                        0x10
+#define SPI_STAT               0x14
+#define SPI_WHBSTATE           0x18
+#define SPI_TB                 0x20
+#define SPI_RB                 0x24
+#define SPI_RXFCON             0x30
+#define SPI_TXFCON             0x34
+#define SPI_FSTAT              0x38
+#define SPI_BRT                        0x40
+#define SPI_BRSTAT             0x44
+#define SPI_SFCON              0x60
+#define SPI_SFSTAT             0x64
+#define SPI_GPOCON             0x70
+#define SPI_GPOSTAT            0x74
+#define SPI_FPGO               0x78
+#define SPI_RXREQ              0x80
+#define SPI_RXCNT              0x84
+#define SPI_DMACON             0xec
+#define SPI_IRNEN              0xf4
+#define SPI_IRNICR             0xf8
+#define SPI_IRNCR              0xfc
+
+#define SPI_CLC_SMC_S          16      /* Clock divider for sleep mode */
+#define SPI_CLC_SMC_M          (0xFF << SPI_CLC_SMC_S)
+#define SPI_CLC_RMC_S          8       /* Clock divider for normal run mode */
+#define SPI_CLC_RMC_M          (0xFF << SPI_CLC_RMC_S)
+#define SPI_CLC_DISS           BIT(1)  /* Disable status bit */
+#define SPI_CLC_DISR           BIT(0)  /* Disable request bit */
+
+#define SPI_ID_TXFS_S          24      /* Implemented TX FIFO size */
+#define SPI_ID_TXFS_M          (0x3F << SPI_ID_TXFS_S)
+#define SPI_ID_RXFS_S          16      /* Implemented RX FIFO size */
+#define SPI_ID_RXFS_M          (0x3F << SPI_ID_RXFS_S)
+#define SPI_ID_MOD_S           8       /* Module ID */
+#define SPI_ID_MOD_M           (0xff << SPI_ID_MOD_S)
+#define SPI_ID_CFG_S           5       /* DMA interface support */
+#define SPI_ID_CFG_M           (1 << SPI_ID_CFG_S)
+#define SPI_ID_REV_M           0x1F    /* Hardware revision number */
+
+#define SPI_CON_BM_S           16      /* Data width selection */
+#define SPI_CON_BM_M           (0x1F << SPI_CON_BM_S)
+#define SPI_CON_EM             BIT(24) /* Echo mode */
+#define SPI_CON_IDLE           BIT(23) /* Idle bit value */
+#define SPI_CON_ENBV           BIT(22) /* Enable byte valid control */
+#define SPI_CON_RUEN           BIT(12) /* Receive underflow error enable */
+#define SPI_CON_TUEN           BIT(11) /* Transmit underflow error enable */
+#define SPI_CON_AEN            BIT(10) /* Abort error enable */
+#define SPI_CON_REN            BIT(9)  /* Receive overflow error enable */
+#define SPI_CON_TEN            BIT(8)  /* Transmit overflow error enable */
+#define SPI_CON_LB             BIT(7)  /* Loopback control */
+#define SPI_CON_PO             BIT(6)  /* Clock polarity control */
+#define SPI_CON_PH             BIT(5)  /* Clock phase control */
+#define SPI_CON_HB             BIT(4)  /* Heading control */
+#define SPI_CON_RXOFF          BIT(1)  /* Switch receiver off */
+#define SPI_CON_TXOFF          BIT(0)  /* Switch transmitter off */
+
+#define SPI_STAT_RXBV_S                28
+#define SPI_STAT_RXBV_M                (0x7 << SPI_STAT_RXBV_S)
+#define SPI_STAT_BSY           BIT(13) /* Busy flag */
+#define SPI_STAT_RUE           BIT(12) /* Receive underflow error flag */
+#define SPI_STAT_TUE           BIT(11) /* Transmit underflow error flag */
+#define SPI_STAT_AE            BIT(10) /* Abort error flag */
+#define SPI_STAT_RE            BIT(9)  /* Receive error flag */
+#define SPI_STAT_TE            BIT(8)  /* Transmit error flag */
+#define SPI_STAT_ME            BIT(7)  /* Mode error flag */
+#define SPI_STAT_MS            BIT(1)  /* Master/slave select bit */
+#define SPI_STAT_EN            BIT(0)  /* Enable bit */
+#define SPI_STAT_ERRORS                (SPI_STAT_ME | SPI_STAT_TE | SPI_STAT_RE | \
+                                SPI_STAT_AE | SPI_STAT_TUE | SPI_STAT_RUE)
+
+#define SPI_WHBSTATE_SETTUE    BIT(15) /* Set transmit underflow error flag */
+#define SPI_WHBSTATE_SETAE     BIT(14) /* Set abort error flag */
+#define SPI_WHBSTATE_SETRE     BIT(13) /* Set receive error flag */
+#define SPI_WHBSTATE_SETTE     BIT(12) /* Set transmit error flag */
+#define SPI_WHBSTATE_CLRTUE    BIT(11) /* Clear transmit underflow error flag */
+#define SPI_WHBSTATE_CLRAE     BIT(10) /* Clear abort error flag */
+#define SPI_WHBSTATE_CLRRE     BIT(9)  /* Clear receive error flag */
+#define SPI_WHBSTATE_CLRTE     BIT(8)  /* Clear transmit error flag */
+#define SPI_WHBSTATE_SETME     BIT(7)  /* Set mode error flag */
+#define SPI_WHBSTATE_CLRME     BIT(6)  /* Clear mode error flag */
+#define SPI_WHBSTATE_SETRUE    BIT(5)  /* Set receive underflow error flag */
+#define SPI_WHBSTATE_CLRRUE    BIT(4)  /* Clear receive underflow error flag */
+#define SPI_WHBSTATE_SETMS     BIT(3)  /* Set master select bit */
+#define SPI_WHBSTATE_CLRMS     BIT(2)  /* Clear master select bit */
+#define SPI_WHBSTATE_SETEN     BIT(1)  /* Set enable bit (operational mode) */
+#define SPI_WHBSTATE_CLREN     BIT(0)  /* Clear enable bit (config mode */
+#define SPI_WHBSTATE_CLR_ERRORS        (SPI_WHBSTATE_CLRRUE | SPI_WHBSTATE_CLRME | \
+                                SPI_WHBSTATE_CLRTE | SPI_WHBSTATE_CLRRE | \
+                                SPI_WHBSTATE_CLRAE | SPI_WHBSTATE_CLRTUE)
+
+#define SPI_RXFCON_RXFITL_S    8       /* FIFO interrupt trigger level */
+#define SPI_RXFCON_RXFITL_M    (0x3F << SPI_RXFCON_RXFITL_S)
+#define SPI_RXFCON_RXFLU       BIT(1)  /* FIFO flush */
+#define SPI_RXFCON_RXFEN       BIT(0)  /* FIFO enable */
+
+#define SPI_TXFCON_TXFITL_S    8       /* FIFO interrupt trigger level */
+#define SPI_TXFCON_TXFITL_M    (0x3F << SPI_TXFCON_TXFITL_S)
+#define SPI_TXFCON_TXFLU       BIT(1)  /* FIFO flush */
+#define SPI_TXFCON_TXFEN       BIT(0)  /* FIFO enable */
+
+#define SPI_FSTAT_RXFFL_S      0
+#define SPI_FSTAT_RXFFL_M      (0x3f << SPI_FSTAT_RXFFL_S)
+#define SPI_FSTAT_TXFFL_S      8
+#define SPI_FSTAT_TXFFL_M      (0x3f << SPI_FSTAT_TXFFL_S)
+
+#define SPI_GPOCON_ISCSBN_S    8
+#define SPI_GPOCON_INVOUTN_S   0
+
+#define SPI_FGPO_SETOUTN_S     8
+#define SPI_FGPO_CLROUTN_S     0
+
+#define SPI_RXREQ_RXCNT_M      0xFFFF  /* Receive count value */
+#define SPI_RXCNT_TODO_M       0xFFFF  /* Recevie to-do value */
+
+#define SPI_IRNEN_TFI          BIT(4)  /* TX finished interrupt */
+#define SPI_IRNEN_F            BIT(3)  /* Frame end interrupt request */
+#define SPI_IRNEN_E            BIT(2)  /* Error end interrupt request */
+#define SPI_IRNEN_T_XWAY       BIT(1)  /* Transmit end interrupt request */
+#define SPI_IRNEN_R_XWAY       BIT(0)  /* Receive end interrupt request */
+#define SPI_IRNEN_R_XRX                BIT(1)  /* Transmit end interrupt request */
+#define SPI_IRNEN_T_XRX                BIT(0)  /* Receive end interrupt request */
+#define SPI_IRNEN_ALL          0x1F
+
+struct lantiq_ssc_hwcfg {
+       unsigned int irnen_r;
+       unsigned int irnen_t;
+};
+
+struct lantiq_ssc_spi {
+       struct spi_master               *master;
+       struct device                   *dev;
+       void __iomem                    *regbase;
+       struct clk                      *spi_clk;
+       struct clk                      *fpi_clk;
+       const struct lantiq_ssc_hwcfg   *hwcfg;
+
+       spinlock_t                      lock;
+       struct workqueue_struct         *wq;
+       struct work_struct              work;
+
+       const u8                        *tx;
+       u8                              *rx;
+       unsigned int                    tx_todo;
+       unsigned int                    rx_todo;
+       unsigned int                    bits_per_word;
+       unsigned int                    speed_hz;
+       unsigned int                    tx_fifo_size;
+       unsigned int                    rx_fifo_size;
+       unsigned int                    base_cs;
+};
+
+static u32 lantiq_ssc_readl(const struct lantiq_ssc_spi *spi, u32 reg)
+{
+       return __raw_readl(spi->regbase + reg);
+}
+
+static void lantiq_ssc_writel(const struct lantiq_ssc_spi *spi, u32 val,
+                             u32 reg)
+{
+       __raw_writel(val, spi->regbase + reg);
+}
+
+static void lantiq_ssc_maskl(const struct lantiq_ssc_spi *spi, u32 clr,
+                            u32 set, u32 reg)
+{
+       u32 val = __raw_readl(spi->regbase + reg);
+
+       val &= ~clr;
+       val |= set;
+       __raw_writel(val, spi->regbase + reg);
+}
+
+static unsigned int tx_fifo_level(const struct lantiq_ssc_spi *spi)
+{
+       u32 fstat = lantiq_ssc_readl(spi, SPI_FSTAT);
+
+       return (fstat & SPI_FSTAT_TXFFL_M) >> SPI_FSTAT_TXFFL_S;
+}
+
+static unsigned int rx_fifo_level(const struct lantiq_ssc_spi *spi)
+{
+       u32 fstat = lantiq_ssc_readl(spi, SPI_FSTAT);
+
+       return fstat & SPI_FSTAT_RXFFL_M;
+}
+
+static unsigned int tx_fifo_free(const struct lantiq_ssc_spi *spi)
+{
+       return spi->tx_fifo_size - tx_fifo_level(spi);
+}
+
+static void rx_fifo_reset(const struct lantiq_ssc_spi *spi)
+{
+       u32 val = spi->rx_fifo_size << SPI_RXFCON_RXFITL_S;
+
+       val |= SPI_RXFCON_RXFEN | SPI_RXFCON_RXFLU;
+       lantiq_ssc_writel(spi, val, SPI_RXFCON);
+}
+
+static void tx_fifo_reset(const struct lantiq_ssc_spi *spi)
+{
+       u32 val = 1 << SPI_TXFCON_TXFITL_S;
+
+       val |= SPI_TXFCON_TXFEN | SPI_TXFCON_TXFLU;
+       lantiq_ssc_writel(spi, val, SPI_TXFCON);
+}
+
+static void rx_fifo_flush(const struct lantiq_ssc_spi *spi)
+{
+       lantiq_ssc_maskl(spi, 0, SPI_RXFCON_RXFLU, SPI_RXFCON);
+}
+
+static void tx_fifo_flush(const struct lantiq_ssc_spi *spi)
+{
+       lantiq_ssc_maskl(spi, 0, SPI_TXFCON_TXFLU, SPI_TXFCON);
+}
+
+static void hw_enter_config_mode(const struct lantiq_ssc_spi *spi)
+{
+       lantiq_ssc_writel(spi, SPI_WHBSTATE_CLREN, SPI_WHBSTATE);
+}
+
+static void hw_enter_active_mode(const struct lantiq_ssc_spi *spi)
+{
+       lantiq_ssc_writel(spi, SPI_WHBSTATE_SETEN, SPI_WHBSTATE);
+}
+
+static void hw_setup_speed_hz(const struct lantiq_ssc_spi *spi,
+                             unsigned int max_speed_hz)
+{
+       u32 spi_clk, brt;
+
+       /*
+        * SPI module clock is derived from FPI bus clock dependent on
+        * divider value in CLC.RMS which is always set to 1.
+        *
+        *                 f_SPI
+        * baudrate = --------------
+        *             2 * (BR + 1)
+        */
+       spi_clk = clk_get_rate(spi->fpi_clk) / 2;
+
+       if (max_speed_hz > spi_clk)
+               brt = 0;
+       else
+               brt = spi_clk / max_speed_hz - 1;
+
+       if (brt > 0xFFFF)
+               brt = 0xFFFF;
+
+       dev_dbg(spi->dev, "spi_clk %u, max_speed_hz %u, brt %u\n",
+               spi_clk, max_speed_hz, brt);
+
+       lantiq_ssc_writel(spi, brt, SPI_BRT);
+}
+
+static void hw_setup_bits_per_word(const struct lantiq_ssc_spi *spi,
+                                  unsigned int bits_per_word)
+{
+       u32 bm;
+
+       /* CON.BM value = bits_per_word - 1 */
+       bm = (bits_per_word - 1) << SPI_CON_BM_S;
+
+       lantiq_ssc_maskl(spi, SPI_CON_BM_M, bm, SPI_CON);
+}
+
+static void hw_setup_clock_mode(const struct lantiq_ssc_spi *spi,
+                               unsigned int mode)
+{
+       u32 con_set = 0, con_clr = 0;
+
+       /*
+        * SPI mode mapping in CON register:
+        * Mode CPOL CPHA CON.PO CON.PH
+        *  0    0    0      0      1
+        *  1    0    1      0      0
+        *  2    1    0      1      1
+        *  3    1    1      1      0
+        */
+       if (mode & SPI_CPHA)
+               con_clr |= SPI_CON_PH;
+       else
+               con_set |= SPI_CON_PH;
+
+       if (mode & SPI_CPOL)
+               con_set |= SPI_CON_PO | SPI_CON_IDLE;
+       else
+               con_clr |= SPI_CON_PO | SPI_CON_IDLE;
+
+       /* Set heading control */
+       if (mode & SPI_LSB_FIRST)
+               con_clr |= SPI_CON_HB;
+       else
+               con_set |= SPI_CON_HB;
+
+       /* Set loopback mode */
+       if (mode & SPI_LOOP)
+               con_set |= SPI_CON_LB;
+       else
+               con_clr |= SPI_CON_LB;
+
+       lantiq_ssc_maskl(spi, con_clr, con_set, SPI_CON);
+}
+
+static void lantiq_ssc_hw_init(const struct lantiq_ssc_spi *spi)
+{
+       const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg;
+
+       /*
+        * Set clock divider for run mode to 1 to
+        * run at same frequency as FPI bus
+        */
+       lantiq_ssc_writel(spi, 1 << SPI_CLC_RMC_S, SPI_CLC);
+
+       /* Put controller into config mode */
+       hw_enter_config_mode(spi);
+
+       /* Clear error flags */
+       lantiq_ssc_maskl(spi, 0, SPI_WHBSTATE_CLR_ERRORS, SPI_WHBSTATE);
+
+       /* Enable error checking, disable TX/RX */
+       lantiq_ssc_writel(spi, SPI_CON_RUEN | SPI_CON_AEN | SPI_CON_TEN |
+               SPI_CON_REN | SPI_CON_TXOFF | SPI_CON_RXOFF, SPI_CON);
+
+       /* Setup default SPI mode */
+       hw_setup_bits_per_word(spi, spi->bits_per_word);
+       hw_setup_clock_mode(spi, SPI_MODE_0);
+
+       /* Enable master mode and clear error flags */
+       lantiq_ssc_writel(spi, SPI_WHBSTATE_SETMS | SPI_WHBSTATE_CLR_ERRORS,
+                              SPI_WHBSTATE);
+
+       /* Reset GPIO/CS registers */
+       lantiq_ssc_writel(spi, 0, SPI_GPOCON);
+       lantiq_ssc_writel(spi, 0xFF00, SPI_FPGO);
+
+       /* Enable and flush FIFOs */
+       rx_fifo_reset(spi);
+       tx_fifo_reset(spi);
+
+       /* Enable interrupts */
+       lantiq_ssc_writel(spi, hwcfg->irnen_t | hwcfg->irnen_r | SPI_IRNEN_E,
+                         SPI_IRNEN);
+}
+
+static int lantiq_ssc_setup(struct spi_device *spidev)
+{
+       struct spi_master *master = spidev->master;
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
+       unsigned int cs = spidev->chip_select;
+       u32 gpocon;
+
+       /* GPIOs are used for CS */
+       if (gpio_is_valid(spidev->cs_gpio))
+               return 0;
+
+       dev_dbg(spi->dev, "using internal chipselect %u\n", cs);
+
+       if (cs < spi->base_cs) {
+               dev_err(spi->dev,
+                       "chipselect %i too small (min %i)\n", cs, spi->base_cs);
+               return -EINVAL;
+       }
+
+       /* set GPO pin to CS mode */
+       gpocon = 1 << ((cs - spi->base_cs) + SPI_GPOCON_ISCSBN_S);
+
+       /* invert GPO pin */
+       if (spidev->mode & SPI_CS_HIGH)
+               gpocon |= 1 << (cs - spi->base_cs);
+
+       lantiq_ssc_maskl(spi, 0, gpocon, SPI_GPOCON);
+
+       return 0;
+}
+
+static int lantiq_ssc_prepare_message(struct spi_master *master,
+                                     struct spi_message *message)
+{
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
+
+       hw_enter_config_mode(spi);
+       hw_setup_clock_mode(spi, message->spi->mode);
+       hw_enter_active_mode(spi);
+
+       return 0;
+}
+
+static void hw_setup_transfer(struct lantiq_ssc_spi *spi,
+                             struct spi_device *spidev, struct spi_transfer *t)
+{
+       unsigned int speed_hz = t->speed_hz;
+       unsigned int bits_per_word = t->bits_per_word;
+       u32 con;
+
+       if (bits_per_word != spi->bits_per_word ||
+               speed_hz != spi->speed_hz) {
+               hw_enter_config_mode(spi);
+               hw_setup_speed_hz(spi, speed_hz);
+               hw_setup_bits_per_word(spi, bits_per_word);
+               hw_enter_active_mode(spi);
+
+               spi->speed_hz = speed_hz;
+               spi->bits_per_word = bits_per_word;
+       }
+
+       /* Configure transmitter and receiver */
+       con = lantiq_ssc_readl(spi, SPI_CON);
+       if (t->tx_buf)
+               con &= ~SPI_CON_TXOFF;
+       else
+               con |= SPI_CON_TXOFF;
+
+       if (t->rx_buf)
+               con &= ~SPI_CON_RXOFF;
+       else
+               con |= SPI_CON_RXOFF;
+
+       lantiq_ssc_writel(spi, con, SPI_CON);
+}
+
+static int lantiq_ssc_unprepare_message(struct spi_master *master,
+                                       struct spi_message *message)
+{
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
+
+       flush_workqueue(spi->wq);
+
+       /* Disable transmitter and receiver while idle */
+       lantiq_ssc_maskl(spi, 0, SPI_CON_TXOFF | SPI_CON_RXOFF, SPI_CON);
+
+       return 0;
+}
+
+static void tx_fifo_write(struct lantiq_ssc_spi *spi)
+{
+       const u8 *tx8;
+       const u16 *tx16;
+       const u32 *tx32;
+       u32 data;
+       unsigned int tx_free = tx_fifo_free(spi);
+
+       while (spi->tx_todo && tx_free) {
+               switch (spi->bits_per_word) {
+               case 2 ... 8:
+                       tx8 = spi->tx;
+                       data = *tx8;
+                       spi->tx_todo--;
+                       spi->tx++;
+                       break;
+               case 16:
+                       tx16 = (u16 *) spi->tx;
+                       data = *tx16;
+                       spi->tx_todo -= 2;
+                       spi->tx += 2;
+                       break;
+               case 32:
+                       tx32 = (u32 *) spi->tx;
+                       data = *tx32;
+                       spi->tx_todo -= 4;
+                       spi->tx += 4;
+                       break;
+               default:
+                       WARN_ON(1);
+                       data = 0;
+                       break;
+               }
+
+               lantiq_ssc_writel(spi, data, SPI_TB);
+               tx_free--;
+       }
+}
+
+static void rx_fifo_read_full_duplex(struct lantiq_ssc_spi *spi)
+{
+       u8 *rx8;
+       u16 *rx16;
+       u32 *rx32;
+       u32 data;
+       unsigned int rx_fill = rx_fifo_level(spi);
+
+       while (rx_fill) {
+               data = lantiq_ssc_readl(spi, SPI_RB);
+
+               switch (spi->bits_per_word) {
+               case 2 ... 8:
+                       rx8 = spi->rx;
+                       *rx8 = data;
+                       spi->rx_todo--;
+                       spi->rx++;
+                       break;
+               case 16:
+                       rx16 = (u16 *) spi->rx;
+                       *rx16 = data;
+                       spi->rx_todo -= 2;
+                       spi->rx += 2;
+                       break;
+               case 32:
+                       rx32 = (u32 *) spi->rx;
+                       *rx32 = data;
+                       spi->rx_todo -= 4;
+                       spi->rx += 4;
+                       break;
+               default:
+                       WARN_ON(1);
+                       break;
+               }
+
+               rx_fill--;
+       }
+}
+
+static void rx_fifo_read_half_duplex(struct lantiq_ssc_spi *spi)
+{
+       u32 data, *rx32;
+       u8 *rx8;
+       unsigned int rxbv, shift;
+       unsigned int rx_fill = rx_fifo_level(spi);
+
+       /*
+        * In RX-only mode the bits per word value is ignored by HW. A value
+        * of 32 is used instead. Thus all 4 bytes per FIFO must be read.
+        * If remaining RX bytes are less than 4, the FIFO must be read
+        * differently. The amount of received and valid bytes is indicated
+        * by STAT.RXBV register value.
+        */
+       while (rx_fill) {
+               if (spi->rx_todo < 4)  {
+                       rxbv = (lantiq_ssc_readl(spi, SPI_STAT) &
+                               SPI_STAT_RXBV_M) >> SPI_STAT_RXBV_S;
+                       data = lantiq_ssc_readl(spi, SPI_RB);
+
+                       shift = (rxbv - 1) * 8;
+                       rx8 = spi->rx;
+
+                       while (rxbv) {
+                               *rx8++ = (data >> shift) & 0xFF;
+                               rxbv--;
+                               shift -= 8;
+                               spi->rx_todo--;
+                               spi->rx++;
+                       }
+               } else {
+                       data = lantiq_ssc_readl(spi, SPI_RB);
+                       rx32 = (u32 *) spi->rx;
+
+                       *rx32++ = data;
+                       spi->rx_todo -= 4;
+                       spi->rx += 4;
+               }
+               rx_fill--;
+       }
+}
+
+static void rx_request(struct lantiq_ssc_spi *spi)
+{
+       unsigned int rxreq, rxreq_max;
+
+       /*
+        * To avoid receive overflows at high clocks it is better to request
+        * only the amount of bytes that fits into all FIFOs. This value
+        * depends on the FIFO size implemented in hardware.
+        */
+       rxreq = spi->rx_todo;
+       rxreq_max = spi->rx_fifo_size * 4;
+       if (rxreq > rxreq_max)
+               rxreq = rxreq_max;
+
+       lantiq_ssc_writel(spi, rxreq, SPI_RXREQ);
+}
+
+static irqreturn_t lantiq_ssc_xmit_interrupt(int irq, void *data)
+{
+       struct lantiq_ssc_spi *spi = data;
+
+       if (spi->tx) {
+               if (spi->rx && spi->rx_todo)
+                       rx_fifo_read_full_duplex(spi);
+
+               if (spi->tx_todo)
+                       tx_fifo_write(spi);
+               else if (!tx_fifo_level(spi))
+                       goto completed;
+       } else if (spi->rx) {
+               if (spi->rx_todo) {
+                       rx_fifo_read_half_duplex(spi);
+
+                       if (spi->rx_todo)
+                               rx_request(spi);
+                       else
+                               goto completed;
+               } else {
+                       goto completed;
+               }
+       }
+
+       return IRQ_HANDLED;
+
+completed:
+       queue_work(spi->wq, &spi->work);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t lantiq_ssc_err_interrupt(int irq, void *data)
+{
+       struct lantiq_ssc_spi *spi = data;
+       u32 stat = lantiq_ssc_readl(spi, SPI_STAT);
+
+       if (!(stat & SPI_STAT_ERRORS))
+               return IRQ_NONE;
+
+       if (stat & SPI_STAT_RUE)
+               dev_err(spi->dev, "receive underflow error\n");
+       if (stat & SPI_STAT_TUE)
+               dev_err(spi->dev, "transmit underflow error\n");
+       if (stat & SPI_STAT_AE)
+               dev_err(spi->dev, "abort error\n");
+       if (stat & SPI_STAT_RE)
+               dev_err(spi->dev, "receive overflow error\n");
+       if (stat & SPI_STAT_TE)
+               dev_err(spi->dev, "transmit overflow error\n");
+       if (stat & SPI_STAT_ME)
+               dev_err(spi->dev, "mode error\n");
+
+       /* Clear error flags */
+       lantiq_ssc_maskl(spi, 0, SPI_WHBSTATE_CLR_ERRORS, SPI_WHBSTATE);
+
+       /* set bad status so it can be retried */
+       if (spi->master->cur_msg)
+               spi->master->cur_msg->status = -EIO;
+       queue_work(spi->wq, &spi->work);
+
+       return IRQ_HANDLED;
+}
+
+static int transfer_start(struct lantiq_ssc_spi *spi, struct spi_device *spidev,
+                         struct spi_transfer *t)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&spi->lock, flags);
+
+       spi->tx = t->tx_buf;
+       spi->rx = t->rx_buf;
+
+       if (t->tx_buf) {
+               spi->tx_todo = t->len;
+
+               /* initially fill TX FIFO */
+               tx_fifo_write(spi);
+       }
+
+       if (spi->rx) {
+               spi->rx_todo = t->len;
+
+               /* start shift clock in RX-only mode */
+               if (!spi->tx)
+                       rx_request(spi);
+       }
+
+       spin_unlock_irqrestore(&spi->lock, flags);
+
+       return t->len;
+}
+
+/*
+ * The driver only gets an interrupt when the FIFO is empty, but there
+ * is an additional shift register from which the data is written to
+ * the wire. We get the last interrupt when the controller starts to
+ * write the last word to the wire, not when it is finished. Do busy
+ * waiting till it finishes.
+ */
+static void lantiq_ssc_bussy_work(struct work_struct *work)
+{
+       struct lantiq_ssc_spi *spi;
+       unsigned long long timeout = 8LL * 1000LL;
+       unsigned long end;
+
+       spi = container_of(work, typeof(*spi), work);
+
+       do_div(timeout, spi->speed_hz);
+       timeout += timeout + 100; /* some tolerance */
+
+       end = jiffies + msecs_to_jiffies(timeout);
+       do {
+               u32 stat = lantiq_ssc_readl(spi, SPI_STAT);
+
+               if (!(stat & SPI_STAT_BSY)) {
+                       spi_finalize_current_transfer(spi->master);
+                       return;
+               }
+
+               cond_resched();
+       } while (!time_after_eq(jiffies, end));
+
+       if (spi->master->cur_msg)
+               spi->master->cur_msg->status = -EIO;
+       spi_finalize_current_transfer(spi->master);
+}
+
+static void lantiq_ssc_handle_err(struct spi_master *master,
+                                 struct spi_message *message)
+{
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
+
+       /* flush FIFOs on timeout */
+       rx_fifo_flush(spi);
+       tx_fifo_flush(spi);
+}
+
+static void lantiq_ssc_set_cs(struct spi_device *spidev, bool enable)
+{
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(spidev->master);
+       unsigned int cs = spidev->chip_select;
+       u32 fgpo;
+
+       if (!!(spidev->mode & SPI_CS_HIGH) == enable)
+               fgpo = (1 << (cs - spi->base_cs));
+       else
+               fgpo = (1 << (cs - spi->base_cs + SPI_FGPO_SETOUTN_S));
+
+       lantiq_ssc_writel(spi, fgpo, SPI_FPGO);
+}
+
+static int lantiq_ssc_transfer_one(struct spi_master *master,
+                                  struct spi_device *spidev,
+                                  struct spi_transfer *t)
+{
+       struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
+
+       hw_setup_transfer(spi, spidev, t);
+
+       return transfer_start(spi, spidev, t);
+}
+
+static const struct lantiq_ssc_hwcfg lantiq_ssc_xway = {
+       .irnen_r = SPI_IRNEN_R_XWAY,
+       .irnen_t = SPI_IRNEN_T_XWAY,
+};
+
+static const struct lantiq_ssc_hwcfg lantiq_ssc_xrx = {
+       .irnen_r = SPI_IRNEN_R_XRX,
+       .irnen_t = SPI_IRNEN_T_XRX,
+};
+
+static const struct of_device_id lantiq_ssc_match[] = {
+       { .compatible = "lantiq,ase-spi", .data = &lantiq_ssc_xway, },
+       { .compatible = "lantiq,falcon-spi", .data = &lantiq_ssc_xrx, },
+       { .compatible = "lantiq,xrx100-spi", .data = &lantiq_ssc_xrx, },
+       {},
+};
+MODULE_DEVICE_TABLE(of, lantiq_ssc_match);
+
+static int lantiq_ssc_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct spi_master *master;
+       struct resource *res;
+       struct lantiq_ssc_spi *spi;
+       const struct lantiq_ssc_hwcfg *hwcfg;
+       const struct of_device_id *match;
+       int err, rx_irq, tx_irq, err_irq;
+       u32 id, supports_dma, revision;
+       unsigned int num_cs;
+
+       match = of_match_device(lantiq_ssc_match, dev);
+       if (!match) {
+               dev_err(dev, "no device match\n");
+               return -EINVAL;
+       }
+       hwcfg = match->data;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "failed to get resources\n");
+               return -ENXIO;
+       }
+
+       rx_irq = platform_get_irq_byname(pdev, SPI_RX_IRQ_NAME);
+       if (rx_irq < 0) {
+               dev_err(dev, "failed to get %s\n", SPI_RX_IRQ_NAME);
+               return -ENXIO;
+       }
+
+       tx_irq = platform_get_irq_byname(pdev, SPI_TX_IRQ_NAME);
+       if (tx_irq < 0) {
+               dev_err(dev, "failed to get %s\n", SPI_TX_IRQ_NAME);
+               return -ENXIO;
+       }
+
+       err_irq = platform_get_irq_byname(pdev, SPI_ERR_IRQ_NAME);
+       if (err_irq < 0) {
+               dev_err(dev, "failed to get %s\n", SPI_ERR_IRQ_NAME);
+               return -ENXIO;
+       }
+
+       master = spi_alloc_master(dev, sizeof(struct lantiq_ssc_spi));
+       if (!master)
+               return -ENOMEM;
+
+       spi = spi_master_get_devdata(master);
+       spi->master = master;
+       spi->dev = dev;
+       spi->hwcfg = hwcfg;
+       platform_set_drvdata(pdev, spi);
+
+       spi->regbase = devm_ioremap_resource(dev, res);
+       if (IS_ERR(spi->regbase)) {
+               err = PTR_ERR(spi->regbase);
+               goto err_master_put;
+       }
+
+       err = devm_request_irq(dev, rx_irq, lantiq_ssc_xmit_interrupt,
+                              0, SPI_RX_IRQ_NAME, spi);
+       if (err)
+               goto err_master_put;
+
+       err = devm_request_irq(dev, tx_irq, lantiq_ssc_xmit_interrupt,
+                              0, SPI_TX_IRQ_NAME, spi);
+       if (err)
+               goto err_master_put;
+
+       err = devm_request_irq(dev, err_irq, lantiq_ssc_err_interrupt,
+                              0, SPI_ERR_IRQ_NAME, spi);
+       if (err)
+               goto err_master_put;
+
+       spi->spi_clk = devm_clk_get(dev, "gate");
+       if (IS_ERR(spi->spi_clk)) {
+               err = PTR_ERR(spi->spi_clk);
+               goto err_master_put;
+       }
+       err = clk_prepare_enable(spi->spi_clk);
+       if (err)
+               goto err_master_put;
+
+       /*
+        * Use the old clk_get_fpi() function on Lantiq platform, till it
+        * supports common clk.
+        */
+#if defined(CONFIG_LANTIQ) && !defined(CONFIG_COMMON_CLK)
+       spi->fpi_clk = clk_get_fpi();
+#else
+       spi->fpi_clk = clk_get(dev, "freq");
+#endif
+       if (IS_ERR(spi->fpi_clk)) {
+               err = PTR_ERR(spi->fpi_clk);
+               goto err_clk_disable;
+       }
+
+       num_cs = 8;
+       of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
+
+       spi->base_cs = 1;
+       of_property_read_u32(pdev->dev.of_node, "base-cs", &spi->base_cs);
+
+       spin_lock_init(&spi->lock);
+       spi->bits_per_word = 8;
+       spi->speed_hz = 0;
+
+       master->dev.of_node = pdev->dev.of_node;
+       master->num_chipselect = num_cs;
+       master->setup = lantiq_ssc_setup;
+       master->set_cs = lantiq_ssc_set_cs;
+       master->handle_err = lantiq_ssc_handle_err;
+       master->prepare_message = lantiq_ssc_prepare_message;
+       master->unprepare_message = lantiq_ssc_unprepare_message;
+       master->transfer_one = lantiq_ssc_transfer_one;
+       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH |
+                               SPI_LOOP;
+       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) |
+                                    SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
+
+       spi->wq = alloc_ordered_workqueue(dev_name(dev), 0);
+       if (!spi->wq) {
+               err = -ENOMEM;
+               goto err_clk_put;
+       }
+       INIT_WORK(&spi->work, lantiq_ssc_bussy_work);
+
+       id = lantiq_ssc_readl(spi, SPI_ID);
+       spi->tx_fifo_size = (id & SPI_ID_TXFS_M) >> SPI_ID_TXFS_S;
+       spi->rx_fifo_size = (id & SPI_ID_RXFS_M) >> SPI_ID_RXFS_S;
+       supports_dma = (id & SPI_ID_CFG_M) >> SPI_ID_CFG_S;
+       revision = id & SPI_ID_REV_M;
+
+       lantiq_ssc_hw_init(spi);
+
+       dev_info(dev,
+               "Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
+               revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
+
+       err = devm_spi_register_master(dev, master);
+       if (err) {
+               dev_err(dev, "failed to register spi_master\n");
+               goto err_wq_destroy;
+       }
+
+       return 0;
+
+err_wq_destroy:
+       destroy_workqueue(spi->wq);
+err_clk_put:
+       clk_put(spi->fpi_clk);
+err_clk_disable:
+       clk_disable_unprepare(spi->spi_clk);
+err_master_put:
+       spi_master_put(master);
+
+       return err;
+}
+
+static int lantiq_ssc_remove(struct platform_device *pdev)
+{
+       struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
+
+       lantiq_ssc_writel(spi, 0, SPI_IRNEN);
+       lantiq_ssc_writel(spi, 0, SPI_CLC);
+       rx_fifo_flush(spi);
+       tx_fifo_flush(spi);
+       hw_enter_config_mode(spi);
+
+       destroy_workqueue(spi->wq);
+       clk_disable_unprepare(spi->spi_clk);
+       clk_put(spi->fpi_clk);
+
+       return 0;
+}
+
+static struct platform_driver lantiq_ssc_driver = {
+       .probe = lantiq_ssc_probe,
+       .remove = lantiq_ssc_remove,
+       .driver = {
+               .name = "spi-lantiq-ssc",
+               .owner = THIS_MODULE,
+               .of_match_table = lantiq_ssc_match,
+       },
+};
+module_platform_driver(lantiq_ssc_driver);
+
+MODULE_DESCRIPTION("Lantiq SSC SPI controller driver");
+MODULE_AUTHOR("Daniel Schwierzeck <daniel.schwierzeck@gmail.com>");
+MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:spi-lantiq-ssc");
index c36002110c30a58e158043d5820fc671fb9b5c64..e8b59ce4dc3a74153cb15ef9f128b44070a573da 100644 (file)
@@ -437,8 +437,9 @@ static int mpc52xx_spi_probe(struct platform_device *op)
        ms->gpio_cs_count = of_gpio_count(op->dev.of_node);
        if (ms->gpio_cs_count > 0) {
                master->num_chipselect = ms->gpio_cs_count;
-               ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int),
-                               GFP_KERNEL);
+               ms->gpio_cs = kmalloc_array(ms->gpio_cs_count,
+                                           sizeof(*ms->gpio_cs),
+                                           GFP_KERNEL);
                if (!ms->gpio_cs) {
                        rc = -ENOMEM;
                        goto err_alloc_gpio;
@@ -448,8 +449,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
                        gpio_cs = of_get_gpio(op->dev.of_node, i);
                        if (gpio_cs < 0) {
                                dev_err(&op->dev,
-                                       "could not parse the gpio field "
-                                       "in oftree\n");
+                                       "could not parse the gpio field in oftree\n");
                                rc = -ENODEV;
                                goto err_gpio;
                        }
@@ -457,8 +457,8 @@ static int mpc52xx_spi_probe(struct platform_device *op)
                        rc = gpio_request(gpio_cs, dev_name(&op->dev));
                        if (rc) {
                                dev_err(&op->dev,
-                                       "can't request spi cs gpio #%d "
-                                       "on gpio line %d\n", i, gpio_cs);
+                                       "can't request spi cs gpio #%d on gpio line %d\n",
+                                       i, gpio_cs);
                                goto err_gpio;
                        }
 
index 899d7a8f0889eaf39388ad458b28a1abbeeba671..278867a319506ff830c634cc24b2a2d819021a6b 100644 (file)
@@ -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)
                                        &reg_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(&reg_val, trans->tx_buf + (cnt * 4), remainder);
+                       writel(reg_val, mdata->base + SPI_TX_DATA_REG);
+               }
+
+               mtk_spi_enable_transfer(master);
+
                return IRQ_HANDLED;
        }
 
index dd3d0a218d8b1ffc2299595fc55adadaaa3bdeeb..967d94844b30d162b353da096e1d2f865f7128e8 100644 (file)
@@ -411,7 +411,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
        if (num_gpios > 0) {
                int i;
 
-               hw->gpios = kzalloc(sizeof(int) * num_gpios, GFP_KERNEL);
+               hw->gpios = kcalloc(num_gpios, sizeof(*hw->gpios), GFP_KERNEL);
                if (!hw->gpios) {
                        ret = -ENOMEM;
                        goto free_master;
@@ -428,8 +428,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
                                /* Real CS - set the initial state. */
                                ret = gpio_request(gpio, np->name);
                                if (ret < 0) {
-                                       dev_err(dev, "can't request gpio "
-                                                       "#%d: %d\n", i, ret);
+                                       dev_err(dev,
+                                               "can't request gpio #%d: %d\n",
+                                               i, ret);
                                        goto free_gpios;
                                }
 
index 58d2d48e16a530869528288d50f3a6581c3ea311..869f188b02eb3b92e994400c886ba631c95f2805 100644 (file)
@@ -41,6 +41,13 @@ struct pxa_spi_info {
 static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
 static struct dw_dma_slave byt_rx_param = { .src_id = 1 };
 
+static struct dw_dma_slave mrfld3_tx_param = { .dst_id = 15 };
+static struct dw_dma_slave mrfld3_rx_param = { .src_id = 14 };
+static struct dw_dma_slave mrfld5_tx_param = { .dst_id = 13 };
+static struct dw_dma_slave mrfld5_rx_param = { .src_id = 12 };
+static struct dw_dma_slave mrfld6_tx_param = { .dst_id = 11 };
+static struct dw_dma_slave mrfld6_rx_param = { .src_id = 10 };
+
 static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
 static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
 static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
@@ -93,22 +100,39 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
 
 static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
 {
+       struct pci_dev *dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
+       struct dw_dma_slave *tx, *rx;
+
        switch (PCI_FUNC(dev->devfn)) {
        case 0:
                c->port_id = 3;
                c->num_chipselect = 1;
+               c->tx_param = &mrfld3_tx_param;
+               c->rx_param = &mrfld3_rx_param;
                break;
        case 1:
                c->port_id = 5;
                c->num_chipselect = 4;
+               c->tx_param = &mrfld5_tx_param;
+               c->rx_param = &mrfld5_rx_param;
                break;
        case 2:
                c->port_id = 6;
                c->num_chipselect = 1;
+               c->tx_param = &mrfld6_tx_param;
+               c->rx_param = &mrfld6_rx_param;
                break;
        default:
                return -ENODEV;
        }
+
+       tx = c->tx_param;
+       tx->dma_dev = &dma_dev->dev;
+
+       rx = c->rx_param;
+       rx->dma_dev = &dma_dev->dev;
+
+       c->dma_filter = lpss_dma_filter;
        return 0;
 }
 
@@ -203,10 +227,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
        ssp = &spi_pdata.ssp;
        ssp->phys_base = pci_resource_start(dev, 0);
        ssp->mmio_base = pcim_iomap_table(dev)[0];
-       ssp->irq = dev->irq;
        ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
        ssp->type = c->type;
 
+       pci_set_master(dev);
+
+       ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
+       if (ret < 0)
+               return ret;
+       ssp->irq = pci_irq_vector(dev, 0);
+
        snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
        ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
                                           c->max_clk_rate);
index dd7b5b47291d551890da8e8dfc324ca74895d66b..47b65d7c40721eaf39fc0ba0e9dfa016a5407cfa 100644 (file)
@@ -732,6 +732,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
        return IRQ_HANDLED;
 }
 
+static void handle_bad_msg(struct driver_data *drv_data)
+{
+       pxa2xx_spi_write(drv_data, SSCR0,
+                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_write(drv_data, SSCR1,
+                        pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1);
+       if (!pxa25x_ssp_comp(drv_data))
+               pxa2xx_spi_write(drv_data, SSTO, 0);
+       write_SSSR_CS(drv_data, drv_data->clear_sr);
+
+       dev_err(&drv_data->pdev->dev,
+               "bad message state in interrupt handler\n");
+}
+
 static irqreturn_t ssp_int(int irq, void *dev_id)
 {
        struct driver_data *drv_data = dev_id;
@@ -771,21 +785,11 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
        if (!(status & mask))
                return IRQ_NONE;
 
-       if (!drv_data->master->cur_msg) {
-
-               pxa2xx_spi_write(drv_data, SSCR0,
-                                pxa2xx_spi_read(drv_data, SSCR0)
-                                & ~SSCR0_SSE);
-               pxa2xx_spi_write(drv_data, SSCR1,
-                                pxa2xx_spi_read(drv_data, SSCR1)
-                                & ~drv_data->int_cr1);
-               if (!pxa25x_ssp_comp(drv_data))
-                       pxa2xx_spi_write(drv_data, SSTO, 0);
-               write_SSSR_CS(drv_data, drv_data->clear_sr);
-
-               dev_err(&drv_data->pdev->dev,
-                       "bad message state in interrupt handler\n");
+       pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg & ~drv_data->int_cr1);
+       pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
 
+       if (!drv_data->master->cur_msg) {
+               handle_bad_msg(drv_data);
                /* Never fail */
                return IRQ_HANDLED;
        }
@@ -1458,6 +1462,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 +1698,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);
index 0f89c2169c244e433a36e7cc7e672d385d3c6560..acf31f36b89856bcf0a3b9c7d0ae113d6e5589cb 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/dmaengine.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/pm_runtime.h>
@@ -843,6 +844,8 @@ static int rockchip_spi_suspend(struct device *dev)
                clk_disable_unprepare(rs->apb_pclk);
        }
 
+       pinctrl_pm_select_sleep_state(dev);
+
        return ret;
 }
 
@@ -852,6 +855,8 @@ static int rockchip_spi_resume(struct device *dev)
        struct spi_master *master = dev_get_drvdata(dev);
        struct rockchip_spi *rs = spi_master_get_devdata(master);
 
+       pinctrl_pm_select_default_state(dev);
+
        if (!pm_runtime_suspended(dev)) {
                ret = clk_prepare_enable(rs->apb_pclk);
                if (ret < 0)
index 9daf500317376bd143cb56eb4b14738d11adbdca..2a10b3f94ff72a4ea3d6924a082ef6d2db174528 100644 (file)
@@ -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;
        }
@@ -1227,10 +1226,8 @@ static int rspi_probe(struct platform_device *pdev)
        const struct spi_ops *ops;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
-       if (master == NULL) {
-               dev_err(&pdev->dev, "spi_alloc_master error.\n");
+       if (master == NULL)
                return -ENOMEM;
-       }
 
        of_id = of_match_device(rspi_of_match, &pdev->dev);
        if (of_id) {
index b8cd356d8d100c101cbfd9c10637869f2616e2b0..b392cca8fa4f5ba3c1c499ea8b1bc228fcabdbee 100644 (file)
@@ -969,7 +969,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;
 }
index 0012ad02e5696d35b547a3a698682f51a2d02819..2ce15ca977828668e0fa8e186b6b9a8393cdc70d 100644 (file)
@@ -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);
@@ -1162,10 +1164,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
        int ret;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
-       if (master == NULL) {
-               dev_err(&pdev->dev, "failed to allocate spi master\n");
+       if (master == NULL)
                return -ENOMEM;
-       }
 
        p = spi_master_get_devdata(master);
 
index ec6fb09e2e1711f7adfbe079559a89f1a9cd343d..0fefa6423ff46f455c032d9294cab20b88e358b8 100644 (file)
@@ -714,9 +714,10 @@ static int ti_qspi_probe(struct platform_device *pdev)
        dma_cap_set(DMA_MEMCPY, mask);
 
        qspi->rx_chan = dma_request_chan_by_mask(&mask);
-       if (!qspi->rx_chan) {
+       if (IS_ERR(qspi->rx_chan)) {
                dev_err(qspi->dev,
                        "No Rx DMA available, trying mmap mode\n");
+               qspi->rx_chan = NULL;
                ret = 0;
                goto no_dma;
        }
index 656dd3e3220c5062b43b5a162a078f245f90630c..f274df9e0e3e2265c723139bb2b2f92ad72e32ba 100644 (file)
@@ -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))
@@ -1502,37 +1504,18 @@ err_init_queue:
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_OF)
-static struct spi_device *
-of_register_spi_device(struct spi_master *master, struct device_node *nc)
+static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi,
+                          struct device_node *nc)
 {
-       struct spi_device *spi;
-       int rc;
        u32 value;
-
-       /* Alloc an spi_device */
-       spi = spi_alloc_device(master);
-       if (!spi) {
-               dev_err(&master->dev, "spi_device alloc error for %s\n",
-                       nc->full_name);
-               rc = -ENOMEM;
-               goto err_out;
-       }
-
-       /* Select device driver */
-       rc = of_modalias_node(nc, spi->modalias,
-                               sizeof(spi->modalias));
-       if (rc < 0) {
-               dev_err(&master->dev, "cannot find modalias for %s\n",
-                       nc->full_name);
-               goto err_out;
-       }
+       int rc;
 
        /* Device address */
        rc = of_property_read_u32(nc, "reg", &value);
        if (rc) {
                dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n",
                        nc->full_name, rc);
-               goto err_out;
+               return rc;
        }
        spi->chip_select = value;
 
@@ -1590,10 +1573,41 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)
        if (rc) {
                dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n",
                        nc->full_name, rc);
-               goto err_out;
+               return rc;
        }
        spi->max_speed_hz = value;
 
+       return 0;
+}
+
+static struct spi_device *
+of_register_spi_device(struct spi_master *master, struct device_node *nc)
+{
+       struct spi_device *spi;
+       int rc;
+
+       /* Alloc an spi_device */
+       spi = spi_alloc_device(master);
+       if (!spi) {
+               dev_err(&master->dev, "spi_device alloc error for %s\n",
+                       nc->full_name);
+               rc = -ENOMEM;
+               goto err_out;
+       }
+
+       /* Select device driver */
+       rc = of_modalias_node(nc, spi->modalias,
+                               sizeof(spi->modalias));
+       if (rc < 0) {
+               dev_err(&master->dev, "cannot find modalias for %s\n",
+                       nc->full_name);
+               goto err_out;
+       }
+
+       rc = of_spi_parse_dt(master, spi, nc);
+       if (rc)
+               goto err_out;
+
        /* Store a pointer to the node in the device structure */
        of_node_get(nc);
        spi->dev.of_node = nc;
@@ -1603,11 +1617,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);
index 9bb63ac13f04574d5cf84a87067f4917dc79a5f8..171a271c2cbd5e1d5d806b0275116b59ee6710bf 100644 (file)
@@ -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 */
index 2d6f0c39ed6833b96f8aad03d9ed8b2e4d445add..a0522328d7aa5c2e3f94a77dc266cd20301046a7 100644 (file)
@@ -90,9 +90,9 @@
 #define SSSR_RFL_MASK  (0xf << 12)     /* Receive FIFO Level mask */
 
 #define SSCR1_TFT      (0x000003c0)    /* Transmit FIFO Threshold (mask) */
-#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
+#define SSCR1_TxTresh(x) (((x) - 1) << 6)      /* level [1..16] */
 #define SSCR1_RFT      (0x00003c00)    /* Receive FIFO Threshold (mask) */
-#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
+#define SSCR1_RxTresh(x) (((x) - 1) << 10)     /* level [1..16] */
 
 #define RX_THRESH_CE4100_DFLT  2
 #define TX_THRESH_CE4100_DFLT  2
 #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10)      /* level [1..4] */
 
 /* QUARK_X1000 SSCR0 bit definition */
-#define QUARK_X1000_SSCR0_DSS  (0x1F)          /* Data Size Select (mask) */
-#define QUARK_X1000_SSCR0_DataSize(x)  ((x) - 1)       /* Data Size Select [4..32] */
-#define QUARK_X1000_SSCR0_FRF  (0x3 << 5)      /* FRame Format (mask) */
+#define QUARK_X1000_SSCR0_DSS          (0x1F << 0)     /* Data Size Select (mask) */
+#define QUARK_X1000_SSCR0_DataSize(x)  ((x) - 1)       /* Data Size Select [4..32] */
+#define QUARK_X1000_SSCR0_FRF          (0x3 << 5)      /* FRame Format (mask) */
 #define QUARK_X1000_SSCR0_Motorola     (0x0 << 5)      /* Motorola's Serial Peripheral Interface (SPI) */
 
 #define RX_THRESH_QUARK_X1000_DFLT     1
 #define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6)  /* level [1..32] */
 #define QUARK_X1000_SSCR1_RFT  (0x1F << 11)    /* Receive FIFO Threshold (mask) */
 #define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */
-#define QUARK_X1000_SSCR1_STRF       (1 << 17)         /* Select FIFO or EFWR */
-#define QUARK_X1000_SSCR1_EFWR (1 << 16)               /* Enable FIFO Write/Read */
+#define QUARK_X1000_SSCR1_STRF (1 << 17)       /* Select FIFO or EFWR */
+#define QUARK_X1000_SSCR1_EFWR (1 << 16)       /* Enable FIFO Write/Read */
 
 /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
 #define SSCR0_TISSP            (1 << 4)        /* TI Sync Serial Protocol */