diff options
Diffstat (limited to 'drivers/spi/spidev.c')
-rw-r--r-- | drivers/spi/spidev.c | 33 |
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 | */ | ||
102 | static void spidev_complete(void *arg) | ||
103 | { | ||
104 | complete(arg); | ||
105 | } | ||
106 | |||
107 | static ssize_t | 98 | static ssize_t |
108 | spidev_sync(struct spidev_data *spidev, struct spi_message *message) | 99 | spidev_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: | |||
647 | static int spidev_release(struct inode *inode, struct file *filp) | 635 | static 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 | ||
682 | static const struct file_operations spidev_fops = { | 669 | static const struct file_operations spidev_fops = { |