diff mbox series

[OpenWrt-Devel] ath79: fix NAND driver compilation for kernel 5.4

Message ID 20200317205927.26314-1-mail@david-bauer.net
State Accepted
Delegated to: David Bauer
Headers show
Series [OpenWrt-Devel] ath79: fix NAND driver compilation for kernel 5.4 | expand

Commit Message

David Bauer March 17, 2020, 8:59 p.m. UTC
This fixes the compilation of the AR934x NAND controller
driver for kernel 5.4 while leaving it untouched for
kernel 4.19.

This change is currently not run-tested, as i do not have such
a device at hand.

CC: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
CC: André Valentin <avalentin@marcant.net>
CC: WeiDong Jia <jwdsccd@gmail.com>
Signed-off-by: David Bauer <mail@david-bauer.net>
---
 .../files/drivers/mtd/nand/raw/ar934x_nand.c  | 127 +++++++++++++++++-
 1 file changed, 122 insertions(+), 5 deletions(-)

Comments

Michal Cieslakiewicz March 22, 2020, 11:35 a.m. UTC | #1
On Tue, 17 Mar 2020 21:59:27 +0100
David Bauer <mail@david-bauer.net> wrote:

> This fixes the compilation of the AR934x NAND controller
> driver for kernel 5.4 while leaving it untouched for
> kernel 4.19.
> 
> This change is currently not run-tested, as i do not have such
> a device at hand.
> 

Hello David,

Good news, Netgear WNDR4300 runs fine on kernel 5.4 with this patch
applied.

Tested-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>

I would also propose to mitigate two compilation warnings by
introducing a return value here (by integrating into your patch):

=========
diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
index 70aa396e25..0e33b07146 100644
--- a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
+++ b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
@@ -1082,14 +1082,24 @@ static int ar934x_nfc_write_page(struct nand_chip *chip,
 	return err;
 }
 
-static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc) {
-	reset_control_assert(nfc->rst);
+static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc)
+{
+	int err;
+
+	err = reset_control_assert(nfc->rst);
 	udelay(250);
+
+	return err;
 }
 
-static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc) {
-	reset_control_deassert(nfc->rst);
+static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc)
+{
+	int err;
+
+	err = reset_control_deassert(nfc->rst);
 	udelay(250);
+
+	return err;
 }
 
 static int ar934x_nfc_hw_init(struct ar934x_nfc *nfc)
=========

And finally, an important information:

Enabling 5.4 for this device exposes a mtd concat issue unrelated
to ar934x-nand driver, apparently affecting all routers that use 
concatenation of flash areas to form one larger volume for ubi. 
This appears to be a generic 5.x kernel problem not introduced by 
OpenWrt in any way.

The quick and dirty solution that worked for me was reverting kernel
patch:

commit 2431c4f5b46c32c4ac495456b1ef4ce59c0bb85d
Author: Boris Brezillon <bbrezillon@kernel.org>
Date:   Thu Dec 20 15:13:20 2018 +0100

    mtd: Implement mtd_{read,write}() as wrappers around
    mtd_{read,write}_oob()

    mtd_{read,write}_oob() already take care of checking the params and
    calling ->_{read,write}() or  ->_{read,write}_oob() based on the
    request and the operations supported by the MTD device.
    No need to duplicate the logic, we can simply implement
    mtd_{read,write}() as wrappers around mtd_{read,write}_oob().

Above commit makes router to oops on WARN_ON canary and exit with error
when creating mtd concat, entering boot loop. Without it my WNDR4300 runs
fine so far.

Best regards
Michal
David Bauer March 22, 2020, 7:01 p.m. UTC | #2
Hi Michal

On 3/22/20 12:35 PM, Michal Cieslakiewicz wrote:
> On Tue, 17 Mar 2020 21:59:27 +0100
> David Bauer <mail@david-bauer.net> wrote:
> 
>> This fixes the compilation of the AR934x NAND controller
>> driver for kernel 5.4 while leaving it untouched for
>> kernel 4.19.
>>
>> This change is currently not run-tested, as i do not have such
>> a device at hand.
>>
> 
> Hello David,
> 
> Good news, Netgear WNDR4300 runs fine on kernel 5.4 with this patch
> applied.

Great to hear!

