Skip to content

Commit 8b51a8e

Browse files
Shubhrajyoti Dattawsakernel
authored andcommitted
i2c: cadence: Implement save restore
The zynqmp platform now supports chip-off so the registers can lose context. Implement save restore for i2c module. Since we have only a couple of registers an unconditional restore is done. Acked-by: Michal Simek <[email protected]> Signed-off-by: Shubhrajyoti Datta <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 661e8a8 commit 8b51a8e

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

drivers/i2c/busses/i2c-cadence.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ enum cdns_i2c_slave_state {
178178
* @clk: Pointer to struct clk
179179
* @clk_rate_change_nb: Notifier block for clock rate changes
180180
* @quirks: flag for broken hold bit usage in r1p10
181+
* @ctrl_reg: Cached value of the control register.
181182
* @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register
182183
* @slave: Registered slave instance.
183184
* @dev_mode: I2C operating role(master/slave).
@@ -202,6 +203,7 @@ struct cdns_i2c {
202203
struct clk *clk;
203204
struct notifier_block clk_rate_change_nb;
204205
u32 quirks;
206+
u32 ctrl_reg;
205207
#if IS_ENABLED(CONFIG_I2C_SLAVE)
206208
u16 ctrl_reg_diva_divb;
207209
struct i2c_client *slave;
@@ -1071,10 +1073,11 @@ static int cdns_i2c_setclk(unsigned long clk_in, struct cdns_i2c *id)
10711073
if (ret)
10721074
return ret;
10731075

1074-
ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
1076+
ctrl_reg = id->ctrl_reg;
10751077
ctrl_reg &= ~(CDNS_I2C_CR_DIVA_MASK | CDNS_I2C_CR_DIVB_MASK);
10761078
ctrl_reg |= ((div_a << CDNS_I2C_CR_DIVA_SHIFT) |
10771079
(div_b << CDNS_I2C_CR_DIVB_SHIFT));
1080+
id->ctrl_reg = ctrl_reg;
10781081
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
10791082
#if IS_ENABLED(CONFIG_I2C_SLAVE)
10801083
id->ctrl_reg_diva_divb = ctrl_reg & (CDNS_I2C_CR_DIVA_MASK |
@@ -1162,6 +1165,26 @@ static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev)
11621165
return 0;
11631166
}
11641167

1168+
/**
1169+
* cdns_i2c_init - Controller initialisation
1170+
* @id: Device private data structure
1171+
*
1172+
* Initialise the i2c controller.
1173+
*
1174+
*/
1175+
static void cdns_i2c_init(struct cdns_i2c *id)
1176+
{
1177+
cdns_i2c_writereg(id->ctrl_reg, CDNS_I2C_CR_OFFSET);
1178+
/*
1179+
* Cadence I2C controller has a bug wherein it generates
1180+
* invalid read transaction after HW timeout in master receiver mode.
1181+
* HW timeout is not used by this driver and the interrupt is disabled.
1182+
* But the feature itself cannot be disabled. Hence maximum value
1183+
* is written to this register to reduce the chances of error.
1184+
*/
1185+
cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET);
1186+
}
1187+
11651188
/**
11661189
* cdns_i2c_runtime_resume - Runtime resume
11671190
* @dev: Address of the platform_device structure
@@ -1180,6 +1203,7 @@ static int __maybe_unused cdns_i2c_runtime_resume(struct device *dev)
11801203
dev_err(dev, "Cannot enable clock.\n");
11811204
return ret;
11821205
}
1206+
cdns_i2c_init(xi2c);
11831207

11841208
return 0;
11851209
}
@@ -1279,7 +1303,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
12791303
id->dev_mode = CDNS_I2C_MODE_MASTER;
12801304
id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
12811305
#endif
1282-
cdns_i2c_writereg(CDNS_I2C_CR_MASTER_EN_MASK, CDNS_I2C_CR_OFFSET);
1306+
id->ctrl_reg = CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS;
12831307

12841308
ret = cdns_i2c_setclk(id->input_clk, id);
12851309
if (ret) {
@@ -1294,15 +1318,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
12941318
dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
12951319
goto err_clk_dis;
12961320
}
1297-
1298-
/*
1299-
* Cadence I2C controller has a bug wherein it generates
1300-
* invalid read transaction after HW timeout in master receiver mode.
1301-
* HW timeout is not used by this driver and the interrupt is disabled.
1302-
* But the feature itself cannot be disabled. Hence maximum value
1303-
* is written to this register to reduce the chances of error.
1304-
*/
1305-
cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET);
1321+
cdns_i2c_init(id);
13061322

13071323
ret = i2c_add_adapter(&id->adap);
13081324
if (ret < 0)

0 commit comments

Comments
 (0)