Merge remote-tracking branches 'spi/topic/res', 'spi/topic/rockchip', 'spi/topic...
authorMark Brown <broonie@kernel.org>
Fri, 11 Mar 2016 07:28:53 +0000 (14:28 +0700)
committerMark Brown <broonie@kernel.org>
Fri, 11 Mar 2016 07:28:53 +0000 (14:28 +0700)
1  2  3  4  5  6 
drivers/spi/Kconfig
drivers/spi/spi-rockchip.c
include/linux/spi/spi.h

diff --combined drivers/spi/Kconfig
index c2a0404923f9890ed5fafde8eb5071af1737f8eb,77064160dd762c26f6c1fd184b252b24360163e3,77064160dd762c26f6c1fd184b252b24360163e3,496e48131db4759a046822534c171fa5b9017f52,77064160dd762c26f6c1fd184b252b24360163e3,77064160dd762c26f6c1fd184b252b24360163e3..9d8c84bb15446a75153d64f94a5900ab165193ac
@@@@@@@ -75,26 -75,11 -75,11 -75,11 -75,11 -75,11 +75,26 @@@@@@@ config SPI_ATME
          This selects a driver for the Atmel SPI Controller, present on
          many AT32 (AVR32) and AT91 (ARM) chips.
      
 +++++config SPI_AU1550
 +++++  tristate "Au1550/Au1200/Au1300 SPI Controller"
 +++++  depends on MIPS_ALCHEMY
 +++++  select SPI_BITBANG
 +++++  help
 +++++    If you say yes to this option, support will be included for the
 +++++    PSC SPI controller found on Au1550, Au1200 and Au1300 series.
 +++++
 +++++config SPI_AXI_SPI_ENGINE
 +++++  tristate "Analog Devices AXI SPI Engine controller"
 +++++  depends on HAS_IOMEM
 +++++  help
 +++++    This enables support for the Analog Devices AXI SPI Engine SPI controller.
 +++++    It is part of the SPI Engine framework that is used in some Analog Devices
 +++++    reference designs for FPGAs.
 +++++
      config SPI_BCM2835
        tristate "BCM2835 SPI controller"
        depends on GPIOLIB
        depends on ARCH_BCM2835 || COMPILE_TEST
 -----  depends on GPIOLIB
        help
          This selects a driver for the Broadcom BCM2835 SPI master.
      
      
      config SPI_BCM2835AUX
        tristate "BCM2835 SPI auxiliary controller"
 -----  depends on ARCH_BCM2835 || COMPILE_TEST
 -----  depends on GPIOLIB
 +++++  depends on (ARCH_BCM2835 && GPIOLIB) || COMPILE_TEST
        help
          This selects a driver for the Broadcom BCM2835 SPI aux master.
      
@@@@@@@ -132,6 -118,14 -118,14 -118,14 -118,14 -118,14 +132,6 @@@@@@@ config SPI_BFIN_SPOR
        help
          Enable support for a SPI bus via the Blackfin SPORT peripheral.
      
 -----config SPI_AU1550
 -----  tristate "Au1550/Au1200/Au1300 SPI Controller"
 -----  depends on MIPS_ALCHEMY
 -----  select SPI_BITBANG
 -----  help
 -----    If you say yes to this option, support will be included for the
 -----    PSC SPI controller found on Au1550, Au1200 and Au1300 series.
 -----
      config SPI_BCM53XX
        tristate "Broadcom BCM53xx SPI controller"
        depends on ARCH_BCM_5301X
@@@@@@@ -203,23 -197,6 -197,6 -197,6 -197,6 -197,6 +203,23 @@@@@@@ config SPI_DAVINC
        help
          SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
      
 +++++config SPI_DESIGNWARE
 +++++  tristate "DesignWare SPI controller core support"
 +++++  help
 +++++    general driver for SPI controller core from DesignWare
 +++++
 +++++config SPI_DW_PCI
 +++++  tristate "PCI interface driver for DW SPI core"
 +++++  depends on SPI_DESIGNWARE && PCI
 +++++
 +++++config SPI_DW_MID_DMA
 +++++  bool "DMA support for DW SPI controller on Intel MID platform"
 +++++  depends on SPI_DW_PCI && DW_DMAC_PCI
 +++++
 +++++config SPI_DW_MMIO
 +++++  tristate "Memory-mapped io interface driver for DW SPI core"
 +++++  depends on SPI_DESIGNWARE
 +++++
      config SPI_DLN2
             tristate "Diolan DLN-2 USB SPI adapter"
             depends on MFD_DLN2
