diff mbox

[V6] i2c: imx: implement bus recovery

Message ID 1442824718-14564-1-git-send-email-b54642@freescale.com
State Changes Requested
Headers show

Commit Message

Gao Pan Sept. 21, 2015, 8:38 a.m. UTC
Implement bus recovery methods for i2c-imx so we can recover from
situations where SCL/SDA are stuck low.

Once i2c bus SCL/SDA are stuck low during transfer, config the i2c
pinctrl to gpio mode by calling pinctrl sleep set function, and then
use GPIO to emulate the i2c protocol to send nine dummy clock to recover
i2c device. After recovery, set i2c pinctrl to default group setting.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Gao Pan <b54642@freescale.com>
---
V2:
As Uwe Kleine-König's suggestion, the version do below changes:
 -replace of_get_named_gpio() with devm_gpiod_get_optional()
 -move gpio_direction_input() and gpio_direction_output() call to the
  prepare callback
 -use 0 and 1 as return value for the get_scl and get_sda callbacks

V3:
 -replace "...-gpio" with "...-gpios" in i2c binding doc
 -document the requirement of using sleep state to configure
  the pins as gpio in i2c binding doc
 -remove i2c_recover_bus() in i2c_imx_trx_complete()
 -use GPIOD_OUT_HIGH as the parameter of devm_gpiod_get_optional to
  config the gpios as output high
 -add error disposal as devm_gpiod_get_optional meets error

V4:
 -remove include <linux/of_gpio.h>
 -call i2c_recover_bus under the condition of the existing of
  both sda and scl. Drop the sda and scl check in i2c_imx_get_scl,
  i2c_imx_get_sda, i2c_imx_set_scl, i2c_imx_prepare_recovery and
  i2c_imx_prepare_recovery
 -use GPIOD_OUT_IN as the parameter of devm_gpiod_get_optional
 -remove documenting the requirement of using sleep state to configure
  the pins as gpio in i2c binding doc

V5:
 -introduce a dedicated gpio state for bus recovery.
 -assign adapter.bus_recovery_info after the two gpios were aquired successfully.

V6:
 -assign adapter.bus_recovery_info under the condition that gpios are acquired successfully
 -not try the recovery when pinctrl_lookup_state returns an error

 Documentation/devicetree/bindings/i2c/i2c-imx.txt |   9 ++
 drivers/i2c/busses/i2c-imx.c                      | 124 ++++++++++++++++++++--
 2 files changed, 126 insertions(+), 7 deletions(-)

Comments

Gao Pandy Sept. 25, 2015, 9:29 a.m. UTC | #1
UGluZy4uLg0KRnJvbTogR2FvIFBhbiA8bWFpbHRvOmI1NDY0MkBmcmVlc2NhbGUuY29tPiBTZW50
OiBNb25kYXksIFNlcHRlbWJlciAyMSwgMjAxNSA0OjM5IFBNDQo+IFRvOiB3c2FAdGhlLWRyZWFt
cy5kZTsgdS5rbGVpbmUta29lbmlnQHBlbmd1dHJvbml4LmRlDQo+IENjOiBsaW51eC1pMmNAdmdl
ci5rZXJuZWwub3JnOyBMaSBGcmFuay1CMjA1OTY7IER1YW4gRnVnYW5nLUIzODYxMTsgR2FvDQo+
IFBhbi1CNTQ2NDI7IGtlcm5lbEBwZW5ndXRyb25peC5kZTsgaGthbGx3ZWl0MUBnbWFpbC5jb20N
Cj4gU3ViamVjdDogW1BhdGNoIFY2XSBpMmM6IGlteDogaW1wbGVtZW50IGJ1cyByZWNvdmVyeQ0K
PiANCj4gSW1wbGVtZW50IGJ1cyByZWNvdmVyeSBtZXRob2RzIGZvciBpMmMtaW14IHNvIHdlIGNh
biByZWNvdmVyIGZyb20NCj4gc2l0dWF0aW9ucyB3aGVyZSBTQ0wvU0RBIGFyZSBzdHVjayBsb3cu
DQo+IA0KPiBPbmNlIGkyYyBidXMgU0NML1NEQSBhcmUgc3R1Y2sgbG93IGR1cmluZyB0cmFuc2Zl
ciwgY29uZmlnIHRoZSBpMmMNCj4gcGluY3RybCB0byBncGlvIG1vZGUgYnkgY2FsbGluZyBwaW5j
dHJsIHNsZWVwIHNldCBmdW5jdGlvbiwgYW5kIHRoZW4gdXNlDQo+IEdQSU8gdG8gZW11bGF0ZSB0
aGUgaTJjIHByb3RvY29sIHRvIHNlbmQgbmluZSBkdW1teSBjbG9jayB0byByZWNvdmVyIGkyYw0K
PiBkZXZpY2UuIEFmdGVyIHJlY292ZXJ5LCBzZXQgaTJjIHBpbmN0cmwgdG8gZGVmYXVsdCBncm91
cCBzZXR0aW5nLg0KPiANCj4gU2lnbmVkLW9mZi1ieTogRnVnYW5nIER1YW4gPEIzODYxMUBmcmVl
c2NhbGUuY29tPg0KPiBTaWduZWQtb2ZmLWJ5OiBHYW8gUGFuIDxiNTQ2NDJAZnJlZXNjYWxlLmNv
bT4NCj4gLS0tDQo+IFYyOg0KPiBBcyBVd2UgS2xlaW5lLUvDtm5pZydzIHN1Z2dlc3Rpb24sIHRo
ZSB2ZXJzaW9uIGRvIGJlbG93IGNoYW5nZXM6DQo+ICAtcmVwbGFjZSBvZl9nZXRfbmFtZWRfZ3Bp
bygpIHdpdGggZGV2bV9ncGlvZF9nZXRfb3B0aW9uYWwoKSAgLW1vdmUNCj4gZ3Bpb19kaXJlY3Rp
b25faW5wdXQoKSBhbmQgZ3Bpb19kaXJlY3Rpb25fb3V0cHV0KCkgY2FsbCB0byB0aGUNCj4gICBw
cmVwYXJlIGNhbGxiYWNrDQo+ICAtdXNlIDAgYW5kIDEgYXMgcmV0dXJuIHZhbHVlIGZvciB0aGUg
Z2V0X3NjbCBhbmQgZ2V0X3NkYSBjYWxsYmFja3MNCj4gDQo+IFYzOg0KPiAgLXJlcGxhY2UgIi4u
Li1ncGlvIiB3aXRoICIuLi4tZ3Bpb3MiIGluIGkyYyBiaW5kaW5nIGRvYyAgLWRvY3VtZW50IHRo
ZQ0KPiByZXF1aXJlbWVudCBvZiB1c2luZyBzbGVlcCBzdGF0ZSB0byBjb25maWd1cmUNCj4gICB0
aGUgcGlucyBhcyBncGlvIGluIGkyYyBiaW5kaW5nIGRvYw0KPiAgLXJlbW92ZSBpMmNfcmVjb3Zl
cl9idXMoKSBpbiBpMmNfaW14X3RyeF9jb21wbGV0ZSgpICAtdXNlIEdQSU9EX09VVF9ISUdIDQo+
IGFzIHRoZSBwYXJhbWV0ZXIgb2YgZGV2bV9ncGlvZF9nZXRfb3B0aW9uYWwgdG8NCj4gICBjb25m
aWcgdGhlIGdwaW9zIGFzIG91dHB1dCBoaWdoDQo+ICAtYWRkIGVycm9yIGRpc3Bvc2FsIGFzIGRl
dm1fZ3Bpb2RfZ2V0X29wdGlvbmFsIG1lZXRzIGVycm9yDQo+IA0KPiBWNDoNCj4gIC1yZW1vdmUg
aW5jbHVkZSA8bGludXgvb2ZfZ3Bpby5oPg0KPiAgLWNhbGwgaTJjX3JlY292ZXJfYnVzIHVuZGVy
IHRoZSBjb25kaXRpb24gb2YgdGhlIGV4aXN0aW5nIG9mDQo+ICAgYm90aCBzZGEgYW5kIHNjbC4g
RHJvcCB0aGUgc2RhIGFuZCBzY2wgY2hlY2sgaW4gaTJjX2lteF9nZXRfc2NsLA0KPiAgIGkyY19p
bXhfZ2V0X3NkYSwgaTJjX2lteF9zZXRfc2NsLCBpMmNfaW14X3ByZXBhcmVfcmVjb3ZlcnkgYW5k
DQo+ICAgaTJjX2lteF9wcmVwYXJlX3JlY292ZXJ5DQo+ICAtdXNlIEdQSU9EX09VVF9JTiBhcyB0
aGUgcGFyYW1ldGVyIG9mIGRldm1fZ3Bpb2RfZ2V0X29wdGlvbmFsICAtcmVtb3ZlDQo+IGRvY3Vt
ZW50aW5nIHRoZSByZXF1aXJlbWVudCBvZiB1c2luZyBzbGVlcCBzdGF0ZSB0byBjb25maWd1cmUN
Cj4gICB0aGUgcGlucyBhcyBncGlvIGluIGkyYyBiaW5kaW5nIGRvYw0KPiANCj4gVjU6DQo+ICAt
aW50cm9kdWNlIGEgZGVkaWNhdGVkIGdwaW8gc3RhdGUgZm9yIGJ1cyByZWNvdmVyeS4NCj4gIC1h
c3NpZ24gYWRhcHRlci5idXNfcmVjb3ZlcnlfaW5mbyBhZnRlciB0aGUgdHdvIGdwaW9zIHdlcmUg
YXF1aXJlZA0KPiBzdWNjZXNzZnVsbHkuDQo+IA0KPiBWNjoNCj4gIC1hc3NpZ24gYWRhcHRlci5i
dXNfcmVjb3ZlcnlfaW5mbyB1bmRlciB0aGUgY29uZGl0aW9uIHRoYXQgZ3Bpb3MgYXJlDQo+IGFj
cXVpcmVkIHN1Y2Nlc3NmdWxseSAgLW5vdCB0cnkgdGhlIHJlY292ZXJ5IHdoZW4gcGluY3RybF9s
b29rdXBfc3RhdGUNCj4gcmV0dXJucyBhbiBlcnJvcg0KPiANCj4gIERvY3VtZW50YXRpb24vZGV2
aWNldHJlZS9iaW5kaW5ncy9pMmMvaTJjLWlteC50eHQgfCAgIDkgKysNCj4gIGRyaXZlcnMvaTJj
L2J1c3Nlcy9pMmMtaW14LmMgICAgICAgICAgICAgICAgICAgICAgfCAxMjQNCj4gKysrKysrKysr
KysrKysrKysrKystLQ0KPiAgMiBmaWxlcyBjaGFuZ2VkLCAxMjYgaW5zZXJ0aW9ucygrKSwgNyBk
ZWxldGlvbnMoLSkNCj4gDQo+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUv
YmluZGluZ3MvaTJjL2kyYy1pbXgudHh0DQo+IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2Jp
bmRpbmdzL2kyYy9pMmMtaW14LnR4dA0KPiBpbmRleCBjZTQzMTFkLi5lYWI1ODM2IDEwMDY0NA0K
PiAtLS0gYS9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvaTJjL2kyYy1pbXgudHh0
DQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9pMmMvaTJjLWlteC50
eHQNCj4gQEAgLTE0LDYgKzE0LDEwIEBAIE9wdGlvbmFsIHByb3BlcnRpZXM6DQo+ICAgIFRoZSBh
YnNlbmNlIG9mIHRoZSBwcm9wb2VydHkgaW5kaWNhdGVzIHRoZSBkZWZhdWx0IGZyZXF1ZW5jeSAx
MDAga0h6Lg0KPiAgLSBkbWFzOiBBIGxpc3Qgb2YgdHdvIGRtYSBzcGVjaWZpZXJzLCBvbmUgZm9y
IGVhY2ggZW50cnkgaW4gZG1hLW5hbWVzLg0KPiAgLSBkbWEtbmFtZXM6IHNob3VsZCBjb250YWlu
ICJ0eCIgYW5kICJyeCIuDQo+ICstIHNjbC1ncGlvczogc3BlY2lmeSB0aGUgZ3BpbyByZWxhdGVk
IHRvIFNDTCBwaW4NCj4gKy0gc2RhLWdwaW9zOiBzcGVjaWZ5IHRoZSBncGlvIHJlbGF0ZWQgdG8g
U0RBIHBpbg0KPiArLSBwaW5jdHJsOiBhZGQgZXh0cmEgcGluY3RybCB0byBjb25maWd1cmUgaTJj
IHBpbnMgdG8gZ3BpbyBmdW5jdGlvbiBmb3INCj4gK2kyYw0KPiArICBidXMgcmVjb3ZlcnksIGNh
bGwgaXQgImdwaW8iIHN0YXRlDQo+IA0KPiAgRXhhbXBsZXM6DQo+IA0KPiBAQCAtMzcsNCArNDEs
OSBAQCBpMmMwOiBpMmNANDAwNjYwMDAgeyAvKiBpMmMwIG9uIHZmNjEwICovDQo+ICAJZG1hcyA9
IDwmZWRtYTAgMCA1MD4sDQo+ICAJCTwmZWRtYTAgMCA1MT47DQo+ICAJZG1hLW5hbWVzID0gInJ4
IiwidHgiOw0KPiArCXBpbmN0cmwtbmFtZXMgPSAiZGVmYXVsdCIsICJncGlvIjsNCj4gKwlwaW5j
dHJsLTAgPSA8JnBpbmN0cmxfaTJjMT47DQo+ICsJcGluY3RybC0xID0gPCZwaW5jdHJsX2kyYzFf
Z3Bpbz47DQo+ICsJc2NsLWdwaW9zID0gPCZncGlvNSAyNiBHUElPX0FDVElWRV9ISUdIPjsNCj4g
KwlzZGEtZ3Bpb3MgPSA8JmdwaW81IDI3IEdQSU9fQUNUSVZFX0hJR0g+Ow0KPiAgfTsNCj4gZGlm
ZiAtLWdpdCBhL2RyaXZlcnMvaTJjL2J1c3Nlcy9pMmMtaW14LmMgYi9kcml2ZXJzL2kyYy9idXNz
ZXMvaTJjLWlteC5jDQo+IGluZGV4IDkxYmRmMjguLjA3NzNlZDEgMTAwNjQ0DQo+IC0tLSBhL2Ry
aXZlcnMvaTJjL2J1c3Nlcy9pMmMtaW14LmMNCj4gKysrIGIvZHJpdmVycy9pMmMvYnVzc2VzL2ky
Yy1pbXguYw0KPiBAQCAtNDAsNiArNDAsNyBAQA0KPiAgI2luY2x1ZGUgPGxpbnV4L2RtYXBvb2wu
aD4NCj4gICNpbmNsdWRlIDxsaW51eC9lcnIuaD4NCj4gICNpbmNsdWRlIDxsaW51eC9lcnJuby5o
Pg0KPiArI2luY2x1ZGUgPGxpbnV4L2dwaW8uaD4NCj4gICNpbmNsdWRlIDxsaW51eC9pMmMuaD4N
Cj4gICNpbmNsdWRlIDxsaW51eC9pbml0Lmg+DQo+ICAjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0
Lmg+DQo+IEBAIC02NCw2ICs2NSw4IEBADQo+ICAvKiBEZWZhdWx0IHZhbHVlICovDQo+ICAjZGVm
aW5lIElNWF9JMkNfQklUX1JBVEUJMTAwMDAwCS8qIDEwMGtIeiAqLw0KPiANCj4gKyNkZWZpbmUg
STJDX1BJTkNUUkxfU1RBVEVfR1BJTwkiZ3BpbyINCj4gKw0KPiAgLyoNCj4gICAqIEVuYWJsZSBE
TUEgaWYgdHJhbnNmZXIgYnl0ZSBzaXplIGlzIGJpZ2dlciB0aGFuIHRoaXMgdGhyZXNob2xkLg0K
PiAgICogQXMgdGhlIGhhcmR3YXJlIHJlcXVlc3QsIGl0IG11c3QgYmlnZ2VyIHRoYW4gNCBieXRl
cy5cIEBAIC0xNzgsNg0KPiArMTgxLDExIEBAIGVudW0gaW14X2kyY190eXBlIHsNCj4gIAlWRjYx
MF9JMkMsDQo+ICB9Ow0KPiANCj4gK3N0cnVjdCBpbXhfaTJjX3BpbmN0cmwgew0KPiArCXN0cnVj
dCBncGlvX2Rlc2MgKnNkYTsNCj4gKwlzdHJ1Y3QgZ3Bpb19kZXNjICpzY2w7DQo+ICt9Ow0KPiAr
DQo+ICBzdHJ1Y3QgaW14X2kyY19od2RhdGEgew0KPiAgCWVudW0gaW14X2kyY190eXBlCWRldnR5
cGU7DQo+ICAJdW5zaWduZWQJCXJlZ3NoaWZ0Ow0KPiBAQCAtMjA5LDggKzIxNywxMyBAQCBzdHJ1
Y3QgaW14X2kyY19zdHJ1Y3Qgew0KPiAgCXVuc2lnbmVkIGludAkJaWZkcjsgLyogSU1YX0kyQ19J
RkRSICovDQo+ICAJdW5zaWduZWQgaW50CQljdXJfY2xrOw0KPiAgCXVuc2lnbmVkIGludAkJYml0
cmF0ZTsNCj4gKwlzdHJ1Y3QgaW14X2kyY19waW5jdHJsCXBpbnM7DQo+ICAJY29uc3Qgc3RydWN0
IGlteF9pMmNfaHdkYXRhCSpod2RhdGE7DQo+IA0KPiArCXN0cnVjdCBwaW5jdHJsICpwaW5jdHJs
Ow0KPiArCXN0cnVjdCBwaW5jdHJsX3N0YXRlICpwaW5jdHJsX3BpbnNfZGVmYXVsdDsNCj4gKwlz
dHJ1Y3QgcGluY3RybF9zdGF0ZSAqcGluY3RybF9waW5zX2dwaW87DQo+ICsNCj4gIAlzdHJ1Y3Qg
aW14X2kyY19kbWEJKmRtYTsNCj4gIH07DQo+IA0KPiBAQCAtNDM5LDcgKzQ1MiwxMCBAQCBzdGF0
aWMgaW50IGkyY19pbXhfYnVzX2J1c3koc3RydWN0IGlteF9pMmNfc3RydWN0DQo+ICppMmNfaW14
LCBpbnQgZm9yX2J1c3kpDQo+ICAJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIG9yaWdfamlmZmll
cyArIG1zZWNzX3RvX2ppZmZpZXMoNTAwKSkpDQo+IHsNCj4gIAkJCWRldl9kYmcoJmkyY19pbXgt
PmFkYXB0ZXIuZGV2LA0KPiAgCQkJCSI8JXM+IEkyQyBidXMgaXMgYnVzeVxuIiwgX19mdW5jX18p
Ow0KPiAtCQkJcmV0dXJuIC1FVElNRURPVVQ7DQo+ICsJCQlpZiAoaTJjX2lteC0+YWRhcHRlci5i
dXNfcmVjb3ZlcnlfaW5mbykNCj4gKwkJCQlyZXR1cm4gaTJjX3JlY292ZXJfYnVzKCZpMmNfaW14
LT5hZGFwdGVyKTsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9VVDsNCj4gIAkJ
fQ0KPiAgCQlzY2hlZHVsZSgpOw0KPiAgCX0NCj4gQEAgLTk2Myw2ICs5NzksNjIgQEAgb3V0Og0K
PiAgCXJldHVybiAocmVzdWx0IDwgMCkgPyByZXN1bHQgOiBudW07DQo+ICB9DQo+IA0KPiArc3Rh
dGljIGludCBpMmNfaW14X2dldF9zY2woc3RydWN0IGkyY19hZGFwdGVyICphZGFwKSB7DQo+ICsJ
c3RydWN0IGlteF9pMmNfc3RydWN0ICppMmNfaW14Ow0KPiArDQo+ICsJaTJjX2lteCA9IGNvbnRh
aW5lcl9vZihhZGFwLCBzdHJ1Y3QgaW14X2kyY19zdHJ1Y3QsIGFkYXB0ZXIpOw0KPiArDQo+ICsJ
cmV0dXJuIGdwaW9kX2dldF92YWx1ZShpMmNfaW14LT5waW5zLnNjbCk7DQo+ICt9DQo+ICsNCj4g
K3N0YXRpYyBpbnQgaTJjX2lteF9nZXRfc2RhKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkgew0K
PiArCXN0cnVjdCBpbXhfaTJjX3N0cnVjdCAqaTJjX2lteDsNCj4gKw0KPiArCWkyY19pbXggPSBj
b250YWluZXJfb2YoYWRhcCwgc3RydWN0IGlteF9pMmNfc3RydWN0LCBhZGFwdGVyKTsNCj4gKw0K
PiArCXJldHVybiBncGlvZF9nZXRfdmFsdWUoaTJjX2lteC0+cGlucy5zZGEpOw0KPiArfQ0KPiAr
DQo+ICtzdGF0aWMgdm9pZCBpMmNfaW14X3NldF9zY2woc3RydWN0IGkyY19hZGFwdGVyICphZGFw
LCBpbnQgdmFsKSB7DQo+ICsJc3RydWN0IGlteF9pMmNfc3RydWN0ICppMmNfaW14Ow0KPiArDQo+
ICsJaTJjX2lteCA9IGNvbnRhaW5lcl9vZihhZGFwLCBzdHJ1Y3QgaW14X2kyY19zdHJ1Y3QsIGFk
YXB0ZXIpOw0KPiArDQo+ICsJZ3Bpb2Rfc2V0X3ZhbHVlKGkyY19pbXgtPnBpbnMuc2NsLCB2YWwp
OyB9DQo+ICsNCj4gK3N0YXRpYyB2b2lkIGkyY19pbXhfcHJlcGFyZV9yZWNvdmVyeShzdHJ1Y3Qg
aTJjX2FkYXB0ZXIgKmFkYXApIHsNCj4gKwlzdHJ1Y3QgaW14X2kyY19zdHJ1Y3QgKmkyY19pbXg7
DQo+ICsNCj4gKwlpMmNfaW14ID0gY29udGFpbmVyX29mKGFkYXAsIHN0cnVjdCBpbXhfaTJjX3N0
cnVjdCwgYWRhcHRlcik7DQo+ICsNCj4gKwlwaW5jdHJsX3NlbGVjdF9zdGF0ZShpMmNfaW14LT5w
aW5jdHJsLCBpMmNfaW14LT5waW5jdHJsX3BpbnNfZ3Bpbyk7DQo+ICsJZ3Bpb2RfZGlyZWN0aW9u
X2lucHV0KGkyY19pbXgtPnBpbnMuc2RhKTsNCj4gKwlncGlvZF9kaXJlY3Rpb25fb3V0cHV0KGky
Y19pbXgtPnBpbnMuc2NsLCAxKTsgfQ0KPiArDQo+ICtzdGF0aWMgdm9pZCBpMmNfaW14X3VucHJl
cGFyZV9yZWNvdmVyeShzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApIHsNCj4gKwlzdHJ1Y3QgaW14
X2kyY19zdHJ1Y3QgKmkyY19pbXg7DQo+ICsNCj4gKwlpMmNfaW14ID0gY29udGFpbmVyX29mKGFk
YXAsIHN0cnVjdCBpbXhfaTJjX3N0cnVjdCwgYWRhcHRlcik7DQo+ICsNCj4gKwlwaW5jdHJsX3Nl
bGVjdF9zdGF0ZShpMmNfaW14LT5waW5jdHJsLCBpMmNfaW14LQ0KPiA+cGluY3RybF9waW5zX2Rl
ZmF1bHQpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgc3RydWN0IGkyY19idXNfcmVjb3ZlcnlfaW5m
byBpMmNfaW14X2J1c19yZWNvdmVyeV9pbmZvID0gew0KPiArCS5nZXRfc2NsID0gaTJjX2lteF9n
ZXRfc2NsLA0KPiArCS5nZXRfc2RhID0gaTJjX2lteF9nZXRfc2RhLA0KPiArCS5zZXRfc2NsID0g
aTJjX2lteF9zZXRfc2NsLA0KPiArCS5wcmVwYXJlX3JlY292ZXJ5ID0gaTJjX2lteF9wcmVwYXJl
X3JlY292ZXJ5LA0KPiArCS51bnByZXBhcmVfcmVjb3ZlcnkgPSBpMmNfaW14X3VucHJlcGFyZV9y
ZWNvdmVyeSwNCj4gKwkucmVjb3Zlcl9idXMgPSBpMmNfZ2VuZXJpY19zY2xfcmVjb3ZlcnksIH07
DQo+ICsNCj4gIHN0YXRpYyB1MzIgaTJjX2lteF9mdW5jKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRh
cHRlcikgIHsNCj4gIAlyZXR1cm4gSTJDX0ZVTkNfSTJDIHwgSTJDX0ZVTkNfU01CVVNfRU1VTCBA
QCAtMTAxMSwxMiArMTA4MywxMiBAQA0KPiBzdGF0aWMgaW50IGkyY19pbXhfcHJvYmUoc3RydWN0
IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gDQo+ICAJLyogU2V0dXAgaTJjX2lteCBkcml2ZXIg
c3RydWN0dXJlICovDQo+ICAJc3RybGNweShpMmNfaW14LT5hZGFwdGVyLm5hbWUsIHBkZXYtPm5h
bWUsIHNpemVvZihpMmNfaW14LQ0KPiA+YWRhcHRlci5uYW1lKSk7DQo+IC0JaTJjX2lteC0+YWRh
cHRlci5vd25lcgkJPSBUSElTX01PRFVMRTsNCj4gLQlpMmNfaW14LT5hZGFwdGVyLmFsZ28JCT0g
JmkyY19pbXhfYWxnbzsNCj4gLQlpMmNfaW14LT5hZGFwdGVyLmRldi5wYXJlbnQJPSAmcGRldi0+
ZGV2Ow0KPiAtCWkyY19pbXgtPmFkYXB0ZXIubnIJCT0gcGRldi0+aWQ7DQo+IC0JaTJjX2lteC0+
YWRhcHRlci5kZXYub2Zfbm9kZQk9IHBkZXYtPmRldi5vZl9ub2RlOw0KPiAtCWkyY19pbXgtPmJh
c2UJCQk9IGJhc2U7DQo+ICsJaTJjX2lteC0+YWRhcHRlci5vd25lciA9IFRISVNfTU9EVUxFOw0K
PiArCWkyY19pbXgtPmFkYXB0ZXIuYWxnbyA9ICZpMmNfaW14X2FsZ287DQo+ICsJaTJjX2lteC0+
YWRhcHRlci5kZXYucGFyZW50ID0gJnBkZXYtPmRldjsNCj4gKwlpMmNfaW14LT5hZGFwdGVyLm5y
ID0gcGRldi0+aWQ7DQo+ICsJaTJjX2lteC0+YWRhcHRlci5kZXYub2Zfbm9kZSA9IHBkZXYtPmRl
di5vZl9ub2RlOw0KPiArCWkyY19pbXgtPmJhc2UgPSBiYXNlOw0KPiANCj4gIAkvKiBHZXQgSTJD
IGNsb2NrICovDQo+ICAJaTJjX2lteC0+Y2xrID0gZGV2bV9jbGtfZ2V0KCZwZGV2LT5kZXYsIE5V
TEwpOyBAQCAtMTAzMSw2ICsxMTAzLDIzDQo+IEBAIHN0YXRpYyBpbnQgaTJjX2lteF9wcm9iZShz
dHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiAgCQlyZXR1cm4gcmV0Ow0KPiAgCX0NCj4g
DQo+ICsJaTJjX2lteC0+cGluY3RybCA9IGRldm1fcGluY3RybF9nZXQoJnBkZXYtPmRldik7DQo+
ICsJaWYgKElTX0VSUihpMmNfaW14LT5waW5jdHJsKSkgew0KPiArCQlyZXQgPSBQVFJfRVJSKGky
Y19pbXgtPnBpbmN0cmwpOw0KPiArCQlnb3RvIGNsa19kaXNhYmxlOw0KPiArCX0NCj4gKw0KPiAr
CWkyY19pbXgtPnBpbmN0cmxfcGluc19kZWZhdWx0ID0gcGluY3RybF9sb29rdXBfc3RhdGUoaTJj
X2lteC0NCj4gPnBpbmN0cmwsDQo+ICsJCQkJCQlQSU5DVFJMX1NUQVRFX0RFRkFVTFQpOw0KPiAr
CWlmIChJU19FUlIoaTJjX2lteC0+cGluY3RybF9waW5zX2RlZmF1bHQpKQ0KPiArCQlkZXZfd2Fy
bigmcGRldi0+ZGV2LCAiY291bGQgbm90IGdldCBkZWZhdWx0IHN0YXRlXG4iKTsNCj4gKwllbHNl
IHsNCj4gKwkJaTJjX2lteC0+cGluY3RybF9waW5zX2dwaW8gPSBwaW5jdHJsX2xvb2t1cF9zdGF0
ZShpMmNfaW14LQ0KPiA+cGluY3RybCwNCj4gKwkJCQkJCUkyQ19QSU5DVFJMX1NUQVRFX0dQSU8p
Ow0KPiArCQlpZiAoSVNfRVJSKGkyY19pbXgtPnBpbmN0cmxfcGluc19ncGlvKSkNCj4gKwkJCWRl
dl93YXJuKCZwZGV2LT5kZXYsICJjb3VsZCBub3QgZ2V0IGdwaW8gc3RhdGVcbiIpOw0KPiArCX0N
Cj4gKw0KPiAgCS8qIFJlcXVlc3QgSVJRICovDQo+ICAJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycSgm
cGRldi0+ZGV2LCBpcnEsIGkyY19pbXhfaXNyLCAwLA0KPiAgCQkJCXBkZXYtPm5hbWUsIGkyY19p
bXgpOw0KPiBAQCAtMTA1Nyw2ICsxMTQ2LDI3IEBAIHN0YXRpYyBpbnQgaTJjX2lteF9wcm9iZShz
dHJ1Y3QgcGxhdGZvcm1fZGV2aWNlDQo+ICpwZGV2KQ0KPiAgCWlmIChyZXQgPCAwKQ0KPiAgCQln
b3RvIHJwbV9kaXNhYmxlOw0KPiANCj4gKwkvKiBJbml0IHJlY292ZXIgcGlucyAqLw0KPiArCWlm
ICghSVNfRVJSKGkyY19pbXgtPnBpbmN0cmxfcGluc19kZWZhdWx0KSAmJiAhSVNfRVJSKGkyY19p
bXgtDQo+ID5waW5jdHJsX3BpbnNfZ3BpbykpIHsNCj4gKwkJaTJjX2lteC0+cGlucy5zZGEgPQ0K
PiArCQkJZGV2bV9ncGlvZF9nZXRfb3B0aW9uYWwoJnBkZXYtPmRldiwgInNkYS1ncGlvcyIsDQo+
IEdQSU9EX0lOKTsNCj4gKwkJaTJjX2lteC0+cGlucy5zY2wgPQ0KPiArCQkJZGV2bV9ncGlvZF9n
ZXRfb3B0aW9uYWwoJnBkZXYtPmRldiwgInNjbC1ncGlvcyIsDQo+IEdQSU9EX0lOKTsNCj4gKw0K
PiArCQlpZiAoSVNfRVJSKGkyY19pbXgtPnBpbnMuc2RhKSkgew0KPiArCQkJcmV0ID0gUFRSX0VS
UihpMmNfaW14LT5waW5zLnNkYSk7DQo+ICsJCQlnb3RvIGNsa19kaXNhYmxlOw0KPiArCQl9DQo+
ICsNCj4gKwkJaWYgKElTX0VSUihpMmNfaW14LT5waW5zLnNjbCkpIHsNCj4gKwkJCXJldCA9IFBU
Ul9FUlIoaTJjX2lteC0+cGlucy5zY2wpOw0KPiArCQkJZ290byBjbGtfZGlzYWJsZTsNCj4gKwkJ
fQ0KPiArDQo+ICsJCWlmIChpMmNfaW14LT5waW5zLnNjbCAmJiBpMmNfaW14LT5waW5zLnNkYSkN
Cj4gKwkJCWkyY19pbXgtPmFkYXB0ZXIuYnVzX3JlY292ZXJ5X2luZm8gPQ0KPiAmaTJjX2lteF9i
dXNfcmVjb3ZlcnlfaW5mbzsNCj4gKwl9DQo+ICsNCj4gIAkvKiBTZXQgdXAgY2xvY2sgZGl2aWRl
ciAqLw0KPiAgCWkyY19pbXgtPmJpdHJhdGUgPSBJTVhfSTJDX0JJVF9SQVRFOw0KPiAgCXJldCA9
IG9mX3Byb3BlcnR5X3JlYWRfdTMyKHBkZXYtPmRldi5vZl9ub2RlLA0KPiAtLQ0KPiAxLjkuMQ0K
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sascha Hauer Sept. 25, 2015, 9:41 a.m. UTC | #2
On Fri, Sep 25, 2015 at 09:29:29AM +0000, Gao Pandy wrote:
> Ping...

