All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20140708090315.3866.15604.stgit@localhost.localdomain>

diff --git a/a/1.txt b/N1/1.txt
index ab77646..b0e2de3 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,300 +1,568 @@
-VGhpcyBwYXRjaCBhZGRzIGJhc2ljIGtlcm5lbCBzdXBwb3J0IGZvciByZWFkaW5nIHBvd2VyIHZh
-bHVlcywgZmFuCnNwZWVkIHJwbSwgdm9sdGFnZSBhbmQgdGVtcGVyYXR1cmUgZGF0YSBvbiBwb3dl
-cm52IHBsYXRmb3JtcyB3aGljaAp3aWxsIGJlIGV4cG9ydGVkIHRvIHVzZXIgc3BhY2UgdGhyb3Vn
-aCBzeXNmcyBpbnRlcmZhY2UuCgpUZXN0IHJlc3VsdHM6Ci0tLS0tLS0tLS0tLS0KW3Jvb3RAdHVs
-MTYzcDEgfl0jIHNlbnNvcnMKaWJtcG93ZXJudi1pc2EtMDAwMApBZGFwdGVyOiBJU0EgYWRhcHRl
-cgpmYW4xOiAgICAgICAgNTQ2NSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuMjogICAgICAgIDUx
-NTIgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjM6ICAgICAgICA1NTIxIFJQTSAgKG1pbiA9ICAg
-IDAgUlBNKQpmYW40OiAgICAgICAgNDg5MSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuNTogICAg
-ICAgICAgIDAgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1p
-biA9ICAgIDAgUlBNKQpmYW43OiAgICAgICAgNzQ4MCBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFu
-ODogICAgICAgIDc5NDQgUlBNICAobWluID0gICAgMCBSUE0pCnRlbXAxOiAgICAgICAgKzM5LjDC
-sEMgIChoaWdoID0gICswLjDCsEMpCnBvd2VyMTogICAgICAxOTAuMDAgVyAgCgpbcm9vdEB0dWwx
-NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwphbGFybXRpbWVyICBpYm1wb3dlcm52
-LjAgIHBvd2VyICBydGMtZ2VuZXJpYyAgc2VyaWFsODI1MCAgdWV2ZW50Cltyb290QHR1bDE2M3Ax
-IH5dIyBscyAvc3lzL2RldmljZXMvcGxhdGZvcm0vaWJtcG93ZXJudi4wL2h3bW9uL2h3bW9uMC8K
-ZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2Vy
-CmZhbjFfZmF1bHQgIGZhbjNfZmF1bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQg
-IHBvd2VyMV9pbnB1dApmYW4xX2lucHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5w
-dXQJaW4yX2ZhdWx0ICBzdWJzeXN0ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAg
-ZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZh
-bjZfZmF1bHQgIGZhbjhfZmF1bHQJaW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFu
-NF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2
-M3AxIH5dIyBscyAvc3lzL2NsYXNzL2h3bW9uL2h3bW9uMC8KZGV2aWNlCSAgICBmYW4yX21pbglm
-YW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2VyCmZhbjFfZmF1bHQgIGZhbjNfZmF1
-bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQgIHBvd2VyMV9pbnB1dApmYW4xX2lu
-cHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICBzdWJzeXN0
-ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0
-ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZhbjZfZmF1bHQgIGZhbjhfZmF1bHQJ
-aW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBm
-YW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2M3AxIH5dIwoKU2lnbmVkLW9mZi1i
-eTogTmVlbGVzaCBHdXB0YSA8bmVlbGVndXBAbGludXgudm5ldC5pYm0uY29tPgpSZXZpZXdlZC1i
-eTogR3VlbnRlciBSb2VjayA8bGludXhAcm9lY2stdXMubmV0PgotLS0KCkNoYW5nZXMgaW4gdjUK
-PT09PT09PT09PT09PQotIEFkZHJlc3NlZCBjb3VwbGUgbWlub3IgY29tbWVudHMgaW4gdjQuCgpD
-aGFuZ2VzIGluIHY0Cj09PT09PT09PT09PT0KLSBSZXBsYWNlZCBwcl9lcnIoKSB3aXRoIGRldl9l
-cnIoKSBmb3IgbG9nZ2luZyBwcmludCBtZXNzYWdlcy4KLSBVc2luZyBrc3RydG91MzIoKSBmdW5j
-dGlvbiBmb3IgY29udmVydGluZyBzdHJpbmcgdG8gdTMyIGluc3RlYWQgb2Ygc3NjYW5mKCkuCgpD
-aGFuZ2VzIGluIHYzCj09PT09PT09PT09PT0KLSBGaXhlZCBhbiBlbmRpYW5uZXNzIGJ1ZyBsZWFk
-aW5nIHRoZSBkcml2ZXIgdG8gYnJlYWsgb24gTEUuCi0gRml4ZWQgYSBidWcgdGhhdCB3aGVuIG9u
-ZSBvZiB0aGUgJ2F0dHJpYnV0ZV9ncm91cCcgbm90IHBvcHVsYXRlZCwgZm9sbG93aW5nCiAgZ3Jv
-dXBzIGF0dHJpYnV0ZXMgd2VyZSBkcm9wcGVkLgotIFJld3JpdGUgdGhlIGdldF9zZW5zb3JfaW5k
-ZXhfYXR0cigpIGZ1bmN0aW9uIHRvIGhhbmRsZSBhbGwgdGhlIGVycm9yIHNjZW5hcmlvcwogIGxp
-a2UgJ3NzY2FuZicgZXRjLgotIEZpeGVkIGFsbCB0aGUgZXJyb3JzL3dhcm5pbmdzIHJlbGF0ZWQg
-dG8gY29kaW5nIHN0eWxlL3doaXRlc3BhY2UuCi0gQWRkZWQgJ0RvY3VtZW50YXRpb24nIGZpbGVz
-LgotIEFkZHJlc3NlZCByZW1haW5pbmcgcmV2aWV3IGNvbW1lbnRzIG9uIFYyLgoKQ2hhbmdlcyBp
-biB2Mgo9PT09PT09PT09PT09Ci0gR2VuZXJpYyB1c2Ugb2YgZGV2bV8qIGZ1bmN0aW9ucyBpbiBo
-d21vbiBsaWtlIHVzaW5nIGRldm1fa3phbGxvYygpIGZvciBkeW5hbWljCiAgbWVtb3J5IHJlcXVl
-c3QsIGF2b2lkaW5nIHRoZSBuZWVkIHRvIGV4cGxpY2l0IGZyZWUgb2YgbWVtb3J5LgogIEFkZGlu
-ZyAnc3RydWN0IGF0dHJpYnV0ZV9ncm91cCcgYXMgbWVtYmVyIG9mIHBsYXRmb3JtIGRhdGEgc3Ry
-dWN0dXJlIHRvIGJlCiAgcG9wdWxhdGVkIGFuZCB0aGVuIHBhc3NlZCB0byBkZXZtX2h3bW9uX2Rl
-dmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgoKICBOb3RlOiBIYXZpbmcgYW4gYXJyYXkgb2Yg
-cG9pbnRlcnMgb2YgJ2F0dHJpYnV0ZV9ncm91cCcgYW5kIGVhY2ggZ3JvdXAKICBjb3JyZXNwb25k
-cyB0byAnZW51bSBzZW5zb3JzJyB0eXBlLiBOb3QgY29tcGxldGVseSBzdXJlLCBpZiBpdCdzIGlk
-ZWFsIG9yCiAgY291bGQgaGF2ZSBqdXN0IG9uZSBncm91cCBwb3B1bGF0ZWQgd2l0aCBhdHRyaWJ1
-dGVzIG9mIHNlbnNvciB0eXBlcz8KCi0gJ2libXBvd2VybnYnIGlzIG5vdCBob3QtcGx1Z2dhYmxl
-IGRldmljZSBzbyBtb3ZpbmcgJ3BsYXRmb3JtX2RyaXZlcicgY2FsbGJhY2sKICBmdW5jdGlvbiAo
-cHJvYmUpIGFzIHBhcnQgb2YgX19pbml0IGNvZGUuCi0gRml4ZWQgaXNzdWVzIHJlbGF0ZWQgdG8g
-Y29kaW5nIHN0eWxlLgotIE90aGVyIGdlbmVyYWwgY29tbWVudHMgaW4gdjEuCgogLi4uL2Rldmlj
-ZXRyZWUvYmluZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQgICAgICAgfCAgIDIzICsKIERvY3Vt
-ZW50YXRpb24vaHdtb24vaWJtcG93ZXJudiAgICAgICAgICAgICAgICAgICAgIHwgICA0MSArKwog
-ZHJpdmVycy9od21vbi9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEx
-ICsKIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg
-ICAgMSAKIGRyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jICAgICAgICAgICAgICAgICAgICAgICAg
-IHwgIDM2NCArKysrKysrKysrKysrKysrKysrKwogNSBmaWxlcyBjaGFuZ2VkLCA0NDAgaW5zZXJ0
-aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5k
-aW5ncy9od21vbi9pYm1wb3dlcm52LnR4dAogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp
-b24vaHdtb24vaWJtcG93ZXJudgogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaHdtb24vaWJt
-cG93ZXJudi5jCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz
-L2h3bW9uL2libXBvd2VybnYudHh0IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz
-L2h3bW9uL2libXBvd2VybnYudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu
-LmY5MzI0MmIKLS0tIC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmlu
-ZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQKQEAgLTAsMCArMSwyMyBAQAorSUJNIFBPV0VSTlYg
-cGxhdGZvcm0gc2Vuc29ycworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZXF1aXJl
-ZCBub2RlIHByb3BlcnRpZXM6CistIGNvbXBhdGlibGU6IG11c3QgYmUgb25lIG9mCisJCSJpYm0s
-b3BhbC1zZW5zb3ItY29vbGluZy1mYW4iCisJCSJpYm0sb3BhbC1zZW5zb3ItYW1iLXRlbXAiCisJ
-CSJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3VwcGx5IgorCQkiaWJtLG9wYWwtc2Vuc29yLXBvd2Vy
-IgorLSBzZW5zb3ItaWQ6IGFuIG9wYXF1ZSBpZCBwcm92aWRlZCBieSB0aGUgZmlybXdhcmUgdG8g
-dGhlIGtlcm5lbCwgaWRlbnRpZmllcyBhCisJICAgICBnaXZlbiBzZW5zb3IgYW5kIGl0cyBhdHRy
-aWJ1dGUgZGF0YQorCitFeGFtcGxlIHNlbnNvcnMgbm9kZToKKworY29vbGluZy1mYW4jOC1kYXRh
-IHsKKwlzZW5zb3ItaWQgPSA8MHg3MDUyMTA3PjsKKwljb21wYXRpYmxlID0gImlibSxvcGFsLXNl
-bnNvci1jb29saW5nLWZhbiI7Cit9OworCithbWItdGVtcCMxLXRocnMgeworCXNlbnNvci1pZCA9
-IDwweDUwOTYwMDA+OworCWNvbXBhdGlibGUgPSAiaWJtLG9wYWwtc2Vuc29yLWFtYi10ZW1wIjsK
-K307CmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYgYi9Eb2N1bWVu
-dGF0aW9uL2h3bW9uL2libXBvd2VybnYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw
-MC4uNjQ0MjQ1YQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdtb24vaWJtcG93
-ZXJudgpAQCAtMCwwICsxLDQxIEBACitLZXJuZWwgRHJpdmVyIElCTVBPV0VOVgorPT09PT09PT09
-PT09PT09PT09PT09PT0KKworU3VwcG9ydGVkIHN5c3RlbXM6CisgICogQW55IHJlY2VudCBJQk0g
-UCBzZXJ2ZXJzIGJhc2VkIG9uIFBPV0VSTlYgcGxhdGZvcm0KKworQXV0aG9yOiBOZWVsZXNoIEd1
-cHRhCisKK0Rlc2NyaXB0aW9uCistLS0tLS0tLS0tLQorCitUaGlzIGRyaXZlciBpbXBsZW1lbnRz
-IHJlYWRpbmcgdGhlIHBsYXRmb3JtIHNlbnNvcnMgZGF0YSBsaWtlIHRlbXBlcmF0dXJlL2Zhbi8K
-K3ZvbHRhZ2UvcG93ZXIgZm9yICdQT1dFUk5WJyBwbGF0Zm9ybS4KKworVGhlIGRyaXZlciB1c2Vz
-IHRoZSBwbGF0Zm9ybSBkZXZpY2UgaW5mcmFzdHJ1Y3R1cmUuIEl0IHByb2JlcyB0aGUgZGV2aWNl
-IHRyZWUKK2ZvciBzZW5zb3IgZGV2aWNlcyBkdXJpbmcgdGhlIF9faW5pdCBwaGFzZSBhbmQgcmVn
-aXN0ZXJzIHRoZW0gd2l0aCB0aGUgJ2h3bW9uJy4KKydod21vbicgcG9wdWxhdGVzIHRoZSAnc3lz
-ZnMnIHRyZWUgaGF2aW5nIGF0dHJpYnV0ZSBmaWxlcywgZWFjaCBmb3IgYSBnaXZlbgorc2Vuc29y
-IHR5cGUgYW5kIGl0cyBhdHRyaWJ1dGUgZGF0YS4KKworQWxsIHRoZSBub2RlcyBpbiB0aGUgRFQg
-YXBwZWFyIHVuZGVyICIvaWJtLG9wYWwvc2Vuc29ycyIgYW5kIGVhY2ggdmFsaWQgbm9kZSBpbgor
-dGhlIERUIG1hcHMgdG8gYW4gYXR0cmlidXRlIGZpbGUgaW4gJ3N5c2ZzJy4gVGhlIG5vZGUgZXhw
-b3J0cyB1bmlxdWUgJ3NlbnNvci1pZCcKK3doaWNoIHRoZSBkcml2ZXIgdXNlcyB0byBtYWtlIGFu
-IE9QQUwgY2FsbCB0byB0aGUgZmlybXdhcmUuCisKK1VzYWdlIG5vdGVzCistLS0tLS0tLS0tLQor
-VGhlIGRyaXZlciBpcyBidWlsdCBzdGF0aWNhbGx5IHdpdGggdGhlIGtlcm5lbCBieSBlbmFibGlu
-ZyB0aGUgY29uZmlnCitDT05GSUdfU0VOU09SU19JQk1QT1dFUk5WLiBJdCBjYW4gYWxzbyBiZSBi
-dWlsdCBhcyBtb2R1bGUgJ2libXBvd2VybnYnLgorCitTeXNmcyBhdHRyaWJ1dGVzCistLS0tLS0t
-LS0tLS0tLS0tCisKK2ZhblhfaW5wdXQJCU1lYXN1cmVkIFJQTSB2YWx1ZS4KK2ZhblhfbWluCQlU
-aHJlc2hvbGQgUlBNIGZvciBhbGVydCBnZW5lcmF0aW9uLgorZmFuWF9mYXVsdAkJMDogTm8gZmFp
-bCBjb25kaXRpb24KKwkJCTE6IEZhaWxpbmcgZmFuCit0ZW1wWF9pbnB1dAkJTWVhc3VyZWQgYW1i
-aWVudCB0ZW1wZXJhdHVyZS4KK3RlbXBYX21heAkJVGhyZXNob2xkIGFtYmllbnQgdGVtcGVyYXR1
-cmUgZm9yIGFsZXJ0IGdlbmVyYXRpb24uCitpblhfaW5wdXQJCU1lYXN1cmVkIHBvd2VyIHN1cHBs
-eSB2b2x0YWdlCitpblhfZmF1bHQJCTA6IE5vIGZhaWwgY29uZGl0aW9uLgorCQkJMTogRmFpbGlu
-ZyBwb3dlciBzdXBwbHkuCitwb3dlcjFfaW5wdXQJCVN5c3RlbSBwb3dlciBjb25zdW1wdGlvbiAo
-bWljcm9XYXR0KQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9o
-d21vbi9LY29uZmlnCmluZGV4IDAyZDNkODUuLjI5YzNmY2IgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMv
-aHdtb24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKQEAgLTU1NCw2ICs1NTQs
-MTcgQEAgY29uZmlnIFNFTlNPUlNfSUJNUEVYCiAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBi
-dWlsdCBhcyBhIG1vZHVsZS4gIElmIHNvLCB0aGUgbW9kdWxlCiAJICB3aWxsIGJlIGNhbGxlZCBp
-Ym1wZXguCiAKK2NvbmZpZyBTRU5TT1JTX0lCTVBPV0VSTlYKKwl0cmlzdGF0ZSAiSUJNIFBPV0VS
-TlYgcGxhdGZvcm0gc2Vuc29ycyIKKwlkZXBlbmRzIG9uIFBQQ19QT1dFUk5WCisJZGVmYXVsdCB5
-CisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIHRoZSB0
-ZW1wZXJhdHVyZS9mYW4vcG93ZXIKKwkgIHNlbnNvcnMgb24geW91ciBQb3dlck5WIHBsYXRmb3Jt
-LgorCisJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28s
-IHRoZSBtb2R1bGUKKwkgIHdpbGwgYmUgY2FsbGVkIGlibXBvd2VybnYuCisKIGNvbmZpZyBTRU5T
-T1JTX0lJT19IV01PTgogCXRyaXN0YXRlICJId21vbiBkcml2ZXIgdGhhdCB1c2VzIGNoYW5uZWxz
-IHNwZWNpZmllZCB2aWEgaWlvIG1hcHMiCiAJZGVwZW5kcyBvbiBJSU8KZGlmZiAtLWdpdCBhL2Ry
-aXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCmluZGV4IDNkYzBm
-MDIuLmZjNGVkMjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKKysrIGIvZHJp
-dmVycy9od21vbi9NYWtlZmlsZQpAQCAtNzEsNiArNzEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S
-U19VTFRSQTQ1KQkrPSB1bHRyYTQ1X2Vudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JNUtfQU1C
-KQkrPSBpNWtfYW1iLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0lCTUFFTSkJKz0gaWJtYWVtLm8K
-IG9iai0kKENPTkZJR19TRU5TT1JTX0lCTVBFWCkJKz0gaWJtcGV4Lm8KK29iai0kKENPTkZJR19T
-RU5TT1JTX0lCTVBPV0VSTlYpKz0gaWJtcG93ZXJudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19J
-SU9fSFdNT04pICs9IGlpb19od21vbi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyMDkpCSs9
-IGluYTIwOS5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyWFgpCSs9IGluYTJ4eC5vCmRpZmYg
-LS1naXQgYS9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYyBiL2RyaXZlcnMvaHdtb24vaWJtcG93
-ZXJudi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YjY1MmEKLS0tIC9k
-ZXYvbnVsbAorKysgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwpAQCAtMCwwICsxLDM2NCBA
-QAorLyoKKyAqIElCTSBQb3dlck5WIHBsYXRmb3JtIHNlbnNvcnMgZm9yIHRlbXBlcmF0dXJlL2Zh
-bi92b2x0YWdlL3Bvd2VyCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSUJNCisgKgorICogVGhpcyBw
-cm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBt
-b2RpZnkKKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExp
-Y2Vuc2UgYXMgcHVibGlzaGVkIGJ5CisgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBl
-aXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICogKGF0IHlvdXIgb3B0aW9uKSBh
-bnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g
-dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJS
-QU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFC
-SUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBH
-TlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqIFlvdSBz
-aG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl
-bnNlCisgKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4KKyAqLworCisjZGVmaW5lIERSVk5BTUUJ
-CSJpYm1wb3dlcm52IgorI2RlZmluZSBwcl9mbXQoZm10KQlEUlZOQU1FICI6ICIgZm10CisKKyNp
-bmNsdWRlIDxsaW51eC9pbml0Lmg+CisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CisjaW5jbHVk
-ZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KKyNpbmNsdWRlIDxs
-aW51eC9od21vbi1zeXNmcy5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGlu
-dXgvc2xhYi5oPgorCisjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CisjaW5jbHVk
-ZSA8YXNtL29wYWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKworI2RlZmluZSBNQVhfQVRU
-Ul9MRU4JMzIKKworLyogU2Vuc29yIHN1ZmZpeCBuYW1lIGZyb20gRFQgKi8KKyNkZWZpbmUgRFRf
-RkFVTFRfQVRUUl9TVUZGSVgJCSJmYXVsdGVkIgorI2RlZmluZSBEVF9EQVRBX0FUVFJfU1VGRklY
-CQkiZGF0YSIKKyNkZWZpbmUgRFRfVEhSRVNIT0xEX0FUVFJfU1VGRklYCSJ0aHJzIgorCisvKgor
-ICogRW51bWVyYXRlcyBhbGwgdGhlIHR5cGVzIG9mIHNlbnNvcnMgaW4gdGhlIFBPV0VSTlYgcGxh
-dGZvcm0gYW5kIGRvZXMgaW5kZXgKKyAqIGludG8gJ3N0cnVjdCBzZW5zb3JfZ3JvdXAnCisgKi8K
-K2VudW0gc2Vuc29ycyB7CisJRkFOLAorCUFNQklFTlRfVEVNUCwKKwlQT1dFUl9TVVBQTFksCisJ
-UE9XRVJfSU5QVVQsCisJTUFYX1NFTlNPUl9UWVBFLAorfTsKKworc3RhdGljIHN0cnVjdCBzZW5z
-b3JfZ3JvdXAgeworCWNvbnN0IGNoYXIgKm5hbWU7CisJY29uc3QgY2hhciAqY29tcGF0aWJsZTsK
-KwlzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGdyb3VwOworCXUzMiBhdHRyX2NvdW50OworfSBzZW5z
-b3JfZ3JvdXBzW10gPSB7CisJeyJmYW4iLCAiaWJtLG9wYWwtc2Vuc29yLWNvb2xpbmctZmFuIn0s
-CisJeyJ0ZW1wIiwgImlibSxvcGFsLXNlbnNvci1hbWItdGVtcCJ9LAorCXsiaW4iLCAiaWJtLG9w
-YWwtc2Vuc29yLXBvd2VyLXN1cHBseSJ9LAorCXsicG93ZXIiLCAiaWJtLG9wYWwtc2Vuc29yLXBv
-d2VyIn0KK307CisKK3N0cnVjdCBzZW5zb3JfZGF0YSB7CisJdTMyIGlkOyAvKiBBbiBvcGFxdWUg
-aWQgb2YgdGhlIGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLworCWVudW0gc2Vuc29ycyB0eXBl
-OworCWNoYXIgbmFtZVtNQVhfQVRUUl9MRU5dOworCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRl
-dl9hdHRyOworfTsKKworc3RydWN0IHBsYXRmb3JtX2RhdGEgeworCWNvbnN0IHN0cnVjdCBhdHRy
-aWJ1dGVfZ3JvdXAgKmF0dHJfZ3JvdXBzW01BWF9TRU5TT1JfVFlQRSArIDFdOworCXUzMiBzZW5z
-b3JzX2NvdW50OyAvKiBUb3RhbCBjb3VudCBvZiBzZW5zb3JzIGZyb20gZWFjaCBncm91cCAqLwor
-fTsKKworLyogUGxhdGZvcm0gZGV2aWNlIHJlcHJlc2VudGluZyBhbGwgdGhlIGlibXBvd2VybnYg
-c2Vuc29ycyAqLworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXZpY2U7CisKK3N0
-YXRpYyBzc2l6ZV90IHNob3dfc2Vuc29yKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmlj
-ZV9hdHRyaWJ1dGUgKmRldmF0dHIsCisJCQkgICBjaGFyICpidWYpCit7CisJc3RydWN0IHNlbnNv
-cl9kYXRhICpzZGF0YSA9IGNvbnRhaW5lcl9vZihkZXZhdHRyLCBzdHJ1Y3Qgc2Vuc29yX2RhdGEs
-CisJCQkJCQkgZGV2X2F0dHIpOworCXNzaXplX3QgcmV0OworCXUzMiB4OworCisJcmV0ID0gb3Bh
-bF9nZXRfc2Vuc29yX2RhdGEoc2RhdGEtPmlkLCAmeCk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl
-dDsKKworCS8qIENvbnZlcnQgdGVtcGVyYXR1cmUgdG8gbWlsbGktZGVncmVlcyAqLworCWlmIChz
-ZGF0YS0+dHlwZSA9PSBBTUJJRU5UX1RFTVApCisJCXggKj0gMTAwMDsKKwkvKiBDb252ZXJ0IHBv
-d2VyIHRvIG1pY3JvLXdhdHRzICovCisJZWxzZSBpZiAoc2RhdGEtPnR5cGUgPT0gUE9XRVJfSU5Q
-VVQpCisJCXggKj0gMTAwMDAwMDsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiV1XG4iLCB4KTsK
-K30KKworc3RhdGljIGludCBfX2luaXQgZ2V0X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0IGNoYXIg
-Km5hbWUsIHUzMiAqaW5kZXgsCisJCQkJCWNoYXIgKmF0dHIpCit7CisJY2hhciAqaGFzaF9wb3Mg
-PSBzdHJjaHIobmFtZSwgJyMnKTsKKwljaGFyIGJ1Zls4XSA9IHsgMCB9OworCWNoYXIgKmRhc2hf
-cG9zOworCXUzMiBjb3B5X2xlbjsKKwlpbnQgZXJyOworCisJaWYgKCFoYXNoX3BvcykKKwkJcmV0
-dXJuIC1FSU5WQUw7CisKKwlkYXNoX3BvcyA9IHN0cmNocihoYXNoX3BvcywgJy0nKTsKKwlpZiAo
-IWRhc2hfcG9zKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWNvcHlfbGVuID0gZGFzaF9wb3MgLSBo
-YXNoX3BvcyAtIDE7CisJaWYgKGNvcHlfbGVuID49IHNpemVvZihidWYpKQorCQlyZXR1cm4gLUVJ
-TlZBTDsKKworCXN0cm5jcHkoYnVmLCBoYXNoX3BvcyArIDEsIGNvcHlfbGVuKTsKKworCWVyciA9
-IGtzdHJ0b3UzMihidWYsIDEwLCBpbmRleCk7CisJaWYgKGVycikKKwkJcmV0dXJuIGVycjsKKwor
-CXN0cm5jcHkoYXR0ciwgZGFzaF9wb3MgKyAxLCBNQVhfQVRUUl9MRU4pOworCisJcmV0dXJuIDA7
-Cit9CisKKy8qCisgKiBUaGlzIGZ1bmN0aW9uIHRyYW5zbGF0ZXMgdGhlIERUIG5vZGUgbmFtZSBp
-bnRvIHRoZSAnaHdtb24nIGF0dHJpYnV0ZSBuYW1lLgorICogSUJNUE9XRVJOViBkZXZpY2Ugbm9k
-ZSBhcHBlYXIgbGlrZSBjb29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCisg
-KiB3aGljaCBuZWVkIHRvIGJlIG1hcHBlZCBhcyBmYW4yX2lucHV0LCB0ZW1wMV9tYXggcmVzcGVj
-dGl2ZWx5IGJlZm9yZQorICogcG9wdWxhdGluZyB0aGVtIGluc2lkZSBod21vbiBkZXZpY2UgY2xh
-c3MuCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9od21vbl9hdHRyX25hbWUoc3RydWN0
-IGRldmljZSAqZGV2LCBlbnVtIHNlbnNvcnMgdHlwZSwKKwkJCQkJIGNvbnN0IGNoYXIgKm5vZGVf
-bmFtZSwKKwkJCQkJIGNoYXIgKmh3bW9uX2F0dHJfbmFtZSkKK3sKKwljaGFyIGF0dHJfc3VmZml4
-W01BWF9BVFRSX0xFTl07CisJY2hhciAqYXR0cl9uYW1lOworCXUzMiBpbmRleDsKKwlpbnQgZXJy
-OworCisJZXJyID0gZ2V0X3NlbnNvcl9pbmRleF9hdHRyKG5vZGVfbmFtZSwgJmluZGV4LCBhdHRy
-X3N1ZmZpeCk7CisJaWYgKGVycikgeworCQlkZXZfZXJyKGRldiwgIlNlbnNvciBkZXZpY2Ugbm9k
-ZSBuYW1lICclcycgaXMgaW52YWxpZFxuIiwKKwkJCW5vZGVfbmFtZSk7CisJCXJldHVybiBlcnI7
-CisJfQorCisJaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX0ZBVUxUX0FUVFJfU1VGRklYKSkg
-eworCQlhdHRyX25hbWUgPSAiZmF1bHQiOworCX0gZWxzZSBpZiAoIXN0cmNtcChhdHRyX3N1ZmZp
-eCwgRFRfREFUQV9BVFRSX1NVRkZJWCkpIHsKKwkJYXR0cl9uYW1lID0gImlucHV0IjsKKwl9IGVs
-c2UgaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX1RIUkVTSE9MRF9BVFRSX1NVRkZJWCkpIHsK
-KwkJaWYgKHR5cGUgPT0gQU1CSUVOVF9URU1QKQorCQkJYXR0cl9uYW1lID0gIm1heCI7CisJCWVs
-c2UgaWYgKHR5cGUgPT0gRkFOKQorCQkJYXR0cl9uYW1lID0gIm1pbiI7CisJCWVsc2UKKwkJCXJl
-dHVybiAtRU5PRU5UOworCX0gZWxzZSB7CisJCXJldHVybiAtRU5PRU5UOworCX0KKworCXNucHJp
-bnRmKGh3bW9uX2F0dHJfbmFtZSwgTUFYX0FUVFJfTEVOLCAiJXMlZF8lcyIsCisJCSBzZW5zb3Jf
-Z3JvdXBzW3R5cGVdLm5hbWUsIGluZGV4LCBhdHRyX25hbWUpOworCXJldHVybiAwOworfQorCitz
-dGF0aWMgaW50IF9faW5pdCBwb3B1bGF0ZV9hdHRyX2dyb3VwcyhzdHJ1Y3QgcGxhdGZvcm1fZGV2
-aWNlICpwZGV2KQoreworCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dl
-dF9kcnZkYXRhKHBkZXYpOworCWNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKipwZ3JvdXBz
-ID0gcGRhdGEtPmF0dHJfZ3JvdXBzOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqb3BhbCwgKm5wOwor
-CWVudW0gc2Vuc29ycyB0eXBlOworCisJb3BhbCA9IG9mX2ZpbmRfbm9kZV9ieV9wYXRoKCIvaWJt
-LG9wYWwvc2Vuc29ycyIpOworCWlmICghb3BhbCkgeworCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJP
-cGFsIG5vZGUgJ3NlbnNvcnMnIG5vdCBmb3VuZFxuIik7CisJCXJldHVybiAtRU5PREVWOworCX0K
-KworCWZvcl9lYWNoX2NoaWxkX29mX25vZGUob3BhbCwgbnApIHsKKwkJaWYgKG5wLT5uYW1lID09
-IE5VTEwpCisJCQljb250aW51ZTsKKworCQlmb3IgKHR5cGUgPSAwOyB0eXBlIDwgTUFYX1NFTlNP
-Ul9UWVBFOyB0eXBlKyspCisJCQlpZiAob2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsCisJCQkJ
-CXNlbnNvcl9ncm91cHNbdHlwZV0uY29tcGF0aWJsZSkpIHsKKwkJCQlzZW5zb3JfZ3JvdXBzW3R5
-cGVdLmF0dHJfY291bnQrKzsKKwkJCQlicmVhazsKKwkJCX0KKwl9CisKKwlvZl9ub2RlX3B1dChv
-cGFsKTsKKworCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykg
-eworCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzID0gZGV2bV9remFsbG9jKCZwZGV2
-LT5kZXYsCisJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRlICopICoKKwkJCQkJKHNlbnNvcl9n
-cm91cHNbdHlwZV0uYXR0cl9jb3VudCArIDEpLAorCQkJCQlHRlBfS0VSTkVMKTsKKwkJaWYgKCFz
-ZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzKQorCQkJcmV0dXJuIC1FTk9NRU07CisKKwkJ
-cGdyb3Vwc1t0eXBlXSA9ICZzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwOworCQlwZGF0YS0+c2Vu
-c29yc19jb3VudCArPSBzZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291bnQ7CisJCXNlbnNvcl9n
-cm91cHNbdHlwZV0uYXR0cl9jb3VudCA9IDA7CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisg
-KiBJdGVyYXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVlIGZvciBlYWNoIGNoaWxkIG9mICdzZW5z
-b3JzJyBub2RlLCBjcmVhdGUKKyAqIGEgc3lzZnMgYXR0cmlidXRlIGZpbGUsIHRoZSBmaWxlIGlz
-IG5hbWVkIGJ5IHRyYW5zbGF0aW5nIHRoZSBEVCBub2RlIG5hbWUKKyAqIHRvIHRoZSBuYW1lIHJl
-cXVpcmVkIGJ5IHRoZSBoaWdoZXIgJ2h3bW9uJyBkcml2ZXIgbGlrZSBmYW4xX2lucHV0LCB0ZW1w
-MV9tYXgKKyAqIGV0Yy4uCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9kZXZpY2VfYXR0
-cnMoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgcGxhdGZvcm1fZGF0
-YSAqcGRhdGEgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwljb25zdCBzdHJ1Y3QgYXR0
-cmlidXRlX2dyb3VwICoqcGdyb3VwcyA9IHBkYXRhLT5hdHRyX2dyb3VwczsKKwlzdHJ1Y3QgZGV2
-aWNlX25vZGUgKm9wYWwsICpucDsKKwlzdHJ1Y3Qgc2Vuc29yX2RhdGEgKnNkYXRhOworCWNvbnN0
-IF9fYmUzMiAqc2Vuc29yX2lkOworCWVudW0gc2Vuc29ycyB0eXBlOworCXUzMiBjb3VudCA9IDA7
-CisJaW50IGVyciA9IDA7CisKKwlvcGFsID0gb2ZfZmluZF9ub2RlX2J5X3BhdGgoIi9pYm0sb3Bh
-bC9zZW5zb3JzIik7CisJc2RhdGEgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgcGRhdGEtPnNl
-bnNvcnNfY291bnQgKiBzaXplb2YoKnNkYXRhKSwKKwkJCSAgICAgR0ZQX0tFUk5FTCk7CisJaWYg
-KCFzZGF0YSkgeworCQllcnIgPSAtRU5PTUVNOworCQlnb3RvIGV4aXRfcHV0X25vZGU7CisJfQor
-CisJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShvcGFsLCBucCkgeworCQlpZiAobnAtPm5hbWUgPT0g
-TlVMTCkKKwkJCWNvbnRpbnVlOworCisJCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09S
-X1RZUEU7IHR5cGUrKykKKwkJCWlmIChvZl9kZXZpY2VfaXNfY29tcGF0aWJsZShucCwKKwkJCQkJ
-c2Vuc29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkKKwkJCQlicmVhazsKKworCQlpZiAodHlw
-ZSA9PSBNQVhfU0VOU09SX1RZUEUpCisJCQljb250aW51ZTsKKworCQlzZW5zb3JfaWQgPSBvZl9n
-ZXRfcHJvcGVydHkobnAsICJzZW5zb3ItaWQiLCBOVUxMKTsKKwkJaWYgKCFzZW5zb3JfaWQpIHsK
-KwkJCWRldl9pbmZvKCZwZGV2LT5kZXYsCisJCQkJICInc2Vuc29yLWlkJyBtaXNzaW5nIGluIHRo
-ZSBub2RlICclcydcbiIsCisJCQkJIG5wLT5uYW1lKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJ
-c2RhdGFbY291bnRdLmlkID0gYmUzMl90b19jcHVwKHNlbnNvcl9pZCk7CisJCXNkYXRhW2NvdW50
-XS50eXBlID0gdHlwZTsKKwkJZXJyID0gY3JlYXRlX2h3bW9uX2F0dHJfbmFtZSgmcGRldi0+ZGV2
-LCB0eXBlLCBucC0+bmFtZSwKKwkJCQkJICAgICBzZGF0YVtjb3VudF0ubmFtZSk7CisJCWlmIChl
-cnIpCisJCQlnb3RvIGV4aXRfcHV0X25vZGU7CisKKwkJc3lzZnNfYXR0cl9pbml0KCZzZGF0YVtj
-b3VudF0uZGV2X2F0dHIuYXR0cik7CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5hdHRyLm5hbWUg
-PSBzZGF0YVtjb3VudF0ubmFtZTsKKwkJc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIubW9kZSA9
-IFNfSVJVR087CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5zaG93ID0gc2hvd19zZW5zb3I7CisK
-KwkJcGdyb3Vwc1t0eXBlXS0+YXR0cnNbc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50Kytd
-ID0KKwkJCQkmc2RhdGFbY291bnQrK10uZGV2X2F0dHIuYXR0cjsKKwl9CisKK2V4aXRfcHV0X25v
-ZGU6CisJb2Zfbm9kZV9wdXQob3BhbCk7CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIGludCBf
-X2luaXQgaWJtcG93ZXJudl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQorewor
-CXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YTsKKwlzdHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7
-CisJaW50IGVycjsKKworCXBkYXRhID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigq
-cGRhdGEpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXBkYXRhKQorCQlyZXR1cm4gLUVOT01FTTsKKwor
-CXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIHBkYXRhKTsKKwlwZGF0YS0+c2Vuc29yc19jb3Vu
-dCA9IDA7CisJZXJyID0gcG9wdWxhdGVfYXR0cl9ncm91cHMocGRldik7CisJaWYgKGVycikKKwkJ
-cmV0dXJuIGVycjsKKworCS8qIENyZWF0ZSBzeXNmcyBhdHRyaWJ1dGUgZGF0YSBmb3IgZWFjaCBz
-ZW5zb3IgZm91bmQgaW4gdGhlIERUICovCisJZXJyID0gY3JlYXRlX2RldmljZV9hdHRycyhwZGV2
-KTsKKwlpZiAoZXJyKQorCQlyZXR1cm4gZXJyOworCisJLyogRmluYWxseSwgcmVnaXN0ZXIgd2l0
-aCBod21vbiAqLworCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhf
-Z3JvdXBzKCZwZGV2LT5kZXYsIERSVk5BTUUsCisJCQkJCQkJICAgcGRhdGEsCisJCQkJCQkJICAg
-cGRhdGEtPmF0dHJfZ3JvdXBzKTsKKworCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2
-KTsKK30KKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaWJtcG93ZXJudl9kcml2ZXIg
-PSB7CisJLmRyaXZlciA9IHsKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJCS5uYW1lID0gRFJW
-TkFNRSwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgaWJtcG93ZXJudl9pbml0KHZvaWQp
-Cit7CisJaW50IGVycjsKKworCXBkZXZpY2UgPSBwbGF0Zm9ybV9kZXZpY2VfYWxsb2MoRFJWTkFN
-RSwgMCk7CisJaWYgKCFwZGV2aWNlKSB7CisJCXByX2VycigiRGV2aWNlIGFsbG9jYXRpb24gZmFp
-bGVkXG4iKTsKKwkJZXJyID0gLUVOT01FTTsKKwkJZ290byBleGl0OworCX0KKworCWVyciA9IHBs
-YXRmb3JtX2RldmljZV9hZGQocGRldmljZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIkRldmlj
-ZSBhZGRpdGlvbiBmYWlsZWQgKCVkKVxuIiwgZXJyKTsKKwkJZ290byBleGl0X2RldmljZV9wdXQ7
-CisJfQorCisJZXJyID0gcGxhdGZvcm1fZHJpdmVyX3Byb2JlKCZpYm1wb3dlcm52X2RyaXZlciwg
-aWJtcG93ZXJudl9wcm9iZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIlBsYXRmcm9tIGRyaXZl
-ciBwcm9iZSBmYWlsZWRcbiIpOworCQlnb3RvIGV4aXRfZGV2aWNlX2RlbDsKKwl9CisKKwlyZXR1
-cm4gMDsKKworZXhpdF9kZXZpY2VfZGVsOgorCXBsYXRmb3JtX2RldmljZV9kZWwocGRldmljZSk7
-CitleGl0X2RldmljZV9wdXQ6CisJcGxhdGZvcm1fZGV2aWNlX3B1dChwZGV2aWNlKTsKK2V4aXQ6
-CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IGlibXBvd2VybnZfZXhpdCh2
-b2lkKQoreworCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZpYm1wb3dlcm52X2RyaXZlcik7
-CisJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIocGRldmljZSk7Cit9CisKK01PRFVMRV9BVVRI
-T1IoIk5lZWxlc2ggR3VwdGEgPG5lZWxlZ3VwQGxpbnV4LnZuZXQuaWJtLmNvbT4iKTsKK01PRFVM
-RV9ERVNDUklQVElPTigiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIpOworTU9EVUxFX0xJ
-Q0VOU0UoIkdQTCIpOworCittb2R1bGVfaW5pdChpYm1wb3dlcm52X2luaXQpOworbW9kdWxlX2V4
-aXQoaWJtcG93ZXJudl9leGl0KTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
-X19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNv
-cnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNl
-bnNvcnM
+This patch adds basic kernel support for reading power values, fan
+speed rpm, voltage and temperature data on powernv platforms which
+will be exported to user space through sysfs interface.
+
+Test results:
+-------------
+[root@tul163p1 ~]# sensors
+ibmpowernv-isa-0000
+Adapter: ISA adapter
+fan1:        5465 RPM  (min =    0 RPM)
+fan2:        5152 RPM  (min =    0 RPM)
+fan3:        5521 RPM  (min =    0 RPM)
+fan4:        4891 RPM  (min =    0 RPM)
+fan5:           0 RPM  (min =    0 RPM)
+fan6:           0 RPM  (min =    0 RPM)
+fan7:        7480 RPM  (min =    0 RPM)
+fan8:        7944 RPM  (min =    0 RPM)
+temp1:        +39.0°C  (high =  +0.0°C)
+power1:      190.00 W  
+
+[root@tul163p1 ~]# ls /sys/devices/platform/
+alarmtimer  ibmpowernv.0  power  rtc-generic  serial8250  uevent
+[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/
+device	    fan2_min	fan4_min    fan6_min	fan8_min   power
+fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  power1_input
+fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  subsystem
+fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_input
+fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  temp1_max
+fan2_input  fan4_input	fan6_input  fan8_input	name	   uevent
+[root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/
+device	    fan2_min	fan4_min    fan6_min	fan8_min   power
+fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  power1_input
+fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  subsystem
+fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_input
+fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  temp1_max
+fan2_input  fan4_input	fan6_input  fan8_input	name	   uevent
+[root@tul163p1 ~]#
+
+Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+---
+
+Changes in v5
+=============
+- Addressed couple minor comments in v4.
+
+Changes in v4
+=============
+- Replaced pr_err() with dev_err() for logging print messages.
+- Using kstrtou32() function for converting string to u32 instead of sscanf().
+
+Changes in v3
+=============
+- Fixed an endianness bug leading the driver to break on LE.
+- Fixed a bug that when one of the 'attribute_group' not populated, following
+  groups attributes were dropped.
+- Rewrite the get_sensor_index_attr() function to handle all the error scenarios
+  like 'sscanf' etc.
+- Fixed all the errors/warnings related to coding style/whitespace.
+- Added 'Documentation' files.
+- Addressed remaining review comments on V2.
+
+Changes in v2
+=============
+- Generic use of devm_* functions in hwmon like using devm_kzalloc() for dynamic
+  memory request, avoiding the need to explicit free of memory.
+  Adding 'struct attribute_group' as member of platform data structure to be
+  populated and then passed to devm_hwmon_device_register_with_groups().
+
+  Note: Having an array of pointers of 'attribute_group' and each group
+  corresponds to 'enum sensors' type. Not completely sure, if it's ideal or
+  could have just one group populated with attributes of sensor types?
+
+- 'ibmpowernv' is not hot-pluggable device so moving 'platform_driver' callback
+  function (probe) as part of __init code.
+- Fixed issues related to coding style.
+- Other general comments in v1.
+
+ .../devicetree/bindings/hwmon/ibmpowernv.txt       |   23 +
+ Documentation/hwmon/ibmpowernv                     |   41 ++
+ drivers/hwmon/Kconfig                              |   11 +
+ drivers/hwmon/Makefile                             |    1 
+ drivers/hwmon/ibmpowernv.c                         |  364 ++++++++++++++++++++
+ 5 files changed, 440 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+ create mode 100644 Documentation/hwmon/ibmpowernv
+ create mode 100644 drivers/hwmon/ibmpowernv.c
+
+diff --git a/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+new file mode 100644
+index 0000000..f93242b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+@@ -0,0 +1,23 @@
++IBM POWERNV platform sensors
++----------------------------
++
++Required node properties:
++- compatible: must be one of
++		"ibm,opal-sensor-cooling-fan"
++		"ibm,opal-sensor-amb-temp"
++		"ibm,opal-sensor-power-supply"
++		"ibm,opal-sensor-power"
++- sensor-id: an opaque id provided by the firmware to the kernel, identifies a
++	     given sensor and its attribute data
++
++Example sensors node:
++
++cooling-fan#8-data {
++	sensor-id = <0x7052107>;
++	compatible = "ibm,opal-sensor-cooling-fan";
++};
++
++amb-temp#1-thrs {
++	sensor-id = <0x5096000>;
++	compatible = "ibm,opal-sensor-amb-temp";
++};
+diff --git a/Documentation/hwmon/ibmpowernv b/Documentation/hwmon/ibmpowernv
+new file mode 100644
+index 0000000..644245a
+--- /dev/null
++++ b/Documentation/hwmon/ibmpowernv
+@@ -0,0 +1,41 @@
++Kernel Driver IBMPOWENV
++=======================
++
++Supported systems:
++  * Any recent IBM P servers based on POWERNV platform
++
++Author: Neelesh Gupta
++
++Description
++-----------
++
++This driver implements reading the platform sensors data like temperature/fan/
++voltage/power for 'POWERNV' platform.
++
++The driver uses the platform device infrastructure. It probes the device tree
++for sensor devices during the __init phase and registers them with the 'hwmon'.
++'hwmon' populates the 'sysfs' tree having attribute files, each for a given
++sensor type and its attribute data.
++
++All the nodes in the DT appear under "/ibm,opal/sensors" and each valid node in
++the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'
++which the driver uses to make an OPAL call to the firmware.
++
++Usage notes
++-----------
++The driver is built statically with the kernel by enabling the config
++CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.
++
++Sysfs attributes
++----------------
++
++fanX_input		Measured RPM value.
++fanX_min		Threshold RPM for alert generation.
++fanX_fault		0: No fail condition
++			1: Failing fan
++tempX_input		Measured ambient temperature.
++tempX_max		Threshold ambient temperature for alert generation.
++inX_input		Measured power supply voltage
++inX_fault		0: No fail condition.
++			1: Failing power supply.
++power1_input		System power consumption (microWatt)
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 02d3d85..29c3fcb 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -554,6 +554,17 @@ config SENSORS_IBMPEX
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called ibmpex.
+ 
++config SENSORS_IBMPOWERNV
++	tristate "IBM POWERNV platform sensors"
++	depends on PPC_POWERNV
++	default y
++	help
++	  If you say yes here you get support for the temperature/fan/power
++	  sensors on your PowerNV platform.
++
++	  This driver can also be built as a module. If so, the module
++	  will be called ibmpowernv.
++
+ config SENSORS_IIO_HWMON
+ 	tristate "Hwmon driver that uses channels specified via iio maps"
+ 	depends on IIO
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 3dc0f02..fc4ed26 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45)	+= ultra45_env.o
+ obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
+ obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
+ obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
++obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
+ obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
+ obj-$(CONFIG_SENSORS_INA209)	+= ina209.o
+ obj-$(CONFIG_SENSORS_INA2XX)	+= ina2xx.o
+diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
+new file mode 100644
+index 0000000..e6b652a
+--- /dev/null
++++ b/drivers/hwmon/ibmpowernv.c
+@@ -0,0 +1,364 @@
++/*
++ * IBM PowerNV platform sensors for temperature/fan/voltage/power
++ * Copyright (C) 2014 IBM
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.
++ */
++
++#define DRVNAME		"ibmpowernv"
++#define pr_fmt(fmt)	DRVNAME ": " fmt
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include <linux/platform_device.h>
++#include <asm/opal.h>
++#include <linux/err.h>
++
++#define MAX_ATTR_LEN	32
++
++/* Sensor suffix name from DT */
++#define DT_FAULT_ATTR_SUFFIX		"faulted"
++#define DT_DATA_ATTR_SUFFIX		"data"
++#define DT_THRESHOLD_ATTR_SUFFIX	"thrs"
++
++/*
++ * Enumerates all the types of sensors in the POWERNV platform and does index
++ * into 'struct sensor_group'
++ */
++enum sensors {
++	FAN,
++	AMBIENT_TEMP,
++	POWER_SUPPLY,
++	POWER_INPUT,
++	MAX_SENSOR_TYPE,
++};
++
++static struct sensor_group {
++	const char *name;
++	const char *compatible;
++	struct attribute_group group;
++	u32 attr_count;
++} sensor_groups[] = {
++	{"fan", "ibm,opal-sensor-cooling-fan"},
++	{"temp", "ibm,opal-sensor-amb-temp"},
++	{"in", "ibm,opal-sensor-power-supply"},
++	{"power", "ibm,opal-sensor-power"}
++};
++
++struct sensor_data {
++	u32 id; /* An opaque id of the firmware for each sensor */
++	enum sensors type;
++	char name[MAX_ATTR_LEN];
++	struct device_attribute dev_attr;
++};
++
++struct platform_data {
++	const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
++	u32 sensors_count; /* Total count of sensors from each group */
++};
++
++/* Platform device representing all the ibmpowernv sensors */
++static struct platform_device *pdevice;
++
++static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
++			   char *buf)
++{
++	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
++						 dev_attr);
++	ssize_t ret;
++	u32 x;
++
++	ret = opal_get_sensor_data(sdata->id, &x);
++	if (ret)
++		return ret;
++
++	/* Convert temperature to milli-degrees */
++	if (sdata->type == AMBIENT_TEMP)
++		x *= 1000;
++	/* Convert power to micro-watts */
++	else if (sdata->type == POWER_INPUT)
++		x *= 1000000;
++
++	return sprintf(buf, "%u\n", x);
++}
++
++static int __init get_sensor_index_attr(const char *name, u32 *index,
++					char *attr)
++{
++	char *hash_pos = strchr(name, '#');
++	char buf[8] = { 0 };
++	char *dash_pos;
++	u32 copy_len;
++	int err;
++
++	if (!hash_pos)
++		return -EINVAL;
++
++	dash_pos = strchr(hash_pos, '-');
++	if (!dash_pos)
++		return -EINVAL;
++
++	copy_len = dash_pos - hash_pos - 1;
++	if (copy_len >= sizeof(buf))
++		return -EINVAL;
++
++	strncpy(buf, hash_pos + 1, copy_len);
++
++	err = kstrtou32(buf, 10, index);
++	if (err)
++		return err;
++
++	strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
++
++	return 0;
++}
++
++/*
++ * This function translates the DT node name into the 'hwmon' attribute name.
++ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
++ * which need to be mapped as fan2_input, temp1_max respectively before
++ * populating them inside hwmon device class.
++ */
++static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,
++					 const char *node_name,
++					 char *hwmon_attr_name)
++{
++	char attr_suffix[MAX_ATTR_LEN];
++	char *attr_name;
++	u32 index;
++	int err;
++
++	err = get_sensor_index_attr(node_name, &index, attr_suffix);
++	if (err) {
++		dev_err(dev, "Sensor device node name '%s' is invalid\n",
++			node_name);
++		return err;
++	}
++
++	if (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {
++		attr_name = "fault";
++	} else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {
++		attr_name = "input";
++	} else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {
++		if (type == AMBIENT_TEMP)
++			attr_name = "max";
++		else if (type == FAN)
++			attr_name = "min";
++		else
++			return -ENOENT;
++	} else {
++		return -ENOENT;
++	}
++
++	snprintf(hwmon_attr_name, MAX_ATTR_LEN, "%s%d_%s",
++		 sensor_groups[type].name, index, attr_name);
++	return 0;
++}
++
++static int __init populate_attr_groups(struct platform_device *pdev)
++{
++	struct platform_data *pdata = platform_get_drvdata(pdev);
++	const struct attribute_group **pgroups = pdata->attr_groups;
++	struct device_node *opal, *np;
++	enum sensors type;
++
++	opal = of_find_node_by_path("/ibm,opal/sensors");
++	if (!opal) {
++		dev_err(&pdev->dev, "Opal node 'sensors' not found\n");
++		return -ENODEV;
++	}
++
++	for_each_child_of_node(opal, np) {
++		if (np->name == NULL)
++			continue;
++
++		for (type = 0; type < MAX_SENSOR_TYPE; type++)
++			if (of_device_is_compatible(np,
++					sensor_groups[type].compatible)) {
++				sensor_groups[type].attr_count++;
++				break;
++			}
++	}
++
++	of_node_put(opal);
++
++	for (type = 0; type < MAX_SENSOR_TYPE; type++) {
++		sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,
++					sizeof(struct attribute *) *
++					(sensor_groups[type].attr_count + 1),
++					GFP_KERNEL);
++		if (!sensor_groups[type].group.attrs)
++			return -ENOMEM;
++
++		pgroups[type] = &sensor_groups[type].group;
++		pdata->sensors_count += sensor_groups[type].attr_count;
++		sensor_groups[type].attr_count = 0;
++	}
++
++	return 0;
++}
++
++/*
++ * Iterate through the device tree for each child of 'sensors' node, create
++ * a sysfs attribute file, the file is named by translating the DT node name
++ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
++ * etc..
++ */
++static int __init create_device_attrs(struct platform_device *pdev)
++{
++	struct platform_data *pdata = platform_get_drvdata(pdev);
++	const struct attribute_group **pgroups = pdata->attr_groups;
++	struct device_node *opal, *np;
++	struct sensor_data *sdata;
++	const __be32 *sensor_id;
++	enum sensors type;
++	u32 count = 0;
++	int err = 0;
++
++	opal = of_find_node_by_path("/ibm,opal/sensors");
++	sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),
++			     GFP_KERNEL);
++	if (!sdata) {
++		err = -ENOMEM;
++		goto exit_put_node;
++	}
++
++	for_each_child_of_node(opal, np) {
++		if (np->name == NULL)
++			continue;
++
++		for (type = 0; type < MAX_SENSOR_TYPE; type++)
++			if (of_device_is_compatible(np,
++					sensor_groups[type].compatible))
++				break;
++
++		if (type == MAX_SENSOR_TYPE)
++			continue;
++
++		sensor_id = of_get_property(np, "sensor-id", NULL);
++		if (!sensor_id) {
++			dev_info(&pdev->dev,
++				 "'sensor-id' missing in the node '%s'\n",
++				 np->name);
++			continue;
++		}
++
++		sdata[count].id = be32_to_cpup(sensor_id);
++		sdata[count].type = type;
++		err = create_hwmon_attr_name(&pdev->dev, type, np->name,
++					     sdata[count].name);
++		if (err)
++			goto exit_put_node;
++
++		sysfs_attr_init(&sdata[count].dev_attr.attr);
++		sdata[count].dev_attr.attr.name = sdata[count].name;
++		sdata[count].dev_attr.attr.mode = S_IRUGO;
++		sdata[count].dev_attr.show = show_sensor;
++
++		pgroups[type]->attrs[sensor_groups[type].attr_count++] =
++				&sdata[count++].dev_attr.attr;
++	}
++
++exit_put_node:
++	of_node_put(opal);
++	return err;
++}
++
++static int __init ibmpowernv_probe(struct platform_device *pdev)
++{
++	struct platform_data *pdata;
++	struct device *hwmon_dev;
++	int err;
++
++	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++	if (!pdata)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pdata);
++	pdata->sensors_count = 0;
++	err = populate_attr_groups(pdev);
++	if (err)
++		return err;
++
++	/* Create sysfs attribute data for each sensor found in the DT */
++	err = create_device_attrs(pdev);
++	if (err)
++		return err;
++
++	/* Finally, register with hwmon */
++	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
++							   pdata,
++							   pdata->attr_groups);
++
++	return PTR_ERR_OR_ZERO(hwmon_dev);
++}
++
++static struct platform_driver ibmpowernv_driver = {
++	.driver = {
++		.owner = THIS_MODULE,
++		.name = DRVNAME,
++	},
++};
++
++static int __init ibmpowernv_init(void)
++{
++	int err;
++
++	pdevice = platform_device_alloc(DRVNAME, 0);
++	if (!pdevice) {
++		pr_err("Device allocation failed\n");
++		err = -ENOMEM;
++		goto exit;
++	}
++
++	err = platform_device_add(pdevice);
++	if (err) {
++		pr_err("Device addition failed (%d)\n", err);
++		goto exit_device_put;
++	}
++
++	err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
++	if (err) {
++		pr_err("Platfrom driver probe failed\n");
++		goto exit_device_del;
++	}
++
++	return 0;
++
++exit_device_del:
++	platform_device_del(pdevice);
++exit_device_put:
++	platform_device_put(pdevice);
++exit:
++	return err;
++}
++
++static void __exit ibmpowernv_exit(void)
++{
++	platform_driver_unregister(&ibmpowernv_driver);
++	platform_device_unregister(pdevice);
++}
++
++MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
++MODULE_DESCRIPTION("IBM POWERNV platform sensors");
++MODULE_LICENSE("GPL");
++
++module_init(ibmpowernv_init);
++module_exit(ibmpowernv_exit);
diff --git a/a/content_digest b/N1/content_digest
index 9d1a780..2fecda4 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,315 +1,581 @@
  "From\0Neelesh Gupta <neelegup@linux.vnet.ibm.com>\0"
