diff options
author | Mark Brown <broonie@linaro.org> | 2014-01-23 08:07:00 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-23 08:07:00 -0500 |
commit | 7e2c225d585cd6d7481ff4ec446a67334ef11f4d (patch) | |
tree | addcb9cdff0dbf2f8a390d48a1460e64ae2008cd | |
parent | 7e22e91102c6b9df7c4ae2168910e19d2bb14cd6 (diff) | |
parent | 13a4279880229240af38486611c94587492b24d3 (diff) |
Merge remote-tracking branch 'spi/fix/core' into spi-linus
-rw-r--r-- | drivers/spi/spi.c | 28 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 12 |
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 | ||
373 | static 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 | */ |
637 | void spi_finalize_current_transfer(struct spi_master *master) | 647 | void 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 |