(http://lkml.org/lkml/2007/4/16/333)

Signed-off-by: Bryan Wu <[EMAIL PROTECTED]>
---
 drivers/spi/Kconfig       |   11 +-
 drivers/spi/Makefile      |    4 +-
 drivers/spi/spi_bfin5xx.c |  345 ++++++++++++++++++++++++---------------------
 3 files changed, 193 insertions(+), 167 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 1ab2ed1..584ed9f 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -58,6 +58,12 @@ config SPI_ATMEL
          This selects a driver for the Atmel SPI Controller, present on
          many AT32 (AVR32) and AT91 (ARM) chips.
 
+config SPI_BFIN
+       tristate "SPI controller driver for ADI Blackfin5xx"
+       depends on SPI_MASTER && BFIN
+       help
+         This is the SPI controller master driver for Blackfin 5xx processor.
+
 config SPI_BITBANG
        tristate "Bitbanging SPI master"
        depends on SPI_MASTER && EXPERIMENTAL
@@ -165,11 +171,6 @@ config SPI_SPIDEV
 #
 # Add new SPI protocol masters in alphabetical order above this line
 #
-config SPI_BFIN
-       tristate "SPI controller driver for ADI Blackfin5xx"
-       depends on SPI_MASTER && BFIN
-       help
-         This is the SPI controller master driver for Blackfin 5xx processor.
 
 # (slave support would go here)
 
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index f9dcdd1..4cc5e99 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,8 +11,9 @@ endif
 obj-$(CONFIG_SPI_MASTER)               += spi.o
 
 # SPI master controller drivers (bus)
-obj-$(CONFIG_SPI_BITBANG)              += spi_bitbang.o
 obj-$(CONFIG_SPI_ATMEL)                        += atmel_spi.o
+obj-$(CONFIG_SPI_BFIN)                 += spi_bfin5xx.o
+obj-$(CONFIG_SPI_BITBANG)              += spi_bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)            += spi_butterfly.o
 obj-$(CONFIG_SPI_IMX)                  += spi_imx.o
 obj-$(CONFIG_SPI_PXA2XX)               += pxa2xx_spi.o
@@ -20,7 +21,6 @@ obj-$(CONFIG_SPI_OMAP_UWIRE)          += omap_uwire.o
 obj-$(CONFIG_SPI_MPC83xx)              += spi_mpc83xx.o
 obj-$(CONFIG_SPI_S3C24XX_GPIO)         += spi_s3c24xx_gpio.o
 obj-$(CONFIG_SPI_S3C24XX)              += spi_s3c24xx.o
-obj-$(CONFIG_SPI_BFIN)                 += spi_bfin5xx.o
 #      ... add above this line ...
 
 # SPI protocol drivers (device/link on bus)
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index ab6781a..2bbbe50 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -76,7 +76,6 @@ DEFINE_SPI_REG(SHAW, 0x18)
 #define QUEUE_RUNNING 0
 #define QUEUE_STOPPED 1
 int dma_requested;
-char chip_select_flag;
 
 struct driver_data {
        /* Driver model hookup */
@@ -175,8 +174,9 @@ static int flush(struct driver_data *drv_data)
        unsigned long limit = loops_per_jiffy << 1;
 
        /* wait for stop and clear stat */
-       do {
-       } while (!(read_STAT() & BIT_STAT_SPIF) && limit--);
+       while (!(read_STAT() & BIT_STAT_SPIF) && limit--)
+               continue;
+       
        write_STAT(BIT_STAT_CLR);
 
        return limit;
@@ -192,42 +192,50 @@ static void restore_state(struct driver_data *drv_data)
        bfin_spi_disable(drv_data);
        pr_debug("restoring spi ctl state\n");
 
-#if defined(CONFIG_BF534)||defined(CONFIG_BF536)||defined(CONFIG_BF537)
-       if (chip->chip_select_num == 1) {
-               pr_debug("set for chip select 1\n");
+#if defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537)
+       pr_debug("chip select number is %d\n", chip->chip_select_num);
+       
+       switch (chip->chip_select_num) {
+       case 1:
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3c00);
                SSYNC();
-
-       } else if (chip->chip_select_num == 2 || chip->chip_select_num == 3) {
-               pr_debug("set for chip select 2\n");
+               break;
+       
+       case 2:
+       case 3:
                bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJSE_SPI);
                SSYNC();
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
                SSYNC();
-
-       } else if (chip->chip_select_num == 4) {
+               break;
+       
+       case 4:
                bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS4E_SPI);
                SSYNC();
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3840);
                SSYNC();
