Commit af6e7de0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Driver bugfixes for I2C.

  Most of them are for the new mlxbf driver which got more exposure
  after rc1. The sh_mobile patch should already have reached you during
  the merge window, but I accidently dropped it. However, since it fixes
  a problem with rebooting, it is still fine for rc3"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: designware: slave should do WRITE_REQUESTED before WRITE_RECEIVED
  i2c: designware: call i2c_dw_read_clear_intrbits_slave() once
  i2c: mlxbf: I2C_MLXBF should depend on MELLANOX_PLATFORM
  i2c: mlxbf: Update author and maintainer email info
  i2c: mlxbf: Update reference clock frequency
  i2c: mlxbf: Remove unecessary wrapper functions
  i2c: mlxbf: Fix resrticted cast warning of sparse
  i2c: mlxbf: Add CONFIG_ACPI to guard ACPI function call
  i2c: sh_mobile: implement atomic transfers
  i2c: mediatek: move dma reset before i2c reset
parents 4b1d362d 3b5f7f10
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11163,7 +11163,7 @@ F: Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt
F:	drivers/input/touchscreen/melfas_mip4.c
MELLANOX BLUEFIELD I2C DRIVER
M:	Khalil Blaiech <kblaiech@mellanox.com>
M:	Khalil Blaiech <kblaiech@nvidia.com>
L:	linux-i2c@vger.kernel.org
S:	Supported
F:	drivers/i2c/busses/i2c-mlxbf.c
+1 −1
Original line number Diff line number Diff line
@@ -733,7 +733,7 @@ config I2C_LPC2K

config I2C_MLXBF
        tristate "Mellanox BlueField I2C controller"
        depends on ARM64
        depends on MELLANOX_PLATFORM && ARM64
        help
          Enabling this option will add I2C SMBus support for Mellanox BlueField
          system.
+19 −33
Original line number Diff line number Diff line
@@ -159,7 +159,6 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
	u32 raw_stat, stat, enabled, tmp;
	u8 val = 0, slave_activity;

	regmap_read(dev->map, DW_IC_INTR_STAT, &stat);
	regmap_read(dev->map, DW_IC_ENABLE, &enabled);
	regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_stat);
	regmap_read(dev->map, DW_IC_STATUS, &tmp);
@@ -168,32 +167,30 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
	if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave)
		return 0;

	stat = i2c_dw_read_clear_intrbits_slave(dev);
	dev_dbg(dev->dev,
		"%#x STATUS SLAVE_ACTIVITY=%#x : RAW_INTR_STAT=%#x : INTR_STAT=%#x\n",
		enabled, slave_activity, raw_stat, stat);

	if ((stat & DW_IC_INTR_RX_FULL) && (stat & DW_IC_INTR_STOP_DET))
		i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED, &val);

	if (stat & DW_IC_INTR_RD_REQ) {
		if (slave_activity) {
	if (stat & DW_IC_INTR_RX_FULL) {
		if (dev->status != STATUS_WRITE_IN_PROGRESS) {
			dev->status = STATUS_WRITE_IN_PROGRESS;
			i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED,
					&val);
		}

		regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
		val = tmp;

				if (!i2c_slave_event(dev->slave,
						     I2C_SLAVE_WRITE_RECEIVED,
						     &val)) {
					dev_vdbg(dev->dev, "Byte %X acked!",
						 val);
		if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
				     &val))
			dev_vdbg(dev->dev, "Byte %X acked!", val);
	}

	if (stat & DW_IC_INTR_RD_REQ) {
		if (slave_activity) {
			regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp);
				stat = i2c_dw_read_clear_intrbits_slave(dev);
			} else {
				regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp);
				regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &tmp);
				stat = i2c_dw_read_clear_intrbits_slave(dev);
			}

			dev->status = STATUS_READ_IN_PROGRESS;
			if (!i2c_slave_event(dev->slave,
					     I2C_SLAVE_READ_REQUESTED,
					     &val))
@@ -205,21 +202,11 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
		if (!i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED,
				     &val))
			regmap_read(dev->map, DW_IC_CLR_RX_DONE, &tmp);

		i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val);
		stat = i2c_dw_read_clear_intrbits_slave(dev);
		return 1;
	}

	if (stat & DW_IC_INTR_RX_FULL) {
		regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
		val = tmp;
		if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
				     &val))
			dev_vdbg(dev->dev, "Byte %X acked!", val);
	} else {
	if (stat & DW_IC_INTR_STOP_DET) {
		dev->status = STATUS_IDLE;
		i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val);
		stat = i2c_dw_read_clear_intrbits_slave(dev);
	}

	return 1;
