Re: [PATCH 2/2 v3] OMAP-McSPI :Adds support for FIFO and auto chip select mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 13, 2010 at 7:59 AM, Govindraj.R <govindraj.raja@xxxxxx> wrote:
>
> From: Hemanth V <hemanthv@xxxxxx>
>
> DMA and FIFO could be enabled together for better throughput.
> Platform config parameters have been added to enable these
> features on any particular McSPI controller.
>
> FIFO can be enabled by defining fifo_depth parameter. fifo_depth needs
> to be a multiple of buffer size that is used for read/write.
>
> Auto chip select mode can be enabled by setting force_cs_mode
> to zero

Hi Hemanth, comments below.

>
> Cc: Tony Lindgren <tony@xxxxxxxxxxx>
> Cc: Grant Likely <grant.likely@xxxxxxxxxxxx>
> Signed-off-by: Hemanth V <hemanthv@xxxxxx>
> Signed-off-by: Govindraj.R <govindraj.raja@xxxxxx>
> ---
>  drivers/spi/omap2_mcspi.c |  336 ++++++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 300 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
> index b3a94ca..dc0420f 100644
> --- a/drivers/spi/omap2_mcspi.c
> +++ b/drivers/spi/omap2_mcspi.c
> @@ -41,6 +41,7 @@
>  #include <plat/mcspi.h>
>
>  #define OMAP2_MCSPI_MAX_FREQ           48000000
> +#define OMAP2_MCSPI_MAX_FIFODEPTH       64
>
>  /* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
>  #define OMAP2_MCSPI_MAX_CTRL           4
> @@ -53,6 +54,7 @@
>  #define OMAP2_MCSPI_WAKEUPENABLE       0x20
>  #define OMAP2_MCSPI_SYST               0x24
>  #define OMAP2_MCSPI_MODULCTRL          0x28
> +#define OMAP2_MCSPI_XFERLEVEL          0x7c
>
>  /* per-channel banks, 0x14 bytes each, first is: */
>  #define OMAP2_MCSPI_CHCONF0            0x2c
> @@ -89,11 +91,15 @@
>  #define OMAP2_MCSPI_CHCONF_IS          BIT(18)
>  #define OMAP2_MCSPI_CHCONF_TURBO       BIT(19)
>  #define OMAP2_MCSPI_CHCONF_FORCE       BIT(20)
> +#define OMAP2_MCSPI_CHCONF_FFET        BIT(27)
> +#define OMAP2_MCSPI_CHCONF_FFER        BIT(28)
>
>  #define OMAP2_MCSPI_CHSTAT_RXS         BIT(0)
>  #define OMAP2_MCSPI_CHSTAT_TXS         BIT(1)
>  #define OMAP2_MCSPI_CHSTAT_EOT         BIT(2)
>
> +#define OMAP2_MCSPI_IRQ_EOW            BIT(17)
> +
>  #define OMAP2_MCSPI_CHCTRL_EN          BIT(0)
>
>  #define OMAP2_MCSPI_WAKEUPENABLE_WKEN  BIT(0)
> @@ -115,7 +121,6 @@ struct omap2_mcspi_dma {
>  */
>  #define DMA_MIN_BYTES                  160
>
> -

Unrelated whitespace change

>  struct omap2_mcspi {
>        struct work_struct      work;
>        /* lock protects queue and registers */
> @@ -129,6 +134,10 @@ struct omap2_mcspi {
>        unsigned long           phys;
>        /* SPI1 has 4 channels, while SPI2 has 2 */
>        struct omap2_mcspi_dma  *dma_channels;
> +       u8                      mcspi_mode;
> +       u8                      dma_mode;
> +       u8                      force_cs_mode;
> +       u16                     fifo_depth;
>  };
>
>  struct omap2_mcspi_cs {
> @@ -152,6 +161,37 @@ struct omap2_mcspi_regs {
>
>  static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
>
> +#ifdef CONFIG_SPI_DEBUG
> +struct reg_type {
> +       char name[40];
> +       int offset;
> +};
> +
> +static struct reg_type reg_map[] = {
> +       {"MCSPI_REV", 0x0},
> +       {"MCSPI_SYSCONFIG", 0x10},
> +       {"MCSPI_SYSSTATUS", 0x14},
> +       {"MCSPI_IRQSTATUS", 0x18},
> +       {"MCSPI_IRQENABLE", 0x1C},
> +       {"MCSPI_WAKEUPENABLE", 0x20},
> +       {"MCSPI_SYST", 0x24},
> +       {"MCSPI_MODULCTRL", 0x28},
> +       {"MCSPI_XFERLEVEL", 0x7c},
> +       {"CH0", 0x2C},
> +       {"CH1", 0x40},
> +       {"CH2", 0x54},
> +       {"CH3", 0x68}
> +};
> +
> +static struct reg_type ch_reg_type[] = {
> +       {"CONF", 0x00},
> +       {"STAT", 0x04},
> +       {"CTRL", 0x08},
> +       {"TX", 0x0C},
> +       {"RX", 0x10},
> +};
> +#endif
> +
>  static struct workqueue_struct *omap2_mcspi_wq;
>
>  #define MOD_REG_BIT(val, mask, set) do { \
> @@ -223,6 +263,39 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
>        mcspi_write_chconf0(spi, l);
>  }
>
> +#ifdef CONFIG_SPI_DEBUG
> +static int
> +omap2_mcspi_dump_regs(struct spi_master *master)
> +{
> +       u32 spi_base;
> +       u32 reg;
> +       u32 channel;
> +       struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
> +
> +       spi_base = (u32)mcspi->base;
> +
> +       for (reg = 0; (reg < ARRAY_SIZE(reg_map)); reg++) {
> +               struct reg_type *reg_d = &reg_map[reg];
> +               u32 base1 = spi_base + reg_d->offset;
> +               if (reg_d->name[0] == 'C') {
> +                       for (channel = 0; (channel < (ARRAY_SIZE(ch_reg_type)));
> +                           channel++) {
> +                               struct reg_type *reg_c = &ch_reg_type[channel];
> +                               u32 base2 = base1 + reg_c->offset;
> +                               pr_debug("MCSPI_%s%s [0x%08X] = 0x%08X\n",
> +                                      reg_d->name, reg_c->name, base2,
> +                                      __raw_readl(base2));
> +                       }
> +               } else {
> +                       pr_debug("%s : [0x%08X] = 0x%08X\n",
> +                               reg_d->name, base1, __raw_readl(base1));
> +               }
> +
> +       }
> +       return 0;
> +}
> +#endif
> +

Large chunk of debug code not mentioned in the patch description.
Please move to a separate patch.

>  static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
>  {
>        u32 l;
> @@ -242,22 +315,135 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active)
>        mcspi_write_chconf0(spi, l);
>  }
>
> +static int omap2_mcspi_set_txfifo(const struct spi_device *spi, int buf_size,
> +                                       int enable)
> +{
> +       u32 l, rw, s;
> +       unsigned short revert = 0;
> +       struct spi_master *master = spi->master;
> +       struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
> +
> +       l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
> +       s = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
> +
> +       if (enable == 1) {
> +
> +               /* FIFO cannot be enabled for both TX and RX
> +                * simultaneously
> +                */
> +               if (l & OMAP2_MCSPI_CHCONF_FFER)
> +                       return -EPERM;
> +
> +               /* Channel needs to be disabled and enabled
> +                * for FIFO setting to take affect
> +                */
> +               if (s & OMAP2_MCSPI_CHCTRL_EN) {
> +                       omap2_mcspi_set_enable(spi, 0);
> +                       revert = 1;
> +               }
> +
> +               if (buf_size < mcspi->fifo_depth)
> +                       mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL,
> +                                               ((buf_size << 16) |
> +                                               (buf_size - 1) << 0));
> +               else
> +                       mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL,
> +                                               ((buf_size << 16) |
> +                                               (mcspi->fifo_depth - 1) << 0));

The following would be more concise and more readable as to what the
difference is between the two conditions:

		s = buf_size < mcspi->fifo_depth ? buf_size : mcspi->fifo_depth;
		mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL,
				(buf_size << 16) | (s - 1));

> +       }
> +
> +       rw = OMAP2_MCSPI_CHCONF_FFET;
> +       MOD_REG_BIT(l, rw, enable);
> +       mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
> +
> +       if (revert)
> +               omap2_mcspi_set_enable(spi, 1);
> +
> +       return 0;
> +
> +}
> +
> +static int omap2_mcspi_set_rxfifo(const struct spi_device *spi, int buf_size,
> +                                       int enable)
> +{
> +       u32 l, rw, s;
> +       unsigned short revert = 0;
> +       struct spi_master *master = spi->master;
> +       struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
> +
> +       l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
> +       s = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
> +
> +       if (enable == 1) {
> +
> +               /* FIFO cannot be enabled for both TX and RX
> +                * simultaneously
> +                */
> +               if (l & OMAP2_MCSPI_CHCONF_FFET)
> +                       return -EPERM;
> +
> +               /* Channel needs to be disabled and enabled
> +                * for FIFO setting to take affect
> +                */
> +               if (s & OMAP2_MCSPI_CHCTRL_EN) {
> +                       omap2_mcspi_set_enable(spi, 0);
> +                       revert = 1;
> +               }
> +
> +               if (buf_size < mcspi->fifo_depth)
> +                       mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL,
> +                                               ((buf_size << 16) |
> +                                               (buf_size - 1) << 8));
> +               else
> +                       mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL,
> +                                               ((buf_size << 16) |
> +                                               (mcspi->fifo_depth - 1) << 8));