-
-       } else if (chip->chip_select_num == 5) {
+               break;
+       
+       case 5:
                bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS5E_SPI);
                SSYNC();
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3820);
                SSYNC();
+               break;
 
-       } else if (chip->chip_select_num == 6) {
+       case 6:
                bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS6E_SPI);
                SSYNC();
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3810);
                SSYNC();
-
-       } else if (chip->chip_select_num == 7) {
+               break;
+       
+       case 7:
                bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJCE_SPI);
                SSYNC();
                bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
                SSYNC();
+               break;
        }
 #endif
 
@@ -251,8 +259,8 @@ static void null_writer(struct driver_data *drv_data)
 
        while (drv_data->tx < drv_data->tx_end) {
                write_TDBR(0);
-               do {
-               } while ((read_STAT() & BIT_STAT_TXS));
+               while ((read_STAT() & BIT_STAT_TXS))
+                       continue;
                drv_data->tx += n_bytes;
        }
 }
@@ -263,8 +271,8 @@ static void null_reader(struct driver_data *drv_data)
        dummy_read();
 
        while (drv_data->rx < drv_data->rx_end) {
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                dummy_read();
                drv_data->rx += n_bytes;
        }
@@ -275,14 +283,14 @@ static void u8_writer(struct driver_data *drv_data)
        pr_debug("cr8-s is 0x%x\n", read_STAT());
        while (drv_data->tx < drv_data->tx_end) {
                write_TDBR(*(u8 *) (drv_data->tx));
-               do {
-               } while (read_STAT() & BIT_STAT_TXS);
+               while (read_STAT() & BIT_STAT_TXS)
+                       continue;
                ++drv_data->tx;
        }
 
        /* poll for SPI completion before returning */
-       do {
-       } while (!(read_STAT() & BIT_STAT_SPIF));
+       while (!(read_STAT() & BIT_STAT_SPIF))
+               continue;
 }
 
 static void u8_cs_chg_writer(struct driver_data *drv_data)
@@ -294,10 +302,10 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
                SSYNC();
 
                write_TDBR(*(u8 *) (drv_data->tx));
-               do {
-               } while (read_STAT() & BIT_STAT_TXS);
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
+               while (read_STAT() & BIT_STAT_TXS)
+                       continue;
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
                if (chip->cs_chg_udelay)
@@ -318,13 +326,14 @@ static void u8_reader(struct driver_data *drv_data)
        dummy_read();
 
        while (drv_data->rx < drv_data->rx_end - 1) {
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u8 *) (drv_data->rx) = read_RDBR();
                ++drv_data->rx;
        }
-       do {
-       } while (!(read_STAT() & BIT_STAT_RXS));
+       
+       while (!(read_STAT() & BIT_STAT_RXS))
+               continue;
        *(u8 *) (drv_data->rx) = read_SHAW();
        ++drv_data->rx;
 }
@@ -338,10 +347,10 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
                SSYNC();
 
                read_RDBR();    /* kick off */
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
                *(u8 *) (drv_data->rx) = read_SHAW();
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
@@ -358,10 +367,10 @@ static void u8_duplex(struct driver_data *drv_data)
        /* in duplex mode, clk is triggered by writing of TDBR */
        while (drv_data->rx < drv_data->rx_end) {
                write_TDBR(*(u8 *) (drv_data->tx));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u8 *) (drv_data->rx) = read_RDBR();
                ++drv_data->rx;
                ++drv_data->tx;