@@ -230,7 +217,6 @@ static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id)
	struct dw_i2c_dev *dev = dev_id;
	int ret;

	i2c_dw_read_clear_intrbits_slave(dev);
	ret = i2c_dw_irq_handler_slave(dev);
	if (ret > 0)
		complete(&dev->cmd_complete);
+86 −118
Original line number Diff line number Diff line
@@ -62,10 +62,8 @@
 * Master. Default value is set to 400MHz.
 */
#define MLXBF_I2C_TYU_PLL_OUT_FREQ  (400 * 1000 * 1000)
/* Reference clock for Bluefield 1 - 156 MHz. */
#define MLXBF_I2C_TYU_PLL_IN_FREQ   (156 * 1000 * 1000)
/* Reference clock for BlueField 2 - 200 MHz. */
#define MLXBF_I2C_YU_PLL_IN_FREQ    (200 * 1000 * 1000)
/* Reference clock for Bluefield - 156 MHz. */
#define MLXBF_I2C_PLL_IN_FREQ       (156 * 1000 * 1000)

/* Constant used to determine the PLL frequency. */
#define MLNXBF_I2C_COREPLL_CONST    16384
@@ -489,44 +487,6 @@ static struct mutex mlxbf_i2c_bus_lock;

#define MLXBF_I2C_FREQUENCY_1GHZ  1000000000

static void mlxbf_i2c_write(void __iomem *io, int reg, u32 val)
{
	writel(val, io + reg);
}

static u32 mlxbf_i2c_read(void __iomem *io, int reg)
{
	return readl(io + reg);
}

/*
 * This function is used to read data from Master GW Data Descriptor.
 * Data bytes in the Master GW Data Descriptor are shifted left so the
 * data starts at the MSB of the descriptor registers as set by the
 * underlying hardware. TYU_READ_DATA enables byte swapping while
 * reading data bytes, and MUST be called by the SMBus read routines
 * to copy data from the 32 * 32-bit HW Data registers a.k.a Master GW
 * Data Descriptor.
 */
static u32 mlxbf_i2c_read_data(void __iomem *io, int reg)
{
	return (u32)be32_to_cpu(mlxbf_i2c_read(io, reg));
}

/*
 * This function is used to write data to the Master GW Data Descriptor.
 * Data copied to the Master GW Data Descriptor MUST be shifted left so
 * the data starts at the MSB of the descriptor registers as required by
 * the underlying hardware. TYU_WRITE_DATA enables byte swapping when
 * writing data bytes, and MUST be called by the SMBus write routines to
 * copy data to the 32 * 32-bit HW Data registers a.k.a Master GW Data
 * Descriptor.
 */
static void mlxbf_i2c_write_data(void __iomem *io, int reg, u32 val)
{
	mlxbf_i2c_write(io, reg, (u32)cpu_to_be32(val));
}

