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,3/7] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller From: Chunfeng Yun Message-Id: <1555295036.10179.192.camel@mhfsdcap03> Date: Mon, 15 Apr 2019 10:23:56 +0800 To: Biju Das Cc: Heikki Krogerus , Greg Kroah-Hartman , Felipe Balbi , linux-usb@vger.kernel.org, Simon Horman , Yoshihiro Shimoda , Geert Uytterhoeven , Chris Paterson , Fabrizio Castro , linux-renesas-soc@vger.kernel.org List-ID: SGksCk9uIEZyaSwgMjAxOS0wNC0xMiBhdCAxMToxNiArMDEwMCwgQmlqdSBEYXMgd3JvdGU6Cj4g RHJpdmVyIGZvciBUSSBIRDNTUzMyMjAgVVNCIFR5cGUtQyBEUlAgcG9ydCBjb250cm9sbGVyLgo+ IAo+IFRoZSBkcml2ZXIgY3VycmVudGx5IHJlZ2lzdGVycyB0aGUgcG9ydCBhbmQgc3VwcG9ydHMg ZGF0YSByb2xlIHN3YXBwaW5nLgo+IAo+IFNpZ25lZC1vZmYtYnk6IEJpanUgRGFzIDxiaWp1LmRh c0BicC5yZW5lc2FzLmNvbT4KPiAtLS0KPiAgTm90ZTogVGhpcyBwYXRjaCBoYXMgY29tcGlsYXRp b24gZGVwZW5kZW5jeSBvbiAKPiAgaHR0cHM6Ly9wYXRjaHdvcmsua2VybmVsLm9yZy9wYXRjaC8x MDg4MjU1NS8KPiAgCj4gIFYyLS0+VjMKPiAgICAqIFVzZWQgdGhlIG5ldyBhcGkgInVzYl9yb2xl X3N3aXRjaCBieSBub2RlIiBmb3IgZ2V0dGluZwo+ICAgICAgcmVtb3RlIGVuZHBvaW50IGFzc29j aWF0ZWQgd2l0aCBUeXBlLUMgVVNCIERSUCBwb3J0Cj4gICAgICBjb250cm9sbGVyIGRldmljZXMu Cj4gIFYxLS0+VjIKPiAgICAqIERyaXZlciB1c2VzIHVzYiByb2xlIGNsYXNzIGluc3RlYWQgb2Yg ZXh0Y29uIGZvciBkdWFsIHJvbGUgc3dpdGNoCj4gICAgICBhbmQgYWxzbyBoYW5kbGVzIGNvbm5l Y3QvZGlzY29ubmVjdCBldmVudHMuCj4gLS0tCj4gIGRyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcg ICAgIHwgIDEwICsrCj4gIGRyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxlICAgIHwgICAxICsKPiAg ZHJpdmVycy91c2IvdHlwZWMvaGQzc3MzMjIwLmMgfCAyNzggKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmlsZXMgY2hhbmdlZCwgMjg5IGluc2VydGlvbnMo KykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL3R5cGVjL2hkM3NzMzIyMC5jCj4g Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcgYi9kcml2ZXJzL3VzYi90 eXBlYy9LY29uZmlnCj4gaW5kZXggODlkOTE5My4uOTJhMzcxNyAxMDA2NDQKPiAtLS0gYS9kcml2 ZXJzL3VzYi90eXBlYy9LY29uZmlnCj4gKysrIGIvZHJpdmVycy91c2IvdHlwZWMvS2NvbmZpZwo+ IEBAIC01MCw2ICs1MCwxNiBAQCBzb3VyY2UgImRyaXZlcnMvdXNiL3R5cGVjL3RjcG0vS2NvbmZp ZyIKPiAgCj4gIHNvdXJjZSAiZHJpdmVycy91c2IvdHlwZWMvdWNzaS9LY29uZmlnIgo+ICAKPiAr Y29uZmlnIFRZUEVDX0hEM1NTMzIyMAo+ICsJdHJpc3RhdGUgIlRJIEhEM1NTMzIyMCBUeXBlLUMg RFJQIFBvcnQgY29udHJvbGxlciBkcml2ZXIiCj4gKwlkZXBlbmRzIG9uIEkyQwo+ICsJaGVscAo+ ICsJICBTYXkgWSBvciBNIGhlcmUgaWYgeW91ciBzeXN0ZW0gaGFzIFRJIEhEM1NTMzIyMCBUeXBl LUMgRFJQIFBvcnQKPiArCSAgY29udHJvbGxlciBkcml2ZXIuCj4gKwo+ICsJICBJZiB5b3UgY2hv b3NlIHRvIGJ1aWxkIHRoaXMgZHJpdmVyIGFzIGEgZHluYW1pY2FsbHkgbGlua2VkIG1vZHVsZSwg dGhlCj4gKwkgIG1vZHVsZSB3aWxsIGJlIGNhbGxlZCBoZDNzczMyMjAua28uCj4gKwo+ICBjb25m aWcgVFlQRUNfVFBTNjU5OFgKPiAgCXRyaXN0YXRlICJUSSBUUFM2NTk4eCBVU0IgUG93ZXIgRGVs aXZlcnkgY29udHJvbGxlciBkcml2ZXIiCj4gIAlkZXBlbmRzIG9uIEkyQwo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZSBiL2RyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxl Cj4gaW5kZXggNjY5NmI3Mi4uNzc1M2E1YzMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy91c2IvdHlw ZWMvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZQo+IEBAIC00LDUg KzQsNiBAQCB0eXBlYy15CQkJCTo9IGNsYXNzLm8gbXV4Lm8gYnVzLm8KPiAgb2JqLSQoQ09ORklH X1RZUEVDKQkJKz0gYWx0bW9kZXMvCj4gIG9iai0kKENPTkZJR19UWVBFQ19UQ1BNKQkrPSB0Y3Bt Lwo+ICBvYmotJChDT05GSUdfVFlQRUNfVUNTSSkJKz0gdWNzaS8KPiArb2JqLSQoQ09ORklHX1RZ UEVDX0hEM1NTMzIyMCkJKz0gaGQzc3MzMjIwLm8KPiAgb2JqLSQoQ09ORklHX1RZUEVDX1RQUzY1 OThYKQkrPSB0cHM2NTk4eC5vCj4gIG9iai0kKENPTkZJR19UWVBFQykJCSs9IG11eC8KPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvaGQzc3MzMjIwLmMgYi9kcml2ZXJzL3VzYi90eXBl Yy9oZDNzczMyMjAuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uYjVj YjQyYwo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9oZDNzczMyMjAu Ywo+IEBAIC0wLDAgKzEsMjc4IEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwt Mi4wKwo+ICsvKgo+ICsgKiBUSSBIRDNTUzMyMjAgVHlwZS1DIERSUCBQb3J0IENvbnRyb2xsZXIg RHJpdmVyCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxOSBSZW5lc2FzIEVsZWN0cm9uaWNz IENvcnAuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVk ZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC91c2Ivcm9sZS5oPgo+ICsjaW5jbHVk ZSA8bGludXgvaXJxcmV0dXJuLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvb2ZfZ3JhcGguaD4K PiArI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgo+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ ICsjaW5jbHVkZSA8bGludXgvdXNiL3R5cGVjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5o Pgo+ICsKPiArI2RlZmluZSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTAkweDA5Cj4gKyNkZWZp bmUgSEQzU1MzMjIwX1JFR19HRU5fQ1RSTAkJMHgwQQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdf REVWX1JFVgkJMHhBMAo+ICsKPiArLyogUmVnaXN0ZXIgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NU UkwqLwo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJMX0FUVEFDSEVEX1NUQVRF X01BU0sJKEJJVCg3KSB8IEJJVCg2KSkKPiArI2RlZmluZSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRf Q1RSTF9BU19ERlAJCUJJVCg2KQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJM X0FTX1VGUAkJQklUKDcpCj4gKyNkZWZpbmUgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkxfVE9f QUNDRVNTT1JZCQkoQklUKDcpIHwgQklUKDYpKQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfQ05f U1RBVF9DVFJMX0lOVF9TVEFUVVMJCUJJVCg0KQo+ICsKPiArLyogUmVnaXN0ZXIgSEQzU1MzMjIw X1JFR19HRU5fQ1RSTCovCj4gKyNkZWZpbmUgSEQzU1MzMjIwX1JFR19HRU5fQ1RSTF9TUkNfUFJF Rl9NQVNLCQkoQklUKDIpIHwgQklUKDEpKQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfR0VOX0NU UkxfU1JDX1BSRUZfRFJQX0RFRkFVTFQJMHgwMAo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfR0VO X0NUUkxfU1JDX1BSRUZfRFJQX1RSWV9TTksJQklUKDEpCj4gKyNkZWZpbmUgSEQzU1MzMjIwX1JF R19HRU5fQ1RSTF9TUkNfUFJFRl9EUlBfVFJZX1NSQwkoQklUKDIpIHwgQklUKDEpKQo+ICsKPiAr c3RydWN0IGhkM3NzMzIyMCB7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwlzdHJ1Y3QgcmVn bWFwICpyZWdtYXA7Cj4gKwlzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoCSpyb2xlX3N3Owo+ICsJc3Ry dWN0IHR5cGVjX3BvcnQgKnBvcnQ7Cj4gKwlzdHJ1Y3QgdHlwZWNfY2FwYWJpbGl0eSB0eXBlY19j YXA7Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IGhkM3NzMzIyMF9zZXRfc291cmNlX3ByZWYoc3Ry dWN0IGhkM3NzMzIyMCAqaGQzc3MzMjIwLCBpbnQgc3JjX3ByZWYpCj4gK3sKPiArCXVuc2lnbmVk IGludCByZWdfdmFsOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChoZDNz czMyMjAtPnJlZ21hcCwgSEQzU1MzMjIwX1JFR19HRU5fQ1RSTCwgJnJlZ192YWwpOwo+ICsJaWYg KHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZWdfdmFsICY9IH5IRDNTUzMyMjBf UkVHX0dFTl9DVFJMX1NSQ19QUkVGX01BU0s7Cj4gKwlyZWdfdmFsIHw9IHNyY19wcmVmOwo+ICsK PiArCXJldHVybiByZWdtYXBfd3JpdGUoaGQzc3MzMjIwLT5yZWdtYXAsIEhEM1NTMzIyMF9SRUdf R0VOX0NUUkwsIHJlZ192YWwpOwp1c2UgcmVnbWFwX3VwZGF0ZV9iaXRzKCk/Cj4gK30KPiArCj4g K3N0YXRpYyBlbnVtIHVzYl9yb2xlIGhkM3NzMzIyMF9nZXRfYXR0YWNoZWRfc3RhdGUoc3RydWN0 IGhkM3NzMzIyMCAqaGQzc3MzMjIwKQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgcmVnX3ZhbDsKPiAr CWVudW0gdXNiX3JvbGUgYXR0YWNoZWRfc3RhdGU7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9 IHJlZ21hcF9yZWFkKGhkM3NzMzIyMC0+cmVnbWFwLCBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RS TCwKPiArCQkJICAmcmVnX3ZhbCk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ ICsKPiArCXN3aXRjaCAocmVnX3ZhbCAmIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJMX0FUVEFD SEVEX1NUQVRFX01BU0spIHsKPiArCWNhc2UgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkxfQVNf REZQOgo+ICsJCWF0dGFjaGVkX3N0YXRlID0gVVNCX1JPTEVfSE9TVDsKPiArCWJyZWFrOwo+ICsJ Y2FzZSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9BU19VRlA6Cj4gKwkJYXR0YWNoZWRfc3Rh dGUgPSBVU0JfUk9MRV9ERVZJQ0U7Cj4gKwlicmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJYXR0YWNo ZWRfc3RhdGUgPSBVU0JfUk9MRV9OT05FOwo+ICsJfQo+ICsKPiArCXJldHVybiBhdHRhY2hlZF9z dGF0ZTsKPiArfQo+ICsKPiArc3RhdGljIGludCBoZDNzczMyMjBfZHJfc2V0KGNvbnN0IHN0cnVj dCB0eXBlY19jYXBhYmlsaXR5ICpjYXAsCj4gKwkJCSAgICBlbnVtIHR5cGVjX2RhdGFfcm9sZSBy b2xlKQo+ICt7Cj4gKwlzdHJ1Y3QgaGQzc3MzMjIwICpoZDNzczMyMjAgPSBjb250YWluZXJfb2Yo Y2FwLCBzdHJ1Y3QgaGQzc3MzMjIwLAo+ICsJCQkJCQkgICB0eXBlY19jYXApOwo+ICsJZW51bSB1 c2Jfcm9sZSByb2xlX3ZhbDsKPiArCWludCBwcmVmLCByZXQgPSAwOwo+ICsKPiArCWlmIChyb2xl ID09IFRZUEVDX0hPU1QpIHsKPiArCQlyb2xlX3ZhbCA9IFVTQl9ST0xFX0hPU1Q7Cj4gKwkJcHJl ZiA9IEhEM1NTMzIyMF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX1RSWV9TUkM7Cj4gKwl9IGVs c2Ugewo+ICsJCXJvbGVfdmFsID0gVVNCX1JPTEVfREVWSUNFOwo+ICsJCXByZWYgPSBIRDNTUzMy MjBfUkVHX0dFTl9DVFJMX1NSQ19QUkVGX0RSUF9UUllfU05LOwo+ICsJfQo+ICsKPiArCXJldCA9 IGhkM3NzMzIyMF9zZXRfc291cmNlX3ByZWYoaGQzc3MzMjIwLCBwcmVmKTsKPiArCXVzbGVlcF9y YW5nZSgxMCwgMTAwKTsKPiArCj4gKwl1c2Jfcm9sZV9zd2l0Y2hfc2V0X3JvbGUoaGQzc3MzMjIw LT5yb2xlX3N3LCByb2xlX3ZhbCk7Cj4gKwl0eXBlY19zZXRfZGF0YV9yb2xlKGhkM3NzMzIyMC0+ cG9ydCwgcm9sZSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQg aGQzc3MzMjIwX3NldF9yb2xlKHN0cnVjdCBoZDNzczMyMjAgKmhkM3NzMzIyMCkKPiArewo+ICsJ ZW51bSB1c2Jfcm9sZSByb2xlX3N0YXRlID0gaGQzc3MzMjIwX2dldF9hdHRhY2hlZF9zdGF0ZSho ZDNzczMyMjApOwo+ICsKPiArCXVzYl9yb2xlX3N3aXRjaF9zZXRfcm9sZShoZDNzczMyMjAtPnJv bGVfc3csIHJvbGVfc3RhdGUpOwo+ICsJaWYgKHJvbGVfc3RhdGUgPT0gVVNCX1JPTEVfTk9ORSkK PiArCQloZDNzczMyMjBfc2V0X3NvdXJjZV9wcmVmKGhkM3NzMzIyMCwKPiArCQkJCUhEM1NTMzIy MF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX0RFRkFVTFQpOwo+ICsKPiArCXN3aXRjaCAocm9s ZV9zdGF0ZSkgewo+ICsJY2FzZSBVU0JfUk9MRV9IT1NUOgo+ICsJCXR5cGVjX3NldF9kYXRhX3Jv bGUoaGQzc3MzMjIwLT5wb3J0LCBUWVBFQ19IT1NUKTsKPiArCQlicmVhazsKPiArCWNhc2UgVVNC X1JPTEVfREVWSUNFOgo+ICsJCXR5cGVjX3NldF9kYXRhX3JvbGUoaGQzc3MzMjIwLT5wb3J0LCBU WVBFQ19ERVZJQ0UpOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlicmVhazsKPiArCX0K PiArfQo+ICsKPiAraXJxcmV0dXJuX3QgaGQzc3MzMjIwX2lycShzdHJ1Y3QgaGQzc3MzMjIwICpo ZDNzczMyMjApCj4gK3sKPiArCWludCBlcnI7Cj4gKwl1bnNpZ25lZCBpbnQgZGF0YTsKPiArCj4g KwloZDNzczMyMjBfc2V0X3JvbGUoaGQzc3MzMjIwKTsKPiArCj4gKwllcnIgPSByZWdtYXBfcmVh ZChoZDNzczMyMjAtPnJlZ21hcCwgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkwsICZkYXRhKTsK PiArCWlmIChlcnIgPCAwKQo+ICsJCXJldHVybiBJUlFfTk9ORTsKPiArCj4gKwllcnIgPSByZWdt YXBfd3JpdGUoaGQzc3MzMjIwLT5yZWdtYXAsIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJMLAo+ ICsJCQkgICBkYXRhIHwgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkxfSU5UX1NUQVRVUyk7Cj4g KwlpZiAoZXJyIDwgMCkKPiArCQlyZXR1cm4gSVJRX05PTkU7CnVzZSByZWdtYXBfeHh4X2JpdHMo KSBpZiBwb3NzaWJsZT8KPiArCj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiArCj4gK3N0 YXRpYyBpcnFyZXR1cm5fdCBoZDNzczMyMjBfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGF0 YSkKPiArewo+ICsJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQoZGF0 YSk7Cj4gKwlzdHJ1Y3QgaGQzc3MzMjIwICpoZDNzczMyMjAgPSBpMmNfZ2V0X2NsaWVudGRhdGEo Y2xpZW50KTsKPiArCj4gKwlyZXR1cm4gaGQzc3MzMjIwX2lycShoZDNzczMyMjApOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9jb25maWcgY29uZmlnID0gewo+ICsJLnJl Z19iaXRzID0gOCwKPiArCS52YWxfYml0cyA9IDgsCj4gKwkubWF4X3JlZ2lzdGVyID0gMHgwQSwK PiArfTsKPiArCj4gK3N0YXRpYyBpbnQgaGQzc3MzMjIwX3Byb2JlKHN0cnVjdCBpMmNfY2xpZW50 ICpjbGllbnQsCj4gKwkJY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+ICt7Cj4gKwlz dHJ1Y3QgaGQzc3MzMjIwICpoZDNzczMyMjA7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wOwo+ ICsJc3RydWN0IGRldmljZV9ub2RlICpwYXJlbnQ7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmNo aWxkOwo+ICsJaW50IHJldDsKPiArCXVuc2lnbmVkIGludCBkYXRhOwo+ICsKPiArCWhkM3NzMzIy MCA9IGRldm1fa3phbGxvYygmY2xpZW50LT5kZXYsIHNpemVvZihzdHJ1Y3QgaGQzc3MzMjIwKSwK PiArCQkJCSBHRlBfS0VSTkVMKTsKPiArCWlmICghaGQzc3MzMjIwKQo+ICsJCXJldHVybiAtRU5P TUVNOwo+ICsKPiArCWkyY19zZXRfY2xpZW50ZGF0YShjbGllbnQsIGhkM3NzMzIyMCk7Cj4gKwo+ ICsJaGQzc3MzMjIwLT5kZXYgPSAmY2xpZW50LT5kZXY7Cj4gKwloZDNzczMyMjAtPnJlZ21hcCA9 IGRldm1fcmVnbWFwX2luaXRfaTJjKGNsaWVudCwgJmNvbmZpZyk7Cj4gKwlpZiAoSVNfRVJSKGhk M3NzMzIyMC0+cmVnbWFwKSkKPiArCQlyZXR1cm4gUFRSX0VSUihoZDNzczMyMjAtPnJlZ21hcCk7 Cj4gKwo+ICsJaGQzc3MzMjIwX3NldF9zb3VyY2VfcHJlZihoZDNzczMyMjAsCj4gKwkJCQkgIEhE M1NTMzIyMF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX0RFRkFVTFQpOwo+ICsJbnAgPSBoZDNz czMyMjAtPmRldi0+b2Zfbm9kZTsKPiArCWNoaWxkID0gb2ZfZ3JhcGhfZ2V0X2VuZHBvaW50X2J5 X3JlZ3MobnAsIC0xLCAwKTsKPiArCXBhcmVudCA9IG9mX2dyYXBoX2dldF9yZW1vdGVfcG9ydF9w YXJlbnQoY2hpbGQpOwo+ICsJaGQzc3MzMjIwLT5yb2xlX3N3ID0gZndub2RlX3VzYl9yb2xlX3N3 aXRjaF9nZXQob2ZfZndub2RlX2hhbmRsZShwYXJlbnQpKTsKPiArCWlmIChJU19FUlJfT1JfTlVM TChoZDNzczMyMjAtPnJvbGVfc3cpKSB7Cj4gKwkJb2Zfbm9kZV9wdXQoY2hpbGQpOwo+ICsJCW9m X25vZGVfcHV0KHBhcmVudCk7Cj4gKwkJcmV0dXJuIFBUUl9FUlIoaGQzc3MzMjIwLT5yb2xlX3N3 KTsKPiArCX0KPiArCj4gKwlvZl9ub2RlX3B1dChjaGlsZCk7Cj4gKwlvZl9ub2RlX3B1dChwYXJl bnQpOwo+ICsKPiArCWhkM3NzMzIyMC0+dHlwZWNfY2FwLnByZWZlcl9yb2xlID0gVFlQRUNfTk9f UFJFRkVSUkVEX1JPTEU7Cj4gKwloZDNzczMyMjAtPnR5cGVjX2NhcC5kcl9zZXQgPSBoZDNzczMy MjBfZHJfc2V0Owo+ICsJaGQzc3MzMjIwLT50eXBlY19jYXAudHlwZSA9IFRZUEVDX1BPUlRfRFJQ Owo+ICsJaGQzc3MzMjIwLT50eXBlY19jYXAuZGF0YSA9IFRZUEVDX1BPUlRfRFJEOwo+ICsKPiAr CWhkM3NzMzIyMC0+cG9ydCA9IHR5cGVjX3JlZ2lzdGVyX3BvcnQoJmNsaWVudC0+ZGV2LAo+ICsJ CQkJCSAgICAgICZoZDNzczMyMjAtPnR5cGVjX2NhcCk7Cj4gKwlpZiAoSVNfRVJSKGhkM3NzMzIy MC0+cG9ydCkpCj4gKwkJcmV0dXJuIFBUUl9FUlIoaGQzc3MzMjIwLT5wb3J0KTsKPiArCj4gKwlo ZDNzczMyMjBfc2V0X3JvbGUoaGQzc3MzMjIwKTsKPiArCWlmIChjbGllbnQtPmlycSA+IDApIHsK PiArCQlyZXQgPSByZWdtYXBfcmVhZChoZDNzczMyMjAtPnJlZ21hcCwgSEQzU1MzMjIwX1JFR19D Tl9TVEFUX0NUUkwsCj4gKwkJCQkgICZkYXRhKTsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJZ290 byBlcnJvcjsKPiArCj4gKwkJaWYgKGRhdGEgJiBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9J TlRfU1RBVFVTKSB7Cj4gKwkJCXJldCA9IHJlZ21hcF93cml0ZShoZDNzczMyMjAtPnJlZ21hcCwK PiArCQkJCUhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJMLAo+ICsJCQkJZGF0YSB8IEhEM1NTMzIy MF9SRUdfQ05fU1RBVF9DVFJMX0lOVF9TVEFUVVMpOwo+ICsJCQlpZiAocmV0IDwgMCkKPiArCQkJ CWdvdG8gZXJyb3I7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRf aXJxKCZjbGllbnQtPmRldiwgY2xpZW50LT5pcnEsIE5VTEwsCj4gKwkJCQkJaGQzc3MzMjIwX2ly cV9oYW5kbGVyLAo+ICsJCQkJCUlSUUZfVFJJR0dFUl9GQUxMSU5HIHwgSVJRRl9PTkVTSE9ULAo+ ICsJCQkJCSJoZDNzczMyMjAiLCAmY2xpZW50LT5kZXYpOwo+ICsJCWlmIChyZXQpCj4gKwkJCWdv dG8gZXJyb3I7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKGNs aWVudCwgSEQzU1MzMjIwX1JFR19ERVZfUkVWKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCWdvdG8g ZXJyb3I7Cj4gKwo+ICsJZGV2X2luZm8oJmNsaWVudC0+ZGV2LCAicHJvYmVkIHJldmlzaW9uPTB4 JXhcbiIsIHJldCk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK2Vycm9yOgo+ICsJdHlwZWNfdW5yZWdp c3Rlcl9wb3J0KGhkM3NzMzIyMC0+cG9ydCk7Cj4gKwl1c2Jfcm9sZV9zd2l0Y2hfcHV0KGhkM3Nz MzIyMC0+cm9sZV9zdyk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBoZDNzczMyMjBfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCj4gK3sKPiArCXN0 cnVjdCBoZDNzczMyMjAgKmhkM3NzMzIyMCA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwo+ ICsKPiArCXR5cGVjX3VucmVnaXN0ZXJfcG9ydChoZDNzczMyMjAtPnBvcnQpOwo+ICsJdXNiX3Jv bGVfc3dpdGNoX3B1dChoZDNzczMyMjAtPnJvbGVfc3cpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBkZXZfaWRzW10gPSB7Cj4g Kwl7IC5jb21wYXRpYmxlID0gInRpLGhkM3NzMzIyMCJ9LAo+ICsJe30KPiArfTsKPiArTU9EVUxF X0RFVklDRV9UQUJMRShvZiwgZGV2X2lkcyk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGkyY19kcml2 ZXIgaGQzc3MzMjIwX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAiaGQz c3MzMjIwIiwKPiArCQkub3duZXIgPSBUSElTX01PRFVMRSwKbm8gbmVlZCBzZXQgLm93bmVyCgo+ ICsJCS5vZl9tYXRjaF90YWJsZSA9IG9mX21hdGNoX3B0cihkZXZfaWRzKSwKPiArCX0sCj4gKwku cHJvYmUgPSBoZDNzczMyMjBfcHJvYmUsCj4gKwkucmVtb3ZlID0gIGhkM3NzMzIyMF9yZW1vdmUs Cj4gK307Cj4gKwo+ICttb2R1bGVfaTJjX2RyaXZlcihoZDNzczMyMjBfZHJpdmVyKTsKPiArCj4g K01PRFVMRV9BVVRIT1IoIkJpanUgRGFzIDxiaWp1LmRhc0BicC5yZW5lc2FzLmNvbT4iKTsKPiAr TU9EVUxFX0RFU0NSSVBUSU9OKCJUSSBIRDNTUzMyMjAgRFJQIFBvcnQgQ29udHJvbGxlciBEcml2 ZXIiKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo= 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=-6.9 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED autolearn=unavailable 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 A7C1CC282CE for ; Mon, 15 Apr 2019 02:24:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6D9C320848 for ; Mon, 15 Apr 2019 02:24:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726178AbfDOCYG (ORCPT ); Sun, 14 Apr 2019 22:24:06 -0400 Received: from Mailgw01.mediatek.com ([1.203.163.78]:9848 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725789AbfDOCYF (ORCPT ); Sun, 14 Apr 2019 22:24:05 -0400 X-UUID: 540df32760c9495cb2ea24fee074a7d6-20190415 X-UUID: 540df32760c9495cb2ea24fee074a7d6-20190415 Received: from mtkcas35.mediatek.inc [(172.27.4.253)] by mailgw01.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLS) with ESMTP id 1841856273; Mon, 15 Apr 2019 10:23:58 +0800 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by MTKMBS31DR.mediatek.inc (172.27.6.102) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 15 Apr 2019 10:23:56 +0800 Received: from [10.17.3.153] (172.27.4.253) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 15 Apr 2019 10:23:56 +0800 Message-ID: <1555295036.10179.192.camel@mhfsdcap03> Subject: Re: [PATCH V3 3/7] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller From: Chunfeng Yun To: Biju Das CC: Heikki Krogerus , Greg Kroah-Hartman , Felipe Balbi , , Simon Horman , "Yoshihiro Shimoda" , Geert Uytterhoeven , Chris Paterson , Fabrizio Castro , Date: Mon, 15 Apr 2019 10:23:56 +0800 In-Reply-To: <1555064179-15626-4-git-send-email-biju.das@bp.renesas.com> References: <1555064179-15626-1-git-send-email-biju.das@bp.renesas.com> <1555064179-15626-4-git-send-email-biju.das@bp.renesas.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 Content-Transfer-Encoding: 7bit MIME-Version: 1.0 X-MTK: N Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Message-ID: <20190415022356.l8gJ1v5VuBNPvtSXhk_zD5xmidca-BTkh0Gvgi0zOU4@z> Hi, On Fri, 2019-04-12 at 11:16 +0100, Biju Das wrote: > Driver for TI HD3SS3220 USB Type-C DRP port controller. > > The driver currently registers the port and supports data role swapping. > > Signed-off-by: Biju Das > --- > Note: This patch has compilation dependency on > https://patchwork.kernel.org/patch/10882555/ > > V2-->V3 > * Used the new api "usb_role_switch by node" for getting > remote endpoint associated with Type-C USB DRP port > controller devices. > V1-->V2 > * Driver uses usb role class instead of extcon for dual role switch > and also handles connect/disconnect events. > --- > drivers/usb/typec/Kconfig | 10 ++ > drivers/usb/typec/Makefile | 1 + > drivers/usb/typec/hd3ss3220.c | 278 ++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 289 insertions(+) > create mode 100644 drivers/usb/typec/hd3ss3220.c > > diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig > index 89d9193..92a3717 100644 > --- a/drivers/usb/typec/Kconfig > +++ b/drivers/usb/typec/Kconfig > @@ -50,6 +50,16 @@ source "drivers/usb/typec/tcpm/Kconfig" > > source "drivers/usb/typec/ucsi/Kconfig" > > +config TYPEC_HD3SS3220 > + tristate "TI HD3SS3220 Type-C DRP Port controller driver" > + depends on I2C > + help > + Say Y or M here if your system has TI HD3SS3220 Type-C DRP Port > + controller driver. > + > + If you choose to build this driver as a dynamically linked module, the > + module will be called hd3ss3220.ko. > + > config TYPEC_TPS6598X > tristate "TI TPS6598x USB Power Delivery controller driver" > depends on I2C > diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile > index 6696b72..7753a5c3 100644 > --- a/drivers/usb/typec/Makefile > +++ b/drivers/usb/typec/Makefile > @@ -4,5 +4,6 @@ typec-y := class.o mux.o bus.o > obj-$(CONFIG_TYPEC) += altmodes/ > obj-$(CONFIG_TYPEC_TCPM) += tcpm/ > obj-$(CONFIG_TYPEC_UCSI) += ucsi/ > +obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o > obj-$(CONFIG_TYPEC_TPS6598X) += tps6598x.o > obj-$(CONFIG_TYPEC) += mux/ > diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c > new file mode 100644 > index 0000000..b5cb42c > --- /dev/null > +++ b/drivers/usb/typec/hd3ss3220.c > @@ -0,0 +1,278 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * TI HD3SS3220 Type-C DRP Port Controller Driver > + * > + * Copyright (C) 2019 Renesas Electronics Corp. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define HD3SS3220_REG_CN_STAT_CTRL 0x09 > +#define HD3SS3220_REG_GEN_CTRL 0x0A > +#define HD3SS3220_REG_DEV_REV 0xA0 > + > +/* Register HD3SS3220_REG_CN_STAT_CTRL*/ > +#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7) > +#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4) > + > +/* Register HD3SS3220_REG_GEN_CTRL*/ > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1)) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00 > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1)) > + > +struct hd3ss3220 { > + struct device *dev; > + struct regmap *regmap; > + struct usb_role_switch *role_sw; > + struct typec_port *port; > + struct typec_capability typec_cap; > +}; > + > +static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int src_pref) > +{ > + unsigned int reg_val; > + int ret; > + > + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, ®_val); > + if (ret < 0) > + return ret; > + > + reg_val &= ~HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK; > + reg_val |= src_pref; > + > + return regmap_write(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, reg_val); use regmap_update_bits()? > +} > + > +static enum usb_role hd3ss3220_get_attached_state(struct hd3ss3220 *hd3ss3220) > +{ > + unsigned int reg_val; > + enum usb_role attached_state; > + int ret; > + > + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, > + ®_val); > + if (ret < 0) > + return ret; > + > + switch (reg_val & HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK) { > + case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP: > + attached_state = USB_ROLE_HOST; > + break; > + case HD3SS3220_REG_CN_STAT_CTRL_AS_UFP: > + attached_state = USB_ROLE_DEVICE; > + break; > + default: > + attached_state = USB_ROLE_NONE; > + } > + > + return attached_state; > +} > + > +static int hd3ss3220_dr_set(const struct typec_capability *cap, > + enum typec_data_role role) > +{ > + struct hd3ss3220 *hd3ss3220 = container_of(cap, struct hd3ss3220, > + typec_cap); > + enum usb_role role_val; > + int pref, ret = 0; > + > + if (role == TYPEC_HOST) { > + role_val = USB_ROLE_HOST; > + pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC; > + } else { > + role_val = USB_ROLE_DEVICE; > + pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK; > + } > + > + ret = hd3ss3220_set_source_pref(hd3ss3220, pref); > + usleep_range(10, 100); > + > + usb_role_switch_set_role(hd3ss3220->role_sw, role_val); > + typec_set_data_role(hd3ss3220->port, role); > + > + return ret; > +} > + > +static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220) > +{ > + enum usb_role role_state = hd3ss3220_get_attached_state(hd3ss3220); > + > + usb_role_switch_set_role(hd3ss3220->role_sw, role_state); > + if (role_state == USB_ROLE_NONE) > + hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT); > + > + switch (role_state) { > + case USB_ROLE_HOST: > + typec_set_data_role(hd3ss3220->port, TYPEC_HOST); > + break; > + case USB_ROLE_DEVICE: > + typec_set_data_role(hd3ss3220->port, TYPEC_DEVICE); > + break; > + default: > + break; > + } > +} > + > +irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220) > +{ > + int err; > + unsigned int data; > + > + hd3ss3220_set_role(hd3ss3220); > + > + err = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data); > + if (err < 0) > + return IRQ_NONE; > + > + err = regmap_write(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, > + data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS); > + if (err < 0) > + return IRQ_NONE; use regmap_xxx_bits() if possible? > + > + return IRQ_HANDLED; > +} > + > +static irqreturn_t hd3ss3220_irq_handler(int irq, void *data) > +{ > + struct i2c_client *client = to_i2c_client(data); > + struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client); > + > + return hd3ss3220_irq(hd3ss3220); > +} > + > +static const struct regmap_config config = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = 0x0A, > +}; > + > +static int hd3ss3220_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + struct hd3ss3220 *hd3ss3220; > + struct device_node *np; > + struct device_node *parent; > + struct device_node *child; > + int ret; > + unsigned int data; > + > + hd3ss3220 = devm_kzalloc(&client->dev, sizeof(struct hd3ss3220), > + GFP_KERNEL); > + if (!hd3ss3220) > + return -ENOMEM; > + > + i2c_set_clientdata(client, hd3ss3220); > + > + hd3ss3220->dev = &client->dev; > + hd3ss3220->regmap = devm_regmap_init_i2c(client, &config); > + if (IS_ERR(hd3ss3220->regmap)) > + return PTR_ERR(hd3ss3220->regmap); > + > + hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT); > + np = hd3ss3220->dev->of_node; > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > + parent = of_graph_get_remote_port_parent(child); > + hd3ss3220->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > + if (IS_ERR_OR_NULL(hd3ss3220->role_sw)) { > + of_node_put(child); > + of_node_put(parent); > + return PTR_ERR(hd3ss3220->role_sw); > + } > + > + of_node_put(child); > + of_node_put(parent); > + > + hd3ss3220->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE; > + hd3ss3220->typec_cap.dr_set = hd3ss3220_dr_set; > + hd3ss3220->typec_cap.type = TYPEC_PORT_DRP; > + hd3ss3220->typec_cap.data = TYPEC_PORT_DRD; > + > + hd3ss3220->port = typec_register_port(&client->dev, > + &hd3ss3220->typec_cap); > + if (IS_ERR(hd3ss3220->port)) > + return PTR_ERR(hd3ss3220->port); > + > + hd3ss3220_set_role(hd3ss3220); > + if (client->irq > 0) { > + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, > + &data); > + if (ret < 0) > + goto error; > + > + if (data & HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS) { > + ret = regmap_write(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, > + data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS); > + if (ret < 0) > + goto error; > + } > + > + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, > + hd3ss3220_irq_handler, > + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, > + "hd3ss3220", &client->dev); > + if (ret) > + goto error; > + } > + > + ret = i2c_smbus_read_byte_data(client, HD3SS3220_REG_DEV_REV); > + if (ret < 0) > + goto error; > + > + dev_info(&client->dev, "probed revision=0x%x\n", ret); > + > + return 0; > +error: > + typec_unregister_port(hd3ss3220->port); > + usb_role_switch_put(hd3ss3220->role_sw); > + > + return ret; > +} > + > +static int hd3ss3220_remove(struct i2c_client *client) > +{ > + struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client); > + > + typec_unregister_port(hd3ss3220->port); > + usb_role_switch_put(hd3ss3220->role_sw); > + > + return 0; > +} > + > +static const struct of_device_id dev_ids[] = { > + { .compatible = "ti,hd3ss3220"}, > + {} > +}; > +MODULE_DEVICE_TABLE(of, dev_ids); > + > +static struct i2c_driver hd3ss3220_driver = { > + .driver = { > + .name = "hd3ss3220", > + .owner = THIS_MODULE, no need set .owner > + .of_match_table = of_match_ptr(dev_ids), > + }, > + .probe = hd3ss3220_probe, > + .remove = hd3ss3220_remove, > +}; > + > +module_i2c_driver(hd3ss3220_driver); > + > +MODULE_AUTHOR("Biju Das "); > +MODULE_DESCRIPTION("TI HD3SS3220 DRP Port Controller Driver"); > +MODULE_LICENSE("GPL");