Merge remote-tracking branches 'spi/topic/sunxi', 'spi/topic/tegra114', 'spi/topic...
authorMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:51:41 +0000 (00:51 +0000)
committerMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:51:41 +0000 (00:51 +0000)
1  2  3  4  5  6  7  8  9 
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/spi-tegra114.c
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-xcomm.c
drivers/spi/spi.c

diff --combined drivers/spi/Kconfig
index 2a1b0a7d9415ca9ba3b75c98bd6afbea02bafcb3,5dffdc1691e8f46d6712f691cff45ea01e08116d,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d,fc940f109f6eece001ef006908b179b379274e58,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d,ba9310bc9acb7449a91ccb59b8f7de5c09c5801d..756b5b3ca2008240b01bfbd365eacdb0c008bafd
@@@@@@@@@@ -150,7 -150,7 -150,7 -150,7 -150,7 -150,7 -150,7 -150,7 -150,7 +150,7 @@@@@@@@@@ config SPI_BUTTERFL
         
         config SPI_CLPS711X
                tristate "CLPS711X host SPI controller"
 --------       depends on ARCH_CLPS711X
 ++++++++       depends on ARCH_CLPS711X || COMPILE_TEST
                help
                  This enables dedicated general purpose SPI/Microwire1-compatible
                  master mode interface (SSI1) for CLPS711X-based CPUs.
@@@@@@@@@@ -212,6 -212,7 -212,7 -212,7 -212,7 -212,7 -212,7 -212,7 -212,7 +212,6 @@@@@@@@@@ config SPI_IM
                tristate "Freescale i.MX SPI controllers"
                depends on ARCH_MXC || COMPILE_TEST
                select SPI_BITBANG
 --------       default m if IMX_HAVE_PLATFORM_SPI_IMX
                help
                  This enables using the Freescale i.MX SPI controllers in master
                  mode.
@@@@@@@@@@ -269,7 -270,6 -270,6 -270,6 -270,6 -270,6 -270,6 -270,6 -270,6 +269,7 @@@@@@@@@@ config SPI_FSL_SP
         config SPI_FSL_DSPI
                tristate "Freescale DSPI controller"
                select SPI_BITBANG
 ++++++++       select REGMAP_MMIO
                depends on SOC_VF610 || COMPILE_TEST
                help
                  This enables support for the Freescale DSPI controller in master
@@@@@@@@@@ -307,7 -307,7 -307,7 -307,7 -307,7 -307,7 -307,7 -307,7 -307,7 +307,7 @@@@@@@@@@ config SPI_OMAP_UWIR
         
         config SPI_OMAP24XX
                tristate "McSPI driver for OMAP"
 --------       depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SH
 ++++++++       depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH
                depends on ARCH_OMAP2PLUS || COMPILE_TEST
                help
                  SPI master controller for OMAP24XX and later Multichannel SPI
@@@@@@@@@@ -376,23 -376,10 -376,10 -376,10 -376,10 -376,10 -376,10 -376,10 -376,10 +376,23 @@@@@@@@@@ config SPI_PXA2XX_PC
                def_tristate SPI_PXA2XX && PCI
         
         config SPI_RSPI
 --------       tristate "Renesas RSPI controller"
 ++++++++       tristate "Renesas RSPI/QSPI controller"
                depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE
                help
 --------         SPI driver for Renesas RSPI blocks.
 ++++++++         SPI driver for Renesas RSPI and QSPI blocks.
 ++++++++
 ++++++++config SPI_QUP
 ++++++++       tristate "Qualcomm SPI controller with QUP interface"
 ++++++++       depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
 ++++++++       help
 ++++++++         Qualcomm Universal Peripheral (QUP) core is an AHB slave that
 ++++++++         provides a common data path (an output FIFO and an input FIFO)
 ++++++++         for serial peripheral interface (SPI) mini-core. SPI in master
 ++++++++         mode supports up to 50MHz, up to four chip selects, programmable
 ++++++++         data path from 4 bits to 32 bits and numerous protocol variants.
 ++++++++
 ++++++++         This driver can also be built as a module.  If so, the module
 ++++++++         will be called spi_qup.
         
         config SPI_S3C24XX
                tristate "Samsung S3C24XX series SPI"
@@@@@@@@@@ -429,6 -416,7 -416,7 -416,7 -416,7 -416,7 -416,7 -416,7 -416,7 +429,6 @@@@@@@@@@ config SPI_SH_MSIO
                tristate "SuperH MSIOF SPI controller"
                depends on HAVE_CLK
                depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
 --------       select SPI_BITBANG
                help
                  SPI driver for SuperH and SH Mobile MSIOF blocks.
         
@@@@@@@@@@ -458,6 -446,19 -446,6 -446,6 -446,6 -446,6 -446,6 -446,6 -446,6 +458,19 @@@@@@@@@@ config SPI_SIR
                help
                  SPI driver for CSR SiRFprimaII SoCs
         
+ +++++++config SPI_SUN4I
+ +++++++       tristate "Allwinner A10 SoCs SPI controller"
+ +++++++       depends on ARCH_SUNXI || COMPILE_TEST
+ +++++++       help
+ +++++++         SPI driver for Allwinner sun4i, sun5i and sun7i SoCs
+ +++++++
+ +++++++config SPI_SUN6I
+ +++++++       tristate "Allwinner A31 SPI controller"
+ +++++++       depends on ARCH_SUNXI || COMPILE_TEST
+ +++++++       depends on RESET_CONTROLLER
+ +++++++       help
+ +++++++         This enables using the SPI controller on the Allwinner A31 SoCs.
+ +++++++
         config SPI_MXS
                tristate "Freescale MXS SPI controller"
                depends on ARCH_MXS