/*
 * Function to poll a set of bits at a specific address; it checks whether
 * the bits are equal to zero when eq_zero is set to 'true', and not equal
@@ -541,7 +501,7 @@ static u32 mlxbf_smbus_poll(void __iomem *io, u32 addr, u32 mask,
	timeout = (timeout / MLXBF_I2C_POLL_FREQ_IN_USEC) + 1;

	do {
		bits = mlxbf_i2c_read(io, addr) & mask;
		bits = readl(io + addr) & mask;
		if (eq_zero ? bits == 0 : bits != 0)
			return eq_zero ? 1 : bits;
		udelay(MLXBF_I2C_POLL_FREQ_IN_USEC);
@@ -609,7 +569,7 @@ static int mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv)
			 MLXBF_I2C_SMBUS_TIMEOUT);

	/* Read cause status bits. */
	cause_status_bits = mlxbf_i2c_read(priv->mst_cause->io,
	cause_status_bits = readl(priv->mst_cause->io +
					MLXBF_I2C_CAUSE_ARBITER);
	cause_status_bits &= MLXBF_I2C_CAUSE_MASTER_ARBITER_BITS_MASK;

@@ -617,7 +577,7 @@ static int mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv)
	 * Parse both Cause and Master GW bits, then return transaction status.
	 */

	master_status_bits = mlxbf_i2c_read(priv->smbus->io,
	master_status_bits = readl(priv->smbus->io +
					MLXBF_I2C_SMBUS_MASTER_STATUS);
	master_status_bits &= MLXBF_I2C_SMBUS_MASTER_STATUS_MASK;

@@ -649,10 +609,17 @@ static void mlxbf_i2c_smbus_write_data(struct mlxbf_i2c_priv *priv,

	aligned_length = round_up(length, 4);

	/* Copy data bytes from 4-byte aligned source buffer. */
	/*
	 * Copy data bytes from 4-byte aligned source buffer.
	 * Data copied to the Master GW Data Descriptor MUST be shifted
	 * left so the data starts at the MSB of the descriptor registers
	 * as required by the underlying hardware. Enable byte swapping
	 * when writing data bytes to the 32 * 32-bit HW Data registers
	 * a.k.a Master GW Data Descriptor.
	 */
	for (offset = 0; offset < aligned_length; offset += sizeof(u32)) {
		data32 = *((u32 *)(data + offset));
		mlxbf_i2c_write_data(priv->smbus->io, addr + offset, data32);
		iowrite32be(data32, priv->smbus->io + addr + offset);
	}
}

@@ -664,15 +631,23 @@ static void mlxbf_i2c_smbus_read_data(struct mlxbf_i2c_priv *priv,

	mask = sizeof(u32) - 1;

	/*
	 * Data bytes in the Master GW Data Descriptor are shifted left
	 * so the data starts at the MSB of the descriptor registers as
	 * set by the underlying hardware. Enable byte swapping while
	 * reading data bytes from the 32 * 32-bit HW Data registers
	 * a.k.a Master GW Data Descriptor.
	 */

	for (offset = 0; offset < (length & ~mask); offset += sizeof(u32)) {
		data32 = mlxbf_i2c_read_data(priv->smbus->io, addr + offset);
		data32 = ioread32be(priv->smbus->io + addr + offset);
		*((u32 *)(data + offset)) = data32;
	}

	if (!(length & mask))
		return;

	data32 = mlxbf_i2c_read_data(priv->smbus->io, addr + offset);
	data32 = ioread32be(priv->smbus->io + addr + offset);

	for (byte = 0; byte < (length & mask); byte++) {
		data[offset + byte] = data32 & GENMASK(7, 0);
@@ -698,16 +673,16 @@ static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave,
	command |= rol32(pec_en, MLXBF_I2C_MASTER_SEND_PEC_SHIFT);

	/* Clear status bits. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_STATUS, 0x0);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_STATUS);
	/* Set the cause data. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_CAUSE_OR_CLEAR, ~0x0);
	writel(~0x0, priv->smbus->io + MLXBF_I2C_CAUSE_OR_CLEAR);
	/* Zero PEC byte. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_PEC, 0x0);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_PEC);
	/* Zero byte count. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_RS_BYTES, 0x0);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_RS_BYTES);

	/* GW activation. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW, command);
	writel(command, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW);

	/*
	 * Poll master status and check status bits. An ACK is sent when
@@ -823,8 +798,8 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
		 * needs to be 'manually' reset. This should be removed in
		 * next tag integration.
		 */
		mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_FSM,
				MLXBF_I2C_SMBUS_MASTER_FSM_PS_STATE_MASK);
		writel(MLXBF_I2C_SMBUS_MASTER_FSM_PS_STATE_MASK,
			priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM);
	}

	return ret;
@@ -1113,8 +1088,8 @@ static void mlxbf_i2c_set_timings(struct mlxbf_i2c_priv *priv,
	timer |= mlxbf_i2c_set_timer(priv, timings->scl_low,
				     false, MLXBF_I2C_MASK_16,
				     MLXBF_I2C_SHIFT_16);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_TIMER_SCL_LOW_SCL_HIGH,
			  timer);
	writel(timer, priv->smbus->io +
		MLXBF_I2C_SMBUS_TIMER_SCL_LOW_SCL_HIGH);

	timer = mlxbf_i2c_set_timer(priv, timings->sda_rise, false,
				    MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_0);
@@ -1124,37 +1099,34 @@ static void mlxbf_i2c_set_timings(struct mlxbf_i2c_priv *priv,
				     MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_16);
	timer |= mlxbf_i2c_set_timer(priv, timings->scl_fall, false,
				     MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_24);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_TIMER_FALL_RISE_SPIKE,
			  timer);
	writel(timer, priv->smbus->io +
		MLXBF_I2C_SMBUS_TIMER_FALL_RISE_SPIKE);

	timer = mlxbf_i2c_set_timer(priv, timings->hold_start, true,
				    MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0);
	timer |= mlxbf_i2c_set_timer(priv, timings->hold_data, true,
				     MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_TIMER_THOLD, timer);
	writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_TIMER_THOLD);

	timer = mlxbf_i2c_set_timer(priv, timings->setup_start, true,
				    MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0);
	timer |= mlxbf_i2c_set_timer(priv, timings->setup_stop, true,
				     MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16);
	mlxbf_i2c_write(priv->smbus->io,
			MLXBF_I2C_SMBUS_TIMER_TSETUP_START_STOP, timer);
	writel(timer, priv->smbus->io +
		MLXBF_I2C_SMBUS_TIMER_TSETUP_START_STOP);

	timer = mlxbf_i2c_set_timer(priv, timings->setup_data, true,
				    MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_TIMER_TSETUP_DATA,
			  timer);
	writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_TIMER_TSETUP_DATA);

	timer = mlxbf_i2c_set_timer(priv, timings->buf, false,
				    MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0);
	timer |= mlxbf_i2c_set_timer(priv, timings->thigh_max, false,
				     MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_THIGH_MAX_TBUF,
			timer);
	writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_THIGH_MAX_TBUF);

	timer = timings->timeout;
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SCL_LOW_TIMEOUT,
			timer);
	writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_SCL_LOW_TIMEOUT);
}

enum mlxbf_i2c_timings_config {
@@ -1426,19 +1398,15 @@ static int mlxbf_i2c_init_master(struct platform_device *pdev,
	 * platform firmware; disabling the bus might compromise the system
	 * functionality.
	 */
	config_reg = mlxbf_i2c_read(gpio_res->io,
				    MLXBF_I2C_GPIO_0_FUNC_EN_0);
	config_reg = readl(gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0);
	config_reg = MLXBF_I2C_GPIO_SMBUS_GW_ASSERT_PINS(priv->bus,
							 config_reg);
	mlxbf_i2c_write(gpio_res->io, MLXBF_I2C_GPIO_0_FUNC_EN_0,
			config_reg);
	writel(config_reg, gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0);

	config_reg = mlxbf_i2c_read(gpio_res->io,
				    MLXBF_I2C_GPIO_0_FORCE_OE_EN);
	config_reg = readl(gpio_res->io + MLXBF_I2C_GPIO_0_FORCE_OE_EN);
	config_reg = MLXBF_I2C_GPIO_SMBUS_GW_RESET_PINS(priv->bus,
							config_reg);
	mlxbf_i2c_write(gpio_res->io, MLXBF_I2C_GPIO_0_FORCE_OE_EN,
			config_reg);
	writel(config_reg, gpio_res->io + MLXBF_I2C_GPIO_0_FORCE_OE_EN);

	mutex_unlock(gpio_res->lock);

@@ -1452,10 +1420,9 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
	u32 corepll_val;
	u16 core_f;

	pad_frequency = MLXBF_I2C_TYU_PLL_IN_FREQ;
	pad_frequency = MLXBF_I2C_PLL_IN_FREQ;

	corepll_val = mlxbf_i2c_read(corepll_res->io,
				     MLXBF_I2C_CORE_PLL_REG1);
	corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);

	/* Get Core PLL configuration bits. */
	core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) &
@@ -1488,12 +1455,10 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
	u8 core_od, core_r;
	u32 core_f;

	pad_frequency = MLXBF_I2C_YU_PLL_IN_FREQ;
	pad_frequency = MLXBF_I2C_PLL_IN_FREQ;

	corepll_reg1_val = mlxbf_i2c_read(corepll_res->io,
					  MLXBF_I2C_CORE_PLL_REG1);
	corepll_reg2_val = mlxbf_i2c_read(corepll_res->io,
					  MLXBF_I2C_CORE_PLL_REG2);
	corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);
	corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2);

	/* Get Core PLL configuration bits */
	core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) &
