From mboxrd@z Thu Jan 1 00:00:00 1970 From: Neelesh Gupta Date: Mon, 26 May 2014 06:34:19 +0000 Subject: Re: [lm-sensors] [PATCH v2] powerpc/powernv: hwmon driver for power values, fan rpm and temperature Message-Id: <5382DD9B.2020406@linux.vnet.ibm.com> List-Id: References: <20140519141931.9248.11356.stgit@neelegup-tp-t420.in.ibm.com> In-Reply-To: <20140519141931.9248.11356.stgit@neelegup-tp-t420.in.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linuxppc-dev@lists.ozlabs.org, linux@roeck-us.net, jdelvare@suse.de, lm-sensors@lm-sensors.org Cc: sbhat@linux.vnet.ibm.com QW55IHVwZGF0ZXMgb24gdGhlIHBhdGNoLgoKLSBOZWVsZXNoCgpPbiAwNS8xOS8yMDE0IDA3OjU2 IFBNLCBOZWVsZXNoIEd1cHRhIHdyb3RlOgo+IFRoaXMgcGF0Y2ggYWRkcyBiYXNpYyBrZXJuZWwg ZW5hYmxlbWVudCBmb3IgcmVhZGluZyBwb3dlciB2YWx1ZXMsIGZhbgo+IHNwZWVkIHJwbSBhbmQg dGVtcGVyYXR1cmUgdmFsdWVzIG9uIHBvd2VybnYgcGxhdGZvcm1zIHdoaWNoIHdpbGwKPiBiZSBl eHBvcnRlZCB0byB1c2VyIHNwYWNlIHRocm91Z2ggc3lzZnMgaW50ZXJmYWNlLgo+Cj4gVGVzdCBy ZXN1bHRzOgo+IC0tLS0tLS0tLS0tLS0KPiBbcm9vdEB0dWwxNjNwMSB+XSMgc2Vuc29ycwo+IGli bXBvd2VybnYtaXNhLTAwMDAKPiBBZGFwdGVyOiBJU0EgYWRhcHRlcgo+IGZhbjE6ICAgICAgICA1 NDg3IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjI6ICAgICAgICA1MTUyIFJQTSAgKG1pbiA9 ICAgIDAgUlBNKQo+IGZhbjM6ICAgICAgICA1NTkwIFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZh bjQ6ICAgICAgICA0OTYzIFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjU6ICAgICAgICAgICAw IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1pbiA9ICAg IDAgUlBNKQo+IGZhbjc6ICAgICAgICA3NDg4IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjg6 ICAgICAgICA3OTQ0IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IHRlbXAxOiAgICAgICAgKzM5LjDC sEMgIChoaWdoID0gICswLjDCsEMpCj4gcG93ZXIxOiAgICAgIDE5Mi4wMCBXCj4KPiBbcm9vdEB0 dWwxNjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwo+IGFsYXJtdGltZXIgIGlibXBv d2VybnYuMCAgcnRjLWdlbmVyaWMgIHNlcmlhbDgyNTAgIHVldmVudAo+IFtyb290QHR1bDE2M3Ax IH5dIyBscyAvc3lzL2RldmljZXMvcGxhdGZvcm0vaWJtcG93ZXJudi4wLwo+IGRyaXZlci8gICAg aHdtb24vICAgICBtb2RhbGlhcyAgIHN1YnN5c3RlbS8gdWV2ZW50Cj4gW3Jvb3RAdHVsMTYzcDEg fl0jIGxzIC9zeXMvZGV2aWNlcy9wbGF0Zm9ybS9pYm1wb3dlcm52LjAvaHdtb24vaHdtb24wLwo+ IGRldmljZQkgICAgZmFuMl9taW4JZmFuNF9taW4gICAgZmFuNl9taW4JZmFuOF9taW4gICBwb3dl cjFfaW5wdXQKPiBmYW4xX2ZhdWx0ICBmYW4zX2ZhdWx0CWZhbjVfZmF1bHQgIGZhbjdfZmF1bHQJ aW4xX2ZhdWx0ICBzdWJzeXN0ZW0KPiBmYW4xX2lucHV0ICBmYW4zX2lucHV0CWZhbjVfaW5wdXQg IGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICB0ZW1wMV9pbnB1dAo+IGZhbjFfbWluICAgIGZhbjNfbWlu CWZhbjVfbWluICAgIGZhbjdfbWluCWluM19mYXVsdCAgdGVtcDFfbWF4Cj4gZmFuMl9mYXVsdCAg ZmFuNF9mYXVsdAlmYW42X2ZhdWx0ICBmYW44X2ZhdWx0CWluNF9mYXVsdCAgdWV2ZW50Cj4gZmFu Ml9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lucHV0CW5hbWUKPiBbcm9vdEB0 dWwxNjNwMSB+XSMKPiBbcm9vdEB0dWwxNjNwMSB+XSMgbHMgL3N5cy9jbGFzcy9od21vbi9od21v bjAvCj4gZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAg IHBvd2VyMV9pbnB1dAo+IGZhbjFfZmF1bHQgIGZhbjNfZmF1bHQJZmFuNV9mYXVsdCAgZmFuN19m YXVsdAlpbjFfZmF1bHQgIHN1YnN5c3RlbQo+IGZhbjFfaW5wdXQgIGZhbjNfaW5wdXQJZmFuNV9p bnB1dCAgZmFuN19pbnB1dAlpbjJfZmF1bHQgIHRlbXAxX2lucHV0Cj4gZmFuMV9taW4gICAgZmFu M19taW4JZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9tYXgKPiBmYW4yX2Zh dWx0ICBmYW40X2ZhdWx0CWZhbjZfZmF1bHQgIGZhbjhfZmF1bHQJaW40X2ZhdWx0ICB1ZXZlbnQK PiBmYW4yX2lucHV0ICBmYW40X2lucHV0CWZhbjZfaW5wdXQgIGZhbjhfaW5wdXQJbmFtZQo+IFty b290QHR1bDE2M3AxIH5dIwo+Cj4gU2lnbmVkLW9mZi1ieTogTmVlbGVzaCBHdXB0YSA8bmVlbGVn dXBAbGludXgudm5ldC5pYm0uY29tPgo+IC0tLQo+Cj4gQ2hhbmdlcyBpbiB2Mgo+ID09PT09PT09 PT09PT0KPiAtIEdlbmVyaWMgdXNlIG9mIGRldm1fKiBmdW5jdGlvbnMgaW4gaHdtb24gbGlrZSB1 c2luZyBkZXZtX2t6YWxsb2MoKSBmb3IgZHluYW1pYwo+ICAgIG1lbW9yeSByZXF1ZXN0LCBhdm9p ZGluZyB0aGUgbmVlZCB0byBleHBsaWNpdCBmcmVlIG9mIG1lbW9yeS4KPiAgICBBZGRpbmcgJ3N0 cnVjdCBhdHRyaWJ1dGVfZ3JvdXAnIGFzIG1lbWJlciBvZiBwbGF0Zm9ybSBkYXRhIHN0cnVjdHVy ZSB0byBiZQo+ICAgIHBvcHVsYXRlZCBhbmQgdGhlbiBwYXNzZWQgdG8gZGV2bV9od21vbl9kZXZp Y2VfcmVnaXN0ZXJfd2l0aF9ncm91cHMoKS4KPgo+ICAgIE5vdGU6IEhhdmluZyBhbiBhcnJheSBv ZiBwb2ludGVycyBvZiAnYXR0cmlidXRlX2dyb3VwJyBhbmQgZWFjaCBncm91cAo+ICAgIGNvcnJl c3BvbmRzIHRvICdlbnVtIHNlbnNvcnMnIHR5cGUuIE5vdCBjb21wbGV0ZWx5IHN1cmUsIGlmIGl0 J3MgaWRlYWwgb3IKPiAgICBjb3VsZCBoYXZlIGp1c3Qgb25lIGdyb3VwIHBvcHVsYXRlZCB3aXRo IGF0dHJpYnV0ZXMgb2Ygc2Vuc29yIHR5cGVzPwo+Cj4gLSAnaWJtcG93ZXJudicgaXMgbm90IGhv dC1wbHVnZ2FibGUgZGV2aWNlIHNvIG1vdmluZyAncGxhdGZvcm1fZHJpdmVyJyBjYWxsYmFjawo+ ICAgIGZ1bmN0aW9uIChwcm9iZSkgYXMgcGFydCBvZiBfX2luaXQgY29kZS4KPiAtIEZpeGVkIGlz c3VlcyByZWxhdGVkIHRvIGNvZGluZyBzdHlsZS4KPiAtIE90aGVyIGdlbmVyYWwgY29tbWVudHMg aW4gdjEuCj4KPiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgIHwgICAgOCArCj4gICBkcml2 ZXJzL2h3bW9uL01ha2VmaWxlICAgICB8ICAgIDEKPiAgIGRyaXZlcnMvaHdtb24vaWJtcG93ZXJu di5jIHwgIDM2OCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ ICAgMyBmaWxlcyBjaGFuZ2VkLCAzNzcgaW5zZXJ0aW9ucygrKQo+ICAgY3JlYXRlIG1vZGUgMTAw NjQ0IGRyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jCj4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9o d21vbi9LY29uZmlnIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gaW5kZXggYmMxOTZmNC4uM2Uz MDhmYSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2h3bW9uL0tjb25maWcKPiArKysgYi9kcml2ZXJz L2h3bW9uL0tjb25maWcKPiBAQCAtNTU0LDYgKzU1NCwxNCBAQCBjb25maWcgU0VOU09SU19JQk1Q RVgKPiAgIAkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiAgSWYg c28sIHRoZSBtb2R1bGUKPiAgIAkgIHdpbGwgYmUgY2FsbGVkIGlibXBleC4KPiAgIAo+ICtjb25m aWcgU0VOU09SU19JQk1QT1dFUk5WCj4gKwl0cmlzdGF0ZSAiSUJNIFBPV0VSTlYgcGxhdGZvcm0g c2Vuc29ycyIKPiArCWRlcGVuZHMgb24gUFBDX1BPV0VSTlYKPiArCWRlZmF1bHQgeQo+ICsJaGVs cAo+ICsJICBJZiB5b3Ugc2F5IHllcyBoZXJlIHlvdSBnZXQgc3VwcG9ydCBmb3IgdGhlIHRlbXBl cmF0dXJlL2Zhbi9wb3dlcgo+ICsJICBzZW5zb3JzIG9uIHlvdXIgcGxhdGZvcm0uCj4gKwo+ICAg Y29uZmlnIFNFTlNPUlNfSUlPX0hXTU9OCj4gICAJdHJpc3RhdGUgIkh3bW9uIGRyaXZlciB0aGF0 IHVzZXMgY2hhbm5lbHMgc3BlY2lmaWVkIHZpYSBpaW8gbWFwcyIKPiAgIAlkZXBlbmRzIG9uIElJ Two+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlIGIvZHJpdmVycy9od21vbi9N YWtlZmlsZQo+IGluZGV4IGM0OGY5ODcuLjE5OWM0MDEgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9o d21vbi9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKPiBAQCAtNzEsNiAr NzEsNyBAQCBvYmotJChDT05GSUdfU0VOU09SU19VTFRSQTQ1KQkrPSB1bHRyYTQ1X2Vudi5vCj4g ICBvYmotJChDT05GSUdfU0VOU09SU19JNUtfQU1CKQkrPSBpNWtfYW1iLm8KPiAgIG9iai0kKENP TkZJR19TRU5TT1JTX0lCTUFFTSkJKz0gaWJtYWVtLm8KPiAgIG9iai0kKENPTkZJR19TRU5TT1JT X0lCTVBFWCkJKz0gaWJtcGV4Lm8KPiArb2JqLSQoQ09ORklHX1NFTlNPUlNfSUJNUE9XRVJOVikr PSBpYm1wb3dlcm52Lm8KPiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0lJT19IV01PTikgKz0gaWlv X2h3bW9uLm8KPiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0lOQTIwOSkJKz0gaW5hMjA5Lm8KPiAg IG9iai0kKENPTkZJR19TRU5TT1JTX0lOQTJYWCkJKz0gaW5hMnh4Lm8KPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9od21vbi9pYm1wb3dlcm52LmMgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwo+ IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uYWZjZTYyMAo+IC0tLSAvZGV2 L251bGwKPiArKysgYi9kcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwo+IEBAIC0wLDAgKzEsMzY4 IEBACj4gKy8qCj4gKyAqIElCTSBQb3dlck5WIHBsYXRmb3JtIHNlbnNvcnMgZm9yIHRlbXBlcmF0 dXJlL2Zhbi9wb3dlcgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSUJNCj4gKyAqCj4gKyAqIFRo aXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQv b3IgbW9kaWZ5Cj4gKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVi bGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5Cj4gKyAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k YXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCj4gKyAqIChhdCB5b3Vy IG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBk aXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAo+ICsgKiBidXQg V0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBv Zgo+ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBP U0UuICBTZWUgdGhlCj4gKyAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRl dGFpbHMuCj4gKyAqCj4gKyAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhl IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCj4gKyAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFt Lgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9pbml0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGlu dXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9vZi5oPgo+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ICsKPiArI2luY2x1ZGUg PGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8YXNtL29wYWwuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsKPiArI2RlZmluZSBEUlZOQU1FCQkiaWJtcG93ZXJudiIK PiArI2RlZmluZSBNQVhfQVRUUl9MRU4JMzIKPiArCj4gKy8qIFNlbnNvciBzdWZmaXggbmFtZSBm cm9tIERUICovCj4gKyNkZWZpbmUgRFRfRkFVTFRfQVRUUl9TVUZGSVgJCSJmYXVsdGVkIgo+ICsj ZGVmaW5lIERUX0RBVEFfQVRUUl9TVUZGSVgJCSJkYXRhIgo+ICsjZGVmaW5lIERUX1RIUkVTSE9M RF9BVFRSX1NVRkZJWAkidGhycyIKPiArCj4gKy8qCj4gKyAqIEVudW1lcmF0ZXMgYWxsIHRoZSB0 eXBlcyBvZiBzZW5zb3JzIGluIHRoZSBQT1dFUk5WIHBsYXRmb3JtIGFuZCBkb2VzIGluZGV4Cj4g KyAqIGludG8gJ3N0cnVjdCBzZW5zb3JfZ3JvdXAnCj4gKyAqLwo+ICtlbnVtIHNlbnNvcnMgewo+ ICsJRkFOLAo+ICsJQU1CSUVOVF9URU1QLAo+ICsJUE9XRVJfU1VQUExZLAo+ICsJUE9XRVJfSU5Q VVQsCj4gKwlNQVhfU0VOU09SX1RZUEUsCj4gK307Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHNlbnNv cl9ncm91cCB7Cj4gKwljb25zdCBjaGFyICpuYW1lOwo+ICsJY29uc3QgY2hhciAqY29tcGF0aWJs ZTsKPiArCXN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgZ3JvdXA7Cj4gKwl1MzIgYXR0cl9jb3VudDsK PiArfSBzZW5zb3JfZ3JvdXBzW10gPSB7Cj4gKwl7ImZhbiIsICJpYm0sb3BhbC1zZW5zb3ItY29v bGluZy1mYW4iLCB7MH0sIDB9LAo+ICsJeyJ0ZW1wIiwgImlibSxvcGFsLXNlbnNvci1hbWItdGVt cCIsIHswfSwgMH0sCj4gKwl7ImluIiwgImlibSxvcGFsLXNlbnNvci1wb3dlci1zdXBwbHkiLCB7 MH0sIDB9LAo+ICsJeyJwb3dlciIsICJpYm0sb3BhbC1zZW5zb3ItcG93ZXIiLCB7MH0sIDB9Cj4g K307Cj4gKwo+ICtzdHJ1Y3Qgc2Vuc29yX2RhdGEgewo+ICsJdTMyIGlkOyAvKiBBbiBvcGFxdWUg aWQgb2YgdGhlIGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLwo+ICsJZW51bSBzZW5zb3JzIHR5 cGU7Cj4gKwljaGFyIG5hbWVbTUFYX0FUVFJfTEVOXTsKPiArCXN0cnVjdCBkZXZpY2VfYXR0cmli dXRlIGRldl9hdHRyOwo+ICt9Owo+ICsKPiArc3RydWN0IHBsYXRmb3JtX2RhdGEgewo+ICsJY29u c3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCAqYXR0cl9ncm91cHNbTUFYX1NFTlNPUl9UWVBFICsg MV07Cj4gKwl1MzIgc2Vuc29yc19jb3VudDsgLyogVG90YWwgY291bnQgb2Ygc2Vuc29ycyBmcm9t IGVhY2ggZ3JvdXAgKi8KPiArfTsKPiArCj4gKy8qIFBsYXRmb3JtIGRldmljZSByZXByZXNlbnRp bmcgYWxsIHRoZSBpYm1wb3dlcm52IHNlbnNvcnMgKi8KPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKnBkZXZpY2U7Cj4gKwo+ICtzdGF0aWMgc3NpemVfdCBzaG93X3NlbnNvcihzdHJ1 Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICpkZXZhdHRyLAo+ICsJCQkg ICBjaGFyICpidWYpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGF0YSAqc2RhdGEgPSBjb250YWlu ZXJfb2YoZGV2YXR0ciwgc3RydWN0IHNlbnNvcl9kYXRhLAo+ICsJCQkJCQkgZGV2X2F0dHIpOwo+ ICsJc3NpemVfdCByZXQ7Cj4gKwl1MzIgeDsKPiArCj4gKwlyZXQgPSBvcGFsX2dldF9zZW5zb3Jf ZGF0YShzZGF0YS0+aWQsICZ4KTsKPiArCWlmIChyZXQpIHsKPiArCQlwcl9lcnIoIiVzOiBGYWls ZWQgdG8gZ2V0IG9wYWwgc2Vuc29yIGRhdGFcbiIsIF9fZnVuY19fKTsKPiArCQlyZXR1cm4gcmV0 Owo+ICsJfQo+ICsKPiArCS8qIENvbnZlcnQgdGVtcGVyYXR1cmUgdG8gbWlsbGktZGVncmVlcyAq Lwo+ICsJaWYgKHNkYXRhLT50eXBlID09IEFNQklFTlRfVEVNUCkKPiArCQl4ICo9IDEwMDA7Cj4g KwkvKiBDb252ZXJ0IHBvd2VyIHRvIG1pY3JvLXdhdHRzICovCj4gKwllbHNlIGlmIChzZGF0YS0+ dHlwZSA9PSBQT1dFUl9JTlBVVCkKPiArCQl4ICo9IDEwMDAwMDA7Cj4gKwo+ICsJcmV0dXJuIHNw cmludGYoYnVmLCAiJWRcbiIsIHgpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2luaXQgZ2V0 X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiAqaW5kZXgsIGNoYXIgKmF0 dHIpCj4gK3sKPiArCWNoYXIgKmhhc2hfcG9zID0gc3RyY2hyKG5hbWUsICcjJyk7Cj4gKwljaGFy ICpkYXNoX3BvczsKPiArCXUzMiBjb3B5X2xlbjsKPiArCWNoYXIgYnVmWzhdOwo+ICsKPiArCW1l bXNldChidWYsIDAsIHNpemVvZihidWYpKTsKPiArCSppbmRleCA9IDA7Cj4gKwkqYXR0ciA9ICdc MCc7Cj4gKwo+ICsJaWYgKGhhc2hfcG9zKSB7Cj4gKwkJZGFzaF9wb3MgPSBzdHJjaHIoaGFzaF9w b3MsICctJyk7Cj4gKwkJaWYgKGRhc2hfcG9zKSB7Cj4gKwkJCWNvcHlfbGVuID0gZGFzaF9wb3Mg LSBoYXNoX3BvcyAtIDE7Cj4gKwkJCWlmIChjb3B5X2xlbiA8IHNpemVvZihidWYpKSB7Cj4gKwkJ CQlzdHJuY3B5KGJ1ZiwgaGFzaF9wb3MgKyAxLCBjb3B5X2xlbik7Cj4gKwkJCQlzc2NhbmYoYnVm LCAiJWQiLCBpbmRleCk7Cj4gKwkJCX0KPiArCj4gKwkJCXN0cm5jcHkoYXR0ciwgZGFzaF9wb3Mg KyAxLCBNQVhfQVRUUl9MRU4pOwo+ICsJCX0KPiArCX0KPiArfQo+ICsKPiArLyoKPiArICogVGhp cyBmdW5jdGlvbiB0cmFuc2xhdGVzIHRoZSBEVCBub2RlIG5hbWUgaW50byB0aGUgJ2h3bW9uJyBh dHRyaWJ1dGUgbmFtZS4KPiArICogSUJNUE9XRVJOViBkZXZpY2Ugbm9kZSBhcHBlYXIgbGlrZSBj b29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCj4gKyAqIHdoaWNoIG5lZWQg dG8gYmUgbWFwcGVkIGFzIGZhbjJfaW5wdXQsIHRlbXAxX21heCByZXNwZWN0aXZlbHkgYmVmb3Jl Cj4gKyAqIHBvcHVsYXRpbmcgdGhlbSBpbnNpZGUgaHdtb24gZGV2aWNlIGNsYXNzLi4KPiArICov Cj4gK3N0YXRpYyBpbnQgX19pbml0IGNyZWF0ZV9od21vbl9hdHRyX25hbWUoZW51bSBzZW5zb3Jz IHR5cGUsIGNvbnN0IGNoYXIgKm5vZGVfbmFtZSwKPiArCQkJCSAgY2hhciAqaHdtb25fYXR0cl9u YW1lKQo+ICt7Cj4gKwljaGFyIGF0dHJfc3VmZml4W01BWF9BVFRSX0xFTl07Cj4gKwljaGFyICph dHRyX25hbWU7Cj4gKwl1MzIgaW5kZXg7Cj4gKwo+ICsJZ2V0X3NlbnNvcl9pbmRleF9hdHRyKG5v ZGVfbmFtZSwgJmluZGV4LCBhdHRyX3N1ZmZpeCk7Cj4gKwlpZiAoIWluZGV4IHx8ICFzdHJsZW4o YXR0cl9zdWZmaXgpKSB7Cj4gKwkJcHJfaW5mbygiJXM6IFNlbnNvciBkZXZpY2Ugbm9kZSBuYW1l IGlzIGludmFsaWQsIG5hbWU6ICVzXG4iLAo+ICsJCQkJX19mdW5jX18sIG5vZGVfbmFtZSk7Cj4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJaWYgKCFzdHJjbXAoYXR0cl9zdWZmaXgs IERUX0ZBVUxUX0FUVFJfU1VGRklYKSkKPiArCQlhdHRyX25hbWUgPSAiZmF1bHQiOwo+ICsJZWxz ZSBpZighc3RyY21wKGF0dHJfc3VmZml4LCBEVF9EQVRBX0FUVFJfU1VGRklYKSkKPiArCQlhdHRy X25hbWUgPSAiaW5wdXQiOwo+ICsJZWxzZSBpZiAoIXN0cmNtcChhdHRyX3N1ZmZpeCwgRFRfVEhS RVNIT0xEX0FUVFJfU1VGRklYKSkgewo+ICsJCWlmICh0eXBlID09IEFNQklFTlRfVEVNUCkKPiAr CQkJYXR0cl9uYW1lID0gIm1heCI7Cj4gKwkJZWxzZSBpZiAodHlwZSA9PSBGQU4pCj4gKwkJCWF0 dHJfbmFtZSA9ICJtaW4iOwo+ICsJCWVsc2UKPiArCQkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwl9IGVs c2UKPiArCQlyZXR1cm4gLUVOT0VOVDsKPiArCj4gKwlzbnByaW50Zihod21vbl9hdHRyX25hbWUs IE1BWF9BVFRSX0xFTiwgIiVzJWRfJXMiLAo+ICsJCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLm5hbWUs IGluZGV4LCBhdHRyX25hbWUpOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQg X19pbml0IHBvcHVsYXRlX2F0dHJfZ3JvdXBzKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYp Cj4gK3sKPiArCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dldF9kcnZk YXRhKHBkZXYpOwo+ICsJY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCAqKnBncm91cHMgPSBw ZGF0YS0+YXR0cl9ncm91cHM7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm9wYWwsICpucDsKPiAr CWVudW0gc2Vuc29ycyB0eXBlOwo+ICsJaW50IGVyciA9IDA7Cj4gKwo+ICsJb3BhbCA9IG9mX2Zp bmRfbm9kZV9ieV9wYXRoKCIvaWJtLG9wYWwvc2Vuc29ycyIpOwo+ICsgICAgICAgIGlmICghb3Bh bCkgewo+ICsJCXByX2VycigiJXM6IE9wYWwgJ3NlbnNvcnMnIG5vZGUgbm90IGZvdW5kXG4iLCBf X2Z1bmNfXyk7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKyAgICAgICAgfQo+ICsKPiArCWZvcl9l YWNoX2NoaWxkX29mX25vZGUob3BhbCwgbnApIHsKPiArCQlpZiAobnAtPm5hbWUgPT0gTlVMTCkK PiArCQkJY29udGludWU7Cj4gKwo+ICsJCWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09S X1RZUEU7IHR5cGUrKykKPiArCQkJaWYgKG9mX2RldmljZV9pc19jb21wYXRpYmxlKG5wLAo+ICsJ CQkJc2Vuc29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkgewo+ICsJCQkJc2Vuc29yX2dyb3Vw c1t0eXBlXS5hdHRyX2NvdW50Kys7Cj4gKwkJCQlicmVhazsKPiArCQkJfQo+ICsJfQo+ICsKPiAr CWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykgewo+ICsJCWlm ICghc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50KQo+ICsJCQljb250aW51ZTsKPiArCj4g KwkJc2Vuc29yX2dyb3Vwc1t0eXBlXS5ncm91cC5hdHRycyA9IGRldm1fa3phbGxvYygmcGRldi0+ ZGV2LAo+ICsJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRlKikgKgo+ICsJCQkJCShzZW5zb3Jf Z3JvdXBzW3R5cGVdLmF0dHJfY291bnQgKyAxKSwKPiArCQkJCQlHRlBfS0VSTkVMKTsKPiArCQlp ZiAoIXNlbnNvcl9ncm91cHNbdHlwZV0uZ3JvdXAuYXR0cnMpIHsKPiArCQkJcHJfZXJyKCIlczog RmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSBmb3IgYXR0cmlidXRlIgo+ICsJCQkJCSJhcnJheVxu IiwgX19mdW5jX18pOwo+ICsJCQllcnIgPSAtRU5PTUVNOwo+ICsJCQlnb3RvIGV4aXRfcHV0X25v ZGU7Cj4gKwkJfQo+ICsKPiArCQlwZ3JvdXBzW3R5cGVdID0gJnNlbnNvcl9ncm91cHNbdHlwZV0u Z3JvdXA7Cj4gKwkJcGRhdGEtPnNlbnNvcnNfY291bnQgKz0gc2Vuc29yX2dyb3Vwc1t0eXBlXS5h dHRyX2NvdW50Owo+ICsJCXNlbnNvcl9ncm91cHNbdHlwZV0uYXR0cl9jb3VudCA9IDA7Cj4gKwl9 Cj4gKwo+ICtleGl0X3B1dF9ub2RlOgo+ICsJb2Zfbm9kZV9wdXQob3BhbCk7Cj4gKwlyZXR1cm4g ZXJyOwo+ICt9Cj4gKwo+ICsvKgo+ICsgKiBJdGVyYXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVl IGZvciBlYWNoIGNoaWxkIG9mIHNlbnNvciBub2RlLCBjcmVhdGUKPiArICogYSBzeXNmcyBhdHRy aWJ1dGUgZmlsZSwgdGhlIGZpbGUgaXMgbmFtZWQgYnkgdHJhbnNsYXRpbmcgdGhlIERUIG5vZGUg bmFtZQo+ICsgKiB0byB0aGUgbmFtZSByZXF1aXJlZCBieSB0aGUgaGlnaGVyICdod21vbicgZHJp dmVyIGxpa2UgZmFuMV9pbnB1dCwgdGVtcDFfbWF4Cj4gKyAqIGV0Yy4uCj4gKyAqLwo+ICtzdGF0 aWMgaW50IF9faW5pdCBjcmVhdGVfZGV2aWNlX2F0dHJzKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXYpCj4gK3sKPiArCXN0cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dl dF9kcnZkYXRhKHBkZXYpOwo+ICsJY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCAqKnBncm91 cHMgPSBwZGF0YS0+YXR0cl9ncm91cHM7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm9wYWwsICpu cDsKPiArCXN0cnVjdCBzZW5zb3JfZGF0YSAqc2RhdGE7Cj4gKwljb25zdCB1MzIgKnNlbnNvcl9p ZDsKPiArCWVudW0gc2Vuc29ycyB0eXBlOwo+ICsJdTMyIGNvdW50ID0gMDsKPiArCWludCBlcnIg PSAwOwo+ICsKPiArCW9wYWwgPSBvZl9maW5kX25vZGVfYnlfcGF0aCgiL2libSxvcGFsL3NlbnNv cnMiKTsKPiArICAgICAgICBpZiAoIW9wYWwpIHsKPiArCQlwcl9lcnIoIiVzOiBPcGFsICdzZW5z b3JzJyBub2RlIG5vdCBmb3VuZFxuIiwgX19mdW5jX18pOwo+ICsJCXJldHVybiAtRU5PREVWOwo+ ICsgICAgICAgIH0KPiArCj4gKwlzZGF0YSA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCAocGRh dGEtPnNlbnNvcnNfY291bnQpICoKPiArCQkJICAgICBzaXplb2YoKnNkYXRhKSwgR0ZQX0tFUk5F TCk7Cj4gKwlpZiAoIXNkYXRhKSB7Cj4gKwkJcHJfZXJyKCIlczogRmFpbGVkIHRvIGFsbG9jYXRl IG1lbW9yeSBmb3IgdGhlIHNlbnNvcl9kYXRhIiwKPiArCQkJCV9fZnVuY19fKTsKPiArCQllcnIg PSAtRU5PTUVNOwo+ICsJCWdvdG8gZXhpdF9wdXRfbm9kZTsKPiArCX0KPiArCj4gKwlmb3JfZWFj aF9jaGlsZF9vZl9ub2RlKG9wYWwsIG5wKSB7Cj4gKyAgICAgICAgICAgICAgICBpZiAobnAtPm5h bWUgPT0gTlVMTCkKPiArICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Cj4gKwo+ICsJ CWZvciAodHlwZSA9IDA7IHR5cGUgPCBNQVhfU0VOU09SX1RZUEU7IHR5cGUrKykKPiArCQkJaWYg KG9mX2RldmljZV9pc19jb21wYXRpYmxlKG5wLAo+ICsJCQkJCXNlbnNvcl9ncm91cHNbdHlwZV0u Y29tcGF0aWJsZSkpCj4gKwkJCQlicmVhazsKPiArCj4gKwkJaWYgKHR5cGUgPT0gTUFYX1NFTlNP Ul9UWVBFKQo+ICsJCQljb250aW51ZTsKPiArCj4gKwkJc2Vuc29yX2lkID0gb2ZfZ2V0X3Byb3Bl cnR5KG5wLCAic2Vuc29yLWlkIiwgTlVMTCk7Cj4gKwkJaWYgKCFzZW5zb3JfaWQpIHsKPiArCQkJ cHJfaW5mbygiJXM6ICVzIGRvZXNuJ3QgaGF2ZSBzZW5zb3ItaWRcbiIsIF9fZnVuY19fLAo+ICsJ CQkJbnAtPm5hbWUpOwo+ICsJCQljb250aW51ZTsKPiArCQl9Cj4gKwo+ICsJCXNkYXRhW2NvdW50 XS5pZCA9ICpzZW5zb3JfaWQ7Cj4gKwkJc2RhdGFbY291bnRdLnR5cGUgPSB0eXBlOwo+ICsJCWVy ciA9IGNyZWF0ZV9od21vbl9hdHRyX25hbWUodHlwZSwgbnAtPm5hbWUsIHNkYXRhW2NvdW50XS5u YW1lKTsKPiArCQlpZiAoZXJyKQo+ICsJCQlnb3RvIGV4aXRfcHV0X25vZGU7Cj4gKwo+ICsJCXN5 c2ZzX2F0dHJfaW5pdCgmc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIpOwo+ICsJCXNkYXRhW2Nv dW50XS5kZXZfYXR0ci5hdHRyLm5hbWUgPSBzZGF0YVtjb3VudF0ubmFtZTsKPiArCQlzZGF0YVtj b3VudF0uZGV2X2F0dHIuYXR0ci5tb2RlID0gU19JUlVHTzsKPiArCQlzZGF0YVtjb3VudF0uZGV2 X2F0dHIuc2hvdyA9IHNob3dfc2Vuc29yOwo+ICsKPiArCQlwZ3JvdXBzW3R5cGVdLT5hdHRyc1tz ZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291bnQrK10gPQo+ICsJCQkJJnNkYXRhW2NvdW50Kytd LmRldl9hdHRyLmF0dHI7Cj4gKwl9Cj4gKwo+ICtleGl0X3B1dF9ub2RlOgo+ICsJb2Zfbm9kZV9w dXQob3BhbCk7Cj4gKwlyZXR1cm4gZXJyOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBp Ym1wb3dlcm52X3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0 cnVjdCBwbGF0Zm9ybV9kYXRhICpwZGF0YTsKPiArCXN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsK PiArCWludCBlcnI7Cj4gKwo+ICsJcGRhdGEgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgc2l6 ZW9mKCpwZGF0YSksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFwZGF0YSkKPiArCQlyZXR1cm4gLUVO T01FTTsKPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBwZGF0YSk7Cj4gKwlwZGF0 YS0+c2Vuc29yc19jb3VudCA9IDA7Cj4gKwllcnIgPSBwb3B1bGF0ZV9hdHRyX2dyb3VwcyhwZGV2 KTsKPiArCWlmIChlcnIpCj4gKwkJcmV0dXJuIGVycjsKPiArCj4gKwkvKiBDcmVhdGUgc3lzZnMg YXR0cmlidXRlIGZpbGUgZm9yIGVhY2ggc2Vuc29yIGZvdW5kIGluIHRoZSBEVCAqLwo+ICsJZXJy ID0gY3JlYXRlX2RldmljZV9hdHRycyhwZGV2KTsKPiArCWlmIChlcnIpCj4gKwkJcmV0dXJuIGVy cjsKPiArCj4gKwkvKiBGaW5hbGx5LCByZWdpc3RlciB3aXRoIGh3bW9uICovCj4gKwlod21vbl9k ZXYgPSBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygmcGRldi0+ZGV2LCBE UlZOQU1FLAo+ICsJCQkJCQkJICAgcGRhdGEsCj4gKwkJCQkJCQkgICBwZGF0YS0+YXR0cl9ncm91 cHMpOwo+ICsKPiArCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2KTsKPiArfQo+ICsK PiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaWJtcG93ZXJudl9kcml2ZXIgPSB7Cj4g KwkuZHJpdmVyID0gewo+ICsJCS5vd25lciA9IFRISVNfTU9EVUxFLAo+ICsJCS5uYW1lID0gRFJW TkFNRSwKPiArCX0sCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBpYm1wb3dlcm52X2lu aXQodm9pZCkKPiArewo+ICsJaW50IGVycjsKPiArCj4gKwlwZGV2aWNlID0gcGxhdGZvcm1fZGV2 aWNlX2FsbG9jKERSVk5BTUUsIDApOwo+ICsJaWYgKCFwZGV2aWNlKSB7Cj4gKwkJcHJfZXJyKCIl czogRGV2aWNlIGFsbG9jYXRpb24gZmFpbGVkXG4iLCBfX2Z1bmNfXyk7Cj4gKwkJZXJyID0gLUVO T01FTTsKPiArCQlnb3RvIGV4aXQ7Cj4gKwl9Cj4gKwo+ICsJZXJyID0gcGxhdGZvcm1fZGV2aWNl X2FkZChwZGV2aWNlKTsKPiArCWlmIChlcnIpIHsKPiArCQlwcl9lcnIoIiVzOiBEZXZpY2UgYWRk aXRpb24gZmFpbGVkICglZClcbiIsIF9fZnVuY19fLCBlcnIpOwo+ICsJCWdvdG8gZXhpdF9kZXZp Y2VfcHV0Owo+ICsJfQo+ICsKPiArCWVyciA9IHBsYXRmb3JtX2RyaXZlcl9wcm9iZSgmaWJtcG93 ZXJudl9kcml2ZXIsIGlibXBvd2VybnZfcHJvYmUpOwo+ICsJaWYgKGVycikgewo+ICsJCXByX2Vy cigiJXM6IFBsYXRmcm9tIGRyaXZlciBwcm9iZSBmYWlsZWRcbiIsIF9fZnVuY19fKTsKPiArCQln b3RvIGV4aXRfZGV2aWNlX2RlbDsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK2V4aXRf ZGV2aWNlX2RlbDoKPiArCXBsYXRmb3JtX2RldmljZV9kZWwocGRldmljZSk7Cj4gK2V4aXRfZGV2 aWNlX3B1dDoKPiArCXBsYXRmb3JtX2RldmljZV9wdXQocGRldmljZSk7Cj4gK2V4aXQ6Cj4gKwly ZXR1cm4gZXJyOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2V4aXQgaWJtcG93ZXJudl9leGl0 KHZvaWQpCj4gK3sKPiArCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZpYm1wb3dlcm52X2Ry aXZlcik7Cj4gKwlwbGF0Zm9ybV9kZXZpY2VfdW5yZWdpc3RlcihwZGV2aWNlKTsKPiArfQo+ICsK PiArTU9EVUxFX0FVVEhPUigiTmVlbGVzaCBHdXB0YSA8bmVlbGVndXBAbGludXgudm5ldC5pYm0u Y29tPiIpOwo+ICtNT0RVTEVfREVTQ1JJUFRJT04oIklCTSBQT1dFUk5WIHBsYXRmb3JtIHNlbnNv cnMiKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo+ICsKPiArbW9kdWxlX2luaXQoaWJtcG93 ZXJudl9pbml0KTsKPiArbW9kdWxlX2V4aXQoaWJtcG93ZXJudl9leGl0KTsKPgo+IF9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCj4gTGludXhwcGMtZGV2IG1h aWxpbmcgbGlzdAo+IExpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnCj4gaHR0cHM6Ly9saXN0 cy5vemxhYnMub3JnL2xpc3RpbmZvL2xpbnV4cHBjLWRldgoKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vu c29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9s aXN0aW5mby9sbS1zZW5zb3Jz From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from e28smtp03.in.ibm.com (e28smtp03.in.ibm.com [122.248.162.3]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 2B1D41A05B7 for ; Mon, 26 May 2014 16:22:38 +1000 (EST) Received: from /spool/local by e28smtp03.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 26 May 2014 11:52:31 +0530 Received: from d28relay05.in.ibm.com (d28relay05.in.ibm.com [9.184.220.62]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id 18F481258053 for ; Mon, 26 May 2014 11:51:37 +0530 (IST) Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay05.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s4Q6MamJ4719040 for ; Mon, 26 May 2014 11:52:37 +0530 Received: from d28av03.in.ibm.com (localhost [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s4Q6MOPS029270 for ; Mon, 26 May 2014 11:52:25 +0530 Message-ID: <5382DD9B.2020406@linux.vnet.ibm.com> Date: Mon, 26 May 2014 11:52:19 +0530 From: Neelesh Gupta MIME-Version: 1.0 To: linuxppc-dev@lists.ozlabs.org, linux@roeck-us.net, jdelvare@suse.de, lm-sensors@lm-sensors.org Subject: Re: [PATCH v2] powerpc/powernv: hwmon driver for power values, fan rpm and temperature References: <20140519141931.9248.11356.stgit@neelegup-tp-t420.in.ibm.com> In-Reply-To: <20140519141931.9248.11356.stgit@neelegup-tp-t420.in.ibm.com> Content-Type: multipart/alternative; boundary="------------000200030503020103000403" Cc: sbhat@linux.vnet.ibm.com List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , This is a multi-part message in MIME format. --------------000200030503020103000403 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Any updates on the patch. - Neelesh On 05/19/2014 07:56 PM, Neelesh Gupta wrote: > This patch adds basic kernel enablement for reading power values, fan > speed rpm and temperature values 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: 5487 RPM (min = 0 RPM) > fan2: 5152 RPM (min = 0 RPM) > fan3: 5590 RPM (min = 0 RPM) > fan4: 4963 RPM (min = 0 RPM) > fan5: 0 RPM (min = 0 RPM) > fan6: 0 RPM (min = 0 RPM) > fan7: 7488 RPM (min = 0 RPM) > fan8: 7944 RPM (min = 0 RPM) > temp1: +39.0°C (high = +0.0°C) > power1: 192.00 W > > [root@tul163p1 ~]# ls /sys/devices/platform/ > alarmtimer ibmpowernv.0 rtc-generic serial8250 uevent > [root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/ > driver/ hwmon/ modalias subsystem/ uevent > [root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/ > device fan2_min fan4_min fan6_min fan8_min power1_input > fan1_fault fan3_fault fan5_fault fan7_fault in1_fault subsystem > fan1_input fan3_input fan5_input fan7_input in2_fault temp1_input > fan1_min fan3_min fan5_min fan7_min in3_fault temp1_max > fan2_fault fan4_fault fan6_fault fan8_fault in4_fault uevent > fan2_input fan4_input fan6_input fan8_input name > [root@tul163p1 ~]# > [root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/ > device fan2_min fan4_min fan6_min fan8_min power1_input > fan1_fault fan3_fault fan5_fault fan7_fault in1_fault subsystem > fan1_input fan3_input fan5_input fan7_input in2_fault temp1_input > fan1_min fan3_min fan5_min fan7_min in3_fault temp1_max > fan2_fault fan4_fault fan6_fault fan8_fault in4_fault uevent > fan2_input fan4_input fan6_input fan8_input name > [root@tul163p1 ~]# > > Signed-off-by: Neelesh Gupta > --- > > 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. > > drivers/hwmon/Kconfig | 8 + > drivers/hwmon/Makefile | 1 > drivers/hwmon/ibmpowernv.c | 368 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 377 insertions(+) > create mode 100644 drivers/hwmon/ibmpowernv.c > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index bc196f4..3e308fa 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -554,6 +554,14 @@ 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 platform. > + > 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 c48f987..199c401 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..afce620 > --- /dev/null > +++ b/drivers/hwmon/ibmpowernv.c > @@ -0,0 +1,368 @@ > +/* > + * IBM PowerNV platform sensors for temperature/fan/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. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#define DRVNAME "ibmpowernv" > +#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", {0}, 0}, > + {"temp", "ibm,opal-sensor-amb-temp", {0}, 0}, > + {"in", "ibm,opal-sensor-power-supply", {0}, 0}, > + {"power", "ibm,opal-sensor-power", {0}, 0} > +}; > + > +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) { > + pr_err("%s: Failed to get opal sensor data\n", __func__); > + 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, "%d\n", x); > +} > + > +static void __init get_sensor_index_attr(const char *name, u32 *index, char *attr) > +{ > + char *hash_pos = strchr(name, '#'); > + char *dash_pos; > + u32 copy_len; > + char buf[8]; > + > + memset(buf, 0, sizeof(buf)); > + *index = 0; > + *attr = '\0'; > + > + if (hash_pos) { > + dash_pos = strchr(hash_pos, '-'); > + if (dash_pos) { > + copy_len = dash_pos - hash_pos - 1; > + if (copy_len < sizeof(buf)) { > + strncpy(buf, hash_pos + 1, copy_len); > + sscanf(buf, "%d", index); > + } > + > + strncpy(attr, dash_pos + 1, MAX_ATTR_LEN); > + } > + } > +} > + > +/* > + * 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(enum sensors type, const char *node_name, > + char *hwmon_attr_name) > +{ > + char attr_suffix[MAX_ATTR_LEN]; > + char *attr_name; > + u32 index; > + > + get_sensor_index_attr(node_name, &index, attr_suffix); > + if (!index || !strlen(attr_suffix)) { > + pr_info("%s: Sensor device node name is invalid, name: %s\n", > + __func__, node_name); > + return -EINVAL; > + } > + > + 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; > + int err = 0; > + > + opal = of_find_node_by_path("/ibm,opal/sensors"); > + if (!opal) { > + pr_err("%s: Opal 'sensors' node not found\n", __func__); > + 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; > + } > + } > + > + for (type = 0; type < MAX_SENSOR_TYPE; type++) { > + if (!sensor_groups[type].attr_count) > + continue; > + > + 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) { > + pr_err("%s: Failed to allocate memory for attribute" > + "array\n", __func__); > + err = -ENOMEM; > + goto exit_put_node; > + } > + > + pgroups[type] = &sensor_groups[type].group; > + pdata->sensors_count += sensor_groups[type].attr_count; > + sensor_groups[type].attr_count = 0; > + } > + > +exit_put_node: > + of_node_put(opal); > + return err; > +} > + > +/* > + * Iterate through the device tree for each child of sensor 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 u32 *sensor_id; > + enum sensors type; > + u32 count = 0; > + int err = 0; > + > + opal = of_find_node_by_path("/ibm,opal/sensors"); > + if (!opal) { > + pr_err("%s: Opal 'sensors' node not found\n", __func__); > + return -ENODEV; > + } > + > + sdata = devm_kzalloc(&pdev->dev, (pdata->sensors_count) * > + sizeof(*sdata), GFP_KERNEL); > + if (!sdata) { > + pr_err("%s: Failed to allocate memory for the sensor_data", > + __func__); > + 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) { > + pr_info("%s: %s doesn't have sensor-id\n", __func__, > + np->name); > + continue; > + } > + > + sdata[count].id = *sensor_id; > + sdata[count].type = type; > + err = create_hwmon_attr_name(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 file 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("%s: Device allocation failed\n", __func__); > + err = -ENOMEM; > + goto exit; > + } > + > + err = platform_device_add(pdevice); > + if (err) { > + pr_err("%s: Device addition failed (%d)\n", __func__, err); > + goto exit_device_put; > + } > + > + err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe); > + if (err) { > + pr_err("%s: Platfrom driver probe failed\n", __func__); > + 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 "); > +MODULE_DESCRIPTION("IBM POWERNV platform sensors"); > +MODULE_LICENSE("GPL"); > + > +module_init(ibmpowernv_init); > +module_exit(ibmpowernv_exit); > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev --------------000200030503020103000403 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit Any updates on the patch.

- Neelesh


On 05/19/2014 07:56 PM, Neelesh Gupta wrote:
This patch adds basic kernel enablement for reading power values, fan
speed rpm and temperature values 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:        5487 RPM  (min =    0 RPM)
fan2:        5152 RPM  (min =    0 RPM)
fan3:        5590 RPM  (min =    0 RPM)
fan4:        4963 RPM  (min =    0 RPM)
fan5:           0 RPM  (min =    0 RPM)
fan6:           0 RPM  (min =    0 RPM)
fan7:        7488 RPM  (min =    0 RPM)
fan8:        7944 RPM  (min =    0 RPM)
temp1:        +39.0°C  (high =  +0.0°C)
power1:      192.00 W  

[root@tul163p1 ~]# ls /sys/devices/platform/
alarmtimer  ibmpowernv.0  rtc-generic  serial8250  uevent
[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/
driver/    hwmon/     modalias   subsystem/ uevent     
[root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/
device	    fan2_min	fan4_min    fan6_min	fan8_min   power1_input
fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  subsystem
fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  temp1_input
fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_max
fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  uevent
fan2_input  fan4_input	fan6_input  fan8_input	name
[root@tul163p1 ~]# 
[root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/
device	    fan2_min	fan4_min    fan6_min	fan8_min   power1_input
fan1_fault  fan3_fault	fan5_fault  fan7_fault	in1_fault  subsystem
fan1_input  fan3_input	fan5_input  fan7_input	in2_fault  temp1_input
fan1_min    fan3_min	fan5_min    fan7_min	in3_fault  temp1_max
fan2_fault  fan4_fault	fan6_fault  fan8_fault	in4_fault  uevent
fan2_input  fan4_input	fan6_input  fan8_input	name
[root@tul163p1 ~]#

Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
---

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.

 drivers/hwmon/Kconfig      |    8 +
 drivers/hwmon/Makefile     |    1 
 drivers/hwmon/ibmpowernv.c |  368 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 377 insertions(+)
 create mode 100644 drivers/hwmon/ibmpowernv.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index bc196f4..3e308fa 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -554,6 +554,14 @@ 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 platform.
+
 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 c48f987..199c401 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..afce620
--- /dev/null
+++ b/drivers/hwmon/ibmpowernv.c
@@ -0,0 +1,368 @@
+/*
+ * IBM PowerNV platform sensors for temperature/fan/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.
+ */
+
+#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 DRVNAME		"ibmpowernv"
+#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", {0}, 0},
+	{"temp", "ibm,opal-sensor-amb-temp", {0}, 0},
+	{"in", "ibm,opal-sensor-power-supply", {0}, 0},
+	{"power", "ibm,opal-sensor-power", {0}, 0}
+};
+
+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) {
+		pr_err("%s: Failed to get opal sensor data\n", __func__);
+		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, "%d\n", x);
+}
+
+static void __init get_sensor_index_attr(const char *name, u32 *index, char *attr)
+{
+	char *hash_pos = strchr(name, '#');
+	char *dash_pos;
+	u32 copy_len;
+	char buf[8];
+
+	memset(buf, 0, sizeof(buf));
+	*index = 0;
+	*attr = '\0';
+
+	if (hash_pos) {
+		dash_pos = strchr(hash_pos, '-');
+		if (dash_pos) {
+			copy_len = dash_pos - hash_pos - 1;
+			if (copy_len < sizeof(buf)) {
+				strncpy(buf, hash_pos + 1, copy_len);
+				sscanf(buf, "%d", index);
+			}
+
+			strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
+		}
+	}
+}
+
+/*
+ * 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(enum sensors type, const char *node_name,
+				  char *hwmon_attr_name)
+{
+	char attr_suffix[MAX_ATTR_LEN];
+	char *attr_name;
+	u32 index;
+
+	get_sensor_index_attr(node_name, &index, attr_suffix);
+	if (!index || !strlen(attr_suffix)) {
+		pr_info("%s: Sensor device node name is invalid, name: %s\n",
+				__func__, node_name);
+		return -EINVAL;
+	}
+
+	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;
+	int err = 0;
+
+	opal = of_find_node_by_path("/ibm,opal/sensors");
+        if (!opal) {
+		pr_err("%s: Opal 'sensors' node not found\n", __func__);
+		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;
+			}
+	}
+
+	for (type = 0; type < MAX_SENSOR_TYPE; type++) {
+		if (!sensor_groups[type].attr_count)
+			continue;
+
+		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) {
+			pr_err("%s: Failed to allocate memory for attribute"
+					"array\n", __func__);
+			err = -ENOMEM;
+			goto exit_put_node;
+		}
+
+		pgroups[type] = &sensor_groups[type].group;
+		pdata->sensors_count += sensor_groups[type].attr_count;
+		sensor_groups[type].attr_count = 0;
+	}
+
+exit_put_node:
+	of_node_put(opal);
+	return err;
+}
+
+/*
+ * Iterate through the device tree for each child of sensor 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 u32 *sensor_id;
+	enum sensors type;
+	u32 count = 0;
+	int err = 0;
+
+	opal = of_find_node_by_path("/ibm,opal/sensors");
+        if (!opal) {
+		pr_err("%s: Opal 'sensors' node not found\n", __func__);
+		return -ENODEV;
+        }
+
+	sdata = devm_kzalloc(&pdev->dev, (pdata->sensors_count) *
+			     sizeof(*sdata), GFP_KERNEL);
+	if (!sdata) {
+		pr_err("%s: Failed to allocate memory for the sensor_data",
+				__func__);
+		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) {
+			pr_info("%s: %s doesn't have sensor-id\n", __func__,
+				np->name);
+			continue;
+		}
+
+		sdata[count].id = *sensor_id;
+		sdata[count].type = type;
+		err = create_hwmon_attr_name(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 file 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("%s: Device allocation failed\n", __func__);
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	err = platform_device_add(pdevice);
+	if (err) {
+		pr_err("%s: Device addition failed (%d)\n", __func__, err);
+		goto exit_device_put;
+	}
+
+	err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
+	if (err) {
+		pr_err("%s: Platfrom driver probe failed\n", __func__);
+		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);

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

--------------000200030503020103000403--