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,2/6] usb: core: Add ability to skip phy exit on suspend and init on resume From: Alan Cooper Message-Id: <1541453493-34981-3-git-send-email-alcooperx@gmail.com> Date: Mon, 5 Nov 2018 16:31:29 -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 , Jianguo Sun , 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 IHdoZXJlIHJlZ2lzdGVyIGFjY2Vzc2VzIHRvIHRoZSBIb3N0IENvbnRyb2xsZXJzCnVzaW5nIHRo ZSBQSFkgd2lsbCBiZSBkaXNhYmxlZCBhbmQgdGhlIGhvc3QgZHJpdmVycyB3aWxsIGNyYXNoLgoK VGhpcyBpcyBlbmFibGVkIHdpdGggdGhlIEhDRCBmbGFnICJzdXNwZW5kX3dpdGhvdXRfcGh5X2V4 aXQiIHdoaWNoCmNhbiBiZSBzZXQgZnJvbSBhbnkgSENEIGRyaXZlci4KClNpZ25lZC1vZmYtYnk6 IEFsIENvb3BlciA8YWxjb29wZXJ4QGdtYWlsLmNvbT4KLS0tCiBkcml2ZXJzL3VzYi9jb3JlL2hj ZC5jICB8ICA4ICsrKystLS0tCiBkcml2ZXJzL3VzYi9jb3JlL3BoeS5jICB8IDE4ICsrKysrKysr KysrKy0tLS0tLQogZHJpdmVycy91c2IvY29yZS9waHkuaCAgfCAgOSArKysrKystLS0KIGluY2x1 ZGUvbGludXgvdXNiL2hjZC5oIHwgIDMgKysrCiA0IGZpbGVzIGNoYW5nZWQsIDI1IGluc2VydGlv bnMoKyksIDEzIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NvcmUvaGNk LmMgYi9kcml2ZXJzL3VzYi9jb3JlL2hjZC5jCmluZGV4IDQ4NzAyNWQzMWQ0NC4uNWViYzgyYTY5 NDAzIDEwMDY0NAotLS0gYS9kcml2ZXJzL3VzYi9jb3JlL2hjZC5jCisrKyBiL2RyaXZlcnMvdXNi L2NvcmUvaGNkLmMKQEAgLTIyNDksNyArMjI0OSw3IEBAIGludCBoY2RfYnVzX3N1c3BlbmQoc3Ry dWN0IHVzYl9kZXZpY2UgKnJoZGV2LCBwbV9tZXNzYWdlX3QgbXNnKQogCQloY2QtPnN0YXRlID0g SENfU1RBVEVfU1VTUEVOREVEOwogCiAJCWlmICghUE1TR19JU19BVVRPKG1zZykpCi0JCQl1c2Jf cGh5X3Jvb3RodWJfc3VzcGVuZChoY2QtPnNlbGYuc3lzZGV2LAorCQkJdXNiX3BoeV9yb290aHVi X3N1c3BlbmQoaGNkLAogCQkJCQkJaGNkLT5waHlfcm9vdGh1Yik7CiAKIAkJLyogRGlkIHdlIHJh Y2Ugd2l0aCBhIHJvb3QtaHViIHdha2V1cCBldmVudD8gKi8KQEAgLTIyOTAsNyArMjI5MCw3IEBA IGludCBoY2RfYnVzX3Jlc3VtZShzdHJ1Y3QgdXNiX2RldmljZSAqcmhkZXYsIHBtX21lc3NhZ2Vf dCBtc2cpCiAJfQogCiAJaWYgKCFQTVNHX0lTX0FVVE8obXNnKSkgewotCQlzdGF0dXMgPSB1c2Jf cGh5X3Jvb3RodWJfcmVzdW1lKGhjZC0+c2VsZi5zeXNkZXYsCisJCXN0YXR1cyA9IHVzYl9waHlf cm9vdGh1Yl9yZXN1bWUoaGNkLAogCQkJCQkJaGNkLT5waHlfcm9vdGh1Yik7CiAJCWlmIChzdGF0 dXMpCiAJCQlyZXR1cm4gc3RhdHVzOwpAQCAtMjMzMyw3ICsyMzMzLDcgQEAgaW50IGhjZF9idXNf cmVzdW1lKHN0cnVjdCB1c2JfZGV2aWNlICpyaGRldiwgcG1fbWVzc2FnZV90IG1zZykKIAkJfQog CX0gZWxzZSB7CiAJCWhjZC0+c3RhdGUgPSBvbGRfc3RhdGU7Ci0JCXVzYl9waHlfcm9vdGh1Yl9z dXNwZW5kKGhjZC0+c2VsZi5zeXNkZXYsIGhjZC0+cGh5X3Jvb3RodWIpOworCQl1c2JfcGh5X3Jv b3RodWJfc3VzcGVuZChoY2QsIGhjZC0+cGh5X3Jvb3RodWIpOwogCQlkZXZfZGJnKCZyaGRldi0+ ZGV2LCAiYnVzICVzIGZhaWwsIGVyciAlZFxuIiwKIAkJCQkicmVzdW1lIiwgc3RhdHVzKTsKIAkJ aWYgKHN0YXR1cyAhPSAtRVNIVVRET1dOKQpAQCAtMjczMCw3ICsyNzMwLDcgQEAgaW50IHVzYl9h ZGRfaGNkKHN0cnVjdCB1c2JfaGNkICpoY2QsCiAJc3RydWN0IHVzYl9kZXZpY2UgKnJoZGV2Owog CiAJaWYgKCFoY2QtPnNraXBfcGh5X2luaXRpYWxpemF0aW9uICYmIHVzYl9oY2RfaXNfcHJpbWFy eV9oY2QoaGNkKSkgewotCQloY2QtPnBoeV9yb290aHViID0gdXNiX3BoeV9yb290aHViX2FsbG9j KGhjZC0+c2VsZi5zeXNkZXYpOworCQloY2QtPnBoeV9yb290aHViID0gdXNiX3BoeV9yb290aHVi X2FsbG9jKGhjZCk7CiAJCWlmIChJU19FUlIoaGNkLT5waHlfcm9vdGh1YikpCiAJCQlyZXR1cm4g UFRSX0VSUihoY2QtPnBoeV9yb290aHViKTsKIApkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvY29y ZS9waHkuYyBiL2RyaXZlcnMvdXNiL2NvcmUvcGh5LmMKaW5kZXggMzhiMmM3NzZjNGI0Li4zMDhk NzE2MzA0ZGEgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL2NvcmUvcGh5LmMKKysrIGIvZHJpdmVy cy91c2IvY29yZS9waHkuYwpAQCAtNDYsMTAgKzQ2LDExIEBAIHN0YXRpYyBpbnQgdXNiX3BoeV9y b290aHViX2FkZF9waHkoc3RydWN0IGRldmljZSAqZGV2LCBpbnQgaW5kZXgsCiAJcmV0dXJuIDA7 CiB9CiAKLXN0cnVjdCB1c2JfcGh5X3Jvb3RodWIgKnVzYl9waHlfcm9vdGh1Yl9hbGxvYyhzdHJ1 Y3QgZGV2aWNlICpkZXYpCitzdHJ1Y3QgdXNiX3BoeV9yb290aHViICp1c2JfcGh5X3Jvb3RodWJf YWxsb2Moc3RydWN0IHVzYl9oY2QgKmhjZCkKIHsKIAlzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpw aHlfcm9vdGh1YjsKIAlpbnQgaSwgbnVtX3BoeXMsIGVycjsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYg PSBoY2QtPnNlbGYuc3lzZGV2OwogCiAJaWYgKCFJU19FTkFCTEVEKENPTkZJR19HRU5FUklDX1BI WSkpCiAJCXJldHVybiBOVUxMOwpAQCAtMTYyLDI2ICsxNjMsMzAgQEAgdm9pZCB1c2JfcGh5X3Jv b3RodWJfcG93ZXJfb2ZmKHN0cnVjdCB1c2JfcGh5X3Jvb3RodWIgKnBoeV9yb290aHViKQogfQog RVhQT1JUX1NZTUJPTF9HUEwodXNiX3BoeV9yb290aHViX3Bvd2VyX29mZik7CiAKLWludCB1c2Jf cGh5X3Jvb3RodWJfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpjb250cm9sbGVyX2RldiwKK2ludCB1 c2JfcGh5X3Jvb3RodWJfc3VzcGVuZChzdHJ1Y3QgdXNiX2hjZCAqaGNkLAogCQkJICAgIHN0cnVj dCB1c2JfcGh5X3Jvb3RodWIgKnBoeV9yb290aHViKQogeworCXN0cnVjdCBkZXZpY2UgKmNvbnRy b2xsZXJfZGV2ID0gaGNkLT5zZWxmLnN5c2RldjsKKwogCXVzYl9waHlfcm9vdGh1Yl9wb3dlcl9v ZmYocGh5X3Jvb3RodWIpOwogCiAJLyoga2VlcCB0aGUgUEhZcyBpbml0aWFsaXplZCBzbyB0aGUg ZGV2aWNlIGNhbiB3YWtlIHVwIHRoZSBzeXN0ZW0gKi8KLQlpZiAoZGV2aWNlX21heV93YWtldXAo Y29udHJvbGxlcl9kZXYpKQorCWlmIChkZXZpY2VfbWF5X3dha2V1cChjb250cm9sbGVyX2Rldikg fHwgaGNkLT5zdXNwZW5kX3dpdGhvdXRfcGh5X2V4aXQpCiAJCXJldHVybiAwOwogCiAJcmV0dXJu IHVzYl9waHlfcm9vdGh1Yl9leGl0KHBoeV9yb290aHViKTsKIH0KIEVYUE9SVF9TWU1CT0xfR1BM KHVzYl9waHlfcm9vdGh1Yl9zdXNwZW5kKTsKIAotaW50IHVzYl9waHlfcm9vdGh1Yl9yZXN1bWUo c3RydWN0IGRldmljZSAqY29udHJvbGxlcl9kZXYsCitpbnQgdXNiX3BoeV9yb290aHViX3Jlc3Vt ZShzdHJ1Y3QgdXNiX2hjZCAqaGNkLAogCQkJICAgc3RydWN0IHVzYl9waHlfcm9vdGh1YiAqcGh5 X3Jvb3RodWIpCiB7CisJc3RydWN0IGRldmljZSAqY29udHJvbGxlcl9kZXYgPSBoY2QtPnNlbGYu c3lzZGV2OwogCWludCBlcnI7CiAKIAkvKiBpZiB0aGUgZGV2aWNlIGNhbid0IHdha2UgdXAgdGhl IHN5c3RlbSBfZXhpdCB3YXMgY2FsbGVkICovCi0JaWYgKCFkZXZpY2VfbWF5X3dha2V1cChjb250 cm9sbGVyX2RldikpIHsKKwlpZiAoIWRldmljZV9tYXlfd2FrZXVwKGNvbnRyb2xsZXJfZGV2KSAm JgorCSAgICAhaGNkLT5zdXNwZW5kX3dpdGhvdXRfcGh5X2V4aXQpIHsKIAkJZXJyID0gdXNiX3Bo eV9yb290aHViX2luaXQocGh5X3Jvb3RodWIpOwogCQlpZiAoZXJyKQogCQkJcmV0dXJuIGVycjsK QEAgLTE5MCw3ICsxOTUsOCBAQCBpbnQgdXNiX3BoeV9yb290aHViX3Jlc3VtZShzdHJ1Y3QgZGV2 aWNlICpjb250cm9sbGVyX2RldiwKIAllcnIgPSB1c2JfcGh5X3Jvb3RodWJfcG93ZXJfb24ocGh5 X3Jvb3RodWIpOwogCiAJLyogdW5kbyBfaW5pdCBpZiBfcG93ZXJfb24gZmFpbGVkICovCi0JaWYg KGVyciAmJiAhZGV2aWNlX21heV93YWtldXAoY29udHJvbGxlcl9kZXYpKQorCWlmIChlcnIgJiYg IWRldmljZV9tYXlfd2FrZXVwKGNvbnRyb2xsZXJfZGV2KQorCSAgICAmJiAhaGNkLT5zdXNwZW5k X3dpdGhvdXRfcGh5X2V4aXQpCiAJCXVzYl9waHlfcm9vdGh1Yl9leGl0KHBoeV9yb290aHViKTsK IAogCXJldHVybiBlcnI7CmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9jb3JlL3BoeS5oIGIvZHJp dmVycy91c2IvY29yZS9waHkuaAppbmRleCA4OGEzYzAzN2U5ZGYuLjM0MjkzZTExYTkxNyAxMDA2 NDQKLS0tIGEvZHJpdmVycy91c2IvY29yZS9waHkuaAorKysgYi9kcml2ZXJzL3VzYi9jb3JlL3Bo eS5oCkBAIC01LDEzICs1LDE2IEBACiAgKiBDb3B5cmlnaHQgKEMpIDIwMTggTWFydGluIEJsdW1l bnN0aW5nbCA8bWFydGluLmJsdW1lbnN0aW5nbEBnb29nbGVtYWlsLmNvbT4KICAqLwogCisjaW5j bHVkZSA8bGludXgvdXNiLmg+CisjaW5jbHVkZSA8bGludXgvdXNiL2hjZC5oPgorCiAjaWZuZGVm IF9fVVNCX0NPUkVfUEhZX0hfCiAjZGVmaW5lIF9fVVNCX0NPUkVfUEhZX0hfCiAKIHN0cnVjdCBk ZXZpY2U7CiBzdHJ1Y3QgdXNiX3BoeV9yb290aHViOwogCi1zdHJ1Y3QgdXNiX3BoeV9yb290aHVi ICp1c2JfcGh5X3Jvb3RodWJfYWxsb2Moc3RydWN0IGRldmljZSAqZGV2KTsKK3N0cnVjdCB1c2Jf cGh5X3Jvb3RodWIgKnVzYl9waHlfcm9vdGh1Yl9hbGxvYyhzdHJ1Y3QgdXNiX2hjZCAqaGNkKTsK IAogaW50IHVzYl9waHlfcm9vdGh1Yl9pbml0KHN0cnVjdCB1c2JfcGh5X3Jvb3RodWIgKnBoeV9y b290aHViKTsKIGludCB1c2JfcGh5X3Jvb3RodWJfZXhpdChzdHJ1Y3QgdXNiX3BoeV9yb290aHVi ICpwaHlfcm9vdGh1Yik7CkBAIC0xOSw5ICsyMiw5IEBACiBpbnQgdXNiX3BoeV9yb290aHViX3Bv d2VyX29uKHN0cnVjdCB1c2JfcGh5X3Jvb3RodWIgKnBoeV9yb290aHViKTsKIHZvaWQgdXNiX3Bo eV9yb290aHViX3Bvd2VyX29mZihzdHJ1Y3QgdXNiX3BoeV9yb290aHViICpwaHlfcm9vdGh1Yik7 CiAKLWludCB1c2JfcGh5X3Jvb3RodWJfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpjb250cm9sbGVy X2RldiwKK2ludCB1c2JfcGh5X3Jvb3RodWJfc3VzcGVuZChzdHJ1Y3QgdXNiX2hjZCAqaGNkLAog CQkJICAgIHN0cnVjdCB1c2JfcGh5X3Jvb3RodWIgKnBoeV9yb290aHViKTsKLWludCB1c2JfcGh5 X3Jvb3RodWJfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmNvbnRyb2xsZXJfZGV2LAoraW50IHVzYl9w aHlfcm9vdGh1Yl9yZXN1bWUoc3RydWN0IHVzYl9oY2QgKmhjZCwKIAkJCSAgIHN0cnVjdCB1c2Jf cGh5X3Jvb3RodWIgKnBoeV9yb290aHViKTsKIAogI2VuZGlmIC8qIF9fVVNCX0NPUkVfUEhZX0hf ICovCmRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L3VzYi9oY2QuaCBiL2luY2x1ZGUvbGludXgv dXNiL2hjZC5oCmluZGV4IDk3ZTJkZGVjMThiMS4uODdhMTA0MDU1YjVlIDEwMDY0NAotLS0gYS9p bmNsdWRlL2xpbnV4L3VzYi9oY2QuaAorKysgYi9pbmNsdWRlL2xpbnV4L3VzYi9oY2QuaApAQCAt MTU3LDYgKzE1Nyw5IEBAIHN0cnVjdCB1c2JfaGNkIHsKIAkgKi8KIAl1bnNpZ25lZAkJc2tpcF9w aHlfaW5pdGlhbGl6YXRpb246MTsKIAorCS8qIFNvbWUgcGh5cyBkb24ndCB3YW50IHRoZSBwaHkn cyBleGl0L2luaXQgY2FsbGVkIG9uIHN1c3BlbmQvcmVzdW1lICovCisJdW5zaWduZWQJCXN1c3Bl bmRfd2l0aG91dF9waHlfZXhpdDoxOworCiAJLyogVGhlIG5leHQgZmxhZyBpcyBhIHN0b3BnYXAs IHRvIGJlIHJlbW92ZWQgd2hlbiBhbGwgdGhlIEhDRHMKIAkgKiBzdXBwb3J0IHRoZSBuZXcgcm9v dC1odWIgcG9sbGluZyBtZWNoYW5pc20uICovCiAJdW5zaWduZWQJCXVzZXNfbmV3X3BvbGxpbmc6 MTsK From mboxrd@z Thu Jan 1 00:00:00 1970 From: Al Cooper Subject: [PATCH V3 2/6] usb: core: Add ability to skip phy exit on suspend and init on resume Date: Mon, 5 Nov 2018 16:31:29 -0500 Message-ID: <1541453493-34981-3-git-send-email-alcooperx@gmail.com> References: <1541453493-34981-1-git-send-email-alcooperx@gmail.com> Return-path: In-Reply-To: <1541453493-34981-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 , Jianguo Sun , Johan Hovold , Kees Cook , linux-usb@ 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 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 "suspend_without_phy_exit" which can be set from any HCD driver. Signed-off-by: Al Cooper --- drivers/usb/core/hcd.c | 8 ++++---- drivers/usb/core/phy.c | 18 ++++++++++++------ drivers/usb/core/phy.h | 9 ++++++--- include/linux/usb/hcd.h | 3 +++ 4 files changed, 25 insertions(+), 13 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..308d716304da 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; @@ -162,26 +163,30 @@ 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)) + if (device_may_wakeup(controller_dev) || hcd->suspend_without_phy_exit) 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 (!device_may_wakeup(controller_dev) && + !hcd->suspend_without_phy_exit) { err = usb_phy_roothub_init(phy_roothub); if (err) return err; @@ -190,7 +195,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->suspend_without_phy_exit) 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..87a104055b5e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -157,6 +157,9 @@ struct usb_hcd { */ unsigned skip_phy_initialization:1; + /* Some phys don't want the phy's exit/init called on suspend/resume */ + unsigned suspend_without_phy_exit: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.9 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,URIBL_BLOCKED,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 A2538C0044C for ; Mon, 5 Nov 2018 21:33:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5482B2085B for ; Mon, 5 Nov 2018 21:33:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DC0QAZM/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5482B2085B 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 S2388119AbeKFGyp (ORCPT ); Tue, 6 Nov 2018 01:54:45 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:46560 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387628AbeKFGyp (ORCPT ); Tue, 6 Nov 2018 01:54:45 -0500 Received: by mail-pf1-f193.google.com with SMTP id r64-v6so5032080pfb.13; Mon, 05 Nov 2018 13:33:03 -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=XHS8gkOFUvy4AC3AC6pIxVYKXEuWaPsDgcn2703bFBQ=; b=DC0QAZM/2Jdtxp2zcyXnvv9+42P0RU902rz3nU5/ClWbpRwMwydX/m5ma4YdgLtZi7 oOcg/F8kLkN9ql1GHB98UbirWYVoPfkwPED9PwnTab3FWEcaDl/wC6eZ9GVGSxZSTIdA ipT6FUTScNbhu3E2U+keUbWkX6VYXRKGoRFnbADSvYdWrViQ5PLVaAcPOPE4gFpQUtXq iPGQnl/qYjp8AT0FmX5kb9QE4n8nTMUBkUsgvcxgeNA2iBbkDcRaT10+BjR7CPyst8Aa BCbIdO1X+tSpHX8oSWwOrPlasxksbNbHUOGra9EyyKfsXZS6JTaKjGsGM9O5RXO5iArM Egcw== 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=XHS8gkOFUvy4AC3AC6pIxVYKXEuWaPsDgcn2703bFBQ=; b=iQSEnR8cmPQKKvKQ3hZ5U6lBmRhLDIqg6xveTwPlv2ssYFtyC9ODt1z3a6sbJkUaRm RKGbk7FHtCYglruIVa83UzvoL5QXq7l8uMYXwO9p4U5aPRBaOzAwKyzgCqnXjEA8F390 pgKW+1w63Cq2p33mr4uq58u6UOt58I3imqHPKsuY06Fs1l13r4ecPscNakHGGo3LaA8p b1Naq7VeXasWNjSvd9n0Py8Wd52JValgtFAMWyT2rJe9oTQcpKEBucUVmK58ZoGVJgRm INGkkfmj1wv7RtfCsPEKF03Be48OUmIBLssDDOO3WvOSqrANM2/jyGbmWais+bRbfbKC 0lVQ== X-Gm-Message-State: AGRZ1gKlo6IB+O3I71UnSSIGIinkC4WBqZsPMyit4bigvVUgdTKmmcvu 8wGTm38/KMXCCCtxk7wMQyh/Usix9jc= X-Google-Smtp-Source: AJdET5enw5kTkw2w/oWlBrr32UcYqcbdDxChR4Yu1FtUwaLpbANaXE0ZIxqCOWOd/zi4M+KsiYkXmQ== X-Received: by 2002:a63:151f:: with SMTP id v31mr10637738pgl.34.1541453582643; Mon, 05 Nov 2018 13:33:02 -0800 (PST) Received: from stbsrv-and-3.and.broadcom.com ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id m129-v6sm14328440pfm.78.2018.11.05.13.32.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Nov 2018 13:33:02 -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 , Jianguo Sun , 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 V3 2/6] usb: core: Add ability to skip phy exit on suspend and init on resume Date: Mon, 5 Nov 2018 16:31:29 -0500 Message-Id: <1541453493-34981-3-git-send-email-alcooperx@gmail.com> X-Mailer: git-send-email 1.9.0.138.g2de3478 In-Reply-To: <1541453493-34981-1-git-send-email-alcooperx@gmail.com> References: <1541453493-34981-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 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 "suspend_without_phy_exit" which can be set from any HCD driver. Signed-off-by: Al Cooper --- drivers/usb/core/hcd.c | 8 ++++---- drivers/usb/core/phy.c | 18 ++++++++++++------ drivers/usb/core/phy.h | 9 ++++++--- include/linux/usb/hcd.h | 3 +++ 4 files changed, 25 insertions(+), 13 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..308d716304da 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; @@ -162,26 +163,30 @@ 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)) + if (device_may_wakeup(controller_dev) || hcd->suspend_without_phy_exit) 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 (!device_may_wakeup(controller_dev) && + !hcd->suspend_without_phy_exit) { err = usb_phy_roothub_init(phy_roothub); if (err) return err; @@ -190,7 +195,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->suspend_without_phy_exit) 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..87a104055b5e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -157,6 +157,9 @@ struct usb_hcd { */ unsigned skip_phy_initialization:1; + /* Some phys don't want the phy's exit/init called on suspend/resume */ + unsigned suspend_without_phy_exit: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