@@ -1585,7 +1550,7 @@ static int mlxbf_slave_enable(struct mlxbf_i2c_priv *priv, u8 addr)
	 * (7-bit address, 1 status bit (1 if enabled, 0 if not)).
	 */
	for (reg = 0; reg < reg_cnt; reg++) {
		slave_reg = mlxbf_i2c_read(priv->smbus->io,
		slave_reg = readl(priv->smbus->io +
				MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4);
		/*
		 * Each register holds 4 slave addresses. So, we have to keep
@@ -1643,8 +1608,8 @@ static int mlxbf_slave_enable(struct mlxbf_i2c_priv *priv, u8 addr)

	/* Enable the slave address and update the register. */
	slave_reg |= (1 << MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT) << (byte * 8);
	mlxbf_i2c_write(priv->smbus->io,
			MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4, slave_reg);
	writel(slave_reg, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG +
		reg * 0x4);

	return 0;
}
@@ -1668,7 +1633,7 @@ static int mlxbf_slave_disable(struct mlxbf_i2c_priv *priv)
	 * (7-bit address, 1 status bit (1 if enabled, 0 if not)).
	 */
	for (reg = 0; reg < reg_cnt; reg++) {
		slave_reg = mlxbf_i2c_read(priv->smbus->io,
		slave_reg = readl(priv->smbus->io +
				MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4);

		/* Check whether the address slots are empty. */
@@ -1708,8 +1673,8 @@ static int mlxbf_slave_disable(struct mlxbf_i2c_priv *priv)

	/* Cleanup the slave address slot. */
	slave_reg &= ~(GENMASK(7, 0) << (slave_byte * 8));
	mlxbf_i2c_write(priv->smbus->io,
			MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4, slave_reg);
	writel(slave_reg, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG +
		reg * 0x4);

	return 0;
}
@@ -1801,7 +1766,7 @@ static int mlxbf_i2c_init_slave(struct platform_device *pdev,
	int ret;

	/* Reset FSM. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_FSM, 0);
	writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_FSM);

	/*
	 * Enable slave cause interrupt bits. Drive
@@ -1810,15 +1775,13 @@ static int mlxbf_i2c_init_slave(struct platform_device *pdev,
	 * masters issue a Read and Write, respectively. But, clear all
	 * interrupts first.
	 */
	mlxbf_i2c_write(priv->slv_cause->io,
			  MLXBF_I2C_CAUSE_OR_CLEAR, ~0);
	writel(~0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR);
	int_reg = MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE;
	int_reg |= MLXBF_I2C_CAUSE_WRITE_SUCCESS;
	mlxbf_i2c_write(priv->slv_cause->io,
			  MLXBF_I2C_CAUSE_OR_EVTEN0, int_reg);
	writel(int_reg, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_EVTEN0);

	/* Finally, set the 'ready' bit to start handling transactions. */
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_READY, 0x1);
	writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY);

	/* Initialize the cause coalesce resource. */
	ret = mlxbf_i2c_init_coalesce(pdev, priv);
@@ -1844,23 +1807,21 @@ static bool mlxbf_i2c_has_coalesce(struct mlxbf_i2c_priv *priv, bool *read,
				MLXBF_I2C_CAUSE_YU_SLAVE_BIT :
				priv->bus + MLXBF_I2C_CAUSE_TYU_SLAVE_BIT;

	coalesce0_reg = mlxbf_i2c_read(priv->coalesce->io,
				       MLXBF_I2C_CAUSE_COALESCE_0);
	coalesce0_reg = readl(priv->coalesce->io + MLXBF_I2C_CAUSE_COALESCE_0);
	is_set = coalesce0_reg & (1 << slave_shift);

	if (!is_set)
		return false;

	/* Check the source of the interrupt, i.e. whether a Read or Write. */
	cause_reg = mlxbf_i2c_read(priv->slv_cause->io,
				     MLXBF_I2C_CAUSE_ARBITER);
	cause_reg = readl(priv->slv_cause->io + MLXBF_I2C_CAUSE_ARBITER);
	if (cause_reg & MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE)
		*read = true;
	else if (cause_reg & MLXBF_I2C_CAUSE_WRITE_SUCCESS)
		*write = true;

	/* Clear cause bits. */
	mlxbf_i2c_write(priv->slv_cause->io, MLXBF_I2C_CAUSE_OR_CLEAR, ~0x0);
	writel(~0x0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR);

	return true;
}
@@ -1900,7 +1861,7 @@ static int mlxbf_smbus_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
	 * address, if supplied.
	 */
	if (recv_bytes > 0) {
		data32 = mlxbf_i2c_read_data(priv->smbus->io,
		data32 = ioread32be(priv->smbus->io +
					MLXBF_I2C_SLAVE_DATA_DESC_ADDR);

		/* Parse the received bytes. */
@@ -1966,7 +1927,7 @@ static int mlxbf_smbus_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
	control32 |= rol32(write_size, MLXBF_I2C_SLAVE_WRITE_BYTES_SHIFT);
	control32 |= rol32(pec_en, MLXBF_I2C_SLAVE_SEND_PEC_SHIFT);

	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_GW, control32);
	writel(control32, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_GW);

	/*
	 * Wait until the transfer is completed; the driver will wait
@@ -1975,10 +1936,9 @@ static int mlxbf_smbus_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
	mlxbf_smbus_slave_wait_for_idle(priv, MLXBF_I2C_SMBUS_TIMEOUT);

	/* Release the Slave GW. */
	mlxbf_i2c_write(priv->smbus->io,
			MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES, 0x0);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_PEC, 0x0);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_READY, 0x1);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_PEC);
	writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY);

	return 0;
}
@@ -2023,10 +1983,9 @@ static int mlxbf_smbus_irq_recv(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
	i2c_slave_event(slave, I2C_SLAVE_STOP, &value);

	/* Release the Slave GW. */
	mlxbf_i2c_write(priv->smbus->io,
			MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES, 0x0);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_PEC, 0x0);
	mlxbf_i2c_write(priv->smbus->io, MLXBF_I2C_SMBUS_SLAVE_READY, 0x1);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES);
	writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_PEC);
	writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY);

	return ret;
}
@@ -2061,7 +2020,7 @@ static irqreturn_t mlxbf_smbus_irq(int irq, void *ptr)
	 * slave, if the higher 8 bits are sent then the slave expect N bytes
	 * from the master.
	 */
	rw_bytes_reg = mlxbf_i2c_read(priv->smbus->io,
	rw_bytes_reg = readl(priv->smbus->io +
				MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES);
	recv_bytes = (rw_bytes_reg >> 8) & GENMASK(7, 0);

@@ -2264,6 +2223,7 @@ static const struct of_device_id mlxbf_i2c_dt_ids[] = {

MODULE_DEVICE_TABLE(of, mlxbf_i2c_dt_ids);

#ifdef CONFIG_ACPI
static const struct acpi_device_id mlxbf_i2c_acpi_ids[] = {
	{ "MLNXBF03", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_1] },
	{ "MLNXBF23", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_2] },
@@ -2305,6 +2265,12 @@ static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)

	return ret;
}
#else
static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
{
	return -ENOENT;
}
#endif /* CONFIG_ACPI */

static int mlxbf_i2c_of_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
{
@@ -2473,7 +2439,9 @@ static struct platform_driver mlxbf_i2c_driver = {
	.driver = {
		.name = "i2c-mlxbf",
		.of_match_table = mlxbf_i2c_dt_ids,
#ifdef CONFIG_ACPI
		.acpi_match_table = ACPI_PTR(mlxbf_i2c_acpi_ids),
#endif /* CONFIG_ACPI  */
	},
};

@@ -2502,5 +2470,5 @@ static void __exit mlxbf_i2c_exit(void)
module_exit(mlxbf_i2c_exit);

MODULE_DESCRIPTION("Mellanox BlueField I2C bus driver");
MODULE_AUTHOR("Khalil Blaiech <kblaiech@mellanox.com>");
MODULE_AUTHOR("Khalil Blaiech <kblaiech@nvidia.com>");
MODULE_LICENSE("GPL v2");
+4 −4
Original line number Diff line number Diff line
@@ -475,6 +475,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
{
	u16 control_reg;

	writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
	udelay(50);
	writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);

	mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET);

	/* Set ioconfig */
@@ -529,10 +533,6 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)

	mtk_i2c_writew(i2c, control_reg, OFFSET_CONTROL);
	mtk_i2c_writew(i2c, I2C_DELAY_LEN, OFFSET_DELAY_LEN);

	writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
	udelay(50);
	writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
}

static const struct i2c_spec_values *mtk_i2c_get_spec(unsigned int speed)
Loading