From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11E77C433ED for ; Tue, 27 Apr 2021 05:13:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DD717613BD for ; Tue, 27 Apr 2021 05:13:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229816AbhD0FOU (ORCPT ); Tue, 27 Apr 2021 01:14:20 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:37621 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S229490AbhD0FOK (ORCPT ); Tue, 27 Apr 2021 01:14:10 -0400 X-UUID: e881996b25bb4259805ab6b01117d145-20210427 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=uzsSyPxHHxrhb1lFeAcu+VgrjfksbWmOKTmPF5fBR68=; b=RgR7ukyRPY3k0BaaZAPWMFU24I3BXATonD2LLxU8dXghTuuZjKhh4D0lwNCxreuxzNyM7JXXq1YOw6nIqomCdZyls6eSuRydZpGHsMim6E9ChHeZjm9144sn7NjYld97akwKgfPB2soCzPOrxVgprxi6ejJSRhciHwb+riQI7Gc=; X-UUID: e881996b25bb4259805ab6b01117d145-20210427 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1418526072; Tue, 27 Apr 2021 13:13:22 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 27 Apr 2021 13:13:21 +0800 Received: from [172.21.77.33] (172.21.77.33) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 27 Apr 2021 13:13:21 +0800 Message-ID: <1619500401.27332.40.camel@mtkswgap22> Subject: Re: [PATCH v2 2/4] memory: mediatek: add DRAM controller driver From: Po-Kai Chi To: Rob Herring CC: Matthias Brugger , , , , , CC Hwang Date: Tue, 27 Apr 2021 13:13:21 +0800 In-Reply-To: <20210420182827.GA3439758@robh.at.kernel.org> References: <1618565538-6972-1-git-send-email-pk.chi@mediatek.com> <1618565538-6972-3-git-send-email-pk.chi@mediatek.com> <20210420182827.GA3439758@robh.at.kernel.org> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org SGVsbG8gUm9iLA0KDQpUaGFua3MgZm9yIHlvdXIgY29tbWVudHMuDQoNClBvLUthaSBDaGkNCg0K T24gVHVlLCAyMDIxLTA0LTIwIGF0IDEzOjI4IC0wNTAwLCBSb2IgSGVycmluZyB3cm90ZToNCj4g T24gRnJpLCBBcHIgMTYsIDIwMjEgYXQgMDU6MzI6MTZQTSArMDgwMCwgUG8tS2FpIENoaSB3cm90 ZToNCj4gPiBNZWRpYVRlayBEUkFNIGNvbnRyb2xsZXIgKERSQU1DKSBkcml2ZXIgcHJvdmlkZXMg Y3Jvc3MtcGxhdGZvcm0gZmVhdHVyZXMNCj4gPiBhcyBiZWxvdzoNCj4gPiANCj4gPiAxLiBwcm92 aWRlIEFQSXMgZm9yIGxvdyBwb3dlciBmZWF0dXJlIHF1ZXJpZXMNCj4gPiAyLiBjcmVhdGUgc3lz ZnMgdG8gcGFzcyB0aGUgRFJBTSBpbmZvcm1hdGlvbiB0byB1c2VyLXNwYWNlDQo+IA0KPiBJJ20g aGVzaXN0YW50IHdpdGggaGF2aW5nIGJvdGggRFQgYW5kIHN5c2ZzIHZlbmRvciBzcGVjaWZpYyBt ZW1vcnkgDQo+IHByb3BlcnRpZXMuIEkgdGhpbmsgd2UgbmVlZCBzb21ldGhpbmcgY29tbW9uIGhl cmUuDQo+IA0KDQpTeXNmcyBwcm92aWRlcyB1c2VycyB3aXRoIGEgdW5pZmllZCBpbnRlcmZhY2Ug Zm9yIHF1ZXJ5aW5nIERSQU0gc3RhdHVzDQphdCBydW50aW1lLg0KDQotIERSSVZFUl9BVFRSX1JP KG1yKQ0KVGhlIGNvbnRlbnQgaXMgdGhlIHNhbWUgYXMgRFQgcGFzc2VkIGZyb20gYm9vdGxvYWRl ciwgYnV0IHByb3ZpZGVzDQpiZXR0ZXIgZmlsZSBwYXRoIGNvbnNpc3RlbmN5Lg0KDQotIERSSVZF Ul9BVFRSX1JPKG1yNCkNClVzZWQgdG8gcXVlcnkgdGhlIGN1cnJlbnQgRFJBTSBjaGlwIHJlZnJl c2ggcmF0ZSAoYnkgcmVhZGluZyBtb2RlDQpyZWdpc3Rlci00IGF0IHJ1biB0aW1lKS4NClRoZSBu YW1pbmcgY2FuIGJlIG1pc2xlYWRpbmcsIEknbGwgcmVuYW1lIGl0IGZvciB0aGUgbmV4dCB2ZXJz aW9uLg0KDQotIERSSVZFUl9BVFRSX1JPKGRyYW1fZGF0YV9yYXRlKQ0KVXNlZCB0byBjYWxjdWxh dGUgdGhlIGN1cnJlbnQgRFJBTSBkYXRhIHJhdGUuDQoNCj4gPiANCj4gPiBTaWduZWQtb2ZmLWJ5 OiBQby1LYWkgQ2hpIDxway5jaGlAbWVkaWF0ZWsuY29tPg0KPiA+IC0tLQ0KPiA+ICBkcml2ZXJz L21lbW9yeS9LY29uZmlnICAgICAgICAgICAgICB8ICAgIDEgKw0KPiA+ICBkcml2ZXJzL21lbW9y eS9NYWtlZmlsZSAgICAgICAgICAgICB8ICAgIDEgKw0KPiA+ICBkcml2ZXJzL21lbW9yeS9tZWRp YXRlay9LY29uZmlnICAgICB8ICAgIDkgKw0KPiA+ICBkcml2ZXJzL21lbW9yeS9tZWRpYXRlay9N YWtlZmlsZSAgICB8ICAgIDMgKw0KPiA+ICBkcml2ZXJzL21lbW9yeS9tZWRpYXRlay9tdGstZHJh bWMuYyB8ICA3MTEgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysNCj4gPiAgaW5j bHVkZS9tZW1vcnkvbWVkaWF0ZWsvZHJhbWMuaCAgICAgfCAgIDE4ICsNCj4gPiAgNiBmaWxlcyBj aGFuZ2VkLCA3NDMgaW5zZXJ0aW9ucygrKQ0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9tZW1vcnkvbWVkaWF0ZWsvS2NvbmZpZw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9tZW1vcnkvbWVkaWF0ZWsvTWFrZWZpbGUNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvbWVtb3J5L21lZGlhdGVrL210ay1kcmFtYy5jDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBp bmNsdWRlL21lbW9yeS9tZWRpYXRlay9kcmFtYy5oDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL2Ry aXZlcnMvbWVtb3J5L0tjb25maWcgYi9kcml2ZXJzL21lbW9yeS9LY29uZmlnDQo+ID4gaW5kZXgg NzJjMGRmMS4uMDU2ZTkwNiAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL21lbW9yeS9LY29uZmln DQo+ID4gKysrIGIvZHJpdmVycy9tZW1vcnkvS2NvbmZpZw0KPiA+IEBAIC0yMjUsNiArMjI1LDcg QEAgY29uZmlnIFNUTTMyX0ZNQzJfRUJJDQo+ID4gIAkgIGRldmljZXMgKGxpa2UgU1JBTSwgZXRo ZXJuZXQgYWRhcHRlcnMsIEZQR0FzLCBMQ0QgZGlzcGxheXMsIC4uLikgb24NCj4gPiAgCSAgU09D cyBjb250YWluaW5nIHRoZSBGTUMyIEV4dGVybmFsIEJ1cyBJbnRlcmZhY2UuDQo+ID4gIA0KPiA+ ICtzb3VyY2UgImRyaXZlcnMvbWVtb3J5L21lZGlhdGVrL0tjb25maWciDQo+ID4gIHNvdXJjZSAi ZHJpdmVycy9tZW1vcnkvc2Ftc3VuZy9LY29uZmlnIg0KPiA+ICBzb3VyY2UgImRyaXZlcnMvbWVt b3J5L3RlZ3JhL0tjb25maWciDQo+ID4gIA0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21lbW9y eS9NYWtlZmlsZSBiL2RyaXZlcnMvbWVtb3J5L01ha2VmaWxlDQo+ID4gaW5kZXggYmM3NjYzZS4u Y2Q0ZjhjZiAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL21lbW9yeS9NYWtlZmlsZQ0KPiA+ICsr KyBiL2RyaXZlcnMvbWVtb3J5L01ha2VmaWxlDQo+ID4gQEAgLTI1LDYgKzI1LDcgQEAgb2JqLSQo Q09ORklHX1BMMzUzX1NNQykJCSs9IHBsMzUzLXNtYy5vDQo+ID4gIG9iai0kKENPTkZJR19SRU5F U0FTX1JQQ0lGKQkrPSByZW5lc2FzLXJwYy1pZi5vDQo+ID4gIG9iai0kKENPTkZJR19TVE0zMl9G TUMyX0VCSSkJKz0gc3RtMzItZm1jMi1lYmkubw0KPiA+ICANCj4gPiArb2JqLSQoQ09ORklHX01U S19EUkFNQykJCSs9IG1lZGlhdGVrLw0KPiA+ICBvYmotJChDT05GSUdfU0FNU1VOR19NQykJKz0g c2Ftc3VuZy8NCj4gPiAgb2JqLSQoQ09ORklHX1RFR1JBX01DKQkJKz0gdGVncmEvDQo+ID4gIG9i ai0kKENPTkZJR19USV9FTUlGX1NSQU0pCSs9IHRpLWVtaWYtc3JhbS5vDQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvbWVtb3J5L21lZGlhdGVrL0tjb25maWcgYi9kcml2ZXJzL21lbW9yeS9tZWRp YXRlay9LY29uZmlnDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gPiBpbmRleCAwMDAwMDAw Li5hMTYxOGIwDQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvbWVtb3J5L21l ZGlhdGVrL0tjb25maWcNCj4gPiBAQCAtMCwwICsxLDkgQEANCj4gPiArIyBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogR1BMLTIuMA0KPiA+ICsNCj4gPiArY29uZmlnIE1US19EUkFNQw0KPiA+ICsJ dHJpc3RhdGUgIk1lZGlhVGVrIERSQU1DIGRyaXZlciINCj4gPiArCWhlbHANCj4gPiArCSAgVGhp cyBzZWxlY3RzIHRoZSBNZWRpYVRlayhSKSBEUkFNQyBkcml2ZXIuDQo+ID4gKwkgIFByb3ZpZGUg dGhlIEFQSSBmb3IgRFJBTUMgbG93IHBvd2VyIHNjZW5hcmlvLCBhbmQgdGhlIGludGVyZmFjZQ0K PiA+ICsJICBmb3IgcmVwb3J0aW5nIERSQU0gaW5mb3JtYXRpb24sIGUuZy4gRFJBTSBtb2RlIHJl Z2lzdGVyIChNUikgZm9yDQo+ID4gKwkgIERSQU0gdmVuZG9yIElELCB0ZW1wZXJhdHVyZSwgYW5k IGRlbnNpdHkuDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVtb3J5L21lZGlhdGVrL01ha2Vm aWxlIGIvZHJpdmVycy9tZW1vcnkvbWVkaWF0ZWsvTWFrZWZpbGUNCj4gPiBuZXcgZmlsZSBtb2Rl IDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjYzMmJlNDgNCj4gPiAtLS0gL2Rldi9udWxsDQo+ ID4gKysrIGIvZHJpdmVycy9tZW1vcnkvbWVkaWF0ZWsvTWFrZWZpbGUNCj4gPiBAQCAtMCwwICsx LDMgQEANCj4gPiArIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMA0KPiA+ICsNCj4g PiArb2JqLSQoQ09ORklHX01US19EUkFNQykJKz0gbXRrLWRyYW1jLm8NCj4gPiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9tZW1vcnkvbWVkaWF0ZWsvbXRrLWRyYW1jLmMgYi9kcml2ZXJzL21lbW9yeS9t ZWRpYXRlay9tdGstZHJhbWMuYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXgg MDAwMDAwMC4uMTU1YjNiNw0KPiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL21l bW9yeS9tZWRpYXRlay9tdGstZHJhbWMuYw0KPiA+IEBAIC0wLDAgKzEsNzExIEBADQo+ID4gKy8v IFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wDQo+ID4gKy8qDQo+ID4gKyAqIENvcHly aWdodCAoYykgMjAyMSBNZWRpYVRlayBJbmMuDQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1 ZGUgPGxpbnV4L2tlcm5lbC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4g KyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3Jt X2RldmljZS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4NCj4gPiArI2luY2x1ZGUgPGxp bnV4L29mX2FkZHJlc3MuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiA+ ICsjaW5jbHVkZSA8bGludXgvcHJpbnRrLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+ DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pby5oPg0KPiA+ICsjaW5jbHVkZSA8bWVtb3J5L21lZGlh dGVrL2RyYW1jLmg+DQo+ID4gKw0KPiA+ICsjZGVmaW5lIERSQU1DX0RSVl9OQU1FCSJtdGstZHJh bWMiDQo+ID4gKw0KPiA+ICtzdHJ1Y3QgbXJfaW5mb190IHsNCj4gPiArCXVuc2lnbmVkIGludCBt cl9pbmRleDsNCj4gPiArCXVuc2lnbmVkIGludCBtcl92YWx1ZTsNCj4gPiArfTsNCj4gPiArDQo+ ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCByZWdfY3RybF90IC0gdG8gZGVzY3JpYmUgdGhlIGJpdHMg cmVxdWlyZWQgaW4gYSByZWdpc3Rlcg0KPiA+ICsgKiBAb2Zmc2V0OiByZWdpc3RlciBhZGRyZXNz IG9mZnNldCBmcm9tIGEgYmFzZQ0KPiA+ICsgKiBAbWFzazogYml0bWFzayBvZiB0aGUgdGFyZ2V0 IGJpdHMNCj4gPiArICogQHNoaWZ0OiBzdGFydGluZyBiaXQgb2YgdGhlIHRhcmdldCBiaXRzDQo+ ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgcmVnX2N0cmxfdCB7DQo+ID4gKwl1bnNpZ25lZCBpbnQgb2Zm c2V0Ow0KPiA+ICsJdW5zaWduZWQgaW50IG1hc2s7DQo+ID4gKwl1bnNpZ25lZCBpbnQgc2hpZnQ7 DQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgZm1ldGVyX2Rldl90IHsNCj4gPiArCXVuc2ln bmVkIGludCBjcnlzdGFsX2ZyZXE7DQo+ID4gKwl1bnNpZ25lZCBpbnQgc2h1X29mOw0KPiA+ICsJ c3RydWN0IHJlZ19jdHJsX3Qgc2h1X2x2Ow0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3QgcGxsX2lk Ow0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3QgcGxsX21kWzJdOw0KPiA+ICsJc3RydWN0IHJlZ19j dHJsX3Qgc2RtcGN3WzJdOw0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3QgcHJlZGl2WzJdOw0KPiA+ ICsJc3RydWN0IHJlZ19jdHJsX3QgcG9zZGl2WzJdOw0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3Qg Y2tkaXY0WzJdOw0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3QgY2xkaXYyWzJdOw0KPiA+ICsJc3Ry dWN0IHJlZ19jdHJsX3QgZmJrc2VsWzJdOw0KPiA+ICsJc3RydWN0IHJlZ19jdHJsX3QgZHFvcGVu WzJdOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RydWN0IG1yNF9kZXZfdCB7DQo+ID4gKwlzdHJ1 Y3QgcmVnX2N0cmxfdCBtcjRfcmc7DQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgZHJhbWNf ZGV2X3Qgew0KPiA+ICsJdW5zaWduZWQgaW50IGRyYW1fdHlwZTsNCj4gPiArCXVuc2lnbmVkIGlu dCBzdXBwb3J0X2NoYW5uZWxfY250Ow0KPiA+ICsJdW5zaWduZWQgaW50IGNoYW5uZWxfY250Ow0K PiA+ICsJdW5zaWduZWQgaW50IHJhbmtfY250Ow0KPiA+ICsJdW5zaWduZWQgaW50IG1yX2NudDsN Cj4gPiArCXVuc2lnbmVkIGludCBmcmVxX2NudDsNCj4gPiArCXVuc2lnbmVkIGludCAqcmFua19z aXplOw0KPiA+ICsJdW5zaWduZWQgaW50ICpmcmVxX3N0ZXA7DQo+ID4gKwlzdHJ1Y3QgbXJfaW5m b190ICptcl9pbmZvX3B0cjsNCj4gPiArCXZvaWQgX19pb21lbSAqKmRyYW1jX2Nobl9iYXNlX2Fv Ow0KPiA+ICsJdm9pZCBfX2lvbWVtICoqZHJhbWNfY2huX2Jhc2VfbmFvOw0KPiA+ICsJdm9pZCBf X2lvbWVtICoqZGRycGh5X2Nobl9iYXNlX2FvOw0KPiA+ICsJdm9pZCAqbXI0X2Rldl9wdHI7DQo+ ID4gKwl2b2lkICpmbWV0ZXJfZGV2X3B0cjsNCj4gPiArfTsNCj4gPiArDQo+ID4gK2VudW0gRFJB TV9UWVBFIHsNCj4gPiArCVRZUEVfTk9ORSA9IDAsDQo+ID4gKwlUWVBFX0REUjEsDQo+ID4gKwlU WVBFX0xQRERSMiwNCj4gPiArCVRZUEVfTFBERFIzLA0KPiA+ICsJVFlQRV9QQ0REUjMsDQo+ID4g KwlUWVBFX0xQRERSNCwNCj4gPiArCVRZUEVfTFBERFI0WCwNCj4gPiArCVRZUEVfTFBERFI0UA0K PiA+ICt9Ow0KPiANCj4gVGhpcyBkb2Vzbid0IGFwcGVhciB0byBiZSB1c2VkLg0KDQpZZXMsIGl0 IGlzIG5vdCBjdXJyZW50bHkgaW4gdXNlLCBJJ2xsIHJlbW92ZSBpdC4NCg0KPiA+ICsNCj4gPiAr c3RhdGljIGNvbnN0IHN0cnVjdCBmbWV0ZXJfZGV2X3QgZm1ldGVyX3YwX210Njc3OV90ID0gew0K PiA+ICsJLmNyeXN0YWxfZnJlcSA9IDUyLA0KPiA+ICsJLnNodV9vZiA9IDB4NTAwLA0KPiA+ICsJ LnNodV9sdiA9IHsgLm9mZnNldCA9IDB4MDBlNCwgLm1hc2sgPSAweDAwMDAwMDA2LCAuc2hpZnQg PSAxIH0sDQo+ID4gKwkucGxsX2lkID0geyAub2Zmc2V0ID0gMHgwNTEwLCAubWFzayA9IDB4ODAw MDAwMDAsIC5zaGlmdCA9IDMxIH0sDQo+ID4gKwkucGxsX21kID0gew0KPiA+ICsJCXsgLm9mZnNl dCA9IDB4MGQ4NCwgLm1hc2sgPSAweDAwMDAwMTAwLCAuc2hpZnQgPSA4IH0sDQo+ID4gKwkJeyAu b2Zmc2V0ID0gMHgwZDg0LCAubWFzayA9IDB4MDAwMDAxMDAsIC5zaGlmdCA9IDggfSwNCj4gPiAr CX0sDQo+ID4gKwkuc2RtcGN3ID0gew0KPiA+ICsJCXsgLm9mZnNldCA9IDB4MGQ5YywgLm1hc2sg PSAweGZmZmYwMDAwLCAuc2hpZnQgPSAxNiB9LA0KPiA+ICsJCXsgLm9mZnNldCA9IDB4MGQ5NCwg Lm1hc2sgPSAweGZmZmYwMDAwLCAuc2hpZnQgPSAxNiB9LA0KPiA+ICsJfSwNCj4gPiArCS5wcmVk aXYgPSB7DQo+ID4gKwkJeyAub2Zmc2V0ID0gMHgwZGE4LCAubWFzayA9IDB4MDAwYzAwMDAsIC5z aGlmdCA9IDE4IH0sDQo+ID4gKwkJeyAub2Zmc2V0ID0gMHgwZGEwLCAubWFzayA9IDB4MDAwYzAw MDAsIC5zaGlmdCA9IDE4IH0sDQo+ID4gKwl9LA0KPiA+ICsJLnBvc2RpdiA9IHsNCj4gPiArCQl7 IC5vZmZzZXQgPSAweDBkYTgsIC5tYXNrID0gMHgwMDAwMDAwNywgLnNoaWZ0ID0gMCB9LA0KPiA+ ICsJCXsgLm9mZnNldCA9IDB4MGRhMCwgLm1hc2sgPSAweDAwMDAwMDA3LCAuc2hpZnQgPSAwIH0s DQo+ID4gKwl9LA0KPiA+ICsJLmNrZGl2NCA9IHsNCj4gPiArCQl7IC5vZmZzZXQgPSAweDBkMTgs IC5tYXNrID0gMHgwODAwMDAwMCwgLnNoaWZ0ID0gMjcgfSwNCj4gPiArCQl7IC5vZmZzZXQgPSAw eDBkMTgsIC5tYXNrID0gMHgwODAwMDAwMCwgLnNoaWZ0ID0gMjcgfSwNCj4gPiArCX0sDQo+ID4g KwkuY2xkaXYyID0gew0KPiA+ICsJCXsgLm9mZnNldCA9IDB4MGMzOCwgLm1hc2sgPSAweDgwMDAw MDAwLCAuc2hpZnQgPSAzMSB9LA0KPiA+ICsJCXsgLm9mZnNldCA9IDB4MGMzOCwgLm1hc2sgPSAw eDgwMDAwMDAwLCAuc2hpZnQgPSAzMSB9LA0KPiA+ICsJfSwNCj4gPiArfTsNCj4gPiArDQo+ID4g K3N0YXRpYyBjb25zdCBzdHJ1Y3QgbXI0X2Rldl90IG1yNF92MV9tdDY3NzlfdCA9IHsNCj4gPiAr CS5tcjRfcmcgPSB7IC5vZmZzZXQgPSAweDAwOTAsIC5tYXNrID0gMHgwMDAwZmZmZiwgLnNoaWZ0 ID0gMCB9LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RydWN0IG10a19kcmFtY19jb21wYXRpYmxl IHsNCj4gPiArCWNvbnN0IHN0cnVjdCBmbWV0ZXJfZGV2X3QgKmZtZXRlcjsNCj4gPiArCWNvbnN0 IHN0cnVjdCBtcjRfZGV2X3QgKm1yNDsNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgbXRrX2RyYW1jX2NvbXBhdGlibGUgbXQ2Nzc5X2NvbXBhdCA9IHsNCj4gPiArCS5m bWV0ZXIgPSAmZm1ldGVyX3YwX210Njc3OV90LA0KPiA+ICsJLm1yNCA9ICZtcjRfdjFfbXQ2Nzc5 X3QsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9p ZCBtdGtfZHJhbWNfb2ZfaWRzW10gPSB7DQo+ID4gKwl7IC5jb21wYXRpYmxlID0gIm1lZGlhdGVr LG10Njc3OS1kcmFtYyIsIC5kYXRhID0gJm10Njc3OV9jb21wYXQgfSwNCj4gPiArCXt9DQo+ID4g K307DQo+ID4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIG10a19kcmFtY19vZl9pZHMpOw0KPiA+ ICsNCj4gPiArLyoNCj4gPiArICogbXRrX2RyYW1jX2dldF9kcnZkYXRhX2J5X2lkcyAtIGdldCB0 aGUgZHJhbWMgZHJpdmVyIGRhdGENCj4gPiArICoNCj4gPiArICogUmV0dXJuIHRoZSBkcmFtYyBk cml2ZXIgZGF0YQ0KPiA+ICsgKi8NCj4gPiArc3RhdGljIHN0cnVjdCBkcmFtY19kZXZfdCAqbXRr X2RyYW1jX2dldF9kcnZkYXRhX2J5X2lkcyh2b2lkKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2 aWNlX25vZGUgKm5wOw0KPiA+ICsJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqZHJhbWNfcGRldjsN Cj4gPiArDQo+ID4gKwlucCA9IG9mX2ZpbmRfbWF0Y2hpbmdfbm9kZV9hbmRfbWF0Y2goTlVMTCwg bXRrX2RyYW1jX29mX2lkcywgTlVMTCk7DQo+ID4gKwlkcmFtY19wZGV2ID0gb2ZfZmluZF9kZXZp Y2VfYnlfbm9kZShucCk7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19wZGV2KQ0KPiA+ICsJCXJl dHVybiBOVUxMOw0KPiA+ICsNCj4gPiArCXJldHVybiAoc3RydWN0IGRyYW1jX2Rldl90ICopcGxh dGZvcm1fZ2V0X2RydmRhdGEoZHJhbWNfcGRldik7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRp YyBzc2l6ZV90IG1yX3Nob3coc3RydWN0IGRldmljZV9kcml2ZXIgKmRyaXZlciwgY2hhciAqYnVm KQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZHJhbWNfZGV2X3QgKmRyYW1jX2Rldl9wdHI7DQo+ID4g KwlzdHJ1Y3QgbXJfaW5mb190ICptcl9pbmZvX3B0cjsNCj4gPiArCXVuc2lnbmVkIGludCBpOw0K PiA+ICsJc3NpemVfdCByZXQ7DQo+ID4gKw0KPiA+ICsJZHJhbWNfZGV2X3B0ciA9IG10a19kcmFt Y19nZXRfZHJ2ZGF0YV9ieV9pZHMoKTsNCj4gPiArDQo+ID4gKwlpZiAoIWRyYW1jX2Rldl9wdHIp DQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJbXJfaW5mb19wdHIgPSBkcmFtY19kZXZf cHRyLT5tcl9pbmZvX3B0cjsNCj4gPiArDQo+ID4gKwlmb3IgKHJldCA9IDAsIGkgPSAwOyBpIDwg ZHJhbWNfZGV2X3B0ci0+bXJfY250OyBpKyspIHsNCj4gPiArCQlyZXQgKz0gc25wcmludGYoYnVm ICsgcmV0LCBQQUdFX1NJWkUgLSByZXQsDQo+ID4gKwkJCQkibXIlZDogMHgleFxuIiwNCj4gDQo+ IFRoZSBmaWxlIG5hbWUgaXMgJ21yJyBhbmQgd2hhdCB5b3UgcmVhZCBzaG91bGQgYmUganVzdCB0 aGUgdmFsdWUuDQoNCidtcicgaXMgdGhlIGFiYnJldmlhdGlvbiBvZiAnTW9kZSBSZWdpc3Rlcics IHdoaWNoIGRlZmluZWQgYnkgSkVERUMuDQoNClRoZXJlIGFyZSA2NCBtb2RlIHJlZ2lzdGVycyBp biBMUEREUjRYIGJ1dCBub3QgYWxsIG9mIHRoZW0gYXJlDQptZWFuaW5nZnVsLCBzbyB3ZSBuZWVk IGEgPGluZGV4LCB2YWx1ZT4gcGFpciB0byBkZXNjcmliZSBzb21lIG9mIHRoZW0uDQoNCldoaWNo IG1vZGUgcmVnaXN0ZXJzIHdpbGwgYmUgYnJvdWdodCB0byB0aGUga2VybmVsIGFyZSBkZXBlbmRz IG9uIHRoZQ0KYm9vdGxvYWRlci4NCg0KPiANCj4gQWxzbywgc3lzZnMgZmlsZXMgcmVxdWlyZSBk b2N1bWVudGF0aW9uIHRvby4NCg0KT2theSwgSSdsbCBmaWxsIGluIHRoZSByZXF1aXJlbWVudHMu DQoNCj4gDQo+ID4gKwkJCQltcl9pbmZvX3B0cltpXS5tcl9pbmRleCwNCj4gPiArCQkJCW1yX2lu Zm9fcHRyW2ldLm1yX3ZhbHVlKTsNCj4gPiArCQlpZiAocmV0ID49IFBBR0VfU0laRSkNCj4gPiAr CQkJcmV0dXJuIHN0cmxlbihidWYpOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVybiBzdHJs ZW4oYnVmKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHNzaXplX3QgbXI0X3Nob3coc3Ry dWN0IGRldmljZV9kcml2ZXIgKmRyaXZlciwgY2hhciAqYnVmKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1 Y3QgZHJhbWNfZGV2X3QgKmRyYW1jX2Rldl9wdHI7DQo+ID4gKwl1bnNpZ25lZCBpbnQgaTsNCj4g PiArCXNzaXplX3QgcmV0Ow0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHIgPSBtdGtfZHJhbWNf Z2V0X2RydmRhdGFfYnlfaWRzKCk7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19kZXZfcHRyKQ0K PiA+ICsJCXJldHVybiAwOw0KPiA+ICsNCj4gPiArCWZvciAocmV0ID0gMCwgaSA9IDA7IGkgPCBk cmFtY19kZXZfcHRyLT5jaGFubmVsX2NudDsgaSsrKSB7DQo+ID4gKwkJcmV0ICs9IHNucHJpbnRm KGJ1ZiArIHJldCwgUEFHRV9TSVpFIC0gcmV0LA0KPiA+ICsJCQkJIm1yNDogY2glZCAweCV4XG4i LA0KPiANCj4gU2FtZSBpc3N1ZXMgaGVyZS4NCj4gDQo+ID4gKwkJCQlpLCBtdGtfZHJhbWNfZ2V0 X21yNChpKSk7DQo+ID4gKwkJaWYgKHJldCA+PSBQQUdFX1NJWkUpDQo+ID4gKwkJCXJldHVybiBz dHJsZW4oYnVmKTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4gc3RybGVuKGJ1Zik7DQo+ ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBzc2l6ZV90IGRyYW1fZGF0YV9yYXRlX3Nob3coc3Ry dWN0IGRldmljZV9kcml2ZXIgKmRyaXZlciwgY2hhciAqYnVmKQ0KPiA+ICt7DQo+ID4gKwlyZXR1 cm4gc25wcmludGYoYnVmLCBQQUdFX1NJWkUsICJEUkFNIGRhdGEgcmF0ZSA9ICVkXG4iLA0KPiA+ ICsJCQltdGtfZHJhbWNfZ2V0X2RhdGFfcmF0ZSgpKTsNCj4gDQo+IEFuZCBoZXJlLg0KPiANCj4g PiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIERSSVZFUl9BVFRSX1JPKG1yKTsNCj4gPiArc3RhdGlj IERSSVZFUl9BVFRSX1JPKG1yNCk7DQo+ID4gK3N0YXRpYyBEUklWRVJfQVRUUl9STyhkcmFtX2Rh dGFfcmF0ZSk7DQo+IA0KPiBBIGRyaXZlciBhdHRyIHdvdWxkIGJlIGdsb2JhbC4gU2hvdWxkbid0 IHRoZXNlIGJlIGRldmljZSBhdHRyJ3Mgd2hpY2ggDQo+IGFyZSBwZXIgaW5zdGFuY2UuDQoNClRo ZXJlIGlzIGFsd2F5cyBvbmx5IG9uZSBEUkFNQyBpbnN0YW5jZSBpbiB0aGUgTWVkaWFUZWsgU29D LCANCg0KPiANCj4gWW91IHNob3VsZCBhbHNvIGJlIHVzaW5nIGF0dHJpYnV0ZSBncm91cHMuDQoN Ck9rYXkuDQoNCj4gDQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGRyYW1jX3Byb2JlKHN0cnVjdCBw bGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAq ZHJhbWNfbm9kZSA9IHBkZXYtPmRldi5vZl9ub2RlOw0KPiA+ICsJc3RydWN0IGRyYW1jX2Rldl90 ICpkcmFtY19kZXZfcHRyOw0KPiA+ICsJY29uc3Qgc3RydWN0IG10a19kcmFtY19jb21wYXRpYmxl ICpkZXZfY29tcDsNCj4gPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzOw0KPiA+ICsJdW5zaWduZWQg aW50IGksIHNpemU7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXByX2luZm8oIiVzOiBt b2R1bGUgcHJvYmUuXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKw0KPiA+ICsJZHJhbWNfZGV2X3B0ciA9 IGRldm1fa21hbGxvYygmcGRldi0+ZGV2LA0KPiANCj4gUHJvYmFibHkgd2FudCB0byB1c2UgZGV2 bV9remFsbG9jIGluc3RlYWQuDQoNCkl0IHdvdWxkIGJlIGJldHRlciwgSSdsbCB1cGRhdGUgaXQu DQoNCj4gDQo+ID4gKwkJCQkgICAgIHNpemVvZihzdHJ1Y3QgZHJhbWNfZGV2X3QpLA0KPiA+ICsJ CQkJICAgICBHRlBfS0VSTkVMKTsNCj4gPiArDQo+ID4gKwlkZXZfY29tcCA9DQo+ID4gKwkJKHN0 cnVjdCBtdGtfZHJhbWNfY29tcGF0aWJsZSAqKQ0KPiA+ICsJCQlvZl9kZXZpY2VfZ2V0X21hdGNo X2RhdGEoJnBkZXYtPmRldik7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19kZXZfcHRyKQ0KPiA+ ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiArCXJldCA9IG9mX3Byb3BlcnR5X3JlYWRf dTMyKGRyYW1jX25vZGUsDQo+ID4gKwkJCQkgICAibWVkaWF0ZWssZHJhbS10eXBlIiwNCj4gPiAr CQkJCSAgICZkcmFtY19kZXZfcHRyLT5kcmFtX3R5cGUpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ ICsJCXByX2luZm8oIiVzOiBnZXQgZHJhbV90eXBlIGZhaWxcbiIsIF9fZnVuY19fKTsNCj4gPiAr CQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSBvZl9wcm9wZXJ0 eV9yZWFkX3UzMihkcmFtY19ub2RlLA0KPiA+ICsJCQkJICAgIm1lZGlhdGVrLHN1cHBvcnQtY2hh bm5lbC1jbnQiLA0KPiA+ICsJCQkJICAgJmRyYW1jX2Rldl9wdHItPnN1cHBvcnRfY2hhbm5lbF9j bnQpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCXByX2luZm8oIiVzOiBnZXQgc3VwcG9ydF9j aGFubmVsX2NudCBmYWlsXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gb2ZfcHJvcGVydHlfcmVhZF91MzIoZHJhbWNfbm9k ZSwNCj4gPiArCQkJCSAgICJtZWRpYXRlayxjaGFubmVsLWNudCIsDQo+ID4gKwkJCQkgICAmZHJh bWNfZGV2X3B0ci0+Y2hhbm5lbF9jbnQpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCXByX2lu Zm8oIiVzOiBnZXQgY2hhbm5lbF9jbnQgZmFpbFxuIiwgX19mdW5jX18pOw0KPiA+ICsJCXJldHVy biAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldCA9IG9mX3Byb3BlcnR5X3JlYWRf dTMyKGRyYW1jX25vZGUsDQo+ID4gKwkJCQkgICAibWVkaWF0ZWsscmFuay1jbnQiLA0KPiA+ICsJ CQkJICAgJmRyYW1jX2Rldl9wdHItPnJhbmtfY250KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiAr CQlwcl9pbmZvKCIlczogZ2V0IHJhbmtfY250IGZhaWxcbiIsIF9fZnVuY19fKTsNCj4gPiArCQly ZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSBvZl9wcm9wZXJ0eV9y ZWFkX3UzMihkcmFtY19ub2RlLA0KPiA+ICsJCQkJICAgIm1lZGlhdGVrLG1yLWNudCIsDQo+ID4g KwkJCQkgICAmZHJhbWNfZGV2X3B0ci0+bXJfY250KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiAr CQlwcl9pbmZvKCIlczogZ2V0IG1yX2NudCBmYWlsXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKwkJcmV0 dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gb2ZfcHJvcGVydHlfcmVh ZF91MzIoZHJhbWNfbm9kZSwNCj4gPiArCQkJCSAgICJtZWRpYXRlayxmcmVxLWNudCIsDQo+ID4g KwkJCQkgICAmZHJhbWNfZGV2X3B0ci0+ZnJlcV9jbnQpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ ICsJCXByX2luZm8oIiVzOiBnZXQgZnJlcV9jbnQgZmFpbFxuIiwgX19mdW5jX18pOw0KPiA+ICsJ CXJldHVybiAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHItPm1y NF9kZXZfcHRyID0gKHZvaWQgKilkZXZfY29tcC0+bXI0Ow0KPiA+ICsNCj4gPiArCXByX2luZm8o IiVzOiAlcyglZCksJXMoJWQpLCVzKCVkKSwlcyglZCksJXMoJWQpLCVzKCVkKSwlcyglcylcbiIs DQo+ID4gKwkJX19mdW5jX18sDQo+ID4gKwkJImRyYW1fdHlwZSIsIGRyYW1jX2Rldl9wdHItPmRy YW1fdHlwZSwNCj4gPiArCQkic3VwcG9ydF9jaGFubmVsX2NudCIsIGRyYW1jX2Rldl9wdHItPnN1 cHBvcnRfY2hhbm5lbF9jbnQsDQo+ID4gKwkJImNoYW5uZWxfY250IiwgZHJhbWNfZGV2X3B0ci0+ Y2hhbm5lbF9jbnQsDQo+ID4gKwkJInJhbmtfY250IiwgZHJhbWNfZGV2X3B0ci0+cmFua19jbnQs DQo+ID4gKwkJIm1yX2NudCIsIGRyYW1jX2Rldl9wdHItPm1yX2NudCwNCj4gPiArCQkiZnJlcV9j bnQiLCBkcmFtY19kZXZfcHRyLT5mcmVxX2NudCwNCj4gPiArCQkibXI0IiwgKGRyYW1jX2Rldl9w dHItPm1yNF9kZXZfcHRyKSA/ICJ0cnVlIiA6ICJmYWxzZSIpOw0KPiANCj4gV2h5IGRvIHlvdSBu ZWVkIHRoaXM/IEl0J3MgYWxyZWFkeSBpbiBEVCB3aGljaCBpcyByZWFkYWJsZSBmcm9tIA0KPiB1 c2Vyc3BhY2UuDQoNClRvIG1ha2UgdGhlIGRyaXZlciBzdGF0dXMgZWFzeSB0byBzZWUgd2hlbiBw cm9iaW5nIGl0Lg0KDQo+IA0KPiA+ICsNCj4gPiArCXNpemUgPSBzaXplb2YodW5zaWduZWQgaW50 KSAqIGRyYW1jX2Rldl9wdHItPnJhbmtfY250Ow0KPiA+ICsJZHJhbWNfZGV2X3B0ci0+cmFua19z aXplID0gZGV2bV9rbWFsbG9jKCZwZGV2LT5kZXYsIHNpemUsIEdGUF9LRVJORUwpOw0KPiA+ICsJ aWYgKCEoZHJhbWNfZGV2X3B0ci0+cmFua19zaXplKSkNCj4gPiArCQlyZXR1cm4gLUVOT01FTTsN Cj4gPiArCXJldCA9IG9mX3Byb3BlcnR5X3JlYWRfdTMyX2FycmF5KGRyYW1jX25vZGUsDQo+ID4g KwkJCQkJICJtZWRpYXRlayxyYW5rLXNpemUiLA0KPiA+ICsJCQkJCSBkcmFtY19kZXZfcHRyLT5y YW5rX3NpemUsDQo+ID4gKwkJCQkJIGRyYW1jX2Rldl9wdHItPnJhbmtfY250KTsNCj4gPiArCWlm IChyZXQpIHsNCj4gPiArCQlwcl9pbmZvKCIlczogZ2V0IHJhbmtfc2l6ZSBmYWlsXG4iLCBfX2Z1 bmNfXyk7DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJaWYg KGRyYW1jX2Rldl9wdHItPm1yX2NudCkgew0KPiA+ICsJCXNpemUgPSBzaXplb2Yoc3RydWN0IG1y X2luZm9fdCkgKiBkcmFtY19kZXZfcHRyLT5tcl9jbnQ7DQo+ID4gKwkJZHJhbWNfZGV2X3B0ci0+ bXJfaW5mb19wdHIgPSBkZXZtX2ttYWxsb2MoJnBkZXYtPmRldiwNCj4gPiArCQkJCQkJCSAgc2l6 ZSwNCj4gPiArCQkJCQkJCSAgR0ZQX0tFUk5FTCk7DQo+ID4gKwkJaWYgKCEoZHJhbWNfZGV2X3B0 ci0+bXJfaW5mb19wdHIpKQ0KPiA+ICsJCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArCQlyZXQgPQ0K PiA+ICsJCSAgICBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShkcmFtY19ub2RlLA0KPiA+ICsJ CQkJCSAgICAgICAibWVkaWF0ZWssbXIiLA0KPiA+ICsJCQkJCSAgICAgICAodW5zaWduZWQgaW50 ICopZHJhbWNfZGV2X3B0ci0+bXJfaW5mb19wdHIsDQo+ID4gKwkJCQkJICAgICAgIHNpemUgPj4g Mik7DQo+ID4gKwkJaWYgKHJldCkgew0KPiA+ICsJCQlwcl9pbmZvKCIlczogZ2V0IG1yX2luZm8g ZmFpbFxuIiwgX19mdW5jX18pOw0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCQl9DQo+ ID4gKwkJZm9yIChpID0gMDsgaSA8IGRyYW1jX2Rldl9wdHItPm1yX2NudDsgaSsrKQ0KPiA+ICsJ CQlwcl9pbmZvKCIlczogbXIlZCgleClcbiIsIF9fZnVuY19fLA0KPiA+ICsJCQkJZHJhbWNfZGV2 X3B0ci0+bXJfaW5mb19wdHJbaV0ubXJfaW5kZXgsDQo+ID4gKwkJCQlkcmFtY19kZXZfcHRyLT5t cl9pbmZvX3B0cltpXS5tcl92YWx1ZSk7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJaWYgKGRyYW1j X2Rldl9wdHItPmZyZXFfY250KSB7DQo+ID4gKwkJc2l6ZSA9IHNpemVvZih1bnNpZ25lZCBpbnQp ICogZHJhbWNfZGV2X3B0ci0+ZnJlcV9jbnQgKiAyOw0KPiA+ICsJCWRyYW1jX2Rldl9wdHItPmZy ZXFfc3RlcCA9DQo+ID4gKwkJCWRldm1fa21hbGxvYygmcGRldi0+ZGV2LCBzaXplLCBHRlBfS0VS TkVMKTsNCj4gPiArCQlpZiAoIShkcmFtY19kZXZfcHRyLT5mcmVxX3N0ZXApKQ0KPiA+ICsJCQly ZXR1cm4gLUVOT01FTTsNCj4gPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShk cmFtY19ub2RlLA0KPiA+ICsJCQkJCQkgIm1lZGlhdGVrLGZyZXEtc3RlcCIsDQo+ID4gKwkJCQkJ CSBkcmFtY19kZXZfcHRyLT5mcmVxX3N0ZXAsDQo+ID4gKwkJCQkJCSBkcmFtY19kZXZfcHRyLT5m cmVxX2NudCAqIDIpOw0KPiA+ICsJCWlmIChyZXQpIHsNCj4gPiArCQkJcHJfaW5mbygiJXM6IGdl dCBmcmVxX3N0ZXAgZmFpbFxuIiwgX19mdW5jX18pOw0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsN Cj4gPiArCQl9DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJc2l6ZSA9IHNpemVvZihwaHlzX2FkZHJf dCkgKiBkcmFtY19kZXZfcHRyLT5zdXBwb3J0X2NoYW5uZWxfY250Ow0KPiA+ICsJZHJhbWNfZGV2 X3B0ci0+ZHJhbWNfY2huX2Jhc2VfYW8gPSBkZXZtX2ttYWxsb2MoJnBkZXYtPmRldiwNCj4gPiAr CQkJCQkJCXNpemUsIEdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCEoZHJhbWNfZGV2X3B0ci0+ZHJh bWNfY2huX2Jhc2VfYW8pKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsJZHJhbWNfZGV2 X3B0ci0+ZHJhbWNfY2huX2Jhc2VfbmFvID0gZGV2bV9rbWFsbG9jKCZwZGV2LT5kZXYsDQo+ID4g KwkJCQkJCQkgc2l6ZSwgR0ZQX0tFUk5FTCk7DQo+ID4gKwlpZiAoIShkcmFtY19kZXZfcHRyLT5k cmFtY19jaG5fYmFzZV9uYW8pKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsJZHJhbWNf ZGV2X3B0ci0+ZGRycGh5X2Nobl9iYXNlX2FvID0gZGV2bV9rbWFsbG9jKCZwZGV2LT5kZXYsDQo+ ID4gKwkJCQkJCQkgc2l6ZSwgR0ZQX0tFUk5FTCk7DQo+ID4gKwlpZiAoIShkcmFtY19kZXZfcHRy LT5kZHJwaHlfY2huX2Jhc2VfYW8pKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4g PiArCWZvciAoaSA9IDA7IGkgPCBkcmFtY19kZXZfcHRyLT5zdXBwb3J0X2NoYW5uZWxfY250OyBp KyspIHsNCj4gPiArCQlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJD RV9NRU0sIGkpOw0KPiA+ICsJCWRyYW1jX2Rldl9wdHItPmRyYW1jX2Nobl9iYXNlX2FvW2ldID0N Cj4gPiArCQkJZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYsIHJlcyk7DQo+ID4gKwkJ aWYgKElTX0VSUihkcmFtY19kZXZfcHRyLT5kcmFtY19jaG5fYmFzZV9hb1tpXSkpIHsNCj4gPiAr CQkJcHJfaW5mbygiJXM6IHVuYWJsZSB0byBtYXAgY2glZCBEUkFNQyBBTyBiYXNlXG4iLA0KPiA+ ICsJCQkJX19mdW5jX18sIGkpOw0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCQl9DQo+ ID4gKw0KPiA+ICsJCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNF X01FTSwNCj4gPiArCQkJCQkgICAgaSArIGRyYW1jX2Rldl9wdHItPnN1cHBvcnRfY2hhbm5lbF9j bnQpOw0KPiA+ICsJCWRyYW1jX2Rldl9wdHItPmRyYW1jX2Nobl9iYXNlX25hb1tpXSA9DQo+ID4g KwkJCWRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOw0KPiA+ICsJCWlmIChJ U19FUlIoZHJhbWNfZGV2X3B0ci0+ZHJhbWNfY2huX2Jhc2VfbmFvW2ldKSkgew0KPiA+ICsJCQlw cl9pbmZvKCIlczogdW5hYmxlIHRvIG1hcCBjaCVkIERSQU1DIE5BTyBiYXNlXG4iLA0KPiA+ICsJ CQkJX19mdW5jX18sIGkpOw0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCQl9DQo+ID4g Kw0KPiA+ICsJCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01F TSwNCj4gPiArCQkJCQkgICAgaSArIGRyYW1jX2Rldl9wdHItPnN1cHBvcnRfY2hhbm5lbF9jbnQg KiAyKTsNCj4gPiArCQlkcmFtY19kZXZfcHRyLT5kZHJwaHlfY2huX2Jhc2VfYW9baV0gPQ0KPiA+ ICsJCQlkZXZtX2lvcmVtYXBfcmVzb3VyY2UoJnBkZXYtPmRldiwgcmVzKTsNCj4gPiArCQlpZiAo SVNfRVJSKGRyYW1jX2Rldl9wdHItPmRkcnBoeV9jaG5fYmFzZV9hb1tpXSkpIHsNCj4gPiArCQkJ cHJfaW5mbygiJXM6IHVuYWJsZSB0byBtYXAgY2glZCBERFJQSFkgQU8gYmFzZVxuIiwNCj4gPiAr CQkJCV9fZnVuY19fLCBpKTsNCj4gPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwkJfQ0KPiA+ ICsJfQ0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHItPmZtZXRlcl9kZXZfcHRyID0gKHZvaWQg KilkZXZfY29tcC0+Zm1ldGVyOw0KPiA+ICsNCj4gPiArCXJldCA9IGRyaXZlcl9jcmVhdGVfZmls ZShwZGV2LT5kZXYuZHJpdmVyLA0KPiA+ICsJCQkJICZkcml2ZXJfYXR0cl9kcmFtX2RhdGFfcmF0 ZSk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJcHJfaW5mbygiJXM6IGZhaWwgdG8gY3JlYXRl IGRyYW1fZGF0YV9yYXRlIHN5c2ZzXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKwkJcmV0dXJuIHJldDsN Cj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSBkcml2ZXJfY3JlYXRlX2ZpbGUocGRldi0+ZGV2 LmRyaXZlciwNCj4gPiArCQkJCSAmZHJpdmVyX2F0dHJfbXIpOw0KPiA+ICsJaWYgKHJldCkgew0K PiA+ICsJCXByX2luZm8oIiVzOiBmYWlsIHRvIGNyZWF0ZSBtciBzeXNmc1xuIiwgX19mdW5jX18p Ow0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJaWYgKGRyYW1jX2Rl dl9wdHItPm1yNF9kZXZfcHRyKSB7DQo+ID4gKwkJcmV0ID0gZHJpdmVyX2NyZWF0ZV9maWxlKHBk ZXYtPmRldi5kcml2ZXIsDQo+ID4gKwkJCQkJICZkcml2ZXJfYXR0cl9tcjQpOw0KPiA+ICsJCWlm IChyZXQpIHsNCj4gPiArCQkJcHJfaW5mbygiJXM6IGZhaWwgdG8gY3JlYXRlIG1yNCBzeXNmc1xu IiwgX19mdW5jX18pOw0KPiA+ICsJCQlyZXR1cm4gcmV0Ow0KPiA+ICsJCX0NCj4gPiArCX0NCj4g PiArDQo+ID4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBkcmFtY19kZXZfcHRyKTsNCj4g PiArCXByX2luZm8oIiVzOiBEUkFNIGRhdGEgdHlwZSA9ICVkXG4iLCBfX2Z1bmNfXywNCj4gPiAr CQltdGtfZHJhbWNfZ2V0X2Rkcl90eXBlKCkpOw0KPiA+ICsNCj4gPiArCXByX2luZm8oIiVzOiBE UkFNIGRhdGEgY2xvY2sgcmF0ZSA9ICVkXG4iLCBfX2Z1bmNfXywNCj4gPiArCQltdGtfZHJhbWNf Z2V0X2RhdGFfcmF0ZSgpKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4g Kw0KPiA+ICsvKg0KPiA+ICsgKiBtdGtfZHJhbWNfZ2V0X3N0ZXBzX2ZyZXEgLSBnZXQgdGhlIGRh dGEgY2xvY2sgcmF0ZSBvZiB0YXJnZXQgRFZGUyBzdGVwDQo+ID4gKyAqIEBzdGVwOiB0aGUgc3Rl cCBpbmRleCBvZiBEVkZTDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybiB0aGUgRFJBTSBzcGVjIGRh dGEgY2xvY2sgcmF0ZSAoTUh6KQ0KPiA+ICsgKi8NCj4gPiAraW50IG10a19kcmFtY19nZXRfc3Rl cHNfZnJlcSh1bnNpZ25lZCBpbnQgc3RlcCkNCj4gPiArew0KPiA+ICsJc3RydWN0IGRyYW1jX2Rl dl90ICpkcmFtY19kZXZfcHRyOw0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHIgPSBtdGtfZHJh bWNfZ2V0X2RydmRhdGFfYnlfaWRzKCk7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19kZXZfcHRy KQ0KPiA+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+ICsNCj4gPiArCWlmIChzdGVwIDwgZHJhbWNf ZGV2X3B0ci0+ZnJlcV9jbnQpDQo+ID4gKwkJcmV0dXJuIGRyYW1jX2Rldl9wdHItPmZyZXFfc3Rl cFtzdGVwICogMiArIDFdOw0KPiA+ICsNCj4gPiArCXJldHVybiAtRUlOVkFMOw0KPiA+ICt9DQo+ ID4gK0VYUE9SVF9TWU1CT0wobXRrX2RyYW1jX2dldF9zdGVwc19mcmVxKTsNCj4gPiArDQo+ID4g Ky8qDQo+ID4gKyAqIGRlY29kZV9mcmVxIC0gZGVjb2RlIHRoZSBzcGVjIGRhdGEgY2xvY2sgcmF0 ZQ0KPiA+ICsgKiBAdmNvX2ZyZXE6IHJlYWwgZGF0YSBjbG9jayByYXRlDQo+ID4gKyAqDQo+ID4g KyAqIFJldHVybiB0aGUgRFJBTSBzcGVjIGRhdGEgY2xvY2sgcmF0ZSAoTUh6KQ0KPiA+ICsgKi8N Cj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBkZWNvZGVfZnJlcSh1bnNpZ25lZCBpbnQgdmNvX2Zy ZXEpDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+ICsJc3RydWN0IGRyYW1jX2Rldl90ICpkcmFt Y19kZXZfcHRyOw0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHIgPSBtdGtfZHJhbWNfZ2V0X2Ry dmRhdGFfYnlfaWRzKCk7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19kZXZfcHRyKQ0KPiA+ICsJ CXJldHVybiAwOw0KPiA+ICsNCj4gPiArCWZvciAoaSA9IDA7IGkgPCBkcmFtY19kZXZfcHRyLT5m cmVxX2NudCAqIDI7IGkgKz0gMikNCj4gPiArCQlpZiAodmNvX2ZyZXEgPT0gZHJhbWNfZGV2X3B0 ci0+ZnJlcV9zdGVwW2ldKQ0KPiA+ICsJCQlyZXR1cm4gZHJhbWNfZGV2X3B0ci0+ZnJlcV9zdGVw W2kgKyAxXTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gdmNvX2ZyZXE7DQo+ID4gK30NCj4gPiArDQo+ ID4gK3N0YXRpYyB1bnNpZ25lZCBpbnQgZm1ldGVyX3YwKHN0cnVjdCBkcmFtY19kZXZfdCAqZHJh bWNfZGV2X3B0cikNCj4gPiArew0KPiA+ICsJc3RydWN0IGZtZXRlcl9kZXZfdCAqZm1ldGVyX2Rl dl9wdHIgPQ0KPiA+ICsJCShzdHJ1Y3QgZm1ldGVyX2Rldl90ICopZHJhbWNfZGV2X3B0ci0+Zm1l dGVyX2Rldl9wdHI7DQo+ID4gKwl1bnNpZ25lZCBpbnQgc2h1X2x2X3ZhbDsNCj4gPiArCXVuc2ln bmVkIGludCBwbGxfaWRfdmFsOw0KPiA+ICsJdW5zaWduZWQgaW50IHBsbF9tZF92YWw7DQo+ID4g Kwl1bnNpZ25lZCBpbnQgc2RtcGN3X3ZhbDsNCj4gPiArCXVuc2lnbmVkIGludCBwcmVkaXZfdmFs Ow0KPiA+ICsJdW5zaWduZWQgaW50IHBvc2Rpdl92YWw7DQo+ID4gKwl1bnNpZ25lZCBpbnQgY2tk aXY0X3ZhbDsNCj4gPiArCXVuc2lnbmVkIGludCBjbGRpdjJfdmFsOw0KPiA+ICsJdW5zaWduZWQg aW50IG9mZnNldDsNCj4gPiArCXVuc2lnbmVkIGludCB2Y29fZnJlcTsNCj4gPiArDQo+ID4gKwlz aHVfbHZfdmFsID0gKHJlYWRsKGRyYW1jX2Rldl9wdHItPmRyYW1jX2Nobl9iYXNlX2FvWzBdICsN Cj4gPiArCQlmbWV0ZXJfZGV2X3B0ci0+c2h1X2x2Lm9mZnNldCkgJg0KPiA+ICsJCWZtZXRlcl9k ZXZfcHRyLT5zaHVfbHYubWFzaykgPj4NCj4gPiArCQlmbWV0ZXJfZGV2X3B0ci0+c2h1X2x2LnNo aWZ0Ow0KPiA+ICsNCj4gPiArCXBsbF9pZF92YWwgPSAocmVhZGwoZHJhbWNfZGV2X3B0ci0+ZGRy cGh5X2Nobl9iYXNlX2FvWzBdICsNCj4gPiArCQlmbWV0ZXJfZGV2X3B0ci0+cGxsX2lkLm9mZnNl dCkgJg0KPiA+ICsJCWZtZXRlcl9kZXZfcHRyLT5wbGxfaWQubWFzaykgPj4NCj4gPiArCQlmbWV0 ZXJfZGV2X3B0ci0+cGxsX2lkLnNoaWZ0Ow0KPiA+ICsNCj4gPiArCW9mZnNldCA9IGZtZXRlcl9k ZXZfcHRyLT5wbGxfbWRbcGxsX2lkX3ZhbF0ub2Zmc2V0ICsNCj4gPiArCQlmbWV0ZXJfZGV2X3B0 ci0+c2h1X29mICogc2h1X2x2X3ZhbDsNCj4gPiArCXBsbF9tZF92YWwgPSAocmVhZGwoZHJhbWNf ZGV2X3B0ci0+ZGRycGh5X2Nobl9iYXNlX2FvWzBdICsgb2Zmc2V0KSAmDQo+ID4gKwkJZm1ldGVy X2Rldl9wdHItPnBsbF9tZFtwbGxfaWRfdmFsXS5tYXNrKSA+Pg0KPiA+ICsJCWZtZXRlcl9kZXZf cHRyLT5wbGxfbWRbcGxsX2lkX3ZhbF0uc2hpZnQ7DQo+ID4gKw0KPiA+ICsJb2Zmc2V0ID0gZm1l dGVyX2Rldl9wdHItPnNkbXBjd1twbGxfaWRfdmFsXS5vZmZzZXQgKw0KPiA+ICsJCWZtZXRlcl9k ZXZfcHRyLT5zaHVfb2YgKiBzaHVfbHZfdmFsOw0KPiA+ICsJc2RtcGN3X3ZhbCA9IChyZWFkbChk cmFtY19kZXZfcHRyLT5kZHJwaHlfY2huX2Jhc2VfYW9bMF0gKyBvZmZzZXQpICYNCj4gPiArCQlm bWV0ZXJfZGV2X3B0ci0+c2RtcGN3W3BsbF9pZF92YWxdLm1hc2spID4+DQo+ID4gKwkJZm1ldGVy X2Rldl9wdHItPnNkbXBjd1twbGxfaWRfdmFsXS5zaGlmdDsNCj4gPiArDQo+ID4gKwlvZmZzZXQg PSBmbWV0ZXJfZGV2X3B0ci0+cHJlZGl2W3BsbF9pZF92YWxdLm9mZnNldCArDQo+ID4gKwkJZm1l dGVyX2Rldl9wdHItPnNodV9vZiAqIHNodV9sdl92YWw7DQo+ID4gKwlwcmVkaXZfdmFsID0gKHJl YWRsKGRyYW1jX2Rldl9wdHItPmRkcnBoeV9jaG5fYmFzZV9hb1swXSArIG9mZnNldCkgJg0KPiA+ ICsJCWZtZXRlcl9kZXZfcHRyLT5wcmVkaXZbcGxsX2lkX3ZhbF0ubWFzaykgPj4NCj4gPiArCQlm bWV0ZXJfZGV2X3B0ci0+cHJlZGl2W3BsbF9pZF92YWxdLnNoaWZ0Ow0KPiA+ICsNCj4gPiArCW9m ZnNldCA9IGZtZXRlcl9kZXZfcHRyLT5wb3NkaXZbcGxsX2lkX3ZhbF0ub2Zmc2V0ICsNCj4gPiAr CQlmbWV0ZXJfZGV2X3B0ci0+c2h1X29mICogc2h1X2x2X3ZhbDsNCj4gPiArCXBvc2Rpdl92YWwg PSAocmVhZGwoZHJhbWNfZGV2X3B0ci0+ZGRycGh5X2Nobl9iYXNlX2FvWzBdICsgb2Zmc2V0KSAm DQo+ID4gKwkJZm1ldGVyX2Rldl9wdHItPnBvc2RpdltwbGxfaWRfdmFsXS5tYXNrKSA+Pg0KPiA+ ICsJCWZtZXRlcl9kZXZfcHRyLT5wb3NkaXZbcGxsX2lkX3ZhbF0uc2hpZnQ7DQo+ID4gKw0KPiA+ ICsJb2Zmc2V0ID0gZm1ldGVyX2Rldl9wdHItPmNrZGl2NFtwbGxfaWRfdmFsXS5vZmZzZXQgKw0K PiA+ICsJCWZtZXRlcl9kZXZfcHRyLT5zaHVfb2YgKiBzaHVfbHZfdmFsOw0KPiA+ICsJY2tkaXY0 X3ZhbCA9IChyZWFkbChkcmFtY19kZXZfcHRyLT5kZHJwaHlfY2huX2Jhc2VfYW9bMF0gKyBvZmZz ZXQpICYNCj4gPiArCQlmbWV0ZXJfZGV2X3B0ci0+Y2tkaXY0W3BsbF9pZF92YWxdLm1hc2spID4+ DQo+ID4gKwkJZm1ldGVyX2Rldl9wdHItPmNrZGl2NFtwbGxfaWRfdmFsXS5zaGlmdDsNCj4gPiAr DQo+ID4gKwlvZmZzZXQgPSBmbWV0ZXJfZGV2X3B0ci0+Y2xkaXYyW3BsbF9pZF92YWxdLm9mZnNl dCArDQo+ID4gKwkJZm1ldGVyX2Rldl9wdHItPnNodV9vZiAqIHNodV9sdl92YWw7DQo+ID4gKwlj bGRpdjJfdmFsID0gKHJlYWRsKGRyYW1jX2Rldl9wdHItPmRkcnBoeV9jaG5fYmFzZV9hb1swXSAr IG9mZnNldCkgJg0KPiA+ICsJCWZtZXRlcl9kZXZfcHRyLT5jbGRpdjJbcGxsX2lkX3ZhbF0ubWFz aykgPj4NCj4gPiArCQlmbWV0ZXJfZGV2X3B0ci0+Y2xkaXYyW3BsbF9pZF92YWxdLnNoaWZ0Ow0K PiA+ICsNCj4gPiArCXZjb19mcmVxID0gKChmbWV0ZXJfZGV2X3B0ci0+Y3J5c3RhbF9mcmVxID4+ IHByZWRpdl92YWwpICoNCj4gPiArCQkoc2RtcGN3X3ZhbCA+PiA4KSkgPj4NCj4gPiArCQlwb3Nk aXZfdmFsID4+IGNrZGl2NF92YWwgPj4gcGxsX21kX3ZhbCA+PiBjbGRpdjJfdmFsOw0KPiA+ICsN Cj4gPiArCXJldHVybiBkZWNvZGVfZnJlcSh2Y29fZnJlcSk7DQo+ID4gK30NCj4gPiArDQo+ID4g Ky8qDQo+ID4gKyAqIG10a19kcmFtY19nZXRfZGF0YV9yYXRlIC0gY2FsY3VsYXRlIERSQU0gZGF0 YSByYXRlDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybiBEUkFNIGRhdGEgcmF0ZSAoTUIvcykNCj4g PiArICovDQo+ID4gK3Vuc2lnbmVkIGludCBtdGtfZHJhbWNfZ2V0X2RhdGFfcmF0ZSh2b2lkKQ0K PiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZHJhbWNfZGV2X3QgKmRyYW1jX2Rldl9wdHI7DQo+ID4gKwlz dHJ1Y3QgZm1ldGVyX2Rldl90ICpmbWV0ZXJfZGV2X3B0cjsNCj4gPiArDQo+ID4gKwlkcmFtY19k ZXZfcHRyID0gbXRrX2RyYW1jX2dldF9kcnZkYXRhX2J5X2lkcygpOw0KPiA+ICsNCj4gPiArCWlm ICghZHJhbWNfZGV2X3B0cikNCj4gPiArCQlyZXR1cm4gMDsNCj4gPiArDQo+ID4gKwlmbWV0ZXJf ZGV2X3B0ciA9IChzdHJ1Y3QgZm1ldGVyX2Rldl90ICopZHJhbWNfZGV2X3B0ci0+Zm1ldGVyX2Rl dl9wdHI7DQo+ID4gKwlpZiAoIWZtZXRlcl9kZXZfcHRyKQ0KPiA+ICsJCXJldHVybiAwOw0KPiA+ ICsNCj4gPiArCXJldHVybiBmbWV0ZXJfdjAoZHJhbWNfZGV2X3B0cik7DQo+ID4gK30NCj4gPiAr RVhQT1JUX1NZTUJPTChtdGtfZHJhbWNfZ2V0X2RhdGFfcmF0ZSk7DQo+ID4gKw0KPiA+ICtzdGF0 aWMgdW5zaWduZWQgaW50IG1yNF92MShzdHJ1Y3QgZHJhbWNfZGV2X3QgKmRyYW1jX2Rldl9wdHIs IHVuc2lnbmVkIGludCBjaCkNCj4gPiArew0KPiA+ICsJc3RydWN0IG1yNF9kZXZfdCAqbXI0X2Rl dl9wdHIgPQ0KPiA+ICsJCShzdHJ1Y3QgbXI0X2Rldl90ICopZHJhbWNfZGV2X3B0ci0+bXI0X2Rl dl9wdHI7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIChyZWFkbChkcmFtY19kZXZfcHRyLT5kcmFtY19j aG5fYmFzZV9uYW9bY2hdICsNCj4gPiArCQltcjRfZGV2X3B0ci0+bXI0X3JnLm9mZnNldCkgJiBt cjRfZGV2X3B0ci0+bXI0X3JnLm1hc2spID4+DQo+ID4gKwkJbXI0X2Rldl9wdHItPm1yNF9yZy5z aGlmdDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogbXRrX2RyYW1jX2dldF9tcjQg LSBnZXQgdGhlIERSQU0gTVI0IHZhbHVlIG9mIHNwZWNpZmljIERSQU0gY2hhbm5lbA0KPiA+ICsg KiBAY2g6CXRoZSBjaGFubmVsIGluZGV4DQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybiB0aGUgTVI0 IHZhbHVlDQo+ID4gKyAqLw0KPiA+ICt1bnNpZ25lZCBpbnQgbXRrX2RyYW1jX2dldF9tcjQodW5z aWduZWQgaW50IGNoKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZHJhbWNfZGV2X3QgKmRyYW1jX2Rl dl9wdHI7DQo+ID4gKwlzdHJ1Y3QgbXI0X2Rldl90ICptcjRfZGV2X3B0cjsNCj4gPiArDQo+ID4g KwlkcmFtY19kZXZfcHRyID0gbXRrX2RyYW1jX2dldF9kcnZkYXRhX2J5X2lkcygpOw0KPiA+ICsN Cj4gPiArCWlmICghZHJhbWNfZGV2X3B0cikNCj4gPiArCQlyZXR1cm4gMDsNCj4gPiArDQo+ID4g KwltcjRfZGV2X3B0ciA9IChzdHJ1Y3QgbXI0X2Rldl90ICopZHJhbWNfZGV2X3B0ci0+bXI0X2Rl dl9wdHI7DQo+ID4gKwlpZiAoIW1yNF9kZXZfcHRyKQ0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsN Cj4gPiArCWlmIChjaCA+PSBkcmFtY19kZXZfcHRyLT5jaGFubmVsX2NudCkNCj4gPiArCQlyZXR1 cm4gMDsNCj4gPiArDQo+ID4gKwlyZXR1cm4gbXI0X3YxKGRyYW1jX2Rldl9wdHIsIGNoKTsNCj4g PiArfQ0KPiA+ICtFWFBPUlRfU1lNQk9MKG10a19kcmFtY19nZXRfbXI0KTsNCj4gPiArDQo+ID4g Ky8qDQo+ID4gKyAqIG10a19kcmFtY19nZXRfZGRyX3R5cGUgLSBnZXQgRFJBTSB0eXBlDQo+ID4g KyAqDQo+ID4gKyAqIFJldHVybiB0aGUgRFJBTSB0eXBlDQo+ID4gKyAqLw0KPiA+ICt1bnNpZ25l ZCBpbnQgbXRrX2RyYW1jX2dldF9kZHJfdHlwZSh2b2lkKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3Qg ZHJhbWNfZGV2X3QgKmRyYW1jX2Rldl9wdHI7DQo+ID4gKw0KPiA+ICsJZHJhbWNfZGV2X3B0ciA9 IG10a19kcmFtY19nZXRfZHJ2ZGF0YV9ieV9pZHMoKTsNCj4gPiArDQo+ID4gKwlpZiAoIWRyYW1j X2Rldl9wdHIpDQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGRyYW1jX2Rl dl9wdHItPmRyYW1fdHlwZTsNCj4gPiArfQ0KPiA+ICtFWFBPUlRfU1lNQk9MKG10a19kcmFtY19n ZXRfZGRyX3R5cGUpOw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogbXRrX2RyYW1jX2dldF9jaGFu bmVsX2NvdW50IC0gZ2V0IERSQU0gY2hhbm5lbCBjb3VudA0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1 cm4gdGhlIERSQU0gY2hhbm5lbCBjb3VudA0KPiA+ICsgKi8NCj4gPiArdW5zaWduZWQgaW50IG10 a19kcmFtY19nZXRfY2hhbm5lbF9jb3VudCh2b2lkKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZHJh bWNfZGV2X3QgKmRyYW1jX2Rldl9wdHI7DQo+ID4gKw0KPiA+ICsJZHJhbWNfZGV2X3B0ciA9IG10 a19kcmFtY19nZXRfZHJ2ZGF0YV9ieV9pZHMoKTsNCj4gPiArDQo+ID4gKwlpZiAoIWRyYW1jX2Rl dl9wdHIpDQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGRyYW1jX2Rldl9w dHItPmNoYW5uZWxfY250Ow0KPiA+ICt9DQo+ID4gK0VYUE9SVF9TWU1CT0wobXRrX2RyYW1jX2dl dF9jaGFubmVsX2NvdW50KTsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIG10a19kcmFtY19nZXRf cmFua19jb3VudCAtIGdldCBEUkFNIHJhbmsgY291bnQNCj4gPiArICoNCj4gPiArICogUmV0dXJu IHRoZSBEUkFNIHJhbmsgY291bnQNCj4gPiArICovDQo+ID4gK3Vuc2lnbmVkIGludCBtdGtfZHJh bWNfZ2V0X3JhbmtfY291bnQodm9pZCkNCj4gPiArew0KPiA+ICsJc3RydWN0IGRyYW1jX2Rldl90 ICpkcmFtY19kZXZfcHRyOw0KPiA+ICsNCj4gPiArCWRyYW1jX2Rldl9wdHIgPSBtdGtfZHJhbWNf Z2V0X2RydmRhdGFfYnlfaWRzKCk7DQo+ID4gKw0KPiA+ICsJaWYgKCFkcmFtY19kZXZfcHRyKQ0K PiA+ICsJCXJldHVybiAwOw0KPiA+ICsNCj4gPiArCXJldHVybiBkcmFtY19kZXZfcHRyLT5yYW5r X2NudDsNCj4gPiArfQ0KPiA+ICtFWFBPUlRfU1lNQk9MKG10a19kcmFtY19nZXRfcmFua19jb3Vu dCk7DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBtdGtfZHJhbWNfZ2V0X3Jhbmtfc2l6ZSAtIGdl dCBzaXplIG9mIERSQU0gcmFuaw0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1cm4gdGhlIHNpemUgb2Yg c3BlY2lmaWMgRFJBTSByYW5rDQo+ID4gKyAqLw0KPiA+ICt1bnNpZ25lZCBpbnQgbXRrX2RyYW1j X2dldF9yYW5rX3NpemUodW5zaWduZWQgaW50IHJhbmspDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBk cmFtY19kZXZfdCAqZHJhbWNfZGV2X3B0cjsNCj4gPiArDQo+ID4gKwlkcmFtY19kZXZfcHRyID0g bXRrX2RyYW1jX2dldF9kcnZkYXRhX2J5X2lkcygpOw0KPiA+ICsNCj4gPiArCWlmICghZHJhbWNf ZGV2X3B0cikNCj4gPiArCQlyZXR1cm4gMDsNCj4gPiArDQo+ID4gKwlpZiAocmFuayA8IGRyYW1j X2Rldl9wdHItPnJhbmtfY250KQ0KPiA+ICsJCXJldHVybiBkcmFtY19kZXZfcHRyLT5yYW5rX3Np emVbcmFua107DQo+ID4gKwllbHNlDQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArRVhQ T1JUX1NZTUJPTChtdGtfZHJhbWNfZ2V0X3Jhbmtfc2l6ZSk7DQo+ID4gKw0KPiA+ICtzdGF0aWMg aW50IGRyYW1jX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiA+ICt7DQo+ ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9y bV9kcml2ZXIgZHJhbWNfZHJ2ID0gew0KPiA+ICsJLnByb2JlID0gZHJhbWNfcHJvYmUsDQo+ID4g KwkucmVtb3ZlID0gZHJhbWNfcmVtb3ZlLA0KPiA+ICsJLmRyaXZlciA9IHsNCj4gPiArCQkubmFt ZSA9IERSQU1DX0RSVl9OQU1FLA0KPiA+ICsJCS5vd25lciA9IFRISVNfTU9EVUxFLA0KPiA+ICsJ CS5vZl9tYXRjaF90YWJsZSA9IG10a19kcmFtY19vZl9pZHMsDQo+ID4gKwl9LA0KPiA+ICt9Ow0K PiA+ICsNCj4gPiArc3RhdGljIGludCBfX2luaXQgZHJhbWNfZHJ2X2luaXQodm9pZCkNCj4gPiAr ew0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlyZXQgPSBwbGF0Zm9ybV9kcml2ZXJfcmVn aXN0ZXIoJmRyYW1jX2Rydik7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJcHJfaW5mbygiJXM6 IGluaXQgZmFpbCwgcmV0IDB4JXhcbiIsIF9fZnVuY19fLCByZXQpOw0KPiA+ICsJCXJldHVybiBy ZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIHZvaWQgX19leGl0IGRyYW1jX2Rydl9leGl0KHZvaWQpDQo+ID4gK3sNCj4gPiAr CXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZkcmFtY19kcnYpOw0KPiA+ICt9DQo+ID4gKw0K PiA+ICttb2R1bGVfaW5pdChkcmFtY19kcnZfaW5pdCk7DQo+ID4gK21vZHVsZV9leGl0KGRyYW1j X2Rydl9leGl0KTsNCj4gPiArDQo+ID4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCj4gPiAr TU9EVUxFX0RFU0NSSVBUSU9OKCJNZWRpYVRlayBEUkFNQyBEcml2ZXIiKTsNCj4gPiArTU9EVUxF X0FVVEhPUigiUG8tS2FpIENoaSA8cGsuY2hpQG1lZGlhdGVrLmNvbT4iKTsNCj4gPiBkaWZmIC0t Z2l0IGEvaW5jbHVkZS9tZW1vcnkvbWVkaWF0ZWsvZHJhbWMuaCBiL2luY2x1ZGUvbWVtb3J5L21l ZGlhdGVrL2RyYW1jLmgNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAw MDAuLmM4ZDIwMGYNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvaW5jbHVkZS9tZW1vcnkv bWVkaWF0ZWsvZHJhbWMuaA0KPiA+IEBAIC0wLDAgKzEsMTggQEANCj4gPiArLyogU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8NCj4gPiArLyoNCj4gPiArICogQ29weXJpZ2h0IChj KSAyMDIxIE1lZGlhVGVrIEluYy4NCj4gPiArICovDQo+ID4gKw0KPiA+ICsjaWZuZGVmIF9fRFJB TUNfSF9fDQo+ID4gKyNkZWZpbmUgX19EUkFNQ19IX18NCj4gPiArDQo+ID4gK2ludCBtdGtfZHJh bWNfZ2V0X3N0ZXBzX2ZyZXEodW5zaWduZWQgaW50IHN0ZXApOw0KPiA+ICt1bnNpZ25lZCBpbnQg bXRrX2RyYW1jX2dldF9kZHJfdHlwZSh2b2lkKTsNCj4gPiArdW5zaWduZWQgaW50IG10a19kcmFt Y19nZXRfZGF0YV9yYXRlKHZvaWQpOw0KPiA+ICt1bnNpZ25lZCBpbnQgbXRrX2RyYW1jX2dldF9t cjQodW5zaWduZWQgaW50IGNoKTsNCj4gPiArdW5zaWduZWQgaW50IG10a19kcmFtY19nZXRfY2hh bm5lbF9jb3VudCh2b2lkKTsNCj4gPiArdW5zaWduZWQgaW50IG10a19kcmFtY19nZXRfcmFua19j b3VudCh2b2lkKTsNCj4gPiArdW5zaWduZWQgaW50IG10a19kcmFtY19nZXRfcmFua19zaXplKHVu c2lnbmVkIGludCByayk7DQo+ID4gKw0KPiA+ICsjZW5kaWYgLyogX19EUkFNQ19IX18gKi8NCj4g PiArDQo+ID4gLS0gDQo+ID4gMS43LjkuNQ0KPiA+IA0KDQo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C235C433ED for ; Tue, 27 Apr 2021 05:24:03 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3274161154 for ; Tue, 27 Apr 2021 05:24:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3274161154 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Date:CC:To:From: Subject:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1Dgb3eujGf3qQ08Ze6BnroCHjvUMxUtZgHkQzQ2pW5s=; b=DhkbN3mN85qdhMLntm7DFJJHb Chz/GQBwRikqnzx/x7N5jK3LK7xkad9BZKa4OeqEvWVtnAAur2J4f0cDNI9BNg+ih6xuK3rwRDpAV HCC5uWZtf9MQgzdZE7v4XdU2poCCJOqodXs5iOfE5nkpAXgoVGO10I+h3rzBU1eF3evHC2mLKPpO4 xgds0VRVeCaZp5ajY9XqxG2M5lEp6kxx3SM09k1EmYmORWwPq/IGC1iT7xVsklq7coXF212VTcYZz CGjDNpwyUeL9UOp1oTLkBsNAvhn4YFsmwOJeokXmCq3kk3nj/Ki4PT4edfkmvpPdcZijAk2tGBj55 Jj4YRCg/w==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lbGCG-000kZ7-Hf; Tue, 27 Apr 2021 05:23:44 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lbGC8-000kY0-HG for linux-mediatek@desiato.infradead.org; Tue, 27 Apr 2021 05:23:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject: Message-ID:Sender:Reply-To:Content-ID:Content-Description; bh=uzsSyPxHHxrhb1lFeAcu+VgrjfksbWmOKTmPF5fBR68=; b=rH/488vGPOvBj4AHo4pQDjup/t 5IpjKxaQcaOsc7F02U+9nlq2pdmjbyhLKJHBZvehJFndduNoH+hnEX1+iWuiaXfbBR/u4NwmOil7l jC35P3OURDGo+S53QUfmFu5Pg9BjtatG6M7gThmTLrElOI+ma+htqBooV0mEbdtqKrFmKqFYOtum7 3bzuo+9kjPpGmqtEkUPidLff77r7FGItlluMM4rYLXZJETmFlqlZytOqOc3ZUUr3k4+vKMlvACgfA eL36VEF7XdSMkDqLBQG0zkJpb26L9Y0+DEIeMmg0GByAdhKlGbuLU4n4DMJqyIX9PmqY3Gdm5wAqR SRPzkJ1Q==; Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lbGC3-00GRyH-EA for linux-mediatek@lists.infradead.org; Tue, 27 Apr 2021 05:23:34 +0000 X-UUID: ce511cf11d9149bf96eeee3e6bf00ef7-20210426 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=uzsSyPxHHxrhb1lFeAcu+VgrjfksbWmOKTmPF5fBR68=; b=RgR7ukyRPY3k0BaaZAPWMFU24I3BXATonD2LLxU8dXghTuuZjKhh4D0lwNCxreuxzNyM7JXXq1YOw6nIqomCdZyls6eSuRydZpGHsMim6E9ChHeZjm9144sn7NjYld97akwKgfPB2soCzPOrxVgprxi6ejJSRhciHwb+riQI7Gc=; X-UUID: ce511cf11d9149bf96eeee3e6bf00ef7-20210426 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 620416161; Mon, 26 Apr 2021 22:23:24 -0700 Received: from MTKMBS01N1.mediatek.inc (172.21.101.68) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 26 Apr 2021 22:13:22 -0700 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 27 Apr 2021 13:13:21 +0800 Received: from [172.21.77.33] (172.21.77.33) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 27 Apr 2021 13:13:21 +0800 Message-ID: <1619500401.27332.40.camel@mtkswgap22> Subject: Re: [PATCH v2 2/4] memory: mediatek: add DRAM controller driver From: Po-Kai Chi To: Rob Herring CC: Matthias Brugger , , , , , CC Hwang Date: Tue, 27 Apr 2021 13:13:21 +0800 In-Reply-To: <20210420182827.GA3439758@robh.at.kernel.org> References: <1618565538-6972-1-git-send-email-pk.chi@mediatek.com> <1618565538-6972-3-git-send-email-pk.chi@mediatek.com> <20210420182827.GA3439758@robh.at.kernel.org> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210426_222331_535397_C3202B90 X-CRM114-Status: GOOD ( 34.88 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Hello Rob, Thanks for your comments. Po-Kai Chi On Tue, 2021-04-20 at 13:28 -0500, Rob Herring wrote: > On Fri, Apr 16, 2021 at 05:32:16PM +0800, Po-Kai Chi wrote: > > MediaTek DRAM controller (DRAMC) driver provides cross-platform features > > as below: > > > > 1. provide APIs for low power feature queries > > 2. create sysfs to pass the DRAM information to user-space > > I'm hesistant with having both DT and sysfs vendor specific memory > properties. I think we need something common here. > Sysfs provides users with a unified interface for querying DRAM status at runtime. - DRIVER_ATTR_RO(mr) The content is the same as DT passed from bootloader, but provides better file path consistency. - DRIVER_ATTR_RO(mr4) Used to query the current DRAM chip refresh rate (by reading mode register-4 at run time). The naming can be misleading, I'll rename it for the next version. - DRIVER_ATTR_RO(dram_data_rate) Used to calculate the current DRAM data rate. > > > > Signed-off-by: Po-Kai Chi > > --- > > drivers/memory/Kconfig | 1 + > > drivers/memory/Makefile | 1 + > > drivers/memory/mediatek/Kconfig | 9 + > > drivers/memory/mediatek/Makefile | 3 + > > drivers/memory/mediatek/mtk-dramc.c | 711 +++++++++++++++++++++++++++++++++++ > > include/memory/mediatek/dramc.h | 18 + > > 6 files changed, 743 insertions(+) > > create mode 100644 drivers/memory/mediatek/Kconfig > > create mode 100644 drivers/memory/mediatek/Makefile > > create mode 100644 drivers/memory/mediatek/mtk-dramc.c > > create mode 100644 include/memory/mediatek/dramc.h > > > > diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig > > index 72c0df1..056e906 100644 > > --- a/drivers/memory/Kconfig > > +++ b/drivers/memory/Kconfig > > @@ -225,6 +225,7 @@ config STM32_FMC2_EBI > > devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on > > SOCs containing the FMC2 External Bus Interface. > > > > +source "drivers/memory/mediatek/Kconfig" > > source "drivers/memory/samsung/Kconfig" > > source "drivers/memory/tegra/Kconfig" > > > > diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile > > index bc7663e..cd4f8cf 100644 > > --- a/drivers/memory/Makefile > > +++ b/drivers/memory/Makefile > > @@ -25,6 +25,7 @@ obj-$(CONFIG_PL353_SMC) += pl353-smc.o > > obj-$(CONFIG_RENESAS_RPCIF) += renesas-rpc-if.o > > obj-$(CONFIG_STM32_FMC2_EBI) += stm32-fmc2-ebi.o > > > > +obj-$(CONFIG_MTK_DRAMC) += mediatek/ > > obj-$(CONFIG_SAMSUNG_MC) += samsung/ > > obj-$(CONFIG_TEGRA_MC) += tegra/ > > obj-$(CONFIG_TI_EMIF_SRAM) += ti-emif-sram.o > > diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kconfig > > new file mode 100644 > > index 0000000..a1618b0 > > --- /dev/null > > +++ b/drivers/memory/mediatek/Kconfig > > @@ -0,0 +1,9 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +config MTK_DRAMC > > + tristate "MediaTek DRAMC driver" > > + help > > + This selects the MediaTek(R) DRAMC driver. > > + Provide the API for DRAMC low power scenario, and the interface > > + for reporting DRAM information, e.g. DRAM mode register (MR) for > > + DRAM vendor ID, temperature, and density. > > diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Makefile > > new file mode 100644 > > index 0000000..632be48 > > --- /dev/null > > +++ b/drivers/memory/mediatek/Makefile > > @@ -0,0 +1,3 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +obj-$(CONFIG_MTK_DRAMC) += mtk-dramc.o > > diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/mtk-dramc.c > > new file mode 100644 > > index 0000000..155b3b7 > > --- /dev/null > > +++ b/drivers/memory/mediatek/mtk-dramc.c > > @@ -0,0 +1,711 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (c) 2021 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define DRAMC_DRV_NAME "mtk-dramc" > > + > > +struct mr_info_t { > > + unsigned int mr_index; > > + unsigned int mr_value; > > +}; > > + > > +/* > > + * struct reg_ctrl_t - to describe the bits required in a register > > + * @offset: register address offset from a base > > + * @mask: bitmask of the target bits > > + * @shift: starting bit of the target bits > > + */ > > +struct reg_ctrl_t { > > + unsigned int offset; > > + unsigned int mask; > > + unsigned int shift; > > +}; > > + > > +struct fmeter_dev_t { > > + unsigned int crystal_freq; > > + unsigned int shu_of; > > + struct reg_ctrl_t shu_lv; > > + struct reg_ctrl_t pll_id; > > + struct reg_ctrl_t pll_md[2]; > > + struct reg_ctrl_t sdmpcw[2]; > > + struct reg_ctrl_t prediv[2]; > > + struct reg_ctrl_t posdiv[2]; > > + struct reg_ctrl_t ckdiv4[2]; > > + struct reg_ctrl_t cldiv2[2]; > > + struct reg_ctrl_t fbksel[2]; > > + struct reg_ctrl_t dqopen[2]; > > +}; > > + > > +struct mr4_dev_t { > > + struct reg_ctrl_t mr4_rg; > > +}; > > + > > +struct dramc_dev_t { > > + unsigned int dram_type; > > + unsigned int support_channel_cnt; > > + unsigned int channel_cnt; > > + unsigned int rank_cnt; > > + unsigned int mr_cnt; > > + unsigned int freq_cnt; > > + unsigned int *rank_size; > > + unsigned int *freq_step; > > + struct mr_info_t *mr_info_ptr; > > + void __iomem **dramc_chn_base_ao; > > + void __iomem **dramc_chn_base_nao; > > + void __iomem **ddrphy_chn_base_ao; > > + void *mr4_dev_ptr; > > + void *fmeter_dev_ptr; > > +}; > > + > > +enum DRAM_TYPE { > > + TYPE_NONE = 0, > > + TYPE_DDR1, > > + TYPE_LPDDR2, > > + TYPE_LPDDR3, > > + TYPE_PCDDR3, > > + TYPE_LPDDR4, > > + TYPE_LPDDR4X, > > + TYPE_LPDDR4P > > +}; > > This doesn't appear to be used. Yes, it is not currently in use, I'll remove it. > > + > > +static const struct fmeter_dev_t fmeter_v0_mt6779_t = { > > + .crystal_freq = 52, > > + .shu_of = 0x500, > > + .shu_lv = { .offset = 0x00e4, .mask = 0x00000006, .shift = 1 }, > > + .pll_id = { .offset = 0x0510, .mask = 0x80000000, .shift = 31 }, > > + .pll_md = { > > + { .offset = 0x0d84, .mask = 0x00000100, .shift = 8 }, > > + { .offset = 0x0d84, .mask = 0x00000100, .shift = 8 }, > > + }, > > + .sdmpcw = { > > + { .offset = 0x0d9c, .mask = 0xffff0000, .shift = 16 }, > > + { .offset = 0x0d94, .mask = 0xffff0000, .shift = 16 }, > > + }, > > + .prediv = { > > + { .offset = 0x0da8, .mask = 0x000c0000, .shift = 18 }, > > + { .offset = 0x0da0, .mask = 0x000c0000, .shift = 18 }, > > + }, > > + .posdiv = { > > + { .offset = 0x0da8, .mask = 0x00000007, .shift = 0 }, > > + { .offset = 0x0da0, .mask = 0x00000007, .shift = 0 }, > > + }, > > + .ckdiv4 = { > > + { .offset = 0x0d18, .mask = 0x08000000, .shift = 27 }, > > + { .offset = 0x0d18, .mask = 0x08000000, .shift = 27 }, > > + }, > > + .cldiv2 = { > > + { .offset = 0x0c38, .mask = 0x80000000, .shift = 31 }, > > + { .offset = 0x0c38, .mask = 0x80000000, .shift = 31 }, > > + }, > > +}; > > + > > +static const struct mr4_dev_t mr4_v1_mt6779_t = { > > + .mr4_rg = { .offset = 0x0090, .mask = 0x0000ffff, .shift = 0 }, > > +}; > > + > > +struct mtk_dramc_compatible { > > + const struct fmeter_dev_t *fmeter; > > + const struct mr4_dev_t *mr4; > > +}; > > + > > +static const struct mtk_dramc_compatible mt6779_compat = { > > + .fmeter = &fmeter_v0_mt6779_t, > > + .mr4 = &mr4_v1_mt6779_t, > > +}; > > + > > +static const struct of_device_id mtk_dramc_of_ids[] = { > > + { .compatible = "mediatek,mt6779-dramc", .data = &mt6779_compat }, > > + {} > > +}; > > +MODULE_DEVICE_TABLE(of, mtk_dramc_of_ids); > > + > > +/* > > + * mtk_dramc_get_drvdata_by_ids - get the dramc driver data > > + * > > + * Return the dramc driver data > > + */ > > +static struct dramc_dev_t *mtk_dramc_get_drvdata_by_ids(void) > > +{ > > + struct device_node *np; > > + struct platform_device *dramc_pdev; > > + > > + np = of_find_matching_node_and_match(NULL, mtk_dramc_of_ids, NULL); > > + dramc_pdev = of_find_device_by_node(np); > > + > > + if (!dramc_pdev) > > + return NULL; > > + > > + return (struct dramc_dev_t *)platform_get_drvdata(dramc_pdev); > > +} > > + > > +static ssize_t mr_show(struct device_driver *driver, char *buf) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + struct mr_info_t *mr_info_ptr; > > + unsigned int i; > > + ssize_t ret; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + mr_info_ptr = dramc_dev_ptr->mr_info_ptr; > > + > > + for (ret = 0, i = 0; i < dramc_dev_ptr->mr_cnt; i++) { > > + ret += snprintf(buf + ret, PAGE_SIZE - ret, > > + "mr%d: 0x%x\n", > > The file name is 'mr' and what you read should be just the value. 'mr' is the abbreviation of 'Mode Register', which defined by JEDEC. There are 64 mode registers in LPDDR4X but not all of them are meaningful, so we need a pair to describe some of them. Which mode registers will be brought to the kernel are depends on the bootloader. > > Also, sysfs files require documentation too. Okay, I'll fill in the requirements. > > > + mr_info_ptr[i].mr_index, > > + mr_info_ptr[i].mr_value); > > + if (ret >= PAGE_SIZE) > > + return strlen(buf); > > + } > > + > > + return strlen(buf); > > +} > > + > > +static ssize_t mr4_show(struct device_driver *driver, char *buf) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + unsigned int i; > > + ssize_t ret; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + for (ret = 0, i = 0; i < dramc_dev_ptr->channel_cnt; i++) { > > + ret += snprintf(buf + ret, PAGE_SIZE - ret, > > + "mr4: ch%d 0x%x\n", > > Same issues here. > > > + i, mtk_dramc_get_mr4(i)); > > + if (ret >= PAGE_SIZE) > > + return strlen(buf); > > + } > > + > > + return strlen(buf); > > +} > > + > > +static ssize_t dram_data_rate_show(struct device_driver *driver, char *buf) > > +{ > > + return snprintf(buf, PAGE_SIZE, "DRAM data rate = %d\n", > > + mtk_dramc_get_data_rate()); > > And here. > > > +} > > + > > +static DRIVER_ATTR_RO(mr); > > +static DRIVER_ATTR_RO(mr4); > > +static DRIVER_ATTR_RO(dram_data_rate); > > A driver attr would be global. Shouldn't these be device attr's which > are per instance. There is always only one DRAMC instance in the MediaTek SoC, > > You should also be using attribute groups. Okay. > > > + > > +static int dramc_probe(struct platform_device *pdev) > > +{ > > + struct device_node *dramc_node = pdev->dev.of_node; > > + struct dramc_dev_t *dramc_dev_ptr; > > + const struct mtk_dramc_compatible *dev_comp; > > + struct resource *res; > > + unsigned int i, size; > > + int ret; > > + > > + pr_info("%s: module probe.\n", __func__); > > + > > + dramc_dev_ptr = devm_kmalloc(&pdev->dev, > > Probably want to use devm_kzalloc instead. It would be better, I'll update it. > > > + sizeof(struct dramc_dev_t), > > + GFP_KERNEL); > > + > > + dev_comp = > > + (struct mtk_dramc_compatible *) > > + of_device_get_match_data(&pdev->dev); > > + > > + if (!dramc_dev_ptr) > > + return -ENOMEM; > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,dram-type", > > + &dramc_dev_ptr->dram_type); > > + if (ret) { > > + pr_info("%s: get dram_type fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,support-channel-cnt", > > + &dramc_dev_ptr->support_channel_cnt); > > + if (ret) { > > + pr_info("%s: get support_channel_cnt fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,channel-cnt", > > + &dramc_dev_ptr->channel_cnt); > > + if (ret) { > > + pr_info("%s: get channel_cnt fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,rank-cnt", > > + &dramc_dev_ptr->rank_cnt); > > + if (ret) { > > + pr_info("%s: get rank_cnt fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,mr-cnt", > > + &dramc_dev_ptr->mr_cnt); > > + if (ret) { > > + pr_info("%s: get mr_cnt fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + ret = of_property_read_u32(dramc_node, > > + "mediatek,freq-cnt", > > + &dramc_dev_ptr->freq_cnt); > > + if (ret) { > > + pr_info("%s: get freq_cnt fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + dramc_dev_ptr->mr4_dev_ptr = (void *)dev_comp->mr4; > > + > > + pr_info("%s: %s(%d),%s(%d),%s(%d),%s(%d),%s(%d),%s(%d),%s(%s)\n", > > + __func__, > > + "dram_type", dramc_dev_ptr->dram_type, > > + "support_channel_cnt", dramc_dev_ptr->support_channel_cnt, > > + "channel_cnt", dramc_dev_ptr->channel_cnt, > > + "rank_cnt", dramc_dev_ptr->rank_cnt, > > + "mr_cnt", dramc_dev_ptr->mr_cnt, > > + "freq_cnt", dramc_dev_ptr->freq_cnt, > > + "mr4", (dramc_dev_ptr->mr4_dev_ptr) ? "true" : "false"); > > Why do you need this? It's already in DT which is readable from > userspace. To make the driver status easy to see when probing it. > > > + > > + size = sizeof(unsigned int) * dramc_dev_ptr->rank_cnt; > > + dramc_dev_ptr->rank_size = devm_kmalloc(&pdev->dev, size, GFP_KERNEL); > > + if (!(dramc_dev_ptr->rank_size)) > > + return -ENOMEM; > > + ret = of_property_read_u32_array(dramc_node, > > + "mediatek,rank-size", > > + dramc_dev_ptr->rank_size, > > + dramc_dev_ptr->rank_cnt); > > + if (ret) { > > + pr_info("%s: get rank_size fail\n", __func__); > > + return -EINVAL; > > + } > > + > > + if (dramc_dev_ptr->mr_cnt) { > > + size = sizeof(struct mr_info_t) * dramc_dev_ptr->mr_cnt; > > + dramc_dev_ptr->mr_info_ptr = devm_kmalloc(&pdev->dev, > > + size, > > + GFP_KERNEL); > > + if (!(dramc_dev_ptr->mr_info_ptr)) > > + return -ENOMEM; > > + ret = > > + of_property_read_u32_array(dramc_node, > > + "mediatek,mr", > > + (unsigned int *)dramc_dev_ptr->mr_info_ptr, > > + size >> 2); > > + if (ret) { > > + pr_info("%s: get mr_info fail\n", __func__); > > + return -EINVAL; > > + } > > + for (i = 0; i < dramc_dev_ptr->mr_cnt; i++) > > + pr_info("%s: mr%d(%x)\n", __func__, > > + dramc_dev_ptr->mr_info_ptr[i].mr_index, > > + dramc_dev_ptr->mr_info_ptr[i].mr_value); > > + } > > + > > + if (dramc_dev_ptr->freq_cnt) { > > + size = sizeof(unsigned int) * dramc_dev_ptr->freq_cnt * 2; > > + dramc_dev_ptr->freq_step = > > + devm_kmalloc(&pdev->dev, size, GFP_KERNEL); > > + if (!(dramc_dev_ptr->freq_step)) > > + return -ENOMEM; > > + ret = of_property_read_u32_array(dramc_node, > > + "mediatek,freq-step", > > + dramc_dev_ptr->freq_step, > > + dramc_dev_ptr->freq_cnt * 2); > > + if (ret) { > > + pr_info("%s: get freq_step fail\n", __func__); > > + return -EINVAL; > > + } > > + } > > + > > + size = sizeof(phys_addr_t) * dramc_dev_ptr->support_channel_cnt; > > + dramc_dev_ptr->dramc_chn_base_ao = devm_kmalloc(&pdev->dev, > > + size, GFP_KERNEL); > > + if (!(dramc_dev_ptr->dramc_chn_base_ao)) > > + return -ENOMEM; > > + dramc_dev_ptr->dramc_chn_base_nao = devm_kmalloc(&pdev->dev, > > + size, GFP_KERNEL); > > + if (!(dramc_dev_ptr->dramc_chn_base_nao)) > > + return -ENOMEM; > > + dramc_dev_ptr->ddrphy_chn_base_ao = devm_kmalloc(&pdev->dev, > > + size, GFP_KERNEL); > > + if (!(dramc_dev_ptr->ddrphy_chn_base_ao)) > > + return -ENOMEM; > > + > > + for (i = 0; i < dramc_dev_ptr->support_channel_cnt; i++) { > > + res = platform_get_resource(pdev, IORESOURCE_MEM, i); > > + dramc_dev_ptr->dramc_chn_base_ao[i] = > > + devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(dramc_dev_ptr->dramc_chn_base_ao[i])) { > > + pr_info("%s: unable to map ch%d DRAMC AO base\n", > > + __func__, i); > > + return -EINVAL; > > + } > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, > > + i + dramc_dev_ptr->support_channel_cnt); > > + dramc_dev_ptr->dramc_chn_base_nao[i] = > > + devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(dramc_dev_ptr->dramc_chn_base_nao[i])) { > > + pr_info("%s: unable to map ch%d DRAMC NAO base\n", > > + __func__, i); > > + return -EINVAL; > > + } > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, > > + i + dramc_dev_ptr->support_channel_cnt * 2); > > + dramc_dev_ptr->ddrphy_chn_base_ao[i] = > > + devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_ao[i])) { > > + pr_info("%s: unable to map ch%d DDRPHY AO base\n", > > + __func__, i); > > + return -EINVAL; > > + } > > + } > > + > > + dramc_dev_ptr->fmeter_dev_ptr = (void *)dev_comp->fmeter; > > + > > + ret = driver_create_file(pdev->dev.driver, > > + &driver_attr_dram_data_rate); > > + if (ret) { > > + pr_info("%s: fail to create dram_data_rate sysfs\n", __func__); > > + return ret; > > + } > > + > > + ret = driver_create_file(pdev->dev.driver, > > + &driver_attr_mr); > > + if (ret) { > > + pr_info("%s: fail to create mr sysfs\n", __func__); > > + return ret; > > + } > > + > > + if (dramc_dev_ptr->mr4_dev_ptr) { > > + ret = driver_create_file(pdev->dev.driver, > > + &driver_attr_mr4); > > + if (ret) { > > + pr_info("%s: fail to create mr4 sysfs\n", __func__); > > + return ret; > > + } > > + } > > + > > + platform_set_drvdata(pdev, dramc_dev_ptr); > > + pr_info("%s: DRAM data type = %d\n", __func__, > > + mtk_dramc_get_ddr_type()); > > + > > + pr_info("%s: DRAM data clock rate = %d\n", __func__, > > + mtk_dramc_get_data_rate()); > > + > > + return ret; > > +} > > + > > +/* > > + * mtk_dramc_get_steps_freq - get the data clock rate of target DVFS step > > + * @step: the step index of DVFS > > + * > > + * Return the DRAM spec data clock rate (MHz) > > + */ > > +int mtk_dramc_get_steps_freq(unsigned int step) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return -ENODEV; > > + > > + if (step < dramc_dev_ptr->freq_cnt) > > + return dramc_dev_ptr->freq_step[step * 2 + 1]; > > + > > + return -EINVAL; > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_steps_freq); > > + > > +/* > > + * decode_freq - decode the spec data clock rate > > + * @vco_freq: real data clock rate > > + * > > + * Return the DRAM spec data clock rate (MHz) > > + */ > > +static unsigned int decode_freq(unsigned int vco_freq) > > +{ > > + int i; > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + for (i = 0; i < dramc_dev_ptr->freq_cnt * 2; i += 2) > > + if (vco_freq == dramc_dev_ptr->freq_step[i]) > > + return dramc_dev_ptr->freq_step[i + 1]; > > + > > + return vco_freq; > > +} > > + > > +static unsigned int fmeter_v0(struct dramc_dev_t *dramc_dev_ptr) > > +{ > > + struct fmeter_dev_t *fmeter_dev_ptr = > > + (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr; > > + unsigned int shu_lv_val; > > + unsigned int pll_id_val; > > + unsigned int pll_md_val; > > + unsigned int sdmpcw_val; > > + unsigned int prediv_val; > > + unsigned int posdiv_val; > > + unsigned int ckdiv4_val; > > + unsigned int cldiv2_val; > > + unsigned int offset; > > + unsigned int vco_freq; > > + > > + shu_lv_val = (readl(dramc_dev_ptr->dramc_chn_base_ao[0] + > > + fmeter_dev_ptr->shu_lv.offset) & > > + fmeter_dev_ptr->shu_lv.mask) >> > > + fmeter_dev_ptr->shu_lv.shift; > > + > > + pll_id_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + > > + fmeter_dev_ptr->pll_id.offset) & > > + fmeter_dev_ptr->pll_id.mask) >> > > + fmeter_dev_ptr->pll_id.shift; > > + > > + offset = fmeter_dev_ptr->pll_md[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + pll_md_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->pll_md[pll_id_val].mask) >> > > + fmeter_dev_ptr->pll_md[pll_id_val].shift; > > + > > + offset = fmeter_dev_ptr->sdmpcw[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + sdmpcw_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->sdmpcw[pll_id_val].mask) >> > > + fmeter_dev_ptr->sdmpcw[pll_id_val].shift; > > + > > + offset = fmeter_dev_ptr->prediv[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + prediv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->prediv[pll_id_val].mask) >> > > + fmeter_dev_ptr->prediv[pll_id_val].shift; > > + > > + offset = fmeter_dev_ptr->posdiv[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + posdiv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->posdiv[pll_id_val].mask) >> > > + fmeter_dev_ptr->posdiv[pll_id_val].shift; > > + > > + offset = fmeter_dev_ptr->ckdiv4[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + ckdiv4_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->ckdiv4[pll_id_val].mask) >> > > + fmeter_dev_ptr->ckdiv4[pll_id_val].shift; > > + > > + offset = fmeter_dev_ptr->cldiv2[pll_id_val].offset + > > + fmeter_dev_ptr->shu_of * shu_lv_val; > > + cldiv2_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) & > > + fmeter_dev_ptr->cldiv2[pll_id_val].mask) >> > > + fmeter_dev_ptr->cldiv2[pll_id_val].shift; > > + > > + vco_freq = ((fmeter_dev_ptr->crystal_freq >> prediv_val) * > > + (sdmpcw_val >> 8)) >> > > + posdiv_val >> ckdiv4_val >> pll_md_val >> cldiv2_val; > > + > > + return decode_freq(vco_freq); > > +} > > + > > +/* > > + * mtk_dramc_get_data_rate - calculate DRAM data rate > > + * > > + * Return DRAM data rate (MB/s) > > + */ > > +unsigned int mtk_dramc_get_data_rate(void) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + struct fmeter_dev_t *fmeter_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + fmeter_dev_ptr = (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr; > > + if (!fmeter_dev_ptr) > > + return 0; > > + > > + return fmeter_v0(dramc_dev_ptr); > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_data_rate); > > + > > +static unsigned int mr4_v1(struct dramc_dev_t *dramc_dev_ptr, unsigned int ch) > > +{ > > + struct mr4_dev_t *mr4_dev_ptr = > > + (struct mr4_dev_t *)dramc_dev_ptr->mr4_dev_ptr; > > + > > + return (readl(dramc_dev_ptr->dramc_chn_base_nao[ch] + > > + mr4_dev_ptr->mr4_rg.offset) & mr4_dev_ptr->mr4_rg.mask) >> > > + mr4_dev_ptr->mr4_rg.shift; > > +} > > + > > +/* > > + * mtk_dramc_get_mr4 - get the DRAM MR4 value of specific DRAM channel > > + * @ch: the channel index > > + * > > + * Return the MR4 value > > + */ > > +unsigned int mtk_dramc_get_mr4(unsigned int ch) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + struct mr4_dev_t *mr4_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + mr4_dev_ptr = (struct mr4_dev_t *)dramc_dev_ptr->mr4_dev_ptr; > > + if (!mr4_dev_ptr) > > + return 0; > > + > > + if (ch >= dramc_dev_ptr->channel_cnt) > > + return 0; > > + > > + return mr4_v1(dramc_dev_ptr, ch); > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_mr4); > > + > > +/* > > + * mtk_dramc_get_ddr_type - get DRAM type > > + * > > + * Return the DRAM type > > + */ > > +unsigned int mtk_dramc_get_ddr_type(void) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + return dramc_dev_ptr->dram_type; > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_ddr_type); > > + > > +/* > > + * mtk_dramc_get_channel_count - get DRAM channel count > > + * > > + * Return the DRAM channel count > > + */ > > +unsigned int mtk_dramc_get_channel_count(void) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + return dramc_dev_ptr->channel_cnt; > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_channel_count); > > + > > +/* > > + * mtk_dramc_get_rank_count - get DRAM rank count > > + * > > + * Return the DRAM rank count > > + */ > > +unsigned int mtk_dramc_get_rank_count(void) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + return dramc_dev_ptr->rank_cnt; > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_rank_count); > > + > > +/* > > + * mtk_dramc_get_rank_size - get size of DRAM rank > > + * > > + * Return the size of specific DRAM rank > > + */ > > +unsigned int mtk_dramc_get_rank_size(unsigned int rank) > > +{ > > + struct dramc_dev_t *dramc_dev_ptr; > > + > > + dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids(); > > + > > + if (!dramc_dev_ptr) > > + return 0; > > + > > + if (rank < dramc_dev_ptr->rank_cnt) > > + return dramc_dev_ptr->rank_size[rank]; > > + else > > + return 0; > > +} > > +EXPORT_SYMBOL(mtk_dramc_get_rank_size); > > + > > +static int dramc_remove(struct platform_device *pdev) > > +{ > > + return 0; > > +} > > + > > +static struct platform_driver dramc_drv = { > > + .probe = dramc_probe, > > + .remove = dramc_remove, > > + .driver = { > > + .name = DRAMC_DRV_NAME, > > + .owner = THIS_MODULE, > > + .of_match_table = mtk_dramc_of_ids, > > + }, > > +}; > > + > > +static int __init dramc_drv_init(void) > > +{ > > + int ret; > > + > > + ret = platform_driver_register(&dramc_drv); > > + if (ret) { > > + pr_info("%s: init fail, ret 0x%x\n", __func__, ret); > > + return ret; > > + } > > + > > + return ret; > > +} > > + > > +static void __exit dramc_drv_exit(void) > > +{ > > + platform_driver_unregister(&dramc_drv); > > +} > > + > > +module_init(dramc_drv_init); > > +module_exit(dramc_drv_exit); > > + > > +MODULE_LICENSE("GPL v2"); > > +MODULE_DESCRIPTION("MediaTek DRAMC Driver"); > > +MODULE_AUTHOR("Po-Kai Chi "); > > diff --git a/include/memory/mediatek/dramc.h b/include/memory/mediatek/dramc.h > > new file mode 100644 > > index 0000000..c8d200f > > --- /dev/null > > +++ b/include/memory/mediatek/dramc.h > > @@ -0,0 +1,18 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (c) 2021 MediaTek Inc. > > + */ > > + > > +#ifndef __DRAMC_H__ > > +#define __DRAMC_H__ > > + > > +int mtk_dramc_get_steps_freq(unsigned int step); > > +unsigned int mtk_dramc_get_ddr_type(void); > > +unsigned int mtk_dramc_get_data_rate(void); > > +unsigned int mtk_dramc_get_mr4(unsigned int ch); > > +unsigned int mtk_dramc_get_channel_count(void); > > +unsigned int mtk_dramc_get_rank_count(void); > > +unsigned int mtk_dramc_get_rank_size(unsigned int rk); > > + > > +#endif /* __DRAMC_H__ */ > > + > > -- > > 1.7.9.5 > > _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek