Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/omap100k', 'spi...
authorMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:51:27 +0000 (00:51 +0000)
committerMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:51:27 +0000 (00:51 +0000)
1  2  3  4  5  6  7  8  9 
drivers/spi/Kconfig
drivers/spi/spi-omap-uwire.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-orion.c
drivers/spi/spi-pl022.c
drivers/spi/spi-s3c24xx.c

diff --combined drivers/spi/Kconfig
@@@@@@@@@@ -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,11 -376,11 -376,11 -376,11 -376,11 -376,11 -376,24 -376,11 -376,11 +376,24 @@@@@@@@@@ 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"
                depends on ARCH_S3C24XX
@@@@@@@@@@ -456,7 -456,7 -456,7 -456,7 -456,7 -456,7 -469,7 -456,6 -456,7 +469,7 @@@@@@@@@@ config SPI_MX
         config SPI_TEGRA114
                tristate "NVIDIA Tegra114 SPI Controller"
                depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
       +        depends on RESET_CONTROLLER
                help
                  SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
                  is different than the older SoCs SPI controller and also register interface
         config SPI_TEGRA20_SFLASH
                tristate "Nvidia Tegra20 Serial flash Controller"
                depends on ARCH_TEGRA || COMPILE_TEST
       +        depends on RESET_CONTROLLER
                help
                  SPI driver for Nvidia Tegra20 Serial flash Controller interface.
                  The main usecase of this controller is to use spi flash as boot
         config SPI_TEGRA20_SLINK
                tristate "Nvidia Tegra20/Tegra30 SLINK Controller"
                depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
       +        depends on RESET_CONTROLLER
                help
                  SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
         
@@@@@@@@@@ -546,7 -546,7 -546,7 -546,7 -546,7 -546,7 -559,7 -543,7 -546,7 +559,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
@@@@@@@@@@ -99,7 -99,6 -99,7 -99,7 -99,7 -99,7 -99,7 -99,7 -99,7 +99,6 @@@@@@@@@@ struct uwire_spi 
         };
         
         struct uwire_state {
- -------       unsigned        bits_per_word;
                unsigned        div1_idx;
         };
         