@@@@@@@@@@ -490,13 -491,13 -478,13 -478,13 -478,6 -478,13 -478,13 -478,13 -478,13 +503,6 @@@@@@@@@@ config SPI_TEGRA20_SLIN
                help
                  SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
         
---- ----config SPI_TI_SSP
---- ----       tristate "TI Sequencer Serial Port - SPI Support"
---- ----       depends on MFD_TI_SSP
---- ----       help
---- ----         This selects an SPI master implementation using a TI sequencer
---- ----         serial port.
---- ----
         config SPI_TOPCLIFF_PCH
                tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI"
                depends on PCI
@@@@@@@@@@ -558,7 -559,7 -546,7 -546,7 -539,7 -546,7 -546,7 -546,7 -546,7 +564,7 @@@@@@@@@@ config SPI_DW_MID_DM
         
         config SPI_DW_MMIO
                tristate "Memory-mapped io interface driver for DW SPI core"
 --------       depends on SPI_DESIGNWARE && HAVE_CLK
 ++++++++       depends on SPI_DESIGNWARE
         
         #
         # There are lots of SPI device types, with sensors and memory
diff --combined drivers/spi/Makefile
index e598147b06efc15290be8af3e435cdbc3b05204b,65f4993ab083ea629f4ab5185fa8a66ec2b69dd1,95af48d2d360d694e25012c80fa0cf127222db16,95af48d2d360d694e25012c80fa0cf127222db16,7da53afaefdb0d5d594ac004f3c449ceae74213f,95af48d2d360d694e25012c80fa0cf127222db16,95af48d2d360d694e25012c80fa0cf127222db16,95af48d2d360d694e25012c80fa0cf127222db16,95af48d2d360d694e25012c80fa0cf127222db16..e245b94d07d86287e489f8d7825498b2436dd864
@@@@@@@@@@ -59,7 -59,6 -59,6 -59,6 -59,6 -59,6 -59,6 -59,6 -59,6 +59,7 @@@@@@@@@@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX
         spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA)   += spi-pxa2xx-dma.o
         obj-$(CONFIG_SPI_PXA2XX)               += spi-pxa2xx-platform.o
         obj-$(CONFIG_SPI_PXA2XX_PCI)           += spi-pxa2xx-pci.o
 ++++++++obj-$(CONFIG_SPI_QUP)                  += spi-qup.o
         obj-$(CONFIG_SPI_RSPI)                 += spi-rspi.o
         obj-$(CONFIG_SPI_S3C24XX)              += spi-s3c24xx-hw.o
         spi-s3c24xx-hw-y                       := spi-s3c24xx.o
@@@@@@@@@@ -71,10 -70,12 -70,10 -70,10 -70,9 -70,10 -70,10 -70,10 -70,10 +71,11 @@@@@@@@@@ obj-$(CONFIG_SPI_SH_HSPI)            += spi-sh-hs
         obj-$(CONFIG_SPI_SH_MSIOF)             += spi-sh-msiof.o
         obj-$(CONFIG_SPI_SH_SCI)               += spi-sh-sci.o
         obj-$(CONFIG_SPI_SIRF)         += spi-sirf.o
+ +++++++obj-$(CONFIG_SPI_SUN4I)                        += spi-sun4i.o
+ +++++++obj-$(CONFIG_SPI_SUN6I)                        += spi-sun6i.o
         obj-$(CONFIG_SPI_TEGRA114)             += spi-tegra114.o
         obj-$(CONFIG_SPI_TEGRA20_SFLASH)       += spi-tegra20-sflash.o
         obj-$(CONFIG_SPI_TEGRA20_SLINK)                += spi-tegra20-slink.o
---- ----obj-$(CONFIG_SPI_TI_SSP)               += spi-ti-ssp.o
         obj-$(CONFIG_SPI_TLE62X0)              += spi-tle62x0.o
         obj-$(CONFIG_SPI_TOPCLIFF_PCH)         += spi-topcliff-pch.o
         obj-$(CONFIG_SPI_TXX9)                 += spi-txx9.o
index 6be661e4c6e1ec034d4f5d9211a5aab15098d48b,413c718434927f0d3278c051d15040639a68237a,ead3ae89a08f6fb31714b537dc52861ad8159e14,413c718434927f0d3278c051d15040639a68237a,413c718434927f0d3278c051d15040639a68237a,413c718434927f0d3278c051d15040639a68237a,413c718434927f0d3278c051d15040639a68237a,413c718434927f0d3278c051d15040639a68237a,413c718434927f0d3278c051d15040639a68237a..400649595505e874e2b8873e1561a9e33310da56
         #include <linux/dma-mapping.h>
         #include <linux/dmapool.h>
         #include <linux/err.h>
 --------#include <linux/init.h>
         #include <linux/interrupt.h>
         #include <linux/io.h>
         #include <linux/kernel.h>
@@@@@@@@@@ -171,6 -172,7 -172,7 -172,7 -172,7 -172,7 -172,7 -172,7 -172,7 +171,6 @@@@@@@@@@ struct tegra_spi_data 
                void __iomem                            *base;
                phys_addr_t                             phys;
                unsigned                                irq;
 --------       u32                                     spi_max_frequency;
                u32                                     cur_speed;
         
                struct spi_device                       *cur_spi;
