All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <568EB58C.3090701@topic.nl>

diff --git a/a/1.txt b/N1/1.txt
index 300346d..1333d0e 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,283 +1,508 @@
-VGhhbmsgeW91IHZlcnkgbXVjaCBmb3IgeW91ciByZXZpZXcgY29tbWVudHMsIEknbGwgdXBkYXRl
-IHRoZSBkcml2ZXIgYW5kIApwb3N0IGEgdjIgcGF0Y2guCgpJbmxpbmVkIHNvbWUgcmVwbGllcyBi
-ZWxvdy4gQXNzdW1lIHRoYXQgSSAid2lsbCBkbyIgZm9yIGFsbCBjb21tZW50cyBJIApkaWRuJ3Qg
-Y29tbWVudCBvbiBpbmxpbmUuLi4KCk9uIDA2LTAxLTE2IDE2OjIyLCBHdWVudGVyIFJvZWNrIHdy
-b3RlOgo+IEhlbGxvIE1pa2UsCj4KPiBPbiAwMS8wNi8yMDE2IDEyOjA3IEFNLCBNaWtlIExvb2lq
-bWFucyB3cm90ZToKPj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9n
-eSBMVEMyOTkwICBJMkMgU3lzdGVtIE1vbml0b3IuCj4KPiBzLyAgLyAvCj4KPj4gVGhlIExUQzI5
-OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBjdXJyZW50IGFuZCB0ZW1wZXJh
-dHVyZQo+PiBtb25pdG9yaW5nLCBidXQgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9y
-dHMgcmVhZGluZyB0d28gY3VycmVudHMKPj4gYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwg
-dm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+Cj4gUGx1cyBWQ0MsIHBsdXMgdGhl
-IGludGVybmFsIHRlbXBlcmF0dXJlLgoKWWVhaCwgSSBzaG91bGQgZ2l2ZSBteXNlbGYgbW9yZSBj
-cmVkaXQgOikgSSdsbCBhZGQgdGhhdCBpbiBLY29uZmlnIHRvby4KCj4+IFRoaXMgaXMgc3VmZmlj
-aWVudCB0byBzdXBwb3J0IHRoZSBUb3BpYyBNaWFtaSBTT00gd2hpY2ggdXNlcyB0aGlzIGNoaXAK
-Pj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRoZSBGUEdBIGFuZCB0aGUg
-Q1BVIHBhcnRzLgo+Pgo+PiBTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29p
-am1hbnNAdG9waWMubmw+Cj4+IC0tLQo+PiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgIHwgIDE1
-ICsrKwo+PiAgIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3
-bW9uL2x0YzI5OTAuYyB8IDI3Mwo+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
-KysrKysrKysrKysrKysKPgo+IFBsZWFzZSBhbHNvIHByb3ZpZGUgRG9jdW1lbnRhdGlvbi9od21v
-bi9sdGMyOTkwLgo+Cj4gQWxzbywgcGxlYXNlIHJlYWQgYW5kIGZvbGxvdyBEb2N1bWVudGF0aW9u
-L2h3bW9uL3N1Ym1pdHRpbmctcGF0Y2hlcy4KPgo+PiAgIDMgZmlsZXMgY2hhbmdlZCwgMjg5IGlu
-c2VydGlvbnMoKykKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9od21vbi9sdGMyOTkw
-LmMKPj4KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt
-b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi5iM2VlZjMxIDEwMDY0NAo+PiAtLS0gYS9kcml2
-ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02
-ODUsNiArNjg1LDIxIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy
-aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls
-bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD
-Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50
-IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIHNl
-bGVjdCBSRUdNQVBfSTJDCj4KPiBVc2luZyByZWdtYXAgZm9yIHRoZSBkcml2ZXIgbWlnaHQgYmUg
-YSBnb29kIGlkZWEsIGJ1dCB5b3UgZG9uJ3QuCgpMb29raW5nIGF0IHRoZSByZWdtYXAsIHRoZSBk
-cml2ZXIgb25seSB3cml0ZXMgdGhlIG9uZSBjYWNoYWJsZSByZWdpc3RlciAKb25jZSwgdGhlICJj
-b250cm9sIi4gQWxsIHRoZSBvdGhlciByZWdpc3RlcnMgY2Fubm90IGJlIGNhY2hlZCwgYXJlIApl
-aXRoZXIgcmVhZC1vbmx5IG9yIHdyaXRlLW9ubHkuIERvbid0IHRoaW5rIHJlZ21hcCB3aWxsIGhl
-bHAsIHNvIEknbGwgCnJlbW92ZSB0aGUgInNlbGVjdCIgaGVyZS4KCj4+ICsgICAgZGVmYXVsdCBu
-Cj4KPiBOb3QgbmVjZXNzYXJ5Lgo+Cj4+ICsgICAgaGVscAo+PiArICAgICAgSWYgeW91IHNheSB5
-ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4g
-KyAgICAgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5h
-dGlvbiBvZiB2b2x0YWdlLAo+PiArICAgICAgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUgbW9uaXRv
-cmluZywgYnV0IHRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5Cj4+ICsgICAgICBzdXBwb3J0cyBy
-ZWFkaW5nIHR3byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbAo+PiB2b2x0
-YWdlcwo+PiArICAgICAgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+ICsKPj4gKyAgICAgIFRo
-aXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVs
-ZSB3aWxsCj4+ICsgICAgICBiZSBjYWxsZWQgbHRjMjk5MC4KPj4gKwo+PiAgIGNvbmZpZyBTRU5T
-T1JTX0xUQzQxNTEKPj4gICAgICAgdHJpc3RhdGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEi
-Cj4+ICAgICAgIGRlcGVuZHMgb24gSTJDCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01h
-a2VmaWxlIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBpbmRleCAxMmEzMjM5Li5lNGJkMTVi
-IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMv
-aHdtb24vTWFrZWZpbGUKPj4gQEAgLTEwMSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S
-U19MTTk1MjM0KSAgICArPSBsbTk1MjM0Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1
-MjQxKSAgICArPSBsbTk1MjQxLm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjQ1KSAg
-ICArPSBsbTk1MjQ1Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1KSAgICArPSBs
-dGMyOTQ1Lm8KPj4gK29iai0kKENPTkZJR19TRU5TT1JTX0xUQzI5OTApICAgICs9IGx0YzI5OTAu
-bwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpICAgICs9IGx0YzQxNTEubwo+PiAg
-IG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpICAgICs9IGx0YzQyMTUubwo+PiAgIG9iai0k
-KENPTkZJR19TRU5TT1JTX0xUQzQyMjIpICAgICs9IGx0YzQyMjIubwo+PiBkaWZmIC0tZ2l0IGEv
-ZHJpdmVycy9od21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+PiBuZXcg
-ZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwLi4xNjFkOTk1Cj4+IC0tLSAvZGV2L251
-bGwKPj4gKysrIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPj4gQEAgLTAsMCArMSwyNzMgQEAK
-Pj4gKy8qCj4+ICsgKiBkcml2ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIg
-bW9uaXRvcgo+Cj4gRHJpdmVyCj4KPj4gKyAqCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9w
-aWMgRW1iZWRkZWQgUHJvZHVjdHMKPgo+IDIwMTUgPwoKSSB3cm90ZSB0aGUgZHJpdmVyIGVhcmx5
-IGxhc3QgeWVhci4gSSBvbmx5IGRpZCBzb21lIGNvc21ldGljIGNsZWFudXAgYW5kIApyZWJhc2Ug
-b24gbWFzdGVyIGJlZm9yZSBzdWJtaXR0aW5nLgoKPgo+PiArICogQXV0aG9yOiBNaWtlIExvb2lq
-bWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4+ICsgKgo+PiArICogTGljZW5zZTogR1BM
-djIKPj4gKyAqCj4+ICsgKiBUaGlzIGRyaXZlciBhc3N1bWVzIHRoZSBjaGlwIGlzIHdpcmVkIGFz
-IGEgZHVhbCBjdXJyZW50IG1vbml0b3IsIGFuZAo+PiArICogcmVwb3J0cyB0aGUgdm9sdGFnZSBk
-cm9wIGFjcm9zcyB0d28gc2VyaWVzIHJlc2lzdG9ycy4KPgo+IEl0IGFsc28gbW9uaXRvcnMgdGhl
-IHRlbXBlcmF0dXJlIGFuZCBWQ0MuCj4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgv
-YnVnLmg+Cj4KPiBJcyB0aGlzIHVzZWQgYW55d2hlcmUgaW4gdGhlIGRyaXZlciA/CgpOb3QgYW55
-IG1vcmUuLi4KCj4KPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUgPGxp
-bnV4L2Vyci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLmg+Cj4+ICsjaW5jbHVkZSA8bGlu
-dXgvaHdtb24tc3lzZnMuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPj4gKyNpbmNsdWRl
-IDxsaW51eC9rZXJuZWwuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gKyNpbmNs
-dWRlIDxsaW51eC9zbGFiLmg+Cj4+ICsKPj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVMgICAgMHgw
-MAo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wgICAgMHgwMQo+PiArI2RlZmluZSBMVEMyOTkw
-X1RSSUdHRVIgICAgMHgwMgo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTVNCICAgIDB4MDQKPj4g
-KyNkZWZpbmUgTFRDMjk5MF9USU5UX0xTQiAgICAweDA1Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjFf
-TVNCICAgIDB4MDYKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMV9MU0IgICAgMHgwNwo+PiArI2RlZmlu
-ZSBMVEMyOTkwX1YyX01TQiAgICAweDA4Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjJfTFNCICAgIDB4
-MDkKPj4gKyNkZWZpbmUgTFRDMjk5MF9WM19NU0IgICAgMHgwQQo+PiArI2RlZmluZSBMVEMyOTkw
-X1YzX0xTQiAgICAweDBCCj4+ICsjZGVmaW5lIExUQzI5OTBfVjRfTVNCICAgIDB4MEMKPj4gKyNk
-ZWZpbmUgTFRDMjk5MF9WNF9MU0IgICAgMHgwRAo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19NU0Ig
-ICAgMHgwRQo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19MU0IgICAgMHgwRgo+PiArCj4+ICsjZGVm
-aW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RB
-VFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1YxICAgIEJJVCgy
-KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4gKyNkZWZpbmUgTFRD
-Mjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1Y0ICAg
-IEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklUKDYpCj4+ICsKPj4g
-Ky8qIE9ubHkgZGVmaW5lIGNvbnRyb2wgc2V0dGluZ3Mgd2UgYWN0dWFsbHkgdXNlICovCj4+ICsj
-ZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxWSU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBM
-VEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAgICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9D
-T05UUk9MX01FQVNVUkVfQUxMICAgICgweDMgPDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05U
-Uk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RF
-X1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICtzdHJ1Y3QgbHRjMjk5MF9kYXRhIHsKPj4gKyAgICBz
-dHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7Cj4+ICsgICAgc3RydWN0IG11dGV4IHVwZGF0ZV9sb2Nr
-Owo+PiArICAgIHVuc2lnbmVkIGxvbmcgbGFzdF91cGRhdGVkOwo+PiArICAgIHNob3J0IHZhbHVl
-c1s2XTsKPgo+IHUxNiA/Cj4KPj4gKyAgICBib29sIHZhbGlkOwo+PiArICAgIHU4IHVwZGF0ZV9j
-b3VudGVyOwo+Cj4gTm90IHVzZWQgYW55d2hlcmUuCj4KPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBp
-bnQgbHRjMjk5MF93cml0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4IHZhbHVl
-KQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgcmVn
-LCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX2J5dGUoc3Ry
-dWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnKQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21i
-dXNfcmVhZF9ieXRlX2RhdGEoaTJjLCByZWcpOwo+PiArfQo+PiArCj4KPiBVc2VsZXNzIHNoaW0g
-ZnVuY3Rpb25zLgoKVHJ1ZSwgc2hvdWxkIGhhdmUgcmVtb3ZlZCB0aGVtIGFmdGVyIHJlZmFjdG9y
-aW5nIHRoZW0gaW50byBvbmUtbGluZXJzLgpUaGV5IHdlcmUgY29udmVuaWVudCBlYXJseSBvbi4K
-Cj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX3dvcmQoc3RydWN0IGkyY19jbGllbnQgKmky
-YywgdTggcmVnKQo+PiArewo+PiArICAgIGludCByZXN1bHQgPSBpMmNfc21idXNfcmVhZF93b3Jk
-X2RhdGEoaTJjLCByZWcpOwo+PiArICAgIC8qIFJlc3VsdCBpcyBNU0IgZmlyc3QsIGJ1dCBzbWJ1
-cyBzcGVjcyBzYXkgTFNCIGZpcnN0LCBzbyBzd2FwIHRoZQo+PiArICAgICAqIHJlc3VsdCAqLwo+
-Cj4gQmFkIG11bHRpLWxpbmUgY29tbWVudC4KPgo+PiArICAgIHJldHVybiByZXN1bHQgPCAwID8g
-cmVzdWx0IDogc3dhYjE2KHJlc3VsdCk7Cj4KPiBQbGVhc2UgdXNlIGkyY19zbWJ1c19yZWFkX3dv
-cmRfc3dhcHBlZCgpIGFuZCBkcm9wIHRoZSBzaGltIGZ1bmN0aW9uLgo+Cj4+ICt9Cj4+ICsKPj4g
-K3N0YXRpYyBzdHJ1Y3QgbHRjMjk5MF9kYXRhICpsdGMyOTkwX3VwZGF0ZV9kZXZpY2Uoc3RydWN0
-IGRldmljZSAqZGV2KQo+PiArewo+PiArICAgIHN0cnVjdCBpMmNfY2xpZW50ICppMmMgPSB0b19p
-MmNfY2xpZW50KGRldik7Cj4+ICsgICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGkyY19n
-ZXRfY2xpZW50ZGF0YShpMmMpOwo+PiArICAgIHN0cnVjdCBsdGMyOTkwX2RhdGEgKnJldCA9IGRh
-dGE7Cj4+ICsgICAgdW5zaWduZWQgaW50IHRpbWVvdXQ7Cj4+ICsKPj4gKyAgICBtdXRleF9sb2Nr
-KCZkYXRhLT51cGRhdGVfbG9jayk7Cj4+ICsKPj4gKyAgICAvKiBVcGRhdGUgYWJvdXQgNCB0aW1l
-cyBwZXIgc2Vjb25kIG1heCAqLwo+PiArICAgIGlmICh0aW1lX2FmdGVyKGppZmZpZXMsIGRhdGEt
-Pmxhc3RfdXBkYXRlZCArIEhaIC8gNCkgfHwKPj4gIWRhdGEtPnZhbGlkKSB7Cj4+ICsgICAgICAg
-IGludCB2YWw7Cj4+ICsgICAgICAgIGludCBpOwo+PiArCj4KPiBQbGVhc2UgY29uc2lkZXIgdXNp
-bmcgY29udGludW91cyBjb252ZXJzaW9uLiBUaGlzIHdvdWxkIHNpbXBsaWZ5IHRoZQo+IGNvZGUg
-c2lnbmlmaWNhbnRseQo+IGFuZCByZWR1Y2UgcmVhZCBkZWxheXMuCgpJdCBtaWdodCBpbmNyZWFz
-ZSBwb3dlciBjb25zdW1wdGlvbiB0aG91Z2gsIGFzIHR5cGljYWxseSBzb21lIHVzZXIgCnByb2dy
-YW0gd291bGQgcG9sbCB0aGlzIGV2ZXJ5IDEwIHNlY29uZHMgb3Igc28uIEknbGwgY2hlY2sgdGhl
-IGRhdGEgc2hlZXQuCgo+PiArICAgICAgICAvKiBUcmlnZ2VyIEFEQywgYW55IHZhbHVlIHdpbGwg
-ZG8gKi8KPj4gKyAgICAgICAgdmFsID0gbHRjMjk5MF93cml0ZShpMmMsIExUQzI5OTBfVFJJR0dF
-UiwgMSk7Cj4+ICsgICAgICAgIGlmICh1bmxpa2VseSh2YWwgPCAwKSkgewo+PiArICAgICAgICAg
-ICAgcmV0ID0gRVJSX1BUUih2YWwpOwo+PiArICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAg
-ICAgICAgfQo+PiArCj4+ICsgICAgICAgIC8qIFdhaXQgZm9yIGNvbnZlcnNpb24gY29tcGxldGUg
-Ki8KPj4gKyAgICAgICAgdGltZW91dCA9IDIwMDsKPj4gKyAgICAgICAgZm9yICg7Oykgewo+PiAr
-ICAgICAgICAgICAgdXNsZWVwX3JhbmdlKDIwMDAsIDQwMDApOwo+PiArICAgICAgICAgICAgdmFs
-ID0gbHRjMjk5MF9yZWFkX2J5dGUoaTJjLCBMVEMyOTkwX1NUQVRVUyk7Cj4+ICsgICAgICAgICAg
-ICBpZiAodW5saWtlbHkodmFsIDwgMCkpIHsKPj4gKyAgICAgICAgICAgICAgICByZXQgPSBFUlJf
-UFRSKHZhbCk7Cj4+ICsgICAgICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAgICAgICAgICAg
-IH0KPj4gKyAgICAgICAgICAgIC8qIFNpbmdsZS1zaG90IG1vZGUsIHdhaXQgZm9yIGNvbnZlcnNp
-b24gdG8gY29tcGxldGUgKi8KPj4gKyAgICAgICAgICAgIGlmICgodmFsICYgTFRDMjk5MF9TVEFU
-VVNfQlVTWSkgPT0gMCkKPgo+ICAgICAgICAgICAgICBpZiAoISguLi4pKQo+Cj4+ICsgICAgICAg
-ICAgICAgICAgYnJlYWs7Cj4+ICsgICAgICAgICAgICBpZiAoLS10aW1lb3V0ID09IDApIHsKPj4g
-KyAgICAgICAgICAgICAgICByZXQgPSBFUlJfUFRSKC1FVElNRURPVVQpOwo+PiArICAgICAgICAg
-ICAgICAgIGdvdG8gYWJvcnQ7Cj4+ICsgICAgICAgICAgICB9Cj4+ICsgICAgICAgIH0KPgo+IEFn
-YWluLCBwbGVhc2UgY29uc2lkZXIgdXNpbmcgY29udGludW91cyBjb252ZXJzaW9uIG1vZGUuCj4K
-PiBJZiB0aGlzIGlzIG5vdCBmZWFzaWJsZSBmb3Igc29tZSByZWFzb24sIHlvdSBtaWdodCBhcyB3
-ZWxsIGp1c3Qgd2FpdCBmb3IKPiB0aGUKPiBtaW5pbXVtIGNvbnZlcnNpb24gdGltZSBiZWZvcmUg
-dHJ5aW5nIHRvIHJlYWQgZm9yIHRoZSBmaXJzdCB0aW1lLiBJZiBzbywKPiBwbGVhc2UgdXNlIGEg
-Zml4ZWQgdGltZW91dCBieSBjb21wYXJpbmcgdGhlIGVsYXBzZWQgdGltZSBpbnN0ZWFkIG9mIGxv
-b3BpbmcKPiBmb3IgYSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcy4gTm90IGV2ZW4gY291bnRpbmcg
-dGhlIHRpbWUgZm9yIGV4ZWN1dGluZyB0aGUKPiBjb2RlLCB0aGUgbWF4aW11bSBkZWxheSBpcyBi
-ZXR3ZWVuIDQwMCBtcyBhbmQgODAwIG1zLCB3aGljaCBpcyB3YXkgdG9vIGhpZ2gKPiAoY2hpcCBz
-cGVjIHNheXMgMTY3IG1zIHdvcnN0IGNhc2UsIGlmIHRocmVlIHRlbXBlcmF0dXJlIHNlbnNvcnMg
-YXJlCj4gY29uZmlndXJlZCkuCgpPciBtYXliZSBJIHNob3VsZCBqdXN0IHNsZWVwIGZvciAxNjdt
-cyBhbmQgYmUgZG9uZSB3aXRoIGl0LiBUaG91Z2ggSSAKdGhpbmsgSSdsIGdvdCB3aXRoIHlvdXIg
-bWluaW1hbCB0aW1lIGZpcnN0IHN1Z2dlc3Rpb24uCgo+PiArCj4+ICsgICAgICAgIC8qIFJlYWQg
-YWxsIHJlZ2lzdGVycyAqLwo+PiArICAgICAgICBmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShk
-YXRhLT52YWx1ZXMpOyArK2kpIHsKPj4gKyAgICAgICAgICAgIHZhbCA9IGx0YzI5OTBfcmVhZF93
-b3JkKGkyYywgKGk8PDEpICsgTFRDMjk5MF9USU5UX01TQik7Cj4KPiBNaXNzaW5nIHNwYWNlcyBh
-cm91bmQgPDwKPgo+PiArICAgICAgICAgICAgaWYgKHVubGlrZWx5KHZhbCA8IDApKSB7Cj4+ICsg
-ICAgICAgICAgICAgICAgZGV2X2RiZyhkZXYsCj4+ICsgICAgICAgICAgICAgICAgICAgICJGYWls
-ZWQgdG8gcmVhZCBBREMgdmFsdWU6IGVycm9yICVkXG4iLAo+PiArICAgICAgICAgICAgICAgICAg
-ICB2YWwpOwo+PiArICAgICAgICAgICAgICAgIHJldCA9IEVSUl9QVFIodmFsKTsKPj4gKyAgICAg
-ICAgICAgICAgICBnb3RvIGFib3J0Owo+PiArICAgICAgICAgICAgfQo+PiArICAgICAgICAgICAg
-ZGF0YS0+dmFsdWVzW2ldID0gdmFsICYgMHg3RkZGOyAvKiBTdHJpcCAnbmV3JyBiaXQgKi8KPgo+
-IFRoZSBiaXQgaXMgbmV2ZXIgZXZhbHVhdGVkLCBzbyB5b3UgbWlnaHQgYXMgd2VsbCBzdG9yZSB0
-aGUgcmF3IHZhbHVlLgo+Cj4+ICsgICAgICAgIH0KPj4gKyAgICAgICAgZGF0YS0+bGFzdF91cGRh
-dGVkID0gamlmZmllczsKPj4gKyAgICAgICAgZGF0YS0+dmFsaWQgPSAxOwo+Cj4gICAgICA9IHRy
-dWU7Cj4KPj4gKwo+PiArICAgICAgICAvKgo+PiArICAgICAgICAgKiAgUXVpcms6IFNlY29uZCB0
-cmlnZ2VyIGlzIGlnbm9yZWQ/IEFmdGVyIHRoaXMsIHRoZSBCVVNZIHdpbGwKPj4gKyAgICAgICAg
-ICogc3RpbGwgYmUgc2V0IHRvICIwIiBhbmQgbm8gY29udmVyc2lvbiBwZXJmb3JtZWQuCj4+ICsg
-ICAgICAgICAqLwo+PiArICAgICAgICB2YWwgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5MF9U
-UklHR0VSLCAwKTsKPj4gKyAgICB9Cj4+ICthYm9ydDoKPj4gKyAgICBtdXRleF91bmxvY2soJmRh
-dGEtPnVwZGF0ZV9sb2NrKTsKPj4gKyAgICByZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICsvKiBS
-ZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBmcm9tIHRoZSBnaXZlbiByZWdpc3RlciBpbiB1ViBv
-ciBtQyAqLwo+PiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgbHRjMjk5MF9k
-YXRhICpkYXRhLCB1OCBpbmRleCkKPj4gK3sKPj4gKyAgICBzMzIgcmVzdWx0Owo+PiArICAgIHMx
-NiB2Owo+PiArCj4+ICsgICAgaWYgKGluZGV4ID09IDApIHsgLyogaW50ZXJuYWwgdGVtcCwgMC4w
-NjI1IGRlZ3JlZXMvTFNCLCAxMi1iaXQgICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNb
-aW5kZXhdIDw8IDM7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDEwMDAgPj4gNzsKPj4g
-KyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkgeyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IsIDE0LWJp
-dCAqLwo+PiArICAgICAgICB2ID0gZGF0YS0+dmFsdWVzW2luZGV4XSA8PCAyOwo+Cj4gRGF0YXNo
-ZWV0IHNheXMgdGhhdCB0aGUgc2lnbiBiaXQgaXMgaW4gYml0IDE0LCBzbyB0aGlzIGRyb3BzIHRo
-ZSBzaWduIGJpdC4KCkknbGwgY2hlY2sgdGhlIGRhdGEgc2hlZXQsIHdvdWxkIG5vdCBoYXZlIG5v
-dGljZWQgdGhpcyBzaW5jZSBjdXJyZW50IApkb2Vzbid0IHRlbmQgdG8gcnVuIGZyb20gdGhlIENQ
-VSBiYWNrIGludG8gdGhlIGJhdHRlcnkgOikKCj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAq
-IDE5NDIgLyAoNCAqIDEwMCk7Cj4+ICsgICAgfSBlbHNlIHsgLyogVmNjLCAzMDUuMTjOvFYvTFNC
-LCAyLjVWIG9mZnNldCwgMTQtYml0ICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNbaW5k
-ZXhdIDw8IDI7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDMwNTE4IC8gKDQgKiAxMDAp
-Owo+PiArICAgICAgICByZXN1bHQgKz0gMjUwMDAwMDsKPj4gKyAgICB9Cj4+ICsgICAgcmV0dXJu
-IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl
-KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf
-YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2
-aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgc3Ry
-dWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGx0YzI5OTBfdXBkYXRlX2RldmljZShkZXYpOwo+PiAr
-ICAgIGludCB2YWx1ZTsKPj4gKwo+PiArICAgIGlmIChJU19FUlIoZGF0YSkpCj4+ICsgICAgICAg
-IHJldHVybiBQVFJfRVJSKGRhdGEpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92
-YWx1ZShkYXRhLCBhdHRyLT5pbmRleCk7Cj4+ICsgICAgcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFH
-RV9TSVpFLCAiJWRcbiIsIHZhbHVlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIFNFTlNPUl9ERVZJ
-Q0VfQVRUUih0ZW1wX2ludCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLAo+PiBOVUxMLCAw
-KTsKPj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodjF2Ml9kaWZmLCBTX0lSVUdPLCBsdGMy
-OTkwX3Nob3dfdmFsdWUsCj4+IE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU
-Uih2M3Y0X2RpZmYsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwKPj4gTlVMTCwgMyk7Cj4+
-ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHZjYywgU19JUlVHTywgbHRjMjk5MF9zaG93X3Zh
-bHVlLCBOVUxMLCA1KTsKPj4gKwo+Cj4gUGxlYXNlIHVzZSBzdGFuZGFyZCBhdHRyaWJ1dGUgbmFt
-ZXMgKGFuZCB1bml0cykgYXMgcGVyCj4gRG9jdW1lbnRhdGlvbi9od21vbi9zeXNmcy1pbnRlcmZh
-Y2UuCj4KPj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpsdGMyOTkwX2F0dHJpYnV0ZXNbXSA9
-IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3RlbXBfaW50LmRldl9hdHRyLmF0dHIsCj4+ICsg
-ICAgJnNlbnNvcl9kZXZfYXR0cl92MXYyX2RpZmYuZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vu
-c29yX2Rldl9hdHRyX3YzdjRfZGlmZi5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2
-X2F0dHJfdmNjLmRldl9hdHRyLmF0dHIsCj4+ICsgICAgTlVMTCwKPj4gK307Cj4+ICsKPj4gK3N0
-YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGx0YzI5OTBfZ3JvdXAgPSB7Cj4+ICsg
-ICAgLmF0dHJzID0gbHRjMjk5MF9hdHRyaWJ1dGVzLAo+PiArfTsKPj4gKwo+Cj4gUGxlYXNlIHVz
-ZSB0aGUgQVRUUklCVVRFX0dST1VQUygpIG1hY3JvLiBBbHNvIHNlZSBiZWxvdy4KCk9rYXksIHdp
-bGwgUlRGTS4KCj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9pMmNfcHJvYmUoCj4+ICsgICAgc3Ry
-dWN0IGkyY19jbGllbnQgKmkyYywgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+Cj4g
-UGxlYXNlIHNwbGl0IGFzCj4KPiBzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3Byb2JlKHN0cnVjdCBp
-MmNfY2xpZW50ICppMmMsCj4gICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGkyY19kZXZp
-Y2VfaWQgKmlkKQo+Cj4+ICt7Cj4+ICsgICAgaW50IHJldDsKPj4gKyAgICBzdHJ1Y3QgbHRjMjk5
-MF9kYXRhICpsdGMyOTkwOwo+PiArCj4+ICsgICAgaWYgKCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0
-eShpMmMtPmFkYXB0ZXIsCj4+IEkyQ19GVU5DX1NNQlVTX0JZVEVfREFUQSkpCj4+ICsgICAgICAg
-IHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgbHRjMjk5MCA9IGRldm1fa3phbGxvYygmaTJj
-LT5kZXYsCj4+ICsgICAgICAgIHNpemVvZihzdHJ1Y3QgbHRjMjk5MF9kYXRhKSwgR0ZQX0tFUk5F
-TCk7Cj4KPiBQbGVhc2UgYWxpZ24gY29udGludWF0aW9uIGxpbmVzIHdpdGggJygnLgo+Cj4+ICsg
-ICAgaWYgKGx0YzI5OTAgPT0gTlVMTCkKPj4gKyAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4+ICsK
-Pj4gKyAgICByZXQgPSBsdGMyOTkwX3JlYWRfYnl0ZShpMmMsIDApOwo+PiArICAgIGlmIChyZXQg
-PCAwKSB7Cj4+ICsgICAgICAgIGRldl9lcnIoJmkyYy0+ZGV2LCAiQ291bGQgbm90IHJlYWQgTFRD
-Mjk5MCBvbiBpMmMgYnVzLlxuIik7Cj4+ICsgICAgICAgIHJldHVybiByZXQ7Cj4+ICsgICAgfQo+
-Cj4gVGhlIHdyaXRlIGJlbG93IHdvdWxkIGFsc28gcmV0dXJuIGFuIGVycm9yIGlmIHRoZSBjaGlw
-IGlzbid0IHRoZXJlLAo+IHNvIHRoaXMgYWRkaXRpb25hbCByZWFkIGRvZXMgbm90IHByb3ZpZGUg
-YW55IHJlYWwgdmFsdWUuCj4KPj4gKyAgICByZXQgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5
-MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMyOTkwX0NPTlRST0xfU0lOR0xFIHwgTFRDMjk5MF9D
-T05UUk9MX01FQVNVUkVfQUxMIHwKPj4gKyAgICAgICAgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VS
-UkVOVCk7Cj4KPiBJJ2xsIGhhdmUgdG8gdGhpbmsgYWJvdXQgdGhpcy4gV2hpbGUgaXQgYWRkcmVz
-c2VzIHlvdXIgdXNlIGNhc2UsCj4gaXQgbGltaXRzIHRoZSBzY29wZSBvZiB0aGlzIGRyaXZlciBz
-aWduaWZpY2FudGx5LiBMb29raW5nIGludG8gdGhlIGJvYXJkCj4gc3BlY2lmaWNhdGlvbnMsIHlv
-dSBtaWdodCBhcyB3ZWxsIGRvIGl0IHJpZ2h0IGFuZCBkZXRlcm1pbmUgKGFuZCBzZXQpCj4gdGhl
-IGNvcnJlY3QgY29uZmlndXJhdGlvbiB1c2luZyBkZXZpY2V0cmVlIGRhdGEgaW5zdGVhZCBvZiBm
-b3JjaW5nIHlvdXIKPiB1c2UgY2FzZSBvbiBldmVyeW9uZS4KPgo+IFN1cmUsIHlvdSBtYXkgYXJn
-dWUgdGhhdCB5b3UgZG9uJ3QgY2FyZSwgYnV0IHdlIHdpbGwgYmUgdGhlIG9uZXMgd2hvCj4gd2ls
-bCBoYXZlCj4gdG8gaGFuZGxlIGVycm9yIHJlcG9ydHMgdGhhdCB0aGUgZHJpdmVyIHVuZXhwZWN0
-ZWRseSBjaGFuZ2VzIHRoZQo+IGNvbmZpZ3VyYXRpb24KPiBpbiBvdGhlciB1c2UgY2FzZXMgKHdo
-ZXJlLCBmb3IgZXhhbXBsZSwgdGhlIG1vZGUgbWF5IGhhdmUgYmVlbiBwcmUtc2V0IGJ5Cj4gdGhl
-IEJJT1Mgb3IgUk9NTU9OKS4KClRoZSByZWFzb24gSSBkaWRuJ3Qgc3VibWl0IHRoZSBkcml2ZXIg
-bGFzdCB5ZWFyIHdhcyB0aGF0IEkgd2FzIHN0aWxsIAp0aGlua2luZyBhYm91dCBpdC4gT24gdGhl
-IG90aGVyIGhhbmQsIGEgbGltaXRlZCBkcml2ZXIgaXMgc3RpbGwgbXVjaCAKYmV0dGVyIHRoYW4g
-bm8gZHJpdmVyIGF0IGFsbCwgc28gdGhhdCBtYWRlIG1lIHBvc3QgaXQsIHdpdGggdGhlIGFkZGVk
-IApyZW1hcmtzIGFib3V0IHRoZSBkcml2ZXIgYmVpbmcgbGltaXRlZC4KCkFkZGluZyB0aGUgb3Ro
-ZXIgZnVuY3Rpb25zIGl0IHF1aXRlIGEgYml0IG1vcmUgd29yayB0aGFuIGp1c3Qgd3JpdGluZyAK
-dGhpcyByZWdpc3Rlci4gSXQgYWxzbyBjaGFuZ2VzIHRoZSBwcm9wZXJ0aWVzIHRvIGJlIGV4cG9y
-dGVkIHRvIHN5c2ZzLCAKYW5kIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgZW5kIHZhbHVlcy4KCj4K
-Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy
-cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g
-cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIG11dGV4X2luaXQoJmx0YzI5OTAtPnVwZGF0ZV9s
-b2NrKTsKPj4gKyAgICBpMmNfc2V0X2NsaWVudGRhdGEoaTJjLCBsdGMyOTkwKTsKPj4gKwo+PiAr
-ICAgIC8qIFJlZ2lzdGVyIHN5c2ZzIGhvb2tzICovCj4+ICsgICAgcmV0ID0gc3lzZnNfY3JlYXRl
-X2dyb3VwKCZpMmMtPmRldi5rb2JqLCAmbHRjMjk5MF9ncm91cCk7Cj4+ICsgICAgaWYgKHJldCkK
-Pj4gKyAgICAgICAgcmV0dXJuIHJldDsKPj4gKwo+PiArICAgIGx0YzI5OTAtPmh3bW9uX2RldiA9
-IGh3bW9uX2RldmljZV9yZWdpc3RlcigmaTJjLT5kZXYpOwo+Cj4gUGxlYXNlIHVzZSBkZXZtX2h3
-bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgo+Cj4+ICsgICAgaWYgKElTX0VSUihs
-dGMyOTkwLT5od21vbl9kZXYpKSB7Cj4+ICsgICAgICAgIHJldCA9IFBUUl9FUlIobHRjMjk5MC0+
-aHdtb25fZGV2KTsKPj4gKyAgICAgICAgZ290byBvdXRfaHdtb25fZGV2aWNlX3JlZ2lzdGVyOwo+
-PiArICAgIH0KPj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArCj4+ICtvdXRfaHdtb25fZGV2aWNl
-X3JlZ2lzdGVyOgo+PiArICAgIHN5c2ZzX3JlbW92ZV9ncm91cCgmaTJjLT5kZXYua29iaiwgJmx0
-YzI5OTBfZ3JvdXApOwo+PiArICAgIHJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBp
-bnQgbHRjMjk5MF9pMmNfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMpCj4+ICt7Cj4+ICsg
-ICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqbHRjMjk5MCA9IGkyY19nZXRfY2xpZW50ZGF0YShpMmMp
-Owo+PiArCj4+ICsgICAgaHdtb25fZGV2aWNlX3VucmVnaXN0ZXIobHRjMjk5MC0+aHdtb25fZGV2
-KTsKPj4gKyAgICBzeXNmc19yZW1vdmVfZ3JvdXAoJmkyYy0+ZGV2LmtvYmosICZsdGMyOTkwX2dy
-b3VwKTsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVj
-dCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10gPSB7Cj4+ICsgICAgeyAibHRjMjk5MCIs
-IDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMy
-OTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2ky
-Y19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsKPj4gKyAgICAgICAgLm5hbWUgPSAibHRj
-Mjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUgICAgPSBsdGMyOTkwX2kyY19wcm9iZSwK
-Pj4gKyAgICAucmVtb3ZlICAgPSBsdGMyOTkwX2kyY19yZW1vdmUsCj4+ICsgICAgLmlkX3RhYmxl
-ID0gbHRjMjk5MF9pMmNfaWQsCj4+ICt9Owo+PiArCj4+ICttb2R1bGVfaTJjX2RyaXZlcihsdGMy
-OTkwX2kyY19kcml2ZXIpOwo+PiArCj4+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkxUQzI5OTAgU2Vu
-c29yIERyaXZlciIpOwo+PiArTU9EVUxFX0FVVEhPUigiVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMi
-KTsKPj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPj4KPgoKCi0tIApNaWtlIExvb2lqbWFu
-cwoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vu
-c29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMu
-bG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz
+Thank you very much for your review comments, I'll update the driver and 
+post a v2 patch.
+
+Inlined some replies below. Assume that I "will do" for all comments I 
+didn't comment on inline...
+
+On 06-01-16 16:22, Guenter Roeck wrote:
+> Hello Mike,
+>
+> On 01/06/2016 12:07 AM, Mike Looijmans wrote:
+>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
+>
+> s/  / /
+>
+>> The LTC2990 supports a combination of voltage, current and temperature
+>> monitoring, but this driver currently only supports reading two currents
+>> by measuring two differential voltages across series resistors.
+>>
+> Plus VCC, plus the internal temperature.
+
+Yeah, I should give myself more credit :) I'll add that in Kconfig too.
+
+>> This is sufficient to support the Topic Miami SOM which uses this chip
+>> to monitor the currents flowing into the FPGA and the CPU parts.
+>>
+>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
+>> ---
+>>   drivers/hwmon/Kconfig   |  15 +++
+>>   drivers/hwmon/Makefile  |   1 +
+>>   drivers/hwmon/ltc2990.c | 273
+>> ++++++++++++++++++++++++++++++++++++++++++++++++
+>
+> Please also provide Documentation/hwmon/ltc2990.
+>
+> Also, please read and follow Documentation/hwmon/submitting-patches.
+>
+>>   3 files changed, 289 insertions(+)
+>>   create mode 100644 drivers/hwmon/ltc2990.c
+>>
+>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+>> index 80a73bf..b3eef31 100644
+>> --- a/drivers/hwmon/Kconfig
+>> +++ b/drivers/hwmon/Kconfig
+>> @@ -685,6 +685,21 @@ config SENSORS_LTC2945
+>>         This driver can also be built as a module. If so, the module will
+>>         be called ltc2945.
+>>
+>> +config SENSORS_LTC2990
+>> +    tristate "Linear Technology LTC2990 (current monitoring mode only)"
+>> +    depends on I2C
+>> +    select REGMAP_I2C
+>
+> Using regmap for the driver might be a good idea, but you don't.
+
+Looking at the regmap, the driver only writes the one cachable register 
+once, the "control". All the other registers cannot be cached, are 
+either read-only or write-only. Don't think regmap will help, so I'll 
+remove the "select" here.
+
+>> +    default n
+>
+> Not necessary.
+>
+>> +    help
+>> +      If you say yes here you get support for Linear Technology LTC2990
+>> +      I2C System Monitor. The LTC2990 supports a combination of voltage,
+>> +      current and temperature monitoring, but this driver currently only
+>> +      supports reading two currents by measuring two differential
+>> voltages
+>> +      across series resistors.
+>> +
+>> +      This driver can also be built as a module. If so, the module will
+>> +      be called ltc2990.
+>> +
+>>   config SENSORS_LTC4151
+>>       tristate "Linear Technology LTC4151"
+>>       depends on I2C
+>> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+>> index 12a3239..e4bd15b 100644
+>> --- a/drivers/hwmon/Makefile
+>> +++ b/drivers/hwmon/Makefile
+>> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)    += lm95234.o
+>>   obj-$(CONFIG_SENSORS_LM95241)    += lm95241.o
+>>   obj-$(CONFIG_SENSORS_LM95245)    += lm95245.o
+>>   obj-$(CONFIG_SENSORS_LTC2945)    += ltc2945.o
+>> +obj-$(CONFIG_SENSORS_LTC2990)    += ltc2990.o
+>>   obj-$(CONFIG_SENSORS_LTC4151)    += ltc4151.o
+>>   obj-$(CONFIG_SENSORS_LTC4215)    += ltc4215.o
+>>   obj-$(CONFIG_SENSORS_LTC4222)    += ltc4222.o
+>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
+>> new file mode 100644
+>> index 0000000..161d995
+>> --- /dev/null
+>> +++ b/drivers/hwmon/ltc2990.c
+>> @@ -0,0 +1,273 @@
+>> +/*
+>> + * driver for Linear Technology LTC2990 power monitor
+>
+> Driver
+>
+>> + *
+>> + * Copyright (C) 2014 Topic Embedded Products
+>
+> 2015 ?
+
+I wrote the driver early last year. I only did some cosmetic cleanup and 
+rebase on master before submitting.
+
+>
+>> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
+>> + *
+>> + * License: GPLv2
+>> + *
+>> + * This driver assumes the chip is wired as a dual current monitor, and
+>> + * reports the voltage drop across two series resistors.
+>
+> It also monitors the temperature and VCC.
+>
+>> + */
+>> +
+>> +#include <linux/bug.h>
+>
+> Is this used anywhere in the driver ?
+
+Not any more...
+
+>
+>> +#include <linux/delay.h>
+>> +#include <linux/err.h>
+>> +#include <linux/hwmon.h>
+>> +#include <linux/hwmon-sysfs.h>
+>> +#include <linux/i2c.h>
+>> +#include <linux/kernel.h>
+>> +#include <linux/module.h>
+>> +#include <linux/slab.h>
+>> +
+>> +#define LTC2990_STATUS    0x00
+>> +#define LTC2990_CONTROL    0x01
+>> +#define LTC2990_TRIGGER    0x02
+>> +#define LTC2990_TINT_MSB    0x04
+>> +#define LTC2990_TINT_LSB    0x05
+>> +#define LTC2990_V1_MSB    0x06
+>> +#define LTC2990_V1_LSB    0x07
+>> +#define LTC2990_V2_MSB    0x08
+>> +#define LTC2990_V2_LSB    0x09
+>> +#define LTC2990_V3_MSB    0x0A
+>> +#define LTC2990_V3_LSB    0x0B
+>> +#define LTC2990_V4_MSB    0x0C
+>> +#define LTC2990_V4_LSB    0x0D
+>> +#define LTC2990_VCC_MSB    0x0E
+>> +#define LTC2990_VCC_LSB    0x0F
+>> +
+>> +#define LTC2990_STATUS_BUSY    BIT(0)
+>> +#define LTC2990_STATUS_TINT    BIT(1)
+>> +#define LTC2990_STATUS_V1    BIT(2)
+>> +#define LTC2990_STATUS_V2    BIT(3)
+>> +#define LTC2990_STATUS_V3    BIT(4)
+>> +#define LTC2990_STATUS_V4    BIT(5)
+>> +#define LTC2990_STATUS_VCC    BIT(6)
+>> +
+>> +/* Only define control settings we actually use */
+>> +#define LTC2990_CONTROL_KELVIN        BIT(7)
+>> +#define LTC2990_CONTROL_SINGLE        BIT(6)
+>> +#define LTC2990_CONTROL_MEASURE_ALL    (0x3 << 3)
+>> +#define LTC2990_CONTROL_MODE_CURRENT    0x06
+>> +#define LTC2990_CONTROL_MODE_VOLTAGE    0x07
+>> +
+>> +struct ltc2990_data {
+>> +    struct device *hwmon_dev;
+>> +    struct mutex update_lock;
+>> +    unsigned long last_updated;
+>> +    short values[6];
+>
+> u16 ?
+>
+>> +    bool valid;
+>> +    u8 update_counter;
+>
+> Not used anywhere.
+>
+>> +};
+>> +
+>> +static int ltc2990_write(struct i2c_client *i2c, u8 reg, u8 value)
+>> +{
+>> +    return i2c_smbus_write_byte_data(i2c, reg, value);
+>> +}
+>> +
+>> +static int ltc2990_read_byte(struct i2c_client *i2c, u8 reg)
+>> +{
+>> +    return i2c_smbus_read_byte_data(i2c, reg);
+>> +}
+>> +
+>
+> Useless shim functions.
+
+True, should have removed them after refactoring them into one-liners.
+They were convenient early on.
+
+>
+>> +static int ltc2990_read_word(struct i2c_client *i2c, u8 reg)
+>> +{
+>> +    int result = i2c_smbus_read_word_data(i2c, reg);
+>> +    /* Result is MSB first, but smbus specs say LSB first, so swap the
+>> +     * result */
+>
+> Bad multi-line comment.
+>
+>> +    return result < 0 ? result : swab16(result);
+>
+> Please use i2c_smbus_read_word_swapped() and drop the shim function.
+>
+>> +}
+>> +
+>> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
+>> +{
+>> +    struct i2c_client *i2c = to_i2c_client(dev);
+>> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);
+>> +    struct ltc2990_data *ret = data;
+>> +    unsigned int timeout;
+>> +
+>> +    mutex_lock(&data->update_lock);
+>> +
+>> +    /* Update about 4 times per second max */
+>> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||
+>> !data->valid) {
+>> +        int val;
+>> +        int i;
+>> +
+>
+> Please consider using continuous conversion. This would simplify the
+> code significantly
+> and reduce read delays.
+
+It might increase power consumption though, as typically some user 
+program would poll this every 10 seconds or so. I'll check the data sheet.
+
+>> +        /* Trigger ADC, any value will do */
+>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
+>> +        if (unlikely(val < 0)) {
+>> +            ret = ERR_PTR(val);
+>> +            goto abort;
+>> +        }
+>> +
+>> +        /* Wait for conversion complete */
+>> +        timeout = 200;
+>> +        for (;;) {
+>> +            usleep_range(2000, 4000);
+>> +            val = ltc2990_read_byte(i2c, LTC2990_STATUS);
+>> +            if (unlikely(val < 0)) {
+>> +                ret = ERR_PTR(val);
+>> +                goto abort;
+>> +            }
+>> +            /* Single-shot mode, wait for conversion to complete */
+>> +            if ((val & LTC2990_STATUS_BUSY) == 0)
+>
+>              if (!(...))
+>
+>> +                break;
+>> +            if (--timeout == 0) {
+>> +                ret = ERR_PTR(-ETIMEDOUT);
+>> +                goto abort;
+>> +            }
+>> +        }
+>
+> Again, please consider using continuous conversion mode.
+>
+> If this is not feasible for some reason, you might as well just wait for
+> the
+> minimum conversion time before trying to read for the first time. If so,
+> please use a fixed timeout by comparing the elapsed time instead of looping
+> for a maximum number of times. Not even counting the time for executing the
+> code, the maximum delay is between 400 ms and 800 ms, which is way too high
+> (chip spec says 167 ms worst case, if three temperature sensors are
+> configured).
+
+Or maybe I should just sleep for 167ms and be done with it. Though I 
+think I'l got with your minimal time first suggestion.
+
+>> +
+>> +        /* Read all registers */
+>> +        for (i = 0; i < ARRAY_SIZE(data->values); ++i) {
+>> +            val = ltc2990_read_word(i2c, (i<<1) + LTC2990_TINT_MSB);
+>
+> Missing spaces around <<
+>
+>> +            if (unlikely(val < 0)) {
+>> +                dev_dbg(dev,
+>> +                    "Failed to read ADC value: error %d\n",
+>> +                    val);
+>> +                ret = ERR_PTR(val);
+>> +                goto abort;
+>> +            }
+>> +            data->values[i] = val & 0x7FFF; /* Strip 'new' bit */
+>
+> The bit is never evaluated, so you might as well store the raw value.
+>
+>> +        }
+>> +        data->last_updated = jiffies;
+>> +        data->valid = 1;
+>
+>      = true;
+>
+>> +
+>> +        /*
+>> +         *  Quirk: Second trigger is ignored? After this, the BUSY will
+>> +         * still be set to "0" and no conversion performed.
+>> +         */
+>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 0);
+>> +    }
+>> +abort:
+>> +    mutex_unlock(&data->update_lock);
+>> +    return ret;
+>> +}
+>> +
+>> +/* Return the converted value from the given register in uV or mC */
+>> +static int ltc2990_get_value(struct ltc2990_data *data, u8 index)
+>> +{
+>> +    s32 result;
+>> +    s16 v;
+>> +
+>> +    if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 12-bit  */
+>> +        v = data->values[index] << 3;
+>> +        result = (s32)v * 1000 >> 7;
+>> +    } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB, 14-bit */
+>> +        v = data->values[index] << 2;
+>
+> Datasheet says that the sign bit is in bit 14, so this drops the sign bit.
+
+I'll check the data sheet, would not have noticed this since current 
+doesn't tend to run from the CPU back into the battery :)
+
+>> +        result = (s32)v * 1942 / (4 * 100);
+>> +    } else { /* Vcc, 305.18μV/LSB, 2.5V offset, 14-bit */
+>> +        v = data->values[index] << 2;
+>> +        result = (s32)v * 30518 / (4 * 100);
+>> +        result += 2500000;
+>> +    }
+>> +    return result;
+>> +}
+>> +
+>> +static ssize_t ltc2990_show_value(struct device *dev,
+>> +                  struct device_attribute *da, char *buf)
+>> +{
+>> +    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+>> +    struct ltc2990_data *data = ltc2990_update_device(dev);
+>> +    int value;
+>> +
+>> +    if (IS_ERR(data))
+>> +        return PTR_ERR(data);
+>> +
+>> +    value = ltc2990_get_value(data, attr->index);
+>> +    return snprintf(buf, PAGE_SIZE, "%d\n", value);
+>> +}
+>> +
+>> +static SENSOR_DEVICE_ATTR(temp_int, S_IRUGO, ltc2990_show_value,
+>> NULL, 0);
+>> +static SENSOR_DEVICE_ATTR(v1v2_diff, S_IRUGO, ltc2990_show_value,
+>> NULL, 1);
+>> +static SENSOR_DEVICE_ATTR(v3v4_diff, S_IRUGO, ltc2990_show_value,
+>> NULL, 3);
+>> +static SENSOR_DEVICE_ATTR(vcc, S_IRUGO, ltc2990_show_value, NULL, 5);
+>> +
+>
+> Please use standard attribute names (and units) as per
+> Documentation/hwmon/sysfs-interface.
+>
+>> +static struct attribute *ltc2990_attributes[] = {
+>> +    &sensor_dev_attr_temp_int.dev_attr.attr,
+>> +    &sensor_dev_attr_v1v2_diff.dev_attr.attr,
+>> +    &sensor_dev_attr_v3v4_diff.dev_attr.attr,
+>> +    &sensor_dev_attr_vcc.dev_attr.attr,
+>> +    NULL,
+>> +};
+>> +
+>> +static const struct attribute_group ltc2990_group = {
+>> +    .attrs = ltc2990_attributes,
+>> +};
+>> +
+>
+> Please use the ATTRIBUTE_GROUPS() macro. Also see below.
+
+Okay, will RTFM.
+
+>
+>> +static int ltc2990_i2c_probe(
+>> +    struct i2c_client *i2c, const struct i2c_device_id *id)
+>
+> Please split as
+>
+> static int ltc2990_i2c_probe(struct i2c_client *i2c,
+>                   const struct i2c_device_id *id)
+>
+>> +{
+>> +    int ret;
+>> +    struct ltc2990_data *ltc2990;
+>> +
+>> +    if (!i2c_check_functionality(i2c->adapter,
+>> I2C_FUNC_SMBUS_BYTE_DATA))
+>> +        return -ENODEV;
+>> +
+>> +    ltc2990 = devm_kzalloc(&i2c->dev,
+>> +        sizeof(struct ltc2990_data), GFP_KERNEL);
+>
+> Please align continuation lines with '('.
+>
+>> +    if (ltc2990 == NULL)
+>> +        return -ENOMEM;
+>> +
+>> +    ret = ltc2990_read_byte(i2c, 0);
+>> +    if (ret < 0) {
+>> +        dev_err(&i2c->dev, "Could not read LTC2990 on i2c bus.\n");
+>> +        return ret;
+>> +    }
+>
+> The write below would also return an error if the chip isn't there,
+> so this additional read does not provide any real value.
+>
+>> +    ret = ltc2990_write(i2c, LTC2990_CONTROL,
+>> +        LTC2990_CONTROL_SINGLE | LTC2990_CONTROL_MEASURE_ALL |
+>> +        LTC2990_CONTROL_MODE_CURRENT);
+>
+> I'll have to think about this. While it addresses your use case,
+> it limits the scope of this driver significantly. Looking into the board
+> specifications, you might as well do it right and determine (and set)
+> the correct configuration using devicetree data instead of forcing your
+> use case on everyone.
+>
+> Sure, you may argue that you don't care, but we will be the ones who
+> will have
+> to handle error reports that the driver unexpectedly changes the
+> configuration
+> in other use cases (where, for example, the mode may have been pre-set by
+> the BIOS or ROMMON).
+
+The reason I didn't submit the driver last year was that I was still 
+thinking about it. On the other hand, a limited driver is still much 
+better than no driver at all, so that made me post it, with the added 
+remarks about the driver being limited.
+
+Adding the other functions it quite a bit more work than just writing 
+this register. It also changes the properties to be exported to sysfs, 
+and the calculation of the end values.
+
+>
+>> +    if (ret < 0) {
+>> +        dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
+>> +        return ret;
+>> +    }
+>> +
+>> +    mutex_init(&ltc2990->update_lock);
+>> +    i2c_set_clientdata(i2c, ltc2990);
+>> +
+>> +    /* Register sysfs hooks */
+>> +    ret = sysfs_create_group(&i2c->dev.kobj, &ltc2990_group);
+>> +    if (ret)
+>> +        return ret;
+>> +
+>> +    ltc2990->hwmon_dev = hwmon_device_register(&i2c->dev);
+>
+> Please use devm_hwmon_device_register_with_groups().
+>
+>> +    if (IS_ERR(ltc2990->hwmon_dev)) {
+>> +        ret = PTR_ERR(ltc2990->hwmon_dev);
+>> +        goto out_hwmon_device_register;
+>> +    }
+>> +
+>> +    return 0;
+>> +
+>> +out_hwmon_device_register:
+>> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
+>> +    return ret;
+>> +}
+>> +
+>> +static int ltc2990_i2c_remove(struct i2c_client *i2c)
+>> +{
+>> +    struct ltc2990_data *ltc2990 = i2c_get_clientdata(i2c);
+>> +
+>> +    hwmon_device_unregister(ltc2990->hwmon_dev);
+>> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
+>> +    return 0;
+>> +}
+>> +
+>> +static const struct i2c_device_id ltc2990_i2c_id[] = {
+>> +    { "ltc2990", 0 },
+>> +    {}
+>> +};
+>> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
+>> +
+>> +static struct i2c_driver ltc2990_i2c_driver = {
+>> +    .driver = {
+>> +        .name = "ltc2990",
+>> +    },
+>> +    .probe    = ltc2990_i2c_probe,
+>> +    .remove   = ltc2990_i2c_remove,
+>> +    .id_table = ltc2990_i2c_id,
+>> +};
+>> +
+>> +module_i2c_driver(ltc2990_i2c_driver);
+>> +
+>> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
+>> +MODULE_AUTHOR("Topic Embedded Products");
+>> +MODULE_LICENSE("GPL v2");
+>>
+>
+
+
+-- 
+Mike Looijmans
diff --git a/a/content_digest b/N1/content_digest
index fdf3626..a73dd89 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,296 +1,521 @@
  "ref\01452067627-24939-1-git-send-email-mike.looijmans@topic.nl\0"
  "ref\0568D3127.5090901@roeck-us.net\0"
  "From\0Mike Looijmans <mike.looijmans@topic.nl>\0"