> 
> Tested-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
> 
> I would also propose to mitigate two compilation warnings by
> introducing a return value here (by integrating into your patch):

I was thinking about the same, but i would like to have this patch touch as little 4.19
code as possible. However, i will look into fixing this in a seperate patch (in case you
are not faster than me) ;)

> 
> =========
> diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
> index 70aa396e25..0e33b07146 100644
> --- a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
> +++ b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
> @@ -1082,14 +1082,24 @@ static int ar934x_nfc_write_page(struct nand_chip *chip,
>  	return err;
>  }
>  
> -static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc) {
> -	reset_control_assert(nfc->rst);
> +static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc)
> +{
> +	int err;
> +
> +	err = reset_control_assert(nfc->rst);
>  	udelay(250);
> +
> +	return err;
>  }
>  
> -static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc) {
> -	reset_control_deassert(nfc->rst);
> +static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc)
> +{
> +	int err;
> +
> +	err = reset_control_deassert(nfc->rst);
>  	udelay(250);
> +
> +	return err;
>  }
>  
>  static int ar934x_nfc_hw_init(struct ar934x_nfc *nfc)
> =========
> 
> And finally, an important information:
> 
> Enabling 5.4 for this device exposes a mtd concat issue unrelated
> to ar934x-nand driver, apparently affecting all routers that use 
> concatenation of flash areas to form one larger volume for ubi. 
> This appears to be a generic 5.x kernel problem not introduced by 
> OpenWrt in any way.
> 
> The quick and dirty solution that worked for me was reverting kernel
> patch:
> 
> commit 2431c4f5b46c32c4ac495456b1ef4ce59c0bb85d
> Author: Boris Brezillon <bbrezillon@kernel.org>
> Date:   Thu Dec 20 15:13:20 2018 +0100
> 
>     mtd: Implement mtd_{read,write}() as wrappers around
>     mtd_{read,write}_oob()
> 
>     mtd_{read,write}_oob() already take care of checking the params and
>     calling ->_{read,write}() or  ->_{read,write}_oob() based on the
>     request and the operations supported by the MTD device.
>     No need to duplicate the logic, we can simply implement
>     mtd_{read,write}() as wrappers around mtd_{read,write}_oob().
> 
> Above commit makes router to oops on WARN_ON canary and exit with error
> when creating mtd concat, entering boot loop. Without it my WNDR4300 runs
> fine so far.

I'm not that deep into the mtd-concat hack (expecially on NAND flash). We might also run
into issues when migrating to the new NAND interface. If you you've found a fix for
this, it would be great to have it up for discussion on ML or GitHub. Especially as this
is more or less target independant and not directly associated with the ath79 driver.

Best wishes
David

> 
> Best regards
> Michal
>
Michal Cieslakiewicz March 23, 2020, 4:20 p.m. UTC | #3
On Sun, 22 Mar 2020 20:01:57 +0100
David Bauer <mail@david-bauer.net> wrote:

> Hi Michal
> 
> 
> I'm not that deep into the mtd-concat hack (expecially on NAND
> flash). We might also run into issues when migrating to the new NAND
> interface. If you you've found a fix for this, it would be great to
> have it up for discussion on ML or GitHub. Especially as this is more
> or less target independant and not directly associated with the ath79
> driver.
> 
> Best wishes
> David
> 

Hello David,

Yes, I'm going to have a deeper look at mtdconcat driver and try to
modify its behaviour to be consistent with what is now required by
mtdcore. Concat is a virtual device, address translation layer mainly,
so understanding how it works should not require any deep flash hacking
knowledge.

Cheers
Michal
Enrico Mioso March 23, 2020, 5:05 p.m. UTC | #4
Hello!!
A little bit off-topic question: I encountered an issue due to a patch causing issues on ramips:
<commit>

... so my Zbtlink ZBT-WG3526 (32M) behaved like SPI flash was damaged. After reverting the patch, anything was OK and the device is still running fine.
So, my question is: are there chances of damaing the flash chip when running on those situations where bugs happen?
and, what if things like those would happen in NAND flash devices? What if, for example, we mark as bad a block that wasn't bad after all?

thanks!!

Enrico

On Mon, 23 Mar 2020, Michal Cieslakiewicz wrote:

