@@ -257,6 +257,14 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
257
257
}
258
258
}
259
259
260
+ static void rcar_i2c_reset_slave (struct rcar_i2c_priv * priv )
261
+ {
262
+ rcar_i2c_write (priv , ICSIER , 0 );
263
+ rcar_i2c_write (priv , ICSSR , 0 );
264
+ rcar_i2c_write (priv , ICSCR , SDBS );
265
+ rcar_i2c_write (priv , ICSAR , 0 ); /* Gen2: must be 0 if not using slave */
266
+ }
267
+
260
268
static int rcar_i2c_bus_barrier (struct rcar_i2c_priv * priv )
261
269
{
262
270
int ret ;
@@ -875,6 +883,10 @@ static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
875
883
{
876
884
int ret ;
877
885
886
+ /* Don't reset if a slave instance is currently running */
887
+ if (priv -> slave )
888
+ return - EISCONN ;
889
+
878
890
ret = reset_control_reset (priv -> rstc );
879
891
if (ret )
880
892
return ret ;
@@ -903,10 +915,10 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
903
915
904
916
/* Gen3+ needs a reset. That also allows RXDMA once */
905
917
if (priv -> devtype >= I2C_RCAR_GEN3 ) {
906
- priv -> flags &= ~ID_P_NO_RXDMA ;
907
918
ret = rcar_i2c_do_reset (priv );
908
919
if (ret )
909
920
goto out ;
921
+ priv -> flags &= ~ID_P_NO_RXDMA ;
910
922
}
911
923
912
924
rcar_i2c_init (priv );
@@ -1033,11 +1045,8 @@ static int rcar_unreg_slave(struct i2c_client *slave)
1033
1045
1034
1046
/* ensure no irq is running before clearing ptr */
1035
1047
disable_irq (priv -> irq );
1036
- rcar_i2c_write (priv , ICSIER , 0 );
1037
- rcar_i2c_write (priv , ICSSR , 0 );
1048
+ rcar_i2c_reset_slave (priv );
1038
1049
enable_irq (priv -> irq );
1039
- rcar_i2c_write (priv , ICSCR , SDBS );
1040
- rcar_i2c_write (priv , ICSAR , 0 ); /* Gen2: must be 0 if not using slave */
1041
1050
1042
1051
priv -> slave = NULL ;
1043
1052
@@ -1152,7 +1161,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
1152
1161
goto out_pm_disable ;
1153
1162
}
1154
1163
1155
- rcar_i2c_write (priv , ICSAR , 0 ); /* Gen2: must be 0 if not using slave */
1164
+ /* Bring hardware to known state */
1165
+ rcar_i2c_init (priv );
1166
+ rcar_i2c_reset_slave (priv );
1156
1167
1157
1168
if (priv -> devtype < I2C_RCAR_GEN3 ) {
1158
1169
irqflags |= IRQF_NO_THREAD ;
@@ -1168,6 +1179,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
1168
1179
if (of_property_read_bool (dev -> of_node , "smbus" ))
1169
1180
priv -> flags |= ID_P_HOST_NOTIFY ;
1170
1181
1182
+ /* R-Car Gen3+ needs a reset before every transfer */
1171
1183
if (priv -> devtype >= I2C_RCAR_GEN3 ) {
1172
1184
priv -> rstc = devm_reset_control_get_exclusive (& pdev -> dev , NULL );
1173
1185
if (IS_ERR (priv -> rstc )) {
@@ -1178,6 +1190,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
1178
1190
ret = reset_control_status (priv -> rstc );
1179
1191
if (ret < 0 )
1180
1192
goto out_pm_put ;
1193
+
1194
+ /* hard reset disturbs HostNotify local target, so disable it */
1195
+ priv -> flags &= ~ID_P_HOST_NOTIFY ;
1181
1196
}
1182
1197
1183
1198
ret = platform_get_irq (pdev , 0 );
0 commit comments