@@@@@@@ -294,16 -271,6 -271,6 -271,6 -271,6 -271,6 +294,16 @@@@@@@ config SPI_LM70_LL
          which interfaces to an LM70 temperature sensor using
          a parallel port.
      
 +++++config SPI_LP8841_RTC
 +++++  tristate "ICP DAS LP-8841 SPI Controller for RTC"
 +++++  depends on MACH_PXA27X_DT || COMPILE_TEST
 +++++  help
 +++++    This driver provides an SPI master device to drive Maxim
 +++++    DS-1302 real time clock.
 +++++
 +++++    Say N here unless you plan to run the kernel on an ICP DAS
 +++++    LP-8x4x industrial computer.
 +++++
      config SPI_MPC52xx
        tristate "Freescale MPC52xx SPI (non-PSC) controller support"
        depends on PPC_MPC52xx
@@@@@@@ -379,13 -346,6 -346,6 -346,6 -346,6 -346,6 +379,13 @@@@@@@ config SPI_MT65X
          say Y or M here.If you are not sure, say N.
          SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
      
 +++++config SPI_NUC900
 +++++  tristate "Nuvoton NUC900 series SPI"
 +++++  depends on ARCH_W90X900
 +++++  select SPI_BITBANG
 +++++  help
 +++++    SPI driver for Nuvoton NUC900 series ARM SoCs
 +++++
      config SPI_OC_TINY
        tristate "OpenCores tiny SPI"
        depends on GPIOLIB || COMPILE_TEST
@@@@@@@ -455,6 -415,10 -415,10 -415,10 -415,10 -415,10 +455,6 @@@@@@@ config SPI_PPC4x
        help
          This selects a driver for the PPC4xx SPI Controller.
      
 -----config SPI_PXA2XX_DMA
 -----  def_bool y
 -----  depends on SPI_PXA2XX
 -----
      config SPI_PXA2XX
        tristate "PXA2xx SSP SPI master"
        depends on (ARCH_PXA || PCI || ACPI)
@@@@@@@ -487,7 -451,7 -451,7 -451,7 -451,7 -451,7 +487,7 @@@@@@@ config SPI_RB4X
      
      config SPI_RSPI
        tristate "Renesas RSPI/QSPI controller"
--- --  depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
+++ ++  depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
        help
          SPI driver for Renesas RSPI and QSPI blocks.
      
@@@@@@@ -537,7 -501,7 -501,7 -501,7 -501,7 -501,7 +537,7 @@@@@@@ config SPI_SC18IS60
      config SPI_SH_MSIOF
        tristate "SuperH MSIOF SPI controller"
        depends on HAVE_CLK && HAS_DMA
--- --  depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
+++ ++  depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
        help
          SPI driver for SuperH and SH Mobile MSIOF blocks.
      
@@@@@@@ -556,7 -520,7 -520,7 -520,7 -520,7 -520,7 +556,7 @@@@@@@ config SPI_SH_SC
      
      config SPI_SH_HSPI
        tristate "SuperH HSPI controller"
--- --  depends on ARCH_SHMOBILE || COMPILE_TEST
+++ ++  depends on ARCH_RENESAS || COMPILE_TEST
        help
          SPI driver for SuperH HSPI blocks.
      
@@@@@@@ -683,10 -647,34 -647,34 -647,34 -647,34 -647,34 +683,10 @@@@@@@ config SPI_ZYNQMP_GQSP
        help
          Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC.
      
 -----config SPI_NUC900
 -----  tristate "Nuvoton NUC900 series SPI"
 -----  depends on ARCH_W90X900
 -----  select SPI_BITBANG
 -----  help
 -----    SPI driver for Nuvoton NUC900 series ARM SoCs
 -----
      #
      # Add new SPI master controllers in alphabetical order above this line
      #
      
 -----config SPI_DESIGNWARE
 -----  tristate "DesignWare SPI controller core support"
 -----  help
 -----    general driver for SPI controller core from DesignWare
 -----
 -----config SPI_DW_PCI
 -----  tristate "PCI interface driver for DW SPI core"
 -----  depends on SPI_DESIGNWARE && PCI
 -----
 -----config SPI_DW_MID_DMA
 -----  bool "DMA support for DW SPI controller on Intel MID platform"
 -----  depends on SPI_DW_PCI && DW_DMAC_PCI
 -----
 -----config SPI_DW_MMIO
 -----  tristate "Memory-mapped io interface driver for DW SPI core"
 -----  depends on SPI_DESIGNWARE
 -----
      #
      # There are lots of SPI device types, with sensors and memory
      # being probably the most widely used ones.
index 7cb1b2d710c10f7aab6c245a31d34e5439dfcbf0,79a8bc4f6cec9e32ec9c78627a2e68fc85ab5e12,5488597cfad4016af4c907f097ab49ff2d318479,79a8bc4f6cec9e32ec9c78627a2e68fc85ab5e12,79a8bc4f6cec9e32ec9c78627a2e68fc85ab5e12,79a8bc4f6cec9e32ec9c78627a2e68fc85ab5e12..26e2688c104ec9e6ba314264b63318a65048596f
       *
       */
      
-- ---#include <linux/init.h>
-- ---#include <linux/module.h>
      #include <linux/clk.h>
-- ---#include <linux/err.h>
-- ---#include <linux/delay.h>
-- ---#include <linux/interrupt.h>
++ +++#include <linux/dmaengine.h>
++ +++#include <linux/module.h>
++ +++#include <linux/of.h>
      #include <linux/platform_device.h>
-- ---#include <linux/slab.h>
      #include <linux/spi/spi.h>
-- ---#include <linux/scatterlist.h>
-- ---#include <linux/of.h>
      #include <linux/pm_runtime.h>
-- ---#include <linux/io.h>
-- ---#include <linux/dmaengine.h>
++ +++#include <linux/scatterlist.h>
      
      #define DRIVER_NAME "rockchip-spi"
      
@@@@@@@ -179,7 -179,7 -173,7 -179,7 -179,7 -179,7 +173,7 @@@@@@@ struct rockchip_spi 
        u8 tmode;
        u8 bpw;
        u8 n_bytes;
-- ---  u8 rsd_nsecs;
++ +++  u32 rsd_nsecs;
        unsigned len;
        u32 speed;
      
        /* protect state */
        spinlock_t lock;
      
-- ---  struct completion xfer_completion;
-- ---
        u32 use_dma;
        struct sg_table tx_sg;
        struct sg_table rx_sg;