Ditto here.

> +       }
> +
> +       rw = OMAP2_MCSPI_CHCONF_FFER;
> +       MOD_REG_BIT(l, rw, enable);
> +       mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
> +
> +       if (revert)
> +               omap2_mcspi_set_enable(spi, 1);
> +
> +       return 0;
> +
> +}
> +
>  static void omap2_mcspi_set_master_mode(struct spi_master *master)
>  {
>        u32 l;
> +       struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
>
>        /* setup when switching from (reset default) slave mode
> -        * to single-channel master mode
> +        * to single-channel master mode based on config value
>         */
>        l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL);
>        MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_STEST, 0);
>        MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
> -       MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
> +
> +       if (mcspi->force_cs_mode)
> +               MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
> +

No mention of adding slave mode support in the patch description.  Nor
do I see any description of how slave mode is intended to work.

>        mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
>
>        omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
>  }
>
> +static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
> +{
> +       unsigned long timeout;
> +
> +       timeout = jiffies + msecs_to_jiffies(1000);
> +       while (!(__raw_readl(reg) & bit)) {
> +               if (time_after(jiffies, timeout))
> +                       return -1;
> +               cpu_relax();
> +       }
> +       return 0;
> +}
> +
>  static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
>  {
>        struct spi_master *spi_cntrl;
> @@ -302,16 +488,18 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>        struct omap2_mcspi      *mcspi;
>        struct omap2_mcspi_cs   *cs = spi->controller_state;
>        struct omap2_mcspi_dma  *mcspi_dma;
> -       unsigned int            count, c;
> +       unsigned int            count, c, bytes_per_transfer;
>        unsigned long           base, tx_reg, rx_reg;
>        int                     word_len, data_type, element_count;
> -       int                     elements;
> +       int                     elements, frame_count, sync_type;
>        u32                     l;
>        u8                      * rx;
>        const u8                * tx;
> +       void __iomem            *irqstat_reg;
>
>        mcspi = spi_master_get_devdata(spi->master);
>        mcspi_dma = &mcspi->dma_channels[spi->chip_select];
> +       irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
>        l = mcspi_cached_chconf0(spi);
>
>        count = xfer->len;
> @@ -327,19 +515,34 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>        if (word_len <= 8) {
>                data_type = OMAP_DMA_DATA_TYPE_S8;
>                element_count = count;
> +               bytes_per_transfer = 1;
>        } else if (word_len <= 16) {
>                data_type = OMAP_DMA_DATA_TYPE_S16;
>                element_count = count >> 1;
> +               bytes_per_transfer = 2;
>        } else /* word_len <= 32 */ {
>                data_type = OMAP_DMA_DATA_TYPE_S32;
>                element_count = count >> 2;
> +               bytes_per_transfer = 4;
> +       }
> +
> +       if ((mcspi->fifo_depth != 0) && (count > mcspi->fifo_depth)) {
> +               sync_type = OMAP_DMA_SYNC_FRAME;
> +               element_count = mcspi->fifo_depth/bytes_per_transfer;
> +               frame_count = count/mcspi->fifo_depth;
> +       } else if ((mcspi->fifo_depth != 0) && (count <=  mcspi->fifo_depth)) {
> +               sync_type = OMAP_DMA_SYNC_FRAME;
> +               frame_count = 1;
> +       } else {
> +               sync_type = OMAP_DMA_SYNC_ELEMENT;
> +               frame_count = 1;
>        }
>
>        if (tx != NULL) {
> +
>                omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel,
> -                               data_type, element_count, 1,
> -                               OMAP_DMA_SYNC_ELEMENT,
> -                               mcspi_dma->dma_tx_sync_dev, 0);
> +                               data_type, element_count, frame_count,
> +                               sync_type, mcspi_dma->dma_tx_sync_dev, 0);
>
>                omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0,
>                                OMAP_DMA_AMODE_CONSTANT,
> @@ -348,6 +551,9 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>                omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0,
>                                OMAP_DMA_AMODE_POST_INC,
>                                xfer->tx_dma, 0, 0);
> +
> +               if (mcspi->fifo_depth != 0)
> +                       omap2_mcspi_set_txfifo(spi, count, 1);
>        }
>
>        if (rx != NULL) {
> @@ -367,6 +573,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>                omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0,
>                                OMAP_DMA_AMODE_POST_INC,
>                                xfer->rx_dma, 0, 0);
> +
> +               if (mcspi->fifo_depth != 0) {
> +                       omap2_mcspi_set_rxfifo(spi, count, 1);
> +
> +                       /* Dummy write required for RX only mode */
> +                       if (tx == NULL)
> +                               mcspi_write_cs_reg(spi, OMAP2_MCSPI_TX0, 0);
> +               }
>        }
>
>        if (tx != NULL) {
> @@ -381,11 +595,32 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>
>        if (tx != NULL) {
>                wait_for_completion(&mcspi_dma->dma_tx_completion);
> +
> +               if (mcspi->fifo_depth != 0) {
> +                       if (mcspi_wait_for_reg_bit(irqstat_reg,
> +                               OMAP2_MCSPI_IRQ_EOW) < 0)
> +                                       dev_err(&spi->dev, "TXS timed out\n");
> +
> +               mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS,
> +                               OMAP2_MCSPI_IRQ_EOW);
> +
> +               omap2_mcspi_set_txfifo(spi, count, 0);
> +               }
> +
>                dma_unmap_single(NULL, xfer->tx_dma, count, DMA_TO_DEVICE);
>        }
>
>        if (rx != NULL) {
>                wait_for_completion(&mcspi_dma->dma_rx_completion);
> +
> +               if (mcspi->fifo_depth != 0) {
> +                       omap2_mcspi_set_rxfifo(spi, count, 0);
> +
> +               mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS,
> +                               OMAP2_MCSPI_IRQ_EOW);
> +
> +               }
> +
>                dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE);
>                omap2_mcspi_set_enable(spi, 0);
>
> @@ -435,19 +670,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>        return count;
>  }
>
> -static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
> -{
> -       unsigned long timeout;
> -
> -       timeout = jiffies + msecs_to_jiffies(1000);
> -       while (!(__raw_readl(reg) & bit)) {
> -               if (time_after(jiffies, timeout))
> -                       return -1;
> -               cpu_relax();
> -       }
> -       return 0;
> -}
> -
>  static unsigned
>  omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
>  {
> @@ -684,8 +906,13 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
>        /* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
>         * REVISIT: this controller could support SPI_3WIRE mode.
>         */
> -       l &= ~(OMAP2_MCSPI_CHCONF_IS|OMAP2_MCSPI_CHCONF_DPE1);
> -       l |= OMAP2_MCSPI_CHCONF_DPE0;
> +       if (mcspi->mcspi_mode == OMAP2_MCSPI_MASTER) {
> +               l &= ~(OMAP2_MCSPI_CHCONF_IS|OMAP2_MCSPI_CHCONF_DPE1);
> +               l |= OMAP2_MCSPI_CHCONF_DPE0;
> +       } else {
> +               return -EINVAL;
> +       }
> +

Continuing my thought from above; please split all the slave mode
support code out of this patch and put it into another.  How the spi
api will behave in slave mode is a critical question to answer, so it
is best kept separate so it doesn't hold up the DMA support code.

>
>        /* wordlength */
>        l &= ~OMAP2_MCSPI_CHCONF_WL_MASK;
> @@ -697,9 +924,11 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
>        else
>                l &= ~OMAP2_MCSPI_CHCONF_EPOL;
>
> -       /* set clock divisor */
> -       l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
> -       l |= div << 2;
> +       if (mcspi->mcspi_mode == OMAP2_MCSPI_MASTER) {
> +               /* set clock divisor */
> +               l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
> +               l |= div << 2;
> +       }
>
>        /* set SPI mode 0..3 */
>        if (spi->mode & SPI_CPOL)
> @@ -909,7 +1138,10 @@ static void omap2_mcspi_work(struct work_struct *work)
>                                        par_override = 0;
>                        }
>
> -                       if (!cs_active) {
> +                       if ((!cs_active) && (mcspi->force_cs_mode) &&
> +                               (mcspi->mcspi_mode ==
> +                               OMAP2_MCSPI_MASTER)) {
> +
>                                omap2_mcspi_force_cs(spi, 1);
>                                cs_active = 1;
>                        }
> @@ -939,10 +1171,14 @@ static void omap2_mcspi_work(struct work_struct *work)
>                                        __raw_writel(0, cs->base
>                                                        + OMAP2_MCSPI_TX0);
>
> -                               if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)
> +                               if (m->is_dma_mapped ||
> +                                       t->len >= DMA_MIN_BYTES ||
> +                                       mcspi->dma_mode)
> +