@@ -377,10 +386,10 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
                SSYNC();
 
                write_TDBR(*(u8 *) (drv_data->tx));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u8 *) (drv_data->rx) = read_RDBR();
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
@@ -398,14 +407,14 @@ static void u16_writer(struct driver_data *drv_data)
        pr_debug("cr16 is 0x%x\n", read_STAT());
        while (drv_data->tx < drv_data->tx_end) {
                write_TDBR(*(u16 *) (drv_data->tx));
-               do {
-               } while ((read_STAT() & BIT_STAT_TXS));
+               while ((read_STAT() & BIT_STAT_TXS))
+                       continue;
                drv_data->tx += 2;
        }
 
        /* poll for SPI completion before returning */
-       do {
-       } while (!(read_STAT() & BIT_STAT_SPIF));
+       while (!(read_STAT() & BIT_STAT_SPIF))
+               continue;
 }
 
 static void u16_cs_chg_writer(struct driver_data *drv_data)
@@ -417,10 +426,10 @@ static void u16_cs_chg_writer(struct driver_data 
*drv_data)
                SSYNC();
 
                write_TDBR(*(u16 *) (drv_data->tx));
-               do {
-               } while ((read_STAT() & BIT_STAT_TXS));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
+               while ((read_STAT() & BIT_STAT_TXS))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
                if (chip->cs_chg_udelay)
@@ -437,13 +446,14 @@ static void u16_reader(struct driver_data *drv_data)
        dummy_read();
 
        while (drv_data->rx < (drv_data->rx_end - 2)) {
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u16 *) (drv_data->rx) = read_RDBR();
                drv_data->rx += 2;
        }
-       do {
-       } while (!(read_STAT() & BIT_STAT_RXS));
+       
+       while (!(read_STAT() & BIT_STAT_RXS))
+               continue;
        *(u16 *) (drv_data->rx) = read_SHAW();
        drv_data->rx += 2;
 }
@@ -457,10 +467,10 @@ static void u16_cs_chg_reader(struct driver_data 
*drv_data)
                SSYNC();
 
                read_RDBR();    /* kick off */
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
                *(u16 *) (drv_data->rx) = read_SHAW();
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
@@ -477,10 +487,10 @@ static void u16_duplex(struct driver_data *drv_data)
        /* in duplex mode, clk is triggered by writing of TDBR */
        while (drv_data->tx < drv_data->tx_end) {
                write_TDBR(*(u16 *) (drv_data->tx));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u16 *) (drv_data->rx) = read_RDBR();
                drv_data->rx += 2;
                drv_data->tx += 2;
@@ -496,10 +506,10 @@ static void u16_cs_chg_duplex(struct driver_data 
*drv_data)
                SSYNC();
 
                write_TDBR(*(u16 *) (drv_data->tx));
-               do {
-               } while (!(read_STAT() & BIT_STAT_SPIF));
-               do {
-               } while (!(read_STAT() & BIT_STAT_RXS));
+               while (!(read_STAT() & BIT_STAT_SPIF))
+                       continue;
+               while (!(read_STAT() & BIT_STAT_RXS))
+                       continue;
                *(u16 *) (drv_data->rx) = read_RDBR();
                write_FLAG(0xFF00 | chip->flag);
                SSYNC();
@@ -528,8 +538,9 @@ static void *next_transfer(struct driver_data *drv_data)
                return DONE_STATE;
 }
 
-/* caller already set message->status; dma and pio irqs are blocked
- * give finished message back
+/*
+ * caller already set message->status;
+ * dma and pio irqs are blocked give finished message back
  */
 static void giveback(struct driver_data *drv_data)
 {
@@ -549,6 +560,7 @@ static void giveback(struct driver_data *drv_data)
                                   struct spi_transfer, transfer_list);
 
        msg->state = NULL;
+
        /* disable chip select signal. And not stop spi in autobuffer mode */
        if (drv_data->tx_dma != 0xFFFF) {
                write_FLAG(0xFF00);
@@ -567,15 +579,19 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id, 
struct pt_regs *regs)
        pr_debug("in dma_irq_handler\n");
        clear_dma_irqstat(CH_SPI);
 
