@@ -222,6 +222,32 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw)
222
222
}
223
223
EXPORT_SYMBOL_NS_GPL (dw_spi_check_status , "SPI_DW_CORE" );
224
224
225
+ static inline bool dw_spi_ctlr_busy (struct dw_spi * dws )
226
+ {
227
+ return dw_readl (dws , DW_SPI_SR ) & DW_SPI_SR_BUSY ;
228
+ }
229
+
230
+ static enum hrtimer_restart dw_spi_hrtimer_handler (struct hrtimer * hr )
231
+ {
232
+ struct dw_spi * dws = container_of (hr , struct dw_spi , hrtimer );
233
+
234
+ if (!dw_spi_ctlr_busy (dws )) {
235
+ spi_finalize_current_transfer (dws -> host );
236
+ return HRTIMER_NORESTART ;
237
+ }
238
+
239
+ if (!dws -> idle_wait_retries ) {
240
+ dev_err (& dws -> host -> dev , "controller stuck at busy\n" );
241
+ spi_finalize_current_transfer (dws -> host );
242
+ return HRTIMER_NORESTART ;
243
+ }
244
+
245
+ dws -> idle_wait_retries -- ;
246
+ hrtimer_forward_now (hr , dws -> idle_wait_interval );
247
+
248
+ return HRTIMER_RESTART ;
249
+ }
250
+
225
251
static irqreturn_t dw_spi_transfer_handler (struct dw_spi * dws )
226
252
{
227
253
u16 irq_status = dw_readl (dws , DW_SPI_ISR );
@@ -248,7 +274,22 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
248
274
}
249
275
} else if (!dws -> tx_len ) {
250
276
dw_spi_mask_intr (dws , DW_SPI_INT_TXEI );
251
- spi_finalize_current_transfer (dws -> host );
277
+ if (dw_spi_ctlr_busy (dws )) {
278
+ ktime_t period = ns_to_ktime (DIV_ROUND_UP (NSEC_PER_SEC , dws -> current_freq ));
279
+
280
+ /*
281
+ * Make the initial wait an underestimate of how long the transfer
282
+ * should take, then poll rapidly to reduce the delay
283
+ */
284
+ hrtimer_start (& dws -> hrtimer ,
285
+ period * (8 * dws -> n_bytes - 1 ),
286
+ HRTIMER_MODE_REL );
287
+ dws -> idle_wait_retries = 10 ;
288
+ dws -> idle_wait_interval = period ;
289
+ } else {
290
+ spi_finalize_current_transfer (dws -> host );
291
+ }
292
+ return IRQ_HANDLED ;
252
293
}
253
294
254
295
/*
@@ -257,9 +298,13 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
257
298
* have the TXE IRQ flood at the final stage of the transfer.
258
299
*/
259
300
if (irq_status & DW_SPI_INT_TXEI ) {
260
- if (!dws -> tx_len )
261
- dw_spi_mask_intr (dws , DW_SPI_INT_TXEI );
262
301
dw_writer (dws );
302
+ if (!dws -> tx_len ) {
303
+ if (dws -> rx_len )
304
+ dw_spi_mask_intr (dws , DW_SPI_INT_TXEI );
305
+ else
306
+ dw_writel (dws , DW_SPI_TXFTLR , 0 );
307
+ }
263
308
}
264
309
265
310
return IRQ_HANDLED ;
@@ -430,7 +475,7 @@ static int dw_spi_poll_transfer(struct dw_spi *dws,
430
475
ret = dw_spi_check_status (dws , true);
431
476
if (ret )
432
477
return ret ;
433
- } while (dws -> rx_len );
478
+ } while (dws -> rx_len || dws -> tx_len || dw_spi_ctlr_busy ( dws ) );
434
479
435
480
return 0 ;
436
481
}
@@ -650,11 +695,6 @@ static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi)
650
695
return 0 ;
651
696
}
652
697
653
- static inline bool dw_spi_ctlr_busy (struct dw_spi * dws )
654
- {
655
- return dw_readl (dws , DW_SPI_SR ) & DW_SPI_SR_BUSY ;
656
- }
657
-
658
698
static int dw_spi_wait_mem_op_done (struct dw_spi * dws )
659
699
{
660
700
int retry = DW_SPI_WAIT_RETRIES ;
@@ -1011,6 +1051,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
1011
1051
}
1012
1052
}
1013
1053
1054
+ hrtimer_setup (& dws -> hrtimer , dw_spi_hrtimer_handler , CLOCK_MONOTONIC , HRTIMER_MODE_ABS );
1055
+
1014
1056
ret = spi_register_controller (host );
1015
1057
if (ret ) {
1016
1058
dev_err_probe (dev , ret , "problem registering spi host\n" );
@@ -1036,6 +1078,7 @@ void dw_spi_remove_host(struct dw_spi *dws)
1036
1078
{
1037
1079
dw_spi_debugfs_remove (dws );
1038
1080
1081
+ hrtimer_cancel (& dws -> hrtimer );
1039
1082
spi_unregister_controller (dws -> host );
1040
1083
1041
1084
if (dws -> dma_ops && dws -> dma_ops -> dma_exit )
0 commit comments