Commit 077e81d5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Another bunch  of driver fixes"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: sprd: depend on COMMON_CLK to fix compile tests
  Revert "i2c: imx: Remove unused .id_table support"
  i2c: octeon: check correct size of maximum RECV_LEN packet
  i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO
  i2c: bpmp-tegra: Ignore unknown I2C_M flags
  i2c: tegra: Wait for config load atomically while in ISR
parents 15cfb0f0 9ecd1d2b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1013,6 +1013,7 @@ config I2C_SIRF
config I2C_SPRD
	tristate "Spreadtrum I2C interface"
	depends on I2C=y && (ARCH_SPRD || COMPILE_TEST)
	depends on COMMON_CLK
	help
	  If you say yes to this option, support will be included for the
	  Spreadtrum I2C interface.
+19 −1
Original line number Diff line number Diff line
@@ -241,6 +241,19 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {

};

static const struct platform_device_id imx_i2c_devtype[] = {
	{
		.name = "imx1-i2c",
		.driver_data = (kernel_ulong_t)&imx1_i2c_hwdata,
	}, {
		.name = "imx21-i2c",
		.driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);

static const struct of_device_id i2c_imx_dt_ids[] = {
	{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
	{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
@@ -1330,7 +1343,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
		return -ENOMEM;

	match = device_get_match_data(&pdev->dev);
	if (match)
		i2c_imx->hwdata = match;
	else
		i2c_imx->hwdata = (struct imx_i2c_hwdata *)
				platform_get_device_id(pdev)->driver_data;

	/* Setup i2c_imx driver structure */
	strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
@@ -1498,6 +1515,7 @@ static struct platform_driver i2c_imx_driver = {
		.of_match_table = i2c_imx_dt_ids,
		.acpi_match_table = i2c_imx_acpi_ids,
	},
	.id_table = imx_i2c_devtype,
};

static int __init i2c_adap_imx_init(void)
+1 −1
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
		if (result)
			return result;
		if (recv_len && i == 0) {
			if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
			if (data[i] > I2C_SMBUS_BLOCK_MAX)
				return -EPROTO;
			length += data[i];
		}
+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 flags, u16 *out)
		flags &= ~I2C_M_RECV_LEN;
	}

	return (flags != 0) ? -EINVAL : 0;
	return 0;
}

/**
+22 −2
Original line number Diff line number Diff line
@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg)
	/* read back register to make sure that register writes completed */
	if (reg != I2C_TX_FIFO)
		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
	else if (i2c_dev->is_vi)
		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS));
}

static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
	writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
}

static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
			   unsigned int reg, unsigned int len)
{
	u32 *data32 = data;

	/*
	 * VI I2C controller has known hardware bug where writes get stuck
	 * when immediate multiple writes happen to TX_FIFO register.
	 * Recommended software work around is to read I2C register after
	 * each write to TX_FIFO register to flush out the data.
	 */
	while (len--)
		i2c_writel(i2c_dev, *data32++, reg);
}

static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
		       unsigned int reg, unsigned int len)
{
@@ -533,7 +550,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
	u32 val;

	if (!i2c_dev->atomic_mode)
	if (!i2c_dev->atomic_mode && !in_irq())
		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
						  delay_us, timeout_us);

@@ -811,6 +828,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
		i2c_dev->msg_buf_remaining = buf_remaining;
		i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;

		if (i2c_dev->is_vi)
			i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
		else
			i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);

		buf += words_to_transfer * BYTES_PER_FIFO_WORD;