From mboxrd@z Thu Jan 1 00:00:00 1970 From: vladimir_zapolskiy@mentor.com (Vladimir Zapolskiy) Date: Wed, 16 Sep 2015 23:58:24 +0300 Subject: [PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support In-Reply-To: References: <1440970470-7155-1-git-send-email-vladimir_zapolskiy@mentor.com> Message-ID: <55F9D7F0.4070402@mentor.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Doug, On 16.09.2015 23:04, Doug Anderson wrote: > Hi, > > On Sun, Aug 30, 2015 at 2:34 PM, Vladimir Zapolskiy > wrote: >> The change adds support of internal HDMI I2C master controller, this >> subdevice is used by default, if "ddc-i2c-bus" DT property is omitted. >> >> The main purpose of this functionality is to support reading EDID from >> an HDMI monitor on boards, which don't have an I2C bus connected to >> DDC pins. >> >> The current implementation does not support "I2C Master Interface >> Extended Read Mode" to read data addressed by non-zero segment >> pointer, this means that if EDID has more than 1 extension blocks, >> EDID reading operation won't succeed, in my practice all tested HDMI >> monitors have at maximum one extension block. >> >> Signed-off-by: Vladimir Zapolskiy >> --- >> The change is based on today's v4.2, please let me know, if it should be rebased. >> >> The change has compilation dependency on I2CM_ADDRESS register name fix, >> see http://lists.freedesktop.org/archives/dri-devel/2015-May/082980.html >> >> From http://lists.freedesktop.org/archives/dri-devel/2015-May/082981.html >> v1 of the change was >> >> Tested-by: Philipp Zabel >> >> but I hesitate to add the tag here due to multiple updates in v2. >> >> Changes from v2 to v3, thanks to Russell: >> - moved register field value definitions to dw_hdmi.h >> - made completions uninterruptible to avoid transfer retries if interrupted >> - use one completion for both read and write transfers as in v1, operation_reg is removed >> - redundant i2c->stat = 0 is removed from dw_hdmi_i2c_read/write() >> - struct i2c_algorithm dw_hdmi_algorithm is qualified as const >> - dw_hdmi_i2c_adapter() does not modify struct dw_hdmi on error path >> - dw_hdmi_i2c_irq() does not modify hdmi->i2c->stat, if interrupt is not for I2CM >> - spin lock is removed from dw_hdmi_i2c_irq() >> - removed spin lock from dw_hdmi_i2c_xfer() around write to HDMI_IH_MUTE_I2CM_STAT0 register >> - split loop over message array in dw_hdmi_i2c_xfer() to validation and transfer parts >> - added a mutex to serialize I2C transfer requests, i2c->lock is completely removed >> - removed if(len) check from dw_hdmi_i2c_write(), hardware supports only len>0 transfers >> - described extension blocks <= 1 limitation in the commit message >> - a number of minor clean ups >> >> Changes from v1 to v2: >> - fixed a devm_kfree() signature >> - split completions for read and write operations >> >> drivers/gpu/drm/bridge/dw_hdmi.c | 262 ++++++++++++++++++++++++++++++++++++++- >> drivers/gpu/drm/bridge/dw_hdmi.h | 19 +++ >> 2 files changed, 275 insertions(+), 6 deletions(-) > > Not sure what the status of this patch is, but I'll make a few more > suggestions in case they're helpful. sure, all review comments are welcome. I have in mind that Philipp asked to add an update to documentation, the next version will contain the fixes. > >> +static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi) >> +{ >> + /* Set Fast Mode speed */ >> + hdmi_writeb(hdmi, 0x0b, HDMI_I2CM_DIV); > > If you're going to hardcode to something, it seems like hardcoding to > standard mode might be better? It's likely that users will plug into > all kinds of broken / crappy HDMI devices out there. I think you'll > get better compatibility by using the slower mode, and EDID transfers > really aren't too performance critical are they? > Accepted. I don't know what are the exact divisors of master clock for fast and standard modes, for reference I'll make a simple performance test and publish its results. I expect that in standard mode SCL is about 100KHz and in fast mode SCL is about 400KHz, and, if in standard mode SCL is less than 100KHz, it will take more than 50ms to read out 512 bytes of data, which might be not acceptable from performance perspective. >> + >> + /* Software reset */ >> + hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ); > > Unless there's a reason not to, it seems like the reset ought to be > the first thing in this function (before setting the I2CM_DIV). Even > if it doesn't actually reset the speed on current hardware, it just > seems cleaner. It makes sense for me. > >> +static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap, >> + struct i2c_msg *msgs, int num) >> +{ >> + struct dw_hdmi *hdmi = i2c_get_adapdata(adap); >> + struct dw_hdmi_i2c *i2c = hdmi->i2c; >> + u8 addr = msgs[0].addr; >> + int i, ret = 0; >> + >> + dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); >> + >> + for (i = 0; i < num; i++) { >> + if (msgs[i].addr != addr) { >> + dev_warn(hdmi->dev, >> + "unsupported transfer, changed slave address\n"); >> + return -EOPNOTSUPP; >> + } >> + >> + if (msgs[i].len == 0) { >> + dev_dbg(hdmi->dev, >> + "unsupported transfer %d/%d, no data\n", >> + i + 1, num); >> + return -EOPNOTSUPP; >> + } >> + } >> + >> + mutex_lock(&i2c->lock); >> + > > If I may make a suggestion, it's worth considering putting > dw_hdmi_i2c_init() here and removing it from the dw_hdmi_bind() > function. There isn't any state kept between i2c transfers (each one > is independent), so re-initting each time won't hurt. ...and doing so > has the potential to fix some things. I think it is resourse wasteful, especially since it does not solve any actual problem, if I understand your arguments correctly. I'd like to see the I2C bus registered even if there is no ongoing transfer, for instance running "modprobe i2c-dev; i2cdetect -l". For information I notice that there is a movement of I2C bus configuration/capture from bind() to probe() in DRM drivers, e.g. see commit 53bdcf5f026c . > On rk3288 there's at least one case where the i2c controller can get > wedged and just totally stops working. Although this particular wedge > isn't fixed by calling dw_hdmi_i2c_init() (it needs a full controller > reset to fix), it's possible that there may be other cases where the > HDMI_I2CM_SOFTRSTZ fixes some bad state. I don't know, may be the shared part of the driver should export a reset() function for RK3288, if it (or its next version) helps? Unlickily I don't possess an RK3288 power board, but in any case I would appreciate, if you share your test, I'll try to reproduce the same problem on iMX6. At the moment I am inclided to preserve I2C bus registration in bind() > Note: if you do that, you can just init HDMI_IH_MUTE_I2CM_STAT0 to > 0x00 at the end of dw_hdmi_i2c_init() and skip the next statement... > >> + hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0); > > With best wishes, Vladimir From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vladimir Zapolskiy Subject: Re: [PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support Date: Wed, 16 Sep 2015 23:58:24 +0300 Message-ID: <55F9D7F0.4070402@mentor.com> References: <1440970470-7155-1-git-send-email-vladimir_zapolskiy@mentor.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from relay1.mentorg.com (relay1.mentorg.com [192.94.38.131]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1A4596E03C for ; Wed, 16 Sep 2015 13:58:38 -0700 (PDT) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Doug Anderson Cc: Fabio Estevam , Thierry Reding , "dri-devel@lists.freedesktop.org" , Yakir Yang , Russell King , Andy Yan , "linux-arm-kernel@lists.infradead.org" List-Id: dri-devel@lists.freedesktop.org SGkgRG91ZywKCk9uIDE2LjA5LjIwMTUgMjM6MDQsIERvdWcgQW5kZXJzb24gd3JvdGU6Cj4gSGks Cj4gCj4gT24gU3VuLCBBdWcgMzAsIDIwMTUgYXQgMjozNCBQTSwgVmxhZGltaXIgWmFwb2xza2l5 Cj4gPHZsYWRpbWlyX3phcG9sc2tpeUBtZW50b3IuY29tPiB3cm90ZToKPj4gVGhlIGNoYW5nZSBh ZGRzIHN1cHBvcnQgb2YgaW50ZXJuYWwgSERNSSBJMkMgbWFzdGVyIGNvbnRyb2xsZXIsIHRoaXMK Pj4gc3ViZGV2aWNlIGlzIHVzZWQgYnkgZGVmYXVsdCwgaWYgImRkYy1pMmMtYnVzIiBEVCBwcm9w ZXJ0eSBpcyBvbWl0dGVkLgo+Pgo+PiBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgZnVuY3Rpb25h bGl0eSBpcyB0byBzdXBwb3J0IHJlYWRpbmcgRURJRCBmcm9tCj4+IGFuIEhETUkgbW9uaXRvciBv biBib2FyZHMsIHdoaWNoIGRvbid0IGhhdmUgYW4gSTJDIGJ1cyBjb25uZWN0ZWQgdG8KPj4gRERD IHBpbnMuCj4+Cj4+IFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQg IkkyQyBNYXN0ZXIgSW50ZXJmYWNlCj4+IEV4dGVuZGVkIFJlYWQgTW9kZSIgdG8gcmVhZCBkYXRh IGFkZHJlc3NlZCBieSBub24temVybyBzZWdtZW50Cj4+IHBvaW50ZXIsIHRoaXMgbWVhbnMgdGhh dCBpZiBFRElEIGhhcyBtb3JlIHRoYW4gMSBleHRlbnNpb24gYmxvY2tzLAo+PiBFRElEIHJlYWRp bmcgb3BlcmF0aW9uIHdvbid0IHN1Y2NlZWQsIGluIG15IHByYWN0aWNlIGFsbCB0ZXN0ZWQgSERN SQo+PiBtb25pdG9ycyBoYXZlIGF0IG1heGltdW0gb25lIGV4dGVuc2lvbiBibG9jay4KPj4KPj4g U2lnbmVkLW9mZi1ieTogVmxhZGltaXIgWmFwb2xza2l5IDx2bGFkaW1pcl96YXBvbHNraXlAbWVu dG9yLmNvbT4KPj4gLS0tCj4+IFRoZSBjaGFuZ2UgaXMgYmFzZWQgb24gdG9kYXkncyB2NC4yLCBw bGVhc2UgbGV0IG1lIGtub3csIGlmIGl0IHNob3VsZCBiZSByZWJhc2VkLgo+Pgo+PiBUaGUgY2hh bmdlIGhhcyBjb21waWxhdGlvbiBkZXBlbmRlbmN5IG9uIEkyQ01fQUREUkVTUyByZWdpc3RlciBu YW1lIGZpeCwKPj4gc2VlIGh0dHA6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvYXJjaGl2ZXMvZHJp LWRldmVsLzIwMTUtTWF5LzA4Mjk4MC5odG1sCj4+Cj4+IEZyb20gaHR0cDovL2xpc3RzLmZyZWVk ZXNrdG9wLm9yZy9hcmNoaXZlcy9kcmktZGV2ZWwvMjAxNS1NYXkvMDgyOTgxLmh0bWwKPj4gdjEg b2YgdGhlIGNoYW5nZSB3YXMKPj4KPj4gICBUZXN0ZWQtYnk6IFBoaWxpcHAgWmFiZWwgPHAuemFi ZWxAcGVuZ3V0cm9uaXguZGU+Cj4+Cj4+IGJ1dCBJIGhlc2l0YXRlIHRvIGFkZCB0aGUgdGFnIGhl cmUgZHVlIHRvIG11bHRpcGxlIHVwZGF0ZXMgaW4gdjIuCj4+Cj4+IENoYW5nZXMgZnJvbSB2MiB0 byB2MywgdGhhbmtzIHRvIFJ1c3NlbGw6Cj4+IC0gbW92ZWQgcmVnaXN0ZXIgZmllbGQgdmFsdWUg ZGVmaW5pdGlvbnMgdG8gZHdfaGRtaS5oCj4+IC0gbWFkZSBjb21wbGV0aW9ucyB1bmludGVycnVw dGlibGUgdG8gYXZvaWQgdHJhbnNmZXIgcmV0cmllcyBpZiBpbnRlcnJ1cHRlZAo+PiAtIHVzZSBv bmUgY29tcGxldGlvbiBmb3IgYm90aCByZWFkIGFuZCB3cml0ZSB0cmFuc2ZlcnMgYXMgaW4gdjEs IG9wZXJhdGlvbl9yZWcgaXMgcmVtb3ZlZAo+PiAtIHJlZHVuZGFudCBpMmMtPnN0YXQgPSAwIGlz IHJlbW92ZWQgZnJvbSBkd19oZG1pX2kyY19yZWFkL3dyaXRlKCkKPj4gLSBzdHJ1Y3QgaTJjX2Fs Z29yaXRobSBkd19oZG1pX2FsZ29yaXRobSBpcyBxdWFsaWZpZWQgYXMgY29uc3QKPj4gLSBkd19o ZG1pX2kyY19hZGFwdGVyKCkgZG9lcyBub3QgbW9kaWZ5IHN0cnVjdCBkd19oZG1pIG9uIGVycm9y IHBhdGgKPj4gLSBkd19oZG1pX2kyY19pcnEoKSBkb2VzIG5vdCBtb2RpZnkgaGRtaS0+aTJjLT5z dGF0LCBpZiBpbnRlcnJ1cHQgaXMgbm90IGZvciBJMkNNCj4+IC0gc3BpbiBsb2NrIGlzIHJlbW92 ZWQgZnJvbSBkd19oZG1pX2kyY19pcnEoKQo+PiAtIHJlbW92ZWQgc3BpbiBsb2NrIGZyb20gZHdf aGRtaV9pMmNfeGZlcigpIGFyb3VuZCB3cml0ZSB0byBIRE1JX0lIX01VVEVfSTJDTV9TVEFUMCBy ZWdpc3Rlcgo+PiAtIHNwbGl0IGxvb3Agb3ZlciBtZXNzYWdlIGFycmF5IGluIGR3X2hkbWlfaTJj X3hmZXIoKSB0byB2YWxpZGF0aW9uIGFuZCB0cmFuc2ZlciBwYXJ0cwo+PiAtIGFkZGVkIGEgbXV0 ZXggdG8gc2VyaWFsaXplIEkyQyB0cmFuc2ZlciByZXF1ZXN0cywgaTJjLT5sb2NrIGlzIGNvbXBs ZXRlbHkgcmVtb3ZlZAo+PiAtIHJlbW92ZWQgaWYobGVuKSBjaGVjayBmcm9tIGR3X2hkbWlfaTJj X3dyaXRlKCksIGhhcmR3YXJlIHN1cHBvcnRzIG9ubHkgbGVuPjAgdHJhbnNmZXJzCj4+IC0gZGVz Y3JpYmVkIGV4dGVuc2lvbiBibG9ja3MgPD0gMSBsaW1pdGF0aW9uIGluIHRoZSBjb21taXQgbWVz c2FnZQo+PiAtIGEgbnVtYmVyIG9mIG1pbm9yIGNsZWFuIHVwcwo+Pgo+PiBDaGFuZ2VzIGZyb20g djEgdG8gdjI6Cj4+IC0gZml4ZWQgYSBkZXZtX2tmcmVlKCkgc2lnbmF0dXJlCj4+IC0gc3BsaXQg Y29tcGxldGlvbnMgZm9yIHJlYWQgYW5kIHdyaXRlIG9wZXJhdGlvbnMKPj4KPj4gIGRyaXZlcnMv Z3B1L2RybS9icmlkZ2UvZHdfaGRtaS5jIHwgMjYyICsrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrLQo+PiAgZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9kd19oZG1pLmggfCAgMTkg KysrCj4+ICAyIGZpbGVzIGNoYW5nZWQsIDI3NSBpbnNlcnRpb25zKCspLCA2IGRlbGV0aW9ucygt KQo+IAo+IE5vdCBzdXJlIHdoYXQgdGhlIHN0YXR1cyBvZiB0aGlzIHBhdGNoIGlzLCBidXQgSSds bCBtYWtlIGEgZmV3IG1vcmUKPiBzdWdnZXN0aW9ucyBpbiBjYXNlIHRoZXkncmUgaGVscGZ1bC4K CnN1cmUsIGFsbCByZXZpZXcgY29tbWVudHMgYXJlIHdlbGNvbWUuCgpJIGhhdmUgaW4gbWluZCB0 aGF0IFBoaWxpcHAgYXNrZWQgdG8gYWRkIGFuIHVwZGF0ZSB0byBkb2N1bWVudGF0aW9uLCB0aGUK bmV4dCB2ZXJzaW9uIHdpbGwgY29udGFpbiB0aGUgZml4ZXMuCgo+IAo+PiArc3RhdGljIHZvaWQg ZHdfaGRtaV9pMmNfaW5pdChzdHJ1Y3QgZHdfaGRtaSAqaGRtaSkKPj4gK3sKPj4gKyAgICAgICAv KiBTZXQgRmFzdCBNb2RlIHNwZWVkICovCj4+ICsgICAgICAgaGRtaV93cml0ZWIoaGRtaSwgMHgw YiwgSERNSV9JMkNNX0RJVik7Cj4gCj4gSWYgeW91J3JlIGdvaW5nIHRvIGhhcmRjb2RlIHRvIHNv bWV0aGluZywgaXQgc2VlbXMgbGlrZSBoYXJkY29kaW5nIHRvCj4gc3RhbmRhcmQgbW9kZSBtaWdo dCBiZSBiZXR0ZXI/ICBJdCdzIGxpa2VseSB0aGF0IHVzZXJzIHdpbGwgcGx1ZyBpbnRvCj4gYWxs IGtpbmRzIG9mIGJyb2tlbiAvIGNyYXBweSBIRE1JIGRldmljZXMgb3V0IHRoZXJlLiAgSSB0aGlu ayB5b3UnbGwKPiBnZXQgYmV0dGVyIGNvbXBhdGliaWxpdHkgYnkgdXNpbmcgdGhlIHNsb3dlciBt b2RlLCBhbmQgRURJRCB0cmFuc2ZlcnMKPiByZWFsbHkgYXJlbid0IHRvbyBwZXJmb3JtYW5jZSBj cml0aWNhbCBhcmUgdGhleT8KPiAKCkFjY2VwdGVkLiBJIGRvbid0IGtub3cgd2hhdCBhcmUgdGhl IGV4YWN0IGRpdmlzb3JzIG9mIG1hc3RlciBjbG9jayBmb3IKZmFzdCBhbmQgc3RhbmRhcmQgbW9k ZXMsIGZvciByZWZlcmVuY2UgSSdsbCBtYWtlIGEgc2ltcGxlIHBlcmZvcm1hbmNlCnRlc3QgYW5k IHB1Ymxpc2ggaXRzIHJlc3VsdHMuIEkgZXhwZWN0IHRoYXQgaW4gc3RhbmRhcmQgbW9kZSBTQ0wg aXMKYWJvdXQgMTAwS0h6IGFuZCBpbiBmYXN0IG1vZGUgU0NMIGlzIGFib3V0IDQwMEtIeiwgYW5k LCBpZiBpbiBzdGFuZGFyZAptb2RlIFNDTCBpcyBsZXNzIHRoYW4gMTAwS0h6LCBpdCB3aWxsIHRh a2UgbW9yZSB0aGFuIDUwbXMgdG8gcmVhZCBvdXQKNTEyIGJ5dGVzIG9mIGRhdGEsIHdoaWNoIG1p Z2h0IGJlIG5vdCBhY2NlcHRhYmxlIGZyb20gcGVyZm9ybWFuY2UKcGVyc3BlY3RpdmUuCgo+PiAr Cj4+ICsgICAgICAgLyogU29mdHdhcmUgcmVzZXQgKi8KPj4gKyAgICAgICBoZG1pX3dyaXRlYiho ZG1pLCAweDAwLCBIRE1JX0kyQ01fU09GVFJTVFopOwo+IAo+IFVubGVzcyB0aGVyZSdzIGEgcmVh c29uIG5vdCB0bywgaXQgc2VlbXMgbGlrZSB0aGUgcmVzZXQgb3VnaHQgdG8gYmUKPiB0aGUgZmly c3QgdGhpbmcgaW4gdGhpcyBmdW5jdGlvbiAoYmVmb3JlIHNldHRpbmcgdGhlIEkyQ01fRElWKS4g IEV2ZW4KPiBpZiBpdCBkb2Vzbid0IGFjdHVhbGx5IHJlc2V0IHRoZSBzcGVlZCBvbiBjdXJyZW50 IGhhcmR3YXJlLCBpdCBqdXN0Cj4gc2VlbXMgY2xlYW5lci4KCkl0IG1ha2VzIHNlbnNlIGZvciBt ZS4KCj4gCj4+ICtzdGF0aWMgaW50IGR3X2hkbWlfaTJjX3hmZXIoc3RydWN0IGkyY19hZGFwdGVy ICphZGFwLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGkyY19tc2cgKm1z Z3MsIGludCBudW0pCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IGR3X2hkbWkgKmhkbWkgPSBpMmNf Z2V0X2FkYXBkYXRhKGFkYXApOwo+PiArICAgICAgIHN0cnVjdCBkd19oZG1pX2kyYyAqaTJjID0g aGRtaS0+aTJjOwo+PiArICAgICAgIHU4IGFkZHIgPSBtc2dzWzBdLmFkZHI7Cj4+ICsgICAgICAg aW50IGksIHJldCA9IDA7Cj4+ICsKPj4gKyAgICAgICBkZXZfZGJnKGhkbWktPmRldiwgInhmZXI6 IG51bTogJWQsIGFkZHI6ICUjeFxuIiwgbnVtLCBhZGRyKTsKPj4gKwo+PiArICAgICAgIGZvciAo aSA9IDA7IGkgPCBudW07IGkrKykgewo+PiArICAgICAgICAgICAgICAgaWYgKG1zZ3NbaV0uYWRk ciAhPSBhZGRyKSB7Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgIGRldl93YXJuKGhkbWktPmRl diwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuc3VwcG9ydGVkIHRyYW5z ZmVyLCBjaGFuZ2VkIHNsYXZlIGFkZHJlc3NcbiIpOwo+PiArICAgICAgICAgICAgICAgICAgICAg ICByZXR1cm4gLUVPUE5PVFNVUFA7Cj4+ICsgICAgICAgICAgICAgICB9Cj4+ICsKPj4gKyAgICAg ICAgICAgICAgIGlmIChtc2dzW2ldLmxlbiA9PSAwKSB7Cj4+ICsgICAgICAgICAgICAgICAgICAg ICAgIGRldl9kYmcoaGRtaS0+ZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICJ1bnN1cHBvcnRlZCB0cmFuc2ZlciAlZC8lZCwgbm8gZGF0YVxuIiwKPj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBpICsgMSwgbnVtKTsKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+PiArICAgICAgICAgICAgICAgfQo+PiArICAgICAgIH0K Pj4gKwo+PiArICAgICAgIG11dGV4X2xvY2soJmkyYy0+bG9jayk7Cj4+ICsKPiAKPiBJZiBJIG1h eSBtYWtlIGEgc3VnZ2VzdGlvbiwgaXQncyB3b3J0aCBjb25zaWRlcmluZyBwdXR0aW5nCj4gZHdf aGRtaV9pMmNfaW5pdCgpIGhlcmUgYW5kIHJlbW92aW5nIGl0IGZyb20gdGhlIGR3X2hkbWlfYmlu ZCgpCj4gZnVuY3Rpb24uICBUaGVyZSBpc24ndCBhbnkgc3RhdGUga2VwdCBiZXR3ZWVuIGkyYyB0 cmFuc2ZlcnMgKGVhY2ggb25lCj4gaXMgaW5kZXBlbmRlbnQpLCBzbyByZS1pbml0dGluZyBlYWNo IHRpbWUgd29uJ3QgaHVydC4gIC4uLmFuZCBkb2luZyBzbwo+IGhhcyB0aGUgcG90ZW50aWFsIHRv IGZpeCBzb21lIHRoaW5ncy4KCkkgdGhpbmsgaXQgaXMgcmVzb3Vyc2Ugd2FzdGVmdWwsIGVzcGVj aWFsbHkgc2luY2UgaXQgZG9lcyBub3Qgc29sdmUgYW55CmFjdHVhbCBwcm9ibGVtLCBpZiBJIHVu ZGVyc3RhbmQgeW91ciBhcmd1bWVudHMgY29ycmVjdGx5LgoKSSdkIGxpa2UgdG8gc2VlIHRoZSBJ MkMgYnVzIHJlZ2lzdGVyZWQgZXZlbiBpZiB0aGVyZSBpcyBubyBvbmdvaW5nCnRyYW5zZmVyLCBm b3IgaW5zdGFuY2UgcnVubmluZyAibW9kcHJvYmUgaTJjLWRldjsgaTJjZGV0ZWN0IC1sIi4KCkZv ciBpbmZvcm1hdGlvbiBJIG5vdGljZSB0aGF0IHRoZXJlIGlzIGEgbW92ZW1lbnQgb2YgSTJDIGJ1 cwpjb25maWd1cmF0aW9uL2NhcHR1cmUgZnJvbSBiaW5kKCkgdG8gcHJvYmUoKSBpbiBEUk0gZHJp dmVycywgZS5nLiBzZWUKY29tbWl0IDUzYmRjZjVmMDI2YyAuCgo+IE9uIHJrMzI4OCB0aGVyZSdz IGF0IGxlYXN0IG9uZSBjYXNlIHdoZXJlIHRoZSBpMmMgY29udHJvbGxlciBjYW4gZ2V0Cj4gd2Vk Z2VkIGFuZCBqdXN0IHRvdGFsbHkgc3RvcHMgd29ya2luZy4gIEFsdGhvdWdoIHRoaXMgcGFydGlj dWxhciB3ZWRnZQo+IGlzbid0IGZpeGVkIGJ5IGNhbGxpbmcgZHdfaGRtaV9pMmNfaW5pdCgpIChp dCBuZWVkcyBhIGZ1bGwgY29udHJvbGxlcgo+IHJlc2V0IHRvIGZpeCksIGl0J3MgcG9zc2libGUg dGhhdCB0aGVyZSBtYXkgYmUgb3RoZXIgY2FzZXMgd2hlcmUgdGhlCj4gSERNSV9JMkNNX1NPRlRS U1RaIGZpeGVzIHNvbWUgYmFkIHN0YXRlLgoKSSBkb24ndCBrbm93LCBtYXkgYmUgdGhlIHNoYXJl ZCBwYXJ0IG9mIHRoZSBkcml2ZXIgc2hvdWxkIGV4cG9ydCBhCnJlc2V0KCkgZnVuY3Rpb24gZm9y IFJLMzI4OCwgaWYgaXQgKG9yIGl0cyBuZXh0IHZlcnNpb24pIGhlbHBzPwoKVW5saWNraWx5IEkg ZG9uJ3QgcG9zc2VzcyBhbiBSSzMyODggcG93ZXIgYm9hcmQsIGJ1dCBpbiBhbnkgY2FzZSBJIHdv dWxkCmFwcHJlY2lhdGUsIGlmIHlvdSBzaGFyZSB5b3VyIHRlc3QsIEknbGwgdHJ5IHRvIHJlcHJv ZHVjZSB0aGUgc2FtZQpwcm9ibGVtIG9uIGlNWDYuCgpBdCB0aGUgbW9tZW50IEkgYW0gaW5jbGlk ZWQgdG8gcHJlc2VydmUgSTJDIGJ1cyByZWdpc3RyYXRpb24gaW4gYmluZCgpCgo+IE5vdGU6IGlm IHlvdSBkbyB0aGF0LCB5b3UgY2FuIGp1c3QgaW5pdCBIRE1JX0lIX01VVEVfSTJDTV9TVEFUMCB0 bwo+IDB4MDAgYXQgdGhlIGVuZCBvZiBkd19oZG1pX2kyY19pbml0KCkgYW5kIHNraXAgdGhlIG5l eHQgc3RhdGVtZW50Li4uCj4gCj4+ICsgICAgICAgaGRtaV93cml0ZWIoaGRtaSwgMHgwMCwgSERN SV9JSF9NVVRFX0kyQ01fU1RBVDApOwo+IAo+IAoKV2l0aCBiZXN0IHdpc2hlcywKVmxhZGltaXIK Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZl bCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwOi8vbGlz dHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==