Merge remote-tracking branch 'spi/topic/core' into spi-next
authorMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:50:55 +0000 (00:50 +0000)
committerMark Brown <broonie@linaro.org>
Sun, 30 Mar 2014 00:50:55 +0000 (00:50 +0000)
1  2 
drivers/spi/spi.c

diff --combined drivers/spi/spi.c
@@@ -255,13 -255,12 +255,12 @@@ EXPORT_SYMBOL_GPL(spi_bus_type)
  static int spi_drv_probe(struct device *dev)
  {
        const struct spi_driver         *sdrv = to_spi_driver(dev->driver);
-       struct spi_device               *spi = to_spi_device(dev);
        int ret;
  
-       acpi_dev_pm_attach(&spi->dev, true);
-       ret = sdrv->probe(spi);
+       acpi_dev_pm_attach(dev, true);
+       ret = sdrv->probe(to_spi_device(dev));
        if (ret)
-               acpi_dev_pm_detach(&spi->dev, true);
+               acpi_dev_pm_detach(dev, true);
  
        return ret;
  }
  static int spi_drv_remove(struct device *dev)
  {
        const struct spi_driver         *sdrv = to_spi_driver(dev->driver);
-       struct spi_device               *spi = to_spi_device(dev);
        int ret;
  
-       ret = sdrv->remove(spi);
-       acpi_dev_pm_detach(&spi->dev, true);
+       ret = sdrv->remove(to_spi_device(dev));
+       acpi_dev_pm_detach(dev, true);
  
        return ret;
  }
@@@ -591,6 -589,7 +589,6 @@@ static int spi_transfer_one_message(str
                                    struct spi_message *msg)
  {
        struct spi_transfer *xfer;
 -      bool cur_cs = true;
        bool keep_cs = false;
        int ret = 0;
  
                                         &msg->transfers)) {
                                keep_cs = true;
                        } else {
 -                              cur_cs = !cur_cs;
 -                              spi_set_cs(msg->spi, cur_cs);
 +                              spi_set_cs(msg->spi, false);
 +                              udelay(10);
 +                              spi_set_cs(msg->spi, true);
                        }
                }
  
@@@ -755,7 -753,9 +753,7 @@@ static void spi_pump_messages(struct kt
        ret = master->transfer_one_message(master, master->cur_msg);
        if (ret) {
                dev_err(&master->dev,
 -                      "failed to transfer one message from queue: %d\n", ret);
 -              master->cur_msg->status = ret;
 -              spi_finalize_current_message(master);
 +                      "failed to transfer one message from queue\n");
                return;
        }
  }
@@@ -892,7 -892,7 +890,7 @@@ static int spi_stop_queue(struct spi_ma
         */
        while ((!list_empty(&master->queue) || master->busy) && limit--) {
                spin_unlock_irqrestore(&master->queue_lock, flags);
-               msleep(10);
+               usleep_range(10000, 11000);
                spin_lock_irqsave(&master->queue_lock, flags);
        }
  
@@@ -1617,11 -1617,10 +1615,10 @@@ static int __spi_validate(struct spi_de
  {
        struct spi_master *master = spi->master;
        struct spi_transfer *xfer;
+       int w_size;
  
        if (list_empty(&message->transfers))
                return -EINVAL;
-       if (!message->complete)
-               return -EINVAL;
  
        /* Half-duplex links include original MicroWire, and ones with
         * only one data pin like SPI_3WIRE (switches direction) or where
                message->frame_length += xfer->len;
                if (!xfer->bits_per_word)
                        xfer->bits_per_word = spi->bits_per_word;
-               if (!xfer->speed_hz) {
+               if (!xfer->speed_hz)
                        xfer->speed_hz = spi->max_speed_hz;
-                       if (master->max_speed_hz &&
-                           xfer->speed_hz > master->max_speed_hz)
-                               xfer->speed_hz = master->max_speed_hz;
-               }
+               if (master->max_speed_hz &&
+                   xfer->speed_hz > master->max_speed_hz)
+                       xfer->speed_hz = master->max_speed_hz;
  
                if (master->bits_per_word_mask) {
                        /* Only 32 bits fit in the mask */
                                return -EINVAL;
                }
  
+               /*
+                * SPI transfer length should be multiple of SPI word size
+                * where SPI word size should be power-of-two multiple
+                */
+               if (xfer->bits_per_word <= 8)
+                       w_size = 1;
+               else if (xfer->bits_per_word <= 16)
+                       w_size = 2;
+               else
+                       w_size = 4;
+               /* No partial transfers accepted */
+               if (xfer->len % w_size)
+                       return -EINVAL;
                if (xfer->speed_hz && master->min_speed_hz &&
                    xfer->speed_hz < master->min_speed_hz)
                        return -EINVAL;
-               if (xfer->speed_hz && master->max_speed_hz &&
-                   xfer->speed_hz > master->max_speed_hz)
-                       return -EINVAL;
  
                if (xfer->tx_buf && !xfer->tx_nbits)
                        xfer->tx_nbits = SPI_NBITS_SINGLE;