Loading drivers/i2c/busses/i2c-qup.c +21 −4 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ enum msm_i2c_state { #define I2C_STATUS_CLK_STATE 13 #define QUP_OUT_FIFO_NOT_EMPTY 0x10 #define I2C_GPIOS_DT_CNT (2) /* sda and scl */ #define I2C_QUP_MAX_BUS_RECOVERY_RETRY 10 /* Register:QUP_I2C_MASTER_CLK_CTL field setters */ #define QUP_I2C_SCL_NOISE_REJECTION(reg_val, noise_rej_val) \ Loading Loading @@ -937,14 +938,13 @@ static int qup_i2c_reset(struct qup_i2c_dev *dev) return ret; } static int qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) static int qup_i2c_try_recover_bus_busy(struct qup_i2c_dev *dev) { int ret; u32 status; ulong min_sleep_usec; disable_irq(dev->err_irq); dev_info(dev->dev, "Executing bus recovery procedure (9 clk pulse)\n"); qup_i2c_reset(dev); Loading Loading @@ -972,14 +972,31 @@ static int qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) usleep_range(min_sleep_usec, min_sleep_usec * 10); status = readl_relaxed(dev->base + QUP_I2C_STATUS); dev_info(dev->dev, "Bus recovery %s\n", (status & I2C_STATUS_BUS_ACTIVE) ? "fail" : "success"); recovery_end: enable_irq(dev->err_irq); return ret; } static void qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) { u32 bus_clr, bus_active, status; int retry = 0; dev_info(dev->dev, "Executing bus recovery procedure (9 clk pulse)\n"); do { qup_i2c_try_recover_bus_busy(dev); bus_clr = readl_relaxed(dev->base + QUP_I2C_MASTER_BUS_CLR); status = readl_relaxed(dev->base + QUP_I2C_STATUS); bus_active = status & I2C_STATUS_BUS_ACTIVE; if (++retry >= I2C_QUP_MAX_BUS_RECOVERY_RETRY) break; } while (bus_clr || bus_active); dev_info(dev->dev, "Bus recovery %s after %d retries\n", (bus_clr || bus_active) ? "fail" : "success", retry); } static int qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { Loading Loading
drivers/i2c/busses/i2c-qup.c +21 −4 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ enum msm_i2c_state { #define I2C_STATUS_CLK_STATE 13 #define QUP_OUT_FIFO_NOT_EMPTY 0x10 #define I2C_GPIOS_DT_CNT (2) /* sda and scl */ #define I2C_QUP_MAX_BUS_RECOVERY_RETRY 10 /* Register:QUP_I2C_MASTER_CLK_CTL field setters */ #define QUP_I2C_SCL_NOISE_REJECTION(reg_val, noise_rej_val) \ Loading Loading @@ -937,14 +938,13 @@ static int qup_i2c_reset(struct qup_i2c_dev *dev) return ret; } static int qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) static int qup_i2c_try_recover_bus_busy(struct qup_i2c_dev *dev) { int ret; u32 status; ulong min_sleep_usec; disable_irq(dev->err_irq); dev_info(dev->dev, "Executing bus recovery procedure (9 clk pulse)\n"); qup_i2c_reset(dev); Loading Loading @@ -972,14 +972,31 @@ static int qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) usleep_range(min_sleep_usec, min_sleep_usec * 10); status = readl_relaxed(dev->base + QUP_I2C_STATUS); dev_info(dev->dev, "Bus recovery %s\n", (status & I2C_STATUS_BUS_ACTIVE) ? "fail" : "success"); recovery_end: enable_irq(dev->err_irq); return ret; } static void qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev) { u32 bus_clr, bus_active, status; int retry = 0; dev_info(dev->dev, "Executing bus recovery procedure (9 clk pulse)\n"); do { qup_i2c_try_recover_bus_busy(dev); bus_clr = readl_relaxed(dev->base + QUP_I2C_MASTER_BUS_CLR); status = readl_relaxed(dev->base + QUP_I2C_STATUS); bus_active = status & I2C_STATUS_BUS_ACTIVE; if (++retry >= I2C_QUP_MAX_BUS_RECOVERY_RETRY) break; } while (bus_clr || bus_active); dev_info(dev->dev, "Bus recovery %s after %d retries\n", (bus_clr || bus_active) ? "fail" : "success", retry); } static int qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { Loading