714-spi-qup-properly-detect-extra-interrupts.patch 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. From b69e5e855aaae2dd9f7fc6f4a40af8e6e0cf98ee Mon Sep 17 00:00:00 2001
  2. From: Matthew McClintock <mmcclint@codeaurora.org>
  3. Date: Thu, 10 Mar 2016 16:44:55 -0600
  4. Subject: [PATCH] spi: qup: properly detect extra interrupts
  5. It's possible for a SPI transaction to complete and get another
  6. interrupt and have it processed on the same spi_transfer before the
  7. transfer_one can set it to NULL.
  8. This masks unexpected interrupts, so let's set the spi_transfer to
  9. NULL in the interrupt once the transaction is done. So we can
  10. properly detect these bad interrupts and print warning messages.
  11. Change-Id: I0e70ed59fb50e5c48a72a38f74bd178b17c9f24d
  12. Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org>
  13. ---
  14. drivers/spi/spi-qup.c | 15 +++++++++------
  15. 1 file changed, 9 insertions(+), 6 deletions(-)
  16. --- a/drivers/spi/spi-qup.c
  17. +++ b/drivers/spi/spi-qup.c
  18. @@ -509,6 +509,7 @@ static irqreturn_t spi_qup_qup_irq(int i
  19. u32 opflags, qup_err, spi_err;
  20. unsigned long flags;
  21. int error = 0;
  22. + bool done = 0;
  23. spin_lock_irqsave(&controller->lock, flags);
  24. xfer = controller->xfer;
  25. @@ -567,16 +568,19 @@ static irqreturn_t spi_qup_qup_irq(int i
  26. spi_qup_write(controller, xfer);
  27. }
  28. - spin_lock_irqsave(&controller->lock, flags);
  29. - controller->error = error;
  30. - controller->xfer = xfer;
  31. - spin_unlock_irqrestore(&controller->lock, flags);
  32. -
  33. /* re-read opflags as flags may have changed due to actions above */
  34. opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
  35. if ((controller->rx_bytes == xfer->len &&
  36. (opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
  37. + done = true;
  38. +
  39. + spin_lock_irqsave(&controller->lock, flags);
  40. + controller->error = error;
  41. + controller->xfer = done ? NULL : xfer;
  42. + spin_unlock_irqrestore(&controller->lock, flags);
  43. +
  44. + if (done)
  45. complete(&controller->done);
  46. return IRQ_HANDLED;
  47. @@ -769,7 +773,6 @@ static int spi_qup_transfer_one(struct s
  48. exit:
  49. spi_qup_set_state(controller, QUP_STATE_RESET);
  50. spin_lock_irqsave(&controller->lock, flags);
  51. - controller->xfer = NULL;
  52. if (!ret)
  53. ret = controller->error;
  54. spin_unlock_irqrestore(&controller->lock, flags);