Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15bd1e5c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Here are two more driver bugfixes for I2C which would be good to have"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: cadence: Set the hardware time-out register to maximum value
  i2c: davinci: generate STP always when NACK is received
parents beb5af40 681d15a0
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -111,6 +111,8 @@
#define CDNS_I2C_DIVA_MAX	4
#define CDNS_I2C_DIVA_MAX	4
#define CDNS_I2C_DIVB_MAX	64
#define CDNS_I2C_DIVB_MAX	64


#define CDNS_I2C_TIMEOUT_MAX	0xFF

#define cdns_i2c_readreg(offset)       readl_relaxed(id->membase + offset)
#define cdns_i2c_readreg(offset)       readl_relaxed(id->membase + offset)
#define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset)
#define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset)


@@ -852,6 +854,15 @@ static int cdns_i2c_probe(struct platform_device *pdev)
		goto err_clk_dis;
		goto err_clk_dis;
	}
	}


	/*
	 * Cadence I2C controller has a bug wherein it generates
	 * invalid read transaction after HW timeout in master receiver mode.
	 * HW timeout is not used by this driver and the interrupt is disabled.
	 * But the feature itself cannot be disabled. Hence maximum value
	 * is written to this register to reduce the chances of error.
	 */
	cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET);

	dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n",
	dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n",
		 id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq);
		 id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq);


+3 −5
Original line number Original line Diff line number Diff line
@@ -407,11 +407,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
	if (dev->cmd_err & DAVINCI_I2C_STR_NACK) {
	if (dev->cmd_err & DAVINCI_I2C_STR_NACK) {
		if (msg->flags & I2C_M_IGNORE_NAK)
		if (msg->flags & I2C_M_IGNORE_NAK)
			return msg->len;
			return msg->len;
		if (stop) {
		w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
		w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
		w |= DAVINCI_I2C_MDR_STP;
		w |= DAVINCI_I2C_MDR_STP;
		davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
		davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
		}
		return -EREMOTEIO;
		return -EREMOTEIO;
	}
	}
	return -EIO;
	return -EIO;