- "Subject\0[lm-sensors] [PATCH v5] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature\0"
- "Date\0Tue, 08 Jul 2014 09:20:38 +0000\0"
- "To\0devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
-  linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
- " lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org\0"
- "Cc\0benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org"
-  svaidy-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org
-  sbhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org
-  jdelvare-l3A5Bk7waGM@public.gmane.org
- " linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org\0"
+ "Subject\0[PATCH v5] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature\0"
+ "Date\0Tue, 08 Jul 2014 14:38:38 +0530\0"
+ "To\0devicetree@vger.kernel.org"
+  linuxppc-dev@lists.ozlabs.org
+ " lm-sensors@lm-sensors.org\0"
+ "Cc\0sbhat@linux.vnet.ibm.com"
+  linux@roeck-us.net
+ " jdelvare@suse.de\0"
  "\00:1\0"
  "b\0"
- "VGhpcyBwYXRjaCBhZGRzIGJhc2ljIGtlcm5lbCBzdXBwb3J0IGZvciByZWFkaW5nIHBvd2VyIHZh\n"
- "bHVlcywgZmFuCnNwZWVkIHJwbSwgdm9sdGFnZSBhbmQgdGVtcGVyYXR1cmUgZGF0YSBvbiBwb3dl\n"
- "cm52IHBsYXRmb3JtcyB3aGljaAp3aWxsIGJlIGV4cG9ydGVkIHRvIHVzZXIgc3BhY2UgdGhyb3Vn\n"
- "aCBzeXNmcyBpbnRlcmZhY2UuCgpUZXN0IHJlc3VsdHM6Ci0tLS0tLS0tLS0tLS0KW3Jvb3RAdHVs\n"
- "MTYzcDEgfl0jIHNlbnNvcnMKaWJtcG93ZXJudi1pc2EtMDAwMApBZGFwdGVyOiBJU0EgYWRhcHRl\n"
- "cgpmYW4xOiAgICAgICAgNTQ2NSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuMjogICAgICAgIDUx\n"
- "NTIgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjM6ICAgICAgICA1NTIxIFJQTSAgKG1pbiA9ICAg\n"
- "IDAgUlBNKQpmYW40OiAgICAgICAgNDg5MSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuNTogICAg\n"
- "ICAgICAgIDAgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1p\n"
- "biA9ICAgIDAgUlBNKQpmYW43OiAgICAgICAgNzQ4MCBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFu\n"
- "ODogICAgICAgIDc5NDQgUlBNICAobWluID0gICAgMCBSUE0pCnRlbXAxOiAgICAgICAgKzM5LjDC\n"
- "sEMgIChoaWdoID0gICswLjDCsEMpCnBvd2VyMTogICAgICAxOTAuMDAgVyAgCgpbcm9vdEB0dWwx\n"
- "NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwphbGFybXRpbWVyICBpYm1wb3dlcm52\n"
- "LjAgIHBvd2VyICBydGMtZ2VuZXJpYyAgc2VyaWFsODI1MCAgdWV2ZW50Cltyb290QHR1bDE2M3Ax\n"
- "IH5dIyBscyAvc3lzL2RldmljZXMvcGxhdGZvcm0vaWJtcG93ZXJudi4wL2h3bW9uL2h3bW9uMC8K\n"
- "ZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2Vy\n"
- "CmZhbjFfZmF1bHQgIGZhbjNfZmF1bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQg\n"
- "IHBvd2VyMV9pbnB1dApmYW4xX2lucHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5w\n"
- "dXQJaW4yX2ZhdWx0ICBzdWJzeXN0ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAg\n"
- "ZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZh\n"
- "bjZfZmF1bHQgIGZhbjhfZmF1bHQJaW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFu\n"
- "NF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2\n"
- "M3AxIH5dIyBscyAvc3lzL2NsYXNzL2h3bW9uL2h3bW9uMC8KZGV2aWNlCSAgICBmYW4yX21pbglm\n"
- "YW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2VyCmZhbjFfZmF1bHQgIGZhbjNfZmF1\n"
- "bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQgIHBvd2VyMV9pbnB1dApmYW4xX2lu\n"
- "cHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICBzdWJzeXN0\n"
- "ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0\n"
- "ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZhbjZfZmF1bHQgIGZhbjhfZmF1bHQJ\n"
- "aW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBm\n"
- "YW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2M3AxIH5dIwoKU2lnbmVkLW9mZi1i\n"
- "eTogTmVlbGVzaCBHdXB0YSA8bmVlbGVndXBAbGludXgudm5ldC5pYm0uY29tPgpSZXZpZXdlZC1i\n"
- "eTogR3VlbnRlciBSb2VjayA8bGludXhAcm9lY2stdXMubmV0PgotLS0KCkNoYW5nZXMgaW4gdjUK\n"
- "PT09PT09PT09PT09PQotIEFkZHJlc3NlZCBjb3VwbGUgbWlub3IgY29tbWVudHMgaW4gdjQuCgpD\n"
- "aGFuZ2VzIGluIHY0Cj09PT09PT09PT09PT0KLSBSZXBsYWNlZCBwcl9lcnIoKSB3aXRoIGRldl9l\n"
- "cnIoKSBmb3IgbG9nZ2luZyBwcmludCBtZXNzYWdlcy4KLSBVc2luZyBrc3RydG91MzIoKSBmdW5j\n"
- "dGlvbiBmb3IgY29udmVydGluZyBzdHJpbmcgdG8gdTMyIGluc3RlYWQgb2Ygc3NjYW5mKCkuCgpD\n"
- "aGFuZ2VzIGluIHYzCj09PT09PT09PT09PT0KLSBGaXhlZCBhbiBlbmRpYW5uZXNzIGJ1ZyBsZWFk\n"
- "aW5nIHRoZSBkcml2ZXIgdG8gYnJlYWsgb24gTEUuCi0gRml4ZWQgYSBidWcgdGhhdCB3aGVuIG9u\n"
- "ZSBvZiB0aGUgJ2F0dHJpYnV0ZV9ncm91cCcgbm90IHBvcHVsYXRlZCwgZm9sbG93aW5nCiAgZ3Jv\n"
- "dXBzIGF0dHJpYnV0ZXMgd2VyZSBkcm9wcGVkLgotIFJld3JpdGUgdGhlIGdldF9zZW5zb3JfaW5k\n"
- "ZXhfYXR0cigpIGZ1bmN0aW9uIHRvIGhhbmRsZSBhbGwgdGhlIGVycm9yIHNjZW5hcmlvcwogIGxp\n"
- "a2UgJ3NzY2FuZicgZXRjLgotIEZpeGVkIGFsbCB0aGUgZXJyb3JzL3dhcm5pbmdzIHJlbGF0ZWQg\n"
- "dG8gY29kaW5nIHN0eWxlL3doaXRlc3BhY2UuCi0gQWRkZWQgJ0RvY3VtZW50YXRpb24nIGZpbGVz\n"
- "LgotIEFkZHJlc3NlZCByZW1haW5pbmcgcmV2aWV3IGNvbW1lbnRzIG9uIFYyLgoKQ2hhbmdlcyBp\n"
- "biB2Mgo9PT09PT09PT09PT09Ci0gR2VuZXJpYyB1c2Ugb2YgZGV2bV8qIGZ1bmN0aW9ucyBpbiBo\n"
- "d21vbiBsaWtlIHVzaW5nIGRldm1fa3phbGxvYygpIGZvciBkeW5hbWljCiAgbWVtb3J5IHJlcXVl\n"
- "c3QsIGF2b2lkaW5nIHRoZSBuZWVkIHRvIGV4cGxpY2l0IGZyZWUgb2YgbWVtb3J5LgogIEFkZGlu\n"
- "ZyAnc3RydWN0IGF0dHJpYnV0ZV9ncm91cCcgYXMgbWVtYmVyIG9mIHBsYXRmb3JtIGRhdGEgc3Ry\n"
- "dWN0dXJlIHRvIGJlCiAgcG9wdWxhdGVkIGFuZCB0aGVuIHBhc3NlZCB0byBkZXZtX2h3bW9uX2Rl\n"
- "dmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgoKICBOb3RlOiBIYXZpbmcgYW4gYXJyYXkgb2Yg\n"
- "cG9pbnRlcnMgb2YgJ2F0dHJpYnV0ZV9ncm91cCcgYW5kIGVhY2ggZ3JvdXAKICBjb3JyZXNwb25k\n"
- "cyB0byAnZW51bSBzZW5zb3JzJyB0eXBlLiBOb3QgY29tcGxldGVseSBzdXJlLCBpZiBpdCdzIGlk\n"
- "ZWFsIG9yCiAgY291bGQgaGF2ZSBqdXN0IG9uZSBncm91cCBwb3B1bGF0ZWQgd2l0aCBhdHRyaWJ1\n"
- "dGVzIG9mIHNlbnNvciB0eXBlcz8KCi0gJ2libXBvd2VybnYnIGlzIG5vdCBob3QtcGx1Z2dhYmxl\n"
- "IGRldmljZSBzbyBtb3ZpbmcgJ3BsYXRmb3JtX2RyaXZlcicgY2FsbGJhY2sKICBmdW5jdGlvbiAo\n"
- "cHJvYmUpIGFzIHBhcnQgb2YgX19pbml0IGNvZGUuCi0gRml4ZWQgaXNzdWVzIHJlbGF0ZWQgdG8g\n"
- "Y29kaW5nIHN0eWxlLgotIE90aGVyIGdlbmVyYWwgY29tbWVudHMgaW4gdjEuCgogLi4uL2Rldmlj\n"
- "ZXRyZWUvYmluZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQgICAgICAgfCAgIDIzICsKIERvY3Vt\n"
- "ZW50YXRpb24vaHdtb24vaWJtcG93ZXJudiAgICAgICAgICAgICAgICAgICAgIHwgICA0MSArKwog\n"
- "ZHJpdmVycy9od21vbi9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEx\n"
- "ICsKIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg\n"
- "ICAgMSAKIGRyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jICAgICAgICAgICAgICAgICAgICAgICAg\n"
- "IHwgIDM2NCArKysrKysrKysrKysrKysrKysrKwogNSBmaWxlcyBjaGFuZ2VkLCA0NDAgaW5zZXJ0\n"
- "aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5k\n"
- "aW5ncy9od21vbi9pYm1wb3dlcm52LnR4dAogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp\n"
- "b24vaHdtb24vaWJtcG93ZXJudgogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaHdtb24vaWJt\n"
- "cG93ZXJudi5jCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz\n"
- "L2h3bW9uL2libXBvd2VybnYudHh0IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz\n"
- "L2h3bW9uL2libXBvd2VybnYudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu\n"
- "LmY5MzI0MmIKLS0tIC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmlu\n"
- "ZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQKQEAgLTAsMCArMSwyMyBAQAorSUJNIFBPV0VSTlYg\n"
- "cGxhdGZvcm0gc2Vuc29ycworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZXF1aXJl\n"
- "ZCBub2RlIHByb3BlcnRpZXM6CistIGNvbXBhdGlibGU6IG11c3QgYmUgb25lIG9mCisJCSJpYm0s\n"
- "b3BhbC1zZW5zb3ItY29vbGluZy1mYW4iCisJCSJpYm0sb3BhbC1zZW5zb3ItYW1iLXRlbXAiCisJ\n"
- "CSJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3VwcGx5IgorCQkiaWJtLG9wYWwtc2Vuc29yLXBvd2Vy\n"
- "IgorLSBzZW5zb3ItaWQ6IGFuIG9wYXF1ZSBpZCBwcm92aWRlZCBieSB0aGUgZmlybXdhcmUgdG8g\n"
- "dGhlIGtlcm5lbCwgaWRlbnRpZmllcyBhCisJICAgICBnaXZlbiBzZW5zb3IgYW5kIGl0cyBhdHRy\n"
- "aWJ1dGUgZGF0YQorCitFeGFtcGxlIHNlbnNvcnMgbm9kZToKKworY29vbGluZy1mYW4jOC1kYXRh\n"
- "IHsKKwlzZW5zb3ItaWQgPSA8MHg3MDUyMTA3PjsKKwljb21wYXRpYmxlID0gImlibSxvcGFsLXNl\n"
- "bnNvci1jb29saW5nLWZhbiI7Cit9OworCithbWItdGVtcCMxLXRocnMgeworCXNlbnNvci1pZCA9\n"
- "IDwweDUwOTYwMDA+OworCWNvbXBhdGlibGUgPSAiaWJtLG9wYWwtc2Vuc29yLWFtYi10ZW1wIjsK\n"
- "K307CmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYgYi9Eb2N1bWVu\n"
- "dGF0aW9uL2h3bW9uL2libXBvd2VybnYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw\n"
- "MC4uNjQ0MjQ1YQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdtb24vaWJtcG93\n"
- "ZXJudgpAQCAtMCwwICsxLDQxIEBACitLZXJuZWwgRHJpdmVyIElCTVBPV0VOVgorPT09PT09PT09\n"
- "PT09PT09PT09PT09PT0KKworU3VwcG9ydGVkIHN5c3RlbXM6CisgICogQW55IHJlY2VudCBJQk0g\n"
- "UCBzZXJ2ZXJzIGJhc2VkIG9uIFBPV0VSTlYgcGxhdGZvcm0KKworQXV0aG9yOiBOZWVsZXNoIEd1\n"
- "cHRhCisKK0Rlc2NyaXB0aW9uCistLS0tLS0tLS0tLQorCitUaGlzIGRyaXZlciBpbXBsZW1lbnRz\n"
- "IHJlYWRpbmcgdGhlIHBsYXRmb3JtIHNlbnNvcnMgZGF0YSBsaWtlIHRlbXBlcmF0dXJlL2Zhbi8K\n"
- "K3ZvbHRhZ2UvcG93ZXIgZm9yICdQT1dFUk5WJyBwbGF0Zm9ybS4KKworVGhlIGRyaXZlciB1c2Vz\n"
- "IHRoZSBwbGF0Zm9ybSBkZXZpY2UgaW5mcmFzdHJ1Y3R1cmUuIEl0IHByb2JlcyB0aGUgZGV2aWNl\n"
- "IHRyZWUKK2ZvciBzZW5zb3IgZGV2aWNlcyBkdXJpbmcgdGhlIF9faW5pdCBwaGFzZSBhbmQgcmVn\n"
- "aXN0ZXJzIHRoZW0gd2l0aCB0aGUgJ2h3bW9uJy4KKydod21vbicgcG9wdWxhdGVzIHRoZSAnc3lz\n"
- "ZnMnIHRyZWUgaGF2aW5nIGF0dHJpYnV0ZSBmaWxlcywgZWFjaCBmb3IgYSBnaXZlbgorc2Vuc29y\n"
- "IHR5cGUgYW5kIGl0cyBhdHRyaWJ1dGUgZGF0YS4KKworQWxsIHRoZSBub2RlcyBpbiB0aGUgRFQg\n"
- "YXBwZWFyIHVuZGVyICIvaWJtLG9wYWwvc2Vuc29ycyIgYW5kIGVhY2ggdmFsaWQgbm9kZSBpbgor\n"
- "dGhlIERUIG1hcHMgdG8gYW4gYXR0cmlidXRlIGZpbGUgaW4gJ3N5c2ZzJy4gVGhlIG5vZGUgZXhw\n"
- "b3J0cyB1bmlxdWUgJ3NlbnNvci1pZCcKK3doaWNoIHRoZSBkcml2ZXIgdXNlcyB0byBtYWtlIGFu\n"
- "IE9QQUwgY2FsbCB0byB0aGUgZmlybXdhcmUuCisKK1VzYWdlIG5vdGVzCistLS0tLS0tLS0tLQor\n"
- "VGhlIGRyaXZlciBpcyBidWlsdCBzdGF0aWNhbGx5IHdpdGggdGhlIGtlcm5lbCBieSBlbmFibGlu\n"
- "ZyB0aGUgY29uZmlnCitDT05GSUdfU0VOU09SU19JQk1QT1dFUk5WLiBJdCBjYW4gYWxzbyBiZSBi\n"
- "dWlsdCBhcyBtb2R1bGUgJ2libXBvd2VybnYnLgorCitTeXNmcyBhdHRyaWJ1dGVzCistLS0tLS0t\n"
- "LS0tLS0tLS0tCisKK2ZhblhfaW5wdXQJCU1lYXN1cmVkIFJQTSB2YWx1ZS4KK2ZhblhfbWluCQlU\n"
- "aHJlc2hvbGQgUlBNIGZvciBhbGVydCBnZW5lcmF0aW9uLgorZmFuWF9mYXVsdAkJMDogTm8gZmFp\n"
- "bCBjb25kaXRpb24KKwkJCTE6IEZhaWxpbmcgZmFuCit0ZW1wWF9pbnB1dAkJTWVhc3VyZWQgYW1i\n"
- "aWVudCB0ZW1wZXJhdHVyZS4KK3RlbXBYX21heAkJVGhyZXNob2xkIGFtYmllbnQgdGVtcGVyYXR1\n"
- "cmUgZm9yIGFsZXJ0IGdlbmVyYXRpb24uCitpblhfaW5wdXQJCU1lYXN1cmVkIHBvd2VyIHN1cHBs\n"
- "eSB2b2x0YWdlCitpblhfZmF1bHQJCTA6IE5vIGZhaWwgY29uZGl0aW9uLgorCQkJMTogRmFpbGlu\n"
- "ZyBwb3dlciBzdXBwbHkuCitwb3dlcjFfaW5wdXQJCVN5c3RlbSBwb3dlciBjb25zdW1wdGlvbiAo\n"
- "bWljcm9XYXR0KQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9o\n"
- "d21vbi9LY29uZmlnCmluZGV4IDAyZDNkODUuLjI5YzNmY2IgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMv\n"
- "aHdtb24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKQEAgLTU1NCw2ICs1NTQs\n"
- "MTcgQEAgY29uZmlnIFNFTlNPUlNfSUJNUEVYCiAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBi\n"
- "dWlsdCBhcyBhIG1vZHVsZS4gIElmIHNvLCB0aGUgbW9kdWxlCiAJICB3aWxsIGJlIGNhbGxlZCBp\n"
- "Ym1wZXguCiAKK2NvbmZpZyBTRU5TT1JTX0lCTVBPV0VSTlYKKwl0cmlzdGF0ZSAiSUJNIFBPV0VS\n"
- "TlYgcGxhdGZvcm0gc2Vuc29ycyIKKwlkZXBlbmRzIG9uIFBQQ19QT1dFUk5WCisJZGVmYXVsdCB5\n"
- "CisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIHRoZSB0\n"
- "ZW1wZXJhdHVyZS9mYW4vcG93ZXIKKwkgIHNlbnNvcnMgb24geW91ciBQb3dlck5WIHBsYXRmb3Jt\n"
- "LgorCisJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28s\n"
- "IHRoZSBtb2R1bGUKKwkgIHdpbGwgYmUgY2FsbGVkIGlibXBvd2VybnYuCisKIGNvbmZpZyBTRU5T\n"
- "T1JTX0lJT19IV01PTgogCXRyaXN0YXRlICJId21vbiBkcml2ZXIgdGhhdCB1c2VzIGNoYW5uZWxz\n"
- "IHNwZWNpZmllZCB2aWEgaWlvIG1hcHMiCiAJZGVwZW5kcyBvbiBJSU8KZGlmZiAtLWdpdCBhL2Ry\n"
- "aXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCmluZGV4IDNkYzBm\n"
- "MDIuLmZjNGVkMjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKKysrIGIvZHJp\n"
- "dmVycy9od21vbi9NYWtlZmlsZQpAQCAtNzEsNiArNzEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S\n"
- "U19VTFRSQTQ1KQkrPSB1bHRyYTQ1X2Vudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JNUtfQU1C\n"
- "KQkrPSBpNWtfYW1iLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0lCTUFFTSkJKz0gaWJtYWVtLm8K\n"
- "IG9iai0kKENPTkZJR19TRU5TT1JTX0lCTVBFWCkJKz0gaWJtcGV4Lm8KK29iai0kKENPTkZJR19T\n"
- "RU5TT1JTX0lCTVBPV0VSTlYpKz0gaWJtcG93ZXJudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19J\n"
- "SU9fSFdNT04pICs9IGlpb19od21vbi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyMDkpCSs9\n"
- "IGluYTIwOS5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyWFgpCSs9IGluYTJ4eC5vCmRpZmYg\n"
- "LS1naXQgYS9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYyBiL2RyaXZlcnMvaHdtb24vaWJtcG93\n"
- "ZXJudi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YjY1MmEKLS0tIC9k\n"
- "ZXYvbnVsbAorKysgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwpAQCAtMCwwICsxLDM2NCBA\n"
- "QAorLyoKKyAqIElCTSBQb3dlck5WIHBsYXRmb3JtIHNlbnNvcnMgZm9yIHRlbXBlcmF0dXJlL2Zh\n"
- "bi92b2x0YWdlL3Bvd2VyCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSUJNCisgKgorICogVGhpcyBw\n"
- "cm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBt\n"
- "b2RpZnkKKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExp\n"
- "Y2Vuc2UgYXMgcHVibGlzaGVkIGJ5CisgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBl\n"
- "aXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICogKGF0IHlvdXIgb3B0aW9uKSBh\n"
- "bnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g\n"
- "dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJS\n"
- "QU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFC\n"
- "SUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBH\n"
- "TlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqIFlvdSBz\n"
- "aG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl\n"
- "bnNlCisgKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4KKyAqLworCisjZGVmaW5lIERSVk5BTUUJ\n"
- "CSJpYm1wb3dlcm52IgorI2RlZmluZSBwcl9mbXQoZm10KQlEUlZOQU1FICI6ICIgZm10CisKKyNp\n"
- "bmNsdWRlIDxsaW51eC9pbml0Lmg+CisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CisjaW5jbHVk\n"
- "ZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KKyNpbmNsdWRlIDxs\n"
- "aW51eC9od21vbi1zeXNmcy5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGlu\n"
- "dXgvc2xhYi5oPgorCisjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CisjaW5jbHVk\n"
- "ZSA8YXNtL29wYWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKworI2RlZmluZSBNQVhfQVRU\n"
- "Ul9MRU4JMzIKKworLyogU2Vuc29yIHN1ZmZpeCBuYW1lIGZyb20gRFQgKi8KKyNkZWZpbmUgRFRf\n"
- "RkFVTFRfQVRUUl9TVUZGSVgJCSJmYXVsdGVkIgorI2RlZmluZSBEVF9EQVRBX0FUVFJfU1VGRklY\n"
- "CQkiZGF0YSIKKyNkZWZpbmUgRFRfVEhSRVNIT0xEX0FUVFJfU1VGRklYCSJ0aHJzIgorCisvKgor\n"
- "ICogRW51bWVyYXRlcyBhbGwgdGhlIHR5cGVzIG9mIHNlbnNvcnMgaW4gdGhlIFBPV0VSTlYgcGxh\n"
- "dGZvcm0gYW5kIGRvZXMgaW5kZXgKKyAqIGludG8gJ3N0cnVjdCBzZW5zb3JfZ3JvdXAnCisgKi8K\n"
- "K2VudW0gc2Vuc29ycyB7CisJRkFOLAorCUFNQklFTlRfVEVNUCwKKwlQT1dFUl9TVVBQTFksCisJ\n"
- "UE9XRVJfSU5QVVQsCisJTUFYX1NFTlNPUl9UWVBFLAorfTsKKworc3RhdGljIHN0cnVjdCBzZW5z\n"
- "b3JfZ3JvdXAgeworCWNvbnN0IGNoYXIgKm5hbWU7CisJY29uc3QgY2hhciAqY29tcGF0aWJsZTsK\n"
- "KwlzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGdyb3VwOworCXUzMiBhdHRyX2NvdW50OworfSBzZW5z\n"
- "b3JfZ3JvdXBzW10gPSB7CisJeyJmYW4iLCAiaWJtLG9wYWwtc2Vuc29yLWNvb2xpbmctZmFuIn0s\n"
- "CisJeyJ0ZW1wIiwgImlibSxvcGFsLXNlbnNvci1hbWItdGVtcCJ9LAorCXsiaW4iLCAiaWJtLG9w\n"
- "YWwtc2Vuc29yLXBvd2VyLXN1cHBseSJ9LAorCXsicG93ZXIiLCAiaWJtLG9wYWwtc2Vuc29yLXBv\n"
- "d2VyIn0KK307CisKK3N0cnVjdCBzZW5zb3JfZGF0YSB7CisJdTMyIGlkOyAvKiBBbiBvcGFxdWUg\n"
- "aWQgb2YgdGhlIGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLworCWVudW0gc2Vuc29ycyB0eXBl\n"
- "OworCWNoYXIgbmFtZVtNQVhfQVRUUl9MRU5dOworCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRl\n"
- "dl9hdHRyOworfTsKKworc3RydWN0IHBsYXRmb3JtX2RhdGEgeworCWNvbnN0IHN0cnVjdCBhdHRy\n"
- "aWJ1dGVfZ3JvdXAgKmF0dHJfZ3JvdXBzW01BWF9TRU5TT1JfVFlQRSArIDFdOworCXUzMiBzZW5z\n"
- "b3JzX2NvdW50OyAvKiBUb3RhbCBjb3VudCBvZiBzZW5zb3JzIGZyb20gZWFjaCBncm91cCAqLwor\n"
- "fTsKKworLyogUGxhdGZvcm0gZGV2aWNlIHJlcHJlc2VudGluZyBhbGwgdGhlIGlibXBvd2VybnYg\n"
- "c2Vuc29ycyAqLworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXZpY2U7CisKK3N0\n"
- "YXRpYyBzc2l6ZV90IHNob3dfc2Vuc29yKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmlj\n"
- "ZV9hdHRyaWJ1dGUgKmRldmF0dHIsCisJCQkgICBjaGFyICpidWYpCit7CisJc3RydWN0IHNlbnNv\n"
- "cl9kYXRhICpzZGF0YSA9IGNvbnRhaW5lcl9vZihkZXZhdHRyLCBzdHJ1Y3Qgc2Vuc29yX2RhdGEs\n"
- "CisJCQkJCQkgZGV2X2F0dHIpOworCXNzaXplX3QgcmV0OworCXUzMiB4OworCisJcmV0ID0gb3Bh\n"
- "bF9nZXRfc2Vuc29yX2RhdGEoc2RhdGEtPmlkLCAmeCk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl\n"
- "dDsKKworCS8qIENvbnZlcnQgdGVtcGVyYXR1cmUgdG8gbWlsbGktZGVncmVlcyAqLworCWlmIChz\n"
- "ZGF0YS0+dHlwZSA9PSBBTUJJRU5UX1RFTVApCisJCXggKj0gMTAwMDsKKwkvKiBDb252ZXJ0IHBv\n"
- "d2VyIHRvIG1pY3JvLXdhdHRzICovCisJZWxzZSBpZiAoc2RhdGEtPnR5cGUgPT0gUE9XRVJfSU5Q\n"
- "VVQpCisJCXggKj0gMTAwMDAwMDsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiV1XG4iLCB4KTsK\n"
- "K30KKworc3RhdGljIGludCBfX2luaXQgZ2V0X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0IGNoYXIg\n"
- "Km5hbWUsIHUzMiAqaW5kZXgsCisJCQkJCWNoYXIgKmF0dHIpCit7CisJY2hhciAqaGFzaF9wb3Mg\n"
- "PSBzdHJjaHIobmFtZSwgJyMnKTsKKwljaGFyIGJ1Zls4XSA9IHsgMCB9OworCWNoYXIgKmRhc2hf\n"
- "cG9zOworCXUzMiBjb3B5X2xlbjsKKwlpbnQgZXJyOworCisJaWYgKCFoYXNoX3BvcykKKwkJcmV0\n"
- "dXJuIC1FSU5WQUw7CisKKwlkYXNoX3BvcyA9IHN0cmNocihoYXNoX3BvcywgJy0nKTsKKwlpZiAo\n"
- "IWRhc2hfcG9zKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWNvcHlfbGVuID0gZGFzaF9wb3MgLSBo\n"
- "YXNoX3BvcyAtIDE7CisJaWYgKGNvcHlfbGVuID49IHNpemVvZihidWYpKQorCQlyZXR1cm4gLUVJ\n"
- "TlZBTDsKKworCXN0cm5jcHkoYnVmLCBoYXNoX3BvcyArIDEsIGNvcHlfbGVuKTsKKworCWVyciA9\n"
- "IGtzdHJ0b3UzMihidWYsIDEwLCBpbmRleCk7CisJaWYgKGVycikKKwkJcmV0dXJuIGVycjsKKwor\n"
- "CXN0cm5jcHkoYXR0ciwgZGFzaF9wb3MgKyAxLCBNQVhfQVRUUl9MRU4pOworCisJcmV0dXJuIDA7\n"
- "Cit9CisKKy8qCisgKiBUaGlzIGZ1bmN0aW9uIHRyYW5zbGF0ZXMgdGhlIERUIG5vZGUgbmFtZSBp\n"
- "bnRvIHRoZSAnaHdtb24nIGF0dHJpYnV0ZSBuYW1lLgorICogSUJNUE9XRVJOViBkZXZpY2Ugbm9k\n"
- "ZSBhcHBlYXIgbGlrZSBjb29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCisg\n"
- "KiB3aGljaCBuZWVkIHRvIGJlIG1hcHBlZCBhcyBmYW4yX2lucHV0LCB0ZW1wMV9tYXggcmVzcGVj\n"
- "dGl2ZWx5IGJlZm9yZQorICogcG9wdWxhdGluZyB0aGVtIGluc2lkZSBod21vbiBkZXZpY2UgY2xh\n"
- "c3MuCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9od21vbl9hdHRyX25hbWUoc3RydWN0\n"
- "IGRldmljZSAqZGV2LCBlbnVtIHNlbnNvcnMgdHlwZSwKKwkJCQkJIGNvbnN0IGNoYXIgKm5vZGVf\n"
- "bmFtZSwKKwkJCQkJIGNoYXIgKmh3bW9uX2F0dHJfbmFtZSkKK3sKKwljaGFyIGF0dHJfc3VmZml4\n"
- "W01BWF9BVFRSX0xFTl07CisJY2hhciAqYXR0cl9uYW1lOworCXUzMiBpbmRleDsKKwlpbnQgZXJy\n"
- "OworCisJZXJyID0gZ2V0X3NlbnNvcl9pbmRleF9hdHRyKG5vZGVfbmFtZSwgJmluZGV4LCBhdHRy\n"
- "X3N1ZmZpeCk7CisJaWYgKGVycikgeworCQlkZXZfZXJyKGRldiwgIlNlbnNvciBkZXZpY2Ugbm9k\n"
- "ZSBuYW1lICclcycgaXMgaW52YWxpZFxuIiwKKwkJCW5vZGVfbmFtZSk7CisJCXJldHVybiBlcnI7\n"
- "CisJfQorCisJaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX0ZBVUxUX0FUVFJfU1VGRklYKSkg\n"
- "eworCQlhdHRyX25hbWUgPSAiZmF1bHQiOworCX0gZWxzZSBpZiAoIXN0cmNtcChhdHRyX3N1ZmZp\n"
- "eCwgRFRfREFUQV9BVFRSX1NVRkZJWCkpIHsKKwkJYXR0cl9uYW1lID0gImlucHV0IjsKKwl9IGVs\n"
- "c2UgaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX1RIUkVTSE9MRF9BVFRSX1NVRkZJWCkpIHsK\n"
- "KwkJaWYgKHR5cGUgPT0gQU1CSUVOVF9URU1QKQorCQkJYXR0cl9uYW1lID0gIm1heCI7CisJCWVs\n"
- "c2UgaWYgKHR5cGUgPT0gRkFOKQorCQkJYXR0cl9uYW1lID0gIm1pbiI7CisJCWVsc2UKKwkJCXJl\n"
- "dHVybiAtRU5PRU5UOworCX0gZWxzZSB7CisJCXJldHVybiAtRU5PRU5UOworCX0KKworCXNucHJp\n"
- "bnRmKGh3bW9uX2F0dHJfbmFtZSwgTUFYX0FUVFJfTEVOLCAiJXMlZF8lcyIsCisJCSBzZW5zb3Jf\n"
- "Z3JvdXBzW3R5cGVdLm5hbWUsIGluZGV4LCBhdHRyX25hbWUpOworCXJldHVybiAwOworfQorCitz\n"
- "dGF0aWMgaW50IF9faW5pdCBwb3B1bGF0ZV9hdHRyX2dyb3VwcyhzdHJ1Y3QgcGxhdGZvcm1fZGV2\n"
- "aWNlICpwZGV2KQoreworCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dl\n"
- "dF9kcnZkYXRhKHBkZXYpOworCWNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKipwZ3JvdXBz\n"
- "ID0gcGRhdGEtPmF0dHJfZ3JvdXBzOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqb3BhbCwgKm5wOwor\n"
- "CWVudW0gc2Vuc29ycyB0eXBlOworCisJb3BhbCA9IG9mX2ZpbmRfbm9kZV9ieV9wYXRoKCIvaWJt\n"
- "LG9wYWwvc2Vuc29ycyIpOworCWlmICghb3BhbCkgeworCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJP\n"
- "cGFsIG5vZGUgJ3NlbnNvcnMnIG5vdCBmb3VuZFxuIik7CisJCXJldHVybiAtRU5PREVWOworCX0K\n"
- "KworCWZvcl9lYWNoX2NoaWxkX29mX25vZGUob3BhbCwgbnApIHsKKwkJaWYgKG5wLT5uYW1lID09\n"
- "IE5VTEwpCisJCQljb250aW51ZTsKKworCQlmb3IgKHR5cGUgPSAwOyB0eXBlIDwgTUFYX1NFTlNP\n"
- "Ul9UWVBFOyB0eXBlKyspCisJCQlpZiAob2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsCisJCQkJ\n"
- "CXNlbnNvcl9ncm91cHNbdHlwZV0uY29tcGF0aWJsZSkpIHsKKwkJCQlzZW5zb3JfZ3JvdXBzW3R5\n"
- "cGVdLmF0dHJfY291bnQrKzsKKwkJCQlicmVhazsKKwkJCX0KKwl9CisKKwlvZl9ub2RlX3B1dChv\n"
- "cGFsKTsKKworCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykg\n"
- "eworCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzID0gZGV2bV9remFsbG9jKCZwZGV2\n"
- "LT5kZXYsCisJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRlICopICoKKwkJCQkJKHNlbnNvcl9n\n"
- "cm91cHNbdHlwZV0uYXR0cl9jb3VudCArIDEpLAorCQkJCQlHRlBfS0VSTkVMKTsKKwkJaWYgKCFz\n"
- "ZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzKQorCQkJcmV0dXJuIC1FTk9NRU07CisKKwkJ\n"
- "cGdyb3Vwc1t0eXBlXSA9ICZzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwOworCQlwZGF0YS0+c2Vu\n"
- "c29yc19jb3VudCArPSBzZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291bnQ7CisJCXNlbnNvcl9n\n"
- "cm91cHNbdHlwZV0uYXR0cl9jb3VudCA9IDA7CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisg\n"
- "KiBJdGVyYXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVlIGZvciBlYWNoIGNoaWxkIG9mICdzZW5z\n"
- "b3JzJyBub2RlLCBjcmVhdGUKKyAqIGEgc3lzZnMgYXR0cmlidXRlIGZpbGUsIHRoZSBmaWxlIGlz\n"
- "IG5hbWVkIGJ5IHRyYW5zbGF0aW5nIHRoZSBEVCBub2RlIG5hbWUKKyAqIHRvIHRoZSBuYW1lIHJl\n"
- "cXVpcmVkIGJ5IHRoZSBoaWdoZXIgJ2h3bW9uJyBkcml2ZXIgbGlrZSBmYW4xX2lucHV0LCB0ZW1w\n"
- "MV9tYXgKKyAqIGV0Yy4uCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9kZXZpY2VfYXR0\n"
- "cnMoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgcGxhdGZvcm1fZGF0\n"
- "YSAqcGRhdGEgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwljb25zdCBzdHJ1Y3QgYXR0\n"
- "cmlidXRlX2dyb3VwICoqcGdyb3VwcyA9IHBkYXRhLT5hdHRyX2dyb3VwczsKKwlzdHJ1Y3QgZGV2\n"
- "aWNlX25vZGUgKm9wYWwsICpucDsKKwlzdHJ1Y3Qgc2Vuc29yX2RhdGEgKnNkYXRhOworCWNvbnN0\n"
- "IF9fYmUzMiAqc2Vuc29yX2lkOworCWVudW0gc2Vuc29ycyB0eXBlOworCXUzMiBjb3VudCA9IDA7\n"
- "CisJaW50IGVyciA9IDA7CisKKwlvcGFsID0gb2ZfZmluZF9ub2RlX2J5X3BhdGgoIi9pYm0sb3Bh\n"
- "bC9zZW5zb3JzIik7CisJc2RhdGEgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgcGRhdGEtPnNl\n"
- "bnNvcnNfY291bnQgKiBzaXplb2YoKnNkYXRhKSwKKwkJCSAgICAgR0ZQX0tFUk5FTCk7CisJaWYg\n"
- "KCFzZGF0YSkgeworCQllcnIgPSAtRU5PTUVNOworCQlnb3RvIGV4aXRfcHV0X25vZGU7CisJfQor\n"
- "CisJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShvcGFsLCBucCkgeworCQlpZiAobnAtPm5hbWUgPT0g\n"
- "TlVMTCkKKwkJCWNvbnRpbnVlOworCisJCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09S\n"
- "X1RZUEU7IHR5cGUrKykKKwkJCWlmIChvZl9kZXZpY2VfaXNfY29tcGF0aWJsZShucCwKKwkJCQkJ\n"
- "c2Vuc29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkKKwkJCQlicmVhazsKKworCQlpZiAodHlw\n"
- "ZSA9PSBNQVhfU0VOU09SX1RZUEUpCisJCQljb250aW51ZTsKKworCQlzZW5zb3JfaWQgPSBvZl9n\n"
- "ZXRfcHJvcGVydHkobnAsICJzZW5zb3ItaWQiLCBOVUxMKTsKKwkJaWYgKCFzZW5zb3JfaWQpIHsK\n"
- "KwkJCWRldl9pbmZvKCZwZGV2LT5kZXYsCisJCQkJICInc2Vuc29yLWlkJyBtaXNzaW5nIGluIHRo\n"
- "ZSBub2RlICclcydcbiIsCisJCQkJIG5wLT5uYW1lKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJ\n"
- "c2RhdGFbY291bnRdLmlkID0gYmUzMl90b19jcHVwKHNlbnNvcl9pZCk7CisJCXNkYXRhW2NvdW50\n"
- "XS50eXBlID0gdHlwZTsKKwkJZXJyID0gY3JlYXRlX2h3bW9uX2F0dHJfbmFtZSgmcGRldi0+ZGV2\n"
- "LCB0eXBlLCBucC0+bmFtZSwKKwkJCQkJICAgICBzZGF0YVtjb3VudF0ubmFtZSk7CisJCWlmIChl\n"
- "cnIpCisJCQlnb3RvIGV4aXRfcHV0X25vZGU7CisKKwkJc3lzZnNfYXR0cl9pbml0KCZzZGF0YVtj\n"
- "b3VudF0uZGV2X2F0dHIuYXR0cik7CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5hdHRyLm5hbWUg\n"
- "PSBzZGF0YVtjb3VudF0ubmFtZTsKKwkJc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIubW9kZSA9\n"
- "IFNfSVJVR087CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5zaG93ID0gc2hvd19zZW5zb3I7CisK\n"
- "KwkJcGdyb3Vwc1t0eXBlXS0+YXR0cnNbc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50Kytd\n"
- "ID0KKwkJCQkmc2RhdGFbY291bnQrK10uZGV2X2F0dHIuYXR0cjsKKwl9CisKK2V4aXRfcHV0X25v\n"
- "ZGU6CisJb2Zfbm9kZV9wdXQob3BhbCk7CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIGludCBf\n"
- "X2luaXQgaWJtcG93ZXJudl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQorewor\n"
- "CXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YTsKKwlzdHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7\n"
- "CisJaW50IGVycjsKKworCXBkYXRhID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigq\n"
- "cGRhdGEpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXBkYXRhKQorCQlyZXR1cm4gLUVOT01FTTsKKwor\n"
- "CXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIHBkYXRhKTsKKwlwZGF0YS0+c2Vuc29yc19jb3Vu\n"
- "dCA9IDA7CisJZXJyID0gcG9wdWxhdGVfYXR0cl9ncm91cHMocGRldik7CisJaWYgKGVycikKKwkJ\n"
- "cmV0dXJuIGVycjsKKworCS8qIENyZWF0ZSBzeXNmcyBhdHRyaWJ1dGUgZGF0YSBmb3IgZWFjaCBz\n"
- "ZW5zb3IgZm91bmQgaW4gdGhlIERUICovCisJZXJyID0gY3JlYXRlX2RldmljZV9hdHRycyhwZGV2\n"
- "KTsKKwlpZiAoZXJyKQorCQlyZXR1cm4gZXJyOworCisJLyogRmluYWxseSwgcmVnaXN0ZXIgd2l0\n"
- "aCBod21vbiAqLworCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhf\n"
- "Z3JvdXBzKCZwZGV2LT5kZXYsIERSVk5BTUUsCisJCQkJCQkJICAgcGRhdGEsCisJCQkJCQkJICAg\n"
- "cGRhdGEtPmF0dHJfZ3JvdXBzKTsKKworCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2\n"
- "KTsKK30KKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaWJtcG93ZXJudl9kcml2ZXIg\n"
- "PSB7CisJLmRyaXZlciA9IHsKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJCS5uYW1lID0gRFJW\n"
- "TkFNRSwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgaWJtcG93ZXJudl9pbml0KHZvaWQp\n"
- "Cit7CisJaW50IGVycjsKKworCXBkZXZpY2UgPSBwbGF0Zm9ybV9kZXZpY2VfYWxsb2MoRFJWTkFN\n"
- "RSwgMCk7CisJaWYgKCFwZGV2aWNlKSB7CisJCXByX2VycigiRGV2aWNlIGFsbG9jYXRpb24gZmFp\n"
- "bGVkXG4iKTsKKwkJZXJyID0gLUVOT01FTTsKKwkJZ290byBleGl0OworCX0KKworCWVyciA9IHBs\n"
- "YXRmb3JtX2RldmljZV9hZGQocGRldmljZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIkRldmlj\n"
- "ZSBhZGRpdGlvbiBmYWlsZWQgKCVkKVxuIiwgZXJyKTsKKwkJZ290byBleGl0X2RldmljZV9wdXQ7\n"
- "CisJfQorCisJZXJyID0gcGxhdGZvcm1fZHJpdmVyX3Byb2JlKCZpYm1wb3dlcm52X2RyaXZlciwg\n"
- "aWJtcG93ZXJudl9wcm9iZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIlBsYXRmcm9tIGRyaXZl\n"
- "ciBwcm9iZSBmYWlsZWRcbiIpOworCQlnb3RvIGV4aXRfZGV2aWNlX2RlbDsKKwl9CisKKwlyZXR1\n"
- "cm4gMDsKKworZXhpdF9kZXZpY2VfZGVsOgorCXBsYXRmb3JtX2RldmljZV9kZWwocGRldmljZSk7\n"
- "CitleGl0X2RldmljZV9wdXQ6CisJcGxhdGZvcm1fZGV2aWNlX3B1dChwZGV2aWNlKTsKK2V4aXQ6\n"
- "CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IGlibXBvd2VybnZfZXhpdCh2\n"
- "b2lkKQoreworCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZpYm1wb3dlcm52X2RyaXZlcik7\n"
- "CisJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIocGRldmljZSk7Cit9CisKK01PRFVMRV9BVVRI\n"
- "T1IoIk5lZWxlc2ggR3VwdGEgPG5lZWxlZ3VwQGxpbnV4LnZuZXQuaWJtLmNvbT4iKTsKK01PRFVM\n"
- "RV9ERVNDUklQVElPTigiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIpOworTU9EVUxFX0xJ\n"
- "Q0VOU0UoIkdQTCIpOworCittb2R1bGVfaW5pdChpYm1wb3dlcm52X2luaXQpOworbW9kdWxlX2V4\n"
- "aXQoaWJtcG93ZXJudl9leGl0KTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n"
- "X19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNv\n"
- "cnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNl\n"
- bnNvcnM
+ "This patch adds basic kernel support for reading power values, fan\n"
+ "speed rpm, voltage and temperature data on powernv platforms which\n"
+ "will be exported to user space through sysfs interface.\n"
+ "\n"
+ "Test results:\n"
+ "-------------\n"
+ "[root@tul163p1 ~]# sensors\n"
+ "ibmpowernv-isa-0000\n"
+ "Adapter: ISA adapter\n"
+ "fan1:        5465 RPM  (min =    0 RPM)\n"
+ "fan2:        5152 RPM  (min =    0 RPM)\n"
+ "fan3:        5521 RPM  (min =    0 RPM)\n"
+ "fan4:        4891 RPM  (min =    0 RPM)\n"
+ "fan5:           0 RPM  (min =    0 RPM)\n"
+ "fan6:           0 RPM  (min =    0 RPM)\n"
+ "fan7:        7480 RPM  (min =    0 RPM)\n"
+ "fan8:        7944 RPM  (min =    0 RPM)\n"
+ "temp1:        +39.0\302\260C  (high =  +0.0\302\260C)\n"
+ "power1:      190.00 W  \n"
+ "\n"
+ "[root@tul163p1 ~]# ls /sys/devices/platform/\n"
+ "alarmtimer  ibmpowernv.0  power  rtc-generic  serial8250  uevent\n"
+ "[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/\n"
+ "device\t    fan2_min\tfan4_min    fan6_min\tfan8_min   power\n"
+ "fan1_fault  fan3_fault\tfan5_fault  fan7_fault\tin1_fault  power1_input\n"
+ "fan1_input  fan3_input\tfan5_input  fan7_input\tin2_fault  subsystem\n"
+ "fan1_min    fan3_min\tfan5_min    fan7_min\tin3_fault  temp1_input\n"
+ "fan2_fault  fan4_fault\tfan6_fault  fan8_fault\tin4_fault  temp1_max\n"
+ "fan2_input  fan4_input\tfan6_input  fan8_input\tname\t   uevent\n"
+ "[root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/\n"
+ "device\t    fan2_min\tfan4_min    fan6_min\tfan8_min   power\n"
+ "fan1_fault  fan3_fault\tfan5_fault  fan7_fault\tin1_fault  power1_input\n"
+ "fan1_input  fan3_input\tfan5_input  fan7_input\tin2_fault  subsystem\n"
+ "fan1_min    fan3_min\tfan5_min    fan7_min\tin3_fault  temp1_input\n"
+ "fan2_fault  fan4_fault\tfan6_fault  fan8_fault\tin4_fault  temp1_max\n"
+ "fan2_input  fan4_input\tfan6_input  fan8_input\tname\t   uevent\n"
+ "[root@tul163p1 ~]#\n"
+ "\n"
+ "Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>\n"
+ "Reviewed-by: Guenter Roeck <linux@roeck-us.net>\n"
+ "---\n"
+ "\n"
+ "Changes in v5\n"
+ "=============\n"
+ "- Addressed couple minor comments in v4.\n"
+ "\n"
+ "Changes in v4\n"
+ "=============\n"
+ "- Replaced pr_err() with dev_err() for logging print messages.\n"
+ "- Using kstrtou32() function for converting string to u32 instead of sscanf().\n"
+ "\n"
+ "Changes in v3\n"
+ "=============\n"
+ "- Fixed an endianness bug leading the driver to break on LE.\n"
+ "- Fixed a bug that when one of the 'attribute_group' not populated, following\n"
+ "  groups attributes were dropped.\n"
+ "- Rewrite the get_sensor_index_attr() function to handle all the error scenarios\n"
+ "  like 'sscanf' etc.\n"
+ "- Fixed all the errors/warnings related to coding style/whitespace.\n"
+ "- Added 'Documentation' files.\n"
+ "- Addressed remaining review comments on V2.\n"
+ "\n"
+ "Changes in v2\n"
+ "=============\n"
+ "- Generic use of devm_* functions in hwmon like using devm_kzalloc() for dynamic\n"
+ "  memory request, avoiding the need to explicit free of memory.\n"
+ "  Adding 'struct attribute_group' as member of platform data structure to be\n"
+ "  populated and then passed to devm_hwmon_device_register_with_groups().\n"
+ "\n"
+ "  Note: Having an array of pointers of 'attribute_group' and each group\n"
+ "  corresponds to 'enum sensors' type. Not completely sure, if it's ideal or\n"
+ "  could have just one group populated with attributes of sensor types?\n"
+ "\n"
+ "- 'ibmpowernv' is not hot-pluggable device so moving 'platform_driver' callback\n"
+ "  function (probe) as part of __init code.\n"
+ "- Fixed issues related to coding style.\n"
+ "- Other general comments in v1.\n"
+ "\n"
+ " .../devicetree/bindings/hwmon/ibmpowernv.txt       |   23 +\n"
+ " Documentation/hwmon/ibmpowernv                     |   41 ++\n"
+ " drivers/hwmon/Kconfig                              |   11 +\n"
+ " drivers/hwmon/Makefile                             |    1 \n"
+ " drivers/hwmon/ibmpowernv.c                         |  364 ++++++++++++++++++++\n"
+ " 5 files changed, 440 insertions(+)\n"
+ " create mode 100644 Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ " create mode 100644 Documentation/hwmon/ibmpowernv\n"
+ " create mode 100644 drivers/hwmon/ibmpowernv.c\n"
+ "\n"
+ "diff --git a/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ "new file mode 100644\n"
+ "index 0000000..f93242b\n"
+ "--- /dev/null\n"
+ "+++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ "@@ -0,0 +1,23 @@\n"
+ "+IBM POWERNV platform sensors\n"
+ "+----------------------------\n"
+ "+\n"
+ "+Required node properties:\n"
+ "+- compatible: must be one of\n"
+ "+\t\t\"ibm,opal-sensor-cooling-fan\"\n"
+ "+\t\t\"ibm,opal-sensor-amb-temp\"\n"
+ "+\t\t\"ibm,opal-sensor-power-supply\"\n"
+ "+\t\t\"ibm,opal-sensor-power\"\n"
+ "+- sensor-id: an opaque id provided by the firmware to the kernel, identifies a\n"
+ "+\t     given sensor and its attribute data\n"
+ "+\n"
+ "+Example sensors node:\n"
+ "+\n"
+ "+cooling-fan#8-data {\n"
+ "+\tsensor-id = <0x7052107>;\n"
+ "+\tcompatible = \"ibm,opal-sensor-cooling-fan\";\n"
+ "+};\n"
+ "+\n"
+ "+amb-temp#1-thrs {\n"
+ "+\tsensor-id = <0x5096000>;\n"
+ "+\tcompatible = \"ibm,opal-sensor-amb-temp\";\n"
+ "+};\n"
+ "diff --git a/Documentation/hwmon/ibmpowernv b/Documentation/hwmon/ibmpowernv\n"
+ "new file mode 100644\n"
+ "index 0000000..644245a\n"
+ "--- /dev/null\n"
+ "+++ b/Documentation/hwmon/ibmpowernv\n"
+ "@@ -0,0 +1,41 @@\n"
+ "+Kernel Driver IBMPOWENV\n"
+ "+=======================\n"
+ "+\n"
+ "+Supported systems:\n"
+ "+  * Any recent IBM P servers based on POWERNV platform\n"
+ "+\n"
+ "+Author: Neelesh Gupta\n"
+ "+\n"
+ "+Description\n"
+ "+-----------\n"
+ "+\n"
+ "+This driver implements reading the platform sensors data like temperature/fan/\n"
+ "+voltage/power for 'POWERNV' platform.\n"
+ "+\n"
+ "+The driver uses the platform device infrastructure. It probes the device tree\n"
+ "+for sensor devices during the __init phase and registers them with the 'hwmon'.\n"
+ "+'hwmon' populates the 'sysfs' tree having attribute files, each for a given\n"
+ "+sensor type and its attribute data.\n"
+ "+\n"
+ "+All the nodes in the DT appear under \"/ibm,opal/sensors\" and each valid node in\n"
+ "+the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'\n"
+ "+which the driver uses to make an OPAL call to the firmware.\n"
+ "+\n"
+ "+Usage notes\n"
+ "+-----------\n"
+ "+The driver is built statically with the kernel by enabling the config\n"
+ "+CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.\n"
+ "+\n"
+ "+Sysfs attributes\n"
+ "+----------------\n"
+ "+\n"
+ "+fanX_input\t\tMeasured RPM value.\n"
+ "+fanX_min\t\tThreshold RPM for alert generation.\n"
+ "+fanX_fault\t\t0: No fail condition\n"
+ "+\t\t\t1: Failing fan\n"
+ "+tempX_input\t\tMeasured ambient temperature.\n"
+ "+tempX_max\t\tThreshold ambient temperature for alert generation.\n"
+ "+inX_input\t\tMeasured power supply voltage\n"
+ "+inX_fault\t\t0: No fail condition.\n"
+ "+\t\t\t1: Failing power supply.\n"
+ "+power1_input\t\tSystem power consumption (microWatt)\n"
+ "diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig\n"
+ "index 02d3d85..29c3fcb 100644\n"
+ "--- a/drivers/hwmon/Kconfig\n"
+ "+++ b/drivers/hwmon/Kconfig\n"
+ "@@ -554,6 +554,17 @@ config SENSORS_IBMPEX\n"
+ " \t  This driver can also be built as a module.  If so, the module\n"
+ " \t  will be called ibmpex.\n"
+ " \n"
+ "+config SENSORS_IBMPOWERNV\n"
+ "+\ttristate \"IBM POWERNV platform sensors\"\n"
+ "+\tdepends on PPC_POWERNV\n"
+ "+\tdefault y\n"
+ "+\thelp\n"
+ "+\t  If you say yes here you get support for the temperature/fan/power\n"
+ "+\t  sensors on your PowerNV platform.\n"
+ "+\n"
+ "+\t  This driver can also be built as a module. If so, the module\n"
+ "+\t  will be called ibmpowernv.\n"
+ "+\n"
+ " config SENSORS_IIO_HWMON\n"
+ " \ttristate \"Hwmon driver that uses channels specified via iio maps\"\n"
+ " \tdepends on IIO\n"
+ "diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile\n"
+ "index 3dc0f02..fc4ed26 100644\n"
+ "--- a/drivers/hwmon/Makefile\n"
+ "+++ b/drivers/hwmon/Makefile\n"
+ "@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45)\t+= ultra45_env.o\n"
+ " obj-$(CONFIG_SENSORS_I5K_AMB)\t+= i5k_amb.o\n"
+ " obj-$(CONFIG_SENSORS_IBMAEM)\t+= ibmaem.o\n"
+ " obj-$(CONFIG_SENSORS_IBMPEX)\t+= ibmpex.o\n"
+ "+obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o\n"
+ " obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o\n"
+ " obj-$(CONFIG_SENSORS_INA209)\t+= ina209.o\n"
+ " obj-$(CONFIG_SENSORS_INA2XX)\t+= ina2xx.o\n"
+ "diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c\n"
+ "new file mode 100644\n"
+ "index 0000000..e6b652a\n"
+ "--- /dev/null\n"
+ "+++ b/drivers/hwmon/ibmpowernv.c\n"
+ "@@ -0,0 +1,364 @@\n"
+ "+/*\n"
+ "+ * IBM PowerNV platform sensors for temperature/fan/voltage/power\n"
+ "+ * Copyright (C) 2014 IBM\n"
+ "+ *\n"
+ "+ * This program is free software; you can redistribute it and/or modify\n"
+ "+ * it under the terms of the GNU General Public License as published by\n"
+ "+ * the Free Software Foundation; either version 2 of the License, or\n"
+ "+ * (at your option) any later version.\n"
+ "+ *\n"
+ "+ * This program is distributed in the hope that it will be useful,\n"
+ "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+ "+ * GNU General Public License for more details.\n"
+ "+ *\n"
+ "+ * You should have received a copy of the GNU General Public License\n"
+ "+ * along with this program.\n"
+ "+ */\n"
+ "+\n"
+ "+#define DRVNAME\t\t\"ibmpowernv\"\n"
+ "+#define pr_fmt(fmt)\tDRVNAME \": \" fmt\n"
+ "+\n"
+ "+#include <linux/init.h>\n"
+ "+#include <linux/module.h>\n"
+ "+#include <linux/kernel.h>\n"
+ "+#include <linux/hwmon.h>\n"
+ "+#include <linux/hwmon-sysfs.h>\n"
+ "+#include <linux/of.h>\n"
+ "+#include <linux/slab.h>\n"
+ "+\n"
+ "+#include <linux/platform_device.h>\n"
+ "+#include <asm/opal.h>\n"
+ "+#include <linux/err.h>\n"
+ "+\n"
+ "+#define MAX_ATTR_LEN\t32\n"
+ "+\n"
+ "+/* Sensor suffix name from DT */\n"
+ "+#define DT_FAULT_ATTR_SUFFIX\t\t\"faulted\"\n"
+ "+#define DT_DATA_ATTR_SUFFIX\t\t\"data\"\n"
+ "+#define DT_THRESHOLD_ATTR_SUFFIX\t\"thrs\"\n"
+ "+\n"
+ "+/*\n"
+ "+ * Enumerates all the types of sensors in the POWERNV platform and does index\n"
+ "+ * into 'struct sensor_group'\n"
+ "+ */\n"
+ "+enum sensors {\n"
+ "+\tFAN,\n"
+ "+\tAMBIENT_TEMP,\n"
+ "+\tPOWER_SUPPLY,\n"
+ "+\tPOWER_INPUT,\n"
+ "+\tMAX_SENSOR_TYPE,\n"
+ "+};\n"
+ "+\n"
+ "+static struct sensor_group {\n"
+ "+\tconst char *name;\n"
+ "+\tconst char *compatible;\n"
+ "+\tstruct attribute_group group;\n"
+ "+\tu32 attr_count;\n"
+ "+} sensor_groups[] = {\n"
+ "+\t{\"fan\", \"ibm,opal-sensor-cooling-fan\"},\n"
+ "+\t{\"temp\", \"ibm,opal-sensor-amb-temp\"},\n"
+ "+\t{\"in\", \"ibm,opal-sensor-power-supply\"},\n"
+ "+\t{\"power\", \"ibm,opal-sensor-power\"}\n"
+ "+};\n"
+ "+\n"
+ "+struct sensor_data {\n"
+ "+\tu32 id; /* An opaque id of the firmware for each sensor */\n"
+ "+\tenum sensors type;\n"
+ "+\tchar name[MAX_ATTR_LEN];\n"
+ "+\tstruct device_attribute dev_attr;\n"
+ "+};\n"
+ "+\n"
+ "+struct platform_data {\n"
+ "+\tconst struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];\n"
+ "+\tu32 sensors_count; /* Total count of sensors from each group */\n"
+ "+};\n"
+ "+\n"
+ "+/* Platform device representing all the ibmpowernv sensors */\n"
+ "+static struct platform_device *pdevice;\n"
+ "+\n"
+ "+static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,\n"
+ "+\t\t\t   char *buf)\n"
+ "+{\n"
+ "+\tstruct sensor_data *sdata = container_of(devattr, struct sensor_data,\n"
+ "+\t\t\t\t\t\t dev_attr);\n"
+ "+\tssize_t ret;\n"
+ "+\tu32 x;\n"
+ "+\n"
+ "+\tret = opal_get_sensor_data(sdata->id, &x);\n"
+ "+\tif (ret)\n"
+ "+\t\treturn ret;\n"
+ "+\n"
+ "+\t/* Convert temperature to milli-degrees */\n"
+ "+\tif (sdata->type == AMBIENT_TEMP)\n"
+ "+\t\tx *= 1000;\n"
+ "+\t/* Convert power to micro-watts */\n"
+ "+\telse if (sdata->type == POWER_INPUT)\n"
+ "+\t\tx *= 1000000;\n"
+ "+\n"
+ "+\treturn sprintf(buf, \"%u\\n\", x);\n"
+ "+}\n"
+ "+\n"
+ "+static int __init get_sensor_index_attr(const char *name, u32 *index,\n"
+ "+\t\t\t\t\tchar *attr)\n"
+ "+{\n"
+ "+\tchar *hash_pos = strchr(name, '#');\n"
+ "+\tchar buf[8] = { 0 };\n"
+ "+\tchar *dash_pos;\n"
+ "+\tu32 copy_len;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tif (!hash_pos)\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tdash_pos = strchr(hash_pos, '-');\n"
+ "+\tif (!dash_pos)\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tcopy_len = dash_pos - hash_pos - 1;\n"
+ "+\tif (copy_len >= sizeof(buf))\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tstrncpy(buf, hash_pos + 1, copy_len);\n"
+ "+\n"
+ "+\terr = kstrtou32(buf, 10, index);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\tstrncpy(attr, dash_pos + 1, MAX_ATTR_LEN);\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/*\n"
+ "+ * This function translates the DT node name into the 'hwmon' attribute name.\n"
+ "+ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.\n"
+ "+ * which need to be mapped as fan2_input, temp1_max respectively before\n"
+ "+ * populating them inside hwmon device class.\n"
+ "+ */\n"
+ "+static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,\n"
+ "+\t\t\t\t\t const char *node_name,\n"
+ "+\t\t\t\t\t char *hwmon_attr_name)\n"
+ "+{\n"
+ "+\tchar attr_suffix[MAX_ATTR_LEN];\n"
+ "+\tchar *attr_name;\n"
+ "+\tu32 index;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\terr = get_sensor_index_attr(node_name, &index, attr_suffix);\n"
+ "+\tif (err) {\n"
+ "+\t\tdev_err(dev, \"Sensor device node name '%s' is invalid\\n\",\n"
+ "+\t\t\tnode_name);\n"
+ "+\t\treturn err;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tif (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {\n"
+ "+\t\tattr_name = \"fault\";\n"
+ "+\t} else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {\n"
+ "+\t\tattr_name = \"input\";\n"
+ "+\t} else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {\n"
+ "+\t\tif (type == AMBIENT_TEMP)\n"
+ "+\t\t\tattr_name = \"max\";\n"
+ "+\t\telse if (type == FAN)\n"
+ "+\t\t\tattr_name = \"min\";\n"
+ "+\t\telse\n"
+ "+\t\t\treturn -ENOENT;\n"
+ "+\t} else {\n"
+ "+\t\treturn -ENOENT;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tsnprintf(hwmon_attr_name, MAX_ATTR_LEN, \"%s%d_%s\",\n"
+ "+\t\t sensor_groups[type].name, index, attr_name);\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+static int __init populate_attr_groups(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata = platform_get_drvdata(pdev);\n"
+ "+\tconst struct attribute_group **pgroups = pdata->attr_groups;\n"
+ "+\tstruct device_node *opal, *np;\n"
+ "+\tenum sensors type;\n"
+ "+\n"
+ "+\topal = of_find_node_by_path(\"/ibm,opal/sensors\");\n"
+ "+\tif (!opal) {\n"
+ "+\t\tdev_err(&pdev->dev, \"Opal node 'sensors' not found\\n\");\n"
+ "+\t\treturn -ENODEV;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tfor_each_child_of_node(opal, np) {\n"
+ "+\t\tif (np->name == NULL)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tfor (type = 0; type < MAX_SENSOR_TYPE; type++)\n"
+ "+\t\t\tif (of_device_is_compatible(np,\n"
+ "+\t\t\t\t\tsensor_groups[type].compatible)) {\n"
+ "+\t\t\t\tsensor_groups[type].attr_count++;\n"
+ "+\t\t\t\tbreak;\n"
+ "+\t\t\t}\n"
+ "+\t}\n"
+ "+\n"
+ "+\tof_node_put(opal);\n"
+ "+\n"
+ "+\tfor (type = 0; type < MAX_SENSOR_TYPE; type++) {\n"
+ "+\t\tsensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,\n"
+ "+\t\t\t\t\tsizeof(struct attribute *) *\n"
+ "+\t\t\t\t\t(sensor_groups[type].attr_count + 1),\n"
+ "+\t\t\t\t\tGFP_KERNEL);\n"
+ "+\t\tif (!sensor_groups[type].group.attrs)\n"
+ "+\t\t\treturn -ENOMEM;\n"
+ "+\n"
+ "+\t\tpgroups[type] = &sensor_groups[type].group;\n"
+ "+\t\tpdata->sensors_count += sensor_groups[type].attr_count;\n"
+ "+\t\tsensor_groups[type].attr_count = 0;\n"
+ "+\t}\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/*\n"
+ "+ * Iterate through the device tree for each child of 'sensors' node, create\n"
+ "+ * a sysfs attribute file, the file is named by translating the DT node name\n"
+ "+ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max\n"
+ "+ * etc..\n"
+ "+ */\n"
+ "+static int __init create_device_attrs(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata = platform_get_drvdata(pdev);\n"
+ "+\tconst struct attribute_group **pgroups = pdata->attr_groups;\n"
+ "+\tstruct device_node *opal, *np;\n"
+ "+\tstruct sensor_data *sdata;\n"
+ "+\tconst __be32 *sensor_id;\n"
+ "+\tenum sensors type;\n"
+ "+\tu32 count = 0;\n"
+ "+\tint err = 0;\n"
+ "+\n"
+ "+\topal = of_find_node_by_path(\"/ibm,opal/sensors\");\n"
+ "+\tsdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),\n"
+ "+\t\t\t     GFP_KERNEL);\n"
+ "+\tif (!sdata) {\n"
+ "+\t\terr = -ENOMEM;\n"
+ "+\t\tgoto exit_put_node;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tfor_each_child_of_node(opal, np) {\n"
+ "+\t\tif (np->name == NULL)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tfor (type = 0; type < MAX_SENSOR_TYPE; type++)\n"
+ "+\t\t\tif (of_device_is_compatible(np,\n"
+ "+\t\t\t\t\tsensor_groups[type].compatible))\n"
+ "+\t\t\t\tbreak;\n"
+ "+\n"
+ "+\t\tif (type == MAX_SENSOR_TYPE)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tsensor_id = of_get_property(np, \"sensor-id\", NULL);\n"
+ "+\t\tif (!sensor_id) {\n"
+ "+\t\t\tdev_info(&pdev->dev,\n"
+ "+\t\t\t\t \"'sensor-id' missing in the node '%s'\\n\",\n"
+ "+\t\t\t\t np->name);\n"
+ "+\t\t\tcontinue;\n"
+ "+\t\t}\n"
+ "+\n"
+ "+\t\tsdata[count].id = be32_to_cpup(sensor_id);\n"
+ "+\t\tsdata[count].type = type;\n"
+ "+\t\terr = create_hwmon_attr_name(&pdev->dev, type, np->name,\n"
+ "+\t\t\t\t\t     sdata[count].name);\n"
+ "+\t\tif (err)\n"
+ "+\t\t\tgoto exit_put_node;\n"
+ "+\n"
+ "+\t\tsysfs_attr_init(&sdata[count].dev_attr.attr);\n"
+ "+\t\tsdata[count].dev_attr.attr.name = sdata[count].name;\n"
+ "+\t\tsdata[count].dev_attr.attr.mode = S_IRUGO;\n"
+ "+\t\tsdata[count].dev_attr.show = show_sensor;\n"
+ "+\n"
+ "+\t\tpgroups[type]->attrs[sensor_groups[type].attr_count++] =\n"
+ "+\t\t\t\t&sdata[count++].dev_attr.attr;\n"
+ "+\t}\n"
+ "+\n"
+ "+exit_put_node:\n"
+ "+\tof_node_put(opal);\n"
+ "+\treturn err;\n"
+ "+}\n"
+ "+\n"
+ "+static int __init ibmpowernv_probe(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata;\n"
+ "+\tstruct device *hwmon_dev;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tpdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);\n"
+ "+\tif (!pdata)\n"
+ "+\t\treturn -ENOMEM;\n"
+ "+\n"
+ "+\tplatform_set_drvdata(pdev, pdata);\n"
+ "+\tpdata->sensors_count = 0;\n"
+ "+\terr = populate_attr_groups(pdev);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\t/* Create sysfs attribute data for each sensor found in the DT */\n"
+ "+\terr = create_device_attrs(pdev);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\t/* Finally, register with hwmon */\n"
+ "+\thwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,\n"
+ "+\t\t\t\t\t\t\t   pdata,\n"
+ "+\t\t\t\t\t\t\t   pdata->attr_groups);\n"
+ "+\n"
+ "+\treturn PTR_ERR_OR_ZERO(hwmon_dev);\n"
+ "+}\n"
+ "+\n"
+ "+static struct platform_driver ibmpowernv_driver = {\n"
+ "+\t.driver = {\n"
+ "+\t\t.owner = THIS_MODULE,\n"
+ "+\t\t.name = DRVNAME,\n"
+ "+\t},\n"
+ "+};\n"
+ "+\n"
+ "+static int __init ibmpowernv_init(void)\n"
+ "+{\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tpdevice = platform_device_alloc(DRVNAME, 0);\n"
+ "+\tif (!pdevice) {\n"
+ "+\t\tpr_err(\"Device allocation failed\\n\");\n"
+ "+\t\terr = -ENOMEM;\n"
+ "+\t\tgoto exit;\n"
+ "+\t}\n"
+ "+\n"
+ "+\terr = platform_device_add(pdevice);\n"
+ "+\tif (err) {\n"
+ "+\t\tpr_err(\"Device addition failed (%d)\\n\", err);\n"
+ "+\t\tgoto exit_device_put;\n"
+ "+\t}\n"
+ "+\n"
+ "+\terr = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);\n"
+ "+\tif (err) {\n"
+ "+\t\tpr_err(\"Platfrom driver probe failed\\n\");\n"
+ "+\t\tgoto exit_device_del;\n"
+ "+\t}\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+\n"
+ "+exit_device_del:\n"
+ "+\tplatform_device_del(pdevice);\n"
+ "+exit_device_put:\n"
+ "+\tplatform_device_put(pdevice);\n"
+ "+exit:\n"
+ "+\treturn err;\n"
+ "+}\n"
+ "+\n"
+ "+static void __exit ibmpowernv_exit(void)\n"
+ "+{\n"
+ "+\tplatform_driver_unregister(&ibmpowernv_driver);\n"
+ "+\tplatform_device_unregister(pdevice);\n"
+ "+}\n"
+ "+\n"
+ "+MODULE_AUTHOR(\"Neelesh Gupta <neelegup@linux.vnet.ibm.com>\");\n"
+ "+MODULE_DESCRIPTION(\"IBM POWERNV platform sensors\");\n"
+ "+MODULE_LICENSE(\"GPL\");\n"
+ "+\n"
+ "+module_init(ibmpowernv_init);\n"
+ +module_exit(ibmpowernv_exit);
 
-f99de827708da98eed28b6adde09d30b1a31d6a06d37cee5bb5aaa5c9ecec889
+064f29445fc63037fbef7f9046ad7f973a46ccbc7a10ad0867cdc34d96d64830

diff --git a/a/1.txt b/N2/1.txt
index ab77646..3259e2d 100644
--- a/a/1.txt
+++ b/N2/1.txt
@@ -1,300 +1,573 @@
-VGhpcyBwYXRjaCBhZGRzIGJhc2ljIGtlcm5lbCBzdXBwb3J0IGZvciByZWFkaW5nIHBvd2VyIHZh
-bHVlcywgZmFuCnNwZWVkIHJwbSwgdm9sdGFnZSBhbmQgdGVtcGVyYXR1cmUgZGF0YSBvbiBwb3dl
-cm52IHBsYXRmb3JtcyB3aGljaAp3aWxsIGJlIGV4cG9ydGVkIHRvIHVzZXIgc3BhY2UgdGhyb3Vn
-aCBzeXNmcyBpbnRlcmZhY2UuCgpUZXN0IHJlc3VsdHM6Ci0tLS0tLS0tLS0tLS0KW3Jvb3RAdHVs
-MTYzcDEgfl0jIHNlbnNvcnMKaWJtcG93ZXJudi1pc2EtMDAwMApBZGFwdGVyOiBJU0EgYWRhcHRl
-cgpmYW4xOiAgICAgICAgNTQ2NSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuMjogICAgICAgIDUx
-NTIgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjM6ICAgICAgICA1NTIxIFJQTSAgKG1pbiA9ICAg
-IDAgUlBNKQpmYW40OiAgICAgICAgNDg5MSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuNTogICAg
-ICAgICAgIDAgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1p
-biA9ICAgIDAgUlBNKQpmYW43OiAgICAgICAgNzQ4MCBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFu
-ODogICAgICAgIDc5NDQgUlBNICAobWluID0gICAgMCBSUE0pCnRlbXAxOiAgICAgICAgKzM5LjDC
-sEMgIChoaWdoID0gICswLjDCsEMpCnBvd2VyMTogICAgICAxOTAuMDAgVyAgCgpbcm9vdEB0dWwx
-NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwphbGFybXRpbWVyICBpYm1wb3dlcm52
-LjAgIHBvd2VyICBydGMtZ2VuZXJpYyAgc2VyaWFsODI1MCAgdWV2ZW50Cltyb290QHR1bDE2M3Ax
-IH5dIyBscyAvc3lzL2RldmljZXMvcGxhdGZvcm0vaWJtcG93ZXJudi4wL2h3bW9uL2h3bW9uMC8K
-ZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2Vy
-CmZhbjFfZmF1bHQgIGZhbjNfZmF1bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQg
-IHBvd2VyMV9pbnB1dApmYW4xX2lucHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5w
-dXQJaW4yX2ZhdWx0ICBzdWJzeXN0ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAg
-ZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZh
-bjZfZmF1bHQgIGZhbjhfZmF1bHQJaW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFu
-NF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2
-M3AxIH5dIyBscyAvc3lzL2NsYXNzL2h3bW9uL2h3bW9uMC8KZGV2aWNlCSAgICBmYW4yX21pbglm
-YW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2VyCmZhbjFfZmF1bHQgIGZhbjNfZmF1
-bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQgIHBvd2VyMV9pbnB1dApmYW4xX2lu
-cHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICBzdWJzeXN0
-ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0
-ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZhbjZfZmF1bHQgIGZhbjhfZmF1bHQJ
-aW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBm
-YW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2M3AxIH5dIwoKU2lnbmVkLW9mZi1i
-eTogTmVlbGVzaCBHdXB0YSA8bmVlbGVndXBAbGludXgudm5ldC5pYm0uY29tPgpSZXZpZXdlZC1i
-eTogR3VlbnRlciBSb2VjayA8bGludXhAcm9lY2stdXMubmV0PgotLS0KCkNoYW5nZXMgaW4gdjUK
-PT09PT09PT09PT09PQotIEFkZHJlc3NlZCBjb3VwbGUgbWlub3IgY29tbWVudHMgaW4gdjQuCgpD
-aGFuZ2VzIGluIHY0Cj09PT09PT09PT09PT0KLSBSZXBsYWNlZCBwcl9lcnIoKSB3aXRoIGRldl9l
-cnIoKSBmb3IgbG9nZ2luZyBwcmludCBtZXNzYWdlcy4KLSBVc2luZyBrc3RydG91MzIoKSBmdW5j
-dGlvbiBmb3IgY29udmVydGluZyBzdHJpbmcgdG8gdTMyIGluc3RlYWQgb2Ygc3NjYW5mKCkuCgpD
-aGFuZ2VzIGluIHYzCj09PT09PT09PT09PT0KLSBGaXhlZCBhbiBlbmRpYW5uZXNzIGJ1ZyBsZWFk
-aW5nIHRoZSBkcml2ZXIgdG8gYnJlYWsgb24gTEUuCi0gRml4ZWQgYSBidWcgdGhhdCB3aGVuIG9u
-ZSBvZiB0aGUgJ2F0dHJpYnV0ZV9ncm91cCcgbm90IHBvcHVsYXRlZCwgZm9sbG93aW5nCiAgZ3Jv
-dXBzIGF0dHJpYnV0ZXMgd2VyZSBkcm9wcGVkLgotIFJld3JpdGUgdGhlIGdldF9zZW5zb3JfaW5k
-ZXhfYXR0cigpIGZ1bmN0aW9uIHRvIGhhbmRsZSBhbGwgdGhlIGVycm9yIHNjZW5hcmlvcwogIGxp
-a2UgJ3NzY2FuZicgZXRjLgotIEZpeGVkIGFsbCB0aGUgZXJyb3JzL3dhcm5pbmdzIHJlbGF0ZWQg
-dG8gY29kaW5nIHN0eWxlL3doaXRlc3BhY2UuCi0gQWRkZWQgJ0RvY3VtZW50YXRpb24nIGZpbGVz
-LgotIEFkZHJlc3NlZCByZW1haW5pbmcgcmV2aWV3IGNvbW1lbnRzIG9uIFYyLgoKQ2hhbmdlcyBp
-biB2Mgo9PT09PT09PT09PT09Ci0gR2VuZXJpYyB1c2Ugb2YgZGV2bV8qIGZ1bmN0aW9ucyBpbiBo
-d21vbiBsaWtlIHVzaW5nIGRldm1fa3phbGxvYygpIGZvciBkeW5hbWljCiAgbWVtb3J5IHJlcXVl
-c3QsIGF2b2lkaW5nIHRoZSBuZWVkIHRvIGV4cGxpY2l0IGZyZWUgb2YgbWVtb3J5LgogIEFkZGlu
-ZyAnc3RydWN0IGF0dHJpYnV0ZV9ncm91cCcgYXMgbWVtYmVyIG9mIHBsYXRmb3JtIGRhdGEgc3Ry
-dWN0dXJlIHRvIGJlCiAgcG9wdWxhdGVkIGFuZCB0aGVuIHBhc3NlZCB0byBkZXZtX2h3bW9uX2Rl
-dmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgoKICBOb3RlOiBIYXZpbmcgYW4gYXJyYXkgb2Yg
-cG9pbnRlcnMgb2YgJ2F0dHJpYnV0ZV9ncm91cCcgYW5kIGVhY2ggZ3JvdXAKICBjb3JyZXNwb25k
-cyB0byAnZW51bSBzZW5zb3JzJyB0eXBlLiBOb3QgY29tcGxldGVseSBzdXJlLCBpZiBpdCdzIGlk
-ZWFsIG9yCiAgY291bGQgaGF2ZSBqdXN0IG9uZSBncm91cCBwb3B1bGF0ZWQgd2l0aCBhdHRyaWJ1
-dGVzIG9mIHNlbnNvciB0eXBlcz8KCi0gJ2libXBvd2VybnYnIGlzIG5vdCBob3QtcGx1Z2dhYmxl
-IGRldmljZSBzbyBtb3ZpbmcgJ3BsYXRmb3JtX2RyaXZlcicgY2FsbGJhY2sKICBmdW5jdGlvbiAo
-cHJvYmUpIGFzIHBhcnQgb2YgX19pbml0IGNvZGUuCi0gRml4ZWQgaXNzdWVzIHJlbGF0ZWQgdG8g
-Y29kaW5nIHN0eWxlLgotIE90aGVyIGdlbmVyYWwgY29tbWVudHMgaW4gdjEuCgogLi4uL2Rldmlj
-ZXRyZWUvYmluZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQgICAgICAgfCAgIDIzICsKIERvY3Vt
-ZW50YXRpb24vaHdtb24vaWJtcG93ZXJudiAgICAgICAgICAgICAgICAgICAgIHwgICA0MSArKwog
-ZHJpdmVycy9od21vbi9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEx
-ICsKIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg
-ICAgMSAKIGRyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jICAgICAgICAgICAgICAgICAgICAgICAg
-IHwgIDM2NCArKysrKysrKysrKysrKysrKysrKwogNSBmaWxlcyBjaGFuZ2VkLCA0NDAgaW5zZXJ0
-aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5k
-aW5ncy9od21vbi9pYm1wb3dlcm52LnR4dAogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp
-b24vaHdtb24vaWJtcG93ZXJudgogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaHdtb24vaWJt
-cG93ZXJudi5jCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz
-L2h3bW9uL2libXBvd2VybnYudHh0IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz
-L2h3bW9uL2libXBvd2VybnYudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu
-LmY5MzI0MmIKLS0tIC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmlu
-ZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQKQEAgLTAsMCArMSwyMyBAQAorSUJNIFBPV0VSTlYg
-cGxhdGZvcm0gc2Vuc29ycworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZXF1aXJl
-ZCBub2RlIHByb3BlcnRpZXM6CistIGNvbXBhdGlibGU6IG11c3QgYmUgb25lIG9mCisJCSJpYm0s
-b3BhbC1zZW5zb3ItY29vbGluZy1mYW4iCisJCSJpYm0sb3BhbC1zZW5zb3ItYW1iLXRlbXAiCisJ
-CSJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3VwcGx5IgorCQkiaWJtLG9wYWwtc2Vuc29yLXBvd2Vy
-IgorLSBzZW5zb3ItaWQ6IGFuIG9wYXF1ZSBpZCBwcm92aWRlZCBieSB0aGUgZmlybXdhcmUgdG8g
-dGhlIGtlcm5lbCwgaWRlbnRpZmllcyBhCisJICAgICBnaXZlbiBzZW5zb3IgYW5kIGl0cyBhdHRy
-aWJ1dGUgZGF0YQorCitFeGFtcGxlIHNlbnNvcnMgbm9kZToKKworY29vbGluZy1mYW4jOC1kYXRh
-IHsKKwlzZW5zb3ItaWQgPSA8MHg3MDUyMTA3PjsKKwljb21wYXRpYmxlID0gImlibSxvcGFsLXNl
-bnNvci1jb29saW5nLWZhbiI7Cit9OworCithbWItdGVtcCMxLXRocnMgeworCXNlbnNvci1pZCA9
-IDwweDUwOTYwMDA+OworCWNvbXBhdGlibGUgPSAiaWJtLG9wYWwtc2Vuc29yLWFtYi10ZW1wIjsK
-K307CmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYgYi9Eb2N1bWVu
-dGF0aW9uL2h3bW9uL2libXBvd2VybnYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw
-MC4uNjQ0MjQ1YQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdtb24vaWJtcG93
-ZXJudgpAQCAtMCwwICsxLDQxIEBACitLZXJuZWwgRHJpdmVyIElCTVBPV0VOVgorPT09PT09PT09
-PT09PT09PT09PT09PT0KKworU3VwcG9ydGVkIHN5c3RlbXM6CisgICogQW55IHJlY2VudCBJQk0g
-UCBzZXJ2ZXJzIGJhc2VkIG9uIFBPV0VSTlYgcGxhdGZvcm0KKworQXV0aG9yOiBOZWVsZXNoIEd1
-cHRhCisKK0Rlc2NyaXB0aW9uCistLS0tLS0tLS0tLQorCitUaGlzIGRyaXZlciBpbXBsZW1lbnRz
-IHJlYWRpbmcgdGhlIHBsYXRmb3JtIHNlbnNvcnMgZGF0YSBsaWtlIHRlbXBlcmF0dXJlL2Zhbi8K
-K3ZvbHRhZ2UvcG93ZXIgZm9yICdQT1dFUk5WJyBwbGF0Zm9ybS4KKworVGhlIGRyaXZlciB1c2Vz
-IHRoZSBwbGF0Zm9ybSBkZXZpY2UgaW5mcmFzdHJ1Y3R1cmUuIEl0IHByb2JlcyB0aGUgZGV2aWNl
-IHRyZWUKK2ZvciBzZW5zb3IgZGV2aWNlcyBkdXJpbmcgdGhlIF9faW5pdCBwaGFzZSBhbmQgcmVn
-aXN0ZXJzIHRoZW0gd2l0aCB0aGUgJ2h3bW9uJy4KKydod21vbicgcG9wdWxhdGVzIHRoZSAnc3lz
-ZnMnIHRyZWUgaGF2aW5nIGF0dHJpYnV0ZSBmaWxlcywgZWFjaCBmb3IgYSBnaXZlbgorc2Vuc29y
-IHR5cGUgYW5kIGl0cyBhdHRyaWJ1dGUgZGF0YS4KKworQWxsIHRoZSBub2RlcyBpbiB0aGUgRFQg
-YXBwZWFyIHVuZGVyICIvaWJtLG9wYWwvc2Vuc29ycyIgYW5kIGVhY2ggdmFsaWQgbm9kZSBpbgor
-dGhlIERUIG1hcHMgdG8gYW4gYXR0cmlidXRlIGZpbGUgaW4gJ3N5c2ZzJy4gVGhlIG5vZGUgZXhw
-b3J0cyB1bmlxdWUgJ3NlbnNvci1pZCcKK3doaWNoIHRoZSBkcml2ZXIgdXNlcyB0byBtYWtlIGFu
-IE9QQUwgY2FsbCB0byB0aGUgZmlybXdhcmUuCisKK1VzYWdlIG5vdGVzCistLS0tLS0tLS0tLQor
-VGhlIGRyaXZlciBpcyBidWlsdCBzdGF0aWNhbGx5IHdpdGggdGhlIGtlcm5lbCBieSBlbmFibGlu
-ZyB0aGUgY29uZmlnCitDT05GSUdfU0VOU09SU19JQk1QT1dFUk5WLiBJdCBjYW4gYWxzbyBiZSBi
-dWlsdCBhcyBtb2R1bGUgJ2libXBvd2VybnYnLgorCitTeXNmcyBhdHRyaWJ1dGVzCistLS0tLS0t
-LS0tLS0tLS0tCisKK2ZhblhfaW5wdXQJCU1lYXN1cmVkIFJQTSB2YWx1ZS4KK2ZhblhfbWluCQlU
-aHJlc2hvbGQgUlBNIGZvciBhbGVydCBnZW5lcmF0aW9uLgorZmFuWF9mYXVsdAkJMDogTm8gZmFp
-bCBjb25kaXRpb24KKwkJCTE6IEZhaWxpbmcgZmFuCit0ZW1wWF9pbnB1dAkJTWVhc3VyZWQgYW1i
-aWVudCB0ZW1wZXJhdHVyZS4KK3RlbXBYX21heAkJVGhyZXNob2xkIGFtYmllbnQgdGVtcGVyYXR1
-cmUgZm9yIGFsZXJ0IGdlbmVyYXRpb24uCitpblhfaW5wdXQJCU1lYXN1cmVkIHBvd2VyIHN1cHBs
-eSB2b2x0YWdlCitpblhfZmF1bHQJCTA6IE5vIGZhaWwgY29uZGl0aW9uLgorCQkJMTogRmFpbGlu
-ZyBwb3dlciBzdXBwbHkuCitwb3dlcjFfaW5wdXQJCVN5c3RlbSBwb3dlciBjb25zdW1wdGlvbiAo
-bWljcm9XYXR0KQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9o
-d21vbi9LY29uZmlnCmluZGV4IDAyZDNkODUuLjI5YzNmY2IgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMv
-aHdtb24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKQEAgLTU1NCw2ICs1NTQs
-MTcgQEAgY29uZmlnIFNFTlNPUlNfSUJNUEVYCiAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBi
-dWlsdCBhcyBhIG1vZHVsZS4gIElmIHNvLCB0aGUgbW9kdWxlCiAJICB3aWxsIGJlIGNhbGxlZCBp
-Ym1wZXguCiAKK2NvbmZpZyBTRU5TT1JTX0lCTVBPV0VSTlYKKwl0cmlzdGF0ZSAiSUJNIFBPV0VS
-TlYgcGxhdGZvcm0gc2Vuc29ycyIKKwlkZXBlbmRzIG9uIFBQQ19QT1dFUk5WCisJZGVmYXVsdCB5
-CisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIHRoZSB0
-ZW1wZXJhdHVyZS9mYW4vcG93ZXIKKwkgIHNlbnNvcnMgb24geW91ciBQb3dlck5WIHBsYXRmb3Jt
-LgorCisJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28s
-IHRoZSBtb2R1bGUKKwkgIHdpbGwgYmUgY2FsbGVkIGlibXBvd2VybnYuCisKIGNvbmZpZyBTRU5T
-T1JTX0lJT19IV01PTgogCXRyaXN0YXRlICJId21vbiBkcml2ZXIgdGhhdCB1c2VzIGNoYW5uZWxz
-IHNwZWNpZmllZCB2aWEgaWlvIG1hcHMiCiAJZGVwZW5kcyBvbiBJSU8KZGlmZiAtLWdpdCBhL2Ry
-aXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCmluZGV4IDNkYzBm
-MDIuLmZjNGVkMjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKKysrIGIvZHJp
-dmVycy9od21vbi9NYWtlZmlsZQpAQCAtNzEsNiArNzEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S
-U19VTFRSQTQ1KQkrPSB1bHRyYTQ1X2Vudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JNUtfQU1C
-KQkrPSBpNWtfYW1iLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0lCTUFFTSkJKz0gaWJtYWVtLm8K
-IG9iai0kKENPTkZJR19TRU5TT1JTX0lCTVBFWCkJKz0gaWJtcGV4Lm8KK29iai0kKENPTkZJR19T
-RU5TT1JTX0lCTVBPV0VSTlYpKz0gaWJtcG93ZXJudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19J
-SU9fSFdNT04pICs9IGlpb19od21vbi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyMDkpCSs9
-IGluYTIwOS5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyWFgpCSs9IGluYTJ4eC5vCmRpZmYg
-LS1naXQgYS9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYyBiL2RyaXZlcnMvaHdtb24vaWJtcG93
-ZXJudi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YjY1MmEKLS0tIC9k
-ZXYvbnVsbAorKysgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwpAQCAtMCwwICsxLDM2NCBA
-QAorLyoKKyAqIElCTSBQb3dlck5WIHBsYXRmb3JtIHNlbnNvcnMgZm9yIHRlbXBlcmF0dXJlL2Zh
-bi92b2x0YWdlL3Bvd2VyCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSUJNCisgKgorICogVGhpcyBw
-cm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBt
-b2RpZnkKKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExp
-Y2Vuc2UgYXMgcHVibGlzaGVkIGJ5CisgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBl
-aXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICogKGF0IHlvdXIgb3B0aW9uKSBh
-bnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g
-dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJS
-QU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFC
-SUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBH
-TlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqIFlvdSBz
-aG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl
-bnNlCisgKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4KKyAqLworCisjZGVmaW5lIERSVk5BTUUJ
-CSJpYm1wb3dlcm52IgorI2RlZmluZSBwcl9mbXQoZm10KQlEUlZOQU1FICI6ICIgZm10CisKKyNp
-bmNsdWRlIDxsaW51eC9pbml0Lmg+CisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CisjaW5jbHVk
-ZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KKyNpbmNsdWRlIDxs
-aW51eC9od21vbi1zeXNmcy5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGlu
-dXgvc2xhYi5oPgorCisjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CisjaW5jbHVk
-ZSA8YXNtL29wYWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKworI2RlZmluZSBNQVhfQVRU
-Ul9MRU4JMzIKKworLyogU2Vuc29yIHN1ZmZpeCBuYW1lIGZyb20gRFQgKi8KKyNkZWZpbmUgRFRf
-RkFVTFRfQVRUUl9TVUZGSVgJCSJmYXVsdGVkIgorI2RlZmluZSBEVF9EQVRBX0FUVFJfU1VGRklY
-CQkiZGF0YSIKKyNkZWZpbmUgRFRfVEhSRVNIT0xEX0FUVFJfU1VGRklYCSJ0aHJzIgorCisvKgor
-ICogRW51bWVyYXRlcyBhbGwgdGhlIHR5cGVzIG9mIHNlbnNvcnMgaW4gdGhlIFBPV0VSTlYgcGxh
-dGZvcm0gYW5kIGRvZXMgaW5kZXgKKyAqIGludG8gJ3N0cnVjdCBzZW5zb3JfZ3JvdXAnCisgKi8K
-K2VudW0gc2Vuc29ycyB7CisJRkFOLAorCUFNQklFTlRfVEVNUCwKKwlQT1dFUl9TVVBQTFksCisJ
-UE9XRVJfSU5QVVQsCisJTUFYX1NFTlNPUl9UWVBFLAorfTsKKworc3RhdGljIHN0cnVjdCBzZW5z
-b3JfZ3JvdXAgeworCWNvbnN0IGNoYXIgKm5hbWU7CisJY29uc3QgY2hhciAqY29tcGF0aWJsZTsK
-KwlzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGdyb3VwOworCXUzMiBhdHRyX2NvdW50OworfSBzZW5z
-b3JfZ3JvdXBzW10gPSB7CisJeyJmYW4iLCAiaWJtLG9wYWwtc2Vuc29yLWNvb2xpbmctZmFuIn0s
-CisJeyJ0ZW1wIiwgImlibSxvcGFsLXNlbnNvci1hbWItdGVtcCJ9LAorCXsiaW4iLCAiaWJtLG9w
-YWwtc2Vuc29yLXBvd2VyLXN1cHBseSJ9LAorCXsicG93ZXIiLCAiaWJtLG9wYWwtc2Vuc29yLXBv
-d2VyIn0KK307CisKK3N0cnVjdCBzZW5zb3JfZGF0YSB7CisJdTMyIGlkOyAvKiBBbiBvcGFxdWUg
-aWQgb2YgdGhlIGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLworCWVudW0gc2Vuc29ycyB0eXBl
-OworCWNoYXIgbmFtZVtNQVhfQVRUUl9MRU5dOworCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRl
-dl9hdHRyOworfTsKKworc3RydWN0IHBsYXRmb3JtX2RhdGEgeworCWNvbnN0IHN0cnVjdCBhdHRy
-aWJ1dGVfZ3JvdXAgKmF0dHJfZ3JvdXBzW01BWF9TRU5TT1JfVFlQRSArIDFdOworCXUzMiBzZW5z
-b3JzX2NvdW50OyAvKiBUb3RhbCBjb3VudCBvZiBzZW5zb3JzIGZyb20gZWFjaCBncm91cCAqLwor
-fTsKKworLyogUGxhdGZvcm0gZGV2aWNlIHJlcHJlc2VudGluZyBhbGwgdGhlIGlibXBvd2VybnYg
-c2Vuc29ycyAqLworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXZpY2U7CisKK3N0
-YXRpYyBzc2l6ZV90IHNob3dfc2Vuc29yKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmlj
-ZV9hdHRyaWJ1dGUgKmRldmF0dHIsCisJCQkgICBjaGFyICpidWYpCit7CisJc3RydWN0IHNlbnNv
-cl9kYXRhICpzZGF0YSA9IGNvbnRhaW5lcl9vZihkZXZhdHRyLCBzdHJ1Y3Qgc2Vuc29yX2RhdGEs
-CisJCQkJCQkgZGV2X2F0dHIpOworCXNzaXplX3QgcmV0OworCXUzMiB4OworCisJcmV0ID0gb3Bh
-bF9nZXRfc2Vuc29yX2RhdGEoc2RhdGEtPmlkLCAmeCk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl
-dDsKKworCS8qIENvbnZlcnQgdGVtcGVyYXR1cmUgdG8gbWlsbGktZGVncmVlcyAqLworCWlmIChz
-ZGF0YS0+dHlwZSA9PSBBTUJJRU5UX1RFTVApCisJCXggKj0gMTAwMDsKKwkvKiBDb252ZXJ0IHBv
-d2VyIHRvIG1pY3JvLXdhdHRzICovCisJZWxzZSBpZiAoc2RhdGEtPnR5cGUgPT0gUE9XRVJfSU5Q
-VVQpCisJCXggKj0gMTAwMDAwMDsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiV1XG4iLCB4KTsK
-K30KKworc3RhdGljIGludCBfX2luaXQgZ2V0X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0IGNoYXIg
-Km5hbWUsIHUzMiAqaW5kZXgsCisJCQkJCWNoYXIgKmF0dHIpCit7CisJY2hhciAqaGFzaF9wb3Mg
-PSBzdHJjaHIobmFtZSwgJyMnKTsKKwljaGFyIGJ1Zls4XSA9IHsgMCB9OworCWNoYXIgKmRhc2hf
-cG9zOworCXUzMiBjb3B5X2xlbjsKKwlpbnQgZXJyOworCisJaWYgKCFoYXNoX3BvcykKKwkJcmV0
-dXJuIC1FSU5WQUw7CisKKwlkYXNoX3BvcyA9IHN0cmNocihoYXNoX3BvcywgJy0nKTsKKwlpZiAo
-IWRhc2hfcG9zKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWNvcHlfbGVuID0gZGFzaF9wb3MgLSBo
-YXNoX3BvcyAtIDE7CisJaWYgKGNvcHlfbGVuID49IHNpemVvZihidWYpKQorCQlyZXR1cm4gLUVJ
-TlZBTDsKKworCXN0cm5jcHkoYnVmLCBoYXNoX3BvcyArIDEsIGNvcHlfbGVuKTsKKworCWVyciA9
-IGtzdHJ0b3UzMihidWYsIDEwLCBpbmRleCk7CisJaWYgKGVycikKKwkJcmV0dXJuIGVycjsKKwor
-CXN0cm5jcHkoYXR0ciwgZGFzaF9wb3MgKyAxLCBNQVhfQVRUUl9MRU4pOworCisJcmV0dXJuIDA7
-Cit9CisKKy8qCisgKiBUaGlzIGZ1bmN0aW9uIHRyYW5zbGF0ZXMgdGhlIERUIG5vZGUgbmFtZSBp
-bnRvIHRoZSAnaHdtb24nIGF0dHJpYnV0ZSBuYW1lLgorICogSUJNUE9XRVJOViBkZXZpY2Ugbm9k
-ZSBhcHBlYXIgbGlrZSBjb29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCisg
-KiB3aGljaCBuZWVkIHRvIGJlIG1hcHBlZCBhcyBmYW4yX2lucHV0LCB0ZW1wMV9tYXggcmVzcGVj
-dGl2ZWx5IGJlZm9yZQorICogcG9wdWxhdGluZyB0aGVtIGluc2lkZSBod21vbiBkZXZpY2UgY2xh
-c3MuCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9od21vbl9hdHRyX25hbWUoc3RydWN0
-IGRldmljZSAqZGV2LCBlbnVtIHNlbnNvcnMgdHlwZSwKKwkJCQkJIGNvbnN0IGNoYXIgKm5vZGVf
-bmFtZSwKKwkJCQkJIGNoYXIgKmh3bW9uX2F0dHJfbmFtZSkKK3sKKwljaGFyIGF0dHJfc3VmZml4
-W01BWF9BVFRSX0xFTl07CisJY2hhciAqYXR0cl9uYW1lOworCXUzMiBpbmRleDsKKwlpbnQgZXJy
-OworCisJZXJyID0gZ2V0X3NlbnNvcl9pbmRleF9hdHRyKG5vZGVfbmFtZSwgJmluZGV4LCBhdHRy
-X3N1ZmZpeCk7CisJaWYgKGVycikgeworCQlkZXZfZXJyKGRldiwgIlNlbnNvciBkZXZpY2Ugbm9k
-ZSBuYW1lICclcycgaXMgaW52YWxpZFxuIiwKKwkJCW5vZGVfbmFtZSk7CisJCXJldHVybiBlcnI7
-CisJfQorCisJaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX0ZBVUxUX0FUVFJfU1VGRklYKSkg
-eworCQlhdHRyX25hbWUgPSAiZmF1bHQiOworCX0gZWxzZSBpZiAoIXN0cmNtcChhdHRyX3N1ZmZp
-eCwgRFRfREFUQV9BVFRSX1NVRkZJWCkpIHsKKwkJYXR0cl9uYW1lID0gImlucHV0IjsKKwl9IGVs
-c2UgaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX1RIUkVTSE9MRF9BVFRSX1NVRkZJWCkpIHsK
-KwkJaWYgKHR5cGUgPT0gQU1CSUVOVF9URU1QKQorCQkJYXR0cl9uYW1lID0gIm1heCI7CisJCWVs
-c2UgaWYgKHR5cGUgPT0gRkFOKQorCQkJYXR0cl9uYW1lID0gIm1pbiI7CisJCWVsc2UKKwkJCXJl
-dHVybiAtRU5PRU5UOworCX0gZWxzZSB7CisJCXJldHVybiAtRU5PRU5UOworCX0KKworCXNucHJp
-bnRmKGh3bW9uX2F0dHJfbmFtZSwgTUFYX0FUVFJfTEVOLCAiJXMlZF8lcyIsCisJCSBzZW5zb3Jf
-Z3JvdXBzW3R5cGVdLm5hbWUsIGluZGV4LCBhdHRyX25hbWUpOworCXJldHVybiAwOworfQorCitz
-dGF0aWMgaW50IF9faW5pdCBwb3B1bGF0ZV9hdHRyX2dyb3VwcyhzdHJ1Y3QgcGxhdGZvcm1fZGV2
-aWNlICpwZGV2KQoreworCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dl
-dF9kcnZkYXRhKHBkZXYpOworCWNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKipwZ3JvdXBz
-ID0gcGRhdGEtPmF0dHJfZ3JvdXBzOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqb3BhbCwgKm5wOwor
-CWVudW0gc2Vuc29ycyB0eXBlOworCisJb3BhbCA9IG9mX2ZpbmRfbm9kZV9ieV9wYXRoKCIvaWJt
-LG9wYWwvc2Vuc29ycyIpOworCWlmICghb3BhbCkgeworCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJP
-cGFsIG5vZGUgJ3NlbnNvcnMnIG5vdCBmb3VuZFxuIik7CisJCXJldHVybiAtRU5PREVWOworCX0K
-KworCWZvcl9lYWNoX2NoaWxkX29mX25vZGUob3BhbCwgbnApIHsKKwkJaWYgKG5wLT5uYW1lID09
-IE5VTEwpCisJCQljb250aW51ZTsKKworCQlmb3IgKHR5cGUgPSAwOyB0eXBlIDwgTUFYX1NFTlNP
-Ul9UWVBFOyB0eXBlKyspCisJCQlpZiAob2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsCisJCQkJ
-CXNlbnNvcl9ncm91cHNbdHlwZV0uY29tcGF0aWJsZSkpIHsKKwkJCQlzZW5zb3JfZ3JvdXBzW3R5
-cGVdLmF0dHJfY291bnQrKzsKKwkJCQlicmVhazsKKwkJCX0KKwl9CisKKwlvZl9ub2RlX3B1dChv
-cGFsKTsKKworCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykg
-eworCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzID0gZGV2bV9remFsbG9jKCZwZGV2
-LT5kZXYsCisJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRlICopICoKKwkJCQkJKHNlbnNvcl9n
-cm91cHNbdHlwZV0uYXR0cl9jb3VudCArIDEpLAorCQkJCQlHRlBfS0VSTkVMKTsKKwkJaWYgKCFz
-ZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzKQorCQkJcmV0dXJuIC1FTk9NRU07CisKKwkJ
-cGdyb3Vwc1t0eXBlXSA9ICZzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwOworCQlwZGF0YS0+c2Vu
-c29yc19jb3VudCArPSBzZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291bnQ7CisJCXNlbnNvcl9n
-cm91cHNbdHlwZV0uYXR0cl9jb3VudCA9IDA7CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisg
-KiBJdGVyYXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVlIGZvciBlYWNoIGNoaWxkIG9mICdzZW5z
-b3JzJyBub2RlLCBjcmVhdGUKKyAqIGEgc3lzZnMgYXR0cmlidXRlIGZpbGUsIHRoZSBmaWxlIGlz
-IG5hbWVkIGJ5IHRyYW5zbGF0aW5nIHRoZSBEVCBub2RlIG5hbWUKKyAqIHRvIHRoZSBuYW1lIHJl
-cXVpcmVkIGJ5IHRoZSBoaWdoZXIgJ2h3bW9uJyBkcml2ZXIgbGlrZSBmYW4xX2lucHV0LCB0ZW1w
-MV9tYXgKKyAqIGV0Yy4uCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9kZXZpY2VfYXR0
-cnMoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgcGxhdGZvcm1fZGF0
-YSAqcGRhdGEgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwljb25zdCBzdHJ1Y3QgYXR0
-cmlidXRlX2dyb3VwICoqcGdyb3VwcyA9IHBkYXRhLT5hdHRyX2dyb3VwczsKKwlzdHJ1Y3QgZGV2
-aWNlX25vZGUgKm9wYWwsICpucDsKKwlzdHJ1Y3Qgc2Vuc29yX2RhdGEgKnNkYXRhOworCWNvbnN0
-IF9fYmUzMiAqc2Vuc29yX2lkOworCWVudW0gc2Vuc29ycyB0eXBlOworCXUzMiBjb3VudCA9IDA7
-CisJaW50IGVyciA9IDA7CisKKwlvcGFsID0gb2ZfZmluZF9ub2RlX2J5X3BhdGgoIi9pYm0sb3Bh
-bC9zZW5zb3JzIik7CisJc2RhdGEgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgcGRhdGEtPnNl
-bnNvcnNfY291bnQgKiBzaXplb2YoKnNkYXRhKSwKKwkJCSAgICAgR0ZQX0tFUk5FTCk7CisJaWYg
-KCFzZGF0YSkgeworCQllcnIgPSAtRU5PTUVNOworCQlnb3RvIGV4aXRfcHV0X25vZGU7CisJfQor
-CisJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShvcGFsLCBucCkgeworCQlpZiAobnAtPm5hbWUgPT0g
-TlVMTCkKKwkJCWNvbnRpbnVlOworCisJCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09S
-X1RZUEU7IHR5cGUrKykKKwkJCWlmIChvZl9kZXZpY2VfaXNfY29tcGF0aWJsZShucCwKKwkJCQkJ
-c2Vuc29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkKKwkJCQlicmVhazsKKworCQlpZiAodHlw
-ZSA9PSBNQVhfU0VOU09SX1RZUEUpCisJCQljb250aW51ZTsKKworCQlzZW5zb3JfaWQgPSBvZl9n
-ZXRfcHJvcGVydHkobnAsICJzZW5zb3ItaWQiLCBOVUxMKTsKKwkJaWYgKCFzZW5zb3JfaWQpIHsK
-KwkJCWRldl9pbmZvKCZwZGV2LT5kZXYsCisJCQkJICInc2Vuc29yLWlkJyBtaXNzaW5nIGluIHRo
-ZSBub2RlICclcydcbiIsCisJCQkJIG5wLT5uYW1lKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJ
-c2RhdGFbY291bnRdLmlkID0gYmUzMl90b19jcHVwKHNlbnNvcl9pZCk7CisJCXNkYXRhW2NvdW50
-XS50eXBlID0gdHlwZTsKKwkJZXJyID0gY3JlYXRlX2h3bW9uX2F0dHJfbmFtZSgmcGRldi0+ZGV2
-LCB0eXBlLCBucC0+bmFtZSwKKwkJCQkJICAgICBzZGF0YVtjb3VudF0ubmFtZSk7CisJCWlmIChl
-cnIpCisJCQlnb3RvIGV4aXRfcHV0X25vZGU7CisKKwkJc3lzZnNfYXR0cl9pbml0KCZzZGF0YVtj
-b3VudF0uZGV2X2F0dHIuYXR0cik7CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5hdHRyLm5hbWUg
-PSBzZGF0YVtjb3VudF0ubmFtZTsKKwkJc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIubW9kZSA9
-IFNfSVJVR087CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5zaG93ID0gc2hvd19zZW5zb3I7CisK
-KwkJcGdyb3Vwc1t0eXBlXS0+YXR0cnNbc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50Kytd
-ID0KKwkJCQkmc2RhdGFbY291bnQrK10uZGV2X2F0dHIuYXR0cjsKKwl9CisKK2V4aXRfcHV0X25v
-ZGU6CisJb2Zfbm9kZV9wdXQob3BhbCk7CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIGludCBf
-X2luaXQgaWJtcG93ZXJudl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQorewor
-CXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YTsKKwlzdHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7
-CisJaW50IGVycjsKKworCXBkYXRhID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigq
-cGRhdGEpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXBkYXRhKQorCQlyZXR1cm4gLUVOT01FTTsKKwor
-CXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIHBkYXRhKTsKKwlwZGF0YS0+c2Vuc29yc19jb3Vu
-dCA9IDA7CisJZXJyID0gcG9wdWxhdGVfYXR0cl9ncm91cHMocGRldik7CisJaWYgKGVycikKKwkJ
-cmV0dXJuIGVycjsKKworCS8qIENyZWF0ZSBzeXNmcyBhdHRyaWJ1dGUgZGF0YSBmb3IgZWFjaCBz
-ZW5zb3IgZm91bmQgaW4gdGhlIERUICovCisJZXJyID0gY3JlYXRlX2RldmljZV9hdHRycyhwZGV2
-KTsKKwlpZiAoZXJyKQorCQlyZXR1cm4gZXJyOworCisJLyogRmluYWxseSwgcmVnaXN0ZXIgd2l0
-aCBod21vbiAqLworCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhf
-Z3JvdXBzKCZwZGV2LT5kZXYsIERSVk5BTUUsCisJCQkJCQkJICAgcGRhdGEsCisJCQkJCQkJICAg
-cGRhdGEtPmF0dHJfZ3JvdXBzKTsKKworCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2
-KTsKK30KKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaWJtcG93ZXJudl9kcml2ZXIg
-PSB7CisJLmRyaXZlciA9IHsKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJCS5uYW1lID0gRFJW
-TkFNRSwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgaWJtcG93ZXJudl9pbml0KHZvaWQp
-Cit7CisJaW50IGVycjsKKworCXBkZXZpY2UgPSBwbGF0Zm9ybV9kZXZpY2VfYWxsb2MoRFJWTkFN
-RSwgMCk7CisJaWYgKCFwZGV2aWNlKSB7CisJCXByX2VycigiRGV2aWNlIGFsbG9jYXRpb24gZmFp
-bGVkXG4iKTsKKwkJZXJyID0gLUVOT01FTTsKKwkJZ290byBleGl0OworCX0KKworCWVyciA9IHBs
-YXRmb3JtX2RldmljZV9hZGQocGRldmljZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIkRldmlj
-ZSBhZGRpdGlvbiBmYWlsZWQgKCVkKVxuIiwgZXJyKTsKKwkJZ290byBleGl0X2RldmljZV9wdXQ7
-CisJfQorCisJZXJyID0gcGxhdGZvcm1fZHJpdmVyX3Byb2JlKCZpYm1wb3dlcm52X2RyaXZlciwg
-aWJtcG93ZXJudl9wcm9iZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIlBsYXRmcm9tIGRyaXZl
-ciBwcm9iZSBmYWlsZWRcbiIpOworCQlnb3RvIGV4aXRfZGV2aWNlX2RlbDsKKwl9CisKKwlyZXR1
-cm4gMDsKKworZXhpdF9kZXZpY2VfZGVsOgorCXBsYXRmb3JtX2RldmljZV9kZWwocGRldmljZSk7
-CitleGl0X2RldmljZV9wdXQ6CisJcGxhdGZvcm1fZGV2aWNlX3B1dChwZGV2aWNlKTsKK2V4aXQ6
-CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IGlibXBvd2VybnZfZXhpdCh2
-b2lkKQoreworCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZpYm1wb3dlcm52X2RyaXZlcik7
-CisJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIocGRldmljZSk7Cit9CisKK01PRFVMRV9BVVRI
-T1IoIk5lZWxlc2ggR3VwdGEgPG5lZWxlZ3VwQGxpbnV4LnZuZXQuaWJtLmNvbT4iKTsKK01PRFVM
-RV9ERVNDUklQVElPTigiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIpOworTU9EVUxFX0xJ
-Q0VOU0UoIkdQTCIpOworCittb2R1bGVfaW5pdChpYm1wb3dlcm52X2luaXQpOworbW9kdWxlX2V4
-aXQoaWJtcG93ZXJudl9leGl0KTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
-X19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNv
-cnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNl
-bnNvcnM
+This patch adds basic kernel support for reading power values, fan
+speed rpm, voltage and temperature data on powernv platforms which
+will be exported to user space through sysfs interface.
+
+Test results:
+-------------
+[root@tul163p1 ~]# sensors
+ibmpowernv-isa-0000
+Adapter: ISA adapter
+fan1:        5465 RPM  (min =    0 RPM)
+fan2:        5152 RPM  (min =    0 RPM)
+fan3:        5521 RPM  (min =    0 RPM)
+fan4:        4891 RPM  (min =    0 RPM)
+fan5:           0 RPM  (min =    0 RPM)
+fan6:           0 RPM  (min =    0 RPM)
+fan7:        7480 RPM  (min =    0 RPM)
+fan8:        7944 RPM  (min =    0 RPM)
+temp1:        +39.0°C  (high =  +0.0°C)
+power1:      190.00 W  
+
+[root@tul163p1 ~]# ls /sys/devices/platform/
+alarmtimer  ibmpowernv.0  power  rtc-generic  serial8250  uevent
+[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/
+device	    fan2_min	fan4_min    fan6_min	fan8_min   power
+fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  power1_input
+fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  subsystem
+fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_input
+fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  temp1_max
+fan2_input  fan4_input	fan6_input  fan8_input	name	   uevent
+[root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/
+device	    fan2_min	fan4_min    fan6_min	fan8_min   power
+fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  power1_input
+fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  subsystem
+fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_input
+fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  temp1_max
+fan2_input  fan4_input	fan6_input  fan8_input	name	   uevent
+[root@tul163p1 ~]#
+
+Signed-off-by: Neelesh Gupta <neelegup-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
+Reviewed-by: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
+---
+
+Changes in v5
+=============
+- Addressed couple minor comments in v4.
+
+Changes in v4
+=============
+- Replaced pr_err() with dev_err() for logging print messages.
+- Using kstrtou32() function for converting string to u32 instead of sscanf().
+
+Changes in v3
+=============
+- Fixed an endianness bug leading the driver to break on LE.
+- Fixed a bug that when one of the 'attribute_group' not populated, following
+  groups attributes were dropped.
+- Rewrite the get_sensor_index_attr() function to handle all the error scenarios
+  like 'sscanf' etc.
+- Fixed all the errors/warnings related to coding style/whitespace.
+- Added 'Documentation' files.
+- Addressed remaining review comments on V2.
+
+Changes in v2
+=============
+- Generic use of devm_* functions in hwmon like using devm_kzalloc() for dynamic
+  memory request, avoiding the need to explicit free of memory.
+  Adding 'struct attribute_group' as member of platform data structure to be
+  populated and then passed to devm_hwmon_device_register_with_groups().
+
+  Note: Having an array of pointers of 'attribute_group' and each group
+  corresponds to 'enum sensors' type. Not completely sure, if it's ideal or
+  could have just one group populated with attributes of sensor types?
+
+- 'ibmpowernv' is not hot-pluggable device so moving 'platform_driver' callback
+  function (probe) as part of __init code.
+- Fixed issues related to coding style.
+- Other general comments in v1.
+
+ .../devicetree/bindings/hwmon/ibmpowernv.txt       |   23 +
+ Documentation/hwmon/ibmpowernv                     |   41 ++
+ drivers/hwmon/Kconfig                              |   11 +
+ drivers/hwmon/Makefile                             |    1 
+ drivers/hwmon/ibmpowernv.c                         |  364 ++++++++++++++++++++
+ 5 files changed, 440 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+ create mode 100644 Documentation/hwmon/ibmpowernv
+ create mode 100644 drivers/hwmon/ibmpowernv.c
+
+diff --git a/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+new file mode 100644
+index 0000000..f93242b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
+@@ -0,0 +1,23 @@
++IBM POWERNV platform sensors
++----------------------------
++
++Required node properties:
++- compatible: must be one of
++		"ibm,opal-sensor-cooling-fan"
++		"ibm,opal-sensor-amb-temp"
++		"ibm,opal-sensor-power-supply"
++		"ibm,opal-sensor-power"
++- sensor-id: an opaque id provided by the firmware to the kernel, identifies a
++	     given sensor and its attribute data
++
++Example sensors node:
++
++cooling-fan#8-data {
++	sensor-id = <0x7052107>;
++	compatible = "ibm,opal-sensor-cooling-fan";
++};
++
++amb-temp#1-thrs {
++	sensor-id = <0x5096000>;
++	compatible = "ibm,opal-sensor-amb-temp";
++};
+diff --git a/Documentation/hwmon/ibmpowernv b/Documentation/hwmon/ibmpowernv
+new file mode 100644
+index 0000000..644245a
+--- /dev/null
++++ b/Documentation/hwmon/ibmpowernv
+@@ -0,0 +1,41 @@
++Kernel Driver IBMPOWENV
++=======================
++
++Supported systems:
++  * Any recent IBM P servers based on POWERNV platform
++
++Author: Neelesh Gupta
++
++Description
++-----------
++
++This driver implements reading the platform sensors data like temperature/fan/
++voltage/power for 'POWERNV' platform.
++
++The driver uses the platform device infrastructure. It probes the device tree
++for sensor devices during the __init phase and registers them with the 'hwmon'.
++'hwmon' populates the 'sysfs' tree having attribute files, each for a given
++sensor type and its attribute data.
++
++All the nodes in the DT appear under "/ibm,opal/sensors" and each valid node in
++the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'
++which the driver uses to make an OPAL call to the firmware.
++
++Usage notes
++-----------
++The driver is built statically with the kernel by enabling the config
++CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.
++
++Sysfs attributes
++----------------
++
++fanX_input		Measured RPM value.
++fanX_min		Threshold RPM for alert generation.
++fanX_fault		0: No fail condition
++			1: Failing fan
++tempX_input		Measured ambient temperature.
++tempX_max		Threshold ambient temperature for alert generation.
++inX_input		Measured power supply voltage
++inX_fault		0: No fail condition.
++			1: Failing power supply.
++power1_input		System power consumption (microWatt)
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 02d3d85..29c3fcb 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -554,6 +554,17 @@ config SENSORS_IBMPEX
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called ibmpex.
+ 
++config SENSORS_IBMPOWERNV
++	tristate "IBM POWERNV platform sensors"
++	depends on PPC_POWERNV
++	default y
++	help
++	  If you say yes here you get support for the temperature/fan/power
++	  sensors on your PowerNV platform.
++
++	  This driver can also be built as a module. If so, the module
++	  will be called ibmpowernv.
++
+ config SENSORS_IIO_HWMON
+ 	tristate "Hwmon driver that uses channels specified via iio maps"
+ 	depends on IIO
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 3dc0f02..fc4ed26 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45)	+= ultra45_env.o
+ obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
+ obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
+ obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
++obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
+ obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
+ obj-$(CONFIG_SENSORS_INA209)	+= ina209.o
+ obj-$(CONFIG_SENSORS_INA2XX)	+= ina2xx.o
+diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
+new file mode 100644
+index 0000000..e6b652a
+--- /dev/null
++++ b/drivers/hwmon/ibmpowernv.c
+@@ -0,0 +1,364 @@
++/*
++ * IBM PowerNV platform sensors for temperature/fan/voltage/power
++ * Copyright (C) 2014 IBM
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.
++ */
++
++#define DRVNAME		"ibmpowernv"
++#define pr_fmt(fmt)	DRVNAME ": " fmt
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include <linux/platform_device.h>
++#include <asm/opal.h>
++#include <linux/err.h>
++
++#define MAX_ATTR_LEN	32
++
++/* Sensor suffix name from DT */
++#define DT_FAULT_ATTR_SUFFIX		"faulted"
++#define DT_DATA_ATTR_SUFFIX		"data"
++#define DT_THRESHOLD_ATTR_SUFFIX	"thrs"
++
++/*
++ * Enumerates all the types of sensors in the POWERNV platform and does index
++ * into 'struct sensor_group'
++ */
++enum sensors {
++	FAN,
++	AMBIENT_TEMP,
++	POWER_SUPPLY,
++	POWER_INPUT,
++	MAX_SENSOR_TYPE,
++};
++
++static struct sensor_group {
++	const char *name;
++	const char *compatible;
++	struct attribute_group group;
++	u32 attr_count;
++} sensor_groups[] = {
++	{"fan", "ibm,opal-sensor-cooling-fan"},
++	{"temp", "ibm,opal-sensor-amb-temp"},
++	{"in", "ibm,opal-sensor-power-supply"},
++	{"power", "ibm,opal-sensor-power"}
++};
++
++struct sensor_data {
++	u32 id; /* An opaque id of the firmware for each sensor */
++	enum sensors type;
++	char name[MAX_ATTR_LEN];
++	struct device_attribute dev_attr;
++};
++
++struct platform_data {
++	const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
++	u32 sensors_count; /* Total count of sensors from each group */
++};
++
++/* Platform device representing all the ibmpowernv sensors */
++static struct platform_device *pdevice;
++
++static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
++			   char *buf)
++{
++	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
++						 dev_attr);
++	ssize_t ret;
++	u32 x;
++
++	ret = opal_get_sensor_data(sdata->id, &x);
++	if (ret)
++		return ret;
++
++	/* Convert temperature to milli-degrees */
++	if (sdata->type == AMBIENT_TEMP)
++		x *= 1000;
++	/* Convert power to micro-watts */
++	else if (sdata->type == POWER_INPUT)
++		x *= 1000000;
++
++	return sprintf(buf, "%u\n", x);
++}
++
++static int __init get_sensor_index_attr(const char *name, u32 *index,
++					char *attr)
++{
++	char *hash_pos = strchr(name, '#');
++	char buf[8] = { 0 };
++	char *dash_pos;
++	u32 copy_len;
++	int err;
++
++	if (!hash_pos)
++		return -EINVAL;
++
++	dash_pos = strchr(hash_pos, '-');
++	if (!dash_pos)
++		return -EINVAL;
++
++	copy_len = dash_pos - hash_pos - 1;
++	if (copy_len >= sizeof(buf))
++		return -EINVAL;
++
++	strncpy(buf, hash_pos + 1, copy_len);
++
++	err = kstrtou32(buf, 10, index);
++	if (err)
++		return err;
++
++	strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
++
++	return 0;
++}
++
++/*
++ * This function translates the DT node name into the 'hwmon' attribute name.
++ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
++ * which need to be mapped as fan2_input, temp1_max respectively before
++ * populating them inside hwmon device class.
++ */
++static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,
++					 const char *node_name,
++					 char *hwmon_attr_name)
++{
++	char attr_suffix[MAX_ATTR_LEN];
++	char *attr_name;
++	u32 index;
++	int err;
++
++	err = get_sensor_index_attr(node_name, &index, attr_suffix);
++	if (err) {
++		dev_err(dev, "Sensor device node name '%s' is invalid\n",
++			node_name);
++		return err;
++	}
++
++	if (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {
++		attr_name = "fault";
++	} else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {
++		attr_name = "input";
++	} else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {
++		if (type == AMBIENT_TEMP)
++			attr_name = "max";
++		else if (type == FAN)
++			attr_name = "min";
++		else
++			return -ENOENT;
++	} else {
++		return -ENOENT;
++	}
++
++	snprintf(hwmon_attr_name, MAX_ATTR_LEN, "%s%d_%s",
++		 sensor_groups[type].name, index, attr_name);
++	return 0;
++}
++
++static int __init populate_attr_groups(struct platform_device *pdev)
++{
++	struct platform_data *pdata = platform_get_drvdata(pdev);
++	const struct attribute_group **pgroups = pdata->attr_groups;
++	struct device_node *opal, *np;
++	enum sensors type;
++
++	opal = of_find_node_by_path("/ibm,opal/sensors");
++	if (!opal) {
++		dev_err(&pdev->dev, "Opal node 'sensors' not found\n");
++		return -ENODEV;
++	}
++
++	for_each_child_of_node(opal, np) {
++		if (np->name == NULL)
++			continue;
++
++		for (type = 0; type < MAX_SENSOR_TYPE; type++)
++			if (of_device_is_compatible(np,
++					sensor_groups[type].compatible)) {
++				sensor_groups[type].attr_count++;
++				break;
++			}
++	}
++
++	of_node_put(opal);
++
++	for (type = 0; type < MAX_SENSOR_TYPE; type++) {
++		sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,
++					sizeof(struct attribute *) *
++					(sensor_groups[type].attr_count + 1),
++					GFP_KERNEL);
++		if (!sensor_groups[type].group.attrs)
++			return -ENOMEM;
++
++		pgroups[type] = &sensor_groups[type].group;
++		pdata->sensors_count += sensor_groups[type].attr_count;
++		sensor_groups[type].attr_count = 0;
++	}
++
++	return 0;
++}
++
++/*
++ * Iterate through the device tree for each child of 'sensors' node, create
++ * a sysfs attribute file, the file is named by translating the DT node name
++ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
++ * etc..
++ */
++static int __init create_device_attrs(struct platform_device *pdev)
++{
++	struct platform_data *pdata = platform_get_drvdata(pdev);
++	const struct attribute_group **pgroups = pdata->attr_groups;
++	struct device_node *opal, *np;
++	struct sensor_data *sdata;
++	const __be32 *sensor_id;
++	enum sensors type;
++	u32 count = 0;
++	int err = 0;
++
++	opal = of_find_node_by_path("/ibm,opal/sensors");
++	sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),
++			     GFP_KERNEL);
++	if (!sdata) {
++		err = -ENOMEM;
++		goto exit_put_node;
++	}
++
++	for_each_child_of_node(opal, np) {
++		if (np->name == NULL)
++			continue;
++
++		for (type = 0; type < MAX_SENSOR_TYPE; type++)
++			if (of_device_is_compatible(np,
++					sensor_groups[type].compatible))
++				break;
++
++		if (type == MAX_SENSOR_TYPE)
++			continue;
++
++		sensor_id = of_get_property(np, "sensor-id", NULL);
++		if (!sensor_id) {
++			dev_info(&pdev->dev,
++				 "'sensor-id' missing in the node '%s'\n",
++				 np->name);
++			continue;
++		}
++
++		sdata[count].id = be32_to_cpup(sensor_id);
++		sdata[count].type = type;
++		err = create_hwmon_attr_name(&pdev->dev, type, np->name,
++					     sdata[count].name);
++		if (err)
++			goto exit_put_node;
++
++		sysfs_attr_init(&sdata[count].dev_attr.attr);
++		sdata[count].dev_attr.attr.name = sdata[count].name;
++		sdata[count].dev_attr.attr.mode = S_IRUGO;
++		sdata[count].dev_attr.show = show_sensor;
++
++		pgroups[type]->attrs[sensor_groups[type].attr_count++] =
++				&sdata[count++].dev_attr.attr;
++	}
++
++exit_put_node:
++	of_node_put(opal);
++	return err;
++}
++
++static int __init ibmpowernv_probe(struct platform_device *pdev)
++{
++	struct platform_data *pdata;
++	struct device *hwmon_dev;
++	int err;
++
++	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++	if (!pdata)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pdata);
++	pdata->sensors_count = 0;
++	err = populate_attr_groups(pdev);
++	if (err)
++		return err;
++
++	/* Create sysfs attribute data for each sensor found in the DT */
++	err = create_device_attrs(pdev);
++	if (err)
++		return err;
++
++	/* Finally, register with hwmon */
++	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
++							   pdata,
++							   pdata->attr_groups);
++
++	return PTR_ERR_OR_ZERO(hwmon_dev);
++}
++
++static struct platform_driver ibmpowernv_driver = {
++	.driver = {
++		.owner = THIS_MODULE,
++		.name = DRVNAME,
++	},
++};
++
++static int __init ibmpowernv_init(void)
++{
++	int err;
++
++	pdevice = platform_device_alloc(DRVNAME, 0);
++	if (!pdevice) {
++		pr_err("Device allocation failed\n");
++		err = -ENOMEM;
++		goto exit;
++	}
++
++	err = platform_device_add(pdevice);
++	if (err) {
++		pr_err("Device addition failed (%d)\n", err);
++		goto exit_device_put;
++	}
++
++	err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
++	if (err) {
++		pr_err("Platfrom driver probe failed\n");
++		goto exit_device_del;
++	}
++
++	return 0;
++
++exit_device_del:
++	platform_device_del(pdevice);
++exit_device_put:
++	platform_device_put(pdevice);
++exit:
++	return err;
++}
++
++static void __exit ibmpowernv_exit(void)
++{
++	platform_driver_unregister(&ibmpowernv_driver);
++	platform_device_unregister(pdevice);
++}
++
++MODULE_AUTHOR("Neelesh Gupta <neelegup-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>");
++MODULE_DESCRIPTION("IBM POWERNV platform sensors");
++MODULE_LICENSE("GPL");
++
++module_init(ibmpowernv_init);
++module_exit(ibmpowernv_exit);
+
+--
+To unsubscribe from this list: send the line "unsubscribe devicetree" in
+the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff --git a/a/content_digest b/N2/content_digest
index 9d1a780..fa124fc 100644
--- a/a/content_digest
+++ b/N2/content_digest
@@ -1,6 +1,6 @@
- "From\0Neelesh Gupta <neelegup@linux.vnet.ibm.com>\0"
- "Subject\0[lm-sensors] [PATCH v5] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature\0"
- "Date\0Tue, 08 Jul 2014 09:20:38 +0000\0"
+ "From\0Neelesh Gupta <neelegup-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>\0"
+ "Subject\0[PATCH v5] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature\0"
+ "Date\0Tue, 08 Jul 2014 14:38:38 +0530\0"
  "To\0devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
   linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
  " lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org\0"
