Commit 7e161a99 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'i2c-for-6.17-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull more i2c updates from Wolfram Sang:
 "A few more patches from I2C. Some are fixes which would be nice to
  have in rc1 already, some patches have nearly been fallen through the
  cracks, some just needed a bit more testing.

   - acpi: enable 100kHz workaround for DLL0945

   - apple: add support for Apple A7–A11, T2 chips; Kconfig update

   - mux: mule: fix error handling path

   - qcom-geni: fix controller frequency mapping

   - stm32f7: add DMA-safe transfer support

   - tegra: use controller reset if device reset is missing

   - tegra: remove unnecessary dma_sync*() calls"

* tag 'i2c-for-6.17-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: muxes: mule: Fix an error handling path in mule_i2c_mux_probe()
  i2c: Force DLL0945 touchpad i2c freq to 100khz
  i2c: apple: Drop default ARCH_APPLE in Kconfig
  i2c: qcom-geni: fix I2C frequency table to achieve accurate bus rates
  dt-bindings: i2c: apple,i2c: Document Apple A7-A11, T2 compatibles
  i2c: tegra: Remove dma_sync_*() calls
  i2c: tegra: Use internal reset when reset property is not available
  i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs
parents 0974f486 33ac5155
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,11 @@ properties:
  compatible:
    items:
      - enum:
          - apple,s5l8960x-i2c
          - apple,t7000-i2c
          - apple,s8000-i2c
          - apple,t8010-i2c
          - apple,t8015-i2c
          - apple,t8103-i2c
          - apple,t8112-i2c
          - apple,t6000-i2c
+0 −1
Original line number Diff line number Diff line
@@ -992,7 +992,6 @@ config I2C_APPLE
	tristate "Apple SMBus platform driver"
	depends on !I2C_PASEMI
	depends on ARCH_APPLE || COMPILE_TEST
	default ARCH_APPLE
	help
	  Say Y here if you want to use the I2C controller present on Apple
	  Silicon chips such as the M1.
+3 −3
Original line number Diff line number Diff line
@@ -155,9 +155,9 @@ static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {

/* source_clock = 32 MHz */
static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
	{ I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 40 },
	{ I2C_MAX_FAST_MODE_FREQ, 4,  3, 11, 20 },
	{ I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3,  6, 15 },
	{ I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38 },
	{ I2C_MAX_FAST_MODE_FREQ, 4,  3, 9, 19 },
	{ I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 5, 15 },
	{}
};

+21 −11
Original line number Diff line number Diff line
@@ -742,11 +742,14 @@ static void stm32f7_i2c_dma_callback(void *arg)
{
	struct stm32f7_i2c_dev *i2c_dev = arg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;

	stm32f7_i2c_disable_dma_req(i2c_dev);
	dmaengine_terminate_async(dma->chan_using);
	dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
			 dma->dma_data_dir);
	if (!f7_msg->smbus)
		i2c_put_dma_safe_msg_buf(f7_msg->buf, i2c_dev->msg, true);
	complete(&dma->dma_complete);
}

@@ -882,6 +885,7 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	void __iomem *base = i2c_dev->base;
	u8 *dma_buf;
	u32 cr1, cr2;
	int ret;

