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

Pull i2c updates from Wolfram Sang:
 "Mostly DT bindings additions this time because Andi was super busy and
  I also could only partly cover it.

   - new ids for qcom-cci, mt65xx, exynos5, apple, tegra20, k1, i801

   - drop support for already removed S3C2410

   - introduce and use fwnode_for_each_child_node_scoped()

   - mmt65xx: improve write-then-read transactions

   - k1: various fixes around bus errors and resets

   - usual share of cleanups, minor improvements, PM fixes...

  at24 updates:

   - add the compatible for Giantec GT24C256C to the device-tree
     bindings"

* tag 'i2c-for-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (33 commits)
  i2c: i801: Add support for Intel Wildcat Lake-U
  dt-bindings: i2c: i2c-mt65xx: Add MediaTek MT8196/6991 compatibles
  i2c: designware: Add disabling clocks when probe fails
  i2c: designware: Fix clock issue when PM is disabled
  i2c: busses: Fix some spelling errors
  i2c: mux: Simplify boolean assignment in i2c_mux_alloc
  i2c: designware: use dev_err_probe() when probing platform device
  i2c: designware: convert to dev_err_probe() on request IRQ error
  i2c: spacemit: ensure SDA is released after bus reset
  i2c: spacemit: check SDA instead of SCL after bus reset
  i2c: spacemit: disable SDA glitch fix to avoid restart delay
  i2c: spacemit: remove stop function to avoid bus error
  i2c: spacemit: ensure bus release check runs when wait_bus_idle() fails
  i2c: mediatek: fix potential incorrect use of I2C_MASTER_WRRD
  i2c: boardinfo: Annotate code used in init phase only
  dt-bindings: i2c: i2c-mt65xx: Document MediaTek MT6878 I2C
  dt-bindings: i2c: samsung,s3c2410-i2c: Drop S3C2410
  i2c: s3c2410: Drop S3C2410 OF support
  dt-bindings: i2c: spacemit,k1-i2c: Minor whitespace cleanup in example
  dt-bindings: i2c: exynos5: add samsung,exynos8890-hsi2c compatible
  ...
This commit is contained in:
Linus Torvalds
2025-10-01 15:11:00 -07:00
30 changed files with 218 additions and 115 deletions
@@ -143,6 +143,7 @@ properties:
- const: atmel,24c128
- items:
- enum:
- giantec,gt24c256c
- puya,p24c256c
- const: atmel,24c256
- items:
@@ -20,17 +20,22 @@ allOf:
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
- const: apple,i2c
oneOf:
- items:
- const: apple,t6020-i2c
- const: apple,t8103-i2c
- items:
- enum:
# Do not add additional SoC to this list.
- apple,s5l8960x-i2c
- apple,t7000-i2c
- apple,s8000-i2c
- apple,t8010-i2c
- apple,t8015-i2c
- apple,t8103-i2c
- apple,t8112-i2c
- apple,t6000-i2c
- const: apple,i2c
reg:
maxItems: 1
@@ -33,11 +33,16 @@ properties:
- samsung,exynos7870-hsi2c
- tesla,fsd-hsi2c
- const: samsung,exynos7-hsi2c
- items:
- enum:
- samsung,exynos8890-hsi2c
- const: samsung,exynos8895-hsi2c
- items:
- enum:
- google,gs101-hsi2c
- samsung,exynos2200-hsi2c
- samsung,exynos850-hsi2c
- samsung,exynos990-hsi2c
- const: samsung,exynosautov9-hsi2c
- const: samsung,exynos5-hsi2c # Exynos5250 and Exynos5420
deprecated: true
@@ -50,6 +50,12 @@ properties:
- enum:
- mediatek,mt6795-i2c
- const: mediatek,mt8173-i2c
- items:
- enum:
- mediatek,mt6878-i2c
- mediatek,mt6991-i2c
- mediatek,mt8196-i2c
- const: mediatek,mt8188-i2c
- items:
- enum:
- mediatek,mt6893-i2c
@@ -80,6 +80,11 @@ properties:
support for 64 KiB transactions whereas earlier chips supported no
more than 4 KiB per transactions.
const: nvidia,tegra194-i2c
- description: |
Tegra256 has 8 generic I2C controllers. The controllers are similar to
the previous generations, but have a different parent clock and hence
the timing parameters are configured differently.
const: nvidia,tegra256-i2c
reg:
maxItems: 1
@@ -186,6 +191,7 @@ allOf:
contains:
enum:
- nvidia,tegra194-i2c
- nvidia,tegra256-i2c
then:
required:
- resets
@@ -25,6 +25,8 @@ properties:
- items:
- enum:
- qcom,qcm2290-cci
- qcom,sa8775p-cci
- qcom,sc7280-cci
- qcom,sc8280xp-cci
- qcom,sdm670-cci
@@ -44,11 +46,11 @@ properties:
const: 0
clocks:
minItems: 3
minItems: 2
maxItems: 6
clock-names:
minItems: 3
minItems: 2
maxItems: 6
interrupts:
@@ -113,6 +115,7 @@ allOf:
then:
properties:
clocks:
minItems: 3
maxItems: 3
clock-names:
items:
@@ -120,6 +123,22 @@ allOf:
- const: cci_ahb
- const: cci
- if:
properties:
compatible:
contains:
enum:
- qcom,qcm2290-cci
then:
properties:
clocks:
minItems: 2
maxItems: 2
clock-names:
items:
- const: ahb
- const: cci
- if:
properties:
compatible:
@@ -223,6 +242,7 @@ allOf:
compatible:
contains:
enum:
- qcom,sa8775p-cci
- qcom,sm8550-cci
- qcom,sm8650-cci
- qcom,x1e80100-cci
@@ -13,7 +13,6 @@ properties:
compatible:
oneOf:
- enum:
- samsung,s3c2410-i2c
- samsung,s3c2440-i2c
# For s3c2440-like I2C used inside HDMIPHY block found on several SoCs:
- samsung,s3c2440-hdmiphy-i2c
@@ -93,7 +92,6 @@ allOf:
compatible:
contains:
enum:
- samsung,s3c2410-i2c
- samsung,s3c2440-i2c
- samsung,s3c2440-hdmiphy-i2c
then:
@@ -56,7 +56,7 @@ examples:
reg = <0xd4010800 0x38>;
interrupt-parent = <&plic>;
interrupts = <36>;
clocks =<&ccu 32>, <&ccu 84>;
clocks = <&ccu 32>, <&ccu 84>;
clock-names = "func", "bus";
clock-frequency = <100000>;
};
+1
View File
@@ -50,6 +50,7 @@ Supported adapters:
* Intel Birch Stream (SOC)
* Intel Arrow Lake (SOC)
* Intel Panther Lake (SOC)
* Intel Wildcat Lake (SOC)
Datasheets: Publicly available at the Intel website
+1
View File
@@ -165,6 +165,7 @@ config I2C_I801
Birch Stream (SOC)
Arrow Lake (SOC)
Panther Lake (SOC)
Wildcat Lake (SOC)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
+4 -5
View File
@@ -1068,11 +1068,10 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
if (!(dev->flags & ACCESS_POLLING)) {
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr,
irq_flags, dev_name(dev->dev), dev);
if (ret) {
dev_err(dev->dev, "failure requesting irq %i: %d\n",
dev->irq, ret);
return ret;
}
if (ret)
return dev_err_probe(dev->dev, ret,
"failure requesting irq %i: %d\n",
dev->irq, ret);
}
ret = i2c_dw_init_recovery_info(dev);
+10 -5
View File
@@ -238,7 +238,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
dev->rst = devm_reset_control_get_optional_exclusive(device, NULL);
if (IS_ERR(dev->rst))
return PTR_ERR(dev->rst);
return dev_err_probe(device, PTR_ERR(dev->rst), "failed to acquire reset\n");
reset_control_deassert(dev->rst);
@@ -247,21 +247,23 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
goto exit_reset;
ret = i2c_dw_probe_lock_support(dev);
if (ret)
if (ret) {
ret = dev_err_probe(device, ret, "failed to probe lock support\n");
goto exit_reset;
}
i2c_dw_configure(dev);
/* Optional interface clock */
dev->pclk = devm_clk_get_optional(device, "pclk");
if (IS_ERR(dev->pclk)) {
ret = PTR_ERR(dev->pclk);
ret = dev_err_probe(device, PTR_ERR(dev->pclk), "failed to acquire pclk\n");
goto exit_reset;
}
dev->clk = devm_clk_get_optional(device, NULL);
if (IS_ERR(dev->clk)) {
ret = PTR_ERR(dev->clk);
ret = dev_err_probe(device, PTR_ERR(dev->clk), "failed to acquire clock\n");
goto exit_reset;
}
@@ -314,6 +316,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
exit_probe:
dw_i2c_plat_pm_cleanup(dev);
i2c_dw_prepare_clk(dev, false);
exit_reset:
reset_control_assert(dev->rst);
return ret;
@@ -331,9 +334,11 @@ static void dw_i2c_plat_remove(struct platform_device *pdev)
i2c_dw_disable(dev);
pm_runtime_dont_use_autosuspend(device);
pm_runtime_put_sync(device);
pm_runtime_put_noidle(device);
dw_i2c_plat_pm_cleanup(dev);
i2c_dw_prepare_clk(dev, false);
i2c_dw_remove_lock_support(dev);
reset_control_assert(dev->rst);
+4 -5
View File
@@ -266,11 +266,10 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr_slave,
IRQF_SHARED, dev_name(dev->dev), dev);
if (ret) {
dev_err(dev->dev, "failure requesting IRQ %i: %d\n",
dev->irq, ret);
return ret;
}
if (ret)
return dev_err_probe(dev->dev, ret,
"failure requesting IRQ %i: %d\n",
dev->irq, ret);
ret = i2c_add_numbered_adapter(adap);
if (ret)
+1 -1
View File
@@ -339,7 +339,7 @@ static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
ret = priv->state;
/*
* If this is the last message to be transfered (stop == 1)
* If this is the last message to be transferred (stop == 1)
* Then check if the bus can be brought back to idle.
*/
if (priv->state == HIX5I2C_STAT_RW_SUCCESS && stop)
+3
View File
@@ -83,6 +83,7 @@
* Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes
* Panther Lake-H (SOC) 0xe322 32 hard yes yes yes
* Panther Lake-P (SOC) 0xe422 32 hard yes yes yes
* Wildcat Lake-U (SOC) 0x4d22 32 hard yes yes yes
*
* Features supported by this driver:
* Software PEC no
@@ -236,6 +237,7 @@
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3
#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23
#define PCI_DEVICE_ID_INTEL_WILDCAT_LAKE_U_SMBUS 0x4d22
#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3
@@ -1056,6 +1058,7 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, WILDCAT_LAKE_U_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ 0, }
};
+45 -26
View File
@@ -3,6 +3,7 @@
* Copyright (C) 2024-2025 Troy Mitchell <troymitchell988@gmail.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/iopoll.h>
@@ -14,6 +15,7 @@
#define SPACEMIT_ICR 0x0 /* Control register */
#define SPACEMIT_ISR 0x4 /* Status register */
#define SPACEMIT_IDBR 0xc /* Data buffer register */
#define SPACEMIT_IRCR 0x18 /* Reset cycle counter */
#define SPACEMIT_IBMR 0x1c /* Bus monitor register */
/* SPACEMIT_ICR register fields */
@@ -25,7 +27,8 @@
#define SPACEMIT_CR_MODE_FAST BIT(8) /* bus mode (master operation) */
/* Bit 9 is reserved */
#define SPACEMIT_CR_UR BIT(10) /* unit reset */
/* Bits 11-12 are reserved */
#define SPACEMIT_CR_RSTREQ BIT(11) /* i2c bus reset request */
/* Bit 12 is reserved */
#define SPACEMIT_CR_SCLE BIT(13) /* master clock enable */
#define SPACEMIT_CR_IUE BIT(14) /* unit enable */
/* Bits 15-17 are reserved */
@@ -76,6 +79,10 @@
SPACEMIT_SR_GCAD | SPACEMIT_SR_IRF | SPACEMIT_SR_ITE | \
SPACEMIT_SR_ALD)
#define SPACEMIT_RCR_SDA_GLITCH_NOFIX BIT(7) /* bypass the SDA glitch fix */
/* the cycles of SCL during bus reset */
#define SPACEMIT_RCR_FIELD_RST_CYC GENMASK(3, 0)
/* SPACEMIT_IBMR register fields */
#define SPACEMIT_BMR_SDA BIT(0) /* SDA line level */
#define SPACEMIT_BMR_SCL BIT(1) /* SCL line level */
@@ -88,6 +95,8 @@
#define SPACEMIT_SR_ERR (SPACEMIT_SR_BED | SPACEMIT_SR_RXOV | SPACEMIT_SR_ALD)
#define SPACEMIT_BUS_RESET_CLK_CNT_MAX 9
enum spacemit_i2c_state {
SPACEMIT_STATE_IDLE,
SPACEMIT_STATE_START,
@@ -160,6 +169,7 @@ static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
{
u32 status;
u8 clk_cnt;
/* if bus is locked, reset unit. 0: locked */
status = readl(i2c->base + SPACEMIT_IBMR);
@@ -169,9 +179,21 @@ static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
spacemit_i2c_reset(i2c);
usleep_range(10, 20);
/* check scl status again */
for (clk_cnt = 0; clk_cnt < SPACEMIT_BUS_RESET_CLK_CNT_MAX; clk_cnt++) {
status = readl(i2c->base + SPACEMIT_IBMR);
if (status & SPACEMIT_BMR_SDA)
return;
/* There's nothing left to save here, we are about to exit */
writel(FIELD_PREP(SPACEMIT_RCR_FIELD_RST_CYC, 1),
i2c->base + SPACEMIT_IRCR);
writel(SPACEMIT_CR_RSTREQ, i2c->base + SPACEMIT_ICR);
usleep_range(20, 30);
}
/* check sda again here */
status = readl(i2c->base + SPACEMIT_IBMR);
if (!(status & SPACEMIT_BMR_SCL))
if (!(status & SPACEMIT_BMR_SDA))
dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
}
@@ -237,6 +259,14 @@ static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
val |= SPACEMIT_CR_MSDE | SPACEMIT_CR_MSDIE;
writel(val, i2c->base + SPACEMIT_ICR);
/*
* The glitch fix in the K1 I2C controller introduces a delay
* on restart signals, so we disable the fix here.
*/
val = readl(i2c->base + SPACEMIT_IRCR);
val |= SPACEMIT_RCR_SDA_GLITCH_NOFIX;
writel(val, i2c->base + SPACEMIT_IRCR);
}
static inline void
@@ -267,19 +297,6 @@ static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
writel(val, i2c->base + SPACEMIT_ICR);
}
static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
{
u32 val;
val = readl(i2c->base + SPACEMIT_ICR);
val |= SPACEMIT_CR_STOP | SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
if (i2c->read)
val |= SPACEMIT_CR_ACKNAK;
writel(val, i2c->base + SPACEMIT_ICR);
}
static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
{
unsigned long time_left;
@@ -412,7 +429,6 @@ static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
val = readl(i2c->base + SPACEMIT_ICR);
val &= ~(SPACEMIT_CR_TB | SPACEMIT_CR_ACKNAK | SPACEMIT_CR_STOP | SPACEMIT_CR_START);
writel(val, i2c->base + SPACEMIT_ICR);
switch (i2c->state) {
case SPACEMIT_STATE_START:
@@ -429,14 +445,16 @@ static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
}
if (i2c->state != SPACEMIT_STATE_IDLE) {
val |= SPACEMIT_CR_TB | SPACEMIT_CR_ALDIE;
if (spacemit_i2c_is_last_msg(i2c)) {
/* trigger next byte with stop */
spacemit_i2c_stop(i2c);
} else {
/* trigger next byte */
val |= SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
writel(val, i2c->base + SPACEMIT_ICR);
val |= SPACEMIT_CR_STOP;
if (i2c->read)
val |= SPACEMIT_CR_ACKNAK;
}
writel(val, i2c->base + SPACEMIT_ICR);
}
err_out:
@@ -476,12 +494,13 @@ static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg *msgs, in
spacemit_i2c_enable(i2c);
ret = spacemit_i2c_wait_bus_idle(i2c);
if (!ret)
if (!ret) {
ret = spacemit_i2c_xfer_msg(i2c);
else if (ret < 0)
dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
else
if (ret < 0)
dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
} else {
spacemit_i2c_check_bus_release(i2c);
}
spacemit_i2c_disable(i2c);
+10 -7
View File
@@ -1243,6 +1243,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
{
int ret;
int left_num = num;
bool write_then_read_en = false;
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
@@ -1256,6 +1257,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
msgs[0].addr == msgs[1].addr) {
i2c->auto_restart = 0;
write_then_read_en = true;
}
}
@@ -1280,12 +1282,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
else
i2c->op = I2C_MASTER_WR;
if (!i2c->auto_restart) {
if (num > 1) {
/* combined two messages into one transaction */
i2c->op = I2C_MASTER_WRRD;
left_num--;
}
if (write_then_read_en) {
/* combined two messages into one transaction */
i2c->op = I2C_MASTER_WRRD;
left_num--;
}
/* always use DMA mode. */
@@ -1293,7 +1293,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
if (ret < 0)
goto err_exit;
msgs++;
if (i2c->op == I2C_MASTER_WRRD)
msgs += 2;
else
msgs++;
}
/* the return value is number of executed messages */
ret = num;
-1
View File
@@ -138,7 +138,6 @@ static void i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
#ifdef CONFIG_OF
static const struct of_device_id s3c24xx_i2c_match[] = {
{ .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
{ .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
{ .compatible = "samsung,s3c2440-hdmiphy-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
+1 -1
View File
@@ -425,7 +425,7 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
* If we did not get one ACK from target when writing data, then we
* should finish this transmission since we got some errors.
*
* When writing data, if i2c_tran == 0 which means we have writen
* When writing data, if i2c_tran == 0 which means we have written
* done all data, then we can finish this transmission.
*
* When reading data, if conut < rx fifo full threshold, which
+1 -1
View File
@@ -152,7 +152,7 @@ struct st_i2c_timings {
/**
* struct st_i2c_client - client specific data
* @addr: 8-bit target addr, including r/w bit
* @count: number of bytes to be transfered
* @count: number of bytes to be transferred
* @xfered: number of bytes already transferred
* @buf: data buffer
* @result: result of the transfer

Some files were not shown because too many files have changed in this diff Show More