]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/spi/spi.c
Merge remote-tracking branch 'spi/fix/core' into spi-linus
[karo-tx-linux.git] / drivers / spi / spi.c
index 349ebba4b1992afdf703e689022dfbf67b07f626..965dd8ac59394ad023ac53f3dbd2cf7e6b5beffb 100644 (file)
@@ -370,6 +370,17 @@ static void spi_dev_set_name(struct spi_device *spi)
                     spi->chip_select);
 }
 
+static int spi_dev_check(struct device *dev, void *data)
+{
+       struct spi_device *spi = to_spi_device(dev);
+       struct spi_device *new_spi = data;
+
+       if (spi->master == new_spi->master &&
+           spi->chip_select == new_spi->chip_select)
+               return -EBUSY;
+       return 0;
+}
+
 /**
  * spi_add_device - Add spi_device allocated with spi_alloc_device
  * @spi: spi_device to register
@@ -384,7 +395,6 @@ int spi_add_device(struct spi_device *spi)
        static DEFINE_MUTEX(spi_add_lock);
        struct spi_master *master = spi->master;
        struct device *dev = master->dev.parent;
-       struct device *d;
        int status;
 
        /* Chipselects are numbered 0..max; validate. */
@@ -404,12 +414,10 @@ int spi_add_device(struct spi_device *spi)
         */
        mutex_lock(&spi_add_lock);
 
-       d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
-       if (d != NULL) {
+       status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
+       if (status) {
                dev_err(dev, "chipselect %d already in use\n",
                                spi->chip_select);
-               put_device(d);
-               status = -EBUSY;
                goto done;
        }
 
@@ -591,8 +599,10 @@ static int spi_transfer_one_message(struct spi_master *master,
                        goto out;
                }
 
-               if (ret > 0)
+               if (ret > 0) {
+                       ret = 0;
                        wait_for_completion(&master->xfer_completion);
+               }
 
                trace_spi_transfer_stop(msg, xfer);
 
@@ -632,7 +642,7 @@ out:
  *
  * Called by SPI drivers using the core transfer_one_message()
  * implementation to notify it that the current interrupt driven
- * transfer has finised and the next one may be scheduled.
+ * transfer has finished and the next one may be scheduled.
  */
 void spi_finalize_current_transfer(struct spi_master *master)
 {
@@ -735,7 +745,9 @@ static void spi_pump_messages(struct kthread_work *work)
        ret = master->transfer_one_message(master, master->cur_msg);
        if (ret) {
                dev_err(&master->dev,
-                       "failed to transfer one message from queue\n");
+                       "failed to transfer one message from queue: %d\n", ret);
+               master->cur_msg->status = ret;
+               spi_finalize_current_message(master);
                return;
        }
 }