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: [V4,2/5] usb: core: Add ability to skip phy exit on suspend and init on resume From: Alan Cooper Message-Id: <1541772120-40394-3-git-send-email-alcooperx@gmail.com> Date: Fri, 9 Nov 2018 09:01:57 -0500 To: linux-kernel@vger.kernel.org Cc: Al Cooper , Alan Stern , Alban Bedel , Alex Elder , Andrew Morton , Arnd Bergmann , Avi Fishman , bcm-kernel-feedback-list@broadcom.com, Bjorn Andersson , Chunfeng Yun , "David S. Miller" , devicetree@vger.kernel.org, Dmitry Osipenko , Greg Kroah-Hartman , "Gustavo A. R. Silva" , Hans de Goede , James Hogan , Johan Hovold , Kees Cook , linux-usb@vger.kernel.org, Lu Baolu , Mark Rutland , Martin Blumenstingl , Mathias Nyman , Mathias Nyman , Mauro Carvalho Chehab , Rishabh Bhatnagar , Rob Herring , Roger Quadros List-ID: QWRkIHRoZSBhYmlsaXR5IHRvIHNraXAgY2FsbGluZyB0aGUgUEhZJ3MgZXhpdCByb3V0aW5lIG9u IHN1c3BlbmQKYW5kIHRoZSBQSFkncyBpbml0IHJvdXRpbmUgb24gcmVzdW1lLiBUaGlzIGlzIHRv IGhhbmRsZSBhIFVTQiBQSFkKdGhhdCBzaG91bGQgaGF2ZSBpdCdzIHBvd2VyX29mZiBmdW5jdGlv biBjYWxsZWQgb24gc3VzcGVuZCBidXQgY2Fubm90CmhhdmUgaXQncyBleGl0IGZ1bmN0aW9uIGNh bGxlZCBiZWNhdXNlIG9uIGV4aXQgaXQgd2lsbCBkaXNhYmxlIHRoZQpQSFkgdG8gdGhlIHBvaW50 IHdoZXJlIGFsbCBVU0IgY2xvY2tzIGFyZSBzdG9wcGVkIGFuZCByZWdpc3RlcgphY2Nlc3NlcyB0 byB0aGUgSG9zdCBDb250cm9sbGVycyB1c2luZyB0aGUgUEhZIHdpbGwgYmUgZGlzYWJsZWQKYW5k IHRoZSBob3N0IGRyaXZlcnMgd2lsbCBjcmFzaC4KClRoaXMgaXMgZW5hYmxlZCB3aXRoIHRoZSBI Q0QgZmxhZyAicGh5X3N1cHBsaWVzX3VzYl9jbG9jayIgd2hpY2gKY2FuIGJlIHNldCBmcm9tIGFu eSBIQ0QgZHJpdmVyIG9yIHdpdGggdGhlIGRldmljZSB0cmVlIHByb3BlcnR5CiJwaHktc3VwcGxp ZXMtdXNiLWNsb2NrIi4KClNpZ25lZC1vZmYtYnk6IEFsIENvb3BlciA8YWxjb29wZXJ4QGdtYWls LmNvbT4KLS0tCiBkcml2ZXJzL3VzYi9jb3JlL2hjZC5jICB8ICA4ICsrKystLS0tCiBkcml2ZXJz L3VzYi9jb3JlL3BoeS5jICB8IDI4ICsrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0KIGRyaXZl cnMvdXNiL2NvcmUvcGh5LmggIHwgIDkgKysrKysrLS0tCiBpbmNsdWRlL2xpbnV4L3VzYi9oY2Qu aCB8ICA2ICsrKysrKwogNCBmaWxlcyBjaGFuZ2VkLCAzNiBpbnNlcnRpb25zKCspLCAxNSBkZWxl dGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9jb3JlL2hjZC5jIGIvZHJpdmVycy91 c2IvY29yZS9oY2QuYwppbmRleCA0ODcwMjVkMzFkNDQuLjVlYmM4MmE2OTQwMyAxMDA2NDQKLS0t IGEvZHJpdmVycy91c2IvY29yZS9oY2QuYworKysgYi9kcml2ZXJzL3VzYi9jb3JlL2hjZC5jCkBA IC0yMjQ5LDcgKzIyNDksNyBAQCBpbnQgaGNkX2J1c19zdXNwZW5kKHN0cnVjdCB1c2JfZGV2aWNl ICpyaGRldiwgcG1fbWVzc2FnZV90IG1zZykKIAkJaGNkLT5zdGF0ZSA9IEhDX1NUQVRFX1NVU1BF TkRFRDsKIAogCQlpZiAoIVBNU0dfSVNfQVVUTyhtc2cpKQotCQkJdXNiX3BoeV9yb290aHViX3N1 c3BlbmQoaGNkLT5zZWxmLnN5c2RldiwKKwkJCXVzYl9waHlfcm9vdGh1Yl9zdXNwZW5kKGhjZCwK IAkJCQkJCWhjZC0+cGh5X3Jvb3RodWIpOwogCiAJCS8qIERpZCB3ZSByYWNlIHdpdGggYSByb290 LWh1YiB3YWtldXAgZXZlbnQ/ICovCkBAIC0yMjkwLDcgKzIyOTAsNyBAQCBpbnQgaGNkX2J1c19y ZXN1bWUoc3RydWN0IHVzYl9kZXZpY2UgKnJoZGV2LCBwbV9tZXNzYWdlX3QgbXNnKQogCX0KIAog CWlmICghUE1TR19JU19BVVRPKG1zZykpIHsKLQkJc3RhdHVzID0gdXNiX3BoeV9yb290aHViX3Jl c3VtZShoY2QtPnNlbGYuc3lzZGV2LAorCQlzdGF0dXMgPSB1c2JfcGh5X3Jvb3RodWJfcmVzdW1l KGhjZCwKIAkJCQkJCWhjZC0+cGh5X3Jvb3RodWIpOwogCQlpZiAoc3RhdHVzKQogCQkJcmV0dXJu IHN0YXR1czsKQEAgLTIzMzMsNyArMjMzMyw3IEBAIGludCBoY2RfYnVzX3Jlc3VtZShzdHJ1Y3Qg dXNiX2RldmljZSAqcmhkZXYsIHBtX21lc3NhZ2VfdCBtc2cpCiAJCX0KIAl9IGVsc2UgewogCQlo Y2QtPnN0YXRlID0gb2xkX3N0YXRlOwotCQl1c2JfcGh5X3Jvb3RodWJfc3VzcGVuZChoY2QtPnNl bGYuc3lzZGV2LCBoY2QtPnBoeV9yb290aHViKTsKKwkJdXNiX3BoeV9yb290aHViX3N1c3BlbmQo aGNkLCBoY2QtPnBoeV9yb290aHViKTsKIAkJZGV2X2RiZygmcmhkZXYtPmRldiwgImJ1cyAlcyBm YWlsLCBlcnIgJWRcbiIsCiAJCQkJInJlc3VtZSIsIHN0YXR1cyk7CiAJCWlmIChzdGF0dXMgIT0g LUVTSFVURE9XTikKQEAgLTI3MzAsNyArMjczMCw3IEBAIGludCB1c2JfYWRkX2hjZChzdHJ1Y3Qg dXNiX2hjZCAqaGNkLAogCXN0cnVjdCB1c2JfZGV2aWNlICpyaGRldjsKIAogCWlmICghaGNkLT5z a2lwX3BoeV9pbml0aWFsaXphdGlvbiAmJiB1c2JfaGNkX2lzX3ByaW1hcnlfaGNkKGhjZCkpIHsK LQkJaGNkLT5waHlfcm9vdGh1YiA9IHVzYl9waHlfcm9vdGh1Yl9hbGxvYyhoY2QtPnNlbGYuc3lz ZGV2KTsKKwkJaGNkLT5waHlfcm9vdGh1YiA9IHVzYl9waHlfcm9vdGh1Yl9hbGxvYyhoY2QpOwog CQlpZiAoSVNfRVJSKGhjZC0+cGh5X3Jvb3RodWIpKQogCQkJcmV0dXJuIFBUUl9FUlIoaGNkLT5w aHlfcm9vdGh1Yik7CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NvcmUvcGh5LmMgYi9kcml2 ZXJzL3VzYi9jb3JlL3BoeS5jCmluZGV4IDM4YjJjNzc2YzRiNC4uOGJmYmFjYjUyYTdiIDEwMDY0 NAotLS0gYS9kcml2ZXJzL3VzYi9jb3JlL3BoeS5jCisrKyBiL2RyaXZlcnMvdXNiL2NvcmUvcGh5 LmMKQEAgLTQ2LDEwICs0NiwxMSBAQCBzdGF0aWMgaW50IHVzYl9waHlfcm9vdGh1Yl9hZGRfcGh5 KHN0cnVjdCBkZXZpY2UgKmRldiwgaW50IGluZGV4LAogCXJldHVybiAwOwogfQogCi1zdHJ1Y3Qg dXNiX3BoeV9yb290aHViICp1c2JfcGh5X3Jvb3RodWJfYWxsb2Moc3RydWN0IGRldmljZSAqZGV2 KQorc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqdXNiX3BoeV9yb290aHViX2FsbG9jKHN0cnVjdCB1 c2JfaGNkICpoY2QpCiB7CiAJc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqcGh5X3Jvb3RodWI7CiAJ aW50IGksIG51bV9waHlzLCBlcnI7CisJc3RydWN0IGRldmljZSAqZGV2ID0gaGNkLT5zZWxmLnN5 c2RldjsKIAogCWlmICghSVNfRU5BQkxFRChDT05GSUdfR0VORVJJQ19QSFkpKQogCQlyZXR1cm4g TlVMTDsKQEAgLTU5LDYgKzYwLDkgQEAgc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqdXNiX3BoeV9y b290aHViX2FsbG9jKHN0cnVjdCBkZXZpY2UgKmRldikKIAlpZiAobnVtX3BoeXMgPD0gMCkKIAkJ cmV0dXJuIE5VTEw7CiAKKwlpZiAoZGV2aWNlX3Byb3BlcnR5X3JlYWRfYm9vbChkZXYsICJwaHkt c3VwcGxpZXMtdXNiLWNsb2NrIikpCisJCWhjZC0+cGh5X3N1cHBsaWVzX3VzYl9jbG9jayA9IDE7 CisKIAlwaHlfcm9vdGh1YiA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqcGh5X3Jvb3RodWIp LCBHRlBfS0VSTkVMKTsKIAlpZiAoIXBoeV9yb290aHViKQogCQlyZXR1cm4gRVJSX1BUUigtRU5P TUVNKTsKQEAgLTE2MiwyNiArMTY2LDMzIEBAIHZvaWQgdXNiX3BoeV9yb290aHViX3Bvd2VyX29m ZihzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpwaHlfcm9vdGh1YikKIH0KIEVYUE9SVF9TWU1CT0xf R1BMKHVzYl9waHlfcm9vdGh1Yl9wb3dlcl9vZmYpOwogCi1pbnQgdXNiX3BoeV9yb290aHViX3N1 c3BlbmQoc3RydWN0IGRldmljZSAqY29udHJvbGxlcl9kZXYsCitpbnQgdXNiX3BoeV9yb290aHVi X3N1c3BlbmQoc3RydWN0IHVzYl9oY2QgKmhjZCwKIAkJCSAgICBzdHJ1Y3QgdXNiX3BoeV9yb290 aHViICpwaHlfcm9vdGh1YikKIHsKKwlzdHJ1Y3QgZGV2aWNlICpjb250cm9sbGVyX2RldiA9IGhj ZC0+c2VsZi5zeXNkZXY7CisKIAl1c2JfcGh5X3Jvb3RodWJfcG93ZXJfb2ZmKHBoeV9yb290aHVi KTsKIAotCS8qIGtlZXAgdGhlIFBIWXMgaW5pdGlhbGl6ZWQgc28gdGhlIGRldmljZSBjYW4gd2Fr ZSB1cCB0aGUgc3lzdGVtICovCi0JaWYgKGRldmljZV9tYXlfd2FrZXVwKGNvbnRyb2xsZXJfZGV2 KSkKKwkvKgorCSAqIGtlZXAgdGhlIFBIWXMgaW5pdGlhbGl6ZWQgc28gdGhlIGRldmljZSBjYW4g d2FrZSB1cCB0aGUgc3lzdGVtCisJICogb3IgaWYgbmVlZGVkIHRvIGtlZXAgdGhlIFVTQiBjbG9j a3MgZW5hYmxlZC4KKwkgKi8KKwlpZiAoZGV2aWNlX21heV93YWtldXAoY29udHJvbGxlcl9kZXYp IHx8IGhjZC0+cGh5X3N1cHBsaWVzX3VzYl9jbG9jaykKIAkJcmV0dXJuIDA7CiAKIAlyZXR1cm4g dXNiX3BoeV9yb290aHViX2V4aXQocGh5X3Jvb3RodWIpOwogfQogRVhQT1JUX1NZTUJPTF9HUEwo dXNiX3BoeV9yb290aHViX3N1c3BlbmQpOwogCi1pbnQgdXNiX3BoeV9yb290aHViX3Jlc3VtZShz dHJ1Y3QgZGV2aWNlICpjb250cm9sbGVyX2RldiwKK2ludCB1c2JfcGh5X3Jvb3RodWJfcmVzdW1l KHN0cnVjdCB1c2JfaGNkICpoY2QsCiAJCQkgICBzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpwaHlf cm9vdGh1YikKIHsKKwlzdHJ1Y3QgZGV2aWNlICpjb250cm9sbGVyX2RldiA9IGhjZC0+c2VsZi5z eXNkZXY7CiAJaW50IGVycjsKIAotCS8qIGlmIHRoZSBkZXZpY2UgY2FuJ3Qgd2FrZSB1cCB0aGUg c3lzdGVtIF9leGl0IHdhcyBjYWxsZWQgKi8KLQlpZiAoIWRldmljZV9tYXlfd2FrZXVwKGNvbnRy b2xsZXJfZGV2KSkgeworCS8qIGlmIF9leGl0IHdhcyBjYWxsZWQgb24gc3VzcGVuZCAqLworCWlm ICghZGV2aWNlX21heV93YWtldXAoY29udHJvbGxlcl9kZXYpICYmCisJICAgICFoY2QtPnBoeV9z dXBwbGllc191c2JfY2xvY2spIHsKIAkJZXJyID0gdXNiX3BoeV9yb290aHViX2luaXQocGh5X3Jv b3RodWIpOwogCQlpZiAoZXJyKQogCQkJcmV0dXJuIGVycjsKQEAgLTE5MCw3ICsyMDEsOCBAQCBp bnQgdXNiX3BoeV9yb290aHViX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpjb250cm9sbGVyX2RldiwK IAllcnIgPSB1c2JfcGh5X3Jvb3RodWJfcG93ZXJfb24ocGh5X3Jvb3RodWIpOwogCiAJLyogdW5k byBfaW5pdCBpZiBfcG93ZXJfb24gZmFpbGVkICovCi0JaWYgKGVyciAmJiAhZGV2aWNlX21heV93 YWtldXAoY29udHJvbGxlcl9kZXYpKQorCWlmIChlcnIgJiYgIWRldmljZV9tYXlfd2FrZXVwKGNv bnRyb2xsZXJfZGV2KQorCSAgICAmJiAhaGNkLT5waHlfc3VwcGxpZXNfdXNiX2Nsb2NrKQogCQl1 c2JfcGh5X3Jvb3RodWJfZXhpdChwaHlfcm9vdGh1Yik7CiAKIAlyZXR1cm4gZXJyOwpkaWZmIC0t Z2l0IGEvZHJpdmVycy91c2IvY29yZS9waHkuaCBiL2RyaXZlcnMvdXNiL2NvcmUvcGh5LmgKaW5k ZXggODhhM2MwMzdlOWRmLi4zNDI5M2UxMWE5MTcgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL2Nv cmUvcGh5LmgKKysrIGIvZHJpdmVycy91c2IvY29yZS9waHkuaApAQCAtNSwxMyArNSwxNiBAQAog ICogQ29weXJpZ2h0IChDKSAyMDE4IE1hcnRpbiBCbHVtZW5zdGluZ2wgPG1hcnRpbi5ibHVtZW5z dGluZ2xAZ29vZ2xlbWFpbC5jb20+CiAgKi8KIAorI2luY2x1ZGUgPGxpbnV4L3VzYi5oPgorI2lu Y2x1ZGUgPGxpbnV4L3VzYi9oY2QuaD4KKwogI2lmbmRlZiBfX1VTQl9DT1JFX1BIWV9IXwogI2Rl ZmluZSBfX1VTQl9DT1JFX1BIWV9IXwogCiBzdHJ1Y3QgZGV2aWNlOwogc3RydWN0IHVzYl9waHlf cm9vdGh1YjsKIAotc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqdXNiX3BoeV9yb290aHViX2FsbG9j KHN0cnVjdCBkZXZpY2UgKmRldik7CitzdHJ1Y3QgdXNiX3BoeV9yb290aHViICp1c2JfcGh5X3Jv b3RodWJfYWxsb2Moc3RydWN0IHVzYl9oY2QgKmhjZCk7CiAKIGludCB1c2JfcGh5X3Jvb3RodWJf aW5pdChzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpwaHlfcm9vdGh1Yik7CiBpbnQgdXNiX3BoeV9y b290aHViX2V4aXQoc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqcGh5X3Jvb3RodWIpOwpAQCAtMTks OSArMjIsOSBAQAogaW50IHVzYl9waHlfcm9vdGh1Yl9wb3dlcl9vbihzdHJ1Y3QgdXNiX3BoeV9y b290aHViICpwaHlfcm9vdGh1Yik7CiB2b2lkIHVzYl9waHlfcm9vdGh1Yl9wb3dlcl9vZmYoc3Ry dWN0IHVzYl9waHlfcm9vdGh1YiAqcGh5X3Jvb3RodWIpOwogCi1pbnQgdXNiX3BoeV9yb290aHVi X3N1c3BlbmQoc3RydWN0IGRldmljZSAqY29udHJvbGxlcl9kZXYsCitpbnQgdXNiX3BoeV9yb290 aHViX3N1c3BlbmQoc3RydWN0IHVzYl9oY2QgKmhjZCwKIAkJCSAgICBzdHJ1Y3QgdXNiX3BoeV9y b290aHViICpwaHlfcm9vdGh1Yik7Ci1pbnQgdXNiX3BoeV9yb290aHViX3Jlc3VtZShzdHJ1Y3Qg ZGV2aWNlICpjb250cm9sbGVyX2RldiwKK2ludCB1c2JfcGh5X3Jvb3RodWJfcmVzdW1lKHN0cnVj dCB1c2JfaGNkICpoY2QsCiAJCQkgICBzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpwaHlfcm9vdGh1 Yik7CiAKICNlbmRpZiAvKiBfX1VTQl9DT1JFX1BIWV9IXyAqLwpkaWZmIC0tZ2l0IGEvaW5jbHVk ZS9saW51eC91c2IvaGNkLmggYi9pbmNsdWRlL2xpbnV4L3VzYi9oY2QuaAppbmRleCA5N2UyZGRl YzE4YjEuLjdjNDJjZjBmNjgzNSAxMDA2NDQKLS0tIGEvaW5jbHVkZS9saW51eC91c2IvaGNkLmgK KysrIGIvaW5jbHVkZS9saW51eC91c2IvaGNkLmgKQEAgLTE1Nyw2ICsxNTcsMTIgQEAgc3RydWN0 IHVzYl9oY2QgewogCSAqLwogCXVuc2lnbmVkCQlza2lwX3BoeV9pbml0aWFsaXphdGlvbjoxOwog CisJLyoKKwkgKiBTb21lIHBoeXMgc3VwcGx5IHRoZSBVU0IgY29udHJvbGxlciBjbG9ja3MgYW5k IHNob3VsZCBub3QKKwkgKiBoYXZlIGV4aXQgY2FsbGVkIG9uIHN1c3BlbmQuCisJICovCisJdW5z aWduZWQJCXBoeV9zdXBwbGllc191c2JfY2xvY2s6MTsKKwogCS8qIFRoZSBuZXh0IGZsYWcgaXMg YSBzdG9wZ2FwLCB0byBiZSByZW1vdmVkIHdoZW4gYWxsIHRoZSBIQ0RzCiAJICogc3VwcG9ydCB0 aGUgbmV3IHJvb3QtaHViIHBvbGxpbmcgbWVjaGFuaXNtLiAqLwogCXVuc2lnbmVkCQl1c2VzX25l d19wb2xsaW5nOjE7Cg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: Al Cooper Subject: [PATCH V4 2/5] usb: core: Add ability to skip phy exit on suspend and init on resume Date: Fri, 9 Nov 2018 09:01:57 -0500 Message-ID: <1541772120-40394-3-git-send-email-alcooperx@gmail.com> References: <1541772120-40394-1-git-send-email-alcooperx@gmail.com> Return-path: In-Reply-To: <1541772120-40394-1-git-send-email-alcooperx@gmail.com> Sender: linux-kernel-owner@vger.kernel.org To: linux-kernel@vger.kernel.org Cc: Al Cooper , Alan Stern , Alban Bedel , Alex Elder , Andrew Morton , Arnd Bergmann , Avi Fishman , bcm-kernel-feedback-list@broadcom.com, Bjorn Andersson , Chunfeng Yun , "David S. Miller" , devicetree@vger.kernel.org, Dmitry Osipenko , Greg Kroah-Hartman , "Gustavo A. R. Silva" , Hans de Goede , James Hogan , Johan Hovold , Kees Cook , linux-usb@vger.kernel.org, Lu Baolu List-Id: devicetree@vger.kernel.org Add the ability to skip calling the PHY's exit routine on suspend and the PHY's init routine on resume. This is to handle a USB PHY that should have it's power_off function called on suspend but cannot have it's exit function called because on exit it will disable the PHY to the point where all USB clocks are stopped and register accesses to the Host Controllers using the PHY will be disabled and the host drivers will crash. This is enabled with the HCD flag "phy_supplies_usb_clock" which can be set from any HCD driver or with the device tree property "phy-supplies-usb-clock". Signed-off-by: Al Cooper --- drivers/usb/core/hcd.c | 8 ++++---- drivers/usb/core/phy.c | 28 ++++++++++++++++++++-------- drivers/usb/core/phy.h | 9 ++++++--- include/linux/usb/hcd.h | 6 ++++++ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 487025d31d44..5ebc82a69403 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2249,7 +2249,7 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_suspend(hcd->self.sysdev, + usb_phy_roothub_suspend(hcd, hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ @@ -2290,7 +2290,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_resume(hcd->self.sysdev, + status = usb_phy_roothub_resume(hcd, hcd->phy_roothub); if (status) return status; @@ -2333,7 +2333,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); + usb_phy_roothub_suspend(hcd, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) @@ -2730,7 +2730,7 @@ int usb_add_hcd(struct usb_hcd *hcd, struct usb_device *rhdev; if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd); if (IS_ERR(hcd->phy_roothub)) return PTR_ERR(hcd->phy_roothub); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 38b2c776c4b4..8bfbacb52a7b 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -46,10 +46,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct usb_hcd *hcd) { struct usb_phy_roothub *phy_roothub; int i, num_phys, err; + struct device *dev = hcd->self.sysdev; if (!IS_ENABLED(CONFIG_GENERIC_PHY)) return NULL; @@ -59,6 +60,9 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) if (num_phys <= 0) return NULL; + if (device_property_read_bool(dev, "phy-supplies-usb-clock")) + hcd->phy_supplies_usb_clock = 1; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); if (!phy_roothub) return ERR_PTR(-ENOMEM); @@ -162,26 +166,33 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); -int usb_phy_roothub_suspend(struct device *controller_dev, +int usb_phy_roothub_suspend(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub) { + struct device *controller_dev = hcd->self.sysdev; + usb_phy_roothub_power_off(phy_roothub); - /* keep the PHYs initialized so the device can wake up the system */ - if (device_may_wakeup(controller_dev)) + /* + * keep the PHYs initialized so the device can wake up the system + * or if needed to keep the USB clocks enabled. + */ + if (device_may_wakeup(controller_dev) || hcd->phy_supplies_usb_clock) return 0; return usb_phy_roothub_exit(phy_roothub); } EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); -int usb_phy_roothub_resume(struct device *controller_dev, +int usb_phy_roothub_resume(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub) { + struct device *controller_dev = hcd->self.sysdev; int err; - /* if the device can't wake up the system _exit was called */ - if (!device_may_wakeup(controller_dev)) { + /* if _exit was called on suspend */ + if (!device_may_wakeup(controller_dev) && + !hcd->phy_supplies_usb_clock) { err = usb_phy_roothub_init(phy_roothub); if (err) return err; @@ -190,7 +201,8 @@ int usb_phy_roothub_resume(struct device *controller_dev, err = usb_phy_roothub_power_on(phy_roothub); /* undo _init if _power_on failed */ - if (err && !device_may_wakeup(controller_dev)) + if (err && !device_may_wakeup(controller_dev) + && !hcd->phy_supplies_usb_clock) usb_phy_roothub_exit(phy_roothub); return err; diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 88a3c037e9df..34293e11a917 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -5,13 +5,16 @@ * Copyright (C) 2018 Martin Blumenstingl */ +#include +#include + #ifndef __USB_CORE_PHY_H_ #define __USB_CORE_PHY_H_ struct device; struct usb_phy_roothub; -struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); +struct usb_phy_roothub *usb_phy_roothub_alloc(struct usb_hcd *hcd); int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); @@ -19,9 +22,9 @@ int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); -int usb_phy_roothub_suspend(struct device *controller_dev, +int usb_phy_roothub_suspend(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub); -int usb_phy_roothub_resume(struct device *controller_dev, +int usb_phy_roothub_resume(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub); #endif /* __USB_CORE_PHY_H_ */ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 97e2ddec18b1..7c42cf0f6835 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -157,6 +157,12 @@ struct usb_hcd { */ unsigned skip_phy_initialization:1; + /* + * Some phys supply the USB controller clocks and should not + * have exit called on suspend. + */ + unsigned phy_supplies_usb_clock:1; + /* The next flag is a stopgap, to be removed when all the HCDs * support the new root-hub polling mechanism. */ unsigned uses_new_polling:1; -- 1.9.0.138.g2de3478 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.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,USER_AGENT_GIT 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 72D41C43441 for ; Fri, 9 Nov 2018 14:11:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 30E55208E3 for ; Fri, 9 Nov 2018 14:11:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="V3gAjg3r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 30E55208E3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.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 S1728746AbeKIXwU (ORCPT ); Fri, 9 Nov 2018 18:52:20 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:40502 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728046AbeKIXwT (ORCPT ); Fri, 9 Nov 2018 18:52:19 -0500 Received: by mail-yb1-f194.google.com with SMTP id g9-v6so1078036ybh.7; Fri, 09 Nov 2018 06:11:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SJTlmwHK0QaJa76tDiqzpr+Ll6iBfOd6+RCAreENEmk=; b=V3gAjg3re2HeM6zvgwn/JWPBmgabme7oBKOk7OU2yRhvmBpWeRQ+VepLqPpxMndvft nmUt6z1LQXByt9Vpb/uqB50/sL6he0s7F+RjvKtH3VKx8DvVoAM6p7bc57xpZE67g4nf Yz1nj90A/eMhxQhrLwbIUGzGqIzTNsQQAC0LDZlz7RP83PipMtbrzjTEse+8+6vX1QtJ BfJr96t2wARJcfw8P9wD8ugSQLeYDJAew7mqONN6T/ruE2k3A4epYZ/+Ufxifs9ZH7ds diroWUYDnghCUl+M3PCsN1j3DEcA1aotKQKN6XwjTEoSdvqLMs7Ss4PYflx3U5d5hXeg t53g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SJTlmwHK0QaJa76tDiqzpr+Ll6iBfOd6+RCAreENEmk=; b=Vfja4KIniSIY220EdpnZSEpZScC2nv1mlkudctin+liHV49dDNfXNHhxmzyVkwFAfM 0PR96hro274ji13aHqRCkoYaRoODYTCR7HTkqh94SVigjR0xqeDnBiEhILqT6C3Qh3MS eqEvyRmXnD8KDMgoPv7OWPRWwHccQaCiDXUJUFH9ZH0HWPu8yoR9XjsCcz6MRjVEXmt9 NEHky+cS0y1EVtwdLrkWjo7S3tGl0mFh91oG6Dl61vIeWA8M2Ktv4f+v02vnCyug50J5 5oUTplfvSd0HCAkoIT72rL7VlerWNud+IlpoqVB+LYvMMErnChXHux1oZ2VmT7yjurTe KO5w== X-Gm-Message-State: AGRZ1gIxL2AKM42N8YFTb6FXHDSvQVx09c8yCRYK8TWZJTfFpLkpYJVZ bnSRV2AWI9Xrlp3Glk9mjVSxUW3xy8I= X-Google-Smtp-Source: AJdET5f9e0eXkypU9Krr0PSlQZ6nenFmdMEAdbEQEr3SykAN0aGwNaEaHlRSTIY+uvDy8nuDbWu5rw== X-Received: by 2002:a25:46c5:: with SMTP id t188-v6mr8943772yba.108.1541772691287; Fri, 09 Nov 2018 06:11:31 -0800 (PST) Received: from stbsrv-and-3.and.broadcom.com ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id c6-v6sm7301965ywh.34.2018.11.09.06.11.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Nov 2018 06:11:30 -0800 (PST) From: Al Cooper To: linux-kernel@vger.kernel.org Cc: Al Cooper , Alan Stern , Alban Bedel , Alex Elder , Andrew Morton , Arnd Bergmann , Avi Fishman , bcm-kernel-feedback-list@broadcom.com, Bjorn Andersson , Chunfeng Yun , "David S. Miller" , devicetree@vger.kernel.org, Dmitry Osipenko , Greg Kroah-Hartman , "Gustavo A. R. Silva" , Hans de Goede , James Hogan , Johan Hovold , Kees Cook , linux-usb@vger.kernel.org, Lu Baolu , Mark Rutland , Martin Blumenstingl , Mathias Nyman , Mathias Nyman , Mauro Carvalho Chehab , Rishabh Bhatnagar , Rob Herring , Roger Quadros Subject: [PATCH V4 2/5] usb: core: Add ability to skip phy exit on suspend and init on resume Date: Fri, 9 Nov 2018 09:01:57 -0500 Message-Id: <1541772120-40394-3-git-send-email-alcooperx@gmail.com> X-Mailer: git-send-email 1.9.0.138.g2de3478 In-Reply-To: <1541772120-40394-1-git-send-email-alcooperx@gmail.com> References: <1541772120-40394-1-git-send-email-alcooperx@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the ability to skip calling the PHY's exit routine on suspend and the PHY's init routine on resume. This is to handle a USB PHY that should have it's power_off function called on suspend but cannot have it's exit function called because on exit it will disable the PHY to the point where all USB clocks are stopped and register accesses to the Host Controllers using the PHY will be disabled and the host drivers will crash. This is enabled with the HCD flag "phy_supplies_usb_clock" which can be set from any HCD driver or with the device tree property "phy-supplies-usb-clock". Signed-off-by: Al Cooper --- drivers/usb/core/hcd.c | 8 ++++---- drivers/usb/core/phy.c | 28 ++++++++++++++++++++-------- drivers/usb/core/phy.h | 9 ++++++--- include/linux/usb/hcd.h | 6 ++++++ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 487025d31d44..5ebc82a69403 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2249,7 +2249,7 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_suspend(hcd->self.sysdev, + usb_phy_roothub_suspend(hcd, hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ @@ -2290,7 +2290,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_resume(hcd->self.sysdev, + status = usb_phy_roothub_resume(hcd, hcd->phy_roothub); if (status) return status; @@ -2333,7 +2333,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); + usb_phy_roothub_suspend(hcd, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) @@ -2730,7 +2730,7 @@ int usb_add_hcd(struct usb_hcd *hcd, struct usb_device *rhdev; if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd); if (IS_ERR(hcd->phy_roothub)) return PTR_ERR(hcd->phy_roothub); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 38b2c776c4b4..8bfbacb52a7b 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -46,10 +46,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct usb_hcd *hcd) { struct usb_phy_roothub *phy_roothub; int i, num_phys, err; + struct device *dev = hcd->self.sysdev; if (!IS_ENABLED(CONFIG_GENERIC_PHY)) return NULL; @@ -59,6 +60,9 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) if (num_phys <= 0) return NULL; + if (device_property_read_bool(dev, "phy-supplies-usb-clock")) + hcd->phy_supplies_usb_clock = 1; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); if (!phy_roothub) return ERR_PTR(-ENOMEM); @@ -162,26 +166,33 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); -int usb_phy_roothub_suspend(struct device *controller_dev, +int usb_phy_roothub_suspend(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub) { + struct device *controller_dev = hcd->self.sysdev; + usb_phy_roothub_power_off(phy_roothub); - /* keep the PHYs initialized so the device can wake up the system */ - if (device_may_wakeup(controller_dev)) + /* + * keep the PHYs initialized so the device can wake up the system + * or if needed to keep the USB clocks enabled. + */ + if (device_may_wakeup(controller_dev) || hcd->phy_supplies_usb_clock) return 0; return usb_phy_roothub_exit(phy_roothub); } EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); -int usb_phy_roothub_resume(struct device *controller_dev, +int usb_phy_roothub_resume(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub) { + struct device *controller_dev = hcd->self.sysdev; int err; - /* if the device can't wake up the system _exit was called */ - if (!device_may_wakeup(controller_dev)) { + /* if _exit was called on suspend */ + if (!device_may_wakeup(controller_dev) && + !hcd->phy_supplies_usb_clock) { err = usb_phy_roothub_init(phy_roothub); if (err) return err; @@ -190,7 +201,8 @@ int usb_phy_roothub_resume(struct device *controller_dev, err = usb_phy_roothub_power_on(phy_roothub); /* undo _init if _power_on failed */ - if (err && !device_may_wakeup(controller_dev)) + if (err && !device_may_wakeup(controller_dev) + && !hcd->phy_supplies_usb_clock) usb_phy_roothub_exit(phy_roothub); return err; diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 88a3c037e9df..34293e11a917 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -5,13 +5,16 @@ * Copyright (C) 2018 Martin Blumenstingl */ +#include +#include + #ifndef __USB_CORE_PHY_H_ #define __USB_CORE_PHY_H_ struct device; struct usb_phy_roothub; -struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); +struct usb_phy_roothub *usb_phy_roothub_alloc(struct usb_hcd *hcd); int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); @@ -19,9 +22,9 @@ int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); -int usb_phy_roothub_suspend(struct device *controller_dev, +int usb_phy_roothub_suspend(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub); -int usb_phy_roothub_resume(struct device *controller_dev, +int usb_phy_roothub_resume(struct usb_hcd *hcd, struct usb_phy_roothub *phy_roothub); #endif /* __USB_CORE_PHY_H_ */ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 97e2ddec18b1..7c42cf0f6835 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -157,6 +157,12 @@ struct usb_hcd { */ unsigned skip_phy_initialization:1; + /* + * Some phys supply the USB controller clocks and should not + * have exit called on suspend. + */ + unsigned phy_supplies_usb_clock:1; + /* The next flag is a stopgap, to be removed when all the HCDs * support the new root-hub polling mechanism. */ unsigned uses_new_polling:1; -- 1.9.0.138.g2de3478