On Fri, Sep 10, 2010 at 08:55:49AM +0900, Jassi Brar wrote:
> We can't do without setting channel and bus width to
> same size. Inorder to do that, use loop read/writes in
> polling mode and appropriate burst size in DMA mode.
> 
> Signed-off-by: Jassi Brar <[email protected]>

applied to -next branch.  Thanks.

g.

> ---
>  drivers/spi/spi_s3c64xx.c |   56 
> +++++++++++++++++++++++++++++++++------------
>  1 files changed, 41 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 39816bb..cf45e01 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -255,15 +255,25 @@ static void enable_datapath(struct 
> s3c64xx_spi_driver_data *sdd,
>               chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>               if (dma_mode) {
>                       modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> -                     s3c2410_dma_config(sdd->tx_dmach, 1);
> +                     s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
>                       s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>                                               xfer->tx_dma, xfer->len);
>                       s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
>               } else {
> -                     unsigned char *buf = (unsigned char *) xfer->tx_buf;
> -                     int i = 0;
> -                     while (i < xfer->len)
> -                             writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
> +                     switch (sdd->cur_bpw) {
> +                     case 32:
> +                             iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                     xfer->tx_buf, xfer->len / 4);
> +                             break;
> +                     case 16:
> +                             iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                     xfer->tx_buf, xfer->len / 2);
> +                             break;
> +                     default:
> +                             iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                     xfer->tx_buf, xfer->len);
> +                             break;
> +                     }
>               }
>       }
>  
> @@ -280,7 +290,7 @@ static void enable_datapath(struct 
> s3c64xx_spi_driver_data *sdd,
>                       writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>                                       | S3C64XX_SPI_PACKET_CNT_EN,
>                                       regs + S3C64XX_SPI_PACKET_CNT);
> -                     s3c2410_dma_config(sdd->rx_dmach, 1);
> +                     s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
>                       s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>                                               xfer->rx_dma, xfer->len);
>                       s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> @@ -360,20 +370,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data 
> *sdd,
>                               return -EIO;
>               }
>       } else {
> -             unsigned char *buf;
> -             int i;
> -
>               /* If it was only Tx */
>               if (xfer->rx_buf == NULL) {
>                       sdd->state &= ~TXBUSY;
>                       return 0;
>               }
>  
> -             i = 0;
> -             buf = xfer->rx_buf;
> -             while (i < xfer->len)
> -                     buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
> -
> +             switch (sdd->cur_bpw) {
> +             case 32:
> +                     ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
> +                             xfer->rx_buf, xfer->len / 4);
> +                     break;
> +             case 16:
> +                     ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
> +                             xfer->rx_buf, xfer->len / 2);
> +                     break;
> +             default:
> +                     ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
> +                             xfer->rx_buf, xfer->len);
> +                     break;
> +             }
>               sdd->state &= ~RXBUSY;
>       }
>  
> @@ -423,15 +439,17 @@ static void s3c64xx_spi_config(struct 
> s3c64xx_spi_driver_data *sdd)
>       switch (sdd->cur_bpw) {
>       case 32:
>               val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
> +             val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
>               break;
>       case 16:
>               val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
> +             val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
>               break;
>       default:
>               val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
> +             val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
>               break;
>       }
> -     val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
>  
>       writel(val, regs + S3C64XX_SPI_MODE_CFG);
>  
> @@ -610,6 +628,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data 
> *sdd,
>               bpw = xfer->bits_per_word ? : spi->bits_per_word;
>               speed = xfer->speed_hz ? : spi->max_speed_hz;
>  
> +             if (xfer->len % (bpw / 8)) {
> +                     dev_err(&spi->dev,
> +                             "Xfer length(%u) not a multiple of word 
> size(%u)\n",
> +                             xfer->len, bpw / 8);
> +                     status = -EIO;
> +                     goto out;
> +             }
> +
>               if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
>                       sdd->cur_bpw = bpw;
>                       sdd->cur_speed = speed;
> -- 
> 1.6.2.5
> 

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to