aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/lantiq/patches-4.9/0090-spi-add-transfer_status-callback.patch
blob: de50e228b26c4b98eb6521d9a57ef584de4b6377 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1013,6 +1013,20 @@ static int spi_transfer_one_message(stru
 								 msecs_to_jiffies(ms));
 			}
 
+			if (master->transfer_status) {
+				ret = master->transfer_status(master, ms);
+				if (ret) {
+					SPI_STATISTICS_INCREMENT_FIELD(statm,
+								       errors);
+					SPI_STATISTICS_INCREMENT_FIELD(stats,
+								       errors);
+					dev_err(&msg->spi->dev,
+						"SPI transfer status: %d\n",
+						ret);
+					goto out;
+				}
+			}
+
 			if (ms == 0) {
 				SPI_STATISTICS_INCREMENT_FIELD(statm,
 							       timedout);
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -370,6 +370,8 @@ static inline void spi_unregister_driver
  *                    transfer_one_message are mutually exclusive; when both
  *                    are set, the generic subsystem does not call your
  *                    transfer_one callback.
+ * @transfer_status: This callback allows the driver to return an error code
+ *		     in case the scheduled single spi transfer failed.
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  *		in the generic implementation of transfer_one_message().
  * @unprepare_message: undo any work done by prepare_message().
@@ -546,6 +548,7 @@ struct spi_master {
 	void (*set_cs)(struct spi_device *spi, bool enable);
 	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
 			    struct spi_transfer *transfer);
+	int (*transfer_status)(struct spi_master *master, unsigned long timeout);
 	void (*handle_err)(struct spi_master *master,
 			   struct spi_message *message);