aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVaradarajan Narayanan <varada@codeaurora.org>2017-07-28 02:53:00 -0400
committerMark Brown <broonie@kernel.org>2017-08-08 07:15:50 -0400
commitcd595b99af24b8efa4a6a8889ad65f4d270fd644 (patch)
tree65f2b3f6ce01b103f492055d6607351789bff5fa
parent5884e17ef3cb3dac2e83e466246cf033bfba0e2f (diff)
spi: qup: Ensure done detection
This patch fixes an issue where a SPI transaction has completed, but the done condition is missed. This occurs because at the time of interrupt the MAX_INPUT_DONE_FLAG is not asserted. However, in the process of reading blocks of data from the FIFO, the last portion of data comes in. The opflags read at the beginning of the irq handler no longer matches the current opflag state. To get around this condition, the block read function should update the opflags so that done detection is correct after the return. Signed-off-by: Andy Gross <agross@codeaurora.org> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org> Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-qup.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 3c2c2c0ed9ab..4c3c938360f4 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -266,7 +266,7 @@ static void spi_qup_read_from_fifo(struct spi_qup *controller, u32 num_words)
266 } 266 }
267} 267}
268 268
269static void spi_qup_read(struct spi_qup *controller) 269static void spi_qup_read(struct spi_qup *controller, u32 *opflags)
270{ 270{
271 u32 remainder, words_per_block, num_words; 271 u32 remainder, words_per_block, num_words;
272 bool is_block_mode = controller->mode == QUP_IO_M_MODE_BLOCK; 272 bool is_block_mode = controller->mode == QUP_IO_M_MODE_BLOCK;
@@ -305,10 +305,12 @@ static void spi_qup_read(struct spi_qup *controller)
305 305
306 /* 306 /*
307 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block 307 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
308 * mode reads, it has to be cleared again at the very end 308 * reads, it has to be cleared again at the very end. However, be sure
309 * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
310 * present and this is used to determine if transaction is complete
309 */ 311 */
310 if (is_block_mode && spi_qup_is_flag_set(controller, 312 *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
311 QUP_OP_MAX_INPUT_DONE_FLAG)) 313 if (is_block_mode && *opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
312 writel_relaxed(QUP_OP_IN_SERVICE_FLAG, 314 writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
313 controller->base + QUP_OPERATIONAL); 315 controller->base + QUP_OPERATIONAL);
314 316
@@ -613,7 +615,7 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
613 writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); 615 writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
614 } else { 616 } else {
615 if (opflags & QUP_OP_IN_SERVICE_FLAG) 617 if (opflags & QUP_OP_IN_SERVICE_FLAG)
616 spi_qup_read(controller); 618 spi_qup_read(controller, &opflags);
617 619
618 if (opflags & QUP_OP_OUT_SERVICE_FLAG) 620 if (opflags & QUP_OP_OUT_SERVICE_FLAG)
619 spi_qup_write(controller); 621 spi_qup_write(controller);