mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 06:43:09 +00:00
A set of regular driver fixes
-----BEGIN PGP SIGNATURE----- iQJDBAABCgAtFiEEOZGx6rniZ1Gk92RdFA3kzBSgKbYFAmQdS5kPHHdzYUBrZXJu ZWwub3JnAAoJEBQN5MwUoCm2C2kQAIt20Q7IibQQoDmWWUpvmMprRtU5QzIGlw2o SXqMw8gWH/lS3omu+2d59N3sKXjDloVcISMGyr2q2hE3wE0/anzoP0YRXfuRK7/T Cl9fm+rEa5FbF+F0/a5/2U23GD8fw8AaHVBe9rR23Lt6IsGgG+IqQQ2nXx9t5Rit KW8fGgFJB5y4x6Kjh3O0xGWiwXxRhBieaMqsKMQ2Aw7BMa8NoGnIMIltJP85D7fj 98CrMVSAi/8rPvFzrkcq8/SZpp766lPcmtcfQANVLFNK6yo7PqCMBjkKm/FHKyJP cb6SknDXyBjir9NiTPVMs8dvOs0DLvQb5RNdUVbNejcaG+9mdJmxU8sBpXUXnEer jYEeOtyDrZfeOGgWBc0ASokfk6QCd+rGtzV7c9Dvcu/zkoZFI2XabmEjweNpSlrG HKd+YzeyU3OFaxfqT3/vOfjENYDUGk5L8em/RxGQtbRFD15Jn0j5q8bowZCM0veM 3TPH/gsboAFRpn3ONYL+6ezZ8RvLNEtpuQlYvvLHfRpBaQFyba2V5/rW56UNFil+ ZE47zcyj5MMEdzlsltiM/eF56FuUzH4b/mlFGjdx5aSMWJWkiHJVY8R/9hBpGApM T2LTEw+I50oH+/tDGDo3fNiN62mne7/KLoDRbYjjRCXP4ONRVZe5W4GoOkZmqBlD qLqCshkn =NK3m -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
ed1407e7f7
@ -316,6 +316,13 @@ static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr)
|
||||
max_write == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the TX_EMPTY interrupt after finishing all the messages to
|
||||
* avoid overwhelming the CPU.
|
||||
*/
|
||||
if (ctlr->msg_tx_idx == ctlr->msg_num)
|
||||
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_TX_EMPTY);
|
||||
}
|
||||
|
||||
static irqreturn_t hisi_i2c_irq(int irq, void *context)
|
||||
@ -341,7 +348,11 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
|
||||
hisi_i2c_read_rx_fifo(ctlr);
|
||||
|
||||
out:
|
||||
if (int_stat & HISI_I2C_INT_TRANS_CPLT || ctlr->xfer_err) {
|
||||
/*
|
||||
* Only use TRANS_CPLT to indicate the completion. On error cases we'll
|
||||
* get two interrupts, INT_ERR first then TRANS_CPLT.
|
||||
*/
|
||||
if (int_stat & HISI_I2C_INT_TRANS_CPLT) {
|
||||
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL);
|
||||
hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
|
||||
complete(ctlr->completion);
|
||||
|
@ -463,6 +463,8 @@ static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
|
||||
if (num == 1 && msgs[0].len == 0)
|
||||
goto stop;
|
||||
|
||||
lpi2c_imx->rx_buf = NULL;
|
||||
lpi2c_imx->tx_buf = NULL;
|
||||
lpi2c_imx->delivered = 0;
|
||||
lpi2c_imx->msglen = msgs[i].len;
|
||||
init_completion(&lpi2c_imx->complete);
|
||||
@ -503,10 +505,14 @@ disable:
|
||||
static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct lpi2c_imx_struct *lpi2c_imx = dev_id;
|
||||
unsigned int enabled;
|
||||
unsigned int temp;
|
||||
|
||||
enabled = readl(lpi2c_imx->base + LPI2C_MIER);
|
||||
|
||||
lpi2c_imx_intctrl(lpi2c_imx, 0);
|
||||
temp = readl(lpi2c_imx->base + LPI2C_MSR);
|
||||
temp &= enabled;
|
||||
|
||||
if (temp & MSR_RDF)
|
||||
lpi2c_imx_read_rxfifo(lpi2c_imx);
|
||||
|
@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
|
||||
}
|
||||
|
||||
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msg, uint32_t flags)
|
||||
struct i2c_msg *msg, u8 *buf, uint32_t flags)
|
||||
{
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
|
||||
@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
|
||||
}
|
||||
|
||||
/* Queue the DMA data transfer. */
|
||||
sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
|
||||
sg_init_one(&i2c->sg_io[1], buf, msg->len);
|
||||
dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
|
||||
desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
|
||||
DMA_DEV_TO_MEM,
|
||||
@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
|
||||
/* Queue the DMA data transfer. */
|
||||
sg_init_table(i2c->sg_io, 2);
|
||||
sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
|
||||
sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
|
||||
sg_set_buf(&i2c->sg_io[1], buf, msg->len);
|
||||
dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
|
||||
desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
|
||||
DMA_MEM_TO_DEV,
|
||||
@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
|
||||
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
|
||||
int ret;
|
||||
int flags;
|
||||
u8 *dma_buf;
|
||||
int use_pio = 0;
|
||||
unsigned long time_left;
|
||||
|
||||
@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
|
||||
if (ret && (ret != -ENXIO))
|
||||
mxs_i2c_reset(i2c);
|
||||
} else {
|
||||
dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
|
||||
if (!dma_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
reinit_completion(&i2c->cmd_complete);
|
||||
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
|
||||
if (ret)
|
||||
ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
|
||||
if (ret) {
|
||||
i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_left = wait_for_completion_timeout(&i2c->cmd_complete,
|
||||
msecs_to_jiffies(1000));
|
||||
i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
|
||||
if (!time_left)
|
||||
goto timeout;
|
||||
|
||||
|
@ -308,6 +308,9 @@ static int slimpro_i2c_blkwr(struct slimpro_i2c_dev *ctx, u32 chip,
|
||||
u32 msg[3];
|
||||
int rc;
|
||||
|
||||
if (writelen > I2C_SMBUS_BLOCK_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(ctx->dma_buffer, data, writelen);
|
||||
paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen,
|
||||
DMA_TO_DEVICE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user