808-i2c-0012-i2c-imx-correct-code-of-errata-A-010650-for-layersca.patch 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. From 27ea8554c8fdcdf1d7aba5ce47630d878ce96691 Mon Sep 17 00:00:00 2001
  2. From: Biwen Li <[email protected]>
  3. Date: Thu, 24 Oct 2019 13:14:44 +0800
  4. Subject: [PATCH] i2c: imx: correct code of errata A-010650 for layerscape
  5. platform
  6. - Simplify code with helper function i2c_imx_clr_al_bit
  7. - Fix an error about clearing arbitration lost bit
  8. - Fix an error that not set I2Cx_IBCR following by
  9. the workaround of A-010650 (in step 5)
  10. Reviewed-by: Clark Wang <[email protected]>
  11. Signed-off-by: Biwen Li <[email protected]>
  12. ---
  13. drivers/i2c/busses/i2c-imx.c | 38 +++++++++++++++++++-------------------
  14. 1 file changed, 19 insertions(+), 19 deletions(-)
  15. --- a/drivers/i2c/busses/i2c-imx.c
  16. +++ b/drivers/i2c/busses/i2c-imx.c
  17. @@ -516,6 +516,14 @@ static void i2c_imx_clear_irq(struct imx
  18. imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
  19. }
  20. +/* Clear arbitration lost bit */
  21. +static void i2c_imx_clr_al_bit(unsigned int status, struct imx_i2c_struct *i2c_imx)
  22. +{
  23. + status &= ~I2SR_IAL;
  24. + status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IAL);
  25. + imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
  26. +}
  27. +
  28. static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
  29. {
  30. unsigned long orig_jiffies = jiffies;
  31. @@ -528,7 +536,7 @@ static int i2c_imx_bus_busy(struct imx_i
  32. /* check for arbitration lost */
  33. if (temp & I2SR_IAL) {
  34. - i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
  35. + i2c_imx_clr_al_bit(temp, i2c_imx);
  36. return -EAGAIN;
  37. }
  38. @@ -724,14 +732,6 @@ static void i2c_imx_clr_if_bit(unsigned
  39. imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
  40. }
  41. -/* Clear arbitration lost bit */
  42. -static void i2c_imx_clr_al_bit(unsigned int status, struct imx_i2c_struct *i2c_imx)
  43. -{
  44. - status &= ~I2SR_IAL;
  45. - status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IAL);
  46. - imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
  47. -}
  48. -
  49. static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx)
  50. {
  51. unsigned int status;
  52. @@ -1080,12 +1080,14 @@ static int i2c_imx_recovery_for_layersca
  53. gpio_set_value(i2c_imx->gpio, 1);
  54. /*
  55. - * Set I2Cx_IBCR = 0h00 to generate a STOP and then
  56. - * set I2Cx_IBCR = 0h80 to reset
  57. + * Set I2Cx_IBCR = 0h00 to generate a STOP
  58. */
  59. - temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
  60. - temp &= ~(I2CR_MSTA | I2CR_MTX);
  61. - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
  62. + imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode, i2c_imx, IMX_I2C_I2CR);
  63. +
  64. + /*
  65. + * Set I2Cx_IBCR = 0h80 to reset the I2Cx controller
  66. + */
  67. + imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode | I2CR_IEN, i2c_imx, IMX_I2C_I2CR);
  68. /* Restore the saved value of the register SCFG_RCWPMUXCR0 */
  69. if (i2c_imx->need_set_pmuxcr == 1) {
  70. @@ -1099,10 +1101,9 @@ static int i2c_imx_recovery_for_layersca
  71. * I2C_IBSR[IBAL] = 1
  72. */
  73. temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
  74. - if (temp & I2SR_IAL) {
  75. - temp &= ~I2SR_IAL;
  76. - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
  77. - }
  78. + if (temp & I2SR_IAL)
  79. + i2c_imx_clr_al_bit(temp, i2c_imx);
  80. +
  81. return 0;
  82. }