> Date: Mon, 23 Mar 2020 17:20:42
> From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
> To: David Bauer <mail@david-bauer.net>
> Cc: openwrt-devel@lists.openwrt.org
> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: fix NAND driver compilation for
>     kernel 5.4
> 
> On Sun, 22 Mar 2020 20:01:57 +0100
> David Bauer <mail@david-bauer.net> wrote:
>
>> Hi Michal
>>
>>
>> I'm not that deep into the mtd-concat hack (expecially on NAND
>> flash). We might also run into issues when migrating to the new NAND
>> interface. If you you've found a fix for this, it would be great to
>> have it up for discussion on ML or GitHub. Especially as this is more
>> or less target independant and not directly associated with the ath79
>> driver.
>>
>> Best wishes
>> David
>>
>
> Hello David,
>
> Yes, I'm going to have a deeper look at mtdconcat driver and try to
> modify its behaviour to be consistent with what is now required by
> mtdcore. Concat is a virtual device, address translation layer mainly,
> so understanding how it works should not require any deep flash hacking
> knowledge.
>
> Cheers
> Michal
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>

Enrico Mioso
Personal Phone Number: +39 3807096934
Tox ID is:
7C593F402A3C8632D87AB4B948D492294C39A6A614464ECF843CA3429FB023284180472C7475
Enrico Mioso March 23, 2020, 5:08 p.m. UTC | #5
sorry, I forgot to mention the commit...
In my case I am referring to an issue with commit
15a0701cdde8eeae2a54880b813cdb8cdc09a384.
fixed with commit fdfca33350150644481096f1c7a80db2b670cdec from David.
Thanks!


On Mon, 23 Mar 2020, Michal Cieslakiewicz wrote:

> Date: Mon, 23 Mar 2020 17:20:42
> From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
> To: David Bauer <mail@david-bauer.net>
> Cc: openwrt-devel@lists.openwrt.org
> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: fix NAND driver compilation for
>     kernel 5.4
> 
> On Sun, 22 Mar 2020 20:01:57 +0100
> David Bauer <mail@david-bauer.net> wrote:
>
>> Hi Michal
>>
>>
>> I'm not that deep into the mtd-concat hack (expecially on NAND
>> flash). We might also run into issues when migrating to the new NAND
>> interface. If you you've found a fix for this, it would be great to
>> have it up for discussion on ML or GitHub. Especially as this is more
>> or less target independant and not directly associated with the ath79
>> driver.
>>
>> Best wishes
>> David
>>
>
> Hello David,
>
> Yes, I'm going to have a deeper look at mtdconcat driver and try to
> modify its behaviour to be consistent with what is now required by
> mtdcore. Concat is a virtual device, address translation layer mainly,
> so understanding how it works should not require any deep flash hacking
> knowledge.
>
> Cheers
> Michal
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>

Enrico Mioso
Personal Phone Number: +39 3807096934
Tox ID is:
7C593F402A3C8632D87AB4B948D492294C39A6A614464ECF843CA3429FB023284180472C7475
diff mbox series

Patch

diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
index 58198e4465..70aa396e25 100644
--- a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
+++ b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c
@@ -631,11 +631,19 @@  static void ar934x_nfc_read_status(struct ar934x_nfc *nfc)
 		nfc->buf[0] = status;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static void ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 			       int column, int page_addr)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
 	struct nand_chip *nand = &nfc->nand_chip;