@@@@@@@@@@ -759,6 -761,11 -761,11 -761,11 -761,11 -761,11 -761,11 -761,11 -761,11 +759,6 @@@@@@@@@@ static int tegra_spi_setup(struct spi_d
                        spi->mode & SPI_CPHA ? "" : "~",
                        spi->max_speed_hz);
         
 --------       BUG_ON(spi->chip_select >= MAX_CHIP_SELECT);
 --------
 --------       /* Set speed to the spi max fequency if spi device has not set */
 --------       spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency;
 --------
                ret = pm_runtime_get_sync(tspi->dev);
                if (ret < 0) {
                        dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret);
@@@@@@@@@@ -846,8 -853,8 -853,8 -853,8 -853,8 -853,8 -853,8 -853,8 -853,8 +846,8 @@@@@@@@@@ complete_xfer
                                                SPI_COMMAND1);
                                tegra_spi_transfer_delay(xfer->delay_usecs);
                                goto exit;
-- ------               } else if (msg->transfers.prev == &xfer->transfer_list) {
-- ------                       /* This is the last transfer in message */
++ ++++++               } else if (list_is_last(&xfer->transfer_list,
++ ++++++                                       &msg->transfers)) {
                                if (xfer->cs_change)
                                        tspi->cs_control = spi;
                                else {
@@@@@@@@@@ -1012,6 -1019,16 -1019,16 -1019,16 -1019,16 -1019,16 -1019,16 -1019,16 -1019,16 +1012,6 @@@@@@@@@@ static irqreturn_t tegra_spi_isr(int ir
                return IRQ_WAKE_THREAD;
         }
         
 --------static void tegra_spi_parse_dt(struct platform_device *pdev,
 --------       struct tegra_spi_data *tspi)
 --------{
 --------       struct device_node *np = pdev->dev.of_node;
 --------
 --------       if (of_property_read_u32(np, "spi-max-frequency",
 --------                               &tspi->spi_max_frequency))
 --------               tspi->spi_max_frequency = 25000000; /* 25MHz */
 --------}
 --------
         static struct of_device_id tegra_spi_of_match[] = {
                { .compatible = "nvidia,tegra114-spi", },
                {}
@@@@@@@@@@ -1033,15 -1050,15 -1050,15 -1050,15 -1050,15 -1050,15 -1050,15 -1050,15 -1050,15 +1033,15 @@@@@@@@@@ static int tegra_spi_probe(struct platf
                platform_set_drvdata(pdev, master);
                tspi = spi_master_get_devdata(master);
         
 --------       /* Parse DT */
 --------       tegra_spi_parse_dt(pdev, tspi);
 ++++++++       if (of_property_read_u32(pdev->dev.of_node, "spi-max-frequency",
 ++++++++                                &master->max_speed_hz))
 ++++++++               master->max_speed_hz = 25000000; /* 25MHz */
         
                /* the spi->mode bits understood by this driver: */
                master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
                master->setup = tegra_spi_setup;
                master->transfer_one_message = tegra_spi_transfer_one_message;
                master->num_chipselect = MAX_CHIP_SELECT;
 --------       master->bus_num = -1;
                master->auto_runtime_pm = true;
         
                tspi->master = master;
index 49ddfc7f12b10813250271460797daa46b24a49d,3d09265b51335e2cefdf3d098ce177826b150674,3d09265b51335e2cefdf3d098ce177826b150674,66a4029ee0359706af380ae6bd11d4d5715b643c,3d09265b51335e2cefdf3d098ce177826b150674,3d09265b51335e2cefdf3d098ce177826b150674,3d09265b51335e2cefdf3d098ce177826b150674,3d09265b51335e2cefdf3d098ce177826b150674,3d09265b51335e2cefdf3d098ce177826b150674..6c211d1910b084645d19d6eaa8cdcc3aa2f7c1c9
@@@@@@@@@@ -429,13 -429,13 -429,13 -429,13 -429,13 -429,13 -429,13 -429,13 -429,13 +429,13 @@@@@@@@@@ static int ti_qspi_probe(struct platfor
         
                master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
         
 --------       master->bus_num = -1;
                master->flags = SPI_MASTER_HALF_DUPLEX;
                master->setup = ti_qspi_setup;
                master->auto_runtime_pm = true;
                master->transfer_one_message = ti_qspi_start_transfer_one;
                master->dev.of_node = pdev->dev.of_node;
 --------       master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1);
 ++++++++       master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
 ++++++++                                    SPI_BPW_MASK(8);
         
                if (!of_property_read_u32(np, "num-cs", &num_cs))
                        master->num_chipselect = num_cs;
                        if (res_mmap == NULL) {
                                dev_err(&pdev->dev,
                                        "memory mapped resource not required\n");
--- -----                       return -ENODEV;
                        }
                }
         
index 88eb57e858b379ac258abad703bf532b60852669,2e7f38c7a9610b11f63fd36c816f311b3372d66d,2e7f38c7a9610b11f63fd36c816f311b3372d66d,2e7f38c7a9610b11f63fd36c816f311b3372d66d,2e7f38c7a9610b11f63fd36c816f311b3372d66d,8fa1a6cbc42b92e3837173ef3993d87728d418c3,2e7f38c7a9610b11f63fd36c816f311b3372d66d,2e7f38c7a9610b11f63fd36c816f311b3372d66d,2e7f38c7a9610b11f63fd36c816f311b3372d66d..f406b30af961fd8f52e969a665ce46fb7b46352c
@@@@@@@@@@ -332,7 -332,7 -332,7 -332,7 -332,7 -332,7 -332,7 -332,7 -332,7 +332,7 @@@@@@@@@@ static void pch_spi_handler_sub(struct 
                                        data->transfer_active = false;
                                        wake_up(&data->wait);
                                } else {
----- ---                               dev_err(&data->master->dev,
+++++ +++                               dev_vdbg(&data->master->dev,
                                                "%s : Transfer is not completed",
                                                __func__);
                                }
@@@@@@@@@@ -464,20 -464,20 -464,20 -464,20 -464,20 -464,6 -464,20 -464,20 -464,20 +464,6 @@@@@@@@@@ static void pch_spi_reset(struct spi_ma
                pch_spi_writereg(master, PCH_SRST, 0x0);
         }
         
----- ---static int pch_spi_setup(struct spi_device *pspi)
----- ---{
----- ---       /* Check baud rate setting */
----- ---       /* if baud rate of chip is greater than
----- ---          max we can support,return error */
----- ---       if ((pspi->max_speed_hz) > PCH_MAX_BAUDRATE)
----- ---               pspi->max_speed_hz = PCH_MAX_BAUDRATE;
----- ---
----- ---       dev_dbg(&pspi->dev, "%s MODE = %x\n", __func__,
----- ---               (pspi->mode) & (SPI_CPOL | SPI_CPHA));
----- ---
----- ---       return 0;
----- ---}
----- ---
         static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)
         {
         
                int retval;
                unsigned long flags;
         
----- ---       /* validate spi message and baud rate */
----- ---       if (unlikely(list_empty(&pmsg->transfers) == 1)) {
----- ---               dev_err(&pspi->dev, "%s list empty\n", __func__);
----- ---               retval = -EINVAL;
----- ---               goto err_out;
----- ---       }
----- ---
----- ---       if (unlikely(pspi->max_speed_hz == 0)) {
----- ---               dev_err(&pspi->dev, "%s pch_spi_transfer maxspeed=%d\n",
----- ---                       __func__, pspi->max_speed_hz);
----- ---               retval = -EINVAL;
----- ---               goto err_out;
----- ---       }
----- ---
----- ---       dev_dbg(&pspi->dev,
----- ---               "%s Transfer List not empty. Transfer Speed is set.\n", __func__);
----- ---
                spin_lock_irqsave(&data->lock, flags);
                /* validate Tx/Rx buffers and Transfer length */
                list_for_each_entry(transfer, &pmsg->transfers, transfer_list) {
                        dev_dbg(&pspi->dev,
                                "%s Tx/Rx buffer valid. Transfer length valid\n",
                                __func__);
----- ---
----- ---               /* if baud rate has been specified validate the same */
----- ---               if (transfer->speed_hz > PCH_MAX_BAUDRATE)
----- ---                       transfer->speed_hz = PCH_MAX_BAUDRATE;
                }
                spin_unlock_irqrestore(&data->lock, flags);
         
@@@@@@@@@@ -915,7 -915,7 -915,7 -915,7 -915,7 -880,7 -915,7 -915,7 -915,7 +880,7 @@@@@@@@@@ static void pch_spi_request_dma(struct 
                /* Set Tx DMA */
                param = &dma->param_tx;
                param->dma_dev = &dma_dev->dev;
 --------       param->chan_id = data->master->bus_num * 2; /* Tx = 0, 2 */
 ++++++++       param->chan_id = data->ch * 2; /* Tx = 0, 2 */;
                param->tx_reg = data->io_base_addr + PCH_SPDWR;
                param->width = width;
                chan = dma_request_channel(mask, pch_spi_filter, param);
                /* Set Rx DMA */
                param = &dma->param_rx;
                param->dma_dev = &dma_dev->dev;
 --------       param->chan_id = data->master->bus_num * 2 + 1; /* Rx = Tx + 1 */
 ++++++++       param->chan_id = data->ch * 2 + 1; /* Rx = Tx + 1 */;
                param->rx_reg = data->io_base_addr + PCH_SPDRR;
                param->width = width;
                chan = dma_request_channel(mask, pch_spi_filter, param);
@@@@@@@@@@ -1151,8 -1151,8 -1151,8 -1151,8 -1151,8 -1116,7 -1151,8 -1151,8 -1151,8 +1116,7 @@@@@@@@@@ static void pch_spi_handle_dma(struct p
                dma->nent = num;
                dma->desc_tx = desc_tx;
         
----- ---       dev_dbg(&data->master->dev, "\n%s:Pulling down SSN low - writing "
----- ---               "0x2 to SSNXCR\n", __func__);
+++++ +++       dev_dbg(&data->master->dev, "%s:Pulling down SSN low - writing 0x2 to SSNXCR\n", __func__);
         
                spin_lock_irqsave(&data->lock, flags);
                pch_spi_writereg(data->master, PCH_SSNXCR, SSN_LOW);
@@@@@@@@@@ -1418,10 -1418,10 -1418,10 -1418,10 -1418,10 -1382,10 -1418,10 -1418,10 -1418,10 +1382,10 @@@@@@@@@@ static int pch_spi_pd_probe(struct plat
         
                /* initialize members of SPI master */
                master->num_chipselect = PCH_MAX_CS;
----- ---       master->setup = pch_spi_setup;
                master->transfer = pch_spi_transfer;
                master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
                master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+++++ +++       master->max_speed_hz = PCH_MAX_BAUDRATE;
         
                data->board_dat = board_dat;
                data->plat_dev = plat_dev;
         
                pch_spi_set_master_mode(master);
         
 ++++++++       if (use_dma) {
 ++++++++               dev_info(&plat_dev->dev, "Use DMA for data transfers\n");
 ++++++++               pch_alloc_dma_buf(board_dat, data);
 ++++++++       }
 ++++++++
                ret = spi_register_master(master);
                if (ret != 0) {
                        dev_err(&plat_dev->dev,
                        goto err_spi_register_master;
                }
         
 --------       if (use_dma) {
 --------               dev_info(&plat_dev->dev, "Use DMA for data transfers\n");
 --------               pch_alloc_dma_buf(board_dat, data);
 --------       }
 --------
                return 0;
         
         err_spi_register_master:
 ++++++++       pch_free_dma_buf(board_dat, data);
                free_irq(board_dat->pdev->irq, data);
         err_request_irq:
                pch_spi_free_resources(board_dat, data);
@@@@@@@@@@ -1605,8 -1604,8 -1604,8 -1604,8 -1604,8 -1568,7 -1604,8 -1604,8 -1604,8 +1569,7 @@@@@@@@@@ static struct platform_driver pch_spi_p
                .resume = pch_spi_pd_resume
         };
         
----- ---static int pch_spi_probe(struct pci_dev *pdev,
----- ---                                  const struct pci_device_id *id)
+++++ +++static int pch_spi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
         {
                struct pch_spi_board_data *board_dat;
                struct platform_device *pd_dev = NULL;
                return 0;
         
         err_platform_device:
+++++ +++       while (--i >= 0)
+++++ +++               platform_device_unregister(pd_dev_save->pd_save[i]);
                pci_disable_device(pdev);
         pci_enable_device:
                pci_release_regions(pdev);
diff --combined drivers/spi/spi-xcomm.c
index 350a76b7e8d49e86bccbc504da8d508e2f2078ca,24c40b13dab1596edb6756e4f6311523393b418a,24c40b13dab1596edb6756e4f6311523393b418a,24c40b13dab1596edb6756e4f6311523393b418a,24c40b13dab1596edb6756e4f6311523393b418a,24c40b13dab1596edb6756e4f6311523393b418a,24c40b13dab1596edb6756e4f6311523393b418a,2505b7e1232a48be131a838f053ab96268dacb30,24c40b13dab1596edb6756e4f6311523393b418a..bb478dccf1d82dd5d9fb1316bd04cf1755f08f0a
@@@@@@@@@@ -8,6 -8,7 -8,7 -8,7 -8,7 -8,7 -8,7 -8,7 -8,7 +8,6 @@@@@@@@@@
          */
         
         #include <linux/kernel.h>
 --------#include <linux/init.h>
         #include <linux/module.h>
         #include <linux/delay.h>
         #include <linux/i2c.h>
@@@@@@@@@@ -73,15 -74,15 -74,15 -74,15 -74,15 -74,15 -74,15 -74,13 -74,15 +73,13 @@@@@@@@@@ static void spi_xcomm_chipselect(struc
         static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,
                struct spi_device *spi, struct spi_transfer *t, unsigned int *settings)
         {
------- -       unsigned int speed;
------- -
                if (t->len > 62)
                        return -EINVAL;
         
------- -       speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
+++++++ +       if (t->speed_hz != spi_xcomm->current_speed) {
+++++++ +               unsigned int divider;
         
------- -       if (speed != spi_xcomm->current_speed) {
------- -               unsigned int divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, speed);
+++++++ +               divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, t->speed_hz);
                        if (divider >= 64)
                                *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_64;
                        else if (divider >= 16)
                        else
                                *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_4;
         
------- -               spi_xcomm->current_speed = speed;
+++++++ +               spi_xcomm->current_speed = t->speed_hz;
                }
         
                if (spi->mode & SPI_CPOL)
@@@@@@@@@@ -147,8 -148,8 -148,8 -148,8 -148,8 -148,8 -148,8 -146,6 -148,8 +145,6 @@@@@@@@@@ static int spi_xcomm_transfer_one(struc
                int status = 0;
                bool is_last;
         
------- -       is_first = true;
------- -
                spi_xcomm_chipselect(spi_xcomm, spi, true);
         
                list_for_each_entry(t, &msg->transfers, transfer_list) {
diff --combined drivers/spi/spi.c
index ffc1a2ebc4ca979de655b88e54fe8b9a47c0e39e,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,23756b0f90363c2f776718925cf7fba84d13c4a3,516643d243c6dc3576406bad88feb9009aa604a6..4eb9bf02996cf179cf3e6365421867aaf8a10593
         #include <linux/device.h>
         #include <linux/init.h>
         #include <linux/cache.h>
 ++++++++#include <linux/dma-mapping.h>
 ++++++++#include <linux/dmaengine.h>
         #include <linux/mutex.h>
         #include <linux/of_device.h>
         #include <linux/of_irq.h>
@@@@@@@@@@ -257,12 -255,13 -255,13 -255,13 -255,13 -255,13 -255,13 -255,13 -255,13 +257,12 @@@@@@@@@@ EXPORT_SYMBOL_GPL(spi_bus_type)
         static int spi_drv_probe(struct device *dev)
         {
                const struct spi_driver         *sdrv = to_spi_driver(dev->driver);
 --------       struct spi_device               *spi = to_spi_device(dev);
                int ret;
         
 --------       acpi_dev_pm_attach(&spi->dev, true);
 --------       ret = sdrv->probe(spi);
 ++++++++       acpi_dev_pm_attach(dev, true);
 ++++++++       ret = sdrv->probe(to_spi_device(dev));
                if (ret)
 --------               acpi_dev_pm_detach(&spi->dev, true);
 ++++++++               acpi_dev_pm_detach(dev, true);
         
                return ret;
         }
         static int spi_drv_remove(struct device *dev)
         {
                const struct spi_driver         *sdrv = to_spi_driver(dev->driver);
 --------       struct spi_device               *spi = to_spi_device(dev);
                int ret;
         
 --------       ret = sdrv->remove(spi);
 --------       acpi_dev_pm_detach(&spi->dev, true);
 ++++++++       ret = sdrv->remove(to_spi_device(dev));
 ++++++++       acpi_dev_pm_detach(dev, true);
         
                return ret;
         }
@@@@@@@@@@ -580,169 -580,6 -580,6 -580,6 -580,6 -580,6 -580,6 -580,6 -580,6 +580,169 @@@@@@@@@@ static void spi_set_cs(struct spi_devic
                        spi->master->set_cs(spi, !enable);
         }
         
 ++++++++static int spi_map_buf(struct spi_master *master, struct device *dev,
 ++++++++                      struct sg_table *sgt, void *buf, size_t len,
 ++++++++                      enum dma_data_direction dir)
 ++++++++{
 ++++++++       const bool vmalloced_buf = is_vmalloc_addr(buf);
 ++++++++       const int desc_len = vmalloced_buf ? PAGE_SIZE : master->max_dma_len;
 ++++++++       const int sgs = DIV_ROUND_UP(len, desc_len);
 ++++++++       struct page *vm_page;
 ++++++++       void *sg_buf;
 ++++++++       size_t min;
 ++++++++       int i, ret;
 ++++++++
 ++++++++       ret = sg_alloc_table(sgt, sgs, GFP_KERNEL);
 ++++++++       if (ret != 0)
 ++++++++               return ret;
 ++++++++
 ++++++++       for (i = 0; i < sgs; i++) {
 ++++++++               min = min_t(size_t, len, desc_len);
 ++++++++
 ++++++++               if (vmalloced_buf) {
 ++++++++                       vm_page = vmalloc_to_page(buf);
 ++++++++                       if (!vm_page) {
 ++++++++                               sg_free_table(sgt);
 ++++++++                               return -ENOMEM;
 ++++++++                       }
 ++++++++                       sg_buf = page_address(vm_page) +
 ++++++++                               ((size_t)buf & ~PAGE_MASK);
 ++++++++               } else {
 ++++++++                       sg_buf = buf;
 ++++++++               }
 ++++++++
 ++++++++               sg_set_buf(&sgt->sgl[i], sg_buf, min);
 ++++++++
 ++++++++               buf += min;
 ++++++++               len -= min;
 ++++++++       }
 ++++++++
 ++++++++       ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
 ++++++++       if (ret < 0) {
 ++++++++               sg_free_table(sgt);
 ++++++++               return ret;
 ++++++++       }
 ++++++++
 ++++++++       sgt->nents = ret;
 ++++++++
 ++++++++       return 0;
 ++++++++}
 ++++++++
 ++++++++static void spi_unmap_buf(struct spi_master *master, struct device *dev,
 ++++++++                         struct sg_table *sgt, enum dma_data_direction dir)
 ++++++++{
 ++++++++       if (sgt->orig_nents) {
 ++++++++               dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir);
 ++++++++               sg_free_table(sgt);
 ++++++++       }
 ++++++++}
 ++++++++
 ++++++++static int spi_map_msg(struct spi_master *master, struct spi_message *msg)
 ++++++++{
 ++++++++       struct device *tx_dev, *rx_dev;
 ++++++++       struct spi_transfer *xfer;
 ++++++++       void *tmp;
 ++++++++       unsigned int max_tx, max_rx;
 ++++++++       int ret;
 ++++++++
 ++++++++       if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) {
 ++++++++               max_tx = 0;
 ++++++++               max_rx = 0;
 ++++++++
 ++++++++               list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 ++++++++                       if ((master->flags & SPI_MASTER_MUST_TX) &&
 ++++++++                           !xfer->tx_buf)
 ++++++++                               max_tx = max(xfer->len, max_tx);
 ++++++++                       if ((master->flags & SPI_MASTER_MUST_RX) &&
 ++++++++                           !xfer->rx_buf)
 ++++++++                               max_rx = max(xfer->len, max_rx);
 ++++++++               }
 ++++++++
 ++++++++               if (max_tx) {
 ++++++++                       tmp = krealloc(master->dummy_tx, max_tx,
 ++++++++                                      GFP_KERNEL | GFP_DMA);
 ++++++++                       if (!tmp)
 ++++++++                               return -ENOMEM;
 ++++++++                       master->dummy_tx = tmp;
 ++++++++                       memset(tmp, 0, max_tx);
 ++++++++               }
 ++++++++
 ++++++++               if (max_rx) {
 ++++++++                       tmp = krealloc(master->dummy_rx, max_rx,
 ++++++++                                      GFP_KERNEL | GFP_DMA);
 ++++++++                       if (!tmp)
 ++++++++                               return -ENOMEM;
 ++++++++                       master->dummy_rx = tmp;
 ++++++++               }
 ++++++++
 ++++++++               if (max_tx || max_rx) {
 ++++++++                       list_for_each_entry(xfer, &msg->transfers,
 ++++++++                                           transfer_list) {
 ++++++++                               if (!xfer->tx_buf)
 ++++++++                                       xfer->tx_buf = master->dummy_tx;
 ++++++++                               if (!xfer->rx_buf)
 ++++++++                                       xfer->rx_buf = master->dummy_rx;
 ++++++++                       }
 ++++++++               }
 ++++++++       }
 ++++++++
 ++++++++       if (!master->can_dma)
 ++++++++               return 0;
 ++++++++
 ++++++++       tx_dev = &master->dma_tx->dev->device;
 ++++++++       rx_dev = &master->dma_rx->dev->device;
 ++++++++
 ++++++++       list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 ++++++++               if (!master->can_dma(master, msg->spi, xfer))
 ++++++++                       continue;
 ++++++++
 ++++++++               if (xfer->tx_buf != NULL) {
 ++++++++                       ret = spi_map_buf(master, tx_dev, &xfer->tx_sg,
 ++++++++                                         (void *)xfer->tx_buf, xfer->len,
 ++++++++                                         DMA_TO_DEVICE);
 ++++++++                       if (ret != 0)
 ++++++++                               return ret;
 ++++++++               }
 ++++++++
 ++++++++               if (xfer->rx_buf != NULL) {
 ++++++++                       ret = spi_map_buf(master, rx_dev, &xfer->rx_sg,
 ++++++++                                         xfer->rx_buf, xfer->len,
 ++++++++                                         DMA_FROM_DEVICE);
 ++++++++                       if (ret != 0) {
 ++++++++                               spi_unmap_buf(master, tx_dev, &xfer->tx_sg,
 ++++++++                                             DMA_TO_DEVICE);
 ++++++++                               return ret;
 ++++++++                       }
 ++++++++               }
 ++++++++       }
 ++++++++
 ++++++++       master->cur_msg_mapped = true;
 ++++++++
 ++++++++       return 0;
 ++++++++}
 ++++++++
 ++++++++static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
 ++++++++{
 ++++++++       struct spi_transfer *xfer;
 ++++++++       struct device *tx_dev, *rx_dev;
 ++++++++
 ++++++++       if (!master->cur_msg_mapped || !master->can_dma)
 ++++++++               return 0;
 ++++++++
 ++++++++       tx_dev = &master->dma_tx->dev->device;
 ++++++++       rx_dev = &master->dma_rx->dev->device;
 ++++++++
 ++++++++       list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 ++++++++               if (!master->can_dma(master, msg->spi, xfer))
 ++++++++                       continue;
 ++++++++
 ++++++++               spi_unmap_buf(master, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE);
 ++++++++               spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE);
 ++++++++       }
 ++++++++
 ++++++++       return 0;
 ++++++++}
 ++++++++
         /*
          * spi_transfer_one_message - Default implementation of transfer_one_message()
          *
@@@@@@@@@@ -754,8 -591,9 -591,9 -591,9 -591,9 -591,9 -591,9 -591,9 -591,10 +754,9 @@@@@@@@@@ static int spi_transfer_one_message(str
                                            struct spi_message *msg)
         {
                struct spi_transfer *xfer;
 --------       bool cur_cs = true;
                bool keep_cs = false;
                int ret = 0;
++++++++        int ms = 1;
         
                spi_set_cs(msg->spi, true);
         
         
                        if (ret > 0) {
                                ret = 0;
--------                        wait_for_completion(&master->xfer_completion);
++++++++                        ms = xfer->len * 8 * 1000 / xfer->speed_hz;
++++++++                        ms += 10; /* some tolerance */
++++++++ 
++++++++                        ms = wait_for_completion_timeout(&master->xfer_completion,
++++++++                                                         msecs_to_jiffies(ms));
++++++++                }
++++++++ 
++++++++                if (ms == 0) {
++++++++                        dev_err(&msg->spi->dev, "SPI transfer timed out\n");
++++++++                        msg->status = -ETIMEDOUT;
                        }
         
                        trace_spi_transfer_stop(msg, xfer);
                                                 &msg->transfers)) {
                                        keep_cs = true;
                                } else {
 --------                               cur_cs = !cur_cs;
 --------                               spi_set_cs(msg->spi, cur_cs);
 ++++++++                               spi_set_cs(msg->spi, false);
 ++++++++                               udelay(10);
 ++++++++                               spi_set_cs(msg->spi, true);
                                }
                        }
         