No need to ping when there are outstanding reviews which by now I have
sent twice:

http://www.spinics.net/lists/arm-kernel/msg445986.html
http://comments.gmane.org/gmane.linux.drivers.i2c/24567

Anyway, as you haven't read the last two mails you probably won't read
this one either.

Could anyone tell Gao to have a look in his junk folder?

Sascha
Gao Pandy Sept. 25, 2015, 10:38 a.m. UTC | #3
From: Sascha Hauer <mailto:s.hauer@pengutronix.de> Sent: Friday, September 25, 2015 5:41 PM
> To: Gao Pan-B54642
> Cc: wsa@the-dreams.de; u.kleine-koenig@pengutronix.de; Duan Fugang-B38611;
> Li Frank-B20596; linux-i2c@vger.kernel.org; kernel@pengutronix.de;
> hkallweit1@gmail.com
> Subject: Re: [Patch V6] i2c: imx: implement bus recovery
> 
> On Fri, Sep 25, 2015 at 09:29:29AM +0000, Gao Pandy wrote:
> > Ping...
> 
> No need to ping when there are outstanding reviews which by now I have
> sent twice:
> 
> http://www.spinics.net/lists/arm-kernel/msg445986.html
> http://comments.gmane.org/gmane.linux.drivers.i2c/24567
> 
> Anyway, as you haven't read the last two mails you probably won't read
> this one either.
> 
> Could anyone tell Gao to have a look in his junk folder?
> 
> Sascha

Sorry for missing your reviews, I will read your reviews seriously. 
Thank you very much.

Best Regards
Gao Pan

> --
> Pengutronix e.K.                           |
> |
> Industrial Linux Solutions                 | http://www.pengutronix.de/
> |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> |
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
index ce4311d..eab5836 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
@@ -14,6 +14,10 @@  Optional properties:
   The absence of the propoerty indicates the default frequency 100 kHz.
 - dmas: A list of two dma specifiers, one for each entry in dma-names.
 - dma-names: should contain "tx" and "rx".
+- scl-gpios: specify the gpio related to SCL pin
+- sda-gpios: specify the gpio related to SDA pin
+- pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c
+  bus recovery, call it "gpio" state
 
 Examples:
 
@@ -37,4 +41,9 @@  i2c0: i2c@40066000 { /* i2c0 on vf610 */
 	dmas = <&edma0 0 50>,
 		<&edma0 0 51>;
 	dma-names = "rx","tx";
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>;
+	sda-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;
 };
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 91bdf28..0773ed1 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -40,6 +40,7 @@ 
 #include <linux/dmapool.h>
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -64,6 +65,8 @@ 
 /* Default value */
 #define IMX_I2C_BIT_RATE	100000	/* 100kHz */
 
+#define I2C_PINCTRL_STATE_GPIO	"gpio"
+
 /*
  * Enable DMA if transfer byte size is bigger than this threshold.
  * As the hardware request, it must bigger than 4 bytes.\
@@ -178,6 +181,11 @@  enum imx_i2c_type {
 	VF610_I2C,
 };
 
+struct imx_i2c_pinctrl {
+	struct gpio_desc *sda;
+	struct gpio_desc *scl;
+};
+
 struct imx_i2c_hwdata {
 	enum imx_i2c_type	devtype;
 	unsigned		regshift;
@@ -209,8 +217,13 @@  struct imx_i2c_struct {
 	unsigned int		ifdr; /* IMX_I2C_IFDR */
 	unsigned int		cur_clk;
 	unsigned int		bitrate;
+	struct imx_i2c_pinctrl	pins;
 	const struct imx_i2c_hwdata	*hwdata;
 
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pinctrl_pins_default;
+	struct pinctrl_state *pinctrl_pins_gpio;
+
 	struct imx_i2c_dma	*dma;
 };
 
@@ -439,7 +452,10 @@  static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
 		if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> I2C bus is busy\n", __func__);
-			return -ETIMEDOUT;
+			if (i2c_imx->adapter.bus_recovery_info)
+				return i2c_recover_bus(&i2c_imx->adapter);
+			else
+				return -ETIMEDOUT;
 		}
 		schedule();
 	}
@@ -963,6 +979,62 @@  out:
 	return (result < 0) ? result : num;
 }
 
+static int i2c_imx_get_scl(struct i2c_adapter *adap)
+{
+	struct imx_i2c_struct *i2c_imx;
+
+	i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
+
+	return gpiod_get_value(i2c_imx->pins.scl);
+}
+
+static int i2c_imx_get_sda(struct i2c_adapter *adap)
+{
+	struct imx_i2c_struct *i2c_imx;
+
+	i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
+
+	return gpiod_get_value(i2c_imx->pins.sda);
+}
+
+static void i2c_imx_set_scl(struct i2c_adapter *adap, int val)
+{
+	struct imx_i2c_struct *i2c_imx;
+
+	i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
+
+	gpiod_set_value(i2c_imx->pins.scl, val);
+}
+
+static void i2c_imx_prepare_recovery(struct i2c_adapter *adap)
+{
+	struct imx_i2c_struct *i2c_imx;
+
+	i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
+
+	pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_gpio);
+	gpiod_direction_input(i2c_imx->pins.sda);
+	gpiod_direction_output(i2c_imx->pins.scl, 1);
+}
+
+static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
+{
+	struct imx_i2c_struct *i2c_imx;
+
+	i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
+
+	pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_default);
+}
+
+static struct i2c_bus_recovery_info i2c_imx_bus_recovery_info = {
+	.get_scl = i2c_imx_get_scl,
+	.get_sda = i2c_imx_get_sda,
+	.set_scl = i2c_imx_set_scl,
+	.prepare_recovery = i2c_imx_prepare_recovery,
+	.unprepare_recovery = i2c_imx_unprepare_recovery,
+	.recover_bus = i2c_generic_scl_recovery,
+};
+
 static u32 i2c_imx_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