@@ -931,17 +935,23 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,

	/* Configure DMA or enable RX/TX interrupt */
	i2c_dev->use_dma = false;
	if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN
	    && !i2c_dev->atomic) {
	if (i2c_dev->dma && !i2c_dev->atomic) {
		dma_buf = i2c_get_dma_safe_msg_buf(msg, STM32F7_I2C_DMA_LEN_MIN);
		if (dma_buf) {
			f7_msg->buf = dma_buf;
			ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
						      msg->flags & I2C_M_RD,
						      f7_msg->count, f7_msg->buf,
						      stm32f7_i2c_dma_callback,
						      i2c_dev);
		if (!ret)
			i2c_dev->use_dma = true;
		else
			if (ret) {
				dev_warn(i2c_dev->dev, "can't use DMA\n");
				i2c_put_dma_safe_msg_buf(f7_msg->buf, msg, false);
				f7_msg->buf = msg->buf;
			} else {
				i2c_dev->use_dma = true;
			}
		}
	}

	if (!i2c_dev->use_dma) {
+44 −20
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@
#define I2C_MST_FIFO_STATUS_TX			GENMASK(23, 16)
#define I2C_MST_FIFO_STATUS_RX			GENMASK(7, 0)

#define I2C_MASTER_RESET_CNTRL			0x0a8

/* configuration load timeout in microseconds */
#define I2C_CONFIG_LOAD_TIMEOUT			1000000

@@ -184,6 +186,9 @@ enum msg_end_type {
 * @has_mst_fifo: The I2C controller contains the new MST FIFO interface that
 *		provides additional features and allows for longer messages to
 *		be transferred in one go.
 * @has_mst_reset: The I2C controller contains MASTER_RESET_CTRL register which
 *		provides an alternative to controller reset when configured as
 *		I2C master
 * @quirks: I2C adapter quirks for limiting write/read transfer size and not
 *		allowing 0 length transfers.
 * @supports_bus_clear: Bus Clear support to recover from bus hang during
@@ -213,6 +218,7 @@ struct tegra_i2c_hw_feature {
	bool has_multi_master_mode;
	bool has_slcg_override_reg;
	bool has_mst_fifo;
	bool has_mst_reset;
	const struct i2c_adapter_quirks *quirks;
	bool supports_bus_clear;
	bool has_apb_dma;
@@ -605,12 +611,42 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
	return 0;
}

static int tegra_i2c_master_reset(struct tegra_i2c_dev *i2c_dev)
{
	if (!i2c_dev->hw->has_mst_reset)
		return -EOPNOTSUPP;

	/*
	 * Writing 1 to I2C_MASTER_RESET_CNTRL will reset all internal state of
	 * Master logic including FIFOs. Clear this bit to 0 for normal operation.
	 * SW needs to wait for 2us after assertion and de-assertion of this soft
	 * reset.
	 */
	i2c_writel(i2c_dev, 0x1, I2C_MASTER_RESET_CNTRL);
	fsleep(2);

	i2c_writel(i2c_dev, 0x0, I2C_MASTER_RESET_CNTRL);
	fsleep(2);

	return 0;
}

static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
{
	u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
	struct i2c_timings *t = &i2c_dev->timings;
	int err;

	/*
	 * Reset the controller before initializing it.
	 * In case if device_reset() returns -ENOENT, i.e. when the reset is
	 * not available, the internal software reset will be used if it is
	 * supported by the controller.
	 */
	err = device_reset(i2c_dev->dev);
	if (err == -ENOENT)
		err = tegra_i2c_master_reset(i2c_dev);

	/*
	 * The reset shouldn't ever fail in practice. The failure will be a
	 * sign of a severe problem that needs to be resolved. Still we don't
@@ -619,7 +655,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
	 * emit a noisy warning on error, which won't stay unnoticed and
	 * won't hose machine entirely.
	 */
	err = device_reset(i2c_dev->dev);
	WARN_ON_ONCE(err);

	if (IS_DVC(i2c_dev))
@@ -1266,17 +1301,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,

	if (i2c_dev->dma_mode) {
		if (i2c_dev->msg_read) {
			dma_sync_single_for_device(i2c_dev->dma_dev,
						   i2c_dev->dma_phys,
						   xfer_size, DMA_FROM_DEVICE);

			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
			if (err)
				return err;
		} else {
			dma_sync_single_for_cpu(i2c_dev->dma_dev,
						i2c_dev->dma_phys,
						xfer_size, DMA_TO_DEVICE);
		}
	}

@@ -1286,11 +1313,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
		if (i2c_dev->dma_mode) {
			memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
			       msg->buf, i2c_dev->msg_len);

			dma_sync_single_for_device(i2c_dev->dma_dev,
						   i2c_dev->dma_phys,
						   xfer_size, DMA_TO_DEVICE);

			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
			if (err)
				return err;
@@ -1331,14 +1353,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
			return -ETIMEDOUT;
		}

		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
			dma_sync_single_for_cpu(i2c_dev->dma_dev,
						i2c_dev->dma_phys,
						xfer_size, DMA_FROM_DEVICE);

		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE)
			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
	}
	}

	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete,
					      xfer_time);
@@ -1468,6 +1485,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = false,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = false,
	.has_apb_dma = true,
@@ -1492,6 +1510,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = false,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = false,
	.has_apb_dma = true,
@@ -1516,6 +1535,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = false,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = true,
	.has_apb_dma = true,
@@ -1540,6 +1560,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = true,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = true,
	.has_apb_dma = true,
@@ -1564,6 +1585,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = true,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = true,
	.has_apb_dma = true,
@@ -1588,6 +1610,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
	.has_multi_master_mode = false,
	.has_slcg_override_reg = true,
	.has_mst_fifo = false,
	.has_mst_reset = false,
	.quirks = &tegra_i2c_quirks,
	.supports_bus_clear = true,
	.has_apb_dma = false,
@@ -1612,6 +1635,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
	.has_multi_master_mode = true,
	.has_slcg_override_reg = true,
	.has_mst_fifo = true,
	.has_mst_reset = true,
	.quirks = &tegra194_i2c_quirks,
	.supports_bus_clear = true,
	.has_apb_dma = false,
Loading