@@@@@@@@@@ -849,10 -686,6 -686,6 -686,6 -686,6 -686,6 -686,6 -686,6 -696,6 +859,10 @@@@@@@@@@ static void spi_pump_messages(struct kt
                        }
                        master->busy = false;
                        spin_unlock_irqrestore(&master->queue_lock, flags);
 ++++++++               kfree(master->dummy_rx);
 ++++++++               master->dummy_rx = NULL;
 ++++++++               kfree(master->dummy_tx);
 ++++++++               master->dummy_tx = NULL;
                        if (master->unprepare_transfer_hardware &&
                            master->unprepare_transfer_hardware(master))
                                dev_err(&master->dev,
                        master->cur_msg_prepared = true;
                }
         
 --------       ret = master->transfer_one_message(master, master->cur_msg);
 ++++++++       ret = spi_map_msg(master, master->cur_msg);
                if (ret) {
 --------               dev_err(&master->dev,
 --------                       "failed to transfer one message from queue: %d\n", ret);
                        master->cur_msg->status = ret;
                        spi_finalize_current_message(master);
                        return;
                }
 ++++++++
 ++++++++       ret = master->transfer_one_message(master, master->cur_msg);
 ++++++++       if (ret) {
 ++++++++               dev_err(&master->dev,
 ++++++++                       "failed to transfer one message from queue\n");
 ++++++++               return;
 ++++++++       }
         }
         
         static int spi_init_queue(struct spi_master *master)
