Skip to content

Commit ace92fd

Browse files
committed
Merge tag 'for-6.7-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull more i2c updates from Wolfram Sang: "This contains one patch which slipped through the cracks (iproc), a core sanitizing improvement as the new memdup_array_user() helper went upstream (i2c-dev), and two driver bugfixes (designware, cp2615)" * tag 'for-6.7-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: cp2615: Fix 'assignment to __be16' warning i2c: dev: copy userspace array safely i2c: designware: Disable TX_EMPTY irq while waiting for block length byte i2c: iproc: handle invalid slave state
2 parents 12418ec + bdba49c commit ace92fd

File tree

4 files changed

+94
-64
lines changed

4 files changed

+94
-64
lines changed

drivers/i2c/busses/i2c-bcm-iproc.c

Lines changed: 75 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -316,26 +316,44 @@ static void bcm_iproc_i2c_slave_init(
316316
iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val);
317317
}
318318

319-
static void bcm_iproc_i2c_check_slave_status(
320-
struct bcm_iproc_i2c_dev *iproc_i2c)
319+
static bool bcm_iproc_i2c_check_slave_status
320+
(struct bcm_iproc_i2c_dev *iproc_i2c, u32 status)
321321
{
322322
u32 val;
323+
bool recover = false;
323324

324-
val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET);
325-
/* status is valid only when START_BUSY is cleared after it was set */
326-
if (val & BIT(S_CMD_START_BUSY_SHIFT))
327-
return;
325+
/* check slave transmit status only if slave is transmitting */
326+
if (!iproc_i2c->slave_rx_only) {
327+
val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET);
328+
/* status is valid only when START_BUSY is cleared */
329+
if (!(val & BIT(S_CMD_START_BUSY_SHIFT))) {
330+
val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK;
331+
if (val == S_CMD_STATUS_TIMEOUT ||
332+
val == S_CMD_STATUS_MASTER_ABORT) {
333+
dev_warn(iproc_i2c->device,
334+
(val == S_CMD_STATUS_TIMEOUT) ?
335+
"slave random stretch time timeout\n" :
336+
"Master aborted read transaction\n");
337+
recover = true;
338+
}
339+
}
340+
}
341+
342+
/* RX_EVENT is not valid when START_BUSY is set */
343+
if ((status & BIT(IS_S_RX_EVENT_SHIFT)) &&
344+
(status & BIT(IS_S_START_BUSY_SHIFT))) {
345+
dev_warn(iproc_i2c->device, "Slave aborted read transaction\n");
346+
recover = true;
347+
}
328348

329-
val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK;
330-
if (val == S_CMD_STATUS_TIMEOUT || val == S_CMD_STATUS_MASTER_ABORT) {
331-
dev_err(iproc_i2c->device, (val == S_CMD_STATUS_TIMEOUT) ?
332-
"slave random stretch time timeout\n" :
333-
"Master aborted read transaction\n");
349+
if (recover) {
334350
/* re-initialize i2c for recovery */
335351
bcm_iproc_i2c_enable_disable(iproc_i2c, false);
336352
bcm_iproc_i2c_slave_init(iproc_i2c, true);
337353
bcm_iproc_i2c_enable_disable(iproc_i2c, true);
338354
}
355+
356+
return recover;
339357
}
340358

341359
static void bcm_iproc_i2c_slave_read(struct bcm_iproc_i2c_dev *iproc_i2c)
@@ -420,48 +438,6 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c,
420438
u32 val;
421439
u8 value;
422440

423-
/*
424-
* Slave events in case of master-write, master-write-read and,
425-
* master-read
426-
*
427-
* Master-write : only IS_S_RX_EVENT_SHIFT event
428-
* Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
429-
* events
430-
* Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
431-
* events or only IS_S_RD_EVENT_SHIFT
432-
*
433-
* iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt
434-
* (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes
435-
* full. This can happen if Master issues write requests of more than
436-
* 64 bytes.
437-
*/
438-
if (status & BIT(IS_S_RX_EVENT_SHIFT) ||
439-
status & BIT(IS_S_RD_EVENT_SHIFT) ||
440-
status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) {
441-
/* disable slave interrupts */
442-
val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET);
443-
val &= ~iproc_i2c->slave_int_mask;
444-
iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val);
445-
446-
if (status & BIT(IS_S_RD_EVENT_SHIFT))
447-
/* Master-write-read request */
448-
iproc_i2c->slave_rx_only = false;
449-
else
450-
/* Master-write request only */
451-
iproc_i2c->slave_rx_only = true;
452-
453-
/* schedule tasklet to read data later */
454-
tasklet_schedule(&iproc_i2c->slave_rx_tasklet);
455-
456-
/*
457-
* clear only IS_S_RX_EVENT_SHIFT and
458-
* IS_S_RX_FIFO_FULL_SHIFT interrupt.
459-
*/
460-
val = BIT(IS_S_RX_EVENT_SHIFT);
461-
if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT))
462-
val |= BIT(IS_S_RX_FIFO_FULL_SHIFT);
463-
iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val);
464-
}
465441

466442
if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) {
467443
iproc_i2c->tx_underrun++;
@@ -493,8 +469,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c,
493469
* less than PKT_LENGTH bytes were output on the SMBUS
494470
*/
495471
iproc_i2c->slave_int_mask &= ~BIT(IE_S_TX_UNDERRUN_SHIFT);
496-
iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET,
497-
iproc_i2c->slave_int_mask);
472+
val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET);
473+
val &= ~BIT(IE_S_TX_UNDERRUN_SHIFT);
474+
iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val);
498475

499476
/* End of SMBUS for Master Read */
500477
val = BIT(S_TX_WR_STATUS_SHIFT);
@@ -515,9 +492,49 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c,
515492
BIT(IS_S_START_BUSY_SHIFT));
516493
}
517494

518-
/* check slave transmit status only if slave is transmitting */
519-
if (!iproc_i2c->slave_rx_only)
520-
bcm_iproc_i2c_check_slave_status(iproc_i2c);
495+
/* if the controller has been reset, immediately return from the ISR */
496+
if (bcm_iproc_i2c_check_slave_status(iproc_i2c, status))
497+
return true;
498+
499+
/*
500+
* Slave events in case of master-write, master-write-read and,
501+
* master-read
502+
*
503+
* Master-write : only IS_S_RX_EVENT_SHIFT event
504+
* Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
505+
* events
506+
* Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
507+
* events or only IS_S_RD_EVENT_SHIFT
508+
*
509+
* iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt
510+
* (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes
511+
* full. This can happen if Master issues write requests of more than
512+
* 64 bytes.
513+
*/
514+
if (status & BIT(IS_S_RX_EVENT_SHIFT) ||
515+
status & BIT(IS_S_RD_EVENT_SHIFT) ||
516+
status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) {
517+
/* disable slave interrupts */
518+
val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET);
519+
val &= ~iproc_i2c->slave_int_mask;
520+
iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val);
521+
522+
if (status & BIT(IS_S_RD_EVENT_SHIFT))
523+
/* Master-write-read request */
524+
iproc_i2c->slave_rx_only = false;
525+
else
526+
/* Master-write request only */
527+
iproc_i2c->slave_rx_only = true;
528+
529+
/* schedule tasklet to read data later */
530+
tasklet_schedule(&iproc_i2c->slave_rx_tasklet);
531+
532+
/* clear IS_S_RX_FIFO_FULL_SHIFT interrupt */
533+
if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) {
534+
val = BIT(IS_S_RX_FIFO_FULL_SHIFT);
535+
iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val);
536+
}
537+
}
521538

522539
return true;
523540
}

drivers/i2c/busses/i2c-cp2615.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static int cp2615_init_iop_msg(struct cp2615_iop_msg *ret, enum cp2615_iop_msg_t
8585
if (!ret)
8686
return -EINVAL;
8787

88-
ret->preamble = 0x2A2A;
88+
ret->preamble = htons(0x2A2AU);
8989
ret->length = htons(data_len + 6);
9090
ret->msg = htons(msg);
9191
if (data && data_len)

drivers/i2c/busses/i2c-designware-master.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,10 +519,16 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
519519

520520
/*
521521
* Because we don't know the buffer length in the
522-
* I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop
523-
* the transaction here.
522+
* I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop the
523+
* transaction here. Also disable the TX_EMPTY IRQ
524+
* while waiting for the data length byte to avoid the
525+
* bogus interrupts flood.
524526
*/
525-
if (buf_len > 0 || flags & I2C_M_RECV_LEN) {
527+
if (flags & I2C_M_RECV_LEN) {
528+
dev->status |= STATUS_WRITE_IN_PROGRESS;
529+
intr_mask &= ~DW_IC_INTR_TX_EMPTY;
530+
break;
531+
} else if (buf_len > 0) {
526532
/* more bytes to be written */
527533
dev->status |= STATUS_WRITE_IN_PROGRESS;
528534
break;
@@ -558,6 +564,13 @@ i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len)
558564
msgs[dev->msg_read_idx].len = len;
559565
msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN;
560566

567+
/*
568+
* Received buffer length, re-enable TX_EMPTY interrupt
569+
* to resume the SMBUS transaction.
570+
*/
571+
regmap_update_bits(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY,
572+
DW_IC_INTR_TX_EMPTY);
573+
561574
return len;
562575
}
563576

drivers/i2c/i2c-dev.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
450450
if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
451451
return -EINVAL;
452452

453-
rdwr_pa = memdup_user(rdwr_arg.msgs,
454-
rdwr_arg.nmsgs * sizeof(struct i2c_msg));
453+
rdwr_pa = memdup_array_user(rdwr_arg.msgs,
454+
rdwr_arg.nmsgs, sizeof(struct i2c_msg));
455455
if (IS_ERR(rdwr_pa))
456456
return PTR_ERR(rdwr_pa);
457457

0 commit comments

Comments
 (0)