Skip to content

Commit

Permalink
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/wsa/linux into master

Pull i2c fixes from Wolfram Sang:
 "Again some driver bugfixes and some documentation fixes"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: i2c-qcom-geni: Fix DMA transfer race
  i2c: rcar: always clear ICSAR to avoid side effects
  MAINTAINERS: i2c: at91: handover maintenance to Codrin Ciubotariu
  i2c: drop duplicated word in the header file
  i2c: cadence: Clear HOLD bit at correct time in Rx path
  Revert "i2c: cadence: Fix the hold bit setting"
  • Loading branch information
torvalds committed Jul 24, 2020
2 parents b85bcb7 + 02b9aec commit c615035
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 20 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -11241,7 +11241,7 @@ S: Maintained
F: drivers/crypto/atmel-ecc.*

MICROCHIP I2C DRIVER
M: Ludovic Desroches <ludovic.desroches@microchip.com>
M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
L: [email protected]
S: Supported
F: drivers/i2c/busses/i2c-at91-*.c
Expand Down
28 changes: 12 additions & 16 deletions drivers/i2c/busses/i2c-cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,20 +421,21 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
/* Read data if receive data valid is set */
while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) &
CDNS_I2C_SR_RXDV) {
/*
* Clear hold bit that was set for FIFO control if
* RX data left is less than FIFO depth, unless
* repeated start is selected.
*/
if ((id->recv_count < CDNS_I2C_FIFO_DEPTH) &&
!id->bus_hold_flag)
cdns_i2c_clear_bus_hold(id);

if (id->recv_count > 0) {
*(id->p_recv_buf)++ =
cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
id->recv_count--;
id->curr_recv_count--;

/*
* Clear hold bit that was set for FIFO control
* if RX data left is less than or equal to
* FIFO DEPTH unless repeated start is selected
*/
if (id->recv_count <= CDNS_I2C_FIFO_DEPTH &&
!id->bus_hold_flag)
cdns_i2c_clear_bus_hold(id);

} else {
dev_err(id->adap.dev.parent,
"xfer_size reg rollover. xfer aborted!\n");
Expand Down Expand Up @@ -594,10 +595,8 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth.
*/
if ((id->recv_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag)
if (id->recv_count > CDNS_I2C_FIFO_DEPTH)
ctrl_reg |= CDNS_I2C_CR_HOLD;
else
ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD;

cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);

Expand Down Expand Up @@ -654,11 +653,8 @@ static void cdns_i2c_msend(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth.
*/
if ((id->send_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag)
if (id->send_count > CDNS_I2C_FIFO_DEPTH)
ctrl_reg |= CDNS_I2C_CR_HOLD;
else
ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD;

cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);

/* Clear the interrupts in interrupt status register. */
Expand Down
6 changes: 4 additions & 2 deletions drivers/i2c/busses/i2c-qcom-geni.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,15 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
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;
}

geni_se_setup_m_cmd(se, I2C_READ, m_param);

time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
if (!time_left)
geni_i2c_abort_xfer(gi2c);
Expand Down Expand Up @@ -408,14 +409,15 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
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;
}

geni_se_setup_m_cmd(se, I2C_WRITE, m_param);

if (!dma_buf) /* Get FIFO IRQ */
writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);

Expand Down
3 changes: 3 additions & 0 deletions drivers/i2c/busses/i2c-rcar.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
/* disable irqs and ensure none is running before clearing ptr */
rcar_i2c_write(priv, ICSIER, 0);
rcar_i2c_write(priv, ICSCR, 0);
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */

synchronize_irq(priv->irq);
priv->slave = NULL;
Expand Down Expand Up @@ -969,6 +970,8 @@ static int rcar_i2c_probe(struct platform_device *pdev)
if (ret < 0)
goto out_pm_put;

rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */

if (priv->devtype == I2C_RCAR_GEN3) {
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (!IS_ERR(priv->rstc)) {
Expand Down
2 changes: 1 addition & 1 deletion include/linux/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct property_entry;
* on a bus (or read from them). Apart from two basic transfer functions to
* transmit one message at a time, a more complex version can be used to
* transmit an arbitrary number of messages without interruption.
* @count must be be less than 64k since msg.len is u16.
* @count must be less than 64k since msg.len is u16.
*/
int i2c_transfer_buffer_flags(const struct i2c_client *client,
char *buf, int count, u16 flags);
Expand Down

0 comments on commit c615035

Please sign in to comment.