@@ -1011,12 +1083,12 @@  static int i2c_imx_probe(struct platform_device *pdev)
 
 	/* Setup i2c_imx driver structure */
 	strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
-	i2c_imx->adapter.owner		= THIS_MODULE;
-	i2c_imx->adapter.algo		= &i2c_imx_algo;
-	i2c_imx->adapter.dev.parent	= &pdev->dev;
-	i2c_imx->adapter.nr		= pdev->id;
-	i2c_imx->adapter.dev.of_node	= pdev->dev.of_node;
-	i2c_imx->base			= base;
+	i2c_imx->adapter.owner = THIS_MODULE;
+	i2c_imx->adapter.algo = &i2c_imx_algo;
+	i2c_imx->adapter.dev.parent = &pdev->dev;
+	i2c_imx->adapter.nr = pdev->id;
+	i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
+	i2c_imx->base = base;
 
 	/* Get I2C clock */
 	i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1031,6 +1103,23 @@  static int i2c_imx_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
+	if (IS_ERR(i2c_imx->pinctrl)) {
+		ret = PTR_ERR(i2c_imx->pinctrl);
+		goto clk_disable;
+	}
+
+	i2c_imx->pinctrl_pins_default = pinctrl_lookup_state(i2c_imx->pinctrl,
+						PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(i2c_imx->pinctrl_pins_default))
+		dev_warn(&pdev->dev, "could not get default state\n");
+	else {
+		i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
+						I2C_PINCTRL_STATE_GPIO);
+		if (IS_ERR(i2c_imx->pinctrl_pins_gpio))
+			dev_warn(&pdev->dev, "could not get gpio state\n");
+	}
+
 	/* Request IRQ */
 	ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
 				pdev->name, i2c_imx);
