Skip to content

Commit ed1407e

Browse files
committed
Merge tag 'i2c-for-6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "A set of regular driver fixes" * tag 'i2c-for-6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer() i2c: hisi: Only use the completion interrupt to finish the transfer i2c: hisi: Avoid redundant interrupts i2c: mxs: ensure that DMA buffers are safe for DMA i2c: imx-lpi2c: check only for enabled interrupt flags i2c: imx-lpi2c: clean rx/tx buffers upon new message
2 parents 608f1b1 + 92fbb6d commit ed1407e

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

drivers/i2c/busses/i2c-hisi.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,13 @@ static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr)
316316
max_write == 0)
317317
break;
318318
}
319+
320+
/*
321+
* Disable the TX_EMPTY interrupt after finishing all the messages to
322+
* avoid overwhelming the CPU.
323+
*/
324+
if (ctlr->msg_tx_idx == ctlr->msg_num)
325+
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_TX_EMPTY);
319326
}
320327

321328
static irqreturn_t hisi_i2c_irq(int irq, void *context)
@@ -341,7 +348,11 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
341348
hisi_i2c_read_rx_fifo(ctlr);
342349

343350
out:
344-
if (int_stat & HISI_I2C_INT_TRANS_CPLT || ctlr->xfer_err) {
351+
/*
352+
* Only use TRANS_CPLT to indicate the completion. On error cases we'll
353+
* get two interrupts, INT_ERR first then TRANS_CPLT.
354+
*/
355+
if (int_stat & HISI_I2C_INT_TRANS_CPLT) {
345356
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL);
346357
hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
347358
complete(ctlr->completion);

drivers/i2c/busses/i2c-imx-lpi2c.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,8 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
463463
if (num == 1 && msgs[0].len == 0)
464464
goto stop;
465465

466+
lpi2c_imx->rx_buf = NULL;
467+
lpi2c_imx->tx_buf = NULL;
466468
lpi2c_imx->delivered = 0;
467469
lpi2c_imx->msglen = msgs[i].len;
468470
init_completion(&lpi2c_imx->complete);
@@ -503,10 +505,14 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
503505
static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
504506
{
505507
struct lpi2c_imx_struct *lpi2c_imx = dev_id;
508+
unsigned int enabled;
506509
unsigned int temp;
507510

511+
enabled = readl(lpi2c_imx->base + LPI2C_MIER);
512+
508513
lpi2c_imx_intctrl(lpi2c_imx, 0);
509514
temp = readl(lpi2c_imx->base + LPI2C_MSR);
515+
temp &= enabled;
510516

511517
if (temp & MSR_RDF)
512518
lpi2c_imx_read_rxfifo(lpi2c_imx);

drivers/i2c/busses/i2c-mxs.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
171171
}
172172

173173
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
174-
struct i2c_msg *msg, uint32_t flags)
174+
struct i2c_msg *msg, u8 *buf, uint32_t flags)
175175
{
176176
struct dma_async_tx_descriptor *desc;
177177
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
@@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
226226
}
227227

228228
/* Queue the DMA data transfer. */
229-
sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
229+
sg_init_one(&i2c->sg_io[1], buf, msg->len);
230230
dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
231231
desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
232232
DMA_DEV_TO_MEM,
@@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
259259
/* Queue the DMA data transfer. */
260260
sg_init_table(i2c->sg_io, 2);
261261
sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
262-
sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
262+
sg_set_buf(&i2c->sg_io[1], buf, msg->len);
263263
dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
264264
desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
265265
DMA_MEM_TO_DEV,
@@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
563563
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
564564
int ret;
565565
int flags;
566+
u8 *dma_buf;
566567
int use_pio = 0;
567568
unsigned long time_left;
568569

@@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
588589
if (ret && (ret != -ENXIO))
589590
mxs_i2c_reset(i2c);
590591
} else {
592+
dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
593+
if (!dma_buf)
594+
return -ENOMEM;
595+
591596
reinit_completion(&i2c->cmd_complete);
592-
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
593-
if (ret)
597+
ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
598+
if (ret) {
599+
i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
594600
return ret;
601+
}
595602

596603
time_left = wait_for_completion_timeout(&i2c->cmd_complete,
597604
msecs_to_jiffies(1000));
605+
i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
598606
if (!time_left)
599607
goto timeout;
600608

drivers/i2c/busses/i2c-xgene-slimpro.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ static int slimpro_i2c_blkwr(struct slimpro_i2c_dev *ctx, u32 chip,
308308
u32 msg[3];
309309
int rc;
310310

311+
if (writelen > I2C_SMBUS_BLOCK_MAX)
312+
return -EINVAL;
313+
311314
memcpy(ctx->dma_buffer, data, writelen);
312315
paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen,
313316
DMA_TO_DEVICE);

0 commit comments

Comments
 (0)