- "Subject\0Re: [lm-sensors] [PATCH] hwmon: Add LTC2990 sensor driver\0"
- "Date\0Thu, 07 Jan 2016 18:59:24 +0000\0"
+ "Subject\0Re: [PATCH] hwmon: Add LTC2990 sensor driver\0"
+ "Date\0Thu, 7 Jan 2016 19:59:24 +0100\0"
  "To\0Guenter Roeck <linux@roeck-us.net>"
  " lm-sensors@lm-sensors.org\0"
  "Cc\0jdelvare@suse.com"
  " linux-kernel@vger.kernel.org\0"
  "\00:1\0"
  "b\0"
- "VGhhbmsgeW91IHZlcnkgbXVjaCBmb3IgeW91ciByZXZpZXcgY29tbWVudHMsIEknbGwgdXBkYXRl\n"
- "IHRoZSBkcml2ZXIgYW5kIApwb3N0IGEgdjIgcGF0Y2guCgpJbmxpbmVkIHNvbWUgcmVwbGllcyBi\n"
- "ZWxvdy4gQXNzdW1lIHRoYXQgSSAid2lsbCBkbyIgZm9yIGFsbCBjb21tZW50cyBJIApkaWRuJ3Qg\n"
- "Y29tbWVudCBvbiBpbmxpbmUuLi4KCk9uIDA2LTAxLTE2IDE2OjIyLCBHdWVudGVyIFJvZWNrIHdy\n"
- "b3RlOgo+IEhlbGxvIE1pa2UsCj4KPiBPbiAwMS8wNi8yMDE2IDEyOjA3IEFNLCBNaWtlIExvb2lq\n"
- "bWFucyB3cm90ZToKPj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9n\n"
- "eSBMVEMyOTkwICBJMkMgU3lzdGVtIE1vbml0b3IuCj4KPiBzLyAgLyAvCj4KPj4gVGhlIExUQzI5\n"
- "OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBjdXJyZW50IGFuZCB0ZW1wZXJh\n"
- "dHVyZQo+PiBtb25pdG9yaW5nLCBidXQgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9y\n"
- "dHMgcmVhZGluZyB0d28gY3VycmVudHMKPj4gYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwg\n"
- "dm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+Cj4gUGx1cyBWQ0MsIHBsdXMgdGhl\n"
- "IGludGVybmFsIHRlbXBlcmF0dXJlLgoKWWVhaCwgSSBzaG91bGQgZ2l2ZSBteXNlbGYgbW9yZSBj\n"
- "cmVkaXQgOikgSSdsbCBhZGQgdGhhdCBpbiBLY29uZmlnIHRvby4KCj4+IFRoaXMgaXMgc3VmZmlj\n"
- "aWVudCB0byBzdXBwb3J0IHRoZSBUb3BpYyBNaWFtaSBTT00gd2hpY2ggdXNlcyB0aGlzIGNoaXAK\n"
- "Pj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRoZSBGUEdBIGFuZCB0aGUg\n"
- "Q1BVIHBhcnRzLgo+Pgo+PiBTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29p\n"
- "am1hbnNAdG9waWMubmw+Cj4+IC0tLQo+PiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgIHwgIDE1\n"
- "ICsrKwo+PiAgIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3\n"
- "bW9uL2x0YzI5OTAuYyB8IDI3Mwo+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr\n"
- "KysrKysrKysrKysrKysKPgo+IFBsZWFzZSBhbHNvIHByb3ZpZGUgRG9jdW1lbnRhdGlvbi9od21v\n"
- "bi9sdGMyOTkwLgo+Cj4gQWxzbywgcGxlYXNlIHJlYWQgYW5kIGZvbGxvdyBEb2N1bWVudGF0aW9u\n"
- "L2h3bW9uL3N1Ym1pdHRpbmctcGF0Y2hlcy4KPgo+PiAgIDMgZmlsZXMgY2hhbmdlZCwgMjg5IGlu\n"
- "c2VydGlvbnMoKykKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9od21vbi9sdGMyOTkw\n"
- "LmMKPj4KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt\n"
- "b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi5iM2VlZjMxIDEwMDY0NAo+PiAtLS0gYS9kcml2\n"
- "ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02\n"
- "ODUsNiArNjg1LDIxIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy\n"
- "aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls\n"
- "bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD\n"
- "Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50\n"
- "IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIHNl\n"
- "bGVjdCBSRUdNQVBfSTJDCj4KPiBVc2luZyByZWdtYXAgZm9yIHRoZSBkcml2ZXIgbWlnaHQgYmUg\n"
- "YSBnb29kIGlkZWEsIGJ1dCB5b3UgZG9uJ3QuCgpMb29raW5nIGF0IHRoZSByZWdtYXAsIHRoZSBk\n"
- "cml2ZXIgb25seSB3cml0ZXMgdGhlIG9uZSBjYWNoYWJsZSByZWdpc3RlciAKb25jZSwgdGhlICJj\n"
- "b250cm9sIi4gQWxsIHRoZSBvdGhlciByZWdpc3RlcnMgY2Fubm90IGJlIGNhY2hlZCwgYXJlIApl\n"
- "aXRoZXIgcmVhZC1vbmx5IG9yIHdyaXRlLW9ubHkuIERvbid0IHRoaW5rIHJlZ21hcCB3aWxsIGhl\n"
- "bHAsIHNvIEknbGwgCnJlbW92ZSB0aGUgInNlbGVjdCIgaGVyZS4KCj4+ICsgICAgZGVmYXVsdCBu\n"
- "Cj4KPiBOb3QgbmVjZXNzYXJ5Lgo+Cj4+ICsgICAgaGVscAo+PiArICAgICAgSWYgeW91IHNheSB5\n"
- "ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4g\n"
- "KyAgICAgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5h\n"
- "dGlvbiBvZiB2b2x0YWdlLAo+PiArICAgICAgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUgbW9uaXRv\n"
- "cmluZywgYnV0IHRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5Cj4+ICsgICAgICBzdXBwb3J0cyBy\n"
- "ZWFkaW5nIHR3byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbAo+PiB2b2x0\n"
- "YWdlcwo+PiArICAgICAgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+ICsKPj4gKyAgICAgIFRo\n"
- "aXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVs\n"
- "ZSB3aWxsCj4+ICsgICAgICBiZSBjYWxsZWQgbHRjMjk5MC4KPj4gKwo+PiAgIGNvbmZpZyBTRU5T\n"
- "T1JTX0xUQzQxNTEKPj4gICAgICAgdHJpc3RhdGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEi\n"
- "Cj4+ICAgICAgIGRlcGVuZHMgb24gSTJDCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01h\n"
- "a2VmaWxlIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBpbmRleCAxMmEzMjM5Li5lNGJkMTVi\n"
- "IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMv\n"
- "aHdtb24vTWFrZWZpbGUKPj4gQEAgLTEwMSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S\n"
- "U19MTTk1MjM0KSAgICArPSBsbTk1MjM0Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1\n"
- "MjQxKSAgICArPSBsbTk1MjQxLm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjQ1KSAg\n"
- "ICArPSBsbTk1MjQ1Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1KSAgICArPSBs\n"
- "dGMyOTQ1Lm8KPj4gK29iai0kKENPTkZJR19TRU5TT1JTX0xUQzI5OTApICAgICs9IGx0YzI5OTAu\n"
- "bwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpICAgICs9IGx0YzQxNTEubwo+PiAg\n"
- "IG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpICAgICs9IGx0YzQyMTUubwo+PiAgIG9iai0k\n"
- "KENPTkZJR19TRU5TT1JTX0xUQzQyMjIpICAgICs9IGx0YzQyMjIubwo+PiBkaWZmIC0tZ2l0IGEv\n"
- "ZHJpdmVycy9od21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+PiBuZXcg\n"
- "ZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwLi4xNjFkOTk1Cj4+IC0tLSAvZGV2L251\n"
- "bGwKPj4gKysrIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPj4gQEAgLTAsMCArMSwyNzMgQEAK\n"
- "Pj4gKy8qCj4+ICsgKiBkcml2ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIg\n"
- "bW9uaXRvcgo+Cj4gRHJpdmVyCj4KPj4gKyAqCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9w\n"
- "aWMgRW1iZWRkZWQgUHJvZHVjdHMKPgo+IDIwMTUgPwoKSSB3cm90ZSB0aGUgZHJpdmVyIGVhcmx5\n"
- "IGxhc3QgeWVhci4gSSBvbmx5IGRpZCBzb21lIGNvc21ldGljIGNsZWFudXAgYW5kIApyZWJhc2Ug\n"
- "b24gbWFzdGVyIGJlZm9yZSBzdWJtaXR0aW5nLgoKPgo+PiArICogQXV0aG9yOiBNaWtlIExvb2lq\n"
- "bWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4+ICsgKgo+PiArICogTGljZW5zZTogR1BM\n"
- "djIKPj4gKyAqCj4+ICsgKiBUaGlzIGRyaXZlciBhc3N1bWVzIHRoZSBjaGlwIGlzIHdpcmVkIGFz\n"
- "IGEgZHVhbCBjdXJyZW50IG1vbml0b3IsIGFuZAo+PiArICogcmVwb3J0cyB0aGUgdm9sdGFnZSBk\n"
- "cm9wIGFjcm9zcyB0d28gc2VyaWVzIHJlc2lzdG9ycy4KPgo+IEl0IGFsc28gbW9uaXRvcnMgdGhl\n"
- "IHRlbXBlcmF0dXJlIGFuZCBWQ0MuCj4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgv\n"
- "YnVnLmg+Cj4KPiBJcyB0aGlzIHVzZWQgYW55d2hlcmUgaW4gdGhlIGRyaXZlciA/CgpOb3QgYW55\n"
- "IG1vcmUuLi4KCj4KPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUgPGxp\n"
- "bnV4L2Vyci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLmg+Cj4+ICsjaW5jbHVkZSA8bGlu\n"
- "dXgvaHdtb24tc3lzZnMuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPj4gKyNpbmNsdWRl\n"
- "IDxsaW51eC9rZXJuZWwuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gKyNpbmNs\n"
- "dWRlIDxsaW51eC9zbGFiLmg+Cj4+ICsKPj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVMgICAgMHgw\n"
- "MAo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wgICAgMHgwMQo+PiArI2RlZmluZSBMVEMyOTkw\n"
- "X1RSSUdHRVIgICAgMHgwMgo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTVNCICAgIDB4MDQKPj4g\n"
- "KyNkZWZpbmUgTFRDMjk5MF9USU5UX0xTQiAgICAweDA1Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjFf\n"
- "TVNCICAgIDB4MDYKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMV9MU0IgICAgMHgwNwo+PiArI2RlZmlu\n"
- "ZSBMVEMyOTkwX1YyX01TQiAgICAweDA4Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjJfTFNCICAgIDB4\n"
- "MDkKPj4gKyNkZWZpbmUgTFRDMjk5MF9WM19NU0IgICAgMHgwQQo+PiArI2RlZmluZSBMVEMyOTkw\n"
- "X1YzX0xTQiAgICAweDBCCj4+ICsjZGVmaW5lIExUQzI5OTBfVjRfTVNCICAgIDB4MEMKPj4gKyNk\n"
- "ZWZpbmUgTFRDMjk5MF9WNF9MU0IgICAgMHgwRAo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19NU0Ig\n"
- "ICAgMHgwRQo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19MU0IgICAgMHgwRgo+PiArCj4+ICsjZGVm\n"
- "aW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RB\n"
- "VFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1YxICAgIEJJVCgy\n"
- "KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4gKyNkZWZpbmUgTFRD\n"
- "Mjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1Y0ICAg\n"
- "IEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklUKDYpCj4+ICsKPj4g\n"
- "Ky8qIE9ubHkgZGVmaW5lIGNvbnRyb2wgc2V0dGluZ3Mgd2UgYWN0dWFsbHkgdXNlICovCj4+ICsj\n"
- "ZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxWSU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBM\n"
- "VEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAgICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9D\n"
- "T05UUk9MX01FQVNVUkVfQUxMICAgICgweDMgPDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05U\n"
- "Uk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RF\n"
- "X1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICtzdHJ1Y3QgbHRjMjk5MF9kYXRhIHsKPj4gKyAgICBz\n"
- "dHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7Cj4+ICsgICAgc3RydWN0IG11dGV4IHVwZGF0ZV9sb2Nr\n"
- "Owo+PiArICAgIHVuc2lnbmVkIGxvbmcgbGFzdF91cGRhdGVkOwo+PiArICAgIHNob3J0IHZhbHVl\n"
- "c1s2XTsKPgo+IHUxNiA/Cj4KPj4gKyAgICBib29sIHZhbGlkOwo+PiArICAgIHU4IHVwZGF0ZV9j\n"
- "b3VudGVyOwo+Cj4gTm90IHVzZWQgYW55d2hlcmUuCj4KPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBp\n"
- "bnQgbHRjMjk5MF93cml0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4IHZhbHVl\n"
- "KQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgcmVn\n"
- "LCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX2J5dGUoc3Ry\n"
- "dWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnKQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21i\n"
- "dXNfcmVhZF9ieXRlX2RhdGEoaTJjLCByZWcpOwo+PiArfQo+PiArCj4KPiBVc2VsZXNzIHNoaW0g\n"
- "ZnVuY3Rpb25zLgoKVHJ1ZSwgc2hvdWxkIGhhdmUgcmVtb3ZlZCB0aGVtIGFmdGVyIHJlZmFjdG9y\n"
- "aW5nIHRoZW0gaW50byBvbmUtbGluZXJzLgpUaGV5IHdlcmUgY29udmVuaWVudCBlYXJseSBvbi4K\n"
- "Cj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX3dvcmQoc3RydWN0IGkyY19jbGllbnQgKmky\n"
- "YywgdTggcmVnKQo+PiArewo+PiArICAgIGludCByZXN1bHQgPSBpMmNfc21idXNfcmVhZF93b3Jk\n"
- "X2RhdGEoaTJjLCByZWcpOwo+PiArICAgIC8qIFJlc3VsdCBpcyBNU0IgZmlyc3QsIGJ1dCBzbWJ1\n"
- "cyBzcGVjcyBzYXkgTFNCIGZpcnN0LCBzbyBzd2FwIHRoZQo+PiArICAgICAqIHJlc3VsdCAqLwo+\n"
- "Cj4gQmFkIG11bHRpLWxpbmUgY29tbWVudC4KPgo+PiArICAgIHJldHVybiByZXN1bHQgPCAwID8g\n"
- "cmVzdWx0IDogc3dhYjE2KHJlc3VsdCk7Cj4KPiBQbGVhc2UgdXNlIGkyY19zbWJ1c19yZWFkX3dv\n"
- "cmRfc3dhcHBlZCgpIGFuZCBkcm9wIHRoZSBzaGltIGZ1bmN0aW9uLgo+Cj4+ICt9Cj4+ICsKPj4g\n"
- "K3N0YXRpYyBzdHJ1Y3QgbHRjMjk5MF9kYXRhICpsdGMyOTkwX3VwZGF0ZV9kZXZpY2Uoc3RydWN0\n"
- "IGRldmljZSAqZGV2KQo+PiArewo+PiArICAgIHN0cnVjdCBpMmNfY2xpZW50ICppMmMgPSB0b19p\n"
- "MmNfY2xpZW50KGRldik7Cj4+ICsgICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGkyY19n\n"
- "ZXRfY2xpZW50ZGF0YShpMmMpOwo+PiArICAgIHN0cnVjdCBsdGMyOTkwX2RhdGEgKnJldCA9IGRh\n"
- "dGE7Cj4+ICsgICAgdW5zaWduZWQgaW50IHRpbWVvdXQ7Cj4+ICsKPj4gKyAgICBtdXRleF9sb2Nr\n"
- "KCZkYXRhLT51cGRhdGVfbG9jayk7Cj4+ICsKPj4gKyAgICAvKiBVcGRhdGUgYWJvdXQgNCB0aW1l\n"
- "cyBwZXIgc2Vjb25kIG1heCAqLwo+PiArICAgIGlmICh0aW1lX2FmdGVyKGppZmZpZXMsIGRhdGEt\n"
- "Pmxhc3RfdXBkYXRlZCArIEhaIC8gNCkgfHwKPj4gIWRhdGEtPnZhbGlkKSB7Cj4+ICsgICAgICAg\n"
- "IGludCB2YWw7Cj4+ICsgICAgICAgIGludCBpOwo+PiArCj4KPiBQbGVhc2UgY29uc2lkZXIgdXNp\n"
- "bmcgY29udGludW91cyBjb252ZXJzaW9uLiBUaGlzIHdvdWxkIHNpbXBsaWZ5IHRoZQo+IGNvZGUg\n"
- "c2lnbmlmaWNhbnRseQo+IGFuZCByZWR1Y2UgcmVhZCBkZWxheXMuCgpJdCBtaWdodCBpbmNyZWFz\n"
- "ZSBwb3dlciBjb25zdW1wdGlvbiB0aG91Z2gsIGFzIHR5cGljYWxseSBzb21lIHVzZXIgCnByb2dy\n"
- "YW0gd291bGQgcG9sbCB0aGlzIGV2ZXJ5IDEwIHNlY29uZHMgb3Igc28uIEknbGwgY2hlY2sgdGhl\n"
- "IGRhdGEgc2hlZXQuCgo+PiArICAgICAgICAvKiBUcmlnZ2VyIEFEQywgYW55IHZhbHVlIHdpbGwg\n"
- "ZG8gKi8KPj4gKyAgICAgICAgdmFsID0gbHRjMjk5MF93cml0ZShpMmMsIExUQzI5OTBfVFJJR0dF\n"
- "UiwgMSk7Cj4+ICsgICAgICAgIGlmICh1bmxpa2VseSh2YWwgPCAwKSkgewo+PiArICAgICAgICAg\n"
- "ICAgcmV0ID0gRVJSX1BUUih2YWwpOwo+PiArICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAg\n"
- "ICAgICAgfQo+PiArCj4+ICsgICAgICAgIC8qIFdhaXQgZm9yIGNvbnZlcnNpb24gY29tcGxldGUg\n"
- "Ki8KPj4gKyAgICAgICAgdGltZW91dCA9IDIwMDsKPj4gKyAgICAgICAgZm9yICg7Oykgewo+PiAr\n"
- "ICAgICAgICAgICAgdXNsZWVwX3JhbmdlKDIwMDAsIDQwMDApOwo+PiArICAgICAgICAgICAgdmFs\n"
- "ID0gbHRjMjk5MF9yZWFkX2J5dGUoaTJjLCBMVEMyOTkwX1NUQVRVUyk7Cj4+ICsgICAgICAgICAg\n"
- "ICBpZiAodW5saWtlbHkodmFsIDwgMCkpIHsKPj4gKyAgICAgICAgICAgICAgICByZXQgPSBFUlJf\n"
- "UFRSKHZhbCk7Cj4+ICsgICAgICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAgICAgICAgICAg\n"
- "IH0KPj4gKyAgICAgICAgICAgIC8qIFNpbmdsZS1zaG90IG1vZGUsIHdhaXQgZm9yIGNvbnZlcnNp\n"
- "b24gdG8gY29tcGxldGUgKi8KPj4gKyAgICAgICAgICAgIGlmICgodmFsICYgTFRDMjk5MF9TVEFU\n"
- "VVNfQlVTWSkgPT0gMCkKPgo+ICAgICAgICAgICAgICBpZiAoISguLi4pKQo+Cj4+ICsgICAgICAg\n"
- "ICAgICAgICAgYnJlYWs7Cj4+ICsgICAgICAgICAgICBpZiAoLS10aW1lb3V0ID09IDApIHsKPj4g\n"
- "KyAgICAgICAgICAgICAgICByZXQgPSBFUlJfUFRSKC1FVElNRURPVVQpOwo+PiArICAgICAgICAg\n"
- "ICAgICAgIGdvdG8gYWJvcnQ7Cj4+ICsgICAgICAgICAgICB9Cj4+ICsgICAgICAgIH0KPgo+IEFn\n"
- "YWluLCBwbGVhc2UgY29uc2lkZXIgdXNpbmcgY29udGludW91cyBjb252ZXJzaW9uIG1vZGUuCj4K\n"
- "PiBJZiB0aGlzIGlzIG5vdCBmZWFzaWJsZSBmb3Igc29tZSByZWFzb24sIHlvdSBtaWdodCBhcyB3\n"
- "ZWxsIGp1c3Qgd2FpdCBmb3IKPiB0aGUKPiBtaW5pbXVtIGNvbnZlcnNpb24gdGltZSBiZWZvcmUg\n"
- "dHJ5aW5nIHRvIHJlYWQgZm9yIHRoZSBmaXJzdCB0aW1lLiBJZiBzbywKPiBwbGVhc2UgdXNlIGEg\n"
- "Zml4ZWQgdGltZW91dCBieSBjb21wYXJpbmcgdGhlIGVsYXBzZWQgdGltZSBpbnN0ZWFkIG9mIGxv\n"
- "b3BpbmcKPiBmb3IgYSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcy4gTm90IGV2ZW4gY291bnRpbmcg\n"
- "dGhlIHRpbWUgZm9yIGV4ZWN1dGluZyB0aGUKPiBjb2RlLCB0aGUgbWF4aW11bSBkZWxheSBpcyBi\n"
- "ZXR3ZWVuIDQwMCBtcyBhbmQgODAwIG1zLCB3aGljaCBpcyB3YXkgdG9vIGhpZ2gKPiAoY2hpcCBz\n"
- "cGVjIHNheXMgMTY3IG1zIHdvcnN0IGNhc2UsIGlmIHRocmVlIHRlbXBlcmF0dXJlIHNlbnNvcnMg\n"
- "YXJlCj4gY29uZmlndXJlZCkuCgpPciBtYXliZSBJIHNob3VsZCBqdXN0IHNsZWVwIGZvciAxNjdt\n"
- "cyBhbmQgYmUgZG9uZSB3aXRoIGl0LiBUaG91Z2ggSSAKdGhpbmsgSSdsIGdvdCB3aXRoIHlvdXIg\n"
- "bWluaW1hbCB0aW1lIGZpcnN0IHN1Z2dlc3Rpb24uCgo+PiArCj4+ICsgICAgICAgIC8qIFJlYWQg\n"
- "YWxsIHJlZ2lzdGVycyAqLwo+PiArICAgICAgICBmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShk\n"
- "YXRhLT52YWx1ZXMpOyArK2kpIHsKPj4gKyAgICAgICAgICAgIHZhbCA9IGx0YzI5OTBfcmVhZF93\n"
- "b3JkKGkyYywgKGk8PDEpICsgTFRDMjk5MF9USU5UX01TQik7Cj4KPiBNaXNzaW5nIHNwYWNlcyBh\n"
- "cm91bmQgPDwKPgo+PiArICAgICAgICAgICAgaWYgKHVubGlrZWx5KHZhbCA8IDApKSB7Cj4+ICsg\n"
- "ICAgICAgICAgICAgICAgZGV2X2RiZyhkZXYsCj4+ICsgICAgICAgICAgICAgICAgICAgICJGYWls\n"
- "ZWQgdG8gcmVhZCBBREMgdmFsdWU6IGVycm9yICVkXG4iLAo+PiArICAgICAgICAgICAgICAgICAg\n"
- "ICB2YWwpOwo+PiArICAgICAgICAgICAgICAgIHJldCA9IEVSUl9QVFIodmFsKTsKPj4gKyAgICAg\n"
- "ICAgICAgICAgICBnb3RvIGFib3J0Owo+PiArICAgICAgICAgICAgfQo+PiArICAgICAgICAgICAg\n"
- "ZGF0YS0+dmFsdWVzW2ldID0gdmFsICYgMHg3RkZGOyAvKiBTdHJpcCAnbmV3JyBiaXQgKi8KPgo+\n"
- "IFRoZSBiaXQgaXMgbmV2ZXIgZXZhbHVhdGVkLCBzbyB5b3UgbWlnaHQgYXMgd2VsbCBzdG9yZSB0\n"
- "aGUgcmF3IHZhbHVlLgo+Cj4+ICsgICAgICAgIH0KPj4gKyAgICAgICAgZGF0YS0+bGFzdF91cGRh\n"
- "dGVkID0gamlmZmllczsKPj4gKyAgICAgICAgZGF0YS0+dmFsaWQgPSAxOwo+Cj4gICAgICA9IHRy\n"
- "dWU7Cj4KPj4gKwo+PiArICAgICAgICAvKgo+PiArICAgICAgICAgKiAgUXVpcms6IFNlY29uZCB0\n"
- "cmlnZ2VyIGlzIGlnbm9yZWQ/IEFmdGVyIHRoaXMsIHRoZSBCVVNZIHdpbGwKPj4gKyAgICAgICAg\n"
- "ICogc3RpbGwgYmUgc2V0IHRvICIwIiBhbmQgbm8gY29udmVyc2lvbiBwZXJmb3JtZWQuCj4+ICsg\n"
- "ICAgICAgICAqLwo+PiArICAgICAgICB2YWwgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5MF9U\n"
- "UklHR0VSLCAwKTsKPj4gKyAgICB9Cj4+ICthYm9ydDoKPj4gKyAgICBtdXRleF91bmxvY2soJmRh\n"
- "dGEtPnVwZGF0ZV9sb2NrKTsKPj4gKyAgICByZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICsvKiBS\n"
- "ZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBmcm9tIHRoZSBnaXZlbiByZWdpc3RlciBpbiB1ViBv\n"
- "ciBtQyAqLwo+PiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgbHRjMjk5MF9k\n"
- "YXRhICpkYXRhLCB1OCBpbmRleCkKPj4gK3sKPj4gKyAgICBzMzIgcmVzdWx0Owo+PiArICAgIHMx\n"
- "NiB2Owo+PiArCj4+ICsgICAgaWYgKGluZGV4ID09IDApIHsgLyogaW50ZXJuYWwgdGVtcCwgMC4w\n"
- "NjI1IGRlZ3JlZXMvTFNCLCAxMi1iaXQgICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNb\n"
- "aW5kZXhdIDw8IDM7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDEwMDAgPj4gNzsKPj4g\n"
- "KyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkgeyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IsIDE0LWJp\n"
- "dCAqLwo+PiArICAgICAgICB2ID0gZGF0YS0+dmFsdWVzW2luZGV4XSA8PCAyOwo+Cj4gRGF0YXNo\n"
- "ZWV0IHNheXMgdGhhdCB0aGUgc2lnbiBiaXQgaXMgaW4gYml0IDE0LCBzbyB0aGlzIGRyb3BzIHRo\n"
- "ZSBzaWduIGJpdC4KCkknbGwgY2hlY2sgdGhlIGRhdGEgc2hlZXQsIHdvdWxkIG5vdCBoYXZlIG5v\n"
- "dGljZWQgdGhpcyBzaW5jZSBjdXJyZW50IApkb2Vzbid0IHRlbmQgdG8gcnVuIGZyb20gdGhlIENQ\n"
- "VSBiYWNrIGludG8gdGhlIGJhdHRlcnkgOikKCj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAq\n"
- "IDE5NDIgLyAoNCAqIDEwMCk7Cj4+ICsgICAgfSBlbHNlIHsgLyogVmNjLCAzMDUuMTjOvFYvTFNC\n"
- "LCAyLjVWIG9mZnNldCwgMTQtYml0ICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNbaW5k\n"
- "ZXhdIDw8IDI7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDMwNTE4IC8gKDQgKiAxMDAp\n"
- "Owo+PiArICAgICAgICByZXN1bHQgKz0gMjUwMDAwMDsKPj4gKyAgICB9Cj4+ICsgICAgcmV0dXJu\n"
- "IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl\n"
- "KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf\n"
- "YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2\n"
- "aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgc3Ry\n"
- "dWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGx0YzI5OTBfdXBkYXRlX2RldmljZShkZXYpOwo+PiAr\n"
- "ICAgIGludCB2YWx1ZTsKPj4gKwo+PiArICAgIGlmIChJU19FUlIoZGF0YSkpCj4+ICsgICAgICAg\n"
- "IHJldHVybiBQVFJfRVJSKGRhdGEpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92\n"
- "YWx1ZShkYXRhLCBhdHRyLT5pbmRleCk7Cj4+ICsgICAgcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFH\n"
- "RV9TSVpFLCAiJWRcbiIsIHZhbHVlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIFNFTlNPUl9ERVZJ\n"
- "Q0VfQVRUUih0ZW1wX2ludCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLAo+PiBOVUxMLCAw\n"
- "KTsKPj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodjF2Ml9kaWZmLCBTX0lSVUdPLCBsdGMy\n"
- "OTkwX3Nob3dfdmFsdWUsCj4+IE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU\n"
- "Uih2M3Y0X2RpZmYsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwKPj4gTlVMTCwgMyk7Cj4+\n"
- "ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHZjYywgU19JUlVHTywgbHRjMjk5MF9zaG93X3Zh\n"
- "bHVlLCBOVUxMLCA1KTsKPj4gKwo+Cj4gUGxlYXNlIHVzZSBzdGFuZGFyZCBhdHRyaWJ1dGUgbmFt\n"
- "ZXMgKGFuZCB1bml0cykgYXMgcGVyCj4gRG9jdW1lbnRhdGlvbi9od21vbi9zeXNmcy1pbnRlcmZh\n"
- "Y2UuCj4KPj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpsdGMyOTkwX2F0dHJpYnV0ZXNbXSA9\n"
- "IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3RlbXBfaW50LmRldl9hdHRyLmF0dHIsCj4+ICsg\n"
- "ICAgJnNlbnNvcl9kZXZfYXR0cl92MXYyX2RpZmYuZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vu\n"
- "c29yX2Rldl9hdHRyX3YzdjRfZGlmZi5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2\n"
- "X2F0dHJfdmNjLmRldl9hdHRyLmF0dHIsCj4+ICsgICAgTlVMTCwKPj4gK307Cj4+ICsKPj4gK3N0\n"
- "YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGx0YzI5OTBfZ3JvdXAgPSB7Cj4+ICsg\n"
- "ICAgLmF0dHJzID0gbHRjMjk5MF9hdHRyaWJ1dGVzLAo+PiArfTsKPj4gKwo+Cj4gUGxlYXNlIHVz\n"
- "ZSB0aGUgQVRUUklCVVRFX0dST1VQUygpIG1hY3JvLiBBbHNvIHNlZSBiZWxvdy4KCk9rYXksIHdp\n"
- "bGwgUlRGTS4KCj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9pMmNfcHJvYmUoCj4+ICsgICAgc3Ry\n"
- "dWN0IGkyY19jbGllbnQgKmkyYywgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+Cj4g\n"
- "UGxlYXNlIHNwbGl0IGFzCj4KPiBzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3Byb2JlKHN0cnVjdCBp\n"
- "MmNfY2xpZW50ICppMmMsCj4gICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGkyY19kZXZp\n"
- "Y2VfaWQgKmlkKQo+Cj4+ICt7Cj4+ICsgICAgaW50IHJldDsKPj4gKyAgICBzdHJ1Y3QgbHRjMjk5\n"
- "MF9kYXRhICpsdGMyOTkwOwo+PiArCj4+ICsgICAgaWYgKCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0\n"
- "eShpMmMtPmFkYXB0ZXIsCj4+IEkyQ19GVU5DX1NNQlVTX0JZVEVfREFUQSkpCj4+ICsgICAgICAg\n"
- "IHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgbHRjMjk5MCA9IGRldm1fa3phbGxvYygmaTJj\n"
- "LT5kZXYsCj4+ICsgICAgICAgIHNpemVvZihzdHJ1Y3QgbHRjMjk5MF9kYXRhKSwgR0ZQX0tFUk5F\n"
- "TCk7Cj4KPiBQbGVhc2UgYWxpZ24gY29udGludWF0aW9uIGxpbmVzIHdpdGggJygnLgo+Cj4+ICsg\n"
- "ICAgaWYgKGx0YzI5OTAgPT0gTlVMTCkKPj4gKyAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4+ICsK\n"
- "Pj4gKyAgICByZXQgPSBsdGMyOTkwX3JlYWRfYnl0ZShpMmMsIDApOwo+PiArICAgIGlmIChyZXQg\n"
- "PCAwKSB7Cj4+ICsgICAgICAgIGRldl9lcnIoJmkyYy0+ZGV2LCAiQ291bGQgbm90IHJlYWQgTFRD\n"
- "Mjk5MCBvbiBpMmMgYnVzLlxuIik7Cj4+ICsgICAgICAgIHJldHVybiByZXQ7Cj4+ICsgICAgfQo+\n"
- "Cj4gVGhlIHdyaXRlIGJlbG93IHdvdWxkIGFsc28gcmV0dXJuIGFuIGVycm9yIGlmIHRoZSBjaGlw\n"
- "IGlzbid0IHRoZXJlLAo+IHNvIHRoaXMgYWRkaXRpb25hbCByZWFkIGRvZXMgbm90IHByb3ZpZGUg\n"
- "YW55IHJlYWwgdmFsdWUuCj4KPj4gKyAgICByZXQgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5\n"
- "MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMyOTkwX0NPTlRST0xfU0lOR0xFIHwgTFRDMjk5MF9D\n"
- "T05UUk9MX01FQVNVUkVfQUxMIHwKPj4gKyAgICAgICAgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VS\n"
- "UkVOVCk7Cj4KPiBJJ2xsIGhhdmUgdG8gdGhpbmsgYWJvdXQgdGhpcy4gV2hpbGUgaXQgYWRkcmVz\n"
- "c2VzIHlvdXIgdXNlIGNhc2UsCj4gaXQgbGltaXRzIHRoZSBzY29wZSBvZiB0aGlzIGRyaXZlciBz\n"
- "aWduaWZpY2FudGx5LiBMb29raW5nIGludG8gdGhlIGJvYXJkCj4gc3BlY2lmaWNhdGlvbnMsIHlv\n"
- "dSBtaWdodCBhcyB3ZWxsIGRvIGl0IHJpZ2h0IGFuZCBkZXRlcm1pbmUgKGFuZCBzZXQpCj4gdGhl\n"
- "IGNvcnJlY3QgY29uZmlndXJhdGlvbiB1c2luZyBkZXZpY2V0cmVlIGRhdGEgaW5zdGVhZCBvZiBm\n"
- "b3JjaW5nIHlvdXIKPiB1c2UgY2FzZSBvbiBldmVyeW9uZS4KPgo+IFN1cmUsIHlvdSBtYXkgYXJn\n"
- "dWUgdGhhdCB5b3UgZG9uJ3QgY2FyZSwgYnV0IHdlIHdpbGwgYmUgdGhlIG9uZXMgd2hvCj4gd2ls\n"
- "bCBoYXZlCj4gdG8gaGFuZGxlIGVycm9yIHJlcG9ydHMgdGhhdCB0aGUgZHJpdmVyIHVuZXhwZWN0\n"
- "ZWRseSBjaGFuZ2VzIHRoZQo+IGNvbmZpZ3VyYXRpb24KPiBpbiBvdGhlciB1c2UgY2FzZXMgKHdo\n"
- "ZXJlLCBmb3IgZXhhbXBsZSwgdGhlIG1vZGUgbWF5IGhhdmUgYmVlbiBwcmUtc2V0IGJ5Cj4gdGhl\n"
- "IEJJT1Mgb3IgUk9NTU9OKS4KClRoZSByZWFzb24gSSBkaWRuJ3Qgc3VibWl0IHRoZSBkcml2ZXIg\n"
- "bGFzdCB5ZWFyIHdhcyB0aGF0IEkgd2FzIHN0aWxsIAp0aGlua2luZyBhYm91dCBpdC4gT24gdGhl\n"
- "IG90aGVyIGhhbmQsIGEgbGltaXRlZCBkcml2ZXIgaXMgc3RpbGwgbXVjaCAKYmV0dGVyIHRoYW4g\n"
- "bm8gZHJpdmVyIGF0IGFsbCwgc28gdGhhdCBtYWRlIG1lIHBvc3QgaXQsIHdpdGggdGhlIGFkZGVk\n"
- "IApyZW1hcmtzIGFib3V0IHRoZSBkcml2ZXIgYmVpbmcgbGltaXRlZC4KCkFkZGluZyB0aGUgb3Ro\n"
- "ZXIgZnVuY3Rpb25zIGl0IHF1aXRlIGEgYml0IG1vcmUgd29yayB0aGFuIGp1c3Qgd3JpdGluZyAK\n"
- "dGhpcyByZWdpc3Rlci4gSXQgYWxzbyBjaGFuZ2VzIHRoZSBwcm9wZXJ0aWVzIHRvIGJlIGV4cG9y\n"
- "dGVkIHRvIHN5c2ZzLCAKYW5kIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgZW5kIHZhbHVlcy4KCj4K\n"
- "Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy\n"
- "cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g\n"
- "cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIG11dGV4X2luaXQoJmx0YzI5OTAtPnVwZGF0ZV9s\n"
- "b2NrKTsKPj4gKyAgICBpMmNfc2V0X2NsaWVudGRhdGEoaTJjLCBsdGMyOTkwKTsKPj4gKwo+PiAr\n"
- "ICAgIC8qIFJlZ2lzdGVyIHN5c2ZzIGhvb2tzICovCj4+ICsgICAgcmV0ID0gc3lzZnNfY3JlYXRl\n"
- "X2dyb3VwKCZpMmMtPmRldi5rb2JqLCAmbHRjMjk5MF9ncm91cCk7Cj4+ICsgICAgaWYgKHJldCkK\n"
- "Pj4gKyAgICAgICAgcmV0dXJuIHJldDsKPj4gKwo+PiArICAgIGx0YzI5OTAtPmh3bW9uX2RldiA9\n"
- "IGh3bW9uX2RldmljZV9yZWdpc3RlcigmaTJjLT5kZXYpOwo+Cj4gUGxlYXNlIHVzZSBkZXZtX2h3\n"
- "bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgo+Cj4+ICsgICAgaWYgKElTX0VSUihs\n"
- "dGMyOTkwLT5od21vbl9kZXYpKSB7Cj4+ICsgICAgICAgIHJldCA9IFBUUl9FUlIobHRjMjk5MC0+\n"
- "aHdtb25fZGV2KTsKPj4gKyAgICAgICAgZ290byBvdXRfaHdtb25fZGV2aWNlX3JlZ2lzdGVyOwo+\n"
- "PiArICAgIH0KPj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArCj4+ICtvdXRfaHdtb25fZGV2aWNl\n"
- "X3JlZ2lzdGVyOgo+PiArICAgIHN5c2ZzX3JlbW92ZV9ncm91cCgmaTJjLT5kZXYua29iaiwgJmx0\n"
- "YzI5OTBfZ3JvdXApOwo+PiArICAgIHJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBp\n"
- "bnQgbHRjMjk5MF9pMmNfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMpCj4+ICt7Cj4+ICsg\n"
- "ICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqbHRjMjk5MCA9IGkyY19nZXRfY2xpZW50ZGF0YShpMmMp\n"
- "Owo+PiArCj4+ICsgICAgaHdtb25fZGV2aWNlX3VucmVnaXN0ZXIobHRjMjk5MC0+aHdtb25fZGV2\n"
- "KTsKPj4gKyAgICBzeXNmc19yZW1vdmVfZ3JvdXAoJmkyYy0+ZGV2LmtvYmosICZsdGMyOTkwX2dy\n"
- "b3VwKTsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVj\n"
- "dCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10gPSB7Cj4+ICsgICAgeyAibHRjMjk5MCIs\n"
- "IDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMy\n"
- "OTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2ky\n"
- "Y19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsKPj4gKyAgICAgICAgLm5hbWUgPSAibHRj\n"
- "Mjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUgICAgPSBsdGMyOTkwX2kyY19wcm9iZSwK\n"
- "Pj4gKyAgICAucmVtb3ZlICAgPSBsdGMyOTkwX2kyY19yZW1vdmUsCj4+ICsgICAgLmlkX3RhYmxl\n"
- "ID0gbHRjMjk5MF9pMmNfaWQsCj4+ICt9Owo+PiArCj4+ICttb2R1bGVfaTJjX2RyaXZlcihsdGMy\n"
- "OTkwX2kyY19kcml2ZXIpOwo+PiArCj4+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkxUQzI5OTAgU2Vu\n"
- "c29yIERyaXZlciIpOwo+PiArTU9EVUxFX0FVVEhPUigiVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMi\n"
- "KTsKPj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPj4KPgoKCi0tIApNaWtlIExvb2lqbWFu\n"
- "cwoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vu\n"
- "c29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMu\n"
- bG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz
+ "Thank you very much for your review comments, I'll update the driver and \n"
+ "post a v2 patch.\n"
+ "\n"
+ "Inlined some replies below. Assume that I \"will do\" for all comments I \n"
+ "didn't comment on inline...\n"
+ "\n"
+ "On 06-01-16 16:22, Guenter Roeck wrote:\n"
+ "> Hello Mike,\n"
+ ">\n"
+ "> On 01/06/2016 12:07 AM, Mike Looijmans wrote:\n"
+ ">> This adds support for the Linear Technology LTC2990  I2C System Monitor.\n"
+ ">\n"
+ "> s/  / /\n"
+ ">\n"
+ ">> The LTC2990 supports a combination of voltage, current and temperature\n"
+ ">> monitoring, but this driver currently only supports reading two currents\n"
+ ">> by measuring two differential voltages across series resistors.\n"
+ ">>\n"
+ "> Plus VCC, plus the internal temperature.\n"
+ "\n"
+ "Yeah, I should give myself more credit :) I'll add that in Kconfig too.\n"
+ "\n"
+ ">> This is sufficient to support the Topic Miami SOM which uses this chip\n"
+ ">> to monitor the currents flowing into the FPGA and the CPU parts.\n"
+ ">>\n"
+ ">> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>\n"
+ ">> ---\n"
+ ">>   drivers/hwmon/Kconfig   |  15 +++\n"
+ ">>   drivers/hwmon/Makefile  |   1 +\n"
+ ">>   drivers/hwmon/ltc2990.c | 273\n"
+ ">> ++++++++++++++++++++++++++++++++++++++++++++++++\n"
+ ">\n"
+ "> Please also provide Documentation/hwmon/ltc2990.\n"
+ ">\n"
+ "> Also, please read and follow Documentation/hwmon/submitting-patches.\n"
+ ">\n"
+ ">>   3 files changed, 289 insertions(+)\n"
+ ">>   create mode 100644 drivers/hwmon/ltc2990.c\n"
+ ">>\n"
+ ">> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig\n"
+ ">> index 80a73bf..b3eef31 100644\n"
+ ">> --- a/drivers/hwmon/Kconfig\n"
+ ">> +++ b/drivers/hwmon/Kconfig\n"
+ ">> @@ -685,6 +685,21 @@ config SENSORS_LTC2945\n"
+ ">>         This driver can also be built as a module. If so, the module will\n"
+ ">>         be called ltc2945.\n"
+ ">>\n"
+ ">> +config SENSORS_LTC2990\n"
+ ">> +    tristate \"Linear Technology LTC2990 (current monitoring mode only)\"\n"
+ ">> +    depends on I2C\n"
+ ">> +    select REGMAP_I2C\n"
+ ">\n"
+ "> Using regmap for the driver might be a good idea, but you don't.\n"
+ "\n"
+ "Looking at the regmap, the driver only writes the one cachable register \n"
+ "once, the \"control\". All the other registers cannot be cached, are \n"
+ "either read-only or write-only. Don't think regmap will help, so I'll \n"
+ "remove the \"select\" here.\n"
+ "\n"
+ ">> +    default n\n"
+ ">\n"
+ "> Not necessary.\n"
+ ">\n"
+ ">> +    help\n"
+ ">> +      If you say yes here you get support for Linear Technology LTC2990\n"
+ ">> +      I2C System Monitor. The LTC2990 supports a combination of voltage,\n"
+ ">> +      current and temperature monitoring, but this driver currently only\n"
+ ">> +      supports reading two currents by measuring two differential\n"
+ ">> voltages\n"
+ ">> +      across series resistors.\n"
+ ">> +\n"
+ ">> +      This driver can also be built as a module. If so, the module will\n"
+ ">> +      be called ltc2990.\n"
+ ">> +\n"
+ ">>   config SENSORS_LTC4151\n"
+ ">>       tristate \"Linear Technology LTC4151\"\n"
+ ">>       depends on I2C\n"
+ ">> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile\n"
+ ">> index 12a3239..e4bd15b 100644\n"
+ ">> --- a/drivers/hwmon/Makefile\n"
+ ">> +++ b/drivers/hwmon/Makefile\n"
+ ">> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)    += lm95234.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LM95241)    += lm95241.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LM95245)    += lm95245.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LTC2945)    += ltc2945.o\n"
+ ">> +obj-$(CONFIG_SENSORS_LTC2990)    += ltc2990.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LTC4151)    += ltc4151.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LTC4215)    += ltc4215.o\n"
+ ">>   obj-$(CONFIG_SENSORS_LTC4222)    += ltc4222.o\n"
+ ">> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c\n"
+ ">> new file mode 100644\n"
+ ">> index 0000000..161d995\n"
+ ">> --- /dev/null\n"
+ ">> +++ b/drivers/hwmon/ltc2990.c\n"
+ ">> @@ -0,0 +1,273 @@\n"
+ ">> +/*\n"
+ ">> + * driver for Linear Technology LTC2990 power monitor\n"
+ ">\n"
+ "> Driver\n"
+ ">\n"
+ ">> + *\n"
+ ">> + * Copyright (C) 2014 Topic Embedded Products\n"
+ ">\n"
+ "> 2015 ?\n"
+ "\n"
+ "I wrote the driver early last year. I only did some cosmetic cleanup and \n"
+ "rebase on master before submitting.\n"
+ "\n"
+ ">\n"
+ ">> + * Author: Mike Looijmans <mike.looijmans@topic.nl>\n"
+ ">> + *\n"
+ ">> + * License: GPLv2\n"
+ ">> + *\n"
+ ">> + * This driver assumes the chip is wired as a dual current monitor, and\n"
+ ">> + * reports the voltage drop across two series resistors.\n"
+ ">\n"
+ "> It also monitors the temperature and VCC.\n"
+ ">\n"
+ ">> + */\n"
+ ">> +\n"
+ ">> +#include <linux/bug.h>\n"
+ ">\n"
+ "> Is this used anywhere in the driver ?\n"
+ "\n"
+ "Not any more...\n"
+ "\n"
+ ">\n"
+ ">> +#include <linux/delay.h>\n"
+ ">> +#include <linux/err.h>\n"
+ ">> +#include <linux/hwmon.h>\n"
+ ">> +#include <linux/hwmon-sysfs.h>\n"
+ ">> +#include <linux/i2c.h>\n"
+ ">> +#include <linux/kernel.h>\n"
+ ">> +#include <linux/module.h>\n"
+ ">> +#include <linux/slab.h>\n"
+ ">> +\n"
+ ">> +#define LTC2990_STATUS    0x00\n"
+ ">> +#define LTC2990_CONTROL    0x01\n"
+ ">> +#define LTC2990_TRIGGER    0x02\n"
+ ">> +#define LTC2990_TINT_MSB    0x04\n"
+ ">> +#define LTC2990_TINT_LSB    0x05\n"
+ ">> +#define LTC2990_V1_MSB    0x06\n"
+ ">> +#define LTC2990_V1_LSB    0x07\n"
+ ">> +#define LTC2990_V2_MSB    0x08\n"
+ ">> +#define LTC2990_V2_LSB    0x09\n"
+ ">> +#define LTC2990_V3_MSB    0x0A\n"
+ ">> +#define LTC2990_V3_LSB    0x0B\n"
+ ">> +#define LTC2990_V4_MSB    0x0C\n"
+ ">> +#define LTC2990_V4_LSB    0x0D\n"
+ ">> +#define LTC2990_VCC_MSB    0x0E\n"
+ ">> +#define LTC2990_VCC_LSB    0x0F\n"
+ ">> +\n"
+ ">> +#define LTC2990_STATUS_BUSY    BIT(0)\n"
+ ">> +#define LTC2990_STATUS_TINT    BIT(1)\n"
+ ">> +#define LTC2990_STATUS_V1    BIT(2)\n"
+ ">> +#define LTC2990_STATUS_V2    BIT(3)\n"
+ ">> +#define LTC2990_STATUS_V3    BIT(4)\n"
+ ">> +#define LTC2990_STATUS_V4    BIT(5)\n"
+ ">> +#define LTC2990_STATUS_VCC    BIT(6)\n"
+ ">> +\n"
+ ">> +/* Only define control settings we actually use */\n"
+ ">> +#define LTC2990_CONTROL_KELVIN        BIT(7)\n"
+ ">> +#define LTC2990_CONTROL_SINGLE        BIT(6)\n"
+ ">> +#define LTC2990_CONTROL_MEASURE_ALL    (0x3 << 3)\n"
+ ">> +#define LTC2990_CONTROL_MODE_CURRENT    0x06\n"
+ ">> +#define LTC2990_CONTROL_MODE_VOLTAGE    0x07\n"
+ ">> +\n"
+ ">> +struct ltc2990_data {\n"
+ ">> +    struct device *hwmon_dev;\n"
+ ">> +    struct mutex update_lock;\n"
+ ">> +    unsigned long last_updated;\n"
+ ">> +    short values[6];\n"
+ ">\n"
+ "> u16 ?\n"
+ ">\n"
+ ">> +    bool valid;\n"
+ ">> +    u8 update_counter;\n"
+ ">\n"
+ "> Not used anywhere.\n"
+ ">\n"
+ ">> +};\n"
+ ">> +\n"
+ ">> +static int ltc2990_write(struct i2c_client *i2c, u8 reg, u8 value)\n"
+ ">> +{\n"
+ ">> +    return i2c_smbus_write_byte_data(i2c, reg, value);\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static int ltc2990_read_byte(struct i2c_client *i2c, u8 reg)\n"
+ ">> +{\n"
+ ">> +    return i2c_smbus_read_byte_data(i2c, reg);\n"
+ ">> +}\n"
+ ">> +\n"
+ ">\n"
+ "> Useless shim functions.\n"
+ "\n"
+ "True, should have removed them after refactoring them into one-liners.\n"
+ "They were convenient early on.\n"
+ "\n"
+ ">\n"
+ ">> +static int ltc2990_read_word(struct i2c_client *i2c, u8 reg)\n"
+ ">> +{\n"
+ ">> +    int result = i2c_smbus_read_word_data(i2c, reg);\n"
+ ">> +    /* Result is MSB first, but smbus specs say LSB first, so swap the\n"
+ ">> +     * result */\n"
+ ">\n"
+ "> Bad multi-line comment.\n"
+ ">\n"
+ ">> +    return result < 0 ? result : swab16(result);\n"
+ ">\n"
+ "> Please use i2c_smbus_read_word_swapped() and drop the shim function.\n"
+ ">\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)\n"
+ ">> +{\n"
+ ">> +    struct i2c_client *i2c = to_i2c_client(dev);\n"
+ ">> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);\n"
+ ">> +    struct ltc2990_data *ret = data;\n"
+ ">> +    unsigned int timeout;\n"
+ ">> +\n"
+ ">> +    mutex_lock(&data->update_lock);\n"
+ ">> +\n"
+ ">> +    /* Update about 4 times per second max */\n"
+ ">> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||\n"
+ ">> !data->valid) {\n"
+ ">> +        int val;\n"
+ ">> +        int i;\n"
+ ">> +\n"
+ ">\n"
+ "> Please consider using continuous conversion. This would simplify the\n"
+ "> code significantly\n"
+ "> and reduce read delays.\n"
+ "\n"
+ "It might increase power consumption though, as typically some user \n"
+ "program would poll this every 10 seconds or so. I'll check the data sheet.\n"
+ "\n"
+ ">> +        /* Trigger ADC, any value will do */\n"
+ ">> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);\n"
+ ">> +        if (unlikely(val < 0)) {\n"
+ ">> +            ret = ERR_PTR(val);\n"
+ ">> +            goto abort;\n"
+ ">> +        }\n"
+ ">> +\n"
+ ">> +        /* Wait for conversion complete */\n"
+ ">> +        timeout = 200;\n"
+ ">> +        for (;;) {\n"
+ ">> +            usleep_range(2000, 4000);\n"
+ ">> +            val = ltc2990_read_byte(i2c, LTC2990_STATUS);\n"
+ ">> +            if (unlikely(val < 0)) {\n"
+ ">> +                ret = ERR_PTR(val);\n"
+ ">> +                goto abort;\n"
+ ">> +            }\n"
+ ">> +            /* Single-shot mode, wait for conversion to complete */\n"
+ ">> +            if ((val & LTC2990_STATUS_BUSY) == 0)\n"
+ ">\n"
+ ">              if (!(...))\n"
+ ">\n"
+ ">> +                break;\n"
+ ">> +            if (--timeout == 0) {\n"
+ ">> +                ret = ERR_PTR(-ETIMEDOUT);\n"
+ ">> +                goto abort;\n"
+ ">> +            }\n"
+ ">> +        }\n"
+ ">\n"
+ "> Again, please consider using continuous conversion mode.\n"
+ ">\n"
+ "> If this is not feasible for some reason, you might as well just wait for\n"
+ "> the\n"
+ "> minimum conversion time before trying to read for the first time. If so,\n"
+ "> please use a fixed timeout by comparing the elapsed time instead of looping\n"
+ "> for a maximum number of times. Not even counting the time for executing the\n"
+ "> code, the maximum delay is between 400 ms and 800 ms, which is way too high\n"
+ "> (chip spec says 167 ms worst case, if three temperature sensors are\n"
+ "> configured).\n"
+ "\n"
+ "Or maybe I should just sleep for 167ms and be done with it. Though I \n"
+ "think I'l got with your minimal time first suggestion.\n"
+ "\n"
+ ">> +\n"
+ ">> +        /* Read all registers */\n"
+ ">> +        for (i = 0; i < ARRAY_SIZE(data->values); ++i) {\n"
+ ">> +            val = ltc2990_read_word(i2c, (i<<1) + LTC2990_TINT_MSB);\n"
+ ">\n"
+ "> Missing spaces around <<\n"
+ ">\n"
+ ">> +            if (unlikely(val < 0)) {\n"
+ ">> +                dev_dbg(dev,\n"
+ ">> +                    \"Failed to read ADC value: error %d\\n\",\n"
+ ">> +                    val);\n"
+ ">> +                ret = ERR_PTR(val);\n"
+ ">> +                goto abort;\n"
+ ">> +            }\n"
+ ">> +            data->values[i] = val & 0x7FFF; /* Strip 'new' bit */\n"
+ ">\n"
+ "> The bit is never evaluated, so you might as well store the raw value.\n"
+ ">\n"
+ ">> +        }\n"
+ ">> +        data->last_updated = jiffies;\n"
+ ">> +        data->valid = 1;\n"
+ ">\n"
+ ">      = true;\n"
+ ">\n"
+ ">> +\n"
+ ">> +        /*\n"
+ ">> +         *  Quirk: Second trigger is ignored? After this, the BUSY will\n"
+ ">> +         * still be set to \"0\" and no conversion performed.\n"
+ ">> +         */\n"
+ ">> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 0);\n"
+ ">> +    }\n"
+ ">> +abort:\n"
+ ">> +    mutex_unlock(&data->update_lock);\n"
+ ">> +    return ret;\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +/* Return the converted value from the given register in uV or mC */\n"
+ ">> +static int ltc2990_get_value(struct ltc2990_data *data, u8 index)\n"
+ ">> +{\n"
+ ">> +    s32 result;\n"
+ ">> +    s16 v;\n"
+ ">> +\n"
+ ">> +    if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 12-bit  */\n"
+ ">> +        v = data->values[index] << 3;\n"
+ ">> +        result = (s32)v * 1000 >> 7;\n"
+ ">> +    } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB, 14-bit */\n"
+ ">> +        v = data->values[index] << 2;\n"
+ ">\n"
+ "> Datasheet says that the sign bit is in bit 14, so this drops the sign bit.\n"
+ "\n"
+ "I'll check the data sheet, would not have noticed this since current \n"
+ "doesn't tend to run from the CPU back into the battery :)\n"
+ "\n"
+ ">> +        result = (s32)v * 1942 / (4 * 100);\n"
+ ">> +    } else { /* Vcc, 305.18\316\274V/LSB, 2.5V offset, 14-bit */\n"
+ ">> +        v = data->values[index] << 2;\n"
+ ">> +        result = (s32)v * 30518 / (4 * 100);\n"
+ ">> +        result += 2500000;\n"
+ ">> +    }\n"
+ ">> +    return result;\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static ssize_t ltc2990_show_value(struct device *dev,\n"
+ ">> +                  struct device_attribute *da, char *buf)\n"
+ ">> +{\n"
+ ">> +    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);\n"
+ ">> +    struct ltc2990_data *data = ltc2990_update_device(dev);\n"
+ ">> +    int value;\n"
+ ">> +\n"
+ ">> +    if (IS_ERR(data))\n"
+ ">> +        return PTR_ERR(data);\n"
+ ">> +\n"
+ ">> +    value = ltc2990_get_value(data, attr->index);\n"
+ ">> +    return snprintf(buf, PAGE_SIZE, \"%d\\n\", value);\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static SENSOR_DEVICE_ATTR(temp_int, S_IRUGO, ltc2990_show_value,\n"
+ ">> NULL, 0);\n"
+ ">> +static SENSOR_DEVICE_ATTR(v1v2_diff, S_IRUGO, ltc2990_show_value,\n"
+ ">> NULL, 1);\n"
+ ">> +static SENSOR_DEVICE_ATTR(v3v4_diff, S_IRUGO, ltc2990_show_value,\n"
+ ">> NULL, 3);\n"
+ ">> +static SENSOR_DEVICE_ATTR(vcc, S_IRUGO, ltc2990_show_value, NULL, 5);\n"
+ ">> +\n"
+ ">\n"
+ "> Please use standard attribute names (and units) as per\n"
+ "> Documentation/hwmon/sysfs-interface.\n"
+ ">\n"
+ ">> +static struct attribute *ltc2990_attributes[] = {\n"
+ ">> +    &sensor_dev_attr_temp_int.dev_attr.attr,\n"
+ ">> +    &sensor_dev_attr_v1v2_diff.dev_attr.attr,\n"
+ ">> +    &sensor_dev_attr_v3v4_diff.dev_attr.attr,\n"
+ ">> +    &sensor_dev_attr_vcc.dev_attr.attr,\n"
+ ">> +    NULL,\n"
+ ">> +};\n"
+ ">> +\n"
+ ">> +static const struct attribute_group ltc2990_group = {\n"
+ ">> +    .attrs = ltc2990_attributes,\n"
+ ">> +};\n"
+ ">> +\n"
+ ">\n"
+ "> Please use the ATTRIBUTE_GROUPS() macro. Also see below.\n"
+ "\n"
+ "Okay, will RTFM.\n"
+ "\n"
+ ">\n"
+ ">> +static int ltc2990_i2c_probe(\n"
+ ">> +    struct i2c_client *i2c, const struct i2c_device_id *id)\n"
+ ">\n"
+ "> Please split as\n"
+ ">\n"
+ "> static int ltc2990_i2c_probe(struct i2c_client *i2c,\n"
+ ">                   const struct i2c_device_id *id)\n"
+ ">\n"
+ ">> +{\n"
+ ">> +    int ret;\n"
+ ">> +    struct ltc2990_data *ltc2990;\n"
+ ">> +\n"
+ ">> +    if (!i2c_check_functionality(i2c->adapter,\n"
+ ">> I2C_FUNC_SMBUS_BYTE_DATA))\n"
+ ">> +        return -ENODEV;\n"
+ ">> +\n"
+ ">> +    ltc2990 = devm_kzalloc(&i2c->dev,\n"
+ ">> +        sizeof(struct ltc2990_data), GFP_KERNEL);\n"
+ ">\n"
+ "> Please align continuation lines with '('.\n"
+ ">\n"
+ ">> +    if (ltc2990 == NULL)\n"
+ ">> +        return -ENOMEM;\n"
+ ">> +\n"
+ ">> +    ret = ltc2990_read_byte(i2c, 0);\n"
+ ">> +    if (ret < 0) {\n"
+ ">> +        dev_err(&i2c->dev, \"Could not read LTC2990 on i2c bus.\\n\");\n"
+ ">> +        return ret;\n"
+ ">> +    }\n"
+ ">\n"
+ "> The write below would also return an error if the chip isn't there,\n"
+ "> so this additional read does not provide any real value.\n"
+ ">\n"
+ ">> +    ret = ltc2990_write(i2c, LTC2990_CONTROL,\n"
+ ">> +        LTC2990_CONTROL_SINGLE | LTC2990_CONTROL_MEASURE_ALL |\n"
+ ">> +        LTC2990_CONTROL_MODE_CURRENT);\n"
+ ">\n"
+ "> I'll have to think about this. While it addresses your use case,\n"
+ "> it limits the scope of this driver significantly. Looking into the board\n"
+ "> specifications, you might as well do it right and determine (and set)\n"
+ "> the correct configuration using devicetree data instead of forcing your\n"
+ "> use case on everyone.\n"
+ ">\n"
+ "> Sure, you may argue that you don't care, but we will be the ones who\n"
+ "> will have\n"
+ "> to handle error reports that the driver unexpectedly changes the\n"
+ "> configuration\n"
+ "> in other use cases (where, for example, the mode may have been pre-set by\n"
+ "> the BIOS or ROMMON).\n"
+ "\n"
+ "The reason I didn't submit the driver last year was that I was still \n"
+ "thinking about it. On the other hand, a limited driver is still much \n"
+ "better than no driver at all, so that made me post it, with the added \n"
+ "remarks about the driver being limited.\n"
+ "\n"
+ "Adding the other functions it quite a bit more work than just writing \n"
+ "this register. It also changes the properties to be exported to sysfs, \n"
+ "and the calculation of the end values.\n"
+ "\n"
+ ">\n"
+ ">> +    if (ret < 0) {\n"
+ ">> +        dev_err(&i2c->dev, \"Error: Failed to set control mode.\\n\");\n"
+ ">> +        return ret;\n"
+ ">> +    }\n"
+ ">> +\n"
+ ">> +    mutex_init(&ltc2990->update_lock);\n"
+ ">> +    i2c_set_clientdata(i2c, ltc2990);\n"
+ ">> +\n"
+ ">> +    /* Register sysfs hooks */\n"
+ ">> +    ret = sysfs_create_group(&i2c->dev.kobj, &ltc2990_group);\n"
+ ">> +    if (ret)\n"
+ ">> +        return ret;\n"
+ ">> +\n"
+ ">> +    ltc2990->hwmon_dev = hwmon_device_register(&i2c->dev);\n"
+ ">\n"
+ "> Please use devm_hwmon_device_register_with_groups().\n"
+ ">\n"
+ ">> +    if (IS_ERR(ltc2990->hwmon_dev)) {\n"
+ ">> +        ret = PTR_ERR(ltc2990->hwmon_dev);\n"
+ ">> +        goto out_hwmon_device_register;\n"
+ ">> +    }\n"
+ ">> +\n"
+ ">> +    return 0;\n"
+ ">> +\n"
+ ">> +out_hwmon_device_register:\n"
+ ">> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);\n"
+ ">> +    return ret;\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static int ltc2990_i2c_remove(struct i2c_client *i2c)\n"
+ ">> +{\n"
+ ">> +    struct ltc2990_data *ltc2990 = i2c_get_clientdata(i2c);\n"
+ ">> +\n"
+ ">> +    hwmon_device_unregister(ltc2990->hwmon_dev);\n"
+ ">> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);\n"
+ ">> +    return 0;\n"
+ ">> +}\n"
+ ">> +\n"
+ ">> +static const struct i2c_device_id ltc2990_i2c_id[] = {\n"
+ ">> +    { \"ltc2990\", 0 },\n"
+ ">> +    {}\n"
+ ">> +};\n"
+ ">> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);\n"
+ ">> +\n"
+ ">> +static struct i2c_driver ltc2990_i2c_driver = {\n"
+ ">> +    .driver = {\n"
+ ">> +        .name = \"ltc2990\",\n"
+ ">> +    },\n"
+ ">> +    .probe    = ltc2990_i2c_probe,\n"
+ ">> +    .remove   = ltc2990_i2c_remove,\n"
+ ">> +    .id_table = ltc2990_i2c_id,\n"
+ ">> +};\n"
+ ">> +\n"
+ ">> +module_i2c_driver(ltc2990_i2c_driver);\n"
+ ">> +\n"
+ ">> +MODULE_DESCRIPTION(\"LTC2990 Sensor Driver\");\n"
+ ">> +MODULE_AUTHOR(\"Topic Embedded Products\");\n"
+ ">> +MODULE_LICENSE(\"GPL v2\");\n"
+ ">>\n"
+ ">\n"
+ "\n"
+ "\n"
+ "-- \n"
+ Mike Looijmans
 
-9eea4df70acbde1829fbe7cd6e211a8761c9c57dc8e04b7fe788fc8167bf7835
+bc267d1278385396a5ad4fc179a6aca9a62b435f3bcc94ef5358e374d45f9540

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.