@@@@@@@ -265,7 -265,7 -257,10 -265,7 -265,7 -265,7 +257,10 @@@@@@@ static inline u32 rx_max(struct rockchi
      static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
      {
        u32 ser;
-- ---  struct rockchip_spi *rs = spi_master_get_devdata(spi->master);
++ +++  struct spi_master *master = spi->master;
++ +++  struct rockchip_spi *rs = spi_master_get_devdata(master);
++ +++
++ +++  pm_runtime_get_sync(rs->dev);
      
        ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK;
      
                ser &= ~(1 << spi->chip_select);
      
        writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER);
++ +++
++ +++  pm_runtime_put_sync(rs->dev);
      }
      
      static int rockchip_spi_prepare_message(struct spi_master *master,
@@@@@@@ -319,12 -319,12 -316,12 -319,12 -319,12 -319,12 +316,12 @@@@@@@ static void rockchip_spi_handle_err(str
         */
        if (rs->use_dma) {
                if (rs->state & RXBUSY) {
-- ---                  dmaengine_terminate_all(rs->dma_rx.ch);
++ +++                  dmaengine_terminate_async(rs->dma_rx.ch);
                        flush_fifo(rs);
                }
      
                if (rs->state & TXBUSY)
-- ---                  dmaengine_terminate_all(rs->dma_tx.ch);
++ +++                  dmaengine_terminate_async(rs->dma_tx.ch);
        }
      
        spin_unlock_irqrestore(&rs->lock, flags);
@@@@@@@ -433,7 -433,7 -430,7 -433,7 -433,7 -433,7 +430,7 @@@@@@@ static void rockchip_spi_dma_txcb(void 
        spin_unlock_irqrestore(&rs->lock, flags);
      }
      
-- ---static void rockchip_spi_prepare_dma(struct rockchip_spi *rs)
++ +++static int rockchip_spi_prepare_dma(struct rockchip_spi *rs)
      {
        unsigned long flags;
        struct dma_slave_config rxconf, txconf;
                                rs->dma_rx.ch,
                                rs->rx_sg.sgl, rs->rx_sg.nents,
                                rs->dma_rx.direction, DMA_PREP_INTERRUPT);
++ +++          if (!rxdesc)
++ +++                  return -EINVAL;
      
                rxdesc->callback = rockchip_spi_dma_rxcb;
                rxdesc->callback_param = rs;
                                rs->dma_tx.ch,
                                rs->tx_sg.sgl, rs->tx_sg.nents,
                                rs->dma_tx.direction, DMA_PREP_INTERRUPT);
++ +++          if (!txdesc) {
++ +++                  if (rxdesc)
++ +++                          dmaengine_terminate_sync(rs->dma_rx.ch);
++ +++                  return -EINVAL;
++ +++          }
      
                txdesc->callback = rockchip_spi_dma_txcb;
                txdesc->callback_param = rs;
                dmaengine_submit(txdesc);
                dma_async_issue_pending(rs->dma_tx.ch);
        }
++ +++
++ +++  return 0;
      }
      
      static void rockchip_spi_config(struct rockchip_spi *rs)
        int rsd = 0;
      
        u32 cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET)
-- ---          | (CR0_SSD_ONE << CR0_SSD_OFFSET);
++ +++          | (CR0_SSD_ONE << CR0_SSD_OFFSET)
++ +++          | (CR0_EM_BIG << CR0_EM_OFFSET);
      
        cr0 |= (rs->n_bytes << CR0_DFS_OFFSET);
        cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET);
@@@@@@@ -606,12 -606,12 -613,12 -606,12 -606,12 -606,12 +613,12 @@@@@@@ static int rockchip_spi_transfer_one
        if (rs->use_dma) {
                if (rs->tmode == CR0_XFM_RO) {
                        /* rx: dma must be prepared first */
-- ---                  rockchip_spi_prepare_dma(rs);
++ +++                  ret = rockchip_spi_prepare_dma(rs);
                        spi_enable_chip(rs, 1);
                } else {
                        /* tx or tr: spi must be enabled first */
                        spi_enable_chip(rs, 1);
-- ---                  rockchip_spi_prepare_dma(rs);
++ +++                  ret = rockchip_spi_prepare_dma(rs);
                }
        } else {
                spi_enable_chip(rs, 1);
@@@@@@@ -717,8 -717,8 -724,14 -717,8 -717,8 -717,8 +724,14 @@@@@@@ static int rockchip_spi_probe(struct pl
        master->handle_err = rockchip_spi_handle_err;
      
        rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx");
-- ---  if (!rs->dma_tx.ch)
++ +++  if (IS_ERR_OR_NULL(rs->dma_tx.ch)) {
++ +++          /* Check tx to see if we need defer probing driver */
++ +++          if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) {
++ +++                  ret = -EPROBE_DEFER;
++ +++                  goto err_get_fifo_len;
++ +++          }
                dev_warn(rs->dev, "Failed to request TX DMA channel\n");
++ +++  }
      
        rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx");
        if (!rs->dma_rx.ch) {
        return 0;
      
      err_register_master:
 +++++  pm_runtime_disable(&pdev->dev);
        if (rs->dma_tx.ch)
                dma_release_channel(rs->dma_tx.ch);
        if (rs->dma_rx.ch)
@@@@@@@ -779,8 -778,6 -791,6 -778,6 -778,6 -778,6 +792,8 @@@@@@@ static int rockchip_spi_remove(struct p
        if (rs->dma_rx.ch)
                dma_release_channel(rs->dma_rx.ch);
      
 +++++  spi_master_put(master);
 +++++
        return 0;
      }
      
@@@@@@@ -871,6 -868,6 -881,7 -868,6 -868,6 -868,6 +884,7 @@@@@@@ static const struct of_device_id rockch
        { .compatible = "rockchip,rk3066-spi", },
        { .compatible = "rockchip,rk3188-spi", },
        { .compatible = "rockchip,rk3288-spi", },
++ +++  { .compatible = "rockchip,rk3399-spi", },
        { },
      };
      MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
diff --combined include/linux/spi/spi.h
index f54667b7b3c85c9f87e084b325d1423f6a44dcbd,5396ee5fc51f8016ada605d3843ef74fbb074781,53be3a4c60cbe4d53388a18ef7ca96d3204b26cc,53be3a4c60cbe4d53388a18ef7ca96d3204b26cc,ba0dee9d05a3d7be68e8a884075443e95714a39f,53be3a4c60cbe4d53388a18ef7ca96d3204b26cc..857a9a1d82b58ad3569c7daeb9fffb17f690926a
      struct dma_chan;
      struct spi_master;
      struct spi_transfer;
 +++ +struct spi_flash_read_message;
      
      /*
       * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@@@@@@ -54,10 -53,6 -53,6 -53,6 -54,6 -53,6 +54,10 @@@@@@@ extern struct bus_type spi_bus_type
       *
       * @transfer_bytes_histo:
       *                 transfer bytes histogramm
 +++++ *
 +++++ * @transfers_split_maxsize:
 +++++ *                 number of transfers that have been split because of
 +++++ *                 maxsize limit
       */
      struct spi_statistics {
        spinlock_t              lock; /* lock for the whole structure */
      
      #define SPI_STATISTICS_HISTO_SIZE 17
        unsigned long transfer_bytes_histo[SPI_STATISTICS_HISTO_SIZE];
 +++++
 +++++  unsigned long transfers_split_maxsize;
      };
      
      void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
@@@@@@@ -310,8 -303,6 -303,6 -303,6 -304,6 -303,6 +310,8 @@@@@@@ static inline void spi_unregister_drive
       * @min_speed_hz: Lowest supported transfer speed
       * @max_speed_hz: Highest supported transfer speed
       * @flags: other constraints relevant to this driver
 +++++ * @max_transfer_size: function that returns the max transfer size for
 +++++ *        a &spi_device; may be %NULL, so the default %SIZE_MAX will be used.
       * @bus_lock_spinlock: spinlock for SPI bus locking
       * @bus_lock_mutex: mutex for SPI bus locking
       * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
       * @handle_err: the subsystem calls the driver to handle an error that occurs
       *                in the generic implementation of transfer_one_message().
       * @unprepare_message: undo any work done by prepare_message().
 +++ + * @spi_flash_read: to support spi-controller hardwares that provide
 +++ + *                  accelerated interface to read from flash devices.
       * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
       *        number. Any individual value may be -ENOENT for CS lines that
       *        are not GPIOs (driven by the SPI controller itself).
       * @dma_rx: DMA receive channel
       * @dummy_rx: dummy receive buffer for full-duplex devices
       * @dummy_tx: dummy transmit buffer for full-duplex devices
 +++++ * @fw_translate_cs: If the boot firmware uses different numbering scheme
 +++++ *        what Linux expects, this optional hook can be used to translate
 +++++ *        between the two.
       *
       * Each SPI master controller can communicate with one or more @spi_device
       * children.  These make a small bus, sharing MOSI, MISO and SCK signals
@@@@@@@ -527,8 -513,6 -513,6 -513,6 -516,8 -513,6 +527,8 @@@@@@@ struct spi_master 
                               struct spi_message *message);
        int (*unprepare_message)(struct spi_master *master,
                                 struct spi_message *message);
 +++ +  int (*spi_flash_read)(struct  spi_device *spi,
 +++ +                        struct spi_flash_read_message *msg);
      
        /*
         * These hooks are for drivers that use a generic implementation
        /* dummy data for full duplex devices */
        void                    *dummy_rx;
        void                    *dummy_tx;
 +++++
 +++++  int (*fw_translate_cs)(struct spi_master *master, unsigned cs);
      };
      
      static inline void *spi_master_get_devdata(struct spi_master *master)
@@@@@@@ -600,37 -582,38 -582,6 -582,6 -587,6 -582,6 +600,38 @@@@@@@ extern void spi_unregister_master(struc
      
      extern struct spi_master *spi_busnum_to_master(u16 busnum);
      
-     typedef void (*spi_res_release_t)(struct spi_master *master,
-                                 struct spi_message *msg,
-                                 void *res);
  ++++/*
  ++++ * SPI resource management while processing a SPI message
  ++++ */
  ++++
+ ++++typedef void (*spi_res_release_t)(struct spi_master *master,
+ ++++                            struct spi_message *msg,
+ ++++                            void *res);
+ ++++
  ++++/**
  ++++ * struct spi_res - spi resource management structure
  ++++ * @entry:   list entry
  ++++ * @release: release code called prior to freeing this resource
  ++++ * @data:    extra data allocated for the specific use-case
  ++++ *
  ++++ * this is based on ideas from devres, but focused on life-cycle
  ++++ * management during spi_message processing
  ++++ */
  ++++struct spi_res {
  ++++  struct list_head        entry;
  ++++  spi_res_release_t       release;
  ++++  unsigned long long      data[]; /* guarantee ull alignment */
  ++++};
  ++++
  ++++extern void *spi_res_alloc(struct spi_device *spi,
  ++++                     spi_res_release_t release,
  ++++                     size_t size, gfp_t gfp);
  ++++extern void spi_res_add(struct spi_message *message, void *res);
  ++++extern void spi_res_free(void *res);
  ++++
  ++++extern void spi_res_release(struct spi_master *master,
  ++++                      struct spi_message *message);
  ++++
      /*---------------------------------------------------------------------------*/
      
      /*
@@@@@@@ -769,7 -752,7 -720,6 -720,6 -725,6 -720,6 +770,7 @@@@@@@ struct spi_transfer 
       * @status: zero for success, else negative errno
       * @queue: for use by whichever driver currently owns the message
       * @state: for use by whichever driver currently owns the message
  ++++ * @resources: for resource management when the spi message is processed
       *
       * A @spi_message is used to execute an atomic sequence of data transfers,
       * each represented by a struct spi_transfer.  The sequence is "atomic"
@@@@@@@ -816,15 -799,15 -766,11 -766,11 -771,11 -766,11 +817,15 @@@@@@@ struct spi_message 
         */
        struct list_head        queue;
        void                    *state;
  ++++
  ++++  /* list of spi_res reources when the spi message is processed */
  ++++  struct list_head        resources;
      };
      
      static inline void spi_message_init_no_memset(struct spi_message *m)
      {
        INIT_LIST_HEAD(&m->transfers);
  ++++  INIT_LIST_HEAD(&m->resources);
      }
      
      static inline void spi_message_init(struct spi_message *m)
@@@@@@@ -908,60 -891,6 -854,6 -854,6 -859,6 -854,6 +909,60 @@@@@@@ spi_max_transfer_size(struct spi_devic
      
      /*---------------------------------------------------------------------------*/
      
 +++++/* SPI transfer replacement methods which make use of spi_res */
 +++++
 +++++struct spi_replaced_transfers;
 +++++typedef void (*spi_replaced_release_t)(struct spi_master *master,
 +++++                                 struct spi_message *msg,
 +++++                                 struct spi_replaced_transfers *res);
 +++++/**
 +++++ * struct spi_replaced_transfers - structure describing the spi_transfer
 +++++ *                                 replacements that have occurred
 +++++ *                                 so that they can get reverted
 +++++ * @release:            some extra release code to get executed prior to
 +++++ *                      relasing this structure
 +++++ * @extradata:          pointer to some extra data if requested or NULL
 +++++ * @replaced_transfers: transfers that have been replaced and which need
 +++++ *                      to get restored
 +++++ * @replaced_after:     the transfer after which the @replaced_transfers
 +++++ *                      are to get re-inserted
 +++++ * @inserted:           number of transfers inserted
 +++++ * @inserted_transfers: array of spi_transfers of array-size @inserted,
 +++++ *                      that have been replacing replaced_transfers
 +++++ *
 +++++ * note: that @extradata will point to @inserted_transfers[@inserted]
 +++++ * if some extra allocation is requested, so alignment will be the same
 +++++ * as for spi_transfers
 +++++ */
 +++++struct spi_replaced_transfers {
 +++++  spi_replaced_release_t release;
 +++++  void *extradata;
 +++++  struct list_head replaced_transfers;
 +++++  struct list_head *replaced_after;
 +++++  size_t inserted;
 +++++  struct spi_transfer inserted_transfers[];
 +++++};
 +++++
 +++++extern struct spi_replaced_transfers *spi_replace_transfers(
 +++++  struct spi_message *msg,
 +++++  struct spi_transfer *xfer_first,
 +++++  size_t remove,
 +++++  size_t insert,
 +++++  spi_replaced_release_t release,
 +++++  size_t extradatasize,
 +++++  gfp_t gfp);
 +++++
 +++++/*---------------------------------------------------------------------------*/
 +++++
 +++++/* SPI transfer transformation methods */
 +++++
 +++++extern int spi_split_transfers_maxsize(struct spi_master *master,
 +++++                                 struct spi_message *msg,
 +++++                                 size_t maxsize,
 +++++                                 gfp_t gfp);
 +++++
 +++++/*---------------------------------------------------------------------------*/
 +++++
      /* All these synchronous SPI transfer routines are utilities layered
       * over the core async transfer primitive.  Here, "synchronous" means
       * they will sleep uninterruptibly until the async transfer completes.
@@@@@@@ -1127,42 -1056,6 -1019,6 -1019,6 -1024,42 -1019,6 +1128,42 @@@@@@@ static inline ssize_t spi_w8r16be(struc
        return be16_to_cpu(result);
      }
      
 +++ +/**
 +++ + * struct spi_flash_read_message - flash specific information for
 +++ + * spi-masters that provide accelerated flash read interfaces
 +++ + * @buf: buffer to read data
 +++ + * @from: offset within the flash from where data is to be read
 +++ + * @len: length of data to be read
 +++ + * @retlen: actual length of data read
 +++ + * @read_opcode: read_opcode to be used to communicate with flash
 +++ + * @addr_width: number of address bytes
 +++ + * @dummy_bytes: number of dummy bytes
 +++ + * @opcode_nbits: number of lines to send opcode
 +++ + * @addr_nbits: number of lines to send address
 +++ + * @data_nbits: number of lines for data
 +++ + */
 +++ +struct spi_flash_read_message {
 +++ +  void *buf;
 +++ +  loff_t from;
 +++ +  size_t len;
 +++ +  size_t retlen;
 +++ +  u8 read_opcode;
 +++ +  u8 addr_width;
 +++ +  u8 dummy_bytes;
 +++ +  u8 opcode_nbits;
 +++ +  u8 addr_nbits;
 +++ +  u8 data_nbits;
 +++ +};
 +++ +
 +++ +/* SPI core interface for flash read support */
 +++ +static inline bool spi_flash_read_supported(struct spi_device *spi)
 +++ +{
 +++ +  return spi->master->spi_flash_read ? true : false;
 +++ +}
 +++ +
 +++ +int spi_flash_read(struct spi_device *spi,
 +++ +             struct spi_flash_read_message *msg);
 +++ +
      /*---------------------------------------------------------------------------*/
      
      /*