@@ -11,305 +11,578 @@
  " linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org\0"
  "\00:1\0"
  "b\0"
- "VGhpcyBwYXRjaCBhZGRzIGJhc2ljIGtlcm5lbCBzdXBwb3J0IGZvciByZWFkaW5nIHBvd2VyIHZh\n"
- "bHVlcywgZmFuCnNwZWVkIHJwbSwgdm9sdGFnZSBhbmQgdGVtcGVyYXR1cmUgZGF0YSBvbiBwb3dl\n"
- "cm52IHBsYXRmb3JtcyB3aGljaAp3aWxsIGJlIGV4cG9ydGVkIHRvIHVzZXIgc3BhY2UgdGhyb3Vn\n"
- "aCBzeXNmcyBpbnRlcmZhY2UuCgpUZXN0IHJlc3VsdHM6Ci0tLS0tLS0tLS0tLS0KW3Jvb3RAdHVs\n"
- "MTYzcDEgfl0jIHNlbnNvcnMKaWJtcG93ZXJudi1pc2EtMDAwMApBZGFwdGVyOiBJU0EgYWRhcHRl\n"
- "cgpmYW4xOiAgICAgICAgNTQ2NSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuMjogICAgICAgIDUx\n"
- "NTIgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjM6ICAgICAgICA1NTIxIFJQTSAgKG1pbiA9ICAg\n"
- "IDAgUlBNKQpmYW40OiAgICAgICAgNDg5MSBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFuNTogICAg\n"
- "ICAgICAgIDAgUlBNICAobWluID0gICAgMCBSUE0pCmZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1p\n"
- "biA9ICAgIDAgUlBNKQpmYW43OiAgICAgICAgNzQ4MCBSUE0gIChtaW4gPSAgICAwIFJQTSkKZmFu\n"
- "ODogICAgICAgIDc5NDQgUlBNICAobWluID0gICAgMCBSUE0pCnRlbXAxOiAgICAgICAgKzM5LjDC\n"
- "sEMgIChoaWdoID0gICswLjDCsEMpCnBvd2VyMTogICAgICAxOTAuMDAgVyAgCgpbcm9vdEB0dWwx\n"
- "NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwphbGFybXRpbWVyICBpYm1wb3dlcm52\n"
- "LjAgIHBvd2VyICBydGMtZ2VuZXJpYyAgc2VyaWFsODI1MCAgdWV2ZW50Cltyb290QHR1bDE2M3Ax\n"
- "IH5dIyBscyAvc3lzL2RldmljZXMvcGxhdGZvcm0vaWJtcG93ZXJudi4wL2h3bW9uL2h3bW9uMC8K\n"
- "ZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2Vy\n"
- "CmZhbjFfZmF1bHQgIGZhbjNfZmF1bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQg\n"
- "IHBvd2VyMV9pbnB1dApmYW4xX2lucHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5w\n"
- "dXQJaW4yX2ZhdWx0ICBzdWJzeXN0ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAg\n"
- "ZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZh\n"
- "bjZfZmF1bHQgIGZhbjhfZmF1bHQJaW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFu\n"
- "NF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2\n"
- "M3AxIH5dIyBscyAvc3lzL2NsYXNzL2h3bW9uL2h3bW9uMC8KZGV2aWNlCSAgICBmYW4yX21pbglm\n"
- "YW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAgIHBvd2VyCmZhbjFfZmF1bHQgIGZhbjNfZmF1\n"
- "bHQJZmFuNV9mYXVsdCAgZmFuN19mYXVsdAlpbjFfZmF1bHQgIHBvd2VyMV9pbnB1dApmYW4xX2lu\n"
- "cHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICBzdWJzeXN0\n"
- "ZW0KZmFuMV9taW4gICAgZmFuM19taW4JZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0\n"
- "ZW1wMV9pbnB1dApmYW4yX2ZhdWx0ICBmYW40X2ZhdWx0CWZhbjZfZmF1bHQgIGZhbjhfZmF1bHQJ\n"
- "aW40X2ZhdWx0ICB0ZW1wMV9tYXgKZmFuMl9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBm\n"
- "YW44X2lucHV0CW5hbWUJICAgdWV2ZW50Cltyb290QHR1bDE2M3AxIH5dIwoKU2lnbmVkLW9mZi1i\n"
- "eTogTmVlbGVzaCBHdXB0YSA8bmVlbGVndXBAbGludXgudm5ldC5pYm0uY29tPgpSZXZpZXdlZC1i\n"
- "eTogR3VlbnRlciBSb2VjayA8bGludXhAcm9lY2stdXMubmV0PgotLS0KCkNoYW5nZXMgaW4gdjUK\n"
- "PT09PT09PT09PT09PQotIEFkZHJlc3NlZCBjb3VwbGUgbWlub3IgY29tbWVudHMgaW4gdjQuCgpD\n"
- "aGFuZ2VzIGluIHY0Cj09PT09PT09PT09PT0KLSBSZXBsYWNlZCBwcl9lcnIoKSB3aXRoIGRldl9l\n"
- "cnIoKSBmb3IgbG9nZ2luZyBwcmludCBtZXNzYWdlcy4KLSBVc2luZyBrc3RydG91MzIoKSBmdW5j\n"
- "dGlvbiBmb3IgY29udmVydGluZyBzdHJpbmcgdG8gdTMyIGluc3RlYWQgb2Ygc3NjYW5mKCkuCgpD\n"
- "aGFuZ2VzIGluIHYzCj09PT09PT09PT09PT0KLSBGaXhlZCBhbiBlbmRpYW5uZXNzIGJ1ZyBsZWFk\n"
- "aW5nIHRoZSBkcml2ZXIgdG8gYnJlYWsgb24gTEUuCi0gRml4ZWQgYSBidWcgdGhhdCB3aGVuIG9u\n"
- "ZSBvZiB0aGUgJ2F0dHJpYnV0ZV9ncm91cCcgbm90IHBvcHVsYXRlZCwgZm9sbG93aW5nCiAgZ3Jv\n"
- "dXBzIGF0dHJpYnV0ZXMgd2VyZSBkcm9wcGVkLgotIFJld3JpdGUgdGhlIGdldF9zZW5zb3JfaW5k\n"
- "ZXhfYXR0cigpIGZ1bmN0aW9uIHRvIGhhbmRsZSBhbGwgdGhlIGVycm9yIHNjZW5hcmlvcwogIGxp\n"
- "a2UgJ3NzY2FuZicgZXRjLgotIEZpeGVkIGFsbCB0aGUgZXJyb3JzL3dhcm5pbmdzIHJlbGF0ZWQg\n"
- "dG8gY29kaW5nIHN0eWxlL3doaXRlc3BhY2UuCi0gQWRkZWQgJ0RvY3VtZW50YXRpb24nIGZpbGVz\n"
- "LgotIEFkZHJlc3NlZCByZW1haW5pbmcgcmV2aWV3IGNvbW1lbnRzIG9uIFYyLgoKQ2hhbmdlcyBp\n"
- "biB2Mgo9PT09PT09PT09PT09Ci0gR2VuZXJpYyB1c2Ugb2YgZGV2bV8qIGZ1bmN0aW9ucyBpbiBo\n"
- "d21vbiBsaWtlIHVzaW5nIGRldm1fa3phbGxvYygpIGZvciBkeW5hbWljCiAgbWVtb3J5IHJlcXVl\n"
- "c3QsIGF2b2lkaW5nIHRoZSBuZWVkIHRvIGV4cGxpY2l0IGZyZWUgb2YgbWVtb3J5LgogIEFkZGlu\n"
- "ZyAnc3RydWN0IGF0dHJpYnV0ZV9ncm91cCcgYXMgbWVtYmVyIG9mIHBsYXRmb3JtIGRhdGEgc3Ry\n"
- "dWN0dXJlIHRvIGJlCiAgcG9wdWxhdGVkIGFuZCB0aGVuIHBhc3NlZCB0byBkZXZtX2h3bW9uX2Rl\n"
- "dmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgoKICBOb3RlOiBIYXZpbmcgYW4gYXJyYXkgb2Yg\n"
- "cG9pbnRlcnMgb2YgJ2F0dHJpYnV0ZV9ncm91cCcgYW5kIGVhY2ggZ3JvdXAKICBjb3JyZXNwb25k\n"
- "cyB0byAnZW51bSBzZW5zb3JzJyB0eXBlLiBOb3QgY29tcGxldGVseSBzdXJlLCBpZiBpdCdzIGlk\n"
- "ZWFsIG9yCiAgY291bGQgaGF2ZSBqdXN0IG9uZSBncm91cCBwb3B1bGF0ZWQgd2l0aCBhdHRyaWJ1\n"
- "dGVzIG9mIHNlbnNvciB0eXBlcz8KCi0gJ2libXBvd2VybnYnIGlzIG5vdCBob3QtcGx1Z2dhYmxl\n"
- "IGRldmljZSBzbyBtb3ZpbmcgJ3BsYXRmb3JtX2RyaXZlcicgY2FsbGJhY2sKICBmdW5jdGlvbiAo\n"
- "cHJvYmUpIGFzIHBhcnQgb2YgX19pbml0IGNvZGUuCi0gRml4ZWQgaXNzdWVzIHJlbGF0ZWQgdG8g\n"
- "Y29kaW5nIHN0eWxlLgotIE90aGVyIGdlbmVyYWwgY29tbWVudHMgaW4gdjEuCgogLi4uL2Rldmlj\n"
- "ZXRyZWUvYmluZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQgICAgICAgfCAgIDIzICsKIERvY3Vt\n"
- "ZW50YXRpb24vaHdtb24vaWJtcG93ZXJudiAgICAgICAgICAgICAgICAgICAgIHwgICA0MSArKwog\n"
- "ZHJpdmVycy9od21vbi9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEx\n"
- "ICsKIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg\n"
- "ICAgMSAKIGRyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jICAgICAgICAgICAgICAgICAgICAgICAg\n"
- "IHwgIDM2NCArKysrKysrKysrKysrKysrKysrKwogNSBmaWxlcyBjaGFuZ2VkLCA0NDAgaW5zZXJ0\n"
- "aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5k\n"
- "aW5ncy9od21vbi9pYm1wb3dlcm52LnR4dAogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp\n"
- "b24vaHdtb24vaWJtcG93ZXJudgogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaHdtb24vaWJt\n"
- "cG93ZXJudi5jCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz\n"
- "L2h3bW9uL2libXBvd2VybnYudHh0IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdz\n"
- "L2h3bW9uL2libXBvd2VybnYudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu\n"
- "LmY5MzI0MmIKLS0tIC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmlu\n"
- "ZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQKQEAgLTAsMCArMSwyMyBAQAorSUJNIFBPV0VSTlYg\n"
- "cGxhdGZvcm0gc2Vuc29ycworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSZXF1aXJl\n"
- "ZCBub2RlIHByb3BlcnRpZXM6CistIGNvbXBhdGlibGU6IG11c3QgYmUgb25lIG9mCisJCSJpYm0s\n"
- "b3BhbC1zZW5zb3ItY29vbGluZy1mYW4iCisJCSJpYm0sb3BhbC1zZW5zb3ItYW1iLXRlbXAiCisJ\n"
- "CSJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3VwcGx5IgorCQkiaWJtLG9wYWwtc2Vuc29yLXBvd2Vy\n"
- "IgorLSBzZW5zb3ItaWQ6IGFuIG9wYXF1ZSBpZCBwcm92aWRlZCBieSB0aGUgZmlybXdhcmUgdG8g\n"
- "dGhlIGtlcm5lbCwgaWRlbnRpZmllcyBhCisJICAgICBnaXZlbiBzZW5zb3IgYW5kIGl0cyBhdHRy\n"
- "aWJ1dGUgZGF0YQorCitFeGFtcGxlIHNlbnNvcnMgbm9kZToKKworY29vbGluZy1mYW4jOC1kYXRh\n"
- "IHsKKwlzZW5zb3ItaWQgPSA8MHg3MDUyMTA3PjsKKwljb21wYXRpYmxlID0gImlibSxvcGFsLXNl\n"
- "bnNvci1jb29saW5nLWZhbiI7Cit9OworCithbWItdGVtcCMxLXRocnMgeworCXNlbnNvci1pZCA9\n"
- "IDwweDUwOTYwMDA+OworCWNvbXBhdGlibGUgPSAiaWJtLG9wYWwtc2Vuc29yLWFtYi10ZW1wIjsK\n"
- "K307CmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYgYi9Eb2N1bWVu\n"
- "dGF0aW9uL2h3bW9uL2libXBvd2VybnYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw\n"
- "MC4uNjQ0MjQ1YQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdtb24vaWJtcG93\n"
- "ZXJudgpAQCAtMCwwICsxLDQxIEBACitLZXJuZWwgRHJpdmVyIElCTVBPV0VOVgorPT09PT09PT09\n"
- "PT09PT09PT09PT09PT0KKworU3VwcG9ydGVkIHN5c3RlbXM6CisgICogQW55IHJlY2VudCBJQk0g\n"
- "UCBzZXJ2ZXJzIGJhc2VkIG9uIFBPV0VSTlYgcGxhdGZvcm0KKworQXV0aG9yOiBOZWVsZXNoIEd1\n"
- "cHRhCisKK0Rlc2NyaXB0aW9uCistLS0tLS0tLS0tLQorCitUaGlzIGRyaXZlciBpbXBsZW1lbnRz\n"
- "IHJlYWRpbmcgdGhlIHBsYXRmb3JtIHNlbnNvcnMgZGF0YSBsaWtlIHRlbXBlcmF0dXJlL2Zhbi8K\n"
- "K3ZvbHRhZ2UvcG93ZXIgZm9yICdQT1dFUk5WJyBwbGF0Zm9ybS4KKworVGhlIGRyaXZlciB1c2Vz\n"
- "IHRoZSBwbGF0Zm9ybSBkZXZpY2UgaW5mcmFzdHJ1Y3R1cmUuIEl0IHByb2JlcyB0aGUgZGV2aWNl\n"
- "IHRyZWUKK2ZvciBzZW5zb3IgZGV2aWNlcyBkdXJpbmcgdGhlIF9faW5pdCBwaGFzZSBhbmQgcmVn\n"
- "aXN0ZXJzIHRoZW0gd2l0aCB0aGUgJ2h3bW9uJy4KKydod21vbicgcG9wdWxhdGVzIHRoZSAnc3lz\n"
- "ZnMnIHRyZWUgaGF2aW5nIGF0dHJpYnV0ZSBmaWxlcywgZWFjaCBmb3IgYSBnaXZlbgorc2Vuc29y\n"
- "IHR5cGUgYW5kIGl0cyBhdHRyaWJ1dGUgZGF0YS4KKworQWxsIHRoZSBub2RlcyBpbiB0aGUgRFQg\n"
- "YXBwZWFyIHVuZGVyICIvaWJtLG9wYWwvc2Vuc29ycyIgYW5kIGVhY2ggdmFsaWQgbm9kZSBpbgor\n"
- "dGhlIERUIG1hcHMgdG8gYW4gYXR0cmlidXRlIGZpbGUgaW4gJ3N5c2ZzJy4gVGhlIG5vZGUgZXhw\n"
- "b3J0cyB1bmlxdWUgJ3NlbnNvci1pZCcKK3doaWNoIHRoZSBkcml2ZXIgdXNlcyB0byBtYWtlIGFu\n"
- "IE9QQUwgY2FsbCB0byB0aGUgZmlybXdhcmUuCisKK1VzYWdlIG5vdGVzCistLS0tLS0tLS0tLQor\n"
- "VGhlIGRyaXZlciBpcyBidWlsdCBzdGF0aWNhbGx5IHdpdGggdGhlIGtlcm5lbCBieSBlbmFibGlu\n"
- "ZyB0aGUgY29uZmlnCitDT05GSUdfU0VOU09SU19JQk1QT1dFUk5WLiBJdCBjYW4gYWxzbyBiZSBi\n"
- "dWlsdCBhcyBtb2R1bGUgJ2libXBvd2VybnYnLgorCitTeXNmcyBhdHRyaWJ1dGVzCistLS0tLS0t\n"
- "LS0tLS0tLS0tCisKK2ZhblhfaW5wdXQJCU1lYXN1cmVkIFJQTSB2YWx1ZS4KK2ZhblhfbWluCQlU\n"
- "aHJlc2hvbGQgUlBNIGZvciBhbGVydCBnZW5lcmF0aW9uLgorZmFuWF9mYXVsdAkJMDogTm8gZmFp\n"
- "bCBjb25kaXRpb24KKwkJCTE6IEZhaWxpbmcgZmFuCit0ZW1wWF9pbnB1dAkJTWVhc3VyZWQgYW1i\n"
- "aWVudCB0ZW1wZXJhdHVyZS4KK3RlbXBYX21heAkJVGhyZXNob2xkIGFtYmllbnQgdGVtcGVyYXR1\n"
- "cmUgZm9yIGFsZXJ0IGdlbmVyYXRpb24uCitpblhfaW5wdXQJCU1lYXN1cmVkIHBvd2VyIHN1cHBs\n"
- "eSB2b2x0YWdlCitpblhfZmF1bHQJCTA6IE5vIGZhaWwgY29uZGl0aW9uLgorCQkJMTogRmFpbGlu\n"
- "ZyBwb3dlciBzdXBwbHkuCitwb3dlcjFfaW5wdXQJCVN5c3RlbSBwb3dlciBjb25zdW1wdGlvbiAo\n"
- "bWljcm9XYXR0KQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9o\n"
- "d21vbi9LY29uZmlnCmluZGV4IDAyZDNkODUuLjI5YzNmY2IgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMv\n"
- "aHdtb24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKQEAgLTU1NCw2ICs1NTQs\n"
- "MTcgQEAgY29uZmlnIFNFTlNPUlNfSUJNUEVYCiAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBi\n"
- "dWlsdCBhcyBhIG1vZHVsZS4gIElmIHNvLCB0aGUgbW9kdWxlCiAJICB3aWxsIGJlIGNhbGxlZCBp\n"
- "Ym1wZXguCiAKK2NvbmZpZyBTRU5TT1JTX0lCTVBPV0VSTlYKKwl0cmlzdGF0ZSAiSUJNIFBPV0VS\n"
- "TlYgcGxhdGZvcm0gc2Vuc29ycyIKKwlkZXBlbmRzIG9uIFBQQ19QT1dFUk5WCisJZGVmYXVsdCB5\n"
- "CisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIHRoZSB0\n"
- "ZW1wZXJhdHVyZS9mYW4vcG93ZXIKKwkgIHNlbnNvcnMgb24geW91ciBQb3dlck5WIHBsYXRmb3Jt\n"
- "LgorCisJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28s\n"
- "IHRoZSBtb2R1bGUKKwkgIHdpbGwgYmUgY2FsbGVkIGlibXBvd2VybnYuCisKIGNvbmZpZyBTRU5T\n"
- "T1JTX0lJT19IV01PTgogCXRyaXN0YXRlICJId21vbiBkcml2ZXIgdGhhdCB1c2VzIGNoYW5uZWxz\n"
- "IHNwZWNpZmllZCB2aWEgaWlvIG1hcHMiCiAJZGVwZW5kcyBvbiBJSU8KZGlmZiAtLWdpdCBhL2Ry\n"
- "aXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCmluZGV4IDNkYzBm\n"
- "MDIuLmZjNGVkMjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKKysrIGIvZHJp\n"
- "dmVycy9od21vbi9NYWtlZmlsZQpAQCAtNzEsNiArNzEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S\n"
- "U19VTFRSQTQ1KQkrPSB1bHRyYTQ1X2Vudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JNUtfQU1C\n"
- "KQkrPSBpNWtfYW1iLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0lCTUFFTSkJKz0gaWJtYWVtLm8K\n"
- "IG9iai0kKENPTkZJR19TRU5TT1JTX0lCTVBFWCkJKz0gaWJtcGV4Lm8KK29iai0kKENPTkZJR19T\n"
- "RU5TT1JTX0lCTVBPV0VSTlYpKz0gaWJtcG93ZXJudi5vCiBvYmotJChDT05GSUdfU0VOU09SU19J\n"
- "SU9fSFdNT04pICs9IGlpb19od21vbi5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyMDkpCSs9\n"
- "IGluYTIwOS5vCiBvYmotJChDT05GSUdfU0VOU09SU19JTkEyWFgpCSs9IGluYTJ4eC5vCmRpZmYg\n"
- "LS1naXQgYS9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYyBiL2RyaXZlcnMvaHdtb24vaWJtcG93\n"
- "ZXJudi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YjY1MmEKLS0tIC9k\n"
- "ZXYvbnVsbAorKysgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwpAQCAtMCwwICsxLDM2NCBA\n"
- "QAorLyoKKyAqIElCTSBQb3dlck5WIHBsYXRmb3JtIHNlbnNvcnMgZm9yIHRlbXBlcmF0dXJlL2Zh\n"
- "bi92b2x0YWdlL3Bvd2VyCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSUJNCisgKgorICogVGhpcyBw\n"
- "cm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBt\n"
- "b2RpZnkKKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExp\n"
- "Y2Vuc2UgYXMgcHVibGlzaGVkIGJ5CisgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBl\n"
- "aXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICogKGF0IHlvdXIgb3B0aW9uKSBh\n"
- "bnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g\n"
- "dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJS\n"
- "QU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFC\n"
- "SUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBH\n"
- "TlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqIFlvdSBz\n"
- "aG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl\n"
- "bnNlCisgKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4KKyAqLworCisjZGVmaW5lIERSVk5BTUUJ\n"
- "CSJpYm1wb3dlcm52IgorI2RlZmluZSBwcl9mbXQoZm10KQlEUlZOQU1FICI6ICIgZm10CisKKyNp\n"
- "bmNsdWRlIDxsaW51eC9pbml0Lmg+CisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CisjaW5jbHVk\n"
- "ZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KKyNpbmNsdWRlIDxs\n"
- "aW51eC9od21vbi1zeXNmcy5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGlu\n"
- "dXgvc2xhYi5oPgorCisjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CisjaW5jbHVk\n"
- "ZSA8YXNtL29wYWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKworI2RlZmluZSBNQVhfQVRU\n"
- "Ul9MRU4JMzIKKworLyogU2Vuc29yIHN1ZmZpeCBuYW1lIGZyb20gRFQgKi8KKyNkZWZpbmUgRFRf\n"
- "RkFVTFRfQVRUUl9TVUZGSVgJCSJmYXVsdGVkIgorI2RlZmluZSBEVF9EQVRBX0FUVFJfU1VGRklY\n"
- "CQkiZGF0YSIKKyNkZWZpbmUgRFRfVEhSRVNIT0xEX0FUVFJfU1VGRklYCSJ0aHJzIgorCisvKgor\n"
- "ICogRW51bWVyYXRlcyBhbGwgdGhlIHR5cGVzIG9mIHNlbnNvcnMgaW4gdGhlIFBPV0VSTlYgcGxh\n"
- "dGZvcm0gYW5kIGRvZXMgaW5kZXgKKyAqIGludG8gJ3N0cnVjdCBzZW5zb3JfZ3JvdXAnCisgKi8K\n"
- "K2VudW0gc2Vuc29ycyB7CisJRkFOLAorCUFNQklFTlRfVEVNUCwKKwlQT1dFUl9TVVBQTFksCisJ\n"
- "UE9XRVJfSU5QVVQsCisJTUFYX1NFTlNPUl9UWVBFLAorfTsKKworc3RhdGljIHN0cnVjdCBzZW5z\n"
- "b3JfZ3JvdXAgeworCWNvbnN0IGNoYXIgKm5hbWU7CisJY29uc3QgY2hhciAqY29tcGF0aWJsZTsK\n"
- "KwlzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGdyb3VwOworCXUzMiBhdHRyX2NvdW50OworfSBzZW5z\n"
- "b3JfZ3JvdXBzW10gPSB7CisJeyJmYW4iLCAiaWJtLG9wYWwtc2Vuc29yLWNvb2xpbmctZmFuIn0s\n"
- "CisJeyJ0ZW1wIiwgImlibSxvcGFsLXNlbnNvci1hbWItdGVtcCJ9LAorCXsiaW4iLCAiaWJtLG9w\n"
- "YWwtc2Vuc29yLXBvd2VyLXN1cHBseSJ9LAorCXsicG93ZXIiLCAiaWJtLG9wYWwtc2Vuc29yLXBv\n"
- "d2VyIn0KK307CisKK3N0cnVjdCBzZW5zb3JfZGF0YSB7CisJdTMyIGlkOyAvKiBBbiBvcGFxdWUg\n"
- "aWQgb2YgdGhlIGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLworCWVudW0gc2Vuc29ycyB0eXBl\n"
- "OworCWNoYXIgbmFtZVtNQVhfQVRUUl9MRU5dOworCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRl\n"
- "dl9hdHRyOworfTsKKworc3RydWN0IHBsYXRmb3JtX2RhdGEgeworCWNvbnN0IHN0cnVjdCBhdHRy\n"
- "aWJ1dGVfZ3JvdXAgKmF0dHJfZ3JvdXBzW01BWF9TRU5TT1JfVFlQRSArIDFdOworCXUzMiBzZW5z\n"
- "b3JzX2NvdW50OyAvKiBUb3RhbCBjb3VudCBvZiBzZW5zb3JzIGZyb20gZWFjaCBncm91cCAqLwor\n"
- "fTsKKworLyogUGxhdGZvcm0gZGV2aWNlIHJlcHJlc2VudGluZyBhbGwgdGhlIGlibXBvd2VybnYg\n"
- "c2Vuc29ycyAqLworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXZpY2U7CisKK3N0\n"
- "YXRpYyBzc2l6ZV90IHNob3dfc2Vuc29yKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmlj\n"
- "ZV9hdHRyaWJ1dGUgKmRldmF0dHIsCisJCQkgICBjaGFyICpidWYpCit7CisJc3RydWN0IHNlbnNv\n"
- "cl9kYXRhICpzZGF0YSA9IGNvbnRhaW5lcl9vZihkZXZhdHRyLCBzdHJ1Y3Qgc2Vuc29yX2RhdGEs\n"
- "CisJCQkJCQkgZGV2X2F0dHIpOworCXNzaXplX3QgcmV0OworCXUzMiB4OworCisJcmV0ID0gb3Bh\n"
- "bF9nZXRfc2Vuc29yX2RhdGEoc2RhdGEtPmlkLCAmeCk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl\n"
- "dDsKKworCS8qIENvbnZlcnQgdGVtcGVyYXR1cmUgdG8gbWlsbGktZGVncmVlcyAqLworCWlmIChz\n"
- "ZGF0YS0+dHlwZSA9PSBBTUJJRU5UX1RFTVApCisJCXggKj0gMTAwMDsKKwkvKiBDb252ZXJ0IHBv\n"
- "d2VyIHRvIG1pY3JvLXdhdHRzICovCisJZWxzZSBpZiAoc2RhdGEtPnR5cGUgPT0gUE9XRVJfSU5Q\n"
- "VVQpCisJCXggKj0gMTAwMDAwMDsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiV1XG4iLCB4KTsK\n"
- "K30KKworc3RhdGljIGludCBfX2luaXQgZ2V0X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0IGNoYXIg\n"
- "Km5hbWUsIHUzMiAqaW5kZXgsCisJCQkJCWNoYXIgKmF0dHIpCit7CisJY2hhciAqaGFzaF9wb3Mg\n"
- "PSBzdHJjaHIobmFtZSwgJyMnKTsKKwljaGFyIGJ1Zls4XSA9IHsgMCB9OworCWNoYXIgKmRhc2hf\n"
- "cG9zOworCXUzMiBjb3B5X2xlbjsKKwlpbnQgZXJyOworCisJaWYgKCFoYXNoX3BvcykKKwkJcmV0\n"
- "dXJuIC1FSU5WQUw7CisKKwlkYXNoX3BvcyA9IHN0cmNocihoYXNoX3BvcywgJy0nKTsKKwlpZiAo\n"
- "IWRhc2hfcG9zKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWNvcHlfbGVuID0gZGFzaF9wb3MgLSBo\n"
- "YXNoX3BvcyAtIDE7CisJaWYgKGNvcHlfbGVuID49IHNpemVvZihidWYpKQorCQlyZXR1cm4gLUVJ\n"
- "TlZBTDsKKworCXN0cm5jcHkoYnVmLCBoYXNoX3BvcyArIDEsIGNvcHlfbGVuKTsKKworCWVyciA9\n"
- "IGtzdHJ0b3UzMihidWYsIDEwLCBpbmRleCk7CisJaWYgKGVycikKKwkJcmV0dXJuIGVycjsKKwor\n"
- "CXN0cm5jcHkoYXR0ciwgZGFzaF9wb3MgKyAxLCBNQVhfQVRUUl9MRU4pOworCisJcmV0dXJuIDA7\n"
- "Cit9CisKKy8qCisgKiBUaGlzIGZ1bmN0aW9uIHRyYW5zbGF0ZXMgdGhlIERUIG5vZGUgbmFtZSBp\n"
- "bnRvIHRoZSAnaHdtb24nIGF0dHJpYnV0ZSBuYW1lLgorICogSUJNUE9XRVJOViBkZXZpY2Ugbm9k\n"
- "ZSBhcHBlYXIgbGlrZSBjb29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCisg\n"
- "KiB3aGljaCBuZWVkIHRvIGJlIG1hcHBlZCBhcyBmYW4yX2lucHV0LCB0ZW1wMV9tYXggcmVzcGVj\n"
- "dGl2ZWx5IGJlZm9yZQorICogcG9wdWxhdGluZyB0aGVtIGluc2lkZSBod21vbiBkZXZpY2UgY2xh\n"
- "c3MuCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9od21vbl9hdHRyX25hbWUoc3RydWN0\n"
- "IGRldmljZSAqZGV2LCBlbnVtIHNlbnNvcnMgdHlwZSwKKwkJCQkJIGNvbnN0IGNoYXIgKm5vZGVf\n"
- "bmFtZSwKKwkJCQkJIGNoYXIgKmh3bW9uX2F0dHJfbmFtZSkKK3sKKwljaGFyIGF0dHJfc3VmZml4\n"
- "W01BWF9BVFRSX0xFTl07CisJY2hhciAqYXR0cl9uYW1lOworCXUzMiBpbmRleDsKKwlpbnQgZXJy\n"
- "OworCisJZXJyID0gZ2V0X3NlbnNvcl9pbmRleF9hdHRyKG5vZGVfbmFtZSwgJmluZGV4LCBhdHRy\n"
- "X3N1ZmZpeCk7CisJaWYgKGVycikgeworCQlkZXZfZXJyKGRldiwgIlNlbnNvciBkZXZpY2Ugbm9k\n"
- "ZSBuYW1lICclcycgaXMgaW52YWxpZFxuIiwKKwkJCW5vZGVfbmFtZSk7CisJCXJldHVybiBlcnI7\n"
- "CisJfQorCisJaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX0ZBVUxUX0FUVFJfU1VGRklYKSkg\n"
- "eworCQlhdHRyX25hbWUgPSAiZmF1bHQiOworCX0gZWxzZSBpZiAoIXN0cmNtcChhdHRyX3N1ZmZp\n"
- "eCwgRFRfREFUQV9BVFRSX1NVRkZJWCkpIHsKKwkJYXR0cl9uYW1lID0gImlucHV0IjsKKwl9IGVs\n"
- "c2UgaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgsIERUX1RIUkVTSE9MRF9BVFRSX1NVRkZJWCkpIHsK\n"
- "KwkJaWYgKHR5cGUgPT0gQU1CSUVOVF9URU1QKQorCQkJYXR0cl9uYW1lID0gIm1heCI7CisJCWVs\n"
- "c2UgaWYgKHR5cGUgPT0gRkFOKQorCQkJYXR0cl9uYW1lID0gIm1pbiI7CisJCWVsc2UKKwkJCXJl\n"
- "dHVybiAtRU5PRU5UOworCX0gZWxzZSB7CisJCXJldHVybiAtRU5PRU5UOworCX0KKworCXNucHJp\n"
- "bnRmKGh3bW9uX2F0dHJfbmFtZSwgTUFYX0FUVFJfTEVOLCAiJXMlZF8lcyIsCisJCSBzZW5zb3Jf\n"
- "Z3JvdXBzW3R5cGVdLm5hbWUsIGluZGV4LCBhdHRyX25hbWUpOworCXJldHVybiAwOworfQorCitz\n"
- "dGF0aWMgaW50IF9faW5pdCBwb3B1bGF0ZV9hdHRyX2dyb3VwcyhzdHJ1Y3QgcGxhdGZvcm1fZGV2\n"
- "aWNlICpwZGV2KQoreworCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dl\n"
- "dF9kcnZkYXRhKHBkZXYpOworCWNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKipwZ3JvdXBz\n"
- "ID0gcGRhdGEtPmF0dHJfZ3JvdXBzOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqb3BhbCwgKm5wOwor\n"
- "CWVudW0gc2Vuc29ycyB0eXBlOworCisJb3BhbCA9IG9mX2ZpbmRfbm9kZV9ieV9wYXRoKCIvaWJt\n"
- "LG9wYWwvc2Vuc29ycyIpOworCWlmICghb3BhbCkgeworCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJP\n"
- "cGFsIG5vZGUgJ3NlbnNvcnMnIG5vdCBmb3VuZFxuIik7CisJCXJldHVybiAtRU5PREVWOworCX0K\n"
- "KworCWZvcl9lYWNoX2NoaWxkX29mX25vZGUob3BhbCwgbnApIHsKKwkJaWYgKG5wLT5uYW1lID09\n"
- "IE5VTEwpCisJCQljb250aW51ZTsKKworCQlmb3IgKHR5cGUgPSAwOyB0eXBlIDwgTUFYX1NFTlNP\n"
- "Ul9UWVBFOyB0eXBlKyspCisJCQlpZiAob2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsCisJCQkJ\n"
- "CXNlbnNvcl9ncm91cHNbdHlwZV0uY29tcGF0aWJsZSkpIHsKKwkJCQlzZW5zb3JfZ3JvdXBzW3R5\n"
- "cGVdLmF0dHJfY291bnQrKzsKKwkJCQlicmVhazsKKwkJCX0KKwl9CisKKwlvZl9ub2RlX3B1dChv\n"
- "cGFsKTsKKworCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykg\n"
- "eworCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzID0gZGV2bV9remFsbG9jKCZwZGV2\n"
- "LT5kZXYsCisJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRlICopICoKKwkJCQkJKHNlbnNvcl9n\n"
- "cm91cHNbdHlwZV0uYXR0cl9jb3VudCArIDEpLAorCQkJCQlHRlBfS0VSTkVMKTsKKwkJaWYgKCFz\n"
- "ZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJzKQorCQkJcmV0dXJuIC1FTk9NRU07CisKKwkJ\n"
- "cGdyb3Vwc1t0eXBlXSA9ICZzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwOworCQlwZGF0YS0+c2Vu\n"
- "c29yc19jb3VudCArPSBzZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291bnQ7CisJCXNlbnNvcl9n\n"
- "cm91cHNbdHlwZV0uYXR0cl9jb3VudCA9IDA7CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qCisg\n"
- "KiBJdGVyYXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVlIGZvciBlYWNoIGNoaWxkIG9mICdzZW5z\n"
- "b3JzJyBub2RlLCBjcmVhdGUKKyAqIGEgc3lzZnMgYXR0cmlidXRlIGZpbGUsIHRoZSBmaWxlIGlz\n"
- "IG5hbWVkIGJ5IHRyYW5zbGF0aW5nIHRoZSBEVCBub2RlIG5hbWUKKyAqIHRvIHRoZSBuYW1lIHJl\n"
- "cXVpcmVkIGJ5IHRoZSBoaWdoZXIgJ2h3bW9uJyBkcml2ZXIgbGlrZSBmYW4xX2lucHV0LCB0ZW1w\n"
- "MV9tYXgKKyAqIGV0Yy4uCisgKi8KK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9kZXZpY2VfYXR0\n"
- "cnMoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgcGxhdGZvcm1fZGF0\n"
- "YSAqcGRhdGEgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwljb25zdCBzdHJ1Y3QgYXR0\n"
- "cmlidXRlX2dyb3VwICoqcGdyb3VwcyA9IHBkYXRhLT5hdHRyX2dyb3VwczsKKwlzdHJ1Y3QgZGV2\n"
- "aWNlX25vZGUgKm9wYWwsICpucDsKKwlzdHJ1Y3Qgc2Vuc29yX2RhdGEgKnNkYXRhOworCWNvbnN0\n"
- "IF9fYmUzMiAqc2Vuc29yX2lkOworCWVudW0gc2Vuc29ycyB0eXBlOworCXUzMiBjb3VudCA9IDA7\n"
- "CisJaW50IGVyciA9IDA7CisKKwlvcGFsID0gb2ZfZmluZF9ub2RlX2J5X3BhdGgoIi9pYm0sb3Bh\n"
- "bC9zZW5zb3JzIik7CisJc2RhdGEgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgcGRhdGEtPnNl\n"
- "bnNvcnNfY291bnQgKiBzaXplb2YoKnNkYXRhKSwKKwkJCSAgICAgR0ZQX0tFUk5FTCk7CisJaWYg\n"
- "KCFzZGF0YSkgeworCQllcnIgPSAtRU5PTUVNOworCQlnb3RvIGV4aXRfcHV0X25vZGU7CisJfQor\n"
- "CisJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShvcGFsLCBucCkgeworCQlpZiAobnAtPm5hbWUgPT0g\n"
- "TlVMTCkKKwkJCWNvbnRpbnVlOworCisJCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09S\n"
- "X1RZUEU7IHR5cGUrKykKKwkJCWlmIChvZl9kZXZpY2VfaXNfY29tcGF0aWJsZShucCwKKwkJCQkJ\n"
- "c2Vuc29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkKKwkJCQlicmVhazsKKworCQlpZiAodHlw\n"
- "ZSA9PSBNQVhfU0VOU09SX1RZUEUpCisJCQljb250aW51ZTsKKworCQlzZW5zb3JfaWQgPSBvZl9n\n"
- "ZXRfcHJvcGVydHkobnAsICJzZW5zb3ItaWQiLCBOVUxMKTsKKwkJaWYgKCFzZW5zb3JfaWQpIHsK\n"
- "KwkJCWRldl9pbmZvKCZwZGV2LT5kZXYsCisJCQkJICInc2Vuc29yLWlkJyBtaXNzaW5nIGluIHRo\n"
- "ZSBub2RlICclcydcbiIsCisJCQkJIG5wLT5uYW1lKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJ\n"
- "c2RhdGFbY291bnRdLmlkID0gYmUzMl90b19jcHVwKHNlbnNvcl9pZCk7CisJCXNkYXRhW2NvdW50\n"
- "XS50eXBlID0gdHlwZTsKKwkJZXJyID0gY3JlYXRlX2h3bW9uX2F0dHJfbmFtZSgmcGRldi0+ZGV2\n"
- "LCB0eXBlLCBucC0+bmFtZSwKKwkJCQkJICAgICBzZGF0YVtjb3VudF0ubmFtZSk7CisJCWlmIChl\n"
- "cnIpCisJCQlnb3RvIGV4aXRfcHV0X25vZGU7CisKKwkJc3lzZnNfYXR0cl9pbml0KCZzZGF0YVtj\n"
- "b3VudF0uZGV2X2F0dHIuYXR0cik7CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5hdHRyLm5hbWUg\n"
- "PSBzZGF0YVtjb3VudF0ubmFtZTsKKwkJc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIubW9kZSA9\n"
- "IFNfSVJVR087CisJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5zaG93ID0gc2hvd19zZW5zb3I7CisK\n"
- "KwkJcGdyb3Vwc1t0eXBlXS0+YXR0cnNbc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50Kytd\n"
- "ID0KKwkJCQkmc2RhdGFbY291bnQrK10uZGV2X2F0dHIuYXR0cjsKKwl9CisKK2V4aXRfcHV0X25v\n"
- "ZGU6CisJb2Zfbm9kZV9wdXQob3BhbCk7CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIGludCBf\n"
- "X2luaXQgaWJtcG93ZXJudl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQorewor\n"
- "CXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YTsKKwlzdHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7\n"
- "CisJaW50IGVycjsKKworCXBkYXRhID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigq\n"
- "cGRhdGEpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXBkYXRhKQorCQlyZXR1cm4gLUVOT01FTTsKKwor\n"
- "CXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIHBkYXRhKTsKKwlwZGF0YS0+c2Vuc29yc19jb3Vu\n"
- "dCA9IDA7CisJZXJyID0gcG9wdWxhdGVfYXR0cl9ncm91cHMocGRldik7CisJaWYgKGVycikKKwkJ\n"
- "cmV0dXJuIGVycjsKKworCS8qIENyZWF0ZSBzeXNmcyBhdHRyaWJ1dGUgZGF0YSBmb3IgZWFjaCBz\n"
- "ZW5zb3IgZm91bmQgaW4gdGhlIERUICovCisJZXJyID0gY3JlYXRlX2RldmljZV9hdHRycyhwZGV2\n"
- "KTsKKwlpZiAoZXJyKQorCQlyZXR1cm4gZXJyOworCisJLyogRmluYWxseSwgcmVnaXN0ZXIgd2l0\n"
- "aCBod21vbiAqLworCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhf\n"
- "Z3JvdXBzKCZwZGV2LT5kZXYsIERSVk5BTUUsCisJCQkJCQkJICAgcGRhdGEsCisJCQkJCQkJICAg\n"
- "cGRhdGEtPmF0dHJfZ3JvdXBzKTsKKworCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2\n"
- "KTsKK30KKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaWJtcG93ZXJudl9kcml2ZXIg\n"
- "PSB7CisJLmRyaXZlciA9IHsKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJCS5uYW1lID0gRFJW\n"
- "TkFNRSwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgaWJtcG93ZXJudl9pbml0KHZvaWQp\n"
- "Cit7CisJaW50IGVycjsKKworCXBkZXZpY2UgPSBwbGF0Zm9ybV9kZXZpY2VfYWxsb2MoRFJWTkFN\n"
- "RSwgMCk7CisJaWYgKCFwZGV2aWNlKSB7CisJCXByX2VycigiRGV2aWNlIGFsbG9jYXRpb24gZmFp\n"
- "bGVkXG4iKTsKKwkJZXJyID0gLUVOT01FTTsKKwkJZ290byBleGl0OworCX0KKworCWVyciA9IHBs\n"
- "YXRmb3JtX2RldmljZV9hZGQocGRldmljZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIkRldmlj\n"
- "ZSBhZGRpdGlvbiBmYWlsZWQgKCVkKVxuIiwgZXJyKTsKKwkJZ290byBleGl0X2RldmljZV9wdXQ7\n"
- "CisJfQorCisJZXJyID0gcGxhdGZvcm1fZHJpdmVyX3Byb2JlKCZpYm1wb3dlcm52X2RyaXZlciwg\n"
- "aWJtcG93ZXJudl9wcm9iZSk7CisJaWYgKGVycikgeworCQlwcl9lcnIoIlBsYXRmcm9tIGRyaXZl\n"
- "ciBwcm9iZSBmYWlsZWRcbiIpOworCQlnb3RvIGV4aXRfZGV2aWNlX2RlbDsKKwl9CisKKwlyZXR1\n"
- "cm4gMDsKKworZXhpdF9kZXZpY2VfZGVsOgorCXBsYXRmb3JtX2RldmljZV9kZWwocGRldmljZSk7\n"
- "CitleGl0X2RldmljZV9wdXQ6CisJcGxhdGZvcm1fZGV2aWNlX3B1dChwZGV2aWNlKTsKK2V4aXQ6\n"
- "CisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IGlibXBvd2VybnZfZXhpdCh2\n"
- "b2lkKQoreworCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZpYm1wb3dlcm52X2RyaXZlcik7\n"
- "CisJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIocGRldmljZSk7Cit9CisKK01PRFVMRV9BVVRI\n"
- "T1IoIk5lZWxlc2ggR3VwdGEgPG5lZWxlZ3VwQGxpbnV4LnZuZXQuaWJtLmNvbT4iKTsKK01PRFVM\n"
- "RV9ERVNDUklQVElPTigiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIpOworTU9EVUxFX0xJ\n"
- "Q0VOU0UoIkdQTCIpOworCittb2R1bGVfaW5pdChpYm1wb3dlcm52X2luaXQpOworbW9kdWxlX2V4\n"
- "aXQoaWJtcG93ZXJudl9leGl0KTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n"
- "X19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNv\n"
- "cnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNl\n"
- bnNvcnM
+ "This patch adds basic kernel support for reading power values, fan\n"
+ "speed rpm, voltage and temperature data on powernv platforms which\n"
+ "will be exported to user space through sysfs interface.\n"
+ "\n"
+ "Test results:\n"
+ "-------------\n"
+ "[root@tul163p1 ~]# sensors\n"
+ "ibmpowernv-isa-0000\n"
+ "Adapter: ISA adapter\n"
+ "fan1:        5465 RPM  (min =    0 RPM)\n"
+ "fan2:        5152 RPM  (min =    0 RPM)\n"
+ "fan3:        5521 RPM  (min =    0 RPM)\n"
+ "fan4:        4891 RPM  (min =    0 RPM)\n"
+ "fan5:           0 RPM  (min =    0 RPM)\n"
+ "fan6:           0 RPM  (min =    0 RPM)\n"
+ "fan7:        7480 RPM  (min =    0 RPM)\n"
+ "fan8:        7944 RPM  (min =    0 RPM)\n"
+ "temp1:        +39.0\302\260C  (high =  +0.0\302\260C)\n"
+ "power1:      190.00 W  \n"
+ "\n"
+ "[root@tul163p1 ~]# ls /sys/devices/platform/\n"
+ "alarmtimer  ibmpowernv.0  power  rtc-generic  serial8250  uevent\n"
+ "[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/\n"
+ "device\t    fan2_min\tfan4_min    fan6_min\tfan8_min   power\n"
+ "fan1_fault  fan3_fault\tfan5_fault  fan7_fault\tin1_fault  power1_input\n"
+ "fan1_input  fan3_input\tfan5_input  fan7_input\tin2_fault  subsystem\n"
+ "fan1_min    fan3_min\tfan5_min    fan7_min\tin3_fault  temp1_input\n"
+ "fan2_fault  fan4_fault\tfan6_fault  fan8_fault\tin4_fault  temp1_max\n"
+ "fan2_input  fan4_input\tfan6_input  fan8_input\tname\t   uevent\n"
+ "[root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/\n"
+ "device\t    fan2_min\tfan4_min    fan6_min\tfan8_min   power\n"
+ "fan1_fault  fan3_fault\tfan5_fault  fan7_fault\tin1_fault  power1_input\n"
+ "fan1_input  fan3_input\tfan5_input  fan7_input\tin2_fault  subsystem\n"
+ "fan1_min    fan3_min\tfan5_min    fan7_min\tin3_fault  temp1_input\n"
+ "fan2_fault  fan4_fault\tfan6_fault  fan8_fault\tin4_fault  temp1_max\n"
+ "fan2_input  fan4_input\tfan6_input  fan8_input\tname\t   uevent\n"
+ "[root@tul163p1 ~]#\n"
+ "\n"
+ "Signed-off-by: Neelesh Gupta <neelegup-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>\n"
+ "Reviewed-by: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>\n"
+ "---\n"
+ "\n"
+ "Changes in v5\n"
+ "=============\n"
+ "- Addressed couple minor comments in v4.\n"
+ "\n"
+ "Changes in v4\n"
+ "=============\n"
+ "- Replaced pr_err() with dev_err() for logging print messages.\n"
+ "- Using kstrtou32() function for converting string to u32 instead of sscanf().\n"
+ "\n"
+ "Changes in v3\n"
+ "=============\n"
+ "- Fixed an endianness bug leading the driver to break on LE.\n"
+ "- Fixed a bug that when one of the 'attribute_group' not populated, following\n"
+ "  groups attributes were dropped.\n"
+ "- Rewrite the get_sensor_index_attr() function to handle all the error scenarios\n"
+ "  like 'sscanf' etc.\n"
+ "- Fixed all the errors/warnings related to coding style/whitespace.\n"
+ "- Added 'Documentation' files.\n"
+ "- Addressed remaining review comments on V2.\n"
+ "\n"
+ "Changes in v2\n"
+ "=============\n"
+ "- Generic use of devm_* functions in hwmon like using devm_kzalloc() for dynamic\n"
+ "  memory request, avoiding the need to explicit free of memory.\n"
+ "  Adding 'struct attribute_group' as member of platform data structure to be\n"
+ "  populated and then passed to devm_hwmon_device_register_with_groups().\n"
+ "\n"
+ "  Note: Having an array of pointers of 'attribute_group' and each group\n"
+ "  corresponds to 'enum sensors' type. Not completely sure, if it's ideal or\n"
+ "  could have just one group populated with attributes of sensor types?\n"
+ "\n"
+ "- 'ibmpowernv' is not hot-pluggable device so moving 'platform_driver' callback\n"
+ "  function (probe) as part of __init code.\n"
+ "- Fixed issues related to coding style.\n"
+ "- Other general comments in v1.\n"
+ "\n"
+ " .../devicetree/bindings/hwmon/ibmpowernv.txt       |   23 +\n"
+ " Documentation/hwmon/ibmpowernv                     |   41 ++\n"
+ " drivers/hwmon/Kconfig                              |   11 +\n"
+ " drivers/hwmon/Makefile                             |    1 \n"
+ " drivers/hwmon/ibmpowernv.c                         |  364 ++++++++++++++++++++\n"
+ " 5 files changed, 440 insertions(+)\n"
+ " create mode 100644 Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ " create mode 100644 Documentation/hwmon/ibmpowernv\n"
+ " create mode 100644 drivers/hwmon/ibmpowernv.c\n"
+ "\n"
+ "diff --git a/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ "new file mode 100644\n"
+ "index 0000000..f93242b\n"
+ "--- /dev/null\n"
+ "+++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt\n"
+ "@@ -0,0 +1,23 @@\n"
+ "+IBM POWERNV platform sensors\n"
+ "+----------------------------\n"
+ "+\n"
+ "+Required node properties:\n"
+ "+- compatible: must be one of\n"
+ "+\t\t\"ibm,opal-sensor-cooling-fan\"\n"
+ "+\t\t\"ibm,opal-sensor-amb-temp\"\n"
+ "+\t\t\"ibm,opal-sensor-power-supply\"\n"
+ "+\t\t\"ibm,opal-sensor-power\"\n"
+ "+- sensor-id: an opaque id provided by the firmware to the kernel, identifies a\n"
+ "+\t     given sensor and its attribute data\n"
+ "+\n"
+ "+Example sensors node:\n"
+ "+\n"
+ "+cooling-fan#8-data {\n"
+ "+\tsensor-id = <0x7052107>;\n"
+ "+\tcompatible = \"ibm,opal-sensor-cooling-fan\";\n"
+ "+};\n"
+ "+\n"
+ "+amb-temp#1-thrs {\n"
+ "+\tsensor-id = <0x5096000>;\n"
+ "+\tcompatible = \"ibm,opal-sensor-amb-temp\";\n"
+ "+};\n"
+ "diff --git a/Documentation/hwmon/ibmpowernv b/Documentation/hwmon/ibmpowernv\n"
+ "new file mode 100644\n"
+ "index 0000000..644245a\n"
+ "--- /dev/null\n"
+ "+++ b/Documentation/hwmon/ibmpowernv\n"
+ "@@ -0,0 +1,41 @@\n"
+ "+Kernel Driver IBMPOWENV\n"
+ "+=======================\n"
+ "+\n"
+ "+Supported systems:\n"
+ "+  * Any recent IBM P servers based on POWERNV platform\n"
+ "+\n"
+ "+Author: Neelesh Gupta\n"
+ "+\n"
+ "+Description\n"
+ "+-----------\n"
+ "+\n"
+ "+This driver implements reading the platform sensors data like temperature/fan/\n"
+ "+voltage/power for 'POWERNV' platform.\n"
+ "+\n"
+ "+The driver uses the platform device infrastructure. It probes the device tree\n"
+ "+for sensor devices during the __init phase and registers them with the 'hwmon'.\n"
+ "+'hwmon' populates the 'sysfs' tree having attribute files, each for a given\n"
+ "+sensor type and its attribute data.\n"
+ "+\n"
+ "+All the nodes in the DT appear under \"/ibm,opal/sensors\" and each valid node in\n"
+ "+the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'\n"
+ "+which the driver uses to make an OPAL call to the firmware.\n"
+ "+\n"
+ "+Usage notes\n"
+ "+-----------\n"
+ "+The driver is built statically with the kernel by enabling the config\n"
+ "+CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.\n"
+ "+\n"
+ "+Sysfs attributes\n"
+ "+----------------\n"
+ "+\n"
+ "+fanX_input\t\tMeasured RPM value.\n"
+ "+fanX_min\t\tThreshold RPM for alert generation.\n"
+ "+fanX_fault\t\t0: No fail condition\n"
+ "+\t\t\t1: Failing fan\n"
+ "+tempX_input\t\tMeasured ambient temperature.\n"
+ "+tempX_max\t\tThreshold ambient temperature for alert generation.\n"
+ "+inX_input\t\tMeasured power supply voltage\n"
+ "+inX_fault\t\t0: No fail condition.\n"
+ "+\t\t\t1: Failing power supply.\n"
+ "+power1_input\t\tSystem power consumption (microWatt)\n"
+ "diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig\n"
+ "index 02d3d85..29c3fcb 100644\n"
+ "--- a/drivers/hwmon/Kconfig\n"
+ "+++ b/drivers/hwmon/Kconfig\n"
+ "@@ -554,6 +554,17 @@ config SENSORS_IBMPEX\n"
+ " \t  This driver can also be built as a module.  If so, the module\n"
+ " \t  will be called ibmpex.\n"
+ " \n"
+ "+config SENSORS_IBMPOWERNV\n"
+ "+\ttristate \"IBM POWERNV platform sensors\"\n"
+ "+\tdepends on PPC_POWERNV\n"
+ "+\tdefault y\n"
+ "+\thelp\n"
+ "+\t  If you say yes here you get support for the temperature/fan/power\n"
+ "+\t  sensors on your PowerNV platform.\n"
+ "+\n"
+ "+\t  This driver can also be built as a module. If so, the module\n"
+ "+\t  will be called ibmpowernv.\n"
+ "+\n"
+ " config SENSORS_IIO_HWMON\n"
+ " \ttristate \"Hwmon driver that uses channels specified via iio maps\"\n"
+ " \tdepends on IIO\n"
+ "diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile\n"
+ "index 3dc0f02..fc4ed26 100644\n"
+ "--- a/drivers/hwmon/Makefile\n"
+ "+++ b/drivers/hwmon/Makefile\n"
+ "@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45)\t+= ultra45_env.o\n"
+ " obj-$(CONFIG_SENSORS_I5K_AMB)\t+= i5k_amb.o\n"
+ " obj-$(CONFIG_SENSORS_IBMAEM)\t+= ibmaem.o\n"
+ " obj-$(CONFIG_SENSORS_IBMPEX)\t+= ibmpex.o\n"
+ "+obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o\n"
+ " obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o\n"
+ " obj-$(CONFIG_SENSORS_INA209)\t+= ina209.o\n"
+ " obj-$(CONFIG_SENSORS_INA2XX)\t+= ina2xx.o\n"
+ "diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c\n"
+ "new file mode 100644\n"
+ "index 0000000..e6b652a\n"
+ "--- /dev/null\n"
+ "+++ b/drivers/hwmon/ibmpowernv.c\n"
+ "@@ -0,0 +1,364 @@\n"
+ "+/*\n"
+ "+ * IBM PowerNV platform sensors for temperature/fan/voltage/power\n"
+ "+ * Copyright (C) 2014 IBM\n"
+ "+ *\n"
+ "+ * This program is free software; you can redistribute it and/or modify\n"
+ "+ * it under the terms of the GNU General Public License as published by\n"
+ "+ * the Free Software Foundation; either version 2 of the License, or\n"
+ "+ * (at your option) any later version.\n"
+ "+ *\n"
+ "+ * This program is distributed in the hope that it will be useful,\n"
+ "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+ "+ * GNU General Public License for more details.\n"
+ "+ *\n"
+ "+ * You should have received a copy of the GNU General Public License\n"
+ "+ * along with this program.\n"
+ "+ */\n"
+ "+\n"
+ "+#define DRVNAME\t\t\"ibmpowernv\"\n"
+ "+#define pr_fmt(fmt)\tDRVNAME \": \" fmt\n"
+ "+\n"
+ "+#include <linux/init.h>\n"
+ "+#include <linux/module.h>\n"
+ "+#include <linux/kernel.h>\n"
+ "+#include <linux/hwmon.h>\n"
+ "+#include <linux/hwmon-sysfs.h>\n"
+ "+#include <linux/of.h>\n"
+ "+#include <linux/slab.h>\n"
+ "+\n"
+ "+#include <linux/platform_device.h>\n"
+ "+#include <asm/opal.h>\n"
+ "+#include <linux/err.h>\n"
+ "+\n"
+ "+#define MAX_ATTR_LEN\t32\n"
+ "+\n"
+ "+/* Sensor suffix name from DT */\n"
+ "+#define DT_FAULT_ATTR_SUFFIX\t\t\"faulted\"\n"
+ "+#define DT_DATA_ATTR_SUFFIX\t\t\"data\"\n"
+ "+#define DT_THRESHOLD_ATTR_SUFFIX\t\"thrs\"\n"
+ "+\n"
+ "+/*\n"
+ "+ * Enumerates all the types of sensors in the POWERNV platform and does index\n"
+ "+ * into 'struct sensor_group'\n"
+ "+ */\n"
+ "+enum sensors {\n"
+ "+\tFAN,\n"
+ "+\tAMBIENT_TEMP,\n"
+ "+\tPOWER_SUPPLY,\n"
+ "+\tPOWER_INPUT,\n"
+ "+\tMAX_SENSOR_TYPE,\n"
+ "+};\n"
+ "+\n"
+ "+static struct sensor_group {\n"
+ "+\tconst char *name;\n"
+ "+\tconst char *compatible;\n"
+ "+\tstruct attribute_group group;\n"
+ "+\tu32 attr_count;\n"
+ "+} sensor_groups[] = {\n"
+ "+\t{\"fan\", \"ibm,opal-sensor-cooling-fan\"},\n"
+ "+\t{\"temp\", \"ibm,opal-sensor-amb-temp\"},\n"
+ "+\t{\"in\", \"ibm,opal-sensor-power-supply\"},\n"
+ "+\t{\"power\", \"ibm,opal-sensor-power\"}\n"
+ "+};\n"
+ "+\n"
+ "+struct sensor_data {\n"
+ "+\tu32 id; /* An opaque id of the firmware for each sensor */\n"
+ "+\tenum sensors type;\n"
+ "+\tchar name[MAX_ATTR_LEN];\n"
+ "+\tstruct device_attribute dev_attr;\n"
+ "+};\n"
+ "+\n"
+ "+struct platform_data {\n"
+ "+\tconst struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];\n"
+ "+\tu32 sensors_count; /* Total count of sensors from each group */\n"
+ "+};\n"
+ "+\n"
+ "+/* Platform device representing all the ibmpowernv sensors */\n"
+ "+static struct platform_device *pdevice;\n"
+ "+\n"
+ "+static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,\n"
+ "+\t\t\t   char *buf)\n"
+ "+{\n"
+ "+\tstruct sensor_data *sdata = container_of(devattr, struct sensor_data,\n"
+ "+\t\t\t\t\t\t dev_attr);\n"
+ "+\tssize_t ret;\n"
+ "+\tu32 x;\n"
+ "+\n"
+ "+\tret = opal_get_sensor_data(sdata->id, &x);\n"
+ "+\tif (ret)\n"
+ "+\t\treturn ret;\n"
+ "+\n"
+ "+\t/* Convert temperature to milli-degrees */\n"
+ "+\tif (sdata->type == AMBIENT_TEMP)\n"
+ "+\t\tx *= 1000;\n"
+ "+\t/* Convert power to micro-watts */\n"
+ "+\telse if (sdata->type == POWER_INPUT)\n"
+ "+\t\tx *= 1000000;\n"
+ "+\n"
+ "+\treturn sprintf(buf, \"%u\\n\", x);\n"
+ "+}\n"
+ "+\n"
+ "+static int __init get_sensor_index_attr(const char *name, u32 *index,\n"
+ "+\t\t\t\t\tchar *attr)\n"
+ "+{\n"
+ "+\tchar *hash_pos = strchr(name, '#');\n"
+ "+\tchar buf[8] = { 0 };\n"
+ "+\tchar *dash_pos;\n"
+ "+\tu32 copy_len;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tif (!hash_pos)\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tdash_pos = strchr(hash_pos, '-');\n"
+ "+\tif (!dash_pos)\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tcopy_len = dash_pos - hash_pos - 1;\n"
+ "+\tif (copy_len >= sizeof(buf))\n"
+ "+\t\treturn -EINVAL;\n"
+ "+\n"
+ "+\tstrncpy(buf, hash_pos + 1, copy_len);\n"
+ "+\n"
+ "+\terr = kstrtou32(buf, 10, index);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\tstrncpy(attr, dash_pos + 1, MAX_ATTR_LEN);\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/*\n"
+ "+ * This function translates the DT node name into the 'hwmon' attribute name.\n"
+ "+ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.\n"
+ "+ * which need to be mapped as fan2_input, temp1_max respectively before\n"
+ "+ * populating them inside hwmon device class.\n"
+ "+ */\n"
+ "+static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,\n"
+ "+\t\t\t\t\t const char *node_name,\n"
+ "+\t\t\t\t\t char *hwmon_attr_name)\n"
+ "+{\n"
+ "+\tchar attr_suffix[MAX_ATTR_LEN];\n"
+ "+\tchar *attr_name;\n"
+ "+\tu32 index;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\terr = get_sensor_index_attr(node_name, &index, attr_suffix);\n"
+ "+\tif (err) {\n"
+ "+\t\tdev_err(dev, \"Sensor device node name '%s' is invalid\\n\",\n"
+ "+\t\t\tnode_name);\n"
+ "+\t\treturn err;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tif (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {\n"
+ "+\t\tattr_name = \"fault\";\n"
+ "+\t} else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {\n"
+ "+\t\tattr_name = \"input\";\n"
+ "+\t} else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {\n"
+ "+\t\tif (type == AMBIENT_TEMP)\n"
+ "+\t\t\tattr_name = \"max\";\n"
+ "+\t\telse if (type == FAN)\n"
+ "+\t\t\tattr_name = \"min\";\n"
+ "+\t\telse\n"
+ "+\t\t\treturn -ENOENT;\n"
+ "+\t} else {\n"
+ "+\t\treturn -ENOENT;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tsnprintf(hwmon_attr_name, MAX_ATTR_LEN, \"%s%d_%s\",\n"
+ "+\t\t sensor_groups[type].name, index, attr_name);\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+static int __init populate_attr_groups(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata = platform_get_drvdata(pdev);\n"
+ "+\tconst struct attribute_group **pgroups = pdata->attr_groups;\n"
+ "+\tstruct device_node *opal, *np;\n"
+ "+\tenum sensors type;\n"
+ "+\n"
+ "+\topal = of_find_node_by_path(\"/ibm,opal/sensors\");\n"
+ "+\tif (!opal) {\n"
+ "+\t\tdev_err(&pdev->dev, \"Opal node 'sensors' not found\\n\");\n"
+ "+\t\treturn -ENODEV;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tfor_each_child_of_node(opal, np) {\n"
+ "+\t\tif (np->name == NULL)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tfor (type = 0; type < MAX_SENSOR_TYPE; type++)\n"
+ "+\t\t\tif (of_device_is_compatible(np,\n"
+ "+\t\t\t\t\tsensor_groups[type].compatible)) {\n"
+ "+\t\t\t\tsensor_groups[type].attr_count++;\n"
+ "+\t\t\t\tbreak;\n"
+ "+\t\t\t}\n"
+ "+\t}\n"
+ "+\n"
+ "+\tof_node_put(opal);\n"
+ "+\n"
+ "+\tfor (type = 0; type < MAX_SENSOR_TYPE; type++) {\n"
+ "+\t\tsensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,\n"
+ "+\t\t\t\t\tsizeof(struct attribute *) *\n"
+ "+\t\t\t\t\t(sensor_groups[type].attr_count + 1),\n"
+ "+\t\t\t\t\tGFP_KERNEL);\n"
+ "+\t\tif (!sensor_groups[type].group.attrs)\n"
+ "+\t\t\treturn -ENOMEM;\n"
+ "+\n"
+ "+\t\tpgroups[type] = &sensor_groups[type].group;\n"
+ "+\t\tpdata->sensors_count += sensor_groups[type].attr_count;\n"
+ "+\t\tsensor_groups[type].attr_count = 0;\n"
+ "+\t}\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+}\n"
+ "+\n"
+ "+/*\n"
+ "+ * Iterate through the device tree for each child of 'sensors' node, create\n"
+ "+ * a sysfs attribute file, the file is named by translating the DT node name\n"
+ "+ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max\n"
+ "+ * etc..\n"
+ "+ */\n"
+ "+static int __init create_device_attrs(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata = platform_get_drvdata(pdev);\n"
+ "+\tconst struct attribute_group **pgroups = pdata->attr_groups;\n"
+ "+\tstruct device_node *opal, *np;\n"
+ "+\tstruct sensor_data *sdata;\n"
+ "+\tconst __be32 *sensor_id;\n"
+ "+\tenum sensors type;\n"
+ "+\tu32 count = 0;\n"
+ "+\tint err = 0;\n"
+ "+\n"
+ "+\topal = of_find_node_by_path(\"/ibm,opal/sensors\");\n"
+ "+\tsdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),\n"
+ "+\t\t\t     GFP_KERNEL);\n"
+ "+\tif (!sdata) {\n"
+ "+\t\terr = -ENOMEM;\n"
+ "+\t\tgoto exit_put_node;\n"
+ "+\t}\n"
+ "+\n"
+ "+\tfor_each_child_of_node(opal, np) {\n"
+ "+\t\tif (np->name == NULL)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tfor (type = 0; type < MAX_SENSOR_TYPE; type++)\n"
+ "+\t\t\tif (of_device_is_compatible(np,\n"
+ "+\t\t\t\t\tsensor_groups[type].compatible))\n"
+ "+\t\t\t\tbreak;\n"
+ "+\n"
+ "+\t\tif (type == MAX_SENSOR_TYPE)\n"
+ "+\t\t\tcontinue;\n"
+ "+\n"
+ "+\t\tsensor_id = of_get_property(np, \"sensor-id\", NULL);\n"
+ "+\t\tif (!sensor_id) {\n"
+ "+\t\t\tdev_info(&pdev->dev,\n"
+ "+\t\t\t\t \"'sensor-id' missing in the node '%s'\\n\",\n"
+ "+\t\t\t\t np->name);\n"
+ "+\t\t\tcontinue;\n"
+ "+\t\t}\n"
+ "+\n"
+ "+\t\tsdata[count].id = be32_to_cpup(sensor_id);\n"
+ "+\t\tsdata[count].type = type;\n"
+ "+\t\terr = create_hwmon_attr_name(&pdev->dev, type, np->name,\n"
+ "+\t\t\t\t\t     sdata[count].name);\n"
+ "+\t\tif (err)\n"
+ "+\t\t\tgoto exit_put_node;\n"
+ "+\n"
+ "+\t\tsysfs_attr_init(&sdata[count].dev_attr.attr);\n"
+ "+\t\tsdata[count].dev_attr.attr.name = sdata[count].name;\n"
+ "+\t\tsdata[count].dev_attr.attr.mode = S_IRUGO;\n"
+ "+\t\tsdata[count].dev_attr.show = show_sensor;\n"
+ "+\n"
+ "+\t\tpgroups[type]->attrs[sensor_groups[type].attr_count++] =\n"
+ "+\t\t\t\t&sdata[count++].dev_attr.attr;\n"
+ "+\t}\n"
+ "+\n"
+ "+exit_put_node:\n"
+ "+\tof_node_put(opal);\n"
+ "+\treturn err;\n"
+ "+}\n"
+ "+\n"
+ "+static int __init ibmpowernv_probe(struct platform_device *pdev)\n"
+ "+{\n"
+ "+\tstruct platform_data *pdata;\n"
+ "+\tstruct device *hwmon_dev;\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tpdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);\n"
+ "+\tif (!pdata)\n"
+ "+\t\treturn -ENOMEM;\n"
+ "+\n"
+ "+\tplatform_set_drvdata(pdev, pdata);\n"
+ "+\tpdata->sensors_count = 0;\n"
+ "+\terr = populate_attr_groups(pdev);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\t/* Create sysfs attribute data for each sensor found in the DT */\n"
+ "+\terr = create_device_attrs(pdev);\n"
+ "+\tif (err)\n"
+ "+\t\treturn err;\n"
+ "+\n"
+ "+\t/* Finally, register with hwmon */\n"
+ "+\thwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,\n"
+ "+\t\t\t\t\t\t\t   pdata,\n"
+ "+\t\t\t\t\t\t\t   pdata->attr_groups);\n"
+ "+\n"
+ "+\treturn PTR_ERR_OR_ZERO(hwmon_dev);\n"
+ "+}\n"
+ "+\n"
+ "+static struct platform_driver ibmpowernv_driver = {\n"
+ "+\t.driver = {\n"
+ "+\t\t.owner = THIS_MODULE,\n"
+ "+\t\t.name = DRVNAME,\n"
+ "+\t},\n"
+ "+};\n"
+ "+\n"
+ "+static int __init ibmpowernv_init(void)\n"
+ "+{\n"
+ "+\tint err;\n"
+ "+\n"
+ "+\tpdevice = platform_device_alloc(DRVNAME, 0);\n"
+ "+\tif (!pdevice) {\n"
+ "+\t\tpr_err(\"Device allocation failed\\n\");\n"
+ "+\t\terr = -ENOMEM;\n"
+ "+\t\tgoto exit;\n"
+ "+\t}\n"
+ "+\n"
+ "+\terr = platform_device_add(pdevice);\n"
+ "+\tif (err) {\n"
+ "+\t\tpr_err(\"Device addition failed (%d)\\n\", err);\n"
+ "+\t\tgoto exit_device_put;\n"
+ "+\t}\n"
+ "+\n"
+ "+\terr = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);\n"
+ "+\tif (err) {\n"
+ "+\t\tpr_err(\"Platfrom driver probe failed\\n\");\n"
+ "+\t\tgoto exit_device_del;\n"
+ "+\t}\n"
+ "+\n"
+ "+\treturn 0;\n"
+ "+\n"
+ "+exit_device_del:\n"
+ "+\tplatform_device_del(pdevice);\n"
+ "+exit_device_put:\n"
+ "+\tplatform_device_put(pdevice);\n"
+ "+exit:\n"
+ "+\treturn err;\n"
+ "+}\n"
+ "+\n"
+ "+static void __exit ibmpowernv_exit(void)\n"
+ "+{\n"
+ "+\tplatform_driver_unregister(&ibmpowernv_driver);\n"
+ "+\tplatform_device_unregister(pdevice);\n"
+ "+}\n"
+ "+\n"
+ "+MODULE_AUTHOR(\"Neelesh Gupta <neelegup-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>\");\n"
+ "+MODULE_DESCRIPTION(\"IBM POWERNV platform sensors\");\n"
+ "+MODULE_LICENSE(\"GPL\");\n"
+ "+\n"
+ "+module_init(ibmpowernv_init);\n"
+ "+module_exit(ibmpowernv_exit);\n"
+ "\n"
+ "--\n"
+ "To unsubscribe from this list: send the line \"unsubscribe devicetree\" in\n"
+ "the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org\n"
+ More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
-f99de827708da98eed28b6adde09d30b1a31d6a06d37cee5bb5aaa5c9ecec889
+0343a3b3380c8135e584c358cb20f69bbe6e6dde14fa5aa0ff122f60778cf61d

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.