Hmmm.  I'm not sure what is intended here.  Perhaps I started with the
wrong impression, but it appears that the driver *already* supports
DMA transfers.  What is the intention of the dma_mode flag?

>                                        count = omap2_mcspi_txrx_dma(spi, t);
>                                else
>                                        count = omap2_mcspi_txrx_pio(spi, t);
> +

unrelated whitespace change.

>                                m->actual_length += count;
>
>                                if (count != t->len) {
> @@ -955,7 +1191,10 @@ static void omap2_mcspi_work(struct work_struct *work)
>                                udelay(t->delay_usecs);
>
>                        /* ignore the "leave it on after last xfer" hint */
> -                       if (t->cs_change) {
> +                       if ((t->cs_change) && (mcspi->force_cs_mode) &&
> +                               (mcspi->mcspi_mode ==
> +                               OMAP2_MCSPI_MASTER)) {
> +
>                                omap2_mcspi_force_cs(spi, 0);
>                                cs_active = 0;
>                        }
> @@ -967,8 +1206,9 @@ static void omap2_mcspi_work(struct work_struct *work)
>                        status = omap2_mcspi_setup_transfer(spi, NULL);
>                }
>
> -               if (cs_active)
> -                       omap2_mcspi_force_cs(spi, 0);
> +               if ((cs_active) && (mcspi->force_cs_mode) &&
> +                       (mcspi->mcspi_mode == OMAP2_MCSPI_MASTER))
> +                               omap2_mcspi_force_cs(spi, 0);
>
>                omap2_mcspi_set_enable(spi, 0);
>
> @@ -993,6 +1233,8 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
>        m->actual_length = 0;
>        m->status = 0;
>
> +       mcspi = spi_master_get_devdata(spi->master);
> +
>        /* reject invalid messages and transfers */
>        if (list_empty(&m->transfers) || !m->complete)
>                return -EINVAL;
> @@ -1021,7 +1263,14 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
>                        return -EINVAL;
>                }
>
> -               if (m->is_dma_mapped || len < DMA_MIN_BYTES)
> +               if (mcspi->fifo_depth != 0) {
> +                       if ((len % mcspi->fifo_depth) != 0)
> +                               return -EINVAL;
> +               }

