From mboxrd@z Thu Jan 1 00:00:00 1970 From: Guenter Roeck Date: Sat, 05 Jul 2014 02:25:36 +0000 Subject: Re: [lm-sensors] [PATCH v4] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperatur Message-Id: <53B76220.9090900@roeck-us.net> List-Id: References: <20140704105343.22437.52125.stgit@localhost.localdomain> In-Reply-To: <20140704105343.22437.52125.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: Neelesh Gupta , linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, jdelvare-l3A5Bk7waGM@public.gmane.org, lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org Cc: benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org, svaidy-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, sbhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, "devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" T24gMDcvMDQvMjAxNCAwNDowMiBBTSwgTmVlbGVzaCBHdXB0YSB3cm90ZToKPiBUaGlzIHBhdGNo IGFkZHMgYmFzaWMga2VybmVsIHN1cHBvcnQgZm9yIHJlYWRpbmcgcG93ZXIgdmFsdWVzLCBmYW4K PiBzcGVlZCBycG0sIHZvbHRhZ2UgYW5kIHRlbXBlcmF0dXJlIGRhdGEgb24gcG93ZXJudiBwbGF0 Zm9ybXMgd2hpY2ggd2lsbAo+IGJlIGV4cG9ydGVkIHRvIHVzZXIgc3BhY2UgdGhyb3VnaCBzeXNm cyBpbnRlcmZhY2UuCj4KCkhpIE5lZWxlc2gsCgpDb3B5aW5nIGRldmljZXRyZWUgbWFpbGluZyBs aXN0LiBQbGVhc2UgY29weSBpdCBvbiB0aGUgbmV4dCAoaG9wZWZ1bGx5IGZpbmFsKQpyZXZpc2lv bjsgZGV2aWNldHJlZSBtYWludGFpbmVycyBhdCBsZWFzdCBuZWVkIGEgY2hhbmNlIHRvIGNvbW1l bnQuClsgWWVzLCBJIHVuZGVyc3RhbmQgdGhpcyBpcyBhIHNoaXBwaW5nIHByb2R1Y3QsIGJ1dCBz dGlsbCAuLi4gXQoKSSBhbSBvayB3aXRoIHRoZSBjb2RlIGV4Y2VwdCBmb3IgYSBjb3VwbGUgb2Yg bWlub3Igbml0cGlja3MgKHNlZSBiZWxvdykuCgpUaGFua3MsCkd1ZW50ZXIKCj4gVGVzdCByZXN1 bHRzOgo+IC0tLS0tLS0tLS0tLS0KPiBbcm9vdEB0dWwxNjNwMSB+XSMgc2Vuc29ycwo+IGlibXBv d2VybnYtaXNhLTAwMDAKPiBBZGFwdGVyOiBJU0EgYWRhcHRlcgo+IGZhbjE6ICAgICAgICA1NTY3 IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjI6ICAgICAgICA1MjMyIFJQTSAgKG1pbiA9ICAg IDAgUlBNKQo+IGZhbjM6ICAgICAgICA1NTMyIFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjQ6 ICAgICAgICA0OTQ1IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjU6ICAgICAgICAgICAwIFJQ TSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjY6ICAgICAgICAgICAwIFJQTSAgKG1pbiA9ICAgIDAg UlBNKQo+IGZhbjc6ICAgICAgICA3MzkyIFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IGZhbjg6ICAg ICAgICA3OTM2IFJQTSAgKG1pbiA9ICAgIDAgUlBNKQo+IHRlbXAxOiAgICAgICAgKzM5LjDCsEMg IChoaWdoID0gICswLjDCsEMpCj4gcG93ZXIxOiAgICAgIDE5MS4wMCBXCj4KPiBbcm9vdEB0dWwx NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtLwo+IGFsYXJtdGltZXIgIGlibXBvd2Vy bnYuMCAgcG93ZXIgIHJ0Yy1nZW5lcmljICBzZXJpYWw4MjUwICB1ZXZlbnQKPiBbcm9vdEB0dWwx NjNwMSB+XSMgbHMgL3N5cy9kZXZpY2VzL3BsYXRmb3JtL2libXBvd2VybnYuMC9od21vbi9od21v bjAvCj4gZGV2aWNlCSAgICBmYW4yX21pbglmYW40X21pbiAgICBmYW42X21pbglmYW44X21pbiAg IHBvd2VyCj4gZmFuMV9mYXVsdCAgZmFuM19mYXVsdAlmYW41X2ZhdWx0ICBmYW43X2ZhdWx0CWlu MV9mYXVsdCAgcG93ZXIxX2lucHV0Cj4gZmFuMV9pbnB1dCAgZmFuM19pbnB1dAlmYW41X2lucHV0 ICBmYW43X2lucHV0CWluMl9mYXVsdCAgc3Vic3lzdGVtCj4gZmFuMV9taW4gICAgZmFuM19taW4J ZmFuNV9taW4gICAgZmFuN19taW4JaW4zX2ZhdWx0ICB0ZW1wMV9pbnB1dAo+IGZhbjJfZmF1bHQg IGZhbjRfZmF1bHQJZmFuNl9mYXVsdCAgZmFuOF9mYXVsdAlpbjRfZmF1bHQgIHRlbXAxX21heAo+ IGZhbjJfaW5wdXQgIGZhbjRfaW5wdXQJZmFuNl9pbnB1dCAgZmFuOF9pbnB1dAluYW1lCSAgIHVl dmVudAo+IFtyb290QHR1bDE2M3AxIH5dIwo+IFtyb290QHR1bDE2M3AxIH5dIyBscyAvc3lzL2Ns YXNzL2h3bW9uL2h3bW9uMC8KPiBkZXZpY2UJICAgIGZhbjJfbWluCWZhbjRfbWluICAgIGZhbjZf bWluCWZhbjhfbWluICAgcG93ZXIKPiBmYW4xX2ZhdWx0ICBmYW4zX2ZhdWx0CWZhbjVfZmF1bHQg IGZhbjdfZmF1bHQJaW4xX2ZhdWx0ICBwb3dlcjFfaW5wdXQKPiBmYW4xX2lucHV0ICBmYW4zX2lu cHV0CWZhbjVfaW5wdXQgIGZhbjdfaW5wdXQJaW4yX2ZhdWx0ICBzdWJzeXN0ZW0KPiBmYW4xX21p biAgICBmYW4zX21pbglmYW41X21pbiAgICBmYW43X21pbglpbjNfZmF1bHQgIHRlbXAxX2lucHV0 Cj4gZmFuMl9mYXVsdCAgZmFuNF9mYXVsdAlmYW42X2ZhdWx0ICBmYW44X2ZhdWx0CWluNF9mYXVs dCAgdGVtcDFfbWF4Cj4gZmFuMl9pbnB1dCAgZmFuNF9pbnB1dAlmYW42X2lucHV0ICBmYW44X2lu cHV0CW5hbWUJICAgdWV2ZW50Cj4gW3Jvb3RAdHVsMTYzcDEgfl0jCj4KPiBTaWduZWQtb2ZmLWJ5 OiBOZWVsZXNoIEd1cHRhIDxuZWVsZWd1cEBsaW51eC52bmV0LmlibS5jb20+Cj4gLS0tCj4KPiBD aGFuZ2VzIGluIHY0Cj4gPT09PT09PT09PT09PQo+IC0gUmVwbGFjZWQgcHJfZXJyKCkgd2l0aCBk ZXZfZXJyKCkgZm9yIGxvZ2dpbiBwcmludCBtZXNzYWdlcy4KPiAtIFVzaW5nIGtzdHJ0b3UzMigp IGZ1bmN0aW9uIGZvciBjb252ZXJ0aW5nIHN0cmluZyB0byB1MzIgaW5zdGVhZCBvZiBzc2NhbmYo KS4KPgo+IENoYW5nZXMgaW4gdjMKPiA9PT09PT09PT09PT09Cj4gLSBGaXhlZCBhbiBlbmRpYW5u ZXNzIGJ1ZyBsZWFkaW5nIHRoZSBkcml2ZXIgdG8gYnJlYWsgb24gTEUuCj4gLSBGaXhlZCBhIGJ1 ZyB0aGF0IHdoZW4gb25lIG9mIHRoZSAnYXR0cmlidXRlX2dyb3VwJyBub3QgcG9wdWxhdGVkLCBm b2xsb3dpbmcKPiAgICBncm91cHMgYXR0cmlidXRlcyB3ZXJlIGRyb3BwZWQuCj4gLSBSZXdyaXRl IHRoZSBnZXRfc2Vuc29yX2luZGV4X2F0dHIoKSBmdW5jdGlvbiB0byBoYW5kbGUgYWxsIHRoZSBl cnJvciBzY2VuYXJpb3MKPiAgICBsaWtlICdzc2NhbmYnIGV0Yy4KPiAtIEZpeGVkIGFsbCB0aGUg ZXJyb3JzL3dhcm5pbmdzIHJlbGF0ZWQgdG8gY29kaW5nIHN0eWxlL3doaXRlc3BhY2UuCj4gLSBB ZGRlZCAnRG9jdW1lbnRhdGlvbicgZmlsZXMuCj4gLSBBZGRyZXNzZWQgcmVtYWluaW5nIHJldmll dyBjb21tZW50cyBvbiBWMi4KPgo+IENoYW5nZXMgaW4gdjIKPiA9PT09PT09PT09PT09Cj4gLSBH ZW5lcmljIHVzZSBvZiBkZXZtXyogZnVuY3Rpb25zIGluIGh3bW9uIGxpa2UgdXNpbmcgZGV2bV9r emFsbG9jKCkgZm9yIGR5bmFtaWMKPiAgICBtZW1vcnkgcmVxdWVzdCwgYXZvaWRpbmcgdGhlIG5l ZWQgdG8gZXhwbGljaXQgZnJlZSBvZiBtZW1vcnkuCj4gICAgQWRkaW5nICdzdHJ1Y3QgYXR0cmli dXRlX2dyb3VwJyBhcyBtZW1iZXIgb2YgcGxhdGZvcm0gZGF0YSBzdHJ1Y3R1cmUgdG8gYmUKPiAg ICBwb3B1bGF0ZWQgYW5kIHRoZW4gcGFzc2VkIHRvIGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVy X3dpdGhfZ3JvdXBzKCkuCj4KPiAgICBOb3RlOiBIYXZpbmcgYW4gYXJyYXkgb2YgcG9pbnRlcnMg b2YgJ2F0dHJpYnV0ZV9ncm91cCcgYW5kIGVhY2ggZ3JvdXAKPiAgICBjb3JyZXNwb25kcyB0byAn ZW51bSBzZW5zb3JzJyB0eXBlLiBOb3QgY29tcGxldGVseSBzdXJlLCBpZiBpdCdzIGlkZWFsIG9y Cj4gICAgY291bGQgaGF2ZSBqdXN0IG9uZSBncm91cCBwb3B1bGF0ZWQgd2l0aCBhdHRyaWJ1dGVz IG9mIHNlbnNvciB0eXBlcz8KPgo+IC0gJ2libXBvd2VybnYnIGlzIG5vdCBob3QtcGx1Z2dhYmxl IGRldmljZSBzbyBtb3ZpbmcgJ3BsYXRmb3JtX2RyaXZlcicgY2FsbGJhY2sKPiAgICBmdW5jdGlv biAocHJvYmUpIGFzIHBhcnQgb2YgX19pbml0IGNvZGUuCj4gLSBGaXhlZCBpc3N1ZXMgcmVsYXRl ZCB0byBjb2Rpbmcgc3R5bGUuCj4gLSBPdGhlciBnZW5lcmFsIGNvbW1lbnRzIGluIHYxLgo+Cj4g ICAuLi4vZGV2aWNldHJlZS9iaW5kaW5ncy9od21vbi9pYm1wb3dlcm52LnR4dCAgICAgICB8ICAg MjcgKwo+ICAgRG9jdW1lbnRhdGlvbi9od21vbi9pYm1wb3dlcm52ICAgICAgICAgICAgICAgICAg ICAgfCAgIDQxICsrCj4gICBkcml2ZXJzL2h3bW9uL0tjb25maWcgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgMTEgKwo+ICAgZHJpdmVycy9od21vbi9NYWtlZmlsZSAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAxCj4gICBkcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYyAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAzNjIgKysrKysrKysrKysrKysrKysrKysKPiAgIDUg ZmlsZXMgY2hhbmdlZCwgNDQyIGluc2VydGlvbnMoKykKPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBE b2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvaHdtb24vaWJtcG93ZXJudi50eHQKPiAg IGNyZWF0ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYKPiAgIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2h3bW9uL2libXBvd2VybnYuYwo+Cj4gZGlmZiAtLWdp dCBhL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9od21vbi9pYm1wb3dlcm52LnR4 dCBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9od21vbi9pYm1wb3dlcm52LnR4 dAo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uZTNiZDFlYgo+IC0tLSAv ZGV2L251bGwKPiArKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvaHdtb24v aWJtcG93ZXJudi50eHQKPiBAQCAtMCwwICsxLDI3IEBACj4gK0lCTSBQT1dFUk5WIHBsYXRmb3Jt IHNlbnNvcnMKPiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+ICsKPiArUmVxdWlyZWQg bm9kZSBwcm9wZXJ0aWVzOgo+ICstIGNvbXBhdGlibGU6IG11c3QgYmUgb25lIG9mCj4gKwkJImli bSxvcGFsLXNlbnNvci1jb29saW5nLWZhbiIKPiArCQkiaWJtLG9wYWwtc2Vuc29yLWFtYi10ZW1w Igo+ICsJCSJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3VwcGx5Igo+ICsJCSJpYm0sb3BhbC1zZW5z b3ItcG93ZXIiCj4gKy0gc2Vuc29yLWlkOiBhbiBvcGFxdWUgaWQgcHJvdmlkZWQgYnkgdGhlIGZp cm13YXJlIHRvIHRoZSBrZXJuZWwsIGlkZW50aWZpZXMgYQo+ICsJICAgICBnaXZlbiBzZW5zb3Ig YW5kIGl0cyBhdHRyaWJ1dGUgZGF0YQo+ICsKPiArRXhhbXBsZSBzZW5zb3JzIG5vZGU6Cj4gKwo+ ICtjb29saW5nLWZhbiM4LWRhdGEgewo+ICsJc2Vuc29yLWlkID0gPDB4NzA1MjEwNz47Cj4gKwlw aGFuZGxlID0gPDB4MTAwMDAwMjg+Owo+ICsJbGludXgscGhhbmRsZSA9IDwweDEwMDAwMDI4PjsK PiArCWNvbXBhdGlibGUgPSAiaWJtLG9wYWwtc2Vuc29yLWNvb2xpbmctZmFuIjsKCnBoYW5kbGUg YW5kIGxpbnV4LXBoYW5kbGUgYXJlIG5laXRoZXIgZG9jdW1lbnRlZCBub3IgdXNlZC4gRWl0aGVy IGRvY3VtZW50IG9yIGRyb3AuCgo+ICt9Owo+ICsKPiArYW1iLXRlbXAjMS10aHJzIHsKPiArCXNl bnNvci1pZCA9IDwweDUwOTYwMDA+Owo+ICsJcGhhbmRsZSA9IDwweDEwMDAwMDE3PjsKPiArCWxp bnV4LHBoYW5kbGUgPSA8MHgxMDAwMDAxNz47Cj4gKwljb21wYXRpYmxlID0gImlibSxvcGFsLXNl bnNvci1hbWItdGVtcCI7Cj4gK307Cj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vaHdtb24v aWJtcG93ZXJudiBiL0RvY3VtZW50YXRpb24vaHdtb24vaWJtcG93ZXJudgo+IG5ldyBmaWxlIG1v ZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uNjQ0MjQ1YQo+IC0tLSAvZGV2L251bGwKPiArKysg Yi9Eb2N1bWVudGF0aW9uL2h3bW9uL2libXBvd2VybnYKPiBAQCAtMCwwICsxLDQxIEBACj4gK0tl cm5lbCBEcml2ZXIgSUJNUE9XRU5WCj4gKz09PT09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtT dXBwb3J0ZWQgc3lzdGVtczoKPiArICAqIEFueSByZWNlbnQgSUJNIFAgc2VydmVycyBiYXNlZCBv biBQT1dFUk5WIHBsYXRmb3JtCj4gKwo+ICtBdXRob3I6IE5lZWxlc2ggR3VwdGEKPiArCj4gK0Rl c2NyaXB0aW9uCj4gKy0tLS0tLS0tLS0tCj4gKwo+ICtUaGlzIGRyaXZlciBpbXBsZW1lbnRzIHJl YWRpbmcgdGhlIHBsYXRmb3JtIHNlbnNvcnMgZGF0YSBsaWtlIHRlbXBlcmF0dXJlL2Zhbi8KPiAr dm9sdGFnZS9wb3dlciBmb3IgJ1BPV0VSTlYnIHBsYXRmb3JtLgo+ICsKPiArVGhlIGRyaXZlciB1 c2VzIHRoZSBwbGF0Zm9ybSBkZXZpY2UgaW5mcmFzdHJ1Y3R1cmUuIEl0IHByb2JlcyB0aGUgZGV2 aWNlIHRyZWUKPiArZm9yIHNlbnNvciBkZXZpY2VzIGR1cmluZyB0aGUgX19pbml0IHBoYXNlIGFu ZCByZWdpc3RlcnMgdGhlbSB3aXRoIHRoZSAnaHdtb24nLgo+ICsnaHdtb24nIHBvcHVsYXRlcyB0 aGUgJ3N5c2ZzJyB0cmVlIGhhdmluZyBhdHRyaWJ1dGUgZmlsZXMsIGVhY2ggZm9yIGEgZ2l2ZW4K PiArc2Vuc29yIHR5cGUgYW5kIGl0cyBhdHRyaWJ1dGUgZGF0YS4KPiArCj4gK0FsbCB0aGUgbm9k ZXMgaW4gdGhlIERUIGFwcGVhciB1bmRlciAiL2libSxvcGFsL3NlbnNvcnMiIGFuZCBlYWNoIHZh bGlkIG5vZGUgaW4KPiArdGhlIERUIG1hcHMgdG8gYW4gYXR0cmlidXRlIGZpbGUgaW4gJ3N5c2Zz Jy4gVGhlIG5vZGUgZXhwb3J0cyB1bmlxdWUgJ3NlbnNvci1pZCcKPiArd2hpY2ggdGhlIGRyaXZl ciB1c2VzIHRvIG1ha2UgYW4gT1BBTCBjYWxsIHRvIHRoZSBmaXJtd2FyZS4KPiArCj4gK1VzYWdl IG5vdGVzCj4gKy0tLS0tLS0tLS0tCj4gK1RoZSBkcml2ZXIgaXMgYnVpbHQgc3RhdGljYWxseSB3 aXRoIHRoZSBrZXJuZWwgYnkgZW5hYmxpbmcgdGhlIGNvbmZpZwo+ICtDT05GSUdfU0VOU09SU19J Qk1QT1dFUk5WLiBJdCBjYW4gYWxzbyBiZSBidWlsdCBhcyBtb2R1bGUgJ2libXBvd2VybnYnLgo+ ICsKPiArU3lzZnMgYXR0cmlidXRlcwo+ICstLS0tLS0tLS0tLS0tLS0tCj4gKwo+ICtmYW5YX2lu cHV0CQlNZWFzdXJlZCBSUE0gdmFsdWUuCj4gK2ZhblhfbWluCQlUaHJlc2hvbGQgUlBNIGZvciBh bGVydCBnZW5lcmF0aW9uLgo+ICtmYW5YX2ZhdWx0CQkwOiBObyBmYWlsIGNvbmRpdGlvbgo+ICsJ CQkxOiBGYWlsaW5nIGZhbgo+ICt0ZW1wWF9pbnB1dAkJTWVhc3VyZWQgYW1iaWVudCB0ZW1wZXJh dHVyZS4KPiArdGVtcFhfbWF4CQlUaHJlc2hvbGQgYW1iaWVudCB0ZW1wZXJhdHVyZSBmb3IgYWxl cnQgZ2VuZXJhdGlvbi4KPiAraW5YX2lucHV0CQlNZWFzdXJlZCBwb3dlciBzdXBwbHkgdm9sdGFn ZQo+ICtpblhfZmF1bHQJCTA6IE5vIGZhaWwgY29uZGl0aW9uLgo+ICsJCQkxOiBGYWlsaW5nIHBv d2VyIHN1cHBseS4KPiArcG93ZXIxX2lucHV0CQlTeXN0ZW0gcG93ZXIgY29uc3VtcHRpb24gKG1p Y3JvV2F0dCkKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9o d21vbi9LY29uZmlnCj4gaW5kZXggMDJkM2Q4NS4uMjljM2ZjYiAxMDA2NDQKPiAtLS0gYS9kcml2 ZXJzL2h3bW9uL0tjb25maWcKPiArKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKPiBAQCAtNTU0 LDYgKzU1NCwxNyBAQCBjb25maWcgU0VOU09SU19JQk1QRVgKPiAgIAkgIFRoaXMgZHJpdmVyIGNh biBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiAgSWYgc28sIHRoZSBtb2R1bGUKPiAgIAkgIHdp bGwgYmUgY2FsbGVkIGlibXBleC4KPgo+ICtjb25maWcgU0VOU09SU19JQk1QT1dFUk5WCj4gKwl0 cmlzdGF0ZSAiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIKPiArCWRlcGVuZHMgb24gUFBD X1BPV0VSTlYKPiArCWRlZmF1bHQgeQo+ICsJaGVscAo+ICsJICBJZiB5b3Ugc2F5IHllcyBoZXJl IHlvdSBnZXQgc3VwcG9ydCBmb3IgdGhlIHRlbXBlcmF0dXJlL2Zhbi9wb3dlcgo+ICsJICBzZW5z b3JzIG9uIHlvdXIgUG93ZXJOViBwbGF0Zm9ybS4KPiArCj4gKwkgIFRoaXMgZHJpdmVyIGNhbiBh bHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVsZQo+ICsJICB3aWxsIGJl IGNhbGxlZCBpYm1wb3dlcm52Lgo+ICsKPiAgIGNvbmZpZyBTRU5TT1JTX0lJT19IV01PTgo+ICAg CXRyaXN0YXRlICJId21vbiBkcml2ZXIgdGhhdCB1c2VzIGNoYW5uZWxzIHNwZWNpZmllZCB2aWEg aWlvIG1hcHMiCj4gICAJZGVwZW5kcyBvbiBJSU8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21v bi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKPiBpbmRleCAzZGMwZjAyLi5mYzRl ZDI2IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKPiArKysgYi9kcml2ZXJz L2h3bW9uL01ha2VmaWxlCj4gQEAgLTcxLDYgKzcxLDcgQEAgb2JqLSQoQ09ORklHX1NFTlNPUlNf VUxUUkE0NSkJKz0gdWx0cmE0NV9lbnYubwo+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfSTVLX0FN QikJKz0gaTVrX2FtYi5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19JQk1BRU0pCSs9IGlibWFl bS5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19JQk1QRVgpCSs9IGlibXBleC5vCj4gK29iai0k KENPTkZJR19TRU5TT1JTX0lCTVBPV0VSTlYpKz0gaWJtcG93ZXJudi5vCj4gICBvYmotJChDT05G SUdfU0VOU09SU19JSU9fSFdNT04pICs9IGlpb19od21vbi5vCj4gICBvYmotJChDT05GSUdfU0VO U09SU19JTkEyMDkpCSs9IGluYTIwOS5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19JTkEyWFgp CSs9IGluYTJ4eC5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vaWJtcG93ZXJudi5jIGIv ZHJpdmVycy9od21vbi9pYm1wb3dlcm52LmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4 IDAwMDAwMDAuLjQ0ZGNkOTkKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9od21vbi9p Ym1wb3dlcm52LmMKPiBAQCAtMCwwICsxLDM2MiBAQAo+ICsvKgo+ICsgKiBJQk0gUG93ZXJOViBw bGF0Zm9ybSBzZW5zb3JzIGZvciB0ZW1wZXJhdHVyZS9mYW4vdm9sdGFnZS9wb3dlcgo+ICsgKiBD b3B5cmlnaHQgKEMpIDIwMTQgSUJNCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNv ZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4gKyAqIGl0IHVu ZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlz aGVkIGJ5Cj4gKyAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9u IDIgb2YgdGhlIExpY2Vuc2UsIG9yCj4gKyAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZl cnNpb24uCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9w ZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAo+ICsgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7 IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo+ICsgKiBNRVJDSEFOVEFCSUxJ VFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCj4gKyAqIEdO VSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4gKyAqCj4gKyAqIFlv dSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBM aWNlbnNlCj4gKyAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLgo+ICsgKi8KPiArCj4gKyNkZWZp bmUgRFJWTkFNRQkJImlibXBvd2VybnYiCj4gKyNkZWZpbmUgcHJfZm10KGZtdCkJRFJWTkFNRSAi OiAiIGZtdAo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9od21vbi5oPgo+ICsjaW5jbHVkZSA8bGludXgvaHdtb24tc3lzZnMuaD4KPiArI2luY2x1ZGUg PGxpbnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKwo+ICsjaW5jbHVkZSA8 bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxhc20vb3BhbC5oPgo+ICsjaW5j bHVkZSA8bGludXgvZXJyLmg+Cj4gKwo+ICsjZGVmaW5lIE1BWF9BVFRSX0xFTgkzMgo+ICsKPiAr LyogU2Vuc29yIHN1ZmZpeCBuYW1lIGZyb20gRFQgKi8KPiArI2RlZmluZSBEVF9GQVVMVF9BVFRS X1NVRkZJWAkJImZhdWx0ZWQiCj4gKyNkZWZpbmUgRFRfREFUQV9BVFRSX1NVRkZJWAkJImRhdGEi Cj4gKyNkZWZpbmUgRFRfVEhSRVNIT0xEX0FUVFJfU1VGRklYCSJ0aHJzIgo+ICsKPiArLyoKPiAr ICogRW51bWVyYXRlcyBhbGwgdGhlIHR5cGVzIG9mIHNlbnNvcnMgaW4gdGhlIFBPV0VSTlYgcGxh dGZvcm0gYW5kIGRvZXMgaW5kZXgKPiArICogaW50byAnc3RydWN0IHNlbnNvcl9ncm91cCcKPiAr ICovCj4gK2VudW0gc2Vuc29ycyB7Cj4gKwlGQU4sCj4gKwlBTUJJRU5UX1RFTVAsCj4gKwlQT1dF Ul9TVVBQTFksCj4gKwlQT1dFUl9JTlBVVCwKPiArCU1BWF9TRU5TT1JfVFlQRSwKPiArfTsKPiAr Cj4gK3N0YXRpYyBzdHJ1Y3Qgc2Vuc29yX2dyb3VwIHsKPiArCWNvbnN0IGNoYXIgKm5hbWU7Cj4g Kwljb25zdCBjaGFyICpjb21wYXRpYmxlOwo+ICsJc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBncm91 cDsKPiArCXUzMiBhdHRyX2NvdW50Owo+ICt9IHNlbnNvcl9ncm91cHNbXSA9IHsKPiArCXsiZmFu IiwgImlibSxvcGFsLXNlbnNvci1jb29saW5nLWZhbiJ9LAo+ICsJeyJ0ZW1wIiwgImlibSxvcGFs LXNlbnNvci1hbWItdGVtcCJ9LAo+ICsJeyJpbiIsICJpYm0sb3BhbC1zZW5zb3ItcG93ZXItc3Vw cGx5In0sCj4gKwl7InBvd2VyIiwgImlibSxvcGFsLXNlbnNvci1wb3dlciJ9Cj4gK307Cj4gKwo+ ICtzdHJ1Y3Qgc2Vuc29yX2RhdGEgewo+ICsJdTMyIGlkOyAvKiBBbiBvcGFxdWUgaWQgb2YgdGhl IGZpcm13YXJlIGZvciBlYWNoIHNlbnNvciAqLwo+ICsJZW51bSBzZW5zb3JzIHR5cGU7Cj4gKwlj aGFyIG5hbWVbTUFYX0FUVFJfTEVOXTsKPiArCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRldl9h dHRyOwo+ICt9Owo+ICsKPiArc3RydWN0IHBsYXRmb3JtX2RhdGEgewo+ICsJY29uc3Qgc3RydWN0 IGF0dHJpYnV0ZV9ncm91cCAqYXR0cl9ncm91cHNbTUFYX1NFTlNPUl9UWVBFICsgMV07Cj4gKwl1 MzIgc2Vuc29yc19jb3VudDsgLyogVG90YWwgY291bnQgb2Ygc2Vuc29ycyBmcm9tIGVhY2ggZ3Jv dXAgKi8KPiArfTsKPiArCj4gKy8qIFBsYXRmb3JtIGRldmljZSByZXByZXNlbnRpbmcgYWxsIHRo ZSBpYm1wb3dlcm52IHNlbnNvcnMgKi8KPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXZpY2U7Cj4gKwo+ICtzdGF0aWMgc3NpemVfdCBzaG93X3NlbnNvcihzdHJ1Y3QgZGV2aWNl ICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICpkZXZhdHRyLAo+ICsJCQkgICBjaGFyICpi dWYpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGF0YSAqc2RhdGEgPSBjb250YWluZXJfb2YoZGV2 YXR0ciwgc3RydWN0IHNlbnNvcl9kYXRhLAo+ICsJCQkJCQkgZGV2X2F0dHIpOwo+ICsJc3NpemVf dCByZXQ7Cj4gKwl1MzIgeDsKPiArCj4gKwlyZXQgPSBvcGFsX2dldF9zZW5zb3JfZGF0YShzZGF0 YS0+aWQsICZ4KTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwkvKiBDb252 ZXJ0IHRlbXBlcmF0dXJlIHRvIG1pbGxpLWRlZ3JlZXMgKi8KPiArCWlmIChzZGF0YS0+dHlwZSA9 PSBBTUJJRU5UX1RFTVApCj4gKwkJeCAqPSAxMDAwOwo+ICsJLyogQ29udmVydCBwb3dlciB0byBt aWNyby13YXR0cyAqLwo+ICsJZWxzZSBpZiAoc2RhdGEtPnR5cGUgPT0gUE9XRVJfSU5QVVQpCj4g KwkJeCAqPSAxMDAwMDAwOwo+ICsKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiV1XG4iLCB4KTsK PiArfQo+ICsKPiArc3RhdGljIGludCBfX2luaXQgZ2V0X3NlbnNvcl9pbmRleF9hdHRyKGNvbnN0 IGNoYXIgKm5hbWUsIHUzMiAqaW5kZXgsCj4gKwkJCQkJY2hhciAqYXR0cikKPiArewo+ICsJY2hh ciAqaGFzaF9wb3MgPSBzdHJjaHIobmFtZSwgJyMnKTsKPiArCWNoYXIgYnVmWzhdID0geyAwIH07 Cj4gKwljaGFyICpkYXNoX3BvczsKPiArCXUzMiBjb3B5X2xlbjsKPiArCj4gKwlpZiAoIWhhc2hf cG9zKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWRhc2hfcG9zID0gc3RyY2hyKGhhc2hf cG9zLCAnLScpOwo+ICsJaWYgKCFkYXNoX3BvcykKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4g Kwljb3B5X2xlbiA9IGRhc2hfcG9zIC0gaGFzaF9wb3MgLSAxOwo+ICsJaWYgKGNvcHlfbGVuID49 IHNpemVvZihidWYpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXN0cm5jcHkoYnVmLCBo YXNoX3BvcyArIDEsIGNvcHlfbGVuKTsKPiArCj4gKwlpZiAoa3N0cnRvdTMyKGJ1ZiwgMTAsIGlu ZGV4KSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCnNtYXRjaCBpc24ndCBnb2luZyB0byBsaWtl IHRoYXQuIFBsZWFzZSB1c2UKCglpbnQgZXJyOwoJLi4uCgllcnIgPSBrc3RydG91MzIoYnVmLCAx MCwgaW5kZXgpKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCj4gKwlzdHJuY3B5KGF0dHIsIGRh c2hfcG9zICsgMSwgTUFYX0FUVFJfTEVOKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiAr LyoKPiArICogVGhpcyBmdW5jdGlvbiB0cmFuc2xhdGVzIHRoZSBEVCBub2RlIG5hbWUgaW50byB0 aGUgJ2h3bW9uJyBhdHRyaWJ1dGUgbmFtZS4KPiArICogSUJNUE9XRVJOViBkZXZpY2Ugbm9kZSBh cHBlYXIgbGlrZSBjb29saW5nLWZhbiMyLWRhdGEsIGFtYi10ZW1wIzEtdGhycyBldGMuCj4gKyAq IHdoaWNoIG5lZWQgdG8gYmUgbWFwcGVkIGFzIGZhbjJfaW5wdXQsIHRlbXAxX21heCByZXNwZWN0 aXZlbHkgYmVmb3JlCj4gKyAqIHBvcHVsYXRpbmcgdGhlbSBpbnNpZGUgaHdtb24gZGV2aWNlIGNs YXNzLgo+ICsgKi8KPiArc3RhdGljIGludCBfX2luaXQgY3JlYXRlX2h3bW9uX2F0dHJfbmFtZShz dHJ1Y3QgZGV2aWNlICpkZXYsIGVudW0gc2Vuc29ycyB0eXBlLAo+ICsJCQkJCSBjb25zdCBjaGFy ICpub2RlX25hbWUsCj4gKwkJCQkJIGNoYXIgKmh3bW9uX2F0dHJfbmFtZSkKPiArewo+ICsJY2hh ciBhdHRyX3N1ZmZpeFtNQVhfQVRUUl9MRU5dOwo+ICsJY2hhciAqYXR0cl9uYW1lOwo+ICsJdTMy IGluZGV4Owo+ICsJaW50IGVycjsKPiArCj4gKwllcnIgPSBnZXRfc2Vuc29yX2luZGV4X2F0dHIo bm9kZV9uYW1lLCAmaW5kZXgsIGF0dHJfc3VmZml4KTsKPiArCWlmIChlcnIpIHsKPiArCQlkZXZf ZXJyKGRldiwgIlNlbnNvciBkZXZpY2Ugbm9kZSBuYW1lICclcycgaXMgaW52YWxpZFxuIiwKPiAr CQkJbm9kZV9uYW1lKTsKPiArCQlyZXR1cm4gZXJyOwo+ICsJfQo+ICsKPiArCWlmICghc3RyY21w KGF0dHJfc3VmZml4LCBEVF9GQVVMVF9BVFRSX1NVRkZJWCkpIHsKPiArCQlhdHRyX25hbWUgPSAi ZmF1bHQiOwo+ICsJfSBlbHNlIGlmICghc3RyY21wKGF0dHJfc3VmZml4LCBEVF9EQVRBX0FUVFJf U1VGRklYKSkgewo+ICsJCWF0dHJfbmFtZSA9ICJpbnB1dCI7Cj4gKwl9IGVsc2UgaWYgKCFzdHJj bXAoYXR0cl9zdWZmaXgsIERUX1RIUkVTSE9MRF9BVFRSX1NVRkZJWCkpIHsKPiArCQlpZiAodHlw ZSA9PSBBTUJJRU5UX1RFTVApCj4gKwkJCWF0dHJfbmFtZSA9ICJtYXgiOwo+ICsJCWVsc2UgaWYg KHR5cGUgPT0gRkFOKQo+ICsJCQlhdHRyX25hbWUgPSAibWluIjsKPiArCQllbHNlCj4gKwkJCXJl dHVybiAtRU5PRU5UOwo+ICsJfSBlbHNlIHsKPiArCQlyZXR1cm4gLUVOT0VOVDsKPiArCX0KPiAr Cj4gKwlzbnByaW50Zihod21vbl9hdHRyX25hbWUsIE1BWF9BVFRSX0xFTiwgIiVzJWRfJXMiLAo+ ICsJCSBzZW5zb3JfZ3JvdXBzW3R5cGVdLm5hbWUsIGluZGV4LCBhdHRyX25hbWUpOwo+ICsJcmV0 dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgX19pbml0IHBvcHVsYXRlX2F0dHJfZ3JvdXBz KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBwbGF0Zm9ybV9k YXRhICpwZGF0YSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsJY29uc3Qgc3RydWN0 IGF0dHJpYnV0ZV9ncm91cCAqKnBncm91cHMgPSBwZGF0YS0+YXR0cl9ncm91cHM7Cj4gKwlzdHJ1 Y3QgZGV2aWNlX25vZGUgKm9wYWwsICpucDsKPiArCWVudW0gc2Vuc29ycyB0eXBlOwo+ICsKPiAr CW9wYWwgPSBvZl9maW5kX25vZGVfYnlfcGF0aCgiL2libSxvcGFsL3NlbnNvcnMiKTsKPiArCWlm ICghb3BhbCkgewo+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgIk9wYWwgbm9kZSAnc2Vuc29ycycg bm90IGZvdW5kXG4iKTsKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCX0KPiArCj4gKwlmb3JfZWFj aF9jaGlsZF9vZl9ub2RlKG9wYWwsIG5wKSB7Cj4gKwkJaWYgKG5wLT5uYW1lID09IE5VTEwpCj4g KwkJCWNvbnRpbnVlOwo+ICsKPiArCQlmb3IgKHR5cGUgPSAwOyB0eXBlIDwgTUFYX1NFTlNPUl9U WVBFOyB0eXBlKyspCj4gKwkJCWlmIChvZl9kZXZpY2VfaXNfY29tcGF0aWJsZShucCwKPiArCQkJ CQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmNvbXBhdGlibGUpKSB7Cj4gKwkJCQlzZW5zb3JfZ3JvdXBz W3R5cGVdLmF0dHJfY291bnQrKzsKPiArCQkJCWJyZWFrOwo+ICsJCQl9Cj4gKwl9Cj4gKwo+ICsJ b2Zfbm9kZV9wdXQob3BhbCk7Cj4gKwo+ICsJZm9yICh0eXBlID0gMDsgdHlwZSA8IE1BWF9TRU5T T1JfVFlQRTsgdHlwZSsrKSB7Cj4gKwkJc2Vuc29yX2dyb3Vwc1t0eXBlXS5ncm91cC5hdHRycyA9 IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LAo+ICsJCQkJCXNpemVvZihzdHJ1Y3QgYXR0cmlidXRl ICopICoKPiArCQkJCQkoc2Vuc29yX2dyb3Vwc1t0eXBlXS5hdHRyX2NvdW50ICsgMSksCj4gKwkJ CQkJR0ZQX0tFUk5FTCk7Cj4gKwkJaWYgKCFzZW5zb3JfZ3JvdXBzW3R5cGVdLmdyb3VwLmF0dHJz KQo+ICsJCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwkJcGdyb3Vwc1t0eXBlXSA9ICZzZW5zb3Jf Z3JvdXBzW3R5cGVdLmdyb3VwOwo+ICsJCXBkYXRhLT5zZW5zb3JzX2NvdW50ICs9IHNlbnNvcl9n cm91cHNbdHlwZV0uYXR0cl9jb3VudDsKPiArCQlzZW5zb3JfZ3JvdXBzW3R5cGVdLmF0dHJfY291 bnQgPSAwOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKgo+ICsgKiBJdGVy YXRlIHRocm91Z2ggdGhlIGRldmljZSB0cmVlIGZvciBlYWNoIGNoaWxkIG9mICdzZW5zb3JzJyBu b2RlLCBjcmVhdGUKPiArICogYSBzeXNmcyBhdHRyaWJ1dGUgZmlsZSwgdGhlIGZpbGUgaXMgbmFt ZWQgYnkgdHJhbnNsYXRpbmcgdGhlIERUIG5vZGUgbmFtZQo+ICsgKiB0byB0aGUgbmFtZSByZXF1 aXJlZCBieSB0aGUgaGlnaGVyICdod21vbicgZHJpdmVyIGxpa2UgZmFuMV9pbnB1dCwgdGVtcDFf bWF4Cj4gKyAqIGV0Yy4uCj4gKyAqLwo+ICtzdGF0aWMgaW50IF9faW5pdCBjcmVhdGVfZGV2aWNl X2F0dHJzKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBwbGF0 Zm9ybV9kYXRhICpwZGF0YSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsJY29uc3Qg c3RydWN0IGF0dHJpYnV0ZV9ncm91cCAqKnBncm91cHMgPSBwZGF0YS0+YXR0cl9ncm91cHM7Cj4g KwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm9wYWwsICpucDsKPiArCXN0cnVjdCBzZW5zb3JfZGF0YSAq c2RhdGE7Cj4gKwljb25zdCBfX2JlMzIgKnNlbnNvcl9pZDsKPiArCWVudW0gc2Vuc29ycyB0eXBl Owo+ICsJdTMyIGNvdW50ID0gMDsKPiArCWludCBlcnIgPSAwOwo+ICsKPiArCW9wYWwgPSBvZl9m aW5kX25vZGVfYnlfcGF0aCgiL2libSxvcGFsL3NlbnNvcnMiKTsKPiArCXNkYXRhID0gZGV2bV9r emFsbG9jKCZwZGV2LT5kZXYsIHBkYXRhLT5zZW5zb3JzX2NvdW50ICogc2l6ZW9mKCpzZGF0YSks Cj4gKwkJCSAgICAgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXNkYXRhKSB7Cj4gKwkJZXJyID0gLUVO T01FTTsKPiArCQlnb3RvIGV4aXRfcHV0X25vZGU7Cj4gKwl9Cj4gKwo+ICsJZm9yX2VhY2hfY2hp bGRfb2Zfbm9kZShvcGFsLCBucCkgewo+ICsJCWlmIChucC0+bmFtZSA9PSBOVUxMKQo+ICsJCQlj b250aW51ZTsKPiArCj4gKwkJZm9yICh0eXBlID0gMDsgdHlwZSA8IE1BWF9TRU5TT1JfVFlQRTsg dHlwZSsrKQo+ICsJCQlpZiAob2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsCj4gKwkJCQkJc2Vu c29yX2dyb3Vwc1t0eXBlXS5jb21wYXRpYmxlKSkKPiArCQkJCWJyZWFrOwo+ICsKPiArCQlpZiAo dHlwZSA9PSBNQVhfU0VOU09SX1RZUEUpCj4gKwkJCWNvbnRpbnVlOwo+ICsKPiArCQlzZW5zb3Jf aWQgPSBvZl9nZXRfcHJvcGVydHkobnAsICJzZW5zb3ItaWQiLCBOVUxMKTsKPiArCQlpZiAoIXNl bnNvcl9pZCkgewo+ICsJCQlkZXZfaW5mbygmcGRldi0+ZGV2LAo+ICsJCQkJICInc2Vuc29yLWlk JyBtaXNzaW5nIGluIHRoZSBub2RlICclcydcbiIsCj4gKwkJCQkgbnAtPm5hbWUpOwo+ICsJCQlj b250aW51ZTsKPiArCQl9Cj4gKwo+ICsJCXNkYXRhW2NvdW50XS5pZCA9IGJlMzJfdG9fY3B1cChz ZW5zb3JfaWQpOwo+ICsJCXNkYXRhW2NvdW50XS50eXBlID0gdHlwZTsKPiArCQllcnIgPSBjcmVh dGVfaHdtb25fYXR0cl9uYW1lKCZwZGV2LT5kZXYsIHR5cGUsIG5wLT5uYW1lLAo+ICsJCQkJCSAg ICAgc2RhdGFbY291bnRdLm5hbWUpOwo+ICsJCWlmIChlcnIpCj4gKwkJCWdvdG8gZXhpdF9wdXRf bm9kZTsKPiArCj4gKwkJc3lzZnNfYXR0cl9pbml0KCZzZGF0YVtjb3VudF0uZGV2X2F0dHIuYXR0 cik7Cj4gKwkJc2RhdGFbY291bnRdLmRldl9hdHRyLmF0dHIubmFtZSA9IHNkYXRhW2NvdW50XS5u YW1lOwo+ICsJCXNkYXRhW2NvdW50XS5kZXZfYXR0ci5hdHRyLm1vZGUgPSBTX0lSVUdPOwo+ICsJ CXNkYXRhW2NvdW50XS5kZXZfYXR0ci5zaG93ID0gc2hvd19zZW5zb3I7Cj4gKwo+ICsJCXBncm91 cHNbdHlwZV0tPmF0dHJzW3NlbnNvcl9ncm91cHNbdHlwZV0uYXR0cl9jb3VudCsrXSA9Cj4gKwkJ CQkmc2RhdGFbY291bnQrK10uZGV2X2F0dHIuYXR0cjsKPiArCX0KPiArCj4gK2V4aXRfcHV0X25v ZGU6Cj4gKwlvZl9ub2RlX3B1dChvcGFsKTsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gK3N0 YXRpYyBpbnQgX19pbml0IGlibXBvd2VybnZfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAq cGRldikKPiArewo+ICsJc3RydWN0IHBsYXRmb3JtX2RhdGEgKnBkYXRhOwo+ICsJc3RydWN0IGRl dmljZSAqaHdtb25fZGV2Owo+ICsJaW50IGVycjsKPiArCj4gKwlwZGF0YSA9IGRldm1fa3phbGxv YygmcGRldi0+ZGV2LCBzaXplb2YoKnBkYXRhKSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXBkYXRh KQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYs IHBkYXRhKTsKPiArCXBkYXRhLT5zZW5zb3JzX2NvdW50ID0gMDsKPiArCWVyciA9IHBvcHVsYXRl X2F0dHJfZ3JvdXBzKHBkZXYpOwo+ICsJaWYgKGVycikKPiArCQlyZXR1cm4gZXJyOwo+ICsKPiAr CS8qIENyZWF0ZSBzeXNmcyBhdHRyaWJ1dGUgZGF0YSBmb3IgZWFjaCBzZW5zb3IgZm91bmQgaW4g dGhlIERUICovCj4gKwllcnIgPSBjcmVhdGVfZGV2aWNlX2F0dHJzKHBkZXYpOwo+ICsJaWYgKGVy cikKPiArCQlyZXR1cm4gZXJyOwo+ICsKPiArCS8qIEZpbmFsbHksIHJlZ2lzdGVyIHdpdGggaHdt b24gKi8KPiArCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhfZ3Jv dXBzKCZwZGV2LT5kZXYsIERSVk5BTUUsCj4gKwkJCQkJCQkgICBwZGF0YSwKPiArCQkJCQkJCSAg IHBkYXRhLT5hdHRyX2dyb3Vwcyk7Cj4gKwo+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21v bl9kZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBpYm1wb3dl cm52X2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm93bmVyID0gVEhJU19NT0RVTEUs Cj4gKwkJLm5hbWUgPSBEUlZOQU1FLAo+ICsJfSwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgX19p bml0IGlibXBvd2VybnZfaW5pdCh2b2lkKQo+ICt7Cj4gKwlpbnQgZXJyOwo+ICsKPiArCXBkZXZp Y2UgPSBwbGF0Zm9ybV9kZXZpY2VfYWxsb2MoRFJWTkFNRSwgMCk7Cj4gKwlpZiAoIXBkZXZpY2Up IHsKPiArCQlwcl9lcnIoIkRldmljZSBhbGxvY2F0aW9uIGZhaWxlZFxuIik7Cj4gKwkJZXJyID0g LUVOT01FTTsKPiArCQlnb3RvIGV4aXQ7Cj4gKwl9Cj4gKwo+ICsJZXJyID0gcGxhdGZvcm1fZGV2 aWNlX2FkZChwZGV2aWNlKTsKPiArCWlmIChlcnIpIHsKPiArCQlwcl9lcnIoIkRldmljZSBhZGRp dGlvbiBmYWlsZWQgKCVkKVxuIiwgZXJyKTsKPiArCQlnb3RvIGV4aXRfZGV2aWNlX3B1dDsKPiAr CX0KPiArCj4gKwllcnIgPSBwbGF0Zm9ybV9kcml2ZXJfcHJvYmUoJmlibXBvd2VybnZfZHJpdmVy LCBpYm1wb3dlcm52X3Byb2JlKTsKPiArCWlmIChlcnIpIHsKPiArCQlwcl9lcnIoIlBsYXRmcm9t IGRyaXZlciBwcm9iZSBmYWlsZWRcbiIpOwo+ICsJCWdvdG8gZXhpdF9kZXZpY2VfZGVsOwo+ICsJ fQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXhpdF9kZXZpY2VfZGVsOgo+ICsJcGxhdGZvcm1f ZGV2aWNlX2RlbChwZGV2aWNlKTsKPiArZXhpdF9kZXZpY2VfcHV0Ogo+ICsJcGxhdGZvcm1fZGV2 aWNlX3B1dChwZGV2aWNlKTsKPiArZXhpdDoKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gK3N0 YXRpYyB2b2lkIF9fZXhpdCBpYm1wb3dlcm52X2V4aXQodm9pZCkKPiArewo+ICsJcGxhdGZvcm1f ZHJpdmVyX3VucmVnaXN0ZXIoJmlibXBvd2VybnZfZHJpdmVyKTsKPiArCXBsYXRmb3JtX2Rldmlj ZV91bnJlZ2lzdGVyKHBkZXZpY2UpOwo+ICt9Cj4gKwo+ICtNT0RVTEVfQVVUSE9SKCJOZWVsZXNo IEd1cHRhIDxuZWVsZWd1cEBsaW51eC52bmV0LmlibS5jb20+Iik7Cj4gK01PRFVMRV9ERVNDUklQ VElPTigiSUJNIFBPV0VSTlYgcGxhdGZvcm0gc2Vuc29ycyIpOwo+ICtNT0RVTEVfTElDRU5TRSgi R1BMIik7Cj4gKwo+ICttb2R1bGVfaW5pdChpYm1wb3dlcm52X2luaXQpOwo+ICttb2R1bGVfZXhp dChpYm1wb3dlcm52X2V4aXQpOwo+Cj4KPgoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmxtLXNlbnNvcnMgbWFpbGluZyBsaXN0CmxtLXNlbnNvcnNAbG0t c2Vuc29ycy5vcmcKaHR0cDovL2xpc3RzLmxtLXNlbnNvcnMub3JnL21haWxtYW4vbGlzdGluZm8v bG0tc2Vuc29ycw= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.active-venture.com (mail.active-venture.com [67.228.131.205]) by lists.ozlabs.org (Postfix) with ESMTP id AEE071A000C for ; Sat, 5 Jul 2014 12:25:40 +1000 (EST) Message-ID: <53B76220.9090900@roeck-us.net> Date: Fri, 04 Jul 2014 19:25:36 -0700 From: Guenter Roeck MIME-Version: 1.0 To: Neelesh Gupta , linuxppc-dev@lists.ozlabs.org, jdelvare@suse.de, lm-sensors@lm-sensors.org Subject: Re: [PATCH v4] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature References: <20140704105343.22437.52125.stgit@localhost.localdomain> In-Reply-To: <20140704105343.22437.52125.stgit@localhost.localdomain> Content-Type: text/plain; charset=UTF-8; format=flowed Cc: sbhat@linux.vnet.ibm.com, "devicetree@vger.kernel.org" List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On 07/04/2014 04:02 AM, Neelesh Gupta wrote: > 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. > Hi Neelesh, Copying devicetree mailing list. Please copy it on the next (hopefully final) revision; devicetree maintainers at least need a chance to comment. [ Yes, I understand this is a shipping product, but still ... ] I am ok with the code except for a couple of minor nitpicks (see below). Thanks, Guenter > Test results: > ------------- > [root@tul163p1 ~]# sensors > ibmpowernv-isa-0000 > Adapter: ISA adapter > fan1: 5567 RPM (min = 0 RPM) > fan2: 5232 RPM (min = 0 RPM) > fan3: 5532 RPM (min = 0 RPM) > fan4: 4945 RPM (min = 0 RPM) > fan5: 0 RPM (min = 0 RPM) > fan6: 0 RPM (min = 0 RPM) > fan7: 7392 RPM (min = 0 RPM) > fan8: 7936 RPM (min = 0 RPM) > temp1: +39.0°C (high = +0.0°C) > power1: 191.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 ~]# > [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 > --- > > Changes in v4 > ============= > - Replaced pr_err() with dev_err() for loggin 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 | 27 + > Documentation/hwmon/ibmpowernv | 41 ++ > drivers/hwmon/Kconfig | 11 + > drivers/hwmon/Makefile | 1 > drivers/hwmon/ibmpowernv.c | 362 ++++++++++++++++++++ > 5 files changed, 442 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..e3bd1eb > --- /dev/null > +++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt > @@ -0,0 +1,27 @@ > +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>; > + phandle = <0x10000028>; > + linux,phandle = <0x10000028>; > + compatible = "ibm,opal-sensor-cooling-fan"; phandle and linux-phandle are neither documented nor used. Either document or drop. > +}; > + > +amb-temp#1-thrs { > + sensor-id = <0x5096000>; > + phandle = <0x10000017>; > + linux,phandle = <0x10000017>; > + 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..44dcd99 > --- /dev/null > +++ b/drivers/hwmon/ibmpowernv.c > @@ -0,0 +1,362 @@ > +/* > + * 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 > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#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; > + > + 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); > + > + if (kstrtou32(buf, 10, index)) > + return -EINVAL; > + smatch isn't going to like that. Please use int err; ... 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 "); > +MODULE_DESCRIPTION("IBM POWERNV platform sensors"); > +MODULE_LICENSE("GPL"); > + > +module_init(ibmpowernv_init); > +module_exit(ibmpowernv_exit); > > > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Guenter Roeck Subject: Re: [PATCH v4] powerpc/powernv: hwmon driver for power, fan rpm, voltage and temperature Date: Fri, 04 Jul 2014 19:25:36 -0700 Message-ID: <53B76220.9090900@roeck-us.net> References: <20140704105343.22437.52125.stgit@localhost.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE Return-path: In-Reply-To: <20140704105343.22437.52125.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org> Sender: devicetree-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Neelesh Gupta , linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, jdelvare-l3A5Bk7waGM@public.gmane.org, lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org Cc: benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org, svaidy-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, sbhat-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, "devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" List-Id: devicetree@vger.kernel.org On 07/04/2014 04:02 AM, Neelesh Gupta wrote: > This patch adds basic kernel support for reading power values, fan > speed rpm, voltage and temperature data on powernv platforms which wi= ll > be exported to user space through sysfs interface. > Hi Neelesh, Copying devicetree mailing list. Please copy it on the next (hopefully = final) revision; devicetree maintainers at least need a chance to comment. [ Yes, I understand this is a shipping product, but still ... ] I am ok with the code except for a couple of minor nitpicks (see below)= =2E Thanks, Guenter > Test results: > ------------- > [root@tul163p1 ~]# sensors > ibmpowernv-isa-0000 > Adapter: ISA adapter > fan1: 5567 RPM (min =3D 0 RPM) > fan2: 5232 RPM (min =3D 0 RPM) > fan3: 5532 RPM (min =3D 0 RPM) > fan4: 4945 RPM (min =3D 0 RPM) > fan5: 0 RPM (min =3D 0 RPM) > fan6: 0 RPM (min =3D 0 RPM) > fan7: 7392 RPM (min =3D 0 RPM) > fan8: 7936 RPM (min =3D 0 RPM) > temp1: +39.0=C2=B0C (high =3D +0.0=C2=B0C) > power1: 191.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 ~]# > [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 > --- > > Changes in v4 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - Replaced pr_err() with dev_err() for loggin print messages. > - Using kstrtou32() function for converting string to u32 instead of = sscanf(). > > Changes in v3 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - Fixed an endianness bug leading the driver to break on LE. > - Fixed a bug that when one of the 'attribute_group' not populated, f= ollowing > groups attributes were dropped. > - Rewrite the get_sensor_index_attr() function to handle all the erro= r 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - 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 structu= re to be > populated and then passed to devm_hwmon_device_register_with_group= s(). > > Note: Having an array of pointers of 'attribute_group' and each gr= oup > corresponds to 'enum sensors' type. Not completely sure, if it's i= deal or > could have just one group populated with attributes of sensor type= s? > > - '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 | 27 + > Documentation/hwmon/ibmpowernv | 41 ++ > drivers/hwmon/Kconfig | 11 + > drivers/hwmon/Makefile | 1 > drivers/hwmon/ibmpowernv.c | 362 +++++++++= +++++++++++ > 5 files changed, 442 insertions(+) > create mode 100644 Documentation/devicetree/bindings/hwmon/ibmpower= nv.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..e3bd1eb > --- /dev/null > +++ b/Documentation/devicetree/bindings/hwmon/ibmpowernv.txt > @@ -0,0 +1,27 @@ > +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, id= entifies a > + given sensor and its attribute data > + > +Example sensors node: > + > +cooling-fan#8-data { > + sensor-id =3D <0x7052107>; > + phandle =3D <0x10000028>; > + linux,phandle =3D <0x10000028>; > + compatible =3D "ibm,opal-sensor-cooling-fan"; phandle and linux-phandle are neither documented nor used. Either docum= ent or drop. > +}; > + > +amb-temp#1-thrs { > + sensor-id =3D <0x5096000>; > + phandle =3D <0x10000017>; > + linux,phandle =3D <0x10000017>; > + compatible =3D "ibm,opal-sensor-amb-temp"; > +}; > diff --git a/Documentation/hwmon/ibmpowernv b/Documentation/hwmon/ibm= powernv > new file mode 100644 > index 0000000..644245a > --- /dev/null > +++ b/Documentation/hwmon/ibmpowernv > @@ -0,0 +1,41 @@ > +Kernel Driver IBMPOWENV > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + > +Supported systems: > + * Any recent IBM P servers based on POWERNV platform > + > +Author: Neelesh Gupta > + > +Description > +----------- > + > +This driver implements reading the platform sensors data like temper= ature/fan/ > +voltage/power for 'POWERNV' platform. > + > +The driver uses the platform device infrastructure. It probes the de= vice tree > +for sensor devices during the __init phase and registers them with t= he '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 va= lid 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 confi= g > +CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowern= v'. > + > +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) +=3D ultra45_env.o > obj-$(CONFIG_SENSORS_I5K_AMB) +=3D i5k_amb.o > obj-$(CONFIG_SENSORS_IBMAEM) +=3D ibmaem.o > obj-$(CONFIG_SENSORS_IBMPEX) +=3D ibmpex.o > +obj-$(CONFIG_SENSORS_IBMPOWERNV)+=3D ibmpowernv.o > obj-$(CONFIG_SENSORS_IIO_HWMON) +=3D iio_hwmon.o > obj-$(CONFIG_SENSORS_INA209) +=3D ina209.o > obj-$(CONFIG_SENSORS_INA2XX) +=3D ina2xx.o > diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c > new file mode 100644 > index 0000000..44dcd99 > --- /dev/null > +++ b/drivers/hwmon/ibmpowernv.c > @@ -0,0 +1,362 @@ > +/* > + * IBM PowerNV platform sensors for temperature/fan/voltage/power > + * Copyright (C) 2014 IBM > + * > + * This program is free software; you can redistribute it and/or mod= ify > + * 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 > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#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 d= oes 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[] =3D { > + {"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_attribu= te *devattr, > + char *buf) > +{ > + struct sensor_data *sdata =3D container_of(devattr, struct sensor_d= ata, > + dev_attr); > + ssize_t ret; > + u32 x; > + > + ret =3D opal_get_sensor_data(sdata->id, &x); > + if (ret) > + return ret; > + > + /* Convert temperature to milli-degrees */ > + if (sdata->type =3D=3D AMBIENT_TEMP) > + x *=3D 1000; > + /* Convert power to micro-watts */ > + else if (sdata->type =3D=3D POWER_INPUT) > + x *=3D 1000000; > + > + return sprintf(buf, "%u\n", x); > +} > + > +static int __init get_sensor_index_attr(const char *name, u32 *index= , > + char *attr) > +{ > + char *hash_pos =3D strchr(name, '#'); > + char buf[8] =3D { 0 }; > + char *dash_pos; > + u32 copy_len; > + > + if (!hash_pos) > + return -EINVAL; > + > + dash_pos =3D strchr(hash_pos, '-'); > + if (!dash_pos) > + return -EINVAL; > + > + copy_len =3D dash_pos - hash_pos - 1; > + if (copy_len >=3D sizeof(buf)) > + return -EINVAL; > + > + strncpy(buf, hash_pos + 1, copy_len); > + > + if (kstrtou32(buf, 10, index)) > + return -EINVAL; > + smatch isn't going to like that. Please use int err; ... err =3D 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' attrib= ute 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 bef= ore > + * populating them inside hwmon device class. > + */ > +static int __init create_hwmon_attr_name(struct device *dev, enum se= nsors type, > + const char *node_name, > + char *hwmon_attr_name) > +{ > + char attr_suffix[MAX_ATTR_LEN]; > + char *attr_name; > + u32 index; > + int err; > + > + err =3D 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 =3D "fault"; > + } else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) { > + attr_name =3D "input"; > + } else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) { > + if (type =3D=3D AMBIENT_TEMP) > + attr_name =3D "max"; > + else if (type =3D=3D FAN) > + attr_name =3D "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 =3D platform_get_drvdata(pdev); > + const struct attribute_group **pgroups =3D pdata->attr_groups; > + struct device_node *opal, *np; > + enum sensors type; > + > + opal =3D 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 =3D=3D NULL) > + continue; > + > + for (type =3D 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 =3D 0; type < MAX_SENSOR_TYPE; type++) { > + sensor_groups[type].group.attrs =3D 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] =3D &sensor_groups[type].group; > + pdata->sensors_count +=3D sensor_groups[type].attr_count; > + sensor_groups[type].attr_count =3D 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 n= ode 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 =3D platform_get_drvdata(pdev); > + const struct attribute_group **pgroups =3D pdata->attr_groups; > + struct device_node *opal, *np; > + struct sensor_data *sdata; > + const __be32 *sensor_id; > + enum sensors type; > + u32 count =3D 0; > + int err =3D 0; > + > + opal =3D of_find_node_by_path("/ibm,opal/sensors"); > + sdata =3D devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*s= data), > + GFP_KERNEL); > + if (!sdata) { > + err =3D -ENOMEM; > + goto exit_put_node; > + } > + > + for_each_child_of_node(opal, np) { > + if (np->name =3D=3D NULL) > + continue; > + > + for (type =3D 0; type < MAX_SENSOR_TYPE; type++) > + if (of_device_is_compatible(np, > + sensor_groups[type].compatible)) > + break; > + > + if (type =3D=3D MAX_SENSOR_TYPE) > + continue; > + > + sensor_id =3D 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 =3D be32_to_cpup(sensor_id); > + sdata[count].type =3D type; > + err =3D 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 =3D sdata[count].name; > + sdata[count].dev_attr.attr.mode =3D S_IRUGO; > + sdata[count].dev_attr.show =3D show_sensor; > + > + pgroups[type]->attrs[sensor_groups[type].attr_count++] =3D > + &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 =3D devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); > + if (!pdata) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, pdata); > + pdata->sensors_count =3D 0; > + err =3D populate_attr_groups(pdev); > + if (err) > + return err; > + > + /* Create sysfs attribute data for each sensor found in the DT */ > + err =3D create_device_attrs(pdev); > + if (err) > + return err; > + > + /* Finally, register with hwmon */ > + hwmon_dev =3D devm_hwmon_device_register_with_groups(&pdev->dev, DR= VNAME, > + pdata, > + pdata->attr_groups); > + > + return PTR_ERR_OR_ZERO(hwmon_dev); > +} > + > +static struct platform_driver ibmpowernv_driver =3D { > + .driver =3D { > + .owner =3D THIS_MODULE, > + .name =3D DRVNAME, > + }, > +}; > + > +static int __init ibmpowernv_init(void) > +{ > + int err; > + > + pdevice =3D platform_device_alloc(DRVNAME, 0); > + if (!pdevice) { > + pr_err("Device allocation failed\n"); > + err =3D -ENOMEM; > + goto exit; > + } > + > + err =3D platform_device_add(pdevice); > + if (err) { > + pr_err("Device addition failed (%d)\n", err); > + goto exit_device_put; > + } > + > + err =3D 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 "); > +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" i= n the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html