+#else
+static void ar934x_nfc_cmdfunc(struct nand_chip *nand, unsigned int command,
+			       int column, int page_addr)
+{
+	struct mtd_info *mtd = nand_to_mtd(nand);
+	struct ar934x_nfc *nfc = nand->priv;
+#endif
 
 	nfc->read_id = false;
 	if (command != NAND_CMD_PAGEPROG)
@@ -740,16 +748,28 @@  static void ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_dev_ready(struct mtd_info *mtd)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_dev_ready(struct nand_chip *chip)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+#endif
 
 	return __ar934x_nfc_dev_ready(nfc);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static u8 ar934x_nfc_read_byte(struct mtd_info *mtd)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static u8 ar934x_nfc_read_byte(struct nand_chip *chip)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+#endif
 	u8 data;
 
 	WARN_ON(nfc->buf_index >= nfc->buf_size);
@@ -764,9 +784,15 @@  static u8 ar934x_nfc_read_byte(struct mtd_info *mtd)
 	return data;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static void ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static void ar934x_nfc_write_buf(struct nand_chip *chip, const u8 *buf, int len)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+#endif
 	int i;
 
 	WARN_ON(nfc->buf_index + len > nfc->buf_size);
@@ -784,9 +810,15 @@  static void ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static void ar934x_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static void ar934x_nfc_read_buf(struct nand_chip *chip, u8 *buf, int len)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+#endif
 	int buf_index;
 	int i;
 
@@ -821,10 +853,18 @@  static inline void ar934x_nfc_disable_hwecc(struct ar934x_nfc *nfc)
 	nfc->ctrl_reg |= AR934X_NFC_CTRL_CUSTOM_SIZE_EN;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 			       int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_read_oob(struct nand_chip *chip,
+			       int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	int err;
 
 	nfc_dbg(nfc, "read_oob: page:%d\n", page);
@@ -839,11 +879,18 @@  static int ar934x_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	return 0;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 				int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-
+#else
+static int ar934x_nfc_write_oob(struct nand_chip *chip,
+				int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	nfc_dbg(nfc, "write_oob: page:%d\n", page);
 
 	memcpy(nfc->buf, chip->oob_poi, mtd->oobsize);
@@ -852,11 +899,20 @@  static int ar934x_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 				     page, mtd->oobsize);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_read_page_raw(struct mtd_info *mtd,
 				    struct nand_chip *chip, u8 *buf,
 				    int oob_required, int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_read_page_raw(
+				    struct nand_chip *chip, u8 *buf,
+				    int oob_required, int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	int len;
 	int err;
 
@@ -878,10 +934,18 @@  static int ar934x_nfc_read_page_raw(struct mtd_info *mtd,
 	return 0;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 				u8 *buf, int oob_required, int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_read_page(struct nand_chip *chip,
+				u8 *buf, int oob_required, int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	u32 ecc_ctrl;
 	int max_bitflips = 0;
 	bool ecc_failed;
@@ -950,11 +1014,20 @@  static int ar934x_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	return max_bitflips;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_write_page_raw(struct mtd_info *mtd,
 				     struct nand_chip *chip, const u8 *buf,
 				     int oob_required, int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_write_page_raw(
+				     struct nand_chip *chip, const u8 *buf,
+				     int oob_required, int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	int len;
 
 	nfc_dbg(nfc, "write_page_raw: page:%d oob:%d\n", page, oob_required);
@@ -970,10 +1043,18 @@  static int ar934x_nfc_write_page_raw(struct mtd_info *mtd,
 	return ar934x_nfc_send_write(nfc, NAND_CMD_PAGEPROG, 0, page, len);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static int ar934x_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				 const u8 *buf, int oob_required, int page)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
+#else
+static int ar934x_nfc_write_page(struct nand_chip *chip,
+				 const u8 *buf, int oob_required, int page)
+{
+	struct ar934x_nfc *nfc = chip->priv;
+	struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
+#endif
 	int err;
 
 	nfc_dbg(nfc, "write_page: page:%d oob:%d\n", page, oob_required);
@@ -981,7 +1062,11 @@  static int ar934x_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 	/* write OOB first */
 	if (oob_required &&
 	    !is_all_ff(chip->oob_poi, mtd->oobsize)) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 		err = ar934x_nfc_write_oob(mtd, chip, page);
+#else
+		err = ar934x_nfc_write_oob(chip, page);
+#endif
 		if (err)
 			return err;
 	}
@@ -1083,6 +1168,11 @@  static int ar934x_nfc_init_tail(struct mtd_info *mtd)
 {
 	struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
 	struct nand_chip *chip = &nfc->nand_chip;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
+	u64 chipsize = chip->chipsize;
+#else
+	u64 chipsize = nanddev_target_size(&chip->base);
+#endif
 	u32 ctrl;
 	u32 t;
 	int err;
@@ -1169,10 +1259,10 @@  static int ar934x_nfc_init_tail(struct mtd_info *mtd)
 	if (nfc->small_page) {
 		ctrl |= AR934X_NFC_CTRL_SMALL_PAGE;
 
-		if (chip->chipsize > (32 << 20)) {
+		if (chipsize > (32 << 20)) {
 			nfc->addr_count0 = 4;
 			nfc->addr_count1 = 3;
-		} else if (chip->chipsize > (2 << 16)) {
+		} else if (chipsize > (2 << 16)) {
 			nfc->addr_count0 = 3;
 			nfc->addr_count1 = 2;
 		} else {
@@ -1180,10 +1270,10 @@  static int ar934x_nfc_init_tail(struct mtd_info *mtd)
 			nfc->addr_count1 = 1;
 		}
 	} else {
-		if (chip->chipsize > (128 << 20)) {
+		if (chipsize > (128 << 20)) {
 			nfc->addr_count0 = 5;
 			nfc->addr_count1 = 3;
-		} else if (chip->chipsize > (8 << 16)) {
+		} else if (chipsize > (8 << 16)) {
 			nfc->addr_count0 = 4;
 			nfc->addr_count1 = 2;
 		} else {
@@ -1329,8 +1419,13 @@  static int ar934x_nfc_attach_chip(struct nand_chip *nand)
 
 static u64 ar934x_nfc_dma_mask = DMA_BIT_MASK(32);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 static void ar934x_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
 				unsigned int ctrl)
+#else
+static void ar934x_nfc_cmd_ctrl(struct nand_chip *chip, int dat,
+				unsigned int ctrl)
+#endif
 {
 	WARN_ON(dat != NAND_CMD_NONE);
 }
@@ -1401,6 +1496,7 @@  static int ar934x_nfc_probe(struct platform_device *pdev)
 
 	nand_set_controller_data(nand, nfc);
 	nand_set_flash_node(nand, pdev->dev.of_node);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 	nand->chip_delay = 25;
 	nand->dev_ready = ar934x_nfc_dev_ready;
 	nand->cmdfunc = ar934x_nfc_cmdfunc;
@@ -1408,7 +1504,17 @@  static int ar934x_nfc_probe(struct platform_device *pdev)
 	nand->read_byte = ar934x_nfc_read_byte;
 	nand->write_buf = ar934x_nfc_write_buf;
 	nand->read_buf = ar934x_nfc_read_buf;
+#else
+	nand->legacy.chip_delay = 25;
+	nand->legacy.dev_ready = ar934x_nfc_dev_ready;
+	nand->legacy.cmdfunc = ar934x_nfc_cmdfunc;
+	nand->legacy.cmd_ctrl = ar934x_nfc_cmd_ctrl;	/* dummy */
+	nand->legacy.read_byte = ar934x_nfc_read_byte;
+	nand->legacy.write_buf = ar934x_nfc_write_buf;
+	nand->legacy.read_buf = ar934x_nfc_read_buf;
+#endif
 	nand->ecc.mode = NAND_ECC_HW;	/* default */
+	nand->priv = nfc;
 	platform_set_drvdata(pdev, nfc);
 
 	ret = ar934x_nfc_alloc_buf(nfc, AR934X_NFC_ID_BUF_SIZE);
@@ -1421,8 +1527,13 @@  static int ar934x_nfc_probe(struct platform_device *pdev)
 		goto err_free_buf;
 	}
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 	nand->dummy_controller.ops = &ar934x_nfc_controller_ops;
 	ret = nand_scan(mtd, 1);
+#else
+	nand->legacy.dummy_controller.ops = &ar934x_nfc_controller_ops;
+	ret = nand_scan(nand, 1);
+#endif
 	if (ret) {
 		dev_err(&pdev->dev, "nand_scan failed, err:%d\n", ret);
 		goto err_free_buf;
@@ -1444,12 +1555,18 @@  err_free_buf:
 static int ar934x_nfc_remove(struct platform_device *pdev)
 {
 	struct ar934x_nfc *nfc;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 	struct mtd_info *mtd;
+#endif
 
 	nfc = platform_get_drvdata(pdev);
 	if (nfc) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
 		mtd = ar934x_nfc_to_mtd(nfc);
 		nand_release(mtd);
+#else
+		nand_release(&nfc->nand_chip);
+#endif
 		ar934x_nfc_free_buf(nfc);
 	}