-       /* wait for the last transaction shifted out.  yes, these two
+       /*
+        * wait for the last transaction shifted out.  yes, these two
         * while loops are supposed to be the same (see the HRM).
         */
        if (drv_data->tx != NULL) {
-               while (bfin_read_SPI_STAT() & TXS) ;
-               while (bfin_read_SPI_STAT() & TXS) ;
+               while (bfin_read_SPI_STAT() & TXS)
+                       continue;
+               while (bfin_read_SPI_STAT() & TXS)
+                       continue;
        }
 
-       while (!(bfin_read_SPI_STAT() & SPIF)) ;
+       while (!(bfin_read_SPI_STAT() & SPIF))
+               continue;
 
        bfin_spi_disable(drv_data);
 
@@ -609,8 +625,11 @@ static void pump_transfers(unsigned long data)
        transfer = drv_data->cur_transfer;
        chip = drv_data->cur_chip;
 
-       /* if msg is error or done, report it back using complete() callback */
-       /* Handle for abort */
+       /*
+        * if msg is error or done, report it back using complete() callback
+        */
+
+        /* Handle for abort */
        if (message->state == ERROR_STATE) {
                message->status = -EIO;
                giveback(drv_data);
@@ -676,7 +695,6 @@ static void pump_transfers(unsigned long data)
             drv_data->write, chip->write, null_writer);
 
        /* speed and width has been set on per message */
-
        message->state = RUNNING_STATE;
        dma_config = 0;
 
@@ -690,8 +708,12 @@ static void pump_transfers(unsigned long data)
 
        pr_debug("now pumping a transfer: width is %d, len is %d\n", width,
                 transfer->len);
-       /* Try to map dma buffer and do a dma transfer if successful */
-       /* use different way to r/w according to drv_data->cur_chip->enable_dma 
*/
+
+       /*
+        * Try to map dma buffer and do a dma transfer if
+        * successful use different way to r/w according to
+        * drv_data->cur_chip->enable_dma
+        */
        if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
 
                write_STAT(BIT_STAT_CLR);
@@ -699,8 +721,8 @@ static void pump_transfers(unsigned long data)
                clear_dma_irqstat(CH_SPI);
                bfin_spi_disable(drv_data);
 
-               pr_debug("doing dma transfer\n");
                /* config dma channel */
+               pr_debug("doing dma transfer\n");
                if (width == CFG_SPI_WORDSIZE16) {
                        set_dma_x_count(CH_SPI, drv_data->len);
                        set_dma_x_modify(CH_SPI, 2);
@@ -711,9 +733,8 @@ static void pump_transfers(unsigned long data)
                        dma_width = WDSIZE_8;
                }
 
-               /* Go baby, go */
                /* set transfer width,direction. And enable spi */
-               cr = (read_CTRL() & (~BIT_CTL_TIMOD));  /* clear the TIMOD bits 
*/
+               cr = (read_CTRL() & (~BIT_CTL_TIMOD));
 
                /* dirty hack for autobuffer DMA mode */
                if (drv_data->tx_dma == 0xFFFF) {
@@ -727,6 +748,7 @@ static void pump_transfers(unsigned long data)
                        enable_dma(CH_SPI);
                        write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
                                   (CFG_SPI_ENABLE << 14));
+
                        /* just return here, there can only be one transfer in 
this mode */
                        message->status = 0;
                        giveback(drv_data);
@@ -760,6 +782,7 @@ static void pump_transfers(unsigned long data)
                        write_CTRL(cr);
                } else if (drv_data->tx != NULL) {
                        pr_debug("doing DMA out.\n");
+
                        /* start dma */
                        dma_enable_irq(CH_SPI);
                        dma_config = (RESTART | dma_width | DI_EN);
@@ -771,13 +794,14 @@ static void pump_transfers(unsigned long data)
                                   (CFG_SPI_ENABLE << 14));
 
                }
