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: [RFC,v2,11/15] usb:cdns3: Implements ISR functionality. From: Roger Quadros Message-Id: <5BFEAC14.1030408@ti.com> Date: Wed, 28 Nov 2018 16:54:12 +0200 To: Pawel Laszczak , devicetree@vger.kernel.org Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, adouglas@cadence.com, jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, pjez@cadence.com, kurahul@cadence.com List-ID: T24gMTgvMTEvMTggMTI6MDksIFBhd2VsIExhc3pjemFrIHdyb3RlOgo+IFBhdGNoIGFkZHMgc2V0 IG9mIGdlbmVyaWMgZnVuY3Rpb25zIHVzZWQgZm9yIGhhbmRsaW5nIGludGVycnVwdHMKPiBnZW5l cmF0ZWQgYnkgY29udHJvbGxlci4gSW50ZXJydXB0IHJlbGF0ZWQgZnVuY3Rpb25zIGFyZSBkaXZp ZGVkCj4gaW50byB0aHJlZSBncm91cHMuIFRoZSBmaXJzdCBpcyByZWxhdGVkIHRvIGVwMCBhbmQg aXMgcGxhY2VkIGluIGVwMC5jLgo+IFRoZSBzZWNvbmQgaXMgcmVzcG9uc2libGUgZm9yIG5vbi1k ZWZhdWx0IGVuZHBvaW50cyBhbmQgaXMKPiBpbXBsZW1lbnRlZCBpbiBnYWRnZXQuYyBmaWxlLiBU aGUgbGFzdCBncm91cCBpcyBub3QgcmVsYXRlZCB0bwo+IGVuZHBvaW50cyBpbnRlcnJ1cHRzIGFu ZCBpcyBwbGFjZWQgaW4gZ2FkZ2V0LmMuCj4gQWxsIGdyb3VwcyBoYXZlIGNvbW1vbiBlbnRyeSBw b2ludCBpbiBjZG5zM19pcnFfaGFuZGxlcl90aHJlYWQgZnVuY3Rpb24uCj4gCj4gU2lnbmVkLW9m Zi1ieTogUGF3ZWwgTGFzemN6YWsgPHBhd2VsbEBjYWRlbmNlLmNvbT4KPiAtLS0KPiAgZHJpdmVy cy91c2IvY2RuczMvZXAwLmMgICAgfCAgNjMgKysrKysrKysrKysKPiAgZHJpdmVycy91c2IvY2Ru czMvZ2FkZ2V0LmMgfCAyMjQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQo+ ICBkcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuaCB8ICAgMSArCj4gIDMgZmlsZXMgY2hhbmdlZCwg Mjg3IGluc2VydGlvbnMoKyksIDEgZGVsZXRpb24oLSkKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVy cy91c2IvY2RuczMvZXAwLmMgYi9kcml2ZXJzL3VzYi9jZG5zMy9lcDAuYwo+IGluZGV4IGQwNTE2 OWU3MzYzMS4uZWI5MmZkMjM0YmQ3IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvdXNiL2NkbnMzL2Vw MC5jCj4gKysrIGIvZHJpdmVycy91c2IvY2RuczMvZXAwLmMKPiBAQCAtOTAsNiArOTAsNjkgQEAg c3RhdGljIHZvaWQgY2RuczNfc2V0X2h3X2NvbmZpZ3VyYXRpb24oc3RydWN0IGNkbnMzX2Rldmlj ZSAqcHJpdl9kZXYpCj4gIAl9Cj4gIH0KPiAgCj4gK3N0YXRpYyB2b2lkIF9fcGVuZGluZ19zZXR1 cF9zdGF0dXNfaGFuZGxlcihzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldikKPiArewo+ICsJ Ly9UT0RPOiBJbXBsZW1lbnRzIHRoaXMgZnVuY3Rpb24KPiArfQo+ICsKPiArLyoqCj4gKyAqIGNk bnMzX2VwMF9zZXR1cF9waGFzZSAtIEhhbmRsaW5nIHNldHVwIFVTQiByZXF1ZXN0cwo+ICsgKiBA cHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICovCj4gK3N0YXRpYyB2b2lkIGNk bnMzX2VwMF9zZXR1cF9waGFzZShzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldikKPiArewo+ ICsJLy9UT0RPOiBJbXBsZW1lbnRzIHRoaXMgZnVuY3Rpb24uCj4gK30KPiArCj4gK3N0YXRpYyB2 b2lkIGNkbnMzX3RyYW5zZmVyX2NvbXBsZXRlZChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2Rl dikKPiArewo+ICsJLy9UT0RPOiBJbXBsZW1lbnRzIHRoaXMgZnVuY3Rpb24KPiArfQo+ICsKPiAr LyoqCj4gKyAqIGNkbnMzX2NoZWNrX2VwMF9pbnRlcnJ1cHRfcHJvY2VlZCAtIFByb2Nlc3NlcyBp bnRlcnJ1cHQgcmVsYXRlZCB0byBlbmRwb2ludCAwCj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQg Z2FkZ2V0IG9iamVjdAo+ICsgKiBAZGlyOiAxIGZvciBJTiBkaXJlY3Rpb24sIDAgZm9yIE9VVCBk aXJlY3Rpb24KPiArICovCj4gK3ZvaWQgY2RuczNfY2hlY2tfZXAwX2ludGVycnVwdF9wcm9jZWVk KHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LCBpbnQgZGlyKQo+ICt7Cj4gKwlzdHJ1Y3Qg Y2RuczNfdXNiX3JlZ3MgX19pb21lbSAqcmVncyA9IHByaXZfZGV2LT5yZWdzOwo+ICsJdTMyIGVw X3N0c19yZWc7Cj4gKwo+ICsJY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCAwIHwgKGRpciA/IFVT Ql9ESVJfSU4gOiBVU0JfRElSX09VVCkpOwo+ICsJZXBfc3RzX3JlZyA9IHJlYWRsKCZyZWdzLT5l cF9zdHMpOwo+ICsKPiArCV9fcGVuZGluZ19zZXR1cF9zdGF0dXNfaGFuZGxlcihwcml2X2Rldik7 Cj4gKwo+ICsJaWYgKChlcF9zdHNfcmVnICYgRVBfU1RTX1NFVFVQKSAmJiBkaXIgPT0gMCkgewo+ ICsJCXN0cnVjdCB1c2JfY3RybHJlcXVlc3QgKnNldHVwID0gcHJpdl9kZXYtPnNldHVwOwo+ICsK PiArCQl3cml0ZWwoRVBfU1RTX1NFVFVQIHwgRVBfU1RTX0lPQyB8IEVQX1NUU19JU1AsICZyZWdz LT5lcF9zdHMpOwoKaW5zdGVhZCB5b3UgY2FuIGp1c3QgY2xlYXIgYWxsIGV2ZW50cyBhdCB0aGUg ZW5kIG9mIHRoaXMgZnVuY3Rpb24gYnkKCXdyaXRlbChlcF9zdHNfcmVnLCAmcmVncy0+ZXBfc3Rz KTsKPiArCj4gKwkJcHJpdl9kZXYtPmVwMF9kYXRhX2RpciA9IHNldHVwLT5iUmVxdWVzdFR5cGUg JiBVU0JfRElSX0lOOwo+ICsJCWNkbnMzX2VwMF9zZXR1cF9waGFzZShwcml2X2Rldik7Cj4gKwkJ ZXBfc3RzX3JlZyAmPSB+KEVQX1NUU19TRVRVUCB8IEVQX1NUU19JT0MgfCBFUF9TVFNfSVNQKTsK Ck5vdCByZXF1aXJlZC4KCj4gKwl9Cj4gKwo+ICsJaWYgKGVwX3N0c19yZWcgJiBFUF9TVFNfVFJC RVJSKQo+ICsJCXdyaXRlbChFUF9TVFNfVFJCRVJSLCAmcHJpdl9kZXYtPnJlZ3MtPmVwX3N0cyk7 CgpDYW4gYmUgb21pdHRlZC4KPiArCj4gKwlpZiAoZXBfc3RzX3JlZyAmIEVQX1NUU19ERVNDTUlT KSB7Cj4gKwkJd3JpdGVsKEVQX1NUU19ERVNDTUlTLCAmcHJpdl9kZXYtPnJlZ3MtPmVwX3N0cyk7 CgpUaGlzIGFzIHdlbGwuCj4gKwo+ICsJCWlmIChkaXIgPT0gMCAmJiAhcHJpdl9kZXYtPnNldHVw X3BlbmRpbmcpIHsKPiArCQkJcHJpdl9kZXYtPmVwMF9kYXRhX2RpciA9IDA7Cj4gKwkJCWNkbnMz X2VwMF9ydW5fdHJhbnNmZXIocHJpdl9kZXYsIHByaXZfZGV2LT5zZXR1cF9kbWEsCj4gKwkJCQkJ ICAgICAgIDgsIDApOwo+ICsJCX0KPiArCX0KPiArCj4gKwlpZiAoKGVwX3N0c19yZWcgJiBFUF9T VFNfSU9DKSB8fCAoZXBfc3RzX3JlZyAmIEVQX1NUU19JU1ApKSB7Cj4gKwkJd3JpdGVsKEVQX1NU U19JT0MsICZwcml2X2Rldi0+cmVncy0+ZXBfc3RzKTsKCnRoaXMgd3JpdGUgY2FuIGJlIG9taXR0 ZWQuCj4gKwkJY2RuczNfdHJhbnNmZXJfY29tcGxldGVkKHByaXZfZGV2KTsKPiArCX0KCmhlcmUg eW91IGNhbiBkbwoJd3JpdGVsKGVwX3N0c19yZWcsICZyZWdzLT5lcF9zdHMpOwo+ICt9Cj4gKwo+ ICAvKioKPiAgICogY2RuczNfZ2FkZ2V0X2VwMF9lbmFibGUKPiAgICogRnVuY3Rpb24gc2hvdWxk bid0IGJlIGNhbGxlZCBieSBnYWRnZXQgZHJpdmVyLAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Vz Yi9jZG5zMy9nYWRnZXQuYyBiL2RyaXZlcnMvdXNiL2NkbnMzL2dhZGdldC5jCj4gaW5kZXggYzk2 NWRhMTZjMGM4Li4zMDkyMDI0NzRlNTcgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy91c2IvY2RuczMv Z2FkZ2V0LmMKPiArKysgYi9kcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuYwo+IEBAIC01OCw2ICs1 OCwxOCBAQCB2b2lkIGNkbnMzX3NldF9yZWdpc3Rlcl9iaXQodm9pZCBfX2lvbWVtICpwdHIsIHUz MiBtYXNrKQo+ICAJd3JpdGVsKG1hc2ssIHB0cik7Cj4gIH0KPiAgCj4gKy8qKgo+ICsgKiBjZG5z M19lcF9yZWdfcG9zX3RvX2luZGV4IC0gTWFjcm8gY29udmVydHMgYml0IHBvc2l0aW9uIG9mIGVw X2lzdHMgcmVnaXN0ZXIKPiArICogdG8gaW5kZXggb2YgZW5kcG9pbnQgb2JqZWN0IGluIGNkbnMz X2RldmljZS5lcHNbXSBjb250YWluZXIKPiArICogQGk6IGJpdCBwb3NpdGlvbiBvZiBlbmRwb2lu dCBmb3Igd2hpY2ggZW5kcG9pbnQgb2JqZWN0IGlzIHJlcXVpcmVkCj4gKyAqCj4gKyAqIFJlbWVt YmVyIHRoYXQgZW5kcG9pbnQgY29udGFpbmVyIGRvZXNuJ3QgY29udGFpbiBkZWZhdWx0IGVuZHBv aW50Cj4gKyAqLwo+ICtzdGF0aWMgdTggY2RuczNfZXBfcmVnX3Bvc190b19pbmRleChpbnQgaSkK PiArewo+ICsJcmV0dXJuICgoaSAvIDE2KSArICgoKGkgJSAxNikgLSAyKSAqIDIpKTsKPiArfQo+ ICsKPiAgLyoqCj4gICAqIGNkbnMzX25leHRfcmVxdWVzdCAtIHJldHVybnMgbmV4dCByZXF1ZXN0 IGZyb20gbGlzdAo+ICAgKiBAbGlzdDogbGlzdCBjb250YWluaW5nIHJlcXVlc3RzCj4gQEAgLTE4 OCw2ICsyMDAsMjEgQEAgc3RhdGljIHZvaWQgY2RuczNfZXBfc3RhbGxfZmx1c2goc3RydWN0IGNk bnMzX2VuZHBvaW50ICpwcml2X2VwKQo+ICAJcHJpdl9lcC0+ZmxhZ3MgfD0gRVBfU1RBTEw7Cj4g IH0KPiAgCj4gKy8qKgo+ICsgKiBjZG5zM19nYWRnZXRfdW5jb25maWcgLSByZXNldCBkZXZpY2Ug Y29uZmlndXJhdGlvbgo+ICsgKiBAcHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiAr ICovCj4gK3ZvaWQgY2RuczNfZ2FkZ2V0X3VuY29uZmlnKHN0cnVjdCBjZG5zM19kZXZpY2UgKnBy aXZfZGV2KQo+ICt7Cj4gKwkvKiBSRVNFVCBDT05GSUdVUkFUSU9OICovCj4gKwl3cml0ZWwoVVNC X0NPTkZfQ0ZHUlNULCAmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jb25mKTsKPiArCj4gKwljZG5zM19l bmFibGVfbDEocHJpdl9kZXYsIDApOwo+ICsJcHJpdl9kZXYtPmh3X2NvbmZpZ3VyZWRfZmxhZyA9 IDA7Cj4gKwlwcml2X2Rldi0+b25jaGlwX21lbV9hbGxvY2F0ZWRfc2l6ZSA9IDA7Cj4gKwlwcml2 X2Rldi0+b3V0X21lbV9pc19hbGxvY2F0ZWQgPSAwOwo+ICt9Cj4gKwo+ICB2b2lkIGNkbnMzX2Vu YWJsZV9sMShzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwgaW50IGVuYWJsZSkKPiAgewo+ ICAJaWYgKGVuYWJsZSkKPiBAQCAtMTk2LDYgKzIyMywyMyBAQCB2b2lkIGNkbnMzX2VuYWJsZV9s MShzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwgaW50IGVuYWJsZSkKPiAgCQl3cml0ZWwo VVNCX0NPTkZfTDFEUywgJnByaXZfZGV2LT5yZWdzLT51c2JfY29uZik7Cj4gIH0KPiAgCj4gK3N0 YXRpYyBlbnVtIHVzYl9kZXZpY2Vfc3BlZWQgY2RuczNfZ2V0X3NwZWVkKHN0cnVjdCBjZG5zM19k ZXZpY2UgKnByaXZfZGV2KQo+ICt7Cj4gKwl1MzIgcmVnOwo+ICsKPiArCXJlZyA9IHJlYWRsKCZw cml2X2Rldi0+cmVncy0+dXNiX3N0cyk7Cj4gKwo+ICsJaWYgKERFVl9TVVBFUlNQRUVEKHJlZykp Cj4gKwkJcmV0dXJuIFVTQl9TUEVFRF9TVVBFUjsKPiArCWVsc2UgaWYgKERFVl9ISUdIU1BFRUQo cmVnKSkKPiArCQlyZXR1cm4gVVNCX1NQRUVEX0hJR0g7Cj4gKwllbHNlIGlmIChERVZfRlVMTFNQ RUVEKHJlZykpCj4gKwkJcmV0dXJuIFVTQl9TUEVFRF9GVUxMOwo+ICsJZWxzZSBpZiAoREVWX0xP V1NQRUVEKHJlZykpCj4gKwkJcmV0dXJuIFVTQl9TUEVFRF9MT1c7Cj4gKwlyZXR1cm4gVVNCX1NQ RUVEX1VOS05PV047Cj4gK30KPiArCj4gIC8qKgo+ICAgKiBjZG5zM19nYWRnZXRfZ2l2ZWJhY2sg LSBjYWxsIHN0cnVjdCB1c2JfcmVxdWVzdCdzIC0+Y29tcGxldGUgY2FsbGJhY2sKPiAgICogQHBy aXZfZXA6IFRoZSBlbmRwb2ludCB0byB3aG9tIHRoZSByZXF1ZXN0IGJlbG9uZ3MgdG8KPiBAQCAt MjIxLDEyICsyNjUsMTM2IEBAIHZvaWQgY2RuczNfZ2FkZ2V0X2dpdmViYWNrKHN0cnVjdCBjZG5z M19lbmRwb2ludCAqcHJpdl9lcCwKPiAgICovCj4gIGludCBjZG5zM19lcF9ydW5fdHJhbnNmZXIo c3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLAo+ICAJCQkgIHN0cnVjdCB1c2JfcmVxdWVz dCAqcmVxdWVzdCkKPiArewo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGNk bnMzX3RyYW5zZmVyX2NvbXBsZXRlZChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwKPiAr CQkJCSAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwKQo+ICB7Cj4gIAkvL1RPRE86 IEltcGxlbWVudHMgdGhpcyBmdW5jdGlvbi4KPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2No ZWNrX2VwX2ludGVycnVwdF9wcm9jZWVkIC0gUHJvY2Vzc2VzIGludGVycnVwdCByZWxhdGVkIHRv IGVuZHBvaW50Cj4gKyAqIEBwcml2X2VwOiBlbmRwb2ludCBvYmplY3QKPiArICoKPiArICogUmV0 dXJucyAwCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNkbnMzX2NoZWNrX2VwX2ludGVycnVwdF9wcm9j ZWVkKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCkKPiArewo+ICsJc3RydWN0IGNkbnMz X2RldmljZSAqcHJpdl9kZXYgPSBwcml2X2VwLT5jZG5zM19kZXY7Cj4gKwlzdHJ1Y3QgY2RuczNf dXNiX3JlZ3MgX19pb21lbSAqcmVnczsKPiArCXUzMiBlcF9zdHNfcmVnOwo+ICsKPiArCXJlZ3Mg PSBwcml2X2Rldi0+cmVnczsKPiArCj4gKwljZG5zM19zZWxlY3RfZXAocHJpdl9kZXYsIHByaXZf ZXAtPmVuZHBvaW50LmFkZHJlc3MpOwo+ICsJZXBfc3RzX3JlZyA9IHJlYWRsKCZyZWdzLT5lcF9z dHMpOwo+ICsKPiArCWlmIChlcF9zdHNfcmVnICYgRVBfU1RTX1RSQkVSUikKPiArCQl3cml0ZWwo RVBfU1RTX1RSQkVSUiwgJnJlZ3MtPmVwX3N0cyk7Cj4gKwo+ICsJaWYgKGVwX3N0c19yZWcgJiBF UF9TVFNfSVNPRVJSKQo+ICsJCXdyaXRlbChFUF9TVFNfSVNPRVJSLCAmcmVncy0+ZXBfc3RzKTsK PiArCj4gKwlpZiAoZXBfc3RzX3JlZyAmIEVQX1NUU19PVVRTTU0pCj4gKwkJd3JpdGVsKEVQX1NU U19PVVRTTU0sICZyZWdzLT5lcF9zdHMpOwo+ICsKPiArCWlmIChlcF9zdHNfcmVnICYgRVBfU1RT X05SRFkpCj4gKwkJd3JpdGVsKEVQX1NUU19OUkRZLCAmcmVncy0+ZXBfc3RzKTsKCldoeSBjaGVj ayBmb3IgZWFjaCBiaXQgd2hlbiB5b3UgYXJlIG5vdCBkb2luZyBhbnl0aGluZy4gSW5zdGVhZCBh dCB0aGUgZW5kCnlvdSBjb3VsZCBqdXN0IGRvCgl3cml0ZWwoZXBfc3RzX3JlZywgJnJlZ3MtPmVw X3N0cykKdG8gY2xlYXIgYWxsIHBlbmRpbmcgZXZlbnRzLgoKPiArCj4gKwlpZiAoKGVwX3N0c19y ZWcgJiBFUF9TVFNfSU9DKSB8fCAoZXBfc3RzX3JlZyAmIEVQX1NUU19JU1ApKSB7Cj4gKwkJd3Jp dGVsKEVQX1NUU19JT0MgfCBFUF9TVFNfSVNQLCAmcmVncy0+ZXBfc3RzKTsKPiArCQljZG5zM190 cmFuc2Zlcl9jb21wbGV0ZWQocHJpdl9kZXYsIHByaXZfZXApOwo+ICsJfQo+ICsKPiArCWlmIChl cF9zdHNfcmVnICYgRVBfU1RTX0RFU0NNSVMpCj4gKwkJd3JpdGVsKEVQX1NUU19ERVNDTUlTLCAm cmVncy0+ZXBfc3RzKTsKPiAgCj4gIAlyZXR1cm4gMDsKPiAgfQo+ICAKPiArLyoqCj4gKyAqIGNk bnMzX2NoZWNrX3VzYl9pbnRlcnJ1cHRfcHJvY2VlZCAtIFByb2Nlc3NlcyBpbnRlcnJ1cHQgcmVs YXRlZCB0byBkZXZpY2UKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4g KyAqIEB1c2JfaXN0czogYml0bWFwIHJlcHJlc2VudGF0aW9uIG9mIGRldmljZSdzIHJlcG9ydGVk IGludGVycnVwdHMKPiArICogKHVzYl9pc3RzIHJlZ2lzdGVyIHZhbHVlKQo+ICsgKi8KPiArc3Rh dGljIHZvaWQgY2RuczNfY2hlY2tfdXNiX2ludGVycnVwdF9wcm9jZWVkKHN0cnVjdCBjZG5zM19k ZXZpY2UgKnByaXZfZGV2LAo+ICsJCQkJCSAgICAgIHUzMiB1c2JfaXN0cykKPiArewo+ICsJc3Ry dWN0IGNkbnMzX3VzYl9yZWdzIF9faW9tZW0gKnJlZ3M7Cj4gKwlpbnQgc3BlZWQgPSAwOwo+ICsK PiArCXJlZ3MgPSBwcml2X2Rldi0+cmVnczsKPiArCj4gKwkvKiBDb25uZWN0aW9uIGRldGVjdGVk ICovCj4gKwlpZiAodXNiX2lzdHMgJiAoVVNCX0lTVFNfQ09OMkkgfCBVU0JfSVNUU19DT05JKSkg ewo+ICsJCXdyaXRlbChVU0JfSVNUU19DT04ySSB8IFVTQl9JU1RTX0NPTkksICZyZWdzLT51c2Jf aXN0cyk7Cj4gKwkJc3BlZWQgPSBjZG5zM19nZXRfc3BlZWQocHJpdl9kZXYpOwo+ICsKPiArCQlk ZXZfZGJnKCZwcml2X2Rldi0+ZGV2LCAiQ29ubmVjdGlvbiBkZXRlY3RlZCBhdCBzcGVlZDogJXMg JWRcbiIsCj4gKwkJCXVzYl9zcGVlZF9zdHJpbmcoc3BlZWQpLCBzcGVlZCk7Cj4gKwo+ICsJCXBy aXZfZGV2LT5nYWRnZXQuc3BlZWQgPSBzcGVlZDsKPiArCQlwcml2X2Rldi0+aXNfY29ubmVjdGVk ID0gMTsKPiArCQl1c2JfZ2FkZ2V0X3NldF9zdGF0ZSgmcHJpdl9kZXYtPmdhZGdldCwgVVNCX1NU QVRFX1BPV0VSRUQpOwo+ICsJCWNkbnMzX2VwMF9jb25maWcocHJpdl9kZXYpOwo+ICsJfQo+ICsK PiArCS8qIFNTIERpc2Nvbm5lY3Rpb24gZGV0ZWN0ZWQgKi8KPiArCWlmICh1c2JfaXN0cyAmIChV U0JfSVNUU19ESVMySSB8IFVTQl9JU1RTX0RJU0kpKSB7Cj4gKwkJZGV2X2RiZygmcHJpdl9kZXYt PmRldiwgIkRpc2Nvbm5lY3Rpb24gZGV0ZWN0ZWRcbiIpOwo+ICsKPiArCQl3cml0ZWwoVVNCX0lT VFNfRElTMkkgfCBVU0JfSVNUU19ESVNJLCAmcmVncy0+dXNiX2lzdHMpOwo+ICsJCWlmIChwcml2 X2Rldi0+Z2FkZ2V0X2RyaXZlciAmJgo+ICsJCSAgICBwcml2X2Rldi0+Z2FkZ2V0X2RyaXZlci0+ ZGlzY29ubmVjdCkgewo+ICsJCQlzcGluX3VubG9jaygmcHJpdl9kZXYtPmxvY2spOwo+ICsJCQlw cml2X2Rldi0+Z2FkZ2V0X2RyaXZlci0+ZGlzY29ubmVjdCgmcHJpdl9kZXYtPmdhZGdldCk7Cj4g KwkJCXNwaW5fbG9jaygmcHJpdl9kZXYtPmxvY2spOwo+ICsJCX0KPiArCQlwcml2X2Rldi0+Z2Fk Z2V0LnNwZWVkID0gVVNCX1NQRUVEX1VOS05PV047Cj4gKwkJdXNiX2dhZGdldF9zZXRfc3RhdGUo JnByaXZfZGV2LT5nYWRnZXQsIFVTQl9TVEFURV9OT1RBVFRBQ0hFRCk7Cj4gKwkJcHJpdl9kZXYt PmlzX2Nvbm5lY3RlZCA9IDA7Cj4gKwkJY2RuczNfZ2FkZ2V0X3VuY29uZmlnKHByaXZfZGV2KTsK PiArCX0KCldoYXQgYWJvdXQgbm9uIFN1cGVyLVNwZWVkIGRpc2Nvbm5lY3RzPwoKPiArCj4gKwlp ZiAodXNiX2lzdHMgJiBVU0JfSVNUU19MMkVOVEkpIHsKPiArCQlkZXZfZGJnKCZwcml2X2Rldi0+ ZGV2LCAiRGV2aWNlIHN1c3BlbmRlZFxuIik7Cj4gKwkJd3JpdGVsKFVTQl9JU1RTX0wyRU5USSwg JnJlZ3MtPnVzYl9pc3RzKTsKPiArCX0KPiArCj4gKwkvKiBFeGl0IGZyb20gc3RhbmRieSBtb2Rl IG9uIEwyIGV4aXQgKFN1c3BlbmQgaW4gSFMvRlMgb3IgU1MpICovCj4gKwlpZiAodXNiX2lzdHMg JiBVU0JfSVNUU19MMkVYVEkpIHsKPiArCQlkZXZfZGJnKCZwcml2X2Rldi0+ZGV2LCAiW0ludGVy cnVwdF0gTDIgZXhpdCBkZXRlY3RlZFxuIik7Cj4gKwkJd3JpdGVsKFVTQl9JU1RTX0wyRVhUSSwg JnJlZ3MtPnVzYl9pc3RzKTsKPiArCX0KPiArCj4gKwkvKiBFeGl0IGZyb20gc3RhbmRieSBtb2Rl IG9uIFUzIGV4aXQgKFN1c3BlbmQgaW4gSFMvRlMgb3IgU1MpLiAqLwo+ICsJaWYgKHVzYl9pc3Rz ICYgVVNCX0lTVFNfVTNFWFRJKSB7Cj4gKwkJZGV2X2RiZygmcHJpdl9kZXYtPmRldiwgIlUzIGV4 aXQgZGV0ZWN0ZWRcbiIpOwo+ICsJCXdyaXRlbChVU0JfSVNUU19VM0VYVEksICZyZWdzLT51c2Jf aXN0cyk7Cj4gKwl9Cj4gKwo+ICsJLyogcmVzZXRzIGNhc2VzICovCj4gKwlpZiAodXNiX2lzdHMg JiAoVVNCX0lTVFNfVVdSRVNJIHwgVVNCX0lTVFNfVUhSRVNJIHwgVVNCX0lTVFNfVTJSRVNJKSkg ewo+ICsJCXdyaXRlbChVU0JfSVNUU19VMlJFU0kgfCBVU0JfSVNUU19VV1JFU0kgfCBVU0JfSVNU U19VSFJFU0ksCj4gKwkJICAgICAgICZyZWdzLT51c2JfaXN0cyk7Cj4gKwo+ICsJCS8qcmVhZCBh Z2FpbiB0byBjaGVjayB0aGUgYWN0dWFsbCBzcGVlZCovCj4gKwkJc3BlZWQgPSBjZG5zM19nZXRf c3BlZWQocHJpdl9kZXYpOwo+ICsKPiArCQlkZXZfZGJnKCZwcml2X2Rldi0+ZGV2LCAiUmVzZXQg ZGV0ZWN0ZWQgYXQgc3BlZWQ6ICVzICVkXG4iLAo+ICsJCQl1c2Jfc3BlZWRfc3RyaW5nKHNwZWVk KSwgc3BlZWQpOwo+ICsKPiArCQl1c2JfZ2FkZ2V0X3NldF9zdGF0ZSgmcHJpdl9kZXYtPmdhZGdl dCwgVVNCX1NUQVRFX0RFRkFVTFQpOwo+ICsJCXByaXZfZGV2LT5nYWRnZXQuc3BlZWQgPSBzcGVl ZDsKPiArCQljZG5zM19nYWRnZXRfdW5jb25maWcocHJpdl9kZXYpOwo+ICsJCWNkbnMzX2VwMF9j b25maWcocHJpdl9kZXYpOwo+ICsJfQo+ICt9Cj4gKwo+ICAvKioKPiAgICogY2RuczNfaXJxX2hh bmRsZXIgLSBpcnEgbGluZSBpbnRlcnJ1cHQgaGFuZGxlcgo+ICAgKiBAY2RuczogY2RuczMgaW5z dGFuY2UKPiBAQCAtMjM3LDggKzQwNSw2MiBAQCBpbnQgY2RuczNfZXBfcnVuX3RyYW5zZmVyKHN0 cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCwKPiAgICovCj4gIHN0YXRpYyBpcnFyZXR1cm5f dCBjZG5zM19pcnFfaGFuZGxlcl90aHJlYWQoc3RydWN0IGNkbnMzICpjZG5zKQo+ICB7Cj4gKwlz dHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldjsKPiAgCWlycXJldHVybl90IHJldCA9IElSUV9O T05FOwo+IC0JLy9UT0RPOiBpbXBsZW1lbnRzIHRoaXMgZnVuY3Rpb24KPiArCXVuc2lnbmVkIGxv bmcgZmxhZ3M7Cj4gKwl1MzIgcmVnOwo+ICsKPiArCXByaXZfZGV2ID0gY29udGFpbmVyX29mKGNk bnMtPmdhZGdldF9kZXYsIHN0cnVjdCBjZG5zM19kZXZpY2UsIGRldik7Cj4gKwlzcGluX2xvY2tf aXJxc2F2ZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArCj4gKwkvKiBjaGVjayBVU0IgZGV2 aWNlIGludGVycnVwdCAqLwo+ICsJcmVnID0gcmVhZGwoJnByaXZfZGV2LT5yZWdzLT51c2JfaXN0 cyk7Cj4gKwlpZiAocmVnKSB7Cj4gKwkJZGV2X2RiZygmcHJpdl9kZXYtPmRldiwgIklSUTogdXNi X2lzdHM6ICUwOFhcbiIsIHJlZyk7CgpkZXZfZGJnIHdpbGwgYmUgdGVycmlibHkgc2xvdyB0byBi ZSB1c2VmdWwuIFRyYWNlcG9pbnRzPwoKPiArCQljZG5zM19jaGVja191c2JfaW50ZXJydXB0X3By b2NlZWQocHJpdl9kZXYsIHJlZyk7Cj4gKwkJcmV0ID0gSVJRX0hBTkRMRUQ7Cj4gKwl9Cj4gKwo+ ICsJLyogY2hlY2sgZW5kcG9pbnQgaW50ZXJydXB0ICovCj4gKwlyZWcgPSByZWFkbCgmcHJpdl9k ZXYtPnJlZ3MtPmVwX2lzdHMpOwo+ICsJaWYgKHJlZyAhPSAwKSB7Cj4gKwkJZGV2X2RiZygmcHJp dl9kZXYtPmRldiwgIklSUSBlcF9pc3RzOiAlMDhYXG4iLCByZWcpOwo+ICsJfSBlbHNlIHsKPiAr CQlpZiAoVVNCX1NUU19DRkdTVFMocmVhZGwoJnByaXZfZGV2LT5yZWdzLT51c2Jfc3RzKSkpCj4g KwkJCXJldCA9IElSUV9IQU5ETEVEOwoKV2h5IGlzIHRoaXMgZG9uZS4gV2UgZG9uJ3Qgc2VlbSB0 byBiZSBoYW5kbGluZyBhbnl0aGluZyBoZXJlLgpEb24ndCB3ZSBuZWVkIHRvIGNsZWFyIHRoZSB1 c2Jfc3RzPwoKPiArCQlnb3RvIGlycWVuZDsKPiArCX0KPiArCj4gKwkvKiBoYW5kbGUgZGVmYXVs dCBlbmRwb2ludCBPVVQgKi8KPiArCWlmIChyZWcgJiBFUF9JU1RTX0VQX09VVDApIHsKPiArCQlj ZG5zM19jaGVja19lcDBfaW50ZXJydXB0X3Byb2NlZWQocHJpdl9kZXYsIDApOwo+ICsJCXJldCA9 IElSUV9IQU5ETEVEOwo+ICsJfQo+ICsKPiArCS8qIGhhbmRsZSBkZWZhdWx0IGVuZHBvaW50IElO ICovCj4gKwlpZiAocmVnICYgRVBfSVNUU19FUF9JTjApIHsKPiArCQljZG5zM19jaGVja19lcDBf aW50ZXJydXB0X3Byb2NlZWQocHJpdl9kZXYsIDEpOwo+ICsJCXJldCA9IElSUV9IQU5ETEVEOwo+ ICsJfQo+ICsKPiArCS8qIGNoZWNrIGlmIGludGVycnVwdCBmcm9tIG5vbiBkZWZhdWx0IGVuZHBv aW50LCBpZiBubyBleGl0ICovCj4gKwlyZWcgJj0gfihFUF9JU1RTX0VQX09VVDAgfCBFUF9JU1RT X0VQX0lOMCk7Cj4gKwlpZiAoIXJlZykKPiArCQlnb3RvIGlycWVuZDsKPiArCj4gKwlkbyB7Cj4g KwkJdW5zaWduZWQgaW50IGJpdF9wb3MgPSBmZnMocmVnKTsKPiArCQl1MzIgYml0X21hc2sgPSAx IDw8IChiaXRfcG9zIC0gMSk7Cj4gKwkJaW50IGluZGV4Owo+ICsKPiArCQlpbmRleCA9IGNkbnMz X2VwX3JlZ19wb3NfdG9faW5kZXgoYml0X3Bvcyk7Cj4gKwkJY2RuczNfY2hlY2tfZXBfaW50ZXJy dXB0X3Byb2NlZWQocHJpdl9kZXYtPmVwc1tpbmRleF0pOwo+ICsJCXJlZyAmPSB+Yml0X21hc2s7 Cj4gKwkJcmV0ID0gSVJRX0hBTkRMRUQ7Cj4gKwl9IHdoaWxlIChyZWcpOwo+ICsKPiAraXJxZW5k Ogo+ICsJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiAg CXJldHVybiByZXQ7Cj4gIH0KPiAgCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2dh ZGdldC5oIGIvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmgKPiBpbmRleCAyMjRmNmI4MzBiYzku LjhjMmYzNjNmOTM0MCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuaAo+ ICsrKyBiL2RyaXZlcnMvdXNiL2NkbnMzL2dhZGdldC5oCj4gQEAgLTEwNzIsNiArMTA3Miw3IEBA IGludCBjZG5zM19oYW5kc2hha2Uodm9pZCBfX2lvbWVtICpwdHIsIHUzMiBtYXNrLCB1MzIgZG9u ZSwgaW50IHVzZWMpOwo+ICB2b2lkIGNkbnMzX3NldF9yZWdpc3Rlcl9iaXQodm9pZCBfX2lvbWVt ICpwdHIsIHUzMiBtYXNrKTsKPiAgaW50IGNkbnMzX2luaXRfZXAwKHN0cnVjdCBjZG5zM19kZXZp Y2UgKnByaXZfZGV2KTsKPiAgdm9pZCBjZG5zM19lcDBfY29uZmlnKHN0cnVjdCBjZG5zM19kZXZp Y2UgKnByaXZfZGV2KTsKPiArdm9pZCBjZG5zM19jaGVja19lcDBfaW50ZXJydXB0X3Byb2NlZWQo c3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsIGludCBkaXIpOwo+ICB2b2lkIGNkbnMzX3Nl bGVjdF9lcChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwgdTMyIGVwKTsKPiAgdm9pZCBj ZG5zM19lbmFibGVfbDEoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsIGludCBlbmFibGUp Owo+ICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKmNkbnMzX25leHRfcmVxdWVzdChzdHJ1Y3QgbGlzdF9o ZWFkICpsaXN0KTsKPiAKCmNoZWVycywKLXJvZ2VyCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roger Quadros Subject: Re: [RFC PATCH v2 11/15] usb:cdns3: Implements ISR functionality. Date: Wed, 28 Nov 2018 16:54:12 +0200 Message-ID: <5BFEAC14.1030408@ti.com> References: <1542535751-16079-1-git-send-email-pawell@cadence.com> <1542535751-16079-12-git-send-email-pawell@cadence.com> Mime-Version: 1.0 Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1542535751-16079-12-git-send-email-pawell@cadence.com> Sender: linux-kernel-owner@vger.kernel.org To: Pawel Laszczak , devicetree@vger.kernel.org Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, adouglas@cadence.com, jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, pjez@cadence.com, kurahul@cadence.com List-Id: devicetree@vger.kernel.org On 18/11/18 12:09, Pawel Laszczak wrote: > Patch adds set of generic functions used for handling interrupts > generated by controller. Interrupt related functions are divided > into three groups. The first is related to ep0 and is placed in ep0.c. > The second is responsible for non-default endpoints and is > implemented in gadget.c file. The last group is not related to > endpoints interrupts and is placed in gadget.c. > All groups have common entry point in cdns3_irq_handler_thread function. > > Signed-off-by: Pawel Laszczak > --- > drivers/usb/cdns3/ep0.c | 63 +++++++++++ > drivers/usb/cdns3/gadget.c | 224 ++++++++++++++++++++++++++++++++++++- > drivers/usb/cdns3/gadget.h | 1 + > 3 files changed, 287 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > index d05169e73631..eb92fd234bd7 100644 > --- a/drivers/usb/cdns3/ep0.c > +++ b/drivers/usb/cdns3/ep0.c > @@ -90,6 +90,69 @@ static void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) > } > } > > +static void __pending_setup_status_handler(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function > +} > + > +/** > + * cdns3_ep0_setup_phase - Handling setup USB requests > + * @priv_dev: extended gadget object > + */ > +static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function. > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function > +} > + > +/** > + * cdns3_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0 > + * @priv_dev: extended gadget object > + * @dir: 1 for IN direction, 0 for OUT direction > + */ > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, 0 | (dir ? USB_DIR_IN : USB_DIR_OUT)); > + ep_sts_reg = readl(®s->ep_sts); > + > + __pending_setup_status_handler(priv_dev); > + > + if ((ep_sts_reg & EP_STS_SETUP) && dir == 0) { > + struct usb_ctrlrequest *setup = priv_dev->setup; > + > + writel(EP_STS_SETUP | EP_STS_IOC | EP_STS_ISP, ®s->ep_sts); instead you can just clear all events at the end of this function by writel(ep_sts_reg, ®s->ep_sts); > + > + priv_dev->ep0_data_dir = setup->bRequestType & USB_DIR_IN; > + cdns3_ep0_setup_phase(priv_dev); > + ep_sts_reg &= ~(EP_STS_SETUP | EP_STS_IOC | EP_STS_ISP); Not required. > + } > + > + if (ep_sts_reg & EP_STS_TRBERR) > + writel(EP_STS_TRBERR, &priv_dev->regs->ep_sts); Can be omitted. > + > + if (ep_sts_reg & EP_STS_DESCMIS) { > + writel(EP_STS_DESCMIS, &priv_dev->regs->ep_sts); This as well. > + > + if (dir == 0 && !priv_dev->setup_pending) { > + priv_dev->ep0_data_dir = 0; > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + 8, 0); > + } > + } > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + writel(EP_STS_IOC, &priv_dev->regs->ep_sts); this write can be omitted. > + cdns3_transfer_completed(priv_dev); > + } here you can do writel(ep_sts_reg, ®s->ep_sts); > +} > + > /** > * cdns3_gadget_ep0_enable > * Function shouldn't be called by gadget driver, > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > index c965da16c0c8..309202474e57 100644 > --- a/drivers/usb/cdns3/gadget.c > +++ b/drivers/usb/cdns3/gadget.c > @@ -58,6 +58,18 @@ void cdns3_set_register_bit(void __iomem *ptr, u32 mask) > writel(mask, ptr); > } > > +/** > + * cdns3_ep_reg_pos_to_index - Macro converts bit position of ep_ists register > + * to index of endpoint object in cdns3_device.eps[] container > + * @i: bit position of endpoint for which endpoint object is required > + * > + * Remember that endpoint container doesn't contain default endpoint > + */ > +static u8 cdns3_ep_reg_pos_to_index(int i) > +{ > + return ((i / 16) + (((i % 16) - 2) * 2)); > +} > + > /** > * cdns3_next_request - returns next request from list > * @list: list containing requests > @@ -188,6 +200,21 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > priv_ep->flags |= EP_STALL; > } > > +/** > + * cdns3_gadget_unconfig - reset device configuration > + * @priv_dev: extended gadget object > + */ > +void cdns3_gadget_unconfig(struct cdns3_device *priv_dev) > +{ > + /* RESET CONFIGURATION */ > + writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); > + > + cdns3_enable_l1(priv_dev, 0); > + priv_dev->hw_configured_flag = 0; > + priv_dev->onchip_mem_allocated_size = 0; > + priv_dev->out_mem_is_allocated = 0; > +} > + > void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) > { > if (enable) > @@ -196,6 +223,23 @@ void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) > writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > } > > +static enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev) > +{ > + u32 reg; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (DEV_SUPERSPEED(reg)) > + return USB_SPEED_SUPER; > + else if (DEV_HIGHSPEED(reg)) > + return USB_SPEED_HIGH; > + else if (DEV_FULLSPEED(reg)) > + return USB_SPEED_FULL; > + else if (DEV_LOWSPEED(reg)) > + return USB_SPEED_LOW; > + return USB_SPEED_UNKNOWN; > +} > + > /** > * cdns3_gadget_giveback - call struct usb_request's ->complete callback > * @priv_ep: The endpoint to whom the request belongs to > @@ -221,12 +265,136 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > */ > int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > struct usb_request *request) > +{ > + return 0; > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > { > //TODO: Implements this function. > +} > + > +/** > + * cdns3_check_ep_interrupt_proceed - Processes interrupt related to endpoint > + * @priv_ep: endpoint object > + * > + * Returns 0 > + */ > +static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_usb_regs __iomem *regs; > + u32 ep_sts_reg; > + > + regs = priv_dev->regs; > + > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + ep_sts_reg = readl(®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_TRBERR) > + writel(EP_STS_TRBERR, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_ISOERR) > + writel(EP_STS_ISOERR, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_OUTSMM) > + writel(EP_STS_OUTSMM, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_NRDY) > + writel(EP_STS_NRDY, ®s->ep_sts); Why check for each bit when you are not doing anything. Instead at the end you could just do writel(ep_sts_reg, ®s->ep_sts) to clear all pending events. > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + writel(EP_STS_IOC | EP_STS_ISP, ®s->ep_sts); > + cdns3_transfer_completed(priv_dev, priv_ep); > + } > + > + if (ep_sts_reg & EP_STS_DESCMIS) > + writel(EP_STS_DESCMIS, ®s->ep_sts); > > return 0; > } > > +/** > + * cdns3_check_usb_interrupt_proceed - Processes interrupt related to device > + * @priv_dev: extended gadget object > + * @usb_ists: bitmap representation of device's reported interrupts > + * (usb_ists register value) > + */ > +static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, > + u32 usb_ists) > +{ > + struct cdns3_usb_regs __iomem *regs; > + int speed = 0; > + > + regs = priv_dev->regs; > + > + /* Connection detected */ > + if (usb_ists & (USB_ISTS_CON2I | USB_ISTS_CONI)) { > + writel(USB_ISTS_CON2I | USB_ISTS_CONI, ®s->usb_ists); > + speed = cdns3_get_speed(priv_dev); > + > + dev_dbg(&priv_dev->dev, "Connection detected at speed: %s %d\n", > + usb_speed_string(speed), speed); > + > + priv_dev->gadget.speed = speed; > + priv_dev->is_connected = 1; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_POWERED); > + cdns3_ep0_config(priv_dev); > + } > + > + /* SS Disconnection detected */ > + if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) { > + dev_dbg(&priv_dev->dev, "Disconnection detected\n"); > + > + writel(USB_ISTS_DIS2I | USB_ISTS_DISI, ®s->usb_ists); > + if (priv_dev->gadget_driver && > + priv_dev->gadget_driver->disconnect) { > + spin_unlock(&priv_dev->lock); > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + spin_lock(&priv_dev->lock); > + } > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED); > + priv_dev->is_connected = 0; > + cdns3_gadget_unconfig(priv_dev); > + } What about non Super-Speed disconnects? > + > + if (usb_ists & USB_ISTS_L2ENTI) { > + dev_dbg(&priv_dev->dev, "Device suspended\n"); > + writel(USB_ISTS_L2ENTI, ®s->usb_ists); > + } > + > + /* Exit from standby mode on L2 exit (Suspend in HS/FS or SS) */ > + if (usb_ists & USB_ISTS_L2EXTI) { > + dev_dbg(&priv_dev->dev, "[Interrupt] L2 exit detected\n"); > + writel(USB_ISTS_L2EXTI, ®s->usb_ists); > + } > + > + /* Exit from standby mode on U3 exit (Suspend in HS/FS or SS). */ > + if (usb_ists & USB_ISTS_U3EXTI) { > + dev_dbg(&priv_dev->dev, "U3 exit detected\n"); > + writel(USB_ISTS_U3EXTI, ®s->usb_ists); > + } > + > + /* resets cases */ > + if (usb_ists & (USB_ISTS_UWRESI | USB_ISTS_UHRESI | USB_ISTS_U2RESI)) { > + writel(USB_ISTS_U2RESI | USB_ISTS_UWRESI | USB_ISTS_UHRESI, > + ®s->usb_ists); > + > + /*read again to check the actuall speed*/ > + speed = cdns3_get_speed(priv_dev); > + > + dev_dbg(&priv_dev->dev, "Reset detected at speed: %s %d\n", > + usb_speed_string(speed), speed); > + > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_DEFAULT); > + priv_dev->gadget.speed = speed; > + cdns3_gadget_unconfig(priv_dev); > + cdns3_ep0_config(priv_dev); > + } > +} > + > /** > * cdns3_irq_handler - irq line interrupt handler > * @cdns: cdns3 instance > @@ -237,8 +405,62 @@ int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > */ > static irqreturn_t cdns3_irq_handler_thread(struct cdns3 *cdns) > { > + struct cdns3_device *priv_dev; > irqreturn_t ret = IRQ_NONE; > - //TODO: implements this function > + unsigned long flags; > + u32 reg; > + > + priv_dev = container_of(cdns->gadget_dev, struct cdns3_device, dev); > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + /* check USB device interrupt */ > + reg = readl(&priv_dev->regs->usb_ists); > + if (reg) { > + dev_dbg(&priv_dev->dev, "IRQ: usb_ists: %08X\n", reg); dev_dbg will be terribly slow to be useful. Tracepoints? > + cdns3_check_usb_interrupt_proceed(priv_dev, reg); > + ret = IRQ_HANDLED; > + } > + > + /* check endpoint interrupt */ > + reg = readl(&priv_dev->regs->ep_ists); > + if (reg != 0) { > + dev_dbg(&priv_dev->dev, "IRQ ep_ists: %08X\n", reg); > + } else { > + if (USB_STS_CFGSTS(readl(&priv_dev->regs->usb_sts))) > + ret = IRQ_HANDLED; Why is this done. We don't seem to be handling anything here. Don't we need to clear the usb_sts? > + goto irqend; > + } > + > + /* handle default endpoint OUT */ > + if (reg & EP_ISTS_EP_OUT0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, 0); > + ret = IRQ_HANDLED; > + } > + > + /* handle default endpoint IN */ > + if (reg & EP_ISTS_EP_IN0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, 1); > + ret = IRQ_HANDLED; > + } > + > + /* check if interrupt from non default endpoint, if no exit */ > + reg &= ~(EP_ISTS_EP_OUT0 | EP_ISTS_EP_IN0); > + if (!reg) > + goto irqend; > + > + do { > + unsigned int bit_pos = ffs(reg); > + u32 bit_mask = 1 << (bit_pos - 1); > + int index; > + > + index = cdns3_ep_reg_pos_to_index(bit_pos); > + cdns3_check_ep_interrupt_proceed(priv_dev->eps[index]); > + reg &= ~bit_mask; > + ret = IRQ_HANDLED; > + } while (reg); > + > +irqend: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > return ret; > } > > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > index 224f6b830bc9..8c2f363f9340 100644 > --- a/drivers/usb/cdns3/gadget.h > +++ b/drivers/usb/cdns3/gadget.h > @@ -1072,6 +1072,7 @@ int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > int cdns3_init_ep0(struct cdns3_device *priv_dev); > void cdns3_ep0_config(struct cdns3_device *priv_dev); > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir); > void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable); > struct usb_request *cdns3_next_request(struct list_head *list); > cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki 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=-8.6 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED 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 41400C43441 for ; Wed, 28 Nov 2018 14:54:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EE6BE224E3 for ; Wed, 28 Nov 2018 14:54:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="LQlNdAIv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EE6BE224E3 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com 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 S1728590AbeK2B4U (ORCPT ); Wed, 28 Nov 2018 20:56:20 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:36280 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727789AbeK2B4U (ORCPT ); Wed, 28 Nov 2018 20:56:20 -0500 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id wASEsHFF117938; Wed, 28 Nov 2018 08:54:17 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1543416857; bh=EVJ8l61Ls+bWnu1ZpMY6Q67JGzQtBtkcF8EVPtibDPo=; h=Subject:To:References:CC:From:Date:In-Reply-To; b=LQlNdAIvQDHiTvxe8jSfpKkYoHxioqCoSPmUK0AioMBUSdqAdAsmn944picx5GAL6 bkgEkfS3M+Nb5upB/kj+fYLTRCmDyTXoHZxuXj0d455P3Zw6C90wmX6/lYMaaqUPj0 vbj9oqBS3qbYnmQ9oAXe85v//7xcX5Pwv+A2woU4= Received: from DLEE104.ent.ti.com (dlee104.ent.ti.com [157.170.170.34]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id wASEsHC3072103 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 28 Nov 2018 08:54:17 -0600 Received: from DLEE113.ent.ti.com (157.170.170.24) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Wed, 28 Nov 2018 08:54:16 -0600 Received: from dlep33.itg.ti.com (157.170.170.75) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Wed, 28 Nov 2018 08:54:16 -0600 Received: from [192.168.2.6] (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id wASEsCvI025482; Wed, 28 Nov 2018 08:54:13 -0600 Subject: Re: [RFC PATCH v2 11/15] usb:cdns3: Implements ISR functionality. To: Pawel Laszczak , References: <1542535751-16079-1-git-send-email-pawell@cadence.com> <1542535751-16079-12-git-send-email-pawell@cadence.com> CC: , , , , , , , , , , From: Roger Quadros Message-ID: <5BFEAC14.1030408@ti.com> Date: Wed, 28 Nov 2018 16:54:12 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: <1542535751-16079-12-git-send-email-pawell@cadence.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 18/11/18 12:09, Pawel Laszczak wrote: > Patch adds set of generic functions used for handling interrupts > generated by controller. Interrupt related functions are divided > into three groups. The first is related to ep0 and is placed in ep0.c. > The second is responsible for non-default endpoints and is > implemented in gadget.c file. The last group is not related to > endpoints interrupts and is placed in gadget.c. > All groups have common entry point in cdns3_irq_handler_thread function. > > Signed-off-by: Pawel Laszczak > --- > drivers/usb/cdns3/ep0.c | 63 +++++++++++ > drivers/usb/cdns3/gadget.c | 224 ++++++++++++++++++++++++++++++++++++- > drivers/usb/cdns3/gadget.h | 1 + > 3 files changed, 287 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > index d05169e73631..eb92fd234bd7 100644 > --- a/drivers/usb/cdns3/ep0.c > +++ b/drivers/usb/cdns3/ep0.c > @@ -90,6 +90,69 @@ static void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) > } > } > > +static void __pending_setup_status_handler(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function > +} > + > +/** > + * cdns3_ep0_setup_phase - Handling setup USB requests > + * @priv_dev: extended gadget object > + */ > +static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function. > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev) > +{ > + //TODO: Implements this function > +} > + > +/** > + * cdns3_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0 > + * @priv_dev: extended gadget object > + * @dir: 1 for IN direction, 0 for OUT direction > + */ > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, 0 | (dir ? USB_DIR_IN : USB_DIR_OUT)); > + ep_sts_reg = readl(®s->ep_sts); > + > + __pending_setup_status_handler(priv_dev); > + > + if ((ep_sts_reg & EP_STS_SETUP) && dir == 0) { > + struct usb_ctrlrequest *setup = priv_dev->setup; > + > + writel(EP_STS_SETUP | EP_STS_IOC | EP_STS_ISP, ®s->ep_sts); instead you can just clear all events at the end of this function by writel(ep_sts_reg, ®s->ep_sts); > + > + priv_dev->ep0_data_dir = setup->bRequestType & USB_DIR_IN; > + cdns3_ep0_setup_phase(priv_dev); > + ep_sts_reg &= ~(EP_STS_SETUP | EP_STS_IOC | EP_STS_ISP); Not required. > + } > + > + if (ep_sts_reg & EP_STS_TRBERR) > + writel(EP_STS_TRBERR, &priv_dev->regs->ep_sts); Can be omitted. > + > + if (ep_sts_reg & EP_STS_DESCMIS) { > + writel(EP_STS_DESCMIS, &priv_dev->regs->ep_sts); This as well. > + > + if (dir == 0 && !priv_dev->setup_pending) { > + priv_dev->ep0_data_dir = 0; > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + 8, 0); > + } > + } > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + writel(EP_STS_IOC, &priv_dev->regs->ep_sts); this write can be omitted. > + cdns3_transfer_completed(priv_dev); > + } here you can do writel(ep_sts_reg, ®s->ep_sts); > +} > + > /** > * cdns3_gadget_ep0_enable > * Function shouldn't be called by gadget driver, > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > index c965da16c0c8..309202474e57 100644 > --- a/drivers/usb/cdns3/gadget.c > +++ b/drivers/usb/cdns3/gadget.c > @@ -58,6 +58,18 @@ void cdns3_set_register_bit(void __iomem *ptr, u32 mask) > writel(mask, ptr); > } > > +/** > + * cdns3_ep_reg_pos_to_index - Macro converts bit position of ep_ists register > + * to index of endpoint object in cdns3_device.eps[] container > + * @i: bit position of endpoint for which endpoint object is required > + * > + * Remember that endpoint container doesn't contain default endpoint > + */ > +static u8 cdns3_ep_reg_pos_to_index(int i) > +{ > + return ((i / 16) + (((i % 16) - 2) * 2)); > +} > + > /** > * cdns3_next_request - returns next request from list > * @list: list containing requests > @@ -188,6 +200,21 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > priv_ep->flags |= EP_STALL; > } > > +/** > + * cdns3_gadget_unconfig - reset device configuration > + * @priv_dev: extended gadget object > + */ > +void cdns3_gadget_unconfig(struct cdns3_device *priv_dev) > +{ > + /* RESET CONFIGURATION */ > + writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); > + > + cdns3_enable_l1(priv_dev, 0); > + priv_dev->hw_configured_flag = 0; > + priv_dev->onchip_mem_allocated_size = 0; > + priv_dev->out_mem_is_allocated = 0; > +} > + > void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) > { > if (enable) > @@ -196,6 +223,23 @@ void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) > writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > } > > +static enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev) > +{ > + u32 reg; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (DEV_SUPERSPEED(reg)) > + return USB_SPEED_SUPER; > + else if (DEV_HIGHSPEED(reg)) > + return USB_SPEED_HIGH; > + else if (DEV_FULLSPEED(reg)) > + return USB_SPEED_FULL; > + else if (DEV_LOWSPEED(reg)) > + return USB_SPEED_LOW; > + return USB_SPEED_UNKNOWN; > +} > + > /** > * cdns3_gadget_giveback - call struct usb_request's ->complete callback > * @priv_ep: The endpoint to whom the request belongs to > @@ -221,12 +265,136 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > */ > int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > struct usb_request *request) > +{ > + return 0; > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > { > //TODO: Implements this function. > +} > + > +/** > + * cdns3_check_ep_interrupt_proceed - Processes interrupt related to endpoint > + * @priv_ep: endpoint object > + * > + * Returns 0 > + */ > +static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_usb_regs __iomem *regs; > + u32 ep_sts_reg; > + > + regs = priv_dev->regs; > + > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + ep_sts_reg = readl(®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_TRBERR) > + writel(EP_STS_TRBERR, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_ISOERR) > + writel(EP_STS_ISOERR, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_OUTSMM) > + writel(EP_STS_OUTSMM, ®s->ep_sts); > + > + if (ep_sts_reg & EP_STS_NRDY) > + writel(EP_STS_NRDY, ®s->ep_sts); Why check for each bit when you are not doing anything. Instead at the end you could just do writel(ep_sts_reg, ®s->ep_sts) to clear all pending events. > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + writel(EP_STS_IOC | EP_STS_ISP, ®s->ep_sts); > + cdns3_transfer_completed(priv_dev, priv_ep); > + } > + > + if (ep_sts_reg & EP_STS_DESCMIS) > + writel(EP_STS_DESCMIS, ®s->ep_sts); > > return 0; > } > > +/** > + * cdns3_check_usb_interrupt_proceed - Processes interrupt related to device > + * @priv_dev: extended gadget object > + * @usb_ists: bitmap representation of device's reported interrupts > + * (usb_ists register value) > + */ > +static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, > + u32 usb_ists) > +{ > + struct cdns3_usb_regs __iomem *regs; > + int speed = 0; > + > + regs = priv_dev->regs; > + > + /* Connection detected */ > + if (usb_ists & (USB_ISTS_CON2I | USB_ISTS_CONI)) { > + writel(USB_ISTS_CON2I | USB_ISTS_CONI, ®s->usb_ists); > + speed = cdns3_get_speed(priv_dev); > + > + dev_dbg(&priv_dev->dev, "Connection detected at speed: %s %d\n", > + usb_speed_string(speed), speed); > + > + priv_dev->gadget.speed = speed; > + priv_dev->is_connected = 1; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_POWERED); > + cdns3_ep0_config(priv_dev); > + } > + > + /* SS Disconnection detected */ > + if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) { > + dev_dbg(&priv_dev->dev, "Disconnection detected\n"); > + > + writel(USB_ISTS_DIS2I | USB_ISTS_DISI, ®s->usb_ists); > + if (priv_dev->gadget_driver && > + priv_dev->gadget_driver->disconnect) { > + spin_unlock(&priv_dev->lock); > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + spin_lock(&priv_dev->lock); > + } > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED); > + priv_dev->is_connected = 0; > + cdns3_gadget_unconfig(priv_dev); > + } What about non Super-Speed disconnects? > + > + if (usb_ists & USB_ISTS_L2ENTI) { > + dev_dbg(&priv_dev->dev, "Device suspended\n"); > + writel(USB_ISTS_L2ENTI, ®s->usb_ists); > + } > + > + /* Exit from standby mode on L2 exit (Suspend in HS/FS or SS) */ > + if (usb_ists & USB_ISTS_L2EXTI) { > + dev_dbg(&priv_dev->dev, "[Interrupt] L2 exit detected\n"); > + writel(USB_ISTS_L2EXTI, ®s->usb_ists); > + } > + > + /* Exit from standby mode on U3 exit (Suspend in HS/FS or SS). */ > + if (usb_ists & USB_ISTS_U3EXTI) { > + dev_dbg(&priv_dev->dev, "U3 exit detected\n"); > + writel(USB_ISTS_U3EXTI, ®s->usb_ists); > + } > + > + /* resets cases */ > + if (usb_ists & (USB_ISTS_UWRESI | USB_ISTS_UHRESI | USB_ISTS_U2RESI)) { > + writel(USB_ISTS_U2RESI | USB_ISTS_UWRESI | USB_ISTS_UHRESI, > + ®s->usb_ists); > + > + /*read again to check the actuall speed*/ > + speed = cdns3_get_speed(priv_dev); > + > + dev_dbg(&priv_dev->dev, "Reset detected at speed: %s %d\n", > + usb_speed_string(speed), speed); > + > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_DEFAULT); > + priv_dev->gadget.speed = speed; > + cdns3_gadget_unconfig(priv_dev); > + cdns3_ep0_config(priv_dev); > + } > +} > + > /** > * cdns3_irq_handler - irq line interrupt handler > * @cdns: cdns3 instance > @@ -237,8 +405,62 @@ int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > */ > static irqreturn_t cdns3_irq_handler_thread(struct cdns3 *cdns) > { > + struct cdns3_device *priv_dev; > irqreturn_t ret = IRQ_NONE; > - //TODO: implements this function > + unsigned long flags; > + u32 reg; > + > + priv_dev = container_of(cdns->gadget_dev, struct cdns3_device, dev); > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + /* check USB device interrupt */ > + reg = readl(&priv_dev->regs->usb_ists); > + if (reg) { > + dev_dbg(&priv_dev->dev, "IRQ: usb_ists: %08X\n", reg); dev_dbg will be terribly slow to be useful. Tracepoints? > + cdns3_check_usb_interrupt_proceed(priv_dev, reg); > + ret = IRQ_HANDLED; > + } > + > + /* check endpoint interrupt */ > + reg = readl(&priv_dev->regs->ep_ists); > + if (reg != 0) { > + dev_dbg(&priv_dev->dev, "IRQ ep_ists: %08X\n", reg); > + } else { > + if (USB_STS_CFGSTS(readl(&priv_dev->regs->usb_sts))) > + ret = IRQ_HANDLED; Why is this done. We don't seem to be handling anything here. Don't we need to clear the usb_sts? > + goto irqend; > + } > + > + /* handle default endpoint OUT */ > + if (reg & EP_ISTS_EP_OUT0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, 0); > + ret = IRQ_HANDLED; > + } > + > + /* handle default endpoint IN */ > + if (reg & EP_ISTS_EP_IN0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, 1); > + ret = IRQ_HANDLED; > + } > + > + /* check if interrupt from non default endpoint, if no exit */ > + reg &= ~(EP_ISTS_EP_OUT0 | EP_ISTS_EP_IN0); > + if (!reg) > + goto irqend; > + > + do { > + unsigned int bit_pos = ffs(reg); > + u32 bit_mask = 1 << (bit_pos - 1); > + int index; > + > + index = cdns3_ep_reg_pos_to_index(bit_pos); > + cdns3_check_ep_interrupt_proceed(priv_dev->eps[index]); > + reg &= ~bit_mask; > + ret = IRQ_HANDLED; > + } while (reg); > + > +irqend: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > return ret; > } > > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > index 224f6b830bc9..8c2f363f9340 100644 > --- a/drivers/usb/cdns3/gadget.h > +++ b/drivers/usb/cdns3/gadget.h > @@ -1072,6 +1072,7 @@ int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > int cdns3_init_ep0(struct cdns3_device *priv_dev); > void cdns3_ep0_config(struct cdns3_device *priv_dev); > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir); > void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable); > struct usb_request *cdns3_next_request(struct list_head *list); > cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki