Skip to content

Commit dec5fcf

Browse files
seebegregkh
authored andcommitted
i2c: riic: correctly finish transfers
[ Upstream commit 71ccea095ea1d4efd004dab971be6d599e06fc3f ] This fixes the condition where the controller has not fully completed its final transfer and leaves the bus and controller in a undesirable state. At the end of the last transmitted byte, the existing driver would just signal for a STOP condition to be transmitted then immediately signal completion. However, the full STOP procedure might not have fully taken place by the time the runtime PM shuts off the peripheral clock, leaving the bus in a suspended state. Alternatively, the STOP condition on the bus may have completed, but when the next transaction is requested by the upper layer, not all the necessary register cleanup was finished from the last transfer which made the driver return BUS BUSY when it really wasn't. This patch now makes all transmit and receive transactions wait for the STOP condition to fully complete before signaling a completed transaction. With this new method, runtime PM no longer seems to be an issue. Fixes: 310c18a ("i2c: riic: add driver") Signed-off-by: Chris Brandt <chris.brandt@renesas.com> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 3580080 commit dec5fcf

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

drivers/i2c/busses/i2c-riic.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#define ICIER_TEIE 0x40
8181
#define ICIER_RIE 0x20
8282
#define ICIER_NAKIE 0x10
83+
#define ICIER_SPIE 0x08
8384

8485
#define ICSR2_NACKF 0x10
8586

@@ -216,11 +217,10 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
216217
return IRQ_NONE;
217218
}
218219

219-
if (riic->is_last || riic->err)
220+
if (riic->is_last || riic->err) {
221+
riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER);
220222
writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
221-
222-
writeb(0, riic->base + RIIC_ICIER);
223-
complete(&riic->msg_done);
223+
}
224224

225225
return IRQ_HANDLED;
226226
}
@@ -240,13 +240,13 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
240240

241241
if (riic->bytes_left == 1) {
242242
/* STOP must come before we set ACKBT! */
243-
if (riic->is_last)
243+
if (riic->is_last) {
244+
riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER);
244245
writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
246+
}
245247

246248
riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3);
247249

248-
writeb(0, riic->base + RIIC_ICIER);
249-
complete(&riic->msg_done);
250250
} else {
251251
riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3);
252252
}
@@ -259,6 +259,21 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
259259
return IRQ_HANDLED;
260260
}
261261

262+
static irqreturn_t riic_stop_isr(int irq, void *data)
263+
{
264+
struct riic_dev *riic = data;
265+
266+
/* read back registers to confirm writes have fully propagated */
267+
writeb(0, riic->base + RIIC_ICSR2);
268+
readb(riic->base + RIIC_ICSR2);
269+
writeb(0, riic->base + RIIC_ICIER);
270+
readb(riic->base + RIIC_ICIER);
271+
272+
complete(&riic->msg_done);
273+
274+
return IRQ_HANDLED;
275+
}
276+
262277
static u32 riic_func(struct i2c_adapter *adap)
263278
{
264279
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@@ -326,6 +341,7 @@ static struct riic_irq_desc riic_irqs[] = {
326341
{ .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" },
327342
{ .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" },
328343
{ .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" },
344+
{ .res_num = 3, .isr = riic_stop_isr, .name = "riic-stop" },
329345
{ .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" },
330346
};
331347

0 commit comments

Comments
 (0)