@@@@@@@@@@ -210,9 -209,8 -210,9 -210,9 -210,9 -210,9 -210,9 -210,9 -210,9 +209,8 @@@@@@@@@@ static void uwire_chipselect(struct spi
         
         static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
         {
- -------       struct uwire_state *ust = spi->controller_state;
                unsigned        len = t->len;
- -------       unsigned        bits = ust->bits_per_word;
+ +++++++       unsigned        bits = t->bits_per_word ? : spi->bits_per_word;
                unsigned        bytes;
                u16             val, w;
                int             status = 0;
                if (!t->tx_buf && !t->rx_buf)
                        return 0;
         
- -------       /* Microwire doesn't read and write concurrently */
- -------       if (t->tx_buf && t->rx_buf)
- -------               return -EPERM;
- -------
                w = spi->chip_select << 10;
                w |= CS_CMD;
         
@@@@@@@@@@ -322,7 -316,6 -322,7 -322,7 -322,7 -322,7 -322,7 -322,7 -322,7 +316,6 @@@@@@@@@@ static int uwire_setup_transfer(struct 
                struct uwire_state      *ust = spi->controller_state;
                struct uwire_spi        *uwire;
                unsigned                flags = 0;
- -------       unsigned                bits;
                unsigned                hz;
                unsigned long           rate;
                int                     div1_idx;
         
                uwire = spi_master_get_devdata(spi->master);
         
  -------       if (spi->chip_select > 3) {
  -------               pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select);
  -------               status = -ENODEV;
  -------               goto done;
  -------       }
  -------
- -------       bits = spi->bits_per_word;
- -------       if (t != NULL && t->bits_per_word)
- -------               bits = t->bits_per_word;
- -------
- -------       if (bits > 16) {
- -------               pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
- -------               status = -ENODEV;
- -------               goto done;
- -------       }
- -------       ust->bits_per_word = bits;
- -------
                /* mode 0..3, clock inverted separately;
                 * standard nCS signaling;
                 * don't treat DI=high as "not ready"
@@@@@@@@@@ -496,6 -478,7 -502,6 -502,6 -502,6 -502,6 -502,6 -502,6 -502,6 +478,7 @@@@@@@@@@ static int uwire_probe(struct platform_
                        status = PTR_ERR(uwire->ck);
                        dev_dbg(&pdev->dev, "no functional clock?\n");
                        spi_master_put(master);
+ +++++++               iounmap(uwire_base);
                        return status;
                }
                clk_enable(uwire->ck);
         
                /* the spi->mode bits understood by this driver: */
                master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
- -------
+ +++++++       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
                master->flags = SPI_MASTER_HALF_DUPLEX;
         
                master->bus_num = 2;    /* "official" */
         static int uwire_remove(struct platform_device *pdev)
         {
                struct uwire_spi        *uwire = platform_get_drvdata(pdev);
 --------       int                     status;
         
                // FIXME remove all child devices, somewhere ...
         
 --------       status = spi_bitbang_stop(&uwire->bitbang);
 ++++++++       spi_bitbang_stop(&uwire->bitbang);
                uwire_off(uwire);
                iounmap(uwire_base);
 --------       return status;
 ++++++++       return 0;
         }
         
         /* work with hotplug and coldplug */
          */
         
         #include <linux/kernel.h>
 --------#include <linux/init.h>
         #include <linux/interrupt.h>
         #include <linux/module.h>
         #include <linux/device.h>
         #include <linux/platform_data/spi-omap2-mcspi.h>
         
         #define OMAP2_MCSPI_MAX_FREQ           48000000
+++ +++++#define OMAP2_MCSPI_MAX_DIVIDER                4096
         #define OMAP2_MCSPI_MAX_FIFODEPTH      64
         #define OMAP2_MCSPI_MAX_FIFOWCNT       0xFFFF
         #define SPI_AUTOSUSPEND_TIMEOUT                2000
         #define OMAP2_MCSPI_CHCONF_FORCE       BIT(20)
         #define OMAP2_MCSPI_CHCONF_FFET                BIT(27)
         #define OMAP2_MCSPI_CHCONF_FFER                BIT(28)
+++ +++++#define OMAP2_MCSPI_CHCONF_CLKG                BIT(29)
         
         #define OMAP2_MCSPI_CHSTAT_RXS         BIT(0)
         #define OMAP2_MCSPI_CHSTAT_TXS         BIT(1)
         #define OMAP2_MCSPI_CHSTAT_TXFFE       BIT(3)
         
         #define OMAP2_MCSPI_CHCTRL_EN          BIT(0)
+++ +++++#define OMAP2_MCSPI_CHCTRL_EXTCLK_MASK (0xff << 8)
         
         #define OMAP2_MCSPI_WAKEUPENABLE_WKEN  BIT(0)
         
@@@@@@@@@@ -148,7 -149,7 -149,7 -152,7 -149,7 -149,7 -149,7 -149,7 -149,7 +151,7 @@@@@@@@@@ struct omap2_mcspi_cs 
                int                     word_len;
                struct list_head        node;
                /* Context save and restore shadow register */
--- -----       u32                     chconf0;
+++ +++++       u32                     chconf0, chctrl0;
         };
         
         static inline void mcspi_write_reg(struct spi_master *master,
@@@@@@@@@@ -229,10 -230,10 -230,10 -233,16 -230,10 -230,10 -230,10 -230,10 -230,10 +232,16 @@@@@@@@@@ static void omap2_mcspi_set_dma_req(con
         
         static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
         {
+++ +++++       struct omap2_mcspi_cs *cs = spi->controller_state;
                u32 l;
         
--- -----       l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0;
--- -----       mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l);
+++ +++++       l = cs->chctrl0;
+++ +++++       if (enable)
+++ +++++               l |= OMAP2_MCSPI_CHCTRL_EN;
+++ +++++       else
+++ +++++               l &= ~OMAP2_MCSPI_CHCTRL_EN;
+++ +++++       cs->chctrl0 = l;
+++ +++++       mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
                /* Flash post-writes */
                mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
         }
@@@@@@@@@@ -839,7 -840,7 -840,7 -849,7 -840,7 -840,7 -840,7 -840,7 -840,7 +848,7 @@@@@@@@@@ static int omap2_mcspi_setup_transfer(s
                struct omap2_mcspi_cs *cs = spi->controller_state;
                struct omap2_mcspi *mcspi;
                struct spi_master *spi_cntrl;
--- -----       u32 l = 0, div = 0;
+++ +++++       u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0;
                u8 word_len = spi->bits_per_word;
                u32 speed_hz = spi->max_speed_hz;
         
                        speed_hz = t->speed_hz;
         
                speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
--- -----       div = omap2_mcspi_calc_divisor(speed_hz);
+++ +++++       if (speed_hz < (OMAP2_MCSPI_MAX_FREQ / OMAP2_MCSPI_MAX_DIVIDER)) {
+++ +++++               clkd = omap2_mcspi_calc_divisor(speed_hz);
+++ +++++               speed_hz = OMAP2_MCSPI_MAX_FREQ >> clkd;
+++ +++++               clkg = 0;
+++ +++++       } else {
+++ +++++               div = (OMAP2_MCSPI_MAX_FREQ + speed_hz - 1) / speed_hz;
+++ +++++               speed_hz = OMAP2_MCSPI_MAX_FREQ / div;
+++ +++++               clkd = (div - 1) & 0xf;
+++ +++++               extclk = (div - 1) >> 4;
+++ +++++               clkg = OMAP2_MCSPI_CHCONF_CLKG;
+++ +++++       }
         
                l = mcspi_cached_chconf0(spi);
         
         
                /* set clock divisor */
                l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
--- -----       l |= div << 2;
+++ +++++       l |= clkd << 2;
+++ +++++
+++ +++++       /* set clock granularity */
+++ +++++       l &= ~OMAP2_MCSPI_CHCONF_CLKG;
+++ +++++       l |= clkg;
+++ +++++       if (clkg) {
+++ +++++               cs->chctrl0 &= ~OMAP2_MCSPI_CHCTRL_EXTCLK_MASK;
+++ +++++               cs->chctrl0 |= extclk << 8;
+++ +++++               mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
+++ +++++       }
         
                /* set SPI mode 0..3 */
                if (spi->mode & SPI_CPOL)
                mcspi_write_chconf0(spi, l);
         
                dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
--- -----                       OMAP2_MCSPI_MAX_FREQ >> div,
+++ +++++                       speed_hz,
                                (spi->mode & SPI_CPHA) ? "trailing" : "leading",
                                (spi->mode & SPI_CPOL) ? "inverted" : "normal");
         
@@@@@@@@@@ -971,6 -972,6 -972,6 -1000,7 -972,6 -972,6 -972,6 -972,6 -972,6 +999,7 @@@@@@@@@@ static int omap2_mcspi_setup(struct spi
                        cs->base = mcspi->base + spi->chip_select * 0x14;
                        cs->phys = mcspi->phys + spi->chip_select * 0x14;
                        cs->chconf0 = 0;
+++ +++++               cs->chctrl0 = 0;
                        spi->controller_state = cs;
                        /* Link this to context save list */
                        list_add_tail(&cs->node, &ctx->cs);
@@@@@@@@@@ -1056,12 -1057,12 -1057,12 -1086,15 -1057,12 -1057,12 -1057,12 -1057,12 -1057,12 +1085,15 @@@@@@@@@@ static void omap2_mcspi_work(struct oma
                                status = -EINVAL;
                                break;
                        }
--- -----               if (par_override || t->speed_hz || t->bits_per_word) {
+++ +++++               if (par_override ||
+++ +++++                   (t->speed_hz != spi->max_speed_hz) ||
+++ +++++                   (t->bits_per_word != spi->bits_per_word)) {
                                par_override = 1;
                                status = omap2_mcspi_setup_transfer(spi, t);
                                if (status < 0)
                                        break;
--- -----                       if (!t->speed_hz && !t->bits_per_word)
+++ +++++                       if (t->speed_hz == spi->max_speed_hz &&
+++ +++++                           t->bits_per_word == spi->bits_per_word)
                                        par_override = 0;
                        }
                        if (cd && cd->cs_per_word) {
@@@@@@@@@@ -1175,16 -1176,16 -1176,16 -1208,12 -1176,16 -1176,16 -1176,16 -1176,16 -1176,16 +1207,12 @@@@@@@@@@ static int omap2_mcspi_transfer_one_mes
                m->actual_length = 0;
                m->status = 0;
         
--- -----       /* reject invalid messages and transfers */
--- -----       if (list_empty(&m->transfers))
--- -----               return -EINVAL;
                list_for_each_entry(t, &m->transfers, transfer_list) {
                        const void      *tx_buf = t->tx_buf;
                        void            *rx_buf = t->rx_buf;
                        unsigned        len = t->len;
         
--- -----               if (t->speed_hz > OMAP2_MCSPI_MAX_FREQ
--- -----                               || (len && !(rx_buf || tx_buf))) {
+++ +++++               if ((len && !(rx_buf || tx_buf))) {
                                dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
                                                t->speed_hz,
                                                len,
                                                t->bits_per_word);
                                return -EINVAL;
                        }
--- -----               if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
--- -----                       dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n",
--- -----                                       t->speed_hz,
--- -----                                       OMAP2_MCSPI_MAX_FREQ >> 15);
--- -----                       return -EINVAL;
--- -----               }
         
                        if (m->is_dma_mapped || len < DMA_MIN_BYTES)
                                continue;
@@@@@@@@@@ -1310,6 -1311,6 -1311,6 -1333,8 -1311,6 -1311,6 -1311,6 -1311,6 -1311,6 +1332,8 @@@@@@@@@@ static int omap2_mcspi_probe(struct pla
                master->transfer_one_message = omap2_mcspi_transfer_one_message;
                master->cleanup = omap2_mcspi_cleanup;
                master->dev.of_node = node;
+++ +++++       master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
+++ +++++       master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
         
                platform_set_drvdata(pdev, master);
         
diff --combined drivers/spi/spi-orion.c
@@@@@@@@@@ -9,6 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 +9,6 @@@@@@@@@@
          * published by the Free Software Foundation.
          */
         
 --------#include <linux/init.h>
         #include <linux/interrupt.h>
         #include <linux/delay.h>
         #include <linux/platform_device.h>
         struct orion_spi {
                struct spi_master       *master;
                void __iomem            *base;
---- ----       unsigned int            max_speed;
---- ----       unsigned int            min_speed;
                struct clk              *clk;
         };
         
@@@@@@@@@@ -74,23 -75,23 -75,23 -75,23 -73,6 -75,23 -75,23 -75,23 -75,23 +72,6 @@@@@@@@@@ orion_spi_clrbits(struct orion_spi *ori
                writel(val, reg_addr);
         }
         
---- ----static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size)
---- ----{
---- ----       if (size == 16) {
---- ----               orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
---- ----                                 ORION_SPI_IF_8_16_BIT_MODE);
---- ----       } else if (size == 8) {
---- ----               orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
---- ----                                 ORION_SPI_IF_8_16_BIT_MODE);
---- ----       } else {
---- ----               pr_debug("Bad bits per word value %d (only 8 or 16 are allowed).\n",
---- ----                       size);
---- ----               return -EINVAL;
---- ----       }
---- ----
---- ----       return 0;
---- ----}
---- ----
         static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
         {
                u32 tclk_hz;
@@@@@@@@@@ -169,7 -170,7 -170,7 -170,7 -151,14 -170,7 -170,7 -170,7 -170,7 +150,14 @@@@@@@@@@ orion_spi_setup_transfer(struct spi_dev
                if (rc)
                        return rc;
         
---- ----       return orion_spi_set_transfer_size(orion_spi, bits_per_word);
++++ ++++       if (bits_per_word == 16)
++++ ++++               orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
++++ ++++                                 ORION_SPI_IF_8_16_BIT_MODE);
++++ ++++       else
++++ ++++               orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
++++ ++++                                 ORION_SPI_IF_8_16_BIT_MODE);
++++ ++++
++++ ++++       return 0;
         }
         
         static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
@@@@@@@@@@ -259,11 -260,11 -260,11 -260,11 -248,9 -260,11 -260,11 -260,11 -260,11 +247,9 @@@@@@@@@@ orion_spi_write_read_16bit(struct spi_d
         static unsigned int
         orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
         {
---- ----       struct orion_spi *orion_spi;
                unsigned int count;
                int word_len;
         
---- ----       orion_spi = spi_master_get_devdata(spi->master);
                word_len = spi->bits_per_word;
                count = xfer->len;
         
@@@@@@@@@@ -309,27 -310,27 -310,27 -310,27 -296,6 -310,27 -310,27 -310,27 -310,27 +295,6 @@@@@@@@@@ static int orion_spi_transfer_one_messa
                        goto msg_done;
         
                list_for_each_entry(t, &m->transfers, transfer_list) {
---- ----               /* make sure buffer length is even when working in 16
---- ----                * bit mode*/
---- ----               if ((t->bits_per_word == 16) && (t->len & 1)) {
---- ----                       dev_err(&spi->dev,
---- ----                               "message rejected : "
---- ----                               "odd data length %d while in 16 bit mode\n",
---- ----                               t->len);
---- ----                       status = -EIO;
---- ----                       goto msg_done;
---- ----               }
---- ----
---- ----               if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
---- ----                       dev_err(&spi->dev,
---- ----                               "message rejected : "
---- ----                               "device min speed (%d Hz) exceeds "
---- ----                               "required transfer speed (%d Hz)\n",
---- ----                               orion_spi->min_speed, t->speed_hz);
---- ----                       status = -EIO;
---- ----                       goto msg_done;
---- ----               }
---- ----
                        if (par_override || t->speed_hz || t->bits_per_word) {
                                par_override = 1;
                                status = orion_spi_setup_transfer(spi, t);
@@@@@@@@@@ -374,28 -375,28 -375,28 -375,28 -340,6 -375,28 -375,28 -375,28 -375,28 +339,6 @@@@@@@@@@ static int orion_spi_reset(struct orion
                return 0;
         }
         
---- ----static int orion_spi_setup(struct spi_device *spi)
---- ----{
---- ----       struct orion_spi *orion_spi;
---- ----
---- ----       orion_spi = spi_master_get_devdata(spi->master);
---- ----
---- ----       if ((spi->max_speed_hz == 0)
---- ----                       || (spi->max_speed_hz > orion_spi->max_speed))
---- ----               spi->max_speed_hz = orion_spi->max_speed;
---- ----
---- ----       if (spi->max_speed_hz < orion_spi->min_speed) {
---- ----               dev_err(&spi->dev, "setup: requested speed too low %d Hz\n",
---- ----                       spi->max_speed_hz);
---- ----               return -EINVAL;
---- ----       }
---- ----
---- ----       /*
---- ----        * baudrate & width will be set orion_spi_setup_transfer
---- ----        */
---- ----       return 0;
---- ----}
---- ----
         static int orion_spi_probe(struct platform_device *pdev)
         {
                struct spi_master *master;
                /* we support only mode 0, and no options */
                master->mode_bits = SPI_CPHA | SPI_CPOL;
         
---- ----       master->setup = orion_spi_setup;
                master->transfer_one_message = orion_spi_transfer_one_message;
                master->num_chipselect = ORION_NUM_CHIPSELECTS;
++++ ++++       master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
         
                platform_set_drvdata(pdev, master);
         
                clk_prepare(spi->clk);
                clk_enable(spi->clk);
                tclk_hz = clk_get_rate(spi->clk);
---- ----       spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
---- ----       spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
++++ ++++       master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4);
++++ ++++       master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30);
         
                r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                spi->base = devm_ioremap_resource(&pdev->dev, r);
diff --combined drivers/spi/spi-pl022.c
@@@@@@@@@@ -459,8 -459,9 -459,9 -459,9 -459,9 -459,9 -459,9 -459,9 -459,9 +459,8 @@@@@@@@@@ static void giveback(struct pl022 *pl02
                struct spi_transfer *last_transfer;
                pl022->next_msg_cs_active = false;
         
 --------       last_transfer = list_entry(pl022->cur_msg->transfers.prev,
 --------                                       struct spi_transfer,
 --------                                       transfer_list);
 ++++++++       last_transfer = list_last_entry(&pl022->cur_msg->transfers,
 ++++++++                                       struct spi_transfer, transfer_list);
         
                /* Delay if requested before any change in chip select */
                if (last_transfer->delay_usecs)
@@@@@@@@@@ -2108,8 -2109,8 -2109,8 -2109,8 -2109,8 -2109,6 -2109,8 -2109,8 -2109,8 +2108,6 @@@@@@@@@@ static int pl022_probe(struct amba_devi
                pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
                                                  GFP_KERNEL);
         
----- ---       pinctrl_pm_select_default_state(dev);
----- ---
                /*
                 * Bus Number Which has been Assigned to this SSP controller
                 * on this board
                        goto err_no_clk;
                }
         
----- ---       status = clk_prepare(pl022->clk);
----- ---       if (status) {
----- ---               dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
----- ---               goto  err_clk_prep;
----- ---       }
----- ---
----- ---       status = clk_enable(pl022->clk);
+++++ +++       status = clk_prepare_enable(pl022->clk);
                if (status) {
                        dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
                        goto err_no_clk_en;
                if (platform_info->enable_dma)
                        pl022_dma_remove(pl022);
          err_no_irq:
----- ---       clk_disable(pl022->clk);
+++++ +++       clk_disable_unprepare(pl022->clk);
          err_no_clk_en:
----- ---       clk_unprepare(pl022->clk);
----- --- err_clk_prep:
          err_no_clk:
          err_no_ioremap:
                amba_release_regions(adev);
@@@@@@@@@@ -2280,42 -2281,42 -2281,42 -2281,42 -2281,42 -2271,13 -2281,42 -2281,42 -2281,42 +2270,13 @@@@@@@@@@ pl022_remove(struct amba_device *adev
                if (pl022->master_info->enable_dma)
                        pl022_dma_remove(pl022);
         
----- ---       clk_disable(pl022->clk);
----- ---       clk_unprepare(pl022->clk);
+++++ +++       clk_disable_unprepare(pl022->clk);
                amba_release_regions(adev);
                tasklet_disable(&pl022->pump_transfers);
                return 0;
         }
         
----- ---#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
----- ---/*
----- --- * These two functions are used from both suspend/resume and
----- --- * the runtime counterparts to handle external resources like
----- --- * clocks, pins and regulators when going to sleep.
----- --- */
----- ---static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
----- ---{
----- ---       clk_disable(pl022->clk);
----- ---
----- ---       if (runtime)
----- ---               pinctrl_pm_select_idle_state(&pl022->adev->dev);
----- ---       else
----- ---               pinctrl_pm_select_sleep_state(&pl022->adev->dev);
----- ---}
----- ---
----- ---static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
----- ---{
----- ---       /* First go to the default state */
----- ---       pinctrl_pm_select_default_state(&pl022->adev->dev);
----- ---       if (!runtime)
----- ---               /* Then let's idle the pins until the next transfer happens */
----- ---               pinctrl_pm_select_idle_state(&pl022->adev->dev);
----- ---
----- ---       clk_enable(pl022->clk);
----- ---}
----- ---#endif
----- ---
----- ---#ifdef CONFIG_SUSPEND
+++++ +++#ifdef CONFIG_PM_SLEEP
         static int pl022_suspend(struct device *dev)
         {
                struct pl022 *pl022 = dev_get_drvdata(dev);
                        return ret;
                }
         
----- ---       pm_runtime_get_sync(dev);
----- ---       pl022_suspend_resources(pl022, false);
+++++ +++       ret = pm_runtime_force_suspend(dev);
+++++ +++       if (ret) {
+++++ +++               spi_master_resume(pl022->master);
+++++ +++               return ret;
+++++ +++       }
+++++ +++
+++++ +++       pinctrl_pm_select_sleep_state(dev);
         
                dev_dbg(dev, "suspended\n");
                return 0;
@@@@@@@@@@ -2339,8 -2340,8 -2340,8 -2340,8 -2340,8 -2306,9 -2340,8 -2340,8 -2340,8 +2305,9 @@@@@@@@@@ static int pl022_resume(struct device *
                struct pl022 *pl022 = dev_get_drvdata(dev);
                int ret;
         
----- ---       pl022_resume_resources(pl022, false);
----- ---       pm_runtime_put(dev);
+++++ +++       ret = pm_runtime_force_resume(dev);
+++++ +++       if (ret)
+++++ +++               dev_err(dev, "problem resuming\n");
         
                /* Start the queue running */
                ret = spi_master_resume(pl022->master);
         
                return ret;
         }
----- ---#endif /* CONFIG_PM */
+++++ +++#endif
         
----- ---#ifdef CONFIG_PM_RUNTIME
+++++ +++#ifdef CONFIG_PM
         static int pl022_runtime_suspend(struct device *dev)
         {
                struct pl022 *pl022 = dev_get_drvdata(dev);
         
----- ---       pl022_suspend_resources(pl022, true);
+++++ +++       clk_disable_unprepare(pl022->clk);
+++++ +++       pinctrl_pm_select_idle_state(dev);
+++++ +++
                return 0;
         }
         
@@@@@@@@@@ -2366,14 -2367,14 -2367,14 -2367,14 -2367,14 -2336,16 -2367,14 -2367,14 -2367,14 +2335,16 @@@@@@@@@@ static int pl022_runtime_resume(struct 
         {
                struct pl022 *pl022 = dev_get_drvdata(dev);
         
----- ---       pl022_resume_resources(pl022, true);
+++++ +++       pinctrl_pm_select_default_state(dev);
+++++ +++       clk_prepare_enable(pl022->clk);
+++++ +++
                return 0;
         }
         #endif
         
         static const struct dev_pm_ops pl022_dev_pm_ops = {
                SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
----- ---       SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+++++ +++       SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
         };
         
         static struct vendor_data vendor_arm = {
@@@@@@@@@@ -9,6 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 -9,7 +9,6 @@@@@@@@@@
          *
         */
         
 --------#include <linux/init.h>
         #include <linux/spinlock.h>
         #include <linux/workqueue.h>
         #include <linux/interrupt.h>
@@@@@@@@@@ -122,25 -123,25 -123,25 -123,25 -123,25 -123,25 -123,25 -123,25 -123,15 +122,15 @@@@@@@@@@ static int s3c24xx_spi_update_state(str
         {
                struct s3c24xx_spi *hw = to_hw(spi);
                struct s3c24xx_spi_devstate *cs = spi->controller_state;
--------        unsigned int bpw;
                unsigned int hz;
                unsigned int div;
                unsigned long clk;
         
--------        bpw = t ? t->bits_per_word : spi->bits_per_word;
                hz  = t ? t->speed_hz : spi->max_speed_hz;
         
--------        if (!bpw)
--------                bpw = 8;
-------- 
                if (!hz)
                        hz = spi->max_speed_hz;
         
--------        if (bpw != 8) {
--------                dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
--------                return -EINVAL;
--------        }
-------- 
                if (spi->mode != cs->mode) {
                        u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
         
@@@@@@@@@@ -543,6 -544,6 -544,6 -544,6 -544,6 -544,6 -544,6 -544,6 -534,7 +533,7 @@@@@@@@@@ static int s3c24xx_spi_probe(struct pla
         
                master->num_chipselect = hw->pdata->num_cs;
                master->bus_num = pdata->bus_num;
++++++++        master->bits_per_word_mask = SPI_BPW_MASK(8);
         
                /* setup the state for the bitbang driver */
         
@@@@@@@@@@ -642,6 -643,6 -643,6 -643,6 -643,6 -643,6 -643,6 -643,6 -634,11 +633,11 @@@@@@@@@@ static int s3c24xx_spi_remove(struct pl
         static int s3c24xx_spi_suspend(struct device *dev)
         {
                struct s3c24xx_spi *hw = dev_get_drvdata(dev);
++++++++        int ret;
++++++++ 
++++++++        ret = spi_master_suspend(hw->master);
++++++++        if (ret)
++++++++                return ret;
         
                if (hw->pdata && hw->pdata->gpio_setup)
                        hw->pdata->gpio_setup(hw->pdata, 0);
@@@@@@@@@@ -655,7 -656,7 -656,7 -656,7 -656,7 -656,7 -656,7 -656,7 -652,7 +651,7 @@@@@@@@@@ static int s3c24xx_spi_resume(struct de
                struct s3c24xx_spi *hw = dev_get_drvdata(dev);
         
                s3c24xx_spi_initialsetup(hw);
--------        return 0;
++++++++        return spi_master_resume(hw->master);
         }
         
         static const struct dev_pm_ops s3c24xx_spi_pmops = {