aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spidev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spidev.c')
-rw-r--r--drivers/spi/spidev.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 92c909eed6b5..dd616ff0ffc5 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -95,37 +95,25 @@ MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
95 95
96/*-------------------------------------------------------------------------*/ 96/*-------------------------------------------------------------------------*/
97 97
98/*
99 * We can't use the standard synchronous wrappers for file I/O; we
100 * need to protect against async removal of the underlying spi_device.
101 */
102static void spidev_complete(void *arg)
103{
104 complete(arg);
105}
106
107static ssize_t 98static ssize_t
108spidev_sync(struct spidev_data *spidev, struct spi_message *message) 99spidev_sync(struct spidev_data *spidev, struct spi_message *message)
109{ 100{
110 DECLARE_COMPLETION_ONSTACK(done); 101 DECLARE_COMPLETION_ONSTACK(done);
111 int status; 102 int status;
112 103 struct spi_device *spi;
113 message->complete = spidev_complete;
114 message->context = &done;
115 104
116 spin_lock_irq(&spidev->spi_lock); 105 spin_lock_irq(&spidev->spi_lock);
117 if (spidev->spi == NULL) 106 spi = spidev->spi;
107 spin_unlock_irq(&spidev->spi_lock);
108
109 if (spi == NULL)
118 status = -ESHUTDOWN; 110 status = -ESHUTDOWN;
119 else 111 else
120 status = spi_async(spidev->spi, message); 112 status = spi_sync(spi, message);
121 spin_unlock_irq(&spidev->spi_lock); 113
114 if (status == 0)
115 status = message->actual_length;
122 116
123 if (status == 0) {
124 wait_for_completion(&done);
125 status = message->status;
126 if (status == 0)
127 status = message->actual_length;
128 }
129 return status; 117 return status;
130} 118}
131 119
@@ -647,7 +635,6 @@ err_find_dev:
647static int spidev_release(struct inode *inode, struct file *filp) 635static int spidev_release(struct inode *inode, struct file *filp)
648{ 636{
649 struct spidev_data *spidev; 637 struct spidev_data *spidev;
650 int status = 0;
651 638
652 mutex_lock(&device_list_lock); 639 mutex_lock(&device_list_lock);
653 spidev = filp->private_data; 640 spidev = filp->private_data;
@@ -676,7 +663,7 @@ static int spidev_release(struct inode *inode, struct file *filp)
676 } 663 }
677 mutex_unlock(&device_list_lock); 664 mutex_unlock(&device_list_lock);
678 665
679 return status; 666 return 0;
680} 667}
681 668
682static const struct file_operations spidev_fops = { 669static const struct file_operations spidev_fops = {