-       } else {                /* IO mode write then read */
-               /* Go baby, go */
+       } else {
+               /* IO mode write then read */
                pr_debug("doing IO transfer\n");
 
                write_STAT(BIT_STAT_CLR);
 
-               if (drv_data->tx != NULL && drv_data->rx != NULL) {     /* full 
duplex mode */
+               if (drv_data->tx != NULL && drv_data->rx != NULL) {
+                       /* full duplex mode */
                        BUG_ON((drv_data->tx_end - drv_data->tx) !=
                               (drv_data->rx_end - drv_data->rx));
                        cr = (read_CTRL() & (~BIT_CTL_TIMOD));  /* clear the 
TIMOD bits */
@@ -793,7 +817,8 @@ static void pump_transfers(unsigned long data)
 
                        if (drv_data->tx != drv_data->tx_end)
                                tranf_success = 0;
-               } else if (drv_data->tx != NULL) {      /* write only half 
duplex */
+               } else if (drv_data->tx != NULL) {
+                       /* write only half duplex */
                        cr = (read_CTRL() & (~BIT_CTL_TIMOD));  /* clear the 
TIMOD bits */
                        cr |=
                            CFG_SPI_WRITE | (width << 8) | (CFG_SPI_ENABLE <<
@@ -807,8 +832,8 @@ static void pump_transfers(unsigned long data)
 
                        if (drv_data->tx != drv_data->tx_end)
                                tranf_success = 0;
-               } else if (drv_data->rx != NULL) {      /* read only half 
duplex */
-
+               } else if (drv_data->rx != NULL) {
+                       /* read only half duplex */
                        cr = (read_CTRL() & (~BIT_CTL_TIMOD));  /* cleare the 
TIMOD bits */
                        cr |=
                            CFG_SPI_READ | (width << 8) | (CFG_SPI_ENABLE <<
@@ -887,7 +912,10 @@ static void pump_messages(struct work_struct *work)
        spin_unlock_irqrestore(&drv_data->lock, flags);
 }
 
-/* got a msg to transfer, queue it in drv_data->queue. And kick off message 
pumper */
+/*
+ * got a msg to transfer, queue it in drv_data->queue.
+ * And kick off message pumper
+ */
 static int transfer(struct spi_device *spi, struct spi_message *msg)
 {
        struct driver_data *drv_data = spi_master_get_devdata(spi->master);
@@ -923,16 +951,15 @@ static int setup(struct spi_device *spi)
        struct driver_data *drv_data = spi_master_get_devdata(spi->master);
        u8 spi_flg;
 
-       if (chip_select_flag & (1 << (spi->chip_select))) {
-               printk(KERN_ERR
-                      "spi_bfin: error: %s is using the same chip selection as 
another device.\n",
-                      spi->modalias);
-               return -ENODEV;
+       /* Abort device setup if requested features are not supported */
+       if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) {
+               dev_err(&spi->dev, "requested mode not fully supported\n");
+               return -EINVAL;
        }
-       chip_select_flag |= (1 << (spi->chip_select));
 
+       /* Zero (the default) here means 8 bits */
        if (!spi->bits_per_word)
-               spi->bits_per_word = 16;
+               spi->bits_per_word = 8;
 
        if (spi->bits_per_word != 8 && spi->bits_per_word != 16)
                return -EINVAL;
@@ -958,13 +985,20 @@ static int setup(struct spi_device *spi)
                chip->cs_chg_udelay = chip_info->cs_chg_udelay;
        }
 
+       /* translate common spi framework into our register */
        if (spi->mode & SPI_CPOL)
-               chip->ctl_reg &= CPOL;
+               chip->ctl_reg |= CPOL;
        if (spi->mode & SPI_CPHA)
-               chip->ctl_reg &= CPHA;
-
-       /* if any one SPI chip is registered and wants DMA, request the
-          DMA channel for it */
+               chip->ctl_reg |= CPHA;
+       if (spi->mode & SPI_LSB_FIRST)
+               chip->ctl_reg |= LSBF;
+       /* we dont support running in slave mode (yet?) */
+       chip->ctl_reg |= MSTR;
+
+       /*
+        * if any one SPI chip is registered and wants DMA, request the
+        * DMA channel for it
+        */
        if (chip->enable_dma && !dma_requested) {
                /* register dma irq handler */
                if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) {
@@ -981,50 +1015,59 @@ static int setup(struct spi_device *spi)
                dma_requested = 1;
        }
 
-       /* Notice: for blackfin, the speed_hz is the value of register
-          SPI_BAUD, not the real baudrate */
+       /*
+        * Notice: for blackfin, the speed_hz is the value of register
+        * SPI_BAUD, not the real baudrate
+        */
        chip->baud = hz_to_spi_baud(spi->max_speed_hz);
        spi_flg = ~(1 << (spi->chip_select));
        chip->flag = ((u16) spi_flg << 8) | (1 << (spi->chip_select));
        chip->chip_select_num = spi->chip_select;
 
-       if (chip->bits_per_word <= 8) {
+       switch (chip->bits_per_word) {
+       case 8:
                chip->n_bytes = 1;
                chip->width = CFG_SPI_WORDSIZE8;
-               chip->read =
-                   chip->cs_change_per_word ? u8_cs_chg_reader : u8_reader;
-               chip->write =
-                   chip->cs_change_per_word ? u8_cs_chg_writer : u8_writer;
-               chip->duplex =
-                   chip->cs_change_per_word ? u8_cs_chg_duplex : u8_duplex;
-               pr_debug("8bit: chip->write is %p, u8_writer is %p\n",
-                        chip->write, u8_writer);
-       } else if (spi->bits_per_word <= 16) {
+               chip->read = chip->cs_change_per_word ?
+                       u8_cs_chg_reader : u8_reader;
+               chip->write = chip->cs_change_per_word ?
+                       u8_cs_chg_writer : u8_writer;
+               chip->duplex = chip->cs_change_per_word ?
+                       u8_cs_chg_duplex : u8_duplex;
+               break;
+
+       case 16:
                chip->n_bytes = 2;
                chip->width = CFG_SPI_WORDSIZE16;
-               chip->read =
-                   chip->cs_change_per_word ? u16_cs_chg_reader : u16_reader;
-               chip->write =
-                   chip->cs_change_per_word ? u16_cs_chg_writer : u16_writer;
-               chip->duplex =
-                   chip->cs_change_per_word ? u16_cs_chg_duplex : u16_duplex;
-               pr_debug("16bit: chip->write is %p, u16_writer is %p\n",
-                        chip->write, u16_writer);
-       } else {
-               dev_err(&spi->dev, "invalid wordsize\n");
+               chip->read = chip->cs_change_per_word ?
+                       u16_cs_chg_reader : u16_reader;
+               chip->write = chip->cs_change_per_word ?
+                       u16_cs_chg_writer : u16_writer;
+               chip->duplex = chip->cs_change_per_word ?
+                       u16_cs_chg_duplex : u16_duplex;
+               break;
+
+       default:
+               dev_err(&spi->dev, "%d bits_per_word is not supported\n",
+                               chip->bits_per_word);
                kfree(chip);
                return -ENODEV;
        }
-       pr_debug
-           ("setup spi chip %s, width is %d, dma is %d, ctl_reg is 0x%x, 
flag_reg is 0x%x\n",
-            spi->modalias, chip->width, chip->enable_dma, chip->ctl_reg,
-            chip->flag);
+
+       pr_debug("setup spi chip %s, width is %d, dma is %d,",
+                       spi->modalias, chip->width, chip->enable_dma);
+       pr_debug("ctl_reg is 0x%x, flag_reg is 0x%x\n",
+                       chip->ctl_reg, chip->flag);
+
        spi_set_ctldata(spi, chip);
 
        return 0;
 }
 
-/* callback for spi framework. clean driver specific data */
+/*
+ * callback for spi framework.
+ * clean driver specific data
+ */
 static void cleanup(const struct spi_device *spi)
 {
        struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
@@ -1032,7 +1075,7 @@ static void cleanup(const struct spi_device *spi)
        kfree(chip);
 }
 
-static int init_queue(struct driver_data *drv_data)
+static inline int init_queue(struct driver_data *drv_data)
 {
        INIT_LIST_HEAD(&drv_data->queue);
        spin_lock_init(&drv_data->lock);
@@ -1054,7 +1097,7 @@ static int init_queue(struct driver_data *drv_data)
        return 0;
 }
 
-static int start_queue(struct driver_data *drv_data)
+static inline int start_queue(struct driver_data *drv_data)
 {
        unsigned long flags;
 
@@ -1076,7 +1119,7 @@ static int start_queue(struct driver_data *drv_data)
        return 0;
 }
 
-static int stop_queue(struct driver_data *drv_data)
+static inline int stop_queue(struct driver_data *drv_data)
 {
        unsigned long flags;
        unsigned limit = 500;
@@ -1084,10 +1127,12 @@ static int stop_queue(struct driver_data *drv_data)
 
        spin_lock_irqsave(&drv_data->lock, flags);
 
-       /* This is a bit lame, but is optimized for the common execution path.
+       /*
+        * This is a bit lame, but is optimized for the common execution path.
         * A wait_queue on the drv_data->busy could be used, but then the common
         * execution path (pump_messages) would be required to call wake_up or
-        * friends on every SPI message. Do this instead */
+        * friends on every SPI message. Do this instead
+        */
        drv_data->run = QUEUE_STOPPED;
        while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
                spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -1103,7 +1148,7 @@ static int stop_queue(struct driver_data *drv_data)
        return status;
 }
 
-static int destroy_queue(struct driver_data *drv_data)
+static inline int destroy_queue(struct driver_data *drv_data)
 {
        int status;
 
@@ -1116,7 +1161,7 @@ static int destroy_queue(struct driver_data *drv_data)
        return 0;
 }
 
-static int bfin5xx_spi_probe(struct platform_device *pdev)
+static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct bfin5xx_spi_master *platform_info;
@@ -1126,7 +1171,7 @@ static int bfin5xx_spi_probe(struct platform_device *pdev)
 
        platform_info = dev->platform_data;
 
-       /* Allocate master with space for drv_data and null dma buffer */
+       /* Allocate master with space for drv_data */
        master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
        if (!master) {
                dev_err(&pdev->dev, "can not alloc spi_master\n");
@@ -1172,7 +1217,7 @@ static int bfin5xx_spi_probe(struct platform_device *pdev)
 }
 
 /* stop hardware and remove the driver */
-static int bfin5xx_spi_remove(struct platform_device *pdev)
+static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
 {
        struct driver_data *drv_data = platform_get_drvdata(pdev);
        int status = 0;
@@ -1203,31 +1248,12 @@ static int bfin5xx_spi_remove(struct platform_device 
*pdev)
        return 0;
 }
 
-/* PM, do nothing now */
 #ifdef CONFIG_PM
-static int suspend_devices(struct device *dev, void *pm_message)
-{
-       pm_message_t *state = pm_message;
-
-       if (dev->power.power_state.event != state->event && dev->driver != 
NULL) {
-               dev_warn(dev, "pm state does not match request\n");
-               return -1;
-       }
-
-       return 0;
-}
-
 static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t 
state)
 {
        struct driver_data *drv_data = platform_get_drvdata(pdev);
        int status = 0;
 
-       /* Check all childern for current power state */
-       if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) {
-               dev_warn(&pdev->dev, "suspend aborted\n");
-               return -1;
-       }
-
        status = stop_queue(drv_data);
        if (status != 0)
                return status;
@@ -1260,7 +1286,7 @@ static int bfin5xx_spi_resume(struct platform_device 
*pdev)
 #define bfin5xx_spi_resume NULL
 #endif                         /* CONFIG_PM */
 
-static struct platform_driver driver = {
+static struct platform_driver bfin5xx_spi_driver = {
        .driver = {
                   .name = "bfin-spi-master",
                   .bus = &platform_bus_type,
@@ -1274,15 +1300,14 @@ static struct platform_driver driver = {
 
 static int __init bfin5xx_spi_init(void)
 {
-       platform_driver_register(&driver);
-       return 0;
+       return platform_driver_register(&bfin5xx_spi_driver);
 }
 
 module_init(bfin5xx_spi_init);
 
 static void __exit bfin5xx_spi_exit(void)
 {
-       platform_driver_unregister(&driver);
+       platform_driver_unregister(&bfin5xx_spi_driver);
 }
 
 module_exit(bfin5xx_spi_exit);
-- 
1.5.1.2
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to