This looks wrong. There cannot be a guarantee that the buffer length
will be a multiple of the fifo depth.

> +
> +               /* Ignore DMA_MIN_BYTES check if dma only mode is set */
> +               if (m->is_dma_mapped || ((len < DMA_MIN_BYTES) &&
> +                                               (!mcspi->dma_mode)))
>                        continue;
>
>                /* Do DMA mapping "early" for better error reporting and
> @@ -1052,8 +1301,6 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
>                }
>        }
>
> -       mcspi = spi_master_get_devdata(spi->master);
> -
>        spin_lock_irqsave(&mcspi->lock, flags);
>        list_add_tail(&m->queue, &mcspi->msg_queue);
>        queue_work(omap2_mcspi_wq, &mcspi->work);
> @@ -1066,6 +1313,7 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
>  {
>        struct spi_master       *master = mcspi->master;
>        u32                     tmp;
> +       u32                     error = 0;
>
>        if (omap2_mcspi_enable_clocks(mcspi))
>                return -1;
> @@ -1086,9 +1334,13 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
>        mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
>        omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;
>
> -       omap2_mcspi_set_master_mode(master);
> +       if (mcspi->mcspi_mode == OMAP2_MCSPI_MASTER)
> +               omap2_mcspi_set_master_mode(master);
> +       else
> +               error = -EINVAL;
> +
>        omap2_mcspi_disable_clocks(mcspi);
> -       return 0;
> +       return error;
>  }
>
>  static u8 __initdata spi1_rxdma_id [] = {
> @@ -1141,6 +1393,8 @@ static u8 __initdata spi4_txdma_id[] = {
>  static int __init omap2_mcspi_probe(struct platform_device *pdev)
>  {
>        struct spi_master       *master;
> +       struct omap2_mcspi_platform_config *pdata =
> +               (struct omap2_mcspi_platform_config *)pdev->dev.platform_data;
>        struct omap2_mcspi      *mcspi;
>        struct resource         *r;
>        int                     status = 0, i;
> @@ -1198,6 +1452,16 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
>
>        mcspi = spi_master_get_devdata(master);
>        mcspi->master = master;
> +       mcspi->mcspi_mode = OMAP2_MCSPI_MASTER;
> +       mcspi->dma_mode = pdata->dma_mode;
> +       mcspi->force_cs_mode = pdata->force_cs_mode;
> +
> +       if (pdata->fifo_depth <= OMAP2_MCSPI_MAX_FIFODEPTH)
> +               mcspi->fifo_depth = pdata->fifo_depth;
> +       else {
> +               mcspi->fifo_depth = 0;
> +               dev_dbg(&pdev->dev, "Invalid fifo depth specified\n");
> +       }
>
>        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>        if (r == NULL) {
> --
> 1.6.3.3


Sorry, I have to Nack this patch.  It makes several unrelated changes
that should be in separate patches, and I suspect that the changes are
incorrect (please correct me if I'm misunderstanding).

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux