From mboxrd@z Thu Jan 1 00:00:00 1970 From: mturquette@linaro.org (Mike Turquette) Date: Wed, 11 Sep 2013 17:21:32 -0700 Subject: [PATCH RFC] of: add a basic memory driver In-Reply-To: <52303909.5050103@elopez.com.ar> References: <1378863781-4235-1-git-send-email-emilio@elopez.com.ar> <20130911075400.GG2746@lukather> <52303909.5050103@elopez.com.ar> Message-ID: <20130912002132.27384.14149@quantum> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Quoting Emilio L?pez (2013-09-11 02:34:01) > Hi Maxime, > > El 11/09/13 04:54, Maxime Ripard escribi?: > > Hi Emilio, > > > > On Tue, Sep 10, 2013 at 10:43:01PM -0300, Emilio L?pez wrote: > >> This driver's only job is to claim and ensure that the necessary clock > >> for memory operation on a DT-enabled machine remains enabled. > >> > >> Signed-off-by: Emilio L?pez > >> --- > >> > >> Hi, > >> > >> I am currently facing an issue with the clock setup: a critical but > >> unclaimed clock gets disabled as a side effect of disabling one of its > >> children. The clock setup looks something like this: > >> > >> PLL > >> | > >> ------------ > >> | | > >> DDR Others > >> | > >> periph > >> > >> The PLL clock is marked with the CLK_IGNORE_UNUSED flag, so on a normal > >> boot it remains on, even after the unused clocks cleanup code runs. The > >> problem occurs when someone enables "periph" and then, later on, disables > >> it: the framework starts disabling clocks upwards on the tree, > >> eventually switching the PLL off (and that kills the machine, as the memory > >> clock is shut down). > > > > That looks like a bug in the clock framework. I'd expect it to at least > > behave in the same way when disabling the unused clocks at late startup > > and when going up disabling some clocks' parent later on. > > Yes, I kind of expected the same, and the flag description seems to > imply so too: > > #define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ > > >> There's two possible solutions I can think of: > >> 1) add some extra checks on the framework to not turn off clocks marked > >> with such a flag on the non-explicit case (ie, when I'm disabling > >> some other clock) > >> > >> 2) create an actual user of the DDR clock, that way it won't get > >> disabled simply because it's being used. > >> > >> I considered 1) and implemented it, but the result was not pretty. > > > > What was not pretty about it? > > It required adding an extra parameter to __clk_disable/__clk_unprepare > to keep track of the call's explicitness, and ignore the > disable/unprepare callback on the implicit case (when > __clk_disable/__clk_unprepare is called recursively) if the flag is set. > This also means adding a wrapping function to at least __clk_unprepare, > so as to to not break callers outside of the clk framework. Overall it > felt too hacky for something that could be properly handled by the > generic code if it had at least 1 user. > > I would like to hear Mike's thoughts on this; maybe CLK_IGNORE_UNUSED is > not what we think it should be. CLK_IGNORE_UNUSED was only meant to solve the issue of gating unclaimed clocks during clk_disable_unused that we do not want to gate at that point in time. To that end it is doing the right thing for your platform and I don't see a bug here. Your issue is that you have a normal clk_disable chain affecting the clock. Always the right way to do this is to have a driver claim that clock with clk_get and call clk_enable on it. That is how the clk API works. This is what your 2) approach does and is probably The Right Thing. Alternatively a new flag could be added, CLK_ALWON. This flag should be discussed but it could do a number of things: 1) any attempts to disable a clk with this flag set will always fail silently (since clk_disable has void return type). 2) same as 1) above but the clock framework could additionally call clk_enable on it after registering the clock with the CLK_ALWON flag set Anyways I think a new flag like CLK_ALWON should only really exist to solve this problem for clocks that do not have drivers in Linux. Since you went to the trouble of writing a small driver then I think just claiming the clock and enabling it there is the best solution. Regards, Mike > > >> This patch is my take on 2). Please let me know what you think; all > >> feedback is welcome :) > >> > >> Cheers, > >> > >> Emilio > >> > >> drivers/of/Kconfig | 6 ++++++ > >> drivers/of/Makefile | 1 + > >> drivers/of/of_memory.c | 30 ++++++++++++++++++++++++++++++ > >> 3 files changed, 37 insertions(+) > >> create mode 100644 drivers/of/of_memory.c > >> > >> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig > >> index 9d2009a..f6c5e20 100644 > >> --- a/drivers/of/Kconfig > >> +++ b/drivers/of/Kconfig > >> @@ -80,4 +80,10 @@ config OF_RESERVED_MEM > >> help > >> Initialization code for DMA reserved memory > >> > >> +config OF_MEMORY > >> + depends on COMMON_CLK > >> + def_bool y > >> + help > >> + Simple memory initialization > >> + > >> endmenu # OF > >> diff --git a/drivers/of/Makefile b/drivers/of/Makefile > >> index ed9660a..15f0167 100644 > >> --- a/drivers/of/Makefile > >> +++ b/drivers/of/Makefile > >> @@ -10,3 +10,4 @@ obj-$(CONFIG_OF_PCI) += of_pci.o > >> obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o > >> obj-$(CONFIG_OF_MTD) += of_mtd.o > >> obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o > >> +obj-$(CONFIG_OF_MEMORY) += of_memory.o > >> diff --git a/drivers/of/of_memory.c b/drivers/of/of_memory.c > >> new file mode 100644 > >> index 0000000..a833f7a > >> --- /dev/null > >> +++ b/drivers/of/of_memory.c > >> @@ -0,0 +1,30 @@ > >> +/* > >> + * Simple memory driver > >> + */ > >> + > >> +#include > >> +#include > >> + > >> +static int __init of_memory_enable(void) > >> +{ > >> + struct device_node *np; > >> + struct clk *clk; > >> + > >> + np = of_find_node_by_path("/memory"); > >> + if (!np) { > >> + pr_err("no /memory on DT!\n"); > >> + return 0; > >> + } > >> + > >> + clk = of_clk_get(np, 0); > >> + if (!IS_ERR(clk)) { > >> + clk_prepare_enable(clk); > >> + clk_put(clk); > >> + } > >> + > >> + of_node_put(np); > >> + > >> + return 0; > >> +} > >> + > >> +device_initcall(of_memory_enable); > > > > I like this idea as well. But imho, both 1 and 2 should be done. 2) is > > only about memory devices, while 1) is much more generic. > > > > And fwiw, the Marvell Armada 370 is also in this case of having a > > gatable clock for the DDR that could potentially be disabled (but is > > not, since it has no other users than the DDR itself, and as such, no > > one ever calls clk_disable on it). > > Nice to know, thanks for the information :) > > Cheers, > > Emilio From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Turquette Subject: Re: [PATCH RFC] of: add a basic memory driver Date: Wed, 11 Sep 2013 17:21:32 -0700 Message-ID: <20130912002132.27384.14149@quantum> References: <1378863781-4235-1-git-send-email-emilio@elopez.com.ar> <20130911075400.GG2746@lukather> <52303909.5050103@elopez.com.ar> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <52303909.5050103@elopez.com.ar> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: =?utf-8?q?Emilio_L=C3=B3pez?= , Maxime Ripard Cc: grant.likely@linaro.org, devicetree@vger.kernel.org, david.lanzendoerfer@o2s.ch, linux-arm-kernel@lists.infradead.org, rob.herring@calxeda.com List-Id: devicetree@vger.kernel.org UXVvdGluZyBFbWlsaW8gTMOzcGV6ICgyMDEzLTA5LTExIDAyOjM0OjAxKQo+IEhpIE1heGltZSwK PiAKPiBFbCAxMS8wOS8xMyAwNDo1NCwgTWF4aW1lIFJpcGFyZCBlc2NyaWJpw7M6Cj4gPiBIaSBF bWlsaW8sCj4gPgo+ID4gT24gVHVlLCBTZXAgMTAsIDIwMTMgYXQgMTA6NDM6MDFQTSAtMDMwMCwg RW1pbGlvIEzDs3BleiB3cm90ZToKPiA+PiBUaGlzIGRyaXZlcidzIG9ubHkgam9iIGlzIHRvIGNs YWltIGFuZCBlbnN1cmUgdGhhdCB0aGUgbmVjZXNzYXJ5IGNsb2NrCj4gPj4gZm9yIG1lbW9yeSBv cGVyYXRpb24gb24gYSBEVC1lbmFibGVkIG1hY2hpbmUgcmVtYWlucyBlbmFibGVkLgo+ID4+Cj4g Pj4gU2lnbmVkLW9mZi1ieTogRW1pbGlvIEzDs3BleiA8ZW1pbGlvQGVsb3Blei5jb20uYXI+Cj4g Pj4gLS0tCj4gPj4KPiA+PiBIaSwKPiA+Pgo+ID4+IEkgYW0gY3VycmVudGx5IGZhY2luZyBhbiBp c3N1ZSB3aXRoIHRoZSBjbG9jayBzZXR1cDogYSBjcml0aWNhbCBidXQKPiA+PiB1bmNsYWltZWQg Y2xvY2sgZ2V0cyBkaXNhYmxlZCBhcyBhIHNpZGUgZWZmZWN0IG9mIGRpc2FibGluZyBvbmUgb2Yg aXRzCj4gPj4gY2hpbGRyZW4uIFRoZSBjbG9jayBzZXR1cCBsb29rcyBzb21ldGhpbmcgbGlrZSB0 aGlzOgo+ID4+Cj4gPj4gICAgICAgIFBMTAo+ID4+ICAgICAgICAgfAo+ID4+ICAgLS0tLS0tLS0t LS0tCj4gPj4gICB8ICAgICAgICAgIHwKPiA+PiBERFIgICAgICAgT3RoZXJzCj4gPj4gICAgICAg ICAgICAgIHwKPiA+PiAgICAgICAgICAgIHBlcmlwaAo+ID4+Cj4gPj4gVGhlIFBMTCBjbG9jayBp cyBtYXJrZWQgd2l0aCB0aGUgQ0xLX0lHTk9SRV9VTlVTRUQgZmxhZywgc28gb24gYSBub3JtYWwK PiA+PiBib290IGl0IHJlbWFpbnMgb24sIGV2ZW4gYWZ0ZXIgdGhlIHVudXNlZCBjbG9ja3MgY2xl YW51cCBjb2RlIHJ1bnMuIFRoZQo+ID4+IHByb2JsZW0gb2NjdXJzIHdoZW4gc29tZW9uZSBlbmFi bGVzICJwZXJpcGgiIGFuZCB0aGVuLCBsYXRlciBvbiwgZGlzYWJsZXMKPiA+PiBpdDogdGhlIGZy YW1ld29yayBzdGFydHMgZGlzYWJsaW5nIGNsb2NrcyB1cHdhcmRzIG9uIHRoZSB0cmVlLAo+ID4+ IGV2ZW50dWFsbHkgc3dpdGNoaW5nIHRoZSBQTEwgb2ZmIChhbmQgdGhhdCBraWxscyB0aGUgbWFj aGluZSwgYXMgdGhlIG1lbW9yeQo+ID4+IGNsb2NrIGlzIHNodXQgZG93bikuCj4gPgo+ID4gVGhh dCBsb29rcyBsaWtlIGEgYnVnIGluIHRoZSBjbG9jayBmcmFtZXdvcmsuIEknZCBleHBlY3QgaXQg dG8gYXQgbGVhc3QKPiA+IGJlaGF2ZSBpbiB0aGUgc2FtZSB3YXkgd2hlbiBkaXNhYmxpbmcgdGhl IHVudXNlZCBjbG9ja3MgYXQgbGF0ZSBzdGFydHVwCj4gPiBhbmQgd2hlbiBnb2luZyB1cCBkaXNh Ymxpbmcgc29tZSBjbG9ja3MnIHBhcmVudCBsYXRlciBvbi4KPiAKPiBZZXMsIEkga2luZCBvZiBl eHBlY3RlZCB0aGUgc2FtZSwgYW5kIHRoZSBmbGFnIGRlc2NyaXB0aW9uIHNlZW1zIHRvIAo+IGlt cGx5IHNvIHRvbzoKPiAKPiAgICAgICNkZWZpbmUgQ0xLX0lHTk9SRV9VTlVTRUQgIEJJVCgzKSAv KiBkbyBub3QgZ2F0ZSBldmVuIGlmIHVudXNlZCAqLwo+IAo+ID4+IFRoZXJlJ3MgdHdvIHBvc3Np YmxlIHNvbHV0aW9ucyBJIGNhbiB0aGluayBvZjoKPiA+PiAgIDEpIGFkZCBzb21lIGV4dHJhIGNo ZWNrcyBvbiB0aGUgZnJhbWV3b3JrIHRvIG5vdCB0dXJuIG9mZiBjbG9ja3MgbWFya2VkCj4gPj4g ICAgICB3aXRoIHN1Y2ggYSBmbGFnIG9uIHRoZSBub24tZXhwbGljaXQgY2FzZSAoaWUsIHdoZW4g SSdtIGRpc2FibGluZwo+ID4+ICAgICAgc29tZSBvdGhlciBjbG9jaykKPiA+Pgo+ID4+ICAgMikg Y3JlYXRlIGFuIGFjdHVhbCB1c2VyIG9mIHRoZSBERFIgY2xvY2ssIHRoYXQgd2F5IGl0IHdvbid0 IGdldAo+ID4+ICAgICAgZGlzYWJsZWQgc2ltcGx5IGJlY2F1c2UgaXQncyBiZWluZyB1c2VkLgo+ ID4+Cj4gPj4gSSBjb25zaWRlcmVkIDEpIGFuZCBpbXBsZW1lbnRlZCBpdCwgYnV0IHRoZSByZXN1 bHQgd2FzIG5vdCBwcmV0dHkuCj4gPgo+ID4gV2hhdCB3YXMgbm90IHByZXR0eSBhYm91dCBpdD8K PiAKPiBJdCByZXF1aXJlZCBhZGRpbmcgYW4gZXh0cmEgcGFyYW1ldGVyIHRvIF9fY2xrX2Rpc2Fi bGUvX19jbGtfdW5wcmVwYXJlIAo+IHRvIGtlZXAgdHJhY2sgb2YgdGhlIGNhbGwncyBleHBsaWNp dG5lc3MsIGFuZCBpZ25vcmUgdGhlIAo+IGRpc2FibGUvdW5wcmVwYXJlIGNhbGxiYWNrIG9uIHRo ZSBpbXBsaWNpdCBjYXNlICh3aGVuIAo+IF9fY2xrX2Rpc2FibGUvX19jbGtfdW5wcmVwYXJlIGlz IGNhbGxlZCByZWN1cnNpdmVseSkgaWYgdGhlIGZsYWcgaXMgc2V0LiAKPiBUaGlzIGFsc28gbWVh bnMgYWRkaW5nIGEgd3JhcHBpbmcgZnVuY3Rpb24gdG8gYXQgbGVhc3QgX19jbGtfdW5wcmVwYXJl LCAKPiBzbyBhcyB0byB0byBub3QgYnJlYWsgY2FsbGVycyBvdXRzaWRlIG9mIHRoZSBjbGsgZnJh bWV3b3JrLiBPdmVyYWxsIGl0IAo+IGZlbHQgdG9vIGhhY2t5IGZvciBzb21ldGhpbmcgdGhhdCBj b3VsZCBiZSBwcm9wZXJseSBoYW5kbGVkIGJ5IHRoZSAKPiBnZW5lcmljIGNvZGUgaWYgaXQgaGFk IGF0IGxlYXN0IDEgdXNlci4KPiAKPiBJIHdvdWxkIGxpa2UgdG8gaGVhciBNaWtlJ3MgdGhvdWdo dHMgb24gdGhpczsgbWF5YmUgQ0xLX0lHTk9SRV9VTlVTRUQgaXMgCj4gbm90IHdoYXQgd2UgdGhp bmsgaXQgc2hvdWxkIGJlLgoKQ0xLX0lHTk9SRV9VTlVTRUQgd2FzIG9ubHkgbWVhbnQgdG8gc29s dmUgdGhlIGlzc3VlIG9mIGdhdGluZyB1bmNsYWltZWQKY2xvY2tzIGR1cmluZyBjbGtfZGlzYWJs ZV91bnVzZWQgdGhhdCB3ZSBkbyBub3Qgd2FudCB0byBnYXRlIGF0IHRoYXQKcG9pbnQgaW4gdGlt ZS4gVG8gdGhhdCBlbmQgaXQgaXMgZG9pbmcgdGhlIHJpZ2h0IHRoaW5nIGZvciB5b3VyIHBsYXRm b3JtCmFuZCBJIGRvbid0IHNlZSBhIGJ1ZyBoZXJlLgoKWW91ciBpc3N1ZSBpcyB0aGF0IHlvdSBo YXZlIGEgbm9ybWFsIGNsa19kaXNhYmxlIGNoYWluIGFmZmVjdGluZyB0aGUKY2xvY2suIEFsd2F5 cyB0aGUgcmlnaHQgd2F5IHRvIGRvIHRoaXMgaXMgdG8gaGF2ZSBhIGRyaXZlciBjbGFpbSB0aGF0 CmNsb2NrIHdpdGggY2xrX2dldCBhbmQgY2FsbCBjbGtfZW5hYmxlIG9uIGl0LiBUaGF0IGlzIGhv dyB0aGUgY2xrIEFQSQp3b3Jrcy4gVGhpcyBpcyB3aGF0IHlvdXIgMikgYXBwcm9hY2ggZG9lcyBh bmQgaXMgcHJvYmFibHkgVGhlIFJpZ2h0ClRoaW5nLgoKQWx0ZXJuYXRpdmVseSBhIG5ldyBmbGFn IGNvdWxkIGJlIGFkZGVkLCBDTEtfQUxXT04uIFRoaXMgZmxhZyBzaG91bGQgYmUKZGlzY3Vzc2Vk IGJ1dCBpdCBjb3VsZCBkbyBhIG51bWJlciBvZiB0aGluZ3M6CgoxKSBhbnkgYXR0ZW1wdHMgdG8g ZGlzYWJsZSBhIGNsayB3aXRoIHRoaXMgZmxhZyBzZXQgd2lsbCBhbHdheXMgZmFpbApzaWxlbnRs eSAoc2luY2UgY2xrX2Rpc2FibGUgaGFzIHZvaWQgcmV0dXJuIHR5cGUpLgoKMikgc2FtZSBhcyAx KSBhYm92ZSBidXQgdGhlIGNsb2NrIGZyYW1ld29yayBjb3VsZCBhZGRpdGlvbmFsbHkgY2FsbApj bGtfZW5hYmxlIG9uIGl0IGFmdGVyIHJlZ2lzdGVyaW5nIHRoZSBjbG9jayB3aXRoIHRoZSBDTEtf QUxXT04gZmxhZyBzZXQKCkFueXdheXMgSSB0aGluayBhIG5ldyBmbGFnIGxpa2UgQ0xLX0FMV09O IHNob3VsZCBvbmx5IHJlYWxseSBleGlzdCB0bwpzb2x2ZSB0aGlzIHByb2JsZW0gZm9yIGNsb2Nr cyB0aGF0IGRvIG5vdCBoYXZlIGRyaXZlcnMgaW4gTGludXguIFNpbmNlCnlvdSB3ZW50IHRvIHRo ZSB0cm91YmxlIG9mIHdyaXRpbmcgYSBzbWFsbCBkcml2ZXIgdGhlbiBJIHRoaW5rIGp1c3QKY2xh aW1pbmcgdGhlIGNsb2NrIGFuZCBlbmFibGluZyBpdCB0aGVyZSBpcyB0aGUgYmVzdCBzb2x1dGlv bi4KClJlZ2FyZHMsCk1pa2UKCj4gCj4gPj4gVGhpcyBwYXRjaCBpcyBteSB0YWtlIG9uIDIpLiBQ bGVhc2UgbGV0IG1lIGtub3cgd2hhdCB5b3UgdGhpbms7IGFsbAo+ID4+IGZlZWRiYWNrIGlzIHdl bGNvbWUgOikKPiA+Pgo+ID4+IENoZWVycywKPiA+Pgo+ID4+IEVtaWxpbwo+ID4+Cj4gPj4gICBk cml2ZXJzL29mL0tjb25maWcgICAgIHwgIDYgKysrKysrCj4gPj4gICBkcml2ZXJzL29mL01ha2Vm aWxlICAgIHwgIDEgKwo+ID4+ICAgZHJpdmVycy9vZi9vZl9tZW1vcnkuYyB8IDMwICsrKysrKysr KysrKysrKysrKysrKysrKysrKysrKwo+ID4+ICAgMyBmaWxlcyBjaGFuZ2VkLCAzNyBpbnNlcnRp b25zKCspCj4gPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9vZi9vZl9tZW1vcnkuYwo+ ID4+Cj4gPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvb2YvS2NvbmZpZyBiL2RyaXZlcnMvb2YvS2Nv bmZpZwo+ID4+IGluZGV4IDlkMjAwOWEuLmY2YzVlMjAgMTAwNjQ0Cj4gPj4gLS0tIGEvZHJpdmVy cy9vZi9LY29uZmlnCj4gPj4gKysrIGIvZHJpdmVycy9vZi9LY29uZmlnCj4gPj4gQEAgLTgwLDQg KzgwLDEwIEBAIGNvbmZpZyBPRl9SRVNFUlZFRF9NRU0KPiA+PiAgICAgIGhlbHAKPiA+PiAgICAg ICAgSW5pdGlhbGl6YXRpb24gY29kZSBmb3IgRE1BIHJlc2VydmVkIG1lbW9yeQo+ID4+Cj4gPj4g K2NvbmZpZyBPRl9NRU1PUlkKPiA+PiArICAgIGRlcGVuZHMgb24gQ09NTU9OX0NMSwo+ID4+ICsg ICAgZGVmX2Jvb2wgeQo+ID4+ICsgICAgaGVscAo+ID4+ICsgICAgICBTaW1wbGUgbWVtb3J5IGlu aXRpYWxpemF0aW9uCj4gPj4gKwo+ID4+ICAgZW5kbWVudSAjIE9GCj4gPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvb2YvTWFrZWZpbGUgYi9kcml2ZXJzL29mL01ha2VmaWxlCj4gPj4gaW5kZXggZWQ5 NjYwYS4uMTVmMDE2NyAxMDA2NDQKPiA+PiAtLS0gYS9kcml2ZXJzL29mL01ha2VmaWxlCj4gPj4g KysrIGIvZHJpdmVycy9vZi9NYWtlZmlsZQo+ID4+IEBAIC0xMCwzICsxMCw0IEBAIG9iai0kKENP TkZJR19PRl9QQ0kpICAgICAgICs9IG9mX3BjaS5vCj4gPj4gICBvYmotJChDT05GSUdfT0ZfUENJ X0lSUSkgICs9IG9mX3BjaV9pcnEubwo+ID4+ICAgb2JqLSQoQ09ORklHX09GX01URCkgICAgICAg Kz0gb2ZfbXRkLm8KPiA+PiAgIG9iai0kKENPTkZJR19PRl9SRVNFUlZFRF9NRU0pICs9IG9mX3Jl c2VydmVkX21lbS5vCj4gPj4gK29iai0kKENPTkZJR19PRl9NRU1PUlkpICs9IG9mX21lbW9yeS5v Cj4gPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvb2Yvb2ZfbWVtb3J5LmMgYi9kcml2ZXJzL29mL29m X21lbW9yeS5jCj4gPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiA+PiBpbmRleCAwMDAwMDAwLi5h ODMzZjdhCj4gPj4gLS0tIC9kZXYvbnVsbAo+ID4+ICsrKyBiL2RyaXZlcnMvb2Yvb2ZfbWVtb3J5 LmMKPiA+PiBAQCAtMCwwICsxLDMwIEBACj4gPj4gKy8qCj4gPj4gKyAqIFNpbXBsZSBtZW1vcnkg ZHJpdmVyCj4gPj4gKyAqLwo+ID4+ICsKPiA+PiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4gPj4g KyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgX19pbml0IG9m X21lbW9yeV9lbmFibGUodm9pZCkKPiA+PiArewo+ID4+ICsgICAgc3RydWN0IGRldmljZV9ub2Rl ICpucDsKPiA+PiArICAgIHN0cnVjdCBjbGsgKmNsazsKPiA+PiArCj4gPj4gKyAgICBucCA9IG9m X2ZpbmRfbm9kZV9ieV9wYXRoKCIvbWVtb3J5Iik7Cj4gPj4gKyAgICBpZiAoIW5wKSB7Cj4gPj4g KyAgICAgICAgICAgIHByX2Vycigibm8gL21lbW9yeSBvbiBEVCFcbiIpOwo+ID4+ICsgICAgICAg ICAgICByZXR1cm4gMDsKPiA+PiArICAgIH0KPiA+PiArCj4gPj4gKyAgICBjbGsgPSBvZl9jbGtf Z2V0KG5wLCAwKTsKPiA+PiArICAgIGlmICghSVNfRVJSKGNsaykpIHsKPiA+PiArICAgICAgICAg ICAgY2xrX3ByZXBhcmVfZW5hYmxlKGNsayk7Cj4gPj4gKyAgICAgICAgICAgIGNsa19wdXQoY2xr KTsKPiA+PiArICAgIH0KPiA+PiArCj4gPj4gKyAgICBvZl9ub2RlX3B1dChucCk7Cj4gPj4gKwo+ ID4+ICsgICAgcmV0dXJuIDA7Cj4gPj4gK30KPiA+PiArCj4gPj4gK2RldmljZV9pbml0Y2FsbChv Zl9tZW1vcnlfZW5hYmxlKTsKPiA+Cj4gPiBJIGxpa2UgdGhpcyBpZGVhIGFzIHdlbGwuIEJ1dCBp bWhvLCBib3RoIDEgYW5kIDIgc2hvdWxkIGJlIGRvbmUuIDIpIGlzCj4gPiBvbmx5IGFib3V0IG1l bW9yeSBkZXZpY2VzLCB3aGlsZSAxKSBpcyBtdWNoIG1vcmUgZ2VuZXJpYy4KPiA+Cj4gPiBBbmQg ZndpdywgdGhlIE1hcnZlbGwgQXJtYWRhIDM3MCBpcyBhbHNvIGluIHRoaXMgY2FzZSBvZiBoYXZp bmcgYQo+ID4gZ2F0YWJsZSBjbG9jayBmb3IgdGhlIEREUiB0aGF0IGNvdWxkIHBvdGVudGlhbGx5 IGJlIGRpc2FibGVkIChidXQgaXMKPiA+IG5vdCwgc2luY2UgaXQgaGFzIG5vIG90aGVyIHVzZXJz IHRoYW4gdGhlIEREUiBpdHNlbGYsIGFuZCBhcyBzdWNoLCBubwo+ID4gb25lIGV2ZXIgY2FsbHMg Y2xrX2Rpc2FibGUgb24gaXQpLgo+IAo+IE5pY2UgdG8ga25vdywgdGhhbmtzIGZvciB0aGUgaW5m b3JtYXRpb24gOikKPiAKPiBDaGVlcnMsCj4gCj4gRW1pbGlvCgpfX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlz dApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJh ZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==