From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v3] USB: serial: ftdi_sio: implement GPIO support for FT-X devices From: Johan Hovold Message-Id: <20180914161155.GB3443@localhost> Date: Fri, 14 Sep 2018 18:11:55 +0200 To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Loic Poulain List-ID: T24gTW9uLCBTZXAgMTAsIDIwMTggYXQgMDc6NDM6MjJQTSArMDIwMCwgS2Fyb2x5IFBhZG9zIHdy b3RlOgo+IFRoaXMgcGF0Y2ggYWxsb3dzIHVzaW5nIHRoZSBDQlVTIHBpbnMgb2YgRlQtWCBkZXZp Y2VzIGFzIEdQSU8gaW4gQ0JVUwo+IGJpdGJhbmdpbmcgbW9kZS4gVGhlcmUgaXMgbm8gY29uZmxp Y3QgYmV0d2VlbiB0aGUgR1BJTyBhbmQgVkNQCj4gZnVuY3Rpb25hbGl0eSBpbiB0aGlzIG1vZGUu IFRlc3RlZCBvbiBGVDIzMFggYW5kIEZUMjMxWC4KPiAKPiBBcyB0aGVyZSBpcyBubyB3YXkgdG8g cmVxdWVzdCB0aGUgY3VycmVudCBDQlVTIHJlZ2lzdGVyIGNvbmZpZ3VyYXRpb24KPiBmcm9tIHRo ZSBkZXZpY2UsIGFsbCBDQlVTIHBpbnMgYXJlIHNldCB0byBhIGtub3duIHN0YXRlIHdoZW4gdGhl IGZpcnN0Cj4gR1BJTyBpcyByZXF1ZXN0ZWQuIFRoaXMgYWxsb3dzIHVzaW5nIGxpYmZ0ZGkgdG8g c2V0IHRoZSBHUElPIHBpbnMKPiBiZWZvcmUgbG9hZGluZyB0aGlzIG1vZHVsZSBmb3IgVUFSVCBm dW5jdGlvbmFsaXR5LCBhIGJlaGF2aW9yIHRoYXQKPiBleGlzdGluZyBhcHBsaWNhdGlvbnMgbWln aHQgYmUgcmVseWluZyB1cG9uICh0aG91Z2ggbm8gc3BlY2lmaWMgY2FzZQo+IGlzIGtub3duIHRv IHRoZSBhdXRob3JzIG9mIHRoaXMgcGF0Y2gpLgo+IAo+IFNpZ25lZC1vZmYtYnk6IEthcm9seSBQ YWRvcyA8cGFkb3NAcGFkb3MuaHU+Cj4gLS0tCj4gCj4gQ2hhbmdlbG9nOgo+IC0gdjI6IEZpeCBj b21waWxlIGVycm9yIHdoZW4gQ09ORklHX0dQSU9MSUIgaXMgbm90IGRlZmluZWQuCj4gLSB2Mzog SW5jb3Jwb3JhdGUgcmV2aWV3IGZlZWRiYWNrLgoKTmV4dCB0aW1lLCBwbGVhc2UgYmUgbW9yZSBz cGVjaWZpYyBhYm91dCB3aGF0IHlvdSBjaGFuZ2VkIGhlcmUuCgo+IFRob3VnaCB0aGVyZSBpcyBu byBjb2RlIGNvcGllZCwgbGliZnRkaSB3YXMgdXNlZCBhcyAKPiBhIHJlZmVyZW5jZS4gZnRkaV9y ZWFkX2VlcHJvbSBpcyBiYXNlZCBvbiBMb2ljIFBvdWxhaW4ncyBwYXRjaC4KPiAKPiBJJ3ZlIHJl bW92ZWQgLS1zdHJpY3QgZnJvbSBjaGVja3BhdGNoLnBsIGludm9jYXRpb24sIHlldCBpdCBzdGls bCBnaXZlcwo+IG1lIHRob3NlIHdhcm5pbmdzIGl0IHNob3VsZG4ndC4gTWF5YmUgSSBoYXZlIGEg ZGlmZmVyZW50IHZlcnNpb24/IE5vdwo+IGluIHYzIEkgYWxzbyBnZXQgdHdvIG5ldyBJJ20gbm90 IHN1cmUgaG93IHRvIGRlYWwgd2l0aC4gUmVzdCBvZiB0ZXh0IAo+IGJlbG93IHNhbWUgYXMgYmVm b3JlLgoKWWVhaCwgdGhlIHR3byBuZXcgb25lcyBJIGdldCB0b28sIGFuZCB0aGV5IG5lZWQgdG8g YmUgZml4ZWQuIE1vcmUgYmVsb3cuCgo+IEkgbm90aWNlZCB0aGVyZSBoYXZlIGJlZW4gbnVtZXJv dXMgaGlzdG9yaWMgYXR0ZW1wdHMgYnkgb3RoZXIgcGVvcGxlIGF0IAo+IGFkZGluZyBHUElPIHN1 cHBvcnQgdG8gZnRkaV9zaW8uIE9uZSB0cmllZCBhZGRpbmcgaXQgaW4gc29tZSB2ZXJ5IAo+IGFw cGxpY2F0aW9uLXNwZWNpZmljIHdheSwgYW5vdGhlciBvbmUgdHJpZWQgdG8gdXNlIHRoZSBtZmQg ZnJhbWV3b3JrLCB0aGUKPiB0cmllZCB1c2luZyBhIEdQSU8gbW9kZSB3aGljaCBpcyBtdXR1YWxs eSBleGNsdXNpdmUgdG8gVkNQLCBhbm90aGVyCj4gb25lIGRpZCBub3QgaW1wbGVtZW50IHRoZSBy ZXZpZXcgcmVzdWx0cyBldGMuLi4gSSBob3BlIEkgbGVhcm5lZCBmcm9tIHRob3NlIAo+IGF0dGVt cHRzIGFuZCBhbSBwbGFubmluZyB0byByZXNwb25kIHRvIHJldmlld3MuIEFsc28sIHRoaXMgcGF0 Y2ggZm9sbG93cyAKPiB0aGUgcm91Z2ggc3RydWN0dXJlIG9mIHRoZSBHUElPIHN1cHBvcnQgZm9y IGNwMjEweCBkZXZpY2VzIHRoYXQgaGF2ZSAKPiBhbHJlYWR5IGJlZW4gYWNjZXB0ZWQsIGluIHRo ZSBob3BlIHRoYXQgaXQgaXMgYSBnb29kIHN0YXJ0aW5nIHBvaW50Lgo+IAo+IFRoaXMgcGF0Y2gg dXNlcyBDQlVTIGJpdGJhbmdpbmcgbW9kZSwgd2hpY2ggd29ya3MgbmljZWx5IGluIHBhcmFsbGVs IHdpdGgKPiB0aGUgVkNQIGZ1bmN0aW9uLiBUaGUgb3RoZXIgbW9kZXMgZG8gbm90LCBhbmQgc28g SU1ITyBpdCBkb2VzIG5vdCBtYWtlCj4gc2Vuc2UgdG8gdHJ5IGFkZGluZyB0aGVtIHRvIHRoaXMg c2FtZSBtb2R1bGUuCj4gCj4gRm9yIHRoaXMgZGV2aWNlLCB3aGVuZXZlciBjaGFuZ2luZyB0aGUg c3RhdGUgb2YgYW55IHNpbmdsZSBwaW4sIGFsbCB0aGUKPiBvdGhlcnMgbmVlZCB0byBiZSB3cml0 dGVuIHRvby4gVGhpcyBtZWFucyBpbiBvcmRlciB0byBjaGFuZ2UgYW55IHBpbiwgd2UgCj4gbmVl ZCB0byBrbm93IHRoZSBjdXJyZW50IHN0YXRlIG9mIGFsbCB0aGUgb3RoZXJzLiBTbyB3aGVuIHVz aW5nIEdQSU8sCj4gd2UgbmVlZCB0byBoYXZlIGEga25vd24gc3RhcnRpbmcgc3RhdGUgZm9yIGFs bCBwaW5zLCBidXQgdGhlcmUgc2VlbXMgdG8gCj4gYmUgbm8gd2F5IHRvIHJldHJpZXZlIHRoZSBl eGlzdGluZyBHUElPIGNvbmZpZ3VyYXRpb24gKGRpcmVjdGlvbnMgYW5kCj4gb3V0cHV0IHJlZ2lz dGVyIHZhbHVlcykuIFRoZSB3YXkgSSBoYW5kbGUgdGhpcyBpbiB0aGlzIHBhdGNoIGlzIHRoYXQg d2hlbgo+IHJlcXVlc3RpbmcgYSBHUElPIGZvciB0aGUgZmlyc3QgdGltZSwgdGhlIG1vZHVsZSBp bml0aWFsaXplcyBhbGwgcGlucyB0byAKPiBhIGtub3duIGRlZmF1bHQgc3RhdGUgKHRvIGlucHV0 cykuIElucHV0IHdhcyBjaG9zZW4sIGJlY2F1c2UgYSBwb3RlbnRpYWxseQo+IGZsb2F0aW5nIHBp biBpcyBiZXR0ZXIgdGhhbiBhIHBvdGVudGlhbCBkcml2ZXIgY29uZmxpY3QsIGJlY2F1c2UgdGhl IGxhdHRlcgo+IGNvdWxkIHJlc3VsdCBpbiBoYXJkd2FyZSBkYW1hZ2UuIEhvd2V2ZXIsIGlmIHRo ZSB1c2VyIGRvZXMgbm90IHJlcXVlc3QgYSAKPiBHUElPLCB0aGUgQ0JVUyBwaW5zIGFyZSBub3Qg aW5pdGlhbGl6ZWQsIGF2b2lkaW5nIHVubmVjZXNzYXJpbHkgY2hhbmdpbmcgCj4gaGFyZHdhcmUg c3RhdGUuIEkgZmlndXJlZCBJIGNhbm5vdCByZWx5IG9uIHRoZSBkZWZhdWx0IHBvd2VyLW9uIHN0 YXRlIG9mCj4gdGhlIGRldmljZSBmb3IgdGhpcyBhcyB0aGUgdXNlciBtaWdodCBoYXZlIHVzZWQg bGliZnRkaSBiZWZvcmUgbG9hZGluZyAKPiBvdXIgbW9kdWxlLiBXaGVuIHRoZSBtb2R1bGUgaXMg dW5sb2FkZWQsIENCVVMgYml0YmFuZ2luZyBtb2RlIGlzIGV4aXRlZCAKPiBpZiBpdCB3ZXJlIHVz IHdobyBlbnRlcmVkIGl0IGVhcmxpZXIuCj4gCj4gCj4gIGRyaXZlcnMvdXNiL3NlcmlhbC9mdGRp X3Npby5jIHwgMzE4ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0KPiAgZHJpdmVy cy91c2Ivc2VyaWFsL2Z0ZGlfc2lvLmggfCAgMjcgKystCj4gIDIgZmlsZXMgY2hhbmdlZCwgMzQz IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv dXNiL3NlcmlhbC9mdGRpX3Npby5jIGIvZHJpdmVycy91c2Ivc2VyaWFsL2Z0ZGlfc2lvLmMKPiBp bmRleCBiNWNlZjMyMjgyNmYuLjAwYjZjNmFiZGQwOSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3Vz Yi9zZXJpYWwvZnRkaV9zaW8uYwo+ICsrKyBiL2RyaXZlcnMvdXNiL3NlcmlhbC9mdGRpX3Npby5j Cj4gQEAgLTQwLDYgKzQwLDkgQEAKPiAgI2luY2x1ZGUgPGxpbnV4L3VzYi5oPgo+ICAjaW5jbHVk ZSA8bGludXgvc2VyaWFsLmg+Cj4gICNpbmNsdWRlIDxsaW51eC91c2Ivc2VyaWFsLmg+Cj4gKyNp ZiBkZWZpbmVkKENPTkZJR19HUElPTElCKQo+ICsjaW5jbHVkZSA8bGludXgvZ3Bpby9kcml2ZXIu aD4KPiArI2VuZGlmCgpIbW0uIEkgYWxyZWFkeSBjb21tZW50ZWQgb24gdGhpcyBpbiB2MS4KCj4g ICNpbmNsdWRlICJmdGRpX3Npby5oIgo+ICAjaW5jbHVkZSAiZnRkaV9zaW9faWRzLmgiCj4gIAo+ IEBAIC03Miw2ICs3NSwxNCBAQCBzdHJ1Y3QgZnRkaV9wcml2YXRlIHsKPiAgCXVuc2lnbmVkIGlu dCBsYXRlbmN5OwkJLyogbGF0ZW5jeSBzZXR0aW5nIGluIHVzZSAqLwo+ICAJdW5zaWduZWQgc2hv cnQgbWF4X3BhY2tldF9zaXplOwo+ICAJc3RydWN0IG11dGV4IGNmZ19sb2NrOyAvKiBBdm9pZCBt ZXNzIGJ5IHBhcmFsbGVsIGNhbGxzIG9mIGNvbmZpZyBpb2N0bCgpIGFuZCBjaGFuZ2Vfc3BlZWQo KSAqLwo+ICsjaWYgZGVmaW5lZChDT05GSUdfR1BJT0xJQikKPiArCXN0cnVjdCBncGlvX2NoaXAg Z2M7Cj4gKwlib29sCWdwaW9fcmVnaXN0ZXJlZDsgIC8qIGlzIHRoZSBncGlvY2hpcCBpbiBrZXJu ZWwgcmVnaXN0ZXJlZCAqLwo+ICsJYm9vbAlncGlvX3VzZWQ7CSAgLyogdHJ1ZSBpZiB0aGUgdXNl ciByZXF1ZXN0ZWQgYSBncGlvICovCj4gKwl1OAlncGlvX2FsdGZ1bmM7CSAgLyogd2hpY2ggcGlu cyBhcmUgaW4gZ3BpbyBtb2RlICovCj4gKwl1OAlncGlvX2lucHV0OwkgIC8qIHBpbiBkaXJlY3Rp b25zIGNhY2hlICovCgpBbmQgSSBhc2tlZCB5b3UgdG8gaW52ZXJ0IHRoaXMgb25lIChpLmUuIHJl cGxhY2Ugd2l0aCBncGlvX291dHB1dCkuCgo+ICsJdTgJZ3Bpb192YWx1ZTsJICAvKiBwaW4gdmFs dWUgZm9yIG91dHB1dHMgKi8KPiArI2VuZGlmCj4gIH07Cj4gIAo+ICAvKiBzdHJ1Y3QgZnRkaV9z aW9fcXVpcmsgaXMgdXNlZCBieSBkZXZpY2VzIHJlcXVpcmluZyBzcGVjaWFsIGF0dGVudGlvbi4g Ki8KPiBAQCAtMTc2Niw2ICsxNzc3LDMwMSBAQCBzdGF0aWMgdm9pZCByZW1vdmVfc3lzZnNfYXR0 cnMoc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiAgCj4gIH0KPiAgCj4gKyNpZiBkZWZp bmVkKENPTkZJR19HUElPTElCKQo+ICsKPiArc3RhdGljIGludCBmdGRpX3NldF9iaXRtb2RlX3Jl cShzdHJ1Y3QgdXNiX3NlcmlhbF9wb3J0ICpwb3J0LCB1OCBtb2RlKQo+ICt7Cj4gKwlzdHJ1Y3Qg ZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICsJ c3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCA9IHBvcnQtPnNlcmlhbDsKPiArCWludCByZXN1bHQ7 Cj4gKwl1MTYgdmFsOwo+ICsKPiArCS8qIGRldmljZSdzIGRpcmVjdGlvbiBwb2xhcml0eSBpcyBk aWZmZXJlbnQgZnJvbSBrZXJuZWwncyAqLwo+ICsJdTggZGlyZWN0aW9uID0gKH5wcml2LT5ncGlv X2lucHV0KSAmIDB4MGY7Cj4gKwo+ICsJdmFsID0gKG1vZGUgPDwgOCkgfCAoZGlyZWN0aW9uIDw8 IDQpIHwgKHByaXYtPmdwaW9fdmFsdWUgJiAweDBmKTsKPiArCXJlc3VsdCA9IHVzYl9jb250cm9s X21zZyhzZXJpYWwtPmRldiwKPiArCQkJCSB1c2Jfc25kY3RybHBpcGUoc2VyaWFsLT5kZXYsIDAp LAo+ICsJCQkJIEZURElfU0lPX1NFVF9CSVRNT0RFX1JFUVVFU1QsCj4gKwkJCQkgRlRESV9TSU9f U0VUX0JJVE1PREVfUkVRVUVTVF9UWVBFLCB2YWwsCj4gKwkJCQkgcHJpdi0+aW50ZXJmYWNlLCBO VUxMLCAwLCBXRFJfVElNRU9VVCk7Cj4gKwoKQW5kIEkgYXNrZWQgeW91IHRvIHJlbW92ZSBzdWNo IGVtcHR5IGxpbmVzLgoKPiArCWlmIChyZXN1bHQgPCAwKSB7Cj4gKwkJZGV2X2Vycigmc2VyaWFs LT5pbnRlcmZhY2UtPmRldiwKPiArCQkJImJpdG1vZGUgcmVxdWVzdCBmYWlsZWQgZm9yIHZhbHVl OiAlZFxuIiwKClVzZSBoZXggbm90YXRpb24gYW5kIGluY2x1ZGUgdGhlIGVycm5vOgoJCgkiYml0 bW9kZSByZXF1ZXN0IGZhaWxlZCBmb3IgdmFsdWUgMHglMDR4OiAlZFxuIiwgdmFsLCByZXN1bHQK Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsKPiArc3RhdGljIGludCBmdGRp X3NldF9jYnVzX3BpbnMoc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiArewo+ICsJcmV0 dXJuIGZ0ZGlfc2V0X2JpdG1vZGVfcmVxKHBvcnQsIEZURElfU0lPX0JJVE1PREVfQ0JVUyk7Cj4g K30KPiArCj4gK3N0YXRpYyBpbnQgZnRkaV9leGl0X2NidXNfbW9kZShzdHJ1Y3QgdXNiX3Nlcmlh bF9wb3J0ICpwb3J0KQo+ICt7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dl dF9zZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICsKPiArCXByaXYtPmdwaW9faW5wdXQgPSAwOwo+ ICsJcHJpdi0+Z3Bpb192YWx1ZSA9IDA7Cj4gKwlyZXR1cm4gZnRkaV9zZXRfYml0bW9kZV9yZXEo cG9ydCwgRlRESV9TSU9fQklUTU9ERV9SRVNFVCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZnRk aV9ncGlvX3JlcXVlc3Qoc3RydWN0IGdwaW9fY2hpcCAqZ2MsIHVuc2lnbmVkIGludCBvZmZzZXQp Cj4gK3sKPiArCXN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBvcnQgPSBncGlvY2hpcF9nZXRfZGF0 YShnYyk7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxfcG9y dF9kYXRhKHBvcnQpOwo+ICsJaW50IHJlc3VsdDsKPiArCj4gKwlpZiAocHJpdi0+Z3Bpb19hbHRm dW5jICYgQklUKG9mZnNldCkpCj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwo+ICsJaWYgKCFwcml2 LT5ncGlvX3VzZWQpIHsKPiArCQkvKiBTZXQgZGVmYXVsdCBwaW4gc3RhdGVzLCBhcyB3ZSBjYW5u b3QgZ2V0IHRoZW0gZnJvbSBkZXZpY2UgKi8KPiArCQlwcml2LT5ncGlvX2lucHV0ID0gMHhmZjsK PiArCQlwcml2LT5ncGlvX3ZhbHVlID0gMHgwMDsKPiArCQlyZXN1bHQgPSBmdGRpX3NldF9jYnVz X3BpbnMocG9ydCk7Cj4gKwkJaWYgKHJlc3VsdCkKPiArCQkJcmV0dXJuIHJlc3VsdDsKPiArCj4g KwkJcHJpdi0+Z3Bpb191c2VkID0gdHJ1ZTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ ICsKPiArc3RhdGljIGludCBmdGRpX2dwaW9fZ2V0KHN0cnVjdCBncGlvX2NoaXAgKmdjLCB1bnNp Z25lZCBpbnQgZ3BpbykKPiArewo+ICsJc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCA9IGdw aW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBmdGRpX3ByaXZhdGUgKnByaXYgPSB1c2Jf Z2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwlzdHJ1Y3QgdXNiX3NlcmlhbCAqc2VyaWFs ID0gcG9ydC0+c2VyaWFsOwo+ICsJdW5zaWduZWQgY2hhciAqcmN2YnVmOwo+ICsJaW50IHJlc3Vs dDsKPiArCj4gKwlyY3ZidWYgPSBrbWFsbG9jKDEsIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFyY3Zi dWYpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJcmVzdWx0ID0gdXNiX2NvbnRyb2xfbXNn KHNlcmlhbC0+ZGV2LAo+ICsJCQkJIHVzYl9yY3ZjdHJscGlwZShzZXJpYWwtPmRldiwgMCksCj4g KwkJCQkgRlRESV9TSU9fUkVBRF9QSU5TX1JFUVVFU1QsCj4gKwkJCQkgRlRESV9TSU9fUkVBRF9Q SU5TX1JFUVVFU1RfVFlQRSwgMCwKPiArCQkJCSBwcml2LT5pbnRlcmZhY2UsIHJjdmJ1ZiwgMSwg V0RSX1RJTUVPVVQpOwo+ICsJaWYgKHJlc3VsdCA8IDApIHsKPiArCX0gZWxzZSBpZiAocmVzdWx0 IDwgMSkKPiArCQlyZXN1bHQgPSAtRUlPOwo+ICsJZWxzZQo+ICsJCXJlc3VsdCA9ICEhKHJjdmJ1 ZlswXSAmIEJJVChncGlvKSk7CgpJbXBsZW1lbnQgdGhpcyBhcwoKCWlmIChyZXN1bHQgPCAxKSB7 CgkJaWYgKHJlc3VsdCA+PSAwKQoJCQlyZXN1bHQgPSAtRUlPOwoJfSBlbHNlIHsKCQlyZXN1bHQg PSAuLi4KCX0KCndoaWNoIGZvbGxvd3MgYSBjb21tb24gcGF0dGVybiBhbmQgZG9lc24ndCB2aW9s YXRlIHRoZSBjb2Rpbmcgc3R5bGUuCgo+ICsKPiArCWtmcmVlKHJjdmJ1Zik7Cj4gKwo+ICsJcmV0 dXJuIHJlc3VsdDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZnRkaV9ncGlvX3NldChzdHJ1Y3Qg Z3Bpb19jaGlwICpnYywKPiArCQkJICAgICAgdW5zaWduZWQgaW50IGdwaW8sCj4gKwkJCSAgICAg IGludCB2YWx1ZSkKPiArewo+ICsJc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCA9IGdwaW9j aGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBmdGRpX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0 X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwlpbnQgcmVzdWx0Owo+ICsKPiArCWlmICh2YWx1 ZSkKPiArCQlwcml2LT5ncGlvX3ZhbHVlIHw9IEJJVChncGlvKTsKPiArCWVsc2UKPiArCQlwcml2 LT5ncGlvX3ZhbHVlICY9IH5CSVQoZ3Bpbyk7Cj4gKwo+ICsJcmVzdWx0ID0gZnRkaV9zZXRfY2J1 c19waW5zKHBvcnQpOwo+ICsJaWYgKHJlc3VsdCA8IDApIHsKPiArCQlkZXZfZXJyKCZwb3J0LT5z ZXJpYWwtPmludGVyZmFjZS0+ZGV2LAo+ICsJCQkiZmFpbGVkIHRvIHNldCBHUElPIHZhbHVlOiAl ZFxuIiwKPiArCQkJcmVzdWx0KTsKPiArCX0KCllvdSBjb3VsZCBub3cgZHJvcCB0aGUgZGV2X2Vy ciBoZXJlIGlmIHlvdSB3YW50LgoKPiArfQo+ICsKPiArc3RhdGljIGludCBmdGRpX2dwaW9fZGly ZWN0aW9uX2dldChzdHJ1Y3QgZ3Bpb19jaGlwICpnYywKPiArCQkJCSAgICAgICB1bnNpZ25lZCBp bnQgZ3BpbykKCkxvb2tzIGxpa2UgdGhlcmUncyBubyBsb25nZXIgYW55IG5lZWQgZm9yIGEgbGlu ZSBicmVhayBhYm92ZSAoYW5kCmVsc2V3aGVyZT8pLgoKPiArewo+ICsJc3RydWN0IHVzYl9zZXJp YWxfcG9ydCAqcG9ydCA9IGdwaW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBmdGRpX3By aXZhdGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwo+ICsJcmV0 dXJuIHByaXYtPmdwaW9faW5wdXQgJiBCSVQoZ3Bpbyk7CgpSZXR1cm4gMCBvciAxIGhlcmUgYXMg bW9zdCAoYWxsPykgZHJpdmVycyBkby4KCj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZnRkaV9ncGlv X2RpcmVjdGlvbl9pbnB1dChzdHJ1Y3QgZ3Bpb19jaGlwICpnYywKPiArCQkJCQkgdW5zaWduZWQg aW50IGdwaW8pCj4gK3sKPiArCXN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBvcnQgPSBncGlvY2hp cF9nZXRfZGF0YShnYyk7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9z ZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICsKPiArCXByaXYtPmdwaW9faW5wdXQgfD0gQklUKGdw aW8pOwo+ICsKPiArCXJldHVybiBmdGRpX3NldF9jYnVzX3BpbnMocG9ydCk7Cj4gK30KPiArCj4g K3N0YXRpYyBpbnQgZnRkaV9ncGlvX2RpcmVjdGlvbl9vdXRwdXQoc3RydWN0IGdwaW9fY2hpcCAq Z2MsCj4gKwkJCQkJICB1bnNpZ25lZCBpbnQgZ3BpbywKPiArCQkJCQkgIGludCB2YWx1ZSkKPiAr ewo+ICsJc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCA9IGdwaW9jaGlwX2dldF9kYXRhKGdj KTsKPiArCXN0cnVjdCBmdGRpX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2Rh dGEocG9ydCk7Cj4gKwo+ICsJcHJpdi0+Z3Bpb19pbnB1dCAmPSB+QklUKGdwaW8pOwo+ICsJaWYg KHZhbHVlKQo+ICsJCXByaXYtPmdwaW9fdmFsdWUgfD0gQklUKGdwaW8pOwo+ICsJZWxzZQo+ICsJ CXByaXYtPmdwaW9fdmFsdWUgJj0gfkJJVChncGlvKTsKPiArCj4gKwlyZXR1cm4gZnRkaV9zZXRf Y2J1c19waW5zKHBvcnQpOwo+ICt9Cj4gKwo+ICsvKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0 ZXMgcmVhZCAqLwo+ICtzdGF0aWMgaW50IGZ0ZGlfcmVhZF9lZXByb20oc3RydWN0IHVzYl9zZXJp YWwgKnNlcmlhbCwKPiArCQkJICAgIHZvaWQgKmRzdCwJLyogbXVzdCBiZSBrbWFsbG9jJ2QgdXNp bmcgR0ZQX0tFUk5FTCovCgpXaGV0aGVyIEdGUF9LRVJORUwgd2FzIHVzZWQgaXMgbm90IHJlYWxs eSByZWxldmFudCwgYnV0IGhpZ2hsaWdodGluZwp0aGF0IHRoZSBidWZmZXIgbmVlZHMgdG8gYmUg RE1BLWFibGUgaXMgZ29vZC4KCj4gKwkJCSAgICB1MTYgYWRkciwJLyogbXVzdCBiZSBhbGlnbmVk IHRvIDE2IGJpdHMgKi8KPiArCQkJICAgIHUxNiBuYnl0ZXMpCS8qIG11c3QgYmUgYSBtdWx0aXBs ZSBvZiAxNiBiaXRzICovCgpJIHRoaW5rIGNoZWNrcGF0Y2ggZ2V0cyBjb25mdXNlZCBieSB5b3Ug b2RkIGFyZ3VtZW50IGNvbW1lbnRzIGhlcmUuIFVzZQphIGtlcm5lbCBkb2MgY29tbWVudCwgaWYg eW91IHdhbnQgdG8gYmUgdGhpcyBzcGVjaWZpYyBpbnN0ZWFkLgoKPiArewo+ICsJaW50IHJlYWQg PSAwOwo+ICsKPiArCS8qIEFyZ3VtZW50IGNoZWNrcyAqLwoKQ29tbWVudCBub3QgbmVlZGVkLgoK PiArCWlmIChhZGRyICUgMiAhPSAwKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJaWYgKG5ieXRl cyAlIDIgIT0gMCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwkvKiBSZWFkIEVFUFJPTSB0 d28gYnl0ZXMgYXQgYSB0aW1lICovCj4gKwl3aGlsZSAocmVhZCA8IG5ieXRlcykgewo+ICsJCWlu dCBydjsKPiArCj4gKwkJcnYgPSB1c2JfY29udHJvbF9tc2coc2VyaWFsLT5kZXYsCj4gKwkJCQkg ICAgIHVzYl9yY3ZjdHJscGlwZShzZXJpYWwtPmRldiwgMCksCj4gKwkJCQkgICAgIEZURElfU0lP X1JFQURfRUVQUk9NX1JFUVVFU1QsCj4gKwkJCQkgICAgIEZURElfU0lPX1JFQURfRUVQUk9NX1JF UVVFU1RfVFlQRSwKPiArCQkJCSAgICAgMCwgKGFkZHIgKyByZWFkKSAvIDIsIGRzdCArIHJlYWQs IDIsCj4gKwkJCQkgICAgIFdEUl9USU1FT1VUKTsKPiArCQlpZiAocnYgPCAwKQo+ICsJCQlyZXR1 cm4gcnY7Cj4gKwo+ICsJCXJlYWQgKz0gcnY7Cj4gKwo+ICsJCWlmIChydiA8IDIpCj4gKwkJCWJy ZWFrOwoKVHJlYXQgYW55IHNob3J0IHJlYWQgYXMgYW4gZXJyb3IuCgo+ICsJfQo+ICsKPiArCXJl dHVybiByZWFkOwoKSnVzdCByZXR1cm4gMCBvbiBzdWNjZXNzIGFuZCBhbHdheXMgcmV0dXJuIGFz IG1hbnkgYnl0ZXMgYXMgd2FzCnJlcXVlc3RlZC4KCj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZnR4 X2dwaW9jb25mX2luaXQoc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiArewo+ICsJc3Ry dWN0IGZ0ZGlfcHJpdmF0ZSAqcHJpdiA9IHVzYl9nZXRfc2VyaWFsX3BvcnRfZGF0YShwb3J0KTsK PiArCXN0cnVjdCB1c2Jfc2VyaWFsICpzZXJpYWwgPSBwb3J0LT5zZXJpYWw7Cj4gKwljb25zdCB1 MTYgY2J1c19jZmdfYWRkciA9IDB4MWE7Cj4gKwljb25zdCB1MTYgY2J1c19jZmdfc2l6ZSA9IDg7 Cj4gKwl1OCAqY2J1c19jZmdfYnVmOwo+ICsJaW50IHJlc3VsdDsKPiArCXU4IGk7Cj4gKwo+ICsJ LyogUmVhZCBhIHBhcnQgb2YgZGV2aWNlIEVFUFJPTSAqLwo+ICsJY2J1c19jZmdfYnVmID0ga21h bGxvYyhjYnVzX2NmZ19zaXplLCBHRlBfS0VSTkVMKTsKPiArCWlmICghY2J1c19jZmdfYnVmKQo+ ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXJlc3VsdCA9IGZ0ZGlfcmVhZF9lZXByb20oc2Vy aWFsLCBjYnVzX2NmZ19idWYsCj4gKwkJCQkgIGNidXNfY2ZnX2FkZHIsIGNidXNfY2ZnX3NpemUp Owo+ICsKCk5vIGVtcHR5IGxpbmUuCgo+ICsJaWYgKHJlc3VsdCA8IDApCj4gKwkJZ290byBvdXRf ZnJlZTsKPiArCWVsc2UgaWYgKHJlc3VsdCA8IDgpIHsKPiArCQlyZXN1bHQgPSAtRUlPOwoKSnVz dCBoYW5kbGUgdGhpcyBjYXNlIGluIHRoZSBoZWxwZXIuCgo+ICsJCWdvdG8gb3V0X2ZyZWU7Cj4g Kwl9IGVsc2UKPiArCQlyZXN1bHQgPSAwOwoKTm90ZSB0aGF0IHlvdSBuZWVkIGJyYWNrZXRzIG9u IGFsbCBicmFuY2hlcyBhcyBwZXIgdGhlIGNvZGluZyBzdHlsZS4KCj4gKwo+ICsJLyogQ2hpcC10 eXBlIGd1ZXNzaW5nIGxvZ2ljIGJhc2VkIG9uIGxpYmZ0ZGkuICovCj4gKwlwcml2LT5nYy5uZ3Bp byA9IDQ7ICAvKiBGVDIzMFgsIEZUMjMxWCAqLwo+ICsJaWYgKGxlMTZfdG9fY3B1KHNlcmlhbC0+ ZGV2LT5kZXNjcmlwdG9yLmJjZERldmljZSkgIT0gMHgxMDAwKQo+ICsJCXByaXYtPmdjLm5ncGlv ID0gMTsgIC8qIEZUMjM0WEQgKi8KCk5vIGtub3duIHdheSB0byBpZGVudGlmeSBGVDIzNFhEIGhl cmU/CgpBZnRlciB0YWtpbmcgYSBxdWljayBwZWVrIGF0IGxpYmZ0ZGksIGl0IHNlZW1zIHdlIHJl YWxseSBoYXZlIG5vIGNsdWUKaG93IHRvIGRldGVjdCB0aGVzZSBkZXZpY2UgdHlwZXMgYW5kIDB4 MTAwMCBjb3VsZCBiZSBmb3IgYWxsIEZUWApkZXZpY2VzLiBIZWNrLCB0aGUgY3VycmVudCBrZXJu ZWwgZHJpdmVyIGp1c3QgYXNzdW1lcyBhbnl0aGluZyB3ZSBkb24ndApyZWNvZ25pc2UgdG8gYmUg YW4gRlRYLCBzb21ldGhpbmcgd2hpY2ggd291bGQgbm93IGhpdCB0aGlzIGNvZGUgcGF0aC4uLgoK V2hhdCBkZXZpY2VzIGRpZCB5b3UgYW5kIExvaWMgaGF2ZT8gQ291bGQgeW91IHBvc3QgdGhlIGxz dXNiIC12IG91dHB1dApmb3IgdGhlc2U/IFBlcmhhcHMgc29tZW9uZSB3aXRoIGFuIEZUMjM0WEQg Y2FuIGNoaW1lIGluIGFzIHdlbGwuCgo+ICsKPiArCS8qIERldGVybWluZSB3aGljaCBwaW5zIGFy ZSBjb25maWd1cmVkIGZvciBDQlVTIGJpdGJhbmdpbmcgKi8KPiArCXByaXYtPmdwaW9fYWx0ZnVu YyA9IDB4ZmY7Cj4gKwlmb3IgKGkgPSAwOyBpIDwgcHJpdi0+Z2MubmdwaW87ICsraSkgewo+ICsJ CWlmIChjYnVzX2NmZ19idWZbaV0gPT0gRlRESV9TSU9fQ0JVU19NVVhfR1BJTykKPiArCQkJcHJp di0+Z3Bpb19hbHRmdW5jICY9IH5CSVQoaSk7Cj4gKwl9Cj4gKwo+ICtvdXRfZnJlZToKPiArCWtm cmVlKGNidXNfY2ZnX2J1Zik7Cj4gKwo+ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBmdGRpX2dwaW9faW5pdChzdHJ1Y3QgdXNiX3NlcmlhbF9wb3J0ICpwb3J0KQo+ICt7 Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxfcG9ydF9kYXRh KHBvcnQpOwo+ICsJc3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCA9IHBvcnQtPnNlcmlhbDsKPiAr CWludCByZXN1bHQ7Cj4gKwo+ICsJLyogRGV2aWNlLXNwZWNpZmljIGluaXRpYWxpemF0aW9ucyAq Lwo+ICsJc3dpdGNoIChwcml2LT5jaGlwX3R5cGUpIHsKPiArCWNhc2UgRlRYOgo+ICsJCXJlc3Vs dCA9IGZ0eF9ncGlvY29uZl9pbml0KHBvcnQpOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiAr CQlyZXR1cm4gMDsKPiArCX0KPiArCj4gKwlpZiAocmVzdWx0IDwgMCkKPiArCQlyZXR1cm4gcmVz dWx0Owo+ICsKPiArCS8qIFJlZ2lzdGVyIEdQSU8gY2hpcCB0byBrZXJuZWwgKi8KPiArCXByaXYt PmdjLmxhYmVsID0gImZ0ZGktY2J1cyI7Cj4gKwlwcml2LT5nYy5yZXF1ZXN0ID0gZnRkaV9ncGlv X3JlcXVlc3Q7Cj4gKwlwcml2LT5nYy5nZXRfZGlyZWN0aW9uID0gZnRkaV9ncGlvX2RpcmVjdGlv bl9nZXQ7Cj4gKwlwcml2LT5nYy5kaXJlY3Rpb25faW5wdXQgPSBmdGRpX2dwaW9fZGlyZWN0aW9u X2lucHV0Owo+ICsJcHJpdi0+Z2MuZGlyZWN0aW9uX291dHB1dCA9IGZ0ZGlfZ3Bpb19kaXJlY3Rp b25fb3V0cHV0Owo+ICsJcHJpdi0+Z2MuZ2V0ID0gZnRkaV9ncGlvX2dldDsKPiArCXByaXYtPmdj LnNldCA9IGZ0ZGlfZ3Bpb19zZXQ7Cj4gKwlwcml2LT5nYy5vd25lciA9IFRISVNfTU9EVUxFOwo+ ICsJcHJpdi0+Z2MucGFyZW50ID0gJnNlcmlhbC0+aW50ZXJmYWNlLT5kZXY7Cj4gKwlwcml2LT5n Yy5iYXNlID0gLTE7Cj4gKwlwcml2LT5nYy5jYW5fc2xlZXAgPSB0cnVlOwo+ICsKPiArCXJlc3Vs dCA9IGdwaW9jaGlwX2FkZF9kYXRhKCZwcml2LT5nYywgcG9ydCk7Cj4gKwlpZiAoIXJlc3VsdCkK PiArCQlwcml2LT5ncGlvX3JlZ2lzdGVyZWQgPSB0cnVlOwo+ICsKPiArCXJldHVybiByZXN1bHQ7 Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGZ0ZGlfZ3Bpb19yZW1vdmUoc3RydWN0IHVzYl9zZXJp YWxfcG9ydCAqcG9ydCkKPiArewo+ICsJc3RydWN0IGZ0ZGlfcHJpdmF0ZSAqcHJpdiA9IHVzYl9n ZXRfc2VyaWFsX3BvcnRfZGF0YShwb3J0KTsKPiArCj4gKwlpZiAocHJpdi0+Z3Bpb191c2VkKSB7 Cj4gKwkJLyogUmVtYXJrOiBFeGl0aW5nIENCVVMtbW9kZSBkb2VzIG5vdCByZXNldCBwaW4gc3Rh dGVzIHRvbyAqLwo+ICsJCWZ0ZGlfZXhpdF9jYnVzX21vZGUocG9ydCk7Cj4gKwkJcHJpdi0+Z3Bp b191c2VkID0gZmFsc2U7Cj4gKwl9Cj4gKwo+ICsJaWYgKHByaXYtPmdwaW9fcmVnaXN0ZXJlZCkg ewo+ICsJCWdwaW9jaGlwX3JlbW92ZSgmcHJpdi0+Z2MpOwo+ICsJCXByaXYtPmdwaW9fcmVnaXN0 ZXJlZCA9IGZhbHNlOwo+ICsJfQo+ICt9Cj4gKwo+ICsjZWxzZQo+ICsKPiArc3RhdGljIGludCBm dGRpX2dwaW9faW5pdChzdHJ1Y3QgdXNiX3NlcmlhbF9wb3J0ICpwb3J0KQo+ICt7Cj4gKwlyZXR1 cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZnRkaV9ncGlvX3JlbW92ZShzdHJ1Y3QgdXNi X3NlcmlhbF9wb3J0ICpwb3J0KSB7IH0KPiArCj4gKyNlbmRpZgo+ICsKPiAgLyoKPiAgICogKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqCj4gICAqIEZUREkgZHJpdmVyIHNwZWNpZmljIGZ1bmN0aW9ucwo+IEBA IC0xNzk0LDcgKzIxMDAsNyBAQCBzdGF0aWMgaW50IGZ0ZGlfc2lvX3BvcnRfcHJvYmUoc3RydWN0 IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiAgewo+ICAJc3RydWN0IGZ0ZGlfcHJpdmF0ZSAqcHJp djsKPiAgCWNvbnN0IHN0cnVjdCBmdGRpX3Npb19xdWlyayAqcXVpcmsgPSB1c2JfZ2V0X3Nlcmlh bF9kYXRhKHBvcnQtPnNlcmlhbCk7Cj4gLQo+ICsJaW50IHJlc3VsdDsKPiAgCj4gIAlwcml2ID0g a3phbGxvYyhzaXplb2Yoc3RydWN0IGZ0ZGlfcHJpdmF0ZSksIEdGUF9LRVJORUwpOwo+ICAJaWYg KCFwcml2KQo+IEBAIC0xODEzLDYgKzIxMTksMTQgQEAgc3RhdGljIGludCBmdGRpX3Npb19wb3J0 X3Byb2JlKHN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBvcnQpCj4gIAkJcHJpdi0+bGF0ZW5jeSA9 IDE2Owo+ICAJd3JpdGVfbGF0ZW5jeV90aW1lcihwb3J0KTsKPiAgCWNyZWF0ZV9zeXNmc19hdHRy cyhwb3J0KTsKPiArCj4gKwlyZXN1bHQgPSBmdGRpX2dwaW9faW5pdChwb3J0KTsKPiArCWlmIChy ZXN1bHQgPCAwKSB7Cj4gKwkJZGV2X2VycigmcG9ydC0+c2VyaWFsLT5pbnRlcmZhY2UtPmRldiwK PiArCQkJIkdQSU8gaW5pdGlhbGlzYXRpb24gZmFpbGVkOiAlZFxuIiwKPiArCQkJcmVzdWx0KTsK PiArCX0KPiArCj4gIAlyZXR1cm4gMDsKPiAgfQo+ICAKPiBAQCAtMTkzMCw2ICsyMjQ0LDggQEAg c3RhdGljIGludCBmdGRpX3Npb19wb3J0X3JlbW92ZShzdHJ1Y3QgdXNiX3NlcmlhbF9wb3J0ICpw b3J0KQo+ICB7Cj4gIAlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxf cG9ydF9kYXRhKHBvcnQpOwo+ICAKPiArCWZ0ZGlfZ3Bpb19yZW1vdmUocG9ydCk7Cj4gKwo+ICAJ cmVtb3ZlX3N5c2ZzX2F0dHJzKHBvcnQpOwo+ICAKPiAgCWtmcmVlKHByaXYpOwo+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL3VzYi9zZXJpYWwvZnRkaV9zaW8uaCBiL2RyaXZlcnMvdXNiL3NlcmlhbC9m dGRpX3Npby5oCj4gaW5kZXggZGNkMGI2ZTA1YmFmLi41YTI5NmU5ZTg3YTIgMTAwNjQ0Cj4gLS0t IGEvZHJpdmVycy91c2Ivc2VyaWFsL2Z0ZGlfc2lvLmgKPiArKysgYi9kcml2ZXJzL3VzYi9zZXJp YWwvZnRkaV9zaW8uaAo+IEBAIC0zNSw3ICszNSwxMCBAQAo+ICAjZGVmaW5lIEZURElfU0lPX1NF VF9FVkVOVF9DSEFSCQk2IC8qIFNldCB0aGUgZXZlbnQgY2hhcmFjdGVyICovCj4gICNkZWZpbmUg RlRESV9TSU9fU0VUX0VSUk9SX0NIQVIJCTcgLyogU2V0IHRoZSBlcnJvciBjaGFyYWN0ZXIgKi8K PiAgI2RlZmluZSBGVERJX1NJT19TRVRfTEFURU5DWV9USU1FUgk5IC8qIFNldCB0aGUgbGF0ZW5j eSB0aW1lciAqLwo+IC0jZGVmaW5lIEZURElfU0lPX0dFVF9MQVRFTkNZX1RJTUVSCTEwIC8qIEdl dCB0aGUgbGF0ZW5jeSB0aW1lciAqLwo+ICsjZGVmaW5lIEZURElfU0lPX0dFVF9MQVRFTkNZX1RJ TUVSCTB4MGEgLyogR2V0IHRoZSBsYXRlbmN5IHRpbWVyICovCj4gKyNkZWZpbmUgRlRESV9TSU9f U0VUX0JJVE1PREUJCTB4MGIgLyogU2V0IENCVVMgR1BJTyBwaW4gbW9kZSAqLwoKVGhhdCBjb21t ZW50IGlzIHRvbyBzcGVjaWZpYy4gSXQncyBqdXN0IHVzZWQgdG8gc2V0ICphKiBiaXRiYW5nIG1v ZGUsCnJpZ2h0PwoKPiArI2RlZmluZSBGVERJX1NJT19SRUFEX1BJTlMJCTB4MGMgLyogUmVhZCBp bW1lZGlhdGUgdmFsdWUgb2YgcGlucyAqLwo+ICsjZGVmaW5lIEZURElfU0lPX1JFQURfRUVQUk9N CQkweDkwIC8qIFJlYWQgRUVQUk9NICovCj4gIAo+ICAvKiBJbnRlcmZhY2UgaW5kaWNlcyBmb3Ig RlQyMjMyLCBGVDIyMzJIIGFuZCBGVDQyMzJIIGRldmljZXMgKi8KPiAgI2RlZmluZSBJTlRFUkZB Q0VfQQkJMQo+IEBAIC00MzMsNiArNDM2LDI4IEBAIGVudW0gZnRkaV9zaW9fYmF1ZHJhdGUgewo+ ICAgKiAgICAgICAgIDEgPSBhY3RpdmUKPiAgICovCj4gIAo+ICsvKiBGVERJX1NJT19TRVRfQklU TU9ERSAqLwo+ICsjZGVmaW5lIEZURElfU0lPX1NFVF9CSVRNT0RFX1JFUVVFU1RfVFlQRSAweDQw Cj4gKyNkZWZpbmUgRlRESV9TSU9fU0VUX0JJVE1PREVfUkVRVUVTVCBGVERJX1NJT19TRVRfQklU TU9ERQo+ICsKPiArLyogUG9zc2libGUgYml0bW9kZXMgZm9yIEZURElfU0lPX1NFVF9CSVRNT0RF X1JFUVVFU1QgKi8KPiArI2RlZmluZSBGVERJX1NJT19CSVRNT0RFX1JFU0VUCQkweDAwCj4gKyNk ZWZpbmUgRlRESV9TSU9fQklUTU9ERV9DQlVTCQkweDIwCj4gKwo+ICsvKiBGVERJX1NJT19SRUFE X1BJTlMgKi8KPiArI2RlZmluZSBGVERJX1NJT19SRUFEX1BJTlNfUkVRVUVTVF9UWVBFIDB4YzAK PiArI2RlZmluZSBGVERJX1NJT19SRUFEX1BJTlNfUkVRVUVTVCBGVERJX1NJT19SRUFEX1BJTlMK PiArCj4gKy8qCj4gKyAqIEZURElfU0lPX1JFQURfRUVQUk9NCj4gKyAqCj4gKyAqIEVFUFJPTSBm b3JtYXQgZm91bmQgaW4gRlRESSBBTl8yMDEsICJGVC1YIE1UUCBtZW1vcnkgQ29uZmlndXJhdGlv biIsCj4gKyAqIGh0dHA6Ly93d3cuZnRkaWNoaXAuY29tL1N1cHBvcnQvRG9jdW1lbnRzL0FwcE5v dGVzL0FOXzIwMV9GVC1YJTIwTVRQJTIwTWVtb3J5JTIwQ29uZmlndXJhdGlvbi5wZGYKPiArICov Cj4gKyNkZWZpbmUgRlRESV9TSU9fUkVBRF9FRVBST01fUkVRVUVTVF9UWVBFIDB4YzAKPiArI2Rl ZmluZSBGVERJX1NJT19SRUFEX0VFUFJPTV9SRVFVRVNUIEZURElfU0lPX1JFQURfRUVQUk9NCj4g Kwo+ICsjZGVmaW5lIEZURElfU0lPX0NCVVNfTVVYX0dQSU8JCTgKCkFnYWluLCB0aGlzIG9uZSBp cyBGVFggc3BlY2lmaWMgYW5kIHdhcnJhbnRzIGFuIEZUWCBpbmZpeCAoaW5zdGVhZCBvZgpTSU8p LgoKSm9oYW4K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.4 required=3.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,SPF_PASS,T_DKIM_INVALID,URIBL_BLOCKED,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F3EFFC6182 for ; Fri, 14 Sep 2018 16:12:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8402C2083A for ; Fri, 14 Sep 2018 16:12:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="tgULJAp3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8402C2083A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728153AbeINV1H (ORCPT ); Fri, 14 Sep 2018 17:27:07 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:46938 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726900AbeINV1H (ORCPT ); Fri, 14 Sep 2018 17:27:07 -0400 Received: by mail-lj1-f196.google.com with SMTP id 203-v6so7951046ljj.13; Fri, 14 Sep 2018 09:11:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=IQmdHxD3CoBeeWnOIi78CA4wBxNbrQghy38GaLKArPE=; b=tgULJAp3c3UwTzC8YxOFQaVcS0x5TN6N1B7+7NODdcoFSezhHhzD2ozkknZIaijXSf D8cRHVQ8PKl2OIroW3zMRnv7i5yNl6B9/a764SYZmk8zCjQHZYPx9sSFURaV1JhM1NOm Z1nQ4RIYsPKetXSV2zutyHZVgPcwkVphKm6KKC9+f+kHc//JFOVBmrt5poSqAT8owG5+ PnnwuShtKZnyOeEns4UzWPBMs8cKb2mSW8w3KwfuxoVuhB6QoGxuWM6yRQk5PBNgH58g WPasG2j++48x1JRzswjIe3aTlPMSDojUYyq8pyayjq3eLwywc6qMGELYf+DJXhzfHjff bKtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=IQmdHxD3CoBeeWnOIi78CA4wBxNbrQghy38GaLKArPE=; b=MuclXD4cyGBwMjBCZpBrf4ThPde1be3gGnEDK0fZpIsQUTamJ+UNXZVndFsWLMFA/c s+11pCK/mdzPEq7gGs+MRgSBP63WOLECYCtfLrBYN44nnExcG98WKoRn9go/yuEUEYAL Bidv+wyrl4nuUpdEApmKZKSZG4Oo22+yxwnoBZeuS9iA7qABrHVpLhf3lBTwOQm49+MF Pzt7nb1oPFS9aQZgZ/n+N8vU/0pX+9wqknj+EOZmTgsP9iVDW6JzOVJDc2LEOzEUf36+ f62Db4qL9GqOhCaVsXI83NtgfQ4mz9WF7EnhO8nChrluJfkBoKlmOSronMKhHeMijWkm fSxA== X-Gm-Message-State: APzg51Ajkzls15RuWcg611lY5XXS7A7Yl+KsJgxJDNt13IsEyRnCQmSD K4qrEUZU3wEIn4Y/zgbHIHwhcJUL X-Google-Smtp-Source: ANB0VdbsA9+wXUIdKhO6r2gz8eovaMLkdNbX4bnUBQXFvHeLfObnn3XCmw+7MVpDSa76eie7hu0xow== X-Received: by 2002:a2e:8513:: with SMTP id j19-v6mr8290070lji.10.1536941513661; Fri, 14 Sep 2018 09:11:53 -0700 (PDT) Received: from xi.terra (c-74bee655.07-184-6d6c6d4.bbcust.telenor.se. [85.230.190.116]) by smtp.gmail.com with ESMTPSA id v14-v6sm1237959lji.80.2018.09.14.09.11.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Sep 2018 09:11:52 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.91) (envelope-from ) id 1g0qhH-0006Ny-Ej; Fri, 14 Sep 2018 18:11:55 +0200 Date: Fri, 14 Sep 2018 18:11:55 +0200 From: Johan Hovold To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Loic Poulain Subject: Re: [PATCH v3] USB: serial: ftdi_sio: implement GPIO support for FT-X devices Message-ID: <20180914161155.GB3443@localhost> References: <20180910174322.1042-1-pados@pados.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180910174322.1042-1-pados@pados.hu> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Sep 10, 2018 at 07:43:22PM +0200, Karoly Pados wrote: > This patch allows using the CBUS pins of FT-X devices as GPIO in CBUS > bitbanging mode. There is no conflict between the GPIO and VCP > functionality in this mode. Tested on FT230X and FT231X. > > As there is no way to request the current CBUS register configuration > from the device, all CBUS pins are set to a known state when the first > GPIO is requested. This allows using libftdi to set the GPIO pins > before loading this module for UART functionality, a behavior that > existing applications might be relying upon (though no specific case > is known to the authors of this patch). > > Signed-off-by: Karoly Pados > --- > > Changelog: > - v2: Fix compile error when CONFIG_GPIOLIB is not defined. > - v3: Incorporate review feedback. Next time, please be more specific about what you changed here. > Though there is no code copied, libftdi was used as > a reference. ftdi_read_eeprom is based on Loic Poulain's patch. > > I've removed --strict from checkpatch.pl invocation, yet it still gives > me those warnings it shouldn't. Maybe I have a different version? Now > in v3 I also get two new I'm not sure how to deal with. Rest of text > below same as before. Yeah, the two new ones I get too, and they need to be fixed. More below. > I noticed there have been numerous historic attempts by other people at > adding GPIO support to ftdi_sio. One tried adding it in some very > application-specific way, another one tried to use the mfd framework, the > tried using a GPIO mode which is mutually exclusive to VCP, another > one did not implement the review results etc... I hope I learned from those > attempts and am planning to respond to reviews. Also, this patch follows > the rough structure of the GPIO support for cp210x devices that have > already been accepted, in the hope that it is a good starting point. > > This patch uses CBUS bitbanging mode, which works nicely in parallel with > the VCP function. The other modes do not, and so IMHO it does not make > sense to try adding them to this same module. > > For this device, whenever changing the state of any single pin, all the > others need to be written too. This means in order to change any pin, we > need to know the current state of all the others. So when using GPIO, > we need to have a known starting state for all pins, but there seems to > be no way to retrieve the existing GPIO configuration (directions and > output register values). The way I handle this in this patch is that when > requesting a GPIO for the first time, the module initializes all pins to > a known default state (to inputs). Input was chosen, because a potentially > floating pin is better than a potential driver conflict, because the latter > could result in hardware damage. However, if the user does not request a > GPIO, the CBUS pins are not initialized, avoiding unnecessarily changing > hardware state. I figured I cannot rely on the default power-on state of > the device for this as the user might have used libftdi before loading > our module. When the module is unloaded, CBUS bitbanging mode is exited > if it were us who entered it earlier. > > > drivers/usb/serial/ftdi_sio.c | 318 +++++++++++++++++++++++++++++++++- > drivers/usb/serial/ftdi_sio.h | 27 ++- > 2 files changed, 343 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c > index b5cef322826f..00b6c6abdd09 100644 > --- a/drivers/usb/serial/ftdi_sio.c > +++ b/drivers/usb/serial/ftdi_sio.c > @@ -40,6 +40,9 @@ > #include > #include > #include > +#if defined(CONFIG_GPIOLIB) > +#include > +#endif Hmm. I already commented on this in v1. > #include "ftdi_sio.h" > #include "ftdi_sio_ids.h" > > @@ -72,6 +75,14 @@ struct ftdi_private { > unsigned int latency; /* latency setting in use */ > unsigned short max_packet_size; > struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ > +#if defined(CONFIG_GPIOLIB) > + struct gpio_chip gc; > + bool gpio_registered; /* is the gpiochip in kernel registered */ > + bool gpio_used; /* true if the user requested a gpio */ > + u8 gpio_altfunc; /* which pins are in gpio mode */ > + u8 gpio_input; /* pin directions cache */ And I asked you to invert this one (i.e. replace with gpio_output). > + u8 gpio_value; /* pin value for outputs */ > +#endif > }; > > /* struct ftdi_sio_quirk is used by devices requiring special attention. */ > @@ -1766,6 +1777,301 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) > > } > > +#if defined(CONFIG_GPIOLIB) > + > +static int ftdi_set_bitmode_req(struct usb_serial_port *port, u8 mode) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + int result; > + u16 val; > + > + /* device's direction polarity is different from kernel's */ > + u8 direction = (~priv->gpio_input) & 0x0f; > + > + val = (mode << 8) | (direction << 4) | (priv->gpio_value & 0x0f); > + result = usb_control_msg(serial->dev, > + usb_sndctrlpipe(serial->dev, 0), > + FTDI_SIO_SET_BITMODE_REQUEST, > + FTDI_SIO_SET_BITMODE_REQUEST_TYPE, val, > + priv->interface, NULL, 0, WDR_TIMEOUT); > + And I asked you to remove such empty lines. > + if (result < 0) { > + dev_err(&serial->interface->dev, > + "bitmode request failed for value: %d\n", Use hex notation and include the errno: "bitmode request failed for value 0x%04x: %d\n", val, result > + } > + > + return result; > +} > + > +static int ftdi_set_cbus_pins(struct usb_serial_port *port) > +{ > + return ftdi_set_bitmode_req(port, FTDI_SIO_BITMODE_CBUS); > +} > + > +static int ftdi_exit_cbus_mode(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + priv->gpio_input = 0; > + priv->gpio_value = 0; > + return ftdi_set_bitmode_req(port, FTDI_SIO_BITMODE_RESET); > +} > + > +static int ftdi_gpio_request(struct gpio_chip *gc, unsigned int offset) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + int result; > + > + if (priv->gpio_altfunc & BIT(offset)) > + return -ENODEV; > + > + if (!priv->gpio_used) { > + /* Set default pin states, as we cannot get them from device */ > + priv->gpio_input = 0xff; > + priv->gpio_value = 0x00; > + result = ftdi_set_cbus_pins(port); > + if (result) > + return result; > + > + priv->gpio_used = true; > + } > + > + return 0; > +} > + > +static int ftdi_gpio_get(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + unsigned char *rcvbuf; > + int result; > + > + rcvbuf = kmalloc(1, GFP_KERNEL); > + if (!rcvbuf) > + return -ENOMEM; > + > + result = usb_control_msg(serial->dev, > + usb_rcvctrlpipe(serial->dev, 0), > + FTDI_SIO_READ_PINS_REQUEST, > + FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, > + priv->interface, rcvbuf, 1, WDR_TIMEOUT); > + if (result < 0) { > + } else if (result < 1) > + result = -EIO; > + else > + result = !!(rcvbuf[0] & BIT(gpio)); Implement this as if (result < 1) { if (result >= 0) result = -EIO; } else { result = ... } which follows a common pattern and doesn't violate the coding style. > + > + kfree(rcvbuf); > + > + return result; > +} > + > +static void ftdi_gpio_set(struct gpio_chip *gc, > + unsigned int gpio, > + int value) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + int result; > + > + if (value) > + priv->gpio_value |= BIT(gpio); > + else > + priv->gpio_value &= ~BIT(gpio); > + > + result = ftdi_set_cbus_pins(port); > + if (result < 0) { > + dev_err(&port->serial->interface->dev, > + "failed to set GPIO value: %d\n", > + result); > + } You could now drop the dev_err here if you want. > +} > + > +static int ftdi_gpio_direction_get(struct gpio_chip *gc, > + unsigned int gpio) Looks like there's no longer any need for a line break above (and elsewhere?). > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + return priv->gpio_input & BIT(gpio); Return 0 or 1 here as most (all?) drivers do. > +} > + > +static int ftdi_gpio_direction_input(struct gpio_chip *gc, > + unsigned int gpio) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + priv->gpio_input |= BIT(gpio); > + > + return ftdi_set_cbus_pins(port); > +} > + > +static int ftdi_gpio_direction_output(struct gpio_chip *gc, > + unsigned int gpio, > + int value) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + priv->gpio_input &= ~BIT(gpio); > + if (value) > + priv->gpio_value |= BIT(gpio); > + else > + priv->gpio_value &= ~BIT(gpio); > + > + return ftdi_set_cbus_pins(port); > +} > + > +/* Returns the number of bytes read */ > +static int ftdi_read_eeprom(struct usb_serial *serial, > + void *dst, /* must be kmalloc'd using GFP_KERNEL*/ Whether GFP_KERNEL was used is not really relevant, but highlighting that the buffer needs to be DMA-able is good. > + u16 addr, /* must be aligned to 16 bits */ > + u16 nbytes) /* must be a multiple of 16 bits */ I think checkpatch gets confused by you odd argument comments here. Use a kernel doc comment, if you want to be this specific instead. > +{ > + int read = 0; > + > + /* Argument checks */ Comment not needed. > + if (addr % 2 != 0) > + return -EINVAL; > + if (nbytes % 2 != 0) > + return -EINVAL; > + > + /* Read EEPROM two bytes at a time */ > + while (read < nbytes) { > + int rv; > + > + rv = usb_control_msg(serial->dev, > + usb_rcvctrlpipe(serial->dev, 0), > + FTDI_SIO_READ_EEPROM_REQUEST, > + FTDI_SIO_READ_EEPROM_REQUEST_TYPE, > + 0, (addr + read) / 2, dst + read, 2, > + WDR_TIMEOUT); > + if (rv < 0) > + return rv; > + > + read += rv; > + > + if (rv < 2) > + break; Treat any short read as an error. > + } > + > + return read; Just return 0 on success and always return as many bytes as was requested. > +} > + > +static int ftx_gpioconf_init(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + const u16 cbus_cfg_addr = 0x1a; > + const u16 cbus_cfg_size = 8; > + u8 *cbus_cfg_buf; > + int result; > + u8 i; > + > + /* Read a part of device EEPROM */ > + cbus_cfg_buf = kmalloc(cbus_cfg_size, GFP_KERNEL); > + if (!cbus_cfg_buf) > + return -ENOMEM; > + > + result = ftdi_read_eeprom(serial, cbus_cfg_buf, > + cbus_cfg_addr, cbus_cfg_size); > + No empty line. > + if (result < 0) > + goto out_free; > + else if (result < 8) { > + result = -EIO; Just handle this case in the helper. > + goto out_free; > + } else > + result = 0; Note that you need brackets on all branches as per the coding style. > + > + /* Chip-type guessing logic based on libftdi. */ > + priv->gc.ngpio = 4; /* FT230X, FT231X */ > + if (le16_to_cpu(serial->dev->descriptor.bcdDevice) != 0x1000) > + priv->gc.ngpio = 1; /* FT234XD */ No known way to identify FT234XD here? After taking a quick peek at libftdi, it seems we really have no clue how to detect these device types and 0x1000 could be for all FTX devices. Heck, the current kernel driver just assumes anything we don't recognise to be an FTX, something which would now hit this code path... What devices did you and Loic have? Could you post the lsusb -v output for these? Perhaps someone with an FT234XD can chime in as well. > + > + /* Determine which pins are configured for CBUS bitbanging */ > + priv->gpio_altfunc = 0xff; > + for (i = 0; i < priv->gc.ngpio; ++i) { > + if (cbus_cfg_buf[i] == FTDI_SIO_CBUS_MUX_GPIO) > + priv->gpio_altfunc &= ~BIT(i); > + } > + > +out_free: > + kfree(cbus_cfg_buf); > + > + return result; > +} > + > +static int ftdi_gpio_init(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + int result; > + > + /* Device-specific initializations */ > + switch (priv->chip_type) { > + case FTX: > + result = ftx_gpioconf_init(port); > + break; > + default: > + return 0; > + } > + > + if (result < 0) > + return result; > + > + /* Register GPIO chip to kernel */ > + priv->gc.label = "ftdi-cbus"; > + priv->gc.request = ftdi_gpio_request; > + priv->gc.get_direction = ftdi_gpio_direction_get; > + priv->gc.direction_input = ftdi_gpio_direction_input; > + priv->gc.direction_output = ftdi_gpio_direction_output; > + priv->gc.get = ftdi_gpio_get; > + priv->gc.set = ftdi_gpio_set; > + priv->gc.owner = THIS_MODULE; > + priv->gc.parent = &serial->interface->dev; > + priv->gc.base = -1; > + priv->gc.can_sleep = true; > + > + result = gpiochip_add_data(&priv->gc, port); > + if (!result) > + priv->gpio_registered = true; > + > + return result; > +} > + > +static void ftdi_gpio_remove(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + if (priv->gpio_used) { > + /* Remark: Exiting CBUS-mode does not reset pin states too */ > + ftdi_exit_cbus_mode(port); > + priv->gpio_used = false; > + } > + > + if (priv->gpio_registered) { > + gpiochip_remove(&priv->gc); > + priv->gpio_registered = false; > + } > +} > + > +#else > + > +static int ftdi_gpio_init(struct usb_serial_port *port) > +{ > + return 0; > +} > + > +static void ftdi_gpio_remove(struct usb_serial_port *port) { } > + > +#endif > + > /* > * *************************************************************************** > * FTDI driver specific functions > @@ -1794,7 +2100,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) > { > struct ftdi_private *priv; > const struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); > - > + int result; > > priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); > if (!priv) > @@ -1813,6 +2119,14 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) > priv->latency = 16; > write_latency_timer(port); > create_sysfs_attrs(port); > + > + result = ftdi_gpio_init(port); > + if (result < 0) { > + dev_err(&port->serial->interface->dev, > + "GPIO initialisation failed: %d\n", > + result); > + } > + > return 0; > } > > @@ -1930,6 +2244,8 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) > { > struct ftdi_private *priv = usb_get_serial_port_data(port); > > + ftdi_gpio_remove(port); > + > remove_sysfs_attrs(port); > > kfree(priv); > diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h > index dcd0b6e05baf..5a296e9e87a2 100644 > --- a/drivers/usb/serial/ftdi_sio.h > +++ b/drivers/usb/serial/ftdi_sio.h > @@ -35,7 +35,10 @@ > #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ > #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ > #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ > -#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ > +#define FTDI_SIO_GET_LATENCY_TIMER 0x0a /* Get the latency timer */ > +#define FTDI_SIO_SET_BITMODE 0x0b /* Set CBUS GPIO pin mode */ That comment is too specific. It's just used to set *a* bitbang mode, right? > +#define FTDI_SIO_READ_PINS 0x0c /* Read immediate value of pins */ > +#define FTDI_SIO_READ_EEPROM 0x90 /* Read EEPROM */ > > /* Interface indices for FT2232, FT2232H and FT4232H devices */ > #define INTERFACE_A 1 > @@ -433,6 +436,28 @@ enum ftdi_sio_baudrate { > * 1 = active > */ > > +/* FTDI_SIO_SET_BITMODE */ > +#define FTDI_SIO_SET_BITMODE_REQUEST_TYPE 0x40 > +#define FTDI_SIO_SET_BITMODE_REQUEST FTDI_SIO_SET_BITMODE > + > +/* Possible bitmodes for FTDI_SIO_SET_BITMODE_REQUEST */ > +#define FTDI_SIO_BITMODE_RESET 0x00 > +#define FTDI_SIO_BITMODE_CBUS 0x20 > + > +/* FTDI_SIO_READ_PINS */ > +#define FTDI_SIO_READ_PINS_REQUEST_TYPE 0xc0 > +#define FTDI_SIO_READ_PINS_REQUEST FTDI_SIO_READ_PINS > + > +/* > + * FTDI_SIO_READ_EEPROM > + * > + * EEPROM format found in FTDI AN_201, "FT-X MTP memory Configuration", > + * http://www.ftdichip.com/Support/Documents/AppNotes/AN_201_FT-X%20MTP%20Memory%20Configuration.pdf > + */ > +#define FTDI_SIO_READ_EEPROM_REQUEST_TYPE 0xc0 > +#define FTDI_SIO_READ_EEPROM_REQUEST FTDI_SIO_READ_EEPROM > + > +#define FTDI_SIO_CBUS_MUX_GPIO 8 Again, this one is FTX specific and warrants an FTX infix (instead of SIO). Johan