From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.3 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1602C2D0C8 for ; Tue, 17 Dec 2019 13:44:06 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B232120717 for ; Tue, 17 Dec 2019 13:44:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="O3IPfFIg"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Xjvpsk0R" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B232120717 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EC13E1616; Tue, 17 Dec 2019 14:43:13 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EC13E1616 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1576590244; bh=Nhev72dyTqdGYnfKxN3nQDdJia3JjhaS6QhS4H/zyHM=; h=Date:From:To:References:In-Reply-To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=O3IPfFIgnduJ6UpxIsTXCINRaINeOeUahm5g5brgLHNtqB1WaIcx3TUmOoFYeGt2t yBuKIp/7ckrn2EsXtZCuUObED2nq5rie2geZpd0SQEmvgnwAQJNhGmWwgWEJua3y7c SKKuOEg7gkrfPiVmLlkAib+TQVYQfEXc+H+bCYMA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 11B5AF80234; Tue, 17 Dec 2019 14:40:01 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2B06DF80256; Tue, 17 Dec 2019 14:40:00 +0100 (CET) Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 13635F80218 for ; Tue, 17 Dec 2019 14:39:54 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 13635F80218 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Xjvpsk0R" Received: by mail-wm1-x344.google.com with SMTP id a5so2987555wmb.0 for ; Tue, 17 Dec 2019 05:39:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=IFZR7yFfjCaJ5Zyd28wmKFHJJ/uVBiofrkGTbX0qZ+4=; b=Xjvpsk0Rut7XusBTv1UAB4fzGBImRbEixw95u7oUKkag4bvoy73xc6FZYbixAspz0K iax8Qu9XI2XGtGSfPAQqzd+pM9HDhxq4yR9fXDO+G0+JBlgO0b3Keo/fCo6tBG+eP5nh NvwXv/5UPRer8b73CkXGQXJu+t3EpwkQxUmm8L+maMS9hHcinefthMibV4Cku5w9s4e/ IIf/lypkUKA82uPTyyWfKC11371ruqD7yg9p7MavGKLulUMcB9DiXH4lLIMBsB3w5gK5 RplbDF8dCX8T8HaEZ41WO8lqh4FMBOUv0R/eCnFNMoqBoW0++nm9sTuTWF2yOSj5gG47 RD+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=IFZR7yFfjCaJ5Zyd28wmKFHJJ/uVBiofrkGTbX0qZ+4=; b=TO6PKFTMwTFEB1+Vh1Pug60IQeIZ2QkFaGtjALrHiIF4NXjSIyVJRTH13/ABvO9Fq6 o/F4AstODp8ashK1km8pMto8vI3aecsGITf3Zgv9qi9Via8gF+/N0j9DtGVzsbOPF5iv KZ68nJ2xYvzNxHsm8fWjHkFPV8ACuLKtCPyknCh4I5Gu+Zq8Vcd4VKuduHpBSJTyYbTn VX+O8448MsmEBMvGSgGRnSjfuDIe32czQYXcBPfv5vQrdStVsMH2+2IDfOXofyRKXlwm sYi9Cc6p+R6gDk/2dLba1vodrrO3yK1YxmO3iZyKwgy+Yb8c5ZobeQLAByuJXM/gki0J UrNQ== X-Gm-Message-State: APjAAAXBG5xlO4c9vZae1pqRQeekoj3CLhVSPfwdHIvBE1iTynUO/E7f u+thinF/wJt8MoWuJAPYV2jlHA== X-Google-Smtp-Source: APXvYqxJTewRU195IS242gKYuHK+XJLt8HGH8G88T/2+mC0xM987A3hj6SntcX86H3haWFgyBaAv/A== X-Received: by 2002:a05:600c:2283:: with SMTP id 3mr5743027wmf.100.1576589993375; Tue, 17 Dec 2019 05:39:53 -0800 (PST) Received: from dell ([2.27.35.132]) by smtp.gmail.com with ESMTPSA id o7sm2946632wmh.11.2019.12.17.05.39.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Dec 2019 05:39:52 -0800 (PST) Date: Tue, 17 Dec 2019 13:39:52 +0000 From: Lee Jones To: Daniel Mack Message-ID: <20191217133952.GJ18955@dell> References: <20191209183511.3576038-1-daniel@zonque.org> <20191209183511.3576038-8-daniel@zonque.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191209183511.3576038-8-daniel@zonque.org> User-Agent: Mutt/1.10.1 (2018-07-13) Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, lars@metafoo.de, sboyd@kernel.org, mturquette@baylibre.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, robh+dt@kernel.org, broonie@kernel.org, linux-i2c@vger.kernel.org, pascal.huerst@gmail.com, linux-clk@vger.kernel.org Subject: Re: [alsa-devel] [PATCH 06/10] mfd: Add core driver for AD242x A2B transceivers X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" T24gTW9uLCAwOSBEZWMgMjAxOSwgRGFuaWVsIE1hY2sgd3JvdGU6Cgo+IFRoZSBjb3JlIGRyaXZl ciBmb3IgdGhlc2UgZGV2aWNlcyBpcyBzcGxpdCBpbnRvIHNldmVyYWwgcGFydHMuCj4gCj4gVGhl IG1hc3RlciBub2RlIGRyaXZlciBpcyBhbiBJMkMgY2xpZW50LiBJdCBpcyByZXNwb25zaWJsZSBm b3IKPiBicmluZ2luZyB1cCB0aGUgYnVzIHRvcG9sb2d5IGFuZCBkaXNjb3ZlcmluZyB0aGUgc2xh dmUgbm9kZXMuCj4gVGhpcyBwcm9jZXNzIHJlcXVyaWVzIHNvbWUga25vd2xlZ2RlIG9mIHRoZSBz bGF2ZSBub2RlIGNvbmZpZ3VyYXRpb24KPiB0byBwcm9ncmFtIHRoZSBidXMgdGltaW5ncyBjb3Jy ZWN0bHksIHNvIHRoZSBtYXN0ZXIgZHJpdmVycyB3YWxrcwo+IHRoZSB0cmVlIG9mIG5vZGVzIGlu IHRoZSBkZXZpY2V0cmVlLiBUaGUgc2xhdmUgZHJpdmVyIGhhbmRsZXMgcGxhdGZvcm0KPiBkZXZp Y2VzIHRoYXQgYXJlIGluc3RhbnRpYXRlZCBieSB0aGUgbWFzdGVyIG5vZGUgZHJpdmVyIGFmdGVy Cj4gZGlzY292ZXJ5IGhhcyBmaW5pc2hlZC4KPiAKPiBNYXN0ZXIgbm9kZXMgZXhwb3NlIHR3byBh ZGRyZXNzZXMgb24gdGhlIEkyQyBidXMsIG9uZSAocmVmZXJyZWQgdG8gYXMKPiAnQkFTRScgaW4g dGhlIGRhdGFzaGVldCkgZm9yIGFjY2Vzc2luZyByZWdpc3RlcnMgb24gdGhlIHRyYW5zY2VpdmVy Cj4gbm9kZSBpdHNlbGYsIGFuZCBvbmUgKHJlZmVycmVkIHRvIGFzICdCVVMnKSBmb3IgYWNjZXNz aW5nIHJlbW90ZQo+IHJlZ2lzdGVycywgZWl0aGVyIG9uIHRoZSByZW1vdGUgdHJhbnNjZWl2ZXIg aXRzZWxmLCBvciBvbiBJMkMgaGFyZHdhcmUKPiBjb25uZWN0ZWQgdG8gdGhhdCByZW1vdGUgdHJh bnNjZWl2ZXIsIHdoaWNoIHRoZW4gYWN0cyBhcyBhIHJlbW90ZSBJMkMKPiBidXMgbWFzdGVyLgo+ IAo+IEluIG9yZGVyIHRvIGFsbG93IE1GRCBzdWItZGV2aWNlcyB0byBiZSByZWdpc3RlcmVkIGFz IGNoaWxkcmVuIG9mCj4gZWl0aGVyIHRoZSBtYXN0ZXIgb3IgYW55IHNsYXZlIG5vZGUsIHRoZSBk ZXRhaWxzIG9uIGhvdyB0byBhY2Nlc3MgdGhlCj4gcmVnaXN0ZXJzIGFyZSBoaWRkZW4gYmVoaW5k IGEgcmVnbWFwIGNvbmZpZy4gQSBwb2ludGVyIHRvIHRoZSByZWdtYXAKPiBpcyB0aGVuIGV4cG9z ZWQgaW4gdGhlIHN0cnVjdCBzaGFyZWQgd2l0aCB0aGUgc3ViLWRldmljZXMuCj4gCj4gVGhlIGFk MjQyeC1idXMgZHJpdmVyIGlzIGEgc2ltcGxlIHByb3h5IHRoYXQgb2NjdXBpZXMgdGhlIEJVUyBJ MkMKPiBhZGRyZXNzIGFuZCB3aGljaCBpcyByZWZlcnJlZCB0byB0aHJvdWdoIGEgZGV2aWNldHJl ZSBoYW5kbGUgYnkgdGhlCj4gbWFzdGVyIGRyaXZlci4KPiAKPiBGb3IgdGhlIGRpc2NvdmVyeSBw cm9jZXNzLCB0aGUgZHJpdmVyIGhhcyB0byB3YWl0IGZvciBhbiBpbnRlcnJ1cHQKPiB0byBvY2N1 ci4gSW4gY2FzZSBubyBpbnRlcnJ1cHQgaXMgY29uZmlndXJlZCBpbiBEVCwgdGhlIGRyaXZlciBm YWxscwo+IGJhY2sgdG8gaW50ZXJydXB0IHBvbGxpbmcuIEFmdGVyIHRoZSBkaXNjb3ZlcnkgcGhh c2UgaXMgY29tcGxldGVkLAo+IGludGVycnVwdHMgYXJlIG9ubHkgbmVlZGVkIGZvciBlcnJvciBo YW5kbGluZyBhbmQgR1BJTyBoYW5kbGluZywKPiBib3RoIG9mIHdoaWNoIGlzIG5vdCBjdXJyZW50 eSBpbXBsZW1lbnRlZC4KPiAKPiBDb2RlIGNvbW1vbiB0byBib3RoIHRoZSBtYXN0ZXIgYW5kIHRo ZSBzbGF2ZSBkcml2ZXIgbGl2ZXMgaW4KPiAnYWQyNDJ4LW5vZGUuYycuCj4gCj4gU2lnbmVkLW9m Zi1ieTogRGFuaWVsIE1hY2sgPGRhbmllbEB6b25xdWUub3JnPgo+IAo+IG1mZAoKPwoKPiAtLS0K PiAgZHJpdmVycy9tZmQvS2NvbmZpZyAgICAgICAgIHwgIDExICsKPiAgZHJpdmVycy9tZmQvTWFr ZWZpbGUgICAgICAgIHwgICAxICsKPiAgZHJpdmVycy9tZmQvYWQyNDJ4LWJ1cy5jICAgIHwgIDQy ICsrKwo+ICBkcml2ZXJzL21mZC9hZDI0MngtbWFzdGVyLmMgfCA2MTEgKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrCj4gIGRyaXZlcnMvbWZkL2FkMjQyeC1ub2RlLmMgICB8IDI2 MiArKysrKysrKysrKysrKysrCj4gIGRyaXZlcnMvbWZkL2FkMjQyeC1zbGF2ZS5jICB8IDIzNCAr KysrKysrKysrKysrKwo+ICBpbmNsdWRlL2xpbnV4L21mZC9hZDI0MnguaCAgfCA0MDAgKysrKysr KysrKysrKysrKysrKysrKysKClRoaXMgZGV2aWNlLCBvciBhdCBsZWFzdCB0aGUgd2F5IGl0J3Mg YmVlbiBjb2RlZCBpcyBiYXR0eSEKCkl0J3MgZ29pbmcgdG8gbmVlZCBhIGxvdCBvZiBtYXNzYWdp bmcgYmVmb3JlIGJlaW5nIGFjY2VwdGVkLgoKTGV0J3Mgc3RhcnQgd2l0aCBhIHF1aWNrIChpdCdz IHRha2VuIDIgaG91cnMgYWxyZWFkeSEpIGdsYW5jZS4KClNlZSBiZWxvdyAuLi4KCj4gIDcgZmls ZXMgY2hhbmdlZCwgMTU2MSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL21mZC9hZDI0MngtYnVzLmMKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbWZkL2Fk MjQyeC1tYXN0ZXIuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZmQvYWQyNDJ4LW5v ZGUuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZmQvYWQyNDJ4LXNsYXZlLmMKPiAg Y3JlYXRlIG1vZGUgMTAwNjQ0IGluY2x1ZGUvbGludXgvbWZkL2FkMjQyeC5oCj4gCj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvbWZkL0tjb25maWcgYi9kcml2ZXJzL21mZC9LY29uZmlnCj4gaW5kZXgg NDIwOTAwODUyMTY2Li43MjdhMzUwNTNkOGMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9tZmQvS2Nv bmZpZwo+ICsrKyBiL2RyaXZlcnMvbWZkL0tjb25maWcKPiBAQCAtOTksNiArOTksMTcgQEAgY29u ZmlnIFBNSUNfQURQNTUyMAo+ICAJICBpbmRpdmlkdWFsIGNvbXBvbmVudHMgbGlrZSBMQ0QgYmFj a2xpZ2h0LCBMRURzLCBHUElPcyBhbmQgS2VwYWQKPiAgCSAgdW5kZXIgdGhlIGNvcnJlc3BvbmRp bmcgbWVudXMuCj4gIAo+ICtjb25maWcgTUZEX0FEMjQyWAo+ICsJYm9vbCAiQW5hbG9nIERldmlj ZXMgQUQyNDJ4IEEyQiBzdXBwb3J0Igo+ICsJc2VsZWN0IE1GRF9DT1JFCj4gKwlzZWxlY3QgUkVH TUFQX0kyQwo+ICsJZGVwZW5kcyBvbiBJMkM9eSAmJiBPRgo+ICsJaGVscAo+ICsJICBJZiB5b3Ug c2F5IHllcyBoZXJlLCB5b3UgZ2V0IHN1cHBvcnQgZm9yIGRldmljZXMgZnJvbSB0aGUgQUQyNDJ4 Cj4gKwkgIGZhbWlsaXkuIFRoaXMgZHJpdmVyIHByb3ZpZGVzIGNvbW1vbiBzdXBwb3J0IGZvciBh Y2Nlc3NpbmcgdGhlCj4gKwkgIGRldmljZXMsIGFkZGl0aW9uYWwgZHJpdmVycyBtdXN0IGJlIGVu YWJsZWQgaW4gb3JkZXIgdG8gdXNlIHRoZQo+ICsJICBmdW5jdGlvbmFsaXR5IG9mIHRoZSBkZXZp Y2VzLgo+ICsKPiAgY29uZmlnIE1GRF9BQVQyODcwX0NPUkUKPiAgCWJvb2wgIkFuYWxvZ2ljVGVj aCBBQVQyODcwIgo+ICAJc2VsZWN0IE1GRF9DT1JFCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWZk L01ha2VmaWxlIGIvZHJpdmVycy9tZmQvTWFrZWZpbGUKPiBpbmRleCBhZWQ5OWYwODczOWYuLjIz NjFjNjc2ZjZjOCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL21mZC9NYWtlZmlsZQo+ICsrKyBiL2Ry aXZlcnMvbWZkL01ha2VmaWxlCj4gQEAgLTIwMyw2ICsyMDMsNyBAQCBvYmotJChDT05GSUdfTUZE X1NQTUlfUE1JQykJKz0gcWNvbS1zcG1pLXBtaWMubwo+ICBvYmotJChDT05GSUdfVFBTNjU5MTFf Q09NUEFSQVRPUikJKz0gdHBzNjU5MTEtY29tcGFyYXRvci5vCj4gIG9iai0kKENPTkZJR19NRkRf VFBTNjUwOTApCSs9IHRwczY1MDkwLm8KPiAgb2JqLSQoQ09ORklHX01GRF9BQVQyODcwX0NPUkUp CSs9IGFhdDI4NzAtY29yZS5vCj4gK29iai0kKENPTkZJR19NRkRfQUQyNDJYKQkrPSBhZDI0Mngt bWFzdGVyLm8gYWQyNDJ4LXNsYXZlLm8gYWQyNDJ4LWJ1cy5vIGFkMjQyeC1ub2RlLm8KPiAgb2Jq LSQoQ09ORklHX01GRF9BVDkxX1VTQVJUKQkrPSBhdDkxLXVzYXJ0Lm8KPiAgb2JqLSQoQ09ORklH X01GRF9BVE1FTF9GTEVYQ09NKQkrPSBhdG1lbC1mbGV4Y29tLm8KPiAgb2JqLSQoQ09ORklHX01G RF9BVE1FTF9ITENEQykJKz0gYXRtZWwtaGxjZGMubwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21m ZC9hZDI0MngtYnVzLmMgYi9kcml2ZXJzL21mZC9hZDI0MngtYnVzLmMKPiBuZXcgZmlsZSBtb2Rl IDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uNjY2MGUxM2NlNDNkCj4gLS0tIC9kZXYvbnVs bAo+ICsrKyBiL2RyaXZlcnMvbWZkL2FkMjQyeC1idXMuYwo+IEBAIC0wLDAgKzEsNDIgQEAKPiAr Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsKPiArI2luY2x1ZGUg PGxpbnV4L2kyYy5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW5pdC5oPgo+ICsjaW5jbHVkZSA8bGlu dXgvbWZkL2FkMjQyeC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9vZi5oPgo+ICsKPiArc3RhdGljIGludCBhZDI0MnhfYnVzX2kyY19wcm9iZShzdHJ1 Y3QgaTJjX2NsaWVudCAqaTJjLAo+ICsJCQkJY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlk KQo+ICt7Cj4gKwlkZXZfc2V0X2RydmRhdGEoJmkyYy0+ZGV2LCBpMmMpOwo+ICsJaTJjX3NldF9j bGllbnRkYXRhKGkyYywgJmkyYy0+ZGV2KTsKClBsZWFzZSBleHBsYWluIHRvIG1lIHdoYXQgeW91 IHRoaW5rIGlzIGhhcHBlbmluZyBoZXJlLgoKPiArCXJldHVybiAwOwo+ICt9CgpXaGF0IGRvZXMg dGhpcyBkcml2ZXIgZG8/ICBTZWVtcyBraW5kYSBwb2ludGxlc3M/Cgo+ICtzdGF0aWMgY29uc3Qg c3RydWN0IG9mX2RldmljZV9pZCBhZDI0MnhfYnVzX29mX21hdGNoW10gPSB7Cj4gKwl7IC5jb21w YXRpYmxlID0gImFkaSxhZDI0Mjh3LWJ1cyIgfSwKPiArCXsgfSwKPiArfTsKPiArTU9EVUxFX0RF VklDRV9UQUJMRShvZiwgYWQyNDJ4X2J1c19vZl9tYXRjaCk7Cj4gKwo+ICtzdGF0aWMgY29uc3Qg c3RydWN0IGkyY19kZXZpY2VfaWQgYWQyNDJ4X2J1c19pMmNfaWRbXSA9IHsKPiArCXsgImFkMjQy eF9idXMiLCAwIH0sCj4gKwl7IH0sCj4gK307Cj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCBh ZDI0MnhfYnVzX2kyY19pZCk7CgpUaGlzIHRhYmxlIGNhbSBiZSByZW1vdmVkIGlmIHlvdSB1c2Ug cHJvYmVfbmV3LgoKPiArc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVyIGFkMjQyeF9idXNfaTJjX2Ry aXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAiYWQyNDJ4LWJ1cyIsCj4gKwkJ Lm9mX21hdGNoX3RhYmxlID0gYWQyNDJ4X2J1c19vZl9tYXRjaCwKPiArCX0sCj4gKwkucHJvYmUg PSBhZDI0MnhfYnVzX2kyY19wcm9iZSwKPiArCS5pZF90YWJsZSA9IGFkMjQyeF9idXNfaTJjX2lk LAo+ICt9Owo+ICsKPiArbW9kdWxlX2kyY19kcml2ZXIoYWQyNDJ4X2J1c19pMmNfZHJpdmVyKTsK PiArCj4gK01PRFVMRV9ERVNDUklQVElPTigiQUQyNDJ4IGJ1cyBkcml2ZXIiKTsKPiArTU9EVUxF X0FVVEhPUigiRGFuaWVsIE1hY2sgPGRhbmllbEB6b25xdWUub3JnPiIpOwo+ICtNT0RVTEVfTElD RU5TRSgiR1BMIHYyIik7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWZkL2FkMjQyeC1tYXN0ZXIu YyBiL2RyaXZlcnMvbWZkL2FkMjQyeC1tYXN0ZXIuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4g aW5kZXggMDAwMDAwMDAwMDAwLi4xYjBiZjkwNDQyYTIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIv ZHJpdmVycy9tZmQvYWQyNDJ4LW1hc3Rlci5jCj4gQEAgLTAsMCArMSw2MTEgQEAKPiArLy8gU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsKPiArI2luY2x1ZGUgPGxpbnV4 L2Nsay5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLXByb3ZpZGVyLmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9lcnIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgo+ICsjaW5jbHVkZSA8bGludXgv aW5pdC5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9pcnEuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21mZC9hZDI0MnguaD4KPiArI2luY2x1ZGUgPGxp bnV4L21mZC9jb3JlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUg PGxpbnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4KPiArI2luY2x1ZGUg PGxpbnV4L3JlZ21hcC5oPgo+ICsKPiArc3RydWN0IGFkMjQyeF9tYXN0ZXIgewo+ICsJc3RydWN0 IGFkMjQyeF9ub2RlCW5vZGU7Cj4gKwlzdHJ1Y3QgY2xrCQkqc3luY19jbGs7Cj4gKwlzdHJ1Y3Qg Y29tcGxldGlvbglydW5fY29tcGxldGlvbjsKPiArCXN0cnVjdCBjb21wbGV0aW9uCWRpc2NvdmVy X2NvbXBsZXRpb247Cj4gKwlzdHJ1Y3QgYWQyNDJ4X2kyY19idXMJYnVzOwo+ICsJdW5zaWduZWQg aW50CQl1cF9zbG90X3NpemU7Cj4gKwl1bnNpZ25lZCBpbnQJCWRuX3Nsb3Rfc2l6ZTsKPiArCWJv b2wJCQl1cF9zbG90X2FsdF9mbXQ7Cj4gKwlib29sCQkJZG5fc2xvdF9hbHRfZm10Owo+ICsJdW5z aWduZWQgaW50CQlzeW5jX2Nsa19yYXRlOwo+ICsJaW50CQkJaXJxOwo+ICsJdTgJCQlyZXNwb25z ZV9jeWNsZXM7Cj4gK307Cgo+ICtzdHJ1Y3QgYWQyNDJ4X25vZGUgKmFkMjQyeF9tYXN0ZXJfZ2V0 X25vZGUoc3RydWN0IGFkMjQyeF9tYXN0ZXIgKm1hc3RlcikKPiArewo+ICsJcmV0dXJuICZtYXN0 ZXItPm5vZGU7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwoYWQyNDJ4X21hc3Rlcl9nZXRfbm9k ZSk7Cj4gKwo+ICtzdHJ1Y3QgYWQyNDJ4X2kyY19idXMgKmFkMjQyeF9tYXN0ZXJfZ2V0X2J1cyhz dHJ1Y3QgYWQyNDJ4X21hc3RlciAqbWFzdGVyKQo+ICt7Cj4gKwlyZXR1cm4gJm1hc3Rlci0+YnVz Owo+ICt9Cj4gK0VYUE9SVF9TWU1CT0xfR1BMKGFkMjQyeF9tYXN0ZXJfZ2V0X2J1cyk7Cj4gKwo+ ICtjb25zdCBjaGFyICphZDI0MnhfbWFzdGVyX2dldF9jbGtfbmFtZShzdHJ1Y3QgYWQyNDJ4X21h c3RlciAqbWFzdGVyKQo+ICt7Cj4gKwlyZXR1cm4gX19jbGtfZ2V0X25hbWUobWFzdGVyLT5zeW5j X2Nsayk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwoYWQyNDJ4X21hc3Rlcl9nZXRfY2xrX25h bWUpOwo+ICsKPiArdW5zaWduZWQgaW50IGFkMjQyeF9tYXN0ZXJfZ2V0X2Nsa19yYXRlKHN0cnVj dCBhZDI0MnhfbWFzdGVyICptYXN0ZXIpCj4gK3sKPiArCXJldHVybiBtYXN0ZXItPnN5bmNfY2xr X3JhdGU7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwoYWQyNDJ4X21hc3Rlcl9nZXRfY2xrX3Jh dGUpOwoKQWxsIG9mIHRoZXNlIGZ1bmN0aW9ucyBwcm92aWRlIGFic3RyYWN0aW9uIGZvciB0aGUg c2FrZSBvZgphYnN0cmFjdGlvbi4gIFRoZXkgc2hvdWxkIGJlIHJlbW92ZWQgYW5kIHJlcGxhY2Vk IHdpdGggdGhlIGNvZGUKY29udGFpbmVkIHdpdGhpbiB0aGVtLgoKPiArc3RhdGljIGludCBhZDI0 MnhfcmVhZF9vbmVfaXJxKHN0cnVjdCBhZDI0MnhfbWFzdGVyICptYXN0ZXIpCj4gK3sKPiArCXN0 cnVjdCByZWdtYXAgKnJlZ21hcCA9IG1hc3Rlci0+bm9kZS5yZWdtYXA7Cj4gKwlzdHJ1Y3QgZGV2 aWNlICpkZXYgPSBtYXN0ZXItPm5vZGUuZGV2Owo+ICsJdW5zaWduZWQgaW50IHZhbCwgaW50dHlw ZTsKPiArCWludCByZXQ7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3JlYWQocmVnbWFwLCBBRDI0Mlhf SU5UU1RBVCwgJnZhbCk7Cj4gKwlpZiAocmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAidW5h YmxlIHRvIHJlYWQgSU5UU1RBVCByZWdpc3RlcjogJWRcbiIsIHJldCk7CgpVc2VycyBkbyBub3Qg Y2FyZSBhYm91dCByZWdpc3RlcnMuCgoiRmFpbGVkIHRvIG9idGFpbiBpbnRlcnJ1cHQgc3RhdHVz IgoKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWlmICghKHZhbCAmIEFEMjQyWF9JTlRT VEFUX0lSUSkpCj4gKwkJcmV0dXJuIC1FTk9FTlQ7CgpXaGF0IGhhcHBlbmVkIGhlcmU/ICBObyBp bnRlcnJ1cHRzIGZpcmVkPwoKSVJRX05PTkUgd291bGQgYmUgYmV0dGVyIHRoYW4gIk5vIHN1Y2gg ZmlsZSBvciBkaXJlY3RvcnkiLgoKPiArCXJldCA9IHJlZ21hcF9yZWFkKHJlZ21hcCwgQUQyNDJY X0lOVFRZUEUsICZpbnR0eXBlKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYs ICJ1bmFibGUgdG8gcmVhZCBJTlRUWVBFIHJlZ2lzdGVyOiAlZFxuIiwgcmV0KTsKClNhbWUgZm9y IGFsbCBsb2cgbWVzc2FnZXMgdGhyb3VnaG91dCB0aGlzIHBhdGNoLXNldC4KCj4gKwkJcmV0dXJu IHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChyZWdtYXAsIEFEMjQyWF9JTlRT UkMsICZ2YWwpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgInVuYWJsZSB0 byByZWFkIElOVFNSQyByZWdpc3RlcjogJWRcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsKPiAr CX0KCldoYXQgZG9lcyB0aGlzIHByb3ZlPyAgV2h5IGFyZW4ndCB5b3UgZG9pbmcgYW55dGhpbmcg d2l0aCB0aGUgdmFsdWU/Cgo+ICsJcmV0ID0gcmVnbWFwX3JlYWQocmVnbWFwLCBBRDI0MlhfSU5U UE5EMCwgJnZhbCk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJl dCA9IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQyWF9JTlRQTkQwLCB2YWwpOwo+ICsJaWYgKHJl dCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChyZWdtYXAs IEFEMjQyWF9JTlRQTkQxLCAmdmFsKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVybiByZXQ7 Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJYX0lOVFBORDEsIHZhbCk7 Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0OwoKV2hhdCBkb2VzIHdyaXRpbmcgYmFj ayB0aGUgdmFsdWUgZG8/ICBDb21tZW50cyBwbGVhc2UuCgo+ICsJaWYgKHZhbCAmIEFEMjQyWF9J TlRTUkNfTVNUSU5UKSB7Cj4gKwkJcmV0ID0gcmVnbWFwX3JlYWQocmVnbWFwLCBBRDI0MlhfSU5U UE5EMiwgJnZhbCk7Cj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4gKwo+ICsJ CXJldCA9IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQyWF9JTlRQTkQyLCB2YWwpOwo+ICsJCWlm IChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWRldl9lcnIoZGV2LCAi JXMoKSBpbnR0eXBlOiAweCUwMnhcbiIsIF9fZnVuY19fLCBpbnR0eXBlKTsKCk5vIGRlYnVnZ2lu ZyB0eXBlICdmdW5jJ3MgcGxlYXNlLgoKV2hhdCBtYWtlcyB0aGlzIGFuIGVycm9yPwoKPiArCXN3 aXRjaCAoaW50dHlwZSkgewo+ICsJY2FzZSBBRDI0MlhfSU5UVFlQRV9EU0NET05FOgo+ICsJCWNv bXBsZXRlKCZtYXN0ZXItPmRpc2NvdmVyX2NvbXBsZXRpb24pOwo+ICsJCWJyZWFrOwo+ICsJY2Fz ZSBBRDI0MlhfSU5UVFlQRV9NU1RSX1JVTk5JTkc6Cj4gKwkJY29tcGxldGUoJm1hc3Rlci0+cnVu X2NvbXBsZXRpb24pOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlkZXZfaW5mbyhkZXYs ICJVbmhhbmRsZWQgaW50ZXJydXB0IHR5cGUgMHglMDJ4XG4iLCBpbnR0eXBlKTsKPiArCX0KPiAr Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBhZDI0MnhfcmVhZF9pcnFzKHN0 cnVjdCBhZDI0MnhfbWFzdGVyICptYXN0ZXIpCj4gK3sKPiArCWludCByZXQ7Cj4gKwlib29sIGZp cnN0ID0gdHJ1ZTsKPiArCj4gKwl3aGlsZSAodHJ1ZSkgewo+ICsJCXJldCA9IGFkMjQyeF9yZWFk X29uZV9pcnEobWFzdGVyKTsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiAr CQlpZiAocmV0ID09IC1FTk9FTlQpCj4gKwkJCXJldHVybiBmaXJzdCA/IHJldCA6IDA7Cj4gKwo+ ICsJCWZpcnN0ID0gZmFsc2U7Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBh ZDI0MnhfaGFuZGxlX2lycShpbnQgaXJxLCB2b2lkICpkZXZpZCkKPiArewo+ICsJc3RydWN0IGFk MjQyeF9tYXN0ZXIgKm1hc3RlciA9IGRldmlkOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSBh ZDI0MnhfcmVhZF9pcnFzKG1hc3Rlcik7Cj4gKwlpZiAocmV0ID09IC1FTk9FTlQpCj4gKwkJcmV0 dXJuIElSUV9OT05FOwo+ICsKPiArCXJldHVybiBJUlFfSEFORExFRDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBhZDI0Mnhfd2FpdF9mb3JfaXJxKHN0cnVjdCBhZDI0MnhfbWFzdGVyICptYXN0ZXIs Cj4gKwkJCSAgICAgICBzdHJ1Y3QgY29tcGxldGlvbiAqY29tcGxldGlvbiwKPiArCQkJICAgICAg IHVuc2lnbmVkIGludCB0aW1lb3V0KQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWlmIChtYXN0 ZXItPmlycSA+IDApIHsKPiArCQlyZXQgPSB3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoY29t cGxldGlvbiwKPiArCQkJCQkJICBtc2Vjc190b19qaWZmaWVzKHRpbWVvdXQpKTsKPiArCX0gZWxz ZSB7Cj4gKwkJdXNsZWVwX3JhbmdlKHRpbWVvdXQgKiAxMDAwLCB0aW1lb3V0ICogMTUwMCk7Cj4g KwkJYWQyNDJ4X3JlYWRfaXJxcyhtYXN0ZXIpOwo+ICsJCXJldCA9IGNvbXBsZXRpb25fZG9uZShj b21wbGV0aW9uKTsKPiArCX0KCldoYXQgYXJlIHRoZSBzZW1hbnRpY3Mgb2YgdGhpcyBmdW5jdGlv bi4gIENvbW1lbnRzIHBsZWFzZS4KCj4gKwlyZXR1cm4gcmV0ID09IDAgPyAtRVRJTUVET1VUIDog MDsKPiArfQo+ICsKPiArLyogU2VlIFRhYmxlIDMtMiBpbiB0aGUgZGF0YXNoZWV0ICovCgpEbyB5 b3UgcHJvdmlkZSBhIGxpbmsgdG8gdGhlIGRhdGFzaGVldCBhbnl3aGVyZT8KCkFsbCBJIGNhbiBm aW5kIGlzIGEgMSBwYWdlIG92ZXJ2aWV3LgoKUGxlYXNlIHByb3ZpZGUgYSBkZXNjcmlwdGlvbiB0 byB3aGF0IHlvdSdyZSBkb2luZyAqaGVyZSouCgo+ICtzdGF0aWMgdW5zaWduZWQgaW50IGFkMjQy eF9idXNfYml0cyh1bnNpZ25lZCBpbnQgc2xvdF9zaXplLCBib29sIGFsdF9mbXQpCj4gK3sKPiAr CWludCBhbHRfYml0c1s4XSA9IHsgMCwgMTMsIDE3LCAyMSwgMzAsIDAsIDM5LCAwIH07Cj4gKwlp bnQgaWR4ID0gQUQyNDJYX1NMT1RGTVRfRE5TSVpFKHNsb3Rfc2l6ZSk7Cj4gKwo+ICsJcmV0dXJu IGFsdF9mbXQgPyBhbHRfYml0c1tpZHhdIDogc2xvdF9zaXplICsgMTsKPiArfQo+ICsKPiArLyog U2VlIFRhYmxlIDktMSBpbiB0aGUgZGF0YXNoZWV0ICovCgpJdCdzIG9rYXkgdG8gcmVmZXJlbmNl IHRoZSBkYXRhc2hlZXQsIGJ1dCB0ZWxsIHVzIHdoYXQgeW91J3JlIGRvaW5nCmhlcmUgYXMgd2Vs bC4KCj4gK3N0YXRpYyB1bnNpZ25lZCBpbnQgYWQyNDJ4X21hc3Rlcl9yZXNwb2ZmcyhzdHJ1Y3Qg YWQyNDJ4X25vZGUgKm5vZGUpCj4gK3sKPiArCWlmIChub2RlLT50ZG1fbW9kZSA9PSAyICYmIG5v ZGUtPnRkbV9zbG90X3NpemUgPT0gMTYpCj4gKwkJcmV0dXJuIDIzODsKPiArCj4gKwlpZiAoKG5v ZGUtPnRkbV9tb2RlID09IDIgJiYgbm9kZS0+dGRtX3Nsb3Rfc2l6ZSA9PSAzMikgfHwKPiArCSAg ICAobm9kZS0+dGRtX21vZGUgPT0gNCAmJiBub2RlLT50ZG1fc2xvdF9zaXplID09IDE2KSkKPiAr CQlyZXR1cm4gMjQ1Owo+ICsKPiArCXJldHVybiAyNDg7CgpObyBtYWdpYyBudW1iZXJzIHBsZWFz ZS4gIFlvdSBuZWVkIHRvIGRlZmluZSB0aGVtLgoKPiArfQo+ICsKPiArc3RhdGljIGludCBhZDI0 MnhfZGlzY292ZXIoc3RydWN0IGFkMjQyeF9tYXN0ZXIgKm1hc3RlciwKPiArCQkJICAgc3RydWN0 IGRldmljZV9ub2RlICpub2Rlc19ucCkKPiArewo+ICsJc3RydWN0IHJlZ21hcCAqcmVnbWFwID0g bWFzdGVyLT5ub2RlLnJlZ21hcDsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IG1hc3Rlci0+bm9k ZS5kZXY7Cj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmNoaWxkX25wOwo+ICsJdW5zaWduZWQgaW50 IHZhbCwgbiA9IDAsIGksIHJlc3BvZmZzLCByZXNwY3ljczsKCj4gKwl1bnNpZ25lZCBpbnQgcmVz cGN5Y3NfdXBfbWluID0gVUlOVF9NQVg7Cj4gKwl1bnNpZ25lZCBpbnQgcmVzcGN5Y3NfZG5fbWF4 ID0gMDsKCldoYXQgYXJlIHRoZXNlPwoKPiArCXVuc2lnbmVkIGludCBtYXN0ZXJfdXBfc2xvdHMg PSAwOwo+ICsJdW5zaWduZWQgaW50IG1hc3Rlcl9kbl9zbG90cyA9IDA7Cj4gKwlib29sIHVwX2Vu YWJsZWQgPSBmYWxzZSwgZG5fZW5hYmxlZCA9IGZhbHNlOwo+ICsJdWludDhfdCBzbGF2ZV9jb250 cm9sID0gMDsKPiArCWludCByZXQ7Cj4gKwo+ICsJcmVzcG9mZnMgPSBhZDI0MnhfbWFzdGVyX3Jl c3BvZmZzKCZtYXN0ZXItPm5vZGUpOwo+ICsKPiArCWZvcl9lYWNoX2F2YWlsYWJsZV9jaGlsZF9v Zl9ub2RlKG5vZGVzX25wLCBjaGlsZF9ucCkgewoKV2hhdCBhcmUgd2UgZGlzY292ZXJpbmcgaGVy ZT8gIENoaWxkIGRldmljZXMsIG9yIHNvbWV0aGluZyBlbHNlPwoKPiArCQl1bnNpZ25lZCBpbnQg ZG5zbG90X2FjdGl2aXR5LCB1cHNsb3RfYWN0aXZpdHk7Cj4gKwkJdW5zaWduZWQgaW50IHNsYXZl X2RuX3Nsb3RzLCBzbGF2ZV91cF9zbG90czsKPiArCQl1bnNpZ25lZCBpbnQgcmVzcGN5Y3NfZG4s IHJlc3BjeWNzX3VwOwo+ICsJCXN0cnVjdCBhZDI0Mnhfc2xvdF9jb25maWcgc2xvdF9jb25maWc7 Cj4gKwo+ICsJCXJldCA9IGFkMjQyeF9yZWFkX3Nsb3RfY29uZmlnKGRldiwgY2hpbGRfbnAsICZz bG90X2NvbmZpZyk7Cj4gKwkJaWYgKHJldCA8IDApIHsKPiArCQkJZGV2X2VycihkZXYsICJzbG90 IGNvbmZpZyBvZiBzbGF2ZSAlZCBpcyBpbnZhbGlkXG4iLCBuKTsKPiArCQkJcmV0dXJuIHJldDsK PiArCQl9CgpXaGF0IGlzIGEgJ3Nsb3QnIGRlZmluZWQgYXM/Cgo+ICsJCS8qIFNlZSBzZWN0aW9u IDMtMTggaW4gdGhlIGRhdGFzaGVldCAqLwoKR2l2ZSB1cyBhIHF1aWNrIGV4cGxhbmF0aW9uLgoK PiArCQlzbGF2ZV9kbl9zbG90cyA9IG1heF90KGludCwgc2xvdF9jb25maWcuZG5fbl9mb3J3YXJk X3Nsb3RzLAo+ICsJCQkJICAgICAgIGZscyhzbG90X2NvbmZpZy5kbl9yeF9zbG90cykpOwo+ICsJ CXNsYXZlX3VwX3Nsb3RzID0gbWF4X3QoaW50LCBzbG90X2NvbmZpZy51cF9uX2ZvcndhcmRfc2xv dHMsCj4gKwkJCQkgICAgICAgZmxzKHNsb3RfY29uZmlnLnVwX3J4X3Nsb3RzKSk7Cj4gKwo+ICsJ CWlmIChuID09IDApIHsKPiArCQkJbWFzdGVyX3VwX3Nsb3RzID0gc2xhdmVfdXBfc2xvdHM7Cj4g KwkJCW1hc3Rlcl9kbl9zbG90cyA9IHNsYXZlX2RuX3Nsb3RzOwo+ICsJCX0KPiArCj4gKwkJLyog U2VlIEFwcGVuZGl4IEIgaW4gdGhlIGRhdGFzaGVldCAqLwoKR2l2ZSB1cyBhIHF1aWNrIGV4cGxh bmF0aW9uLgoKPiArCQlkbnNsb3RfYWN0aXZpdHkgPSBzbGF2ZV9kbl9zbG90cyAqCj4gKwkJCWFk MjQyeF9idXNfYml0cyhtYXN0ZXItPmRuX3Nsb3Rfc2l6ZSwKPiArCQkJCQltYXN0ZXItPmRuX3Ns b3RfYWx0X2ZtdCk7Cj4gKwkJdXBzbG90X2FjdGl2aXR5ID0gc2xhdmVfdXBfc2xvdHMgKgo+ICsJ CQlhZDI0MnhfYnVzX2JpdHMobWFzdGVyLT51cF9zbG90X3NpemUsCj4gKwkJCQkJbWFzdGVyLT51 cF9zbG90X2FsdF9mbXQpOwo+ICsKPiArCQlyZXNwY3ljc19kbiA9IERJVl9ST1VORF9VUCg2NCAr IGRuc2xvdF9hY3Rpdml0eSwgNCkgKyA0Km4gKyAyOwoKU3BhY2VzIGFyb3VuZCB0aGUgJyonLiAg SWYgaXQncyBub3QgY2xlYXIsIHVzZSBicmFja2V0cy4KCj4gKwkJcmVzcGN5Y3NfdXAgPSByZXNw b2ZmcyAtCj4gKwkJCSAgICAgIChESVZfUk9VTkRfVVAoNjQgKyB1cHNsb3RfYWN0aXZpdHksIDQp ICsgMSk7CgpObyBpZGVhIHdoYXQncyBnb2luZyBvbiBoZXJlLgoKWW91IG5lZWQgdG8gZGVmaW5l IHRoZXNlIG1hZ2ljIG51bWJlcnMgdG8gbWFrZSBpdCBjbGVhci4KCj4gKwkJaWYgKHJlc3BjeWNz X2RuID4gcmVzcGN5Y3NfZG5fbWF4KQo+ICsJCQlyZXNwY3ljc19kbl9tYXggPSByZXNwY3ljc19k bjsKPiArCj4gKwkJaWYgKHJlc3BjeWNzX3VwIDwgcmVzcGN5Y3NfdXBfbWluKQo+ICsJCQlyZXNw Y3ljc191cF9taW4gPSByZXNwY3ljc191cDsKPiArCj4gKwkJaWYgKHNsYXZlX2RuX3Nsb3RzID4g MCkKPiArCQkJZG5fZW5hYmxlZCA9IHRydWU7Cj4gKwo+ICsJCWlmIChzbGF2ZV91cF9zbG90cyA+ IDApCj4gKwkJCXVwX2VuYWJsZWQgPSB0cnVlOwo+ICsKPiArCQluKys7Cj4gKwl9Cj4gKwo+ICsJ aWYgKG4gPT0gMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiTm8gY2hpbGQgbm9kZXMgc3BlY2lmaWVk XG4iKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCj4gKwlpZiAob2ZfcHJvcGVydHlf cmVhZF9ib29sKGRldi0+b2Zfbm9kZSwgImFkaSxpbnZlcnQteGN2ci1iIikpIHsKPiArCQlyZXQg PSByZWdtYXBfdXBkYXRlX2JpdHMocmVnbWFwLCBBRDI0MlhfQ09OVFJPTCwKPiArCQkJCQkgQUQy NDJYX0NPTlRST0xfWENWUkJJTlYsCj4gKwkJCQkJIEFEMjQyWF9DT05UUk9MX1hDVlJCSU5WKTsK PiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCj4gKwkJc2xhdmVfY29udHJv bCA9IEFEMjQyWF9DT05UUk9MX1hDVlJCSU5WOwo+ICsJfQo+ICsKPiArCWlmIChyZXNwY3ljc19k bl9tYXggPiByZXNwY3ljc191cF9taW4pIHsKPiArCQlkZXZfZXJyKGRldiwgIlVuc3VwcG9ydGVk IGJ1cyB0b3BvbG9neVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJcmVz cGN5Y3MgPSAocmVzcGN5Y3NfZG5fbWF4ICsgcmVzcGN5Y3NfdXBfbWluKSAvIDI7Cj4gKwlyZXQg PSByZWdtYXBfd3JpdGUocmVnbWFwLCBBRDI0MlhfUkVTUENZQ1MsIHJlc3BjeWNzKTsKPiArCWlm IChyZXQgPCAwKQo+ICsJCXJldHVybiByZXQ7CgpDb21tZW50cyBwbGVhc2UuCgpJbiBmYWN0LCBj b21tZW50cyB0aHJvdWdob3V0IHBsZWFzZS4KCkFueXRoaW5nIHRoYXQgaXNuJ3QgYWJzb2x1dGVs eSBjcnlzdGFsIGNsZWFyIHNob3VsZCBoYXZlIGF0IGxlYXN0IGEKbGl0dGxlIG9uZSBsaW5lciB0 byBjbGFyaWZ5IHdoYXQgaXMgYmVpbmcgY2FsY3VsYXRlZC9zZXQuCgo+ICsJcmV0ID0gcmVnbWFw X3VwZGF0ZV9iaXRzKHJlZ21hcCwgQUQyNDJYX0NPTlRST0wsCj4gKwkJCQkgQUQyNDJYX0NPTlRS T0xfTkVXU1RSQ1QsCj4gKwkJCQkgQUQyNDJYX0NPTlRST0xfTkVXU1RSQ1QpOwo+ICsJaWYgKHJl dCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSByZWdtYXBfd3JpdGUocmVnbWFw LCBBRDI0MlhfU1dDVEwsIEFEMjQyWF9TV0NUTF9FTlNXKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJ CXJldHVybiByZXQ7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IG47IGkrKykgewo+ICsJCXJldCA9 IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQyWF9ESVNDVlJZLCByZXNwY3ljcyAtICg0KmkpKTsK ClNwYWNlcy4KCldoYXQgaXMgND8KCj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7 Cj4gKwo+ICsJCXJldCA9IGFkMjQyeF93YWl0X2Zvcl9pcnEobWFzdGVyLAo+ICsJCQkJCSAgJm1h c3Rlci0+ZGlzY292ZXJfY29tcGxldGlvbiwgMzUpOwoKRGVmaW5lIG1hZ2ljIG51bWJlcnMgdGhy b3VnaG91dC4KCj4gKwkJaWYgKHJldCA8IDApIHsKPiArCQkJZGV2X2VycihkZXYsICJEaXNjb3Zl cnkgb2Ygbm9kZSAlZCB0aW1lZCBvdXRcbiIsIGkpOwo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCX0K PiArCj4gKwkJdmFsID0gQUQyNDJYX1NXQ1RMX01PREUoMikgfCBBRDI0MlhfU1dDVExfRU5TVzsK PiArCj4gKwkJaWYgKGkgPT0gMCkKPiArCQkJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQy NDJYX1NXQ1RMLCB2YWwpOwo+ICsJCWVsc2UKPiArCQkJcmV0ID0gYWQyNDJ4X3NsYXZlX3dyaXRl KCZtYXN0ZXItPmJ1cywgcmVnbWFwLCBpLAo+ICsJCQkJCQkgQUQyNDJYX1NXQ1RMLCB2YWwpOwo+ ICsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCj4gKwkJZGV2X2luZm8o ZGV2LCAiTm9kZSAlZCBkaXNjb3ZlcmVkXG4iLCBpKTsKPiArCj4gKwkJLyogTGFzdCBub2RlPyAq Lwo+ICsJCWlmIChpID09IG4gLSAxKQo+ICsJCQlicmVhazsKPiArCj4gKwkJcmV0ID0gYWQyNDJ4 X3NsYXZlX3dyaXRlKCZtYXN0ZXItPmJ1cywgcmVnbWFwLCBpLAo+ICsJCQkJCSBBRDI0MlhfSU5U TVNLMiwKPiArCQkJCQkgQUQyNDJYX0lOVE1TSzJfRFNDRElFTik7Cj4gKwkJaWYgKHJldCA8IDAp Cj4gKwkJCXJldHVybiByZXQ7Cj4gKwo+ICsJCXJldCA9IGFkMjQyeF9zbGF2ZV93cml0ZSgmbWFz dGVyLT5idXMsIHJlZ21hcCwgaSwKPiArCQkJCQkgQUQyNDJYX0NPTlRST0wsIHNsYXZlX2NvbnRy b2wpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsKPiArCQlyZXQgPSBh ZDI0Mnhfc2xhdmVfd3JpdGUoJm1hc3Rlci0+YnVzLCByZWdtYXAsIGksCj4gKwkJCQkJIEFEMjQy WF9TV0NUTCwgQUQyNDJYX1NXQ1RMX0VOU1cpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1 cm4gcmV0Owo+ICsKPiArCQlyZWluaXRfY29tcGxldGlvbigmbWFzdGVyLT5kaXNjb3Zlcl9jb21w bGV0aW9uKTsKPiArCX0KPiArCj4gKwlyZXQgPSByZWdtYXBfd3JpdGUocmVnbWFwLCBBRDI0Mlhf RE5TTE9UUywgbWFzdGVyX2RuX3Nsb3RzKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVybiBy ZXQ7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJYX1VQU0xPVFMsIG1h c3Rlcl91cF9zbG90cyk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiAr CXZhbCA9IDA7Cj4gKwlpZiAoZG5fZW5hYmxlZCkKPiArCQl2YWwgfD0gQUQyNDJYX0RBVENUTF9E TlM7Cj4gKwo+ICsJaWYgKHVwX2VuYWJsZWQpCj4gKwkJdmFsIHw9IEFEMjQyWF9EQVRDVExfVVBT Owo+ICsKPiArCXJldCA9IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQyWF9EQVRDVEwsIHZhbCk7 Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgaW50IGFkMjQyeF9pbml0X2lycShzdHJ1Y3QgYWQyNDJ4X21hc3RlciAq bWFzdGVyKQo+ICt7Cj4gKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXAgPSBtYXN0ZXItPm5vZGUucmVn bWFwOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gbWFzdGVyLT5ub2RlLmRldjsKPiArCWludCBy ZXQ7Cj4gKwo+ICsJaWYgKG1hc3Rlci0+aXJxID4gMCkgewo+ICsJCXJldCA9IGRldm1fcmVxdWVz dF90aHJlYWRlZF9pcnEoZGV2LCBtYXN0ZXItPmlycSwgTlVMTCwKPiArCQkJCQkJYWQyNDJ4X2hh bmRsZV9pcnEsIElSUUZfT05FU0hPVCwKPiArCQkJCQkJZGV2X25hbWUoZGV2KSwgbWFzdGVyKTsK PiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSBy ZWdtYXBfd3JpdGUocmVnbWFwLCBBRDI0MlhfSU5UTVNLMCwKPiArCQkJICAgQUQyNDJYX0lOVE1T SzBfU1JGRUlFTiB8IEFEMjQyWF9JTlRNU0swX0JFQ0lFTiB8Cj4gKwkJCSAgIEFEMjQyWF9JTlRN U0swX1BXUkVJRU4gfCBBRDI0MlhfSU5UTVNLMF9DUkNFSUVOIHwKPiArCQkJICAgQUQyNDJYX0lO VE1TSzBfRERFSUVOICB8IEFEMjQyWF9JTlRNU0swX0hDRUlFTik7Cj4gKwlpZiAocmV0IDwgMCkK PiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQy WF9JTlRNU0syLAo+ICsJCQkgICBBRDI0MlhfSU5UTVNLMl9EU0NESUVOIHwgQUQyNDJYX0lOVE1T SzJfU0xWSVJRRU4pOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwly ZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCByZWdtYXBfY29uZmlnIGFk MjQyeF9yZWdtYXBfY29uZmlnID0gewo+ICsJLnJlZ19iaXRzCT0gOCwKPiArCS52YWxfYml0cwk9 IDgsCj4gKwkudm9sYXRpbGVfcmVnCT0gYWQyNDJ4X2lzX3ZvbGF0aWxlX3JlZywKPiArCS53cml0 ZWFibGVfcmVnCT0gYWQyNDJ4X2lzX3dyaXRlYWJsZV9yZWcsCj4gKwkubWF4X3JlZ2lzdGVyCT0g QUQyNDJYX01BWF9SRUcsCj4gKwkuY2FjaGVfdHlwZQk9IFJFR0NBQ0hFX1JCVFJFRSwKPiArfTsK PiArCj4gK3N0YXRpYyBpbnQgYWQyNDJ4X21hc3Rlcl9wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAq aTJjLAo+ICsJCQkgICAgICAgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+ICt7Cj4g KwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmJ1c19ucCwgKm5vZGVzX25wLCAqbnA7Cj4gKwlzdHJ1Y3Qg ZGV2aWNlICpidXNkZXYsICpkZXYgPSAmaTJjLT5kZXY7Cj4gKwlzdHJ1Y3QgYWQyNDJ4X21hc3Rl ciAqbWFzdGVyOwo+ICsJc3RydWN0IHJlZ21hcCAqcmVnbWFwOwo+ICsJdW5zaWduZWQgaW50IHZh bDsKPiArCWludCByZXQ7Cj4gKwo+ICsJbm9kZXNfbnAgPSBvZl9nZXRfY2hpbGRfYnlfbmFtZShk ZXYtPm9mX25vZGUsICJub2RlcyIpOwo+ICsJaWYgKCFub2Rlc19ucCkgewo+ICsJCWRldl9lcnIo ZGV2LCAibm8gJ25vZGVzJyBwcm9wZXJ0eSBnaXZlblxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7 Cj4gKwl9Cj4gKwo+ICsJYnVzX25wID0gb2ZfcGFyc2VfcGhhbmRsZShkZXYtPm9mX25vZGUsICJh ZGksYTJiLWJ1cyIsIDApOwo+ICsJaWYgKCFidXNfbnApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5v ICdhZGksYTJiLWJ1cycgaGFuZGxlIHNwZWNpZmllZCBmb3IgbWFzdGVyIG5vZGVcbiIpOwo+ICsJ CXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCWJ1c2RldiA9IGJ1c19maW5kX2RldmljZV9i eV9vZl9ub2RlKCZpMmNfYnVzX3R5cGUsIGJ1c19ucCk7Cj4gKwlpZiAoIWJ1c2Rldikgewo+ICsJ CWRldl9lcnIoZGV2LCAiJ2FkaSxhMmItYnVzJyBoYW5kbGUgaW52YWxpZFxuIik7Cj4gKwkJcmV0 dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJbWFzdGVyID0gZGV2bV9remFsbG9jKGRldiwgc2l6 ZW9mKHN0cnVjdCBhZDI0MnhfbWFzdGVyKSwgR0ZQX0tFUk5FTCk7CgpzaXplb2YoKm1hc3RlcikK Cj4gKwlpZiAoIW1hc3RlcikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltdXRleF9pbml0 KCZtYXN0ZXItPmJ1cy5tdXRleCk7Cj4gKwlpbml0X2NvbXBsZXRpb24oJm1hc3Rlci0+cnVuX2Nv bXBsZXRpb24pOwo+ICsJaW5pdF9jb21wbGV0aW9uKCZtYXN0ZXItPmRpc2NvdmVyX2NvbXBsZXRp b24pOwoKPiArCWRldl9zZXRfZHJ2ZGF0YShkZXYsICZtYXN0ZXItPm5vZGUpOwo+ICsJaTJjX3Nl dF9jbGllbnRkYXRhKGkyYywgbWFzdGVyKTsKCldoYXQgZG8geW91IHRoaW5rIGlzIGhhcHBlbmlu ZyBoZXJlPwoKPiArCXJlZ21hcCA9IGRldm1fcmVnbWFwX2luaXRfaTJjKGkyYywgJmFkMjQyeF9y ZWdtYXBfY29uZmlnKTsKPiArCWlmIChJU19FUlIocmVnbWFwKSkgewo+ICsJCXJldCA9IFBUUl9F UlIocmVnbWFwKTsKPiArCQlkZXZfZXJyKGRldiwgInJlZ21hcCBpbml0IGZhaWxlZDogJWRcbiIs IHJldCk7CgoiaW5pdGlhbGlzYXRpb24iCgpPciBldmVuIGJldHRlciAiRmFpbGVkIHRvIGluaXRp YWxpc2UgSTJDIFJlZ21hcCIKCj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwltYXN0ZXIt PmJ1cy5jbGllbnQgPSB0b19pMmNfY2xpZW50KGJ1c2Rldik7CgpXaGF0IGRvZXMgJ2J1cycgZG8g aW4gdGhpcyBjb250ZXh0PwoKPiArCW1hc3Rlci0+bm9kZS5yZWdtYXAgPSByZWdtYXA7Cj4gKwlt YXN0ZXItPm5vZGUuZGV2ID0gZGV2Owo+ICsJbWFzdGVyLT5ub2RlLm1hc3RlciA9IG1hc3RlcjsK PiArCW1hc3Rlci0+bm9kZS5pZCA9IEFEMjQyWF9NQVNURVJfSUQ7Cj4gKwltYXN0ZXItPmlycSA9 IGkyYy0+aXJxOwo+ICsKPiArCW1hc3Rlci0+c3luY19jbGsgPSBkZXZtX2Nsa19nZXQoZGV2LCAi c3luYyIpOwo+ICsJaWYgKElTX0VSUihtYXN0ZXItPnN5bmNfY2xrKSkgewo+ICsJCXJldCA9IFBU Ul9FUlIobWFzdGVyLT5zeW5jX2Nsayk7Cj4gKwkJaWYgKHJldCAhPSAtRVBST0JFX0RFRkVSKQo+ ICsJCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgc3luYyBjbGs6ICVkXG4iLCByZXQpOwo+ ICsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWlmIChvZl9wcm9wZXJ0eV9yZWFkX3Uz MihkZXYtPm9mX25vZGUsICJjbG9jay1mcmVxdWVuY3kiLAo+ICsJCQkJICZtYXN0ZXItPnN5bmNf Y2xrX3JhdGUpKSB7Cj4gKwkJcmV0ID0gY2xrX3NldF9yYXRlKG1hc3Rlci0+c3luY19jbGssIG1h c3Rlci0+c3luY19jbGtfcmF0ZSk7Cj4gKwkJaWYgKHJldCA8IDApIHsKPiArCQkJZGV2X2Vycihk ZXYsICJDYW5ub3Qgc2V0IHN5bmMgY2xvY2sgcmF0ZTogJWRcbiIsIHJldCk7Cj4gKwkJCXJldHVy biByZXQ7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCW1hc3Rlci0+c3luY19jbGtfcmF0ZSA9IGNsa19n ZXRfcmF0ZShtYXN0ZXItPnN5bmNfY2xrKTsKPiArCWlmIChtYXN0ZXItPnN5bmNfY2xrX3JhdGUg IT0gNDQxMDAgJiYgbWFzdGVyLT5zeW5jX2Nsa19yYXRlICE9IDQ4MDAwKSB7CgpQbGVhc2UgZGVm aW5lIHRoZXNlIG1hZ2ljIG51bWJlcnMuCgpTb21ldGhpbmcgZGVzY3JpcHRpdmUgdGhhdCB0ZWxs cyB1cyB3aGF0IHRoZSBkaWZmZXJlbnQgY2xvY2sgc3BlZWRzCmRvLgoKPiArCQlkZXZfZXJyKGRl diwgIlNZTkMgY2xvY2sgcmF0ZSAlZCBpcyBpbnZhbGlkXG4iLAo+ICsJCQltYXN0ZXItPnN5bmNf Y2xrX3JhdGUpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19w cmVwYXJlX2VuYWJsZShtYXN0ZXItPnN5bmNfY2xrKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJ ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZW5hYmxlIHN5bmMgY2xrOiAlZFxuIiwgcmV0KTsKPiAr CQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCS8qIE1hc3RlciBub2RlIHNldHVwICovCj4gKwo+ ICsJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJYX0NPTlRST0wsCj4gKwkJCSAgIEFE MjQyWF9DT05UUk9MX01TVFIgfCBBRDI0MlhfQ09OVFJPTF9TT0ZUUlNUKTsKPiArCWlmIChyZXQg PCAwKQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gYWQyNDJ4X3dhaXRfZm9yX2lycSht YXN0ZXIsICZtYXN0ZXItPnJ1bl9jb21wbGV0aW9uLCAxMCk7Cj4gKwlpZiAocmV0IDwgMCkgewo+ ICsJCWRldl9lcnIoZGV2LCAidGltZW91dCB3YWl0aW5nIGZvciBQTEwgc3luYzogJWRcbiIsIHJl dCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSByZWdtYXBfdXBkYXRlX2Jp dHMocmVnbWFwLCBBRDI0MlhfQ09OVFJPTCwKPiArCQkJCSBBRDI0MlhfQ09OVFJPTF9TT0ZUUlNU LCAwKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gYWQy NDJ4X25vZGVfcHJvYmUoJm1hc3Rlci0+bm9kZSk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1 cm4gcmV0Owo+ICsKPiArCXJldCA9IGFkMjQyeF9pbml0X2lycShtYXN0ZXIpOwo+ICsJaWYgKHJl dCA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgIlVuYWJsZSB0byBzZXQgdXAgSVJROiAlZCIsIHJl dCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwkvKiBTbG90IGZvcm1hdCBzZXR1cCAq Lwo+ICsKPiArCW9mX3Byb3BlcnR5X3JlYWRfdTMyKGRldi0+b2Zfbm9kZSwgImFkaSx1cHN0cmVh bS1zbG90LXNpemUiLCAmdmFsKTsKPiArCWlmICh2YWwgPCA4IHx8IHZhbCA+IDMyIHx8ICh2YWwg JSA0ICE9IDApKSB7Cj4gKwkJZGV2X2VycihkZXYsICJpbnZhbGlkIHVwc3RyZWFtLXNsb3Qtc2l6 ZSAlZFxuIiwgdmFsKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCW1hc3Rlci0+dXBf c2xvdF9zaXplID0gdmFsOwo+ICsKPiArCW9mX3Byb3BlcnR5X3JlYWRfdTMyKGRldi0+b2Zfbm9k ZSwgImFkaSxkb3duc3RyZWFtLXNsb3Qtc2l6ZSIsICZ2YWwpOwo+ICsJaWYgKHZhbCA8IDggfHwg dmFsID4gMzIgfHwgKHZhbCAlIDQgIT0gMCkpIHsKPiArCQlkZXZfZXJyKGRldiwgImludmFsaWQg ZG93bnN0cmVhbS1zbG90LXNpemUgJWRcbiIsIHZhbCk7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4g Kwl9Cj4gKwltYXN0ZXItPmRuX3Nsb3Rfc2l6ZSA9IHZhbDsKPiArCj4gKwltYXN0ZXItPmRuX3Ns b3RfYWx0X2ZtdCA9Cj4gKwkJb2ZfcHJvcGVydHlfcmVhZF9ib29sKGRldi0+b2Zfbm9kZSwKPiAr CQkJCSAgICAgICJhZGksYWx0ZXJuYXRlLWRvd25zdHJlYW0tc2xvdC1mb3JtYXQiKTsKPiArCW1h c3Rlci0+dXBfc2xvdF9hbHRfZm10ID0KPiArCQlvZl9wcm9wZXJ0eV9yZWFkX2Jvb2woZGV2LT5v Zl9ub2RlLAo+ICsJCQkJICAgICAgImFkaSxhbHRlcm5hdGUtdXBzdHJlYW0tc2xvdC1mb3JtYXQi KTsKCk9idmlvdXNseSB0aGlzIGFsbCBuZWVkcyB0byBiZSBydW4gcGFzdCB0aGUgRFQgbWFpbnRh aW5lcihzKS4KCj4gKwl2YWwgPSBBRDI0MlhfU0xPVEZNVF9ETlNJWkUobWFzdGVyLT5kbl9zbG90 X3NpemUpIHwKPiArCSAgICAgIEFEMjQyWF9TTE9URk1UX1VQU0laRShtYXN0ZXItPnVwX3Nsb3Rf c2l6ZSk7Cj4gKwo+ICsJaWYgKG1hc3Rlci0+ZG5fc2xvdF9hbHRfZm10KQo+ICsJCXZhbCB8PSBB RDI0MlhfU0xPVEZNVF9ETkZNVDsKPiArCj4gKwlpZiAobWFzdGVyLT51cF9zbG90X2FsdF9mbXQp Cj4gKwkJdmFsIHw9IEFEMjQyWF9TTE9URk1UX1VQRk1UOwo+ICsKPiArCXJldCA9IHJlZ21hcF93 cml0ZShyZWdtYXAsIEFEMjQyWF9TTE9URk1ULCB2YWwpOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJ cmV0dXJuIHJldDsKPiArCj4gKwkvKiBOb2RlIGRpc2NvdmVyeSBhbmQgTUZEIHNldHVwICovCj4g Kwo+ICsJcmV0ID0gYWQyNDJ4X2Rpc2NvdmVyKG1hc3Rlciwgbm9kZXNfbnApOwo+ICsJaWYgKHJl dCA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgImVycm9yIGRpc2NvdmVyaW5nIG5vZGVzOiAlZFxu IiwgcmV0KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGFkMjQyeF9ub2Rl X2FkZF9tZmRfY2VsbHMoZGV2KTsKCldoeSBpcyB0aGlzIGNhbGxlZCB0d2ljZSB3aXRoIHRoZSBz YW1lIGNoaWxkcmVuPwoKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJmYWls ZWQgdG8gYWRkIE1GRCBkZXZpY2VzICVkXG4iLCByZXQpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9 Cj4gKwo+ICsJLyogUmVnaXN0ZXIgcGxhdGZvcm0gZGV2aWNlcyBmb3Igbm9kZXMgKi8KPiArCj4g Kwlmb3JfZWFjaF9hdmFpbGFibGVfY2hpbGRfb2Zfbm9kZShub2Rlc19ucCwgbnApCj4gKwkJb2Zf cGxhdGZvcm1fZGV2aWNlX2NyZWF0ZShucCwgTlVMTCwgZGV2KTsKCldoYXQgYXJlIHlvdSBkb2lu ZyBoZXJlPwoKRWl0aGVyIHVzZSBPRiB0byByZWdpc3RlciBhbGwgY2hpbGQgZGV2aWNlcyBPUiB1 c2UgTUZELCBub3QgYSBtaXh0dXJlCm9mIGJvdGguCgo+ICsJb2Zfbm9kZV9wdXQobm9kZXNfbnAp Owo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGFkMjQyeF9tYXN0ZXJf cmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMpCj4gK3sKPiArCXN0cnVjdCBhZDI0MnhfbWFz dGVyICptYXN0ZXIgPSBpMmNfZ2V0X2NsaWVudGRhdGEoaTJjKTsKPiArCj4gKwlpZiAobWFzdGVy LT5zeW5jX2NsaykKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobWFzdGVyLT5zeW5jX2Nsayk7 Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2 aWNlX2lkIGFkMjQyeF9tYXN0ZXJfb2ZfbWF0Y2hbXSA9IHsKPiArCXsgLmNvbXBhdGlibGUgPSAi YWRpLGFkMjQyOHctbWFzdGVyIiB9LAo+ICsJeyB9Cj4gK307Cj4gK01PRFVMRV9ERVZJQ0VfVEFC TEUob2YsIGFkMjQyeF9tYXN0ZXJfb2ZfbWF0Y2gpOwo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVj dCBpMmNfZGV2aWNlX2lkIGFkMjQyeF9tYXN0ZXJfaTJjX2lkW10gPSB7Cj4gKwl7ImFkMjQyeC1t YXN0ZXIiLCAwfSwKPiArCXsgfQo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKGkyYywgYWQy NDJ4X21hc3Rlcl9pMmNfaWQpOwoKSWYgeW91IG9uZSB0aGUgT0YgbWF0Y2ggdGFibGUsIHlvdSBk b24ndCBuZWVkIHRoaXMgZW1wdHkgSTJDIHRhYmxlLgpHcmVwIGZvciBwcm9iZV9uZXcuCgo+ICtz dGF0aWMgc3RydWN0IGkyY19kcml2ZXIgYWQyNDJ4X21hc3Rlcl9pMmNfZHJpdmVyID0gewo+ICsJ LmRyaXZlcgk9IHsKPiArCQkubmFtZSA9ICJhZDI0MngtbWFzdGVyIiwKPiArCQkub2ZfbWF0Y2hf dGFibGUJPSBhZDI0MnhfbWFzdGVyX29mX21hdGNoLAo+ICsJfSwKPiArCS5wcm9iZSA9IGFkMjQy eF9tYXN0ZXJfcHJvYmUsCj4gKwkucmVtb3ZlID0gYWQyNDJ4X21hc3Rlcl9yZW1vdmUsCj4gKwku aWRfdGFibGUgPSBhZDI0MnhfbWFzdGVyX2kyY19pZCwKPiArfTsKPiArCgpSZW1vdmUgdGhpcyBs aW5lLgoKPiArbW9kdWxlX2kyY19kcml2ZXIoYWQyNDJ4X21hc3Rlcl9pMmNfZHJpdmVyKTsKPiAr Cj4gK01PRFVMRV9ERVNDUklQVElPTigiQUQyNDJ4IG1hc3RlciBtYXN0ZXIgZHJpdmVyIik7CgpU eXBvLgoKPiArTU9EVUxFX0FVVEhPUigiRGFuaWVsIE1hY2sgPGRhbmllbEB6b25xdWUub3JnPiIp Owo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWZk L2FkMjQyeC1ub2RlLmMgYi9kcml2ZXJzL21mZC9hZDI0Mngtbm9kZS5jCj4gbmV3IGZpbGUgbW9k ZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLmY5ZGI2ODkzODBhNwo+IC0tLSAvZGV2L251 bGwKPiArKysgYi9kcml2ZXJzL21mZC9hZDI0Mngtbm9kZS5jCj4gQEAgLTAsMCArMSwyNjIgQEAK PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsKPiArI2luY2x1 ZGUgPGxpbnV4L2Nsay5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9pMmMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L2ludGVycnVwdC5oPgo+ICsjaW5jbHVkZSA8bGludXgvaXJxLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9tZmQvY29yZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbWZkL2FkMjQyeC5oPgo+ICsjaW5jbHVk ZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPgo+ICsjaW5jbHVkZSA8 bGludXgvb2ZfZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KPiArCj4gKy8q IFNlZSBUYWJsZSA3LTQzIGluIHRoZSBkYXRhc2hlZXQgKi8KCk1vcmUgaW5mb3JtYXRpb24gcGxl YXNlLgoKPiArc3RhdGljIGludCBhZDI0MnhfdGRtbW9kZV9pbmRleCh1bnNpZ25lZCBpbnQgbW9k ZSwgYm9vbCBzbGF2ZSkKPiArewo+ICsJc3dpdGNoIChtb2RlKSB7Cj4gKwljYXNlIDI6Cj4gKwkJ cmV0dXJuIDA7Cj4gKwljYXNlIDQ6Cj4gKwkJcmV0dXJuIDE7Cj4gKwljYXNlIDg6Cj4gKwkJcmV0 dXJuIDI7Cj4gKwljYXNlIDEyOgo+ICsJCXJldHVybiBzbGF2ZSA/IC1FSU5WQUwgOiAzOwo+ICsJ Y2FzZSAxNjoKPiArCQlyZXR1cm4gNDsKPiArCWNhc2UgMjA6Cj4gKwkJcmV0dXJuIHNsYXZlID8g LUVJTlZBTCA6IDU7Cj4gKwljYXNlIDI0Ogo+ICsJCXJldHVybiBzbGF2ZSA/IC1FSU5WQUwgOiA2 Owo+ICsJY2FzZSAzMjoKPiArCQlyZXR1cm4gNzsKPiArCWRlZmF1bHQ6Cj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4gKwl9Cj4gK30KPiArCj4gK2ludCBhZDI0Mnhfbm9kZV9wcm9iZShzdHJ1Y3QgYWQy NDJ4X25vZGUgKm5vZGUpCj4gK3sKPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBub2RlLT5k ZXYtPm9mX25vZGU7Cj4gKwl1bnNpZ25lZCBpbnQgdmFsOwo+ICsJaW50IHJldDsKPiArCj4gKwly ZXQgPSByZWdtYXBfcmVhZChub2RlLT5yZWdtYXAsIEFEMjQyWF9WRU5ET1IsICZ2YWwpOwo+ICsJ aWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKG5vZGUtPmRldiwgImZhaWxlZCB0byByZWFkIFZF TkRPUiByZWdpc3RlciAlZFxuIiwgcmV0KTsKClBsZWFzZSByZS13cml0ZSBhbGwgb2YgeW91ciBr ZXJuZWwgbG9nIG1lc3NhZ2VzIHRvIGJlIHVzZXIgZnJpZW5kbHkuCgo+ICsJCXJldHVybiByZXQ7 Cj4gKwl9Cj4gKwo+ICsJaWYgKHZhbCAhPSAweGFkKSB7CgpObyBtYWdpYyBudW1iZXJzIC0gcGxl YXNlIGRlZmluZSB0aGVtIGFsbC4KCj4gKwkJZGV2X2Vycihub2RlLT5kZXYsICJib2d1cyB2YWx1 ZSAweCUwMnggaW4gVkVORE9SIHJlZ2lzdGVyXG4iLAo+ICsJCQl2YWwpOwo+ICsJCXJldHVybiAt RU5PREVWOwo+ICsJfQo+ICsKPiArCXJldCA9IHJlZ21hcF9yZWFkKG5vZGUtPnJlZ21hcCwgQUQy NDJYX1BST0RVQ1QsICZ2YWwpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKG5vZGUt PmRldiwgImZhaWxlZCB0byByZWFkIFBST0RVQ1QgcmVnaXN0ZXIgJWRcbiIsCj4gKwkJCXJldCk7 Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlpZiAodmFsICE9IDB4MjgpIHsKPiArCQlk ZXZfZXJyKG5vZGUtPmRldiwgImJvZ3VzIHZhbHVlIDB4JTAyeCBpbiBQUk9EVUNUIHJlZ2lzdGVy XG4iLAo+ICsJCQl2YWwpOwo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsJfQo+ICsKPiArCXJldCA9 IHJlZ21hcF9yZWFkKG5vZGUtPnJlZ21hcCwgQUQyNDJYX1ZFUlNJT04sICZ2YWwpOwo+ICsJaWYg KHJldCA8IDApIHsKPiArCQlkZXZfZXJyKG5vZGUtPmRldiwgImZhaWxlZCB0byByZWFkIFZFUlNJ T04gcmVnaXN0ZXIgJWRcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlp ZiAobm9kZS0+aWQgPT0gQUQyNDJYX01BU1RFUl9JRCkKPiArCQlkZXZfaW5mbyhub2RlLT5kZXYs Cj4gKwkJCSAiRGV0ZWN0ZWQgQUQyNDJ4IG1hc3RlciBub2RlLCB2ZXJzaW9uICVkLiVkXG4iLAo+ ICsJCQkgdmFsID4+IDQsIHZhbCAmIDB4Zik7Cj4gKwllbHNlCj4gKwkJZGV2X2luZm8obm9kZS0+ ZGV2LAo+ICsJCQkgIkRldGVjdGVkIEFEMjQyeCBzbGF2ZSBub2RlLCB2ZXJzaW9uICVkLiVkLCBp ZCAlZFxuIiwKPiArCQkJIHZhbCA+PiA0LCB2YWwgJiAweGYsIG5vZGUtPmlkKTsKPiArCj4gKwly ZXQgPSByZWdtYXBfcmVhZChub2RlLT5yZWdtYXAsIEFEMjQyWF9DQVBBQklMSVRZLCAmdmFsKTsK PiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2Vycihub2RlLT5kZXYsICJmYWlsZWQgdG8gcmVh ZCBDQVBBQklMSVRZIHJlZ2lzdGVyICVkXG4iLAo+ICsJCQlyZXQpOwo+ICsJCXJldHVybiByZXQ7 Cj4gKwl9Cj4gKwo+ICsJbm9kZS0+Y2FwcyA9IHZhbDsKPiArCj4gKwl2YWwgPSAwOwo+ICsKPiAr CWlmIChvZl9wcm9wZXJ0eV9yZWFkX2Jvb2wobnAsICJhZGksc3ByZWFkLWEyYi1jbG9jayIpKQo+ ICsJCXZhbCB8PSBBRDI0MlhfUExMQ1RMX1NTTU9ERV9BQjsKPiArCWVsc2UgaWYgKG9mX3Byb3Bl cnR5X3JlYWRfYm9vbChucCwgImFkaSxzcHJlYWQtYTJiLWkycy1jbG9jayIpKQo+ICsJCXZhbCB8 PSBBRDI0MlhfUExMQ1RMX1NTTU9ERV9BQl9JMlM7Cj4gKwo+ICsJaWYgKG9mX3Byb3BlcnR5X3Jl YWRfYm9vbChucCwgImFkaSxzcHJlYWQtc3BlY3RydW0taGlnaCIpKQo+ICsJCXZhbCB8PSBBRDI0 MlhfUExMQ1RMX1NTREVQVEg7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKG5vZGUtPnJlZ21h cCwgQUQyNDJYX1BMTENUTCwgdmFsKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2Vycihu b2RlLT5kZXYsICJmYWlsZWQgdG8gd3JpdGUgUExMQ1RMIHJlZ2lzdGVyICVkXG4iLCByZXQpOwo+ ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJLyogSTJTIGdsb2JhbCBzZXR1cCAqLwo+ICsK PiArCW9mX3Byb3BlcnR5X3JlYWRfdTMyKG5wLCAiYWRpLHRkbS1tb2RlIiwgJm5vZGUtPnRkbV9t b2RlKTsKPiArCW9mX3Byb3BlcnR5X3JlYWRfdTMyKG5wLCAiYWRpLHRkbS1zbG90LXNpemUiLCAm bm9kZS0+dGRtX3Nsb3Rfc2l6ZSk7Cj4gKwo+ICsJcmV0ID0gYWQyNDJ4X3RkbW1vZGVfaW5kZXgo bm9kZS0+dGRtX21vZGUsIGZhbHNlKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2Vycihu b2RlLT5kZXYsICJpbnZhbGlkIFRETSBtb2RlICVkXG4iLCBub2RlLT50ZG1fbW9kZSk7Cj4gKwkJ cmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJdmFsID0gQUQyNDJYX0kyU0dDVExfVERNTU9E RShyZXQpOwo+ICsKPiArCWlmIChub2RlLT50ZG1fc2xvdF9zaXplID09IDE2KSB7Cj4gKwkJdmFs IHw9IEFEMjQyWF9JMlNHQ1RMX1RETVNTOwo+ICsJfSBlbHNlIGlmIChub2RlLT50ZG1fc2xvdF9z aXplICE9IDMyKSB7Cj4gKwkJZGV2X2Vycihub2RlLT5kZXYsICJpbnZhbGlkIFRETSBzbG90IHNp emUgJWRcbiIsCj4gKwkJCW5vZGUtPnRkbV9zbG90X3NpemUpOwo+ICsJCXJldHVybiAtRUlOVkFM Owo+ICsJfQo+ICsKPiArCWlmIChvZl9wcm9wZXJ0eV9yZWFkX2Jvb2wobnAsICJhZGksYWx0ZXJu YXRpbmctc3luYyIpKQo+ICsJCXZhbCB8PSBBRDI0MlhfSTJTR0NUTF9BTFQ7Cj4gKwo+ICsJaWYg KG9mX3Byb3BlcnR5X3JlYWRfYm9vbChucCwgImFkaSxlYXJseS1zeW5jIikpCj4gKwkJdmFsIHw9 IEFEMjQyWF9JMlNHQ1RMX0VBUkxZOwo+ICsKPiArCWlmIChvZl9wcm9wZXJ0eV9yZWFkX2Jvb2wo bnAsICJhZGksaW52ZXJ0LXN5bmMiKSkKPiArCQl2YWwgfD0gQUQyNDJYX0kyU0dDVExfSU5WOwo+ ICsKPiArCXJldCA9IHJlZ21hcF93cml0ZShub2RlLT5yZWdtYXAsIEFEMjQyWF9JMlNHQ1RMLCB2 YWwpOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtZmRfY2VsbCBhZDI0MnhfbWZkX2NlbGxz W10gPSB7Cj4gKwl7Cj4gKwkJLm9mX2NvbXBhdGlibGUJPSAiYWRpLGFkMjQyOHctaTJjIiwKPiAr CQkubmFtZQkJPSAiYWQyNDJ4LWkyYyIsCgpTd2FwIHRoZXNlIGFyb3VuZC4gIE9yIGJldHRlciBz dGlsbCwgdXNlIHRoZSBtYWNyb3MgZm91bmQgaW46CgogIGluY2x1ZGUvbGludXgvbWZkL2NvcmUu aAoKPiArCX0sCj4gKwl7Cj4gKwkJLm9mX2NvbXBhdGlibGUJPSAiYWRpLGFkMjQyOHctZ3BpbyIs Cj4gKwkJLm5hbWUJCT0gImFkMjQyeC1ncGlvIiwKPiArCX0sCj4gKwl7Cj4gKwkJLm9mX2NvbXBh dGlibGUJPSAiYWRpLGFkMjQyOHctY2xrIiwKPiArCQkubmFtZQkJPSAiYWQyNDJ4LWNsayIsCj4g Kwl9LAo+ICsJewo+ICsJCS5vZl9jb21wYXRpYmxlCT0gImFkaSxhZDI0Mjh3LWNvZGVjIiwKPiAr CQkubmFtZQkJPSAiYWQyNDJ4LWNvZGVjIiwKPiArCX0sCj4gK307Cj4gKwo+ICtpbnQgYWQyNDJ4 X25vZGVfYWRkX21mZF9jZWxscyhzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gK3sKPiArCXJldHVybiBk ZXZtX21mZF9hZGRfZGV2aWNlcyhkZXYsIFBMQVRGT1JNX0RFVklEX0FVVE8sCj4gKwkJCQkgICAg YWQyNDJ4X21mZF9jZWxscywKPiArCQkJCSAgICBBUlJBWV9TSVpFKGFkMjQyeF9tZmRfY2VsbHMp LAo+ICsJCQkJICAgIE5VTEwsIDAsIE5VTEwpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGFkMjQy eF9nZXRfc2xvdF9tYXNrKGNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAsCj4gKwkJCQljb25z dCBjaGFyICpwcm9wbmFtZSwgdTMyICptYXNrKQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgaSwgbnVt Owo+ICsJaW50IHJldCwgcHJvcGxlbjsKPiArCXUzMiBzbG90c1szMl07CgpZb3Ugc2hvdWxkIGRl ZmluZSAzMiBhcyB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2xvdHMgYXZhaWxhYmxlLCB0aGVuCnVz ZSBpdCBhZ2FpbiBmb3IgbW9zdCBvZiB0aGUgcmFuZG9tICczMidzIGJlbG93LgoKPiArCWlmICgh b2ZfZ2V0X3Byb3BlcnR5KG5wLCBwcm9wbmFtZSwgJnByb3BsZW4pKQo+ICsJCXJldHVybiAtRU5P RU5UOwoKVGhpcyB3aG9sZSBwaWVjZSBiZWNvbWVzIHNpbXBsZXIgaWYgeW91IHVzZToKCiBvZl9w cm9wZXJ0eV9yZWFkX3ZhcmlhYmxlX3UzMl9hcnJheSgpCgo+ICsJbnVtID0gcHJvcGxlbiAvIHNp emVvZih1MzIpOwo+ICsKPiArCWlmIChudW0gPiBBUlJBWV9TSVpFKHNsb3RzKSkKPiArCQlyZXR1 cm4gLUVPVkVSRkxPVzsKPiArCj4gKwlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShu cCwgcHJvcG5hbWUsIHNsb3RzLCBudW0pOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJcmV0dXJuIHJl dDsKPiArCj4gKwkqbWFzayA9IDA7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IG51bTsgaSsrKSB7 Cj4gKwkJaWYgKHNsb3RzW2ldID49IDMyKQo+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwkJ Km1hc2sgfD0gQklUKHNsb3RzW2ldKTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiAraW50IGFkMjQyeF9yZWFkX3Nsb3RfY29uZmlnKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJ ICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAsCj4gKwkJCSAgICBzdHJ1Y3QgYWQyNDJ4X3Nsb3Rf Y29uZmlnICpjb25maWcpCj4gK3sKPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqZG5fbnAsICp1cF9u cDsKPiArCWludCByZXQ7Cj4gKwo+ICsJZG5fbnAgPSBvZl9nZXRfY2hpbGRfYnlfbmFtZShucCwg ImRvd25zdHJlYW0iKTsKPiArCWlmICghZG5fbnApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5vIGRv d25zdHJlYW0gbm9kZVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJdXBf bnAgPSBvZl9nZXRfY2hpbGRfYnlfbmFtZShucCwgInVwc3RyZWFtIik7Cj4gKwlpZiAoIWRuX25w KSB7Cj4gKwkJZGV2X2VycihkZXYsICJubyB1cHN0cmVhbSBub2RlXG4iKTsKPiArCQlyZXQgPSAt RUlOVkFMOwo+ICsJCWdvdG8gZXJyX3B1dF9kbl9ub2RlOwo+ICsJfQo+ICsKPiArCXJldCA9IGFk MjQyeF9nZXRfc2xvdF9tYXNrKGRuX25wLCAicngtc2xvdHMiLCAmY29uZmlnLT5kbl9yeF9zbG90 cyk7Cj4gKwlpZiAocmV0IDwgMCAmJiByZXQgIT0gLUVOT0VOVCkgewoKSWYgeW91J3JlIGdvaW5n IHRvIGlnbm9yZSAtRU5PRU5ULCB3aHkgbm90IGp1c3QgcmV0dXJuIDA/Cgo+ICsJCWRldl9lcnIo ZGV2LCAiaW52YWxpZCBkb3duc3RyZWFtIHJ4LXNsb3RzIHByb3BlcnR5XG4iKTsKPiArCQlnb3Rv IGVycl9wdXRfbm9kZXM7Cj4gKwl9Cj4gKwo+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIoZG5fbnAs ICIjdHgtc2xvdHMiLCAmY29uZmlnLT5kbl9uX3R4X3Nsb3RzKTsKPiArCW9mX3Byb3BlcnR5X3Jl YWRfdTMyKGRuX25wLCAiI2ZvcndhcmQtc2xvdHMiLAo+ICsJCQkgICAgICZjb25maWctPmRuX25f Zm9yd2FyZF9zbG90cyk7Cj4gKwlpZiAoY29uZmlnLT5kbl9uX3R4X3Nsb3RzICsgY29uZmlnLT5k bl9uX2ZvcndhcmRfc2xvdHMgPj0gMzIpIHsKPiArCQlkZXZfZXJyKGRldiwgImludmFsaWQgZG93 bnN0cmVhbSB0eC1zbG90cyBwcm9wZXJ0eVxuIik7Cj4gKwkJZ290byBlcnJfcHV0X25vZGVzOwo+ ICsJfQo+ICsKPiArCgpTdXBlcmZsdW91cyAnXG4nLgoKPiArCXJldCA9IGFkMjQyeF9nZXRfc2xv dF9tYXNrKHVwX25wLCAicngtc2xvdHMiLCAmY29uZmlnLT51cF9yeF9zbG90cyk7Cj4gKwlpZiAo cmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiaW52YWxpZCB1cHN0cmVhbSByeC1zbG90cyBw cm9wZXJ0eVxuIik7Cj4gKwkJZ290byBlcnJfcHV0X25vZGVzOwo+ICsJfQo+ICsKPiArCW9mX3By b3BlcnR5X3JlYWRfdTMyKHVwX25wLCAiI3R4LXNsb3RzIiwgJmNvbmZpZy0+dXBfbl90eF9zbG90 cyk7Cj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMih1cF9ucCwgIiNmb3J3YXJkLXNsb3RzIiwKPiAr CQkJICAgICAmY29uZmlnLT51cF9uX2ZvcndhcmRfc2xvdHMpOwo+ICsJaWYgKGNvbmZpZy0+dXBf bl90eF9zbG90cyArIGNvbmZpZy0+dXBfbl9mb3J3YXJkX3Nsb3RzID49IDMyKSB7Cj4gKwkJZGV2 X2VycihkZXYsICJpbnZhbGlkIGRvd25zdHJlYW0gdHgtc2xvdHMgcHJvcGVydHlcbiIpOwo+ICsJ CWdvdG8gZXJyX3B1dF9ub2RlczsKPiArCX0KPiArCj4gK2Vycl9wdXRfbm9kZXM6Cj4gKwlvZl9u b2RlX3B1dCh1cF9ucCk7Cj4gK2Vycl9wdXRfZG5fbm9kZToKPiArCW9mX25vZGVfcHV0KGRuX25w KTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWZkL2Fk MjQyeC1zbGF2ZS5jIGIvZHJpdmVycy9tZmQvYWQyNDJ4LXNsYXZlLmMKPiBuZXcgZmlsZSBtb2Rl IDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uYWQyNTVkNjdhNWI2Cj4gLS0tIC9kZXYvbnVs bAo+ICsrKyBiL2RyaXZlcnMvbWZkL2FkMjQyeC1zbGF2ZS5jCj4gQEAgLTAsMCArMSwyMzQgQEAK PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsKPiArI2luY2x1 ZGUgPGxpbnV4L2Nsay5oPgo+ICsjaW5jbHVkZSA8bGludXgvY29tcGxldGlvbi5oPgo+ICsjaW5j bHVkZSA8bGludXgvZXJyLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPiArI2luY2x1ZGUg PGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21mZC9hZDI0MnguaD4KPiArI2luY2x1 ZGUgPGxpbnV4L21mZC9jb3JlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgo+ICsjaW5j bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPgo+ICsjaW5jbHVk ZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4K PiArCj4gK3N0cnVjdCBhZDI0Mnhfc2xhdmUgewo+ICsJc3RydWN0IGFkMjQyeF9ub2RlCQlub2Rl Owo+ICsJc3RydWN0IGFkMjQyeF9ub2RlCQkqbWFzdGVyOwo+ICsJc3RydWN0IGFkMjQyeF9zbG90 X2NvbmZpZwlzbG90X2NvbmZpZzsKPiArCXVuc2lnbmVkIGludAkJCXN5bmNfb2Zmc2V0Owo+ICt9 Owo+ICsKPiAraW50IGFkMjQyeF9zbGF2ZV9yZWFkKHN0cnVjdCBhZDI0MnhfaTJjX2J1cyAqYnVz LAo+ICsJCSAgICAgIHN0cnVjdCByZWdtYXAgKm1hc3Rlcl9yZWdtYXAsCj4gKwkJICAgICAgdWlu dDhfdCBub2RlX2lkLCB1aW50OF90IHJlZywgdW5zaWduZWQgaW50ICp2YWwpCj4gK3sKPiArCWlu dCByZXQ7Cj4gKwo+ICsJbXV0ZXhfbG9jaygmYnVzLT5tdXRleCk7Cj4gKwo+ICsJcmV0ID0gcmVn bWFwX3dyaXRlKG1hc3Rlcl9yZWdtYXAsIEFEMjQyWF9OT0RFQURSLCBub2RlX2lkKTsKPiArCWlm IChyZXQgPCAwKQo+ICsJCWdvdG8gZXJyX3VubG9jazsKPiArCj4gKwlyZXQgPSBpMmNfc21idXNf cmVhZF9ieXRlX2RhdGEoYnVzLT5jbGllbnQsIHJlZyk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQln b3RvIGVycl91bmxvY2s7Cj4gKwo+ICsJKnZhbCA9IHJldDsKPiArCXJldCA9IDA7Cj4gKwo+ICtl cnJfdW5sb2NrOgo+ICsJbXV0ZXhfdW5sb2NrKCZidXMtPm11dGV4KTsKPiArCj4gKwlyZXR1cm4g cmV0Owo+ICt9Cj4gK0VYUE9SVF9TWU1CT0xfR1BMKGFkMjQyeF9zbGF2ZV9yZWFkKTsKPiArCj4g K2ludCBhZDI0Mnhfc2xhdmVfd3JpdGUoc3RydWN0IGFkMjQyeF9pMmNfYnVzICpidXMsCj4gKwkJ ICAgICAgIHN0cnVjdCByZWdtYXAgKm1hc3Rlcl9yZWdtYXAsCj4gKwkJICAgICAgIHVpbnQ4X3Qg bm9kZV9pZCwgdWludDhfdCByZWcsIHVuc2lnbmVkIGludCB2YWwpCj4gK3sKPiArCWludCByZXQ7 Cj4gKwo+ICsJbXV0ZXhfbG9jaygmYnVzLT5tdXRleCk7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dy aXRlKG1hc3Rlcl9yZWdtYXAsIEFEMjQyWF9OT0RFQURSLCBub2RlX2lkKTsKPiArCWlmIChyZXQg PCAwKQo+ICsJCWdvdG8gZXJyX3VubG9jazsKPiArCj4gKwlyZXQgPSBpMmNfc21idXNfd3JpdGVf Ynl0ZV9kYXRhKGJ1cy0+Y2xpZW50LCByZWcsIHZhbCk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQln b3RvIGVycl91bmxvY2s7Cj4gKwo+ICsJcmV0ID0gMDsKPiArCj4gK2Vycl91bmxvY2s6Cj4gKwlt dXRleF91bmxvY2soJmJ1cy0+bXV0ZXgpOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArRVhQ T1JUX1NZTUJPTF9HUEwoYWQyNDJ4X3NsYXZlX3dyaXRlKTsKPiArCj4gK3N0YXRpYyBpbnQgYWQy NDJ4X3NsYXZlX3JlZ21hcF9yZWFkKHZvaWQgKmNvbnRleHQsIHVuc2lnbmVkIGludCByZWcsCj4g KwkJCQkgICAgdW5zaWduZWQgaW50ICp2YWwpCj4gK3sKPiArCXN0cnVjdCBhZDI0Mnhfc2xhdmUg KnNsYXZlID0gY29udGV4dDsKPiArCXN0cnVjdCBhZDI0MnhfaTJjX2J1cyAqYnVzID0gYWQyNDJ4 X21hc3Rlcl9nZXRfYnVzKHNsYXZlLT5ub2RlLm1hc3Rlcik7Cj4gKwlzdHJ1Y3QgYWQyNDJ4X25v ZGUgKm1ub2RlID0gYWQyNDJ4X21hc3Rlcl9nZXRfbm9kZShzbGF2ZS0+bm9kZS5tYXN0ZXIpOwo+ ICsKPiArCWlmIChyZWcgPiAweGZmKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXJldHVy biBhZDI0Mnhfc2xhdmVfcmVhZChidXMsIG1ub2RlLT5yZWdtYXAsIHNsYXZlLT5ub2RlLmlkLCBy ZWcsIHZhbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgYWQyNDJ4X3NsYXZlX3JlZ21hcF93cml0 ZSh2b2lkICpjb250ZXh0LCB1bnNpZ25lZCBpbnQgcmVnLAo+ICsJCQkJICAgICB1bnNpZ25lZCBp bnQgdmFsKQo+ICt7Cj4gKwlzdHJ1Y3QgYWQyNDJ4X3NsYXZlICpzbGF2ZSA9IGNvbnRleHQ7Cj4g KwlzdHJ1Y3QgYWQyNDJ4X2kyY19idXMgKmJ1cyA9IGFkMjQyeF9tYXN0ZXJfZ2V0X2J1cyhzbGF2 ZS0+bm9kZS5tYXN0ZXIpOwo+ICsJc3RydWN0IGFkMjQyeF9ub2RlICptbm9kZSA9IGFkMjQyeF9t YXN0ZXJfZ2V0X25vZGUoc2xhdmUtPm5vZGUubWFzdGVyKTsKPiArCj4gKwlpZiAodmFsID4gMHhm ZiB8fCByZWcgPiAweGZmKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXJldHVybiBhZDI0 Mnhfc2xhdmVfd3JpdGUoYnVzLCBtbm9kZS0+cmVnbWFwLCBzbGF2ZS0+bm9kZS5pZCwgcmVnLCB2 YWwpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9jb25maWcgYWQyNDJ4 X3JlZ21hcF9jb25maWcgPSB7Cj4gKwkucmVnX2JpdHMJPSA4LAo+ICsJLnZhbF9iaXRzCT0gOCwK PiArCS52b2xhdGlsZV9yZWcJPSBhZDI0MnhfaXNfdm9sYXRpbGVfcmVnLAo+ICsJLndyaXRlYWJs ZV9yZWcJPSBhZDI0MnhfaXNfd3JpdGVhYmxlX3JlZywKPiArCS5yZWdfcmVhZAk9IGFkMjQyeF9z bGF2ZV9yZWdtYXBfcmVhZCwKPiArCS5yZWdfd3JpdGUJPSBhZDI0Mnhfc2xhdmVfcmVnbWFwX3dy aXRlLAo+ICsJLm1heF9yZWdpc3Rlcgk9IEFEMjQyWF9NQVhfUkVHLAo+ICsJLmNhY2hlX3R5cGUJ PSBSRUdDQUNIRV9SQlRSRUUsCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IGFkMjQyeF9jYWxjX3N5 bmNfb2Zmc2V0KHVuc2lnbmVkIGludCB2YWwpCj4gK3sKPiArCWlmICh2YWwgPT0gMCkKPiArCQly ZXR1cm4gMDsKPiArCj4gKwlpZiAodmFsID4gMTI3KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCXJldHVybiAyNTYgLSB2YWw7CgpNb3JlIG1hZ2ljIG51bWJlcnMgdG8gZGVmaW5lLgoKPiAr fQo+ICsKPiArc3RhdGljIGludCBhZDI0Mnhfc2xhdmVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rl dmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKPiAr CXN0cnVjdCBhZDI0Mnhfc2xhdmUgKnNsYXZlOwo+ICsJc3RydWN0IGFkMjQyeF9ub2RlICptbm9k ZTsKPiArCXN0cnVjdCByZWdtYXAgKnJlZ21hcDsKPiArCXVuc2lnbmVkIGludCB2YWw7Cj4gKwlp bnQgaSwgcmV0Owo+ICsKPiArCXNsYXZlID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpzbGF2 ZSksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFzbGF2ZSkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiAr Cj4gKwlyZWdtYXAgPSBkZXZtX3JlZ21hcF9pbml0KGRldiwgTlVMTCwgc2xhdmUsICZhZDI0Mnhf cmVnbWFwX2NvbmZpZyk7Cj4gKwlpZiAoSVNfRVJSKHJlZ21hcCkpIHsKPiArCQlyZXQgPSBQVFJf RVJSKHJlZ21hcCk7Cj4gKwkJZGV2X2VycihkZXYsICJyZWdtYXAgaW5pdCBmYWlsZWQ6ICVkXG4i LCByZXQpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJb2ZfcHJvcGVydHlfcmVhZF91 MzIoZGV2LT5vZl9ub2RlLCAicmVnIiwgJnZhbCk7Cj4gKwlzbGF2ZS0+bm9kZS5pZCA9IHZhbDsK ClRoaXMgbG9va3MgbGlrZSBhbiBhYnVzZSBvZiB0aGUgJ3JlZycgcHJvcGVydHkuCgo+ICsJc2xh dmUtPm5vZGUuZGV2ID0gZGV2Owo+ICsJc2xhdmUtPm5vZGUucmVnbWFwID0gcmVnbWFwOwo+ICsK PiArCW1ub2RlID0gZGV2X2dldF9kcnZkYXRhKGRldi0+cGFyZW50KTsKCldoYXQgaXMgdGhlIHBh cmVudCBvZiB0aGUgc2xhdmU/CgooaXQncyBub3QgY2xlYXIgd2l0aG91dCBsb29raW5nIGF0IHRo ZSBEVCBJIGd1ZXNzKQoKPiArCXNsYXZlLT5ub2RlLm1hc3RlciA9IG1ub2RlLT5tYXN0ZXI7Cj4g Kwo+ICsJZGV2X3NldF9uYW1lKGRldiwgIiVzLWEyYi0lZCIsIGRldl9uYW1lKGRldi0+cGFyZW50 KSwgc2xhdmUtPm5vZGUuaWQpOwo+ICsJZGV2X3NldF9kcnZkYXRhKGRldiwgJnNsYXZlLT5ub2Rl KTsKPiArCj4gKwlyZXQgPSBhZDI0Mnhfbm9kZV9wcm9iZSgmc2xhdmUtPm5vZGUpOwo+ICsJaWYg KHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSBhZDI0MnhfcmVhZF9zbG90 X2NvbmZpZyhkZXYsIGRldi0+b2Zfbm9kZSwgJnNsYXZlLT5zbG90X2NvbmZpZyk7Cj4gKwlpZiAo cmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAic2xvdCBjb25maWcgaXMgaW52YWxpZDogJWRc biIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSByZWdtYXBfd3Jp dGUocmVnbWFwLCBBRDI0MlhfVVBTTE9UUywKPiArCQkJICAgc2xhdmUtPnNsb3RfY29uZmlnLnVw X25fZm9yd2FyZF9zbG90cyk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsK PiArCXJldCA9IHJlZ21hcF93cml0ZShyZWdtYXAsIEFEMjQyWF9ETlNMT1RTLAo+ICsJCQkgICBz bGF2ZS0+c2xvdF9jb25maWcuZG5fbl9mb3J3YXJkX3Nsb3RzKTsKPiArCWlmIChyZXQgPCAwKQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJY X0xVUFNMT1RTLAo+ICsJCQkgICBzbGF2ZS0+c2xvdF9jb25maWcudXBfbl90eF9zbG90cyk7Cj4g KwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9IHJlZ21hcF93cml0 ZShyZWdtYXAsIEFEMjQyWF9MRE5TTE9UUywKPiArCQkJICAgc2xhdmUtPnNsb3RfY29uZmlnLmRu X25fdHhfc2xvdHMgfAo+ICsJCQkgICBBRDI0MlhfTEROU0xPVFNfRE5NQVNLRU4pOwo+ICsJaWYg KHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgNDsgaSsr KSB7CgpXaHkgND8gIFBsZWFzZSBkZWZpbmUgaXQuCgo+ICsJCXJldCA9IHJlZ21hcF93cml0ZShy ZWdtYXAsIEFEMjQyWF9VUE1BU0soaSksCj4gKwkJCShzbGF2ZS0+c2xvdF9jb25maWcudXBfcnhf c2xvdHMgPj4gKGkgKiA4KSkgJiAweGZmKTsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJu IHJldDsKPiArCj4gKwkJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJYX0ROTUFTSyhp KSwKPiArCQkJKHNsYXZlLT5zbG90X2NvbmZpZy5kbl9yeF9zbG90cyA+PiAoaSAqIDgpKSAmIDB4 ZmYpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCW9m X3Byb3BlcnR5X3JlYWRfdTMyKGRldi0+b2Zfbm9kZSwgImFkaSxzeW5jLW9mZnNldCIsCj4gKwkJ CSAgICAgJnNsYXZlLT5zeW5jX29mZnNldCk7Cj4gKwo+ICsJcmV0ID0gYWQyNDJ4X2NhbGNfc3lu Y19vZmZzZXQoc2xhdmUtPnN5bmNfb2Zmc2V0KTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVy biByZXQ7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKHJlZ21hcCwgQUQyNDJYX1NZTkNPRkZT RVQsIHJldCk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9 IGFkMjQyeF9ub2RlX2FkZF9tZmRfY2VsbHMoZGV2KTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJ ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gYWRkIE1GRCBkZXZpY2VzICVkXG4iLCByZXQpOwo+ICsJ CXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBj b25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIGFkMjQyeF9zbGF2ZV9vZl9tYXRjaFtdID0gewo+ICsJ eyAuY29tcGF0aWJsZSA9ICJhZGksYWQyNDI4dy1zbGF2ZSIgfSwKPiArCXsgfQo+ICt9Owo+ICtN T0RVTEVfREVWSUNFX1RBQkxFKG9mLCBhZDI0Mnhfc2xhdmVfb2ZfbWF0Y2gpOwo+ICsKPiArc3Rh dGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgYWQyNDJ4X3NsYXZlX2RyaXZlciA9IHsKPiArCS5k cml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAiYWQyNDJ4LXNsYXZlIiwKPiArCQkub2ZfbWF0Y2hfdGFi bGUgPSBhZDI0Mnhfc2xhdmVfb2ZfbWF0Y2gsCj4gKwl9LAo+ICsJLnByb2JlID0gYWQyNDJ4X3Ns YXZlX3Byb2JlLAo+ICt9Owo+ICsKPiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihhZDI0Mnhfc2xh dmVfZHJpdmVyKTsKPiArCj4gK01PRFVMRV9ERVNDUklQVElPTigiQUQyNDJ4IHNsYXZlIG5vZGUg ZHJpdmVyIik7Cj4gK01PRFVMRV9BVVRIT1IoIkRhbmllbCBNYWNrIDxkYW5pZWxAem9ucXVlLm9y Zz4iKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+IGRpZmYgLS1naXQgYS9pbmNsdWRl L2xpbnV4L21mZC9hZDI0MnguaCBiL2luY2x1ZGUvbGludXgvbWZkL2FkMjQyeC5oCj4gbmV3IGZp bGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjAyYTE3NDgyNGY4NQo+IC0tLSAv ZGV2L251bGwKPiArKysgYi9pbmNsdWRlL2xpbnV4L21mZC9hZDI0MnguaAo+IEBAIC0wLDAgKzEs NDAwIEBACj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPiAr Cj4gKyNpZm5kZWYgX19MSU5VWF9NRkRfQUQyNDJYX0gKPiArI2RlZmluZSBfX0xJTlVYX01GRF9B RDI0MlhfSAo+ICsKPiArI2RlZmluZSBBRDI0MlhfQ0hJUAkJCTB4MDAKPiArI2RlZmluZSBBRDI0 MlhfTk9ERUFEUgkJCTB4MDEKPiArI2RlZmluZSBBRDI0MlhfTk9ERUFEUl9NQVNLCQkweDBmCj4g KyNkZWZpbmUgQUQyNDJYX05PREVBRFJfUEVSSQkJQklUKDUpCj4gKyNkZWZpbmUgQUQyNDJYX05P REVBRFJfQlJDU1QJCUJJVCg3KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfVkVORE9SCQkJMHgwMgo+ ICsjZGVmaW5lIEFEMjQyWF9QUk9EVUNUCQkJMHgwMwo+ICsjZGVmaW5lIEFEMjQyWF9WRVJTSU9O CQkJMHgwNAo+ICsKPiArI2RlZmluZSBBRDI0MlhfQ0FQQUJJTElUWQkJMHgwNQo+ICsjZGVmaW5l IEFEMjQyWF9DQVBBQklMSVRZX0kyQwkJQklUKDApCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9TV0NU TAkJCTB4MDkKPiArI2RlZmluZSBBRDI0MlhfU1dDVExfRU5TVwkJQklUKDApCj4gKyNkZWZpbmUg QUQyNDJYX1NXQ1RMX0RJQUdNT0RFCQlCSVQoMykKPiArI2RlZmluZSBBRDI0MlhfU1dDVExfTU9E RShYKQkJKCgoWCkgJiAzKSA8PCA0KQo+ICsjZGVmaW5lIEFEMjQyWF9TV0NUTF9NT0RFX01BU0sJ CSgzIDw8IDQpCj4gKyNkZWZpbmUgQUQyNDJYX1NXQ1RMX0RJU05YVAkJQklUKDYpCj4gKwo+ICsj ZGVmaW5lIEFEMjQyWF9CQ0ROU0xPVFMJCTB4MGEKPiArI2RlZmluZSBBRDI0MlhfQkNETlNMT1RT X01BU0sJCTB4M2YKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0xETlNMT1RTCQkJMHgwYgo+ICsjZGVm aW5lIEFEMjQyWF9MRE5TTE9UU19NQVNLCQkweDNmCj4gKyNkZWZpbmUgQUQyNDJYX0xETlNMT1RT X0ROTUFTS0VOCUJJVCg3KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfTFVQU0xPVFMJCQkweDBjCj4g KyNkZWZpbmUgQUQyNDJYX0xVUFNMT1RTX01BU0sJCTB4M2YKPiArCj4gKyNkZWZpbmUgQUQyNDJY X0ROU0xPVFMJCQkweDBkCj4gKyNkZWZpbmUgQUQyNDJYX0ROU0xPVFNfTUFTSwkJMHgzZgo+ICsK PiArI2RlZmluZSBBRDI0MlhfVVBTTE9UUwkJCTB4MGUKPiArI2RlZmluZSBBRDI0MlhfVVBTTE9U U19NQVNLCQkweDNmCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9SRVNQQ1lDUwkJCTB4MGYKPiArCj4g KyNkZWZpbmUgQUQyNDJYX1NMT1RGTVQJCQkweDEwCj4gKyNkZWZpbmUgQUQyNDJYX1NMT1RGTVRf RE5TSVpFKFgpCSgoKChYKSAtIDgpID4+IDIpICYgNykKPiArI2RlZmluZSBBRDI0MlhfU0xPVEZN VF9ETkZNVAkJQklUKDMpCj4gKyNkZWZpbmUgQUQyNDJYX1NMT1RGTVRfVVBTSVpFKFgpCSgoKCgo WCkgLSA4KSA+PiAyKSAmIDcpIDw8IDQpCj4gKyNkZWZpbmUgQUQyNDJYX1NMT1RGTVRfVVBGTVQJ CUJJVCg3KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfREFUQ1RMCQkJMHgxMQo+ICsjZGVmaW5lIEFE MjQyWF9EQVRDVExfRE5TCQlCSVQoMCkKPiArI2RlZmluZSBBRDI0MlhfREFUQ1RMX1VQUwkJQklU KDEpCj4gKyNkZWZpbmUgQUQyNDJYX0RBVENUTF9FTkRTTklGRgkJQklUKDUpCj4gKyNkZWZpbmUg QUQyNDJYX0RBVENUTF9TVEFOREJZCQlCSVQoNykKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0NPTlRS T0wJCQkweDEyCj4gKyNkZWZpbmUgQUQyNDJYX0NPTlRST0xfTkVXU1RSQ1QJCUJJVCgwKQo+ICsj ZGVmaW5lIEFEMjQyWF9DT05UUk9MX0VORERTQwkJQklUKDEpCj4gKyNkZWZpbmUgQUQyNDJYX0NP TlRST0xfU09GVFJTVAkJQklUKDIpCj4gKyNkZWZpbmUgQUQyNDJYX0NPTlRST0xfU1dCWVAJCUJJ VCgzKQo+ICsjZGVmaW5lIEFEMjQyWF9DT05UUk9MX1hDVlJCSU5WCQlCSVQoNCkKPiArI2RlZmlu ZSBBRDI0MlhfQ09OVFJPTF9NU1RSCQlCSVQoNykKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0RJU0NW UlkJCQkweDEzCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9TV1NUQVQJCQkweDE0Cj4gKyNkZWZpbmUg QUQyNDJYX1NXU1RBVF9GSU4JCUJJVCgwKQo+ICsjZGVmaW5lIEFEMjQyWF9TV1NUQVRfRkFVTFQJ CUJJVCgxKQo+ICsjZGVmaW5lIEFEMjQyWF9TV1NUQVRfRkFVTFRDT0RFKFgpCSgoKFgpICYgMHg3 KSA+PiA0KQo+ICsjZGVmaW5lIEFEMjQyWF9TV1NUQVRfRkFVTFRfTkxPQwlCSVQoNykKPiArCj4g KyNkZWZpbmUgQUQyNDJYX0lOVFNUQVQJCQkweDE1Cj4gKyNkZWZpbmUgQUQyNDJYX0lOVFNUQVRf SVJRCQlCSVQoMCkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0lOVFNSQwkJCTB4MTYKPiArI2RlZmlu ZSBBRDI0MlhfSU5UU1JDX0lOT0RFCQkweDBmCj4gKyNkZWZpbmUgQUQyNDJYX0lOVFNSQ19TTFZJ TlQJCUJJVCg2KQo+ICsjZGVmaW5lIEFEMjQyWF9JTlRTUkNfTVNUSU5UCQlCSVQoNykKPiArCj4g KyNkZWZpbmUgQUQyNDJYX0lOVFRZUEUJCQkweDE3Cj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9JTlRU WVBFX0RTQ0RPTkUJCTI0Cj4gKyNkZWZpbmUgQUQyNDJYX0lOVFRZUEVfTVNUUl9SVU5OSU5HCTI1 NQo+ICsKPiArI2RlZmluZSBBRDI0MlhfSU5UUE5EMAkJCTB4MTgKPiArI2RlZmluZSBBRDI0Mlhf SU5UUEROMF9IRENOVEVSUgkJQklUKDApCj4gKyNkZWZpbmUgQUQyNDJYX0lOVFBETjBfRERFUlIJ CUJJVCgxKQo+ICsjZGVmaW5lIEFEMjQyWF9JTlRQRE4wX0NSQ0VSUgkJQklUKDIpCj4gKyNkZWZp bmUgQUQyNDJYX0lOVFBETjBfRFBFUlIJCUJJVCgzKQo+ICsjZGVmaW5lIEFEMjQyWF9JTlRQRE4w X1BXUkVSUgkJQklUKDQpCj4gKyNkZWZpbmUgQUQyNDJYX0lOVFBETjBfQkVDT1ZGCQlCSVQoNSkK PiArI2RlZmluZSBBRDI0MlhfSU5UUEROMF9TUkZFUlIJCUJJVCg2KQo+ICsjZGVmaW5lIEFEMjQy WF9JTlRQRE4wX1NSRkNSQ0VSUglCSVQoNykKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0lOVFBORDEJ CQkweDE5Cj4gKyNkZWZpbmUgQUQyNDJYX0lOVFBORDFfSU9QTkQoWCkJCUJJVChYKQo+ICsKPiAr I2RlZmluZSBBRDI0MlhfSU5UUE5EMgkJCTB4MWEKPiArI2RlZmluZSBBRDI0MlhfSU5UUE5EMl9E U0NET05FCQlCSVQoMCkKPiArI2RlZmluZSBBRDI0MlhfSU5UUE5EMl9JMkNFUlIJCUJJVCgxKQo+ ICsjZGVmaW5lIEFEMjQyWF9JTlRQTkQyX0lDUkNFUlIJCUJJVCgyKQo+ICsjZGVmaW5lIEFEMjQy WF9JTlRQTkQyX1NMVklSUQkJQklUKDMpCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9JTlRNU0swCQkJ MHgxYgo+ICsjZGVmaW5lIEFEMjQyWF9JTlRNU0swX0hDRUlFTgkJQklUKDApCj4gKyNkZWZpbmUg QUQyNDJYX0lOVE1TSzBfRERFSUVOCQlCSVQoMSkKPiArI2RlZmluZSBBRDI0MlhfSU5UTVNLMF9D UkNFSUVOCQlCSVQoMikKPiArI2RlZmluZSBBRDI0MlhfSU5UTVNLMF9EUEVJRU4JCUJJVCgzKQo+ ICsjZGVmaW5lIEFEMjQyWF9JTlRNU0swX1BXUkVJRU4JCUJJVCg0KQo+ICsjZGVmaW5lIEFEMjQy WF9JTlRNU0swX0JFQ0lFTgkJQklUKDUpCj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzBfU1JGRUlF TgkJQklUKDYpCj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzBfU1JGQ1JDRUlFTglCSVQoNykKPiAr Cj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzEJCQkweDFjCj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1T SzFfSU9JUlFFTihYKQlCSVQoWCkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzIJCQkweDFk Cj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzJfRFNDRElFTgkJQklUKDApCj4gKyNkZWZpbmUgQUQy NDJYX0lOVE1TSzJfSTJDRUlFTgkJQklUKDEpCj4gKyNkZWZpbmUgQUQyNDJYX0lOVE1TSzJfSUNS Q0VJRU4JCUJJVCgyKQo+ICsjZGVmaW5lIEFEMjQyWF9JTlRNU0syX1NMVklSUUVOCQlCSVQoMykK PiArCj4gKyNkZWZpbmUgQUQyNDJYX0JFQ0NUTAkJCTB4MWUKPiArI2RlZmluZSBBRDI0MlhfQkVD Q1RMX0VOSERDTlQJCUJJVCgwKQo+ICsjZGVmaW5lIEFEMjQyWF9CRUNDVExfRU5ERAkJQklUKDEp Cj4gKyNkZWZpbmUgQUQyNDJYX0JFQ0NUTF9FTkNSQwkJQklUKDIpCj4gKyNkZWZpbmUgQUQyNDJY X0JFQ0NUTF9FTkRQCQlCSVQoMykKPiArI2RlZmluZSBBRDI0MlhfQkVDQ1RMX0VOSUNSQwkJQklU KDQpCj4gKyNkZWZpbmUgQUQyNDJYX0JFQ0NUTF9USFJFU0hMRChYKQkoKFgpID4+IDUpCj4gKwo+ ICsjZGVmaW5lIEFEMjQyWF9CRUNOVAkJCTB4MWYKPiArCj4gKyNkZWZpbmUgQUQyNDJYX1RFU1RN T0RFCQkJMHgyMAo+ICsjZGVmaW5lIEFEMjQyWF9URVNUTU9ERV9QUkJTVVAJCUJJVCgwKQo+ICsj ZGVmaW5lIEFEMjQyWF9URVNUTU9ERV9QUkJTRE4JCUJJVCgxKQo+ICsjZGVmaW5lIEFEMjQyWF9U RVNUTU9ERV9QUkJTTjJOCQlCSVQoMikKPiArI2RlZmluZSBBRDI0MlhfVEVTVE1PREVfUlhEUFRI KFgpCSgoWCkgPj4gNCkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0VSUkNOVDAJCQkweDIxCj4gKyNk ZWZpbmUgQUQyNDJYX0VSUkNOVDEJCQkweDIyCj4gKyNkZWZpbmUgQUQyNDJYX0VSUkNOVDIJCQkw eDIzCj4gKyNkZWZpbmUgQUQyNDJYX0VSUkNOVDMJCQkweDI0Cj4gKwo+ICsjZGVmaW5lIEFEMjQy WF9OT0RFCQkJMHgyOQo+ICsjZGVmaW5lIEFEMjQyWF9OT0RFX01BU0sJCTB4Zgo+ICsjZGVmaW5l IEFEMjQyWF9OT0RFX0RJU0NWRAkJQklUKDUpCj4gKyNkZWZpbmUgQUQyNDJYX05PREVfTkxBU1QJ CUJJVCg2KQo+ICsjZGVmaW5lIEFEMjQyWF9OT0RFX0xBU1QJCUJJVCg3KQo+ICsKPiArI2RlZmlu ZSBBRDI0MlhfRElTQ1NUQVQJCQkweDJiCj4gKyNkZWZpbmUgQUQyNDJYX0RJU0NTVEFUX0ROT0RF KFgpCSgoWCkgJiAweGYpCj4gKyNkZWZpbmUgQUQyNDJYX0RJU0NTVEFUX0RTQ0FDVAkJQklUKDcp Cj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9UWEFDVEwJCQkweDJlCj4gKyNkZWZpbmUgQUQyNDJYX1RY QUNUTF9MRVZFTF9ISUdICTAKPiArI2RlZmluZSBBRDI0MlhfVFhBQ1RMX0xFVkVMX01FRElVTQky Cj4gKyNkZWZpbmUgQUQyNDJYX1RYQUNUTF9MRVZFTF9MT1cJCTMKPiArCj4gKyNkZWZpbmUgQUQy NDJYX1RYQkNUTAkJCTB4MzAKPiArI2RlZmluZSBBRDI0MlhfVFhCQ1RMX0xFVkVMX0hJR0gJMAo+ ICsjZGVmaW5lIEFEMjQyWF9UWEJDVExfTEVWRUxfTUVESVVNCTIKPiArI2RlZmluZSBBRDI0Mlhf VFhCQ1RMX0xFVkVMX0xPVwkJMwo+ICsKPiArI2RlZmluZSBBRDI0MlhfTElOVFRZUEUJCQkweDNl Cj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9JMkNDRkcJCQkweDNmCj4gKyNkZWZpbmUgQUQyNDJYX0ky Q0NGR19EQVRBUkFURQkJQklUKDApCj4gKyNkZWZpbmUgQUQyNDJYX0kyQ0NGR19FQUNLCQlCSVQo MSkKPiArI2RlZmluZSBBRDI0MlhfSTJDQ0ZHX0ZSQU1FUkFURQkJQklUKDIpCj4gKwo+ICsjZGVm aW5lIEFEMjQyWF9QTExDVEwJCQkweDQwCj4gKyNkZWZpbmUgQUQyNDJYX1BMTENUTF9TU0ZSRVEo WCkJCSgoWCkgJiAzKQo+ICsjZGVmaW5lIEFEMjQyWF9QTExDVExfU1NERVBUSAkJQklUKDIpCj4g KyNkZWZpbmUgQUQyNDJYX1BMTENUTF9TU01PREVfQUIJCSgxIDw8IDYpCj4gKyNkZWZpbmUgQUQy NDJYX1BMTENUTF9TU01PREVfQUJfSTJTCSgyIDw8IDYpCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9J MlNHQ1RMCQkJMHg0MQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNHQ1RMX1RETU1PREUoWCkJKChYKSAm IDMpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU0dDVExfUlhPTkRUWDEJCUJJVCgzKQo+ICsjZGVmaW5l IEFEMjQyWF9JMlNHQ1RMX1RETVNTCQlCSVQoNCkKPiArI2RlZmluZSBBRDI0MlhfSTJTR0NUTF9B TFQJCUJJVCg1KQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNHQ1RMX0VBUkxZCQlCSVQoNikKPiArI2Rl ZmluZSBBRDI0MlhfSTJTR0NUTF9JTlYJCUJJVCg3KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfSTJT Q1RMCQkJMHg0Mgo+ICsjZGVmaW5lIEFEMjQyWF9JMlNDVExfVFgwRU4JCUJJVCgwKQo+ICsjZGVm aW5lIEFEMjQyWF9JMlNDVExfVFgxRU4JCUJJVCgxKQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNDVExf VFgyUElOVEwJCUJJVCgyKQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNDVExfVFhCQ0xLSU5WCQlCSVQo MykKPiArI2RlZmluZSBBRDI0MlhfSTJTQ1RMX1JYMEVOCQlCSVQoNCkKPiArI2RlZmluZSBBRDI0 MlhfSTJTQ1RMX1JYMUVOCQlCSVQoNSkKPiArI2RlZmluZSBBRDI0MlhfSTJTQ1RMX1JYMlBJTlRM CQlCSVQoNikKPiArI2RlZmluZSBBRDI0MlhfSTJTQ1RMX1JYQkNMS0lOVgkJQklUKDcpCj4gKwo+ ICsjZGVmaW5lIEFEMjQyWF9JMlNSQVRFCQkJMHg0Mwo+ICsjZGVmaW5lIEFEMjQyWF9JMlNSQVRF X0kyU1JBVEUoWCkJKChYKSAmIDMpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1JBVEVfQkNMS1JBVEUo WCkJKCgoWCkgPDwgMykgJiAzKQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNSQVRFX1JFRFVDRQkJQklU KDYpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1JBVEVfU0hBUkUJCUJJVCg3KQo+ICsKPiArI2RlZmlu ZSBBRDI0MlhfSTJTVFhPRkZTRVQJCTB4NDQKPiArI2RlZmluZSBBRDI0MlhfSTJTVFhPRkZTRVRf VkFSKFgpCSgoWCkgJiAweDNmKQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNUWE9GRlNFVF9UU0FGVEVS CUJJVCg2KQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNUWE9GRlNFVF9UU0JFRk9SRQlCSVQoNykKPiAr Cj4gKyNkZWZpbmUgQUQyNDJYXzJTUlhPRkZTRVQJCTB4NDUKPiArI2RlZmluZSBBRDI0MlhfSTJT UlhPRkZTRVRfVkFSKFgpCSgoWCkgJiAweDNmKQo+ICsKPiArI2RlZmluZSBBRDI0MlhfU1lOQ09G RlNFVAkJMHg0Ngo+ICsKPiArI2RlZmluZSBBRDI0MlhfUERNQ1RMCQkJMHg0Nwo+ICsjZGVmaW5l IEFEMjQyWF9QRE1DVExfUERNMEVOCQlCSVQoMCkKPiArI2RlZmluZSBBRDI0MlhfUERNQ1RMX1BE TTBTTE9UUwkJQklUKDEpCj4gKyNkZWZpbmUgQUQyNDJYX1BETUNUTF9QRE0xRU4JCUJJVCgyKQo+ ICsjZGVmaW5lIEFEMjQyWF9QRE1DVExfUERNMVNMT1RTCQlCSVQoMykKPiArI2RlZmluZSBBRDI0 MlhfUERNQ1RMX0hQRkVOCQlCSVQoNCkKPiArI2RlZmluZSBBRDI0MlhfUERNQ1RMX1BETVJBVEUo WCkJKCgoWCkgJiAzKSA8PCA1KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfRVJSTUdNVAkJCTB4NDgK PiArI2RlZmluZSBBRDI0MlhfRVJSTUdNVF9FUlJMU0IJCUJJVCgwKQo+ICsjZGVmaW5lIEFEMjQy WF9FUlJNR01UX0VSUlNJRwkJQklUKDEpCj4gKyNkZWZpbmUgQUQyNDJYX0VSUk1HTVRfRVJSU0xP VAkJQklUKDIpCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9HUElPREFUCQkJMHg0YQo+ICsjZGVmaW5l IEFEMjQyWF9HUElPREFUX1NFVAkJMHg0Ygo+ICsjZGVmaW5lIEFEMjQyWF9HUElPREFUX0NMUgkJ MHg0Ywo+ICsjZGVmaW5lIEFEMjQyWF9HUElPT0VOCQkJMHg0ZAo+ICsjZGVmaW5lIEFEMjQyWF9H UElPSUVOCQkJMHg0ZQo+ICsjZGVmaW5lIEFEMjQyWF9HUElPREFUX0lOCQkweDRmCj4gKyNkZWZp bmUgQUQyNDJYX1BJTlRFTgkJCTB4NTAKPiArI2RlZmluZSBBRDI0MlhfUElOVElOVgkJCTB4NTEK PiArCj4gKyNkZWZpbmUgQUQyNDJYX1BJTkNGRwkJCTB4NTIKPiArI2RlZmluZSBBRDI0MlhfUElO Q0ZHX0RSVlNUUgkJQklUKDApCj4gKyNkZWZpbmUgQUQyNDJYX1BJTkNGR19JUlFJTlYJCUJJVCg0 KQo+ICsjZGVmaW5lIEFEMjQyWF9QSU5DRkdfSVJRVFMJCUJJVCg1KQo+ICsKPiArI2RlZmluZSBB RDI0MlhfSTJTVEVTVAkJCTB4NTMKPiArI2RlZmluZSBBRDI0MlhfSTJTVEVTVF9QQVRUUk4yVFgJ QklUKDApCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1RFU1RfTE9PUEJLMlRYCUJJVCgxKQo+ICsjZGVm aW5lIEFEMjQyWF9JMlNURVNUX1JYMkxPT1BCSwlCSVQoMikKPiArI2RlZmluZSBBRDI0MlhfSTJT VEVTVF9TRUxSWDEJCUJJVCgzKQo+ICsjZGVmaW5lIEFEMjQyWF9JMlNURVNUX0JVU0xPT1BCSwlC SVQoNCkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX1JBSVNFCQkJMHg1NAo+ICsKPiArI2RlZmluZSBB RDI0MlhfR0VORVJSCQkJMHg1NQo+ICsjZGVmaW5lIEFEMjQyWF9HRU5FUlJfR0VOSENFUlIJCUJJ VCgwKQo+ICsjZGVmaW5lIEFEMjQyWF9HRU5FUlJfR0VORERFUlIJCUJJVCgxKQo+ICsjZGVmaW5l IEFEMjQyWF9HRU5FUlJfR0VOQ1JDRVJSCQlCSVQoMikKPiArI2RlZmluZSBBRDI0MlhfR0VORVJS X0dFTkRQRVJSCQlCSVQoMykKPiArI2RlZmluZSBBRDI0MlhfR0VORVJSX0dFTklDUkNFUlIJQklU KDQpCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9JMlNSUkFURQkJCTB4NTYKPiArI2RlZmluZSBBRDI0 MlhfSTJTUlJBVEVfUlJESVYoWCkJKChYKSAmIDB4M2YpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1JS QVRFX1JCVVMJCUJJVCg3KQo+ICsKPiArI2RlZmluZSBBRDI0MlhfSTJTUlJDVEwJCQkweDU3Cj4g KyNkZWZpbmUgQUQyNDJYX0kyU1JSQ1RMX0VOVkxTQgkJQklUKDApCj4gKyNkZWZpbmUgQUQyNDJY X0kyU1JSQ1RMX0VOWEJJVAkJQklUKDEpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1JSQ1RMX0VOU1RS QgkJQklUKDQpCj4gKyNkZWZpbmUgQUQyNDJYX0kyU1JSQ1RMX1NUUkJESVIJCUJJVCg1KQo+ICsK PiArI2RlZmluZSBBRDI0MlhfSTJTUlJTT0ZGUwkJMHg1OAo+ICsKPiArI2RlZmluZSBBRDI0Mlhf Q0xLMUNGRwkJCTB4NTkKPiArI2RlZmluZSBBRDI0MlhfQ0xLMkNGRwkJCTB4NWEKPiArI2RlZmlu ZSBBRDI0MlhfQ0xLQ0ZHX0RJVihYKQkJKChYKSAmIDB4ZikKPiArI2RlZmluZSBBRDI0MlhfQ0xL Q0ZHX0RJVk1TSwkJMHhmCj4gKyNkZWZpbmUgQUQyNDJYX0NMS0NGR19QRElWMzIJCUJJVCg1KQo+ ICsjZGVmaW5lIEFEMjQyWF9DTEtDRkdfSU5WCQlCSVQoNikKPiArI2RlZmluZSBBRDI0MlhfQ0xL Q0ZHX0VOCQlCSVQoNykKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0JNTUNGRwkJCTB4NWIKPiArI2Rl ZmluZSBBRDI0MlhfQk1NQ0ZHX0JNTUVOCQlCSVQoMCkKPiArI2RlZmluZSBBRDI0MlhfQk1NQ0ZH X0JNTVJYRU4JCUJJVCgxKQo+ICsjZGVmaW5lIEFEMjQyWF9CTU1DRkdfQk1NTkRTQwkJQklUKDIp Cj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9QRE1DVEwyCQkJMHg1ZAo+ICsjZGVmaW5lIEFEMjQyWF9Q RE1DVEwyX0RFU1RfQTJCCQkwCj4gKyNkZWZpbmUgQUQyNDJYX1BETUNUTDJfREVTVF9EVFgJCTEK PiArI2RlZmluZSBBRDI0MlhfUERNQ1RMMl9ERVNUX0EyQl9EVFgJMgo+ICsKPiArI2RlZmluZSBB RDI0MlhfVVBNQVNLKFgpCQkoMHg2MCArICgoWCkgJiAzKSkKPiArCj4gKyNkZWZpbmUgQUQyNDJY X1VQT0ZGU0VUCQkJMHg2NAo+ICsjZGVmaW5lIEFEMjQyWF9VUE9GRlNFVF9WQUwoWCkJCSgoWCkg JiAweDFmKQo+ICsKPiArI2RlZmluZSBBRDI0MlhfRE5NQVNLKFgpCQkoMHg2NSArICgoWCkgJSAz KSkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0ROT0ZGU0VUCQkJMHg2OQo+ICsjZGVmaW5lIEFEMjQy WF9ETk9GRlNFVF9WQUwoWCkJCSgoWCkgJiAweDFmKQo+ICsKPiArI2RlZmluZSBBRDI0MlhfQ0hJ UElEKFgpCQkoKFgpICsgMHg2YSkKPiArCj4gKyNkZWZpbmUgQUQyNDJYX0dQSU9ERU4JCQkweDgw Cj4gKyNkZWZpbmUgQUQyNDJYX0dQSU9EX01TSyhYKQkJKChYKSArIDB4ODEpCj4gKwo+ICsjZGVm aW5lIEFEMjQyWF9HUElPRERBVAkJCTB4ODkKPiArI2RlZmluZSBBRDI0MlhfR1BJT0RJTlYJCQkw eDhhCj4gKwo+ICsjZGVmaW5lIEFEMjQyWF9NQVhfUkVHCQkJMHg5Ygo+ICsKPiArc3RhdGljIGlu bGluZSBib29sIGFkMjQyeF9pc192b2xhdGlsZV9yZWcoc3RydWN0IGRldmljZSAqZGV2LCB1bnNp Z25lZCBpbnQgcmVnKQo+ICt7Cj4gKwlzd2l0Y2ggKHJlZykgewo+ICsJY2FzZSBBRDI0MlhfVkVO RE9SOgo+ICsJY2FzZSBBRDI0MlhfUFJPRFVDVDoKPiArCWNhc2UgQUQyNDJYX1ZFUlNJT046Cj4g KwljYXNlIEFEMjQyWF9DQVBBQklMSVRZOgo+ICsJY2FzZSBBRDI0MlhfU1dTVEFUOgo+ICsJY2Fz ZSBBRDI0MlhfSU5UU1RBVDoKPiArCWNhc2UgQUQyNDJYX0lOVFNSQzoKPiArCWNhc2UgQUQyNDJY X0lOVFRZUEU6Cj4gKwljYXNlIEFEMjQyWF9JTlRQTkQwOgo+ICsJY2FzZSBBRDI0MlhfSU5UUE5E MToKPiArCWNhc2UgQUQyNDJYX0lOVFBORDI6Cj4gKwljYXNlIEFEMjQyWF9CRUNOVDoKPiArCWNh c2UgQUQyNDJYX0VSUkNOVDA6Cj4gKwljYXNlIEFEMjQyWF9FUlJDTlQxOgo+ICsJY2FzZSBBRDI0 MlhfRVJSQ05UMjoKPiArCWNhc2UgQUQyNDJYX0VSUkNOVDM6Cj4gKwljYXNlIEFEMjQyWF9OT0RF Ogo+ICsJY2FzZSBBRDI0MlhfRElTQ1NUQVQ6Cj4gKwljYXNlIEFEMjQyWF9MSU5UVFlQRToKPiAr CWNhc2UgQUQyNDJYX0dQSU9EQVQ6Cj4gKwljYXNlIEFEMjQyWF9HUElPREFUX0lOOgo+ICsJCXJl dHVybiB0cnVlOwo+ICsJZGVmYXVsdDoKPiArCQlyZXR1cm4gZmFsc2U7Cj4gKwl9Cj4gK30KPiAr Cj4gK3N0YXRpYyBpbmxpbmUgYm9vbCBhZDI0MnhfaXNfd3JpdGVhYmxlX3JlZyhzdHJ1Y3QgZGV2 aWNlICpkZXYsIHVuc2lnbmVkIGludCByZWcpCj4gK3sKPiArCS8qIFdyaXRlLXRvLWNsZWFuIHJl Z2lzdGVycyAqLwo+ICsJc3dpdGNoIChyZWcpIHsKPiArCWNhc2UgQUQyNDJYX0lOVFBORDA6Cj4g KwljYXNlIEFEMjQyWF9JTlRQTkQxOgo+ICsJY2FzZSBBRDI0MlhfSU5UUE5EMjoKPiArCWNhc2Ug QUQyNDJYX0JFQ05UOgo+ICsJCXJldHVybiB0cnVlOwo+ICsJZGVmYXVsdDoKPiArCQlyZXR1cm4g IWFkMjQyeF9pc192b2xhdGlsZV9yZWcoZGV2LCByZWcpOwo+ICsJfQo+ICt9Cj4gKwo+ICsjZGVm aW5lIEFEMjQyWF9NQVNURVJfSUQgMHhmZgo+ICsKPiArc3RydWN0IGFkMjQyeF9tYXN0ZXI7Cj4g Kwo+ICtzdHJ1Y3QgYWQyNDJ4X2kyY19idXMgewo+ICsJc3RydWN0IGkyY19jbGllbnQJKmNsaWVu dDsKPiArCXN0cnVjdCBtdXRleAkJbXV0ZXg7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgYWQyNDJ4X25v ZGUgewo+ICsJc3RydWN0IGRldmljZQkJKmRldjsKPiArCXN0cnVjdCByZWdtYXAJCSpyZWdtYXA7 Cj4gKwlzdHJ1Y3QgYWQyNDJ4X21hc3RlcgkqbWFzdGVyOwo+ICsJdW5zaWduZWQgaW50CQl0ZG1f bW9kZTsKPiArCXVuc2lnbmVkIGludAkJdGRtX3Nsb3Rfc2l6ZTsKPiArCXVpbnQ4X3QJCQlpZDsK PiArCXVpbnQ4X3QJCQljYXBzOwo+ICt9Owo+ICsKPiArc3RydWN0IGFkMjQyeF9zbG90X2NvbmZp ZyB7Cj4gKwl1bnNpZ25lZCBpbnQgZG5fcnhfc2xvdHM7Cj4gKwl1bnNpZ25lZCBpbnQgZG5fbl90 eF9zbG90czsKPiArCXVuc2lnbmVkIGludCBkbl9uX2ZvcndhcmRfc2xvdHM7Cj4gKwl1bnNpZ25l ZCBpbnQgdXBfcnhfc2xvdHM7Cj4gKwl1bnNpZ25lZCBpbnQgdXBfbl90eF9zbG90czsKPiArCXVu c2lnbmVkIGludCB1cF9uX2ZvcndhcmRfc2xvdHM7Cj4gK307Cj4gKwo+ICtpbnQgYWQyNDJ4X3Jl YWRfc2xvdF9jb25maWcoc3RydWN0IGRldmljZSAqZGV2LAo+ICsJCQkgICAgc3RydWN0IGRldmlj ZV9ub2RlICpucCwKPiArCQkJICAgIHN0cnVjdCBhZDI0Mnhfc2xvdF9jb25maWcgKmNvbmZpZyk7 Cj4gKwo+ICtzdGF0aWMgaW5saW5lIGJvb2wgYWQyNDJ4X25vZGVfaXNfbWFzdGVyKHN0cnVjdCBh ZDI0Mnhfbm9kZSAqbm9kZSkKPiArewo+ICsJcmV0dXJuIG5vZGUtPmlkID09IEFEMjQyWF9NQVNU RVJfSUQ7Cj4gK30KPiArCj4gK2ludCBhZDI0Mnhfbm9kZV9wcm9iZShzdHJ1Y3QgYWQyNDJ4X25v ZGUgKm5vZGUpOwo+ICtpbnQgYWQyNDJ4X25vZGVfYWRkX21mZF9jZWxscyhzdHJ1Y3QgZGV2aWNl ICpkZXYpOwo+ICsKPiArc3RydWN0IGFkMjQyeF9ub2RlICphZDI0MnhfbWFzdGVyX2dldF9ub2Rl KHN0cnVjdCBhZDI0MnhfbWFzdGVyICptYXN0ZXIpOwo+ICtzdHJ1Y3QgYWQyNDJ4X2kyY19idXMg KmFkMjQyeF9tYXN0ZXJfZ2V0X2J1cyhzdHJ1Y3QgYWQyNDJ4X21hc3RlciAqbWFzdGVyKTsKPiAr Y29uc3QgY2hhciAqYWQyNDJ4X21hc3Rlcl9nZXRfY2xrX25hbWUoc3RydWN0IGFkMjQyeF9tYXN0 ZXIgKm1hc3Rlcik7Cj4gK3Vuc2lnbmVkIGludCBhZDI0MnhfbWFzdGVyX2dldF9jbGtfcmF0ZShz dHJ1Y3QgYWQyNDJ4X21hc3RlciAqbWFzdGVyKTsKPiArCj4gK2ludCBhZDI0Mnhfc2xhdmVfcmVh ZChzdHJ1Y3QgYWQyNDJ4X2kyY19idXMgKmJ1cywKPiArCQkgICAgICBzdHJ1Y3QgcmVnbWFwICpt YXN0ZXJfcmVnbWFwLAo+ICsJCSAgICAgIHVpbnQ4X3Qgbm9kZV9pZCwgdWludDhfdCByZWcsIHVu c2lnbmVkIGludCAqdmFsKTsKPiAraW50IGFkMjQyeF9zbGF2ZV93cml0ZShzdHJ1Y3QgYWQyNDJ4 X2kyY19idXMgKmJ1cywKPiArCQkgICAgICAgc3RydWN0IHJlZ21hcCAqbWFzdGVyX3JlZ21hcCwK PiArCQkgICAgICAgdWludDhfdCBub2RlX2lkLCB1aW50OF90IHJlZywgdW5zaWduZWQgaW50IHZh bCk7Cj4gKwo+ICsjZW5kaWYKCi0tIApMZWUgSm9uZXMgW+adjueQvOaWr10KTGluYXJvIFNlcnZp Y2VzIFRlY2huaWNhbCBMZWFkCkxpbmFyby5vcmcg4pSCIE9wZW4gc291cmNlIHNvZnR3YXJlIGZv ciBBUk0gU29DcwpGb2xsb3cgTGluYXJvOiBGYWNlYm9vayB8IFR3aXR0ZXIgfCBCbG9nCl9fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkFsc2EtZGV2ZWwgbWFp bGluZyBsaXN0CkFsc2EtZGV2ZWxAYWxzYS1wcm9qZWN0Lm9yZwpodHRwczovL21haWxtYW4uYWxz YS1wcm9qZWN0Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL2Fsc2EtZGV2ZWwK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.4 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ACE8FC43603 for ; Tue, 17 Dec 2019 13:39:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5EC21206B7 for ; Tue, 17 Dec 2019 13:39:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Xjvpsk0R" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726164AbfLQNj6 (ORCPT ); Tue, 17 Dec 2019 08:39:58 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:53213 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728345AbfLQNj5 (ORCPT ); Tue, 17 Dec 2019 08:39:57 -0500 Received: by mail-wm1-f67.google.com with SMTP id p9so2974696wmc.2 for ; Tue, 17 Dec 2019 05:39:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=IFZR7yFfjCaJ5Zyd28wmKFHJJ/uVBiofrkGTbX0qZ+4=; b=Xjvpsk0Rut7XusBTv1UAB4fzGBImRbEixw95u7oUKkag4bvoy73xc6FZYbixAspz0K iax8Qu9XI2XGtGSfPAQqzd+pM9HDhxq4yR9fXDO+G0+JBlgO0b3Keo/fCo6tBG+eP5nh NvwXv/5UPRer8b73CkXGQXJu+t3EpwkQxUmm8L+maMS9hHcinefthMibV4Cku5w9s4e/ IIf/lypkUKA82uPTyyWfKC11371ruqD7yg9p7MavGKLulUMcB9DiXH4lLIMBsB3w5gK5 RplbDF8dCX8T8HaEZ41WO8lqh4FMBOUv0R/eCnFNMoqBoW0++nm9sTuTWF2yOSj5gG47 RD+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=IFZR7yFfjCaJ5Zyd28wmKFHJJ/uVBiofrkGTbX0qZ+4=; b=NVQzQT59Vh2RtJmHPI/FkHa2iBXSMvQoFTOJknBwhBf2DJQiX5p5DGKPL3w2CuH1tv l7C1qHoFtt39jB4bsD1MRYtP1WKahBCqZZ/XDigzOo51csdUnMpgRtwmSSqH4+tq4md+ RGPWsxZ3SAmmYZV36BmKp87v7LLtX24Xq449ZxKbMzWuldaCwTPk7fvmbygv6BBlFoTD U62qP2kSX8ZemGaKUi55WI0+KFfNHQMfenMtzUJlZQr2joKZvcDLNYL8WfTYvZtrLE8D GFQptGZXGO/99LCh5sYv6OGws/nnO70xTV/BtsjJWO+JKd5RWpsRLY+395QREP9WOP0I xsKw== X-Gm-Message-State: APjAAAVngqXmC+E3Zq94gYKWjEioBLyYWvO0+0gsBnFHmga5IjxYDHgi /jprDtHrFGvU8Erct3xp2nI8SVqW2mM= X-Google-Smtp-Source: APXvYqxJTewRU195IS242gKYuHK+XJLt8HGH8G88T/2+mC0xM987A3hj6SntcX86H3haWFgyBaAv/A== X-Received: by 2002:a05:600c:2283:: with SMTP id 3mr5743027wmf.100.1576589993375; Tue, 17 Dec 2019 05:39:53 -0800 (PST) Received: from dell ([2.27.35.132]) by smtp.gmail.com with ESMTPSA id o7sm2946632wmh.11.2019.12.17.05.39.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Dec 2019 05:39:52 -0800 (PST) Date: Tue, 17 Dec 2019 13:39:52 +0000 From: Lee Jones To: Daniel Mack Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org, alsa-devel@alsa-project.org, devicetree@vger.kernel.org, linux-clk@vger.kernel.org, mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, broonie@kernel.org, lars@metafoo.de, pascal.huerst@gmail.com Subject: Re: [PATCH 06/10] mfd: Add core driver for AD242x A2B transceivers Message-ID: <20191217133952.GJ18955@dell> References: <20191209183511.3576038-1-daniel@zonque.org> <20191209183511.3576038-8-daniel@zonque.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20191209183511.3576038-8-daniel@zonque.org> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org On Mon, 09 Dec 2019, Daniel Mack wrote: > The core driver for these devices is split into several parts. > > The master node driver is an I2C client. It is responsible for > bringing up the bus topology and discovering the slave nodes. > This process requries some knowlegde of the slave node configuration > to program the bus timings correctly, so the master drivers walks > the tree of nodes in the devicetree. The slave driver handles platform > devices that are instantiated by the master node driver after > discovery has finished. > > Master nodes expose two addresses on the I2C bus, one (referred to as > 'BASE' in the datasheet) for accessing registers on the transceiver > node itself, and one (referred to as 'BUS') for accessing remote > registers, either on the remote transceiver itself, or on I2C hardware > connected to that remote transceiver, which then acts as a remote I2C > bus master. > > In order to allow MFD sub-devices to be registered as children of > either the master or any slave node, the details on how to access the > registers are hidden behind a regmap config. A pointer to the regmap > is then exposed in the struct shared with the sub-devices. > > The ad242x-bus driver is a simple proxy that occupies the BUS I2C > address and which is referred to through a devicetree handle by the > master driver. > > For the discovery process, the driver has to wait for an interrupt > to occur. In case no interrupt is configured in DT, the driver falls > back to interrupt polling. After the discovery phase is completed, > interrupts are only needed for error handling and GPIO handling, > both of which is not currenty implemented. > > Code common to both the master and the slave driver lives in > 'ad242x-node.c'. > > Signed-off-by: Daniel Mack > > mfd ? > --- > drivers/mfd/Kconfig | 11 + > drivers/mfd/Makefile | 1 + > drivers/mfd/ad242x-bus.c | 42 +++ > drivers/mfd/ad242x-master.c | 611 ++++++++++++++++++++++++++++++++++++ > drivers/mfd/ad242x-node.c | 262 ++++++++++++++++ > drivers/mfd/ad242x-slave.c | 234 ++++++++++++++ > include/linux/mfd/ad242x.h | 400 +++++++++++++++++++++++ This device, or at least the way it's been coded is batty! It's going to need a lot of massaging before being accepted. Let's start with a quick (it's taken 2 hours already!) glance. See below ... > 7 files changed, 1561 insertions(+) > create mode 100644 drivers/mfd/ad242x-bus.c > create mode 100644 drivers/mfd/ad242x-master.c > create mode 100644 drivers/mfd/ad242x-node.c > create mode 100644 drivers/mfd/ad242x-slave.c > create mode 100644 include/linux/mfd/ad242x.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 420900852166..727a35053d8c 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -99,6 +99,17 @@ config PMIC_ADP5520 > individual components like LCD backlight, LEDs, GPIOs and Kepad > under the corresponding menus. > > +config MFD_AD242X > + bool "Analog Devices AD242x A2B support" > + select MFD_CORE > + select REGMAP_I2C > + depends on I2C=y && OF > + help > + If you say yes here, you get support for devices from the AD242x > + familiy. This driver provides common support for accessing the > + devices, additional drivers must be enabled in order to use the > + functionality of the devices. > + > config MFD_AAT2870_CORE > bool "AnalogicTech AAT2870" > select MFD_CORE > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index aed99f08739f..2361c676f6c8 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -203,6 +203,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o > obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o > obj-$(CONFIG_MFD_TPS65090) += tps65090.o > obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o > +obj-$(CONFIG_MFD_AD242X) += ad242x-master.o ad242x-slave.o ad242x-bus.o ad242x-node.o > obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o > obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o > obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o > diff --git a/drivers/mfd/ad242x-bus.c b/drivers/mfd/ad242x-bus.c > new file mode 100644 > index 000000000000..6660e13ce43d > --- /dev/null > +++ b/drivers/mfd/ad242x-bus.c > @@ -0,0 +1,42 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#include > +#include > +#include > +#include > +#include > + > +static int ad242x_bus_i2c_probe(struct i2c_client *i2c, > + const struct i2c_device_id *id) > +{ > + dev_set_drvdata(&i2c->dev, i2c); > + i2c_set_clientdata(i2c, &i2c->dev); Please explain to me what you think is happening here. > + return 0; > +} What does this driver do? Seems kinda pointless? > +static const struct of_device_id ad242x_bus_of_match[] = { > + { .compatible = "adi,ad2428w-bus" }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, ad242x_bus_of_match); > + > +static const struct i2c_device_id ad242x_bus_i2c_id[] = { > + { "ad242x_bus", 0 }, > + { }, > +}; > +MODULE_DEVICE_TABLE(i2c, ad242x_bus_i2c_id); This table cam be removed if you use probe_new. > +static struct i2c_driver ad242x_bus_i2c_driver = { > + .driver = { > + .name = "ad242x-bus", > + .of_match_table = ad242x_bus_of_match, > + }, > + .probe = ad242x_bus_i2c_probe, > + .id_table = ad242x_bus_i2c_id, > +}; > + > +module_i2c_driver(ad242x_bus_i2c_driver); > + > +MODULE_DESCRIPTION("AD242x bus driver"); > +MODULE_AUTHOR("Daniel Mack "); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/mfd/ad242x-master.c b/drivers/mfd/ad242x-master.c > new file mode 100644 > index 000000000000..1b0bf90442a2 > --- /dev/null > +++ b/drivers/mfd/ad242x-master.c > @@ -0,0 +1,611 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct ad242x_master { > + struct ad242x_node node; > + struct clk *sync_clk; > + struct completion run_completion; > + struct completion discover_completion; > + struct ad242x_i2c_bus bus; > + unsigned int up_slot_size; > + unsigned int dn_slot_size; > + bool up_slot_alt_fmt; > + bool dn_slot_alt_fmt; > + unsigned int sync_clk_rate; > + int irq; > + u8 response_cycles; > +}; > +struct ad242x_node *ad242x_master_get_node(struct ad242x_master *master) > +{ > + return &master->node; > +} > +EXPORT_SYMBOL_GPL(ad242x_master_get_node); > + > +struct ad242x_i2c_bus *ad242x_master_get_bus(struct ad242x_master *master) > +{ > + return &master->bus; > +} > +EXPORT_SYMBOL_GPL(ad242x_master_get_bus); > + > +const char *ad242x_master_get_clk_name(struct ad242x_master *master) > +{ > + return __clk_get_name(master->sync_clk); > +} > +EXPORT_SYMBOL_GPL(ad242x_master_get_clk_name); > + > +unsigned int ad242x_master_get_clk_rate(struct ad242x_master *master) > +{ > + return master->sync_clk_rate; > +} > +EXPORT_SYMBOL_GPL(ad242x_master_get_clk_rate); All of these functions provide abstraction for the sake of abstraction. They should be removed and replaced with the code contained within them. > +static int ad242x_read_one_irq(struct ad242x_master *master) > +{ > + struct regmap *regmap = master->node.regmap; > + struct device *dev = master->node.dev; > + unsigned int val, inttype; > + int ret; > + > + ret = regmap_read(regmap, AD242X_INTSTAT, &val); > + if (ret < 0) { > + dev_err(dev, "unable to read INTSTAT register: %d\n", ret); Users do not care about registers. "Failed to obtain interrupt status" > + return ret; > + } > + > + if (!(val & AD242X_INTSTAT_IRQ)) > + return -ENOENT; What happened here? No interrupts fired? IRQ_NONE would be better than "No such file or directory". > + ret = regmap_read(regmap, AD242X_INTTYPE, &inttype); > + if (ret < 0) { > + dev_err(dev, "unable to read INTTYPE register: %d\n", ret); Same for all log messages throughout this patch-set. > + return ret; > + } > + > + ret = regmap_read(regmap, AD242X_INTSRC, &val); > + if (ret < 0) { > + dev_err(dev, "unable to read INTSRC register: %d\n", ret); > + return ret; > + } What does this prove? Why aren't you doing anything with the value? > + ret = regmap_read(regmap, AD242X_INTPND0, &val); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_INTPND0, val); > + if (ret < 0) > + return ret; > + > + ret = regmap_read(regmap, AD242X_INTPND1, &val); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_INTPND1, val); > + if (ret < 0) > + return ret; What does writing back the value do? Comments please. > + if (val & AD242X_INTSRC_MSTINT) { > + ret = regmap_read(regmap, AD242X_INTPND2, &val); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_INTPND2, val); > + if (ret < 0) > + return ret; > + } > + > + dev_err(dev, "%s() inttype: 0x%02x\n", __func__, inttype); No debugging type 'func's please. What makes this an error? > + switch (inttype) { > + case AD242X_INTTYPE_DSCDONE: > + complete(&master->discover_completion); > + break; > + case AD242X_INTTYPE_MSTR_RUNNING: > + complete(&master->run_completion); > + break; > + default: > + dev_info(dev, "Unhandled interrupt type 0x%02x\n", inttype); > + } > + > + return 0; > +} > + > +static int ad242x_read_irqs(struct ad242x_master *master) > +{ > + int ret; > + bool first = true; > + > + while (true) { > + ret = ad242x_read_one_irq(master); > + if (ret < 0) > + return ret; > + if (ret == -ENOENT) > + return first ? ret : 0; > + > + first = false; > + } > +} > + > +static irqreturn_t ad242x_handle_irq(int irq, void *devid) > +{ > + struct ad242x_master *master = devid; > + int ret; > + > + ret = ad242x_read_irqs(master); > + if (ret == -ENOENT) > + return IRQ_NONE; > + > + return IRQ_HANDLED; > +} > + > +static int ad242x_wait_for_irq(struct ad242x_master *master, > + struct completion *completion, > + unsigned int timeout) > +{ > + int ret; > + > + if (master->irq > 0) { > + ret = wait_for_completion_timeout(completion, > + msecs_to_jiffies(timeout)); > + } else { > + usleep_range(timeout * 1000, timeout * 1500); > + ad242x_read_irqs(master); > + ret = completion_done(completion); > + } What are the semantics of this function. Comments please. > + return ret == 0 ? -ETIMEDOUT : 0; > +} > + > +/* See Table 3-2 in the datasheet */ Do you provide a link to the datasheet anywhere? All I can find is a 1 page overview. Please provide a description to what you're doing *here*. > +static unsigned int ad242x_bus_bits(unsigned int slot_size, bool alt_fmt) > +{ > + int alt_bits[8] = { 0, 13, 17, 21, 30, 0, 39, 0 }; > + int idx = AD242X_SLOTFMT_DNSIZE(slot_size); > + > + return alt_fmt ? alt_bits[idx] : slot_size + 1; > +} > + > +/* See Table 9-1 in the datasheet */ It's okay to reference the datasheet, but tell us what you're doing here as well. > +static unsigned int ad242x_master_respoffs(struct ad242x_node *node) > +{ > + if (node->tdm_mode == 2 && node->tdm_slot_size == 16) > + return 238; > + > + if ((node->tdm_mode == 2 && node->tdm_slot_size == 32) || > + (node->tdm_mode == 4 && node->tdm_slot_size == 16)) > + return 245; > + > + return 248; No magic numbers please. You need to define them. > +} > + > +static int ad242x_discover(struct ad242x_master *master, > + struct device_node *nodes_np) > +{ > + struct regmap *regmap = master->node.regmap; > + struct device *dev = master->node.dev; > + struct device_node *child_np; > + unsigned int val, n = 0, i, respoffs, respcycs; > + unsigned int respcycs_up_min = UINT_MAX; > + unsigned int respcycs_dn_max = 0; What are these? > + unsigned int master_up_slots = 0; > + unsigned int master_dn_slots = 0; > + bool up_enabled = false, dn_enabled = false; > + uint8_t slave_control = 0; > + int ret; > + > + respoffs = ad242x_master_respoffs(&master->node); > + > + for_each_available_child_of_node(nodes_np, child_np) { What are we discovering here? Child devices, or something else? > + unsigned int dnslot_activity, upslot_activity; > + unsigned int slave_dn_slots, slave_up_slots; > + unsigned int respcycs_dn, respcycs_up; > + struct ad242x_slot_config slot_config; > + > + ret = ad242x_read_slot_config(dev, child_np, &slot_config); > + if (ret < 0) { > + dev_err(dev, "slot config of slave %d is invalid\n", n); > + return ret; > + } What is a 'slot' defined as? > + /* See section 3-18 in the datasheet */ Give us a quick explanation. > + slave_dn_slots = max_t(int, slot_config.dn_n_forward_slots, > + fls(slot_config.dn_rx_slots)); > + slave_up_slots = max_t(int, slot_config.up_n_forward_slots, > + fls(slot_config.up_rx_slots)); > + > + if (n == 0) { > + master_up_slots = slave_up_slots; > + master_dn_slots = slave_dn_slots; > + } > + > + /* See Appendix B in the datasheet */ Give us a quick explanation. > + dnslot_activity = slave_dn_slots * > + ad242x_bus_bits(master->dn_slot_size, > + master->dn_slot_alt_fmt); > + upslot_activity = slave_up_slots * > + ad242x_bus_bits(master->up_slot_size, > + master->up_slot_alt_fmt); > + > + respcycs_dn = DIV_ROUND_UP(64 + dnslot_activity, 4) + 4*n + 2; Spaces around the '*'. If it's not clear, use brackets. > + respcycs_up = respoffs - > + (DIV_ROUND_UP(64 + upslot_activity, 4) + 1); No idea what's going on here. You need to define these magic numbers to make it clear. > + if (respcycs_dn > respcycs_dn_max) > + respcycs_dn_max = respcycs_dn; > + > + if (respcycs_up < respcycs_up_min) > + respcycs_up_min = respcycs_up; > + > + if (slave_dn_slots > 0) > + dn_enabled = true; > + > + if (slave_up_slots > 0) > + up_enabled = true; > + > + n++; > + } > + > + if (n == 0) { > + dev_err(dev, "No child nodes specified\n"); > + return -EINVAL; > + } > + > + if (of_property_read_bool(dev->of_node, "adi,invert-xcvr-b")) { > + ret = regmap_update_bits(regmap, AD242X_CONTROL, > + AD242X_CONTROL_XCVRBINV, > + AD242X_CONTROL_XCVRBINV); > + if (ret < 0) > + return ret; > + > + slave_control = AD242X_CONTROL_XCVRBINV; > + } > + > + if (respcycs_dn_max > respcycs_up_min) { > + dev_err(dev, "Unsupported bus topology\n"); > + return -EINVAL; > + } > + > + respcycs = (respcycs_dn_max + respcycs_up_min) / 2; > + ret = regmap_write(regmap, AD242X_RESPCYCS, respcycs); > + if (ret < 0) > + return ret; Comments please. In fact, comments throughout please. Anything that isn't absolutely crystal clear should have at least a little one liner to clarify what is being calculated/set. > + ret = regmap_update_bits(regmap, AD242X_CONTROL, > + AD242X_CONTROL_NEWSTRCT, > + AD242X_CONTROL_NEWSTRCT); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_SWCTL, AD242X_SWCTL_ENSW); > + if (ret < 0) > + return ret; > + > + for (i = 0; i < n; i++) { > + ret = regmap_write(regmap, AD242X_DISCVRY, respcycs - (4*i)); Spaces. What is 4? > + if (ret < 0) > + return ret; > + > + ret = ad242x_wait_for_irq(master, > + &master->discover_completion, 35); Define magic numbers throughout. > + if (ret < 0) { > + dev_err(dev, "Discovery of node %d timed out\n", i); > + return ret; > + } > + > + val = AD242X_SWCTL_MODE(2) | AD242X_SWCTL_ENSW; > + > + if (i == 0) > + ret = regmap_write(regmap, AD242X_SWCTL, val); > + else > + ret = ad242x_slave_write(&master->bus, regmap, i, > + AD242X_SWCTL, val); > + > + if (ret < 0) > + return ret; > + > + dev_info(dev, "Node %d discovered\n", i); > + > + /* Last node? */ > + if (i == n - 1) > + break; > + > + ret = ad242x_slave_write(&master->bus, regmap, i, > + AD242X_INTMSK2, > + AD242X_INTMSK2_DSCDIEN); > + if (ret < 0) > + return ret; > + > + ret = ad242x_slave_write(&master->bus, regmap, i, > + AD242X_CONTROL, slave_control); > + if (ret < 0) > + return ret; > + > + ret = ad242x_slave_write(&master->bus, regmap, i, > + AD242X_SWCTL, AD242X_SWCTL_ENSW); > + if (ret < 0) > + return ret; > + > + reinit_completion(&master->discover_completion); > + } > + > + ret = regmap_write(regmap, AD242X_DNSLOTS, master_dn_slots); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_UPSLOTS, master_up_slots); > + if (ret < 0) > + return ret; > + > + val = 0; > + if (dn_enabled) > + val |= AD242X_DATCTL_DNS; > + > + if (up_enabled) > + val |= AD242X_DATCTL_UPS; > + > + ret = regmap_write(regmap, AD242X_DATCTL, val); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > +static int ad242x_init_irq(struct ad242x_master *master) > +{ > + struct regmap *regmap = master->node.regmap; > + struct device *dev = master->node.dev; > + int ret; > + > + if (master->irq > 0) { > + ret = devm_request_threaded_irq(dev, master->irq, NULL, > + ad242x_handle_irq, IRQF_ONESHOT, > + dev_name(dev), master); > + if (ret < 0) > + return ret; > + } > + > + ret = regmap_write(regmap, AD242X_INTMSK0, > + AD242X_INTMSK0_SRFEIEN | AD242X_INTMSK0_BECIEN | > + AD242X_INTMSK0_PWREIEN | AD242X_INTMSK0_CRCEIEN | > + AD242X_INTMSK0_DDEIEN | AD242X_INTMSK0_HCEIEN); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_INTMSK2, > + AD242X_INTMSK2_DSCDIEN | AD242X_INTMSK2_SLVIRQEN); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > +static const struct regmap_config ad242x_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .volatile_reg = ad242x_is_volatile_reg, > + .writeable_reg = ad242x_is_writeable_reg, > + .max_register = AD242X_MAX_REG, > + .cache_type = REGCACHE_RBTREE, > +}; > + > +static int ad242x_master_probe(struct i2c_client *i2c, > + const struct i2c_device_id *id) > +{ > + struct device_node *bus_np, *nodes_np, *np; > + struct device *busdev, *dev = &i2c->dev; > + struct ad242x_master *master; > + struct regmap *regmap; > + unsigned int val; > + int ret; > + > + nodes_np = of_get_child_by_name(dev->of_node, "nodes"); > + if (!nodes_np) { > + dev_err(dev, "no 'nodes' property given\n"); > + return -EINVAL; > + } > + > + bus_np = of_parse_phandle(dev->of_node, "adi,a2b-bus", 0); > + if (!bus_np) { > + dev_err(dev, "no 'adi,a2b-bus' handle specified for master node\n"); > + return -EINVAL; > + } > + > + busdev = bus_find_device_by_of_node(&i2c_bus_type, bus_np); > + if (!busdev) { > + dev_err(dev, "'adi,a2b-bus' handle invalid\n"); > + return -EINVAL; > + } > + > + master = devm_kzalloc(dev, sizeof(struct ad242x_master), GFP_KERNEL); sizeof(*master) > + if (!master) > + return -ENOMEM; > + > + mutex_init(&master->bus.mutex); > + init_completion(&master->run_completion); > + init_completion(&master->discover_completion); > + dev_set_drvdata(dev, &master->node); > + i2c_set_clientdata(i2c, master); What do you think is happening here? > + regmap = devm_regmap_init_i2c(i2c, &ad242x_regmap_config); > + if (IS_ERR(regmap)) { > + ret = PTR_ERR(regmap); > + dev_err(dev, "regmap init failed: %d\n", ret); "initialisation" Or even better "Failed to initialise I2C Regmap" > + return ret; > + } > + > + master->bus.client = to_i2c_client(busdev); What does 'bus' do in this context? > + master->node.regmap = regmap; > + master->node.dev = dev; > + master->node.master = master; > + master->node.id = AD242X_MASTER_ID; > + master->irq = i2c->irq; > + > + master->sync_clk = devm_clk_get(dev, "sync"); > + if (IS_ERR(master->sync_clk)) { > + ret = PTR_ERR(master->sync_clk); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "failed to get sync clk: %d\n", ret); > + > + return ret; > + } > + > + if (of_property_read_u32(dev->of_node, "clock-frequency", > + &master->sync_clk_rate)) { > + ret = clk_set_rate(master->sync_clk, master->sync_clk_rate); > + if (ret < 0) { > + dev_err(dev, "Cannot set sync clock rate: %d\n", ret); > + return ret; > + } > + } > + > + master->sync_clk_rate = clk_get_rate(master->sync_clk); > + if (master->sync_clk_rate != 44100 && master->sync_clk_rate != 48000) { Please define these magic numbers. Something descriptive that tells us what the different clock speeds do. > + dev_err(dev, "SYNC clock rate %d is invalid\n", > + master->sync_clk_rate); > + return -EINVAL; > + } > + > + ret = clk_prepare_enable(master->sync_clk); > + if (ret < 0) { > + dev_err(dev, "failed to enable sync clk: %d\n", ret); > + return ret; > + } > + > + /* Master node setup */ > + > + ret = regmap_write(regmap, AD242X_CONTROL, > + AD242X_CONTROL_MSTR | AD242X_CONTROL_SOFTRST); > + if (ret < 0) > + return ret; > + > + ret = ad242x_wait_for_irq(master, &master->run_completion, 10); > + if (ret < 0) { > + dev_err(dev, "timeout waiting for PLL sync: %d\n", ret); > + return ret; > + } > + > + ret = regmap_update_bits(regmap, AD242X_CONTROL, > + AD242X_CONTROL_SOFTRST, 0); > + if (ret < 0) > + return ret; > + > + ret = ad242x_node_probe(&master->node); > + if (ret < 0) > + return ret; > + > + ret = ad242x_init_irq(master); > + if (ret < 0) { > + dev_err(dev, "Unable to set up IRQ: %d", ret); > + return ret; > + } > + > + /* Slot format setup */ > + > + of_property_read_u32(dev->of_node, "adi,upstream-slot-size", &val); > + if (val < 8 || val > 32 || (val % 4 != 0)) { > + dev_err(dev, "invalid upstream-slot-size %d\n", val); > + return -EINVAL; > + } > + master->up_slot_size = val; > + > + of_property_read_u32(dev->of_node, "adi,downstream-slot-size", &val); > + if (val < 8 || val > 32 || (val % 4 != 0)) { > + dev_err(dev, "invalid downstream-slot-size %d\n", val); > + return -EINVAL; > + } > + master->dn_slot_size = val; > + > + master->dn_slot_alt_fmt = > + of_property_read_bool(dev->of_node, > + "adi,alternate-downstream-slot-format"); > + master->up_slot_alt_fmt = > + of_property_read_bool(dev->of_node, > + "adi,alternate-upstream-slot-format"); Obviously this all needs to be run past the DT maintainer(s). > + val = AD242X_SLOTFMT_DNSIZE(master->dn_slot_size) | > + AD242X_SLOTFMT_UPSIZE(master->up_slot_size); > + > + if (master->dn_slot_alt_fmt) > + val |= AD242X_SLOTFMT_DNFMT; > + > + if (master->up_slot_alt_fmt) > + val |= AD242X_SLOTFMT_UPFMT; > + > + ret = regmap_write(regmap, AD242X_SLOTFMT, val); > + if (ret < 0) > + return ret; > + > + /* Node discovery and MFD setup */ > + > + ret = ad242x_discover(master, nodes_np); > + if (ret < 0) { > + dev_err(dev, "error discovering nodes: %d\n", ret); > + return ret; > + } > + > + ret = ad242x_node_add_mfd_cells(dev); Why is this called twice with the same children? > + if (ret < 0) { > + dev_err(dev, "failed to add MFD devices %d\n", ret); > + return ret; > + } > + > + /* Register platform devices for nodes */ > + > + for_each_available_child_of_node(nodes_np, np) > + of_platform_device_create(np, NULL, dev); What are you doing here? Either use OF to register all child devices OR use MFD, not a mixture of both. > + of_node_put(nodes_np); > + > + return 0; > +} > + > +static int ad242x_master_remove(struct i2c_client *i2c) > +{ > + struct ad242x_master *master = i2c_get_clientdata(i2c); > + > + if (master->sync_clk) > + clk_disable_unprepare(master->sync_clk); > + > + return 0; > +} > + > +static const struct of_device_id ad242x_master_of_match[] = { > + { .compatible = "adi,ad2428w-master" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, ad242x_master_of_match); > + > +static const struct i2c_device_id ad242x_master_i2c_id[] = { > + {"ad242x-master", 0}, > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, ad242x_master_i2c_id); If you one the OF match table, you don't need this empty I2C table. Grep for probe_new. > +static struct i2c_driver ad242x_master_i2c_driver = { > + .driver = { > + .name = "ad242x-master", > + .of_match_table = ad242x_master_of_match, > + }, > + .probe = ad242x_master_probe, > + .remove = ad242x_master_remove, > + .id_table = ad242x_master_i2c_id, > +}; > + Remove this line. > +module_i2c_driver(ad242x_master_i2c_driver); > + > +MODULE_DESCRIPTION("AD242x master master driver"); Typo. > +MODULE_AUTHOR("Daniel Mack "); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/mfd/ad242x-node.c b/drivers/mfd/ad242x-node.c > new file mode 100644 > index 000000000000..f9db689380a7 > --- /dev/null > +++ b/drivers/mfd/ad242x-node.c > @@ -0,0 +1,262 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* See Table 7-43 in the datasheet */ More information please. > +static int ad242x_tdmmode_index(unsigned int mode, bool slave) > +{ > + switch (mode) { > + case 2: > + return 0; > + case 4: > + return 1; > + case 8: > + return 2; > + case 12: > + return slave ? -EINVAL : 3; > + case 16: > + return 4; > + case 20: > + return slave ? -EINVAL : 5; > + case 24: > + return slave ? -EINVAL : 6; > + case 32: > + return 7; > + default: > + return -EINVAL; > + } > +} > + > +int ad242x_node_probe(struct ad242x_node *node) > +{ > + struct device_node *np = node->dev->of_node; > + unsigned int val; > + int ret; > + > + ret = regmap_read(node->regmap, AD242X_VENDOR, &val); > + if (ret < 0) { > + dev_err(node->dev, "failed to read VENDOR register %d\n", ret); Please re-write all of your kernel log messages to be user friendly. > + return ret; > + } > + > + if (val != 0xad) { No magic numbers - please define them all. > + dev_err(node->dev, "bogus value 0x%02x in VENDOR register\n", > + val); > + return -ENODEV; > + } > + > + ret = regmap_read(node->regmap, AD242X_PRODUCT, &val); > + if (ret < 0) { > + dev_err(node->dev, "failed to read PRODUCT register %d\n", > + ret); > + return ret; > + } > + > + if (val != 0x28) { > + dev_err(node->dev, "bogus value 0x%02x in PRODUCT register\n", > + val); > + return -ENODEV; > + } > + > + ret = regmap_read(node->regmap, AD242X_VERSION, &val); > + if (ret < 0) { > + dev_err(node->dev, "failed to read VERSION register %d\n", ret); > + return ret; > + } > + > + if (node->id == AD242X_MASTER_ID) > + dev_info(node->dev, > + "Detected AD242x master node, version %d.%d\n", > + val >> 4, val & 0xf); > + else > + dev_info(node->dev, > + "Detected AD242x slave node, version %d.%d, id %d\n", > + val >> 4, val & 0xf, node->id); > + > + ret = regmap_read(node->regmap, AD242X_CAPABILITY, &val); > + if (ret < 0) { > + dev_err(node->dev, "failed to read CAPABILITY register %d\n", > + ret); > + return ret; > + } > + > + node->caps = val; > + > + val = 0; > + > + if (of_property_read_bool(np, "adi,spread-a2b-clock")) > + val |= AD242X_PLLCTL_SSMODE_AB; > + else if (of_property_read_bool(np, "adi,spread-a2b-i2s-clock")) > + val |= AD242X_PLLCTL_SSMODE_AB_I2S; > + > + if (of_property_read_bool(np, "adi,spread-spectrum-high")) > + val |= AD242X_PLLCTL_SSDEPTH; > + > + ret = regmap_write(node->regmap, AD242X_PLLCTL, val); > + if (ret < 0) { > + dev_err(node->dev, "failed to write PLLCTL register %d\n", ret); > + return ret; > + } > + > + /* I2S global setup */ > + > + of_property_read_u32(np, "adi,tdm-mode", &node->tdm_mode); > + of_property_read_u32(np, "adi,tdm-slot-size", &node->tdm_slot_size); > + > + ret = ad242x_tdmmode_index(node->tdm_mode, false); > + if (ret < 0) { > + dev_err(node->dev, "invalid TDM mode %d\n", node->tdm_mode); > + return -EINVAL; > + } > + > + val = AD242X_I2SGCTL_TDMMODE(ret); > + > + if (node->tdm_slot_size == 16) { > + val |= AD242X_I2SGCTL_TDMSS; > + } else if (node->tdm_slot_size != 32) { > + dev_err(node->dev, "invalid TDM slot size %d\n", > + node->tdm_slot_size); > + return -EINVAL; > + } > + > + if (of_property_read_bool(np, "adi,alternating-sync")) > + val |= AD242X_I2SGCTL_ALT; > + > + if (of_property_read_bool(np, "adi,early-sync")) > + val |= AD242X_I2SGCTL_EARLY; > + > + if (of_property_read_bool(np, "adi,invert-sync")) > + val |= AD242X_I2SGCTL_INV; > + > + ret = regmap_write(node->regmap, AD242X_I2SGCTL, val); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > +static const struct mfd_cell ad242x_mfd_cells[] = { > + { > + .of_compatible = "adi,ad2428w-i2c", > + .name = "ad242x-i2c", Swap these around. Or better still, use the macros found in: include/linux/mfd/core.h > + }, > + { > + .of_compatible = "adi,ad2428w-gpio", > + .name = "ad242x-gpio", > + }, > + { > + .of_compatible = "adi,ad2428w-clk", > + .name = "ad242x-clk", > + }, > + { > + .of_compatible = "adi,ad2428w-codec", > + .name = "ad242x-codec", > + }, > +}; > + > +int ad242x_node_add_mfd_cells(struct device *dev) > +{ > + return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, > + ad242x_mfd_cells, > + ARRAY_SIZE(ad242x_mfd_cells), > + NULL, 0, NULL); > +} > + > +static int ad242x_get_slot_mask(const struct device_node *np, > + const char *propname, u32 *mask) > +{ > + unsigned int i, num; > + int ret, proplen; > + u32 slots[32]; You should define 32 as the maximum number of slots available, then use it again for most of the random '32's below. > + if (!of_get_property(np, propname, &proplen)) > + return -ENOENT; This whole piece becomes simpler if you use: of_property_read_variable_u32_array() > + num = proplen / sizeof(u32); > + > + if (num > ARRAY_SIZE(slots)) > + return -EOVERFLOW; > + > + ret = of_property_read_u32_array(np, propname, slots, num); > + if (ret < 0) > + return ret; > + > + *mask = 0; > + > + for (i = 0; i < num; i++) { > + if (slots[i] >= 32) > + return -EINVAL; > + > + *mask |= BIT(slots[i]); > + } > + > + return 0; > +} > + > +int ad242x_read_slot_config(struct device *dev, > + struct device_node *np, > + struct ad242x_slot_config *config) > +{ > + struct device_node *dn_np, *up_np; > + int ret; > + > + dn_np = of_get_child_by_name(np, "downstream"); > + if (!dn_np) { > + dev_err(dev, "no downstream node\n"); > + return -EINVAL; > + } > + > + up_np = of_get_child_by_name(np, "upstream"); > + if (!dn_np) { > + dev_err(dev, "no upstream node\n"); > + ret = -EINVAL; > + goto err_put_dn_node; > + } > + > + ret = ad242x_get_slot_mask(dn_np, "rx-slots", &config->dn_rx_slots); > + if (ret < 0 && ret != -ENOENT) { If you're going to ignore -ENOENT, why not just return 0? > + dev_err(dev, "invalid downstream rx-slots property\n"); > + goto err_put_nodes; > + } > + > + of_property_read_u32(dn_np, "#tx-slots", &config->dn_n_tx_slots); > + of_property_read_u32(dn_np, "#forward-slots", > + &config->dn_n_forward_slots); > + if (config->dn_n_tx_slots + config->dn_n_forward_slots >= 32) { > + dev_err(dev, "invalid downstream tx-slots property\n"); > + goto err_put_nodes; > + } > + > + Superfluous '\n'. > + ret = ad242x_get_slot_mask(up_np, "rx-slots", &config->up_rx_slots); > + if (ret < 0) { > + dev_err(dev, "invalid upstream rx-slots property\n"); > + goto err_put_nodes; > + } > + > + of_property_read_u32(up_np, "#tx-slots", &config->up_n_tx_slots); > + of_property_read_u32(up_np, "#forward-slots", > + &config->up_n_forward_slots); > + if (config->up_n_tx_slots + config->up_n_forward_slots >= 32) { > + dev_err(dev, "invalid downstream tx-slots property\n"); > + goto err_put_nodes; > + } > + > +err_put_nodes: > + of_node_put(up_np); > +err_put_dn_node: > + of_node_put(dn_np); > + > + return ret; > +} > diff --git a/drivers/mfd/ad242x-slave.c b/drivers/mfd/ad242x-slave.c > new file mode 100644 > index 000000000000..ad255d67a5b6 > --- /dev/null > +++ b/drivers/mfd/ad242x-slave.c > @@ -0,0 +1,234 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct ad242x_slave { > + struct ad242x_node node; > + struct ad242x_node *master; > + struct ad242x_slot_config slot_config; > + unsigned int sync_offset; > +}; > + > +int ad242x_slave_read(struct ad242x_i2c_bus *bus, > + struct regmap *master_regmap, > + uint8_t node_id, uint8_t reg, unsigned int *val) > +{ > + int ret; > + > + mutex_lock(&bus->mutex); > + > + ret = regmap_write(master_regmap, AD242X_NODEADR, node_id); > + if (ret < 0) > + goto err_unlock; > + > + ret = i2c_smbus_read_byte_data(bus->client, reg); > + if (ret < 0) > + goto err_unlock; > + > + *val = ret; > + ret = 0; > + > +err_unlock: > + mutex_unlock(&bus->mutex); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(ad242x_slave_read); > + > +int ad242x_slave_write(struct ad242x_i2c_bus *bus, > + struct regmap *master_regmap, > + uint8_t node_id, uint8_t reg, unsigned int val) > +{ > + int ret; > + > + mutex_lock(&bus->mutex); > + > + ret = regmap_write(master_regmap, AD242X_NODEADR, node_id); > + if (ret < 0) > + goto err_unlock; > + > + ret = i2c_smbus_write_byte_data(bus->client, reg, val); > + if (ret < 0) > + goto err_unlock; > + > + ret = 0; > + > +err_unlock: > + mutex_unlock(&bus->mutex); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(ad242x_slave_write); > + > +static int ad242x_slave_regmap_read(void *context, unsigned int reg, > + unsigned int *val) > +{ > + struct ad242x_slave *slave = context; > + struct ad242x_i2c_bus *bus = ad242x_master_get_bus(slave->node.master); > + struct ad242x_node *mnode = ad242x_master_get_node(slave->node.master); > + > + if (reg > 0xff) > + return -EINVAL; > + > + return ad242x_slave_read(bus, mnode->regmap, slave->node.id, reg, val); > +} > + > +static int ad242x_slave_regmap_write(void *context, unsigned int reg, > + unsigned int val) > +{ > + struct ad242x_slave *slave = context; > + struct ad242x_i2c_bus *bus = ad242x_master_get_bus(slave->node.master); > + struct ad242x_node *mnode = ad242x_master_get_node(slave->node.master); > + > + if (val > 0xff || reg > 0xff) > + return -EINVAL; > + > + return ad242x_slave_write(bus, mnode->regmap, slave->node.id, reg, val); > +} > + > +static const struct regmap_config ad242x_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .volatile_reg = ad242x_is_volatile_reg, > + .writeable_reg = ad242x_is_writeable_reg, > + .reg_read = ad242x_slave_regmap_read, > + .reg_write = ad242x_slave_regmap_write, > + .max_register = AD242X_MAX_REG, > + .cache_type = REGCACHE_RBTREE, > +}; > + > +static int ad242x_calc_sync_offset(unsigned int val) > +{ > + if (val == 0) > + return 0; > + > + if (val > 127) > + return -EINVAL; > + > + return 256 - val; More magic numbers to define. > +} > + > +static int ad242x_slave_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct ad242x_slave *slave; > + struct ad242x_node *mnode; > + struct regmap *regmap; > + unsigned int val; > + int i, ret; > + > + slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL); > + if (!slave) > + return -ENOMEM; > + > + regmap = devm_regmap_init(dev, NULL, slave, &ad242x_regmap_config); > + if (IS_ERR(regmap)) { > + ret = PTR_ERR(regmap); > + dev_err(dev, "regmap init failed: %d\n", ret); > + return ret; > + } > + > + of_property_read_u32(dev->of_node, "reg", &val); > + slave->node.id = val; This looks like an abuse of the 'reg' property. > + slave->node.dev = dev; > + slave->node.regmap = regmap; > + > + mnode = dev_get_drvdata(dev->parent); What is the parent of the slave? (it's not clear without looking at the DT I guess) > + slave->node.master = mnode->master; > + > + dev_set_name(dev, "%s-a2b-%d", dev_name(dev->parent), slave->node.id); > + dev_set_drvdata(dev, &slave->node); > + > + ret = ad242x_node_probe(&slave->node); > + if (ret < 0) > + return ret; > + > + ret = ad242x_read_slot_config(dev, dev->of_node, &slave->slot_config); > + if (ret < 0) { > + dev_err(dev, "slot config is invalid: %d\n", ret); > + return ret; > + } > + > + ret = regmap_write(regmap, AD242X_UPSLOTS, > + slave->slot_config.up_n_forward_slots); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_DNSLOTS, > + slave->slot_config.dn_n_forward_slots); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_LUPSLOTS, > + slave->slot_config.up_n_tx_slots); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_LDNSLOTS, > + slave->slot_config.dn_n_tx_slots | > + AD242X_LDNSLOTS_DNMASKEN); > + if (ret < 0) > + return ret; > + > + for (i = 0; i < 4; i++) { Why 4? Please define it. > + ret = regmap_write(regmap, AD242X_UPMASK(i), > + (slave->slot_config.up_rx_slots >> (i * 8)) & 0xff); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_DNMASK(i), > + (slave->slot_config.dn_rx_slots >> (i * 8)) & 0xff); > + if (ret < 0) > + return ret; > + } > + > + of_property_read_u32(dev->of_node, "adi,sync-offset", > + &slave->sync_offset); > + > + ret = ad242x_calc_sync_offset(slave->sync_offset); > + if (ret < 0) > + return ret; > + > + ret = regmap_write(regmap, AD242X_SYNCOFFSET, ret); > + if (ret < 0) > + return ret; > + > + ret = ad242x_node_add_mfd_cells(dev); > + if (ret < 0) { > + dev_err(dev, "failed to add MFD devices %d\n", ret); > + return ret; > + } > + > + return 0; > +} > + > +static const struct of_device_id ad242x_slave_of_match[] = { > + { .compatible = "adi,ad2428w-slave" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, ad242x_slave_of_match); > + > +static struct platform_driver ad242x_slave_driver = { > + .driver = { > + .name = "ad242x-slave", > + .of_match_table = ad242x_slave_of_match, > + }, > + .probe = ad242x_slave_probe, > +}; > + > +module_platform_driver(ad242x_slave_driver); > + > +MODULE_DESCRIPTION("AD242x slave node driver"); > +MODULE_AUTHOR("Daniel Mack "); > +MODULE_LICENSE("GPL v2"); > diff --git a/include/linux/mfd/ad242x.h b/include/linux/mfd/ad242x.h > new file mode 100644 > index 000000000000..02a174824f85 > --- /dev/null > +++ b/include/linux/mfd/ad242x.h > @@ -0,0 +1,400 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > + > +#ifndef __LINUX_MFD_AD242X_H > +#define __LINUX_MFD_AD242X_H > + > +#define AD242X_CHIP 0x00 > +#define AD242X_NODEADR 0x01 > +#define AD242X_NODEADR_MASK 0x0f > +#define AD242X_NODEADR_PERI BIT(5) > +#define AD242X_NODEADR_BRCST BIT(7) > + > +#define AD242X_VENDOR 0x02 > +#define AD242X_PRODUCT 0x03 > +#define AD242X_VERSION 0x04 > + > +#define AD242X_CAPABILITY 0x05 > +#define AD242X_CAPABILITY_I2C BIT(0) > + > +#define AD242X_SWCTL 0x09 > +#define AD242X_SWCTL_ENSW BIT(0) > +#define AD242X_SWCTL_DIAGMODE BIT(3) > +#define AD242X_SWCTL_MODE(X) (((X) & 3) << 4) > +#define AD242X_SWCTL_MODE_MASK (3 << 4) > +#define AD242X_SWCTL_DISNXT BIT(6) > + > +#define AD242X_BCDNSLOTS 0x0a > +#define AD242X_BCDNSLOTS_MASK 0x3f > + > +#define AD242X_LDNSLOTS 0x0b > +#define AD242X_LDNSLOTS_MASK 0x3f > +#define AD242X_LDNSLOTS_DNMASKEN BIT(7) > + > +#define AD242X_LUPSLOTS 0x0c > +#define AD242X_LUPSLOTS_MASK 0x3f > + > +#define AD242X_DNSLOTS 0x0d > +#define AD242X_DNSLOTS_MASK 0x3f > + > +#define AD242X_UPSLOTS 0x0e > +#define AD242X_UPSLOTS_MASK 0x3f > + > +#define AD242X_RESPCYCS 0x0f > + > +#define AD242X_SLOTFMT 0x10 > +#define AD242X_SLOTFMT_DNSIZE(X) ((((X) - 8) >> 2) & 7) > +#define AD242X_SLOTFMT_DNFMT BIT(3) > +#define AD242X_SLOTFMT_UPSIZE(X) (((((X) - 8) >> 2) & 7) << 4) > +#define AD242X_SLOTFMT_UPFMT BIT(7) > + > +#define AD242X_DATCTL 0x11 > +#define AD242X_DATCTL_DNS BIT(0) > +#define AD242X_DATCTL_UPS BIT(1) > +#define AD242X_DATCTL_ENDSNIFF BIT(5) > +#define AD242X_DATCTL_STANDBY BIT(7) > + > +#define AD242X_CONTROL 0x12 > +#define AD242X_CONTROL_NEWSTRCT BIT(0) > +#define AD242X_CONTROL_ENDDSC BIT(1) > +#define AD242X_CONTROL_SOFTRST BIT(2) > +#define AD242X_CONTROL_SWBYP BIT(3) > +#define AD242X_CONTROL_XCVRBINV BIT(4) > +#define AD242X_CONTROL_MSTR BIT(7) > + > +#define AD242X_DISCVRY 0x13 > + > +#define AD242X_SWSTAT 0x14 > +#define AD242X_SWSTAT_FIN BIT(0) > +#define AD242X_SWSTAT_FAULT BIT(1) > +#define AD242X_SWSTAT_FAULTCODE(X) (((X) & 0x7) >> 4) > +#define AD242X_SWSTAT_FAULT_NLOC BIT(7) > + > +#define AD242X_INTSTAT 0x15 > +#define AD242X_INTSTAT_IRQ BIT(0) > + > +#define AD242X_INTSRC 0x16 > +#define AD242X_INTSRC_INODE 0x0f > +#define AD242X_INTSRC_SLVINT BIT(6) > +#define AD242X_INTSRC_MSTINT BIT(7) > + > +#define AD242X_INTTYPE 0x17 > + > +#define AD242X_INTTYPE_DSCDONE 24 > +#define AD242X_INTTYPE_MSTR_RUNNING 255 > + > +#define AD242X_INTPND0 0x18 > +#define AD242X_INTPDN0_HDCNTERR BIT(0) > +#define AD242X_INTPDN0_DDERR BIT(1) > +#define AD242X_INTPDN0_CRCERR BIT(2) > +#define AD242X_INTPDN0_DPERR BIT(3) > +#define AD242X_INTPDN0_PWRERR BIT(4) > +#define AD242X_INTPDN0_BECOVF BIT(5) > +#define AD242X_INTPDN0_SRFERR BIT(6) > +#define AD242X_INTPDN0_SRFCRCERR BIT(7) > + > +#define AD242X_INTPND1 0x19 > +#define AD242X_INTPND1_IOPND(X) BIT(X) > + > +#define AD242X_INTPND2 0x1a > +#define AD242X_INTPND2_DSCDONE BIT(0) > +#define AD242X_INTPND2_I2CERR BIT(1) > +#define AD242X_INTPND2_ICRCERR BIT(2) > +#define AD242X_INTPND2_SLVIRQ BIT(3) > + > +#define AD242X_INTMSK0 0x1b > +#define AD242X_INTMSK0_HCEIEN BIT(0) > +#define AD242X_INTMSK0_DDEIEN BIT(1) > +#define AD242X_INTMSK0_CRCEIEN BIT(2) > +#define AD242X_INTMSK0_DPEIEN BIT(3) > +#define AD242X_INTMSK0_PWREIEN BIT(4) > +#define AD242X_INTMSK0_BECIEN BIT(5) > +#define AD242X_INTMSK0_SRFEIEN BIT(6) > +#define AD242X_INTMSK0_SRFCRCEIEN BIT(7) > + > +#define AD242X_INTMSK1 0x1c > +#define AD242X_INTMSK1_IOIRQEN(X) BIT(X) > + > +#define AD242X_INTMSK2 0x1d > +#define AD242X_INTMSK2_DSCDIEN BIT(0) > +#define AD242X_INTMSK2_I2CEIEN BIT(1) > +#define AD242X_INTMSK2_ICRCEIEN BIT(2) > +#define AD242X_INTMSK2_SLVIRQEN BIT(3) > + > +#define AD242X_BECCTL 0x1e > +#define AD242X_BECCTL_ENHDCNT BIT(0) > +#define AD242X_BECCTL_ENDD BIT(1) > +#define AD242X_BECCTL_ENCRC BIT(2) > +#define AD242X_BECCTL_ENDP BIT(3) > +#define AD242X_BECCTL_ENICRC BIT(4) > +#define AD242X_BECCTL_THRESHLD(X) ((X) >> 5) > + > +#define AD242X_BECNT 0x1f > + > +#define AD242X_TESTMODE 0x20 > +#define AD242X_TESTMODE_PRBSUP BIT(0) > +#define AD242X_TESTMODE_PRBSDN BIT(1) > +#define AD242X_TESTMODE_PRBSN2N BIT(2) > +#define AD242X_TESTMODE_RXDPTH(X) ((X) >> 4) > + > +#define AD242X_ERRCNT0 0x21 > +#define AD242X_ERRCNT1 0x22 > +#define AD242X_ERRCNT2 0x23 > +#define AD242X_ERRCNT3 0x24 > + > +#define AD242X_NODE 0x29 > +#define AD242X_NODE_MASK 0xf > +#define AD242X_NODE_DISCVD BIT(5) > +#define AD242X_NODE_NLAST BIT(6) > +#define AD242X_NODE_LAST BIT(7) > + > +#define AD242X_DISCSTAT 0x2b > +#define AD242X_DISCSTAT_DNODE(X) ((X) & 0xf) > +#define AD242X_DISCSTAT_DSCACT BIT(7) > + > +#define AD242X_TXACTL 0x2e > +#define AD242X_TXACTL_LEVEL_HIGH 0 > +#define AD242X_TXACTL_LEVEL_MEDIUM 2 > +#define AD242X_TXACTL_LEVEL_LOW 3 > + > +#define AD242X_TXBCTL 0x30 > +#define AD242X_TXBCTL_LEVEL_HIGH 0 > +#define AD242X_TXBCTL_LEVEL_MEDIUM 2 > +#define AD242X_TXBCTL_LEVEL_LOW 3 > + > +#define AD242X_LINTTYPE 0x3e > + > +#define AD242X_I2CCFG 0x3f > +#define AD242X_I2CCFG_DATARATE BIT(0) > +#define AD242X_I2CCFG_EACK BIT(1) > +#define AD242X_I2CCFG_FRAMERATE BIT(2) > + > +#define AD242X_PLLCTL 0x40 > +#define AD242X_PLLCTL_SSFREQ(X) ((X) & 3) > +#define AD242X_PLLCTL_SSDEPTH BIT(2) > +#define AD242X_PLLCTL_SSMODE_AB (1 << 6) > +#define AD242X_PLLCTL_SSMODE_AB_I2S (2 << 6) > + > +#define AD242X_I2SGCTL 0x41 > +#define AD242X_I2SGCTL_TDMMODE(X) ((X) & 3) > +#define AD242X_I2SGCTL_RXONDTX1 BIT(3) > +#define AD242X_I2SGCTL_TDMSS BIT(4) > +#define AD242X_I2SGCTL_ALT BIT(5) > +#define AD242X_I2SGCTL_EARLY BIT(6) > +#define AD242X_I2SGCTL_INV BIT(7) > + > +#define AD242X_I2SCTL 0x42 > +#define AD242X_I2SCTL_TX0EN BIT(0) > +#define AD242X_I2SCTL_TX1EN BIT(1) > +#define AD242X_I2SCTL_TX2PINTL BIT(2) > +#define AD242X_I2SCTL_TXBCLKINV BIT(3) > +#define AD242X_I2SCTL_RX0EN BIT(4) > +#define AD242X_I2SCTL_RX1EN BIT(5) > +#define AD242X_I2SCTL_RX2PINTL BIT(6) > +#define AD242X_I2SCTL_RXBCLKINV BIT(7) > + > +#define AD242X_I2SRATE 0x43 > +#define AD242X_I2SRATE_I2SRATE(X) ((X) & 3) > +#define AD242X_I2SRATE_BCLKRATE(X) (((X) << 3) & 3) > +#define AD242X_I2SRATE_REDUCE BIT(6) > +#define AD242X_I2SRATE_SHARE BIT(7) > + > +#define AD242X_I2STXOFFSET 0x44 > +#define AD242X_I2STXOFFSET_VAR(X) ((X) & 0x3f) > +#define AD242X_I2STXOFFSET_TSAFTER BIT(6) > +#define AD242X_I2STXOFFSET_TSBEFORE BIT(7) > + > +#define AD242X_2SRXOFFSET 0x45 > +#define AD242X_I2SRXOFFSET_VAR(X) ((X) & 0x3f) > + > +#define AD242X_SYNCOFFSET 0x46 > + > +#define AD242X_PDMCTL 0x47 > +#define AD242X_PDMCTL_PDM0EN BIT(0) > +#define AD242X_PDMCTL_PDM0SLOTS BIT(1) > +#define AD242X_PDMCTL_PDM1EN BIT(2) > +#define AD242X_PDMCTL_PDM1SLOTS BIT(3) > +#define AD242X_PDMCTL_HPFEN BIT(4) > +#define AD242X_PDMCTL_PDMRATE(X) (((X) & 3) << 5) > + > +#define AD242X_ERRMGMT 0x48 > +#define AD242X_ERRMGMT_ERRLSB BIT(0) > +#define AD242X_ERRMGMT_ERRSIG BIT(1) > +#define AD242X_ERRMGMT_ERRSLOT BIT(2) > + > +#define AD242X_GPIODAT 0x4a > +#define AD242X_GPIODAT_SET 0x4b > +#define AD242X_GPIODAT_CLR 0x4c > +#define AD242X_GPIOOEN 0x4d > +#define AD242X_GPIOIEN 0x4e > +#define AD242X_GPIODAT_IN 0x4f > +#define AD242X_PINTEN 0x50 > +#define AD242X_PINTINV 0x51 > + > +#define AD242X_PINCFG 0x52 > +#define AD242X_PINCFG_DRVSTR BIT(0) > +#define AD242X_PINCFG_IRQINV BIT(4) > +#define AD242X_PINCFG_IRQTS BIT(5) > + > +#define AD242X_I2STEST 0x53 > +#define AD242X_I2STEST_PATTRN2TX BIT(0) > +#define AD242X_I2STEST_LOOPBK2TX BIT(1) > +#define AD242X_I2STEST_RX2LOOPBK BIT(2) > +#define AD242X_I2STEST_SELRX1 BIT(3) > +#define AD242X_I2STEST_BUSLOOPBK BIT(4) > + > +#define AD242X_RAISE 0x54 > + > +#define AD242X_GENERR 0x55 > +#define AD242X_GENERR_GENHCERR BIT(0) > +#define AD242X_GENERR_GENDDERR BIT(1) > +#define AD242X_GENERR_GENCRCERR BIT(2) > +#define AD242X_GENERR_GENDPERR BIT(3) > +#define AD242X_GENERR_GENICRCERR BIT(4) > + > +#define AD242X_I2SRRATE 0x56 > +#define AD242X_I2SRRATE_RRDIV(X) ((X) & 0x3f) > +#define AD242X_I2SRRATE_RBUS BIT(7) > + > +#define AD242X_I2SRRCTL 0x57 > +#define AD242X_I2SRRCTL_ENVLSB BIT(0) > +#define AD242X_I2SRRCTL_ENXBIT BIT(1) > +#define AD242X_I2SRRCTL_ENSTRB BIT(4) > +#define AD242X_I2SRRCTL_STRBDIR BIT(5) > + > +#define AD242X_I2SRRSOFFS 0x58 > + > +#define AD242X_CLK1CFG 0x59 > +#define AD242X_CLK2CFG 0x5a > +#define AD242X_CLKCFG_DIV(X) ((X) & 0xf) > +#define AD242X_CLKCFG_DIVMSK 0xf > +#define AD242X_CLKCFG_PDIV32 BIT(5) > +#define AD242X_CLKCFG_INV BIT(6) > +#define AD242X_CLKCFG_EN BIT(7) > + > +#define AD242X_BMMCFG 0x5b > +#define AD242X_BMMCFG_BMMEN BIT(0) > +#define AD242X_BMMCFG_BMMRXEN BIT(1) > +#define AD242X_BMMCFG_BMMNDSC BIT(2) > + > +#define AD242X_PDMCTL2 0x5d > +#define AD242X_PDMCTL2_DEST_A2B 0 > +#define AD242X_PDMCTL2_DEST_DTX 1 > +#define AD242X_PDMCTL2_DEST_A2B_DTX 2 > + > +#define AD242X_UPMASK(X) (0x60 + ((X) & 3)) > + > +#define AD242X_UPOFFSET 0x64 > +#define AD242X_UPOFFSET_VAL(X) ((X) & 0x1f) > + > +#define AD242X_DNMASK(X) (0x65 + ((X) % 3)) > + > +#define AD242X_DNOFFSET 0x69 > +#define AD242X_DNOFFSET_VAL(X) ((X) & 0x1f) > + > +#define AD242X_CHIPID(X) ((X) + 0x6a) > + > +#define AD242X_GPIODEN 0x80 > +#define AD242X_GPIOD_MSK(X) ((X) + 0x81) > + > +#define AD242X_GPIODDAT 0x89 > +#define AD242X_GPIODINV 0x8a > + > +#define AD242X_MAX_REG 0x9b > + > +static inline bool ad242x_is_volatile_reg(struct device *dev, unsigned int reg) > +{ > + switch (reg) { > + case AD242X_VENDOR: > + case AD242X_PRODUCT: > + case AD242X_VERSION: > + case AD242X_CAPABILITY: > + case AD242X_SWSTAT: > + case AD242X_INTSTAT: > + case AD242X_INTSRC: > + case AD242X_INTTYPE: > + case AD242X_INTPND0: > + case AD242X_INTPND1: > + case AD242X_INTPND2: > + case AD242X_BECNT: > + case AD242X_ERRCNT0: > + case AD242X_ERRCNT1: > + case AD242X_ERRCNT2: > + case AD242X_ERRCNT3: > + case AD242X_NODE: > + case AD242X_DISCSTAT: > + case AD242X_LINTTYPE: > + case AD242X_GPIODAT: > + case AD242X_GPIODAT_IN: > + return true; > + default: > + return false; > + } > +} > + > +static inline bool ad242x_is_writeable_reg(struct device *dev, unsigned int reg) > +{ > + /* Write-to-clean registers */ > + switch (reg) { > + case AD242X_INTPND0: > + case AD242X_INTPND1: > + case AD242X_INTPND2: > + case AD242X_BECNT: > + return true; > + default: > + return !ad242x_is_volatile_reg(dev, reg); > + } > +} > + > +#define AD242X_MASTER_ID 0xff > + > +struct ad242x_master; > + > +struct ad242x_i2c_bus { > + struct i2c_client *client; > + struct mutex mutex; > +}; > + > +struct ad242x_node { > + struct device *dev; > + struct regmap *regmap; > + struct ad242x_master *master; > + unsigned int tdm_mode; > + unsigned int tdm_slot_size; > + uint8_t id; > + uint8_t caps; > +}; > + > +struct ad242x_slot_config { > + unsigned int dn_rx_slots; > + unsigned int dn_n_tx_slots; > + unsigned int dn_n_forward_slots; > + unsigned int up_rx_slots; > + unsigned int up_n_tx_slots; > + unsigned int up_n_forward_slots; > +}; > + > +int ad242x_read_slot_config(struct device *dev, > + struct device_node *np, > + struct ad242x_slot_config *config); > + > +static inline bool ad242x_node_is_master(struct ad242x_node *node) > +{ > + return node->id == AD242X_MASTER_ID; > +} > + > +int ad242x_node_probe(struct ad242x_node *node); > +int ad242x_node_add_mfd_cells(struct device *dev); > + > +struct ad242x_node *ad242x_master_get_node(struct ad242x_master *master); > +struct ad242x_i2c_bus *ad242x_master_get_bus(struct ad242x_master *master); > +const char *ad242x_master_get_clk_name(struct ad242x_master *master); > +unsigned int ad242x_master_get_clk_rate(struct ad242x_master *master); > + > +int ad242x_slave_read(struct ad242x_i2c_bus *bus, > + struct regmap *master_regmap, > + uint8_t node_id, uint8_t reg, unsigned int *val); > +int ad242x_slave_write(struct ad242x_i2c_bus *bus, > + struct regmap *master_regmap, > + uint8_t node_id, uint8_t reg, unsigned int val); > + > +#endif -- Lee Jones [李琼斯] Linaro Services Technical Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog