Commit 9e6c269d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Usual set of driver fixes. A bit more than usual because I was
  unavailable for a while"

* tag 'i2c-for-6.5-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue
  i2c: Update documentation to use .probe() again
  i2c: sun6i-p2wi: Fix an error message in probe()
  i2c: hisi: Only handle the interrupt of the driver's transfer
  i2c: tegra: Fix i2c-tegra DMA config option processing
  i2c: tegra: Fix failure during probe deferral cleanup
  i2c: designware: Handle invalid SMBus block data response length value
  i2c: designware: Correct length byte validation logic
  i2c: imx-lpi2c: return -EINVAL when i2c peripheral clk doesn't work
parents 12e6cced 4caf4cb1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ driver model device node, and its I2C address.
	},

	.id_table	= foo_idtable,
	.probe_new	= foo_probe,
	.probe		= foo_probe,
	.remove		= foo_remove,
	/* if device autodetection is needed: */
	.class		= I2C_CLASS_SOMETHING,
+7 −4
Original line number Diff line number Diff line
@@ -233,13 +233,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
				   u32 offset)
{
	u32 val;
	unsigned long flags;

	if (iproc_i2c->idm_base) {
		spin_lock(&iproc_i2c->idm_lock);
		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
		writel(iproc_i2c->ape_addr_mask,
		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
		val = readl(iproc_i2c->base + offset);
		spin_unlock(&iproc_i2c->idm_lock);
		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
	} else {
		val = readl(iproc_i2c->base + offset);
	}
@@ -250,12 +251,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
				    u32 offset, u32 val)
{
	unsigned long flags;

	if (iproc_i2c->idm_base) {
		spin_lock(&iproc_i2c->idm_lock);
		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
		writel(iproc_i2c->ape_addr_mask,
		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
		writel(val, iproc_i2c->base + offset);
		spin_unlock(&iproc_i2c->idm_lock);
		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
	} else {
		writel(val, iproc_i2c->base + offset);
	}
+14 −2
Original line number Diff line number Diff line
@@ -588,9 +588,21 @@ i2c_dw_read(struct dw_i2c_dev *dev)
			u32 flags = msgs[dev->msg_read_idx].flags;

			regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
			tmp &= DW_IC_DATA_CMD_DAT;
			/* Ensure length byte is a valid value */
			if (flags & I2C_M_RECV_LEN &&
			    (tmp & DW_IC_DATA_CMD_DAT) <= I2C_SMBUS_BLOCK_MAX && tmp > 0) {
			if (flags & I2C_M_RECV_LEN) {
				/*
				 * if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be
				 * detected from the registers, the controller can be
				 * disabled if the STOP bit is set. But it is only set
				 * after receiving block data response length in
				 * I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read
				 * another byte with STOP bit set when the block data
				 * response length is invalid to complete the transaction.
				 */
				if (!tmp || tmp > I2C_SMBUS_BLOCK_MAX)
					tmp = 1;

				len = i2c_dw_recv_len(dev, tmp);
			}
			*buf++ = tmp;
+8 −0
Original line number Diff line number Diff line
@@ -330,6 +330,14 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
	struct hisi_i2c_controller *ctlr = context;
	u32 int_stat;

	/*
	 * Don't handle the interrupt if cltr->completion is NULL. We may
	 * reach here because the interrupt is spurious or the transfer is
	 * started by another port (e.g. firmware) rather than us.
	 */
	if (!ctlr->completion)
		return IRQ_NONE;

	int_stat = readl(ctlr->iobase + HISI_I2C_INT_MSTAT);
	hisi_i2c_clear_int(ctlr, int_stat);
	if (!(int_stat & HISI_I2C_INT_ALL))
+3 −0
Original line number Diff line number Diff line
@@ -209,6 +209,9 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
	lpi2c_imx_set_mode(lpi2c_imx);

	clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
	if (!clk_rate)
		return -EINVAL;

	if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
		filt = 0;
	else
Loading