Skip to content

Commit 26de861

Browse files
author
Wolfram Sang
committed
Merge tag 'i2c-host-fixes-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-current
I2C host fixes for v6.12-rc1 The DesignWare driver now has the correct ENABLE-ABORT sequence, ensuring ABORT can always be sent when needed. In the SynQuacer controller we now check for PCLK as an optional clock, allowing ACPI to directly provide the clock rate. The recent KEBA driver required a dependency fix in Kconfig. The XIIC driver now has a corrected power suspend sequence.
2 parents 075dbe9 + 0c8d604 commit 26de861

File tree

6 files changed

+58
-3
lines changed

6 files changed

+58
-3
lines changed

drivers/i2c/busses/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ config I2C_JZ4780
782782
config I2C_KEBA
783783
tristate "KEBA I2C controller support"
784784
depends on HAS_IOMEM
785+
depends on KEBA_CP500 || COMPILE_TEST
785786
select AUXILIARY_BUS
786787
help
787788
This driver supports the I2C controller found in KEBA system FPGA

drivers/i2c/busses/i2c-designware-common.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
523523

524524
void __i2c_dw_disable(struct dw_i2c_dev *dev)
525525
{
526+
struct i2c_timings *t = &dev->timings;
526527
unsigned int raw_intr_stats;
527528
unsigned int enable;
528529
int timeout = 100;
@@ -535,6 +536,19 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev)
535536

536537
abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD;
537538
if (abort_needed) {
539+
if (!(enable & DW_IC_ENABLE_ENABLE)) {
540+
regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE);
541+
/*
542+
* Wait 10 times the signaling period of the highest I2C
543+
* transfer supported by the driver (for 400KHz this is
544+
* 25us) to ensure the I2C ENABLE bit is already set
545+
* as described in the DesignWare I2C databook.
546+
*/
547+
fsleep(DIV_ROUND_CLOSEST_ULL(10 * MICRO, t->bus_freq_hz));
548+
/* Set ENABLE bit before setting ABORT */
549+
enable |= DW_IC_ENABLE_ENABLE;
550+
}
551+
538552
regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT);
539553
ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable,
540554
!(enable & DW_IC_ENABLE_ABORT), 10,

drivers/i2c/busses/i2c-designware-core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
DW_IC_INTR_RX_UNDER | \
109109
DW_IC_INTR_RD_REQ)
110110

111+
#define DW_IC_ENABLE_ENABLE BIT(0)
111112
#define DW_IC_ENABLE_ABORT BIT(1)
112113

113114
#define DW_IC_STATUS_ACTIVITY BIT(0)

drivers/i2c/busses/i2c-designware-master.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,34 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
271271
__i2c_dw_write_intr_mask(dev, DW_IC_INTR_MASTER_MASK);
272272
}
273273

274+
/*
275+
* This function waits for the controller to be idle before disabling I2C
276+
* When the controller is not in the IDLE state, the MST_ACTIVITY bit
277+
* (IC_STATUS[5]) is set.
278+
*
279+
* Values:
280+
* 0x1 (ACTIVE): Controller not idle
281+
* 0x0 (IDLE): Controller is idle
282+
*
283+
* The function is called after completing the current transfer.
284+
*
285+
* Returns:
286+
* False when the controller is in the IDLE state.
287+
* True when the controller is in the ACTIVE state.
288+
*/
289+
static bool i2c_dw_is_controller_active(struct dw_i2c_dev *dev)
290+
{
291+
u32 status;
292+
293+
regmap_read(dev->map, DW_IC_STATUS, &status);
294+
if (!(status & DW_IC_STATUS_MASTER_ACTIVITY))
295+
return false;
296+
297+
return regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status,
298+
!(status & DW_IC_STATUS_MASTER_ACTIVITY),
299+
1100, 20000) != 0;
300+
}
301+
274302
static int i2c_dw_check_stopbit(struct dw_i2c_dev *dev)
275303
{
276304
u32 val;
@@ -806,6 +834,16 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
806834
goto done;
807835
}
808836

837+
/*
838+
* This happens rarely (~1:500) and is hard to reproduce. Debug trace
839+
* showed that IC_STATUS had value of 0x23 when STOP_DET occurred,
840+
* if disable IC_ENABLE.ENABLE immediately that can result in
841+
* IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if
842+
* controller is still ACTIVE before disabling I2C.
843+
*/
844+
if (i2c_dw_is_controller_active(dev))
845+
dev_err(dev->dev, "controller active\n");
846+
809847
/*
810848
* We must disable the adapter before returning and signaling the end
811849
* of the current transfer. Otherwise the hardware might continue

drivers/i2c/busses/i2c-synquacer.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
550550
device_property_read_u32(&pdev->dev, "socionext,pclk-rate",
551551
&i2c->pclkrate);
552552

553-
pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
553+
pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
554554
if (IS_ERR(pclk))
555555
return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
556556
"failed to get and enable clock\n");
557557

558-
i2c->pclkrate = clk_get_rate(pclk);
558+
if (pclk)
559+
i2c->pclkrate = clk_get_rate(pclk);
559560

560561
if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE ||
561562
i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE)

drivers/i2c/busses/i2c-xiic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,8 +1337,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)
13371337
return 0;
13381338

13391339
err_pm_disable:
1340-
pm_runtime_set_suspended(&pdev->dev);
13411340
pm_runtime_disable(&pdev->dev);
1341+
pm_runtime_set_suspended(&pdev->dev);
13421342

13431343
return ret;
13441344
}

0 commit comments

Comments
 (0)