@@@@@@@@@@ -1013,8 -841,6 -841,6 -841,6 -841,6 -841,6 -841,6 -841,6 -851,6 +1023,8 @@@@@@@@@@ void spi_finalize_current_message(struc
                queue_kthread_work(&master->kworker, &master->pump_messages);
                spin_unlock_irqrestore(&master->queue_lock, flags);
         
 ++++++++       spi_unmap_msg(master, mesg);
 ++++++++
                if (master->cur_msg_prepared && master->unprepare_message) {
                        ret = master->unprepare_message(master, mesg);
                        if (ret) {
@@@@@@@@@@ -1068,7 -894,7 -894,7 -894,7 -894,7 -894,7 -894,7 -894,7 -904,7 +1078,7 @@@@@@@@@@ static int spi_stop_queue(struct spi_ma
                 */
                while ((!list_empty(&master->queue) || master->busy) && limit--) {
                        spin_unlock_irqrestore(&master->queue_lock, flags);
 --------               msleep(10);
 ++++++++               usleep_range(10000, 11000);
                        spin_lock_irqsave(&master->queue_lock, flags);
                }
         
@@@@@@@@@@ -1548,8 -1374,6 -1374,6 -1374,6 -1374,6 -1374,6 -1374,6 -1374,6 -1384,6 +1558,8 @@@@@@@@@@ int spi_register_master(struct spi_mast
                mutex_init(&master->bus_lock_mutex);
                master->bus_lock_flag = 0;
                init_completion(&master->xfer_completion);
 ++++++++       if (!master->max_dma_len)
 ++++++++               master->max_dma_len = INT_MAX;
         
                /* register the device, then userspace will see it.
                 * registration fails if the bus ID is in use.
@@@@@@@@@@ -1775,9 -1599,6 -1599,6 -1599,6 -1599,6 -1599,6 -1599,6 -1599,6 -1609,6 +1785,9 @@@@@@@@@@ int spi_setup(struct spi_device *spi
                if (!spi->bits_per_word)
                        spi->bits_per_word = 8;
         
 ++++++++       if (!spi->max_speed_hz)
 ++++++++               spi->max_speed_hz = spi->master->max_speed_hz;
 ++++++++
                if (spi->master->setup)
                        status = spi->master->setup(spi);
         
@@@@@@@@@@ -1798,10 -1619,11 -1619,11 -1619,11 -1619,11 -1619,11 -1619,11 -1619,11 -1629,11 +1808,10 @@@@@@@@@@ static int __spi_validate(struct spi_de
         {
                struct spi_master *master = spi->master;
                struct spi_transfer *xfer;
 ++++++++       int w_size;
         
                if (list_empty(&message->transfers))
                        return -EINVAL;
 --------       if (!message->complete)
 --------               return -EINVAL;
         
                /* Half-duplex links include original MicroWire, and ones with
                 * only one data pin like SPI_3WIRE (switches direction) or where
                        message->frame_length += xfer->len;
                        if (!xfer->bits_per_word)
                                xfer->bits_per_word = spi->bits_per_word;
 --------               if (!xfer->speed_hz) {
 ++++++++
 ++++++++               if (!xfer->speed_hz)
                                xfer->speed_hz = spi->max_speed_hz;
 --------                       if (master->max_speed_hz &&
 --------                           xfer->speed_hz > master->max_speed_hz)
 --------                               xfer->speed_hz = master->max_speed_hz;
 --------               }
 ++++++++
 ++++++++               if (master->max_speed_hz &&
 ++++++++                   xfer->speed_hz > master->max_speed_hz)
 ++++++++                       xfer->speed_hz = master->max_speed_hz;
         
                        if (master->bits_per_word_mask) {
                                /* Only 32 bits fit in the mask */
                                        return -EINVAL;
                        }
         
 ++++++++               /*
 ++++++++                * SPI transfer length should be multiple of SPI word size
 ++++++++                * where SPI word size should be power-of-two multiple
 ++++++++                */
 ++++++++               if (xfer->bits_per_word <= 8)
 ++++++++                       w_size = 1;
 ++++++++               else if (xfer->bits_per_word <= 16)
 ++++++++                       w_size = 2;
 ++++++++               else
 ++++++++                       w_size = 4;
 ++++++++
 ++++++++               /* No partial transfers accepted */
 ++++++++               if (xfer->len % w_size)
 ++++++++                       return -EINVAL;
 ++++++++
                        if (xfer->speed_hz && master->min_speed_hz &&
                            xfer->speed_hz < master->min_speed_hz)
                                return -EINVAL;
 --------               if (xfer->speed_hz && master->max_speed_hz &&
 --------                   xfer->speed_hz > master->max_speed_hz)
 --------                       return -EINVAL;
         
                        if (xfer->tx_buf && !xfer->tx_nbits)
                                xfer->tx_nbits = SPI_NBITS_SINGLE;