@@ -1057,6 +1146,27 @@  static int i2c_imx_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto rpm_disable;
 
+	/* Init recover pins */
+	if (!IS_ERR(i2c_imx->pinctrl_pins_default) && !IS_ERR(i2c_imx->pinctrl_pins_gpio)) {
+		i2c_imx->pins.sda =
+			devm_gpiod_get_optional(&pdev->dev, "sda-gpios", GPIOD_IN);
+		i2c_imx->pins.scl =
+			devm_gpiod_get_optional(&pdev->dev, "scl-gpios", GPIOD_IN);
+
+		if (IS_ERR(i2c_imx->pins.sda)) {
+			ret = PTR_ERR(i2c_imx->pins.sda);
+			goto clk_disable;
+		}
+
+		if (IS_ERR(i2c_imx->pins.scl)) {
+			ret = PTR_ERR(i2c_imx->pins.scl);
+			goto clk_disable;
+		}
+
+		if (i2c_imx->pins.scl && i2c_imx->pins.sda)
+			i2c_imx->adapter.bus_recovery_info = &i2c_imx_bus_recovery_info;
+	}
+
 	/* Set up clock divider */
 	i2c_imx->bitrate = IMX_I2C_BIT_RATE;
 	ret = of_property_read_u32(pdev->dev.of_node,