svn commit: r354294 - head/sys/dev/ichiic

Vladimir Kondratyev wulf at FreeBSD.org
Sun Nov 3 20:43:03 UTC 2019


Author: wulf
Date: Sun Nov  3 20:43:02 2019
New Revision: 354294
URL: https://svnweb.freebsd.org/changeset/base/354294

Log:
  [ig4] Drop driver's internal RX FIFO
  
  There is no need to read all controller's RX FIFO data to clear RX_FULL
  bit in interrupt handler as interrupts are masked permanently since
  previous commit.

Modified:
  head/sys/dev/ichiic/ig4_iic.c
  head/sys/dev/ichiic/ig4_var.h

Modified: head/sys/dev/ichiic/ig4_iic.c
==============================================================================
--- head/sys/dev/ichiic/ig4_iic.c	Sun Nov  3 20:42:04 2019	(r354293)
+++ head/sys/dev/ichiic/ig4_iic.c	Sun Nov  3 20:43:02 2019	(r354294)
@@ -168,17 +168,6 @@ wait_status(ig4iic_softc_t *sc, uint32_t status)
 		}
 
 		/*
-		 * When waiting for receive data break-out if the interrupt
-		 * loaded data into the FIFO.
-		 */
-		if (status & IG4_STATUS_RX_NOTEMPTY) {
-			if (sc->rpos != sc->rnext) {
-				error = 0;
-				break;
-			}
-		}
-
-		/*
 		 * When waiting for the transmit FIFO to become empty,
 		 * reset the timeout if we see a change in the transmit
 		 * FIFO level as progress is being made.
@@ -217,25 +206,6 @@ wait_status(ig4iic_softc_t *sc, uint32_t status)
 }
 
 /*
- * Read I2C data.  The data might have already been read by
- * the interrupt code, otherwise it is sitting in the data
- * register.
- */
-static uint8_t
-data_read(ig4iic_softc_t *sc)
-{
-	uint8_t c;
-
-	if (sc->rpos == sc->rnext) {
-		c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
-	} else {
-		c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
-		++sc->rpos;
-	}
-	return (c);
-}
-
-/*
  * Set the slave address.  The controller must be disabled when
  * changing the address.
  *
@@ -334,7 +304,7 @@ ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t
 		error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
 		if (error)
 			break;
-		buf[i] = data_read(sc);
+		buf[i] = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
 	}
 
 	(void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
@@ -455,16 +425,6 @@ ig4iic_transfer(device_t dev, struct iic_msg *msgs, ui
 	 */
 	reg_read(sc, IG4_REG_CLR_TX_ABORT);
 
-	/*
-	 * Clean out any previously received data.
-	 */
-	if (sc->rpos != sc->rnext && bootverbose) {
-		device_printf(sc->dev, "discarding %d bytes of spurious data\n",
-		    sc->rnext - sc->rpos);
-	}
-	sc->rpos = 0;
-	sc->rnext = 0;
-
 	rpstart = false;
 	error = 0;
 	for (i = 0; i < nmsgs; i++) {
@@ -734,19 +694,10 @@ static void
 ig4iic_intr(void *cookie)
 {
 	ig4iic_softc_t *sc = cookie;
-	uint32_t status;
 
 	mtx_lock(&sc->io_lock);
 	set_intr_mask(sc, 0);
 	reg_read(sc, IG4_REG_CLR_INTR);
-	status = reg_read(sc, IG4_REG_I2C_STA);
-	while (status & IG4_STATUS_RX_NOTEMPTY) {
-		sc->rbuf[sc->rnext & IG4_RBUFMASK] =
-		    (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
-		++sc->rnext;
-		status = reg_read(sc, IG4_REG_I2C_STA);
-	}
-
 	wakeup(sc);
 	mtx_unlock(&sc->io_lock);
 }

Modified: head/sys/dev/ichiic/ig4_var.h
==============================================================================
--- head/sys/dev/ichiic/ig4_var.h	Sun Nov  3 20:42:04 2019	(r354293)
+++ head/sys/dev/ichiic/ig4_var.h	Sun Nov  3 20:43:02 2019	(r354294)
@@ -43,9 +43,6 @@
 #include "pci_if.h"
 #include "iicbus_if.h"
 
-#define IG4_RBUFSIZE	128
-#define IG4_RBUFMASK	(IG4_RBUFSIZE - 1)
-
 enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE };
 enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE, IG4_APL };
 
@@ -62,9 +59,6 @@ struct ig4iic_softc {
 	enum ig4_vers	version;
 	enum ig4_op	op;
 	int		cmd;
-	int		rnext;
-	int		rpos;
-	char		rbuf[IG4_RBUFSIZE];
 	uint32_t	intr_mask;
 	int		error;
 	uint8_t		last_slave;
@@ -81,19 +75,6 @@ struct ig4iic_softc {
 	 * with the controller acquire an exclusive lock on call_lock
 	 * to prevent interleaving of calls to the interface and a lock on
 	 * io_lock right afterwards, to synchronize controller I/O activity.
-	 *
-	 * The interrupt handler can only read data while no iicbus call
-	 * is in progress or while io_lock is dropped during mtx_sleep in
-	 * wait_status and set_controller. It is safe to drop io_lock in those
-	 * places, because the interrupt handler only accesses those registers:
-	 *
-	 * - IG4_REG_I2C_STA  (I2C Status)
-	 * - IG4_REG_DATA_CMD (Data Buffer and Command)
-	 * - IG4_REG_CLR_INTR (Clear Interrupt)
-	 *
-	 * Locking outside of those places is required to make the content
-	 * of rpos/rnext predictable (e.g. whenever data_read is called and in
-	 * ig4iic_transfer).
 	 */
 	struct sx	call_lock;
 	struct mtx	io_lock;


More information about the svn-src-all mailing list