Commit cd8843f5 authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Wolfram Sang

i2c: uniphier-f: fill TX-FIFO only in IRQ handler for repeated START

- For a repeated START condition, this controller starts data transfer
   immediately after the slave address is written to the TX-FIFO.

 - Once the TX-FIFO empty interrupt is asserted, the controller makes
   a pause even if additional data are written to the TX-FIFO.

Given those circumstances, the data after a repeated START may not be
transferred if the interrupt is asserted while the TX-FIFO is being
filled up. A more reliable way is to append TX data only in the
interrupt handler.
Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent c2a653de
...@@ -269,7 +269,8 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) ...@@ -269,7 +269,8 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr) static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr,
bool repeat)
{ {
priv->enabled_irqs |= UNIPHIER_FI2C_INT_TE; priv->enabled_irqs |= UNIPHIER_FI2C_INT_TE;
uniphier_fi2c_set_irqs(priv); uniphier_fi2c_set_irqs(priv);
...@@ -279,7 +280,11 @@ static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr) ...@@ -279,7 +280,11 @@ static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr)
/* set slave address */ /* set slave address */
writel(UNIPHIER_FI2C_DTTX_CMD | addr << 1, writel(UNIPHIER_FI2C_DTTX_CMD | addr << 1,
priv->membase + UNIPHIER_FI2C_DTTX); priv->membase + UNIPHIER_FI2C_DTTX);
/* first chunk of data */ /*
* First chunk of data. For a repeated START condition, do not write
* data to the TX fifo here to avoid the timing issue.
*/
if (!repeat)
uniphier_fi2c_fill_txfifo(priv, true); uniphier_fi2c_fill_txfifo(priv, true);
} }
...@@ -361,7 +366,7 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap, ...@@ -361,7 +366,7 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
if (is_read) if (is_read)
uniphier_fi2c_rx_init(priv, msg->addr); uniphier_fi2c_rx_init(priv, msg->addr);
else else
uniphier_fi2c_tx_init(priv, msg->addr); uniphier_fi2c_tx_init(priv, msg->addr, repeat);
dev_dbg(&adap->dev, "start condition\n"); dev_dbg(&adap->dev, "start condition\n");
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment