|
@@ -365,29 +365,24 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
|
|
u32 m_param)
|
|
|
{
|
|
|
dma_addr_t rx_dma;
|
|
|
- enum geni_se_xfer_mode mode;
|
|
|
- unsigned long time_left = XFER_TIMEOUT;
|
|
|
+ unsigned long time_left;
|
|
|
void *dma_buf;
|
|
|
+ struct geni_se *se = &gi2c->se;
|
|
|
+ size_t len = msg->len;
|
|
|
|
|
|
- gi2c->cur = msg;
|
|
|
- mode = GENI_SE_FIFO;
|
|
|
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
|
|
|
if (dma_buf)
|
|
|
- mode = GENI_SE_DMA;
|
|
|
-
|
|
|
- geni_se_select_mode(&gi2c->se, mode);
|
|
|
- writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
|
|
|
- geni_se_setup_m_cmd(&gi2c->se, I2C_READ, m_param);
|
|
|
- if (mode == GENI_SE_DMA) {
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = geni_se_rx_dma_prep(&gi2c->se, dma_buf, msg->len,
|
|
|
- &rx_dma);
|
|
|
- if (ret) {
|
|
|
- mode = GENI_SE_FIFO;
|
|
|
- geni_se_select_mode(&gi2c->se, mode);
|
|
|
- i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
|
|
|
- }
|
|
|
+ geni_se_select_mode(se, GENI_SE_DMA);
|
|
|
+ else
|
|
|
+ geni_se_select_mode(se, GENI_SE_FIFO);
|
|
|
+
|
|
|
+ writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
|
|
|
+ geni_se_setup_m_cmd(se, I2C_READ, m_param);
|
|
|
+
|
|
|
+ if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
|
|
|
+ geni_se_select_mode(se, GENI_SE_FIFO);
|
|
|
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
|
|
|
+ dma_buf = NULL;
|
|
|
}
|
|
|
|
|
|
time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
|
|
@@ -395,12 +390,13 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
|
|
geni_i2c_abort_xfer(gi2c);
|
|
|
|
|
|
gi2c->cur_rd = 0;
|
|
|
- if (mode == GENI_SE_DMA) {
|
|
|
+ if (dma_buf) {
|
|
|
if (gi2c->err)
|
|
|
geni_i2c_rx_fsm_rst(gi2c);
|
|
|
- geni_se_rx_dma_unprep(&gi2c->se, rx_dma, msg->len);
|
|
|
+ geni_se_rx_dma_unprep(se, rx_dma, len);
|
|
|
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
|
|
|
}
|
|
|
+
|
|
|
return gi2c->err;
|
|
|
}
|
|
|
|
|
@@ -408,45 +404,41 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
|
|
|
u32 m_param)
|
|
|
{
|
|
|
dma_addr_t tx_dma;
|
|
|
- enum geni_se_xfer_mode mode;
|
|
|
unsigned long time_left;
|
|
|
void *dma_buf;
|
|
|
+ struct geni_se *se = &gi2c->se;
|
|
|
+ size_t len = msg->len;
|
|
|
|
|
|
- gi2c->cur = msg;
|
|
|
- mode = GENI_SE_FIFO;
|
|
|
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
|
|
|
if (dma_buf)
|
|
|
- mode = GENI_SE_DMA;
|
|
|
-
|
|
|
- geni_se_select_mode(&gi2c->se, mode);
|
|
|
- writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
|
|
|
- geni_se_setup_m_cmd(&gi2c->se, I2C_WRITE, m_param);
|
|
|
- if (mode == GENI_SE_DMA) {
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = geni_se_tx_dma_prep(&gi2c->se, dma_buf, msg->len,
|
|
|
- &tx_dma);
|
|
|
- if (ret) {
|
|
|
- mode = GENI_SE_FIFO;
|
|
|
- geni_se_select_mode(&gi2c->se, mode);
|
|
|
- i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
|
|
|
- }
|
|
|
+ geni_se_select_mode(se, GENI_SE_DMA);
|
|
|
+ else
|
|
|
+ geni_se_select_mode(se, GENI_SE_FIFO);
|
|
|
+
|
|
|
+ writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
|
|
|
+ geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
|
|
|
+
|
|
|
+ if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
|
|
|
+ geni_se_select_mode(se, GENI_SE_FIFO);
|
|
|
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
|
|
|
+ dma_buf = NULL;
|
|
|
}
|
|
|
|
|
|
- if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
|
|
|
- writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
|
|
|
+ if (!dma_buf) /* Get FIFO IRQ */
|
|
|
+ writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);
|
|
|
|
|
|
time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
|
|
|
if (!time_left)
|
|
|
geni_i2c_abort_xfer(gi2c);
|
|
|
|
|
|
gi2c->cur_wr = 0;
|
|
|
- if (mode == GENI_SE_DMA) {
|
|
|
+ if (dma_buf) {
|
|
|
if (gi2c->err)
|
|
|
geni_i2c_tx_fsm_rst(gi2c);
|
|
|
- geni_se_tx_dma_unprep(&gi2c->se, tx_dma, msg->len);
|
|
|
+ geni_se_tx_dma_unprep(se, tx_dma, len);
|
|
|
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
|
|
|
}
|
|
|
+
|
|
|
return gi2c->err;
|
|
|
}
|
|
|
|
|
@@ -474,6 +466,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
|
|
|
|
|
|
m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
|
|
|
|
|
|
+ gi2c->cur = &msgs[i];
|
|
|
if (msgs[i].flags & I2C_M_RD)
|
|
|
ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
|
|
|
else
|