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=-6.8 required=3.0 tests=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 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 1DBC6C48BD7 for ; Thu, 27 Jun 2019 17:37:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EDED02133F for ; Thu, 27 Jun 2019 17:36:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Z3oeu8zy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EDED02133F 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=bombadil.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=1FwoeNyOEbrKfFE2Kin6rGACHBzOBuoxbb5EhMTWKsY=; b=Z3oeu8zyxUITwm QG3vMKy0ymFyJyWEKbHG5/9fbtK+QY6HNrElfaAQan2E0E7S3Y0d7dtXuSmSGi6btboCOYBq8UvXh 2FwxA1RjUK7b0FeiZSMcQlYmiQ8q8mYys8STmfHT0una7fhH8zD8XvdbP3fI7gAcBwTT1DQDegwS6 KMXgHPo5qB+wNCEoytYxoAtW8wXzZNOu/p2e2+64bmRiDxz9ODJvv/rtB3VXto8ENUGeklikUgmBu R8Jcj3OOGgol9zjakP3WWlH27UH/JV8JG993R5mqO5OPMgae54BA7NA2VB+MrlO3CaeR91vVDB57/ PN8AiggwPpt8zBk2wIzQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hgYKE-0003LJ-OY; Thu, 27 Jun 2019 17:36:46 +0000 Received: from relay9-d.mail.gandi.net ([217.70.183.199]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hgYKB-0003KW-KF for linux-mtd@lists.infradead.org; Thu, 27 Jun 2019 17:36:46 +0000 X-Originating-IP: 91.224.148.103 Received: from xps13 (unknown [91.224.148.103]) (Authenticated sender: miquel.raynal@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id D92C9FF80A; Thu, 27 Jun 2019 17:36:36 +0000 (UTC) Date: Thu, 27 Jun 2019 19:36:35 +0200 From: Miquel Raynal To: Mason Yang Subject: Re: [PATCH v4 1/2] mtd: rawnand: Add Macronix Raw NAND controller Message-ID: <20190627193635.29abff43@xps13> In-Reply-To: <1561443056-13766-2-git-send-email-masonccyang@mxic.com.tw> References: <1561443056-13766-1-git-send-email-masonccyang@mxic.com.tw> <1561443056-13766-2-git-send-email-masonccyang@mxic.com.tw> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (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-20190627_103643_983153_DEA52D6E X-CRM114-Status: GOOD ( 22.39 ) 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: devicetree@vger.kernel.org, anders.roxell@linaro.org, vigneshr@ti.com, jianxin.pan@amlogic.com, bbrezillon@kernel.org, juliensu@mxic.com.tw, richard@nod.at, broonie@kernel.org, linux-kernel@vger.kernel.org, stefan@agner.ch, paul@crapouillou.net, marek.vasut@gmail.com, paul.burton@mips.com, liang.yang@amlogic.com, linux-mtd@lists.infradead.org, christophe.kerello@st.com, lee.jones@linaro.org, computersforpeace@gmail.com, dwmw2@infradead.org 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 SGkgTWFzb24sCgpNYXNvbiBZYW5nIDxtYXNvbmNjeWFuZ0BteGljLmNvbS50dz4gd3JvdGUgb24g VHVlLCAyNSBKdW4gMjAxOSAxNDoxMDo1NQorMDgwMDoKCj4gQWRkIGEgZHJpdmVyIGZvciBNYWNy b25peCByYXcgTkFORCBjb250cm9sbGVyLgoKQ291bGQgeW91IHBhc3MgdXNlcnNwYWNlIG1ham9y IE1URCB0ZXN0cyBhbmQgY2FuIHlvdSBhdHRhY2gvbW91bnQvZWRpdAphIFVCSS9VQklGUyBzdG9y YWdlPwoKTG9va3MgcHJldHR5IG5pY2UgdG8gbWUsIGEgZmV3IGNvbW1lbnRzIGJlbG93LgoKPiAK PiBTaWduZWQtb2ZmLWJ5OiBNYXNvbiBZYW5nIDxtYXNvbmNjeWFuZ0BteGljLmNvbS50dz4KPiAt LS0KPiAgZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZyAgICAgfCAgIDYgKwo+ICBkcml2ZXJz L210ZC9uYW5kL3Jhdy9NYWtlZmlsZSAgICB8ICAgMSArCj4gIGRyaXZlcnMvbXRkL25hbmQvcmF3 L214aWNfbmFuZC5jIHwgNTUxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr Kwo+ICAzIGZpbGVzIGNoYW5nZWQsIDU1OCBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEw MDY0NCBkcml2ZXJzL210ZC9uYW5kL3Jhdy9teGljX25hbmQuYwo+IAo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZp Zwo+IGluZGV4IDVhNzExZDguLjljZmYzNmEgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9tdGQvbmFu ZC9yYXcvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcKPiBAQCAt NDA3LDYgKzQwNywxMiBAQCBjb25maWcgTVREX05BTkRfTVRLCj4gIAkgIEVuYWJsZXMgc3VwcG9y dCBmb3IgTkFORCBjb250cm9sbGVyIG9uIE1USyBTb0NzLgo+ICAJICBUaGlzIGNvbnRyb2xsZXIg aXMgZm91bmQgb24gbXQyN3h4LCBtdDgxeHgsIG10NjV4eCBTb0NzLgo+ICAKPiArY29uZmlnIE1U RF9OQU5EX01YSUMKPiArCXRyaXN0YXRlICJNYWNyb25peCByYXcgTkFORCBjb250cm9sbGVyIgo+ ICsJZGVwZW5kcyBvbiBIQVNfSU9NRU0gfHwgQ09NUElMRV9URVNUCj4gKwloZWxwCj4gKwkgIFRo aXMgc2VsZWN0cyB0aGUgTWFjcm9uaXggcmF3IE5BTkQgY29udHJvbGxlciBkcml2ZXIuCj4gKwo+ ICBjb25maWcgTVREX05BTkRfVEVHUkEKPiAgCXRyaXN0YXRlICJOVklESUEgVGVncmEgTkFORCBj b250cm9sbGVyIgo+ICAJZGVwZW5kcyBvbiBBUkNIX1RFR1JBIHx8IENPTVBJTEVfVEVTVAo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZSBiL2RyaXZlcnMvbXRkL25h bmQvcmF3L01ha2VmaWxlCj4gaW5kZXggZWZhZjVjZC4uOWI0M2ZiZiAxMDA2NDQKPiAtLS0gYS9k cml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3 L01ha2VmaWxlCj4gQEAgLTU0LDYgKzU0LDcgQEAgb2JqLSQoQ09ORklHX01URF9OQU5EX0hJU0k1 MDQpCSAgICAgICAgKz0gaGlzaTUwNF9uYW5kLm8KPiAgb2JqLSQoQ09ORklHX01URF9OQU5EX0JS Q01OQU5EKQkJKz0gYnJjbW5hbmQvCj4gIG9iai0kKENPTkZJR19NVERfTkFORF9RQ09NKQkJKz0g cWNvbV9uYW5kYy5vCj4gIG9iai0kKENPTkZJR19NVERfTkFORF9NVEspCQkrPSBtdGtfZWNjLm8g bXRrX25hbmQubwo+ICtvYmotJChDT05GSUdfTVREX05BTkRfTVhJQykJCSs9IG14aWNfbmFuZC5v Cj4gIG9iai0kKENPTkZJR19NVERfTkFORF9URUdSQSkJCSs9IHRlZ3JhX25hbmQubwo+ICBvYmot JChDT05GSUdfTVREX05BTkRfU1RNMzJfRk1DMikJKz0gc3RtMzJfZm1jMl9uYW5kLm8KPiAgb2Jq LSQoQ09ORklHX01URF9OQU5EX01FU09OKQkJKz0gbWVzb25fbmFuZC5vCj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvbXRkL25hbmQvcmF3L214aWNfbmFuZC5jIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcv bXhpY19uYW5kLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjE0YzBi M2IKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvbXhpY19uYW5k LmMKPiBAQCAtMCwwICsxLDU1MSBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMAo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTkgTWFjcm9uaXggSW50ZXJuYXRpb25h bCBDby4sIEx0ZC4KPiArICoKPiArICogQXV0aG9yOgo+ICsgKglNYXNvbiBZYW5nIDxtYXNvbmNj eWFuZ0BteGljLmNvbS50dz4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4g KyNpbmNsdWRlIDxsaW51eC9pby5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW9wb2xsLmg+Cj4gKyNp bmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L210ZC9tdGQuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L210ZC9yYXduYW5kLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tdGQvbmFu ZF9lY2MuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsKPiArI2lu Y2x1ZGUgImludGVybmFscy5oIgo+ICsKPiArI2RlZmluZSBIQ19DRkcJCQkweDAKPiArI2RlZmlu ZSBIQ19DRkdfSUZfQ0ZHKHgpCSgoeCkgPDwgMjcpCj4gKyNkZWZpbmUgSENfQ0ZHX0RVQUxfU0xB VkUJQklUKDMxKQo+ICsjZGVmaW5lIEhDX0NGR19JTkRJVklEVUFMCUJJVCgzMCkKPiArI2RlZmlu ZSBIQ19DRkdfTklPKHgpCQkoKCh4KSAvIDQpIDw8IDI3KQo+ICsjZGVmaW5lIEhDX0NGR19UWVBF KHMsIHQpCSgodCkgPDwgKDIzICsgKChzKSAqIDIpKSkKPiArI2RlZmluZSBIQ19DRkdfVFlQRV9T UElfTk9SCTAKPiArI2RlZmluZSBIQ19DRkdfVFlQRV9TUElfTkFORAkxCj4gKyNkZWZpbmUgSENf Q0ZHX1RZUEVfU1BJX1JBTQkyCj4gKyNkZWZpbmUgSENfQ0ZHX1RZUEVfUkFXX05BTkQJMwo+ICsj ZGVmaW5lIEhDX0NGR19TTFZfQUNUKHgpCSgoeCkgPDwgMjEpCj4gKyNkZWZpbmUgSENfQ0ZHX0NM S19QSF9FTglCSVQoMjApCj4gKyNkZWZpbmUgSENfQ0ZHX0NMS19QT0xfSU5WCUJJVCgxOSkKPiAr I2RlZmluZSBIQ19DRkdfQklHX0VORElBTglCSVQoMTgpCj4gKyNkZWZpbmUgSENfQ0ZHX0RBVEFf UEFTUwlCSVQoMTcpCj4gKyNkZWZpbmUgSENfQ0ZHX0lETEVfU0lPX0xWTCh4KQkoKHgpIDw8IDE2 KQo+ICsjZGVmaW5lIEhDX0NGR19NQU5fU1RBUlRfRU4JQklUKDMpCj4gKyNkZWZpbmUgSENfQ0ZH X01BTl9TVEFSVAlCSVQoMikKPiArI2RlZmluZSBIQ19DRkdfTUFOX0NTX0VOCUJJVCgxKQo+ICsj ZGVmaW5lIEhDX0NGR19NQU5fQ1NfQVNTRVJUCUJJVCgwKQo+ICsKPiArI2RlZmluZSBJTlRfU1RT CQkJMHg0Cj4gKyNkZWZpbmUgSU5UX1NUU19FTgkJMHg4Cj4gKyNkZWZpbmUgSU5UX1NJR19FTgkJ MHhjCj4gKyNkZWZpbmUgSU5UX1NUU19BTEwJCUdFTk1BU0soMzEsIDApCj4gKyNkZWZpbmUgSU5U X1JEWV9QSU4JCUJJVCgyNikKPiArI2RlZmluZSBJTlRfUkRZX1NSCQlCSVQoMjUpCj4gKyNkZWZp bmUgSU5UX0xOUl9TVVNQCQlCSVQoMjQpCj4gKyNkZWZpbmUgSU5UX0VDQ19FUlIJCUJJVCgxNykK PiArI2RlZmluZSBJTlRfQ1JDX0VSUgkJQklUKDE2KQo+ICsjZGVmaW5lIElOVF9MV1JfRElTCQlC SVQoMTIpCj4gKyNkZWZpbmUgSU5UX0xSRF9ESVMJCUJJVCgxMSkKPiArI2RlZmluZSBJTlRfU0RN QV9JTlQJCUJJVCgxMCkKPiArI2RlZmluZSBJTlRfRE1BX0ZJTklTSAkJQklUKDkpCj4gKyNkZWZp bmUgSU5UX1JYX05PVF9GVUxMCQlCSVQoMykKPiArI2RlZmluZSBJTlRfUlhfTk9UX0VNUFRZCUJJ VCgyKQo+ICsjZGVmaW5lIElOVF9UWF9OT1RfRlVMTAkJQklUKDEpCj4gKyNkZWZpbmUgSU5UX1RY X0VNUFRZCQlCSVQoMCkKPiArCj4gKyNkZWZpbmUgSENfRU4JCQkweDEwCj4gKyNkZWZpbmUgSENf RU5fQklUCQlCSVQoMCkKPiArCj4gKyNkZWZpbmUgVFhEKHgpCQkJKDB4MTQgKyAoKHgpICogNCkp Cj4gKyNkZWZpbmUgUlhECQkJMHgyNAo+ICsKPiArI2RlZmluZSBTU19DVFJMKHMpCQkoMHgzMCAr ICgocykgKiA0KSkKPiArI2RlZmluZSBMUkRfQ0ZHCQkJMHg0NAo+ICsjZGVmaW5lIExXUl9DRkcJ CQkweDgwCj4gKyNkZWZpbmUgUldXX0NGRwkJCTB4NzAKPiArI2RlZmluZSBPUF9SRUFECQkJQklU KDIzKQo+ICsjZGVmaW5lIE9QX0RVTU1ZX0NZQyh4KQkJKCh4KSA8PCAxNykKPiArI2RlZmluZSBP UF9BRERSX0JZVEVTKHgpCSgoeCkgPDwgMTQpCj4gKyNkZWZpbmUgT1BfQ01EX0JZVEVTKHgpCQko KCh4KSAtIDEpIDw8IDEzKQo+ICsjZGVmaW5lIE9QX09DVEFfQ1JDX0VOCQlCSVQoMTIpCj4gKyNk ZWZpbmUgT1BfRFFTX0VOCQlCSVQoMTEpCj4gKyNkZWZpbmUgT1BfRU5IQ19FTgkJQklUKDEwKQo+ ICsjZGVmaW5lIE9QX1BSRUFNQkxFX0VOCQlCSVQoOSkKPiArI2RlZmluZSBPUF9EQVRBX0REUgkJ QklUKDgpCj4gKyNkZWZpbmUgT1BfREFUQV9CVVNXKHgpCQkoKHgpIDw8IDYpCj4gKyNkZWZpbmUg T1BfQUREUl9ERFIJCUJJVCg1KQo+ICsjZGVmaW5lIE9QX0FERFJfQlVTVyh4KQkJKCh4KSA8PCAz KQo+ICsjZGVmaW5lIE9QX0NNRF9ERFIJCUJJVCgyKQo+ICsjZGVmaW5lIE9QX0NNRF9CVVNXKHgp CQkoeCkKPiArI2RlZmluZSBPUF9CVVNXXzEJCTAKPiArI2RlZmluZSBPUF9CVVNXXzIJCTEKPiAr I2RlZmluZSBPUF9CVVNXXzQJCTIKPiArI2RlZmluZSBPUF9CVVNXXzgJCTMKPiArCj4gKyNkZWZp bmUgT0NUQV9DUkMJCTB4MzgKPiArI2RlZmluZSBPQ1RBX0NSQ19JTl9FTihzKQlCSVQoMyArICgo cykgKiAxNikpCj4gKyNkZWZpbmUgT0NUQV9DUkNfQ0hVTksocywgeCkJKChmbHMoKHgpIC8gMzIp KSA8PCAoMSArICgocykgKiAxNikpKQo+ICsjZGVmaW5lIE9DVEFfQ1JDX09VVF9FTihzKQlCSVQo MCArICgocykgKiAxNikpCj4gKwo+ICsjZGVmaW5lIE9ORklfRElOX0NOVChzKQkJKDB4M2MgKyAo cykpCj4gKwo+ICsjZGVmaW5lIExSRF9DVFJMCQkweDQ4Cj4gKyNkZWZpbmUgUldXX0NUUkwJCTB4 NzQKPiArI2RlZmluZSBMV1JfQ1RSTAkJMHg4NAo+ICsjZGVmaW5lIExNT0RFX0VOCQlCSVQoMzEp Cj4gKyNkZWZpbmUgTE1PREVfU0xWX0FDVCh4KQkoKHgpIDw8IDIxKQo+ICsjZGVmaW5lIExNT0RF X0NNRDEoeCkJCSgoeCkgPDwgOCkKPiArI2RlZmluZSBMTU9ERV9DTUQwKHgpCQkoeCkKPiArCj4g KyNkZWZpbmUgTFJEX0FERFIJCTB4NGMKPiArI2RlZmluZSBMV1JfQUREUgkJMHg4OAo+ICsjZGVm aW5lIExSRF9SQU5HRQkJMHg1MAo+ICsjZGVmaW5lIExXUl9SQU5HRQkJMHg4Ywo+ICsKPiArI2Rl ZmluZSBBWElfU0xWX0FERFIJCTB4NTQKPiArCj4gKyNkZWZpbmUgRE1BQ19SRF9DRkcJCTB4NTgK PiArI2RlZmluZSBETUFDX1dSX0NGRwkJMHg5NAo+ICsjZGVmaW5lIERNQUNfQ0ZHX1BFUklQSF9F TglCSVQoMzEpCj4gKyNkZWZpbmUgRE1BQ19DRkdfQUxMRkxVU0hfRU4JQklUKDMwKQo+ICsjZGVm aW5lIERNQUNfQ0ZHX0xBU1RGTFVTSF9FTglCSVQoMjkpCj4gKyNkZWZpbmUgRE1BQ19DRkdfUUUo eCkJCSgoKHgpICsgMSkgPDwgMTYpCj4gKyNkZWZpbmUgRE1BQ19DRkdfQlVSU1RfTEVOKHgpCSgo KHgpICsgMSkgPDwgMTIpCj4gKyNkZWZpbmUgRE1BQ19DRkdfQlVSU1RfU1ooeCkJKCh4KSA8PCA4 KQo+ICsjZGVmaW5lIERNQUNfQ0ZHX0RJUl9SRUFECUJJVCgxKQo+ICsjZGVmaW5lIERNQUNfQ0ZH X1NUQVJUCQlCSVQoMCkKPiArCj4gKyNkZWZpbmUgRE1BQ19SRF9DTlQJCTB4NWMKPiArI2RlZmlu ZSBETUFDX1dSX0NOVAkJMHg5OAo+ICsKPiArI2RlZmluZSBTRE1BX0FERFIJCTB4NjAKPiArCj4g KyNkZWZpbmUgRE1BTV9DRkcJCTB4NjQKPiArI2RlZmluZSBETUFNX0NGR19TVEFSVAkJQklUKDMx KQo+ICsjZGVmaW5lIERNQU1fQ0ZHX0NPTlQJCUJJVCgzMCkKPiArI2RlZmluZSBETUFNX0NGR19T RE1BX0dBUCh4KQkoZmxzKCh4KSAvIDgxOTIpIDw8IDIpCj4gKyNkZWZpbmUgRE1BTV9DRkdfRElS X1JFQUQJQklUKDEpCj4gKyNkZWZpbmUgRE1BTV9DRkdfRU4JCUJJVCgwKQo+ICsKPiArI2RlZmlu ZSBETUFNX0NOVAkJMHg2OAo+ICsKPiArI2RlZmluZSBMTlJfVElNRVJfVEgJCTB4NmMKPiArCj4g KyNkZWZpbmUgUkRNX0NGRzAJCTB4NzgKPiArI2RlZmluZSBSRE1fQ0ZHMF9QT0xZKHgpCSh4KQo+ ICsKPiArI2RlZmluZSBSRE1fQ0ZHMQkJMHg3Ywo+ICsjZGVmaW5lIFJETV9DRkcxX1JETV9FTgkJ QklUKDMxKQo+ICsjZGVmaW5lIFJETV9DRkcxX1NFRUQoeCkJKHgpCj4gKwo+ICsjZGVmaW5lIExX Ul9TVVNQX0NUUkwJCTB4OTAKPiArI2RlZmluZSBMV1JfU1VTUF9DVFJMX0VOCUJJVCgzMSkKPiAr Cj4gKyNkZWZpbmUgRE1BU19DVFJMCQkweDljCj4gKyNkZWZpbmUgRE1BU19DVFJMX0RJUl9SRUFE CUJJVCgzMSkKPiArI2RlZmluZSBETUFTX0NUUkxfRU4JCUJJVCgzMCkKPiArCj4gKyNkZWZpbmUg REFUQV9TVFJPQgkJMHhhMAo+ICsjZGVmaW5lIERBVEFfU1RST0JfRURPX0VOCUJJVCgyKQo+ICsj ZGVmaW5lIERBVEFfU1RST0JfSU5WX1BPTAlCSVQoMSkKPiArI2RlZmluZSBEQVRBX1NUUk9CX0RF TEFZXzJDWUMJQklUKDApCj4gKwo+ICsjZGVmaW5lIElETFlfQ09ERSh4KQkJKDB4YTQgKyAoKHgp ICogNCkpCj4gKyNkZWZpbmUgSURMWV9DT0RFX1ZBTCh4LCB2KQkoKHYpIDw8ICgoKHgpICUgNCkg KiA4KSkKPiArCj4gKyNkZWZpbmUgR1BJTwkJCTB4YzQKPiArI2RlZmluZSBHUElPX1BUKHgpCQlC SVQoMyArICgoeCkgKiAxNikpCj4gKyNkZWZpbmUgR1BJT19SRVNFVCh4KQkJQklUKDIgKyAoKHgp ICogMTYpKQo+ICsjZGVmaW5lIEdQSU9fSE9MREIoeCkJCUJJVCgxICsgKCh4KSAqIDE2KSkKPiAr I2RlZmluZSBHUElPX1dQQih4KQkJQklUKCh4KSAqIDE2KQo+ICsKPiArI2RlZmluZSBIQ19WRVIJ CQkweGQwCj4gKwo+ICsjZGVmaW5lIEhXX1RFU1QoeCkJCSgweGUwICsgKCh4KSAqIDQpKQo+ICsK PiArI2RlZmluZSBNWElDX05GQ19NQVhfQ0xLX0haCTUwMDAwMDAwCj4gKwo+ICtzdHJ1Y3QgbXhp Y19uYW5kX2N0bHIgewo+ICsJc3RydWN0IGNsayAqcHNfY2xrOwo+ICsJc3RydWN0IGNsayAqc2Vu ZF9jbGs7Cj4gKwlzdHJ1Y3QgY2xrICpzZW5kX2RseV9jbGs7Cj4gKwl2b2lkIF9faW9tZW0gKnJl Z3M7Cj4gKwlzdHJ1Y3QgbmFuZF9jb250cm9sbGVyIGNvbnRyb2xsZXI7Cj4gKwl2b2lkICpwcml2 Owo+ICt9Owo+ICsKPiArc3RydWN0IG14aWNfbmFuZF9jaGlwIHsKPiArCXN0cnVjdCBuYW5kX2No aXAgY2hpcDsKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgbXhpY19uZmNfY2xrX2VuYWJsZShzdHJ1 Y3QgbXhpY19uYW5kX2N0bHIgKm5mYykKPiArewo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSBj bGtfcHJlcGFyZV9lbmFibGUobmZjLT5zZW5kX2Nsayk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVy biByZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKG5mYy0+c2VuZF9kbHlfY2xr KTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBlcnJfc2VuZF9kbHlfY2xrOwoKSSdtIG5vdCBzdXJl IHdoeSB5b3Ugb25seSBlbmFibGUgMiBvdXQgb2YgMyBjbG9ja3MgYW5kIGFsc28gd2h5IG91Cmhh bmRsZSB0d28gb2YgdGhlbSBoZXJlICh3aGljaCBpcyBncmVhdCwgSSBwcmVmZXIgaGF2aW5nIGEg c2VwYXJhdGUKaGVscGVyIGZvciB0aGF0KSBhbmQgdGhlIG90aGVyIG9uZSBlbHNld2hlcmU/Cgo+ ICsKPiArCXJldHVybiByZXQ7Cj4gKwo+ICtlcnJfc2VuZF9kbHlfY2xrOgo+ICsJY2xrX2Rpc2Fi bGVfdW5wcmVwYXJlKG5mYy0+c2VuZF9jbGspOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiAr Cj4gK3N0YXRpYyB2b2lkIG14aWNfbmZjX2Nsa19kaXNhYmxlKHN0cnVjdCBteGljX25hbmRfY3Rs ciAqbmZjKQo+ICt7Cj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5zZW5kX2Nsayk7Cj4g KwljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5zZW5kX2RseV9jbGspOwo+ICt9Cj4gKwo+ICtz dGF0aWMgdm9pZCBteGljX25mY19zZXRfaW5wdXRfZGVsYXkoc3RydWN0IG14aWNfbmFuZF9jdGxy ICpuZmMsIHU4IGlkbHlfY29kZSkKPiArewo+ICsJd3JpdGVsKElETFlfQ09ERV9WQUwoMCwgaWRs eV9jb2RlKSB8Cj4gKwkgICAgICAgSURMWV9DT0RFX1ZBTCgxLCBpZGx5X2NvZGUpIHwKPiArCSAg ICAgICBJRExZX0NPREVfVkFMKDIsIGlkbHlfY29kZSkgfAo+ICsJICAgICAgIElETFlfQ09ERV9W QUwoMywgaWRseV9jb2RlKSwKPiArCSAgICAgICBuZmMtPnJlZ3MgKyBJRExZX0NPREUoMCkpOwo+ ICsJd3JpdGVsKElETFlfQ09ERV9WQUwoNCwgaWRseV9jb2RlKSB8Cj4gKwkgICAgICAgSURMWV9D T0RFX1ZBTCg1LCBpZGx5X2NvZGUpIHwKPiArCSAgICAgICBJRExZX0NPREVfVkFMKDYsIGlkbHlf Y29kZSkgfAo+ICsJICAgICAgIElETFlfQ09ERV9WQUwoNywgaWRseV9jb2RlKSwKPiArCSAgICAg ICBuZmMtPnJlZ3MgKyBJRExZX0NPREUoMSkpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG14aWNf bmZjX2Nsa19zZXR1cChzdHJ1Y3QgbXhpY19uYW5kX2N0bHIgKm5mYywgdW5zaWduZWQgbG9uZyBm cmVxKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IGNsa19zZXRfcmF0ZShuZmMtPnNl bmRfY2xrLCBmcmVxKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQg PSBjbGtfc2V0X3JhdGUobmZjLT5zZW5kX2RseV9jbGssIGZyZXEpOwo+ICsJaWYgKHJldCkKPiAr CQlyZXR1cm4gcmV0Owo+ICsKPiArCS8qCj4gKwkgKiBBIGNvbnN0YW50IGRlbGF5IHJhbmdlIGZy b20gMHgwIH4gMHgxRiBmb3IgaW5wdXQgZGVsYXksCj4gKwkgKiB0aGUgdW5pdCBpcyA3OCBwcywg dGhlIG1heCBpbnB1dCBkZWxheSBpcyAyLjQxOCBucy4KPiArCSAqLwo+ICsJbXhpY19uZmNfc2V0 X2lucHV0X2RlbGF5KG5mYywgMHhmKTsKPiArCj4gKwkvKgo+ICsJICogUGhhc2UgZGVncmVlID0g MzYwICogZnJlcSAqIG91dHB1dC1kZWxheQo+ICsJICogd2hlcmUgb3V0cHV0LWRlbGF5IGlzIGEg Y29uc3RhbnQgdmFsdWUgMSBucyBpbiBGUEdBLgoKV2lsbCBpdCBhbHdheXMgYmUgaW4gRlBHQT8K Cj4gKwkgKgo+ICsJICogR2V0IFBoYXNlIGRlZ3JlZSA9IDM2MCAqIGZyZXEgKiAxIG5zCj4gKwkg KiAgICAgICAgICAgICAgICAgID0gMzYwICogZnJlcSAqIDEgc2VjIC8gMTAwMDAwMDAwMAo+ICsJ ICogICAgICAgICAgICAgICAgICA9IDkgKiBmcmVxIC8gMjUwMDAwMDAKPiArCSAqLwo+ICsJcmV0 ID0gY2xrX3NldF9waGFzZShuZmMtPnNlbmRfZGx5X2NsaywgOSAqIGZyZXEgLyAyNTAwMDAwMCk7 Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiAr Cj4gK3N0YXRpYyBpbnQgbXhpY19uZmNfc2V0X2ZyZXEoc3RydWN0IG14aWNfbmFuZF9jdGxyICpu ZmMsIHVuc2lnbmVkIGxvbmcgZnJlcSkKPiArewo+ICsJaW50IHJldDsKPiArCj4gKwlpZiAoZnJl cSA+IE1YSUNfTkZDX01BWF9DTEtfSFopCj4gKwkJZnJlcSA9IE1YSUNfTkZDX01BWF9DTEtfSFo7 Cj4gKwo+ICsJbXhpY19uZmNfY2xrX2Rpc2FibGUobmZjKTsKPiArCXJldCA9IG14aWNfbmZjX2Ns a19zZXR1cChuZmMsIGZyZXEpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiAr CXJldCA9IG14aWNfbmZjX2Nsa19lbmFibGUobmZjKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJu IHJldDsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXhpY19uZmNf aHdfaW5pdChzdHJ1Y3QgbXhpY19uYW5kX2N0bHIgKm5mYykKPiArewo+ICsJd3JpdGVsKERBVEFf U1RST0JfRURPX0VOLCBuZmMtPnJlZ3MgKyBEQVRBX1NUUk9CKTsKPiArCXdyaXRlbChIQ19DRkdf TklPKDgpIHwgSENfQ0ZHX1RZUEUoMSwgSENfQ0ZHX1RZUEVfUkFXX05BTkQpIHwKPiArCSAgICAg ICBIQ19DRkdfU0xWX0FDVCgwKSB8IEhDX0NGR19NQU5fQ1NfRU4gfAo+ICsJICAgICAgIEhDX0NG R19JRExFX1NJT19MVkwoMSksIG5mYy0+cmVncyArIEhDX0NGRyk7Cj4gKwl3cml0ZWwoSU5UX1NU U19BTEwsIG5mYy0+cmVncyArIElOVF9TVFNfRU4pOwo+ICsJd3JpdGVsKDB4MCwgbmZjLT5yZWdz ICsgT05GSV9ESU5fQ05UKDApKTsKPiArCXdyaXRlbCgwLCBuZmMtPnJlZ3MgKyBMUkRfQ0ZHKTsK PiArCXdyaXRlbCgwLCBuZmMtPnJlZ3MgKyBMUkRfQ1RSTCk7Cj4gKwl3cml0ZWwoMHgwLCBuZmMt PnJlZ3MgKyBIQ19FTik7Cj4gKwo+ICsJLyogRGVmYXVsdCAxMCBNSHogdG8gc2V0dXAgdFJDX21p bi90V0NfbWluOjEwMCBucyAqLwo+ICsJbXhpY19uZmNfc2V0X2ZyZXEobmZjLCAxMDAwMDAwMCk7 Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG14aWNfbmZjX2NzX2VuYWJsZShzdHJ1Y3QgbXhpY19u YW5kX2N0bHIgKm5mYykKPiArewo+ICsJd3JpdGVsKHJlYWRsKG5mYy0+cmVncyArIEhDX0NGRykg fCBIQ19DRkdfTUFOX0NTX0VOLAo+ICsJICAgICAgIG5mYy0+cmVncyArIEhDX0NGRyk7Cj4gKwl3 cml0ZWwoSENfQ0ZHX01BTl9DU19BU1NFUlQgfCByZWFkbChuZmMtPnJlZ3MgKyBIQ19DRkcpLAo+ ICsJICAgICAgIG5mYy0+cmVncyArIEhDX0NGRyk7CgpTbyB5b3UgY2FuIGRyaXZlIG9ubHkgb25l IENTIHdpdGggdGhpcyBjb250cm9sbGVyPwoKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXhpY19u ZmNfY3NfZGlzYWJsZShzdHJ1Y3QgbXhpY19uYW5kX2N0bHIgKm5mYykKPiArewo+ICsJd3JpdGVs KH5IQ19DRkdfTUFOX0NTX0FTU0VSVCAmIHJlYWRsKG5mYy0+cmVncyArIEhDX0NGRyksCj4gKwkg ICAgICAgbmZjLT5yZWdzICsgSENfQ0ZHKTsKPiArfQo+ICsKPiArc3RhdGljIGludCAgbXhpY19u ZmNfd2FpdF9yZWFkeShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlzdHJ1Y3QgbXhp Y19uYW5kX2N0bHIgKm5mYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShjaGlwKTsKPiArCXUz MiBzdHM7Cj4gKwo+ICsJcmV0dXJuIHJlYWRsX3BvbGxfdGltZW91dChuZmMtPnJlZ3MgKyBJTlRf U1RTLCBzdHMsCj4gKwkJCQkgIHN0cyAmIElOVF9SRFlfUElOLCAwLCBVU0VDX1BFUl9TRUMpOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG14aWNfbmZjX2RhdGFfeGZlcihzdHJ1Y3QgbXhpY19uYW5k X2N0bHIgKm5mYywgY29uc3Qgdm9pZCAqdHhidWYsCj4gKwkJCSAgICAgIHZvaWQgKnJ4YnVmLCB1 bnNpZ25lZCBpbnQgbGVuKQo+ICt7Cj4gKwl1bnNpZ25lZCBpbnQgcG9zID0gMDsKPiArCj4gKwl3 aGlsZSAocG9zIDwgbGVuKSB7Cj4gKwkJdW5zaWduZWQgaW50IG5ieXRlcyA9IGxlbiAtIHBvczsK PiArCQl1MzIgZGF0YSA9IDB4ZmZmZmZmZmY7Cj4gKwkJdTMyIHN0czsKPiArCQlpbnQgcmV0Owo+ ICsKPiArCQlpZiAobmJ5dGVzID4gNCkKPiArCQkJbmJ5dGVzID0gNDsKPiArCj4gKwkJaWYgKHR4 YnVmKQo+ICsJCQltZW1jcHkoJmRhdGEsIHR4YnVmICsgcG9zLCBuYnl0ZXMpOwo+ICsKPiArCQly ZXQgPSByZWFkbF9wb2xsX3RpbWVvdXQobmZjLT5yZWdzICsgSU5UX1NUUywgc3RzLAo+ICsJCQkJ CSBzdHMgJiBJTlRfVFhfRU1QVFksIDAsIFVTRUNfUEVSX1NFQyk7Cj4gKwkJaWYgKHJldCkKPiAr CQkJcmV0dXJuIHJldDsKPiArCj4gKwkJd3JpdGVsKGRhdGEsIG5mYy0+cmVncyArIFRYRChuYnl0 ZXMgJSA0KSk7Cj4gKwo+ICsJCWlmIChyeGJ1Zikgewo+ICsJCQlyZXQgPSByZWFkbF9wb2xsX3Rp bWVvdXQobmZjLT5yZWdzICsgSU5UX1NUUywgc3RzLAo+ICsJCQkJCQkgc3RzICYgSU5UX1RYX0VN UFRZLCAwLAo+ICsJCQkJCQkgVVNFQ19QRVJfU0VDKTsKPiArCQkJaWYgKHJldCkKPiArCQkJCXJl dHVybiByZXQ7Cj4gKwo+ICsJCQlyZXQgPSByZWFkbF9wb2xsX3RpbWVvdXQobmZjLT5yZWdzICsg SU5UX1NUUywgc3RzLAo+ICsJCQkJCQkgc3RzICYgSU5UX1JYX05PVF9FTVBUWSwgMCwKPiArCQkJ CQkJIFVTRUNfUEVSX1NFQyk7Cj4gKwkJCWlmIChyZXQpCj4gKwkJCQlyZXR1cm4gcmV0Owo+ICsK PiArCQkJZGF0YSA9IHJlYWRsKG5mYy0+cmVncyArIFJYRCk7Cj4gKwkJCWRhdGEgPj49ICg4ICog KDQgLSBuYnl0ZXMpKTsKPiArCQkJbWVtY3B5KHJ4YnVmICsgcG9zLCAmZGF0YSwgbmJ5dGVzKTsK PiArCQkJV0FSTl9PTihyZWFkbChuZmMtPnJlZ3MgKyBJTlRfU1RTKSAmIElOVF9SWF9OT1RfRU1Q VFkpOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCXJlYWRsKG5mYy0+cmVncyArIFJYRCk7Cj4gKwkJfQo+ ICsJCVdBUk5fT04ocmVhZGwobmZjLT5yZWdzICsgSU5UX1NUUykgJiBJTlRfUlhfTk9UX0VNUFRZ KTsKCldBUk5fT04oKSBpcyBtYXliZSBhIGJpdCBvdmVya2lsbCBoZXJlPwoKPiArCj4gKwkJcG9z ICs9IG5ieXRlczsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBteGljX25mY19leGVjX29wKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsCj4gKwkJCSAgICBjb25z dCBzdHJ1Y3QgbmFuZF9vcGVyYXRpb24gKm9wLCBib29sIGNoZWNrX29ubHkpCj4gK3sKPiArCXN0 cnVjdCBteGljX25hbmRfY3RsciAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXAp Owo+ICsJY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyID0gTlVMTDsKPiArCWludCBy ZXQgPSAwOwo+ICsJdW5zaWduZWQgaW50IG9wX2lkOwo+ICsKPiArCW14aWNfbmZjX2NzX2VuYWJs ZShuZmMpOwo+ICsKPiArCWZvciAob3BfaWQgPSAwOyBvcF9pZCA8IG9wLT5uaW5zdHJzOyBvcF9p ZCsrKSB7Cj4gKwkJaW5zdHIgPSAmb3AtPmluc3Ryc1tvcF9pZF07Cj4gKwo+ICsJCXN3aXRjaCAo aW5zdHItPnR5cGUpIHsKPiArCQljYXNlIE5BTkRfT1BfQ01EX0lOU1RSOgo+ICsJCQl3cml0ZWwo MCwgbmZjLT5yZWdzICsgSENfRU4pOwo+ICsJCQl3cml0ZWwoSENfRU5fQklULCBuZmMtPnJlZ3Mg KyBIQ19FTik7Cj4gKwkJCXdyaXRlbChPUF9DTURfQlVTVyhPUF9CVVNXXzgpIHwgIE9QX0RVTU1Z X0NZQygweDNGKSB8Cj4gKwkJCSAgICAgICBPUF9DTURfQllURVMoMCksIG5mYy0+cmVncyArIFNT X0NUUkwoMCkpOwo+ICsKPiArCQkJcmV0ID0gbXhpY19uZmNfZGF0YV94ZmVyKG5mYywKPiArCQkJ CQkJICZpbnN0ci0+Y3R4LmNtZC5vcGNvZGUsCj4gKwkJCQkJCSBOVUxMLCAxKTsKPiArCQkJYnJl YWs7Cj4gKwo+ICsJCWNhc2UgTkFORF9PUF9BRERSX0lOU1RSOgo+ICsJCQl3cml0ZWwoT1BfQURE Ul9CVVNXKE9QX0JVU1dfOCkgfCBPUF9EVU1NWV9DWUMoMHgzRikgfAo+ICsJCQkgICAgICAgT1Bf QUREUl9CWVRFUyhpbnN0ci0+Y3R4LmFkZHIubmFkZHJzKSwKPiArCQkJICAgICAgIG5mYy0+cmVn cyArIFNTX0NUUkwoMCkpOwo+ICsJCQlyZXQgPSBteGljX25mY19kYXRhX3hmZXIobmZjLAo+ICsJ CQkJCQkgaW5zdHItPmN0eC5hZGRyLmFkZHJzLCBOVUxMLAo+ICsJCQkJCQkgaW5zdHItPmN0eC5h ZGRyLm5hZGRycyk7Cj4gKwkJCWJyZWFrOwo+ICsKPiArCQljYXNlIE5BTkRfT1BfREFUQV9JTl9J TlNUUjoKPiArCQkJd3JpdGVsKDB4MCwgbmZjLT5yZWdzICsgT05GSV9ESU5fQ05UKDApKTsKPiAr CQkJd3JpdGVsKE9QX0RBVEFfQlVTVyhPUF9CVVNXXzgpIHwgT1BfRFVNTVlfQ1lDKDB4M0YpIHwK PiArCQkJICAgICAgIE9QX1JFQUQsIG5mYy0+cmVncyArIFNTX0NUUkwoMCkpOwo+ICsJCQlyZXQg PSBteGljX25mY19kYXRhX3hmZXIobmZjLCBOVUxMLAo+ICsJCQkJCQkgaW5zdHItPmN0eC5kYXRh LmJ1Zi5pbiwKPiArCQkJCQkJIGluc3RyLT5jdHguZGF0YS5sZW4pOwo+ICsJCQlicmVhazsKPiAr Cj4gKwkJY2FzZSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSOgo+ICsJCQl3cml0ZWwoaW5zdHItPmN0 eC5kYXRhLmxlbiwKPiArCQkJICAgICAgIG5mYy0+cmVncyArIE9ORklfRElOX0NOVCgwKSk7Cj4g KwkJCXdyaXRlbChPUF9EQVRBX0JVU1coT1BfQlVTV184KSB8IE9QX0RVTU1ZX0NZQygweDNGKSwK PiArCQkJICAgICAgIG5mYy0+cmVncyArIFNTX0NUUkwoMCkpOwo+ICsJCQlyZXQgPSBteGljX25m Y19kYXRhX3hmZXIobmZjLAo+ICsJCQkJCQkgaW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQsIE5VTEws Cj4gKwkJCQkJCSBpbnN0ci0+Y3R4LmRhdGEubGVuKTsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNh c2UgTkFORF9PUF9XQUlUUkRZX0lOU1RSOgo+ICsJCQlyZXQgPSBteGljX25mY193YWl0X3JlYWR5 KGNoaXApOwo+ICsJCQlicmVhazsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJbXhpY19uZmNfY3NfZGlz YWJsZShuZmMpOwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGludCBteGljX25m Y19zZXR1cF9kYXRhX2ludGVyZmFjZShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCBpbnQgY2hpcG5y LAo+ICsJCQkJCSBjb25zdCBzdHJ1Y3QgbmFuZF9kYXRhX2ludGVyZmFjZSAqY29uZikKPiArewo+ ICsJc3RydWN0IG14aWNfbmFuZF9jdGxyICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEo Y2hpcCk7Cj4gKwljb25zdCBzdHJ1Y3QgbmFuZF9zZHJfdGltaW5ncyAqc2RyOwo+ICsJdW5zaWdu ZWQgbG9uZyBmcmVxOwo+ICsKPiArCXNkciA9IG5hbmRfZ2V0X3Nkcl90aW1pbmdzKGNvbmYpOwo+ ICsJaWYgKElTX0VSUihzZHIpKQo+ICsJCXJldHVybiBQVFJfRVJSKHNkcik7Cj4gKwo+ICsJaWYg KGNoaXBuciA8IDApCj4gKwkJcmV0dXJuIDA7Cj4gKwo+ICsJaWYgKHNkci0+dFJDX21pbikKPiAr CQlmcmVxID0gMTAwMDAwMDAwMCAvIChzZHItPnRSQ19taW4gLyAxMDAwKTsKPiArCj4gKwlyZXR1 cm4gbXhpY19uZmNfc2V0X2ZyZXEobmZjLCBmcmVxKTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBuYW5kX2NvbnRyb2xsZXJfb3BzIG14aWNfbmFuZF9jb250cm9sbGVyX29wcyA9IHsK PiArCS5leGVjX29wID0gbXhpY19uZmNfZXhlY19vcCwKPiArCS5zZXR1cF9kYXRhX2ludGVyZmFj ZSA9IG14aWNfbmZjX3NldHVwX2RhdGFfaW50ZXJmYWNlLAo+ICt9Owo+ICsKPiArc3RhdGljIGlu dCBteGljX25mY19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlz dHJ1Y3QgbXRkX2luZm8gKm10ZDsKPiArCXN0cnVjdCBteGljX25hbmRfY3RsciAqbmZjOwo+ICsJ c3RydWN0IG14aWNfbmFuZF9jaGlwICpteGljX25hbmQ7Cj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpu YW5kX2NoaXA7Cj4gKwlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsKPiArCWludCBlcnI7Cj4gKwo+ICsJ bmZjID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZihzdHJ1Y3QgbXhpY19uYW5kX2N0 bHIpLAo+ICsJCQkgICBHRlBfS0VSTkVMKTsKPiArCWlmICghbmZjKQo+ICsJCXJldHVybiAtRU5P TUVNOwo+ICsKPiArCW14aWNfbmFuZCA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2Yo c3RydWN0IG14aWNfbmFuZF9jaGlwKSwKPiArCQkJCSBHRlBfS0VSTkVMKTsKPiArCWlmICghbXhp Y19uYW5kKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCW5mYy0+cHNfY2xrID0gZGV2bV9j bGtfZ2V0KCZwZGV2LT5kZXYsICJwc19jbGsiKTsKPiArCWlmIChJU19FUlIobmZjLT5wc19jbGsp KQo+ICsJCXJldHVybiBQVFJfRVJSKG5mYy0+cHNfY2xrKTsKPiArCj4gKwluZmMtPnNlbmRfY2xr ID0gZGV2bV9jbGtfZ2V0KCZwZGV2LT5kZXYsICJzZW5kX2NsayIpOwo+ICsJaWYgKElTX0VSUihu ZmMtPnNlbmRfY2xrKSkKPiArCQlyZXR1cm4gUFRSX0VSUihuZmMtPnNlbmRfY2xrKTsKPiArCj4g KwluZmMtPnNlbmRfZGx5X2NsayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAic2VuZF9kbHlf Y2xrIik7Cj4gKwlpZiAoSVNfRVJSKG5mYy0+c2VuZF9kbHlfY2xrKSkKPiArCQlyZXR1cm4gUFRS X0VSUihuZmMtPnNlbmRfZGx5X2Nsayk7Cj4gKwo+ICsJcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291 cmNlX2J5bmFtZShwZGV2LCBJT1JFU09VUkNFX01FTSwgInJlZ3MiKTsKPiArCW5mYy0+cmVncyA9 IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOwo+ICsJaWYgKElTX0VSUihu ZmMtPnJlZ3MpKQo+ICsJCXJldHVybiBQVFJfRVJSKG5mYy0+cmVncyk7Cj4gKwo+ICsJbmFuZF9j aGlwID0gJm14aWNfbmFuZC0+Y2hpcDsKPiArCW10ZCA9IG5hbmRfdG9fbXRkKG5hbmRfY2hpcCk7 Cj4gKwltdGQtPmRldi5wYXJlbnQgPSAmcGRldi0+ZGV2Owo+ICsJbmFuZF9jaGlwLT5lY2MucHJp diA9IE5VTEw7Cj4gKwluYW5kX3NldF9mbGFzaF9ub2RlKG5hbmRfY2hpcCwgcGRldi0+ZGV2Lm9m X25vZGUpOwo+ICsJbmFuZF9jaGlwLT5wcml2ID0gbmZjOwo+ICsJbmZjLT5wcml2ID0gbmFuZF9j aGlwOwo+ICsKPiArCW5mYy0+Y29udHJvbGxlci5vcHMgPSAmbXhpY19uYW5kX2NvbnRyb2xsZXJf b3BzOwo+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJm5mYy0+Y29udHJvbGxlcik7Cj4gKwluYW5k X2NoaXAtPmNvbnRyb2xsZXIgPSAmbmZjLT5jb250cm9sbGVyOwo+ICsKPiArCW14aWNfbmZjX2h3 X2luaXQobmZjKTsKPiArCj4gKwllcnIgPSBuYW5kX3NjYW4obmFuZF9jaGlwLCAxKTsKPiArCWlm IChlcnIpCj4gKwkJZ290byBmYWlsOwo+ICsKPiArCWVyciA9IG10ZF9kZXZpY2VfcmVnaXN0ZXIo bXRkLCBOVUxMLCAwKTsKPiArCWlmIChlcnIpCj4gKwkJZ290byBmYWlsOwo+ICsKPiArCXBsYXRm b3JtX3NldF9kcnZkYXRhKHBkZXYsIG5mYyk7Cj4gKwlyZXR1cm4gMDsKPiArCj4gK2ZhaWw6Cj4g KwlteGljX25mY19jbGtfZGlzYWJsZShuZmMpOwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5m Yy0+cHNfY2xrKTsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXhpY19u ZmNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBt eGljX25hbmRfY3RsciAqbmZjID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7Cj4gKwo+ICsJ bmFuZF9yZWxlYXNlKG5mYy0+cHJpdik7Cj4gKwlteGljX25mY19jbGtfZGlzYWJsZShuZmMpOwo+ ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5mYy0+cHNfY2xrKTsKPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgbXhpY19uZmNfb2Zf aWRzW10gPSB7Cj4gKwl7IC5jb21wYXRpYmxlID0gIm14aWMscmF3LW5hbmQtY3RsciIsIH0sCj4g Kwl7fSwKPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgbXhpY19uZmNfb2ZfaWRzKTsK PiArCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG14aWNfbmZjX2RyaXZlciA9IHsK PiArCS5wcm9iZSA9IG14aWNfbmZjX3Byb2JlLAo+ICsJLnJlbW92ZSA9IG14aWNfbmZjX3JlbW92 ZSwKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAibXhpYy1uZmMiLAo+ICsJCS5vZl9tYXRj aF90YWJsZSA9IG14aWNfbmZjX29mX2lkcywKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9y bV9kcml2ZXIobXhpY19uZmNfZHJpdmVyKTsKPiArCj4gK01PRFVMRV9BVVRIT1IoIk1hc29uIFlh bmcgPG1hc29uY2N5YW5nQG14aWMuY29tLnR3PiIpOwo+ICtNT0RVTEVfREVTQ1JJUFRJT04oIk1h Y3Jvbml4IFJBVyBOQU5EIEZsYXNoIENvbnRyb2xsZXIgZHJpdmVyIik7Cj4gK01PRFVMRV9MSUNF TlNFKCJHUEwgdjIiKTsKCgoKClRoYW5rcywKTWlxdcOobAoKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4IE1URCBkaXNjdXNzaW9uIG1h aWxpbmcgbGlzdApodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xp bnV4LW10ZC8K From mboxrd@z Thu Jan 1 00:00:00 1970 From: Miquel Raynal Subject: Re: [PATCH v4 1/2] mtd: rawnand: Add Macronix Raw NAND controller Date: Thu, 27 Jun 2019 19:36:35 +0200 Message-ID: <20190627193635.29abff43@xps13> References: <1561443056-13766-1-git-send-email-masonccyang@mxic.com.tw> <1561443056-13766-2-git-send-email-masonccyang@mxic.com.tw> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Return-path: In-Reply-To: <1561443056-13766-2-git-send-email-masonccyang@mxic.com.tw> Sender: linux-kernel-owner@vger.kernel.org To: Mason Yang Cc: marek.vasut@gmail.com, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, bbrezillon@kernel.org, dwmw2@infradead.org, computersforpeace@gmail.com, vigneshr@ti.com, paul.burton@mips.com, liang.yang@amlogic.com, richard@nod.at, anders.roxell@linaro.org, christophe.kerello@st.com, paul@crapouillou.net, jianxin.pan@amlogic.com, stefan@agner.ch, devicetree@vger.kernel.org, juliensu@mxic.com.tw, lee.jones@linaro.org, broonie@kernel.org List-Id: devicetree@vger.kernel.org Hi Mason, Mason Yang wrote on Tue, 25 Jun 2019 14:10:55 +0800: > Add a driver for Macronix raw NAND controller. Could you pass userspace major MTD tests and can you attach/mount/edit a UBI/UBIFS storage? Looks pretty nice to me, a few comments below. > > Signed-off-by: Mason Yang > --- > drivers/mtd/nand/raw/Kconfig | 6 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/mxic_nand.c | 551 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 558 insertions(+) > create mode 100644 drivers/mtd/nand/raw/mxic_nand.c > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index 5a711d8..9cff36a 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -407,6 +407,12 @@ config MTD_NAND_MTK > Enables support for NAND controller on MTK SoCs. > This controller is found on mt27xx, mt81xx, mt65xx SoCs. > > +config MTD_NAND_MXIC > + tristate "Macronix raw NAND controller" > + depends on HAS_IOMEM || COMPILE_TEST > + help > + This selects the Macronix raw NAND controller driver. > + > config MTD_NAND_TEGRA > tristate "NVIDIA Tegra NAND controller" > depends on ARCH_TEGRA || COMPILE_TEST > diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile > index efaf5cd..9b43fbf 100644 > --- a/drivers/mtd/nand/raw/Makefile > +++ b/drivers/mtd/nand/raw/Makefile > @@ -54,6 +54,7 @@ obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o > obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ > obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o > obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o > +obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o > obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o > obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o > obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o > diff --git a/drivers/mtd/nand/raw/mxic_nand.c b/drivers/mtd/nand/raw/mxic_nand.c > new file mode 100644 > index 0000000..14c0b3b > --- /dev/null > +++ b/drivers/mtd/nand/raw/mxic_nand.c > @@ -0,0 +1,551 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2019 Macronix International Co., Ltd. > + * > + * Author: > + * Mason Yang > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "internals.h" > + > +#define HC_CFG 0x0 > +#define HC_CFG_IF_CFG(x) ((x) << 27) > +#define HC_CFG_DUAL_SLAVE BIT(31) > +#define HC_CFG_INDIVIDUAL BIT(30) > +#define HC_CFG_NIO(x) (((x) / 4) << 27) > +#define HC_CFG_TYPE(s, t) ((t) << (23 + ((s) * 2))) > +#define HC_CFG_TYPE_SPI_NOR 0 > +#define HC_CFG_TYPE_SPI_NAND 1 > +#define HC_CFG_TYPE_SPI_RAM 2 > +#define HC_CFG_TYPE_RAW_NAND 3 > +#define HC_CFG_SLV_ACT(x) ((x) << 21) > +#define HC_CFG_CLK_PH_EN BIT(20) > +#define HC_CFG_CLK_POL_INV BIT(19) > +#define HC_CFG_BIG_ENDIAN BIT(18) > +#define HC_CFG_DATA_PASS BIT(17) > +#define HC_CFG_IDLE_SIO_LVL(x) ((x) << 16) > +#define HC_CFG_MAN_START_EN BIT(3) > +#define HC_CFG_MAN_START BIT(2) > +#define HC_CFG_MAN_CS_EN BIT(1) > +#define HC_CFG_MAN_CS_ASSERT BIT(0) > + > +#define INT_STS 0x4 > +#define INT_STS_EN 0x8 > +#define INT_SIG_EN 0xc > +#define INT_STS_ALL GENMASK(31, 0) > +#define INT_RDY_PIN BIT(26) > +#define INT_RDY_SR BIT(25) > +#define INT_LNR_SUSP BIT(24) > +#define INT_ECC_ERR BIT(17) > +#define INT_CRC_ERR BIT(16) > +#define INT_LWR_DIS BIT(12) > +#define INT_LRD_DIS BIT(11) > +#define INT_SDMA_INT BIT(10) > +#define INT_DMA_FINISH BIT(9) > +#define INT_RX_NOT_FULL BIT(3) > +#define INT_RX_NOT_EMPTY BIT(2) > +#define INT_TX_NOT_FULL BIT(1) > +#define INT_TX_EMPTY BIT(0) > + > +#define HC_EN 0x10 > +#define HC_EN_BIT BIT(0) > + > +#define TXD(x) (0x14 + ((x) * 4)) > +#define RXD 0x24 > + > +#define SS_CTRL(s) (0x30 + ((s) * 4)) > +#define LRD_CFG 0x44 > +#define LWR_CFG 0x80 > +#define RWW_CFG 0x70 > +#define OP_READ BIT(23) > +#define OP_DUMMY_CYC(x) ((x) << 17) > +#define OP_ADDR_BYTES(x) ((x) << 14) > +#define OP_CMD_BYTES(x) (((x) - 1) << 13) > +#define OP_OCTA_CRC_EN BIT(12) > +#define OP_DQS_EN BIT(11) > +#define OP_ENHC_EN BIT(10) > +#define OP_PREAMBLE_EN BIT(9) > +#define OP_DATA_DDR BIT(8) > +#define OP_DATA_BUSW(x) ((x) << 6) > +#define OP_ADDR_DDR BIT(5) > +#define OP_ADDR_BUSW(x) ((x) << 3) > +#define OP_CMD_DDR BIT(2) > +#define OP_CMD_BUSW(x) (x) > +#define OP_BUSW_1 0 > +#define OP_BUSW_2 1 > +#define OP_BUSW_4 2 > +#define OP_BUSW_8 3 > + > +#define OCTA_CRC 0x38 > +#define OCTA_CRC_IN_EN(s) BIT(3 + ((s) * 16)) > +#define OCTA_CRC_CHUNK(s, x) ((fls((x) / 32)) << (1 + ((s) * 16))) > +#define OCTA_CRC_OUT_EN(s) BIT(0 + ((s) * 16)) > + > +#define ONFI_DIN_CNT(s) (0x3c + (s)) > + > +#define LRD_CTRL 0x48 > +#define RWW_CTRL 0x74 > +#define LWR_CTRL 0x84 > +#define LMODE_EN BIT(31) > +#define LMODE_SLV_ACT(x) ((x) << 21) > +#define LMODE_CMD1(x) ((x) << 8) > +#define LMODE_CMD0(x) (x) > + > +#define LRD_ADDR 0x4c > +#define LWR_ADDR 0x88 > +#define LRD_RANGE 0x50 > +#define LWR_RANGE 0x8c > + > +#define AXI_SLV_ADDR 0x54 > + > +#define DMAC_RD_CFG 0x58 > +#define DMAC_WR_CFG 0x94 > +#define DMAC_CFG_PERIPH_EN BIT(31) > +#define DMAC_CFG_ALLFLUSH_EN BIT(30) > +#define DMAC_CFG_LASTFLUSH_EN BIT(29) > +#define DMAC_CFG_QE(x) (((x) + 1) << 16) > +#define DMAC_CFG_BURST_LEN(x) (((x) + 1) << 12) > +#define DMAC_CFG_BURST_SZ(x) ((x) << 8) > +#define DMAC_CFG_DIR_READ BIT(1) > +#define DMAC_CFG_START BIT(0) > + > +#define DMAC_RD_CNT 0x5c > +#define DMAC_WR_CNT 0x98 > + > +#define SDMA_ADDR 0x60 > + > +#define DMAM_CFG 0x64 > +#define DMAM_CFG_START BIT(31) > +#define DMAM_CFG_CONT BIT(30) > +#define DMAM_CFG_SDMA_GAP(x) (fls((x) / 8192) << 2) > +#define DMAM_CFG_DIR_READ BIT(1) > +#define DMAM_CFG_EN BIT(0) > + > +#define DMAM_CNT 0x68 > + > +#define LNR_TIMER_TH 0x6c > + > +#define RDM_CFG0 0x78 > +#define RDM_CFG0_POLY(x) (x) > + > +#define RDM_CFG1 0x7c > +#define RDM_CFG1_RDM_EN BIT(31) > +#define RDM_CFG1_SEED(x) (x) > + > +#define LWR_SUSP_CTRL 0x90 > +#define LWR_SUSP_CTRL_EN BIT(31) > + > +#define DMAS_CTRL 0x9c > +#define DMAS_CTRL_DIR_READ BIT(31) > +#define DMAS_CTRL_EN BIT(30) > + > +#define DATA_STROB 0xa0 > +#define DATA_STROB_EDO_EN BIT(2) > +#define DATA_STROB_INV_POL BIT(1) > +#define DATA_STROB_DELAY_2CYC BIT(0) > + > +#define IDLY_CODE(x) (0xa4 + ((x) * 4)) > +#define IDLY_CODE_VAL(x, v) ((v) << (((x) % 4) * 8)) > + > +#define GPIO 0xc4 > +#define GPIO_PT(x) BIT(3 + ((x) * 16)) > +#define GPIO_RESET(x) BIT(2 + ((x) * 16)) > +#define GPIO_HOLDB(x) BIT(1 + ((x) * 16)) > +#define GPIO_WPB(x) BIT((x) * 16) > + > +#define HC_VER 0xd0 > + > +#define HW_TEST(x) (0xe0 + ((x) * 4)) > + > +#define MXIC_NFC_MAX_CLK_HZ 50000000 > + > +struct mxic_nand_ctlr { > + struct clk *ps_clk; > + struct clk *send_clk; > + struct clk *send_dly_clk; > + void __iomem *regs; > + struct nand_controller controller; > + void *priv; > +}; > + > +struct mxic_nand_chip { > + struct nand_chip chip; > +}; > + > +static int mxic_nfc_clk_enable(struct mxic_nand_ctlr *nfc) > +{ > + int ret; > + > + ret = clk_prepare_enable(nfc->send_clk); > + if (ret) > + return ret; > + > + ret = clk_prepare_enable(nfc->send_dly_clk); > + if (ret) > + goto err_send_dly_clk; I'm not sure why you only enable 2 out of 3 clocks and also why ou handle two of them here (which is great, I prefer having a separate helper for that) and the other one elsewhere? > + > + return ret; > + > +err_send_dly_clk: > + clk_disable_unprepare(nfc->send_clk); > + > + return ret; > +} > + > +static void mxic_nfc_clk_disable(struct mxic_nand_ctlr *nfc) > +{ > + clk_disable_unprepare(nfc->send_clk); > + clk_disable_unprepare(nfc->send_dly_clk); > +} > + > +static void mxic_nfc_set_input_delay(struct mxic_nand_ctlr *nfc, u8 idly_code) > +{ > + writel(IDLY_CODE_VAL(0, idly_code) | > + IDLY_CODE_VAL(1, idly_code) | > + IDLY_CODE_VAL(2, idly_code) | > + IDLY_CODE_VAL(3, idly_code), > + nfc->regs + IDLY_CODE(0)); > + writel(IDLY_CODE_VAL(4, idly_code) | > + IDLY_CODE_VAL(5, idly_code) | > + IDLY_CODE_VAL(6, idly_code) | > + IDLY_CODE_VAL(7, idly_code), > + nfc->regs + IDLY_CODE(1)); > +} > + > +static int mxic_nfc_clk_setup(struct mxic_nand_ctlr *nfc, unsigned long freq) > +{ > + int ret; > + > + ret = clk_set_rate(nfc->send_clk, freq); > + if (ret) > + return ret; > + > + ret = clk_set_rate(nfc->send_dly_clk, freq); > + if (ret) > + return ret; > + > + /* > + * A constant delay range from 0x0 ~ 0x1F for input delay, > + * the unit is 78 ps, the max input delay is 2.418 ns. > + */ > + mxic_nfc_set_input_delay(nfc, 0xf); > + > + /* > + * Phase degree = 360 * freq * output-delay > + * where output-delay is a constant value 1 ns in FPGA. Will it always be in FPGA? > + * > + * Get Phase degree = 360 * freq * 1 ns > + * = 360 * freq * 1 sec / 1000000000 > + * = 9 * freq / 25000000 > + */ > + ret = clk_set_phase(nfc->send_dly_clk, 9 * freq / 25000000); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static int mxic_nfc_set_freq(struct mxic_nand_ctlr *nfc, unsigned long freq) > +{ > + int ret; > + > + if (freq > MXIC_NFC_MAX_CLK_HZ) > + freq = MXIC_NFC_MAX_CLK_HZ; > + > + mxic_nfc_clk_disable(nfc); > + ret = mxic_nfc_clk_setup(nfc, freq); > + if (ret) > + return ret; > + > + ret = mxic_nfc_clk_enable(nfc); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static void mxic_nfc_hw_init(struct mxic_nand_ctlr *nfc) > +{ > + writel(DATA_STROB_EDO_EN, nfc->regs + DATA_STROB); > + writel(HC_CFG_NIO(8) | HC_CFG_TYPE(1, HC_CFG_TYPE_RAW_NAND) | > + HC_CFG_SLV_ACT(0) | HC_CFG_MAN_CS_EN | > + HC_CFG_IDLE_SIO_LVL(1), nfc->regs + HC_CFG); > + writel(INT_STS_ALL, nfc->regs + INT_STS_EN); > + writel(0x0, nfc->regs + ONFI_DIN_CNT(0)); > + writel(0, nfc->regs + LRD_CFG); > + writel(0, nfc->regs + LRD_CTRL); > + writel(0x0, nfc->regs + HC_EN); > + > + /* Default 10 MHz to setup tRC_min/tWC_min:100 ns */ > + mxic_nfc_set_freq(nfc, 10000000); > +} > + > +static void mxic_nfc_cs_enable(struct mxic_nand_ctlr *nfc) > +{ > + writel(readl(nfc->regs + HC_CFG) | HC_CFG_MAN_CS_EN, > + nfc->regs + HC_CFG); > + writel(HC_CFG_MAN_CS_ASSERT | readl(nfc->regs + HC_CFG), > + nfc->regs + HC_CFG); So you can drive only one CS with this controller? > +} > + > +static void mxic_nfc_cs_disable(struct mxic_nand_ctlr *nfc) > +{ > + writel(~HC_CFG_MAN_CS_ASSERT & readl(nfc->regs + HC_CFG), > + nfc->regs + HC_CFG); > +} > + > +static int mxic_nfc_wait_ready(struct nand_chip *chip) > +{ > + struct mxic_nand_ctlr *nfc = nand_get_controller_data(chip); > + u32 sts; > + > + return readl_poll_timeout(nfc->regs + INT_STS, sts, > + sts & INT_RDY_PIN, 0, USEC_PER_SEC); > +} > + > +static int mxic_nfc_data_xfer(struct mxic_nand_ctlr *nfc, const void *txbuf, > + void *rxbuf, unsigned int len) > +{ > + unsigned int pos = 0; > + > + while (pos < len) { > + unsigned int nbytes = len - pos; > + u32 data = 0xffffffff; > + u32 sts; > + int ret; > + > + if (nbytes > 4) > + nbytes = 4; > + > + if (txbuf) > + memcpy(&data, txbuf + pos, nbytes); > + > + ret = readl_poll_timeout(nfc->regs + INT_STS, sts, > + sts & INT_TX_EMPTY, 0, USEC_PER_SEC); > + if (ret) > + return ret; > + > + writel(data, nfc->regs + TXD(nbytes % 4)); > + > + if (rxbuf) { > + ret = readl_poll_timeout(nfc->regs + INT_STS, sts, > + sts & INT_TX_EMPTY, 0, > + USEC_PER_SEC); > + if (ret) > + return ret; > + > + ret = readl_poll_timeout(nfc->regs + INT_STS, sts, > + sts & INT_RX_NOT_EMPTY, 0, > + USEC_PER_SEC); > + if (ret) > + return ret; > + > + data = readl(nfc->regs + RXD); > + data >>= (8 * (4 - nbytes)); > + memcpy(rxbuf + pos, &data, nbytes); > + WARN_ON(readl(nfc->regs + INT_STS) & INT_RX_NOT_EMPTY); > + } else { > + readl(nfc->regs + RXD); > + } > + WARN_ON(readl(nfc->regs + INT_STS) & INT_RX_NOT_EMPTY); WARN_ON() is maybe a bit overkill here? > + > + pos += nbytes; > + } > + > + return 0; > +} > + > +static int mxic_nfc_exec_op(struct nand_chip *chip, > + const struct nand_operation *op, bool check_only) > +{ > + struct mxic_nand_ctlr *nfc = nand_get_controller_data(chip); > + const struct nand_op_instr *instr = NULL; > + int ret = 0; > + unsigned int op_id; > + > + mxic_nfc_cs_enable(nfc); > + > + for (op_id = 0; op_id < op->ninstrs; op_id++) { > + instr = &op->instrs[op_id]; > + > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + writel(0, nfc->regs + HC_EN); > + writel(HC_EN_BIT, nfc->regs + HC_EN); > + writel(OP_CMD_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F) | > + OP_CMD_BYTES(0), nfc->regs + SS_CTRL(0)); > + > + ret = mxic_nfc_data_xfer(nfc, > + &instr->ctx.cmd.opcode, > + NULL, 1); > + break; > + > + case NAND_OP_ADDR_INSTR: > + writel(OP_ADDR_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F) | > + OP_ADDR_BYTES(instr->ctx.addr.naddrs), > + nfc->regs + SS_CTRL(0)); > + ret = mxic_nfc_data_xfer(nfc, > + instr->ctx.addr.addrs, NULL, > + instr->ctx.addr.naddrs); > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + writel(0x0, nfc->regs + ONFI_DIN_CNT(0)); > + writel(OP_DATA_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F) | > + OP_READ, nfc->regs + SS_CTRL(0)); > + ret = mxic_nfc_data_xfer(nfc, NULL, > + instr->ctx.data.buf.in, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + writel(instr->ctx.data.len, > + nfc->regs + ONFI_DIN_CNT(0)); > + writel(OP_DATA_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F), > + nfc->regs + SS_CTRL(0)); > + ret = mxic_nfc_data_xfer(nfc, > + instr->ctx.data.buf.out, NULL, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + ret = mxic_nfc_wait_ready(chip); > + break; > + } > + } > + > + mxic_nfc_cs_disable(nfc); > + return ret; > +} > + > +static int mxic_nfc_setup_data_interface(struct nand_chip *chip, int chipnr, > + const struct nand_data_interface *conf) > +{ > + struct mxic_nand_ctlr *nfc = nand_get_controller_data(chip); > + const struct nand_sdr_timings *sdr; > + unsigned long freq; > + > + sdr = nand_get_sdr_timings(conf); > + if (IS_ERR(sdr)) > + return PTR_ERR(sdr); > + > + if (chipnr < 0) > + return 0; > + > + if (sdr->tRC_min) > + freq = 1000000000 / (sdr->tRC_min / 1000); > + > + return mxic_nfc_set_freq(nfc, freq); > +} > + > +static const struct nand_controller_ops mxic_nand_controller_ops = { > + .exec_op = mxic_nfc_exec_op, > + .setup_data_interface = mxic_nfc_setup_data_interface, > +}; > + > +static int mxic_nfc_probe(struct platform_device *pdev) > +{ > + struct mtd_info *mtd; > + struct mxic_nand_ctlr *nfc; > + struct mxic_nand_chip *mxic_nand; > + struct nand_chip *nand_chip; > + struct resource *res; > + int err; > + > + nfc = devm_kzalloc(&pdev->dev, sizeof(struct mxic_nand_ctlr), > + GFP_KERNEL); > + if (!nfc) > + return -ENOMEM; > + > + mxic_nand = devm_kzalloc(&pdev->dev, sizeof(struct mxic_nand_chip), > + GFP_KERNEL); > + if (!mxic_nand) > + return -ENOMEM; > + > + nfc->ps_clk = devm_clk_get(&pdev->dev, "ps_clk"); > + if (IS_ERR(nfc->ps_clk)) > + return PTR_ERR(nfc->ps_clk); > + > + nfc->send_clk = devm_clk_get(&pdev->dev, "send_clk"); > + if (IS_ERR(nfc->send_clk)) > + return PTR_ERR(nfc->send_clk); > + > + nfc->send_dly_clk = devm_clk_get(&pdev->dev, "send_dly_clk"); > + if (IS_ERR(nfc->send_dly_clk)) > + return PTR_ERR(nfc->send_dly_clk); > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); > + nfc->regs = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(nfc->regs)) > + return PTR_ERR(nfc->regs); > + > + nand_chip = &mxic_nand->chip; > + mtd = nand_to_mtd(nand_chip); > + mtd->dev.parent = &pdev->dev; > + nand_chip->ecc.priv = NULL; > + nand_set_flash_node(nand_chip, pdev->dev.of_node); > + nand_chip->priv = nfc; > + nfc->priv = nand_chip; > + > + nfc->controller.ops = &mxic_nand_controller_ops; > + nand_controller_init(&nfc->controller); > + nand_chip->controller = &nfc->controller; > + > + mxic_nfc_hw_init(nfc); > + > + err = nand_scan(nand_chip, 1); > + if (err) > + goto fail; > + > + err = mtd_device_register(mtd, NULL, 0); > + if (err) > + goto fail; > + > + platform_set_drvdata(pdev, nfc); > + return 0; > + > +fail: > + mxic_nfc_clk_disable(nfc); > + clk_disable_unprepare(nfc->ps_clk); > + return err; > +} > + > +static int mxic_nfc_remove(struct platform_device *pdev) > +{ > + struct mxic_nand_ctlr *nfc = platform_get_drvdata(pdev); > + > + nand_release(nfc->priv); > + mxic_nfc_clk_disable(nfc); > + clk_disable_unprepare(nfc->ps_clk); > + > + return 0; > +} > + > +static const struct of_device_id mxic_nfc_of_ids[] = { > + { .compatible = "mxic,raw-nand-ctlr", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, mxic_nfc_of_ids); > + > +static struct platform_driver mxic_nfc_driver = { > + .probe = mxic_nfc_probe, > + .remove = mxic_nfc_remove, > + .driver = { > + .name = "mxic-nfc", > + .of_match_table = mxic_nfc_of_ids, > + }, > +}; > +module_platform_driver(mxic_nfc_driver); > + > +MODULE_AUTHOR("Mason Yang "); > +MODULE_DESCRIPTION("Macronix RAW NAND Flash Controller driver"); > +MODULE_LICENSE("GPL v2"); Thanks, Miquèl