mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
i2c-fixes for v7.2-rc4
imx: fix empty SMBus block reads in atomic and IRQ paths spacemit: return IRQ_NONE for empty interrupt status mlxbf: fix a use-after-free issue mediatek: restore WRRD support without automatic restart CREDITS: add Wolfram Sang -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQScDfrjQa34uOld1VLaeAVmJtMtbgUCaltX3AAKCRDaeAVmJtMt bqqgAPsFCe+3Y/71UNBWzOEI99zUlyFu7OH7Rt/015HVXsmelgEAjkQ0X5RX2Njg AswoeT+OGvxxVxlNeNMMrxAM4s6caQU= =yKh8 -----END PGP SIGNATURE----- Merge tag 'i2c-fixes-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux Pull i2c fixes from Andi Shyti: "A handful of small fixes for host controller drivers. One patch also adds Wolfram Sang to CREDITS after more than a decade of work on I2C" * tag 'i2c-fixes-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux: i2c: mediatek: fix WRRD for SoCs without auto_restart option i2c: mlxbf: Fix use-after-free in mlxbf_i2c_init_resource() i2c: spacemit: fix spurious IRQ handling returning IRQ_HANDLED i2c: imx: fix locked bus on SMBus block-read of 0 (IRQ) i2c: imx: fix locked bus on SMBus block-read of 0 (atomic) CREDITS: Add Wolfram Sang
This commit is contained in:
commit
ba6bd0df9a
7
CREDITS
7
CREDITS
|
|
@ -3626,6 +3626,13 @@ S: 69 rue Dunois
|
|||
S: 75013 Paris
|
||||
S: France
|
||||
|
||||
N: Wolfram Sang
|
||||
E: wsa@kernel.org
|
||||
W: sang-engineering.com
|
||||
P: rsa4096/140DE4CC14A029B6 3991 B1EA B9E2 6751 A4F7 645D 140D E4CC 14A0 29B6
|
||||
D: I2C Maintainer 2012 - 2026
|
||||
S: Berlin, Germany
|
||||
|
||||
N: Aleksa Sarai
|
||||
E: cyphar@cyphar.com
|
||||
W: https://www.cyphar.com/
|
||||
|
|
|
|||
|
|
@ -1061,11 +1061,28 @@ static inline enum imx_i2c_state i2c_imx_isr_read_continue(struct imx_i2c_struct
|
|||
static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_imx)
|
||||
{
|
||||
u8 len = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
|
||||
unsigned int temp;
|
||||
|
||||
if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) {
|
||||
/*
|
||||
* SMBus 3.1 6.5.7: support count byte of 0.
|
||||
* I2C_SMBUS_BLOCK_MAX case should not hold the SDA either.
|
||||
* So NACK it (TXAK) to not hold the bus.
|
||||
*/
|
||||
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
|
||||
temp |= I2CR_TXAK;
|
||||
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
|
||||
|
||||
if (len == 0) {
|
||||
i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = 0;
|
||||
i2c_imx->msg->len = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
i2c_imx->isr_result = -EPROTO;
|
||||
i2c_imx->state = IMX_I2C_STATE_FAILED;
|
||||
wake_up(&i2c_imx->queue);
|
||||
return;
|
||||
}
|
||||
i2c_imx->msg->len += len;
|
||||
i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = len;
|
||||
|
|
@ -1415,6 +1432,7 @@ static int i2c_imx_atomic_read(struct imx_i2c_struct *i2c_imx,
|
|||
int i, result;
|
||||
unsigned int temp;
|
||||
int block_data = msgs->flags & I2C_M_RECV_LEN;
|
||||
int block_err = 0;
|
||||
|
||||
result = i2c_imx_prepare_read(i2c_imx, msgs, false);
|
||||
if (result)
|
||||
|
|
@ -1436,8 +1454,20 @@ static int i2c_imx_atomic_read(struct imx_i2c_struct *i2c_imx,
|
|||
*/
|
||||
if ((!i) && block_data) {
|
||||
len = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
|
||||
if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX))
|
||||
return -EPROTO;
|
||||
if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
|
||||
/*
|
||||
* SMBus 3.1 6.5.7: support count byte of 0.
|
||||
* I2C_SMBUS_BLOCK_MAX case should not hold the SDA either.
|
||||
*/
|
||||
if (len > I2C_SMBUS_BLOCK_MAX)
|
||||
block_err = -EPROTO;
|
||||
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
|
||||
temp |= I2CR_TXAK;
|
||||
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
|
||||
msgs->buf[0] = 0;
|
||||
msgs->len = 2;
|
||||
continue;
|
||||
}
|
||||
dev_dbg(&i2c_imx->adapter.dev,
|
||||
"<%s> read length: 0x%X\n",
|
||||
__func__, len);
|
||||
|
|
@ -1485,7 +1515,7 @@ static int i2c_imx_atomic_read(struct imx_i2c_struct *i2c_imx,
|
|||
"<%s> read byte: B%d=0x%X\n",
|
||||
__func__, i, msgs->buf[i]);
|
||||
}
|
||||
return 0;
|
||||
return block_err;
|
||||
}
|
||||
|
||||
static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
|
|||
|
||||
status = readl(i2c->base + SPACEMIT_ISR);
|
||||
if (!status)
|
||||
return IRQ_HANDLED;
|
||||
return IRQ_NONE;
|
||||
|
||||
i2c->status = status;
|
||||
|
||||
|
|
|
|||
|
|
@ -1051,8 +1051,10 @@ static int mlxbf_i2c_init_resource(struct platform_device *pdev,
|
|||
|
||||
tmp_res->io = devm_platform_get_and_ioremap_resource(pdev, type, &tmp_res->params);
|
||||
if (IS_ERR(tmp_res->io)) {
|
||||
int ret = PTR_ERR(tmp_res->io);
|
||||
|
||||
devm_kfree(dev, tmp_res);
|
||||
return PTR_ERR(tmp_res->io);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tmp_res->type = type;
|
||||
|
|
|
|||
|
|
@ -1258,7 +1258,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
|||
i2c->auto_restart = i2c->dev_comp->auto_restart;
|
||||
|
||||
/* checking if we can skip restart and optimize using WRRD mode */
|
||||
if (i2c->auto_restart && num == 2) {
|
||||
if (num == 2) {
|
||||
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
|
||||
msgs[0].addr == msgs[1].addr) {
|
||||
i2c->auto_restart = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user