static int qup_update_state(struct qup_i2c_dev *dev, unsigned state) { if (qup_i2c_poll_state(dev, 0) != 0) return -EIO; writel(state, dev->base + QUP_STATE); if (qup_i2c_poll_state(dev, state) != 0) return -EIO; return 0; }
static int qup_update_state(struct qup_i2c_dev *dev, uint32_t state) { if (qup_i2c_poll_state(dev, 0) != 0) return -EIO; writel_relaxed(state, dev->base + QUP_STATE); if (qup_i2c_poll_state(dev, state) != 0) return -EIO; return 0; }
static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state) { if (qup_i2c_poll_state_valid(qup) != 0) return -EIO; writel(state, qup->base + QUP_STATE); if (qup_i2c_poll_state(qup, state) != 0) return -EIO; return 0; }
static int qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct qup_i2c_dev *qup = i2c_get_adapdata(adap); int ret, idx; ret = pm_runtime_get_sync(qup->dev); if (ret < 0) goto out; writel(1, qup->base + QUP_SW_RESET); ret = qup_i2c_poll_state(qup, QUP_RESET_STATE); if (ret) goto out; /* Configure QUP as I2C mini core */ writel(I2C_MINI_CORE | I2C_N_VAL, qup->base + QUP_CONFIG); for (idx = 0; idx < num; idx++) { if (msgs[idx].len == 0) { ret = -EINVAL; goto out; } if (qup_i2c_poll_state_i2c_master(qup)) { ret = -EIO; goto out; } if (msgs[idx].flags & I2C_M_RD) ret = qup_i2c_read_one(qup, &msgs[idx]); else ret = qup_i2c_write_one(qup, &msgs[idx]); if (ret) break; ret = qup_i2c_change_state(qup, QUP_RESET_STATE); if (ret) break; } if (ret == 0) ret = num; out: pm_runtime_mark_last_busy(qup->dev); pm_runtime_put_autosuspend(qup->dev); return ret; }