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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3C72BC61DD3 for ; Thu, 3 Sep 2026 13:15:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=hRs88XAY2CkcYgaOeo1zeJ92OOkq80vQrClH0GKC1g8=; b=KT/asGJqexC0pN NTC+fAXz8N0yahhAUb5pyljbfSSQk3Mc4APOm0m7hcSPfXPNjHV9f8j4KMwWDVcSfxP9IK9YNZVEx PEi2jY/MFZ40zyrC90e6jxUuAnNb1nu5/BB6DuFzX+INFDV5A37fEp7MEFzfOJMhqmr85FlaLf2Fu muSRbDLS9UsecJdYt6xHJqC1tqvVSxy1VAUUH3kSGNgIT/qgs+3OzSFY8uiuUF6U1GNFtzQ9XhEme P2ZXLJNdc/4Qmj1mhm/IhEfgGWxwWTTZiKdiPI9pdTh8Fh+lXKz2vCeA/ZWPUJGhRozJWMxhBeUK0 MshYUtjVxW2+9NU4781A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x27IK-0000000HO1B-3MEb; Thu, 03 Sep 2026 13:15:56 +0000 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x27IH-0000000HO0n-0VmV for linux-phy@lists.infradead.org; Thu, 03 Sep 2026 13:15:55 +0000 Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-5b4a9175181so274070e87.3 for ; Thu, 03 Sep 2026 06:15:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788441351; x=1789046151; darn=lists.infradead.org; h=content-transfer-encoding:content-type:in-reply-to:from:references :cc:to:subject:user-agent:mime-version:date:message-id:from:to:cc :subject:date:message-id:reply-to:content-type; bh=mr9isTlDJb3v/C7vbLOsv9lj+fKnUwGkrvAs7o9qNh0=; b=rYTk2wlsr7XHdljWmYUFgbU4LoOZZJFh3kBsn1+2KdfLlMAgIHs08uEnEGvAZ6XAsJ 0BHbRCm3nm6ycTI3VzWj+1ulgE7pSpOKrny8NM1KeXWAKYtk2DIpn3m44VwgMnavDWKB YkMK3A/zakVyPGlFPlioFFlZYdw7j+GT34ssP7xOGub92a4TPRSHgs+chxG5/pY8Qg5w HI9x2nDmNP1aUZYW3Qrr29aLS19rtehkcfeyt7PS2ZP3tKp59eLG/Z9YNLqfc9tSDef2 ctkvawLcpleG3YoHcgwikpWEO/Jll0AqXQCrbsEdSUUOQuGiCbAAxfNjBDQ+WmZlBuu7 5J7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788441351; x=1789046151; h=content-transfer-encoding:content-type:in-reply-to:from:references :cc:to:subject:user-agent:mime-version:date:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=mr9isTlDJb3v/C7vbLOsv9lj+fKnUwGkrvAs7o9qNh0=; b=QwbE7MKGOKfEfE8D6AOHUUt52Su+h62WGXOPiUrPtsCIxYj1vB50yCOQwqVxH92pNv 7495edexqXMl+dGGk4c7pWp0uVYLaBZTFndxJI/HfnyDlQc32wfug1WDO0Y45SGrHZ9w BbCS2msXaO9RjviXF1AD6b2qNMXbpyZKy36iIxiEBJAOk+/BRb9p+HB31IykqViO5M9U mUdfXBaevIwd6Vpv2Bfq+Ay1qhRHImCayExPXptU2gnnEHYTgGezG/Uqq0wD43ca+dMO SaIoZBsto5sOuAwEiny7GdrNSoQcIeHr1/D3R6y3WPZGXoHp28LPbi+8m2Z+8qUR/bEG n55Q== X-Forwarded-Encrypted: i=1; AKwUvBwtG1caRtAJ/MlVpcAGQKQ1g7Sj7lr9IArRFdWkL2h31DOZDLtA5Y7e1qSk2m9BuDClZdP9Bh0LVFw=@lists.infradead.org X-Gm-Message-State: AFuF++kmwdXgVSntsR9ebACbZzdCa2BI8izTQZUhgj2uX3J/jaH3BibG Ed3x5Qt5G8mDd0NKMgtFG9NpesRm8H5NmhbPz2aCwP6uPvRyg2jbMQoheGgQcIoVr+o= X-Gm-Gg: AYBFou1+69DMGVCRd+QCeb8PPR/h+QCfVIozF8ee65ZuxlcL0w191VaT6Q/ebgdYZoh cEu390EjANYE76P7OEtDLW9uMGjRHmaP4gG2hjjjRzBYlOtLo32lKqw6RJqruz26V1YomTG28uf 7ULM1tARBXOP/5rGo3TnnSCfljqiqJbl1PhOu3WCTuIqRaX/CuWuEGmjcrF9dTqT6wJbY/43xRt 73qgkQt2Q8izTpqpefoxZtfouL29Cjw6rU0SHft4wnpLCYgbYZcBZ/irpvTjfwIWb1j1iAPVvy7 3GFbOoN2UdEy8ZD3xBwRl2pUSI4C3Bw8My3SatcBh9oUTO8JALgDdyAo7rOjwUUDPB1ggIleT17 Ob665SLChv697m7fNBBYNiwcUrldw+ElGY4kOf3HV9UJjGCeocH/hHfZQBKNWI2o82DpsOBvXAi P5pqnQViuooLZxqN1vEHNAMdeELhKYXRlGufoca9hTv4dVc9Q+Xgk8owMKOor1PmwjP9FWE1bPn EAXEWPpBq1ZBvnxMfEjzJPLd64+PcOBWBVdQa2mOg== X-Received: by 2002:a05:6512:3a82:b0:5b0:312:21ca with SMTP id 2adb3069b0e04-5b608347a4dmr2488301e87.2.1788441350385; Thu, 03 Sep 2026 06:15:50 -0700 (PDT) Received: from [192.168.1.100] (91-159-24-186.elisa-laajakaista.fi. [91.159.24.186]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a34a8ed421sm11153871fa.2.2026.09.03.06.15.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Sep 2026 06:15:49 -0700 (PDT) Message-ID: <2de02744-1fcc-4ded-9f07-51b7aa74c423@linaro.org> Date: Thu, 3 Sep 2026 16:15:49 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v16 2/2] phy: qcom-mipi-csi2: Add a CSI2 MIPI DPHY driver To: Bryan O'Donoghue , Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Neil Armstrong Cc: Bryan O'Donoghue , linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org References: <20260901-x1e-csi2-phy-v16-0-dd863b929080@linaro.org> <20260901-x1e-csi2-phy-v16-2-dd863b929080@linaro.org> From: Vladimir Zapolskiy In-Reply-To: <20260901-x1e-csi2-phy-v16-2-dd863b929080@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260903_061553_482983_6E11E777 X-CRM114-Status: GOOD ( 29.89 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org T24gOS8xLzI2IDIzOjE1LCBCcnlhbiBPJ0Rvbm9naHVlIHdyb3RlOgo+IEFkZCBhIG5ldyBNSVBJ IENTSTIgZHJpdmVyIGluIERQSFkgbW9kZSBpbml0aWFsbHkuIFRoZSBlbnRpcmUgc2V0IG9mCj4g ZXhpc3RpbmcgQ0FNU1MgQ1NJIFBIWSBpbml0IHNlcXVlbmNlcyBhcmUgaW1wb3J0ZWQgaW4gb3Jk ZXIgdG8gc2F2ZSB0aW1lCj4gYW5kIGVmZm9ydCBpbiBsYXRlciBwYXRjaGVzLgo+IAo+IFRoZSBm b2xsb3dpbmcgZGV2aWNlcyBhcmUgc3VwcG9ydGVkIGluIHRoaXMgZHJvcDoKPiAicWNvbSx4MWU4 MDEwMC1jc2kyLXBoeSIKPiAKPiBJbi1saW5lIHdpdGggb3RoZXIgUEhZIGRyaXZlcnMgdGhlIHBy b2Nlc3Mgbm9kZSBpcyBpbmNsdWRlZCBpbiB0aGUgbmFtZS4KPiBEYXRhLWxhbmUgYW5kIGNsb2Nr IGxhbmUgcG9zaXRpb25pbmcgYW5kIHBvbGFyaXR5IHNlbGVjdGlvbiB2aWEgbmV3bHkKPiBhbWVu ZGVkIHN0cnVjdCBwaHlfY29uZmlndXJlX29wdHNfbWlwaV9kcGh5e30gaXMgc3VwcG9ydGVkLgo+ IAo+IFRoZSBRdWFsY29tbSAzUEggY2xhc3Mgb2YgUEhZcyBjYW4gZG8gYm90aCBEUEhZIGFuZCBD UEhZIG1vZGUuIEZvciBub3cgb25seQo+IERQSFkgaXMgc3VwcG9ydGVkLgo+IAo+IEluIHBvcnRp bmcgc29tZSBvZiB0aGUgbG9naWMgb3ZlciBmcm9tIGNhbXNzLWNzaXBoeSouYyB0byBoZXJlIGl0 cyBhbHNvCj4gcG9zc2libGUgdG8gcmF0aW9uYWxpc2Ugc29tZSBvZiB0aGUgY29kZS4KPiAKPiBJ biBwYXJ0aWN1bGFyIHVzZSBvZiByZWd1bGF0b3JfYnVsayBhbmQgY2xrX2J1bGsgYXMgd2VsbCBh cyBkcm9wcGluZyB0aGUKPiBzZWVtaW5nbHkgdXNlbGVzcyBhbmQgdW51c2VkIGludGVycnVwdCBo YW5kbGVyLgo+IAo+IFRoZSBQSFkgc2VxdWVuY2VzIGFuZCBhIGxvdCBvZiB0aGUgbG9naWMgdGhh dCBnb2VzIHdpdGggdGhlbSBhcmUgd2VsbAo+IHByb3ZlbiBpbiBDQU1TUyBhbmQgbWF0dXJlIHNv IHRoZSBtYWluIHRoaW5nIHRvIHdhdGNoIG91dCBmb3IgaGVyZSBpcyBob3cKPiB0byBnZXQgdGhl IHJpZ2h0IHNlcXVlbmNpbmcgb2YgcmVndWxhdG9ycywgY2xvY2tzIGFuZCByZWdpc3Rlci13cml0 ZXMuCj4gCj4gVGhlIHJlZ2lzdGVyIGluaXQgc2VxdWVuY2UgdGFibGUgaXMgaW1wb3J0ZWQgdmVy YmF0aW0gZnJvbSB0aGUgZXhpc3RpbmcKPiBDQU1TUyBjc2lwaHkgZHJpdmVyLiBBIGZvbGxvdy11 cCBzZXJpZXMgd2lsbCByZXdvcmsgdGhlIHRhYmxlIHRvIGV4dHJhY3QKPiB0aGUgcmVwZXRpdGl2 ZSBwZXItbGFuZSBwYXR0ZXJuIGludG8gYSBsb29wLgo+IAo+IFNpZ25lZC1vZmYtYnk6IEJyeWFu IE8nRG9ub2dodWUgPGJyeWFuLm9kb25vZ2h1ZUBsaW5hcm8ub3JnPgo+IC0tLQo+ICAgTUFJTlRB SU5FUlMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgMTAgKwo+ICAg ZHJpdmVycy9waHkvcXVhbGNvbW0vS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgfCAgMTUg Kwo+ICAgZHJpdmVycy9waHkvcXVhbGNvbW0vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAg fCAgIDUgKwo+ICAgZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2kyLTNwaC1k cGh5LmMgfCAzODUgKysrKysrKysrKysrKysrKysKPiAgIGRyaXZlcnMvcGh5L3F1YWxjb21tL3Bo eS1xY29tLW1pcGktY3NpMi1jb3JlLmMgICAgIHwgNDYyICsrKysrKysrKysrKysrKysrKysrKwo+ ICAgZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2kyLmggICAgICAgICAgfCAg OTcgKysrKysKPiAgIDYgZmlsZXMgY2hhbmdlZCwgOTc0IGluc2VydGlvbnMoKykKPiAKPiBkaWZm IC0tZ2l0IGEvTUFJTlRBSU5FUlMgYi9NQUlOVEFJTkVSUwo+IGluZGV4IDE1MDExZjU3NTJhOTku LmEyMDNiNDE0NzVlYTQgMTAwNjQ0Cj4gLS0tIGEvTUFJTlRBSU5FUlMKPiArKysgYi9NQUlOVEFJ TkVSUwo+IEBAIC0yMjI5Niw2ICsyMjI5NiwxNiBAQCBTOglNYWludGFpbmVkCj4gICBGOglEb2N1 bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvbWVkaWEvcWNvbSwqLWlyaXMueWFtbAo+ICAg RjoJZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9xY29tL2lyaXMvCj4gICAKPiArUVVBTENPTU0gTUlQ SSBDU0kyIFBIWSBEUklWRVIKPiArTToJQnJ5YW4gTydEb25vZ2h1ZSA8Ym9kQGtlcm5lbC5vcmc+ Cj4gK0w6CWxpbnV4LXBoeUBsaXN0cy5pbmZyYWRlYWQub3JnCj4gK0w6CWxpbnV4LW1lZGlhQHZn ZXIua2VybmVsLm9yZwo+ICtMOglsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZwo+ICtTOglN YWludGFpbmVkCj4gK0Y6CURvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9waHkvcWNv bSwqLWNzaTItcGh5LnlhbWwKPiArRjoJZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlw aS1jc2kyKi5jCj4gK0Y6CWRyaXZlcnMvcGh5L3F1YWxjb21tL3BoeS1xY29tLW1pcGktY3NpMiou aAo+ICsKPiAgIFFVQUxDT01NIE5BTkQgQ09OVFJPTExFUiBEUklWRVIKPiAgIE06CU1hbml2YW5u YW4gU2FkaGFzaXZhbSA8bWFuaUBrZXJuZWwub3JnPgo+ICAgTDoJbGludXgtbXRkQGxpc3RzLmlu ZnJhZGVhZC5vcmcKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9waHkvcXVhbGNvbW0vS2NvbmZpZyBi L2RyaXZlcnMvcGh5L3F1YWxjb21tL0tjb25maWcKPiBpbmRleCA2MGEwZWFkMTI3ZmE5Li5jZDY5 NTllNjliZWY3IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvcGh5L3F1YWxjb21tL0tjb25maWcKPiAr KysgYi9kcml2ZXJzL3BoeS9xdWFsY29tbS9LY29uZmlnCj4gQEAgLTI4LDYgKzI4LDIxIEBAIGNv bmZpZyBQSFlfUUNPTV9FRFAKPiAgIAkgIEVuYWJsZSB0aGlzIGRyaXZlciB0byBzdXBwb3J0IHRo ZSBRdWFsY29tbSBlRFAgUEhZIGZvdW5kIGluIHZhcmlvdXMKPiAgIAkgIFF1YWxjb21tIGNoaXBz ZXRzLgo+ICAgCj4gK2NvbmZpZyBQSFlfUUNPTV9NSVBJX0NTSTIKPiArCXRyaXN0YXRlICJRdWFs Y29tbSBNSVBJIENTSTIgUEhZIGRyaXZlciIKPiArCWRlcGVuZHMgb24gQVJDSF9RQ09NIHx8IENP TVBJTEVfVEVTVAo+ICsJZGVwZW5kcyBvbiBPRgo+ICsJZGVwZW5kcyBvbiBQTQo+ICsJZGVwZW5k cyBvbiBQTV9PUFAKPiArCWRlcGVuZHMgb24gQ09NTU9OX0NMSwo+ICsJc2VsZWN0IEdFTkVSSUNf UEhZCj4gKwlzZWxlY3QgR0VORVJJQ19QSFlfTUlQSV9EUEhZCj4gKwloZWxwCj4gKwkgIEVuYWJs ZSB0aGlzIHRvIHN1cHBvcnQgdGhlIE1JUEkgQ1NJMiBQSFkgZHJpdmVyIGZvdW5kIGluIHZhcmlv dXMKPiArCSAgUXVhbGNvbW0gY2hpcHNldHMuIFRoaXMgUEhZIGlzIHVzZWQgdG8gY29ubmVjdCBN SVBJIENTSTIKPiArCSAgY2FtZXJhIHNlbnNvcnMgdG8gdGhlIENTSSBEZWNvZGVyIGluIHRoZSBR dWFsY29tbSBDYW1lcmEgU3Vic3lzdGVtCj4gKwkgIENBTVNTLgo+ICsKPiAgIGNvbmZpZyBQSFlf UUNPTV9JUFE0MDE5X1VTQgo+ICAgCXRyaXN0YXRlICJRdWFsY29tbSBJUFE0MDE5IFVTQiBQSFkg ZHJpdmVyIgo+ICAgCWRlcGVuZHMgb24gT0YgJiYgKEFSQ0hfUUNPTSB8fCBDT01QSUxFX1RFU1Qp Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L3F1YWxjb21tL01ha2VmaWxlIGIvZHJpdmVycy9w aHkvcXVhbGNvbW0vTWFrZWZpbGUKPiBpbmRleCBiNzFhNmEwYmVkM2YxLi4zODJjYjU5NGIwNmI2 IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvcGh5L3F1YWxjb21tL01ha2VmaWxlCj4gKysrIGIvZHJp dmVycy9waHkvcXVhbGNvbW0vTWFrZWZpbGUKPiBAQCAtNiw2ICs2LDExIEBAIG9iai0kKENPTkZJ R19QSFlfUUNPTV9JUFE0MDE5X1VTQikJKz0gcGh5LXFjb20taXBxNDAxOS11c2Iubwo+ICAgb2Jq LSQoQ09ORklHX1BIWV9RQ09NX0lQUTgwNlhfU0FUQSkJKz0gcGh5LXFjb20taXBxODA2eC1zYXRh Lm8KPiAgIG9iai0kKENPTkZJR19QSFlfUUNPTV9NMzFfVVNCKQkJKz0gcGh5LXFjb20tbTMxLm8K PiAgIG9iai0kKENPTkZJR19QSFlfUUNPTV9NMzFfRVVTQikJCSs9IHBoeS1xY29tLW0zMS1ldXNi Mi5vCj4gKwo+ICtwaHktcWNvbS1taXBpLWNzaTItb2JqcwkJCSs9IHBoeS1xY29tLW1pcGktY3Np Mi1jb3JlLm8gXAo+ICsJCQkJCSAgIHBoeS1xY29tLW1pcGktY3NpMi0zcGgtZHBoeS5vCj4gK29i ai0kKENPTkZJR19QSFlfUUNPTV9NSVBJX0NTSTIpCSs9IHBoeS1xY29tLW1pcGktY3NpMi5vCj4g Kwo+ICAgb2JqLSQoQ09ORklHX1BIWV9RQ09NX1BDSUUyKQkJKz0gcGh5LXFjb20tcGNpZTIubwo+ ICAgCj4gICBvYmotJChDT05GSUdfUEhZX1FDT01fUU1QX0NPTUJPKQkrPSBwaHktcWNvbS1xbXAt Y29tYm8ubyBwaHktcWNvbS1xbXAtdXNiYy5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L3F1 YWxjb21tL3BoeS1xY29tLW1pcGktY3NpMi0zcGgtZHBoeS5jIGIvZHJpdmVycy9waHkvcXVhbGNv bW0vcGh5LXFjb20tbWlwaS1jc2kyLTNwaC1kcGh5LmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ IGluZGV4IDAwMDAwMDAwMDAwMDAuLjk2NmQ3OWM5OGY5YjIKPiAtLS0gL2Rldi9udWxsCj4gKysr IGIvZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2kyLTNwaC1kcGh5LmMKPiBA QCAtMCwwICsxLDM4NSBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ ICsvKgo+ICsgKiBRdWFsY29tbSBNU00gQ2FtZXJhIFN1YnN5c3RlbSAtIENTSVBIWSBNb2R1bGUg M3BoYXNlIHYxLjAKPiArICoKPiArICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTUsIFRoZSBMaW51 eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIw MTYtMjAyNiBMaW5hcm8gTHRkLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5o Pgo+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pby5o Pgo+ICsjaW5jbHVkZSA8bGludXgvdGltZTY0Lmg+Cj4gKwo+ICsjaW5jbHVkZSAicGh5LXFjb20t bWlwaS1jc2kyLmgiCj4gKwo+ICsjZGVmaW5lIENTSVBIWV8zUEhfQ01OX0NTSV9DT01NT05fQ1RS TG4ob2Zmc2V0LCBuKQkoKG9mZnNldCkgKyAweDQgKiAobikpCj4gKyNkZWZpbmUgQ1NJUEhZXzNQ SF9DTU5fQ1NJX0NPTU1PTl9DVFJMMF9QSFlfU1dfUkVTRVQJQklUKDApCj4gKyNkZWZpbmUgQ1NJ UEhZXzNQSF9DTU5fQ1NJX0NPTU1PTl9DVFJMNV9DTEtfRU5BQkxFCUJJVCg3KQo+ICsjZGVmaW5l IENTSVBIWV8zUEhfQ01OX0NTSV9DT01NT05fQ1RSTDZfQ09NTU9OX1BXUkROX0IJQklUKDApCj4g KyNkZWZpbmUgQ1NJUEhZXzNQSF9DTU5fQ1NJX0NPTU1PTl9DVFJMNl9TSE9XX1JFVl9JRAlCSVQo MSkKPiArI2RlZmluZSBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX0NUUkwxMF9JUlFfQ0xFQVJf Q01ECUJJVCgwKQo+ICsjZGVmaW5lIENTSVBIWV8zUEhfQ01OX0NTSV9DT01NT05fU1RBVFVTbihv ZmZzZXQsIG4pCSgob2Zmc2V0KSArIDB4YjAgKyAweDQgKiAobikpCj4gKwo+ICsjZGVmaW5lIENT SVBIWV8yUEhfTE5fQ1NJXzJQSEFTRV9DVFJMOW4obikJCSgoMHgyMDAgKiAobikpICsgMHgyNCkK PiArCj4gKy8qCj4gKyAqIDMgcGhhc2UgQ1NJIGhhcyAxOSBjb21tb24gc3RhdHVzIHJlZ3Mgd2l0 aCBvbmx5IDAtMTAgYmVpbmcgdXNlZAo+ICsgKiBhbmQgMTEtMTggYmVpbmcgcmVzZXJ2ZWQuCj4g KyAqLwo+ICsjZGVmaW5lIENTSV9DT01NT05fU1RBVFVTX05VTQkJCQkxMQo+ICsvKgo+ICsgKiBU aGVyZSBhcmUgYSBudW1iZXIgb2YgY29tbW9uIGNvbnRyb2wgcmVnaXN0ZXJzCj4gKyAqIFRoZSBv ZmZzZXQgdG8gY2xlYXIgdGhlIENTSVBIWSBJUlEgc3RhdHVzIHN0YXJ0cyBAIDIyCj4gKyAqIFNv IHRvIGNsZWFyIENTSV9DT01NT05fU1RBVFVTMCB0aGlzIGlzIENTSV9DT01NT05fQ09OVFJPTDIy LCBTVEFUVVMxIGlzCj4gKyAqIENPTlRST0wyMyBhbmQgc28gb24KPiArICovCj4gKyNkZWZpbmUg Q1NJX0NUUkxfU1RBVFVTX0lOREVYCQkJCTIyCj4gKwo+ICsvKgo+ICsgKiBUaGVyZSBhcmUgNDMg Q09NTU9OX0NUUkwgcmVnaXN0ZXJzIHdpdGggcmVncyBhZnRlciAjIDMzIGJlaW5nIHJlc2VydmVk Cj4gKyAqLwo+ICsjZGVmaW5lIENTSV9DVFJMX01BWAkJCQkJMzMKPiArCj4gKyNkZWZpbmUgQ1NJ UEhZX0RFRkFVTFRfUEFSQU1TCQkJCTAKPiArI2RlZmluZSBDU0lQSFlfU0VUVExFX0NOVF9MT1dF Ul9CWVRFCQkJMgo+ICsjZGVmaW5lIENTSVBIWV9TS0VXX0NBTAkJCQkJNwo+ICsKPiArLyogNG5t IDJQSCB2IDIuMS4yIDJwNUdicHMgNCBsYW5lIERQSFkgbW9kZSAqLwo+ICtzdGF0aWMgY29uc3Qg c3RydWN0Cj4gK21pcGlfY3NpMnBoeV9sYW5lX3JlZ3MgbGFuZV9yZWdzX3gxZTgwMTAwW10gPSB7 Cj4gKwkvKiBQb3dlciB1cCBsYW5lcyAycGggbW9kZSAqLwo+ICsJey5yZWdfYWRkciA9IDB4MTAx YywgLnJlZ19kYXRhID0gMHg3YSwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9 LAo+ICsJey5yZWdfYWRkciA9IDB4MTAxOCwgLnJlZ19kYXRhID0gMHgwMSwgLnBhcmFtX3R5cGUg PSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsKPiArCXsucmVnX2FkZHIgPSAweDAwOTQsIC5y ZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiAr CXsucmVnX2FkZHIgPSAweDAwYTAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJ UEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwOTAsIC5yZWdfZGF0YSA9 IDB4MGYsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2Fk ZHIgPSAweDAwOTgsIC5yZWdfZGF0YSA9IDB4MDgsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFV TFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwOTQsIC5yZWdfZGF0YSA9IDB4MDcsIC5k ZWxheV91cyA9IDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiAr CXsucmVnX2FkZHIgPSAweDAwMzAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJ UEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwMDAsIC5yZWdfZGF0YSA9 IDB4OGUsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2Fk ZHIgPSAweDAwMzgsIC5yZWdfZGF0YSA9IDB4ZmUsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFV TFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwMmMsIC5yZWdfZGF0YSA9IDB4MDEsIC5w YXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAw MzQsIC5yZWdfZGF0YSA9IDB4MGYsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1T fSwKPiArCXsucmVnX2FkZHIgPSAweDAwMWMsIC5yZWdfZGF0YSA9IDB4MGEsIC5wYXJhbV90eXBl ID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwMTQsIC5yZWdf ZGF0YSA9IDB4NjAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsu cmVnX2FkZHIgPSAweDAwM2MsIC5yZWdfZGF0YSA9IDB4YjgsIC5wYXJhbV90eXBlID0gQ1NJUEhZ X0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwMDQsIC5yZWdfZGF0YSA9IDB4 MGMsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIg PSAweDAwMjAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRf UEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDAwMDgsIC5yZWdfZGF0YSA9IDB4MTAsIC5wYXJh bV90eXBlID0gQ1NJUEhZX1NFVFRMRV9DTlRfTE9XRVJfQllURX0sCj4gKwl7LnJlZ19hZGRyID0g MHgwMDEwLCAucmVnX2RhdGEgPSAweDUyLCAucGFyYW1fdHlwZSA9IENTSVBIWV9ERUZBVUxUX1BB UkFNU30sCj4gKwl7LnJlZ19hZGRyID0gMHgwMDk0LCAucmVnX2RhdGEgPSAweGQ3LCAucGFyYW1f dHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwMDVjLCAucmVnX2Rh dGEgPSAweDAwLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRy ID0gMHgwMDYwLCAucmVnX2RhdGEgPSAweGJkLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NB TH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwMDY0LCAucmVnX2RhdGEgPSAweDdmLCAucGFyYW1fdHlw ZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwo+ICsJey5yZWdfYWRkciA9IDB4MGU5NCwgLnJlZ19k YXRhID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5y ZWdfYWRkciA9IDB4MGVhMCwgLnJlZ19kYXRhID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlf REVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MGU5MCwgLnJlZ19kYXRhID0gMHgw ZiwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9 IDB4MGU5OCwgLnJlZ19kYXRhID0gMHgwOCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9Q QVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MGU5NCwgLnJlZ19kYXRhID0gMHgwNywgLmRlbGF5 X3VzID0gIDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsu cmVnX2FkZHIgPSAweDBlMzAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZ X0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMjgsIC5yZWdfZGF0YSA9IDB4 MDQsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIg PSAweDBlMDAsIC5yZWdfZGF0YSA9IDB4ODAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRf UEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMGMsIC5yZWdfZGF0YSA9IDB4ZmYsIC5wYXJh bV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMzgs IC5yZWdfZGF0YSA9IDB4MWYsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwK PiArCXsucmVnX2FkZHIgPSAweDBlMmMsIC5yZWdfZGF0YSA9IDB4MDEsIC5wYXJhbV90eXBlID0g Q1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMzQsIC5yZWdfZGF0 YSA9IDB4MGYsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVn X2FkZHIgPSAweDBlMWMsIC5yZWdfZGF0YSA9IDB4MGEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RF RkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMTQsIC5yZWdfZGF0YSA9IDB4NjAs IC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAw eDBlM2MsIC5yZWdfZGF0YSA9IDB4YjgsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFS QU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMDQsIC5yZWdfZGF0YSA9IDB4MGMsIC5wYXJhbV90 eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBlMjAsIC5y ZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiAr CXsucmVnX2FkZHIgPSAweDBlMDgsIC5yZWdfZGF0YSA9IDB4MTAsIC5wYXJhbV90eXBlID0gQ1NJ UEhZX1NFVFRMRV9DTlRfTE9XRVJfQllURX0sCj4gKwl7LnJlZ19hZGRyID0gMHgwZTEwLCAucmVn X2RhdGEgPSAweDUyLCAucGFyYW1fdHlwZSA9IENTSVBIWV9ERUZBVUxUX1BBUkFNU30sCj4gKwo+ ICsJey5yZWdfYWRkciA9IDB4MDQ5NCwgLnJlZ19kYXRhID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBD U0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MDRhMCwgLnJlZ19kYXRh ID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdf YWRkciA9IDB4MDQ5MCwgLnJlZ19kYXRhID0gMHgwZiwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVG QVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MDQ5OCwgLnJlZ19kYXRhID0gMHgwOCwg LnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4 MDQ5NCwgLnJlZ19kYXRhID0gMHgwNywgLmRlbGF5X3VzID0gIDB4MDEsIC5wYXJhbV90eXBlID0g Q1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0MzAsIC5yZWdfZGF0 YSA9IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVn X2FkZHIgPSAweDA0MDAsIC5yZWdfZGF0YSA9IDB4OGUsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RF RkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0MzgsIC5yZWdfZGF0YSA9IDB4ZmUs IC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAw eDA0MmMsIC5yZWdfZGF0YSA9IDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFS QU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0MzQsIC5yZWdfZGF0YSA9IDB4MGYsIC5wYXJhbV90 eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0MWMsIC5y ZWdfZGF0YSA9IDB4MGEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiAr CXsucmVnX2FkZHIgPSAweDA0MTQsIC5yZWdfZGF0YSA9IDB4NjAsIC5wYXJhbV90eXBlID0gQ1NJ UEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0M2MsIC5yZWdfZGF0YSA9 IDB4YjgsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2Fk ZHIgPSAweDA0MDQsIC5yZWdfZGF0YSA9IDB4MGMsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFV TFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0MjAsIC5yZWdfZGF0YSA9IDB4MDAsIC5w YXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA0 MDgsIC5yZWdfZGF0YSA9IDB4MTAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX1NFVFRMRV9DTlRfTE9X RVJfQllURX0sCj4gKwl7LnJlZ19hZGRyID0gMHgwNDEwLCAucmVnX2RhdGEgPSAweDUyLCAucGFy YW1fdHlwZSA9IENTSVBIWV9ERUZBVUxUX1BBUkFNU30sCj4gKwl7LnJlZ19hZGRyID0gMHgwNDk0 LCAucmVnX2RhdGEgPSAweGQ3LCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7 LnJlZ19hZGRyID0gMHgwNDVjLCAucmVnX2RhdGEgPSAweDAwLCAucGFyYW1fdHlwZSA9IENTSVBI WV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwNDYwLCAucmVnX2RhdGEgPSAweGJkLCAu cGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwNDY0LCAu cmVnX2RhdGEgPSAweDdmLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwo+ICsJ ey5yZWdfYWRkciA9IDB4MDg5NCwgLnJlZ19kYXRhID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQ SFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MDhhMCwgLnJlZ19kYXRhID0g MHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRk ciA9IDB4MDg5MCwgLnJlZ19kYXRhID0gMHgwZiwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVM VF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MDg5OCwgLnJlZ19kYXRhID0gMHgwOCwgLnBh cmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MDg5 NCwgLnJlZ19kYXRhID0gMHgwNywgLmRlbGF5X3VzID0gIDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJ UEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4MzAsIC5yZWdfZGF0YSA9 IDB4MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2Fk ZHIgPSAweDA4MDAsIC5yZWdfZGF0YSA9IDB4OGUsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFV TFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4MzgsIC5yZWdfZGF0YSA9IDB4ZmUsIC5w YXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4 MmMsIC5yZWdfZGF0YSA9IDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1T fSwKPiArCXsucmVnX2FkZHIgPSAweDA4MzQsIC5yZWdfZGF0YSA9IDB4MGYsIC5wYXJhbV90eXBl ID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4MWMsIC5yZWdf ZGF0YSA9IDB4MGEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsu cmVnX2FkZHIgPSAweDA4MTQsIC5yZWdfZGF0YSA9IDB4NjAsIC5wYXJhbV90eXBlID0gQ1NJUEhZ X0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4M2MsIC5yZWdfZGF0YSA9IDB4 YjgsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIg PSAweDA4MDQsIC5yZWdfZGF0YSA9IDB4MGMsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRf UEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4MjAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJh bV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDA4MDgs IC5yZWdfZGF0YSA9IDB4MTAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX1NFVFRMRV9DTlRfTE9XRVJf QllURX0sCj4gKwl7LnJlZ19hZGRyID0gMHgwODEwLCAucmVnX2RhdGEgPSAweDUyLCAucGFyYW1f dHlwZSA9IENTSVBIWV9ERUZBVUxUX1BBUkFNU30sCj4gKwl7LnJlZ19hZGRyID0gMHgwODk0LCAu cmVnX2RhdGEgPSAweGQ3LCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJl Z19hZGRyID0gMHgwODVjLCAucmVnX2RhdGEgPSAweDAwLCAucGFyYW1fdHlwZSA9IENTSVBIWV9T S0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwODYwLCAucmVnX2RhdGEgPSAweGJkLCAucGFy YW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwODY0LCAucmVn X2RhdGEgPSAweDdmLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwo+ICsJey5y ZWdfYWRkciA9IDB4MGM5NCwgLnJlZ19kYXRhID0gMHgwMCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlf REVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MGNhMCwgLnJlZ19kYXRhID0gMHgw MCwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9 IDB4MGM5MCwgLnJlZ19kYXRhID0gMHgwZiwgLnBhcmFtX3R5cGUgPSBDU0lQSFlfREVGQVVMVF9Q QVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MGM5OCwgLnJlZ19kYXRhID0gMHgwOCwgLnBhcmFt X3R5cGUgPSBDU0lQSFlfREVGQVVMVF9QQVJBTVN9LAo+ICsJey5yZWdfYWRkciA9IDB4MGM5NCwg LnJlZ19kYXRhID0gMHgwNywgLmRlbGF5X3VzID0gIDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZ X0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMzAsIC5yZWdfZGF0YSA9IDB4 MDAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIg PSAweDBjMDAsIC5yZWdfZGF0YSA9IDB4OGUsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRf UEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMzgsIC5yZWdfZGF0YSA9IDB4ZmUsIC5wYXJh bV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMmMs IC5yZWdfZGF0YSA9IDB4MDEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwK PiArCXsucmVnX2FkZHIgPSAweDBjMzQsIC5yZWdfZGF0YSA9IDB4MGYsIC5wYXJhbV90eXBlID0g Q1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMWMsIC5yZWdfZGF0 YSA9IDB4MGEsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVn X2FkZHIgPSAweDBjMTQsIC5yZWdfZGF0YSA9IDB4NjAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RF RkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjM2MsIC5yZWdfZGF0YSA9IDB4Yjgs IC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAw eDBjMDQsIC5yZWdfZGF0YSA9IDB4MGMsIC5wYXJhbV90eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFS QU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMjAsIC5yZWdfZGF0YSA9IDB4MDAsIC5wYXJhbV90 eXBlID0gQ1NJUEhZX0RFRkFVTFRfUEFSQU1TfSwKPiArCXsucmVnX2FkZHIgPSAweDBjMDgsIC5y ZWdfZGF0YSA9IDB4MTAsIC5wYXJhbV90eXBlID0gQ1NJUEhZX1NFVFRMRV9DTlRfTE9XRVJfQllU RX0sCj4gKwl7LnJlZ19hZGRyID0gMHgwYzEwLCAucmVnX2RhdGEgPSAweDUyLCAucGFyYW1fdHlw ZSA9IENTSVBIWV9ERUZBVUxUX1BBUkFNU30sCj4gKwl7LnJlZ19hZGRyID0gMHgwYzk0LCAucmVn X2RhdGEgPSAweGQ3LCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19h ZGRyID0gMHgwYzVjLCAucmVnX2RhdGEgPSAweDAwLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VX X0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwYzYwLCAucmVnX2RhdGEgPSAweGJkLCAucGFyYW1f dHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gKwl7LnJlZ19hZGRyID0gMHgwYzY0LCAucmVnX2Rh dGEgPSAweDdmLCAucGFyYW1fdHlwZSA9IENTSVBIWV9TS0VXX0NBTH0sCj4gK307Cj4gKwo+ICtz dGF0aWMgaW5saW5lIGNvbnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlX3JlZ3MgKgo+ICtj c2kycGh5X2Rldl90b19yZWdzKHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlICpjc2kycGh5KQo+ ICt7Cj4gKwlyZXR1cm4gJmNzaTJwaHktPnNvY19jZmctPnJlZ19pbmZvOwo+ICt9Cj4gKwo+ICtz dGF0aWMgdm9pZCBwaHlfcWNvbV9taXBpX2NzaTJfaHdfdmVyc2lvbl9yZWFkKHN0cnVjdCBtaXBp X2NzaTJwaHlfZGV2aWNlICpjc2kycGh5KQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3QgbWlwaV9jc2ky cGh5X2RldmljZV9yZWdzICpyZWdzID0gY3NpMnBoeV9kZXZfdG9fcmVncyhjc2kycGh5KTsKPiAr CXUzMiB0bXA7Cj4gKwo+ICsJd3JpdGVsKENTSVBIWV8zUEhfQ01OX0NTSV9DT01NT05fQ1RSTDZf U0hPV19SRVZfSUQsIGNzaTJwaHktPmJhc2UgKwo+ICsJICAgICAgIENTSVBIWV8zUEhfQ01OX0NT SV9DT01NT05fQ1RSTG4ocmVncy0+Y29tbW9uX3JlZ3Nfb2Zmc2V0LCA2KSk7Cj4gKwo+ICsJdG1w ID0gcmVhZGxfcmVsYXhlZChjc2kycGh5LT5iYXNlICsKPiArCQkJICAgIENTSVBIWV8zUEhfQ01O X0NTSV9DT01NT05fU1RBVFVTbihyZWdzLT5jb21tb25fcmVnc19vZmZzZXQsIDEyKSk7Cj4gKwlj c2kycGh5LT5od192ZXJzaW9uID0gdG1wOwo+ICsKPiArCXRtcCA9IHJlYWRsX3JlbGF4ZWQoY3Np MnBoeS0+YmFzZSArCj4gKwkJCSAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX1NUQVRVU24o cmVncy0+Y29tbW9uX3JlZ3Nfb2Zmc2V0LCAxMykpOwo+ICsJY3NpMnBoeS0+aHdfdmVyc2lvbiB8 PSAodG1wIDw8IDgpICYgMHhGRjAwOwo+ICsKPiArCXRtcCA9IHJlYWRsX3JlbGF4ZWQoY3NpMnBo eS0+YmFzZSArCj4gKwkJCSAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX1NUQVRVU24ocmVn cy0+Y29tbW9uX3JlZ3Nfb2Zmc2V0LCAxNCkpOwo+ICsJY3NpMnBoeS0+aHdfdmVyc2lvbiB8PSAo dG1wIDw8IDE2KSAmIDB4RkYwMDAwOwo+ICsKPiArCXRtcCA9IHJlYWRsX3JlbGF4ZWQoY3NpMnBo eS0+YmFzZSArCj4gKwkJCSAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX1NUQVRVU24ocmVn cy0+Y29tbW9uX3JlZ3Nfb2Zmc2V0LCAxNSkpOwo+ICsJY3NpMnBoeS0+aHdfdmVyc2lvbiB8PSAo dG1wIDw8IDI0KSAmIDB4RkYwMDAwMDA7Cj4gKwo+ICsJZGV2X2RiZ19vbmNlKGNzaTJwaHktPmRl diwgIkNTSVBIWSAzUEggSFcgVmVyc2lvbiA9IDB4JTA4eFxuIiwgY3NpMnBoeS0+aHdfdmVyc2lv bik7Cj4gK30KPiArCj4gKy8qCj4gKyAqIHBoeV9xY29tX21pcGlfY3NpMl9yZXNldCAtIFBlcmZv cm0gc29mdHdhcmUgcmVzZXQgb24gQ1NJUEhZIG1vZHVsZQo+ICsgKiBAcGh5X3Fjb21fbWlwaV9j c2kyOiBDU0lQSFkgZGV2aWNlCj4gKyAqLwo+ICtzdGF0aWMgdm9pZCBwaHlfcWNvbV9taXBpX2Nz aTJfcmVzZXQoc3RydWN0IG1pcGlfY3NpMnBoeV9kZXZpY2UgKmNzaTJwaHkpCj4gK3sKPiArCWNv bnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlX3JlZ3MgKnJlZ3MgPSBjc2kycGh5X2Rldl90 b19yZWdzKGNzaTJwaHkpOwo+ICsKPiArCXdyaXRlbChDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9O X0NUUkwwX1BIWV9TV19SRVNFVCwKPiArCSAgICAgICBjc2kycGh5LT5iYXNlICsgQ1NJUEhZXzNQ SF9DTU5fQ1NJX0NPTU1PTl9DVFJMbihyZWdzLT5jb21tb25fcmVnc19vZmZzZXQsIDApKTsKPiAr CXVzbGVlcF9yYW5nZSg1MDAwLCA4MDAwKTsKPiArCXdyaXRlbCgweDAsIGNzaTJwaHktPmJhc2Ug Kwo+ICsJICAgICAgIENTSVBIWV8zUEhfQ01OX0NTSV9DT01NT05fQ1RSTG4ocmVncy0+Y29tbW9u X3JlZ3Nfb2Zmc2V0LCAwKSk7Cj4gK30KPiArCj4gKy8qCj4gKyAqIHBoeV9xY29tX21pcGlfY3Np Ml9zZXR0bGVfY250X2NhbGMgLSBDYWxjdWxhdGUgc2V0dGxlIGNvdW50IHZhbHVlCj4gKyAqCj4g KyAqIEhlbHBlciBmdW5jdGlvbiB0byBjYWxjdWxhdGUgc2V0dGxlIGNvdW50IHZhbHVlLiBUaGlz IGlzCj4gKyAqIGJhc2VkIG9uIHRoZSBDU0kyIFRfaHNfc2V0dGxlIHBhcmFtZXRlciB3aGljaCBp biB0dXJuCj4gKyAqIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gdGhlIENTSTIgdHJhbnNtaXR0ZXIg bGluayBmcmVxdWVuY3kuCj4gKyAqCj4gKyAqIFJldHVybiBzZXR0bGUgY291bnQuCj4gKyAqLwo+ ICtzdGF0aWMgdTggcGh5X3Fjb21fbWlwaV9jc2kyX3NldHRsZV9jbnRfY2FsYyhzNjQgbGlua19m cmVxLCB1MzIgdGltZXJfY2xrX3JhdGUpCj4gK3sKPiArCXUzMiB0X2hzX3ByZXBhcmVfbWF4X3Bz Owo+ICsJdTMyIHRpbWVyX3BlcmlvZF9wczsKPiArCXUzMiB0X2hzX3NldHRsZV9wczsKPiArCXU4 IHNldHRsZV9jbnQ7Cj4gKwl1MzIgdWlfcHM7Cj4gKwo+ICsJdWlfcHMgPSBkaXY2NF91NjQoUFNF Q19QRVJfU0VDLCBsaW5rX2ZyZXEpOwo+ICsJdWlfcHMgLz0gMjsKPiArCXRfaHNfcHJlcGFyZV9t YXhfcHMgPSA4NTAwMCArIDYgKiB1aV9wczsKPiArCXRfaHNfc2V0dGxlX3BzID0gdF9oc19wcmVw YXJlX21heF9wczsKPiArCj4gKwl0aW1lcl9wZXJpb2RfcHMgPSBkaXZfdTY0KFBTRUNfUEVSX1NF QywgdGltZXJfY2xrX3JhdGUpOwo+ICsKPiArCWlmICgodF9oc19zZXR0bGVfcHMgLyB0aW1lcl9w ZXJpb2RfcHMpIDwgNikKPiArCQlyZXR1cm4gMDsKPiArCj4gKwlzZXR0bGVfY250ID0gdF9oc19z ZXR0bGVfcHMgLyB0aW1lcl9wZXJpb2RfcHMgLSA2Owo+ICsKPiArCXJldHVybiBzZXR0bGVfY250 Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZAo+ICtwaHlfcWNvbV9taXBpX2NzaTJfZ2VuMl9jb25m aWdfbGFuZXMoc3RydWN0IG1pcGlfY3NpMnBoeV9kZXZpY2UgKmNzaTJwaHksCj4gKwkJCQkgICAg IHU4IHNldHRsZV9jbnQpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNl X3JlZ3MgKnJlZ3MgPSBjc2kycGh5X2Rldl90b19yZWdzKGNzaTJwaHkpOwo+ICsJY29uc3Qgc3Ry dWN0IG1pcGlfY3NpMnBoeV9sYW5lX3JlZ3MgKnIgPSByZWdzLT5pbml0X3NlcTsKPiArCWludCBp LCBhcnJheV9zaXplID0gcmVncy0+bGFuZV9hcnJheV9zaXplOwo+ICsJdTMyIHZhbDsKPiArCj4g Kwlmb3IgKGkgPSAwOyBpIDwgYXJyYXlfc2l6ZTsgaSsrLCByKyspIHsKPiArCQlzd2l0Y2ggKHIt PnBhcmFtX3R5cGUpIHsKPiArCQljYXNlIENTSVBIWV9TRVRUTEVfQ05UX0xPV0VSX0JZVEU6Cj4g KwkJCXZhbCA9IHNldHRsZV9jbnQgJiAweGZmOwo+ICsJCQlicmVhazsKPiArCQljYXNlIENTSVBI WV9TS0VXX0NBTDoKPiArCQkJLyogVE9ETzogc3VwcG9ydCBhcHBsaWNhdGlvbiBvZiBza2V3IGZy b20gZHQgZmxhZyAqLwo+ICsJCQljb250aW51ZTsKPiArCQlkZWZhdWx0Ogo+ICsJCQl2YWwgPSBy LT5yZWdfZGF0YTsKPiArCQkJYnJlYWs7Cj4gKwkJfQo+ICsJCXdyaXRlbCh2YWwsIGNzaTJwaHkt PmJhc2UgKyByLT5yZWdfYWRkcik7Cj4gKwkJaWYgKHItPmRlbGF5X3VzKQo+ICsJCQl1ZGVsYXko ci0+ZGVsYXlfdXMpOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHBoeV9xY29tX21pcGlf Y3NpMl9sYW5lc19lbmFibGUoc3RydWN0IG1pcGlfY3NpMnBoeV9kZXZpY2UgKmNzaTJwaHksCj4g KwkJCQkJICAgc3RydWN0IG1pcGlfY3NpMnBoeV9zdHJlYW1fY2ZnICpjZmcpCj4gK3sKPiArCWNv bnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlX3JlZ3MgKnJlZ3MgPSBjc2kycGh5X2Rldl90 b19yZWdzKGNzaTJwaHkpOwo+ICsJc3RydWN0IG1pcGlfY3NpMnBoeV9sYW5lc19jZmcgKmxhbmVf Y2ZnID0gJmNmZy0+bGFuZV9jZmc7Cj4gKwl1OCBzZXR0bGVfY250Owo+ICsJdTggdmFsOwo+ICsJ aW50IGk7Cj4gKwo+ICsJaWYgKGNmZy0+bGlua19mcmVxIDw9IDApCj4gKwkJcmV0dXJuIC1FSU5W QUw7CgpUaGUgZXJyb3IgY29uZGl0aW9uIHNob3VsZCBub3QgYmUgbWV0IGF0IHRoaXMgc3RhZ2Us IHRoZSBjaGVjayBpcyB0byBiZSByZW1vdmVkLgoKPiArCj4gKwlzZXR0bGVfY250ID0gcGh5X3Fj b21fbWlwaV9jc2kyX3NldHRsZV9jbnRfY2FsYyhjZmctPmxpbmtfZnJlcSwgY3NpMnBoeS0+dGlt ZXJfY2xrX3JhdGUpOwo+ICsJaWYgKCFzZXR0bGVfY250KQo+ICsJCXJldHVybiAtRU5PREVWOwoK SXQgc2VlbXMgdG8gYmUgYW4gb3ZlcmtpbGwgdG8gcmVjb21wdXRlICdzZXR0bGVfY250JyBldmVy eSB0aW1lIHdoZW4KLmxhbmVzX2VuYWJsZSgpIGlzIGNhbGxlZCwgdGhlIHZhbHVlIGNhbiBiZSBj b21wdXRlZCBvbmNlIGF0IHRoZSBpbml0IHN0YWdlLgoKPiArCj4gKwkvKgo+ICsJICogQ1NJX0NP TU1PTl9DVFJMNSBpcyBhIHBoeXNpY2FsIGxhbmUgcG93ZXItdXAgYml0bWFwOgo+ICsJICogLSBC aXRzIFswLDIsNCw2XSDihpIgRC1QSFkgZGF0YSBsYW5lcyhMTjAsIExOMiwgTE40LCBMTjYpCj4g KwkgKiAtIEJpdHMgWzEsMyw1XSDihpIgQy1QSFkgdHJpbyBsYW5lcyhMTjEsIExOMywgTE41KQo+ ICsJICogLSBCaXQgWzddIOKGkiBELVBIWSBjbG9jayBsYW5lKExOQ0spIGRlZGljYXRlZCBjbG9j ayBlbmFibGUKPiArCSAqLwo+ICsJdmFsID0gQklUKGxhbmVfY2ZnLT5jbGsucG9zKTsKPiArCWZv ciAoaSA9IDA7IGkgPCBjZmctPm51bV9kYXRhX2xhbmVzOyBpKyspCj4gKwkJdmFsIHw9IEJJVChs YW5lX2NmZy0+ZGF0YVtpXS5wb3MgKiAyKTsKPiArCj4gKwl3cml0ZWwodmFsLCBjc2kycGh5LT5i YXNlICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX0NUUkxuKHJlZ3MtPmNv bW1vbl9yZWdzX29mZnNldCwgNSkpOwo+ICsKPiArCS8qIExhbmUgY29uZmlndXJhdGlvbiBmb3Ig cG9sYXJpdHkgQCBDU0lQSFktYmFzZSArIENUUkw5ICovCj4gKwlmb3IgKGkgPSAwOyBpIDwgY2Zn LT5udW1fZGF0YV9sYW5lczsgaSsrKSB7Cj4gKwkJaWYgKGxhbmVfY2ZnLT5kYXRhW2ldLnBvbCkg ewo+ICsJCQl1OCBwb3MgPSBsYW5lX2NmZy0+ZGF0YVtpXS5wb3M7Cj4gKwo+ICsJCQl3cml0ZWwo QklUKDIpLCBjc2kycGh5LT5iYXNlICsgQ1NJUEhZXzJQSF9MTl9DU0lfMlBIQVNFX0NUUkw5bihw b3MgKiAyKSk7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWlmIChsYW5lX2NmZy0+Y2xrLnBvbCkKPiAr CQl3cml0ZWwoQklUKDIpLCBjc2kycGh5LT5iYXNlICsgQ1NJUEhZXzJQSF9MTl9DU0lfMlBIQVNF X0NUUkw5bihsYW5lX2NmZy0+Y2xrLnBvcykpOwo+ICsKPiArCXZhbCA9IENTSVBIWV8zUEhfQ01O X0NTSV9DT01NT05fQ1RSTDZfQ09NTU9OX1BXUkROX0I7Cj4gKwl3cml0ZWwodmFsLCBjc2kycGh5 LT5iYXNlICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX0NUUkxuKHJlZ3Mt PmNvbW1vbl9yZWdzX29mZnNldCwgNikpOwo+ICsKPiArCXZhbCA9IDB4MDI7Cj4gKwl3cml0ZWwo dmFsLCBjc2kycGh5LT5iYXNlICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9O X0NUUkxuKHJlZ3MtPmNvbW1vbl9yZWdzX29mZnNldCwgNykpOwo+ICsKPiArCXZhbCA9IDB4MDA7 Cj4gKwl3cml0ZWwodmFsLCBjc2kycGh5LT5iYXNlICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NN Tl9DU0lfQ09NTU9OX0NUUkxuKHJlZ3MtPmNvbW1vbl9yZWdzX29mZnNldCwgMCkpOwo+ICsKPiAr CXBoeV9xY29tX21pcGlfY3NpMl9nZW4yX2NvbmZpZ19sYW5lcyhjc2kycGh5LCBzZXR0bGVfY250 KTsKPiArCj4gKwkvKiBJUlFfTUFTSyByZWdpc3RlcnMgLSBkaXNhYmxlIGFsbCBpbnRlcnJ1cHRz ICovCj4gKwlmb3IgKGkgPSBDU0lfQ09NTU9OX1NUQVRVU19OVU07IGkgPCBDU0lfQ1RSTF9TVEFU VVNfSU5ERVg7IGkrKykgewo+ICsJCXdyaXRlbCgwLCBjc2kycGh5LT5iYXNlICsKPiArCQkgICAg ICAgQ1NJUEhZXzNQSF9DTU5fQ1NJX0NPTU1PTl9DVFJMbihyZWdzLT5jb21tb25fcmVnc19vZmZz ZXQsIGkpKTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQK PiArcGh5X3Fjb21fbWlwaV9jc2kyX2xhbmVzX2Rpc2FibGUoc3RydWN0IG1pcGlfY3NpMnBoeV9k ZXZpY2UgKmNzaTJwaHksCj4gKwkJCQkgc3RydWN0IG1pcGlfY3NpMnBoeV9zdHJlYW1fY2ZnICpj ZmcpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlX3JlZ3MgKnJlZ3Mg PSBjc2kycGh5X2Rldl90b19yZWdzKGNzaTJwaHkpOwo+ICsKPiArCXdyaXRlbCgwLCBjc2kycGh5 LT5iYXNlICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX0NUUkxuKHJlZ3Mt PmNvbW1vbl9yZWdzX29mZnNldCwgNSkpOwo+ICsKPiArCXdyaXRlbCgwLCBjc2kycGh5LT5iYXNl ICsKPiArCSAgICAgICBDU0lQSFlfM1BIX0NNTl9DU0lfQ09NTU9OX0NUUkxuKHJlZ3MtPmNvbW1v bl9yZWdzX29mZnNldCwgNikpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG1pcGlf Y3NpMnBoeV9od19vcHMgcGh5X3Fjb21fbWlwaV9jc2kyX29wc18zcGhfMV8wID0gewo+ICsJLmh3 X3ZlcnNpb25fcmVhZCA9IHBoeV9xY29tX21pcGlfY3NpMl9od192ZXJzaW9uX3JlYWQsCj4gKwku cmVzZXQgPSBwaHlfcWNvbV9taXBpX2NzaTJfcmVzZXQsCj4gKwkubGFuZXNfZW5hYmxlID0gcGh5 X3Fjb21fbWlwaV9jc2kyX2xhbmVzX2VuYWJsZSwKPiArCS5sYW5lc19kaXNhYmxlID0gcGh5X3Fj b21fbWlwaV9jc2kyX2xhbmVzX2Rpc2FibGUsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3QgY2hh ciAqIGNvbnN0IHgxZV9jbGtzW10gPSB7Cj4gKwkiY29yZSIsCj4gKwkidGltZXIiLAo+ICsJImFo YiIKPiArfTsKPiArCj4gK3N0YXRpYyBjb25zdCBjaGFyICogY29uc3QgeDFlX3N1cHBsaWVzW10g PSB7Cj4gKwkidmRkYS0wcDkiLAo+ICsJInZkZGEtMXAyIgo+ICt9Owo+ICsKPiArc3RhdGljIHN0 cnVjdCBtaXBpX2NzaTJfZ2VucGQgeDFlX2dlbnBkc1tdID0gewo+ICsJeyAubmFtZSA9ICJ0b3Ai LCAuc2NhbGVkID0gZmFsc2UgfSwKPiArCXsgLm5hbWUgPSAibW1jeCIsIC5zY2FsZWQgPSB0cnVl IH0sCj4gKwl7IC5uYW1lID0gIm14IiwgLnNjYWxlZCA9IHRydWUgfSwKPiArfTsKPiArCj4gK2Nv bnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfc29jX2NmZyBtaXBpX2NzaTJfZHBoeV80bm1feDFlID0g ewo+ICsJLm9wcyA9ICZwaHlfcWNvbV9taXBpX2NzaTJfb3BzXzNwaF8xXzAsCj4gKwkucmVnX2lu Zm8gPSB7Cj4gKwkJLmluaXRfc2VxID0gbGFuZV9yZWdzX3gxZTgwMTAwLAo+ICsJCS5sYW5lX2Fy cmF5X3NpemUgPSBBUlJBWV9TSVpFKGxhbmVfcmVnc194MWU4MDEwMCksCj4gKwkJLmNvbW1vbl9y ZWdzX29mZnNldCA9IDB4MTAwMCwKPiArCX0sCj4gKwkuc3VwcGx5X25hbWVzID0gKGNvbnN0IGNo YXIgKiopeDFlX3N1cHBsaWVzLAo+ICsJLm51bV9zdXBwbGllcyA9IEFSUkFZX1NJWkUoeDFlX3N1 cHBsaWVzKSwKPiArCS5jbGtfbmFtZXMgPSAoY29uc3QgY2hhciAqKil4MWVfY2xrcywKPiArCS5u dW1fY2xrID0gQVJSQVlfU0laRSh4MWVfY2xrcyksCj4gKwkuZ2VucGRzID0geDFlX2dlbnBkcywK PiArCS5udW1fZ2VucGRzID0gQVJSQVlfU0laRSh4MWVfZ2VucGRzKSwKPiArfTsKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2kyLWNvcmUuYyBiL2Ry aXZlcnMvcGh5L3F1YWxjb21tL3BoeS1xY29tLW1pcGktY3NpMi1jb3JlLmMKPiBuZXcgZmlsZSBt b2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMDAuLjI0Y2NkMzI2NDY4NmYKPiAtLS0gL2Rl di9udWxsCj4gKysrIGIvZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2kyLWNv cmUuYwo+IEBAIC0wLDAgKzEsNDYyIEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBH UEwtMi4wCj4gKy8qCj4gKyAqIENvcHlyaWdodCAoYykgMjAyNiwgTGluYXJvIEx0ZC4KPiArICov Cj4gKwo+ICsjaW5jbHVkZSA8ZHQtYmluZGluZ3MvbWVkaWEvdmlkZW8taW50ZXJmYWNlcy5oPgo+ ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+ICsj aW5jbHVkZSA8bGludXgvZXJyLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pby5oPgo+ICsjaW5jbHVk ZSA8bGludXgva2VybmVsLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wbV9vcHAuaD4KPiArI2luY2x1ZGUg PGxpbnV4L3BoeS9waHkuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BoeS9waHktbWlwaS1kcGh5Lmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L3BtX2RvbWFpbi5oPgo+ICsjaW5jbHVkZSA8bGludXgvcG1fcnVudGltZS5oPgo+ICsjaW5jbHVk ZSA8bGludXgvcmVnbWFwLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWd1bGF0b3IvY29uc3VtZXIu aD4KPiArI2luY2x1ZGUgPGxpbnV4L3Jlc2V0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+ Cj4gKwo+ICsjaW5jbHVkZSAicGh5LXFjb20tbWlwaS1jc2kyLmgiCj4gKwo+ICtzdGF0aWMgaW50 Cj4gK3BoeV9xY29tX21pcGlfY3NpMl9zZXRfY2xvY2tfcmF0ZXMoc3RydWN0IG1pcGlfY3NpMnBo eV9kZXZpY2UgKmNzaTJwaHksCj4gKwkJCQkgICBzNjQgbGlua19mcmVxKQo+ICt7Cj4gKwlzdHJ1 Y3QgZGV2aWNlICpkZXYgPSBjc2kycGh5LT5kZXY7Cj4gKwl1bnNpZ25lZCBsb25nIG9wcF9yYXRl ID0gbGlua19mcmVxIC8gNDsKPiArCXN0cnVjdCBkZXZfcG1fb3BwICpvcHA7Cj4gKwlsb25nIHRp bWVyX3JhdGU7Cj4gKwlpbnQgaSwgcHN0YXRlOwo+ICsJaW50IHJldDsKPiArCj4gKwlvcHAgPSBk ZXZfcG1fb3BwX2ZpbmRfZnJlcV9jZWlsKGRldiwgJm9wcF9yYXRlKTsKPiArCWlmIChJU19FUlIo b3BwKSkgewo+ICsJCWRldl9lcnIoY3NpMnBoeS0+ZGV2LCAiQ291bGRuJ3QgZmluZCBjZWlsaW5n IGZvciAlbGxkIEh6XG4iLAo+ICsJCQlsaW5rX2ZyZXEpOwo+ICsJCXJldHVybiBQVFJfRVJSKG9w cCk7Cj4gKwl9Cj4gKwo+ICsJcHN0YXRlID0gMDsKPiArCWZvciAoaSA9IDA7IGkgPCBjc2kycGh5 LT5wZF9saXN0LT5udW1fcGRzOyBpKyspIHsKPiArCQl1bnNpZ25lZCBpbnQgcGVyZjsKPiArCj4g KwkJaWYgKCFjc2kycGh5LT5zb2NfY2ZnLT5nZW5wZHNbaV0uc2NhbGVkKQo+ICsJCQljb250aW51 ZTsKPiArCj4gKwkJcGVyZiA9IGRldl9wbV9vcHBfZ2V0X3JlcXVpcmVkX3BzdGF0ZShvcHAsIHBz dGF0ZSk7Cj4gKwkJcHN0YXRlICs9IDE7Cj4gKwo+ICsJCXJldCA9IGRldl9wbV9nZW5wZF9zZXRf cGVyZm9ybWFuY2Vfc3RhdGUoY3NpMnBoeS0+cGRfbGlzdC0+cGRfZGV2c1tpXSwgcGVyZik7Cj4g KwkJaWYgKHJldCkgewo+ICsJCQlkZXZfZXJyKGNzaTJwaHktPmRldiwgIkNvdWxkbid0IHNldCBw ZXJmIHN0YXRlICV1XG4iLAo+ICsJCQkJcGVyZik7Cj4gKwkJCWRldl9wbV9vcHBfcHV0KG9wcCk7 Cj4gKwkJCWdvdG8gdW5zZXRfcHN0YXRlOwo+ICsJCX0KPiArCX0KPiArCWRldl9wbV9vcHBfcHV0 KG9wcCk7Cj4gKwo+ICsJcmV0ID0gZGV2X3BtX29wcF9zZXRfcmF0ZShkZXYsIG9wcF9yYXRlKTsK PiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGNzaTJwaHktPmRldiwgImRldl9wbV9vcHBfc2V0 X3JhdGUoKSBmYWlsXG4iKTsKPiArCQlnb3RvIHVuc2V0X29wcF9yYXRlOwo+ICsJfQo+ICsKPiAr CXRpbWVyX3JhdGUgPSBjbGtfcm91bmRfcmF0ZShjc2kycGh5LT50aW1lcl9jbGssIGxpbmtfZnJl cSAvIDQpOwo+ICsJaWYgKHRpbWVyX3JhdGUgPD0gMCkgewo+ICsJCXJldCA9IC1FTk9ERVY7Cj4g KwkJZ290byB1bnNldF9vcHBfcmF0ZTsKPiArCX0KPiArCj4gKwlyZXQgPSBjbGtfc2V0X3JhdGUo Y3NpMnBoeS0+dGltZXJfY2xrLCB0aW1lcl9yYXRlKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byB1 bnNldF9vcHBfcmF0ZTsKPiArCj4gKwljc2kycGh5LT50aW1lcl9jbGtfcmF0ZSA9IHRpbWVyX3Jh dGU7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gKwo+ICt1bnNldF9vcHBfcmF0ZToKPiArCWRldl9wbV9v cHBfc2V0X3JhdGUoZGV2LCAwKTsKPiArCj4gK3Vuc2V0X3BzdGF0ZToKPiArCXdoaWxlIChpLS0p IHsKPiArCQlpZiAoIWNzaTJwaHktPnNvY19jZmctPmdlbnBkc1tpXS5zY2FsZWQpCj4gKwkJCWNv bnRpbnVlOwo+ICsKPiArCQlkZXZfcG1fZ2VucGRfc2V0X3BlcmZvcm1hbmNlX3N0YXRlKGNzaTJw aHktPnBkX2xpc3QtPnBkX2RldnNbaV0sIDApOwo+ICsJfQo+ICsKPiArCXJldHVybiByZXQ7Cj4g K30KPiArCj4gK3N0YXRpYyBpbnQgcGh5X3Fjb21fbWlwaV9jc2kyX2NvbmZpZ3VyZShzdHJ1Y3Qg cGh5ICpwaHksCj4gKwkJCQkJdW5pb24gcGh5X2NvbmZpZ3VyZV9vcHRzICpvcHRzKQo+ICt7Cj4g KwlzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3NpMnBoeSA9IHBoeV9nZXRfZHJ2ZGF0YShw aHkpOwo+ICsJc3RydWN0IHBoeV9jb25maWd1cmVfb3B0c19taXBpX2RwaHkgKmRwaHlfY2ZnID0g Jm9wdHMtPm1pcGlfZHBoeTsKPiArCXN0cnVjdCBtaXBpX2NzaTJwaHlfc3RyZWFtX2NmZyAqc3Ry ZWFtX2NmZyA9ICZjc2kycGh5LT5zdHJlYW1fY2ZnOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQg PSBwaHlfbWlwaV9kcGh5X2NvbmZpZ192YWxpZGF0ZShkcGh5X2NmZyk7Cj4gKwlpZiAocmV0KQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJaWYgKGRwaHlfY2ZnLT5sYW5lcyA8IDEgfHwgZHBoeV9j ZmctPmxhbmVzID4gQ1NJMl9NQVhfREFUQV9MQU5FUykKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiAr Cj4gKwlzdHJlYW1fY2ZnLT5saW5rX2ZyZXEgPSBkcGh5X2NmZy0+aHNfY2xrX3JhdGU7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcGh5X3Fjb21fbWlwaV9jc2kyX3Nl dF9tb2RlKHN0cnVjdCBwaHkgKnBoeSwKPiArCQkJCSAgICAgICBlbnVtIHBoeV9tb2RlIG1vZGUs IGludCBzdWJtb2RlKQo+ICt7Cj4gKwlzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3NpMnBo eSA9IHBoeV9nZXRfZHJ2ZGF0YShwaHkpOwo+ICsKPiArCWlmIChtb2RlICE9IFBIWV9NT0RFX01J UElfRFBIWSkKPiArCQlyZXR1cm4gLUVPUE5PVFNVUFA7Cj4gKwo+ICsJY3NpMnBoeS0+cGh5X21v ZGUgPSBtb2RlOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcGh5X3Fjb21f bWlwaV9jc2kyX3Bvd2VyX29uKHN0cnVjdCBwaHkgKnBoeSkKPiArewo+ICsJc3RydWN0IG1pcGlf Y3NpMnBoeV9kZXZpY2UgKmNzaTJwaHkgPSBwaHlfZ2V0X2RydmRhdGEocGh5KTsKPiArCWNvbnN0 IHN0cnVjdCBtaXBpX2NzaTJwaHlfaHdfb3BzICpvcHMgPSBjc2kycGh5LT5zb2NfY2ZnLT5vcHM7 Cj4gKwlpbnQgaSwgcmV0Owo+ICsKPiArCXJldCA9IHJlZ3VsYXRvcl9idWxrX2VuYWJsZShjc2ky cGh5LT5zb2NfY2ZnLT5udW1fc3VwcGxpZXMsCj4gKwkJCQkgICAgY3NpMnBoeS0+c3VwcGxpZXMp Owo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9IHBtX3J1bnRpbWVf cmVzdW1lX2FuZF9nZXQoY3NpMnBoeS0+ZGV2KTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCWdvdG8g ZGlzYWJsZV9yZWd1bGF0b3JzOwo+ICsKPiArCXJldCA9IHBoeV9xY29tX21pcGlfY3NpMl9zZXRf Y2xvY2tfcmF0ZXMoY3NpMnBoeSwgY3NpMnBoeS0+c3RyZWFtX2NmZy5saW5rX2ZyZXEpOwo+ICsJ aWYgKHJldCkKPiArCQlnb3RvIHBvd2Vyb2ZmX3BoeTsKPiArCj4gKwlyZXQgPSBjbGtfYnVsa19w cmVwYXJlX2VuYWJsZShjc2kycGh5LT5zb2NfY2ZnLT5udW1fY2xrLAo+ICsJCQkJICAgICAgY3Np MnBoeS0+Y2xrcyk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2Vycihjc2kycGh5LT5kZXYsICJm YWlsZWQgdG8gZW5hYmxlIGNsb2NrcywgJWRcbiIsIHJldCk7Cj4gKwkJZ290byB1bnNldF9yYXRl Owo+ICsJfQo+ICsKPiArCW9wcy0+cmVzZXQoY3NpMnBoeSk7Cj4gKwo+ICsJb3BzLT5od192ZXJz aW9uX3JlYWQoY3NpMnBoeSk7Cj4gKwo+ICsJcmV0ID0gb3BzLT5sYW5lc19lbmFibGUoY3NpMnBo eSwgJmNzaTJwaHktPnN0cmVhbV9jZmcpOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIHVuc2V0X2Ns b2NrczsKPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK3Vuc2V0X2Nsb2NrczoKPiArCWNsa19idWxr X2Rpc2FibGVfdW5wcmVwYXJlKGNzaTJwaHktPnNvY19jZmctPm51bV9jbGssCj4gKwkJCQkgICBj c2kycGh5LT5jbGtzKTsKPiArCj4gK3Vuc2V0X3JhdGU6Cj4gKwlkZXZfcG1fb3BwX3NldF9yYXRl KGNzaTJwaHktPmRldiwgMCk7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGNzaTJwaHktPnBkX2xp c3QtPm51bV9wZHM7IGkrKykgewo+ICsJCWlmICghY3NpMnBoeS0+c29jX2NmZy0+Z2VucGRzW2ld LnNjYWxlZCkKPiArCQkJY29udGludWU7Cj4gKwo+ICsJCWRldl9wbV9nZW5wZF9zZXRfcGVyZm9y bWFuY2Vfc3RhdGUoY3NpMnBoeS0+cGRfbGlzdC0+cGRfZGV2c1tpXSwgMCk7Cj4gKwl9Cj4gKwo+ ICtwb3dlcm9mZl9waHk6Cj4gKwlwbV9ydW50aW1lX3B1dF9zeW5jKGNzaTJwaHktPmRldik7Cj4g Kwo+ICtkaXNhYmxlX3JlZ3VsYXRvcnM6Cj4gKwlyZWd1bGF0b3JfYnVsa19kaXNhYmxlKGNzaTJw aHktPnNvY19jZmctPm51bV9zdXBwbGllcywKPiArCQkJICAgICAgIGNzaTJwaHktPnN1cHBsaWVz KTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHBoeV9xY29tX21p cGlfY3NpMl9wb3dlcl9vZmYoc3RydWN0IHBoeSAqcGh5KQo+ICt7Cj4gKwlzdHJ1Y3QgbWlwaV9j c2kycGh5X2RldmljZSAqY3NpMnBoeSA9IHBoeV9nZXRfZHJ2ZGF0YShwaHkpOwo+ICsJY29uc3Qg c3RydWN0IG1pcGlfY3NpMnBoeV9od19vcHMgKm9wcyA9IGNzaTJwaHktPnNvY19jZmctPm9wczsK PiArCWludCBpOwo+ICsKPiArCW9wcy0+bGFuZXNfZGlzYWJsZShjc2kycGh5LCAmY3NpMnBoeS0+ c3RyZWFtX2NmZyk7Cj4gKwo+ICsJY2xrX2J1bGtfZGlzYWJsZV91bnByZXBhcmUoY3NpMnBoeS0+ c29jX2NmZy0+bnVtX2NsaywKPiArCQkJCSAgIGNzaTJwaHktPmNsa3MpOwo+ICsKPiArCWRldl9w bV9vcHBfc2V0X3JhdGUoY3NpMnBoeS0+ZGV2LCAwKTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwg Y3NpMnBoeS0+cGRfbGlzdC0+bnVtX3BkczsgaSsrKSB7Cj4gKwkJaWYgKCFjc2kycGh5LT5zb2Nf Y2ZnLT5nZW5wZHNbaV0uc2NhbGVkKQo+ICsJCQljb250aW51ZTsKPiArCj4gKwkJZGV2X3BtX2dl bnBkX3NldF9wZXJmb3JtYW5jZV9zdGF0ZShjc2kycGh5LT5wZF9saXN0LT5wZF9kZXZzW2ldLCAw KTsKPiArCX0KPiArCj4gKwlwbV9ydW50aW1lX3B1dF9zeW5jKGNzaTJwaHktPmRldik7Cj4gKwo+ ICsJcmVndWxhdG9yX2J1bGtfZGlzYWJsZShjc2kycGh5LT5zb2NfY2ZnLT5udW1fc3VwcGxpZXMs Cj4gKwkJCSAgICAgICBjc2kycGh5LT5zdXBwbGllcyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgcGh5X29wcyBwaHlfcWNvbV9taXBpX2NzaTJfb3Bz ID0gewo+ICsJLmNvbmZpZ3VyZQk9IHBoeV9xY29tX21pcGlfY3NpMl9jb25maWd1cmUsCj4gKwku c2V0X21vZGUJPSBwaHlfcWNvbV9taXBpX2NzaTJfc2V0X21vZGUsCj4gKwkucG93ZXJfb24JPSBw aHlfcWNvbV9taXBpX2NzaTJfcG93ZXJfb24sCj4gKwkucG93ZXJfb2ZmCT0gcGh5X3Fjb21fbWlw aV9jc2kyX3Bvd2VyX29mZiwKPiArCS5vd25lcgkJPSBUSElTX01PRFVMRSwKPiArfTsKPiArCj4g K3N0YXRpYyBpbnQgcGh5X3Fjb21fbWlwaV9jc2kyX2F0dGFjaF9wbV9kb21haW5zKHN0cnVjdCBt aXBpX2NzaTJwaHlfZGV2aWNlICpjc2kycGh5KQo+ICt7Cj4gKwlzdHJ1Y3QgZGV2X3BtX2RvbWFp bl9hdHRhY2hfZGF0YSBwZF9kYXRhID0geyAwIH07Cj4gKwljb25zdCBjaGFyICoqcGRfbmFtZXM7 Cj4gKwlpbnQgaTsKPiArCj4gKwlwZF9uYW1lcyA9IGRldm1fa3phbGxvYyhjc2kycGh5LT5kZXYs Cj4gKwkJCQlzaXplb2YoY2hhciAqKSAqIGNzaTJwaHktPnNvY19jZmctPm51bV9nZW5wZHMsCj4g KwkJCQlHRlBfS0VSTkVMKTsKPiArCWlmICghcGRfbmFtZXMpCj4gKwkJcmV0dXJuIC1FTk9NRU07 Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGNzaTJwaHktPnNvY19jZmctPm51bV9nZW5wZHM7IGkr KykKPiArCQlwZF9uYW1lc1tpXSA9IGNzaTJwaHktPnNvY19jZmctPmdlbnBkc1tpXS5uYW1lOwo+ ICsKPiArCXBkX2RhdGEucGRfbmFtZXMgPSBwZF9uYW1lczsKPiArCXBkX2RhdGEubnVtX3BkX25h bWVzID0gY3NpMnBoeS0+c29jX2NmZy0+bnVtX2dlbnBkczsKPiArCj4gKwlyZXR1cm4gZGV2bV9w bV9kb21haW5fYXR0YWNoX2xpc3QoY3NpMnBoeS0+ZGV2LCAmcGRfZGF0YSwKPiArCQkJCQkgICZj c2kycGh5LT5wZF9saXN0KTsKPiArfQo+ICsKPiArc3RhdGljIGludCBwaHlfcWNvbV9taXBpX2Nz aTJfcGFyc2Vfcm91dGluZyhzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3NpMnBoeSkKPiAr ewo+ICsJc3RydWN0IG1pcGlfY3NpMnBoeV9zdHJlYW1fY2ZnICpzdHJlYW1fY2ZnID0gJmNzaTJw aHktPnN0cmVhbV9jZmc7Cj4gKwl1MzIgbGFuZV9wb2xhcml0aWVzW0NTSTJfTUFYX0RBVEFfTEFO RVMgKyAxXTsKPiArCXUzMiBkYXRhX2xhbmVzW0NTSTJfTUFYX0RBVEFfTEFORVNdOwo+ICsJc3Ry dWN0IGRldmljZSAqZGV2ID0gY3NpMnBoeS0+ZGV2Owo+ICsJc3RydWN0IGZ3bm9kZV9oYW5kbGUg KmVwOwo+ICsJaW50IG51bV9wb2xhcml0aWVzOwo+ICsJaW50IG51bV9kYXRhX2xhbmVzOwo+ICsJ dTMyIGJ1c190eXBlOwo+ICsJaW50IGksIHJldDsKPiArCj4gKwllcCA9IGZ3bm9kZV9ncmFwaF9n ZXRfZW5kcG9pbnRfYnlfaWQoZGV2X2Z3bm9kZShkZXYpLCAwLCAxLCAwKTsKPiArCWlmIChlcCkg ewo+ICsJCWZ3bm9kZV9oYW5kbGVfcHV0KGVwKTsKPiArCQlkZXZfZXJyKGRldiwgIkRQSFkgc3Bs aXQgbW9kZSBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKPiArCQlyZXR1cm4gLUVPUE5PVFNVUFA7Cj4g Kwl9Cj4gKwo+ICsJZXAgPSBmd25vZGVfZ3JhcGhfZ2V0X2VuZHBvaW50X2J5X2lkKGRldl9md25v ZGUoZGV2KSwgMCwgMCwgMCk7Cj4gKwlpZiAoIWVwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJNaXNz aW5nIHBvcnRAMFxuIik7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0g Zndub2RlX3Byb3BlcnR5X3JlYWRfdTMyKGVwLCAiYnVzLXR5cGUiLCAmYnVzX3R5cGUpOwo+ICsJ aWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiRmFpbGVkIHRvIHJlYWQgYnVzLXR5cGU6ICVk XG4iLCByZXQpOwo+ICsJCWdvdG8gb3V0X3B1dDsKPiArCX0KPiArCj4gKwlpZiAoYnVzX3R5cGUg IT0gTUVESUFfQlVTX1RZUEVfQ1NJMl9EUEhZKSB7Cj4gKwkJcmV0ID0gLUVPUE5PVFNVUFA7Cj4g KwkJZGV2X2VycihkZXYsICJVbnN1cHBvcnRlZCBidXMtdHlwZSAldVxuIiwgYnVzX3R5cGUpOwo+ ICsJCWdvdG8gb3V0X3B1dDsKPiArCX0KPiArCj4gKwludW1fZGF0YV9sYW5lcyA9IGZ3bm9kZV9w cm9wZXJ0eV9jb3VudF91MzIoZXAsICJkYXRhLWxhbmVzIik7Cj4gKwlpZiAobnVtX2RhdGFfbGFu ZXMgPCAxIHx8IG51bV9kYXRhX2xhbmVzID4gQ1NJMl9NQVhfREFUQV9MQU5FUykgewo+ICsJCXJl dCA9IC1FSU5WQUw7Cj4gKwkJZGV2X2VycihkZXYsICJJbnZhbGlkIGRhdGEtbGFuZXMgY291bnQ6 ICVkXG4iLCBudW1fZGF0YV9sYW5lcyk7Cj4gKwkJZ290byBvdXRfcHV0Owo+ICsJfQo+ICsJc3Ry ZWFtX2NmZy0+bnVtX2RhdGFfbGFuZXMgPSBudW1fZGF0YV9sYW5lczsKPiArCj4gKwlyZXQgPSBm d25vZGVfcHJvcGVydHlfcmVhZF91MzJfYXJyYXkoZXAsICJkYXRhLWxhbmVzIiwgZGF0YV9sYW5l cywKPiArCQkJCQkgICAgIHN0cmVhbV9jZmctPm51bV9kYXRhX2xhbmVzKTsKPiArCWlmIChyZXQp IHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byByZWFkIGRhdGEtbGFuZXM6ICVkXG4iLCBy ZXQpOwo+ICsJCWdvdG8gb3V0X3B1dDsKPiArCX0KPiArCj4gKwkvKiBsYW5lLXBvbGFyaXRpZXM6 IG9wdGlvbmFsLCB1cCB0byBudW1fZGF0YV9sYW5lcyArIDEgZW50cmllcyAqLwo+ICsJbWVtc2V0 KGxhbmVfcG9sYXJpdGllcywgMHgwMCwgc2l6ZW9mKGxhbmVfcG9sYXJpdGllcykpOwo+ICsJbnVt X3BvbGFyaXRpZXMgPSBmd25vZGVfcHJvcGVydHlfY291bnRfdTMyKGVwLCAibGFuZS1wb2xhcml0 aWVzIik7Cj4gKwlpZiAobnVtX3BvbGFyaXRpZXMgPiAwKSB7Cj4gKwkJaWYgKG51bV9wb2xhcml0 aWVzICE9IHN0cmVhbV9jZmctPm51bV9kYXRhX2xhbmVzICsgMSkgewo+ICsJCQlyZXQgPSAtRUlO VkFMOwo+ICsJCQlkZXZfZXJyKGRldiwgImNsb2NrK2RhdGEtbGFuZSAlZC9wb2xhcml0aWVzICVk IG1pc21hdGNoXG4iLAo+ICsJCQkJc3RyZWFtX2NmZy0+bnVtX2RhdGFfbGFuZXMgKyAxLCBudW1f cG9sYXJpdGllcyk7Cj4gKwkJCWdvdG8gb3V0X3B1dDsKPiArCQl9Cj4gKwo+ICsJCXJldCA9IGZ3 bm9kZV9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShlcCwgImxhbmUtcG9sYXJpdGllcyIsIGxhbmVf cG9sYXJpdGllcywKPiArCQkJCQkJICAgICBudW1fcG9sYXJpdGllcyk7Cj4gKwkJaWYgKHJldCkg ewo+ICsJCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byByZWFkIGxhbmUtcG9sYXJpdGllczogJWRc biIsIHJldCk7Cj4gKwkJCWdvdG8gb3V0X3B1dDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJY3NpMnBo eS0+c3RyZWFtX2NmZy5sYW5lX2NmZy5jbGsucG9zID0gQ1NJMl9ERUZBVUxUX0NMS19MQU5FOwo+ ICsJY3NpMnBoeS0+c3RyZWFtX2NmZy5sYW5lX2NmZy5jbGsucG9sID0gbGFuZV9wb2xhcml0aWVz WzBdOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBjc2kycGh5LT5zdHJlYW1fY2ZnLm51bV9kYXRh X2xhbmVzOyBpKyspIHsKPiArCQlpZiAoZGF0YV9sYW5lc1tpXSA8IDEgfHwgZGF0YV9sYW5lc1tp XSA+IENTSTJfTUFYX0RBVEFfTEFORVMpIHsKPiArCQkJZGV2X2VycihkZXYsICJJbnZhbGlkIGxh bmUgJWRcbiIsIGRhdGFfbGFuZXNbaV0pOwo+ICsJCQlyZXQgPSAtRUlOVkFMOwo+ICsJCQlnb3Rv IG91dF9wdXQ7Cj4gKwkJfQo+ICsKPiArCQkvKiBDb252ZXJ0IGRhdGEtbGFuZXMgPSA8MSAyIDMg ND4gdG8gYml0IHBvc2l0aW9ucyAqLwo+ICsJCWNzaTJwaHktPnN0cmVhbV9jZmcubGFuZV9jZmcu ZGF0YVtpXS5wb3MgPSBkYXRhX2xhbmVzW2ldIC0gMTsKPiArCQljc2kycGh5LT5zdHJlYW1fY2Zn LmxhbmVfY2ZnLmRhdGFbaV0ucG9sID0gbGFuZV9wb2xhcml0aWVzW2kgKyAxXTsKPiArCX0KPiAr Cj4gKwlyZXQgPSAwOwo+ICsKPiArb3V0X3B1dDoKPiArCWZ3bm9kZV9oYW5kbGVfcHV0KGVwKTsK PiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHBoeV9xY29tX21pcGlf Y3NpMl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwl1bnNpZ25l ZCBpbnQgaSwgbnVtX2NsaywgbnVtX3N1cHBsaWVzOwo+ICsJc3RydWN0IG1pcGlfY3NpMnBoeV9k ZXZpY2UgKmNzaTJwaHk7Cj4gKwlzdHJ1Y3QgcGh5X3Byb3ZpZGVyICpwaHlfcHJvdmlkZXI7Cj4g KwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+ICsJc3RydWN0IHBoeSAqZ2VuZXJp Y19waHk7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWNzaTJwaHkgPSBkZXZtX2t6YWxsb2MoZGV2LCBz aXplb2YoKmNzaTJwaHkpLCBHRlBfS0VSTkVMKTsKPiArCWlmICghY3NpMnBoeSkKPiArCQlyZXR1 cm4gLUVOT01FTTsKPiArCj4gKwljc2kycGh5LT5kZXYgPSBkZXY7Cj4gKwlkZXZfc2V0X2RydmRh dGEoZGV2LCBjc2kycGh5KTsKPiArCj4gKwljc2kycGh5LT5zb2NfY2ZnID0gZGV2aWNlX2dldF9t YXRjaF9kYXRhKCZwZGV2LT5kZXYpOwo+ICsKPiArCWlmICghY3NpMnBoeS0+c29jX2NmZykKPiAr CQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwludW1fY2xrID0gY3NpMnBoeS0+c29jX2NmZy0+bnVt X2NsazsKPiArCj4gKwlyZXQgPSBwaHlfcWNvbV9taXBpX2NzaTJfcGFyc2Vfcm91dGluZyhjc2ky cGh5KTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSBwaHlfcWNv bV9taXBpX2NzaTJfYXR0YWNoX3BtX2RvbWFpbnMoY3NpMnBoeSk7Cj4gKwlpZiAocmV0IDwgMCB8 fCBjc2kycGh5LT5wZF9saXN0ID09IE5VTEwpIHsKCkhlcmUgdGhlIGNoZWNrIHNob3VsZCBiZSBz aW1wbGlmaWVkOgoJaWYgKHJldCA8PSAwKQoKPiArCQlpZiAocmV0ID09IDApCj4gKwkJCXJldCA9 IC1FTk9ERVY7Cj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJGYWlsZWQgdG8g YXR0YWNoIHBvd2VyLWRvbWFpbiBsaXN0XG4iKTsKPiArCX0KPiArCj4gKwlyZXQgPSBkZXZtX3Bt X3J1bnRpbWVfZW5hYmxlKGRldik7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gZGV2X2Vy cl9wcm9iZShkZXYsIHJldCwgIkZhaWxlZCB0byBlbmFibGUgcG0gcnVudGltZVxuIik7Cj4gKwo+ ICsJcmV0ID0gZGV2bV9jbGtfYnVsa19nZXRfYWxsKGRldiwgJmNzaTJwaHktPmNsa3MpOwo+ICsJ aWYgKHJldCA8IDApCj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJGYWlsZWQg dG8gZ2V0IGNsb2Nrc1xuIik7Cj4gKwo+ICsJaWYgKG51bV9jbGsgIT0gcmV0KSB7Cj4gKwkJcmV0 dXJuIGRldl9lcnJfcHJvYmUoZGV2LCAtRU5PREVWLCAiY2xvY2sgY291bnQgJWQgZXhwZWN0ZWQg JWRcbiIsCj4gKwkJCQkgICAgIHJldCwgbnVtX2Nsayk7Cj4gKwl9Cj4gKwo+ICsJZm9yIChpID0g MDsgaSA8IG51bV9jbGs7IGkrKykgewo+ICsJCWlmICghY3NpMnBoeS0+Y2xrc1tpXS5pZCkKPiAr CQkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCAtRUlOVkFMLCAiTWlzc2luZyBjbG9jay1uYW1l c1xuIik7Cj4gKwo+ICsJCWlmICghc3RyY21wKGNzaTJwaHktPmNsa3NbaV0uaWQsICJ0aW1lciIp KSB7Cj4gKwkJCWNzaTJwaHktPnRpbWVyX2NsayA9IGNzaTJwaHktPmNsa3NbaV0uY2xrOwo+ICsJ CQlicmVhazsKPiArCQl9Cj4gKwl9Cj4gKwlpZiAoIWNzaTJwaHktPnRpbWVyX2NsaykKPiArCQly ZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIC1FTk9ERVYsICJubyB0aW1lciBjbG9ja1xuIik7Cj4g Kwo+ICsJcmV0ID0gZGV2bV9wbV9vcHBfc2V0X2Nsa25hbWUoZGV2LCAiY29yZSIpOwo+ICsJaWYg KHJldCkKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgIkZhaWxlZCB0byBzZXQg b3BwIGNsa25hbWVcbiIpOwo+ICsKPiArCXJldCA9IGRldm1fcG1fb3BwX29mX2FkZF90YWJsZShk ZXYpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgImlu dmFsaWQgT1BQIHRhYmxlIGluIGRldmljZSB0cmVlXG4iKTsKPiArCj4gKwludW1fc3VwcGxpZXMg PSBjc2kycGh5LT5zb2NfY2ZnLT5udW1fc3VwcGxpZXM7Cj4gKwljc2kycGh5LT5zdXBwbGllcyA9 IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqY3NpMnBoeS0+c3VwcGxpZXMpICogbnVtX3N1cHBs aWVzLAo+ICsJCQkJCSBHRlBfS0VSTkVMKTsKPiArCWlmICghY3NpMnBoeS0+c3VwcGxpZXMpCj4g KwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IG51bV9zdXBwbGllczsg aSsrKQo+ICsJCWNzaTJwaHktPnN1cHBsaWVzW2ldLnN1cHBseSA9IGNzaTJwaHktPnNvY19jZmct PnN1cHBseV9uYW1lc1tpXTsKPiArCj4gKwlyZXQgPSBkZXZtX3JlZ3VsYXRvcl9idWxrX2dldChk ZXYsIG51bV9zdXBwbGllcywgY3NpMnBoeS0+c3VwcGxpZXMpOwo+ICsJaWYgKHJldCkKPiArCQly ZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwKPiArCQkJCSAgICAgImZhaWxlZCB0byBnZXQg cmVndWxhdG9yIHN1cHBsaWVzXG4iKTsKPiArCj4gKwljc2kycGh5LT5iYXNlID0gZGV2bV9wbGF0 Zm9ybV9pb3JlbWFwX3Jlc291cmNlKHBkZXYsIDApOwo+ICsJaWYgKElTX0VSUihjc2kycGh5LT5i YXNlKSkKPiArCQlyZXR1cm4gUFRSX0VSUihjc2kycGh5LT5iYXNlKTsKPiArCj4gKwlnZW5lcmlj X3BoeSA9IGRldm1fcGh5X2NyZWF0ZShkZXYsIE5VTEwsICZwaHlfcWNvbV9taXBpX2NzaTJfb3Bz KTsKPiArCWlmIChJU19FUlIoZ2VuZXJpY19waHkpKSB7Cj4gKwkJcmV0ID0gUFRSX0VSUihnZW5l cmljX3BoeSk7Cj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJmYWlsZWQgdG8g Y3JlYXRlIHBoeVxuIik7Cj4gKwl9Cj4gKwljc2kycGh5LT5waHkgPSBnZW5lcmljX3BoeTsKPiAr Cj4gKwlwaHlfc2V0X2RydmRhdGEoZ2VuZXJpY19waHksIGNzaTJwaHkpOwo+ICsKPiArCXBoeV9w cm92aWRlciA9IGRldm1fb2ZfcGh5X3Byb3ZpZGVyX3JlZ2lzdGVyKGRldiwgb2ZfcGh5X3NpbXBs ZV94bGF0ZSk7Cj4gKwlpZiAoIUlTX0VSUihwaHlfcHJvdmlkZXIpKQo+ICsJCWRldl9kYmcoZGV2 LCAiUmVnaXN0ZXJlZCBNSVBJIENTSTIgUEhZIGRldmljZVxuIik7Cj4gKwo+ICsJcmV0dXJuIFBU Ul9FUlJfT1JfWkVSTyhwaHlfcHJvdmlkZXIpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3Ry dWN0IG9mX2RldmljZV9pZCBwaHlfcWNvbV9taXBpX2NzaTJfb2ZfbWF0Y2hfdGFibGVbXSA9IHsK PiArCXsgLmNvbXBhdGlibGUJPSAicWNvbSx4MWU4MDEwMC1jc2kyLXBoeSIsIC5kYXRhID0gJm1p cGlfY3NpMl9kcGh5XzRubV94MWUgfSwKPiArCXsgfQo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RB QkxFKG9mLCBwaHlfcWNvbV9taXBpX2NzaTJfb2ZfbWF0Y2hfdGFibGUpOwo+ICsKPiArc3RhdGlj IHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgcGh5X3Fjb21fbWlwaV9jc2kyX2RyaXZlciA9IHsKPiAr CS5wcm9iZQkJPSBwaHlfcWNvbV9taXBpX2NzaTJfcHJvYmUsCj4gKwkuZHJpdmVyID0gewo+ICsJ CS5uYW1lCT0gInFjb20tbWlwaS1jc2kyLXBoeSIsCj4gKwkJLm9mX21hdGNoX3RhYmxlID0gcGh5 X3Fjb21fbWlwaV9jc2kyX29mX21hdGNoX3RhYmxlLAo+ICsJfSwKPiArfTsKPiArCj4gK21vZHVs ZV9wbGF0Zm9ybV9kcml2ZXIocGh5X3Fjb21fbWlwaV9jc2kyX2RyaXZlcik7Cj4gKwo+ICtNT0RV TEVfREVTQ1JJUFRJT04oIlF1YWxjb21tIE1JUEkgQ1NJMiBQSFkgZHJpdmVyIik7Cj4gK01PRFVM RV9BVVRIT1IoIkJyeWFuIE8nRG9ub2dodWUgPGJvZEBrZXJuZWwub3JnPiIpOwo+ICtNT0RVTEVf TElDRU5TRSgiR1BMIik7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L3F1YWxjb21tL3BoeS1x Y29tLW1pcGktY3NpMi5oIGIvZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFjb20tbWlwaS1jc2ky LmgKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMDAuLjdlNTVhZTAw NzM3MDQKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9waHkvcXVhbGNvbW0vcGh5LXFj b20tbWlwaS1jc2kyLmgKPiBAQCAtMCwwICsxLDk3IEBACj4gKy8qIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiBHUEwtMi4wICovCj4gKy8qCj4gKyAqCj4gKyAqIFF1YWxjb21tIE1JUEkgQ1NJMiBD UEhZL0RQSFkgZHJpdmVyCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAyNSBMaW5hcm8gTHRk Lgo+ICsgKi8KPiArI2lmbmRlZiBfX1BIWV9RQ09NX01JUElfQ1NJMl9IX18KPiArI2RlZmluZSBf X1BIWV9RQ09NX01JUElfQ1NJMl9IX18KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9waHkvcGh5Lmg+ Cj4gKwo+ICsjZGVmaW5lIENTSTJfTUFYX0RBVEFfTEFORVMJNAo+ICsjZGVmaW5lIENTSTJfREVG QVVMVF9DTEtfTEFORQk3CgpJdCB3YXMgbWVudGlvbmVkIG9uZSBkYXkgZWFybGllciB0aGF0IHRo aXMgYml0IHZhbHVlIGlzIG5hbWVkIGF3a3dhcmRseS4KCk1vcmVvdmVyIGl0J3MgdG9vIHNwZWNp ZmljIHRvIEQtUEhZIElQIHRvIGJlIHByZXNlbnQgaW4gdGhlIGdlbmVyaWMgQ1NJMgpoZWFkZXIg ZmlsZSwgdGhlcmVmb3JlIGl0IHNoYWxsIGJlIG1vdmVkIG91dC4KCj4gKwo+ICtzdHJ1Y3QgbWlw aV9jc2kycGh5X2xhbmUgewo+ICsJdTggcG9zOwo+ICsJdTggcG9sOwo+ICt9Owo+ICsKPiArc3Ry dWN0IG1pcGlfY3NpMnBoeV9sYW5lc19jZmcgewo+ICsJc3RydWN0IG1pcGlfY3NpMnBoeV9sYW5l IGRhdGFbQ1NJMl9NQVhfREFUQV9MQU5FU107Cj4gKwlzdHJ1Y3QgbWlwaV9jc2kycGh5X2xhbmUg Y2xrOwo+ICt9Owo+ICsKPiArc3RydWN0IG1pcGlfY3NpMnBoeV9zdHJlYW1fY2ZnIHsKPiArCXM2 NCBsaW5rX2ZyZXE7Cj4gKwl1OCBudW1fZGF0YV9sYW5lczsKPiArCXN0cnVjdCBtaXBpX2NzaTJw aHlfbGFuZXNfY2ZnIGxhbmVfY2ZnOwo+ICt9Owo+ICsKPiArc3RydWN0IG1pcGlfY3NpMnBoeV9k ZXZpY2U7Cj4gKwo+ICtzdHJ1Y3QgbWlwaV9jc2kycGh5X2h3X29wcyB7Cj4gKwl2b2lkICgqaHdf dmVyc2lvbl9yZWFkKShzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3NpMnBoeV9kZXYpOwo+ ICsJdm9pZCAoKnJlc2V0KShzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3NpMnBoeV9kZXYp Owo+ICsJaW50ICgqbGFuZXNfZW5hYmxlKShzdHJ1Y3QgbWlwaV9jc2kycGh5X2RldmljZSAqY3Np MnBoeV9kZXYsCj4gKwkJCSAgICBzdHJ1Y3QgbWlwaV9jc2kycGh5X3N0cmVhbV9jZmcgKmNmZyk7 Cj4gKwl2b2lkICgqbGFuZXNfZGlzYWJsZSkoc3RydWN0IG1pcGlfY3NpMnBoeV9kZXZpY2UgKmNz aTJwaHlfZGV2LAo+ICsJCQkgICAgICBzdHJ1Y3QgbWlwaV9jc2kycGh5X3N0cmVhbV9jZmcgKmNm Zyk7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbWlwaV9jc2kycGh5X2xhbmVfcmVncyB7Cj4gKwljb25z dCBzMzIgcmVnX2FkZHI7Cj4gKwljb25zdCBzMzIgcmVnX2RhdGE7Cj4gKwljb25zdCB1MzIgZGVs YXlfdXM7Cj4gKwljb25zdCB1MzIgcGFyYW1fdHlwZTsKPiArfTsKPiArCj4gK3N0cnVjdCBtaXBp X2NzaTJwaHlfZGV2aWNlX3JlZ3Mgewo+ICsJY29uc3Qgc3RydWN0IG1pcGlfY3NpMnBoeV9sYW5l X3JlZ3MgKmluaXRfc2VxOwo+ICsJY29uc3QgaW50IGxhbmVfYXJyYXlfc2l6ZTsKPiArCWNvbnN0 IHUzMiBjb21tb25fcmVnc19vZmZzZXQ7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbWlwaV9jc2kyX2dl bnBkIHsKPiArCWNvbnN0IGNoYXIgKm5hbWU7Cj4gKwlib29sIHNjYWxlZDsKPiArfTsKPiArCj4g K3N0cnVjdCBtaXBpX2NzaTJwaHlfc29jX2NmZyB7Cj4gKwljb25zdCBzdHJ1Y3QgbWlwaV9jc2ky cGh5X2h3X29wcyAqb3BzOwo+ICsJY29uc3Qgc3RydWN0IG1pcGlfY3NpMnBoeV9kZXZpY2VfcmVn cyByZWdfaW5mbzsKPiArCj4gKwljb25zdCBjaGFyICoqIGNvbnN0IHN1cHBseV9uYW1lczsKPiAr CWNvbnN0IHVuc2lnbmVkIGludCBudW1fc3VwcGxpZXM7Cj4gKwo+ICsJY29uc3QgY2hhciAqKiBj b25zdCBjbGtfbmFtZXM7Cj4gKwljb25zdCB1bnNpZ25lZCBpbnQgbnVtX2NsazsKPiArCj4gKwlj b25zdCBzdHJ1Y3QgbWlwaV9jc2kyX2dlbnBkICpnZW5wZHM7Cj4gKwljb25zdCB1bnNpZ25lZCBp bnQgbnVtX2dlbnBkczsKPiArfTsKPiArCj4gK3N0cnVjdCBtaXBpX2NzaTJwaHlfZGV2aWNlIHsK PiArCXN0cnVjdCBkZXZpY2UgKmRldjsKPiArCXU4IHBoeV9tb2RlOwo+ICsKPiArCXN0cnVjdCBw aHkgKnBoeTsKPiArCXZvaWQgX19pb21lbSAqYmFzZTsKPiArCj4gKwlzdHJ1Y3QgY2xrX2J1bGtf ZGF0YSAqY2xrczsKPiArCXN0cnVjdCBjbGsgKnRpbWVyX2NsazsKPiArCXUzMiB0aW1lcl9jbGtf cmF0ZTsKPiArCj4gKwlzdHJ1Y3QgcmVndWxhdG9yX2J1bGtfZGF0YSAqc3VwcGxpZXM7Cj4gKwlz dHJ1Y3QgZGV2X3BtX2RvbWFpbl9saXN0ICpwZF9saXN0Owo+ICsKPiArCWNvbnN0IHN0cnVjdCBt aXBpX2NzaTJwaHlfc29jX2NmZyAqc29jX2NmZzsKPiArCXN0cnVjdCBtaXBpX2NzaTJwaHlfc3Ry ZWFtX2NmZyBzdHJlYW1fY2ZnOwo+ICsKPiArCXUzMiBod192ZXJzaW9uOwo+ICt9Owo+ICsKPiAr ZXh0ZXJuIGNvbnN0IHN0cnVjdCBtaXBpX2NzaTJwaHlfc29jX2NmZyBtaXBpX2NzaTJfZHBoeV80 bm1feDFlOwo+ICsKPiArI2VuZGlmIC8qIF9fUEhZX1FDT01fTUlQSV9DU0kyX0hfXyAqLwo+IAoK SW4gZ2VuZXJhbCB0aGUgZHJpdmVyIGxvb2tzIHRvIGJlIGFjY2VwdGFibGUsIGhvd2V2ZXIgdGVz dGluZyBvZiB0aGUgZHJpdmVyCnJlcXVpcmVzIENBTVNTIGNoYW5nZXMgYW5kIGJvYXJkIC5kdHMg Y2hhbmdlcywgcHJlZmVyYWJseSBpbmZvcm1hdGlvbiBhYm91dAphbiBvcHRpb24gdG8gdGVzdCB0 aGUgbmV3IGRyaXZlciBzaG91bGQgYmUgZm91bmQgaW4gdGhlIGNvdmVyIGxldHRlci4KCi0tIApC ZXN0IHdpc2hlcywKVmxhZGltaXIKCi0tIApsaW51eC1waHkgbWFpbGluZyBsaXN0CmxpbnV4LXBo eUBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHBzOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFu L2xpc3RpbmZvL2xpbnV4LXBoeQo= From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3942A481FAB for ; Thu, 3 Sep 2026 13:15:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788441373; cv=none; b=BBN+HL3XsANGTb2H+lRBgmZJJ3Vm6bl9Ha/KsyDAnkq2RpUFTZrDohA2poOYGjaCwcowbSHdk7f5spfD6c+LGPyVvJHMF7LGRa4lpstfn6YPt77zR1Z6UrL2ZRz1rgZZaSS6oYHK/yaYyAoRhCQ5BirPHtBd9XT1bTm732oYTy0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788441373; c=relaxed/simple; bh=pR25d62u8LcP6P4i8ls/psNZYfYZ5fZjUQxX2kDZviI=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=bjJWy5Ciu0YG4A3bl+ZRBjhMaJTD1iLAqzbCm6ksiHVB8BkQz9jbvkjgsGGzglowIm7o+drMt6aUii06/ARiNvZOOku7ZHS+3ftBr+FNpQ7yS01hBKGgqIUXNo11t1AD55AKIvmPHU7JOpiFSeCRcSvnXv0tyUTB0zx/5FPfxgA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=kgWTCm0V; arc=none smtp.client-ip=209.85.167.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="kgWTCm0V" Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-5b5e0ec7021so355250e87.1 for ; Thu, 03 Sep 2026 06:15:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788441351; x=1789046151; darn=vger.kernel.org; h=content-transfer-encoding:content-type:in-reply-to:from:references :cc:to:subject:user-agent:mime-version:date:message-id:from:to:cc :subject:date:message-id:reply-to:content-type; bh=mr9isTlDJb3v/C7vbLOsv9lj+fKnUwGkrvAs7o9qNh0=; b=kgWTCm0VJCvgiZ/hL/0eo4VkEVQDRdiMensl3Vl6Qng/GrwxoRkvABuhbdWhvUvm1A R+XaHM8DupDubKUheCHpJ2Rfq51R7+9RMUxQKdQ32plMF32y1gwvkwoBp8LMT+3xVPwd QzJR9AE2CWzTixwImoNOukWMBafecHZa5V0eHQ2GkW98xhAnqC6Q/8ircFdZ5vdO/tvA tvrEl/XRiZPLv0QwrqgC3yGyKKoiDfXANs2ykUoTvHGO9rR6PIjlgrRtbbMIehKQpayM 7nxvbu7xA90QIpdNzIhZp28L4jyLq7AByuWa8eXd7DBExphMWCYzzSbsWREudKPO2MkP 7SOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788441351; x=1789046151; h=content-transfer-encoding:content-type:in-reply-to:from:references :cc:to:subject:user-agent:mime-version:date:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=mr9isTlDJb3v/C7vbLOsv9lj+fKnUwGkrvAs7o9qNh0=; b=F7/yLBBSUnydH8Mqy7OhHZlOvtRqbPDkPTl9rBF1WIKQ1rS4hlc3yxSxyT1otUcNJO +bAq2UCv9JgTl70bFRGEqcucS0zkaS9AejDVlHsPo1kacO3uq7RaEjA3/WBSTlbYwhnP iY5KxCgNJh9ukoI9Sn/M6iSv9LfjK4gM0zVvOIDUKofIYIP2VuifIDfupQNx2hXFvyew KQjSm9Pwc6i3OUWNMcXGL9txZK28CXS2isRNMdbZI/HvyKVbxsiobwxb9EWibpMFTIod cQmFswcc/zlvnTP7roD47PhuRjupmBZYR36CSHTuz2GkhE7Sa8c22cIUJ/uhcopudxId XO8w== X-Forwarded-Encrypted: i=1; AKwUvBwaD1gqcnt78rxlGYxAhjTBL2dcVpN0rq1JVOiwA+EwHere/lvsUNqZIHmo3C/f1wULi5sZNzvPO3Kb@vger.kernel.org X-Gm-Message-State: AFuF++lB7SNmI6hyts9UrHkUnoPG1KDGOPIAoUI1hXPJcQucyotQW83t 32qor2YykyBZC+ZlkeuTcUTo0Etn3WO7dtiIiULY8pXpn85Kdqo8v8R4glcVKorrvhE= X-Gm-Gg: AYBFou3xJMld0wlagwIrPQ7BSFQOJtdUeuGr1YZ0eaBvLlEVDjSfhXeDGOCLr9DGdMd FsQ6uaOPMmL0+wY8r4DWQ8UTE7gq4OWyDEXhMJt76ND3WHkfJgRdp1oQuUEV4elRm+EIsQSUJKf EU4LHl4V5Ul2U4ENVcJLST45h8i+aA+W95z95nXfb9keqTM2SFnHPbJ6LCZvjFekCxijsuEAsYM iOYC7TCj7CqRl6kGC6rchyg9KX97XU8NcM53UZPKYa/bieBHFm8xzlQbayMv/5rM/iRnGv0n9IX nfPwhP/eicx3GsneroBTlwz2ScHCobPxeGy08YTvWhSl5loOW3Ph7FXuniYGAsz6mSqooIPc7ey B86g3+fpJLf5UDHPP/sx+XCzRC0ZSdYvv8hImyEsI+psqAQswyzrLBRzrqy9NYN/Gk50QJ/Xw6A KkimfDGbY9Ar2B4tUXPMSBaic/vxTZ3yiqlQQDbcKpFgUFXbeXaBn7NA3DxL/0HPyT1DwijSMqa apNLc3wxnSNX4sRLtsvXSJz80oUgTKDjq3WQwshTA== X-Received: by 2002:a05:6512:3a82:b0:5b0:312:21ca with SMTP id 2adb3069b0e04-5b608347a4dmr2488301e87.2.1788441350385; Thu, 03 Sep 2026 06:15:50 -0700 (PDT) Received: from [192.168.1.100] (91-159-24-186.elisa-laajakaista.fi. [91.159.24.186]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a34a8ed421sm11153871fa.2.2026.09.03.06.15.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Sep 2026 06:15:49 -0700 (PDT) Message-ID: <2de02744-1fcc-4ded-9f07-51b7aa74c423@linaro.org> Date: Thu, 3 Sep 2026 16:15:49 +0300 Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v16 2/2] phy: qcom-mipi-csi2: Add a CSI2 MIPI DPHY driver To: Bryan O'Donoghue , Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Neil Armstrong Cc: Bryan O'Donoghue , linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org References: <20260901-x1e-csi2-phy-v16-0-dd863b929080@linaro.org> <20260901-x1e-csi2-phy-v16-2-dd863b929080@linaro.org> From: Vladimir Zapolskiy In-Reply-To: <20260901-x1e-csi2-phy-v16-2-dd863b929080@linaro.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 9/1/26 23:15, Bryan O'Donoghue wrote: > Add a new MIPI CSI2 driver in DPHY mode initially. The entire set of > existing CAMSS CSI PHY init sequences are imported in order to save time > and effort in later patches. > > The following devices are supported in this drop: > "qcom,x1e80100-csi2-phy" > > In-line with other PHY drivers the process node is included in the name. > Data-lane and clock lane positioning and polarity selection via newly > amended struct phy_configure_opts_mipi_dphy{} is supported. > > The Qualcomm 3PH class of PHYs can do both DPHY and CPHY mode. For now only > DPHY is supported. > > In porting some of the logic over from camss-csiphy*.c to here its also > possible to rationalise some of the code. > > In particular use of regulator_bulk and clk_bulk as well as dropping the > seemingly useless and unused interrupt handler. > > The PHY sequences and a lot of the logic that goes with them are well > proven in CAMSS and mature so the main thing to watch out for here is how > to get the right sequencing of regulators, clocks and register-writes. > > The register init sequence table is imported verbatim from the existing > CAMSS csiphy driver. A follow-up series will rework the table to extract > the repetitive per-lane pattern into a loop. > > Signed-off-by: Bryan O'Donoghue > --- > MAINTAINERS | 10 + > drivers/phy/qualcomm/Kconfig | 15 + > drivers/phy/qualcomm/Makefile | 5 + > drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 385 +++++++++++++++++ > drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 462 +++++++++++++++++++++ > drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 97 +++++ > 6 files changed, 974 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 15011f5752a99..a203b41475ea4 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -22296,6 +22296,16 @@ S: Maintained > F: Documentation/devicetree/bindings/media/qcom,*-iris.yaml > F: drivers/media/platform/qcom/iris/ > > +QUALCOMM MIPI CSI2 PHY DRIVER > +M: Bryan O'Donoghue > +L: linux-phy@lists.infradead.org > +L: linux-media@vger.kernel.org > +L: linux-arm-msm@vger.kernel.org > +S: Maintained > +F: Documentation/devicetree/bindings/phy/qcom,*-csi2-phy.yaml > +F: drivers/phy/qualcomm/phy-qcom-mipi-csi2*.c > +F: drivers/phy/qualcomm/phy-qcom-mipi-csi2*.h > + > QUALCOMM NAND CONTROLLER DRIVER > M: Manivannan Sadhasivam > L: linux-mtd@lists.infradead.org > diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig > index 60a0ead127fa9..cd6959e69bef7 100644 > --- a/drivers/phy/qualcomm/Kconfig > +++ b/drivers/phy/qualcomm/Kconfig > @@ -28,6 +28,21 @@ config PHY_QCOM_EDP > Enable this driver to support the Qualcomm eDP PHY found in various > Qualcomm chipsets. > > +config PHY_QCOM_MIPI_CSI2 > + tristate "Qualcomm MIPI CSI2 PHY driver" > + depends on ARCH_QCOM || COMPILE_TEST > + depends on OF > + depends on PM > + depends on PM_OPP > + depends on COMMON_CLK > + select GENERIC_PHY > + select GENERIC_PHY_MIPI_DPHY > + help > + Enable this to support the MIPI CSI2 PHY driver found in various > + Qualcomm chipsets. This PHY is used to connect MIPI CSI2 > + camera sensors to the CSI Decoder in the Qualcomm Camera Subsystem > + CAMSS. > + > config PHY_QCOM_IPQ4019_USB > tristate "Qualcomm IPQ4019 USB PHY driver" > depends on OF && (ARCH_QCOM || COMPILE_TEST) > diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile > index b71a6a0bed3f1..382cb594b06b6 100644 > --- a/drivers/phy/qualcomm/Makefile > +++ b/drivers/phy/qualcomm/Makefile > @@ -6,6 +6,11 @@ obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o > obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o > obj-$(CONFIG_PHY_QCOM_M31_USB) += phy-qcom-m31.o > obj-$(CONFIG_PHY_QCOM_M31_EUSB) += phy-qcom-m31-eusb2.o > + > +phy-qcom-mipi-csi2-objs += phy-qcom-mipi-csi2-core.o \ > + phy-qcom-mipi-csi2-3ph-dphy.o > +obj-$(CONFIG_PHY_QCOM_MIPI_CSI2) += phy-qcom-mipi-csi2.o > + > obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o > > obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o > diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c > new file mode 100644 > index 0000000000000..966d79c98f9b2 > --- /dev/null > +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c > @@ -0,0 +1,385 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v1.0 > + * > + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. > + * Copyright (C) 2016-2026 Linaro Ltd. > + */ > + > +#include > +#include > +#include > +#include > + > +#include "phy-qcom-mipi-csi2.h" > + > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(offset, n) ((offset) + 0x4 * (n)) > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET BIT(0) > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7) > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0) > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1) > +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL10_IRQ_CLEAR_CMD BIT(0) > +#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, n) ((offset) + 0xb0 + 0x4 * (n)) > + > +#define CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(n) ((0x200 * (n)) + 0x24) > + > +/* > + * 3 phase CSI has 19 common status regs with only 0-10 being used > + * and 11-18 being reserved. > + */ > +#define CSI_COMMON_STATUS_NUM 11 > +/* > + * There are a number of common control registers > + * The offset to clear the CSIPHY IRQ status starts @ 22 > + * So to clear CSI_COMMON_STATUS0 this is CSI_COMMON_CONTROL22, STATUS1 is > + * CONTROL23 and so on > + */ > +#define CSI_CTRL_STATUS_INDEX 22 > + > +/* > + * There are 43 COMMON_CTRL registers with regs after # 33 being reserved > + */ > +#define CSI_CTRL_MAX 33 > + > +#define CSIPHY_DEFAULT_PARAMS 0 > +#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2 > +#define CSIPHY_SKEW_CAL 7 > + > +/* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */ > +static const struct > +mipi_csi2phy_lane_regs lane_regs_x1e80100[] = { > + /* Power up lanes 2ph mode */ > + {.reg_addr = 0x101c, .reg_data = 0x7a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x1018, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + > + {.reg_addr = 0x0094, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x00a0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0090, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0098, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0094, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0030, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0000, .reg_data = 0x8e, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0038, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x002c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0034, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x001c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0014, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x003c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0004, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0020, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0008, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, > + {.reg_addr = 0x0010, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0094, .reg_data = 0xd7, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x005c, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0060, .reg_data = 0xbd, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0064, .reg_data = 0x7f, .param_type = CSIPHY_SKEW_CAL}, > + > + {.reg_addr = 0x0e94, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0ea0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e90, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e98, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e94, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e30, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e28, .reg_data = 0x04, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e00, .reg_data = 0x80, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e0c, .reg_data = 0xff, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e38, .reg_data = 0x1f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e2c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e34, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e1c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e14, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e3c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e04, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e20, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0e08, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, > + {.reg_addr = 0x0e10, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, > + > + {.reg_addr = 0x0494, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x04a0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0490, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0498, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0494, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0430, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0400, .reg_data = 0x8e, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0438, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x042c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0434, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x041c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0414, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x043c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0404, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0420, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0408, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, > + {.reg_addr = 0x0410, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0494, .reg_data = 0xd7, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x045c, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0460, .reg_data = 0xbd, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0464, .reg_data = 0x7f, .param_type = CSIPHY_SKEW_CAL}, > + > + {.reg_addr = 0x0894, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x08a0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0890, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0898, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0894, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0830, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0800, .reg_data = 0x8e, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0838, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x082c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0834, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x081c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0814, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x083c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0804, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0820, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0808, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, > + {.reg_addr = 0x0810, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0894, .reg_data = 0xd7, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x085c, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0860, .reg_data = 0xbd, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0864, .reg_data = 0x7f, .param_type = CSIPHY_SKEW_CAL}, > + > + {.reg_addr = 0x0c94, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0ca0, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c90, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c98, .reg_data = 0x08, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c94, .reg_data = 0x07, .delay_us = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c30, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c00, .reg_data = 0x8e, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c38, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c2c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c34, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c1c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c14, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c3c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c04, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c20, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c08, .reg_data = 0x10, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE}, > + {.reg_addr = 0x0c10, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS}, > + {.reg_addr = 0x0c94, .reg_data = 0xd7, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0c5c, .reg_data = 0x00, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0c60, .reg_data = 0xbd, .param_type = CSIPHY_SKEW_CAL}, > + {.reg_addr = 0x0c64, .reg_data = 0x7f, .param_type = CSIPHY_SKEW_CAL}, > +}; > + > +static inline const struct mipi_csi2phy_device_regs * > +csi2phy_dev_to_regs(struct mipi_csi2phy_device *csi2phy) > +{ > + return &csi2phy->soc_cfg->reg_info; > +} > + > +static void phy_qcom_mipi_csi2_hw_version_read(struct mipi_csi2phy_device *csi2phy) > +{ > + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); > + u32 tmp; > + > + writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); > + > + tmp = readl_relaxed(csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 12)); > + csi2phy->hw_version = tmp; > + > + tmp = readl_relaxed(csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 13)); > + csi2phy->hw_version |= (tmp << 8) & 0xFF00; > + > + tmp = readl_relaxed(csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 14)); > + csi2phy->hw_version |= (tmp << 16) & 0xFF0000; > + > + tmp = readl_relaxed(csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 15)); > + csi2phy->hw_version |= (tmp << 24) & 0xFF000000; > + > + dev_dbg_once(csi2phy->dev, "CSIPHY 3PH HW Version = 0x%08x\n", csi2phy->hw_version); > +} > + > +/* > + * phy_qcom_mipi_csi2_reset - Perform software reset on CSIPHY module > + * @phy_qcom_mipi_csi2: CSIPHY device > + */ > +static void phy_qcom_mipi_csi2_reset(struct mipi_csi2phy_device *csi2phy) > +{ > + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); > + > + writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET, > + csi2phy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); > + usleep_range(5000, 8000); > + writel(0x0, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); > +} > + > +/* > + * phy_qcom_mipi_csi2_settle_cnt_calc - Calculate settle count value > + * > + * Helper function to calculate settle count value. This is > + * based on the CSI2 T_hs_settle parameter which in turn > + * is calculated based on the CSI2 transmitter link frequency. > + * > + * Return settle count. > + */ > +static u8 phy_qcom_mipi_csi2_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate) > +{ > + u32 t_hs_prepare_max_ps; > + u32 timer_period_ps; > + u32 t_hs_settle_ps; > + u8 settle_cnt; > + u32 ui_ps; > + > + ui_ps = div64_u64(PSEC_PER_SEC, link_freq); > + ui_ps /= 2; > + t_hs_prepare_max_ps = 85000 + 6 * ui_ps; > + t_hs_settle_ps = t_hs_prepare_max_ps; > + > + timer_period_ps = div_u64(PSEC_PER_SEC, timer_clk_rate); > + > + if ((t_hs_settle_ps / timer_period_ps) < 6) > + return 0; > + > + settle_cnt = t_hs_settle_ps / timer_period_ps - 6; > + > + return settle_cnt; > +} > + > +static void > +phy_qcom_mipi_csi2_gen2_config_lanes(struct mipi_csi2phy_device *csi2phy, > + u8 settle_cnt) > +{ > + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); > + const struct mipi_csi2phy_lane_regs *r = regs->init_seq; > + int i, array_size = regs->lane_array_size; > + u32 val; > + > + for (i = 0; i < array_size; i++, r++) { > + switch (r->param_type) { > + case CSIPHY_SETTLE_CNT_LOWER_BYTE: > + val = settle_cnt & 0xff; > + break; > + case CSIPHY_SKEW_CAL: > + /* TODO: support application of skew from dt flag */ > + continue; > + default: > + val = r->reg_data; > + break; > + } > + writel(val, csi2phy->base + r->reg_addr); > + if (r->delay_us) > + udelay(r->delay_us); > + } > +} > + > +static int phy_qcom_mipi_csi2_lanes_enable(struct mipi_csi2phy_device *csi2phy, > + struct mipi_csi2phy_stream_cfg *cfg) > +{ > + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); > + struct mipi_csi2phy_lanes_cfg *lane_cfg = &cfg->lane_cfg; > + u8 settle_cnt; > + u8 val; > + int i; > + > + if (cfg->link_freq <= 0) > + return -EINVAL; The error condition should not be met at this stage, the check is to be removed. > + > + settle_cnt = phy_qcom_mipi_csi2_settle_cnt_calc(cfg->link_freq, csi2phy->timer_clk_rate); > + if (!settle_cnt) > + return -ENODEV; It seems to be an overkill to recompute 'settle_cnt' every time when .lanes_enable() is called, the value can be computed once at the init stage. > + > + /* > + * CSI_COMMON_CTRL5 is a physical lane power-up bitmap: > + * - Bits [0,2,4,6] → D-PHY data lanes(LN0, LN2, LN4, LN6) > + * - Bits [1,3,5] → C-PHY trio lanes(LN1, LN3, LN5) > + * - Bit [7] → D-PHY clock lane(LNCK) dedicated clock enable > + */ > + val = BIT(lane_cfg->clk.pos); > + for (i = 0; i < cfg->num_data_lanes; i++) > + val |= BIT(lane_cfg->data[i].pos * 2); > + > + writel(val, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 5)); > + > + /* Lane configuration for polarity @ CSIPHY-base + CTRL9 */ > + for (i = 0; i < cfg->num_data_lanes; i++) { > + if (lane_cfg->data[i].pol) { > + u8 pos = lane_cfg->data[i].pos; > + > + writel(BIT(2), csi2phy->base + CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(pos * 2)); > + } > + } > + > + if (lane_cfg->clk.pol) > + writel(BIT(2), csi2phy->base + CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(lane_cfg->clk.pos)); > + > + val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B; > + writel(val, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); > + > + val = 0x02; > + writel(val, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 7)); > + > + val = 0x00; > + writel(val, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 0)); > + > + phy_qcom_mipi_csi2_gen2_config_lanes(csi2phy, settle_cnt); > + > + /* IRQ_MASK registers - disable all interrupts */ > + for (i = CSI_COMMON_STATUS_NUM; i < CSI_CTRL_STATUS_INDEX; i++) { > + writel(0, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, i)); > + } > + > + return 0; > +} > + > +static void > +phy_qcom_mipi_csi2_lanes_disable(struct mipi_csi2phy_device *csi2phy, > + struct mipi_csi2phy_stream_cfg *cfg) > +{ > + const struct mipi_csi2phy_device_regs *regs = csi2phy_dev_to_regs(csi2phy); > + > + writel(0, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 5)); > + > + writel(0, csi2phy->base + > + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6)); > +} > + > +static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = { > + .hw_version_read = phy_qcom_mipi_csi2_hw_version_read, > + .reset = phy_qcom_mipi_csi2_reset, > + .lanes_enable = phy_qcom_mipi_csi2_lanes_enable, > + .lanes_disable = phy_qcom_mipi_csi2_lanes_disable, > +}; > + > +static const char * const x1e_clks[] = { > + "core", > + "timer", > + "ahb" > +}; > + > +static const char * const x1e_supplies[] = { > + "vdda-0p9", > + "vdda-1p2" > +}; > + > +static struct mipi_csi2_genpd x1e_genpds[] = { > + { .name = "top", .scaled = false }, > + { .name = "mmcx", .scaled = true }, > + { .name = "mx", .scaled = true }, > +}; > + > +const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = { > + .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0, > + .reg_info = { > + .init_seq = lane_regs_x1e80100, > + .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100), > + .common_regs_offset = 0x1000, > + }, > + .supply_names = (const char **)x1e_supplies, > + .num_supplies = ARRAY_SIZE(x1e_supplies), > + .clk_names = (const char **)x1e_clks, > + .num_clk = ARRAY_SIZE(x1e_clks), > + .genpds = x1e_genpds, > + .num_genpds = ARRAY_SIZE(x1e_genpds), > +}; > diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c > new file mode 100644 > index 0000000000000..24ccd3264686f > --- /dev/null > +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c > @@ -0,0 +1,462 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2026, Linaro Ltd. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "phy-qcom-mipi-csi2.h" > + > +static int > +phy_qcom_mipi_csi2_set_clock_rates(struct mipi_csi2phy_device *csi2phy, > + s64 link_freq) > +{ > + struct device *dev = csi2phy->dev; > + unsigned long opp_rate = link_freq / 4; > + struct dev_pm_opp *opp; > + long timer_rate; > + int i, pstate; > + int ret; > + > + opp = dev_pm_opp_find_freq_ceil(dev, &opp_rate); > + if (IS_ERR(opp)) { > + dev_err(csi2phy->dev, "Couldn't find ceiling for %lld Hz\n", > + link_freq); > + return PTR_ERR(opp); > + } > + > + pstate = 0; > + for (i = 0; i < csi2phy->pd_list->num_pds; i++) { > + unsigned int perf; > + > + if (!csi2phy->soc_cfg->genpds[i].scaled) > + continue; > + > + perf = dev_pm_opp_get_required_pstate(opp, pstate); > + pstate += 1; > + > + ret = dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], perf); > + if (ret) { > + dev_err(csi2phy->dev, "Couldn't set perf state %u\n", > + perf); > + dev_pm_opp_put(opp); > + goto unset_pstate; > + } > + } > + dev_pm_opp_put(opp); > + > + ret = dev_pm_opp_set_rate(dev, opp_rate); > + if (ret) { > + dev_err(csi2phy->dev, "dev_pm_opp_set_rate() fail\n"); > + goto unset_opp_rate; > + } > + > + timer_rate = clk_round_rate(csi2phy->timer_clk, link_freq / 4); > + if (timer_rate <= 0) { > + ret = -ENODEV; > + goto unset_opp_rate; > + } > + > + ret = clk_set_rate(csi2phy->timer_clk, timer_rate); > + if (ret) > + goto unset_opp_rate; > + > + csi2phy->timer_clk_rate = timer_rate; > + > + return 0; > + > +unset_opp_rate: > + dev_pm_opp_set_rate(dev, 0); > + > +unset_pstate: > + while (i--) { > + if (!csi2phy->soc_cfg->genpds[i].scaled) > + continue; > + > + dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], 0); > + } > + > + return ret; > +} > + > +static int phy_qcom_mipi_csi2_configure(struct phy *phy, > + union phy_configure_opts *opts) > +{ > + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); > + struct phy_configure_opts_mipi_dphy *dphy_cfg = &opts->mipi_dphy; > + struct mipi_csi2phy_stream_cfg *stream_cfg = &csi2phy->stream_cfg; > + int ret; > + > + ret = phy_mipi_dphy_config_validate(dphy_cfg); > + if (ret) > + return ret; > + > + if (dphy_cfg->lanes < 1 || dphy_cfg->lanes > CSI2_MAX_DATA_LANES) > + return -EINVAL; > + > + stream_cfg->link_freq = dphy_cfg->hs_clk_rate; > + > + return 0; > +} > + > +static int phy_qcom_mipi_csi2_set_mode(struct phy *phy, > + enum phy_mode mode, int submode) > +{ > + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); > + > + if (mode != PHY_MODE_MIPI_DPHY) > + return -EOPNOTSUPP; > + > + csi2phy->phy_mode = mode; > + return 0; > +} > + > +static int phy_qcom_mipi_csi2_power_on(struct phy *phy) > +{ > + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); > + const struct mipi_csi2phy_hw_ops *ops = csi2phy->soc_cfg->ops; > + int i, ret; > + > + ret = regulator_bulk_enable(csi2phy->soc_cfg->num_supplies, > + csi2phy->supplies); > + if (ret) > + return ret; > + > + ret = pm_runtime_resume_and_get(csi2phy->dev); > + if (ret < 0) > + goto disable_regulators; > + > + ret = phy_qcom_mipi_csi2_set_clock_rates(csi2phy, csi2phy->stream_cfg.link_freq); > + if (ret) > + goto poweroff_phy; > + > + ret = clk_bulk_prepare_enable(csi2phy->soc_cfg->num_clk, > + csi2phy->clks); > + if (ret) { > + dev_err(csi2phy->dev, "failed to enable clocks, %d\n", ret); > + goto unset_rate; > + } > + > + ops->reset(csi2phy); > + > + ops->hw_version_read(csi2phy); > + > + ret = ops->lanes_enable(csi2phy, &csi2phy->stream_cfg); > + if (ret) > + goto unset_clocks; > + > + return 0; > + > +unset_clocks: > + clk_bulk_disable_unprepare(csi2phy->soc_cfg->num_clk, > + csi2phy->clks); > + > +unset_rate: > + dev_pm_opp_set_rate(csi2phy->dev, 0); > + > + for (i = 0; i < csi2phy->pd_list->num_pds; i++) { > + if (!csi2phy->soc_cfg->genpds[i].scaled) > + continue; > + > + dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], 0); > + } > + > +poweroff_phy: > + pm_runtime_put_sync(csi2phy->dev); > + > +disable_regulators: > + regulator_bulk_disable(csi2phy->soc_cfg->num_supplies, > + csi2phy->supplies); > + > + return ret; > +} > + > +static int phy_qcom_mipi_csi2_power_off(struct phy *phy) > +{ > + struct mipi_csi2phy_device *csi2phy = phy_get_drvdata(phy); > + const struct mipi_csi2phy_hw_ops *ops = csi2phy->soc_cfg->ops; > + int i; > + > + ops->lanes_disable(csi2phy, &csi2phy->stream_cfg); > + > + clk_bulk_disable_unprepare(csi2phy->soc_cfg->num_clk, > + csi2phy->clks); > + > + dev_pm_opp_set_rate(csi2phy->dev, 0); > + > + for (i = 0; i < csi2phy->pd_list->num_pds; i++) { > + if (!csi2phy->soc_cfg->genpds[i].scaled) > + continue; > + > + dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], 0); > + } > + > + pm_runtime_put_sync(csi2phy->dev); > + > + regulator_bulk_disable(csi2phy->soc_cfg->num_supplies, > + csi2phy->supplies); > + > + return 0; > +} > + > +static const struct phy_ops phy_qcom_mipi_csi2_ops = { > + .configure = phy_qcom_mipi_csi2_configure, > + .set_mode = phy_qcom_mipi_csi2_set_mode, > + .power_on = phy_qcom_mipi_csi2_power_on, > + .power_off = phy_qcom_mipi_csi2_power_off, > + .owner = THIS_MODULE, > +}; > + > +static int phy_qcom_mipi_csi2_attach_pm_domains(struct mipi_csi2phy_device *csi2phy) > +{ > + struct dev_pm_domain_attach_data pd_data = { 0 }; > + const char **pd_names; > + int i; > + > + pd_names = devm_kzalloc(csi2phy->dev, > + sizeof(char *) * csi2phy->soc_cfg->num_genpds, > + GFP_KERNEL); > + if (!pd_names) > + return -ENOMEM; > + > + for (i = 0; i < csi2phy->soc_cfg->num_genpds; i++) > + pd_names[i] = csi2phy->soc_cfg->genpds[i].name; > + > + pd_data.pd_names = pd_names; > + pd_data.num_pd_names = csi2phy->soc_cfg->num_genpds; > + > + return devm_pm_domain_attach_list(csi2phy->dev, &pd_data, > + &csi2phy->pd_list); > +} > + > +static int phy_qcom_mipi_csi2_parse_routing(struct mipi_csi2phy_device *csi2phy) > +{ > + struct mipi_csi2phy_stream_cfg *stream_cfg = &csi2phy->stream_cfg; > + u32 lane_polarities[CSI2_MAX_DATA_LANES + 1]; > + u32 data_lanes[CSI2_MAX_DATA_LANES]; > + struct device *dev = csi2phy->dev; > + struct fwnode_handle *ep; > + int num_polarities; > + int num_data_lanes; > + u32 bus_type; > + int i, ret; > + > + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 1, 0); > + if (ep) { > + fwnode_handle_put(ep); > + dev_err(dev, "DPHY split mode is not supported\n"); > + return -EOPNOTSUPP; > + } > + > + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0); > + if (!ep) { > + dev_err(dev, "Missing port@0\n"); > + return -ENODEV; > + } > + > + ret = fwnode_property_read_u32(ep, "bus-type", &bus_type); > + if (ret) { > + dev_err(dev, "Failed to read bus-type: %d\n", ret); > + goto out_put; > + } > + > + if (bus_type != MEDIA_BUS_TYPE_CSI2_DPHY) { > + ret = -EOPNOTSUPP; > + dev_err(dev, "Unsupported bus-type %u\n", bus_type); > + goto out_put; > + } > + > + num_data_lanes = fwnode_property_count_u32(ep, "data-lanes"); > + if (num_data_lanes < 1 || num_data_lanes > CSI2_MAX_DATA_LANES) { > + ret = -EINVAL; > + dev_err(dev, "Invalid data-lanes count: %d\n", num_data_lanes); > + goto out_put; > + } > + stream_cfg->num_data_lanes = num_data_lanes; > + > + ret = fwnode_property_read_u32_array(ep, "data-lanes", data_lanes, > + stream_cfg->num_data_lanes); > + if (ret) { > + dev_err(dev, "Failed to read data-lanes: %d\n", ret); > + goto out_put; > + } > + > + /* lane-polarities: optional, up to num_data_lanes + 1 entries */ > + memset(lane_polarities, 0x00, sizeof(lane_polarities)); > + num_polarities = fwnode_property_count_u32(ep, "lane-polarities"); > + if (num_polarities > 0) { > + if (num_polarities != stream_cfg->num_data_lanes + 1) { > + ret = -EINVAL; > + dev_err(dev, "clock+data-lane %d/polarities %d mismatch\n", > + stream_cfg->num_data_lanes + 1, num_polarities); > + goto out_put; > + } > + > + ret = fwnode_property_read_u32_array(ep, "lane-polarities", lane_polarities, > + num_polarities); > + if (ret) { > + dev_err(dev, "Failed to read lane-polarities: %d\n", ret); > + goto out_put; > + } > + } > + > + csi2phy->stream_cfg.lane_cfg.clk.pos = CSI2_DEFAULT_CLK_LANE; > + csi2phy->stream_cfg.lane_cfg.clk.pol = lane_polarities[0]; > + > + for (i = 0; i < csi2phy->stream_cfg.num_data_lanes; i++) { > + if (data_lanes[i] < 1 || data_lanes[i] > CSI2_MAX_DATA_LANES) { > + dev_err(dev, "Invalid lane %d\n", data_lanes[i]); > + ret = -EINVAL; > + goto out_put; > + } > + > + /* Convert data-lanes = <1 2 3 4> to bit positions */ > + csi2phy->stream_cfg.lane_cfg.data[i].pos = data_lanes[i] - 1; > + csi2phy->stream_cfg.lane_cfg.data[i].pol = lane_polarities[i + 1]; > + } > + > + ret = 0; > + > +out_put: > + fwnode_handle_put(ep); > + > + return ret; > +} > + > +static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev) > +{ > + unsigned int i, num_clk, num_supplies; > + struct mipi_csi2phy_device *csi2phy; > + struct phy_provider *phy_provider; > + struct device *dev = &pdev->dev; > + struct phy *generic_phy; > + int ret; > + > + csi2phy = devm_kzalloc(dev, sizeof(*csi2phy), GFP_KERNEL); > + if (!csi2phy) > + return -ENOMEM; > + > + csi2phy->dev = dev; > + dev_set_drvdata(dev, csi2phy); > + > + csi2phy->soc_cfg = device_get_match_data(&pdev->dev); > + > + if (!csi2phy->soc_cfg) > + return -EINVAL; > + > + num_clk = csi2phy->soc_cfg->num_clk; > + > + ret = phy_qcom_mipi_csi2_parse_routing(csi2phy); > + if (ret) > + return ret; > + > + ret = phy_qcom_mipi_csi2_attach_pm_domains(csi2phy); > + if (ret < 0 || csi2phy->pd_list == NULL) { Here the check should be simplified: if (ret <= 0) > + if (ret == 0) > + ret = -ENODEV; > + return dev_err_probe(dev, ret, "Failed to attach power-domain list\n"); > + } > + > + ret = devm_pm_runtime_enable(dev); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to enable pm runtime\n"); > + > + ret = devm_clk_bulk_get_all(dev, &csi2phy->clks); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to get clocks\n"); > + > + if (num_clk != ret) { > + return dev_err_probe(dev, -ENODEV, "clock count %d expected %d\n", > + ret, num_clk); > + } > + > + for (i = 0; i < num_clk; i++) { > + if (!csi2phy->clks[i].id) > + return dev_err_probe(dev, -EINVAL, "Missing clock-names\n"); > + > + if (!strcmp(csi2phy->clks[i].id, "timer")) { > + csi2phy->timer_clk = csi2phy->clks[i].clk; > + break; > + } > + } > + if (!csi2phy->timer_clk) > + return dev_err_probe(dev, -ENODEV, "no timer clock\n"); > + > + ret = devm_pm_opp_set_clkname(dev, "core"); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to set opp clkname\n"); > + > + ret = devm_pm_opp_of_add_table(dev); > + if (ret) > + return dev_err_probe(dev, ret, "invalid OPP table in device tree\n"); > + > + num_supplies = csi2phy->soc_cfg->num_supplies; > + csi2phy->supplies = devm_kzalloc(dev, sizeof(*csi2phy->supplies) * num_supplies, > + GFP_KERNEL); > + if (!csi2phy->supplies) > + return -ENOMEM; > + > + for (i = 0; i < num_supplies; i++) > + csi2phy->supplies[i].supply = csi2phy->soc_cfg->supply_names[i]; > + > + ret = devm_regulator_bulk_get(dev, num_supplies, csi2phy->supplies); > + if (ret) > + return dev_err_probe(dev, ret, > + "failed to get regulator supplies\n"); > + > + csi2phy->base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(csi2phy->base)) > + return PTR_ERR(csi2phy->base); > + > + generic_phy = devm_phy_create(dev, NULL, &phy_qcom_mipi_csi2_ops); > + if (IS_ERR(generic_phy)) { > + ret = PTR_ERR(generic_phy); > + return dev_err_probe(dev, ret, "failed to create phy\n"); > + } > + csi2phy->phy = generic_phy; > + > + phy_set_drvdata(generic_phy, csi2phy); > + > + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); > + if (!IS_ERR(phy_provider)) > + dev_dbg(dev, "Registered MIPI CSI2 PHY device\n"); > + > + return PTR_ERR_OR_ZERO(phy_provider); > +} > + > +static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = { > + { .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, phy_qcom_mipi_csi2_of_match_table); > + > +static struct platform_driver phy_qcom_mipi_csi2_driver = { > + .probe = phy_qcom_mipi_csi2_probe, > + .driver = { > + .name = "qcom-mipi-csi2-phy", > + .of_match_table = phy_qcom_mipi_csi2_of_match_table, > + }, > +}; > + > +module_platform_driver(phy_qcom_mipi_csi2_driver); > + > +MODULE_DESCRIPTION("Qualcomm MIPI CSI2 PHY driver"); > +MODULE_AUTHOR("Bryan O'Donoghue "); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h > new file mode 100644 > index 0000000000000..7e55ae0073704 > --- /dev/null > +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h > @@ -0,0 +1,97 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * > + * Qualcomm MIPI CSI2 CPHY/DPHY driver > + * > + * Copyright (C) 2025 Linaro Ltd. > + */ > +#ifndef __PHY_QCOM_MIPI_CSI2_H__ > +#define __PHY_QCOM_MIPI_CSI2_H__ > + > +#include > + > +#define CSI2_MAX_DATA_LANES 4 > +#define CSI2_DEFAULT_CLK_LANE 7 It was mentioned one day earlier that this bit value is named awkwardly. Moreover it's too specific to D-PHY IP to be present in the generic CSI2 header file, therefore it shall be moved out. > + > +struct mipi_csi2phy_lane { > + u8 pos; > + u8 pol; > +}; > + > +struct mipi_csi2phy_lanes_cfg { > + struct mipi_csi2phy_lane data[CSI2_MAX_DATA_LANES]; > + struct mipi_csi2phy_lane clk; > +}; > + > +struct mipi_csi2phy_stream_cfg { > + s64 link_freq; > + u8 num_data_lanes; > + struct mipi_csi2phy_lanes_cfg lane_cfg; > +}; > + > +struct mipi_csi2phy_device; > + > +struct mipi_csi2phy_hw_ops { > + void (*hw_version_read)(struct mipi_csi2phy_device *csi2phy_dev); > + void (*reset)(struct mipi_csi2phy_device *csi2phy_dev); > + int (*lanes_enable)(struct mipi_csi2phy_device *csi2phy_dev, > + struct mipi_csi2phy_stream_cfg *cfg); > + void (*lanes_disable)(struct mipi_csi2phy_device *csi2phy_dev, > + struct mipi_csi2phy_stream_cfg *cfg); > +}; > + > +struct mipi_csi2phy_lane_regs { > + const s32 reg_addr; > + const s32 reg_data; > + const u32 delay_us; > + const u32 param_type; > +}; > + > +struct mipi_csi2phy_device_regs { > + const struct mipi_csi2phy_lane_regs *init_seq; > + const int lane_array_size; > + const u32 common_regs_offset; > +}; > + > +struct mipi_csi2_genpd { > + const char *name; > + bool scaled; > +}; > + > +struct mipi_csi2phy_soc_cfg { > + const struct mipi_csi2phy_hw_ops *ops; > + const struct mipi_csi2phy_device_regs reg_info; > + > + const char ** const supply_names; > + const unsigned int num_supplies; > + > + const char ** const clk_names; > + const unsigned int num_clk; > + > + const struct mipi_csi2_genpd *genpds; > + const unsigned int num_genpds; > +}; > + > +struct mipi_csi2phy_device { > + struct device *dev; > + u8 phy_mode; > + > + struct phy *phy; > + void __iomem *base; > + > + struct clk_bulk_data *clks; > + struct clk *timer_clk; > + u32 timer_clk_rate; > + > + struct regulator_bulk_data *supplies; > + struct dev_pm_domain_list *pd_list; > + > + const struct mipi_csi2phy_soc_cfg *soc_cfg; > + struct mipi_csi2phy_stream_cfg stream_cfg; > + > + u32 hw_version; > +}; > + > +extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e; > + > +#endif /* __PHY_QCOM_MIPI_CSI2_H__ */ > In general the driver looks to be acceptable, however testing of the driver requires CAMSS changes and board .dts changes, preferably information about an option to test the new driver should be found in the cover letter. -- Best wishes, Vladimir