diff options
author | Marek Vasut <marex@denx.de> | 2021-08-23 23:41:41 +0200 |
---|---|---|
committer | Wolfram Sang <wsa@kernel.org> | 2021-09-14 12:22:44 +0200 |
commit | 861dcffe1b9e986d254ea0d7e9f0a542bfc5ab11 (patch) | |
tree | 1e3fa9fec384d3e6f77e6ee4491907f83817afb1 /drivers | |
parent | i2c: xiic: Fix broken locking on tx_msg (diff) | |
download | linux-861dcffe1b9e986d254ea0d7e9f0a542bfc5ab11.tar.xz linux-861dcffe1b9e986d254ea0d7e9f0a542bfc5ab11.zip |
i2c: xiic: Drop broken interrupt handler
The interrupt handler is missing locking when reading out registers
and is racing with other threads which might access the driver. Drop
it altogether, so that the threaded interrupt is always executed, as
that one is already serialized by the driver mutex. This also allows
dropping local_irq_save()/local_irq_restore() in xiic_start_recv().
Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-xiic.c | 25 |
1 files changed, 1 insertions, 24 deletions
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 50320dd32eea..b13166e94d89 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -554,7 +554,6 @@ static void xiic_start_recv(struct xiic_i2c *i2c) { u8 rx_watermark; struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg; - unsigned long flags; /* Clear and enable Rx full interrupt. */ xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK); @@ -570,7 +569,6 @@ static void xiic_start_recv(struct xiic_i2c *i2c) rx_watermark = IIC_RX_FIFO_DEPTH; xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1); - local_irq_save(flags); if (!(msg->flags & I2C_M_NOSTART)) /* write the address */ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, @@ -580,7 +578,6 @@ static void xiic_start_recv(struct xiic_i2c *i2c) xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0)); - local_irq_restore(flags); if (i2c->nmsgs == 1) /* very last, enable bus not busy as well */ @@ -620,26 +617,6 @@ static void xiic_start_send(struct xiic_i2c *i2c) XIIC_INTR_BNB_MASK); } -static irqreturn_t xiic_isr(int irq, void *dev_id) -{ - struct xiic_i2c *i2c = dev_id; - u32 pend, isr, ier; - irqreturn_t ret = IRQ_NONE; - /* Do not processes a devices interrupts if the device has no - * interrupts pending - */ - - dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__); - - isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); - ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); - pend = isr & ier; - if (pend) - ret = IRQ_WAKE_THREAD; - - return ret; -} - static void __xiic_start_xfer(struct xiic_i2c *i2c) { int first = 1; @@ -818,7 +795,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(i2c->dev); pm_runtime_set_active(i2c->dev); pm_runtime_enable(i2c->dev); - ret = devm_request_threaded_irq(&pdev->dev, irq, xiic_isr, + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, xiic_process, IRQF_ONESHOT, pdev->name, i2c); |