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=-11.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,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 A0D6CC4363A for ; Wed, 28 Oct 2020 10:21:48 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 B59B1246A9 for ; Wed, 28 Oct 2020 10:21:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ttRCDJ11" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B59B1246A9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=dLjJmvyrxzTMk3w9cYrnW6QHijT/EazbC0Aeggnr5w8=; b=ttRCDJ11+7eSBvAr44TeCBDrS 24zQooCS5OyrqaT8OX1OTEZ0Mh6L8n1tQAR8cz+Z1yqOPGmziW3oBOv4y/TctYdyrmJSpmhr9dD7X N3JpuP6XKtS2fx9gkh80MkAc4O5SlrX9pYdIrD35rhSwxxtaAF/SjAeRVQfzutAOztbbdbHIHHUak lkOn9NSUE9xekwJBtElm9v3U/i/IBBfLd3Xs1mvfMyShFoOCsNurtqT7wM8ZKnuGal1gkj19Yk1rY Pex2F3EDKn9Qol6xBN+0bvjJ0nx1jSgEFknAC/ZwVXzwEvMs3qJTyYwcWUonIp+f18AovjzXpW9aI ZI365tdbQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kXiZT-0006yP-9v; Wed, 28 Oct 2020 10:20:47 +0000 Received: from relay6-d.mail.gandi.net ([217.70.183.198]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kXiZP-0006xW-TJ for linux-mtd@lists.infradead.org; Wed, 28 Oct 2020 10:20:45 +0000 X-Originating-IP: 91.224.148.103 Received: from xps13 (unknown [91.224.148.103]) (Authenticated sender: miquel.raynal@bootlin.com) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id F022DC000B; Wed, 28 Oct 2020 10:20:38 +0000 (UTC) Date: Wed, 28 Oct 2020 11:20:37 +0100 From: Miquel Raynal To: "Ramuthevar,Vadivel MuruganX" Subject: Re: [RESENDPATCH v15 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC Message-ID: <20201028112037.326c06e2@xps13> In-Reply-To: <20201026073021.33327-3-vadivel.muruganx.ramuthevar@linux.intel.com> References: <20201026073021.33327-1-vadivel.muruganx.ramuthevar@linux.intel.com> <20201026073021.33327-3-vadivel.muruganx.ramuthevar@linux.intel.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.4 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201028_062044_211673_DACF7576 X-CRM114-Status: GOOD ( 31.24 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cheol.yong.kim@intel.com, devicetree@vger.kernel.org, vigneshr@ti.com, tudor.ambarus@microchip.com, richard@nod.at, simon.k.r.goldschmidt@gmail.com, linux-kernel@vger.kernel.org, dinguyen@kernel.org, robh+dt@kernel.org, linux-mtd@lists.infradead.org, boris.brezillon@collabora.com, qi-ming.wu@intel.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGVsbG8sCgoiUmFtdXRoZXZhcixWYWRpdmVsIE11cnVnYW5YIgo8dmFkaXZlbC5tdXJ1Z2FueC5y YW11dGhldmFyQGxpbnV4LmludGVsLmNvbT4gd3JvdGUgb24gTW9uLCAyNiBPY3QgMjAyMAoxNToz MDoyMSArMDgwMDoKCj4gRnJvbTogUmFtdXRoZXZhciBWYWRpdmVsIE11cnVnYW4gPHZhZGl2ZWwu bXVydWdhbngucmFtdXRoZXZhckBsaW51eC5pbnRlbC5jb20+Cj4gCj4gVGhpcyBwYXRjaCBhZGRz IHRoZSBuZXcgSVAgb2YgTmFuZCBGbGFzaCBDb250cm9sbGVyKE5GQykgc3VwcG9ydAo+IG9uIElu dGVsJ3MgTGlnaHRuaW5nIE1vdW50YWluKExHTSkgU29DLgo+IAo+IERNQSBpcyB1c2VkIGZvciBi dXJzdCBkYXRhIHRyYW5zZmVyIG9wZXJhdGlvbiwgYWxzbyBETUEgSFcgc3VwcG9ydHMKPiBhbGln bmVkIDMyYml0IG1lbW9yeSBhZGRyZXNzIGFuZCBhbGlnbmVkIGRhdGEgYWNjZXNzIGJ5IGRlZmF1 bHQuCj4gRE1BIGJ1cnN0IG9mIDggc3VwcG9ydGVkLiBEYXRhIHJlZ2lzdGVyIHVzZWQgdG8gc3Vw cG9ydCB0aGUgcmVhZC93cml0ZQo+IG9wZXJhdGlvbiBmcm9tL3RvIGRldmljZS4KPiAKPiBOQU5E IGNvbnRyb2xsZXIgZHJpdmVyIGltcGxlbWVudHMgLT5leGVjX29wKCkgdG8gcmVwbGFjZSBsZWdh Y3kgaG9va3MsCj4gdGhlc2Ugc3BlY2lmaWMgY2FsbC1iYWNrIG1ldGhvZCB0byBleGVjdXRlIE5B TkQgb3BlcmF0aW9ucy4KCk5vIG5lZWQgdG8gbWVudGlvbiBsZWdhY3kgaG9va3MgaGVyZSBhcyB0 aGV5IGFyZSBub3QgcGFydCBvZiB5b3VyCmRyaXZlciBhdCBhbGwuCgo+IAo+IFNpZ25lZC1vZmYt Ynk6IFJhbXV0aGV2YXIgVmFkaXZlbCBNdXJ1Z2FuIDx2YWRpdmVsLm11cnVnYW54LnJhbXV0aGV2 YXJAbGludXguaW50ZWwuY29tPgo+IC0tLQo+ICBkcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmln ICAgICAgICAgICAgICAgICB8ICAgOCArCj4gIGRyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxl ICAgICAgICAgICAgICAgIHwgICAxICsKPiAgZHJpdmVycy9tdGQvbmFuZC9yYXcvaW50ZWwtbmFu ZC1jb250cm9sbGVyLmMgfCA3MzQgKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmls ZXMgY2hhbmdlZCwgNzQzIGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvbXRkL25hbmQvcmF3L2ludGVsLW5hbmQtY29udHJvbGxlci5jCj4gCj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29u ZmlnCj4gaW5kZXggNmM0NmYyNWI1N2UyLi4xYjM2OTBmZDA4ZGMgMTAwNjQ0Cj4gLS0tIGEvZHJp dmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L0tj b25maWcKPiBAQCAtNDYyLDYgKzQ2MiwxNCBAQCBjb25maWcgTVREX05BTkRfQVJBU0FOCj4gIAkg IEVuYWJsZXMgdGhlIGRyaXZlciBmb3IgdGhlIEFyYXNhbiBOQU5EIGZsYXNoIGNvbnRyb2xsZXIg b24KPiAgCSAgWnlucSBVbHRyYXNjYWxlKyBNUFNvQy4KPiAgCj4gK2NvbmZpZyBNVERfTkFORF9J TlRFTF9MR00KPiArCXRyaXN0YXRlICJTdXBwb3J0IGZvciBOQU5EIGNvbnRyb2xsZXIgb24gSW50 ZWwgTEdNIFNvQyIKPiArCWRlcGVuZHMgb24gT0YgfHwgQ09NUElMRV9URVNUCj4gKwlkZXBlbmRz IG9uIEhBU19JT01FTQo+ICsJaGVscAo+ICsJICBFbmFibGVzIHN1cHBvcnQgZm9yIE5BTkQgRmxh c2ggY2hpcHMgb24gSW50ZWwncyBMR00gU29DLgo+ICsJICBOQU5EIGZsYXNoIGNvbnRyb2xsZXIg aW50ZXJmYWNlZCB0aHJvdWdoIHRoZSBFeHRlcm5hbCBCdXMgVW5pdC4KPiArCj4gIGNvbW1lbnQg Ik1pc2MiCj4gIAo+ICBjb25maWcgTVREX1NNX0NPTU1PTgo+IGRpZmYgLS1naXQgYS9kcml2ZXJz L210ZC9uYW5kL3Jhdy9NYWtlZmlsZSBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4g aW5kZXggMjkzMGY1YjkwMTVkLi45ZTYwMzczNjNmYzYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9t dGQvbmFuZC9yYXcvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmls ZQo+IEBAIC01OCw2ICs1OCw3IEBAIG9iai0kKENPTkZJR19NVERfTkFORF9TVE0zMl9GTUMyKQkr PSBzdG0zMl9mbWMyX25hbmQubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfTUVTT04pCQkrPSBt ZXNvbl9uYW5kLm8KPiAgb2JqLSQoQ09ORklHX01URF9OQU5EX0NBREVOQ0UpCQkrPSBjYWRlbmNl LW5hbmQtY29udHJvbGxlci5vCj4gIG9iai0kKENPTkZJR19NVERfTkFORF9BUkFTQU4pCQkrPSBh cmFzYW4tbmFuZC1jb250cm9sbGVyLm8KPiArb2JqLSQoQ09ORklHX01URF9OQU5EX0lOVEVMX0xH TSkJKz0gaW50ZWwtbmFuZC1jb250cm9sbGVyLm8KPiAgCj4gIG5hbmQtb2JqcyA6PSBuYW5kX2Jh c2UubyBuYW5kX2xlZ2FjeS5vIG5hbmRfYmJ0Lm8gbmFuZF90aW1pbmdzLm8gbmFuZF9pZHMubwo+ ICBuYW5kLW9ianMgKz0gbmFuZF9vbmZpLm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tdGQvbmFu ZC9yYXcvaW50ZWwtbmFuZC1jb250cm9sbGVyLmMgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9pbnRl bC1uYW5kLWNvbnRyb2xsZXIuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAw MDAwMDAwLi4wYWVmYzQ0MWM3ZDUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9tdGQv bmFuZC9yYXcvaW50ZWwtbmFuZC1jb250cm9sbGVyLmMKPiBAQCAtMCwwICsxLDczNCBAQAo+ICsv LyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsKPiArLyogQ29weXJpZ2h0IChjKSAy MDIwIEludGVsIENvcnBvcmF0aW9uLiAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+ ICsjaW5jbHVkZSA8bGludXgvY29tcGxldGlvbi5oPgo+ICsjaW5jbHVkZSA8bGludXgvZG1hZW5n aW5lLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9kbWEtZGlyZWN0aW9uLmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9kbWEtbWFwcGluZy5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9pbml0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pb3BvbGwuaD4KPiArI2luY2x1ZGUg PGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKwo+ICsjaW5j bHVkZSA8bGludXgvbXRkL210ZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXRkL3Jhd25hbmQuaD4K PiArI2luY2x1ZGUgPGxpbnV4L210ZC9uYW5kX2VjYy5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXRk L25hbmQuaD4KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L3NjaGVkLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC90eXBlcy5oPgo+ICsjaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgo+ICsKPiAr I2RlZmluZSBFQlVfQ0xDCQkJMHgwMDAKPiArI2RlZmluZSBFQlVfQ0xDX1JTVAkJMHgwMDAwMDAw MHUKPiArCj4gKyNkZWZpbmUgRUJVX0FERFJfU0VMKG4pCQkoMHgwMjAgKyAobikgKiA0KQo+ICsv KiA1IGJpdHMgMjY6MjIgaW5jbHVkZWQgZm9yIGNvbXBhcmlzb24gaW4gdGhlIEFERFJfU0VMeCAq Lwo+ICsjZGVmaW5lIEVCVV9BRERSX01BU0soeCkJKCh4KSA8PCA0KQo+ICsjZGVmaW5lIEVCVV9B RERSX1NFTF9SRUdFTgkweDEKPiArCj4gKyNkZWZpbmUgRUJVX0JVU0NPTihuKQkJKDB4MDYwICsg KG4pICogNCkKPiArI2RlZmluZSBFQlVfQlVTQ09OX0NNVUxUX1Y0CTB4MQo+ICsjZGVmaW5lIEVC VV9CVVNDT05fUkVDT1ZDKG4pCSgobikgPDwgMikKPiArI2RlZmluZSBFQlVfQlVTQ09OX0hPTERD KG4pCSgobikgPDwgNCkKPiArI2RlZmluZSBFQlVfQlVTQ09OX1dBSVRSREMobikJKChuKSA8PCA2 KQo+ICsjZGVmaW5lIEVCVV9CVVNDT05fV0FJVFdSQyhuKQkoKG4pIDw8IDgpCj4gKyNkZWZpbmUg RUJVX0JVU0NPTl9CQ0dFTl9DUwkweDAKPiArI2RlZmluZSBFQlVfQlVTQ09OX1NFVFVQX0VOCUJJ VCgyMikKPiArI2RlZmluZSBFQlVfQlVTQ09OX0FMRUMJCTB4QzAwMAo+ICsKPiArI2RlZmluZSBF QlVfQ09OCQkJMHgwQjAKPiArI2RlZmluZSBFQlVfQ09OX05BTkRNX0VOCUJJVCgwKQo+ICsjZGVm aW5lIEVCVV9DT05fTkFORE1fRElTCTB4MAo+ICsjZGVmaW5lIEVCVV9DT05fQ1NNVVhfRV9FTglC SVQoMSkKPiArI2RlZmluZSBFQlVfQ09OX0FMRV9QX0xPVwlCSVQoMikKPiArI2RlZmluZSBFQlVf Q09OX0NMRV9QX0xPVwlCSVQoMykKPiArI2RlZmluZSBFQlVfQ09OX0NTX1BfTE9XCUJJVCg0KQo+ ICsjZGVmaW5lIEVCVV9DT05fU0VfUF9MT1cJQklUKDUpCj4gKyNkZWZpbmUgRUJVX0NPTl9XUF9Q X0xPVwlCSVQoNikKPiArI2RlZmluZSBFQlVfQ09OX1BSRV9QX0xPVwlCSVQoNykKPiArI2RlZmlu ZSBFQlVfQ09OX0lOX0NTX1MobikJKChuKSA8PCA4KQo+ICsjZGVmaW5lIEVCVV9DT05fT1VUX0NT X1MobikJKChuKSA8PCAxMCkKPiArI2RlZmluZSBFQlVfQ09OX0xBVF9FTl9DU19QCSgoMHgzRCkg PDwgMTgpCj4gKwo+ICsjZGVmaW5lIEVCVV9XQUlUCQkweDBCNAo+ICsjZGVmaW5lIEVCVV9XQUlU X1JEQlkJCUJJVCgwKQo+ICsjZGVmaW5lIEVCVV9XQUlUX1dSX0MJCUJJVCgzKQo+ICsKPiArI2Rl ZmluZSBIU05BTkRfQ1RMMQkJMHgxMTAKPiArI2RlZmluZSBIU05BTkRfQ1RMMV9BRERSX1NISUZU CTI0Cj4gKwo+ICsjZGVmaW5lIEhTTkFORF9DVEwyCQkweDExNAo+ICsjZGVmaW5lIEhTTkFORF9D VEwyX0FERFJfU0hJRlQJOAo+ICsjZGVmaW5lIEhTTkFORF9DVEwyX0NZQ19OX1Y1CSgweDIgPDwg MTYpCj4gKwo+ICsjZGVmaW5lIEhTTkFORF9JTlRfTVNLX0NUTAkweDEyNAo+ICsjZGVmaW5lIEhT TkFORF9JTlRfTVNLX0NUTF9XUl9DCUJJVCg0KQo+ICsKPiArI2RlZmluZSBIU05BTkRfSU5UX1NU QQkJMHgxMjgKPiArI2RlZmluZSBIU05BTkRfSU5UX1NUQV9XUl9DCUJJVCg0KQo+ICsKPiArI2Rl ZmluZSBIU05BTkRfQ1RMCQkweDEzMAo+ICsjZGVmaW5lIEhTTkFORF9DVExfRU5BQkxFX0VDQwlC SVQoMCkKPiArI2RlZmluZSBIU05BTkRfQ1RMX0dPCQlCSVQoMikKPiArI2RlZmluZSBIU05BTkRf Q1RMX0NFX1NFTF9DUyhuKQlCSVQoMyArIChuKSkKPiArI2RlZmluZSBIU05BTkRfQ1RMX1JXX1JF QUQJMHgwCj4gKyNkZWZpbmUgSFNOQU5EX0NUTF9SV19XUklURQlCSVQoMTApCj4gKyNkZWZpbmUg SFNOQU5EX0NUTF9FQ0NfT0ZGX1Y4VEgJQklUKDExKQo+ICsjZGVmaW5lIEhTTkFORF9DVExfQ0tG Rl9FTgkweDAKPiArI2RlZmluZSBIU05BTkRfQ1RMX01TR19FTglCSVQoMTcpCj4gKwo+ICsjZGVm aW5lIEhTTkFORF9QQVJBMAkJMHgxM2MKPiArI2RlZmluZSBIU05BTkRfUEFSQTBfUEFHRV9WODE5 MgkweDMKPiArI2RlZmluZSBIU05BTkRfUEFSQTBfUElCX1YyNTYJKDB4MyA8PCA0KQo+ICsjZGVm aW5lIEhTTkFORF9QQVJBMF9CWVBfRU5fTlAJMHgwCj4gKyNkZWZpbmUgSFNOQU5EX1BBUkEwX0JZ UF9ERUNfTlAJMHgwCj4gKyNkZWZpbmUgSFNOQU5EX1BBUkEwX1RZUEVfT05GSQlCSVQoMTgpCj4g KyNkZWZpbmUgSFNOQU5EX1BBUkEwX0FERVBfRU4JQklUKDIxKQo+ICsKPiArI2RlZmluZSBIU05B TkRfQ01TR18wCQkweDE1MAo+ICsjZGVmaW5lIEhTTkFORF9DTVNHXzEJCTB4MTU0Cj4gKwo+ICsj ZGVmaW5lIEhTTkFORF9BTEVfT0ZGUwkJQklUKDIpCj4gKyNkZWZpbmUgSFNOQU5EX0NMRV9PRkZT CQlCSVQoMykKPiArI2RlZmluZSBIU05BTkRfQ1NfT0ZGUwkJQklUKDQpCj4gKwo+ICsjZGVmaW5l IEhTTkFORF9FQ0NfT0ZGU0VUCTB4MDA4Cj4gKwo+ICsjZGVmaW5lIE5BTkRfREFUQV9JRkFDRV9D SEVDS19PTkxZCS0xCj4gKwo+ICsjZGVmaW5lIE1BWF9DUwkyCj4gKwo+ICsjZGVmaW5lIEhaX1BF Ul9NSFoJMTAwMDAwMEwKPiArI2RlZmluZSBVU0VDX1BFUl9TRUMJMTAwMDAwMEwKPiArCj4gK3N0 cnVjdCBlYnVfbmFuZF9jcyB7Cj4gKwl2b2lkIF9faW9tZW0gKmNoaXBhZGRyOwo+ICsJZG1hX2Fk ZHJfdCBuYW5kX3BhOwo+ICsJdTMyIGFkZHJfc2VsOwo+ICt9Owo+ICsKPiArc3RydWN0IGVidV9u YW5kX2NvbnRyb2xsZXIgewo+ICsJc3RydWN0IG5hbmRfY29udHJvbGxlciBjb250cm9sbGVyOwo+ ICsJc3RydWN0IG5hbmRfY2hpcCBjaGlwOwo+ICsJc3RydWN0IGRldmljZSAqZGV2Owo+ICsJdm9p ZCBfX2lvbWVtICplYnU7Cj4gKwl2b2lkIF9faW9tZW0gKmhzbmFuZDsKPiArCXN0cnVjdCBkbWFf Y2hhbiAqZG1hX3R4Owo+ICsJc3RydWN0IGRtYV9jaGFuICpkbWFfcng7Cj4gKwlzdHJ1Y3QgY29t cGxldGlvbiBkbWFfYWNjZXNzX2NvbXBsZXRlOwo+ICsJdW5zaWduZWQgbG9uZyBjbGtfcmF0ZTsK PiArCXN0cnVjdCBjbGsgKmNsazsKPiArCXUzMiBuZF9wYXJhMDsKPiArCXU4IGNzX251bTsKPiAr CXN0cnVjdCBlYnVfbmFuZF9jcyBjc1tNQVhfQ1NdOwo+ICt9Owo+ICsKPiArc3RhdGljIGlubGlu ZSBzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxlciAqbmFuZF90b19lYnUoc3RydWN0IG5hbmRfY2hp cCAqY2hpcCkKPiArewo+ICsJcmV0dXJuIGNvbnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3QgZWJ1X25h bmRfY29udHJvbGxlciwgY2hpcCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZWJ1X25hbmRfd2Fp dHJkeShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCB1bnNpZ25lZCBpbnQgdGltZV9vdXQpCgpQbGVh c2UgbWVudGlvbiB0aGUgdW5pdCBzb21ld2hlcmUuCgo+ICt7Cj4gKwlzdHJ1Y3QgZWJ1X25hbmRf Y29udHJvbGxlciAqY3RybCA9IG5hbmRfdG9fZWJ1KGNoaXApOwo+ICsJdTMyIHN0YXR1czsKPiAr Cj4gKwlyZXR1cm4gcmVhZGxfcG9sbF90aW1lb3V0KGN0cmwtPmVidSArIEVCVV9XQUlULCBzdGF0 dXMsCj4gKwkJCQkgIChzdGF0dXMgJiBFQlVfV0FJVF9SREJZKSB8fAo+ICsJCQkJICAoc3RhdHVz ICYgRUJVX1dBSVRfV1JfQyksIDIwLCB0aW1lX291dCk7Cj4gK30KPiArCj4gK3N0YXRpYyB1OCBl YnVfbmFuZF9yZWFkYihzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlzdHJ1Y3QgZWJ1 X25hbmRfY29udHJvbGxlciAqZWJ1X2hvc3QgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEoY2hp cCk7Cj4gKwl1OCBjc19udW0gPSBlYnVfaG9zdC0+Y3NfbnVtOwo+ICsJdTggdmFsOwo+ICsKPiAr CXZhbCA9IHJlYWRiKGVidV9ob3N0LT5jc1tjc19udW1dLmNoaXBhZGRyICsgSFNOQU5EX0NTX09G RlMpOwo+ICsJZWJ1X25hbmRfd2FpdHJkeShjaGlwLCAxMDAwKTsKPiArCXJldHVybiB2YWw7Cj4g K30KPiArCj4gK3N0YXRpYyB2b2lkIGVidV9uYW5kX3dyaXRlYihzdHJ1Y3QgbmFuZF9jaGlwICpj aGlwLCB1MzIgb2Zmc2V0LCB1OCB2YWx1ZSkKPiArewo+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRy b2xsZXIgKmVidV9ob3N0ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+ICsJdTgg Y3NfbnVtID0gZWJ1X2hvc3QtPmNzX251bTsKPiArCj4gKwl3cml0ZWIodmFsdWUsIGVidV9ob3N0 LT5jc1tjc19udW1dLmNoaXBhZGRyICsgb2Zmc2V0KTsKPiArCWVidV9uYW5kX3dhaXRyZHkoY2hp cCwgMTAwMCk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGVidV9yZWFkX2J1ZihzdHJ1Y3QgbmFu ZF9jaGlwICpjaGlwLCB1X2NoYXIgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikKPiArewo+ICsJaW50 IGk7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQo+ICsJCWJ1ZltpXSA9IGVidV9u YW5kX3JlYWRiKGNoaXApOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBlYnVfd3JpdGVfYnVmKHN0 cnVjdCBuYW5kX2NoaXAgKmNoaXAsIGNvbnN0IHVfY2hhciAqYnVmLCBpbnQgbGVuKQo+ICt7Cj4g KwlpbnQgaTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCj4gKwkJZWJ1X25hbmRf d3JpdGViKGNoaXAsIEhTTkFORF9DU19PRkZTLCBidWZbaV0pOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dm9pZCBlYnVfbmFuZF9kaXNhYmxlKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXApCj4gK3sKPiArCXN0 cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9zdCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJf ZGF0YShjaGlwKTsKPiArCj4gKwl3cml0ZWwoMCwgZWJ1X2hvc3QtPmVidSArIEVCVV9DT04pOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBlYnVfc2VsZWN0X2NoaXAoc3RydWN0IG5hbmRfY2hpcCAq Y2hpcCkKPiArewo+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0ID0gbmFu ZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+ICsJdm9pZCBfX2lvbWVtICpuYW5kX2NvbiA9 IGVidV9ob3N0LT5lYnUgKyBFQlVfQ09OOwo+ICsJdTMyIGNzID0gZWJ1X2hvc3QtPmNzX251bTsK PiArCj4gKwl3cml0ZWwoRUJVX0NPTl9OQU5ETV9FTiB8IEVCVV9DT05fQ1NNVVhfRV9FTiB8IEVC VV9DT05fQ1NfUF9MT1cgfAo+ICsJICAgICAgIEVCVV9DT05fU0VfUF9MT1cgfCBFQlVfQ09OX1dQ X1BfTE9XIHwgRUJVX0NPTl9QUkVfUF9MT1cgfAo+ICsJICAgICAgIEVCVV9DT05fSU5fQ1NfUyhj cykgfCBFQlVfQ09OX09VVF9DU19TKGNzKSB8Cj4gKwkgICAgICAgRUJVX0NPTl9MQVRfRU5fQ1Nf UCwgbmFuZF9jb24pOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBlYnVfbmFuZF9zZXR1cF90aW1p bmcoc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmN0cmwsCj4gKwkJCQkgIGNvbnN0IHN0cnVj dCBuYW5kX3Nkcl90aW1pbmdzICp0aW1pbmdzKQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgcmF0ZSA9 IGNsa19nZXRfcmF0ZShjdHJsLT5jbGspIC8gSFpfUEVSX01IWjsKPiArCXVuc2lnbmVkIGludCBw ZXJpb2QgPSBESVZfUk9VTkRfVVAoVVNFQ19QRVJfU0VDLCByYXRlKTsKPiArCXUzMiB0cmVjb3Ys IHRob2xkLCB0d3J3YWl0LCB0cmR3YWl0Owo+ICsJdTMyIHJlZyA9IDA7Cj4gKwo+ICsJdHJlY292 ID0gRElWX1JPVU5EX1VQKG1heCh0aW1pbmdzLT50UkVBX21heCwgdGltaW5ncy0+dFJFSF9taW4p LAo+ICsJCQkgICAgICBwZXJpb2QpOwo+ICsJcmVnIHw9IEVCVV9CVVNDT05fUkVDT1ZDKHRyZWNv dik7Cj4gKwo+ICsJdGhvbGQgPSBESVZfUk9VTkRfVVAobWF4KHRpbWluZ3MtPnRESF9taW4sIHRp bWluZ3MtPnREU19taW4pLCBwZXJpb2QpOwo+ICsJcmVnIHw9IEVCVV9CVVNDT05fSE9MREModGhv bGQpOwo+ICsKPiArCXRyZHdhaXQgPSBESVZfUk9VTkRfVVAobWF4KHRpbWluZ3MtPnRSQ19taW4s IHRpbWluZ3MtPnRSRUhfbWluKSwKPiArCQkJICAgICAgIHBlcmlvZCk7Cj4gKwlyZWcgfD0gRUJV X0JVU0NPTl9XQUlUUkRDKHRyZHdhaXQpOwo+ICsKPiArCXR3cndhaXQgPSBESVZfUk9VTkRfVVAo bWF4KHRpbWluZ3MtPnRXQ19taW4sIHRpbWluZ3MtPnRXSF9taW4pLCBwZXJpb2QpOwo+ICsJcmVn IHw9IEVCVV9CVVNDT05fV0FJVFdSQyh0d3J3YWl0KTsKPiArCj4gKwlyZWcgfD0gRUJVX0JVU0NP Tl9DTVVMVF9WNCB8IEVCVV9CVVNDT05fQkNHRU5fQ1MgfCBFQlVfQlVTQ09OX0FMRUMgfAo+ICsJ CUVCVV9CVVNDT05fU0VUVVBfRU47Cj4gKwo+ICsJd3JpdGVsKHJlZywgY3RybC0+ZWJ1ICsgRUJV X0JVU0NPTihjdHJsLT5jc19udW0pKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFuZF9z ZXRfdGltaW5ncyhzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCBpbnQgY3NsaW5lLAo+ICsJCQkJY29u c3Qgc3RydWN0IG5hbmRfaW50ZXJmYWNlX2NvbmZpZyAqY29uZikKPiArewo+ICsJc3RydWN0IGVi dV9uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX3RvX2VidShjaGlwKTsKPiArCWNvbnN0IHN0 cnVjdCBuYW5kX3Nkcl90aW1pbmdzICp0aW1pbmdzOwo+ICsKPiArCXRpbWluZ3MgPSBuYW5kX2dl dF9zZHJfdGltaW5ncyhjb25mKTsKPiArCWlmIChJU19FUlIodGltaW5ncykpCj4gKwkJcmV0dXJu IFBUUl9FUlIodGltaW5ncyk7Cj4gKwo+ICsJaWYgKGNzbGluZSA9PSBOQU5EX0RBVEFfSUZBQ0Vf Q0hFQ0tfT05MWSkKPiArCQlyZXR1cm4gMDsKPiArCj4gKwllYnVfbmFuZF9zZXR1cF90aW1pbmco Y3RybCwgdGltaW5ncyk7CgpJIGRvbid0IHRoaW5rIGFkZGluZyB0aGlzIGhlbHBlciBoZWxwcyBt dWNoLiBZb3UgY291bGQgaW5zZXJ0IHRoZSBjb2RlCmZyb20gdGhpcyBmdW5jdGlvbiBoZXJlIGRp cmVjdGx5PwoKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFu ZF9vb2JsYXlvdXRfZWNjKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQgc2VjdGlvbiwKPiArCQkJ CSAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4gK3sKPiArCXN0cnVjdCBuYW5k X2NoaXAgKmNoaXAgPSBtdGRfdG9fbmFuZChtdGQpOwo+ICsKPiArCWlmIChzZWN0aW9uKQo+ICsJ CXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gSFNOQU5EX0VDQ19P RkZTRVQ7Cj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9IGNoaXAtPmVjYy50b3RhbDsKPiArCj4gKwly ZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFuZF9vb2JsYXlvdXRfZnJlZShz dHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNlY3Rpb24sCj4gKwkJCQkgICBzdHJ1Y3QgbXRkX29v Yl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJc3RydWN0IG5hbmRfY2hpcCAqY2hpcCA9IG10 ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNlY3Rpb24pCj4gKwkJcmV0dXJuIC1FUkFOR0U7 Cj4gKwo+ICsJb29icmVnaW9uLT5vZmZzZXQgPSBjaGlwLT5lY2MudG90YWwgKyBIU05BTkRfRUND X09GRlNFVDsKPiArCW9vYnJlZ2lvbi0+bGVuZ3RoID0gbXRkLT5vb2JzaXplIC0gb29icmVnaW9u LT5vZmZzZXQ7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1 Y3QgbXRkX29vYmxheW91dF9vcHMgZWJ1X25hbmRfb29ibGF5b3V0X29wcyA9IHsKPiArCS5lY2Mg PSBlYnVfbmFuZF9vb2JsYXlvdXRfZWNjLAo+ICsJLmZyZWUgPSBlYnVfbmFuZF9vb2JsYXlvdXRf ZnJlZSwKPiArfTsKPiArCj4gK3N0YXRpYyB2b2lkIGVidV9kbWFfcnhfY2FsbGJhY2sodm9pZCAq Y29va2llKQo+ICt7Cj4gKwlzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxlciAqZWJ1X2hvc3QgPSBj b29raWU7Cj4gKwo+ICsJZG1hZW5naW5lX3Rlcm1pbmF0ZV9hc3luYyhlYnVfaG9zdC0+ZG1hX3J4 KTsKPiArCj4gKwljb21wbGV0ZSgmZWJ1X2hvc3QtPmRtYV9hY2Nlc3NfY29tcGxldGUpOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgdm9pZCBlYnVfZG1hX3R4X2NhbGxiYWNrKHZvaWQgKmNvb2tpZSkKPiAr ewo+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0ID0gY29va2llOwo+ICsK PiArCWRtYWVuZ2luZV90ZXJtaW5hdGVfYXN5bmMoZWJ1X2hvc3QtPmRtYV90eCk7Cj4gKwo+ICsJ Y29tcGxldGUoJmVidV9ob3N0LT5kbWFfYWNjZXNzX2NvbXBsZXRlKTsKClBsZWFzZSBjaGVjayBy ZXR1cm4gY29kZXMgd2hlbiB0aGV5IGFyZSByZWxldmFudCwgYW5kIHJldHVybiB0aGUKZXJyb3Jz LiBBbHNvIHRyZWF0IHRoZW0gYmVsb3cuCgo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGVidV9kbWFf c3RhcnQoc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0LCB1MzIgZGlyLAo+ICsJ CQkgY29uc3QgdTggKmJ1ZiwgdTMyIGxlbikKPiArewo+ICsJc3RydWN0IGRtYV9hc3luY190eF9k ZXNjcmlwdG9yICp0eDsKPiArCXN0cnVjdCBjb21wbGV0aW9uICpkbWFfY29tcGxldGlvbjsKPiAr CWRtYV9hc3luY190eF9jYWxsYmFjayBjYWxsYmFjazsKPiArCXN0cnVjdCBkbWFfY2hhbiAqY2hh bjsKPiArCWRtYV9jb29raWVfdCBjb29raWU7Cj4gKwl1bnNpZ25lZCBsb25nIGZsYWdzID0gRE1B X0NUUkxfQUNLIHwgRE1BX1BSRVBfSU5URVJSVVBUOwo+ICsJZG1hX2FkZHJfdCBidWZfZG1hOwo+ ICsJaW50IHJldDsKPiArCXUzMiB0aW1lb3V0Owo+ICsKPiArCWlmIChkaXIgPT0gRE1BX0RFVl9U T19NRU0pIHsKPiArCQljaGFuID0gZWJ1X2hvc3QtPmRtYV9yeDsKPiArCQlkbWFfY29tcGxldGlv biA9ICZlYnVfaG9zdC0+ZG1hX2FjY2Vzc19jb21wbGV0ZTsKPiArCQljYWxsYmFjayA9IGVidV9k bWFfcnhfY2FsbGJhY2s7Cj4gKwl9IGVsc2Ugewo+ICsJCWNoYW4gPSBlYnVfaG9zdC0+ZG1hX3R4 Owo+ICsJCWRtYV9jb21wbGV0aW9uID0gJmVidV9ob3N0LT5kbWFfYWNjZXNzX2NvbXBsZXRlOwo+ ICsJCWNhbGxiYWNrID0gZWJ1X2RtYV90eF9jYWxsYmFjazsKPiArCX0KPiArCj4gKwlidWZfZG1h ID0gZG1hX21hcF9zaW5nbGUoY2hhbi0+ZGV2aWNlLT5kZXYsICh2b2lkICopYnVmLCBsZW4sIGRp cik7Cj4gKwlpZiAoZG1hX21hcHBpbmdfZXJyb3IoY2hhbi0+ZGV2aWNlLT5kZXYsIGJ1Zl9kbWEp KSB7Cj4gKwkJZGV2X2VycihlYnVfaG9zdC0+ZGV2LCAiRmFpbGVkIHRvIG1hcCBETUEgYnVmZmVy XG4iKTsKPiArCQlyZXQgPSAtRUlPOwo+ICsJCWdvdG8gZXJyX3VubWFwOwo+ICsJfQo+ICsKPiAr CXR4ID0gZG1hZW5naW5lX3ByZXBfc2xhdmVfc2luZ2xlKGNoYW4sIGJ1Zl9kbWEsIGxlbiwgZGly LCBmbGFncyk7Cj4gKwlpZiAoIXR4KQo+ICsJCXJldHVybiAtRU5YSU87Cj4gKwo+ICsJdHgtPmNh bGxiYWNrID0gY2FsbGJhY2s7Cj4gKwl0eC0+Y2FsbGJhY2tfcGFyYW0gPSBlYnVfaG9zdDsKPiAr CWNvb2tpZSA9IHR4LT50eF9zdWJtaXQodHgpOwo+ICsKPiArCXJldCA9IGRtYV9zdWJtaXRfZXJy b3IoY29va2llKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGVidV9ob3N0LT5kZXYsICJk bWFfc3VibWl0X2Vycm9yICVkXG4iLCBjb29raWUpOwo+ICsJCXJldCA9IC1FSU87Cj4gKwkJZ290 byBlcnJfdW5tYXA7Cj4gKwl9Cj4gKwo+ICsJaW5pdF9jb21wbGV0aW9uKGRtYV9jb21wbGV0aW9u KTsKPiArCWRtYV9hc3luY19pc3N1ZV9wZW5kaW5nKGNoYW4pOwo+ICsKPiArCS8qIFdhaXQgRE1B IHRvIGZpbmlzaCB0aGUgZGF0YSB0cmFuc2Zlci4qLwo+ICsJdGltZW91dCA9IHdhaXRfZm9yX2Nv bXBsZXRpb25fdGltZW91dChkbWFfY29tcGxldGlvbiwgbXNlY3NfdG9famlmZmllcygxMDAwKSk7 Cj4gKwlpZiAoIXRpbWVvdXQpIHsKPiArCQlkZXZfZXJyKGVidV9ob3N0LT5kZXYsICJJL08gRXJy b3IgaW4gRE1BIFJYIChzdGF0dXMgJWQpXG4iLAo+ICsJCQlkbWFlbmdpbmVfdHhfc3RhdHVzKGNo YW4sIGNvb2tpZSwgTlVMTCkpOwo+ICsJCWRtYWVuZ2luZV90ZXJtaW5hdGVfc3luYyhjaGFuKTsK PiArCQlyZXQgPSAtRVRJTUVET1VUOwo+ICsJCWdvdG8gZXJyX3VubWFwOwo+ICsJfQo+ICsKPiAr CXJldHVybiAwOwo+ICsKPiArZXJyX3VubWFwOgo+ICsJZG1hX3VubWFwX3NpbmdsZShlYnVfaG9z dC0+ZGV2LCBidWZfZG1hLCBsZW4sIGRpcik7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgZWJ1X25hbmRfdHJpZ2dlcihzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxl ciAqZWJ1X2hvc3QsCj4gKwkJCSAgICAgaW50IHBhZ2UsIHUzMiBjbWQpCj4gK3sKPiArCXVuc2ln bmVkIGludCB2YWw7Cj4gKwo+ICsJdmFsID0gY21kIHwgKHBhZ2UgJiAweEZGKSA8PCBIU05BTkRf Q1RMMV9BRERSX1NISUZUOwo+ICsJd3JpdGVsKHZhbCwgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFO RF9DVEwxKTsKPiArCXZhbCA9IChwYWdlICYgMHhGRkZGMDApID4+IDggfCBIU05BTkRfQ1RMMl9D WUNfTl9WNTsKPiArCXdyaXRlbCh2YWwsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfQ1RMMik7 Cj4gKwo+ICsJd3JpdGVsKGVidV9ob3N0LT5uZF9wYXJhMCwgZWJ1X2hvc3QtPmhzbmFuZCArIEhT TkFORF9QQVJBMCk7Cj4gKwo+ICsJLyogY2xlYXIgZmlyc3QsIHdpbGwgdXBkYXRlIGxhdGVyICov Cj4gKwl3cml0ZWwoMHhGRkZGRkZGRiwgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DTVNHXzAp Owo+ICsJd3JpdGVsKDB4RkZGRkZGRkYsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfQ01TR18x KTsKPiArCj4gKwl3cml0ZWwoSFNOQU5EX0lOVF9NU0tfQ1RMX1dSX0MsCj4gKwkgICAgICAgZWJ1 X2hvc3QtPmhzbmFuZCArIEhTTkFORF9JTlRfTVNLX0NUTCk7Cj4gKwo+ICsJaWYgKCFjbWQpCj4g KwkJdmFsID0gSFNOQU5EX0NUTF9SV19SRUFEOwo+ICsJZWxzZQo+ICsJCXZhbCA9IEhTTkFORF9D VExfUldfV1JJVEU7Cj4gKwo+ICsJd3JpdGVsKEhTTkFORF9DVExfTVNHX0VOIHwgSFNOQU5EX0NU TF9DS0ZGX0VOIHwKPiArCSAgICAgICBIU05BTkRfQ1RMX0VDQ19PRkZfVjhUSCB8IEhTTkFORF9D VExfQ0VfU0VMX0NTKGVidV9ob3N0LT5jc19udW0pIHwKPiArCSAgICAgICBIU05BTkRfQ1RMX0VO QUJMRV9FQ0MgfCBIU05BTkRfQ1RMX0dPIHwgdmFsLAo+ICsJICAgICAgIGVidV9ob3N0LT5oc25h bmQgKyBIU05BTkRfQ1RMKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFuZF9yZWFkX3Bh Z2VfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgdTggKmJ1ZiwKPiArCQkJCSAgICBpbnQg b29iX3JlcXVpcmVkLCBpbnQgcGFnZSkKPiArewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBu YW5kX3RvX210ZChjaGlwKTsKPiArCXN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9z dCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShjaGlwKTsKPiArCWludCByZXQsIHJlZ19kYXRh Owo+ICsKPiArCWVidV9uYW5kX3RyaWdnZXIoZWJ1X2hvc3QsIHBhZ2UsIE5BTkRfQ01EX1JFQUQw KTsKPiArCj4gKwlyZXQgPSBlYnVfZG1hX3N0YXJ0KGVidV9ob3N0LCBETUFfREVWX1RPX01FTSwg YnVmLCBtdGQtPndyaXRlc2l6ZSk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ ICsJaWYgKG9vYl9yZXF1aXJlZCkKPiArCQljaGlwLT5lY2MucmVhZF9vb2IoY2hpcCwgcGFnZSk7 Cj4gKwo+ICsJcmVnX2RhdGEgPSByZWFkbChlYnVfaG9zdC0+aHNuYW5kICsgSFNOQU5EX0NUTCk7 Cj4gKwlyZWdfZGF0YSAmPSB+SFNOQU5EX0NUTF9HTzsKPiArCXdyaXRlbChyZWdfZGF0YSwgZWJ1 X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DVEwpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ ICtzdGF0aWMgaW50IGVidV9uYW5kX3dyaXRlX3BhZ2VfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAq Y2hpcCwgY29uc3QgdTggKmJ1ZiwKPiArCQkJCSAgICAgaW50IG9vYl9yZXF1aXJlZCwgaW50IHBh Z2UpCj4gK3sKPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4g KwlzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxlciAqZWJ1X2hvc3QgPSBuYW5kX2dldF9jb250cm9s bGVyX2RhdGEoY2hpcCk7Cj4gKwl2b2lkIF9faW9tZW0gKmludF9zdGEgPSBlYnVfaG9zdC0+aHNu YW5kICsgSFNOQU5EX0lOVF9TVEE7Cj4gKwlpbnQgcmVnX2RhdGEsIHJldCwgdmFsOwo+ICsJdTMy IHJlZzsKPiArCj4gKwllYnVfbmFuZF90cmlnZ2VyKGVidV9ob3N0LCBwYWdlLCBOQU5EX0NNRF9T RVFJTik7Cj4gKwo+ICsJcmV0ID0gZWJ1X2RtYV9zdGFydChlYnVfaG9zdCwgRE1BX01FTV9UT19E RVYsIGJ1ZiwgbXRkLT53cml0ZXNpemUpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ ICsKPiArCWlmIChvb2JfcmVxdWlyZWQpIHsKPiArCQlyZWcgPSBnZXRfdW5hbGlnbmVkX2xlMzIo Y2hpcC0+b29iX3BvaSk7Cj4gKwkJd3JpdGVsKHJlZywgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFO RF9DTVNHXzApOwo+ICsKPiArCQlyZWcgPSBnZXRfdW5hbGlnbmVkX2xlMzIoY2hpcC0+b29iX3Bv aSArIDQpOwo+ICsJCXdyaXRlbChyZWcsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfQ01TR18x KTsKPiArCX0KPiArCj4gKwlyZXQgPSByZWFkbF9wb2xsX3RpbWVvdXRfYXRvbWljKGludF9zdGEs IHZhbCwgISh2YWwgJiBIU05BTkRfSU5UX1NUQV9XUl9DKSwKPiArCQkJCQkxMCwgMTAwMCk7Cj4g KwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmVnX2RhdGEgPSByZWFkbChlYnVf aG9zdC0+aHNuYW5kICsgSFNOQU5EX0NUTCk7Cj4gKwlyZWdfZGF0YSAmPSB+SFNOQU5EX0NUTF9H TzsKPiArCXdyaXRlbChyZWdfZGF0YSwgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DVEwpOwo+ ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3QgdTggZWNjX3N0cmVuZ3Ro W10gPSB7IDEsIDEsIDQsIDgsIDI0LCAzMiwgNDAsIDYwLCB9Owo+ICsKPiArc3RhdGljIGludCBl YnVfbmFuZF9hdHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlzdHJ1 Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKGNoaXApOwo+ICsJc3RydWN0IGVidV9uYW5k X2NvbnRyb2xsZXIgKmVidV9ob3N0ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+ ICsJdTMyIGVjY19zdGVwcywgZWNjX2J5dGVzLCBlY2NfdG90YWwsIHBhZ2VzaXplLCBwZ19wZXJf YmxrOwo+ICsJdTMyIGVjY19zdHJlbmd0aF9kcyA9IGNoaXAtPmVjYy5zdHJlbmd0aDsKPiArCXUz MiBlY2Nfc2l6ZSA9IGNoaXAtPmVjYy5zaXplOwo+ICsJdTMyIHdyaXRlc2l6ZSA9IG10ZC0+d3Jp dGVzaXplOwo+ICsJdTMyIGJsb2Nrc2l6ZSA9IG10ZC0+ZXJhc2VzaXplOwo+ICsJaW50IGJjaF9h bGdvLCBzdGFydCwgdmFsOwo+ICsKPiArCS8qIERlZmF1bHQgdG8gYW4gRUNDIHNpemUgb2YgNTEy ICovCj4gKwlpZiAoIWNoaXAtPmVjYy5zaXplKQo+ICsJCWNoaXAtPmVjYy5zaXplID0gNTEyOwo+ ICsKPiArCXN3aXRjaCAoZWNjX3NpemUpIHsKPiArCWNhc2UgNTEyOgo+ICsJCXN0YXJ0ID0gMTsK PiArCQlpZiAoIWVjY19zdHJlbmd0aF9kcykKPiArCQkJZWNjX3N0cmVuZ3RoX2RzID0gNDsKPiAr CQlicmVhazsKPiArCWNhc2UgMTAyNDoKPiArCQlzdGFydCA9IDQ7Cj4gKwkJaWYgKCFlY2Nfc3Ry ZW5ndGhfZHMpCj4gKwkJCWVjY19zdHJlbmd0aF9kcyA9IDMyOwo+ICsJCWJyZWFrOwo+ICsJZGVm YXVsdDoKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCj4gKwkvKiBCQ0ggRUNDIGFsZ29y aXRobSBTZXR0aW5ncyBmb3IgbnVtYmVyIG9mIGJpdHMgcGVyIDUxMkIvMTAyNEIgKi8KPiArCWJj aF9hbGdvID0gcm91bmRfdXAoc3RhcnQgKyAxLCA0KTsKPiArCWZvciAodmFsID0gc3RhcnQ7IHZh bCA8IGJjaF9hbGdvOyB2YWwrKykgewo+ICsJCWlmIChlY2Nfc3RyZW5ndGhfZHMgPT0gZWNjX3N0 cmVuZ3RoW3ZhbF0pCj4gKwkJCWJyZWFrOwo+ICsJfQo+ICsJaWYgKHZhbCA9PSBiY2hfYWxnbykK PiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoZWNjX3N0cmVuZ3RoX2RzID09IDgpCj4g KwkJZWNjX2J5dGVzID0gMTQ7Cj4gKwllbHNlCj4gKwkJZWNjX2J5dGVzID0gRElWX1JPVU5EX1VQ KGVjY19zdHJlbmd0aF9kcyAqIGZscyg4ICogZWNjX3NpemUpLCA4KTsKPiArCj4gKwllY2Nfc3Rl cHMgPSB3cml0ZXNpemUgLyBlY2Nfc2l6ZTsKPiArCWVjY190b3RhbCA9IGVjY19zdGVwcyAqIGVj Y19ieXRlczsKPiArCWlmICgoZWNjX3RvdGFsICsgOCkgPiBtdGQtPm9vYnNpemUpCj4gKwkJcmV0 dXJuIC1FUkFOR0U7Cj4gKwo+ICsJY2hpcC0+ZWNjLnRvdGFsID0gZWNjX3RvdGFsOwo+ICsJcGFn ZXNpemUgPSBmbHMod3JpdGVzaXplID4+IDExKTsKPiArCWlmIChwYWdlc2l6ZSA+IEhTTkFORF9Q QVJBMF9QQUdFX1Y4MTkyKQo+ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCXBnX3Blcl9ibGsg PSBmbHMoKGJsb2Nrc2l6ZSAvIHdyaXRlc2l6ZSkgPj4gNikgLyA4Owo+ICsJaWYgKHBnX3Blcl9i bGsgPiBIU05BTkRfUEFSQTBfUElCX1YyNTYpCj4gKwkJcmV0dXJuIC1FUkFOR0U7Cj4gKwo+ICsJ ZWJ1X2hvc3QtPm5kX3BhcmEwID0gcGFnZXNpemUgfCBwZ19wZXJfYmxrIHwgSFNOQU5EX1BBUkEw X0JZUF9FTl9OUCB8Cj4gKwkJCSAgICAgSFNOQU5EX1BBUkEwX0JZUF9ERUNfTlAgfCBIU05BTkRf UEFSQTBfQURFUF9FTiB8Cj4gKwkJCSAgICAgSFNOQU5EX1BBUkEwX1RZUEVfT05GSSB8ICh2YWwg PDwgMjkpOwo+ICsKPiArCW10ZF9zZXRfb29ibGF5b3V0KG10ZCwgJmVidV9uYW5kX29vYmxheW91 dF9vcHMpOwo+ICsJY2hpcC0+ZWNjLnJlYWRfcGFnZSA9IGVidV9uYW5kX3JlYWRfcGFnZV9od2Vj YzsKPiArCWNoaXAtPmVjYy53cml0ZV9wYWdlID0gZWJ1X25hbmRfd3JpdGVfcGFnZV9od2VjYzsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFuZF9leGVjX29w KHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsCj4gKwkJCSAgICBjb25zdCBzdHJ1Y3QgbmFuZF9vcGVy YXRpb24gKm9wLCBib29sIGNoZWNrX29ubHkpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBuYW5kX29w X2luc3RyICppbnN0ciA9IE5VTEw7Cj4gKwl1bnNpZ25lZCBpbnQgb3BfaWQ7Cj4gKwlpbnQgaSwg dGltZV9vdXQsIHJldCA9IDA7Cj4gKwo+ICsJaWYgKGNoZWNrX29ubHkpCj4gKwkJcmV0dXJuIDA7 Cj4gKwo+ICsJZWJ1X3NlbGVjdF9jaGlwKGNoaXApOwo+ICsJZm9yIChvcF9pZCA9IDA7IG9wX2lk IDwgb3AtPm5pbnN0cnM7IG9wX2lkKyspIHsKPiArCQlpbnN0ciA9ICZvcC0+aW5zdHJzW29wX2lk XTsKPiArCj4gKwkJc3dpdGNoIChpbnN0ci0+dHlwZSkgewo+ICsJCWNhc2UgTkFORF9PUF9DTURf SU5TVFI6Cj4gKwkJCWVidV9uYW5kX3dyaXRlYihjaGlwLCBIU05BTkRfQ0xFX09GRlMgfCBIU05B TkRfQ1NfT0ZGUywKPiArCQkJCQlpbnN0ci0+Y3R4LmNtZC5vcGNvZGUpOwo+ICsJCQlicmVhazsK PiArCj4gKwkJY2FzZSBOQU5EX09QX0FERFJfSU5TVFI6Cj4gKwkJCWZvciAoaSA9IDA7IGkgPCBp bnN0ci0+Y3R4LmFkZHIubmFkZHJzOyBpKyspCj4gKwkJCQllYnVfbmFuZF93cml0ZWIoY2hpcCwK PiArCQkJCQkJSFNOQU5EX0FMRV9PRkZTIHwgSFNOQU5EX0NTX09GRlMsCj4gKwkJCQkJCWluc3Ry LT5jdHguYWRkci5hZGRyc1tpXSk7Cj4gKwkJCWJyZWFrOwo+ICsKPiArCQljYXNlIE5BTkRfT1Bf REFUQV9JTl9JTlNUUjoKPiArCQkJZWJ1X3JlYWRfYnVmKGNoaXAsIGluc3RyLT5jdHguZGF0YS5i dWYuaW4sCj4gKwkJCQkgICAgIGluc3RyLT5jdHguZGF0YS5sZW4pOwo+ICsJCQlicmVhazsKPiAr Cj4gKwkJY2FzZSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSOgo+ICsJCQllYnVfd3JpdGVfYnVmKGNo aXAsIGluc3RyLT5jdHguZGF0YS5idWYub3V0LAo+ICsJCQkJICAgICAgaW5zdHItPmN0eC5kYXRh Lmxlbik7Cj4gKwkJCWJyZWFrOwo+ICsKPiArCQljYXNlIE5BTkRfT1BfV0FJVFJEWV9JTlNUUjoK PiArCQkJdGltZV9vdXQgPSBpbnN0ci0+Y3R4LndhaXRyZHkudGltZW91dF9tcyAqIDEwMDA7Cj4g KwkJCXJldCA9IGVidV9uYW5kX3dhaXRyZHkoY2hpcCwgdGltZV9vdXQpOwo+ICsJCQlicmVhazsK PiArCQl9Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBuYW5kX2NvbnRyb2xsZXJfb3BzIGVidV9uYW5kX2NvbnRyb2xsZXJfb3BzID0gewo+ ICsJLmF0dGFjaF9jaGlwID0gZWJ1X25hbmRfYXR0YWNoX2NoaXAsCj4gKwkuc2V0dXBfaW50ZXJm YWNlID0gZWJ1X25hbmRfc2V0X3RpbWluZ3MsCj4gKwkuZXhlY19vcCA9IGVidV9uYW5kX2V4ZWNf b3AsCj4gK307Cj4gKwo+ICtzdGF0aWMgdm9pZCBlYnVfZG1hX2NsZWFudXAoc3RydWN0IGVidV9u YW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0KQo+ICt7Cj4gKwlpZiAoZWJ1X2hvc3QtPmRtYV9yeCkK PiArCQlkbWFfcmVsZWFzZV9jaGFubmVsKGVidV9ob3N0LT5kbWFfcngpOwo+ICsKPiArCWlmIChl YnVfaG9zdC0+ZG1hX3R4KQo+ICsJCWRtYV9yZWxlYXNlX2NoYW5uZWwoZWJ1X2hvc3QtPmRtYV90 eCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZWJ1X25hbmRfcHJvYmUoc3RydWN0IHBsYXRmb3Jt X2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsK PiArCXN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9zdDsKPiArCXN0cnVjdCBuYW5k X2NoaXAgKm5hbmQ7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZDsKPiArCXN0cnVjdCByZXNvdXJj ZSAqcmVzOwo+ICsJY2hhciAqcmVzbmFtZTsKPiArCWludCByZXQsIGk7Cj4gKwl1MzIgcmVnOwo+ ICsKPiArCWVidV9ob3N0ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCplYnVfaG9zdCksIEdG UF9LRVJORUwpOwo+ICsJaWYgKCFlYnVfaG9zdCkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4g KwllYnVfaG9zdC0+ZGV2ID0gZGV2Owo+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJmVidV9ob3N0 LT5jb250cm9sbGVyKTsKPiArCj4gKwlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2VfYnluYW1l KHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAiZWJ1bmFuZCIpOwo+ICsJZWJ1X2hvc3QtPmVidSA9IGRl dm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOwo+ICsJaWYgKElTX0VSUihlYnVf aG9zdC0+ZWJ1KSkKPiArCQlyZXR1cm4gUFRSX0VSUihlYnVfaG9zdC0+ZWJ1KTsKPiArCj4gKwly ZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2VfYnluYW1lKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAi aHNuYW5kIik7Cj4gKwllYnVfaG9zdC0+aHNuYW5kID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZw ZGV2LT5kZXYsIHJlcyk7Cj4gKwlpZiAoSVNfRVJSKGVidV9ob3N0LT5oc25hbmQpKQo+ICsJCXJl dHVybiBQVFJfRVJSKGVidV9ob3N0LT5oc25hbmQpOwo+ICsKPiArCXJldCA9IGRldmljZV9wcm9w ZXJ0eV9yZWFkX3UzMihkZXYsICJuYW5kLGNzIiwgJnJlZyk7CgpUaGVyZSBpcyBubyBuYW5kLGNz IHByb3BlcnR5LiBVc2UgJ3JlZycgaW5zdGVhZC4KCj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2Vy cihkZXYsICJmYWlsZWQgdG8gZ2V0IGNoaXAgc2VsZWN0OiAlZFxuIiwgcmV0KTsKPiArCQlyZXR1 cm4gcmV0Owo+ICsJfQo+ICsJZWJ1X2hvc3QtPmNzX251bSA9IHJlZzsKClRoZSBmb2xsb3dpbmcg Zm9yIGxvb3AgaXMgd2VpcmQsIGFib3ZlIHlvdSBjYW4gb25seSBzdG9yZSBhIHNpbmdsZSBjcwpu dW1iZXIsIHdoaWxlIGJlbG93IHlvdSBzZWVtIHRvIHJlc2VydmUgc2VydmVyYWwgbWVtb3J5IGFy ZWFzLiBQbGVhc2UKY2xhcmlmeSB0aGlzIGNvZGUuCgo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBN QVhfQ1M7IGkrKykgewo+ICsJCXJlc25hbWUgPSBkZXZtX2thc3ByaW50ZihkZXYsIEdGUF9LRVJO RUwsICJuYW5kX2NzJWQiLCBpKTsKPiArCQlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2VfYnlu YW1lKHBkZXYsIElPUkVTT1VSQ0VfTUVNLAo+ICsJCQkJCQkgICByZXNuYW1lKTsKPiArCQllYnVf aG9zdC0+Y3NbaV0uY2hpcGFkZHIgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCByZXMpOwo+ ICsJCWVidV9ob3N0LT5jc1tpXS5uYW5kX3BhID0gcmVzLT5zdGFydDsKPiArCQlpZiAoSVNfRVJS KGVidV9ob3N0LT5jc1tpXS5jaGlwYWRkcikpCj4gKwkJCXJldHVybiBQVFJfRVJSKGVidV9ob3N0 LT5jc1tpXS5jaGlwYWRkcik7Cj4gKwl9Cj4gKwo+ICsJZWJ1X2hvc3QtPmNsayA9IGRldm1fY2xr X2dldChkZXYsIE5VTEwpOwo+ICsJaWYgKElTX0VSUihlYnVfaG9zdC0+Y2xrKSkKPiArCQlyZXR1 cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBUUl9FUlIoZWJ1X2hvc3QtPmNsayksCj4gKwkJCQkgICAg ICJmYWlsZWQgdG8gZ2V0IGNsb2NrXG4iKTsKPiArCj4gKwlyZXQgPSBjbGtfcHJlcGFyZV9lbmFi bGUoZWJ1X2hvc3QtPmNsayk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2VycihkZXYsICJmYWls ZWQgdG8gZW5hYmxlIGNsb2NrOiAlZFxuIiwgcmV0KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ ICsJZWJ1X2hvc3QtPmNsa19yYXRlID0gY2xrX2dldF9yYXRlKGVidV9ob3N0LT5jbGspOwo+ICsK PiArCWVidV9ob3N0LT5kbWFfdHggPSBkbWFfcmVxdWVzdF9jaGFuKGRldiwgInR4Iik7Cj4gKwlp ZiAoSVNfRVJSKGVidV9ob3N0LT5kbWFfdHgpKQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRl diwgUFRSX0VSUihlYnVfaG9zdC0+ZG1hX3R4KSwKPiArCQkJCSAgICAgImZhaWxlZCB0byByZXF1 ZXN0IERNQSB0eCBjaGFuIS5cbiIpOwo+ICsKPiArCWVidV9ob3N0LT5kbWFfcnggPSBkbWFfcmVx dWVzdF9jaGFuKGRldiwgInJ4Iik7Cj4gKwlpZiAoSVNfRVJSKGVidV9ob3N0LT5kbWFfcngpKQo+ ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgUFRSX0VSUihlYnVfaG9zdC0+ZG1hX3J4KSwK PiArCQkJCSAgICAgImZhaWxlZCB0byByZXF1ZXN0IERNQSByeCBjaGFuIS5cbiIpOwo+ICsKPiAr CWZvciAoaSA9IDA7IGkgPCBNQVhfQ1M7IGkrKykgewo+ICsJCXJlc25hbWUgPSBkZXZtX2thc3By aW50ZihkZXYsIEdGUF9LRVJORUwsICJhZGRyX3NlbCVkIiwgaSk7Cj4gKwkJcmVzID0gcGxhdGZv cm1fZ2V0X3Jlc291cmNlX2J5bmFtZShwZGV2LCBJT1JFU09VUkNFX01FTSwKPiArCQkJCQkJICAg cmVzbmFtZSk7Cj4gKwkJaWYgKCFyZXMpCj4gKwkJCXJldHVybiAtRUlOVkFMOwo+ICsJCWVidV9o b3N0LT5jc1tpXS5hZGRyX3NlbCA9IHJlcy0+c3RhcnQ7Cj4gKwkJd3JpdGVsKGVidV9ob3N0LT5j c1tpXS5hZGRyX3NlbCB8IEVCVV9BRERSX01BU0soNSkgfAo+ICsJCSAgICAgICBFQlVfQUREUl9T RUxfUkVHRU4sIGVidV9ob3N0LT5lYnUgKyBFQlVfQUREUl9TRUwoaSkpOwo+ICsJfQo+ICsKPiAr CW5hbmRfc2V0X2ZsYXNoX25vZGUoJmVidV9ob3N0LT5jaGlwLCBkZXYtPm9mX25vZGUpOwo+ICsJ aWYgKCFtdGQtPm5hbWUpIHsKPiArCQlkZXZfZXJyKGVidV9ob3N0LT5kZXYsICJOQU5EIGxhYmVs IHByb3BlcnR5IGlzIG1hbmRhdG9yeVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4g Kwo+ICsJbXRkID0gbmFuZF90b19tdGQoJmVidV9ob3N0LT5jaGlwKTsKPiArCW10ZC0+ZGV2LnBh cmVudCA9IGRldjsKPiArCWVidV9ob3N0LT5kZXYgPSBkZXY7Cj4gKwo+ICsJcGxhdGZvcm1fc2V0 X2RydmRhdGEocGRldiwgZWJ1X2hvc3QpOwo+ICsJbmFuZF9zZXRfY29udHJvbGxlcl9kYXRhKCZl YnVfaG9zdC0+Y2hpcCwgZWJ1X2hvc3QpOwo+ICsKPiArCW5hbmQgPSAmZWJ1X2hvc3QtPmNoaXA7 Cj4gKwluYW5kLT5jb250cm9sbGVyID0gJmVidV9ob3N0LT5jb250cm9sbGVyOwo+ICsJbmFuZC0+ Y29udHJvbGxlci0+b3BzID0gJmVidV9uYW5kX2NvbnRyb2xsZXJfb3BzOwo+ICsKPiArCS8qIFNj YW4gdG8gZmluZCBleGlzdGVuY2Ugb2YgdGhlIGRldmljZSAqLwo+ICsJcmV0ID0gbmFuZF9zY2Fu KCZlYnVfaG9zdC0+Y2hpcCwgMSk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gZXJyX2NsZWFudXBf ZG1hOwo+ICsKPiArCXJldCA9IG10ZF9kZXZpY2VfcmVnaXN0ZXIobXRkLCBOVUxMLCAwKTsKPiAr CWlmIChyZXQpCj4gKwkJZ290byBlcnJfY2xlYW5fbmFuZDsKPiArCj4gKwlyZXR1cm4gMDsKPiAr Cj4gK2Vycl9jbGVhbl9uYW5kOgo+ICsJbmFuZF9jbGVhbnVwKCZlYnVfaG9zdC0+Y2hpcCk7Cj4g K2Vycl9jbGVhbnVwX2RtYToKPiArCWVidV9kbWFfY2xlYW51cChlYnVfaG9zdCk7Cj4gKwljbGtf ZGlzYWJsZV91bnByZXBhcmUoZWJ1X2hvc3QtPmNsayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiAr fQo+ICsKPiArc3RhdGljIGludCBlYnVfbmFuZF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikKPiArewo+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0ID0g cGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IG10 ZF9kZXZpY2VfdW5yZWdpc3RlcihuYW5kX3RvX210ZCgmZWJ1X2hvc3QtPmNoaXApKTsKPiArCVdB Uk5fT04ocmV0KTsKPiArCW5hbmRfY2xlYW51cCgmZWJ1X2hvc3QtPmNoaXApOwo+ICsJZWJ1X25h bmRfZGlzYWJsZSgmZWJ1X2hvc3QtPmNoaXApOwo+ICsJZWJ1X2RtYV9jbGVhbnVwKGVidV9ob3N0 KTsKPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShlYnVfaG9zdC0+Y2xrKTsKPiArCj4gKwlyZXR1 cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgZWJ1X25h bmRfbWF0Y2hbXSA9IHsKPiArCXsgLmNvbXBhdGlibGUgPSAiaW50ZWwsbmFuZC1jb250cm9sbGVy IiwgfSwKCk5vIHZlcnNpb24gb3Igc29jIGluIHRoZSBjb21wYXRpYmxlPyAobm90IG1hbmRhdG9y eSkuCgo+ICsJe30KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgZWJ1X25hbmRfbWF0 Y2gpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgZWJ1X25hbmRfZHJpdmVy ID0gewo+ICsJLnByb2JlID0gZWJ1X25hbmRfcHJvYmUsCj4gKwkucmVtb3ZlID0gZWJ1X25hbmRf cmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsKPiArCQkubmFtZSA9ICJpbnRlbC1uYW5kLWNvbnRyb2xs ZXIiLAo+ICsJCS5vZl9tYXRjaF90YWJsZSA9IGVidV9uYW5kX21hdGNoLAo+ICsJfSwKPiArCj4g K307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoZWJ1X25hbmRfZHJpdmVyKTsKPiArCj4gK01P RFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPiArTU9EVUxFX0FVVEhPUigiVmFkaXZlbCBNdXJ1Z2Fu IFIgPHZhZGl2ZWwubXVydWdhbngucmFtdXRoZXZhckBpbnRlbC5jb20+Iik7Cj4gK01PRFVMRV9E RVNDUklQVElPTigiSW50ZWwncyBMR00gRXh0ZXJuYWwgQnVzIE5BTkQgQ29udHJvbGxlciBkcml2 ZXIiKTsKClRoYW5rcywKTWlxdcOobAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fCkxpbnV4IE1URCBkaXNjdXNzaW9uIG1haWxpbmcgbGlzdApo dHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LW10ZC8K 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=-11.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,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 EE572C4363A for ; Thu, 29 Oct 2020 02:44:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 917E22076B for ; Thu, 29 Oct 2020 02:44:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726636AbgJ1Vel convert rfc822-to-8bit (ORCPT ); Wed, 28 Oct 2020 17:34:41 -0400 Received: from mslow2.mail.gandi.net ([217.70.178.242]:33230 "EHLO mslow2.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726627AbgJ1Vek (ORCPT ); Wed, 28 Oct 2020 17:34:40 -0400 Received: from relay6-d.mail.gandi.net (unknown [217.70.183.198]) by mslow2.mail.gandi.net (Postfix) with ESMTP id 54A663AB045; Wed, 28 Oct 2020 10:21:02 +0000 (UTC) X-Originating-IP: 91.224.148.103 Received: from xps13 (unknown [91.224.148.103]) (Authenticated sender: miquel.raynal@bootlin.com) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id F022DC000B; Wed, 28 Oct 2020 10:20:38 +0000 (UTC) Date: Wed, 28 Oct 2020 11:20:37 +0100 From: Miquel Raynal To: "Ramuthevar,Vadivel MuruganX" Cc: vigneshr@ti.com, tudor.ambarus@microchip.com, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, robh+dt@kernel.org, boris.brezillon@collabora.com, devicetree@vger.kernel.org, simon.k.r.goldschmidt@gmail.com, dinguyen@kernel.org, richard@nod.at, cheol.yong.kim@intel.com, qi-ming.wu@intel.com Subject: Re: [RESENDPATCH v15 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC Message-ID: <20201028112037.326c06e2@xps13> In-Reply-To: <20201026073021.33327-3-vadivel.muruganx.ramuthevar@linux.intel.com> References: <20201026073021.33327-1-vadivel.muruganx.ramuthevar@linux.intel.com> <20201026073021.33327-3-vadivel.muruganx.ramuthevar@linux.intel.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.4 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Hello, "Ramuthevar,Vadivel MuruganX" wrote on Mon, 26 Oct 2020 15:30:21 +0800: > From: Ramuthevar Vadivel Murugan > > This patch adds the new IP of Nand Flash Controller(NFC) support > on Intel's Lightning Mountain(LGM) SoC. > > DMA is used for burst data transfer operation, also DMA HW supports > aligned 32bit memory address and aligned data access by default. > DMA burst of 8 supported. Data register used to support the read/write > operation from/to device. > > NAND controller driver implements ->exec_op() to replace legacy hooks, > these specific call-back method to execute NAND operations. No need to mention legacy hooks here as they are not part of your driver at all. > > Signed-off-by: Ramuthevar Vadivel Murugan > --- > drivers/mtd/nand/raw/Kconfig | 8 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/intel-nand-controller.c | 734 +++++++++++++++++++++++++++ > 3 files changed, 743 insertions(+) > create mode 100644 drivers/mtd/nand/raw/intel-nand-controller.c > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index 6c46f25b57e2..1b3690fd08dc 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -462,6 +462,14 @@ config MTD_NAND_ARASAN > Enables the driver for the Arasan NAND flash controller on > Zynq Ultrascale+ MPSoC. > > +config MTD_NAND_INTEL_LGM > + tristate "Support for NAND controller on Intel LGM SoC" > + depends on OF || COMPILE_TEST > + depends on HAS_IOMEM > + help > + Enables support for NAND Flash chips on Intel's LGM SoC. > + NAND flash controller interfaced through the External Bus Unit. > + > comment "Misc" > > config MTD_SM_COMMON > diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile > index 2930f5b9015d..9e6037363fc6 100644 > --- a/drivers/mtd/nand/raw/Makefile > +++ b/drivers/mtd/nand/raw/Makefile > @@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o > obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o > obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o > obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o > +obj-$(CONFIG_MTD_NAND_INTEL_LGM) += intel-nand-controller.o > > nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o > nand-objs += nand_onfi.o > diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c > new file mode 100644 > index 000000000000..0aefc441c7d5 > --- /dev/null > +++ b/drivers/mtd/nand/raw/intel-nand-controller.c > @@ -0,0 +1,734 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* Copyright (c) 2020 Intel Corporation. */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#define EBU_CLC 0x000 > +#define EBU_CLC_RST 0x00000000u > + > +#define EBU_ADDR_SEL(n) (0x020 + (n) * 4) > +/* 5 bits 26:22 included for comparison in the ADDR_SELx */ > +#define EBU_ADDR_MASK(x) ((x) << 4) > +#define EBU_ADDR_SEL_REGEN 0x1 > + > +#define EBU_BUSCON(n) (0x060 + (n) * 4) > +#define EBU_BUSCON_CMULT_V4 0x1 > +#define EBU_BUSCON_RECOVC(n) ((n) << 2) > +#define EBU_BUSCON_HOLDC(n) ((n) << 4) > +#define EBU_BUSCON_WAITRDC(n) ((n) << 6) > +#define EBU_BUSCON_WAITWRC(n) ((n) << 8) > +#define EBU_BUSCON_BCGEN_CS 0x0 > +#define EBU_BUSCON_SETUP_EN BIT(22) > +#define EBU_BUSCON_ALEC 0xC000 > + > +#define EBU_CON 0x0B0 > +#define EBU_CON_NANDM_EN BIT(0) > +#define EBU_CON_NANDM_DIS 0x0 > +#define EBU_CON_CSMUX_E_EN BIT(1) > +#define EBU_CON_ALE_P_LOW BIT(2) > +#define EBU_CON_CLE_P_LOW BIT(3) > +#define EBU_CON_CS_P_LOW BIT(4) > +#define EBU_CON_SE_P_LOW BIT(5) > +#define EBU_CON_WP_P_LOW BIT(6) > +#define EBU_CON_PRE_P_LOW BIT(7) > +#define EBU_CON_IN_CS_S(n) ((n) << 8) > +#define EBU_CON_OUT_CS_S(n) ((n) << 10) > +#define EBU_CON_LAT_EN_CS_P ((0x3D) << 18) > + > +#define EBU_WAIT 0x0B4 > +#define EBU_WAIT_RDBY BIT(0) > +#define EBU_WAIT_WR_C BIT(3) > + > +#define HSNAND_CTL1 0x110 > +#define HSNAND_CTL1_ADDR_SHIFT 24 > + > +#define HSNAND_CTL2 0x114 > +#define HSNAND_CTL2_ADDR_SHIFT 8 > +#define HSNAND_CTL2_CYC_N_V5 (0x2 << 16) > + > +#define HSNAND_INT_MSK_CTL 0x124 > +#define HSNAND_INT_MSK_CTL_WR_C BIT(4) > + > +#define HSNAND_INT_STA 0x128 > +#define HSNAND_INT_STA_WR_C BIT(4) > + > +#define HSNAND_CTL 0x130 > +#define HSNAND_CTL_ENABLE_ECC BIT(0) > +#define HSNAND_CTL_GO BIT(2) > +#define HSNAND_CTL_CE_SEL_CS(n) BIT(3 + (n)) > +#define HSNAND_CTL_RW_READ 0x0 > +#define HSNAND_CTL_RW_WRITE BIT(10) > +#define HSNAND_CTL_ECC_OFF_V8TH BIT(11) > +#define HSNAND_CTL_CKFF_EN 0x0 > +#define HSNAND_CTL_MSG_EN BIT(17) > + > +#define HSNAND_PARA0 0x13c > +#define HSNAND_PARA0_PAGE_V8192 0x3 > +#define HSNAND_PARA0_PIB_V256 (0x3 << 4) > +#define HSNAND_PARA0_BYP_EN_NP 0x0 > +#define HSNAND_PARA0_BYP_DEC_NP 0x0 > +#define HSNAND_PARA0_TYPE_ONFI BIT(18) > +#define HSNAND_PARA0_ADEP_EN BIT(21) > + > +#define HSNAND_CMSG_0 0x150 > +#define HSNAND_CMSG_1 0x154 > + > +#define HSNAND_ALE_OFFS BIT(2) > +#define HSNAND_CLE_OFFS BIT(3) > +#define HSNAND_CS_OFFS BIT(4) > + > +#define HSNAND_ECC_OFFSET 0x008 > + > +#define NAND_DATA_IFACE_CHECK_ONLY -1 > + > +#define MAX_CS 2 > + > +#define HZ_PER_MHZ 1000000L > +#define USEC_PER_SEC 1000000L > + > +struct ebu_nand_cs { > + void __iomem *chipaddr; > + dma_addr_t nand_pa; > + u32 addr_sel; > +}; > + > +struct ebu_nand_controller { > + struct nand_controller controller; > + struct nand_chip chip; > + struct device *dev; > + void __iomem *ebu; > + void __iomem *hsnand; > + struct dma_chan *dma_tx; > + struct dma_chan *dma_rx; > + struct completion dma_access_complete; > + unsigned long clk_rate; > + struct clk *clk; > + u32 nd_para0; > + u8 cs_num; > + struct ebu_nand_cs cs[MAX_CS]; > +}; > + > +static inline struct ebu_nand_controller *nand_to_ebu(struct nand_chip *chip) > +{ > + return container_of(chip, struct ebu_nand_controller, chip); > +} > + > +static int ebu_nand_waitrdy(struct nand_chip *chip, unsigned int time_out) Please mention the unit somewhere. > +{ > + struct ebu_nand_controller *ctrl = nand_to_ebu(chip); > + u32 status; > + > + return readl_poll_timeout(ctrl->ebu + EBU_WAIT, status, > + (status & EBU_WAIT_RDBY) || > + (status & EBU_WAIT_WR_C), 20, time_out); > +} > + > +static u8 ebu_nand_readb(struct nand_chip *chip) > +{ > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + u8 cs_num = ebu_host->cs_num; > + u8 val; > + > + val = readb(ebu_host->cs[cs_num].chipaddr + HSNAND_CS_OFFS); > + ebu_nand_waitrdy(chip, 1000); > + return val; > +} > + > +static void ebu_nand_writeb(struct nand_chip *chip, u32 offset, u8 value) > +{ > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + u8 cs_num = ebu_host->cs_num; > + > + writeb(value, ebu_host->cs[cs_num].chipaddr + offset); > + ebu_nand_waitrdy(chip, 1000); > +} > + > +static void ebu_read_buf(struct nand_chip *chip, u_char *buf, unsigned int len) > +{ > + int i; > + > + for (i = 0; i < len; i++) > + buf[i] = ebu_nand_readb(chip); > +} > + > +static void ebu_write_buf(struct nand_chip *chip, const u_char *buf, int len) > +{ > + int i; > + > + for (i = 0; i < len; i++) > + ebu_nand_writeb(chip, HSNAND_CS_OFFS, buf[i]); > +} > + > +static void ebu_nand_disable(struct nand_chip *chip) > +{ > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + > + writel(0, ebu_host->ebu + EBU_CON); > +} > + > +static void ebu_select_chip(struct nand_chip *chip) > +{ > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + void __iomem *nand_con = ebu_host->ebu + EBU_CON; > + u32 cs = ebu_host->cs_num; > + > + writel(EBU_CON_NANDM_EN | EBU_CON_CSMUX_E_EN | EBU_CON_CS_P_LOW | > + EBU_CON_SE_P_LOW | EBU_CON_WP_P_LOW | EBU_CON_PRE_P_LOW | > + EBU_CON_IN_CS_S(cs) | EBU_CON_OUT_CS_S(cs) | > + EBU_CON_LAT_EN_CS_P, nand_con); > +} > + > +static void ebu_nand_setup_timing(struct ebu_nand_controller *ctrl, > + const struct nand_sdr_timings *timings) > +{ > + unsigned int rate = clk_get_rate(ctrl->clk) / HZ_PER_MHZ; > + unsigned int period = DIV_ROUND_UP(USEC_PER_SEC, rate); > + u32 trecov, thold, twrwait, trdwait; > + u32 reg = 0; > + > + trecov = DIV_ROUND_UP(max(timings->tREA_max, timings->tREH_min), > + period); > + reg |= EBU_BUSCON_RECOVC(trecov); > + > + thold = DIV_ROUND_UP(max(timings->tDH_min, timings->tDS_min), period); > + reg |= EBU_BUSCON_HOLDC(thold); > + > + trdwait = DIV_ROUND_UP(max(timings->tRC_min, timings->tREH_min), > + period); > + reg |= EBU_BUSCON_WAITRDC(trdwait); > + > + twrwait = DIV_ROUND_UP(max(timings->tWC_min, timings->tWH_min), period); > + reg |= EBU_BUSCON_WAITWRC(twrwait); > + > + reg |= EBU_BUSCON_CMULT_V4 | EBU_BUSCON_BCGEN_CS | EBU_BUSCON_ALEC | > + EBU_BUSCON_SETUP_EN; > + > + writel(reg, ctrl->ebu + EBU_BUSCON(ctrl->cs_num)); > +} > + > +static int ebu_nand_set_timings(struct nand_chip *chip, int csline, > + const struct nand_interface_config *conf) > +{ > + struct ebu_nand_controller *ctrl = nand_to_ebu(chip); > + const struct nand_sdr_timings *timings; > + > + timings = nand_get_sdr_timings(conf); > + if (IS_ERR(timings)) > + return PTR_ERR(timings); > + > + if (csline == NAND_DATA_IFACE_CHECK_ONLY) > + return 0; > + > + ebu_nand_setup_timing(ctrl, timings); I don't think adding this helper helps much. You could insert the code from this function here directly? > + > + return 0; > +} > + > +static int ebu_nand_ooblayout_ecc(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section) > + return -ERANGE; > + > + oobregion->offset = HSNAND_ECC_OFFSET; > + oobregion->length = chip->ecc.total; > + > + return 0; > +} > + > +static int ebu_nand_ooblayout_free(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section) > + return -ERANGE; > + > + oobregion->offset = chip->ecc.total + HSNAND_ECC_OFFSET; > + oobregion->length = mtd->oobsize - oobregion->offset; > + > + return 0; > +} > + > +static const struct mtd_ooblayout_ops ebu_nand_ooblayout_ops = { > + .ecc = ebu_nand_ooblayout_ecc, > + .free = ebu_nand_ooblayout_free, > +}; > + > +static void ebu_dma_rx_callback(void *cookie) > +{ > + struct ebu_nand_controller *ebu_host = cookie; > + > + dmaengine_terminate_async(ebu_host->dma_rx); > + > + complete(&ebu_host->dma_access_complete); > +} > + > +static void ebu_dma_tx_callback(void *cookie) > +{ > + struct ebu_nand_controller *ebu_host = cookie; > + > + dmaengine_terminate_async(ebu_host->dma_tx); > + > + complete(&ebu_host->dma_access_complete); Please check return codes when they are relevant, and return the errors. Also treat them below. > +} > + > +static int ebu_dma_start(struct ebu_nand_controller *ebu_host, u32 dir, > + const u8 *buf, u32 len) > +{ > + struct dma_async_tx_descriptor *tx; > + struct completion *dma_completion; > + dma_async_tx_callback callback; > + struct dma_chan *chan; > + dma_cookie_t cookie; > + unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; > + dma_addr_t buf_dma; > + int ret; > + u32 timeout; > + > + if (dir == DMA_DEV_TO_MEM) { > + chan = ebu_host->dma_rx; > + dma_completion = &ebu_host->dma_access_complete; > + callback = ebu_dma_rx_callback; > + } else { > + chan = ebu_host->dma_tx; > + dma_completion = &ebu_host->dma_access_complete; > + callback = ebu_dma_tx_callback; > + } > + > + buf_dma = dma_map_single(chan->device->dev, (void *)buf, len, dir); > + if (dma_mapping_error(chan->device->dev, buf_dma)) { > + dev_err(ebu_host->dev, "Failed to map DMA buffer\n"); > + ret = -EIO; > + goto err_unmap; > + } > + > + tx = dmaengine_prep_slave_single(chan, buf_dma, len, dir, flags); > + if (!tx) > + return -ENXIO; > + > + tx->callback = callback; > + tx->callback_param = ebu_host; > + cookie = tx->tx_submit(tx); > + > + ret = dma_submit_error(cookie); > + if (ret) { > + dev_err(ebu_host->dev, "dma_submit_error %d\n", cookie); > + ret = -EIO; > + goto err_unmap; > + } > + > + init_completion(dma_completion); > + dma_async_issue_pending(chan); > + > + /* Wait DMA to finish the data transfer.*/ > + timeout = wait_for_completion_timeout(dma_completion, msecs_to_jiffies(1000)); > + if (!timeout) { > + dev_err(ebu_host->dev, "I/O Error in DMA RX (status %d)\n", > + dmaengine_tx_status(chan, cookie, NULL)); > + dmaengine_terminate_sync(chan); > + ret = -ETIMEDOUT; > + goto err_unmap; > + } > + > + return 0; > + > +err_unmap: > + dma_unmap_single(ebu_host->dev, buf_dma, len, dir); > + > + return ret; > +} > + > +static void ebu_nand_trigger(struct ebu_nand_controller *ebu_host, > + int page, u32 cmd) > +{ > + unsigned int val; > + > + val = cmd | (page & 0xFF) << HSNAND_CTL1_ADDR_SHIFT; > + writel(val, ebu_host->hsnand + HSNAND_CTL1); > + val = (page & 0xFFFF00) >> 8 | HSNAND_CTL2_CYC_N_V5; > + writel(val, ebu_host->hsnand + HSNAND_CTL2); > + > + writel(ebu_host->nd_para0, ebu_host->hsnand + HSNAND_PARA0); > + > + /* clear first, will update later */ > + writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_0); > + writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_1); > + > + writel(HSNAND_INT_MSK_CTL_WR_C, > + ebu_host->hsnand + HSNAND_INT_MSK_CTL); > + > + if (!cmd) > + val = HSNAND_CTL_RW_READ; > + else > + val = HSNAND_CTL_RW_WRITE; > + > + writel(HSNAND_CTL_MSG_EN | HSNAND_CTL_CKFF_EN | > + HSNAND_CTL_ECC_OFF_V8TH | HSNAND_CTL_CE_SEL_CS(ebu_host->cs_num) | > + HSNAND_CTL_ENABLE_ECC | HSNAND_CTL_GO | val, > + ebu_host->hsnand + HSNAND_CTL); > +} > + > +static int ebu_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf, > + int oob_required, int page) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + int ret, reg_data; > + > + ebu_nand_trigger(ebu_host, page, NAND_CMD_READ0); > + > + ret = ebu_dma_start(ebu_host, DMA_DEV_TO_MEM, buf, mtd->writesize); > + if (ret) > + return ret; > + > + if (oob_required) > + chip->ecc.read_oob(chip, page); > + > + reg_data = readl(ebu_host->hsnand + HSNAND_CTL); > + reg_data &= ~HSNAND_CTL_GO; > + writel(reg_data, ebu_host->hsnand + HSNAND_CTL); > + > + return 0; > +} > + > +static int ebu_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf, > + int oob_required, int page) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + void __iomem *int_sta = ebu_host->hsnand + HSNAND_INT_STA; > + int reg_data, ret, val; > + u32 reg; > + > + ebu_nand_trigger(ebu_host, page, NAND_CMD_SEQIN); > + > + ret = ebu_dma_start(ebu_host, DMA_MEM_TO_DEV, buf, mtd->writesize); > + if (ret) > + return ret; > + > + if (oob_required) { > + reg = get_unaligned_le32(chip->oob_poi); > + writel(reg, ebu_host->hsnand + HSNAND_CMSG_0); > + > + reg = get_unaligned_le32(chip->oob_poi + 4); > + writel(reg, ebu_host->hsnand + HSNAND_CMSG_1); > + } > + > + ret = readl_poll_timeout_atomic(int_sta, val, !(val & HSNAND_INT_STA_WR_C), > + 10, 1000); > + if (ret) > + return ret; > + > + reg_data = readl(ebu_host->hsnand + HSNAND_CTL); > + reg_data &= ~HSNAND_CTL_GO; > + writel(reg_data, ebu_host->hsnand + HSNAND_CTL); > + > + return 0; > +} > + > +static const u8 ecc_strength[] = { 1, 1, 4, 8, 24, 32, 40, 60, }; > + > +static int ebu_nand_attach_chip(struct nand_chip *chip) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); > + u32 ecc_steps, ecc_bytes, ecc_total, pagesize, pg_per_blk; > + u32 ecc_strength_ds = chip->ecc.strength; > + u32 ecc_size = chip->ecc.size; > + u32 writesize = mtd->writesize; > + u32 blocksize = mtd->erasesize; > + int bch_algo, start, val; > + > + /* Default to an ECC size of 512 */ > + if (!chip->ecc.size) > + chip->ecc.size = 512; > + > + switch (ecc_size) { > + case 512: > + start = 1; > + if (!ecc_strength_ds) > + ecc_strength_ds = 4; > + break; > + case 1024: > + start = 4; > + if (!ecc_strength_ds) > + ecc_strength_ds = 32; > + break; > + default: > + return -EINVAL; > + } > + > + /* BCH ECC algorithm Settings for number of bits per 512B/1024B */ > + bch_algo = round_up(start + 1, 4); > + for (val = start; val < bch_algo; val++) { > + if (ecc_strength_ds == ecc_strength[val]) > + break; > + } > + if (val == bch_algo) > + return -EINVAL; > + > + if (ecc_strength_ds == 8) > + ecc_bytes = 14; > + else > + ecc_bytes = DIV_ROUND_UP(ecc_strength_ds * fls(8 * ecc_size), 8); > + > + ecc_steps = writesize / ecc_size; > + ecc_total = ecc_steps * ecc_bytes; > + if ((ecc_total + 8) > mtd->oobsize) > + return -ERANGE; > + > + chip->ecc.total = ecc_total; > + pagesize = fls(writesize >> 11); > + if (pagesize > HSNAND_PARA0_PAGE_V8192) > + return -ERANGE; > + > + pg_per_blk = fls((blocksize / writesize) >> 6) / 8; > + if (pg_per_blk > HSNAND_PARA0_PIB_V256) > + return -ERANGE; > + > + ebu_host->nd_para0 = pagesize | pg_per_blk | HSNAND_PARA0_BYP_EN_NP | > + HSNAND_PARA0_BYP_DEC_NP | HSNAND_PARA0_ADEP_EN | > + HSNAND_PARA0_TYPE_ONFI | (val << 29); > + > + mtd_set_ooblayout(mtd, &ebu_nand_ooblayout_ops); > + chip->ecc.read_page = ebu_nand_read_page_hwecc; > + chip->ecc.write_page = ebu_nand_write_page_hwecc; > + > + return 0; > +} > + > +static int ebu_nand_exec_op(struct nand_chip *chip, > + const struct nand_operation *op, bool check_only) > +{ > + const struct nand_op_instr *instr = NULL; > + unsigned int op_id; > + int i, time_out, ret = 0; > + > + if (check_only) > + return 0; > + > + ebu_select_chip(chip); > + for (op_id = 0; op_id < op->ninstrs; op_id++) { > + instr = &op->instrs[op_id]; > + > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + ebu_nand_writeb(chip, HSNAND_CLE_OFFS | HSNAND_CS_OFFS, > + instr->ctx.cmd.opcode); > + break; > + > + case NAND_OP_ADDR_INSTR: > + for (i = 0; i < instr->ctx.addr.naddrs; i++) > + ebu_nand_writeb(chip, > + HSNAND_ALE_OFFS | HSNAND_CS_OFFS, > + instr->ctx.addr.addrs[i]); > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + ebu_read_buf(chip, instr->ctx.data.buf.in, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + ebu_write_buf(chip, instr->ctx.data.buf.out, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + time_out = instr->ctx.waitrdy.timeout_ms * 1000; > + ret = ebu_nand_waitrdy(chip, time_out); > + break; > + } > + } > + > + return ret; > +} > + > +static const struct nand_controller_ops ebu_nand_controller_ops = { > + .attach_chip = ebu_nand_attach_chip, > + .setup_interface = ebu_nand_set_timings, > + .exec_op = ebu_nand_exec_op, > +}; > + > +static void ebu_dma_cleanup(struct ebu_nand_controller *ebu_host) > +{ > + if (ebu_host->dma_rx) > + dma_release_channel(ebu_host->dma_rx); > + > + if (ebu_host->dma_tx) > + dma_release_channel(ebu_host->dma_tx); > +} > + > +static int ebu_nand_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct ebu_nand_controller *ebu_host; > + struct nand_chip *nand; > + struct mtd_info *mtd; > + struct resource *res; > + char *resname; > + int ret, i; > + u32 reg; > + > + ebu_host = devm_kzalloc(dev, sizeof(*ebu_host), GFP_KERNEL); > + if (!ebu_host) > + return -ENOMEM; > + > + ebu_host->dev = dev; > + nand_controller_init(&ebu_host->controller); > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebunand"); > + ebu_host->ebu = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(ebu_host->ebu)) > + return PTR_ERR(ebu_host->ebu); > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsnand"); > + ebu_host->hsnand = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(ebu_host->hsnand)) > + return PTR_ERR(ebu_host->hsnand); > + > + ret = device_property_read_u32(dev, "nand,cs", ®); There is no nand,cs property. Use 'reg' instead. > + if (ret) { > + dev_err(dev, "failed to get chip select: %d\n", ret); > + return ret; > + } > + ebu_host->cs_num = reg; The following for loop is weird, above you can only store a single cs number, while below you seem to reserve serveral memory areas. Please clarify this code. > + > + for (i = 0; i < MAX_CS; i++) { > + resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", i); > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > + resname); > + ebu_host->cs[i].chipaddr = devm_ioremap_resource(dev, res); > + ebu_host->cs[i].nand_pa = res->start; > + if (IS_ERR(ebu_host->cs[i].chipaddr)) > + return PTR_ERR(ebu_host->cs[i].chipaddr); > + } > + > + ebu_host->clk = devm_clk_get(dev, NULL); > + if (IS_ERR(ebu_host->clk)) > + return dev_err_probe(dev, PTR_ERR(ebu_host->clk), > + "failed to get clock\n"); > + > + ret = clk_prepare_enable(ebu_host->clk); > + if (ret) { > + dev_err(dev, "failed to enable clock: %d\n", ret); > + return ret; > + } > + ebu_host->clk_rate = clk_get_rate(ebu_host->clk); > + > + ebu_host->dma_tx = dma_request_chan(dev, "tx"); > + if (IS_ERR(ebu_host->dma_tx)) > + return dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx), > + "failed to request DMA tx chan!.\n"); > + > + ebu_host->dma_rx = dma_request_chan(dev, "rx"); > + if (IS_ERR(ebu_host->dma_rx)) > + return dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx), > + "failed to request DMA rx chan!.\n"); > + > + for (i = 0; i < MAX_CS; i++) { > + resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", i); > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > + resname); > + if (!res) > + return -EINVAL; > + ebu_host->cs[i].addr_sel = res->start; > + writel(ebu_host->cs[i].addr_sel | EBU_ADDR_MASK(5) | > + EBU_ADDR_SEL_REGEN, ebu_host->ebu + EBU_ADDR_SEL(i)); > + } > + > + nand_set_flash_node(&ebu_host->chip, dev->of_node); > + if (!mtd->name) { > + dev_err(ebu_host->dev, "NAND label property is mandatory\n"); > + return -EINVAL; > + } > + > + mtd = nand_to_mtd(&ebu_host->chip); > + mtd->dev.parent = dev; > + ebu_host->dev = dev; > + > + platform_set_drvdata(pdev, ebu_host); > + nand_set_controller_data(&ebu_host->chip, ebu_host); > + > + nand = &ebu_host->chip; > + nand->controller = &ebu_host->controller; > + nand->controller->ops = &ebu_nand_controller_ops; > + > + /* Scan to find existence of the device */ > + ret = nand_scan(&ebu_host->chip, 1); > + if (ret) > + goto err_cleanup_dma; > + > + ret = mtd_device_register(mtd, NULL, 0); > + if (ret) > + goto err_clean_nand; > + > + return 0; > + > +err_clean_nand: > + nand_cleanup(&ebu_host->chip); > +err_cleanup_dma: > + ebu_dma_cleanup(ebu_host); > + clk_disable_unprepare(ebu_host->clk); > + > + return ret; > +} > + > +static int ebu_nand_remove(struct platform_device *pdev) > +{ > + struct ebu_nand_controller *ebu_host = platform_get_drvdata(pdev); > + int ret; > + > + ret = mtd_device_unregister(nand_to_mtd(&ebu_host->chip)); > + WARN_ON(ret); > + nand_cleanup(&ebu_host->chip); > + ebu_nand_disable(&ebu_host->chip); > + ebu_dma_cleanup(ebu_host); > + clk_disable_unprepare(ebu_host->clk); > + > + return 0; > +} > + > +static const struct of_device_id ebu_nand_match[] = { > + { .compatible = "intel,nand-controller", }, No version or soc in the compatible? (not mandatory). > + {} > +}; > +MODULE_DEVICE_TABLE(of, ebu_nand_match); > + > +static struct platform_driver ebu_nand_driver = { > + .probe = ebu_nand_probe, > + .remove = ebu_nand_remove, > + .driver = { > + .name = "intel-nand-controller", > + .of_match_table = ebu_nand_match, > + }, > + > +}; > +module_platform_driver(ebu_nand_driver); > + > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Vadivel Murugan R "); > +MODULE_DESCRIPTION("Intel's LGM External Bus NAND Controller driver"); Thanks, Miquèl