Commit b4b215cf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "All driver fixes this time:

   - fix interrupt initialization sequence (npcm)

   - fix frequency setting (ls2x)

   - re-enable interrupts properly at irq handler's exit (amd-asf)"

* tag 'i2c-for-6.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: amd-asf: Fix EOI register write to enable successive interrupts
  i2c: ls2x: Fix frequency division register access
  i2c: npcm: disable interrupt enable bit before devm_request_irq
parents df87d843 911c288f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ static irqreturn_t amd_asf_irq_handler(int irq, void *ptr)
		amd_asf_update_ioport_target(piix4_smba, ASF_SLV_INTR, SMBHSTSTS, true);
	}

	iowrite32(irq, dev->eoi_base);
	return IRQ_HANDLED;
}

+12 −4
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
 * Rewritten for mainline by Binbin Zhou <zhoubinbin@loongson.cn>
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/completion.h>
#include <linux/device.h>
@@ -26,7 +27,8 @@
#include <linux/units.h>

/* I2C Registers */
#define I2C_LS2X_PRER		0x0 /* Freq Division Register(16 bits) */
#define I2C_LS2X_PRER_LO	0x0 /* Freq Division Low Byte Register */
#define I2C_LS2X_PRER_HI	0x1 /* Freq Division High Byte Register */
#define I2C_LS2X_CTR		0x2 /* Control Register */
#define I2C_LS2X_TXR		0x3 /* Transport Data Register */
#define I2C_LS2X_RXR		0x3 /* Receive Data Register */
@@ -93,6 +95,7 @@ static irqreturn_t ls2x_i2c_isr(int this_irq, void *dev_id)
 */
static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv)
{
	u16 val;
	struct i2c_timings *t = &priv->i2c_t;
	struct device *dev = priv->adapter.dev.parent;
	u32 acpi_speed = i2c_acpi_find_bus_speed(dev);
@@ -104,9 +107,14 @@ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv)
	else
		t->bus_freq_hz = LS2X_I2C_FREQ_STD;

	/* Calculate and set i2c frequency. */
	writew(LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1,
	       priv->base + I2C_LS2X_PRER);
	/*
	 * According to the chip manual, we can only access the registers as bytes,
	 * otherwise the high bits will be truncated.
	 * So set the I2C frequency with a sequential writeb() instead of writew().
	 */
	val = LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1;
	writeb(FIELD_GET(GENMASK(7, 0), val), priv->base + I2C_LS2X_PRER_LO);
	writeb(FIELD_GET(GENMASK(15, 8), val), priv->base + I2C_LS2X_PRER_HI);
}

static void ls2x_i2c_init(struct ls2x_i2c_priv *priv)
+7 −0
Original line number Diff line number Diff line
@@ -2554,6 +2554,13 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)
	if (irq < 0)
		return irq;

	/*
	 * Disable the interrupt to avoid the interrupt handler being triggered
	 * incorrectly by the asynchronous interrupt status since the machine
	 * might do a warm reset during the last smbus/i2c transfer session.
	 */
	npcm_i2c_int_enable(bus, false);

	ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
			       dev_name(bus->dev), bus);
	if (ret)