From mboxrd@z Thu Jan 1 00:00:00 1970 From: Felipe Balbi Subject: Re: [PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver Date: Wed, 14 Mar 2018 10:50:12 +0200 Message-ID: <87woyfrqgr.fsf@linux.intel.com> References: <1520937362-28777-1-git-send-email-mgautam@codeaurora.org> <1520937362-28777-2-git-send-email-mgautam@codeaurora.org> <878taw8c81.fsf@linux.intel.com> <5a65d202-bb94-0f73-f9aa-9055a1cddf76@codeaurora.org> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" Return-path: In-Reply-To: <5a65d202-bb94-0f73-f9aa-9055a1cddf76@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org To: Manu Gautam , Rob Herring , Andy Gross , Heikki Krogerus Cc: linux-arm-msm@vger.kernel.org, linux-usb@vger.kernel.org, Greg Kroah-Hartman , open list List-Id: linux-arm-msm@vger.kernel.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, Manu Gautam writes: > Hi, > > > On 3/13/2018 4:38 PM, Felipe Balbi wrote: >> Hi, >> >> +Andy >> >> Manu Gautam writes: >>> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper. >>> Some of its uses are described below resulting in need to >>> have a separate glue driver instead of using dwc3-of-simple: >>> - It exposes register interface to override vbus-override >>> and lane0-pwr-present signals going to hardware. These >>> must be updated in peripheral mode for DWC3 if vbus lines >>> are not connected to hardware block. Otherwise RX termination >>> in SS mode or DP pull-up is not applied by device controller. >> right, core needs to know that VBUS is above 4.4V. Why wasn't this a >> problem when the original glue layer was first published? > > Thanks for reviewing. > Original glue layer supported only host mode, hence this wasn't needed. okay >>> - pwr_events_irq_stat support to ensure USB2 PHY is in L2 state >>> before glue driver can turn-off clocks and suspend PHY. >> Core manages PHY suspend automatically. Isn't that working for you? Why? > > Yes, it is not supported with QUSB2 PHY (usb2-phy on Qualcomm SOCs). but the PHY doesn't need to support it, DWC3 does :-) > Issue is that If core suspends USB2 PHY (say in host mode if some SS devi= ce connected), > USB2 PHY stops responding to any attach event as it can't exit suspend st= ate by itself. Okay, so we miss remote wakeup events. Fair enough. >>> - Support to replace pip3 clock going to DWC3 with utmi clock >>> for hardware configuration where SSPHY is not used with DWC3. >> Is that SW configurable? Really? In any case seems like this and SESSVLD >> valid should be handled using Hans' and Heikki's mux support. > > Yes, with this we can use dwc3 without using SSPHY. Please point me to > those patches. There are only bunch of register writes in glue wrapper to > achieve the same. https://www.spinics.net/lists/linux-usb/msg160868.html >>> +static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) >>> +{ >>> + struct dwc3 *dwc =3D platform_get_drvdata(qcom->dwc3); >> nope! Glue shouldn't touch dwc3 at all. > Other than PHY handles, need this to fail runtime suspend if dwc3 hasn't > probed yet. Will that even happen? You should pm_runtime_forbid() by default, anyway and expect it to be enabled via sysfs later, no? >>> + dwc3_qcom_suspend_hsphy(qcom); >>> + >>> + if (dwc->usb2_generic_phy) >>> + phy_pm_runtime_put_sync(dwc->usb2_generic_phy); >>> + if (dwc->usb3_generic_phy) >>> + phy_pm_runtime_put_sync(dwc->usb3_generic_phy); >> core.c should do this. > Recommended sequence from h/w programming guide is that: > 1. PHY autosuspend must be left disabled - snps,dis_u2_susphy_quirk/dis_e= nblslpm_quirk > 2. During runtime-suspend (say on xhci bus_suspend) , PHY should be suspe= nded > =C2=A0 =C2=A0 using GUSB2PHYCFG register this is something that dwc3 core can do on its own suspend implementation. > 3. Wait until pwr_event_irq_stat in qscratch reflects PHY transition to L= 2. this is interesting part. Is this register accessible by the PHY driver? Seems like that would be the best place to stuff this... > 3. USB2 PHY driver can suspend - enable wakeup events and turns off clock= s etc. ... together with this. > 4. dwc3 glue driver can suspend. > > Since, pwr_event_irq stat can't be checked in core driver, I added this h= andling > in glue driver. Alternative approach I can think of is to let dwc3 core s= uspend > PHY using GUSBPHYCFG register on suspend,=C2=A0 add some delay before > suspending PHY. Glue driver can check for pwr_event_irq stat and throw a > warning if PHY not in L2. almost :-) core_suspend fiddles with GUSB2PHYCFG for suspend and calls phy_suspend() (or whatever the function is called heh), that will go to your phy driver's suspend callback, which checks pwr_event_irq_stat and then pm_runtime_put() to schedule ->runtime_suspend() so that can enable wakeups and switch off clocks. >>> + irq =3D platform_get_irq_byname(pdev, "dp_hs_phy_irq"); >>> + if (irq > 0) { >>> + irq_set_status_flags(irq, IRQ_NOAUTOEN); >> why do you need to set this flag? > These wakeup_irqs should be enabled only during suspend. With this flag I > don't need to disable irq immediately after requesting it. oh, okay. You may want to add a comment here :-) > >> >>> + ret =3D devm_request_threaded_irq(qcom->dev, irq, NULL, >>> + qcom_dwc3_resume_irq, >>> + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, >>> + "qcom_dwc3 DP_HS", qcom); >> this is the same as devm_request_irq() > I am passing hard_irq handler as NULL whereas thread_fn is not NULL. > devm_request_irq is just the opposite. oh, indeed. I misparsed it. >>> +static const struct dev_pm_ops dwc3_qcom_dev_pm_ops =3D { >>> + SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume) >>> + SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resum= e, >>> + NULL) >> why don't you have runtime_idle? > > I didn't see any need for that. rpm_idle will invoke rpm_suspend if idle = callback > is not specified. Right, but ->runtime_idle() helps making things a little more readable. It is, however, a matter of taste. No strong feelings here. :-) =2D-=20 balbi --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEElLzh7wn96CXwjh2IzL64meEamQYFAlqo4kYACgkQzL64meEa mQZCCRAA0blI1D1nOAAMl06rb+jsilSfIsJFCN30Dz/9AFv1vMecbB2crJLWQNEJ IT39n7ssbYp2JQLviZ3dZLMEeuUVHy3Ml4KYGRM04VG8BNQZcxGWphDeDOTBujvz xPP/1bjA3VR9MTd05GotWwnLF+EMfHSHsMi4C/waVLTBIillrglXK1D7nrZLXO1m C4VxqcmhkAqGL4rexQ4FyvsKrmYOZGjuVO0PiUGfJelBJR56x5opA7jA4VqCPEYF pVxATPPvm9lj92PEDW39rQIiRSeSAmqFQ23PDoVkm4DzPC+o1SeZ68cxIwQUZtlY FKoIOq8026D8XE8PX3pXagRzOTYEekz1YWAXFP8WMYRlmoIh/htmVtrG/04+0mjo YbeYxslStw1yg7FB+tY5q4O+s9rOey+a5FNBjgUchj4MMTsrfZTTpxSBC32w34Aq wjTSlZQ86p/xVHeEsi4xHqYya0egCggE0So71gx8uwRDXu9kzcYcIGyn8V7lISiG qZB0jtf9Z5oe0mIBMU0/L55qsug0NeG5oscV6U8goZrQKrp1Qov0b160gSe5s/4f ShjZGtbd06LgAbOTgeC/k7GhlhhMUNWoCHRiWnaIBnQN2KPLcsj1stIxbd/fRfaj DEOElEwgnHnJnK0VrVsAqEiicu4uegO9zC3bEA9lTJAF5Qja+wM= =8FBf -----END PGP SIGNATURE----- --=-=-=-- 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: [v1,2/2] usb: dwc3: Add Qualcomm DWC3 glue driver From: Felipe Balbi Message-Id: <87woyfrqgr.fsf@linux.intel.com> Date: Wed, 14 Mar 2018 10:50:12 +0200 To: Manu Gautam , Rob Herring , Andy Gross , Heikki Krogerus Cc: linux-arm-msm@vger.kernel.org, linux-usb@vger.kernel.org, Greg Kroah-Hartman , open list List-ID: SGksCgpNYW51IEdhdXRhbSA8bWdhdXRhbUBjb2RlYXVyb3JhLm9yZz4gd3JpdGVzOgo+IEhpLAo+ Cj4KPiBPbiAzLzEzLzIwMTggNDozOCBQTSwgRmVsaXBlIEJhbGJpIHdyb3RlOgo+PiBIaSwKPj4K Pj4gK0FuZHkKPj4KPj4gTWFudSBHYXV0YW0gPG1nYXV0YW1AY29kZWF1cm9yYS5vcmc+IHdyaXRl czoKPj4+IERXQzMgY29udHJvbGxlciBvbiBRdWFsY29tbSBTT0NzIGhhcyBhIFFzY3JhdGNoIHdy YXBwZXIuCj4+PiBTb21lIG9mIGl0cyB1c2VzIGFyZSBkZXNjcmliZWQgYmVsb3cgcmVzdWx0aW5n IGluIG5lZWQgdG8KPj4+IGhhdmUgYSBzZXBhcmF0ZSBnbHVlIGRyaXZlciBpbnN0ZWFkIG9mIHVz aW5nIGR3YzMtb2Ytc2ltcGxlOgo+Pj4gIC0gSXQgZXhwb3NlcyByZWdpc3RlciBpbnRlcmZhY2Ug dG8gb3ZlcnJpZGUgdmJ1cy1vdmVycmlkZQo+Pj4gICAgYW5kIGxhbmUwLXB3ci1wcmVzZW50IHNp Z25hbHMgZ29pbmcgdG8gaGFyZHdhcmUuIFRoZXNlCj4+PiAgICBtdXN0IGJlIHVwZGF0ZWQgaW4g cGVyaXBoZXJhbCBtb2RlIGZvciBEV0MzIGlmIHZidXMgbGluZXMKPj4+ICAgIGFyZSBub3QgY29u bmVjdGVkIHRvIGhhcmR3YXJlIGJsb2NrLiBPdGhlcndpc2UgUlggdGVybWluYXRpb24KPj4+ICAg IGluIFNTIG1vZGUgb3IgRFAgcHVsbC11cCBpcyBub3QgYXBwbGllZCBieSBkZXZpY2UgY29udHJv bGxlci4KPj4gcmlnaHQsIGNvcmUgbmVlZHMgdG8ga25vdyB0aGF0IFZCVVMgaXMgYWJvdmUgNC40 Vi4gV2h5IHdhc24ndCB0aGlzIGEKPj4gcHJvYmxlbSB3aGVuIHRoZSBvcmlnaW5hbCBnbHVlIGxh eWVyIHdhcyBmaXJzdCBwdWJsaXNoZWQ/Cj4KPiBUaGFua3MgZm9yIHJldmlld2luZy4KPiBPcmln aW5hbCBnbHVlIGxheWVyIHN1cHBvcnRlZCBvbmx5IGhvc3QgbW9kZSwgaGVuY2UgdGhpcyB3YXNu J3QgbmVlZGVkLgoKb2theQoKPj4+ICAtIHB3cl9ldmVudHNfaXJxX3N0YXQgc3VwcG9ydCB0byBl bnN1cmUgVVNCMiBQSFkgaXMgaW4gTDIgc3RhdGUKPj4+ICAgIGJlZm9yZSBnbHVlIGRyaXZlciBj YW4gdHVybi1vZmYgY2xvY2tzIGFuZCBzdXNwZW5kIFBIWS4KPj4gQ29yZSBtYW5hZ2VzIFBIWSBz dXNwZW5kIGF1dG9tYXRpY2FsbHkuIElzbid0IHRoYXQgd29ya2luZyBmb3IgeW91PyBXaHk/Cj4K PiBZZXMsIGl0IGlzIG5vdCBzdXBwb3J0ZWQgd2l0aCBRVVNCMiBQSFkgKHVzYjItcGh5IG9uIFF1 YWxjb21tIFNPQ3MpLgoKYnV0IHRoZSBQSFkgZG9lc24ndCBuZWVkIHRvIHN1cHBvcnQgaXQsIERX QzMgZG9lcyA6LSkKCj4gSXNzdWUgaXMgdGhhdCBJZiBjb3JlIHN1c3BlbmRzIFVTQjIgUEhZIChz YXkgaW4gaG9zdCBtb2RlIGlmIHNvbWUgU1MgZGV2aWNlIGNvbm5lY3RlZCksCj4gVVNCMiBQSFkg c3RvcHMgcmVzcG9uZGluZyB0byBhbnkgYXR0YWNoIGV2ZW50IGFzIGl0IGNhbid0IGV4aXQgc3Vz cGVuZCBzdGF0ZSBieSBpdHNlbGYuCgpPa2F5LCBzbyB3ZSBtaXNzIHJlbW90ZSB3YWtldXAgZXZl bnRzLiBGYWlyIGVub3VnaC4KCj4+PiAgLSBTdXBwb3J0IHRvIHJlcGxhY2UgcGlwMyBjbG9jayBn b2luZyB0byBEV0MzIHdpdGggdXRtaSBjbG9jawo+Pj4gICAgZm9yIGhhcmR3YXJlIGNvbmZpZ3Vy YXRpb24gd2hlcmUgU1NQSFkgaXMgbm90IHVzZWQgd2l0aCBEV0MzLgo+PiBJcyB0aGF0IFNXIGNv bmZpZ3VyYWJsZT8gUmVhbGx5PyBJbiBhbnkgY2FzZSBzZWVtcyBsaWtlIHRoaXMgYW5kIFNFU1NW TEQKPj4gdmFsaWQgc2hvdWxkIGJlIGhhbmRsZWQgdXNpbmcgSGFucycgYW5kIEhlaWtraSdzIG11 eCBzdXBwb3J0Lgo+Cj4gWWVzLCB3aXRoIHRoaXMgd2UgY2FuIHVzZSBkd2MzIHdpdGhvdXQgdXNp bmcgU1NQSFkuIFBsZWFzZSBwb2ludCBtZSB0bwo+IHRob3NlIHBhdGNoZXMuIFRoZXJlIGFyZSBv bmx5IGJ1bmNoIG9mIHJlZ2lzdGVyIHdyaXRlcyBpbiBnbHVlIHdyYXBwZXIgdG8KPiBhY2hpZXZl IHRoZSBzYW1lLgoKaHR0cHM6Ly93d3cuc3Bpbmljcy5uZXQvbGlzdHMvbGludXgtdXNiL21zZzE2 MDg2OC5odG1sCgo+Pj4gK3N0YXRpYyBpbnQgZHdjM19xY29tX3N1c3BlbmQoc3RydWN0IGR3YzNf cWNvbSAqcWNvbSkKPj4+ICt7Cj4+PiArCXN0cnVjdCBkd2MzCSpkd2MgPSBwbGF0Zm9ybV9nZXRf ZHJ2ZGF0YShxY29tLT5kd2MzKTsKPj4gbm9wZSEgR2x1ZSBzaG91bGRuJ3QgdG91Y2ggZHdjMyBh dCBhbGwuCj4gT3RoZXIgdGhhbiBQSFkgaGFuZGxlcywgbmVlZCB0aGlzIHRvIGZhaWwgcnVudGlt ZSBzdXNwZW5kIGlmIGR3YzMgaGFzbid0Cj4gcHJvYmVkIHlldC4KCldpbGwgdGhhdCBldmVuIGhh cHBlbj8gWW91IHNob3VsZCBwbV9ydW50aW1lX2ZvcmJpZCgpIGJ5IGRlZmF1bHQsCmFueXdheSBh bmQgZXhwZWN0IGl0IHRvIGJlIGVuYWJsZWQgdmlhIHN5c2ZzIGxhdGVyLCBubz8KCj4+PiArCWR3 YzNfcWNvbV9zdXNwZW5kX2hzcGh5KHFjb20pOwo+Pj4gKwo+Pj4gKwlpZiAoZHdjLT51c2IyX2dl bmVyaWNfcGh5KQo+Pj4gKwkJcGh5X3BtX3J1bnRpbWVfcHV0X3N5bmMoZHdjLT51c2IyX2dlbmVy aWNfcGh5KTsKPj4+ICsJaWYgKGR3Yy0+dXNiM19nZW5lcmljX3BoeSkKPj4+ICsJCXBoeV9wbV9y dW50aW1lX3B1dF9zeW5jKGR3Yy0+dXNiM19nZW5lcmljX3BoeSk7Cj4+IGNvcmUuYyBzaG91bGQg ZG8gdGhpcy4KPiBSZWNvbW1lbmRlZCBzZXF1ZW5jZSBmcm9tIGgvdyBwcm9ncmFtbWluZyBndWlk ZSBpcyB0aGF0Ogo+IDEuIFBIWSBhdXRvc3VzcGVuZCBtdXN0IGJlIGxlZnQgZGlzYWJsZWQgLSBz bnBzLGRpc191Ml9zdXNwaHlfcXVpcmsvZGlzX2VuYmxzbHBtX3F1aXJrCj4gMi4gRHVyaW5nIHJ1 bnRpbWUtc3VzcGVuZCAoc2F5IG9uIHhoY2kgYnVzX3N1c3BlbmQpICwgUEhZIHNob3VsZCBiZSBz dXNwZW5kZWQKPiDCoCDCoCB1c2luZyBHVVNCMlBIWUNGRyByZWdpc3RlcgoKdGhpcyBpcyBzb21l dGhpbmcgdGhhdCBkd2MzIGNvcmUgY2FuIGRvIG9uIGl0cyBvd24gc3VzcGVuZCBpbXBsZW1lbnRh dGlvbi4KCj4gMy4gV2FpdCB1bnRpbCBwd3JfZXZlbnRfaXJxX3N0YXQgaW4gcXNjcmF0Y2ggcmVm bGVjdHMgUEhZIHRyYW5zaXRpb24gdG8gTDIuCgp0aGlzIGlzIGludGVyZXN0aW5nIHBhcnQuIElz IHRoaXMgcmVnaXN0ZXIgYWNjZXNzaWJsZSBieSB0aGUgUEhZIGRyaXZlcj8KU2VlbXMgbGlrZSB0 aGF0IHdvdWxkIGJlIHRoZSBiZXN0IHBsYWNlIHRvIHN0dWZmIHRoaXMuLi4KCj4gMy4gVVNCMiBQ SFkgZHJpdmVyIGNhbiBzdXNwZW5kIC0gZW5hYmxlIHdha2V1cCBldmVudHMgYW5kIHR1cm5zIG9m ZiBjbG9ja3MgZXRjLgoKLi4uIHRvZ2V0aGVyIHdpdGggdGhpcy4KCj4gNC4gZHdjMyBnbHVlIGRy aXZlciBjYW4gc3VzcGVuZC4KPgo+IFNpbmNlLCBwd3JfZXZlbnRfaXJxIHN0YXQgY2FuJ3QgYmUg Y2hlY2tlZCBpbiBjb3JlIGRyaXZlciwgSSBhZGRlZCB0aGlzIGhhbmRsaW5nCj4gaW4gZ2x1ZSBk cml2ZXIuIEFsdGVybmF0aXZlIGFwcHJvYWNoIEkgY2FuIHRoaW5rIG9mIGlzIHRvIGxldCBkd2Mz IGNvcmUgc3VzcGVuZAo+IFBIWSB1c2luZyBHVVNCUEhZQ0ZHIHJlZ2lzdGVyIG9uIHN1c3BlbmQs wqAgYWRkIHNvbWUgZGVsYXkgYmVmb3JlCj4gc3VzcGVuZGluZyBQSFkuIEdsdWUgZHJpdmVyIGNh biBjaGVjayBmb3IgcHdyX2V2ZW50X2lycSBzdGF0IGFuZCB0aHJvdyBhCj4gd2FybmluZyBpZiBQ SFkgbm90IGluIEwyLgoKYWxtb3N0IDotKSBjb3JlX3N1c3BlbmQgZmlkZGxlcyB3aXRoIEdVU0Iy UEhZQ0ZHIGZvciBzdXNwZW5kIGFuZCBjYWxscwpwaHlfc3VzcGVuZCgpIChvciB3aGF0ZXZlciB0 aGUgZnVuY3Rpb24gaXMgY2FsbGVkIGhlaCksIHRoYXQgd2lsbCBnbyB0bwp5b3VyIHBoeSBkcml2 ZXIncyBzdXNwZW5kIGNhbGxiYWNrLCB3aGljaCBjaGVja3MgcHdyX2V2ZW50X2lycV9zdGF0IGFu ZAp0aGVuIHBtX3J1bnRpbWVfcHV0KCkgdG8gc2NoZWR1bGUgLT5ydW50aW1lX3N1c3BlbmQoKSBz byB0aGF0IGNhbiBlbmFibGUKd2FrZXVwcyBhbmQgc3dpdGNoIG9mZiBjbG9ja3MuCgo+Pj4gKwlp cnEgPSBwbGF0Zm9ybV9nZXRfaXJxX2J5bmFtZShwZGV2LCAiZHBfaHNfcGh5X2lycSIpOwo+Pj4g KwlpZiAoaXJxID4gMCkgewo+Pj4gKwkJaXJxX3NldF9zdGF0dXNfZmxhZ3MoaXJxLCBJUlFfTk9B VVRPRU4pOwo+PiB3aHkgZG8geW91IG5lZWQgdG8gc2V0IHRoaXMgZmxhZz8KPiBUaGVzZSB3YWtl dXBfaXJxcyBzaG91bGQgYmUgZW5hYmxlZCBvbmx5IGR1cmluZyBzdXNwZW5kLiBXaXRoIHRoaXMg ZmxhZyBJCj4gZG9uJ3QgbmVlZCB0byBkaXNhYmxlIGlycSBpbW1lZGlhdGVseSBhZnRlciByZXF1 ZXN0aW5nIGl0LgoKb2gsIG9rYXkuIFlvdSBtYXkgd2FudCB0byBhZGQgYSBjb21tZW50IGhlcmUg Oi0pCgo+Cj4+Cj4+PiArCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJxKHFjb20tPmRl diwgaXJxLCBOVUxMLAo+Pj4gKwkJCQkJcWNvbV9kd2MzX3Jlc3VtZV9pcnEsCj4+PiArCQkJCQlJ UlFGX1RSSUdHRVJfSElHSCB8IElSUUZfT05FU0hPVCwKPj4+ICsJCQkJCSJxY29tX2R3YzMgRFBf SFMiLCBxY29tKTsKPj4gdGhpcyBpcyB0aGUgc2FtZSBhcyBkZXZtX3JlcXVlc3RfaXJxKCkKPiBJ IGFtIHBhc3NpbmcgaGFyZF9pcnEgaGFuZGxlciBhcyBOVUxMIHdoZXJlYXMgdGhyZWFkX2ZuIGlz IG5vdCBOVUxMLgo+IGRldm1fcmVxdWVzdF9pcnEgaXMganVzdCB0aGUgb3Bwb3NpdGUuCgpvaCwg aW5kZWVkLiBJIG1pc3BhcnNlZCBpdC4KCj4+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBkZXZfcG1f b3BzIGR3YzNfcWNvbV9kZXZfcG1fb3BzID0gewo+Pj4gKwlTRVRfU1lTVEVNX1NMRUVQX1BNX09Q Uyhkd2MzX3Fjb21fcG1fc3VzcGVuZCwgZHdjM19xY29tX3BtX3Jlc3VtZSkKPj4+ICsJU0VUX1JV TlRJTUVfUE1fT1BTKGR3YzNfcWNvbV9ydW50aW1lX3N1c3BlbmQsIGR3YzNfcWNvbV9ydW50aW1l X3Jlc3VtZSwKPj4+ICsJCQkgICBOVUxMKQo+PiB3aHkgZG9uJ3QgeW91IGhhdmUgcnVudGltZV9p ZGxlPwo+Cj4gSSBkaWRuJ3Qgc2VlIGFueSBuZWVkIGZvciB0aGF0LiBycG1faWRsZSB3aWxsIGlu dm9rZSBycG1fc3VzcGVuZCBpZiBpZGxlIGNhbGxiYWNrCj4gaXMgbm90IHNwZWNpZmllZC4KClJp Z2h0LCBidXQgLT5ydW50aW1lX2lkbGUoKSBoZWxwcyBtYWtpbmcgdGhpbmdzIGEgbGl0dGxlIG1v cmUKcmVhZGFibGUuIEl0IGlzLCBob3dldmVyLCBhIG1hdHRlciBvZiB0YXN0ZS4gTm8gc3Ryb25n IGZlZWxpbmdzIGhlcmUuIDotKQo=