aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-01-23 08:07:00 -0500
committerMark Brown <broonie@linaro.org>2014-01-23 08:07:00 -0500
commit7e2c225d585cd6d7481ff4ec446a67334ef11f4d (patch)
treeaddcb9cdff0dbf2f8a390d48a1460e64ae2008cd
parent7e22e91102c6b9df7c4ae2168910e19d2bb14cd6 (diff)
parent13a4279880229240af38486611c94587492b24d3 (diff)
Merge remote-tracking branch 'spi/fix/core' into spi-linus
-rw-r--r--drivers/spi/spi.c28
-rw-r--r--include/linux/spi/spi.h12
2 files changed, 27 insertions, 13 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 349ebba4b199..965dd8ac5939 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -370,6 +370,17 @@ static void spi_dev_set_name(struct spi_device *spi)
370 spi->chip_select); 370 spi->chip_select);
371} 371}
372 372
373static int spi_dev_check(struct device *dev, void *data)
374{
375 struct spi_device *spi = to_spi_device(dev);
376 struct spi_device *new_spi = data;
377
378 if (spi->master == new_spi->master &&
379 spi->chip_select == new_spi->chip_select)
380 return -EBUSY;
381 return 0;
382}
383
373/** 384/**
374 * spi_add_device - Add spi_device allocated with spi_alloc_device 385 * spi_add_device - Add spi_device allocated with spi_alloc_device
375 * @spi: spi_device to register 386 * @spi: spi_device to register
@@ -384,7 +395,6 @@ int spi_add_device(struct spi_device *spi)
384 static DEFINE_MUTEX(spi_add_lock); 395 static DEFINE_MUTEX(spi_add_lock);
385 struct spi_master *master = spi->master; 396 struct spi_master *master = spi->master;
386 struct device *dev = master->dev.parent; 397 struct device *dev = master->dev.parent;
387 struct device *d;
388 int status; 398 int status;
389 399
390 /* Chipselects are numbered 0..max; validate. */ 400 /* Chipselects are numbered 0..max; validate. */
@@ -404,12 +414,10 @@ int spi_add_device(struct spi_device *spi)
404 */ 414 */
405 mutex_lock(&spi_add_lock); 415 mutex_lock(&spi_add_lock);
406 416
407 d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev)); 417 status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
408 if (d != NULL) { 418 if (status) {
409 dev_err(dev, "chipselect %d already in use\n", 419 dev_err(dev, "chipselect %d already in use\n",
410 spi->chip_select); 420 spi->chip_select);
411 put_device(d);
412 status = -EBUSY;
413 goto done; 421 goto done;
414 } 422 }
415 423
@@ -591,8 +599,10 @@ static int spi_transfer_one_message(struct spi_master *master,
591 goto out; 599 goto out;
592 } 600 }
593 601
594 if (ret > 0) 602 if (ret > 0) {
603 ret = 0;
595 wait_for_completion(&master->xfer_completion); 604 wait_for_completion(&master->xfer_completion);
605 }
596 606
597 trace_spi_transfer_stop(msg, xfer); 607 trace_spi_transfer_stop(msg, xfer);
598 608
@@ -632,7 +642,7 @@ out:
632 * 642 *
633 * Called by SPI drivers using the core transfer_one_message() 643 * Called by SPI drivers using the core transfer_one_message()
634 * implementation to notify it that the current interrupt driven 644 * implementation to notify it that the current interrupt driven
635 * transfer has finised and the next one may be scheduled. 645 * transfer has finished and the next one may be scheduled.
636 */ 646 */
637void spi_finalize_current_transfer(struct spi_master *master) 647void spi_finalize_current_transfer(struct spi_master *master)
638{ 648{
@@ -735,7 +745,9 @@ static void spi_pump_messages(struct kthread_work *work)
735 ret = master->transfer_one_message(master, master->cur_msg); 745 ret = master->transfer_one_message(master, master->cur_msg);
736 if (ret) { 746 if (ret) {
737 dev_err(&master->dev, 747 dev_err(&master->dev,
738 "failed to transfer one message from queue\n"); 748 "failed to transfer one message from queue: %d\n", ret);
749 master->cur_msg->status = ret;
750 spi_finalize_current_message(master);
739 return; 751 return;
740 } 752 }
741} 753}
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 8c62ba74dd91..9f5242df9311 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -277,15 +277,17 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
277 * @unprepare_transfer_hardware: there are currently no more messages on the 277 * @unprepare_transfer_hardware: there are currently no more messages on the
278 * queue so the subsystem notifies the driver that it may relax the 278 * queue so the subsystem notifies the driver that it may relax the
279 * hardware by issuing this call 279 * hardware by issuing this call
280 * @set_cs: assert or deassert chip select, true to assert. May be called 280 * @set_cs: set the logic level of the chip select line. May be called
281 * from interrupt context. 281 * from interrupt context.
282 * @prepare_message: set up the controller to transfer a single message, 282 * @prepare_message: set up the controller to transfer a single message,
283 * for example doing DMA mapping. Called from threaded 283 * for example doing DMA mapping. Called from threaded
284 * context. 284 * context.
285 * @transfer_one: transfer a single spi_transfer. When the 285 * @transfer_one: transfer a single spi_transfer.
286 * driver is finished with this transfer it must call 286 * - return 0 if the transfer is finished,
287 * spi_finalize_current_transfer() so the subsystem can issue 287 * - return 1 if the transfer is still in progress. When
288 * the next transfer 288 * the driver is finished with this transfer it must
289 * call spi_finalize_current_transfer() so the subsystem
290 * can issue the next transfer
289 * @unprepare_message: undo any work done by prepare_message(). 291 * @unprepare_message: undo any work done by prepare_message().
290 * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS 292 * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
291 * number. Any individual value may be -ENOENT for CS lines that 293 * number. Any individual value may be -ENOENT for CS lines that