From peterpansjtu at gmail.com  Mon Jan  1 18:51:25 2018
From: peterpansjtu at gmail.com (Peter Pan)
Date: Tue, 2 Jan 2018 10:51:25 +0800
Subject: [PATCH v6 00/15] A SPI NAND framework under generic NAND framework
In-Reply-To: <20171222145147.3697fb02@bbrezillon>
References: <20170529225931.226da943@bbrezillon>
 <90bcb366-c494-2dee-3bb7-d16b77e347c6@exceet.de>
 <20171204150514.1f17671d@bbrezillon>
 <A0FE66EC-7E17-43BE-9B66-896F112B92A0@micron.com>
 <20171205135804.478902dc@bbrezillon> <20171205140313.40f3f17d@bbrezillon>
 <256b4ab6-c104-4580-87cd-527178bde460@exceet.de>
 <20171213222710.32d12514@bbrezillon>
 <CAAyFORJcT1abbo21iA4cetLKmF0zE4akFGFryxPpwPO+730LDQ@mail.gmail.com>
 <20171214085036.436b4fcf@bbrezillon>
 <CAAyFOR+=JwTRTm2MXVdMy7KRPsnV8LV4t71kHUh_s=+QOsVurA@mail.gmail.com>
 <23d17416-e555-4b92-cc47-f644fbe676c6@exceet.de>
 <20171214163848.41f6d277@bbrezillon>
 <CAAyFORKeFq+=tF9AK+8hp6GYYiyp3DKcw8+LWrC3RWS2zLNU_w@mail.gmail.com>
 <CAAyFORJEuEaHDXgk+m0ax5RoZ-3cRJs6uFXw7syR4vHE1veEwQ@mail.gmail.com>
 <a06312e4-a7e6-8b7b-9eb5-8320302dcc55@exceet.de>
 <CAAyFORL6mUFXFRvku6sm=Pj2=+Bf4wSV7EoBM_7+wRdPrF-ufw@mail.gmail.com>
 <CAAyFOR+m7GvXU66XKphu+cETP9SQTJ6GuZQEZQA600MX1R6cYw@mail.gmail.com>
 <20171222145147.3697fb02@bbrezillon>
Message-ID: <CAAyFORK9v-V1WrJzTnKk0sAt7_f_st_PHc6nJ6dz0zTL-Jih5A@mail.gmail.com>

Hi Boris,


On Fri, Dec 22, 2017 at 9:51 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Fri, 22 Dec 2017 14:37:06 +0800
> Peter Pan <peterpansjtu at gmail.com> wrote:
>
>> Hi Boris and Frieder
>>
>> On Fri, Dec 22, 2017 at 8:49 AM, Peter Pan <peterpansjtu at gmail.com> wrote:
>> > Hi Frieder,
>> >
>> > On Thu, Dec 21, 2017 at 7:48 PM, Frieder Schrempf
>> > <frieder.schrempf at exceet.de> wrote:
>> >> Hello Boris,
>> >>
>> >>>>>> So shouldn't there be an spinand_die_select_op in the SPI NAND core
>> >>>>>> that
>> >>>>>> is executed when necessary and skipped if there's only one die.
>> >>>>>
>> >>>>>
>> >>>>> Sure, I was arguing against a ->select_chip() at the generic NAND
>> >>>>> level. That's something you can add in the SPI NAND framework.
>> >>
>> >>
>> >> I added an op to send the die selection command and call it, where I think
>> >> it is needed: [1]
>> >
>> > I think we should add die_select_op in vendor's file and call a hook in core.c
>> > since the die select command implementation is different by vendors.
>> >
>> > Thanks
>> > Peter Pan
>> >
>> >
>> >>
>> >> Accessing both dies on the Winbond SPI NAND works fine like this.
>> >>
>> >> While running tests I came across some problems:
>> >>
>> >> * On accessing the BBT in RAM via nanddev_bbt_[set/get]_block_status, the
>> >> calculation of position and offset seems to be wrong.
>> >> My fix is here: [2]
>> >>
>> >> * On calculating the row address for read/program/erase via
>> >> nanddev_pos_to_row, it seems like the eraseblock_addr_shift is wrong.
>> >>
>> >> * Also, I'm not sure if the LUN should be taken into account when
>> >> calculating the row address. At least when you select the LUN by issuing a
>> >> separate command, the row address sent to the chip should only contain the
>> >> page address.
>> >> But I'm not sure if that's the case in general, or if some code is needed to
>> >> differentiate.
>> >>
>> >> See my changes of nanddev_pos_to_row here: [3]
>> >>
>> >> * I run into a mutex deadlock, when spinand_write_page fails (e.g. because
>> >> of a bad block) as the lock is not released in such cases. See my fix here:
>> >> [4]
>> >>
>> >> With these fixes applied and as far as I can tell everything seems to work
>> >> fine. I'll do some tests with UBI next and look into the ECC topic.
>>
>> UBI attach failed since missing mtd->writebufsize assignment in nanddev_init()
>> After fixing it and with Frieder's fixing, UBIFS can be mounted successfully on
>> Zedboard with generic spi controller and Micron SPI NAND 2Gb device.
>>
>> Also, the code now can pass mtd read and page test. 1 error found in oob test
>> since we don't have "past end of partition" check in part_write_oob() which I
>> mentioned in earlier mail. Since we don't support ECC right now, I didn't try
>> nandbiterror test.
>>
>
> Peter, Frider, I just pushed a new version to my nand/spi-nand branch
> [1] fixing the authorship, adding/fixing/removing comments where needed.
>
> Can you please have a look at those changes (everything I changed
> should appear as !fixup commits) and let me know if I did something
> wrong.

You forgot to initialize mtd->writebufsize and mtd->oobavail.
For mtd->writebufsize I think we can do it in nanddev_init() like below:

--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -196,7 +196,9 @@ int nanddev_init(struct nand_device *nand, const
struct nand_ops *ops,
        mtd->flags = MTD_CAP_NANDFLASH;
        mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock;
        mtd->writesize = memorg->pagesize;
+       mtd->writebufsize = mtd->writesize;
        mtd->oobsize = memorg->oobsize;
        mtd->size = nanddev_size(nand);
        mtd->owner = owner;

For mtd->oobavail, I think we need to call some hooks in spinand_init(),
and implement on-die ECC layout in vendor's file and HW ECC layout in
controller's file.

What's your opinion?

With the two thing fixed, we can pass UBIFS mount and mtd test.

Thanks
Peter Pan

>
> We still need to make commit messages a bit more verbose.
>
> This afternoon I'll have a look at the ->select_die() feature.
>
> Regards,
>
> Boris
>
> [1]https://github.com/bbrezillon/linux-0day/commits/nand/spi-nand


From vigneshr at ti.com  Tue Jan  2 02:00:37 2018
From: vigneshr at ti.com (Vignesh R)
Date: Tue, 2 Jan 2018 15:30:37 +0530
Subject: [PATCH 1/3] mtd: spi-nor: add optional DMA-safe bounce buffer for
 data transfer
In-Reply-To: <1514570627.26695.114.camel@impinj.com>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <fc2440c6f52877f28286d89691049e5cba10e6a7.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <1514317385.26695.39.camel@impinj.com>
 <1a7dc424-1ce0-6c64-fc52-bb88ec7db8fa@wedev4u.fr>
 <1514487276.26695.94.camel@impinj.com>
 <08be8b42-732a-bf28-40c4-f46bf9d71c80@ti.com>
 <1514570627.26695.114.camel@impinj.com>
Message-ID: <b4794d21-817f-b67b-1569-05e1400bdbee@ti.com>



On Friday 29 December 2017 11:33 PM, Trent Piepho wrote:
> On Fri, 2017-12-29 at 15:46 +0530, Vignesh R wrote:
>> On Friday 29 December 2017 12:24 AM, Trent Piepho wrote:
>> > 
>> > > Vignesh has suggested to call virt_addr_valid() instead.
>> > > I think Boris has also told me about this function.
>> > > So it might be the right solution. What do you think about their proposal?
>> > 
>> > Not sure what exactly the differences are between these methods.? The
>> > fact that each of the many existing DMA fixes uses slightly different
>> > code to detect what is unsafe speaks to the difficulty of this problem!
>> 
>> My understanding based on Documentation/DMA-API-HOWTO.txt and
>> Documentation/arm/memory.txt is that
>> virt_addr_valid() will guarantee that address is in range of
>> PAGE_OFFSET to high_memory-1 (Kernel direct-mapped RAM region) which is
>> address range of buffers that are DMA'able.
> 
> There's code in gpmi-nand.c that does:
> 
> ??????? /* first try to map the upper buffer directly */
> ??????? if (virt_addr_valid(this->upper_buf) &&
> ??????????????? !object_is_on_stack(this->upper_buf)) {
> ??????????????? sg_init_one(sgl, this->upper_buf, this->upper_len);
> 
> So whoever wrote that thought that stack objects needed an additional
> test beyond virt_addr_valid.? But it does appear to be far more common
> to depend on just virt_addr_valid, so perhaps the code in gpmi-nand is
> in error.
> 

The test in gpmi-nand.c is right. Enabling CONFIG_DMA_API_DEBUG does
warn about DMA'ing into stack objects (in lib/dma-debug.c). So other
places needs to be fixed, I guess.

>> >? virt_addr_valid() is already used by spi-ti-qspi.? spi core uses for
>> > the buffer map helper, but that code path is for buffers which are NOT
>> > vmalloc or highmem, but are still not virt_addr_valid() for some other
>> > reason.
>> > 
>> 
>>??????? if (vmalloced_buf || kmap_buf) {
>>??????????????? /* Handle vmalloc'd or kmap'd buffers */
>>??????????????? ...
> This stuff does get DMAed.? So I have to wonder, if spi.c thinks it can
> use DMA with vmalloc or highmem, couldn't spi-not do the same instead
> of the bounce buffer?

SPI core does try to DMA into underlying physical pages of vmalloc'd
buffer. But this has two problems:

1. Does not work well with VIVT caches[1].
2. On ARM LPAE systems, vmalloc'd buffers can be from highmem region
that are not addressable using 32 bit addresses and is backed by LPAE.
So, a 32 bit DMA cannot access these buffers.

Both these issues lead to random crashes and errors with UBIFS and JFFS2
flash file systems which this patch series tries to address using bounce
buffer

[1] https://patchwork.kernel.org/patch/9579553/


-- 
Regards
Vignesh


From ludovic.desroches at microchip.com  Tue Jan  2 02:22:34 2018
From: ludovic.desroches at microchip.com (Ludovic Desroches)
Date: Tue, 2 Jan 2018 11:22:34 +0100
Subject: [PATCH 2/3] dt-bindings: mtd: atmel-quadspi: add an optional
 property 'dmacap,memcpy'
In-Reply-To: <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <143542c61ca674d53da4985bbabc142e8e6ebefc.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <20171226232330.trljk2ofyvu4ly3n@rob-hp-laptop>
 <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
Message-ID: <20180102102234.GG2612@rfolt0960.corp.atmel.com>

Hi Cyrille,

On Wed, Dec 27, 2017 at 10:40:00PM +0100, Cyrille Pitchen wrote:
> Hi Rob,
> 
> + Ludovic Desroches, maintainer of the DMA controller drivers for AT91 SoCs.
> 
> Le 27/12/2017 ? 00:23, Rob Herring a ?crit :
> > On Sun, Dec 24, 2017 at 05:36:05AM +0100, Cyrille Pitchen wrote:
> >> The optional 'dmacap,memcpy' DT property tells the Atmel QSPI controller
> >> driver to reserve some DMA channel then to use it to perform DMA
> >> memcpy() during data transfers. This feature relies on the generic
> >> bounce buffer helper from spi-nor.c.
> >>
> >> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>
> >> ---
> >>  Documentation/devicetree/bindings/mtd/atmel-quadspi.txt | 5 +++++
> >>  1 file changed, 5 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
> >> index b93c1e2f25dd..002d3f0a445b 100644
> >> --- a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
> >> +++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
> >> @@ -12,6 +12,10 @@ Required properties:
> >>  - #address-cells: Should be <1>.
> >>  - #size-cells:    Should be <0>.
> >>  
> >> +Optional properties:
> >> +- dmacap,memcpy:  Reserve a DMA channel to perform DMA memcpy() between the
> >> +                  system memory and the QSPI mapped memory.
> > 
> > How is this a h/w property? Why would I not want to always enable DMA if 
> > possible?
> 
> The number of DMA channels is limited for a given SoC. This number may be
> lower than the number of enabled controllers (spi, i2c, qspi, aes, sha,
> des, sdmmc, usart, ...).
> 
> So we use a DT property to explicitly tell the matching drivers to request
> and reserved the DMA channels they need. This policy is not driver or even
> SoC specific but board specific. It's very common to reserved DMA channels
> for the most used or most performance dependent controllers, setting the
> relevant properties in the device-tree then restricting remaining
> controllers to their PIO mode.
> 
> > 
> > Furthermore, you are reusing a property, but giving it a different 
> > meaning. The current definition is an indication whether a DMA 
> > controller supports memcpy operations or not. It is not a flag for 
> > clients to use memcpy channels.
> >
> 
> I don't mind changing the name. I thought it would be better to use some
> existing one than creating another. However I was not confident on whether
> "dmacap,memcpy" was actually a good candidate for what I do in the DMA
> patch for the atmel-quadspi.c driver.
> 
> Actually, I was relying on your feedbacks :)
> 
> > Why don't you use "dmas" property to point to the DMA controller.
> 
> I didn't use the "dmas" property because I thought it would not have been
> consistent with how this property is used in all other nodes of the sama5*
> device-trees. The flags provided in the dma-cells are designed for "memory
> to peripheral" or "peripheral to memory" DMA transfers only.
> 
> However, here I need to perform some "memory to memory" transfer: the SPI
> NOR flash memory is mapped into the AHB bus of SAMA5D2 SoCs. Besides,
> once in Serial Memory Mode, data can no longer be transfered through the
> TDR or RDR registers of the QSPI controller, only through its AHB mapped
> memory window.
> 
> So I cannot configured the DMA channel for "peripheral to memory" or
> "memory to peripheral" like for other controllers embedded in the SoC but
> only for "memory to memory".
> 
> Maybe we could extend the flags supported by the "dmas" property but I
> guess it may require some little rework in the at_xdmac_xlate() function
> of the at_xdmac.c driver.
> 

I have no objection about changing the at_xdmac_xlate() behavior.

>From your cover-letter, I understand that the issue you're trying to
solve is not only related to the Atmel devices so you may also have to update
the xlate functions of the other DMA controllers.

> Or maybe no change at all is required at the at_xdmac.c driver side: we
> just don't care about the provided flags in the "dmas" property, especially
> the "peripheral id". They would be ignored anyway when the atmel-quadspi.c
> driver later calls dmaengine_prep_dma_memcpy(). So I could simply set the
> dma cells to 0 in the device-tree?
> 
> Ludovic, what do you think about that ?

It may work but I won't do this. Usually, channels requested through the xlate
function have usually their capaiblities set to DMA_SLAVE and not DMA_MEMCPY.
In the at_xdmac case, it won't be an issue but if you have a controller
which has channels which can support only mem-to-mem or peripheral, it
won't work.

Regards

Ludovic


From yogeshnarayan.gaur at nxp.com  Tue Jan  2 02:39:12 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 2 Jan 2018 16:09:12 +0530
Subject: [PATCH] mtd: fsl-quadspi: fix api naming typo _init_ahb_read
Message-ID: <1514889552-23603-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Fix api naming typo _init_ahb_read
fsl_qspi_init_abh_read --> fsl_qspi_init_ahb_read

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index f17d224..943e9c4 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -661,7 +661,7 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
  * causes the controller to clear the buffer, and use the sequence pointed
  * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
  */
-static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
+static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 {
 	void __iomem *base = q->iobase;
 	int seqid;
@@ -795,7 +795,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	fsl_qspi_init_lut(q);
 
 	/* Init for AHB read */
-	fsl_qspi_init_abh_read(q);
+	fsl_qspi_init_ahb_read(q);
 
 	return 0;
 }
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan  2 02:40:53 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 2 Jan 2018 16:10:53 +0530
Subject: [PATCH] mtd: fsl-quadspi: fix init AHB read in fsl_qspi_nor_setup()
Message-ID: <1514889653-23647-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Move AHB read initialize in fsl_qspi_nor_setup().

In file spi-nor.c, func spi_nor_scan() calls nor->read() thru
spi_nor_read_sfdp() API.

Presently, fsl_qspi_init_ahb_read() called from fsl_qspi_nor_setup_last().
Func fsl_qspi_probe() calls spi_nor_scan() first and then calls
fsl_qspi_nor_setup_last().

When nor->read() being called from inside spi_nor_read_sfdp(), QSPI cntlr
AHB mode initialization is not yet done results in data read error.

Initialize AHB read inside fsl_qspi_nor_setup().

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 943e9c4..c22e3eb 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -769,6 +769,9 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	/* enable the interrupt */
 	qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
 
+	/* Init for AHB read */
+	fsl_qspi_init_ahb_read(q);
+
 	return 0;
 }
 
@@ -794,9 +797,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	/* Init the LUT table again. */
 	fsl_qspi_init_lut(q);
 
-	/* Init for AHB read */
-	fsl_qspi_init_ahb_read(q);
-
 	return 0;
 }
 
-- 
1.9.1



From miquel.raynal at free-electrons.com  Tue Jan  2 03:03:26 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Tue, 2 Jan 2018 12:03:26 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87fu81bc45.fsf@belgarion.home>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
Message-ID: <20180102120326.7a2cf1d1@xps13>

Hello Robert,

On Sat, 23 Dec 2017 18:14:18 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> 
> >> Here it comes in [3]. I suspect the BBT parser here, here is the
> >> extract that _might_ be relevant:
> >> [    3.372907] nand: ->exec_op() parser: pattern not found!  
> >
> > Indeed this might be the problem, it means there is one scenario
> > that should be handled by the parser that is missing. I am really
> > interrogative about which one it is and to discover it, can you
> > rebuild with
> >
> >         #define DEBUG
> >
> > in drivers/mtd/nand/nand_base.c too.  
> It was already there, check the patch I attached to my previous mail.
> 
> > This way the core will display the patterns it try to find a match
> > for.  
> The core displays already debug message, as these are displayed :
> [    3.228598] nand: executing subop:
> [    3.232187] nand:     ->CMD      [0x90]
> [    3.236077] nand:     ->ADDR     [1 cyc: 40]
> [    3.240517] nand:     ->DATA_IN  [5 B, force 8-bit]
> 
> As to your statement "the core will display the patterns it try to
> find a match for", how confident are you with it ? Because my reading
> of the following code is quite different :
> 			if (!nand_op_parser_match_pat(pattern, &ctx))
> 				continue;
> 
> 			nand_op_parser_trace(&ctx);
> 
> > Also to ease the understanding, you might add a dump_stack() right
> > next to this error message.  
> Attached in [1].

I just pushed two fixups on top of the Github branch [1], can you rebase
on top of them and give me the result?

The first patch just adds the auto bus width bit in nand->options.
The second removes the faulty ->change_column(), and does the same
check with another method.

I think the ECC issue you faced was related to pages being written
*and* empty. If this guess is right, the board should boot fine with
these changes.

Otherwise, please add the DEBUG define as before in both the core and
the driver and do not hesitate to add another dump_stack() where it
crashes (if applicable).

Thanks for your help,
Miqu?l

[1] https://github.com/miquelraynal/linux/commits/marvell/nand-next/nfc


From zajec5 at gmail.com  Tue Jan  2 05:04:57 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue,  2 Jan 2018 14:04:57 +0100
Subject: [PATCH V5 1/2] mtd: partitions: add of_match_table parser matching
Message-ID: <20180102130458.16226-1-zajec5@gmail.com>

From: Brian Norris <computersforpeace at gmail.com>

Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.

It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).

This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching

V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
    Merge helpers into a single of_mtd_match_mtd_parser
V3: Add a simple comment to note we will need the best match in the future
V4: Rework new functions to pick parser with the best match
    Move new code in parse_mtd_partitions up so it has precedence over flash
    driver defaults and MTD defaults
V5: Rework matching code to start checking with the most specific string in the
    "compatibility" property.
---
 drivers/mtd/mtdpart.c          | 64 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/partitions.h |  1 +
 2 files changed, 65 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index be088bccd593..a3aaaa4af992 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -880,6 +881,48 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 }
 
 /**
+ * mtd_part_get_parser_by_cp - find MTD parser by a compatible string
+ *
+ * @cp: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_parser_by_cp(const char *cp)
+{
+	struct mtd_part_parser *p, *ret;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->name[0] || matches->type[0] || matches->compatible[0];
+		     matches++) {
+			if (!matches->compatible[0])
+				continue;
+			if (!strcmp(matches->compatible, cp) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
+/**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
  * @types: names of partition parsers to try or %NULL
@@ -905,8 +948,29 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 			 struct mtd_part_parser_data *data)
 {
 	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *cp;
 	int ret, err = 0;
 
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	if (np) {
+		of_property_for_each_string(np, "compatible", prop, cp) {
+			parser = mtd_part_get_parser_by_cp(cp);
+			if (!parser)
+				continue;
+			ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (ret > 0) {
+				of_node_put(np);
+				return 0;
+			}
+			mtd_part_parser_put(parser);
+			if (ret < 0 && !err)
+				err = ret;
+		}
+		of_node_put(np);
+	}
+
 	if (!types)
 		types = default_mtd_part_types;
 
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70dacbd..11cb0c50cd84 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-- 
2.11.0



From zajec5 at gmail.com  Tue Jan  2 05:04:58 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue,  2 Jan 2018 14:04:58 +0100
Subject: [PATCH V5 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
In-Reply-To: <20180102130458.16226-1-zajec5@gmail.com>
References: <20180102130458.16226-1-zajec5@gmail.com>
Message-ID: <20180102130458.16226-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).

This matches existing bindings documentation.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/ofpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e525677..92fcbac046d9 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
 	.parse_fn = parse_ofpart_partitions,
 	.name = "ofpart",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
-- 
2.11.0



From Julia.Lawall at lip6.fr  Tue Jan  2 05:27:56 2018
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Tue,  2 Jan 2018 14:27:56 +0100
Subject: [PATCH 00/12] account for const type of of_device_id.data
Message-ID: <1514899688-27844-1-git-send-email-Julia.Lawall@lip6.fr>

Maintain const annotations when putting values into the data field of
an of_device_id structure, and afterwards when extracting them from
the data field of such a structure.

This was done using the following semantic patch:
(http://coccinelle.lip6.fr/)

// <smpl>
@r@
identifier i,j;
const struct j *m;
struct i *y;
type T;
expression x,e;
position p;
@@

(
y =@p (T)(of_device_get_match_data(...));
|
x = of_match_node(...);
... when != x = e
(
m = e;
|
y =@p (T)(x->data);
)
)

@s@
identifier r.i,j;
@@

const struct i j = { ... };

@t depends on s disable optional_qualifier@
expression e;
identifier r.i,x,j,n;
struct j *m;
struct i *e1;
position any r.p;
type T;
@@

(
+const
struct i *x;
<+...
(
x =@p 
-   (T)(e)
+   e
|
x =@p e
)
...+>
|
m->@e1 n =@p 
-   (T)(e)
+   e
|
m->@e1 n =@p e
)

@disable optional_qualifier@
identifier t.j,t.n,r.i;
@@

struct j {
  ...
+ const
  struct i *n;
  ...
}

@@
identifier x,s.j;
type T;
@@

struct of_device_id x[] = { ...,
  { .data =
-           (T)
            &j, }, ...};

// </smpl>

---

 drivers/i2c/busses/i2c-rk3x.c               |   16 ++++++++--------
 drivers/iio/common/ssp_sensors/ssp.h        |    2 +-
 drivers/iio/common/ssp_sensors/ssp_dev.c    |    2 +-
 drivers/mtd/spi-nor/fsl-quadspi.c           |    8 ++++----
 drivers/pci/dwc/pcie-qcom.c                 |    4 ++--
 drivers/pinctrl/mvebu/pinctrl-armada-37xx.c |    4 ++--
 drivers/pinctrl/pinctrl-at91-pio4.c         |    4 ++--
 drivers/pinctrl/pinctrl-axp209.c            |    2 +-
 drivers/power/avs/rockchip-io-domain.c      |   24 ++++++++++++------------
 drivers/power/reset/at91-sama5d2_shdwc.c    |    4 ++--
 drivers/power/supply/axp20x_ac_power.c      |    8 ++++----
 drivers/spi/spi-fsl-dspi.c                  |    7 +++----
 drivers/spi/spi-sirf.c                      |    4 ++--
 13 files changed, 44 insertions(+), 44 deletions(-)


From Julia.Lawall at lip6.fr  Tue Jan  2 05:28:05 2018
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Tue,  2 Jan 2018 14:28:05 +0100
Subject: [PATCH 09/12] mtd: fsl-quadspi: account for const type of
 of_device_id.data
In-Reply-To: <1514899688-27844-1-git-send-email-Julia.Lawall@lip6.fr>
References: <1514899688-27844-1-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <1514899688-27844-10-git-send-email-Julia.Lawall@lip6.fr>

This driver creates a number of const structures that it stores in the
data field of an of_device_id array.

The data field of an of_device_id structure has type const void *, so
there is no need for a const-discarding cast when putting const values
into such a structure.

Done using Coccinelle.

Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>

---
 drivers/mtd/spi-nor/fsl-quadspi.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff -u -p a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -801,10 +801,10 @@ static int fsl_qspi_nor_setup_last(struc
 }
 
 static const struct of_device_id fsl_qspi_dt_ids[] = {
-	{ .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
-	{ .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
-	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
-	{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
+	{ .compatible = "fsl,vf610-qspi", .data = &vybrid_data, },
+	{ .compatible = "fsl,imx6sx-qspi", .data = &imx6sx_data, },
+	{ .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, },
+	{ .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, },
 	{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
 	{ /* sentinel */ }
 };



From tpiepho at impinj.com  Tue Jan  2 11:18:58 2018
From: tpiepho at impinj.com (Trent Piepho)
Date: Tue, 2 Jan 2018 19:18:58 +0000
Subject: [PATCH 2/3] dt-bindings: mtd: atmel-quadspi: add an optional
 property 'dmacap,memcpy'
In-Reply-To: <20180102102234.GG2612@rfolt0960.corp.atmel.com>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <143542c61ca674d53da4985bbabc142e8e6ebefc.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <20171226232330.trljk2ofyvu4ly3n@rob-hp-laptop>
 <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
 <20180102102234.GG2612@rfolt0960.corp.atmel.com>
Message-ID: <1514920738.26695.171.camel@impinj.com>

On Tue, 2018-01-02 at 11:22 +0100, Ludovic Desroches wrote:
> On Wed, Dec 27, 2017 at 10:40:00PM +0100, Cyrille Pitchen wrote:
> 
> > Or maybe no change at all is required at the at_xdmac.c driver side: we
> > just don't care about the provided flags in the "dmas" property, especially
> > the "peripheral id". They would be ignored anyway when the atmel-quadspi.c
> > driver later calls dmaengine_prep_dma_memcpy(). So I could simply set the
> > dma cells to 0 in the device-tree?
> > 
> > Ludovic, what do you think about that ?
> 
> It may work but I won't do this. Usually, channels requested through the xlate
> function have usually their capaiblities set to DMA_SLAVE and not DMA_MEMCPY.
> In the at_xdmac case, it won't be an issue but if you have a controller
> which has channels which can support only mem-to-mem or peripheral, it
> won't work.

Maybe one could create an "AT91_XDMAC_DT_" macro to indicate a memcpy
channel.  There are still unused bits for another flag.  It also looks
like at_xdma uses peripheral id 0x3f for memcpy transfers (will that
work with memcpy DMA on multiple channels at the same time?).  So
perhaps perid 0x3f could be the indication of wanting a memcpy channel,
rather than another flag bit.  But however it's done, one writes:

dmas = <&dma0 AT91_XDMAC_DT_MEMCPY>; dma-names = "rx-tx";

I think one could have the quadspi driver automatically fill in the dma
cell in the dma specifier if it is not present in the device tree.  So
one could write "dmas = <&dma0>" and the driver adds the
AT91_XDMAC_DT_MEMCPY cell before xlating.  I'm not sure if that's a
good idea or not.

From robert.jarzmik at free.fr  Tue Jan  2 11:21:09 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 02 Jan 2018 20:21:09 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180102120326.7a2cf1d1@xps13> (Miquel RAYNAL's message of "Tue, 
 2 Jan 2018 12:03:26 +0100")
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon> <877etkecig.fsf@belgarion.home>
 <20171218092535.2ca1fe13@xps13> <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon> <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon> <20171222233730.68d9cb9d@xps13>
 <87k1xdblxf.fsf@belgarion.home> <20171223155709.2ba16e95@xps13>
 <87fu81bc45.fsf@belgarion.home> <20180102120326.7a2cf1d1@xps13>
Message-ID: <87d12scbiy.fsf@belgarion.home>

Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:

> I think the ECC issue you faced was related to pages being written
> *and* empty. If this guess is right, the board should boot fine with
> these changes.
>
> Otherwise, please add the DEBUG define as before in both the core and
> the driver and do not hesitate to add another dump_stack() where it
> crashes (if applicable).

The problem looks still the same :
[    3.560163] Bad block table not found for chip 0

Cheers.

--
Robert

-- 
Robert

[1] Dmesg
---8>---
netconsole: port not set
netconsole: registered as netconsole-1
smc91c111 smc91c1110: chip is revision= 9, version= 2
mdio_bus: miibus0: probed
eth0: got preset MAC address: 00:0e:0c:a7:26:f7
nand: NAND device: Manufacturer ID: 0x20, Chip ID: 0xba (ST Micro NAND 256MiB 1,8V 16-bit), 256MiB, page size: 2048, OOB size: 64
mrvl_nand mrvl_nand0: ECC strength 1, ECC step size 512
Bad block table found at page 131008, version 0x01
Bad block table found at page 130944, version 0x01
malloc space: 0x83700000 -> 0x83efffff (size 8 MiB)
running /env/bin/init...
magicvar: No such file or directory
magicvar: No such file or directory
magicvar: No such file or directory

Hit any key to stop autoboot:  3 2 1 0
booting net
netconsole: netconsole initialized with 255.255.255.255:6662
eth0: 100Mbps full duplex link detected
DHCP client bound to address 192.168.1.232
netconsole: netconsole initialized with 255.255.255.255:6662
could not open /mnt/tftp/none-linux-zylonite: No such file or directory
Booting net failed: No such file or directory
booting net failed: No such file or directory
boot: No such file or directory
.[1;32mbarebox at .[1;36mZylonite:/.[0m global linux.bootargs.debug=earlycon
.[1;32mbarebox at .[1;36mZylonite:/.[0m bootm /mnt/tftp/zImage_jenkins

Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
arch_number: 1233
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.15.0-rc1-00042-ge693b77 (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #817 PREEMPT Tue Jan 2 18:08:25 CET 2018
[    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] Memory policy: Data cache writeback
[    0.000000] RO Mode clock: 0.00MHz
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] System bus clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] random: fast init done
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56856K/65536K available (4226K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0428a28   (4227 kB)
[    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
[    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
[    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
[    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
[    0.000069] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
[    0.000265] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
[    0.002135] Console: colour dummy device 80x30
[    0.002294] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
[    0.081023] pid_max: default: 32768 minimum: 301
[    0.081861] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.081961] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.085176] CPU: Testing write buffer coherency: ok
[    0.088966] Setting up static identity map for 0x80008200 - 0x80008260
[    0.089928] Hierarchical SRCU implementation.
[    0.102939] devtmpfs: initialized
[    0.113807] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.113949] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.116286] NET: Registered protocol family 16
[    0.119101] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.385393] Advanced Linux Sound Architecture Driver Initialized.
[    0.398663] clocksource: Switched to clocksource oscr0
[    0.551533] NET: Registered protocol family 2
[    0.557291] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.557517] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.557699] TCP: Hash tables configured (established 1024 bind 1024)
[    0.558259] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.558438] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.560686] NET: Registered protocol family 1
[    0.562714] RPC: Registered named UNIX socket transport module.
[    0.562816] RPC: Registered udp transport module.
[    0.562871] RPC: Registered tcp transport module.
[    0.562931] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.501505] Initialise system trusted keyrings
[    2.502977] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    2.507421] NFS: Registering the id_resolver key type
[    2.507626] Key type id_resolver registered
[    2.507689] Key type id_legacy registered
[    2.513786] Key type asymmetric registered
[    2.513887] Asymmetric key parser 'x509' registered
[    2.514050] io scheduler noop registered
[    2.514116] io scheduler deadline registered
[    2.514509] io scheduler cfq registered (default)
[    2.514579] io scheduler mq-deadline registered
[    2.514643] io scheduler kyber registered
[    2.574261] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
[    2.578634] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
[    3.054506] console [ttyS0] enabled
[    3.061109] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
[    3.073618] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
[    3.091288] nand: executing subop:
[    3.094787] nand:     ->CMD      [0xff]
[    3.099973] nand:     ->WAITRDY  [max 250 ms]
[    3.104480] marvell-nfc pxa3xx-nand: 
[    3.104480] NDCR:  0x90079fff
[    3.104480] NDCB0: 0x00a000ff
[    3.104480] NDCB1: 0x00000000
[    3.104480] NDCB2: 0x00000000
[    3.104480] NDCB3: 0x00000000
[    3.123768] nand: executing subop:
[    3.127243] nand:     ->CMD      [0x90]
[    3.131549] nand:     ->ADDR     [1 cyc: 00]
[    3.135876] nand:     ->DATA_IN  [2 B, force 8-bit]
[    3.141219] marvell-nfc pxa3xx-nand: 
[    3.141219] NDCR:  0x90079fff
[    3.141219] NDCB0: 0x00610090
[    3.141219] NDCB1: 0x00000000
[    3.141219] NDCB2: 0x00000000
[    3.141219] NDCB3: 0x00000000
[    3.160073] nand: executing subop:
[    3.163536] nand:     ->CMD      [0x90]
[    3.167410] nand:     ->ADDR     [1 cyc: 00]
[    3.171900] nand:     ->DATA_IN  [8 B, force 8-bit]
[    3.176892] marvell-nfc pxa3xx-nand: 
[    3.176892] NDCR:  0x90079fff
[    3.176892] NDCB0: 0x00610090
[    3.176892] NDCB1: 0x00000000
[    3.176892] NDCB2: 0x00000000
[    3.176892] NDCB3: 0x00000000
[    3.195557] nand: executing subop:
[    3.199162] nand:     ->CMD      [0x90]
[    3.203053] nand:     ->ADDR     [1 cyc: 20]
[    3.207353] nand:     ->DATA_IN  [4 B, force 8-bit]
[    3.212466] marvell-nfc pxa3xx-nand: 
[    3.212466] NDCR:  0x90079fff
[    3.212466] NDCB0: 0x00610090
[    3.212466] NDCB1: 0x00000020
[    3.212466] NDCB2: 0x00000000
[    3.212466] NDCB3: 0x00000000
[    3.231108] nand: executing subop:
[    3.234561] nand:     ->CMD      [0x90]
[    3.238433] nand:     ->ADDR     [1 cyc: 40]
[    3.242882] nand:     ->DATA_IN  [5 B, force 8-bit]
[    3.247869] marvell-nfc pxa3xx-nand: 
[    3.247869] NDCR:  0x90079fff
[    3.247869] NDCB0: 0x00610090
[    3.247869] NDCB1: 0x00000040
[    3.247869] NDCB2: 0x00000000
[    3.247869] NDCB3: 0x00000000
[    3.266511] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
[    3.273022] nand: ST Micro NAND 256MiB 1,8V 16-bit
[    3.277867] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    3.285604] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
[    3.293273] marvell-nfc pxa3xx-nand: 
[    3.293273] NDCR:  0xdd079fff
[    3.293273] NDCB0: 0x000d3000
[    3.293273] NDCB1: 0xffc00000
[    3.293273] NDCB2: 0x00000001
[    3.293273] NDCB3: 0x00000000
[    3.312627] marvell-nfc pxa3xx-nand: 
[    3.312627] NDCR:  0xdd079fff
[    3.312627] NDCB0: 0x000d3000
[    3.312627] NDCB1: 0xff800000
[    3.312627] NDCB2: 0x00000001
[    3.312627] NDCB3: 0x00000000
[    3.331669] marvell-nfc pxa3xx-nand: 
[    3.331669] NDCR:  0xdd079fff
[    3.331669] NDCB0: 0x000d3000
[    3.331669] NDCB1: 0xff400000
[    3.331669] NDCB2: 0x00000001
[    3.331669] NDCB3: 0x00000000
[    3.350652] marvell-nfc pxa3xx-nand: 
[    3.350652] NDCR:  0x9d079fff
[    3.350652] NDCB0: 0x000d3000
[    3.350652] NDCB1: 0xff400000
[    3.350652] NDCB2: 0x00000001
[    3.350652] NDCB3: 0x00000000
[    3.369749] marvell-nfc pxa3xx-nand: 
[    3.369749] NDCR:  0xdd079fff
[    3.369749] NDCB0: 0x000d3000
[    3.369749] NDCB1: 0xff000000
[    3.369749] NDCB2: 0x00000001
[    3.369749] NDCB3: 0x00000000
[    3.388952] marvell-nfc pxa3xx-nand: 
[    3.388952] NDCR:  0x9d079fff
[    3.388952] NDCB0: 0x000d3000
[    3.388952] NDCB1: 0xff000000
[    3.388952] NDCB2: 0x00000001
[    3.388952] NDCB3: 0x00000000
[    3.408036] marvell-nfc pxa3xx-nand: 
[    3.408036] NDCR:  0xdd079fff
[    3.408036] NDCB0: 0x000d3000
[    3.408036] NDCB1: 0xfec00000
[    3.408036] NDCB2: 0x00000001
[    3.408036] NDCB3: 0x00000000
[    3.427024] marvell-nfc pxa3xx-nand: 
[    3.427024] NDCR:  0x9d079fff
[    3.427024] NDCB0: 0x000d3000
[    3.427024] NDCB1: 0xfec00000
[    3.427024] NDCB2: 0x00000001
[    3.427024] NDCB3: 0x00000000
[    3.446101] marvell-nfc pxa3xx-nand: 
[    3.446101] NDCR:  0xdd079fff
[    3.446101] NDCB0: 0x000d3000
[    3.446101] NDCB1: 0xfe800000
[    3.446101] NDCB2: 0x00000001
[    3.446101] NDCB3: 0x00000000
[    3.465087] marvell-nfc pxa3xx-nand: 
[    3.465087] NDCR:  0x9d079fff
[    3.465087] NDCB0: 0x000d3000
[    3.465087] NDCB1: 0xfe800000
[    3.465087] NDCB2: 0x00000001
[    3.465087] NDCB3: 0x00000000
[    3.484155] marvell-nfc pxa3xx-nand: 
[    3.484155] NDCR:  0xdd079fff
[    3.484155] NDCB0: 0x000d3000
[    3.484155] NDCB1: 0xfe400000
[    3.484155] NDCB2: 0x00000001
[    3.484155] NDCB3: 0x00000000
[    3.503139] marvell-nfc pxa3xx-nand: 
[    3.503139] NDCR:  0x9d079fff
[    3.503139] NDCB0: 0x000d3000
[    3.503139] NDCB1: 0xfe400000
[    3.503139] NDCB2: 0x00000001
[    3.503139] NDCB3: 0x00000000
[    3.522207] marvell-nfc pxa3xx-nand: 
[    3.522207] NDCR:  0xdd079fff
[    3.522207] NDCB0: 0x000d3000
[    3.522207] NDCB1: 0xfe000000
[    3.522207] NDCB2: 0x00000001
[    3.522207] NDCB3: 0x00000000
[    3.541194] marvell-nfc pxa3xx-nand: 
[    3.541194] NDCR:  0x9d079fff
[    3.541194] NDCB0: 0x000d3000
[    3.541194] NDCB1: 0xfe000000
[    3.541194] NDCB2: 0x00000001
[    3.541194] NDCB3: 0x00000000
[    3.560163] Bad block table not found for chip 0
[    3.564937] marvell-nfc pxa3xx-nand: 
[    3.564937] NDCR:  0xdd079fff
[    3.564937] NDCB0: 0x000d3000
[    3.564937] NDCB1: 0xffc00000
[    3.564937] NDCB2: 0x00000001
[    3.564937] NDCB3: 0x00000000
[    3.583953] marvell-nfc pxa3xx-nand: 
[    3.583953] NDCR:  0xdd079fff
[    3.583953] NDCB0: 0x000d3000
[    3.583953] NDCB1: 0xff800000
[    3.583953] NDCB2: 0x00000001
[    3.583953] NDCB3: 0x00000000
[    3.602976] marvell-nfc pxa3xx-nand: 
[    3.602976] NDCR:  0xdd079fff
[    3.602976] NDCB0: 0x000d3000
[    3.602976] NDCB1: 0xff400000
[    3.602976] NDCB2: 0x00000001
[    3.602976] NDCB3: 0x00000000
[    3.621958] marvell-nfc pxa3xx-nand: 
[    3.621958] NDCR:  0x9d079fff
[    3.621958] NDCB0: 0x000d3000
[    3.621958] NDCB1: 0xff400000
[    3.621958] NDCB2: 0x00000001
[    3.621958] NDCB3: 0x00000000
[    3.641031] marvell-nfc pxa3xx-nand: 
[    3.641031] NDCR:  0xdd079fff
[    3.641031] NDCB0: 0x000d3000
[    3.641031] NDCB1: 0xff000000
[    3.641031] NDCB2: 0x00000001
[    3.641031] NDCB3: 0x00000000
[    3.660018] marvell-nfc pxa3xx-nand: 
[    3.660018] NDCR:  0x9d079fff
[    3.660018] NDCB0: 0x000d3000
[    3.660018] NDCB1: 0xff000000
[    3.660018] NDCB2: 0x00000001
[    3.660018] NDCB3: 0x00000000
[    3.679132] marvell-nfc pxa3xx-nand: 
[    3.679132] NDCR:  0xdd079fff
[    3.679132] NDCB0: 0x000d3000
[    3.679132] NDCB1: 0xfec00000
[    3.679132] NDCB2: 0x00000001
[    3.679132] NDCB3: 0x00000000
[    3.698111] marvell-nfc pxa3xx-nand: 
[    3.698111] NDCR:  0x9d079fff
[    3.698111] NDCB0: 0x000d3000
[    3.698111] NDCB1: 0xfec00000
[    3.698111] NDCB2: 0x00000001
[    3.698111] NDCB3: 0x00000000
[    3.717181] marvell-nfc pxa3xx-nand: 
[    3.717181] NDCR:  0xdd079fff
[    3.717181] NDCB0: 0x000d3000
[    3.717181] NDCB1: 0xfe800000
[    3.717181] NDCB2: 0x00000001
[    3.717181] NDCB3: 0x00000000
[    3.736169] marvell-nfc pxa3xx-nand: 
[    3.736169] NDCR:  0x9d079fff
[    3.736169] NDCB0: 0x000d3000
[    3.736169] NDCB1: 0xfe800000
[    3.736169] NDCB2: 0x00000001
[    3.736169] NDCB3: 0x00000000
[    3.755238] marvell-nfc pxa3xx-nand: 
[    3.755238] NDCR:  0xdd079fff
[    3.755238] NDCB0: 0x000d3000
[    3.755238] NDCB1: 0xfe400000
[    3.755238] NDCB2: 0x00000001
[    3.755238] NDCB3: 0x00000000
[    3.774224] marvell-nfc pxa3xx-nand: 
[    3.774224] NDCR:  0x9d079fff
[    3.774224] NDCB0: 0x000d3000
[    3.774224] NDCB1: 0xfe400000
[    3.774224] NDCB2: 0x00000001
[    3.774224] NDCB3: 0x00000000
[    3.793297] marvell-nfc pxa3xx-nand: 
[    3.793297] NDCR:  0xdd079fff
[    3.793297] NDCB0: 0x000d3000
[    3.793297] NDCB1: 0xfe000000
[    3.793297] NDCB2: 0x00000001
[    3.793297] NDCB3: 0x00000000
[    3.812287] marvell-nfc pxa3xx-nand: 
[    3.812287] NDCR:  0x9d079fff
[    3.812287] NDCB0: 0x000d3000
[    3.812287] NDCB1: 0xfe000000
[    3.812287] NDCB2: 0x00000001
[    3.812287] NDCB3: 0x00000000
[    3.831254] Bad block table not found for chip 0
[    3.835915] Scanning device for bad blocks
[    3.840247] nand: nand_do_read_oob: from = 0x00000000, len = 64
[    3.846271] marvell-nfc pxa3xx-nand: 
[    3.846271] NDCR:  0x9d079fff
[    3.846271] NDCB0: 0x000d3000
[    3.846271] NDCB1: 0x00000000
[    3.846271] NDCB2: 0x00000000
[    3.846271] NDCB3: 0x00000000
[    3.865153] Bad eraseblock 0 at 0x000000000000
[    3.869834] nand: nand_do_read_oob: from = 0x00020000, len = 64
[    3.875857] marvell-nfc pxa3xx-nand: 
[    3.875857] NDCR:  0x9d079fff
[    3.875857] NDCB0: 0x000d3000
[    3.875857] NDCB1: 0x00400000
[    3.875857] NDCB2: 0x00000000
[    3.875857] NDCB3: 0x00000000
[    3.894763] nand: nand_do_read_oob: from = 0x00040000, len = 64
[    3.900960] marvell-nfc pxa3xx-nand: 
[    3.900960] NDCR:  0x9d079fff
[    3.900960] NDCB0: 0x000d3000
[    3.900960] NDCB1: 0x00800000
[    3.900960] NDCB2: 0x00000000
[    3.900960] NDCB3: 0x00000000
[    3.919870] Bad eraseblock 2 at 0x000000040000
[    3.924394] nand: nand_do_read_oob: from = 0x00060000, len = 64
[    3.930571] marvell-nfc pxa3xx-nand: 
[    3.930571] NDCR:  0x9d079fff
[    3.930571] NDCB0: 0x000d3000
[    3.930571] NDCB1: 0x00c00000
[    3.930571] NDCB2: 0x00000000
[    3.930571] NDCB3: 0x00000000
[    3.949456] Bad eraseblock 3 at 0x000000060000
[    3.953984] nand: nand_do_read_oob: from = 0x00080000, len = 64
[    3.960164] marvell-nfc pxa3xx-nand: 
[    3.960164] NDCR:  0x9d079fff
[    3.960164] NDCB0: 0x000d3000
[    3.960164] NDCB1: 0x01000000
[    3.960164] NDCB2: 0x00000000
[    3.960164] NDCB3: 0x00000000
[    3.979047] Bad eraseblock 4 at 0x000000080000
[    3.983571] nand: nand_do_read_oob: from = 0x000a0000, len = 64
[    3.989747] marvell-nfc pxa3xx-nand: 
[    3.989747] NDCR:  0x9d079fff
[    3.989747] NDCB0: 0x000d3000
[    3.989747] NDCB1: 0x01400000
[    3.989747] NDCB2: 0x00000000
[    3.989747] NDCB3: 0x00000000
[    4.008735] Bad eraseblock 5 at 0x0000000a0000
[    4.013265] nand: nand_do_read_oob: from = 0x000c0000, len = 64
[    4.019426] marvell-nfc pxa3xx-nand: 
[    4.019426] NDCR:  0x9d079fff
[    4.019426] NDCB0: 0x000d3000
[    4.019426] NDCB1: 0x01800000
[    4.019426] NDCB2: 0x00000000
[    4.019426] NDCB3: 0x00000000
[    4.038293] Bad eraseblock 6 at 0x0000000c0000
[    4.042975] nand: nand_do_read_oob: from = 0x000e0000, len = 64
[    4.049149] marvell-nfc pxa3xx-nand: 
[    4.049149] NDCR:  0x9d079fff
[    4.049149] NDCB0: 0x000d3000
[    4.049149] NDCB1: 0x01c00000
[    4.049149] NDCB2: 0x00000000
[    4.049149] NDCB3: 0x00000000
[    4.068019] Bad eraseblock 7 at 0x0000000e0000
[    4.072699] nand: nand_do_read_oob: from = 0x00100000, len = 64
[    4.078875] marvell-nfc pxa3xx-nand: 
[    4.078875] NDCR:  0x9d079fff
[    4.078875] NDCB0: 0x000d3000
[    4.078875] NDCB1: 0x02000000
[    4.078875] NDCB2: 0x00000000
[    4.078875] NDCB3: 0x00000000
[    4.098109] Bad eraseblock 8 at 0x000000100000
[    4.102830] nand: nand_do_read_oob: from = 0x00120000, len = 64
[    4.109007] marvell-nfc pxa3xx-nand: 
[    4.109007] NDCR:  0x9d079fff
[    4.109007] NDCB0: 0x000d3000
[    4.109007] NDCB1: 0x02400000
[    4.109007] NDCB2: 0x00000000
[    4.109007] NDCB3: 0x00000000
[    4.127919] nand: nand_do_read_oob: from = 0x00140000, len = 64
[    4.134120] marvell-nfc pxa3xx-nand: 
[    4.134120] NDCR:  0x9d079fff
[    4.134120] NDCB0: 0x000d3000
[    4.134120] NDCB1: 0x02800000
[    4.134120] NDCB2: 0x00000000
[    4.134120] NDCB3: 0x00000000
[    4.153008] Bad eraseblock 10 at 0x000000140000
[    4.157619] nand: nand_do_read_oob: from = 0x00160000, len = 64
[    4.163799] marvell-nfc pxa3xx-nand: 
[    4.163799] NDCR:  0x9d079fff
[    4.163799] NDCB0: 0x000d3000
[    4.163799] NDCB1: 0x02c00000
[    4.163799] NDCB2: 0x00000000
[    4.163799] NDCB3: 0x00000000
[    4.182687] Bad eraseblock 11 at 0x000000160000
[    4.187300] nand: nand_do_read_oob: from = 0x00180000, len = 64
[    4.193478] marvell-nfc pxa3xx-nand: 
[    4.193478] NDCR:  0x9d079fff
[    4.193478] NDCB0: 0x000d3000
[    4.193478] NDCB1: 0x03000000
[    4.193478] NDCB2: 0x00000000
[    4.193478] NDCB3: 0x00000000
[    4.212367] Bad eraseblock 12 at 0x000000180000
[    4.216978] nand: nand_do_read_oob: from = 0x001a0000, len = 64
[    4.223158] marvell-nfc pxa3xx-nand: 
[    4.223158] NDCR:  0x9d079fff
[    4.223158] NDCB0: 0x000d3000
[    4.223158] NDCB1: 0x03400000
[    4.223158] NDCB2: 0x00000000
[    4.223158] NDCB3: 0x00000000
[    4.242047] Bad eraseblock 13 at 0x0000001a0000
[    4.246659] nand: nand_do_read_oob: from = 0x001c0000, len = 64
[    4.252836] marvell-nfc pxa3xx-nand: 
[    4.252836] NDCR:  0x9d079fff
[    4.252836] NDCB0: 0x000d3000
[    4.252836] NDCB1: 0x03800000
[    4.252836] NDCB2: 0x00000000
[    4.252836] NDCB3: 0x00000000
[    4.271724] Bad eraseblock 14 at 0x0000001c0000
[    4.276329] nand: nand_do_read_oob: from = 0x001e0000, len = 64
[    4.282510] marvell-nfc pxa3xx-nand: 
[    4.282510] NDCR:  0x9d079fff
[    4.282510] NDCB0: 0x000d3000
[    4.282510] NDCB1: 0x03c00000
[    4.282510] NDCB2: 0x00000000
[    4.282510] NDCB3: 0x00000000
[    4.301396] Bad eraseblock 15 at 0x0000001e0000
[    4.306010] nand: nand_do_read_oob: from = 0x00200000, len = 64
[    4.312187] marvell-nfc pxa3xx-nand: 
[    4.312187] NDCR:  0x9d079fff
[    4.312187] NDCB0: 0x000d3000
[    4.312187] NDCB1: 0x04000000
[    4.312187] NDCB2: 0x00000000
[    4.312187] NDCB3: 0x00000000
[    4.331078] Bad eraseblock 16 at 0x000000200000
[    4.335690] nand: nand_do_read_oob: from = 0x00220000, len = 64
[    4.341868] marvell-nfc pxa3xx-nand: 
[    4.341868] NDCR:  0x9d079fff
[    4.341868] NDCB0: 0x000d3000
[    4.341868] NDCB1: 0x04400000
[    4.341868] NDCB2: 0x00000000
[    4.341868] NDCB3: 0x00000000
[    4.360757] Bad eraseblock 17 at 0x000000220000
[    4.365371] nand: nand_do_read_oob: from = 0x00240000, len = 64
[    4.371546] marvell-nfc pxa3xx-nand: 
[    4.371546] NDCR:  0x9d079fff
[    4.371546] NDCB0: 0x000d3000
[    4.371546] NDCB1: 0x04800000
[    4.371546] NDCB2: 0x00000000
[    4.371546] NDCB3: 0x00000000
[    4.390428] Bad eraseblock 18 at 0x000000240000
[    4.395041] nand: nand_do_read_oob: from = 0x00260000, len = 64
[    4.401219] marvell-nfc pxa3xx-nand: 
[    4.401219] NDCR:  0x9d079fff
[    4.401219] NDCB0: 0x000d3000
[    4.401219] NDCB1: 0x04c00000
[    4.401219] NDCB2: 0x00000000
[    4.401219] NDCB3: 0x00000000
[    4.420110] Bad eraseblock 19 at 0x000000260000
[    4.424721] nand: nand_do_read_oob: from = 0x00280000, len = 64
[    4.430902] marvell-nfc pxa3xx-nand: 
[    4.430902] NDCR:  0x9d079fff
[    4.430902] NDCB0: 0x000d3000
[    4.430902] NDCB1: 0x05000000
[    4.430902] NDCB2: 0x00000000
[    4.430902] NDCB3: 0x00000000
[    4.449790] Bad eraseblock 20 at 0x000000280000
[    4.454402] nand: nand_do_read_oob: from = 0x002a0000, len = 64
[    4.460578] marvell-nfc pxa3xx-nand: 
[    4.460578] NDCR:  0x9d079fff
[    4.460578] NDCB0: 0x000d3000
[    4.460578] NDCB1: 0x05400000
[    4.460578] NDCB2: 0x00000000
[    4.460578] NDCB3: 0x00000000
[    4.479469] Bad eraseblock 21 at 0x0000002a0000
[    4.484081] nand: nand_do_read_oob: from = 0x002c0000, len = 64
[    4.490260] marvell-nfc pxa3xx-nand: 
[    4.490260] NDCR:  0x9d079fff
[    4.490260] NDCB0: 0x000d3000
[    4.490260] NDCB1: 0x05800000
[    4.490260] NDCB2: 0x00000000
[    4.490260] NDCB3: 0x00000000
[    4.509171] Bad eraseblock 22 at 0x0000002c0000
[    4.513779] nand: nand_do_read_oob: from = 0x002e0000, len = 64
[    4.519957] marvell-nfc pxa3xx-nand: 
[    4.519957] NDCR:  0x9d079fff
[    4.519957] NDCB0: 0x000d3000
[    4.519957] NDCB1: 0x05c00000
[    4.519957] NDCB2: 0x00000000
[    4.519957] NDCB3: 0x00000000
[    4.538865] Bad eraseblock 23 at 0x0000002e0000
[    4.543479] nand: nand_do_read_oob: from = 0x00300000, len = 64
[    4.549653] marvell-nfc pxa3xx-nand: 
[    4.549653] NDCR:  0x9d079fff
[    4.549653] NDCB0: 0x000d3000
[    4.549653] NDCB1: 0x06000000
[    4.549653] NDCB2: 0x00000000
[    4.549653] NDCB3: 0x00000000
[    4.568531] Bad eraseblock 24 at 0x000000300000
[    4.573297] nand: nand_do_read_oob: from = 0x00320000, len = 64
[    4.579473] marvell-nfc pxa3xx-nand: 
[    4.579473] NDCR:  0x9d079fff
[    4.579473] NDCB0: 0x000d3000
[    4.579473] NDCB1: 0x06400000
[    4.579473] NDCB2: 0x00000000
[    4.579473] NDCB3: 0x00000000
[    4.598354] Bad eraseblock 25 at 0x000000320000
[    4.603123] nand: nand_do_read_oob: from = 0x00340000, len = 64
[    4.609298] marvell-nfc pxa3xx-nand: 
[    4.609298] NDCR:  0x9d079fff
[    4.609298] NDCB0: 0x000d3000
[    4.609298] NDCB1: 0x06800000
[    4.609298] NDCB2: 0x00000000
[    4.609298] NDCB3: 0x00000000
[    4.628177] Bad eraseblock 26 at 0x000000340000
[    4.632941] nand: nand_do_read_oob: from = 0x00360000, len = 64
[    4.639116] marvell-nfc pxa3xx-nand: 
[    4.639116] NDCR:  0x9d079fff
[    4.639116] NDCB0: 0x000d3000
[    4.639116] NDCB1: 0x06c00000
[    4.639116] NDCB2: 0x00000000
[    4.639116] NDCB3: 0x00000000
[    4.657995] Bad eraseblock 27 at 0x000000360000
[    4.662757] nand: nand_do_read_oob: from = 0x00380000, len = 64
[    4.668933] marvell-nfc pxa3xx-nand: 
[    4.668933] NDCR:  0x9d079fff
[    4.668933] NDCB0: 0x000d3000
[    4.668933] NDCB1: 0x07000000
[    4.668933] NDCB2: 0x00000000
[    4.668933] NDCB3: 0x00000000
[    4.687812] Bad eraseblock 28 at 0x000000380000
[    4.692577] nand: nand_do_read_oob: from = 0x003a0000, len = 64
[    4.698602] marvell-nfc pxa3xx-nand: 
[    4.698602] NDCR:  0x9d079fff
[    4.698602] NDCB0: 0x000d3000
[    4.698602] NDCB1: 0x07400000
[    4.698602] NDCB2: 0x00000000
[    4.698602] NDCB3: 0x00000000
[    4.717583] Bad eraseblock 29 at 0x0000003a0000
[    4.722352] nand: nand_do_read_oob: from = 0x003c0000, len = 64
[    4.728375] marvell-nfc pxa3xx-nand: 
[    4.728375] NDCR:  0x9d079fff
[    4.728375] NDCB0: 0x000d3000
[    4.728375] NDCB1: 0x07800000
[    4.728375] NDCB2: 0x00000000
[    4.728375] NDCB3: 0x00000000
[    4.747249] Bad eraseblock 30 at 0x0000003c0000
[    4.752017] nand: nand_do_read_oob: from = 0x003e0000, len = 64
[    4.758038] marvell-nfc pxa3xx-nand: 
[    4.758038] NDCR:  0x9d079fff
[    4.758038] NDCB0: 0x000d3000
[    4.758038] NDCB1: 0x07c00000
[    4.758038] NDCB2: 0x00000000
[    4.758038] NDCB3: 0x00000000
[    4.776911] Bad eraseblock 31 at 0x0000003e0000
[    4.781677] nand: nand_do_read_oob: from = 0x00400000, len = 64
[    4.787702] marvell-nfc pxa3xx-nand: 
[    4.787702] NDCR:  0x9d079fff
[    4.787702] NDCB0: 0x000d3000
[    4.787702] NDCB1: 0x08000000
[    4.787702] NDCB2: 0x00000000
[    4.787702] NDCB3: 0x00000000
[    4.806582] Bad eraseblock 32 at 0x000000400000
[    4.811349] nand: nand_do_read_oob: from = 0x00420000, len = 64
[    4.817375] marvell-nfc pxa3xx-nand: 
[    4.817375] NDCR:  0x9d079fff
[    4.817375] NDCB0: 0x000d3000
[    4.817375] NDCB1: 0x08400000
[    4.817375] NDCB2: 0x00000000
[    4.817375] NDCB3: 0x00000000
[    4.836255] Bad eraseblock 33 at 0x000000420000
[    4.841020] nand: nand_do_read_oob: from = 0x00440000, len = 64
[    4.847043] marvell-nfc pxa3xx-nand: 
[    4.847043] NDCR:  0x9d079fff
[    4.847043] NDCB0: 0x000d3000
[    4.847043] NDCB1: 0x08800000
[    4.847043] NDCB2: 0x00000000
[    4.847043] NDCB3: 0x00000000
[    4.865918] Bad eraseblock 34 at 0x000000440000
[    4.870684] nand: nand_do_read_oob: from = 0x00460000, len = 64
[    4.876706] marvell-nfc pxa3xx-nand: 
[    4.876706] NDCR:  0x9d079fff
[    4.876706] NDCB0: 0x000d3000
[    4.876706] NDCB1: 0x08c00000
[    4.876706] NDCB2: 0x00000000
[    4.876706] NDCB3: 0x00000000
[    4.895580] Bad eraseblock 35 at 0x000000460000
[    4.900347] nand: nand_do_read_oob: from = 0x00480000, len = 64
[    4.906370] marvell-nfc pxa3xx-nand: 
[    4.906370] NDCR:  0x9d079fff
[    4.906370] NDCB0: 0x000d3000
[    4.906370] NDCB1: 0x09000000
[    4.906370] NDCB2: 0x00000000
[    4.906370] NDCB3: 0x00000000
[    4.925252] Bad eraseblock 36 at 0x000000480000
[    4.930018] nand: nand_do_read_oob: from = 0x004a0000, len = 64
[    4.936039] marvell-nfc pxa3xx-nand: 
[    4.936039] NDCR:  0x9d079fff
[    4.936039] NDCB0: 0x000d3000
[    4.936039] NDCB1: 0x09400000
[    4.936039] NDCB2: 0x00000000
[    4.936039] NDCB3: 0x00000000
[    4.954915] Bad eraseblock 37 at 0x0000004a0000
[    4.959680] nand: nand_do_read_oob: from = 0x004c0000, len = 64
[    4.965704] marvell-nfc pxa3xx-nand: 
[    4.965704] NDCR:  0x9d079fff
[    4.965704] NDCB0: 0x000d3000
[    4.965704] NDCB1: 0x09800000
[    4.965704] NDCB2: 0x00000000
[    4.965704] NDCB3: 0x00000000
[    4.984575] Bad eraseblock 38 at 0x0000004c0000
[    4.989344] nand: nand_do_read_oob: from = 0x004e0000, len = 64
[    4.995365] marvell-nfc pxa3xx-nand: 
[    4.995365] NDCR:  0x9d079fff
[    4.995365] NDCB0: 0x000d3000
[    4.995365] NDCB1: 0x09c00000
[    4.995365] NDCB2: 0x00000000
[    4.995365] NDCB3: 0x00000000
[    5.014251] Bad eraseblock 39 at 0x0000004e0000
[    5.019025] nand: nand_do_read_oob: from = 0x00500000, len = 64
[    5.025046] marvell-nfc pxa3xx-nand: 
[    5.025046] NDCR:  0x9d079fff
[    5.025046] NDCB0: 0x000d3000
[    5.025046] NDCB1: 0x0a000000
[    5.025046] NDCB2: 0x00000000
[    5.025046] NDCB3: 0x00000000
[    5.043920] Bad eraseblock 40 at 0x000000500000
[    5.048527] nand: nand_do_read_oob: from = 0x00520000, len = 64
[    5.054704] marvell-nfc pxa3xx-nand: 
[    5.054704] NDCR:  0x9d079fff
[    5.054704] NDCB0: 0x000d3000
[    5.054704] NDCB1: 0x0a400000
[    5.054704] NDCB2: 0x00000000
[    5.054704] NDCB3: 0x00000000
[    5.073594] Bad eraseblock 41 at 0x000000520000
[    5.078207] nand: nand_do_read_oob: from = 0x00540000, len = 64
[    5.084401] marvell-nfc pxa3xx-nand: 
[    5.084401] NDCR:  0x9d079fff
[    5.084401] NDCB0: 0x000d3000
[    5.084401] NDCB1: 0x0a800000
[    5.084401] NDCB2: 0x00000000
[    5.084401] NDCB3: 0x00000000
[    5.103292] Bad eraseblock 42 at 0x000000540000
[    5.107905] nand: nand_do_read_oob: from = 0x00560000, len = 64
[    5.114083] marvell-nfc pxa3xx-nand: 
[    5.114083] NDCR:  0x9d079fff
[    5.114083] NDCB0: 0x000d3000
[    5.114083] NDCB1: 0x0ac00000
[    5.114083] NDCB2: 0x00000000
[    5.114083] NDCB3: 0x00000000
[    5.132972] Bad eraseblock 43 at 0x000000560000
[    5.137584] nand: nand_do_read_oob: from = 0x00580000, len = 64
[    5.143763] marvell-nfc pxa3xx-nand: 
[    5.143763] NDCR:  0x9d079fff
[    5.143763] NDCB0: 0x000d3000
[    5.143763] NDCB1: 0x0b000000
[    5.143763] NDCB2: 0x00000000
[    5.143763] NDCB3: 0x00000000
[    5.162648] Bad eraseblock 44 at 0x000000580000
[    5.167257] nand: nand_do_read_oob: from = 0x005a0000, len = 64
[    5.173434] marvell-nfc pxa3xx-nand: 
[    5.173434] NDCR:  0x9d079fff
[    5.173434] NDCB0: 0x000d3000
[    5.173434] NDCB1: 0x0b400000
[    5.173434] NDCB2: 0x00000000
[    5.173434] NDCB3: 0x00000000
[    5.192323] Bad eraseblock 45 at 0x0000005a0000
[    5.196934] nand: nand_do_read_oob: from = 0x005c0000, len = 64
[    5.203113] marvell-nfc pxa3xx-nand: 
[    5.203113] NDCR:  0x9d079fff
[    5.203113] NDCB0: 0x000d3000
[    5.203113] NDCB1: 0x0b800000
[    5.203113] NDCB2: 0x00000000
[    5.203113] NDCB3: 0x00000000
[    5.222004] Bad eraseblock 46 at 0x0000005c0000
[    5.226617] nand: nand_do_read_oob: from = 0x005e0000, len = 64
[    5.232793] marvell-nfc pxa3xx-nand: 
[    5.232793] NDCR:  0x9d079fff
[    5.232793] NDCB0: 0x000d3000
[    5.232793] NDCB1: 0x0bc00000
[    5.232793] NDCB2: 0x00000000
[    5.232793] NDCB3: 0x00000000
[    5.251684] Bad eraseblock 47 at 0x0000005e0000
[    5.256295] nand: nand_do_read_oob: from = 0x00600000, len = 64
[    5.262474] marvell-nfc pxa3xx-nand: 
[    5.262474] NDCR:  0x9d079fff
[    5.262474] NDCB0: 0x000d3000
[    5.262474] NDCB1: 0x0c000000
[    5.262474] NDCB2: 0x00000000
[    5.262474] NDCB3: 0x00000000
[    5.281361] Bad eraseblock 48 at 0x000000600000
[    5.285975] nand: nand_do_read_oob: from = 0x00620000, len = 64
[    5.292155] marvell-nfc pxa3xx-nand: 
[    5.292155] NDCR:  0x9d079fff
[    5.292155] NDCB0: 0x000d3000
[    5.292155] NDCB1: 0x0c400000
[    5.292155] NDCB2: 0x00000000
[    5.292155] NDCB3: 0x00000000
[    5.311043] Bad eraseblock 49 at 0x000000620000
[    5.315655] nand: nand_do_read_oob: from = 0x00640000, len = 64
[    5.321833] marvell-nfc pxa3xx-nand: 
[    5.321833] NDCR:  0x9d079fff
[    5.321833] NDCB0: 0x000d3000
[    5.321833] NDCB1: 0x0c800000
[    5.321833] NDCB2: 0x00000000
[    5.321833] NDCB3: 0x00000000
[    5.340720] Bad eraseblock 50 at 0x000000640000
[    5.345329] nand: nand_do_read_oob: from = 0x00660000, len = 64
[    5.351504] marvell-nfc pxa3xx-nand: 
[    5.351504] NDCR:  0x9d079fff
[    5.351504] NDCB0: 0x000d3000
[    5.351504] NDCB1: 0x0cc00000
[    5.351504] NDCB2: 0x00000000
[    5.351504] NDCB3: 0x00000000
[    5.370397] Bad eraseblock 51 at 0x000000660000
[    5.375006] nand: nand_do_read_oob: from = 0x00680000, len = 64
[    5.381188] marvell-nfc pxa3xx-nand: 
[    5.381188] NDCR:  0x9d079fff
[    5.381188] NDCB0: 0x000d3000
[    5.381188] NDCB1: 0x0d000000
[    5.381188] NDCB2: 0x00000000
[    5.381188] NDCB3: 0x00000000
[    5.400075] Bad eraseblock 52 at 0x000000680000
[    5.404686] nand: nand_do_read_oob: from = 0x006a0000, len = 64
[    5.410866] marvell-nfc pxa3xx-nand: 
[    5.410866] NDCR:  0x9d079fff
[    5.410866] NDCB0: 0x000d3000
[    5.410866] NDCB1: 0x0d400000
[    5.410866] NDCB2: 0x00000000
[    5.410866] NDCB3: 0x00000000
[    5.429755] Bad eraseblock 53 at 0x0000006a0000
[    5.434365] nand: nand_do_read_oob: from = 0x006c0000, len = 64
[    5.440546] marvell-nfc pxa3xx-nand: 
[    5.440546] NDCR:  0x9d079fff
[    5.440546] NDCB0: 0x000d3000
[    5.440546] NDCB1: 0x0d800000
[    5.440546] NDCB2: 0x00000000
[    5.440546] NDCB3: 0x00000000
[    5.459434] Bad eraseblock 54 at 0x0000006c0000
[    5.464046] nand: nand_do_read_oob: from = 0x006e0000, len = 64
[    5.470225] marvell-nfc pxa3xx-nand: 
[    5.470225] NDCR:  0x9d079fff
[    5.470225] NDCB0: 0x000d3000
[    5.470225] NDCB1: 0x0dc00000
[    5.470225] NDCB2: 0x00000000
[    5.470225] NDCB3: 0x00000000
[    5.489114] Bad eraseblock 55 at 0x0000006e0000
[    5.493729] nand: nand_do_read_oob: from = 0x00700000, len = 64
[    5.499905] marvell-nfc pxa3xx-nand: 
[    5.499905] NDCR:  0x9d079fff
[    5.499905] NDCB0: 0x000d3000
[    5.499905] NDCB1: 0x0e000000
[    5.499905] NDCB2: 0x00000000
[    5.499905] NDCB3: 0x00000000
[    5.518853] Bad eraseblock 56 at 0x000000700000
[    5.523471] nand: nand_do_read_oob: from = 0x00720000, len = 64
[    5.529652] marvell-nfc pxa3xx-nand: 
[    5.529652] NDCR:  0x9d079fff
[    5.529652] NDCB0: 0x000d3000
[    5.529652] NDCB1: 0x0e400000
[    5.529652] NDCB2: 0x00000000
[    5.529652] NDCB3: 0x00000000
[    5.548558] nand: nand_do_read_oob: from = 0x00740000, len = 64
[    5.554762] marvell-nfc pxa3xx-nand: 
[    5.554762] NDCR:  0x9d079fff
[    5.554762] NDCB0: 0x000d3000
[    5.554762] NDCB1: 0x0e800000
[    5.554762] NDCB2: 0x00000000
[    5.554762] NDCB3: 0x00000000
[    5.573683] nand: nand_do_read_oob: from = 0x00760000, len = 64
[    5.579883] marvell-nfc pxa3xx-nand: 
[    5.579883] NDCR:  0x9d079fff
[    5.579883] NDCB0: 0x000d3000
[    5.579883] NDCB1: 0x0ec00000
[    5.579883] NDCB2: 0x00000000
[    5.579883] NDCB3: 0x00000000
[    5.598875] nand: nand_do_read_oob: from = 0x00780000, len = 64
[    5.604907] marvell-nfc pxa3xx-nand: 
[    5.604907] NDCR:  0x9d079fff
[    5.604907] NDCB0: 0x000d3000
[    5.604907] NDCB1: 0x0f000000
[    5.604907] NDCB2: 0x00000000
[    5.604907] NDCB3: 0x00000000
[    5.623835] nand: nand_do_read_oob: from = 0x007a0000, len = 64
[    5.630035] marvell-nfc pxa3xx-nand: 
[    5.630035] NDCR:  0x9d079fff
[    5.630035] NDCB0: 0x000d3000
[    5.630035] NDCB1: 0x0f400000
[    5.630035] NDCB2: 0x00000000
[    5.630035] NDCB3: 0x00000000
[    5.648994] nand: nand_do_read_oob: from = 0x007c0000, len = 64
[    5.655020] marvell-nfc pxa3xx-nand: 
[    5.655020] NDCR:  0x9d079fff
[    5.655020] NDCB0: 0x000d3000
[    5.655020] NDCB1: 0x0f800000
[    5.655020] NDCB2: 0x00000000
[    5.655020] NDCB3: 0x00000000
[    5.673942] nand: nand_do_read_oob: from = 0x007e0000, len = 64
[    5.680140] marvell-nfc pxa3xx-nand: 
[    5.680140] NDCR:  0x9d079fff
[    5.680140] NDCB0: 0x000d3000
[    5.680140] NDCB1: 0x0fc00000
[    5.680140] NDCB2: 0x00000000
[    5.680140] NDCB3: 0x00000000
[    5.699079] nand: nand_do_read_oob: from = 0x00800000, len = 64
[    5.705111] marvell-nfc pxa3xx-nand: 
[    5.705111] NDCR:  0x9d079fff
[    5.705111] NDCB0: 0x000d3000
[    5.705111] NDCB1: 0x10000000
[    5.705111] NDCB2: 0x00000000
[    5.705111] NDCB3: 0x00000000
[    5.724036] nand: nand_do_read_oob: from = 0x00820000, len = 64
[    5.730239] marvell-nfc pxa3xx-nand: 
[    5.730239] NDCR:  0x9d079fff
[    5.730239] NDCB0: 0x000d3000
[    5.730239] NDCB1: 0x10400000
[    5.730239] NDCB2: 0x00000000
[    5.730239] NDCB3: 0x00000000
[    5.749158] nand: nand_do_read_oob: from = 0x00840000, len = 64
[    5.755191] marvell-nfc pxa3xx-nand: 
[    5.755191] NDCR:  0x9d079fff
[    5.755191] NDCB0: 0x000d3000
[    5.755191] NDCB1: 0x10800000
[    5.755191] NDCB2: 0x00000000
[    5.755191] NDCB3: 0x00000000
[    5.774114] nand: nand_do_read_oob: from = 0x00860000, len = 64
[    5.780313] marvell-nfc pxa3xx-nand: 
[    5.780313] NDCR:  0x9d079fff
[    5.780313] NDCB0: 0x000d3000
[    5.780313] NDCB1: 0x10c00000
[    5.780313] NDCB2: 0x00000000
[    5.780313] NDCB3: 0x00000000
[    5.799234] nand: nand_do_read_oob: from = 0x00880000, len = 64
[    5.805263] marvell-nfc pxa3xx-nand: 
[    5.805263] NDCR:  0x9d079fff
[    5.805263] NDCB0: 0x000d3000
[    5.805263] NDCB1: 0x11000000
[    5.805263] NDCB2: 0x00000000
[    5.805263] NDCB3: 0x00000000
[    5.824187] nand: nand_do_read_oob: from = 0x008a0000, len = 64
[    5.830385] marvell-nfc pxa3xx-nand: 
[    5.830385] NDCR:  0x9d079fff
[    5.830385] NDCB0: 0x000d3000
[    5.830385] NDCB1: 0x11400000
[    5.830385] NDCB2: 0x00000000
[    5.830385] NDCB3: 0x00000000
[    5.849304] nand: nand_do_read_oob: from = 0x008c0000, len = 64
[    5.855338] marvell-nfc pxa3xx-nand: 
[    5.855338] NDCR:  0x9d079fff
[    5.855338] NDCB0: 0x000d3000
[    5.855338] NDCB1: 0x11800000
[    5.855338] NDCB2: 0x00000000
[    5.855338] NDCB3: 0x00000000
[    5.874259] nand: nand_do_read_oob: from = 0x008e0000, len = 64
[    5.880457] marvell-nfc pxa3xx-nand: 
[    5.880457] NDCR:  0x9d079fff
[    5.880457] NDCB0: 0x000d3000
[    5.880457] NDCB1: 0x11c00000
[    5.880457] NDCB2: 0x00000000
[    5.880457] NDCB3: 0x00000000
[    5.899376] nand: nand_do_read_oob: from = 0x00900000, len = 64
[    5.905410] marvell-nfc pxa3xx-nand: 
[    5.905410] NDCR:  0x9d079fff
[    5.905410] NDCB0: 0x000d3000
[    5.905410] NDCB1: 0x12000000
[    5.905410] NDCB2: 0x00000000
[    5.905410] NDCB3: 0x00000000
[    5.924331] nand: nand_do_read_oob: from = 0x00920000, len = 64
[    5.930531] marvell-nfc pxa3xx-nand: 
[    5.930531] NDCR:  0x9d079fff
[    5.930531] NDCB0: 0x000d3000
[    5.930531] NDCB1: 0x12400000
[    5.930531] NDCB2: 0x00000000
[    5.930531] NDCB3: 0x00000000
[    5.949454] nand: nand_do_read_oob: from = 0x00940000, len = 64
[    5.955481] marvell-nfc pxa3xx-nand: 
[    5.955481] NDCR:  0x9d079fff
[    5.955481] NDCB0: 0x000d3000
[    5.955481] NDCB1: 0x12800000
[    5.955481] NDCB2: 0x00000000
[    5.955481] NDCB3: 0x00000000
[    5.974403] nand: nand_do_read_oob: from = 0x00960000, len = 64
[    5.980602] marvell-nfc pxa3xx-nand: 
[    5.980602] NDCR:  0x9d079fff
[    5.980602] NDCB0: 0x000d3000
[    5.980602] NDCB1: 0x12c00000
[    5.980602] NDCB2: 0x00000000
[    5.980602] NDCB3: 0x00000000
[    5.999523] nand: nand_do_read_oob: from = 0x00980000, len = 64
[    6.005555] marvell-nfc pxa3xx-nand: 
[    6.005555] NDCR:  0x9d079fff
[    6.005555] NDCB0: 0x000d3000
[    6.005555] NDCB1: 0x13000000
[    6.005555] NDCB2: 0x00000000
[    6.005555] NDCB3: 0x00000000
[    6.024485] nand: nand_do_read_oob: from = 0x009a0000, len = 64
[    6.030687] marvell-nfc pxa3xx-nand: 
[    6.030687] NDCR:  0x9d079fff
[    6.030687] NDCB0: 0x000d3000
[    6.030687] NDCB1: 0x13400000
[    6.030687] NDCB2: 0x00000000
[    6.030687] NDCB3: 0x00000000
[    6.049604] nand: nand_do_read_oob: from = 0x009c0000, len = 64
[    6.055636] marvell-nfc pxa3xx-nand: 
[    6.055636] NDCR:  0x9d079fff
[    6.055636] NDCB0: 0x000d3000
[    6.055636] NDCB1: 0x13800000
[    6.055636] NDCB2: 0x00000000
[    6.055636] NDCB3: 0x00000000
[    6.074560] nand: nand_do_read_oob: from = 0x009e0000, len = 64
[    6.080757] marvell-nfc pxa3xx-nand: 
[    6.080757] NDCR:  0x9d079fff
[    6.080757] NDCB0: 0x000d3000
[    6.080757] NDCB1: 0x13c00000
[    6.080757] NDCB2: 0x00000000
[    6.080757] NDCB3: 0x00000000
[    6.100387] nand: nand_do_read_oob: from = 0x00a00000, len = 64
[    6.106431] marvell-nfc pxa3xx-nand: 
[    6.106431] NDCR:  0x9d079fff
[    6.106431] NDCB0: 0x000d3000
[    6.106431] NDCB1: 0x14000000
[    6.106431] NDCB2: 0x00000000
[    6.106431] NDCB3: 0x00000000
[    6.125594] nand: nand_do_read_oob: from = 0x00a20000, len = 64
[    6.131995] marvell-nfc pxa3xx-nand: 
[    6.131995] NDCR:  0x9d079fff
[    6.131995] NDCB0: 0x000d3000
[    6.131995] NDCB1: 0x14400000
[    6.131995] NDCB2: 0x00000000
[    6.131995] NDCB3: 0x00000000
[    6.151138] nand: nand_do_read_oob: from = 0x00a40000, len = 64
[    6.157180] marvell-nfc pxa3xx-nand: 
[    6.157180] NDCR:  0x9d079fff
[    6.157180] NDCB0: 0x000d3000
[    6.157180] NDCB1: 0x14800000
[    6.157180] NDCB2: 0x00000000
[    6.157180] NDCB3: 0x00000000
[    6.176135] nand: nand_do_read_oob: from = 0x00a60000, len = 64
[    6.182335] marvell-nfc pxa3xx-nand: 
[    6.182335] NDCR:  0x9d079fff
[    6.182335] NDCB0: 0x000d3000
[    6.182335] NDCB1: 0x14c00000
[    6.182335] NDCB2: 0x00000000
[    6.182335] NDCB3: 0x00000000
[    6.201252] nand: nand_do_read_oob: from = 0x00a80000, len = 64
[    6.207284] marvell-nfc pxa3xx-nand: 
[    6.207284] NDCR:  0x9d079fff
[    6.207284] NDCB0: 0x000d3000
[    6.207284] NDCB1: 0x15000000
[    6.207284] NDCB2: 0x00000000
[    6.207284] NDCB3: 0x00000000
[    6.226208] nand: nand_do_read_oob: from = 0x00aa0000, len = 64
[    6.232417] marvell-nfc pxa3xx-nand: 
[    6.232417] NDCR:  0x9d079fff
[    6.232417] NDCB0: 0x000d3000
[    6.232417] NDCB1: 0x15400000
[    6.232417] NDCB2: 0x00000000
[    6.232417] NDCB3: 0x00000000
[    6.251343] nand: nand_do_read_oob: from = 0x00ac0000, len = 64
[    6.257374] marvell-nfc pxa3xx-nand: 
[    6.257374] NDCR:  0x9d079fff
[    6.257374] NDCB0: 0x000d3000
[    6.257374] NDCB1: 0x15800000
[    6.257374] NDCB2: 0x00000000
[    6.257374] NDCB3: 0x00000000
[    6.276297] nand: nand_do_read_oob: from = 0x00ae0000, len = 64
[    6.282505] marvell-nfc pxa3xx-nand: 
[    6.282505] NDCR:  0x9d079fff
[    6.282505] NDCB0: 0x000d3000
[    6.282505] NDCB1: 0x15c00000
[    6.282505] NDCB2: 0x00000000
[    6.282505] NDCB3: 0x00000000
[    6.301425] nand: nand_do_read_oob: from = 0x00b00000, len = 64
[    6.307456] marvell-nfc pxa3xx-nand: 
[    6.307456] NDCR:  0x9d079fff
[    6.307456] NDCB0: 0x000d3000
[    6.307456] NDCB1: 0x16000000
[    6.307456] NDCB2: 0x00000000
[    6.307456] NDCB3: 0x00000000
[    6.326378] nand: nand_do_read_oob: from = 0x00b20000, len = 64
[    6.332603] marvell-nfc pxa3xx-nand: 
[    6.332603] NDCR:  0x9d079fff
[    6.332603] NDCB0: 0x000d3000
[    6.332603] NDCB1: 0x16400000
[    6.332603] NDCB2: 0x00000000
[    6.332603] NDCB3: 0x00000000
[    6.351525] nand: nand_do_read_oob: from = 0x00b40000, len = 64
[    6.357553] marvell-nfc pxa3xx-nand: 
[    6.357553] NDCR:  0x9d079fff
[    6.357553] NDCB0: 0x000d3000
[    6.357553] NDCB1: 0x16800000
[    6.357553] NDCB2: 0x00000000
[    6.357553] NDCB3: 0x00000000
[    6.376477] nand: nand_do_read_oob: from = 0x00b60000, len = 64
[    6.382676] marvell-nfc pxa3xx-nand: 
[    6.382676] NDCR:  0x9d079fff
[    6.382676] NDCB0: 0x000d3000
[    6.382676] NDCB1: 0x16c00000
[    6.382676] NDCB2: 0x00000000
[    6.382676] NDCB3: 0x00000000
[    6.401595] nand: nand_do_read_oob: from = 0x00b80000, len = 64
[    6.407627] marvell-nfc pxa3xx-nand: 
[    6.407627] NDCR:  0x9d079fff
[    6.407627] NDCB0: 0x000d3000
[    6.407627] NDCB1: 0x17000000
[    6.407627] NDCB2: 0x00000000
[    6.407627] NDCB3: 0x00000000
[    6.426558] nand: nand_do_read_oob: from = 0x00ba0000, len = 64
[    6.432755] marvell-nfc pxa3xx-nand: 
[    6.432755] NDCR:  0x9d079fff
[    6.432755] NDCB0: 0x000d3000
[    6.432755] NDCB1: 0x17400000
[    6.432755] NDCB2: 0x00000000
[    6.432755] NDCB3: 0x00000000
[    6.451675] nand: nand_do_read_oob: from = 0x00bc0000, len = 64
[    6.457708] marvell-nfc pxa3xx-nand: 
[    6.457708] NDCR:  0x9d079fff
[    6.457708] NDCB0: 0x000d3000
[    6.457708] NDCB1: 0x17800000
[    6.457708] NDCB2: 0x00000000
[    6.457708] NDCB3: 0x00000000
[    6.476632] nand: nand_do_read_oob: from = 0x00be0000, len = 64
[    6.482837] marvell-nfc pxa3xx-nand: 
[    6.482837] NDCR:  0x9d079fff
[    6.482837] NDCB0: 0x000d3000
[    6.482837] NDCB1: 0x17c00000
[    6.482837] NDCB2: 0x00000000
[    6.482837] NDCB3: 0x00000000
[    6.501760] nand: nand_do_read_oob: from = 0x00c00000, len = 64
[    6.507789] marvell-nfc pxa3xx-nand: 
[    6.507789] NDCR:  0x9d079fff
[    6.507789] NDCB0: 0x000d3000
[    6.507789] NDCB1: 0x18000000
[    6.507789] NDCB2: 0x00000000
[    6.507789] NDCB3: 0x00000000
[    6.526712] nand: nand_do_read_oob: from = 0x00c20000, len = 64
[    6.532916] marvell-nfc pxa3xx-nand: 
[    6.532916] NDCR:  0x9d079fff
[    6.532916] NDCB0: 0x000d3000
[    6.532916] NDCB1: 0x18400000
[    6.532916] NDCB2: 0x00000000
[    6.532916] NDCB3: 0x00000000
[    6.551839] nand: nand_do_read_oob: from = 0x00c40000, len = 64
[    6.557871] marvell-nfc pxa3xx-nand: 
[    6.557871] NDCR:  0x9d079fff
[    6.557871] NDCB0: 0x000d3000
[    6.557871] NDCB1: 0x18800000
[    6.557871] NDCB2: 0x00000000
[    6.557871] NDCB3: 0x00000000
[    6.576801] nand: nand_do_read_oob: from = 0x00c60000, len = 64
[    6.583001] marvell-nfc pxa3xx-nand: 
[    6.583001] NDCR:  0x9d079fff
[    6.583001] NDCB0: 0x000d3000
[    6.583001] NDCB1: 0x18c00000
[    6.583001] NDCB2: 0x00000000
[    6.583001] NDCB3: 0x00000000
[    6.601918] nand: nand_do_read_oob: from = 0x00c80000, len = 64
[    6.607951] marvell-nfc pxa3xx-nand: 
[    6.607951] NDCR:  0x9d079fff
[    6.607951] NDCB0: 0x000d3000
[    6.607951] NDCB1: 0x19000000
[    6.607951] NDCB2: 0x00000000
[    6.607951] NDCB3: 0x00000000
[    6.626875] nand: nand_do_read_oob: from = 0x00ca0000, len = 64
[    6.633083] marvell-nfc pxa3xx-nand: 
[    6.633083] NDCR:  0x9d079fff
[    6.633083] NDCB0: 0x000d3000
[    6.633083] NDCB1: 0x19400000
[    6.633083] NDCB2: 0x00000000
[    6.633083] NDCB3: 0x00000000
[    6.652000] nand: nand_do_read_oob: from = 0x00cc0000, len = 64
[    6.658032] marvell-nfc pxa3xx-nand: 
[    6.658032] NDCR:  0x9d079fff
[    6.658032] NDCB0: 0x000d3000
[    6.658032] NDCB1: 0x19800000
[    6.658032] NDCB2: 0x00000000
[    6.658032] NDCB3: 0x00000000
[    6.676957] nand: nand_do_read_oob: from = 0x00ce0000, len = 64
[    6.683154] marvell-nfc pxa3xx-nand: 
[    6.683154] NDCR:  0x9d079fff
[    6.683154] NDCB0: 0x000d3000
[    6.683154] NDCB1: 0x19c00000
[    6.683154] NDCB2: 0x00000000
[    6.683154] NDCB3: 0x00000000
[    6.702072] nand: nand_do_read_oob: from = 0x00d00000, len = 64
[    6.708106] marvell-nfc pxa3xx-nand: 
[    6.708106] NDCR:  0x9d079fff
[    6.708106] NDCB0: 0x000d3000
[    6.708106] NDCB1: 0x1a000000
[    6.708106] NDCB2: 0x00000000
[    6.708106] NDCB3: 0x00000000
[    6.727028] nand: nand_do_read_oob: from = 0x00d20000, len = 64
[    6.733227] marvell-nfc pxa3xx-nand: 
[    6.733227] NDCR:  0x9d079fff
[    6.733227] NDCB0: 0x000d3000
[    6.733227] NDCB1: 0x1a400000
[    6.733227] NDCB2: 0x00000000
[    6.733227] NDCB3: 0x00000000
[    6.752146] nand: nand_do_read_oob: from = 0x00d40000, len = 64
[    6.758177] marvell-nfc pxa3xx-nand: 
[    6.758177] NDCR:  0x9d079fff
[    6.758177] NDCB0: 0x000d3000
[    6.758177] NDCB1: 0x1a800000
[    6.758177] NDCB2: 0x00000000
[    6.758177] NDCB3: 0x00000000
[    6.777073] Bad eraseblock 106 at 0x000000d40000
[    6.781928] nand: nand_do_read_oob: from = 0x00d60000, len = 64
[    6.787951] marvell-nfc pxa3xx-nand: 
[    6.787951] NDCR:  0x9d079fff
[    6.787951] NDCB0: 0x000d3000
[    6.787951] NDCB1: 0x1ac00000
[    6.787951] NDCB2: 0x00000000
[    6.787951] NDCB3: 0x00000000
[    6.806828] Bad eraseblock 107 at 0x000000d60000
[    6.811686] nand: nand_do_read_oob: from = 0x00d80000, len = 64
[    6.817711] marvell-nfc pxa3xx-nand: 
[    6.817711] NDCR:  0x9d079fff
[    6.817711] NDCB0: 0x000d3000
[    6.817711] NDCB1: 0x1b000000
[    6.817711] NDCB2: 0x00000000
[    6.817711] NDCB3: 0x00000000
[    6.836594] Bad eraseblock 108 at 0x000000d80000
[    6.841444] nand: nand_do_read_oob: from = 0x00da0000, len = 64
[    6.847469] marvell-nfc pxa3xx-nand: 
[    6.847469] NDCR:  0x9d079fff
[    6.847469] NDCB0: 0x000d3000
[    6.847469] NDCB1: 0x1b400000
[    6.847469] NDCB2: 0x00000000
[    6.847469] NDCB3: 0x00000000
[    6.866351] Bad eraseblock 109 at 0x000000da0000
[    6.871211] nand: nand_do_read_oob: from = 0x00dc0000, len = 64
[    6.877233] marvell-nfc pxa3xx-nand: 
[    6.877233] NDCR:  0x9d079fff
[    6.877233] NDCB0: 0x000d3000
[    6.877233] NDCB1: 0x1b800000
[    6.877233] NDCB2: 0x00000000
[    6.877233] NDCB3: 0x00000000
[    6.896109] Bad eraseblock 110 at 0x000000dc0000
[    6.900958] nand: nand_do_read_oob: from = 0x00de0000, len = 64
[    6.906983] marvell-nfc pxa3xx-nand: 
[    6.906983] NDCR:  0x9d079fff
[    6.906983] NDCB0: 0x000d3000
[    6.906983] NDCB1: 0x1bc00000
[    6.906983] NDCB2: 0x00000000
[    6.906983] NDCB3: 0x00000000
[    6.925856] Bad eraseblock 111 at 0x000000de0000
[    6.930708] nand: nand_do_read_oob: from = 0x00e00000, len = 64
[    6.936732] marvell-nfc pxa3xx-nand: 
[    6.936732] NDCR:  0x9d079fff
[    6.936732] NDCB0: 0x000d3000
[    6.936732] NDCB1: 0x1c000000
[    6.936732] NDCB2: 0x00000000
[    6.936732] NDCB3: 0x00000000
[    6.955620] Bad eraseblock 112 at 0x000000e00000
[    6.960474] nand: nand_do_read_oob: from = 0x00e20000, len = 64
[    6.966498] marvell-nfc pxa3xx-nand: 
[    6.966498] NDCR:  0x9d079fff
[    6.966498] NDCB0: 0x000d3000
[    6.966498] NDCB1: 0x1c400000
[    6.966498] NDCB2: 0x00000000
[    6.966498] NDCB3: 0x00000000
[    6.985403] Bad eraseblock 113 at 0x000000e20000
[    6.990259] nand: nand_do_read_oob: from = 0x00e40000, len = 64
[    6.996282] marvell-nfc pxa3xx-nand: 
[    6.996282] NDCR:  0x9d079fff
[    6.996282] NDCB0: 0x000d3000
[    6.996282] NDCB1: 0x1c800000
[    6.996282] NDCB2: 0x00000000
[    6.996282] NDCB3: 0x00000000
[    7.015181] Bad eraseblock 114 at 0x000000e40000
[    7.020031] nand: nand_do_read_oob: from = 0x00e60000, len = 64
[    7.026057] marvell-nfc pxa3xx-nand: 
[    7.026057] NDCR:  0x9d079fff
[    7.026057] NDCB0: 0x000d3000
[    7.026057] NDCB1: 0x1cc00000
[    7.026057] NDCB2: 0x00000000
[    7.026057] NDCB3: 0x00000000
[    7.044942] Bad eraseblock 115 at 0x000000e60000
[    7.049799] nand: nand_do_read_oob: from = 0x00e80000, len = 64
[    7.055822] marvell-nfc pxa3xx-nand: 
[    7.055822] NDCR:  0x9d079fff
[    7.055822] NDCB0: 0x000d3000
[    7.055822] NDCB1: 0x1d000000
[    7.055822] NDCB2: 0x00000000
[    7.055822] NDCB3: 0x00000000
[    7.074706] Bad eraseblock 116 at 0x000000e80000
[    7.079564] nand: nand_do_read_oob: from = 0x00ea0000, len = 64
[    7.085588] marvell-nfc pxa3xx-nand: 
[    7.085588] NDCR:  0x9d079fff
[    7.085588] NDCB0: 0x000d3000
[    7.085588] NDCB1: 0x1d400000
[    7.085588] NDCB2: 0x00000000
[    7.085588] NDCB3: 0x00000000
[    7.104464] Bad eraseblock 117 at 0x000000ea0000
[    7.109323] nand: nand_do_read_oob: from = 0x00ec0000, len = 64
[    7.115347] marvell-nfc pxa3xx-nand: 
[    7.115347] NDCR:  0x9d079fff
[    7.115347] NDCB0: 0x000d3000
[    7.115347] NDCB1: 0x1d800000
[    7.115347] NDCB2: 0x00000000
[    7.115347] NDCB3: 0x00000000
[    7.134230] Bad eraseblock 118 at 0x000000ec0000
[    7.139089] nand: nand_do_read_oob: from = 0x00ee0000, len = 64
[    7.145111] marvell-nfc pxa3xx-nand: 
[    7.145111] NDCR:  0x9d079fff
[    7.145111] NDCB0: 0x000d3000
[    7.145111] NDCB1: 0x1dc00000
[    7.145111] NDCB2: 0x00000000
[    7.145111] NDCB3: 0x00000000
[    7.163986] Bad eraseblock 119 at 0x000000ee0000
[    7.168847] nand: nand_do_read_oob: from = 0x00f00000, len = 64
[    7.174868] marvell-nfc pxa3xx-nand: 
[    7.174868] NDCR:  0x9d079fff
[    7.174868] NDCB0: 0x000d3000
[    7.174868] NDCB1: 0x1e000000
[    7.174868] NDCB2: 0x00000000
[    7.174868] NDCB3: 0x00000000
[    7.193745] Bad eraseblock 120 at 0x000000f00000
[    7.198446] nand: nand_do_read_oob: from = 0x00f20000, len = 64
[    7.204625] marvell-nfc pxa3xx-nand: 
[    7.204625] NDCR:  0x9d079fff
[    7.204625] NDCB0: 0x000d3000
[    7.204625] NDCB1: 0x1e400000
[    7.204625] NDCB2: 0x00000000
[    7.204625] NDCB3: 0x00000000
[    7.223514] Bad eraseblock 121 at 0x000000f20000
[    7.228211] nand: nand_do_read_oob: from = 0x00f40000, len = 64
[    7.234388] marvell-nfc pxa3xx-nand: 
[    7.234388] NDCR:  0x9d079fff
[    7.234388] NDCB0: 0x000d3000
[    7.234388] NDCB1: 0x1e800000
[    7.234388] NDCB2: 0x00000000
[    7.234388] NDCB3: 0x00000000
[    7.253281] Bad eraseblock 122 at 0x000000f40000
[    7.257975] nand: nand_do_read_oob: from = 0x00f60000, len = 64
[    7.264156] marvell-nfc pxa3xx-nand: 
[    7.264156] NDCR:  0x9d079fff
[    7.264156] NDCB0: 0x000d3000
[    7.264156] NDCB1: 0x1ec00000
[    7.264156] NDCB2: 0x00000000
[    7.264156] NDCB3: 0x00000000
[    7.283045] Bad eraseblock 123 at 0x000000f60000
[    7.287743] nand: nand_do_read_oob: from = 0x00f80000, len = 64
[    7.293923] marvell-nfc pxa3xx-nand: 
[    7.293923] NDCR:  0x9d079fff
[    7.293923] NDCB0: 0x000d3000
[    7.293923] NDCB1: 0x1f000000
[    7.293923] NDCB2: 0x00000000
[    7.293923] NDCB3: 0x00000000
[    7.312812] Bad eraseblock 124 at 0x000000f80000
[    7.317510] nand: nand_do_read_oob: from = 0x00fa0000, len = 64
[    7.323688] marvell-nfc pxa3xx-nand: 
[    7.323688] NDCR:  0x9d079fff
[    7.323688] NDCB0: 0x000d3000
[    7.323688] NDCB1: 0x1f400000
[    7.323688] NDCB2: 0x00000000
[    7.323688] NDCB3: 0x00000000
[    7.342578] Bad eraseblock 125 at 0x000000fa0000
[    7.347274] nand: nand_do_read_oob: from = 0x00fc0000, len = 64
[    7.353455] marvell-nfc pxa3xx-nand: 
[    7.353455] NDCR:  0x9d079fff
[    7.353455] NDCB0: 0x000d3000
[    7.353455] NDCB1: 0x1f800000
[    7.353455] NDCB2: 0x00000000
[    7.353455] NDCB3: 0x00000000
[    7.372344] Bad eraseblock 126 at 0x000000fc0000
[    7.377042] nand: nand_do_read_oob: from = 0x00fe0000, len = 64
[    7.383218] marvell-nfc pxa3xx-nand: 
[    7.383218] NDCR:  0x9d079fff
[    7.383218] NDCB0: 0x000d3000
[    7.383218] NDCB1: 0x1fc00000
[    7.383218] NDCB2: 0x00000000
[    7.383218] NDCB3: 0x00000000
[    7.402110] Bad eraseblock 127 at 0x000000fe0000
[    7.406807] nand: nand_do_read_oob: from = 0x01000000, len = 64
[    7.412988] marvell-nfc pxa3xx-nand: 
[    7.412988] NDCR:  0x9d079fff
[    7.412988] NDCB0: 0x000d3000
[    7.412988] NDCB1: 0x20000000
[    7.412988] NDCB2: 0x00000000
[    7.412988] NDCB3: 0x00000000
[    7.431878] Bad eraseblock 128 at 0x000001000000
[    7.436572] nand: nand_do_read_oob: from = 0x01020000, len = 64
[    7.442752] marvell-nfc pxa3xx-nand: 
[    7.442752] NDCR:  0x9d079fff
[    7.442752] NDCB0: 0x000d3000
[    7.442752] NDCB1: 0x20400000
[    7.442752] NDCB2: 0x00000000
[    7.442752] NDCB3: 0x00000000
[    7.461643] Bad eraseblock 129 at 0x000001020000
[    7.466341] nand: nand_do_read_oob: from = 0x01040000, len = 64
[    7.472520] marvell-nfc pxa3xx-nand: 
[    7.472520] NDCR:  0x9d079fff
[    7.472520] NDCB0: 0x000d3000
[    7.472520] NDCB1: 0x20800000
[    7.472520] NDCB2: 0x00000000
[    7.472520] NDCB3: 0x00000000
[    7.491406] Bad eraseblock 130 at 0x000001040000
[    7.496107] nand: nand_do_read_oob: from = 0x01060000, len = 64
[    7.502284] marvell-nfc pxa3xx-nand: 
[    7.502284] NDCR:  0x9d079fff
[    7.502284] NDCB0: 0x000d3000
[    7.502284] NDCB1: 0x20c00000
[    7.502284] NDCB2: 0x00000000
[    7.502284] NDCB3: 0x00000000
[    7.521175] Bad eraseblock 131 at 0x000001060000
[    7.525873] nand: nand_do_read_oob: from = 0x01080000, len = 64
[    7.532049] marvell-nfc pxa3xx-nand: 
[    7.532049] NDCR:  0x9d079fff
[    7.532049] NDCB0: 0x000d3000
[    7.532049] NDCB1: 0x21000000
[    7.532049] NDCB2: 0x00000000
[    7.532049] NDCB3: 0x00000000
[    7.550940] Bad eraseblock 132 at 0x000001080000
[    7.555640] nand: nand_do_read_oob: from = 0x010a0000, len = 64
[    7.561815] marvell-nfc pxa3xx-nand: 
[    7.561815] NDCR:  0x9d079fff
[    7.561815] NDCB0: 0x000d3000
[    7.561815] NDCB1: 0x21400000
[    7.561815] NDCB2: 0x00000000
[    7.561815] NDCB3: 0x00000000
[    7.580710] Bad eraseblock 133 at 0x0000010a0000
[    7.585404] nand: nand_do_read_oob: from = 0x010c0000, len = 64
[    7.591583] marvell-nfc pxa3xx-nand: 
[    7.591583] NDCR:  0x9d079fff
[    7.591583] NDCB0: 0x000d3000
[    7.591583] NDCB1: 0x21800000
[    7.591583] NDCB2: 0x00000000
[    7.591583] NDCB3: 0x00000000
[    7.610492] Bad eraseblock 134 at 0x0000010c0000
[    7.615187] nand: nand_do_read_oob: from = 0x010e0000, len = 64
[    7.621369] marvell-nfc pxa3xx-nand: 
[    7.621369] NDCR:  0x9d079fff
[    7.621369] NDCB0: 0x000d3000
[    7.621369] NDCB1: 0x21c00000
[    7.621369] NDCB2: 0x00000000
[    7.621369] NDCB3: 0x00000000
[    7.640258] Bad eraseblock 135 at 0x0000010e0000
[    7.644954] nand: nand_do_read_oob: from = 0x01100000, len = 64
[    7.651134] marvell-nfc pxa3xx-nand: 
[    7.651134] NDCR:  0x9d079fff
[    7.651134] NDCB0: 0x000d3000
[    7.651134] NDCB1: 0x22000000
[    7.651134] NDCB2: 0x00000000
[    7.651134] NDCB3: 0x00000000
[    7.670024] Bad eraseblock 136 at 0x000001100000
[    7.674721] nand: nand_do_read_oob: from = 0x01120000, len = 64
[    7.680897] marvell-nfc pxa3xx-nand: 
[    7.680897] NDCR:  0x9d079fff
[    7.680897] NDCB0: 0x000d3000
[    7.680897] NDCB1: 0x22400000
[    7.680897] NDCB2: 0x00000000
[    7.680897] NDCB3: 0x00000000
[    7.699789] Bad eraseblock 137 at 0x000001120000
[    7.704485] nand: nand_do_read_oob: from = 0x01140000, len = 64
[    7.710665] marvell-nfc pxa3xx-nand: 
[    7.710665] NDCR:  0x9d079fff
[    7.710665] NDCB0: 0x000d3000
[    7.710665] NDCB1: 0x22800000
[    7.710665] NDCB2: 0x00000000
[    7.710665] NDCB3: 0x00000000
[    7.729559] Bad eraseblock 138 at 0x000001140000
[    7.734253] nand: nand_do_read_oob: from = 0x01160000, len = 64
[    7.740432] marvell-nfc pxa3xx-nand: 
[    7.740432] NDCR:  0x9d079fff
[    7.740432] NDCB0: 0x000d3000
[    7.740432] NDCB1: 0x22c00000
[    7.740432] NDCB2: 0x00000000
[    7.740432] NDCB3: 0x00000000
[    7.759321] Bad eraseblock 139 at 0x000001160000
[    7.764019] nand: nand_do_read_oob: from = 0x01180000, len = 64
[    7.770198] marvell-nfc pxa3xx-nand: 
[    7.770198] NDCR:  0x9d079fff
[    7.770198] NDCB0: 0x000d3000
[    7.770198] NDCB1: 0x23000000
[    7.770198] NDCB2: 0x00000000
[    7.770198] NDCB3: 0x00000000
[    7.789086] Bad eraseblock 140 at 0x000001180000
[    7.793786] nand: nand_do_read_oob: from = 0x011a0000, len = 64
[    7.799963] marvell-nfc pxa3xx-nand: 
[    7.799963] NDCR:  0x9d079fff
[    7.799963] NDCB0: 0x000d3000
[    7.799963] NDCB1: 0x23400000
[    7.799963] NDCB2: 0x00000000
[    7.799963] NDCB3: 0x00000000
[    7.818901] nand: nand_do_read_oob: from = 0x011c0000, len = 64
[    7.824937] marvell-nfc pxa3xx-nand: 
[    7.824937] NDCR:  0x9d079fff
[    7.824937] NDCB0: 0x000d3000
[    7.824937] NDCB1: 0x23800000
[    7.824937] NDCB2: 0x00000000
[    7.824937] NDCB3: 0x00000000
[    7.843870] nand: nand_do_read_oob: from = 0x011e0000, len = 64
[    7.850073] marvell-nfc pxa3xx-nand: 
[    7.850073] NDCR:  0x9d079fff
[    7.850073] NDCB0: 0x000d3000
[    7.850073] NDCB1: 0x23c00000
[    7.850073] NDCB2: 0x00000000
[    7.850073] NDCB3: 0x00000000
[    7.869032] nand: nand_do_read_oob: from = 0x01200000, len = 64
[    7.875058] marvell-nfc pxa3xx-nand: 
[    7.875058] NDCR:  0x9d079fff
[    7.875058] NDCB0: 0x000d3000
[    7.875058] NDCB1: 0x24000000
[    7.875058] NDCB2: 0x00000000
[    7.875058] NDCB3: 0x00000000
[    7.893983] nand: nand_do_read_oob: from = 0x01220000, len = 64
[    7.900179] marvell-nfc pxa3xx-nand: 
[    7.900179] NDCR:  0x9d079fff
[    7.900179] NDCB0: 0x000d3000
[    7.900179] NDCB1: 0x24400000
[    7.900179] NDCB2: 0x00000000
[    7.900179] NDCB3: 0x00000000
[    7.919100] nand: nand_do_read_oob: from = 0x01240000, len = 64
[    7.925130] marvell-nfc pxa3xx-nand: 
[    7.925130] NDCR:  0x9d079fff
[    7.925130] NDCB0: 0x000d3000
[    7.925130] NDCB1: 0x24800000
[    7.925130] NDCB2: 0x00000000
[    7.925130] NDCB3: 0x00000000
[    7.944059] nand: nand_do_read_oob: from = 0x01260000, len = 64
[    7.950261] marvell-nfc pxa3xx-nand: 
[    7.950261] NDCR:  0x9d079fff
[    7.950261] NDCB0: 0x000d3000
[    7.950261] NDCB1: 0x24c00000
[    7.950261] NDCB2: 0x00000000
[    7.950261] NDCB3: 0x00000000
[    7.969181] nand: nand_do_read_oob: from = 0x01280000, len = 64
[    7.975214] marvell-nfc pxa3xx-nand: 
[    7.975214] NDCR:  0x9d079fff
[    7.975214] NDCB0: 0x000d3000
[    7.975214] NDCB1: 0x25000000
[    7.975214] NDCB2: 0x00000000
[    7.975214] NDCB3: 0x00000000
[    7.994144] nand: nand_do_read_oob: from = 0x012a0000, len = 64
[    8.000341] marvell-nfc pxa3xx-nand: 
[    8.000341] NDCR:  0x9d079fff
[    8.000341] NDCB0: 0x000d3000
[    8.000341] NDCB1: 0x25400000
[    8.000341] NDCB2: 0x00000000
[    8.000341] NDCB3: 0x00000000
[    8.019272] nand: nand_do_read_oob: from = 0x012c0000, len = 64
[    8.025304] marvell-nfc pxa3xx-nand: 
[    8.025304] NDCR:  0x9d079fff
[    8.025304] NDCB0: 0x000d3000
[    8.025304] NDCB1: 0x25800000
[    8.025304] NDCB2: 0x00000000
[    8.025304] NDCB3: 0x00000000
[    8.044235] nand: nand_do_read_oob: from = 0x012e0000, len = 64
[    8.050440] marvell-nfc pxa3xx-nand: 
[    8.050440] NDCR:  0x9d079fff
[    8.050440] NDCB0: 0x000d3000
[    8.050440] NDCB1: 0x25c00000
[    8.050440] NDCB2: 0x00000000
[    8.050440] NDCB3: 0x00000000
[    8.069360] nand: nand_do_read_oob: from = 0x01300000, len = 64
[    8.075391] marvell-nfc pxa3xx-nand: 
[    8.075391] NDCR:  0x9d079fff
[    8.075391] NDCB0: 0x000d3000
[    8.075391] NDCB1: 0x26000000
[    8.075391] NDCB2: 0x00000000
[    8.075391] NDCB3: 0x00000000
[    8.094921] nand: nand_do_read_oob: from = 0x01320000, len = 64
[    8.101167] marvell-nfc pxa3xx-nand: 
[    8.101167] NDCR:  0x9d079fff
[    8.101167] NDCB0: 0x000d3000
[    8.101167] NDCB1: 0x26400000
[    8.101167] NDCB2: 0x00000000
[    8.101167] NDCB3: 0x00000000
[    8.120098] nand: nand_do_read_oob: from = 0x01340000, len = 64
[    8.126128] marvell-nfc pxa3xx-nand: 
[    8.126128] NDCR:  0x9d079fff
[    8.126128] NDCB0: 0x000d3000
[    8.126128] NDCB1: 0x26800000
[    8.126128] NDCB2: 0x00000000
[    8.126128] NDCB3: 0x00000000
[    8.145054] nand: nand_do_read_oob: from = 0x01360000, len = 64
[    8.151260] marvell-nfc pxa3xx-nand: 
[    8.151260] NDCR:  0x9d079fff
[    8.151260] NDCB0: 0x000d3000
[    8.151260] NDCB1: 0x26c00000
[    8.151260] NDCB2: 0x00000000
[    8.151260] NDCB3: 0x00000000
[    8.170181] nand: nand_do_read_oob: from = 0x01380000, len = 64
[    8.176210] marvell-nfc pxa3xx-nand: 
[    8.176210] NDCR:  0x9d079fff
[    8.176210] NDCB0: 0x000d3000
[    8.176210] NDCB1: 0x27000000
[    8.176210] NDCB2: 0x00000000
[    8.176210] NDCB3: 0x00000000
[    8.195135] nand: nand_do_read_oob: from = 0x013a0000, len = 64
[    8.201338] marvell-nfc pxa3xx-nand: 
[    8.201338] NDCR:  0x9d079fff
[    8.201338] NDCB0: 0x000d3000
[    8.201338] NDCB1: 0x27400000
[    8.201338] NDCB2: 0x00000000
[    8.201338] NDCB3: 0x00000000
[    8.220259] nand: nand_do_read_oob: from = 0x013c0000, len = 64
[    8.226290] marvell-nfc pxa3xx-nand: 
[    8.226290] NDCR:  0x9d079fff
[    8.226290] NDCB0: 0x000d3000
[    8.226290] NDCB1: 0x27800000
[    8.226290] NDCB2: 0x00000000
[    8.226290] NDCB3: 0x00000000
[    8.245237] nand: nand_do_read_oob: from = 0x013e0000, len = 64
[    8.251438] marvell-nfc pxa3xx-nand: 
[    8.251438] NDCR:  0x9d079fff
[    8.251438] NDCB0: 0x000d3000
[    8.251438] NDCB1: 0x27c00000
[    8.251438] NDCB2: 0x00000000
[    8.251438] NDCB3: 0x00000000
[    8.270359] nand: nand_do_read_oob: from = 0x01400000, len = 64
[    8.276388] marvell-nfc pxa3xx-nand: 
[    8.276388] NDCR:  0x9d079fff
[    8.276388] NDCB0: 0x000d3000
[    8.276388] NDCB1: 0x28000000
[    8.276388] NDCB2: 0x00000000
[    8.276388] NDCB3: 0x00000000
[    8.295315] nand: nand_do_read_oob: from = 0x01420000, len = 64
[    8.301520] marvell-nfc pxa3xx-nand: 
[    8.301520] NDCR:  0x9d079fff
[    8.301520] NDCB0: 0x000d3000
[    8.301520] NDCB1: 0x28400000
[    8.301520] NDCB2: 0x00000000
[    8.301520] NDCB3: 0x00000000
[    8.320439] nand: nand_do_read_oob: from = 0x01440000, len = 64
[    8.326470] marvell-nfc pxa3xx-nand: 
[    8.326470] NDCR:  0x9d079fff
[    8.326470] NDCB0: 0x000d3000
[    8.326470] NDCB1: 0x28800000
[    8.326470] NDCB2: 0x00000000
[    8.326470] NDCB3: 0x00000000
[    8.345396] nand: nand_do_read_oob: from = 0x01460000, len = 64
[    8.351599] marvell-nfc pxa3xx-nand: 
[    8.351599] NDCR:  0x9d079fff
[    8.351599] NDCB0: 0x000d3000
[    8.351599] NDCB1: 0x28c00000
[    8.351599] NDCB2: 0x00000000
[    8.351599] NDCB3: 0x00000000
[    8.370521] nand: nand_do_read_oob: from = 0x01480000, len = 64
[    8.376552] marvell-nfc pxa3xx-nand: 
[    8.376552] NDCR:  0x9d079fff
[    8.376552] NDCB0: 0x000d3000
[    8.376552] NDCB1: 0x29000000
[    8.376552] NDCB2: 0x00000000
[    8.376552] NDCB3: 0x00000000
[    8.395475] nand: nand_do_read_oob: from = 0x014a0000, len = 64
[    8.401671] marvell-nfc pxa3xx-nand: 
[    8.401671] NDCR:  0x9d079fff
[    8.401671] NDCB0: 0x000d3000
[    8.401671] NDCB1: 0x29400000
[    8.401671] NDCB2: 0x00000000
[    8.401671] NDCB3: 0x00000000
[    8.420591] nand: nand_do_read_oob: from = 0x014c0000, len = 64
[    8.426625] marvell-nfc pxa3xx-nand: 
[    8.426625] NDCR:  0x9d079fff
[    8.426625] NDCB0: 0x000d3000
[    8.426625] NDCB1: 0x29800000
[    8.426625] NDCB2: 0x00000000
[    8.426625] NDCB3: 0x00000000
[    8.445558] nand: nand_do_read_oob: from = 0x014e0000, len = 64
[    8.451760] marvell-nfc pxa3xx-nand: 
[    8.451760] NDCR:  0x9d079fff
[    8.451760] NDCB0: 0x000d3000
[    8.451760] NDCB1: 0x29c00000
[    8.451760] NDCB2: 0x00000000
[    8.451760] NDCB3: 0x00000000
[    8.470686] nand: nand_do_read_oob: from = 0x01500000, len = 64
[    8.476715] marvell-nfc pxa3xx-nand: 
[    8.476715] NDCR:  0x9d079fff
[    8.476715] NDCB0: 0x000d3000
[    8.476715] NDCB1: 0x2a000000
[    8.476715] NDCB2: 0x00000000
[    8.476715] NDCB3: 0x00000000
[    8.495649] nand: nand_do_read_oob: from = 0x01520000, len = 64
[    8.501852] marvell-nfc pxa3xx-nand: 
[    8.501852] NDCR:  0x9d079fff
[    8.501852] NDCB0: 0x000d3000
[    8.501852] NDCB1: 0x2a400000
[    8.501852] NDCB2: 0x00000000
[    8.501852] NDCB3: 0x00000000
[    8.520778] nand: nand_do_read_oob: from = 0x01540000, len = 64
[    8.526815] marvell-nfc pxa3xx-nand: 
[    8.526815] NDCR:  0x9d079fff
[    8.526815] NDCB0: 0x000d3000
[    8.526815] NDCB1: 0x2a800000
[    8.526815] NDCB2: 0x00000000
[    8.526815] NDCB3: 0x00000000
[    8.545750] nand: nand_do_read_oob: from = 0x01560000, len = 64
[    8.551951] marvell-nfc pxa3xx-nand: 
[    8.551951] NDCR:  0x9d079fff
[    8.551951] NDCB0: 0x000d3000
[    8.551951] NDCB1: 0x2ac00000
[    8.551951] NDCB2: 0x00000000
[    8.551951] NDCB3: 0x00000000
[    8.570873] nand: nand_do_read_oob: from = 0x01580000, len = 64
[    8.576904] marvell-nfc pxa3xx-nand: 
[    8.576904] NDCR:  0x9d079fff
[    8.576904] NDCB0: 0x000d3000
[    8.576904] NDCB1: 0x2b000000
[    8.576904] NDCB2: 0x00000000
[    8.576904] NDCB3: 0x00000000
[    8.595838] nand: nand_do_read_oob: from = 0x015a0000, len = 64
[    8.602043] marvell-nfc pxa3xx-nand: 
[    8.602043] NDCR:  0x9d079fff
[    8.602043] NDCB0: 0x000d3000
[    8.602043] NDCB1: 0x2b400000
[    8.602043] NDCB2: 0x00000000
[    8.602043] NDCB3: 0x00000000
[    8.620971] nand: nand_do_read_oob: from = 0x015c0000, len = 64
[    8.627001] marvell-nfc pxa3xx-nand: 
[    8.627001] NDCR:  0x9d079fff
[    8.627001] NDCB0: 0x000d3000
[    8.627001] NDCB1: 0x2b800000
[    8.627001] NDCB2: 0x00000000
[    8.627001] NDCB3: 0x00000000
[    8.645925] nand: nand_do_read_oob: from = 0x015e0000, len = 64
[    8.652130] marvell-nfc pxa3xx-nand: 
[    8.652130] NDCR:  0x9d079fff
[    8.652130] NDCB0: 0x000d3000
[    8.652130] NDCB1: 0x2bc00000
[    8.652130] NDCB2: 0x00000000
[    8.652130] NDCB3: 0x00000000
[    8.671050] nand: nand_do_read_oob: from = 0x01600000, len = 64
[    8.677083] marvell-nfc pxa3xx-nand: 
[    8.677083] NDCR:  0x9d079fff
[    8.677083] NDCB0: 0x000d3000
[    8.677083] NDCB1: 0x2c000000
[    8.677083] NDCB2: 0x00000000
[    8.677083] NDCB3: 0x00000000
[    8.696005] nand: nand_do_read_oob: from = 0x01620000, len = 64
[    8.702203] marvell-nfc pxa3xx-nand: 
[    8.702203] NDCR:  0x9d079fff
[    8.702203] NDCB0: 0x000d3000
[    8.702203] NDCB1: 0x2c400000
[    8.702203] NDCB2: 0x00000000
[    8.702203] NDCB3: 0x00000000
[    8.721125] nand: nand_do_read_oob: from = 0x01640000, len = 64
[    8.727154] marvell-nfc pxa3xx-nand: 
[    8.727154] NDCR:  0x9d079fff
[    8.727154] NDCB0: 0x000d3000
[    8.727154] NDCB1: 0x2c800000
[    8.727154] NDCB2: 0x00000000
[    8.727154] NDCB3: 0x00000000
[    8.746081] nand: nand_do_read_oob: from = 0x01660000, len = 64
[    8.752284] marvell-nfc pxa3xx-nand: 
[    8.752284] NDCR:  0x9d079fff
[    8.752284] NDCB0: 0x000d3000
[    8.752284] NDCB1: 0x2cc00000
[    8.752284] NDCB2: 0x00000000
[    8.752284] NDCB3: 0x00000000
[    8.771175] Bad eraseblock 179 at 0x000001660000
[    8.775871] nand: nand_do_read_oob: from = 0x01680000, len = 64
[    8.782048] marvell-nfc pxa3xx-nand: 
[    8.782048] NDCR:  0x9d079fff
[    8.782048] NDCB0: 0x000d3000
[    8.782048] NDCB1: 0x2d000000
[    8.782048] NDCB2: 0x00000000
[    8.782048] NDCB3: 0x00000000
[    8.800940] Bad eraseblock 180 at 0x000001680000
[    8.805635] nand: nand_do_read_oob: from = 0x016a0000, len = 64
[    8.811815] marvell-nfc pxa3xx-nand: 
[    8.811815] NDCR:  0x9d079fff
[    8.811815] NDCB0: 0x000d3000
[    8.811815] NDCB1: 0x2d400000
[    8.811815] NDCB2: 0x00000000
[    8.811815] NDCB3: 0x00000000
[    8.830704] Bad eraseblock 181 at 0x0000016a0000
[    8.835402] nand: nand_do_read_oob: from = 0x016c0000, len = 64
[    8.841583] marvell-nfc pxa3xx-nand: 
[    8.841583] NDCR:  0x9d079fff
[    8.841583] NDCB0: 0x000d3000
[    8.841583] NDCB1: 0x2d800000
[    8.841583] NDCB2: 0x00000000
[    8.841583] NDCB3: 0x00000000
[    8.860473] Bad eraseblock 182 at 0x0000016c0000
[    8.865168] nand: nand_do_read_oob: from = 0x016e0000, len = 64
[    8.871347] marvell-nfc pxa3xx-nand: 
[    8.871347] NDCR:  0x9d079fff
[    8.871347] NDCB0: 0x000d3000
[    8.871347] NDCB1: 0x2dc00000
[    8.871347] NDCB2: 0x00000000
[    8.871347] NDCB3: 0x00000000
[    8.890257] Bad eraseblock 183 at 0x0000016e0000
[    8.894953] nand: nand_do_read_oob: from = 0x01700000, len = 64
[    8.901132] marvell-nfc pxa3xx-nand: 
[    8.901132] NDCR:  0x9d079fff
[    8.901132] NDCB0: 0x000d3000
[    8.901132] NDCB1: 0x2e000000
[    8.901132] NDCB2: 0x00000000
[    8.901132] NDCB3: 0x00000000
[    8.920020] Bad eraseblock 184 at 0x000001700000
[    8.924718] nand: nand_do_read_oob: from = 0x01720000, len = 64
[    8.930895] marvell-nfc pxa3xx-nand: 
[    8.930895] NDCR:  0x9d079fff
[    8.930895] NDCB0: 0x000d3000
[    8.930895] NDCB1: 0x2e400000
[    8.930895] NDCB2: 0x00000000
[    8.930895] NDCB3: 0x00000000
[    8.949786] Bad eraseblock 185 at 0x000001720000
[    8.954485] nand: nand_do_read_oob: from = 0x01740000, len = 64
[    8.960662] marvell-nfc pxa3xx-nand: 
[    8.960662] NDCR:  0x9d079fff
[    8.960662] NDCB0: 0x000d3000
[    8.960662] NDCB1: 0x2e800000
[    8.960662] NDCB2: 0x00000000
[    8.960662] NDCB3: 0x00000000
[    8.979554] Bad eraseblock 186 at 0x000001740000
[    8.984250] nand: nand_do_read_oob: from = 0x01760000, len = 64
[    8.990427] marvell-nfc pxa3xx-nand: 
[    8.990427] NDCR:  0x9d079fff
[    8.990427] NDCB0: 0x000d3000
[    8.990427] NDCB1: 0x2ec00000
[    8.990427] NDCB2: 0x00000000
[    8.990427] NDCB3: 0x00000000
[    9.009331] Bad eraseblock 187 at 0x000001760000
[    9.014025] nand: nand_do_read_oob: from = 0x01780000, len = 64
[    9.020206] marvell-nfc pxa3xx-nand: 
[    9.020206] NDCR:  0x9d079fff
[    9.020206] NDCB0: 0x000d3000
[    9.020206] NDCB1: 0x2f000000
[    9.020206] NDCB2: 0x00000000
[    9.020206] NDCB3: 0x00000000
[    9.039094] Bad eraseblock 188 at 0x000001780000
[    9.043792] nand: nand_do_read_oob: from = 0x017a0000, len = 64
[    9.049970] marvell-nfc pxa3xx-nand: 
[    9.049970] NDCR:  0x9d079fff
[    9.049970] NDCB0: 0x000d3000
[    9.049970] NDCB1: 0x2f400000
[    9.049970] NDCB2: 0x00000000
[    9.049970] NDCB3: 0x00000000
[    9.068867] Bad eraseblock 189 at 0x0000017a0000
[    9.073569] nand: nand_do_read_oob: from = 0x017c0000, len = 64
[    9.079741] marvell-nfc pxa3xx-nand: 
[    9.079741] NDCR:  0x9d079fff
[    9.079741] NDCB0: 0x000d3000
[    9.079741] NDCB1: 0x2f800000
[    9.079741] NDCB2: 0x00000000
[    9.079741] NDCB3: 0x00000000
[    9.098623] Bad eraseblock 190 at 0x0000017c0000
[    9.103465] nand: nand_do_read_oob: from = 0x017e0000, len = 64
[    9.109624] marvell-nfc pxa3xx-nand: 
[    9.109624] NDCR:  0x9d079fff
[    9.109624] NDCB0: 0x000d3000
[    9.109624] NDCB1: 0x2fc00000
[    9.109624] NDCB2: 0x00000000
[    9.109624] NDCB3: 0x00000000
[    9.128502] Bad eraseblock 191 at 0x0000017e0000
[    9.133362] nand: nand_do_read_oob: from = 0x01800000, len = 64
[    9.139533] marvell-nfc pxa3xx-nand: 
[    9.139533] NDCR:  0x9d079fff
[    9.139533] NDCB0: 0x000d3000
[    9.139533] NDCB1: 0x30000000
[    9.139533] NDCB2: 0x00000000
[    9.139533] NDCB3: 0x00000000
[    9.158414] Bad eraseblock 192 at 0x000001800000
[    9.163264] nand: nand_do_read_oob: from = 0x01820000, len = 64
[    9.169438] marvell-nfc pxa3xx-nand: 
[    9.169438] NDCR:  0x9d079fff
[    9.169438] NDCB0: 0x000d3000
[    9.169438] NDCB1: 0x30400000
[    9.169438] NDCB2: 0x00000000
[    9.169438] NDCB3: 0x00000000
[    9.188319] Bad eraseblock 193 at 0x000001820000
[    9.193177] nand: nand_do_read_oob: from = 0x01840000, len = 64
[    9.199354] marvell-nfc pxa3xx-nand: 
[    9.199354] NDCR:  0x9d079fff
[    9.199354] NDCB0: 0x000d3000
[    9.199354] NDCB1: 0x30800000
[    9.199354] NDCB2: 0x00000000
[    9.199354] NDCB3: 0x00000000
[    9.218231] Bad eraseblock 194 at 0x000001840000
[    9.223090] nand: nand_do_read_oob: from = 0x01860000, len = 64
[    9.229262] marvell-nfc pxa3xx-nand: 
[    9.229262] NDCR:  0x9d079fff
[    9.229262] NDCB0: 0x000d3000
[    9.229262] NDCB1: 0x30c00000
[    9.229262] NDCB2: 0x00000000
[    9.229262] NDCB3: 0x00000000
[    9.248142] Bad eraseblock 195 at 0x000001860000
[    9.252993] nand: nand_do_read_oob: from = 0x01880000, len = 64
[    9.259168] marvell-nfc pxa3xx-nand: 
[    9.259168] NDCR:  0x9d079fff
[    9.259168] NDCB0: 0x000d3000
[    9.259168] NDCB1: 0x31000000
[    9.259168] NDCB2: 0x00000000
[    9.259168] NDCB3: 0x00000000
[    9.278047] Bad eraseblock 196 at 0x000001880000
[    9.282898] nand: nand_do_read_oob: from = 0x018a0000, len = 64
[    9.289072] marvell-nfc pxa3xx-nand: 
[    9.289072] NDCR:  0x9d079fff
[    9.289072] NDCB0: 0x000d3000
[    9.289072] NDCB1: 0x31400000
[    9.289072] NDCB2: 0x00000000
[    9.289072] NDCB3: 0x00000000
[    9.307953] Bad eraseblock 197 at 0x0000018a0000
[    9.312811] nand: nand_do_read_oob: from = 0x018c0000, len = 64
[    9.318985] marvell-nfc pxa3xx-nand: 
[    9.318985] NDCR:  0x9d079fff
[    9.318985] NDCB0: 0x000d3000
[    9.318985] NDCB1: 0x31800000
[    9.318985] NDCB2: 0x00000000
[    9.318985] NDCB3: 0x00000000
[    9.337863] Bad eraseblock 198 at 0x0000018c0000
[    9.342715] nand: nand_do_read_oob: from = 0x018e0000, len = 64
[    9.348889] marvell-nfc pxa3xx-nand: 
[    9.348889] NDCR:  0x9d079fff
[    9.348889] NDCB0: 0x000d3000
[    9.348889] NDCB1: 0x31c00000
[    9.348889] NDCB2: 0x00000000
[    9.348889] NDCB3: 0x00000000
[    9.367767] Bad eraseblock 199 at 0x0000018e0000
[    9.372618] nand: nand_do_read_oob: from = 0x01900000, len = 64
[    9.378794] marvell-nfc pxa3xx-nand: 
[    9.378794] NDCR:  0x9d079fff
[    9.378794] NDCB0: 0x000d3000
[    9.378794] NDCB1: 0x32000000
[    9.378794] NDCB2: 0x00000000
[    9.378794] NDCB3: 0x00000000
[    9.397663] Bad eraseblock 200 at 0x000001900000
[    9.402530] nand: nand_do_read_oob: from = 0x01920000, len = 64
[    9.408554] marvell-nfc pxa3xx-nand: 
[    9.408554] NDCR:  0x9d079fff
[    9.408554] NDCB0: 0x000d3000
[    9.408554] NDCB1: 0x32400000
[    9.408554] NDCB2: 0x00000000
[    9.408554] NDCB3: 0x00000000
[    9.427438] Bad eraseblock 201 at 0x000001920000
[    9.432289] nand: nand_do_read_oob: from = 0x01940000, len = 64
[    9.438313] marvell-nfc pxa3xx-nand: 
[    9.438313] NDCR:  0x9d079fff
[    9.438313] NDCB0: 0x000d3000
[    9.438313] NDCB1: 0x32800000
[    9.438313] NDCB2: 0x00000000
[    9.438313] NDCB3: 0x00000000
[    9.457195] Bad eraseblock 202 at 0x000001940000
[    9.462047] nand: nand_do_read_oob: from = 0x01960000, len = 64
[    9.468069] marvell-nfc pxa3xx-nand: 
[    9.468069] NDCR:  0x9d079fff
[    9.468069] NDCB0: 0x000d3000
[    9.468069] NDCB1: 0x32c00000
[    9.468069] NDCB2: 0x00000000
[    9.468069] NDCB3: 0x00000000
[    9.486945] Bad eraseblock 203 at 0x000001960000
[    9.491807] nand: nand_do_read_oob: from = 0x01980000, len = 64
[    9.497826] marvell-nfc pxa3xx-nand: 
[    9.497826] NDCR:  0x9d079fff
[    9.497826] NDCB0: 0x000d3000
[    9.497826] NDCB1: 0x33000000
[    9.497826] NDCB2: 0x00000000
[    9.497826] NDCB3: 0x00000000
[    9.516702] Bad eraseblock 204 at 0x000001980000
[    9.521563] nand: nand_do_read_oob: from = 0x019a0000, len = 64
[    9.527585] marvell-nfc pxa3xx-nand: 
[    9.527585] NDCR:  0x9d079fff
[    9.527585] NDCB0: 0x000d3000
[    9.527585] NDCB1: 0x33400000
[    9.527585] NDCB2: 0x00000000
[    9.527585] NDCB3: 0x00000000
[    9.546470] Bad eraseblock 205 at 0x0000019a0000
[    9.551328] nand: nand_do_read_oob: from = 0x019c0000, len = 64
[    9.557350] marvell-nfc pxa3xx-nand: 
[    9.557350] NDCR:  0x9d079fff
[    9.557350] NDCB0: 0x000d3000
[    9.557350] NDCB1: 0x33800000
[    9.557350] NDCB2: 0x00000000
[    9.557350] NDCB3: 0x00000000
[    9.576226] Bad eraseblock 206 at 0x0000019c0000
[    9.581084] nand: nand_do_read_oob: from = 0x019e0000, len = 64
[    9.587109] marvell-nfc pxa3xx-nand: 
[    9.587109] NDCR:  0x9d079fff
[    9.587109] NDCB0: 0x000d3000
[    9.587109] NDCB1: 0x33c00000
[    9.587109] NDCB2: 0x00000000
[    9.587109] NDCB3: 0x00000000
[    9.605994] Bad eraseblock 207 at 0x0000019e0000
[    9.610854] nand: nand_do_read_oob: from = 0x01a00000, len = 64
[    9.616874] marvell-nfc pxa3xx-nand: 
[    9.616874] NDCR:  0x9d079fff
[    9.616874] NDCB0: 0x000d3000
[    9.616874] NDCB1: 0x34000000
[    9.616874] NDCB2: 0x00000000
[    9.616874] NDCB3: 0x00000000
[    9.635751] Bad eraseblock 208 at 0x000001a00000
[    9.640608] nand: nand_do_read_oob: from = 0x01a20000, len = 64
[    9.646633] marvell-nfc pxa3xx-nand: 
[    9.646633] NDCR:  0x9d079fff
[    9.646633] NDCB0: 0x000d3000
[    9.646633] NDCB1: 0x34400000
[    9.646633] NDCB2: 0x00000000
[    9.646633] NDCB3: 0x00000000
[    9.665517] Bad eraseblock 209 at 0x000001a20000
[    9.670375] nand: nand_do_read_oob: from = 0x01a40000, len = 64
[    9.676397] marvell-nfc pxa3xx-nand: 
[    9.676397] NDCR:  0x9d079fff
[    9.676397] NDCB0: 0x000d3000
[    9.676397] NDCB1: 0x34800000
[    9.676397] NDCB2: 0x00000000
[    9.676397] NDCB3: 0x00000000
[    9.695274] Bad eraseblock 210 at 0x000001a40000
[    9.700130] nand: nand_do_read_oob: from = 0x01a60000, len = 64
[    9.706155] marvell-nfc pxa3xx-nand: 
[    9.706155] NDCR:  0x9d079fff
[    9.706155] NDCB0: 0x000d3000
[    9.706155] NDCB1: 0x34c00000
[    9.706155] NDCB2: 0x00000000
[    9.706155] NDCB3: 0x00000000
[    9.725032] Bad eraseblock 211 at 0x000001a60000
[    9.729891] nand: nand_do_read_oob: from = 0x01a80000, len = 64
[    9.735912] marvell-nfc pxa3xx-nand: 
[    9.735912] NDCR:  0x9d079fff
[    9.735912] NDCB0: 0x000d3000
[    9.735912] NDCB1: 0x35000000
[    9.735912] NDCB2: 0x00000000
[    9.735912] NDCB3: 0x00000000
[    9.754791] Bad eraseblock 212 at 0x000001a80000
[    9.759646] nand: nand_do_read_oob: from = 0x01aa0000, len = 64
[    9.765671] marvell-nfc pxa3xx-nand: 
[    9.765671] NDCR:  0x9d079fff
[    9.765671] NDCB0: 0x000d3000
[    9.765671] NDCB1: 0x35400000
[    9.765671] NDCB2: 0x00000000
[    9.765671] NDCB3: 0x00000000
[    9.784546] Bad eraseblock 213 at 0x000001aa0000
[    9.789405] nand: nand_do_read_oob: from = 0x01ac0000, len = 64
[    9.795428] marvell-nfc pxa3xx-nand: 
[    9.795428] NDCR:  0x9d079fff
[    9.795428] NDCB0: 0x000d3000
[    9.795428] NDCB1: 0x35800000
[    9.795428] NDCB2: 0x00000000
[    9.795428] NDCB3: 0x00000000
[    9.814303] Bad eraseblock 214 at 0x000001ac0000
[    9.819164] nand: nand_do_read_oob: from = 0x01ae0000, len = 64
[    9.825186] marvell-nfc pxa3xx-nand: 
[    9.825186] NDCR:  0x9d079fff
[    9.825186] NDCB0: 0x000d3000
[    9.825186] NDCB1: 0x35c00000
[    9.825186] NDCB2: 0x00000000
[    9.825186] NDCB3: 0x00000000
[    9.844070] Bad eraseblock 215 at 0x000001ae0000
[    9.848921] nand: nand_do_read_oob: from = 0x01b00000, len = 64
[    9.854943] marvell-nfc pxa3xx-nand: 
[    9.854943] NDCR:  0x9d079fff
[    9.854943] NDCB0: 0x000d3000
[    9.854943] NDCB1: 0x36000000
[    9.854943] NDCB2: 0x00000000
[    9.854943] NDCB3: 0x00000000
[    9.873819] Bad eraseblock 216 at 0x000001b00000
[    9.878521] nand: nand_do_read_oob: from = 0x01b20000, len = 64
[    9.884699] marvell-nfc pxa3xx-nand: 
[    9.884699] NDCR:  0x9d079fff
[    9.884699] NDCB0: 0x000d3000
[    9.884699] NDCB1: 0x36400000
[    9.884699] NDCB2: 0x00000000
[    9.884699] NDCB3: 0x00000000
[    9.903587] Bad eraseblock 217 at 0x000001b20000
[    9.908284] nand: nand_do_read_oob: from = 0x01b40000, len = 64
[    9.914463] marvell-nfc pxa3xx-nand: 
[    9.914463] NDCR:  0x9d079fff
[    9.914463] NDCB0: 0x000d3000
[    9.914463] NDCB1: 0x36800000
[    9.914463] NDCB2: 0x00000000
[    9.914463] NDCB3: 0x00000000
[    9.933355] Bad eraseblock 218 at 0x000001b40000
[    9.938052] nand: nand_do_read_oob: from = 0x01b60000, len = 64
[    9.944230] marvell-nfc pxa3xx-nand: 
[    9.944230] NDCR:  0x9d079fff
[    9.944230] NDCB0: 0x000d3000
[    9.944230] NDCB1: 0x36c00000
[    9.944230] NDCB2: 0x00000000
[    9.944230] NDCB3: 0x00000000
[    9.963121] Bad eraseblock 219 at 0x000001b60000
[    9.967817] nand: nand_do_read_oob: from = 0x01b80000, len = 64
[    9.973996] marvell-nfc pxa3xx-nand: 
[    9.973996] NDCR:  0x9d079fff
[    9.973996] NDCB0: 0x000d3000
[    9.973996] NDCB1: 0x37000000
[    9.973996] NDCB2: 0x00000000
[    9.973996] NDCB3: 0x00000000
[    9.992886] Bad eraseblock 220 at 0x000001b80000
[    9.997584] nand: nand_do_read_oob: from = 0x01ba0000, len = 64
[   10.003762] marvell-nfc pxa3xx-nand: 
[   10.003762] NDCR:  0x9d079fff
[   10.003762] NDCB0: 0x000d3000
[   10.003762] NDCB1: 0x37400000
[   10.003762] NDCB2: 0x00000000
[   10.003762] NDCB3: 0x00000000
[   10.022661] Bad eraseblock 221 at 0x000001ba0000
[   10.027358] nand: nand_do_read_oob: from = 0x01bc0000, len = 64
[   10.033541] marvell-nfc pxa3xx-nand: 
[   10.033541] NDCR:  0x9d079fff
[   10.033541] NDCB0: 0x000d3000
[   10.033541] NDCB1: 0x37800000
[   10.033541] NDCB2: 0x00000000
[   10.033541] NDCB3: 0x00000000
[   10.052456] Bad eraseblock 222 at 0x000001bc0000
[   10.057151] nand: nand_do_read_oob: from = 0x01be0000, len = 64
[   10.063329] marvell-nfc pxa3xx-nand: 
[   10.063329] NDCR:  0x9d079fff
[   10.063329] NDCB0: 0x000d3000
[   10.063329] NDCB1: 0x37c00000
[   10.063329] NDCB2: 0x00000000
[   10.063329] NDCB3: 0x00000000
[   10.082230] Bad eraseblock 223 at 0x000001be0000
[   10.086925] nand: nand_do_read_oob: from = 0x01c00000, len = 64
[   10.093541] marvell-nfc pxa3xx-nand: 
[   10.093541] NDCR:  0x9d079fff
[   10.093541] NDCB0: 0x000d3000
[   10.093541] NDCB1: 0x38000000
[   10.093541] NDCB2: 0x00000000
[   10.093541] NDCB3: 0x00000000
[   10.112522] Bad eraseblock 224 at 0x000001c00000
[   10.117221] nand: nand_do_read_oob: from = 0x01c20000, len = 64
[   10.123407] marvell-nfc pxa3xx-nand: 
[   10.123407] NDCR:  0x9d079fff
[   10.123407] NDCB0: 0x000d3000
[   10.123407] NDCB1: 0x38400000
[   10.123407] NDCB2: 0x00000000
[   10.123407] NDCB3: 0x00000000
[   10.142307] Bad eraseblock 225 at 0x000001c20000
[   10.147009] nand: nand_do_read_oob: from = 0x01c40000, len = 64
[   10.153187] marvell-nfc pxa3xx-nand: 
[   10.153187] NDCR:  0x9d079fff
[   10.153187] NDCB0: 0x000d3000
[   10.153187] NDCB1: 0x38800000
[   10.153187] NDCB2: 0x00000000
[   10.153187] NDCB3: 0x00000000
[   10.172087] Bad eraseblock 226 at 0x000001c40000
[   10.176784] nand: nand_do_read_oob: from = 0x01c60000, len = 64
[   10.182963] marvell-nfc pxa3xx-nand: 
[   10.182963] NDCR:  0x9d079fff
[   10.182963] NDCB0: 0x000d3000
[   10.182963] NDCB1: 0x38c00000
[   10.182963] NDCB2: 0x00000000
[   10.182963] NDCB3: 0x00000000
[   10.201861] Bad eraseblock 227 at 0x000001c60000
[   10.206558] nand: nand_do_read_oob: from = 0x01c80000, len = 64
[   10.212737] marvell-nfc pxa3xx-nand: 
[   10.212737] NDCR:  0x9d079fff
[   10.212737] NDCB0: 0x000d3000
[   10.212737] NDCB1: 0x39000000
[   10.212737] NDCB2: 0x00000000
[   10.212737] NDCB3: 0x00000000
[   10.231639] Bad eraseblock 228 at 0x000001c80000
[   10.236333] nand: nand_do_read_oob: from = 0x01ca0000, len = 64
[   10.242510] marvell-nfc pxa3xx-nand: 
[   10.242510] NDCR:  0x9d079fff
[   10.242510] NDCB0: 0x000d3000
[   10.242510] NDCB1: 0x39400000
[   10.242510] NDCB2: 0x00000000
[   10.242510] NDCB3: 0x00000000
[   10.261400] Bad eraseblock 229 at 0x000001ca0000
[   10.266099] nand: nand_do_read_oob: from = 0x01cc0000, len = 64
[   10.272278] marvell-nfc pxa3xx-nand: 
[   10.272278] NDCR:  0x9d079fff
[   10.272278] NDCB0: 0x000d3000
[   10.272278] NDCB1: 0x39800000
[   10.272278] NDCB2: 0x00000000
[   10.272278] NDCB3: 0x00000000
[   10.291176] Bad eraseblock 230 at 0x000001cc0000
[   10.295877] nand: nand_do_read_oob: from = 0x01ce0000, len = 64
[   10.302060] marvell-nfc pxa3xx-nand: 
[   10.302060] NDCR:  0x9d079fff
[   10.302060] NDCB0: 0x000d3000
[   10.302060] NDCB1: 0x39c00000
[   10.302060] NDCB2: 0x00000000
[   10.302060] NDCB3: 0x00000000
[   10.320960] Bad eraseblock 231 at 0x000001ce0000
[   10.325658] nand: nand_do_read_oob: from = 0x01d00000, len = 64
[   10.331836] marvell-nfc pxa3xx-nand: 
[   10.331836] NDCR:  0x9d079fff
[   10.331836] NDCB0: 0x000d3000
[   10.331836] NDCB1: 0x3a000000
[   10.331836] NDCB2: 0x00000000
[   10.331836] NDCB3: 0x00000000
[   10.350735] Bad eraseblock 232 at 0x000001d00000
[   10.355433] nand: nand_do_read_oob: from = 0x01d20000, len = 64
[   10.361611] marvell-nfc pxa3xx-nand: 
[   10.361611] NDCR:  0x9d079fff
[   10.361611] NDCB0: 0x000d3000
[   10.361611] NDCB1: 0x3a400000
[   10.361611] NDCB2: 0x00000000
[   10.361611] NDCB3: 0x00000000
[   10.380512] Bad eraseblock 233 at 0x000001d20000
[   10.385207] nand: nand_do_read_oob: from = 0x01d40000, len = 64
[   10.391387] marvell-nfc pxa3xx-nand: 
[   10.391387] NDCR:  0x9d079fff
[   10.391387] NDCB0: 0x000d3000
[   10.391387] NDCB1: 0x3a800000
[   10.391387] NDCB2: 0x00000000
[   10.391387] NDCB3: 0x00000000
[   10.410286] Bad eraseblock 234 at 0x000001d40000
[   10.414983] nand: nand_do_read_oob: from = 0x01d60000, len = 64
[   10.421161] marvell-nfc pxa3xx-nand: 
[   10.421161] NDCR:  0x9d079fff
[   10.421161] NDCB0: 0x000d3000
[   10.421161] NDCB1: 0x3ac00000
[   10.421161] NDCB2: 0x00000000
[   10.421161] NDCB3: 0x00000000
[   10.440059] Bad eraseblock 235 at 0x000001d60000
[   10.444759] nand: nand_do_read_oob: from = 0x01d80000, len = 64
[   10.450935] marvell-nfc pxa3xx-nand: 
[   10.450935] NDCR:  0x9d079fff
[   10.450935] NDCB0: 0x000d3000
[   10.450935] NDCB1: 0x3b000000
[   10.450935] NDCB2: 0x00000000
[   10.450935] NDCB3: 0x00000000
[   10.469837] Bad eraseblock 236 at 0x000001d80000
[   10.474531] nand: nand_do_read_oob: from = 0x01da0000, len = 64
[   10.480709] marvell-nfc pxa3xx-nand: 
[   10.480709] NDCR:  0x9d079fff
[   10.480709] NDCB0: 0x000d3000
[   10.480709] NDCB1: 0x3b400000
[   10.480709] NDCB2: 0x00000000
[   10.480709] NDCB3: 0x00000000
[   10.499610] Bad eraseblock 237 at 0x000001da0000
[   10.504306] nand: nand_do_read_oob: from = 0x01dc0000, len = 64
[   10.510483] marvell-nfc pxa3xx-nand: 
[   10.510483] NDCR:  0x9d079fff
[   10.510483] NDCB0: 0x000d3000
[   10.510483] NDCB1: 0x3b800000
[   10.510483] NDCB2: 0x00000000
[   10.510483] NDCB3: 0x00000000
[   10.529383] Bad eraseblock 238 at 0x000001dc0000
[   10.534081] nand: nand_do_read_oob: from = 0x01de0000, len = 64
[   10.540259] marvell-nfc pxa3xx-nand: 
[   10.540259] NDCR:  0x9d079fff
[   10.540259] NDCB0: 0x000d3000
[   10.540259] NDCB1: 0x3bc00000
[   10.540259] NDCB2: 0x00000000
[   10.540259] NDCB3: 0x00000000
[   10.559159] Bad eraseblock 239 at 0x000001de0000
[   10.563856] nand: nand_do_read_oob: from = 0x01e00000, len = 64
[   10.570034] marvell-nfc pxa3xx-nand: 
[   10.570034] NDCR:  0x9d079fff
[   10.570034] NDCB0: 0x000d3000
[   10.570034] NDCB1: 0x3c000000
[   10.570034] NDCB2: 0x00000000
[   10.570034] NDCB3: 0x00000000
[   10.588971] Bad eraseblock 240 at 0x000001e00000
[   10.593675] nand: nand_do_read_oob: from = 0x01e20000, len = 64
[   10.599851] marvell-nfc pxa3xx-nand: 
[   10.599851] NDCR:  0x9d079fff
[   10.599851] NDCB0: 0x000d3000
[   10.599851] NDCB1: 0x3c400000
[   10.599851] NDCB2: 0x00000000
[   10.599851] NDCB3: 0x00000000
[   10.618811] Bad eraseblock 241 at 0x000001e20000
[   10.623511] nand: nand_do_read_oob: from = 0x01e40000, len = 64
[   10.629689] marvell-nfc pxa3xx-nand: 
[   10.629689] NDCR:  0x9d079fff
[   10.629689] NDCB0: 0x000d3000
[   10.629689] NDCB1: 0x3c800000
[   10.629689] NDCB2: 0x00000000
[   10.629689] NDCB3: 0x00000000
[   10.648573] Bad eraseblock 242 at 0x000001e40000
[   10.653415] nand: nand_do_read_oob: from = 0x01e60000, len = 64
[   10.659598] marvell-nfc pxa3xx-nand: 
[   10.659598] NDCR:  0x9d079fff
[   10.659598] NDCB0: 0x000d3000
[   10.659598] NDCB1: 0x3cc00000
[   10.659598] NDCB2: 0x00000000
[   10.659598] NDCB3: 0x00000000
[   10.678480] Bad eraseblock 243 at 0x000001e60000
[   10.683333] nand: nand_do_read_oob: from = 0x01e80000, len = 64
[   10.689511] marvell-nfc pxa3xx-nand: 
[   10.689511] NDCR:  0x9d079fff
[   10.689511] NDCB0: 0x000d3000
[   10.689511] NDCB1: 0x3d000000
[   10.689511] NDCB2: 0x00000000
[   10.689511] NDCB3: 0x00000000
[   10.708391] Bad eraseblock 244 at 0x000001e80000
[   10.713249] nand: nand_do_read_oob: from = 0x01ea0000, len = 64
[   10.719423] marvell-nfc pxa3xx-nand: 
[   10.719423] NDCR:  0x9d079fff
[   10.719423] NDCB0: 0x000d3000
[   10.719423] NDCB1: 0x3d400000
[   10.719423] NDCB2: 0x00000000
[   10.719423] NDCB3: 0x00000000
[   10.738306] Bad eraseblock 245 at 0x000001ea0000
[   10.743159] nand: nand_do_read_oob: from = 0x01ec0000, len = 64
[   10.749336] marvell-nfc pxa3xx-nand: 
[   10.749336] NDCR:  0x9d079fff
[   10.749336] NDCB0: 0x000d3000
[   10.749336] NDCB1: 0x3d800000
[   10.749336] NDCB2: 0x00000000
[   10.749336] NDCB3: 0x00000000
[   10.768217] Bad eraseblock 246 at 0x000001ec0000
[   10.773071] nand: nand_do_read_oob: from = 0x01ee0000, len = 64
[   10.779248] marvell-nfc pxa3xx-nand: 
[   10.779248] NDCR:  0x9d079fff
[   10.779248] NDCB0: 0x000d3000
[   10.779248] NDCB1: 0x3dc00000
[   10.779248] NDCB2: 0x00000000
[   10.779248] NDCB3: 0x00000000
[   10.798129] Bad eraseblock 247 at 0x000001ee0000
[   10.802985] nand: nand_do_read_oob: from = 0x01f00000, len = 64
[   10.809163] marvell-nfc pxa3xx-nand: 
[   10.809163] NDCR:  0x9d079fff
[   10.809163] NDCB0: 0x000d3000
[   10.809163] NDCB1: 0x3e000000
[   10.809163] NDCB2: 0x00000000
[   10.809163] NDCB3: 0x00000000
[   10.828050] Bad eraseblock 248 at 0x000001f00000
[   10.832908] nand: nand_do_read_oob: from = 0x01f20000, len = 64
[   10.839079] marvell-nfc pxa3xx-nand: 
[   10.839079] NDCR:  0x9d079fff
[   10.839079] NDCB0: 0x000d3000
[   10.839079] NDCB1: 0x3e400000
[   10.839079] NDCB2: 0x00000000
[   10.839079] NDCB3: 0x00000000
[   10.857967] Bad eraseblock 249 at 0x000001f20000
[   10.862820] nand: nand_do_read_oob: from = 0x01f40000, len = 64
[   10.868995] marvell-nfc pxa3xx-nand: 
[   10.868995] NDCR:  0x9d079fff
[   10.868995] NDCB0: 0x000d3000
[   10.868995] NDCB1: 0x3e800000
[   10.868995] NDCB2: 0x00000000
[   10.868995] NDCB3: 0x00000000
[   10.887877] Bad eraseblock 250 at 0x000001f40000
[   10.892733] nand: nand_do_read_oob: from = 0x01f60000, len = 64
[   10.898908] marvell-nfc pxa3xx-nand: 
[   10.898908] NDCR:  0x9d079fff
[   10.898908] NDCB0: 0x000d3000
[   10.898908] NDCB1: 0x3ec00000
[   10.898908] NDCB2: 0x00000000
[   10.898908] NDCB3: 0x00000000
[   10.917786] Bad eraseblock 251 at 0x000001f60000
[   10.922645] nand: nand_do_read_oob: from = 0x01f80000, len = 64
[   10.928821] marvell-nfc pxa3xx-nand: 
[   10.928821] NDCR:  0x9d079fff
[   10.928821] NDCB0: 0x000d3000
[   10.928821] NDCB1: 0x3f000000
[   10.928821] NDCB2: 0x00000000
[   10.928821] NDCB3: 0x00000000
[   10.947705] Bad eraseblock 252 at 0x000001f80000
[   10.952560] nand: nand_do_read_oob: from = 0x01fa0000, len = 64
[   10.958582] marvell-nfc pxa3xx-nand: 
[   10.958582] NDCR:  0x9d079fff
[   10.958582] NDCB0: 0x000d3000
[   10.958582] NDCB1: 0x3f400000
[   10.958582] NDCB2: 0x00000000
[   10.958582] NDCB3: 0x00000000
[   10.977575] Bad eraseblock 253 at 0x000001fa0000
[   10.982426] nand: nand_do_read_oob: from = 0x01fc0000, len = 64
[   10.988452] marvell-nfc pxa3xx-nand: 
[   10.988452] NDCR:  0x9d079fff
[   10.988452] NDCB0: 0x000d3000
[   10.988452] NDCB1: 0x3f800000
[   10.988452] NDCB2: 0x00000000
[   10.988452] NDCB3: 0x00000000
[   11.007336] Bad eraseblock 254 at 0x000001fc0000
[   11.012204] nand: nand_do_read_oob: from = 0x01fe0000, len = 64
[   11.018226] marvell-nfc pxa3xx-nand: 
[   11.018226] NDCR:  0x9d079fff
[   11.018226] NDCB0: 0x000d3000
[   11.018226] NDCB1: 0x3fc00000
[   11.018226] NDCB2: 0x00000000
[   11.018226] NDCB3: 0x00000000
[   11.037111] Bad eraseblock 255 at 0x000001fe0000
[   11.041971] nand: nand_do_read_oob: from = 0x02000000, len = 64
[   11.047994] marvell-nfc pxa3xx-nand: 
[   11.047994] NDCR:  0x9d079fff
[   11.047994] NDCB0: 0x000d3000
[   11.047994] NDCB1: 0x40000000
[   11.047994] NDCB2: 0x00000000
[   11.047994] NDCB3: 0x00000000
[   11.066878] Bad eraseblock 256 at 0x000002000000
[   11.071736] nand: nand_do_read_oob: from = 0x02020000, len = 64
[   11.077758] marvell-nfc pxa3xx-nand: 
[   11.077758] NDCR:  0x9d079fff
[   11.077758] NDCB0: 0x000d3000
[   11.077758] NDCB1: 0x40400000
[   11.077758] NDCB2: 0x00000000
[   11.077758] NDCB3: 0x00000000
[   11.096643] Bad eraseblock 257 at 0x000002020000
[   11.101500] nand: nand_do_read_oob: from = 0x02040000, len = 64
[   11.107524] marvell-nfc pxa3xx-nand: 
[   11.107524] NDCR:  0x9d079fff
[   11.107524] NDCB0: 0x000d3000
[   11.107524] NDCB1: 0x40800000
[   11.107524] NDCB2: 0x00000000
[   11.107524] NDCB3: 0x00000000
[   11.126407] Bad eraseblock 258 at 0x000002040000
[   11.131260] nand: nand_do_read_oob: from = 0x02060000, len = 64
[   11.137283] marvell-nfc pxa3xx-nand: 
[   11.137283] NDCR:  0x9d079fff
[   11.137283] NDCB0: 0x000d3000
[   11.137283] NDCB1: 0x40c00000
[   11.137283] NDCB2: 0x00000000
[   11.137283] NDCB3: 0x00000000
[   11.156165] Bad eraseblock 259 at 0x000002060000
[   11.161024] nand: nand_do_read_oob: from = 0x02080000, len = 64
[   11.167050] marvell-nfc pxa3xx-nand: 
[   11.167050] NDCR:  0x9d079fff
[   11.167050] NDCB0: 0x000d3000
[   11.167050] NDCB1: 0x41000000
[   11.167050] NDCB2: 0x00000000
[   11.167050] NDCB3: 0x00000000
[   11.185934] Bad eraseblock 260 at 0x000002080000
[   11.190810] nand: nand_do_read_oob: from = 0x020a0000, len = 64
[   11.196833] marvell-nfc pxa3xx-nand: 
[   11.196833] NDCR:  0x9d079fff
[   11.196833] NDCB0: 0x000d3000
[   11.196833] NDCB1: 0x41400000
[   11.196833] NDCB2: 0x00000000
[   11.196833] NDCB3: 0x00000000
[   11.215718] Bad eraseblock 261 at 0x0000020a0000
[   11.220575] nand: nand_do_read_oob: from = 0x020c0000, len = 64
[   11.226599] marvell-nfc pxa3xx-nand: 
[   11.226599] NDCR:  0x9d079fff
[   11.226599] NDCB0: 0x000d3000
[   11.226599] NDCB1: 0x41800000
[   11.226599] NDCB2: 0x00000000
[   11.226599] NDCB3: 0x00000000
[   11.245482] Bad eraseblock 262 at 0x0000020c0000
[   11.250340] nand: nand_do_read_oob: from = 0x020e0000, len = 64
[   11.256364] marvell-nfc pxa3xx-nand: 
[   11.256364] NDCR:  0x9d079fff
[   11.256364] NDCB0: 0x000d3000
[   11.256364] NDCB1: 0x41c00000
[   11.256364] NDCB2: 0x00000000
[   11.256364] NDCB3: 0x00000000
[   11.275246] Bad eraseblock 263 at 0x0000020e0000
[   11.280108] nand: nand_do_read_oob: from = 0x02100000, len = 64
[   11.286131] marvell-nfc pxa3xx-nand: 
[   11.286131] NDCR:  0x9d079fff
[   11.286131] NDCB0: 0x000d3000
[   11.286131] NDCB1: 0x42000000
[   11.286131] NDCB2: 0x00000000
[   11.286131] NDCB3: 0x00000000
[   11.305013] Bad eraseblock 264 at 0x000002100000
[   11.309866] nand: nand_do_read_oob: from = 0x02120000, len = 64
[   11.315888] marvell-nfc pxa3xx-nand: 
[   11.315888] NDCR:  0x9d079fff
[   11.315888] NDCB0: 0x000d3000
[   11.315888] NDCB1: 0x42400000
[   11.315888] NDCB2: 0x00000000
[   11.315888] NDCB3: 0x00000000
[   11.334770] Bad eraseblock 265 at 0x000002120000
[   11.339622] nand: nand_do_read_oob: from = 0x02140000, len = 64
[   11.345645] marvell-nfc pxa3xx-nand: 
[   11.345645] NDCR:  0x9d079fff
[   11.345645] NDCB0: 0x000d3000
[   11.345645] NDCB1: 0x42800000
[   11.345645] NDCB2: 0x00000000
[   11.345645] NDCB3: 0x00000000
[   11.364528] Bad eraseblock 266 at 0x000002140000
[   11.369389] nand: nand_do_read_oob: from = 0x02160000, len = 64
[   11.375411] marvell-nfc pxa3xx-nand: 
[   11.375411] NDCR:  0x9d079fff
[   11.375411] NDCB0: 0x000d3000
[   11.375411] NDCB1: 0x42c00000
[   11.375411] NDCB2: 0x00000000
[   11.375411] NDCB3: 0x00000000
[   11.394297] Bad eraseblock 267 at 0x000002160000
[   11.399156] nand: nand_do_read_oob: from = 0x02180000, len = 64
[   11.405178] marvell-nfc pxa3xx-nand: 
[   11.405178] NDCR:  0x9d079fff
[   11.405178] NDCB0: 0x000d3000
[   11.405178] NDCB1: 0x43000000
[   11.405178] NDCB2: 0x00000000
[   11.405178] NDCB3: 0x00000000
[   11.424063] Bad eraseblock 268 at 0x000002180000
[   11.428921] nand: nand_do_read_oob: from = 0x021a0000, len = 64
[   11.434944] marvell-nfc pxa3xx-nand: 
[   11.434944] NDCR:  0x9d079fff
[   11.434944] NDCB0: 0x000d3000
[   11.434944] NDCB1: 0x43400000
[   11.434944] NDCB2: 0x00000000
[   11.434944] NDCB3: 0x00000000
[   11.453828] Bad eraseblock 269 at 0x0000021a0000
[   11.458530] nand: nand_do_read_oob: from = 0x021c0000, len = 64
[   11.464707] marvell-nfc pxa3xx-nand: 
[   11.464707] NDCR:  0x9d079fff
[   11.464707] NDCB0: 0x000d3000
[   11.464707] NDCB1: 0x43800000
[   11.464707] NDCB2: 0x00000000
[   11.464707] NDCB3: 0x00000000
[   11.483605] Bad eraseblock 270 at 0x0000021c0000
[   11.488303] nand: nand_do_read_oob: from = 0x021e0000, len = 64
[   11.494480] marvell-nfc pxa3xx-nand: 
[   11.494480] NDCR:  0x9d079fff
[   11.494480] NDCB0: 0x000d3000
[   11.494480] NDCB1: 0x43c00000
[   11.494480] NDCB2: 0x00000000
[   11.494480] NDCB3: 0x00000000
[   11.513370] Bad eraseblock 271 at 0x0000021e0000
[   11.518070] nand: nand_do_read_oob: from = 0x02200000, len = 64
[   11.524247] marvell-nfc pxa3xx-nand: 
[   11.524247] NDCR:  0x9d079fff
[   11.524247] NDCB0: 0x000d3000
[   11.524247] NDCB1: 0x44000000
[   11.524247] NDCB2: 0x00000000
[   11.524247] NDCB3: 0x00000000
[   11.543147] Bad eraseblock 272 at 0x000002200000
[   11.547845] nand: nand_do_read_oob: from = 0x02220000, len = 64
[   11.554024] marvell-nfc pxa3xx-nand: 
[   11.554024] NDCR:  0x9d079fff
[   11.554024] NDCB0: 0x000d3000
[   11.554024] NDCB1: 0x44400000
[   11.554024] NDCB2: 0x00000000
[   11.554024] NDCB3: 0x00000000
[   11.572920] Bad eraseblock 273 at 0x000002220000
[   11.577619] nand: nand_do_read_oob: from = 0x02240000, len = 64
[   11.583797] marvell-nfc pxa3xx-nand: 
[   11.583797] NDCR:  0x9d079fff
[   11.583797] NDCB0: 0x000d3000
[   11.583797] NDCB1: 0x44800000
[   11.583797] NDCB2: 0x00000000
[   11.583797] NDCB3: 0x00000000
[   11.602698] Bad eraseblock 274 at 0x000002240000
[   11.607394] nand: nand_do_read_oob: from = 0x02260000, len = 64
[   11.613570] marvell-nfc pxa3xx-nand: 
[   11.613570] NDCR:  0x9d079fff
[   11.613570] NDCB0: 0x000d3000
[   11.613570] NDCB1: 0x44c00000
[   11.613570] NDCB2: 0x00000000
[   11.613570] NDCB3: 0x00000000
[   11.632467] Bad eraseblock 275 at 0x000002260000
[   11.637169] nand: nand_do_read_oob: from = 0x02280000, len = 64
[   11.643350] marvell-nfc pxa3xx-nand: 
[   11.643350] NDCR:  0x9d079fff
[   11.643350] NDCB0: 0x000d3000
[   11.643350] NDCB1: 0x45000000
[   11.643350] NDCB2: 0x00000000
[   11.643350] NDCB3: 0x00000000
[   11.662246] Bad eraseblock 276 at 0x000002280000
[   11.666944] nand: nand_do_read_oob: from = 0x022a0000, len = 64
[   11.673121] marvell-nfc pxa3xx-nand: 
[   11.673121] NDCR:  0x9d079fff
[   11.673121] NDCB0: 0x000d3000
[   11.673121] NDCB1: 0x45400000
[   11.673121] NDCB2: 0x00000000
[   11.673121] NDCB3: 0x00000000
[   11.692022] Bad eraseblock 277 at 0x0000022a0000
[   11.696719] nand: nand_do_read_oob: from = 0x022c0000, len = 64
[   11.702897] marvell-nfc pxa3xx-nand: 
[   11.702897] NDCR:  0x9d079fff
[   11.702897] NDCB0: 0x000d3000
[   11.702897] NDCB1: 0x45800000
[   11.702897] NDCB2: 0x00000000
[   11.702897] NDCB3: 0x00000000
[   11.721798] Bad eraseblock 278 at 0x0000022c0000
[   11.726494] nand: nand_do_read_oob: from = 0x022e0000, len = 64
[   11.732674] marvell-nfc pxa3xx-nand: 
[   11.732674] NDCR:  0x9d079fff
[   11.732674] NDCB0: 0x000d3000
[   11.732674] NDCB1: 0x45c00000
[   11.732674] NDCB2: 0x00000000
[   11.732674] NDCB3: 0x00000000
[   11.751568] Bad eraseblock 279 at 0x0000022e0000
[   11.756268] nand: nand_do_read_oob: from = 0x02300000, len = 64
[   11.762447] marvell-nfc pxa3xx-nand: 
[   11.762447] NDCR:  0x9d079fff
[   11.762447] NDCB0: 0x000d3000
[   11.762447] NDCB1: 0x46000000
[   11.762447] NDCB2: 0x00000000
[   11.762447] NDCB3: 0x00000000
[   11.781346] Bad eraseblock 280 at 0x000002300000
[   11.786041] nand: nand_do_read_oob: from = 0x02320000, len = 64
[   11.792220] marvell-nfc pxa3xx-nand: 
[   11.792220] NDCR:  0x9d079fff
[   11.792220] NDCB0: 0x000d3000
[   11.792220] NDCB1: 0x46400000
[   11.792220] NDCB2: 0x00000000
[   11.792220] NDCB3: 0x00000000
[   11.811110] Bad eraseblock 281 at 0x000002320000
[   11.815809] nand: nand_do_read_oob: from = 0x02340000, len = 64
[   11.821987] marvell-nfc pxa3xx-nand: 
[   11.821987] NDCR:  0x9d079fff
[   11.821987] NDCB0: 0x000d3000
[   11.821987] NDCB1: 0x46800000
[   11.821987] NDCB2: 0x00000000
[   11.821987] NDCB3: 0x00000000
[   11.840906] Bad eraseblock 282 at 0x000002340000
[   11.845602] nand: nand_do_read_oob: from = 0x02360000, len = 64
[   11.851778] marvell-nfc pxa3xx-nand: 
[   11.851778] NDCR:  0x9d079fff
[   11.851778] NDCB0: 0x000d3000
[   11.851778] NDCB1: 0x46c00000
[   11.851778] NDCB2: 0x00000000
[   11.851778] NDCB3: 0x00000000
[   11.870669] Bad eraseblock 283 at 0x000002360000
[   11.875367] nand: nand_do_read_oob: from = 0x02380000, len = 64
[   11.881544] marvell-nfc pxa3xx-nand: 
[   11.881544] NDCR:  0x9d079fff
[   11.881544] NDCB0: 0x000d3000
[   11.881544] NDCB1: 0x47000000
[   11.881544] NDCB2: 0x00000000
[   11.881544] NDCB3: 0x00000000
[   11.900435] Bad eraseblock 284 at 0x000002380000
[   11.905133] nand: nand_do_read_oob: from = 0x023a0000, len = 64
[   11.911311] marvell-nfc pxa3xx-nand: 
[   11.911311] NDCR:  0x9d079fff
[   11.911311] NDCB0: 0x000d3000
[   11.911311] NDCB1: 0x47400000
[   11.911311] NDCB2: 0x00000000
[   11.911311] NDCB3: 0x00000000
[   11.930211] Bad eraseblock 285 at 0x0000023a0000
[   11.934907] nand: nand_do_read_oob: from = 0x023c0000, len = 64
[   11.941085] marvell-nfc pxa3xx-nand: 
[   11.941085] NDCR:  0x9d079fff
[   11.941085] NDCB0: 0x000d3000
[   11.941085] NDCB1: 0x47800000
[   11.941085] NDCB2: 0x00000000
[   11.941085] NDCB3: 0x00000000
[   11.959983] Bad eraseblock 286 at 0x0000023c0000
[   11.964681] nand: nand_do_read_oob: from = 0x023e0000, len = 64
[   11.970859] marvell-nfc pxa3xx-nand: 
[   11.970859] NDCR:  0x9d079fff
[   11.970859] NDCB0: 0x000d3000
[   11.970859] NDCB1: 0x47c00000
[   11.970859] NDCB2: 0x00000000
[   11.970859] NDCB3: 0x00000000
[   11.989751] Bad eraseblock 287 at 0x0000023e0000
[   11.994449] nand: nand_do_read_oob: from = 0x02400000, len = 64
[   12.000627] marvell-nfc pxa3xx-nand: 
[   12.000627] NDCR:  0x9d079fff
[   12.000627] NDCB0: 0x000d3000
[   12.000627] NDCB1: 0x48000000
[   12.000627] NDCB2: 0x00000000
[   12.000627] NDCB3: 0x00000000
[   12.019526] Bad eraseblock 288 at 0x000002400000
[   12.024224] nand: nand_do_read_oob: from = 0x02420000, len = 64
[   12.030401] marvell-nfc pxa3xx-nand: 
[   12.030401] NDCR:  0x9d079fff
[   12.030401] NDCB0: 0x000d3000
[   12.030401] NDCB1: 0x48400000
[   12.030401] NDCB2: 0x00000000
[   12.030401] NDCB3: 0x00000000
[   12.049300] Bad eraseblock 289 at 0x000002420000
[   12.053998] nand: nand_do_read_oob: from = 0x02440000, len = 64
[   12.060175] marvell-nfc pxa3xx-nand: 
[   12.060175] NDCR:  0x9d079fff
[   12.060175] NDCB0: 0x000d3000
[   12.060175] NDCB1: 0x48800000
[   12.060175] NDCB2: 0x00000000
[   12.060175] NDCB3: 0x00000000
[   12.079067] Bad eraseblock 290 at 0x000002440000
[   12.083765] nand: nand_do_read_oob: from = 0x02460000, len = 64
[   12.090461] marvell-nfc pxa3xx-nand: 
[   12.090461] NDCR:  0x9d079fff
[   12.090461] NDCB0: 0x000d3000
[   12.090461] NDCB1: 0x48c00000
[   12.090461] NDCB2: 0x00000000
[   12.090461] NDCB3: 0x00000000
[   12.109442] Bad eraseblock 291 at 0x000002460000
[   12.114147] nand: nand_do_read_oob: from = 0x02480000, len = 64
[   12.120332] marvell-nfc pxa3xx-nand: 
[   12.120332] NDCR:  0x9d079fff
[   12.120332] NDCB0: 0x000d3000
[   12.120332] NDCB1: 0x49000000
[   12.120332] NDCB2: 0x00000000
[   12.120332] NDCB3: 0x00000000
[   12.139228] Bad eraseblock 292 at 0x000002480000
[   12.143925] nand: nand_do_read_oob: from = 0x024a0000, len = 64
[   12.150105] marvell-nfc pxa3xx-nand: 
[   12.150105] NDCR:  0x9d079fff
[   12.150105] NDCB0: 0x000d3000
[   12.150105] NDCB1: 0x49400000
[   12.150105] NDCB2: 0x00000000
[   12.150105] NDCB3: 0x00000000
[   12.169004] Bad eraseblock 293 at 0x0000024a0000
[   12.173701] nand: nand_do_read_oob: from = 0x024c0000, len = 64
[   12.179880] marvell-nfc pxa3xx-nand: 
[   12.179880] NDCR:  0x9d079fff
[   12.179880] NDCB0: 0x000d3000
[   12.179880] NDCB1: 0x49800000
[   12.179880] NDCB2: 0x00000000
[   12.179880] NDCB3: 0x00000000
[   12.198842] Bad eraseblock 294 at 0x0000024c0000
[   12.203547] nand: nand_do_read_oob: from = 0x024e0000, len = 64
[   12.209724] marvell-nfc pxa3xx-nand: 
[   12.209724] NDCR:  0x9d079fff
[   12.209724] NDCB0: 0x000d3000
[   12.209724] NDCB1: 0x49c00000
[   12.209724] NDCB2: 0x00000000
[   12.209724] NDCB3: 0x00000000
[   12.228610] Bad eraseblock 295 at 0x0000024e0000
[   12.233452] nand: nand_do_read_oob: from = 0x02500000, len = 64
[   12.239612] marvell-nfc pxa3xx-nand: 
[   12.239612] NDCR:  0x9d079fff
[   12.239612] NDCB0: 0x000d3000
[   12.239612] NDCB1: 0x4a000000
[   12.239612] NDCB2: 0x00000000
[   12.239612] NDCB3: 0x00000000
[   12.258498] Bad eraseblock 296 at 0x000002500000
[   12.263355] nand: nand_do_read_oob: from = 0x02520000, len = 64
[   12.269528] marvell-nfc pxa3xx-nand: 
[   12.269528] NDCR:  0x9d079fff
[   12.269528] NDCB0: 0x000d3000
[   12.269528] NDCB1: 0x4a400000
[   12.269528] NDCB2: 0x00000000
[   12.269528] NDCB3: 0x00000000
[   12.288410] Bad eraseblock 297 at 0x000002520000
[   12.293266] nand: nand_do_read_oob: from = 0x02540000, len = 64
[   12.299439] marvell-nfc pxa3xx-nand: 
[   12.299439] NDCR:  0x9d079fff
[   12.299439] NDCB0: 0x000d3000
[   12.299439] NDCB1: 0x4a800000
[   12.299439] NDCB2: 0x00000000
[   12.299439] NDCB3: 0x00000000
[   12.318322] Bad eraseblock 298 at 0x000002540000
[   12.323180] nand: nand_do_read_oob: from = 0x02560000, len = 64
[   12.329354] marvell-nfc pxa3xx-nand: 
[   12.329354] NDCR:  0x9d079fff
[   12.329354] NDCB0: 0x000d3000
[   12.329354] NDCB1: 0x4ac00000
[   12.329354] NDCB2: 0x00000000
[   12.329354] NDCB3: 0x00000000
[   12.348234] Bad eraseblock 299 at 0x000002560000
[   12.353093] nand: nand_do_read_oob: from = 0x02580000, len = 64
[   12.359268] marvell-nfc pxa3xx-nand: 
[   12.359268] NDCR:  0x9d079fff
[   12.359268] NDCB0: 0x000d3000
[   12.359268] NDCB1: 0x4b000000
[   12.359268] NDCB2: 0x00000000
[   12.359268] NDCB3: 0x00000000
[   12.378157] Bad eraseblock 300 at 0x000002580000
[   12.383014] nand: nand_do_read_oob: from = 0x025a0000, len = 64
[   12.389189] marvell-nfc pxa3xx-nand: 
[   12.389189] NDCR:  0x9d079fff
[   12.389189] NDCB0: 0x000d3000
[   12.389189] NDCB1: 0x4b400000
[   12.389189] NDCB2: 0x00000000
[   12.389189] NDCB3: 0x00000000
[   12.408093] Bad eraseblock 301 at 0x0000025a0000
[   12.412952] nand: nand_do_read_oob: from = 0x025c0000, len = 64
[   12.419127] marvell-nfc pxa3xx-nand: 
[   12.419127] NDCR:  0x9d079fff
[   12.419127] NDCB0: 0x000d3000
[   12.419127] NDCB1: 0x4b800000
[   12.419127] NDCB2: 0x00000000
[   12.419127] NDCB3: 0x00000000
[   12.438008] Bad eraseblock 302 at 0x0000025c0000
[   12.442864] nand: nand_do_read_oob: from = 0x025e0000, len = 64
[   12.449039] marvell-nfc pxa3xx-nand: 
[   12.449039] NDCR:  0x9d079fff
[   12.449039] NDCB0: 0x000d3000
[   12.449039] NDCB1: 0x4bc00000
[   12.449039] NDCB2: 0x00000000
[   12.449039] NDCB3: 0x00000000
[   12.467919] Bad eraseblock 303 at 0x0000025e0000
[   12.472777] nand: nand_do_read_oob: from = 0x02600000, len = 64
[   12.478952] marvell-nfc pxa3xx-nand: 
[   12.478952] NDCR:  0x9d079fff
[   12.478952] NDCB0: 0x000d3000
[   12.478952] NDCB1: 0x4c000000
[   12.478952] NDCB2: 0x00000000
[   12.478952] NDCB3: 0x00000000
[   12.497834] Bad eraseblock 304 at 0x000002600000
[   12.502690] nand: nand_do_read_oob: from = 0x02620000, len = 64
[   12.508864] marvell-nfc pxa3xx-nand: 
[   12.508864] NDCR:  0x9d079fff
[   12.508864] NDCB0: 0x000d3000
[   12.508864] NDCB1: 0x4c400000
[   12.508864] NDCB2: 0x00000000
[   12.508864] NDCB3: 0x00000000
[   12.527745] Bad eraseblock 305 at 0x000002620000
[   12.532601] nand: nand_do_read_oob: from = 0x02640000, len = 64
[   12.538626] marvell-nfc pxa3xx-nand: 
[   12.538626] NDCR:  0x9d079fff
[   12.538626] NDCB0: 0x000d3000
[   12.538626] NDCB1: 0x4c800000
[   12.538626] NDCB2: 0x00000000
[   12.538626] NDCB3: 0x00000000
[   12.557622] Bad eraseblock 306 at 0x000002640000
[   12.562479] nand: nand_do_read_oob: from = 0x02660000, len = 64
[   12.568505] marvell-nfc pxa3xx-nand: 
[   12.568505] NDCR:  0x9d079fff
[   12.568505] NDCB0: 0x000d3000
[   12.568505] NDCB1: 0x4cc00000
[   12.568505] NDCB2: 0x00000000
[   12.568505] NDCB3: 0x00000000
[   12.587389] Bad eraseblock 307 at 0x000002660000
[   12.592247] nand: nand_do_read_oob: from = 0x02680000, len = 64
[   12.598272] marvell-nfc pxa3xx-nand: 
[   12.598272] NDCR:  0x9d079fff
[   12.598272] NDCB0: 0x000d3000
[   12.598272] NDCB1: 0x4d000000
[   12.598272] NDCB2: 0x00000000
[   12.598272] NDCB3: 0x00000000
[   12.617155] Bad eraseblock 308 at 0x000002680000
[   12.622013] nand: nand_do_read_oob: from = 0x026a0000, len = 64
[   12.628038] marvell-nfc pxa3xx-nand: 
[   12.628038] NDCR:  0x9d079fff
[   12.628038] NDCB0: 0x000d3000
[   12.628038] NDCB1: 0x4d400000
[   12.628038] NDCB2: 0x00000000
[   12.628038] NDCB3: 0x00000000
[   12.646920] Bad eraseblock 309 at 0x0000026a0000
[   12.651782] nand: nand_do_read_oob: from = 0x026c0000, len = 64
[   12.657804] marvell-nfc pxa3xx-nand: 
[   12.657804] NDCR:  0x9d079fff
[   12.657804] NDCB0: 0x000d3000
[   12.657804] NDCB1: 0x4d800000
[   12.657804] NDCB2: 0x00000000
[   12.657804] NDCB3: 0x00000000
[   12.676689] Bad eraseblock 310 at 0x0000026c0000
[   12.681547] nand: nand_do_read_oob: from = 0x026e0000, len = 64
[   12.687570] marvell-nfc pxa3xx-nand: 
[   12.687570] NDCR:  0x9d079fff
[   12.687570] NDCB0: 0x000d3000
[   12.687570] NDCB1: 0x4dc00000
[   12.687570] NDCB2: 0x00000000
[   12.687570] NDCB3: 0x00000000
[   12.706453] Bad eraseblock 311 at 0x0000026e0000
[   12.711313] nand: nand_do_read_oob: from = 0x02700000, len = 64
[   12.717336] marvell-nfc pxa3xx-nand: 
[   12.717336] NDCR:  0x9d079fff
[   12.717336] NDCB0: 0x000d3000
[   12.717336] NDCB1: 0x4e000000
[   12.717336] NDCB2: 0x00000000
[   12.717336] NDCB3: 0x00000000
[   12.736219] Bad eraseblock 312 at 0x000002700000
[   12.741078] nand: nand_do_read_oob: from = 0x02720000, len = 64
[   12.747101] marvell-nfc pxa3xx-nand: 
[   12.747101] NDCR:  0x9d079fff
[   12.747101] NDCB0: 0x000d3000
[   12.747101] NDCB1: 0x4e400000
[   12.747101] NDCB2: 0x00000000
[   12.747101] NDCB3: 0x00000000
[   12.765985] Bad eraseblock 313 at 0x000002720000
[   12.770844] nand: nand_do_read_oob: from = 0x02740000, len = 64
[   12.776867] marvell-nfc pxa3xx-nand: 
[   12.776867] NDCR:  0x9d079fff
[   12.776867] NDCB0: 0x000d3000
[   12.776867] NDCB1: 0x4e800000
[   12.776867] NDCB2: 0x00000000
[   12.776867] NDCB3: 0x00000000
[   12.795751] Bad eraseblock 314 at 0x000002740000
[   12.800612] nand: nand_do_read_oob: from = 0x02760000, len = 64
[   12.806634] marvell-nfc pxa3xx-nand: 
[   12.806634] NDCR:  0x9d079fff
[   12.806634] NDCB0: 0x000d3000
[   12.806634] NDCB1: 0x4ec00000
[   12.806634] NDCB2: 0x00000000
[   12.806634] NDCB3: 0x00000000
[   12.825517] Bad eraseblock 315 at 0x000002760000
[   12.830377] nand: nand_do_read_oob: from = 0x02780000, len = 64
[   12.836399] marvell-nfc pxa3xx-nand: 
[   12.836399] NDCR:  0x9d079fff
[   12.836399] NDCB0: 0x000d3000
[   12.836399] NDCB1: 0x4f000000
[   12.836399] NDCB2: 0x00000000
[   12.836399] NDCB3: 0x00000000
[   12.855284] Bad eraseblock 316 at 0x000002780000
[   12.860143] nand: nand_do_read_oob: from = 0x027a0000, len = 64
[   12.866167] marvell-nfc pxa3xx-nand: 
[   12.866167] NDCR:  0x9d079fff
[   12.866167] NDCB0: 0x000d3000
[   12.866167] NDCB1: 0x4f400000
[   12.866167] NDCB2: 0x00000000
[   12.866167] NDCB3: 0x00000000
[   12.885052] Bad eraseblock 317 at 0x0000027a0000
[   12.889910] nand: nand_do_read_oob: from = 0x027c0000, len = 64
[   12.895931] marvell-nfc pxa3xx-nand: 
[   12.895931] NDCR:  0x9d079fff
[   12.895931] NDCB0: 0x000d3000
[   12.895931] NDCB1: 0x4f800000
[   12.895931] NDCB2: 0x00000000
[   12.895931] NDCB3: 0x00000000
[   12.914817] Bad eraseblock 318 at 0x0000027c0000
[   12.919674] nand: nand_do_read_oob: from = 0x027e0000, len = 64
[   12.925698] marvell-nfc pxa3xx-nand: 
[   12.925698] NDCR:  0x9d079fff
[   12.925698] NDCB0: 0x000d3000
[   12.925698] NDCB1: 0x4fc00000
[   12.925698] NDCB2: 0x00000000
[   12.925698] NDCB3: 0x00000000
[   12.944581] Bad eraseblock 319 at 0x0000027e0000
[   12.949443] nand: nand_do_read_oob: from = 0x02800000, len = 64
[   12.955465] marvell-nfc pxa3xx-nand: 
[   12.955465] NDCR:  0x9d079fff
[   12.955465] NDCB0: 0x000d3000
[   12.955465] NDCB1: 0x50000000
[   12.955465] NDCB2: 0x00000000
[   12.955465] NDCB3: 0x00000000
[   12.974349] Bad eraseblock 320 at 0x000002800000
[   12.979225] nand: nand_do_read_oob: from = 0x02820000, len = 64
[   12.985249] marvell-nfc pxa3xx-nand: 
[   12.985249] NDCR:  0x9d079fff
[   12.985249] NDCB0: 0x000d3000
[   12.985249] NDCB1: 0x50400000
[   12.985249] NDCB2: 0x00000000
[   12.985249] NDCB3: 0x00000000
[   13.004132] Bad eraseblock 321 at 0x000002820000
[   13.008999] nand: nand_do_read_oob: from = 0x02840000, len = 64
[   13.015023] marvell-nfc pxa3xx-nand: 
[   13.015023] NDCR:  0x9d079fff
[   13.015023] NDCB0: 0x000d3000
[   13.015023] NDCB1: 0x50800000
[   13.015023] NDCB2: 0x00000000
[   13.015023] NDCB3: 0x00000000
[   13.033943] nand: nand_do_read_oob: from = 0x02860000, len = 64
[   13.040143] marvell-nfc pxa3xx-nand: 
[   13.040143] NDCR:  0x9d079fff
[   13.040143] NDCB0: 0x000d3000
[   13.040143] NDCB1: 0x50c00000
[   13.040143] NDCB2: 0x00000000
[   13.040143] NDCB3: 0x00000000
[   13.059073] nand: nand_do_read_oob: from = 0x02880000, len = 64
[   13.065105] marvell-nfc pxa3xx-nand: 
[   13.065105] NDCR:  0x9d079fff
[   13.065105] NDCB0: 0x000d3000
[   13.065105] NDCB1: 0x51000000
[   13.065105] NDCB2: 0x00000000
[   13.065105] NDCB3: 0x00000000
[   13.084035] nand: nand_do_read_oob: from = 0x028a0000, len = 64
[   13.090243] marvell-nfc pxa3xx-nand: 
[   13.090243] NDCR:  0x9d079fff
[   13.090243] NDCB0: 0x000d3000
[   13.090243] NDCB1: 0x51400000
[   13.090243] NDCB2: 0x00000000
[   13.090243] NDCB3: 0x00000000
[   13.109171] nand: nand_do_read_oob: from = 0x028c0000, len = 64
[   13.115203] marvell-nfc pxa3xx-nand: 
[   13.115203] NDCR:  0x9d079fff
[   13.115203] NDCB0: 0x000d3000
[   13.115203] NDCB1: 0x51800000
[   13.115203] NDCB2: 0x00000000
[   13.115203] NDCB3: 0x00000000
[   13.134135] nand: nand_do_read_oob: from = 0x028e0000, len = 64
[   13.140342] marvell-nfc pxa3xx-nand: 
[   13.140342] NDCR:  0x9d079fff
[   13.140342] NDCB0: 0x000d3000
[   13.140342] NDCB1: 0x51c00000
[   13.140342] NDCB2: 0x00000000
[   13.140342] NDCB3: 0x00000000
[   13.159271] nand: nand_do_read_oob: from = 0x02900000, len = 64
[   13.165301] marvell-nfc pxa3xx-nand: 
[   13.165301] NDCR:  0x9d079fff
[   13.165301] NDCB0: 0x000d3000
[   13.165301] NDCB1: 0x52000000
[   13.165301] NDCB2: 0x00000000
[   13.165301] NDCB3: 0x00000000
[   13.184240] nand: nand_do_read_oob: from = 0x02920000, len = 64
[   13.190443] marvell-nfc pxa3xx-nand: 
[   13.190443] NDCR:  0x9d079fff
[   13.190443] NDCB0: 0x000d3000
[   13.190443] NDCB1: 0x52400000
[   13.190443] NDCB2: 0x00000000
[   13.190443] NDCB3: 0x00000000
[   13.209368] nand: nand_do_read_oob: from = 0x02940000, len = 64
[   13.215400] marvell-nfc pxa3xx-nand: 
[   13.215400] NDCR:  0x9d079fff
[   13.215400] NDCB0: 0x000d3000
[   13.215400] NDCB1: 0x52800000
[   13.215400] NDCB2: 0x00000000
[   13.215400] NDCB3: 0x00000000
[   13.234332] nand: nand_do_read_oob: from = 0x02960000, len = 64
[   13.240539] marvell-nfc pxa3xx-nand: 
[   13.240539] NDCR:  0x9d079fff
[   13.240539] NDCB0: 0x000d3000
[   13.240539] NDCB1: 0x52c00000
[   13.240539] NDCB2: 0x00000000
[   13.240539] NDCB3: 0x00000000
[   13.259465] nand: nand_do_read_oob: from = 0x02980000, len = 64
[   13.265498] marvell-nfc pxa3xx-nand: 
[   13.265498] NDCR:  0x9d079fff
[   13.265498] NDCB0: 0x000d3000
[   13.265498] NDCB1: 0x53000000
[   13.265498] NDCB2: 0x00000000
[   13.265498] NDCB3: 0x00000000
[   13.284434] nand: nand_do_read_oob: from = 0x029a0000, len = 64
[   13.290639] marvell-nfc pxa3xx-nand: 
[   13.290639] NDCR:  0x9d079fff
[   13.290639] NDCB0: 0x000d3000
[   13.290639] NDCB1: 0x53400000
[   13.290639] NDCB2: 0x00000000
[   13.290639] NDCB3: 0x00000000
[   13.309566] nand: nand_do_read_oob: from = 0x029c0000, len = 64
[   13.315596] marvell-nfc pxa3xx-nand: 
[   13.315596] NDCR:  0x9d079fff
[   13.315596] NDCB0: 0x000d3000
[   13.315596] NDCB1: 0x53800000
[   13.315596] NDCB2: 0x00000000
[   13.315596] NDCB3: 0x00000000
[   13.334532] nand: nand_do_read_oob: from = 0x029e0000, len = 64
[   13.340734] marvell-nfc pxa3xx-nand: 
[   13.340734] NDCR:  0x9d079fff
[   13.340734] NDCB0: 0x000d3000
[   13.340734] NDCB1: 0x53c00000
[   13.340734] NDCB2: 0x00000000
[   13.340734] NDCB3: 0x00000000
[   13.359662] nand: nand_do_read_oob: from = 0x02a00000, len = 64
[   13.365696] marvell-nfc pxa3xx-nand: 
[   13.365696] NDCR:  0x9d079fff
[   13.365696] NDCB0: 0x000d3000
[   13.365696] NDCB1: 0x54000000
[   13.365696] NDCB2: 0x00000000
[   13.365696] NDCB3: 0x00000000
[   13.384629] nand: nand_do_read_oob: from = 0x02a20000, len = 64
[   13.390833] marvell-nfc pxa3xx-nand: 
[   13.390833] NDCR:  0x9d079fff
[   13.390833] NDCB0: 0x000d3000
[   13.390833] NDCB1: 0x54400000
[   13.390833] NDCB2: 0x00000000
[   13.390833] NDCB3: 0x00000000
[   13.409766] nand: nand_do_read_oob: from = 0x02a40000, len = 64
[   13.415802] marvell-nfc pxa3xx-nand: 
[   13.415802] NDCR:  0x9d079fff
[   13.415802] NDCB0: 0x000d3000
[   13.415802] NDCB1: 0x54800000
[   13.415802] NDCB2: 0x00000000
[   13.415802] NDCB3: 0x00000000
[   13.434704] Bad eraseblock 338 at 0x000002a40000
[   13.439564] nand: nand_do_read_oob: from = 0x02a60000, len = 64
[   13.445586] marvell-nfc pxa3xx-nand: 
[   13.445586] NDCR:  0x9d079fff
[   13.445586] NDCB0: 0x000d3000
[   13.445586] NDCB1: 0x54c00000
[   13.445586] NDCB2: 0x00000000
[   13.445586] NDCB3: 0x00000000
[   13.464468] Bad eraseblock 339 at 0x000002a60000
[   13.469328] nand: nand_do_read_oob: from = 0x02a80000, len = 64
[   13.475351] marvell-nfc pxa3xx-nand: 
[   13.475351] NDCR:  0x9d079fff
[   13.475351] NDCB0: 0x000d3000
[   13.475351] NDCB1: 0x55000000
[   13.475351] NDCB2: 0x00000000
[   13.475351] NDCB3: 0x00000000
[   13.494267] nand: nand_do_read_oob: from = 0x02aa0000, len = 64
[   13.500473] marvell-nfc pxa3xx-nand: 
[   13.500473] NDCR:  0x9d079fff
[   13.500473] NDCB0: 0x000d3000
[   13.500473] NDCB1: 0x55400000
[   13.500473] NDCB2: 0x00000000
[   13.500473] NDCB3: 0x00000000
[   13.519403] nand: nand_do_read_oob: from = 0x02ac0000, len = 64
[   13.525432] marvell-nfc pxa3xx-nand: 
[   13.525432] NDCR:  0x9d079fff
[   13.525432] NDCB0: 0x000d3000
[   13.525432] NDCB1: 0x55800000
[   13.525432] NDCB2: 0x00000000
[   13.525432] NDCB3: 0x00000000
[   13.544366] nand: nand_do_read_oob: from = 0x02ae0000, len = 64
[   13.550575] marvell-nfc pxa3xx-nand: 
[   13.550575] NDCR:  0x9d079fff
[   13.550575] NDCB0: 0x000d3000
[   13.550575] NDCB1: 0x55c00000
[   13.550575] NDCB2: 0x00000000
[   13.550575] NDCB3: 0x00000000
[   13.569499] nand: nand_do_read_oob: from = 0x02b00000, len = 64
[   13.575532] marvell-nfc pxa3xx-nand: 
[   13.575532] NDCR:  0x9d079fff
[   13.575532] NDCB0: 0x000d3000
[   13.575532] NDCB1: 0x56000000
[   13.575532] NDCB2: 0x00000000
[   13.575532] NDCB3: 0x00000000
[   13.594464] nand: nand_do_read_oob: from = 0x02b20000, len = 64
[   13.600669] marvell-nfc pxa3xx-nand: 
[   13.600669] NDCR:  0x9d079fff
[   13.600669] NDCB0: 0x000d3000
[   13.600669] NDCB1: 0x56400000
[   13.600669] NDCB2: 0x00000000
[   13.600669] NDCB3: 0x00000000
[   13.619617] nand: nand_do_read_oob: from = 0x02b40000, len = 64
[   13.625647] marvell-nfc pxa3xx-nand: 
[   13.625647] NDCR:  0x9d079fff
[   13.625647] NDCB0: 0x000d3000
[   13.625647] NDCB1: 0x56800000
[   13.625647] NDCB2: 0x00000000
[   13.625647] NDCB3: 0x00000000
[   13.644583] nand: nand_do_read_oob: from = 0x02b60000, len = 64
[   13.650786] marvell-nfc pxa3xx-nand: 
[   13.650786] NDCR:  0x9d079fff
[   13.650786] NDCB0: 0x000d3000
[   13.650786] NDCB1: 0x56c00000
[   13.650786] NDCB2: 0x00000000
[   13.650786] NDCB3: 0x00000000
[   13.669715] nand: nand_do_read_oob: from = 0x02b80000, len = 64
[   13.675744] marvell-nfc pxa3xx-nand: 
[   13.675744] NDCR:  0x9d079fff
[   13.675744] NDCB0: 0x000d3000
[   13.675744] NDCB1: 0x57000000
[   13.675744] NDCB2: 0x00000000
[   13.675744] NDCB3: 0x00000000
[   13.694679] nand: nand_do_read_oob: from = 0x02ba0000, len = 64
[   13.700886] marvell-nfc pxa3xx-nand: 
[   13.700886] NDCR:  0x9d079fff
[   13.700886] NDCB0: 0x000d3000
[   13.700886] NDCB1: 0x57400000
[   13.700886] NDCB2: 0x00000000
[   13.700886] NDCB3: 0x00000000
[   13.719813] nand: nand_do_read_oob: from = 0x02bc0000, len = 64
[   13.725845] marvell-nfc pxa3xx-nand: 
[   13.725845] NDCR:  0x9d079fff
[   13.725845] NDCB0: 0x000d3000
[   13.725845] NDCB1: 0x57800000
[   13.725845] NDCB2: 0x00000000
[   13.725845] NDCB3: 0x00000000
[   13.744747] Bad eraseblock 350 at 0x000002bc0000
[   13.749607] nand: nand_do_read_oob: from = 0x02be0000, len = 64
[   13.755627] marvell-nfc pxa3xx-nand: 
[   13.755627] NDCR:  0x9d079fff
[   13.755627] NDCB0: 0x000d3000
[   13.755627] NDCB1: 0x57c00000
[   13.755627] NDCB2: 0x00000000
[   13.755627] NDCB3: 0x00000000
[   13.774541] nand: nand_do_read_oob: from = 0x02c00000, len = 64
[   13.780740] marvell-nfc pxa3xx-nand: 
[   13.780740] NDCR:  0x9d079fff
[   13.780740] NDCB0: 0x000d3000
[   13.780740] NDCB1: 0x58000000
[   13.780740] NDCB2: 0x00000000
[   13.780740] NDCB3: 0x00000000
[   13.799669] nand: nand_do_read_oob: from = 0x02c20000, len = 64
[   13.805700] marvell-nfc pxa3xx-nand: 
[   13.805700] NDCR:  0x9d079fff
[   13.805700] NDCB0: 0x000d3000
[   13.805700] NDCB1: 0x58400000
[   13.805700] NDCB2: 0x00000000
[   13.805700] NDCB3: 0x00000000
[   13.824633] nand: nand_do_read_oob: from = 0x02c40000, len = 64
[   13.830838] marvell-nfc pxa3xx-nand: 
[   13.830838] NDCR:  0x9d079fff
[   13.830838] NDCB0: 0x000d3000
[   13.830838] NDCB1: 0x58800000
[   13.830838] NDCB2: 0x00000000
[   13.830838] NDCB3: 0x00000000
[   13.849736] Bad eraseblock 354 at 0x000002c40000
[   13.854434] nand: nand_do_read_oob: from = 0x02c60000, len = 64
[   13.860612] marvell-nfc pxa3xx-nand: 
[   13.860612] NDCR:  0x9d079fff
[   13.860612] NDCB0: 0x000d3000
[   13.860612] NDCB1: 0x58c00000
[   13.860612] NDCB2: 0x00000000
[   13.860612] NDCB3: 0x00000000
[   13.879510] Bad eraseblock 355 at 0x000002c60000
[   13.884206] nand: nand_do_read_oob: from = 0x02c80000, len = 64
[   13.890386] marvell-nfc pxa3xx-nand: 
[   13.890386] NDCR:  0x9d079fff
[   13.890386] NDCB0: 0x000d3000
[   13.890386] NDCB1: 0x59000000
[   13.890386] NDCB2: 0x00000000
[   13.890386] NDCB3: 0x00000000
[   13.909286] Bad eraseblock 356 at 0x000002c80000
[   13.913982] nand: nand_do_read_oob: from = 0x02ca0000, len = 64
[   13.920160] marvell-nfc pxa3xx-nand: 
[   13.920160] NDCR:  0x9d079fff
[   13.920160] NDCB0: 0x000d3000
[   13.920160] NDCB1: 0x59400000
[   13.920160] NDCB2: 0x00000000
[   13.920160] NDCB3: 0x00000000
[   13.939059] Bad eraseblock 357 at 0x000002ca0000
[   13.943758] nand: nand_do_read_oob: from = 0x02cc0000, len = 64
[   13.949935] marvell-nfc pxa3xx-nand: 
[   13.949935] NDCR:  0x9d079fff
[   13.949935] NDCB0: 0x000d3000
[   13.949935] NDCB1: 0x59800000
[   13.949935] NDCB2: 0x00000000
[   13.949935] NDCB3: 0x00000000
[   13.968867] Bad eraseblock 358 at 0x000002cc0000
[   13.973569] nand: nand_do_read_oob: from = 0x02ce0000, len = 64
[   13.979741] marvell-nfc pxa3xx-nand: 
[   13.979741] NDCR:  0x9d079fff
[   13.979741] NDCB0: 0x000d3000
[   13.979741] NDCB1: 0x59c00000
[   13.979741] NDCB2: 0x00000000
[   13.979741] NDCB3: 0x00000000
[   13.998625] Bad eraseblock 359 at 0x000002ce0000
[   14.003465] nand: nand_do_read_oob: from = 0x02d00000, len = 64
[   14.009636] marvell-nfc pxa3xx-nand: 
[   14.009636] NDCR:  0x9d079fff
[   14.009636] NDCB0: 0x000d3000
[   14.009636] NDCB1: 0x5a000000
[   14.009636] NDCB2: 0x00000000
[   14.009636] NDCB3: 0x00000000
[   14.028522] Bad eraseblock 360 at 0x000002d00000
[   14.033379] nand: nand_do_read_oob: from = 0x02d20000, len = 64
[   14.039551] marvell-nfc pxa3xx-nand: 
[   14.039551] NDCR:  0x9d079fff
[   14.039551] NDCB0: 0x000d3000
[   14.039551] NDCB1: 0x5a400000
[   14.039551] NDCB2: 0x00000000
[   14.039551] NDCB3: 0x00000000
[   14.058430] Bad eraseblock 361 at 0x000002d20000
[   14.063289] nand: nand_do_read_oob: from = 0x02d40000, len = 64
[   14.069463] marvell-nfc pxa3xx-nand: 
[   14.069463] NDCR:  0x9d079fff
[   14.069463] NDCB0: 0x000d3000
[   14.069463] NDCB1: 0x5a800000
[   14.069463] NDCB2: 0x00000000
[   14.069463] NDCB3: 0x00000000
[   14.088345] Bad eraseblock 362 at 0x000002d40000
[   14.093533] nand: nand_do_read_oob: from = 0x02d60000, len = 64
[   14.099766] marvell-nfc pxa3xx-nand: 
[   14.099766] NDCR:  0x9d079fff
[   14.099766] NDCB0: 0x000d3000
[   14.099766] NDCB1: 0x5ac00000
[   14.099766] NDCB2: 0x00000000
[   14.099766] NDCB3: 0x00000000
[   14.118873] Bad eraseblock 363 at 0x000002d60000
[   14.123585] nand: nand_do_read_oob: from = 0x02d80000, len = 64
[   14.129771] marvell-nfc pxa3xx-nand: 
[   14.129771] NDCR:  0x9d079fff
[   14.129771] NDCB0: 0x000d3000
[   14.129771] NDCB1: 0x5b000000
[   14.129771] NDCB2: 0x00000000
[   14.129771] NDCB3: 0x00000000
[   14.148757] Bad eraseblock 364 at 0x000002d80000
[   14.153462] nand: nand_do_read_oob: from = 0x02da0000, len = 64
[   14.159630] marvell-nfc pxa3xx-nand: 
[   14.159630] NDCR:  0x9d079fff
[   14.159630] NDCB0: 0x000d3000
[   14.159630] NDCB1: 0x5b400000
[   14.159630] NDCB2: 0x00000000
[   14.159630] NDCB3: 0x00000000
[   14.178515] Bad eraseblock 365 at 0x000002da0000
[   14.183394] nand: nand_do_read_oob: from = 0x02dc0000, len = 64
[   14.189573] marvell-nfc pxa3xx-nand: 
[   14.189573] NDCR:  0x9d079fff
[   14.189573] NDCB0: 0x000d3000
[   14.189573] NDCB1: 0x5b800000
[   14.189573] NDCB2: 0x00000000
[   14.189573] NDCB3: 0x00000000
[   14.208459] Bad eraseblock 366 at 0x000002dc0000
[   14.213319] nand: nand_do_read_oob: from = 0x02de0000, len = 64
[   14.219491] marvell-nfc pxa3xx-nand: 
[   14.219491] NDCR:  0x9d079fff
[   14.219491] NDCB0: 0x000d3000
[   14.219491] NDCB1: 0x5bc00000
[   14.219491] NDCB2: 0x00000000
[   14.219491] NDCB3: 0x00000000
[   14.238369] Bad eraseblock 367 at 0x000002de0000
[   14.243221] nand: nand_do_read_oob: from = 0x02e00000, len = 64
[   14.249395] marvell-nfc pxa3xx-nand: 
[   14.249395] NDCR:  0x9d079fff
[   14.249395] NDCB0: 0x000d3000
[   14.249395] NDCB1: 0x5c000000
[   14.249395] NDCB2: 0x00000000
[   14.249395] NDCB3: 0x00000000
[   14.268278] Bad eraseblock 368 at 0x000002e00000
[   14.273135] nand: nand_do_read_oob: from = 0x02e20000, len = 64
[   14.279309] marvell-nfc pxa3xx-nand: 
[   14.279309] NDCR:  0x9d079fff
[   14.279309] NDCB0: 0x000d3000
[   14.279309] NDCB1: 0x5c400000
[   14.279309] NDCB2: 0x00000000
[   14.279309] NDCB3: 0x00000000
[   14.298188] Bad eraseblock 369 at 0x000002e20000
[   14.303049] nand: nand_do_read_oob: from = 0x02e40000, len = 64
[   14.309222] marvell-nfc pxa3xx-nand: 
[   14.309222] NDCR:  0x9d079fff
[   14.309222] NDCB0: 0x000d3000
[   14.309222] NDCB1: 0x5c800000
[   14.309222] NDCB2: 0x00000000
[   14.309222] NDCB3: 0x00000000
[   14.328099] Bad eraseblock 370 at 0x000002e40000
[   14.332952] nand: nand_do_read_oob: from = 0x02e60000, len = 64
[   14.339124] marvell-nfc pxa3xx-nand: 
[   14.339124] NDCR:  0x9d079fff
[   14.339124] NDCB0: 0x000d3000
[   14.339124] NDCB1: 0x5cc00000
[   14.339124] NDCB2: 0x00000000
[   14.339124] NDCB3: 0x00000000
[   14.358005] Bad eraseblock 371 at 0x000002e60000
[   14.362864] nand: nand_do_read_oob: from = 0x02e80000, len = 64
[   14.369038] marvell-nfc pxa3xx-nand: 
[   14.369038] NDCR:  0x9d079fff
[   14.369038] NDCB0: 0x000d3000
[   14.369038] NDCB1: 0x5d000000
[   14.369038] NDCB2: 0x00000000
[   14.369038] NDCB3: 0x00000000
[   14.387917] Bad eraseblock 372 at 0x000002e80000
[   14.392775] nand: nand_do_read_oob: from = 0x02ea0000, len = 64
[   14.398949] marvell-nfc pxa3xx-nand: 
[   14.398949] NDCR:  0x9d079fff
[   14.398949] NDCB0: 0x000d3000
[   14.398949] NDCB1: 0x5d400000
[   14.398949] NDCB2: 0x00000000
[   14.398949] NDCB3: 0x00000000
[   14.417829] Bad eraseblock 373 at 0x000002ea0000
[   14.422689] nand: nand_do_read_oob: from = 0x02ec0000, len = 64
[   14.428863] marvell-nfc pxa3xx-nand: 
[   14.428863] NDCR:  0x9d079fff
[   14.428863] NDCB0: 0x000d3000
[   14.428863] NDCB1: 0x5d800000
[   14.428863] NDCB2: 0x00000000
[   14.428863] NDCB3: 0x00000000
[   14.447745] Bad eraseblock 374 at 0x000002ec0000
[   14.452599] nand: nand_do_read_oob: from = 0x02ee0000, len = 64
[   14.458626] marvell-nfc pxa3xx-nand: 
[   14.458626] NDCR:  0x9d079fff
[   14.458626] NDCB0: 0x000d3000
[   14.458626] NDCB1: 0x5dc00000
[   14.458626] NDCB2: 0x00000000
[   14.458626] NDCB3: 0x00000000
[   14.477616] Bad eraseblock 375 at 0x000002ee0000
[   14.482471] nand: nand_do_read_oob: from = 0x02f00000, len = 64
[   14.488494] marvell-nfc pxa3xx-nand: 
[   14.488494] NDCR:  0x9d079fff
[   14.488494] NDCB0: 0x000d3000
[   14.488494] NDCB1: 0x5e000000
[   14.488494] NDCB2: 0x00000000
[   14.488494] NDCB3: 0x00000000
[   14.507377] Bad eraseblock 376 at 0x000002f00000
[   14.512238] nand: nand_do_read_oob: from = 0x02f20000, len = 64
[   14.518261] marvell-nfc pxa3xx-nand: 
[   14.518261] NDCR:  0x9d079fff
[   14.518261] NDCB0: 0x000d3000
[   14.518261] NDCB1: 0x5e400000
[   14.518261] NDCB2: 0x00000000
[   14.518261] NDCB3: 0x00000000
[   14.537141] Bad eraseblock 377 at 0x000002f20000
[   14.541995] nand: nand_do_read_oob: from = 0x02f40000, len = 64
[   14.548019] marvell-nfc pxa3xx-nand: 
[   14.548019] NDCR:  0x9d079fff
[   14.548019] NDCB0: 0x000d3000
[   14.548019] NDCB1: 0x5e800000
[   14.548019] NDCB2: 0x00000000
[   14.548019] NDCB3: 0x00000000
[   14.566900] Bad eraseblock 378 at 0x000002f40000
[   14.571753] nand: nand_do_read_oob: from = 0x02f60000, len = 64
[   14.577775] marvell-nfc pxa3xx-nand: 
[   14.577775] NDCR:  0x9d079fff
[   14.577775] NDCB0: 0x000d3000
[   14.577775] NDCB1: 0x5ec00000
[   14.577775] NDCB2: 0x00000000
[   14.577775] NDCB3: 0x00000000
[   14.596659] Bad eraseblock 379 at 0x000002f60000
[   14.601510] nand: nand_do_read_oob: from = 0x02f80000, len = 64
[   14.607534] marvell-nfc pxa3xx-nand: 
[   14.607534] NDCR:  0x9d079fff
[   14.607534] NDCB0: 0x000d3000
[   14.607534] NDCB1: 0x5f000000
[   14.607534] NDCB2: 0x00000000
[   14.607534] NDCB3: 0x00000000
[   14.626415] Bad eraseblock 380 at 0x000002f80000
[   14.631268] nand: nand_do_read_oob: from = 0x02fa0000, len = 64
[   14.637290] marvell-nfc pxa3xx-nand: 
[   14.637290] NDCR:  0x9d079fff
[   14.637290] NDCB0: 0x000d3000
[   14.637290] NDCB1: 0x5f400000
[   14.637290] NDCB2: 0x00000000
[   14.637290] NDCB3: 0x00000000
[   14.656171] Bad eraseblock 381 at 0x000002fa0000
[   14.661027] nand: nand_do_read_oob: from = 0x02fc0000, len = 64
[   14.667048] marvell-nfc pxa3xx-nand: 
[   14.667048] NDCR:  0x9d079fff
[   14.667048] NDCB0: 0x000d3000
[   14.667048] NDCB1: 0x5f800000
[   14.667048] NDCB2: 0x00000000
[   14.667048] NDCB3: 0x00000000
[   14.685931] Bad eraseblock 382 at 0x000002fc0000
[   14.690792] nand: nand_do_read_oob: from = 0x02fe0000, len = 64
[   14.696815] marvell-nfc pxa3xx-nand: 
[   14.696815] NDCR:  0x9d079fff
[   14.696815] NDCB0: 0x000d3000
[   14.696815] NDCB1: 0x5fc00000
[   14.696815] NDCB2: 0x00000000
[   14.696815] NDCB3: 0x00000000
[   14.715697] Bad eraseblock 383 at 0x000002fe0000
[   14.720575] nand: nand_do_read_oob: from = 0x03000000, len = 64
[   14.726598] marvell-nfc pxa3xx-nand: 
[   14.726598] NDCR:  0x9d079fff
[   14.726598] NDCB0: 0x000d3000
[   14.726598] NDCB1: 0x60000000
[   14.726598] NDCB2: 0x00000000
[   14.726598] NDCB3: 0x00000000
[   14.745487] Bad eraseblock 384 at 0x000003000000
[   14.750344] nand: nand_do_read_oob: from = 0x03020000, len = 64
[   14.756365] marvell-nfc pxa3xx-nand: 
[   14.756365] NDCR:  0x9d079fff
[   14.756365] NDCB0: 0x000d3000
[   14.756365] NDCB1: 0x60400000
[   14.756365] NDCB2: 0x00000000
[   14.756365] NDCB3: 0x00000000
[   14.775252] Bad eraseblock 385 at 0x000003020000
[   14.780107] nand: nand_do_read_oob: from = 0x03040000, len = 64
[   14.786131] marvell-nfc pxa3xx-nand: 
[   14.786131] NDCR:  0x9d079fff
[   14.786131] NDCB0: 0x000d3000
[   14.786131] NDCB1: 0x60800000
[   14.786131] NDCB2: 0x00000000
[   14.786131] NDCB3: 0x00000000
[   14.805015] Bad eraseblock 386 at 0x000003040000
[   14.809873] nand: nand_do_read_oob: from = 0x03060000, len = 64
[   14.815897] marvell-nfc pxa3xx-nand: 
[   14.815897] NDCR:  0x9d079fff
[   14.815897] NDCB0: 0x000d3000
[   14.815897] NDCB1: 0x60c00000
[   14.815897] NDCB2: 0x00000000
[   14.815897] NDCB3: 0x00000000
[   14.834782] Bad eraseblock 387 at 0x000003060000
[   14.839640] nand: nand_do_read_oob: from = 0x03080000, len = 64
[   14.845663] marvell-nfc pxa3xx-nand: 
[   14.845663] NDCR:  0x9d079fff
[   14.845663] NDCB0: 0x000d3000
[   14.845663] NDCB1: 0x61000000
[   14.845663] NDCB2: 0x00000000
[   14.845663] NDCB3: 0x00000000
[   14.864548] Bad eraseblock 388 at 0x000003080000
[   14.869407] nand: nand_do_read_oob: from = 0x030a0000, len = 64
[   14.875429] marvell-nfc pxa3xx-nand: 
[   14.875429] NDCR:  0x9d079fff
[   14.875429] NDCB0: 0x000d3000
[   14.875429] NDCB1: 0x61400000
[   14.875429] NDCB2: 0x00000000
[   14.875429] NDCB3: 0x00000000
[   14.894311] Bad eraseblock 389 at 0x0000030a0000
[   14.899163] nand: nand_do_read_oob: from = 0x030c0000, len = 64
[   14.905187] marvell-nfc pxa3xx-nand: 
[   14.905187] NDCR:  0x9d079fff
[   14.905187] NDCB0: 0x000d3000
[   14.905187] NDCB1: 0x61800000
[   14.905187] NDCB2: 0x00000000
[   14.905187] NDCB3: 0x00000000
[   14.924069] Bad eraseblock 390 at 0x0000030c0000
[   14.928930] nand: nand_do_read_oob: from = 0x030e0000, len = 64
[   14.934954] marvell-nfc pxa3xx-nand: 
[   14.934954] NDCR:  0x9d079fff
[   14.934954] NDCB0: 0x000d3000
[   14.934954] NDCB1: 0x61c00000
[   14.934954] NDCB2: 0x00000000
[   14.934954] NDCB3: 0x00000000
[   14.953835] Bad eraseblock 391 at 0x0000030e0000
[   14.958538] nand: nand_do_read_oob: from = 0x03100000, len = 64
[   14.964718] marvell-nfc pxa3xx-nand: 
[   14.964718] NDCR:  0x9d079fff
[   14.964718] NDCB0: 0x000d3000
[   14.964718] NDCB1: 0x62000000
[   14.964718] NDCB2: 0x00000000
[   14.964718] NDCB3: 0x00000000
[   14.983615] Bad eraseblock 392 at 0x000003100000
[   14.988312] nand: nand_do_read_oob: from = 0x03120000, len = 64
[   14.994491] marvell-nfc pxa3xx-nand: 
[   14.994491] NDCR:  0x9d079fff
[   14.994491] NDCB0: 0x000d3000
[   14.994491] NDCB1: 0x62400000
[   14.994491] NDCB2: 0x00000000
[   14.994491] NDCB3: 0x00000000
[   15.013402] Bad eraseblock 393 at 0x000003120000
[   15.018106] nand: nand_do_read_oob: from = 0x03140000, len = 64
[   15.024291] marvell-nfc pxa3xx-nand: 
[   15.024291] NDCR:  0x9d079fff
[   15.024291] NDCB0: 0x000d3000
[   15.024291] NDCB1: 0x62800000
[   15.024291] NDCB2: 0x00000000
[   15.024291] NDCB3: 0x00000000
[   15.043190] Bad eraseblock 394 at 0x000003140000
[   15.047888] nand: nand_do_read_oob: from = 0x03160000, len = 64
[   15.054068] marvell-nfc pxa3xx-nand: 
[   15.054068] NDCR:  0x9d079fff
[   15.054068] NDCB0: 0x000d3000
[   15.054068] NDCB1: 0x62c00000
[   15.054068] NDCB2: 0x00000000
[   15.054068] NDCB3: 0x00000000
[   15.072964] Bad eraseblock 395 at 0x000003160000
[   15.077661] nand: nand_do_read_oob: from = 0x03180000, len = 64
[   15.083840] marvell-nfc pxa3xx-nand: 
[   15.083840] NDCR:  0x9d079fff
[   15.083840] NDCB0: 0x000d3000
[   15.083840] NDCB1: 0x63000000
[   15.083840] NDCB2: 0x00000000
[   15.083840] NDCB3: 0x00000000
[   15.102738] Bad eraseblock 396 at 0x000003180000
[   15.107438] nand: nand_do_read_oob: from = 0x031a0000, len = 64
[   15.113614] marvell-nfc pxa3xx-nand: 
[   15.113614] NDCR:  0x9d079fff
[   15.113614] NDCB0: 0x000d3000
[   15.113614] NDCB1: 0x63400000
[   15.113614] NDCB2: 0x00000000
[   15.113614] NDCB3: 0x00000000
[   15.132513] Bad eraseblock 397 at 0x0000031a0000
[   15.137211] nand: nand_do_read_oob: from = 0x031c0000, len = 64
[   15.143391] marvell-nfc pxa3xx-nand: 
[   15.143391] NDCR:  0x9d079fff
[   15.143391] NDCB0: 0x000d3000
[   15.143391] NDCB1: 0x63800000
[   15.143391] NDCB2: 0x00000000
[   15.143391] NDCB3: 0x00000000
[   15.162287] Bad eraseblock 398 at 0x0000031c0000
[   15.166986] nand: nand_do_read_oob: from = 0x031e0000, len = 64
[   15.173164] marvell-nfc pxa3xx-nand: 
[   15.173164] NDCR:  0x9d079fff
[   15.173164] NDCB0: 0x000d3000
[   15.173164] NDCB1: 0x63c00000
[   15.173164] NDCB2: 0x00000000
[   15.173164] NDCB3: 0x00000000
[   15.192064] Bad eraseblock 399 at 0x0000031e0000
[   15.196761] nand: nand_do_read_oob: from = 0x03200000, len = 64
[   15.202939] marvell-nfc pxa3xx-nand: 
[   15.202939] NDCR:  0x9d079fff
[   15.202939] NDCB0: 0x000d3000
[   15.202939] NDCB1: 0x64000000
[   15.202939] NDCB2: 0x00000000
[   15.202939] NDCB3: 0x00000000
[   15.221831] Bad eraseblock 400 at 0x000003200000
[   15.226527] nand: nand_do_read_oob: from = 0x03220000, len = 64
[   15.232706] marvell-nfc pxa3xx-nand: 
[   15.232706] NDCR:  0x9d079fff
[   15.232706] NDCB0: 0x000d3000
[   15.232706] NDCB1: 0x64400000
[   15.232706] NDCB2: 0x00000000
[   15.232706] NDCB3: 0x00000000
[   15.251605] Bad eraseblock 401 at 0x000003220000
[   15.256301] nand: nand_do_read_oob: from = 0x03240000, len = 64
[   15.262479] marvell-nfc pxa3xx-nand: 
[   15.262479] NDCR:  0x9d079fff
[   15.262479] NDCB0: 0x000d3000
[   15.262479] NDCB1: 0x64800000
[   15.262479] NDCB2: 0x00000000
[   15.262479] NDCB3: 0x00000000
[   15.281371] Bad eraseblock 402 at 0x000003240000
[   15.286068] nand: nand_do_read_oob: from = 0x03260000, len = 64
[   15.292246] marvell-nfc pxa3xx-nand: 
[   15.292246] NDCR:  0x9d079fff
[   15.292246] NDCB0: 0x000d3000
[   15.292246] NDCB1: 0x64c00000
[   15.292246] NDCB2: 0x00000000
[   15.292246] NDCB3: 0x00000000
[   15.311177] nand: nand_do_read_oob: from = 0x03280000, len = 64
[   15.317209] marvell-nfc pxa3xx-nand: 
[   15.317209] NDCR:  0x9d079fff
[   15.317209] NDCB0: 0x000d3000
[   15.317209] NDCB1: 0x65000000
[   15.317209] NDCB2: 0x00000000
[   15.317209] NDCB3: 0x00000000
[   15.336142] nand: nand_do_read_oob: from = 0x032a0000, len = 64
[   15.342347] marvell-nfc pxa3xx-nand: 
[   15.342347] NDCR:  0x9d079fff
[   15.342347] NDCB0: 0x000d3000
[   15.342347] NDCB1: 0x65400000
[   15.342347] NDCB2: 0x00000000
[   15.342347] NDCB3: 0x00000000
[   15.361294] nand: nand_do_read_oob: from = 0x032c0000, len = 64
[   15.367324] marvell-nfc pxa3xx-nand: 
[   15.367324] NDCR:  0x9d079fff
[   15.367324] NDCB0: 0x000d3000
[   15.367324] NDCB1: 0x65800000
[   15.367324] NDCB2: 0x00000000
[   15.367324] NDCB3: 0x00000000
[   15.386260] nand: nand_do_read_oob: from = 0x032e0000, len = 64
[   15.392463] marvell-nfc pxa3xx-nand: 
[   15.392463] NDCR:  0x9d079fff
[   15.392463] NDCB0: 0x000d3000
[   15.392463] NDCB1: 0x65c00000
[   15.392463] NDCB2: 0x00000000
[   15.392463] NDCB3: 0x00000000
[   15.411391] nand: nand_do_read_oob: from = 0x03300000, len = 64
[   15.417424] marvell-nfc pxa3xx-nand: 
[   15.417424] NDCR:  0x9d079fff
[   15.417424] NDCB0: 0x000d3000
[   15.417424] NDCB1: 0x66000000
[   15.417424] NDCB2: 0x00000000
[   15.417424] NDCB3: 0x00000000
[   15.436353] nand: nand_do_read_oob: from = 0x03320000, len = 64
[   15.442555] marvell-nfc pxa3xx-nand: 
[   15.442555] NDCR:  0x9d079fff
[   15.442555] NDCB0: 0x000d3000
[   15.442555] NDCB1: 0x66400000
[   15.442555] NDCB2: 0x00000000
[   15.442555] NDCB3: 0x00000000
[   15.461482] nand: nand_do_read_oob: from = 0x03340000, len = 64
[   15.467512] marvell-nfc pxa3xx-nand: 
[   15.467512] NDCR:  0x9d079fff
[   15.467512] NDCB0: 0x000d3000
[   15.467512] NDCB1: 0x66800000
[   15.467512] NDCB2: 0x00000000
[   15.467512] NDCB3: 0x00000000
[   15.486447] nand: nand_do_read_oob: from = 0x03360000, len = 64
[   15.492651] marvell-nfc pxa3xx-nand: 
[   15.492651] NDCR:  0x9d079fff
[   15.492651] NDCB0: 0x000d3000
[   15.492651] NDCB1: 0x66c00000
[   15.492651] NDCB2: 0x00000000
[   15.492651] NDCB3: 0x00000000
[   15.511580] nand: nand_do_read_oob: from = 0x03380000, len = 64
[   15.517610] marvell-nfc pxa3xx-nand: 
[   15.517610] NDCR:  0x9d079fff
[   15.517610] NDCB0: 0x000d3000
[   15.517610] NDCB1: 0x67000000
[   15.517610] NDCB2: 0x00000000
[   15.517610] NDCB3: 0x00000000
[   15.536551] nand: nand_do_read_oob: from = 0x033a0000, len = 64
[   15.542750] marvell-nfc pxa3xx-nand: 
[   15.542750] NDCR:  0x9d079fff
[   15.542750] NDCB0: 0x000d3000
[   15.542750] NDCB1: 0x67400000
[   15.542750] NDCB2: 0x00000000
[   15.542750] NDCB3: 0x00000000
[   15.561678] nand: nand_do_read_oob: from = 0x033c0000, len = 64
[   15.567711] marvell-nfc pxa3xx-nand: 
[   15.567711] NDCR:  0x9d079fff
[   15.567711] NDCB0: 0x000d3000
[   15.567711] NDCB1: 0x67800000
[   15.567711] NDCB2: 0x00000000
[   15.567711] NDCB3: 0x00000000
[   15.586643] nand: nand_do_read_oob: from = 0x033e0000, len = 64
[   15.592851] marvell-nfc pxa3xx-nand: 
[   15.592851] NDCR:  0x9d079fff
[   15.592851] NDCB0: 0x000d3000
[   15.592851] NDCB1: 0x67c00000
[   15.592851] NDCB2: 0x00000000
[   15.592851] NDCB3: 0x00000000
[   15.611775] nand: nand_do_read_oob: from = 0x03400000, len = 64
[   15.617808] marvell-nfc pxa3xx-nand: 
[   15.617808] NDCR:  0x9d079fff
[   15.617808] NDCB0: 0x000d3000
[   15.617808] NDCB1: 0x68000000
[   15.617808] NDCB2: 0x00000000
[   15.617808] NDCB3: 0x00000000
[   15.636743] nand: nand_do_read_oob: from = 0x03420000, len = 64
[   15.642945] marvell-nfc pxa3xx-nand: 
[   15.642945] NDCR:  0x9d079fff
[   15.642945] NDCB0: 0x000d3000
[   15.642945] NDCB1: 0x68400000
[   15.642945] NDCB2: 0x00000000
[   15.642945] NDCB3: 0x00000000
[   15.661875] nand: nand_do_read_oob: from = 0x03440000, len = 64
[   15.667906] marvell-nfc pxa3xx-nand: 
[   15.667906] NDCR:  0x9d079fff
[   15.667906] NDCB0: 0x000d3000
[   15.667906] NDCB1: 0x68800000
[   15.667906] NDCB2: 0x00000000
[   15.667906] NDCB3: 0x00000000
[   15.686838] nand: nand_do_read_oob: from = 0x03460000, len = 64
[   15.693038] marvell-nfc pxa3xx-nand: 
[   15.693038] NDCR:  0x9d079fff
[   15.693038] NDCB0: 0x000d3000
[   15.693038] NDCB1: 0x68c00000
[   15.693038] NDCB2: 0x00000000
[   15.693038] NDCB3: 0x00000000
[   15.711963] nand: nand_do_read_oob: from = 0x03480000, len = 64
[   15.717998] marvell-nfc pxa3xx-nand: 
[   15.717998] NDCR:  0x9d079fff
[   15.717998] NDCB0: 0x000d3000
[   15.717998] NDCB1: 0x69000000
[   15.717998] NDCB2: 0x00000000
[   15.717998] NDCB3: 0x00000000
[   15.736929] nand: nand_do_read_oob: from = 0x034a0000, len = 64
[   15.743137] marvell-nfc pxa3xx-nand: 
[   15.743137] NDCR:  0x9d079fff
[   15.743137] NDCB0: 0x000d3000
[   15.743137] NDCB1: 0x69400000
[   15.743137] NDCB2: 0x00000000
[   15.743137] NDCB3: 0x00000000
[   15.762067] nand: nand_do_read_oob: from = 0x034c0000, len = 64
[   15.768095] marvell-nfc pxa3xx-nand: 
[   15.768095] NDCR:  0x9d079fff
[   15.768095] NDCB0: 0x000d3000
[   15.768095] NDCB1: 0x69800000
[   15.768095] NDCB2: 0x00000000
[   15.768095] NDCB3: 0x00000000
[   15.787028] nand: nand_do_read_oob: from = 0x034e0000, len = 64
[   15.793233] marvell-nfc pxa3xx-nand: 
[   15.793233] NDCR:  0x9d079fff
[   15.793233] NDCB0: 0x000d3000
[   15.793233] NDCB1: 0x69c00000
[   15.793233] NDCB2: 0x00000000
[   15.793233] NDCB3: 0x00000000
[   15.812162] nand: nand_do_read_oob: from = 0x03500000, len = 64
[   15.818194] marvell-nfc pxa3xx-nand: 
[   15.818194] NDCR:  0x9d079fff
[   15.818194] NDCB0: 0x000d3000
[   15.818194] NDCB1: 0x6a000000
[   15.818194] NDCB2: 0x00000000
[   15.818194] NDCB3: 0x00000000
[   15.837126] nand: nand_do_read_oob: from = 0x03520000, len = 64
[   15.843332] marvell-nfc pxa3xx-nand: 
[   15.843332] NDCR:  0x9d079fff
[   15.843332] NDCB0: 0x000d3000
[   15.843332] NDCB1: 0x6a400000
[   15.843332] NDCB2: 0x00000000
[   15.843332] NDCB3: 0x00000000
[   15.862261] nand: nand_do_read_oob: from = 0x03540000, len = 64
[   15.868293] marvell-nfc pxa3xx-nand: 
[   15.868293] NDCR:  0x9d079fff
[   15.868293] NDCB0: 0x000d3000
[   15.868293] NDCB1: 0x6a800000
[   15.868293] NDCB2: 0x00000000
[   15.868293] NDCB3: 0x00000000
[   15.887223] nand: nand_do_read_oob: from = 0x03560000, len = 64
[   15.893432] marvell-nfc pxa3xx-nand: 
[   15.893432] NDCR:  0x9d079fff
[   15.893432] NDCB0: 0x000d3000
[   15.893432] NDCB1: 0x6ac00000
[   15.893432] NDCB2: 0x00000000
[   15.893432] NDCB3: 0x00000000
[   15.912358] nand: nand_do_read_oob: from = 0x03580000, len = 64
[   15.918389] marvell-nfc pxa3xx-nand: 
[   15.918389] NDCR:  0x9d079fff
[   15.918389] NDCB0: 0x000d3000
[   15.918389] NDCB1: 0x6b000000
[   15.918389] NDCB2: 0x00000000
[   15.918389] NDCB3: 0x00000000
[   15.937323] nand: nand_do_read_oob: from = 0x035a0000, len = 64
[   15.943528] marvell-nfc pxa3xx-nand: 
[   15.943528] NDCR:  0x9d079fff
[   15.943528] NDCB0: 0x000d3000
[   15.943528] NDCB1: 0x6b400000
[   15.943528] NDCB2: 0x00000000
[   15.943528] NDCB3: 0x00000000
[   15.962458] nand: nand_do_read_oob: from = 0x035c0000, len = 64
[   15.968490] marvell-nfc pxa3xx-nand: 
[   15.968490] NDCR:  0x9d079fff
[   15.968490] NDCB0: 0x000d3000
[   15.968490] NDCB1: 0x6b800000
[   15.968490] NDCB2: 0x00000000
[   15.968490] NDCB3: 0x00000000
[   15.987421] nand: nand_do_read_oob: from = 0x035e0000, len = 64
[   15.993628] marvell-nfc pxa3xx-nand: 
[   15.993628] NDCR:  0x9d079fff
[   15.993628] NDCB0: 0x000d3000
[   15.993628] NDCB1: 0x6bc00000
[   15.993628] NDCB2: 0x00000000
[   15.993628] NDCB3: 0x00000000
[   16.012583] nand: nand_do_read_oob: from = 0x03600000, len = 64
[   16.018614] marvell-nfc pxa3xx-nand: 
[   16.018614] NDCR:  0x9d079fff
[   16.018614] NDCB0: 0x000d3000
[   16.018614] NDCB1: 0x6c000000
[   16.018614] NDCB2: 0x00000000
[   16.018614] NDCB3: 0x00000000
[   16.037664] nand: nand_do_read_oob: from = 0x03620000, len = 64
[   16.043862] marvell-nfc pxa3xx-nand: 
[   16.043862] NDCR:  0x9d079fff
[   16.043862] NDCB0: 0x000d3000
[   16.043862] NDCB1: 0x6c400000
[   16.043862] NDCB2: 0x00000000
[   16.043862] NDCB3: 0x00000000
[   16.062792] nand: nand_do_read_oob: from = 0x03640000, len = 64
[   16.068995] marvell-nfc pxa3xx-nand: 
[   16.068995] NDCR:  0x9d079fff
[   16.068995] NDCB0: 0x000d3000
[   16.068995] NDCB1: 0x6c800000
[   16.068995] NDCB2: 0x00000000
[   16.068995] NDCB3: 0x00000000
[   16.087911] nand: nand_do_read_oob: from = 0x03660000, len = 64
[   16.094597] marvell-nfc pxa3xx-nand: 
[   16.094597] NDCR:  0x9d079fff
[   16.094597] NDCB0: 0x000d3000
[   16.094597] NDCB1: 0x6cc00000
[   16.094597] NDCB2: 0x00000000
[   16.094597] NDCB3: 0x00000000
[   16.113619] nand: nand_do_read_oob: from = 0x03680000, len = 64
[   16.119819] marvell-nfc pxa3xx-nand: 
[   16.119819] NDCR:  0x9d079fff
[   16.119819] NDCB0: 0x000d3000
[   16.119819] NDCB1: 0x6d000000
[   16.119819] NDCB2: 0x00000000
[   16.119819] NDCB3: 0x00000000
[   16.138936] nand: nand_do_read_oob: from = 0x036a0000, len = 64
[   16.144980] marvell-nfc pxa3xx-nand: 
[   16.144980] NDCR:  0x9d079fff
[   16.144980] NDCB0: 0x000d3000
[   16.144980] NDCB1: 0x6d400000
[   16.144980] NDCB2: 0x00000000
[   16.144980] NDCB3: 0x00000000
[   16.163932] nand: nand_do_read_oob: from = 0x036c0000, len = 64
[   16.170140] marvell-nfc pxa3xx-nand: 
[   16.170140] NDCR:  0x9d079fff
[   16.170140] NDCB0: 0x000d3000
[   16.170140] NDCB1: 0x6d800000
[   16.170140] NDCB2: 0x00000000
[   16.170140] NDCB3: 0x00000000
[   16.189067] nand: nand_do_read_oob: from = 0x036e0000, len = 64
[   16.195099] marvell-nfc pxa3xx-nand: 
[   16.195099] NDCR:  0x9d079fff
[   16.195099] NDCB0: 0x000d3000
[   16.195099] NDCB1: 0x6dc00000
[   16.195099] NDCB2: 0x00000000
[   16.195099] NDCB3: 0x00000000
[   16.214034] nand: nand_do_read_oob: from = 0x03700000, len = 64
[   16.220239] marvell-nfc pxa3xx-nand: 
[   16.220239] NDCR:  0x9d079fff
[   16.220239] NDCB0: 0x000d3000
[   16.220239] NDCB1: 0x6e000000
[   16.220239] NDCB2: 0x00000000
[   16.220239] NDCB3: 0x00000000
[   16.239166] nand: nand_do_read_oob: from = 0x03720000, len = 64
[   16.245199] marvell-nfc pxa3xx-nand: 
[   16.245199] NDCR:  0x9d079fff
[   16.245199] NDCB0: 0x000d3000
[   16.245199] NDCB1: 0x6e400000
[   16.245199] NDCB2: 0x00000000
[   16.245199] NDCB3: 0x00000000
[   16.264131] nand: nand_do_read_oob: from = 0x03740000, len = 64
[   16.270338] marvell-nfc pxa3xx-nand: 
[   16.270338] NDCR:  0x9d079fff
[   16.270338] NDCB0: 0x000d3000
[   16.270338] NDCB1: 0x6e800000
[   16.270338] NDCB2: 0x00000000
[   16.270338] NDCB3: 0x00000000
[   16.289263] nand: nand_do_read_oob: from = 0x03760000, len = 64
[   16.295298] marvell-nfc pxa3xx-nand: 
[   16.295298] NDCR:  0x9d079fff
[   16.295298] NDCB0: 0x000d3000
[   16.295298] NDCB1: 0x6ec00000
[   16.295298] NDCB2: 0x00000000
[   16.295298] NDCB3: 0x00000000
[   16.314230] nand: nand_do_read_oob: from = 0x03780000, len = 64
[   16.320435] marvell-nfc pxa3xx-nand: 
[   16.320435] NDCR:  0x9d079fff
[   16.320435] NDCB0: 0x000d3000
[   16.320435] NDCB1: 0x6f000000
[   16.320435] NDCB2: 0x00000000
[   16.320435] NDCB3: 0x00000000
[   16.339368] nand: nand_do_read_oob: from = 0x037a0000, len = 64
[   16.345403] marvell-nfc pxa3xx-nand: 
[   16.345403] NDCR:  0x9d079fff
[   16.345403] NDCB0: 0x000d3000
[   16.345403] NDCB1: 0x6f400000
[   16.345403] NDCB2: 0x00000000
[   16.345403] NDCB3: 0x00000000
[   16.364339] nand: nand_do_read_oob: from = 0x037c0000, len = 64
[   16.370541] marvell-nfc pxa3xx-nand: 
[   16.370541] NDCR:  0x9d079fff
[   16.370541] NDCB0: 0x000d3000
[   16.370541] NDCB1: 0x6f800000
[   16.370541] NDCB2: 0x00000000
[   16.370541] NDCB3: 0x00000000
[   16.389471] nand: nand_do_read_oob: from = 0x037e0000, len = 64
[   16.395504] marvell-nfc pxa3xx-nand: 
[   16.395504] NDCR:  0x9d079fff
[   16.395504] NDCB0: 0x000d3000
[   16.395504] NDCB1: 0x6fc00000
[   16.395504] NDCB2: 0x00000000
[   16.395504] NDCB3: 0x00000000
[   16.414434] nand: nand_do_read_oob: from = 0x03800000, len = 64
[   16.420642] marvell-nfc pxa3xx-nand: 
[   16.420642] NDCR:  0x9d079fff
[   16.420642] NDCB0: 0x000d3000
[   16.420642] NDCB1: 0x70000000
[   16.420642] NDCB2: 0x00000000
[   16.420642] NDCB3: 0x00000000
[   16.439569] nand: nand_do_read_oob: from = 0x03820000, len = 64
[   16.445602] marvell-nfc pxa3xx-nand: 
[   16.445602] NDCR:  0x9d079fff
[   16.445602] NDCB0: 0x000d3000
[   16.445602] NDCB1: 0x70400000
[   16.445602] NDCB2: 0x00000000
[   16.445602] NDCB3: 0x00000000
[   16.464534] nand: nand_do_read_oob: from = 0x03840000, len = 64
[   16.470738] marvell-nfc pxa3xx-nand: 
[   16.470738] NDCR:  0x9d079fff
[   16.470738] NDCB0: 0x000d3000
[   16.470738] NDCB1: 0x70800000
[   16.470738] NDCB2: 0x00000000
[   16.470738] NDCB3: 0x00000000
[   16.489668] nand: nand_do_read_oob: from = 0x03860000, len = 64
[   16.495698] marvell-nfc pxa3xx-nand: 
[   16.495698] NDCR:  0x9d079fff
[   16.495698] NDCB0: 0x000d3000
[   16.495698] NDCB1: 0x70c00000
[   16.495698] NDCB2: 0x00000000
[   16.495698] NDCB3: 0x00000000
[   16.514633] nand: nand_do_read_oob: from = 0x03880000, len = 64
[   16.520836] marvell-nfc pxa3xx-nand: 
[   16.520836] NDCR:  0x9d079fff
[   16.520836] NDCB0: 0x000d3000
[   16.520836] NDCB1: 0x71000000
[   16.520836] NDCB2: 0x00000000
[   16.520836] NDCB3: 0x00000000
[   16.539765] nand: nand_do_read_oob: from = 0x038a0000, len = 64
[   16.545799] marvell-nfc pxa3xx-nand: 
[   16.545799] NDCR:  0x9d079fff
[   16.545799] NDCB0: 0x000d3000
[   16.545799] NDCB1: 0x71400000
[   16.545799] NDCB2: 0x00000000
[   16.545799] NDCB3: 0x00000000
[   16.564735] nand: nand_do_read_oob: from = 0x038c0000, len = 64
[   16.570937] marvell-nfc pxa3xx-nand: 
[   16.570937] NDCR:  0x9d079fff
[   16.570937] NDCB0: 0x000d3000
[   16.570937] NDCB1: 0x71800000
[   16.570937] NDCB2: 0x00000000
[   16.570937] NDCB3: 0x00000000
[   16.589863] nand: nand_do_read_oob: from = 0x038e0000, len = 64
[   16.595896] marvell-nfc pxa3xx-nand: 
[   16.595896] NDCR:  0x9d079fff
[   16.595896] NDCB0: 0x000d3000
[   16.595896] NDCB1: 0x71c00000
[   16.595896] NDCB2: 0x00000000
[   16.595896] NDCB3: 0x00000000
[   16.614851] nand: nand_do_read_oob: from = 0x03900000, len = 64
[   16.621051] marvell-nfc pxa3xx-nand: 
[   16.621051] NDCR:  0x9d079fff
[   16.621051] NDCB0: 0x000d3000
[   16.621051] NDCB1: 0x72000000
[   16.621051] NDCB2: 0x00000000
[   16.621051] NDCB3: 0x00000000
[   16.639979] nand: nand_do_read_oob: from = 0x03920000, len = 64
[   16.646011] marvell-nfc pxa3xx-nand: 
[   16.646011] NDCR:  0x9d079fff
[   16.646011] NDCB0: 0x000d3000
[   16.646011] NDCB1: 0x72400000
[   16.646011] NDCB2: 0x00000000
[   16.646011] NDCB3: 0x00000000
[   16.664947] nand: nand_do_read_oob: from = 0x03940000, len = 64
[   16.671151] marvell-nfc pxa3xx-nand: 
[   16.671151] NDCR:  0x9d079fff
[   16.671151] NDCB0: 0x000d3000
[   16.671151] NDCB1: 0x72800000
[   16.671151] NDCB2: 0x00000000
[   16.671151] NDCB3: 0x00000000
[   16.690079] nand: nand_do_read_oob: from = 0x03960000, len = 64
[   16.696110] marvell-nfc pxa3xx-nand: 
[   16.696110] NDCR:  0x9d079fff
[   16.696110] NDCB0: 0x000d3000
[   16.696110] NDCB1: 0x72c00000
[   16.696110] NDCB2: 0x00000000
[   16.696110] NDCB3: 0x00000000
[   16.715040] nand: nand_do_read_oob: from = 0x03980000, len = 64
[   16.721242] marvell-nfc pxa3xx-nand: 
[   16.721242] NDCR:  0x9d079fff
[   16.721242] NDCB0: 0x000d3000
[   16.721242] NDCB1: 0x73000000
[   16.721242] NDCB2: 0x00000000
[   16.721242] NDCB3: 0x00000000
[   16.740169] nand: nand_do_read_oob: from = 0x039a0000, len = 64
[   16.746199] marvell-nfc pxa3xx-nand: 
[   16.746199] NDCR:  0x9d079fff
[   16.746199] NDCB0: 0x000d3000
[   16.746199] NDCB1: 0x73400000
[   16.746199] NDCB2: 0x00000000
[   16.746199] NDCB3: 0x00000000
[   16.765132] nand: nand_do_read_oob: from = 0x039c0000, len = 64
[   16.771339] marvell-nfc pxa3xx-nand: 
[   16.771339] NDCR:  0x9d079fff
[   16.771339] NDCB0: 0x000d3000
[   16.771339] NDCB1: 0x73800000
[   16.771339] NDCB2: 0x00000000
[   16.771339] NDCB3: 0x00000000
[   16.790267] nand: nand_do_read_oob: from = 0x039e0000, len = 64
[   16.796298] marvell-nfc pxa3xx-nand: 
[   16.796298] NDCR:  0x9d079fff
[   16.796298] NDCB0: 0x000d3000
[   16.796298] NDCB1: 0x73c00000
[   16.796298] NDCB2: 0x00000000
[   16.796298] NDCB3: 0x00000000
[   16.815233] nand: nand_do_read_oob: from = 0x03a00000, len = 64
[   16.821436] marvell-nfc pxa3xx-nand: 
[   16.821436] NDCR:  0x9d079fff
[   16.821436] NDCB0: 0x000d3000
[   16.821436] NDCB1: 0x74000000
[   16.821436] NDCB2: 0x00000000
[   16.821436] NDCB3: 0x00000000
[   16.840365] nand: nand_do_read_oob: from = 0x03a20000, len = 64
[   16.846398] marvell-nfc pxa3xx-nand: 
[   16.846398] NDCR:  0x9d079fff
[   16.846398] NDCB0: 0x000d3000
[   16.846398] NDCB1: 0x74400000
[   16.846398] NDCB2: 0x00000000
[   16.846398] NDCB3: 0x00000000
[   16.865330] nand: nand_do_read_oob: from = 0x03a40000, len = 64
[   16.871536] marvell-nfc pxa3xx-nand: 
[   16.871536] NDCR:  0x9d079fff
[   16.871536] NDCB0: 0x000d3000
[   16.871536] NDCB1: 0x74800000
[   16.871536] NDCB2: 0x00000000
[   16.871536] NDCB3: 0x00000000
[   16.890461] nand: nand_do_read_oob: from = 0x03a60000, len = 64
[   16.896496] marvell-nfc pxa3xx-nand: 
[   16.896496] NDCR:  0x9d079fff
[   16.896496] NDCB0: 0x000d3000
[   16.896496] NDCB1: 0x74c00000
[   16.896496] NDCB2: 0x00000000
[   16.896496] NDCB3: 0x00000000
[   16.915426] nand: nand_do_read_oob: from = 0x03a80000, len = 64
[   16.921635] marvell-nfc pxa3xx-nand: 
[   16.921635] NDCR:  0x9d079fff
[   16.921635] NDCB0: 0x000d3000
[   16.921635] NDCB1: 0x75000000
[   16.921635] NDCB2: 0x00000000
[   16.921635] NDCB3: 0x00000000
[   16.940561] nand: nand_do_read_oob: from = 0x03aa0000, len = 64
[   16.946594] marvell-nfc pxa3xx-nand: 
[   16.946594] NDCR:  0x9d079fff
[   16.946594] NDCB0: 0x000d3000
[   16.946594] NDCB1: 0x75400000
[   16.946594] NDCB2: 0x00000000
[   16.946594] NDCB3: 0x00000000
[   16.965526] nand: nand_do_read_oob: from = 0x03ac0000, len = 64
[   16.971733] marvell-nfc pxa3xx-nand: 
[   16.971733] NDCR:  0x9d079fff
[   16.971733] NDCB0: 0x000d3000
[   16.971733] NDCB1: 0x75800000
[   16.971733] NDCB2: 0x00000000
[   16.971733] NDCB3: 0x00000000
[   16.990660] nand: nand_do_read_oob: from = 0x03ae0000, len = 64
[   16.996693] marvell-nfc pxa3xx-nand: 
[   16.996693] NDCR:  0x9d079fff
[   16.996693] NDCB0: 0x000d3000
[   16.996693] NDCB1: 0x75c00000
[   16.996693] NDCB2: 0x00000000
[   16.996693] NDCB3: 0x00000000
[   17.015635] nand: nand_do_read_oob: from = 0x03b00000, len = 64
[   17.021843] marvell-nfc pxa3xx-nand: 
[   17.021843] NDCR:  0x9d079fff
[   17.021843] NDCB0: 0x000d3000
[   17.021843] NDCB1: 0x76000000
[   17.021843] NDCB2: 0x00000000
[   17.021843] NDCB3: 0x00000000
[   17.040767] nand: nand_do_read_oob: from = 0x03b20000, len = 64
[   17.046800] marvell-nfc pxa3xx-nand: 
[   17.046800] NDCR:  0x9d079fff
[   17.046800] NDCB0: 0x000d3000
[   17.046800] NDCB1: 0x76400000
[   17.046800] NDCB2: 0x00000000
[   17.046800] NDCB3: 0x00000000
[   17.065733] nand: nand_do_read_oob: from = 0x03b40000, len = 64
[   17.071938] marvell-nfc pxa3xx-nand: 
[   17.071938] NDCR:  0x9d079fff
[   17.071938] NDCB0: 0x000d3000
[   17.071938] NDCB1: 0x76800000
[   17.071938] NDCB2: 0x00000000
[   17.071938] NDCB3: 0x00000000
[   17.090865] nand: nand_do_read_oob: from = 0x03b60000, len = 64
[   17.096897] marvell-nfc pxa3xx-nand: 
[   17.096897] NDCR:  0x9d079fff
[   17.096897] NDCB0: 0x000d3000
[   17.096897] NDCB1: 0x76c00000
[   17.096897] NDCB2: 0x00000000
[   17.096897] NDCB3: 0x00000000
[   17.115833] nand: nand_do_read_oob: from = 0x03b80000, len = 64
[   17.122035] marvell-nfc pxa3xx-nand: 
[   17.122035] NDCR:  0x9d079fff
[   17.122035] NDCB0: 0x000d3000
[   17.122035] NDCB1: 0x77000000
[   17.122035] NDCB2: 0x00000000
[   17.122035] NDCB3: 0x00000000
[   17.140965] nand: nand_do_read_oob: from = 0x03ba0000, len = 64
[   17.146995] marvell-nfc pxa3xx-nand: 
[   17.146995] NDCR:  0x9d079fff
[   17.146995] NDCB0: 0x000d3000
[   17.146995] NDCB1: 0x77400000
[   17.146995] NDCB2: 0x00000000
[   17.146995] NDCB3: 0x00000000
[   17.165931] nand: nand_do_read_oob: from = 0x03bc0000, len = 64
[   17.172135] marvell-nfc pxa3xx-nand: 
[   17.172135] NDCR:  0x9d079fff
[   17.172135] NDCB0: 0x000d3000
[   17.172135] NDCB1: 0x77800000
[   17.172135] NDCB2: 0x00000000
[   17.172135] NDCB3: 0x00000000
[   17.191063] nand: nand_do_read_oob: from = 0x03be0000, len = 64
[   17.197096] marvell-nfc pxa3xx-nand: 
[   17.197096] NDCR:  0x9d079fff
[   17.197096] NDCB0: 0x000d3000
[   17.197096] NDCB1: 0x77c00000
[   17.197096] NDCB2: 0x00000000
[   17.197096] NDCB3: 0x00000000
[   17.216028] nand: nand_do_read_oob: from = 0x03c00000, len = 64
[   17.222235] marvell-nfc pxa3xx-nand: 
[   17.222235] NDCR:  0x9d079fff
[   17.222235] NDCB0: 0x000d3000
[   17.222235] NDCB1: 0x78000000
[   17.222235] NDCB2: 0x00000000
[   17.222235] NDCB3: 0x00000000
[   17.241159] nand: nand_do_read_oob: from = 0x03c20000, len = 64
[   17.247193] marvell-nfc pxa3xx-nand: 
[   17.247193] NDCR:  0x9d079fff
[   17.247193] NDCB0: 0x000d3000
[   17.247193] NDCB1: 0x78400000
[   17.247193] NDCB2: 0x00000000
[   17.247193] NDCB3: 0x00000000
[   17.266142] nand: nand_do_read_oob: from = 0x03c40000, len = 64
[   17.272349] marvell-nfc pxa3xx-nand: 
[   17.272349] NDCR:  0x9d079fff
[   17.272349] NDCB0: 0x000d3000
[   17.272349] NDCB1: 0x78800000
[   17.272349] NDCB2: 0x00000000
[   17.272349] NDCB3: 0x00000000
[   17.291275] nand: nand_do_read_oob: from = 0x03c60000, len = 64
[   17.297308] marvell-nfc pxa3xx-nand: 
[   17.297308] NDCR:  0x9d079fff
[   17.297308] NDCB0: 0x000d3000
[   17.297308] NDCB1: 0x78c00000
[   17.297308] NDCB2: 0x00000000
[   17.297308] NDCB3: 0x00000000
[   17.316239] nand: nand_do_read_oob: from = 0x03c80000, len = 64
[   17.322439] marvell-nfc pxa3xx-nand: 
[   17.322439] NDCR:  0x9d079fff
[   17.322439] NDCB0: 0x000d3000
[   17.322439] NDCB1: 0x79000000
[   17.322439] NDCB2: 0x00000000
[   17.322439] NDCB3: 0x00000000
[   17.341366] nand: nand_do_read_oob: from = 0x03ca0000, len = 64
[   17.347400] marvell-nfc pxa3xx-nand: 
[   17.347400] NDCR:  0x9d079fff
[   17.347400] NDCB0: 0x000d3000
[   17.347400] NDCB1: 0x79400000
[   17.347400] NDCB2: 0x00000000
[   17.347400] NDCB3: 0x00000000
[   17.366333] nand: nand_do_read_oob: from = 0x03cc0000, len = 64
[   17.372538] marvell-nfc pxa3xx-nand: 
[   17.372538] NDCR:  0x9d079fff
[   17.372538] NDCB0: 0x000d3000
[   17.372538] NDCB1: 0x79800000
[   17.372538] NDCB2: 0x00000000
[   17.372538] NDCB3: 0x00000000
[   17.391466] nand: nand_do_read_oob: from = 0x03ce0000, len = 64
[   17.397496] marvell-nfc pxa3xx-nand: 
[   17.397496] NDCR:  0x9d079fff
[   17.397496] NDCB0: 0x000d3000
[   17.397496] NDCB1: 0x79c00000
[   17.397496] NDCB2: 0x00000000
[   17.397496] NDCB3: 0x00000000
[   17.416429] nand: nand_do_read_oob: from = 0x03d00000, len = 64
[   17.422635] marvell-nfc pxa3xx-nand: 
[   17.422635] NDCR:  0x9d079fff
[   17.422635] NDCB0: 0x000d3000
[   17.422635] NDCB1: 0x7a000000
[   17.422635] NDCB2: 0x00000000
[   17.422635] NDCB3: 0x00000000
[   17.441563] nand: nand_do_read_oob: from = 0x03d20000, len = 64
[   17.447596] marvell-nfc pxa3xx-nand: 
[   17.447596] NDCR:  0x9d079fff
[   17.447596] NDCB0: 0x000d3000
[   17.447596] NDCB1: 0x7a400000
[   17.447596] NDCB2: 0x00000000
[   17.447596] NDCB3: 0x00000000
[   17.466528] nand: nand_do_read_oob: from = 0x03d40000, len = 64
[   17.472736] marvell-nfc pxa3xx-nand: 
[   17.472736] NDCR:  0x9d079fff
[   17.472736] NDCB0: 0x000d3000
[   17.472736] NDCB1: 0x7a800000
[   17.472736] NDCB2: 0x00000000
[   17.472736] NDCB3: 0x00000000
[   17.491664] nand: nand_do_read_oob: from = 0x03d60000, len = 64
[   17.497695] marvell-nfc pxa3xx-nand: 
[   17.497695] NDCR:  0x9d079fff
[   17.497695] NDCB0: 0x000d3000
[   17.497695] NDCB1: 0x7ac00000
[   17.497695] NDCB2: 0x00000000
[   17.497695] NDCB3: 0x00000000
[   17.516626] nand: nand_do_read_oob: from = 0x03d80000, len = 64
[   17.522832] marvell-nfc pxa3xx-nand: 
[   17.522832] NDCR:  0x9d079fff
[   17.522832] NDCB0: 0x000d3000
[   17.522832] NDCB1: 0x7b000000
[   17.522832] NDCB2: 0x00000000
[   17.522832] NDCB3: 0x00000000
[   17.541762] nand: nand_do_read_oob: from = 0x03da0000, len = 64
[   17.547793] marvell-nfc pxa3xx-nand: 
[   17.547793] NDCR:  0x9d079fff
[   17.547793] NDCB0: 0x000d3000
[   17.547793] NDCB1: 0x7b400000
[   17.547793] NDCB2: 0x00000000
[   17.547793] NDCB3: 0x00000000
[   17.566726] nand: nand_do_read_oob: from = 0x03dc0000, len = 64
[   17.572931] marvell-nfc pxa3xx-nand: 
[   17.572931] NDCR:  0x9d079fff
[   17.572931] NDCB0: 0x000d3000
[   17.572931] NDCB1: 0x7b800000
[   17.572931] NDCB2: 0x00000000
[   17.572931] NDCB3: 0x00000000
[   17.591858] nand: nand_do_read_oob: from = 0x03de0000, len = 64
[   17.597892] marvell-nfc pxa3xx-nand: 
[   17.597892] NDCR:  0x9d079fff
[   17.597892] NDCB0: 0x000d3000
[   17.597892] NDCB1: 0x7bc00000
[   17.597892] NDCB2: 0x00000000
[   17.597892] NDCB3: 0x00000000
[   17.616823] nand: nand_do_read_oob: from = 0x03e00000, len = 64
[   17.623028] marvell-nfc pxa3xx-nand: 
[   17.623028] NDCR:  0x9d079fff
[   17.623028] NDCB0: 0x000d3000
[   17.623028] NDCB1: 0x7c000000
[   17.623028] NDCB2: 0x00000000
[   17.623028] NDCB3: 0x00000000
[   17.641958] nand: nand_do_read_oob: from = 0x03e20000, len = 64
[   17.647990] marvell-nfc pxa3xx-nand: 
[   17.647990] NDCR:  0x9d079fff
[   17.647990] NDCB0: 0x000d3000
[   17.647990] NDCB1: 0x7c400000
[   17.647990] NDCB2: 0x00000000
[   17.647990] NDCB3: 0x00000000
[   17.666921] nand: nand_do_read_oob: from = 0x03e40000, len = 64
[   17.673120] marvell-nfc pxa3xx-nand: 
[   17.673120] NDCR:  0x9d079fff
[   17.673120] NDCB0: 0x000d3000
[   17.673120] NDCB1: 0x7c800000
[   17.673120] NDCB2: 0x00000000
[   17.673120] NDCB3: 0x00000000
[   17.692046] nand: nand_do_read_oob: from = 0x03e60000, len = 64
[   17.698079] marvell-nfc pxa3xx-nand: 
[   17.698079] NDCR:  0x9d079fff
[   17.698079] NDCB0: 0x000d3000
[   17.698079] NDCB1: 0x7cc00000
[   17.698079] NDCB2: 0x00000000
[   17.698079] NDCB3: 0x00000000
[   17.717011] nand: nand_do_read_oob: from = 0x03e80000, len = 64
[   17.723220] marvell-nfc pxa3xx-nand: 
[   17.723220] NDCR:  0x9d079fff
[   17.723220] NDCB0: 0x000d3000
[   17.723220] NDCB1: 0x7d000000
[   17.723220] NDCB2: 0x00000000
[   17.723220] NDCB3: 0x00000000
[   17.742146] nand: nand_do_read_oob: from = 0x03ea0000, len = 64
[   17.748176] marvell-nfc pxa3xx-nand: 
[   17.748176] NDCR:  0x9d079fff
[   17.748176] NDCB0: 0x000d3000
[   17.748176] NDCB1: 0x7d400000
[   17.748176] NDCB2: 0x00000000
[   17.748176] NDCB3: 0x00000000
[   17.767108] nand: nand_do_read_oob: from = 0x03ec0000, len = 64
[   17.773307] marvell-nfc pxa3xx-nand: 
[   17.773307] NDCR:  0x9d079fff
[   17.773307] NDCB0: 0x000d3000
[   17.773307] NDCB1: 0x7d800000
[   17.773307] NDCB2: 0x00000000
[   17.773307] NDCB3: 0x00000000
[   17.792235] nand: nand_do_read_oob: from = 0x03ee0000, len = 64
[   17.798267] marvell-nfc pxa3xx-nand: 
[   17.798267] NDCR:  0x9d079fff
[   17.798267] NDCB0: 0x000d3000
[   17.798267] NDCB1: 0x7dc00000
[   17.798267] NDCB2: 0x00000000
[   17.798267] NDCB3: 0x00000000
[   17.817199] nand: nand_do_read_oob: from = 0x03f00000, len = 64
[   17.823398] marvell-nfc pxa3xx-nand: 
[   17.823398] NDCR:  0x9d079fff
[   17.823398] NDCB0: 0x000d3000
[   17.823398] NDCB1: 0x7e000000
[   17.823398] NDCB2: 0x00000000
[   17.823398] NDCB3: 0x00000000
[   17.842325] nand: nand_do_read_oob: from = 0x03f20000, len = 64
[   17.848357] marvell-nfc pxa3xx-nand: 
[   17.848357] NDCR:  0x9d079fff
[   17.848357] NDCB0: 0x000d3000
[   17.848357] NDCB1: 0x7e400000
[   17.848357] NDCB2: 0x00000000
[   17.848357] NDCB3: 0x00000000
[   17.867288] nand: nand_do_read_oob: from = 0x03f40000, len = 64
[   17.873487] marvell-nfc pxa3xx-nand: 
[   17.873487] NDCR:  0x9d079fff
[   17.873487] NDCB0: 0x000d3000
[   17.873487] NDCB1: 0x7e800000
[   17.873487] NDCB2: 0x00000000
[   17.873487] NDCB3: 0x00000000
[   17.892431] nand: nand_do_read_oob: from = 0x03f60000, len = 64
[   17.898464] marvell-nfc pxa3xx-nand: 
[   17.898464] NDCR:  0x9d079fff
[   17.898464] NDCB0: 0x000d3000
[   17.898464] NDCB1: 0x7ec00000
[   17.898464] NDCB2: 0x00000000
[   17.898464] NDCB3: 0x00000000
[   17.917396] nand: nand_do_read_oob: from = 0x03f80000, len = 64
[   17.923603] marvell-nfc pxa3xx-nand: 
[   17.923603] NDCR:  0x9d079fff
[   17.923603] NDCB0: 0x000d3000
[   17.923603] NDCB1: 0x7f000000
[   17.923603] NDCB2: 0x00000000
[   17.923603] NDCB3: 0x00000000
[   17.942535] nand: nand_do_read_oob: from = 0x03fa0000, len = 64
[   17.948572] marvell-nfc pxa3xx-nand: 
[   17.948572] NDCR:  0x9d079fff
[   17.948572] NDCB0: 0x000d3000
[   17.948572] NDCB1: 0x7f400000
[   17.948572] NDCB2: 0x00000000
[   17.948572] NDCB3: 0x00000000
[   17.967624] nand: nand_do_read_oob: from = 0x03fc0000, len = 64
[   17.973831] marvell-nfc pxa3xx-nand: 
[   17.973831] NDCR:  0x9d079fff
[   17.973831] NDCB0: 0x000d3000
[   17.973831] NDCB1: 0x7f800000
[   17.973831] NDCB2: 0x00000000
[   17.973831] NDCB3: 0x00000000
[   17.992757] nand: nand_do_read_oob: from = 0x03fe0000, len = 64
[   17.998961] marvell-nfc pxa3xx-nand: 
[   17.998961] NDCR:  0x9d079fff
[   17.998961] NDCB0: 0x000d3000
[   17.998961] NDCB1: 0x7fc00000
[   17.998961] NDCB2: 0x00000000
[   17.998961] NDCB3: 0x00000000
[   18.017891] nand: nand_do_read_oob: from = 0x04000000, len = 64
[   18.024093] marvell-nfc pxa3xx-nand: 
[   18.024093] NDCR:  0x9d079fff
[   18.024093] NDCB0: 0x000d3000
[   18.024093] NDCB1: 0x80000000
[   18.024093] NDCB2: 0x00000000
[   18.024093] NDCB3: 0x00000000
[   18.043020] nand: nand_do_read_oob: from = 0x04020000, len = 64
[   18.049223] marvell-nfc pxa3xx-nand: 
[   18.049223] NDCR:  0x9d079fff
[   18.049223] NDCB0: 0x000d3000
[   18.049223] NDCB1: 0x80400000
[   18.049223] NDCB2: 0x00000000
[   18.049223] NDCB3: 0x00000000
[   18.068142] nand: nand_do_read_oob: from = 0x04040000, len = 64
[   18.074345] marvell-nfc pxa3xx-nand: 
[   18.074345] NDCR:  0x9d079fff
[   18.074345] NDCB0: 0x000d3000
[   18.074345] NDCB1: 0x80800000
[   18.074345] NDCB2: 0x00000000
[   18.074345] NDCB3: 0x00000000
[   18.093622] nand: nand_do_read_oob: from = 0x04060000, len = 64
[   18.099858] marvell-nfc pxa3xx-nand: 
[   18.099858] NDCR:  0x9d079fff
[   18.099858] NDCB0: 0x000d3000
[   18.099858] NDCB1: 0x80c00000
[   18.099858] NDCB2: 0x00000000
[   18.099858] NDCB3: 0x00000000
[   18.118850] nand: nand_do_read_oob: from = 0x04080000, len = 64
[   18.124890] marvell-nfc pxa3xx-nand: 
[   18.124890] NDCR:  0x9d079fff
[   18.124890] NDCB0: 0x000d3000
[   18.124890] NDCB1: 0x81000000
[   18.124890] NDCB2: 0x00000000
[   18.124890] NDCB3: 0x00000000
[   18.143819] nand: nand_do_read_oob: from = 0x040a0000, len = 64
[   18.150025] marvell-nfc pxa3xx-nand: 
[   18.150025] NDCR:  0x9d079fff
[   18.150025] NDCB0: 0x000d3000
[   18.150025] NDCB1: 0x81400000
[   18.150025] NDCB2: 0x00000000
[   18.150025] NDCB3: 0x00000000
[   18.169138] nand: nand_do_read_oob: from = 0x040c0000, len = 64
[   18.175176] marvell-nfc pxa3xx-nand: 
[   18.175176] NDCR:  0x9d079fff
[   18.175176] NDCB0: 0x000d3000
[   18.175176] NDCB1: 0x81800000
[   18.175176] NDCB2: 0x00000000
[   18.175176] NDCB3: 0x00000000
[   18.194125] nand: nand_do_read_oob: from = 0x040e0000, len = 64
[   18.200329] marvell-nfc pxa3xx-nand: 
[   18.200329] NDCR:  0x9d079fff
[   18.200329] NDCB0: 0x000d3000
[   18.200329] NDCB1: 0x81c00000
[   18.200329] NDCB2: 0x00000000
[   18.200329] NDCB3: 0x00000000
[   18.219258] nand: nand_do_read_oob: from = 0x04100000, len = 64
[   18.225289] marvell-nfc pxa3xx-nand: 
[   18.225289] NDCR:  0x9d079fff
[   18.225289] NDCB0: 0x000d3000
[   18.225289] NDCB1: 0x82000000
[   18.225289] NDCB2: 0x00000000
[   18.225289] NDCB3: 0x00000000
[   18.244221] nand: nand_do_read_oob: from = 0x04120000, len = 64
[   18.250430] marvell-nfc pxa3xx-nand: 
[   18.250430] NDCR:  0x9d079fff
[   18.250430] NDCB0: 0x000d3000
[   18.250430] NDCB1: 0x82400000
[   18.250430] NDCB2: 0x00000000
[   18.250430] NDCB3: 0x00000000
[   18.269353] nand: nand_do_read_oob: from = 0x04140000, len = 64
[   18.275388] marvell-nfc pxa3xx-nand: 
[   18.275388] NDCR:  0x9d079fff
[   18.275388] NDCB0: 0x000d3000
[   18.275388] NDCB1: 0x82800000
[   18.275388] NDCB2: 0x00000000
[   18.275388] NDCB3: 0x00000000
[   18.294322] nand: nand_do_read_oob: from = 0x04160000, len = 64
[   18.300526] marvell-nfc pxa3xx-nand: 
[   18.300526] NDCR:  0x9d079fff
[   18.300526] NDCB0: 0x000d3000
[   18.300526] NDCB1: 0x82c00000
[   18.300526] NDCB2: 0x00000000
[   18.300526] NDCB3: 0x00000000
[   18.319453] nand: nand_do_read_oob: from = 0x04180000, len = 64
[   18.325486] marvell-nfc pxa3xx-nand: 
[   18.325486] NDCR:  0x9d079fff
[   18.325486] NDCB0: 0x000d3000
[   18.325486] NDCB1: 0x83000000
[   18.325486] NDCB2: 0x00000000
[   18.325486] NDCB3: 0x00000000
[   18.344419] nand: nand_do_read_oob: from = 0x041a0000, len = 64
[   18.350626] marvell-nfc pxa3xx-nand: 
[   18.350626] NDCR:  0x9d079fff
[   18.350626] NDCB0: 0x000d3000
[   18.350626] NDCB1: 0x83400000
[   18.350626] NDCB2: 0x00000000
[   18.350626] NDCB3: 0x00000000
[   18.369553] nand: nand_do_read_oob: from = 0x041c0000, len = 64
[   18.375583] marvell-nfc pxa3xx-nand: 
[   18.375583] NDCR:  0x9d079fff
[   18.375583] NDCB0: 0x000d3000
[   18.375583] NDCB1: 0x83800000
[   18.375583] NDCB2: 0x00000000
[   18.375583] NDCB3: 0x00000000
[   18.394516] nand: nand_do_read_oob: from = 0x041e0000, len = 64
[   18.400721] marvell-nfc pxa3xx-nand: 
[   18.400721] NDCR:  0x9d079fff
[   18.400721] NDCB0: 0x000d3000
[   18.400721] NDCB1: 0x83c00000
[   18.400721] NDCB2: 0x00000000
[   18.400721] NDCB3: 0x00000000
[   18.419652] nand: nand_do_read_oob: from = 0x04200000, len = 64
[   18.425684] marvell-nfc pxa3xx-nand: 
[   18.425684] NDCR:  0x9d079fff
[   18.425684] NDCB0: 0x000d3000
[   18.425684] NDCB1: 0x84000000
[   18.425684] NDCB2: 0x00000000
[   18.425684] NDCB3: 0x00000000
[   18.444614] nand: nand_do_read_oob: from = 0x04220000, len = 64
[   18.450822] marvell-nfc pxa3xx-nand: 
[   18.450822] NDCR:  0x9d079fff
[   18.450822] NDCB0: 0x000d3000
[   18.450822] NDCB1: 0x84400000
[   18.450822] NDCB2: 0x00000000
[   18.450822] NDCB3: 0x00000000
[   18.469750] nand: nand_do_read_oob: from = 0x04240000, len = 64
[   18.475780] marvell-nfc pxa3xx-nand: 
[   18.475780] NDCR:  0x9d079fff
[   18.475780] NDCB0: 0x000d3000
[   18.475780] NDCB1: 0x84800000
[   18.475780] NDCB2: 0x00000000
[   18.475780] NDCB3: 0x00000000
[   18.494735] nand: nand_do_read_oob: from = 0x04260000, len = 64
[   18.500935] marvell-nfc pxa3xx-nand: 
[   18.500935] NDCR:  0x9d079fff
[   18.500935] NDCB0: 0x000d3000
[   18.500935] NDCB1: 0x84c00000
[   18.500935] NDCB2: 0x00000000
[   18.500935] NDCB3: 0x00000000
[   18.519864] nand: nand_do_read_oob: from = 0x04280000, len = 64
[   18.525897] marvell-nfc pxa3xx-nand: 
[   18.525897] NDCR:  0x9d079fff
[   18.525897] NDCB0: 0x000d3000
[   18.525897] NDCB1: 0x85000000
[   18.525897] NDCB2: 0x00000000
[   18.525897] NDCB3: 0x00000000
[   18.544830] nand: nand_do_read_oob: from = 0x042a0000, len = 64
[   18.551034] marvell-nfc pxa3xx-nand: 
[   18.551034] NDCR:  0x9d079fff
[   18.551034] NDCB0: 0x000d3000
[   18.551034] NDCB1: 0x85400000
[   18.551034] NDCB2: 0x00000000
[   18.551034] NDCB3: 0x00000000
[   18.569963] nand: nand_do_read_oob: from = 0x042c0000, len = 64
[   18.575995] marvell-nfc pxa3xx-nand: 
[   18.575995] NDCR:  0x9d079fff
[   18.575995] NDCB0: 0x000d3000
[   18.575995] NDCB1: 0x85800000
[   18.575995] NDCB2: 0x00000000
[   18.575995] NDCB3: 0x00000000
[   18.594927] nand: nand_do_read_oob: from = 0x042e0000, len = 64
[   18.601124] marvell-nfc pxa3xx-nand: 
[   18.601124] NDCR:  0x9d079fff
[   18.601124] NDCB0: 0x000d3000
[   18.601124] NDCB1: 0x85c00000
[   18.601124] NDCB2: 0x00000000
[   18.601124] NDCB3: 0x00000000
[   18.620051] nand: nand_do_read_oob: from = 0x04300000, len = 64
[   18.626085] marvell-nfc pxa3xx-nand: 
[   18.626085] NDCR:  0x9d079fff
[   18.626085] NDCB0: 0x000d3000
[   18.626085] NDCB1: 0x86000000
[   18.626085] NDCB2: 0x00000000
[   18.626085] NDCB3: 0x00000000
[   18.645017] nand: nand_do_read_oob: from = 0x04320000, len = 64
[   18.651221] marvell-nfc pxa3xx-nand: 
[   18.651221] NDCR:  0x9d079fff
[   18.651221] NDCB0: 0x000d3000
[   18.651221] NDCB1: 0x86400000
[   18.651221] NDCB2: 0x00000000
[   18.651221] NDCB3: 0x00000000
[   18.670152] nand: nand_do_read_oob: from = 0x04340000, len = 64
[   18.676184] marvell-nfc pxa3xx-nand: 
[   18.676184] NDCR:  0x9d079fff
[   18.676184] NDCB0: 0x000d3000
[   18.676184] NDCB1: 0x86800000
[   18.676184] NDCB2: 0x00000000
[   18.676184] NDCB3: 0x00000000
[   18.695116] nand: nand_do_read_oob: from = 0x04360000, len = 64
[   18.701320] marvell-nfc pxa3xx-nand: 
[   18.701320] NDCR:  0x9d079fff
[   18.701320] NDCB0: 0x000d3000
[   18.701320] NDCB1: 0x86c00000
[   18.701320] NDCB2: 0x00000000
[   18.701320] NDCB3: 0x00000000
[   18.720253] nand: nand_do_read_oob: from = 0x04380000, len = 64
[   18.726282] marvell-nfc pxa3xx-nand: 
[   18.726282] NDCR:  0x9d079fff
[   18.726282] NDCB0: 0x000d3000
[   18.726282] NDCB1: 0x87000000
[   18.726282] NDCB2: 0x00000000
[   18.726282] NDCB3: 0x00000000
[   18.745218] nand: nand_do_read_oob: from = 0x043a0000, len = 64
[   18.751419] marvell-nfc pxa3xx-nand: 
[   18.751419] NDCR:  0x9d079fff
[   18.751419] NDCB0: 0x000d3000
[   18.751419] NDCB1: 0x87400000
[   18.751419] NDCB2: 0x00000000
[   18.751419] NDCB3: 0x00000000
[   18.770352] nand: nand_do_read_oob: from = 0x043c0000, len = 64
[   18.776381] marvell-nfc pxa3xx-nand: 
[   18.776381] NDCR:  0x9d079fff
[   18.776381] NDCB0: 0x000d3000
[   18.776381] NDCB1: 0x87800000
[   18.776381] NDCB2: 0x00000000
[   18.776381] NDCB3: 0x00000000
[   18.795312] nand: nand_do_read_oob: from = 0x043e0000, len = 64
[   18.801519] marvell-nfc pxa3xx-nand: 
[   18.801519] NDCR:  0x9d079fff
[   18.801519] NDCB0: 0x000d3000
[   18.801519] NDCB1: 0x87c00000
[   18.801519] NDCB2: 0x00000000
[   18.801519] NDCB3: 0x00000000
[   18.820449] nand: nand_do_read_oob: from = 0x04400000, len = 64
[   18.826479] marvell-nfc pxa3xx-nand: 
[   18.826479] NDCR:  0x9d079fff
[   18.826479] NDCB0: 0x000d3000
[   18.826479] NDCB1: 0x88000000
[   18.826479] NDCB2: 0x00000000
[   18.826479] NDCB3: 0x00000000
[   18.845411] nand: nand_do_read_oob: from = 0x04420000, len = 64
[   18.851615] marvell-nfc pxa3xx-nand: 
[   18.851615] NDCR:  0x9d079fff
[   18.851615] NDCB0: 0x000d3000
[   18.851615] NDCB1: 0x88400000
[   18.851615] NDCB2: 0x00000000
[   18.851615] NDCB3: 0x00000000
[   18.870547] nand: nand_do_read_oob: from = 0x04440000, len = 64
[   18.876578] marvell-nfc pxa3xx-nand: 
[   18.876578] NDCR:  0x9d079fff
[   18.876578] NDCB0: 0x000d3000
[   18.876578] NDCB1: 0x88800000
[   18.876578] NDCB2: 0x00000000
[   18.876578] NDCB3: 0x00000000
[   18.895510] nand: nand_do_read_oob: from = 0x04460000, len = 64
[   18.901716] marvell-nfc pxa3xx-nand: 
[   18.901716] NDCR:  0x9d079fff
[   18.901716] NDCB0: 0x000d3000
[   18.901716] NDCB1: 0x88c00000
[   18.901716] NDCB2: 0x00000000
[   18.901716] NDCB3: 0x00000000
[   18.920645] nand: nand_do_read_oob: from = 0x04480000, len = 64
[   18.926675] marvell-nfc pxa3xx-nand: 
[   18.926675] NDCR:  0x9d079fff
[   18.926675] NDCB0: 0x000d3000
[   18.926675] NDCB1: 0x89000000
[   18.926675] NDCB2: 0x00000000
[   18.926675] NDCB3: 0x00000000
[   18.945611] nand: nand_do_read_oob: from = 0x044a0000, len = 64
[   18.951814] marvell-nfc pxa3xx-nand: 
[   18.951814] NDCR:  0x9d079fff
[   18.951814] NDCB0: 0x000d3000
[   18.951814] NDCB1: 0x89400000
[   18.951814] NDCB2: 0x00000000
[   18.951814] NDCB3: 0x00000000
[   18.970742] nand: nand_do_read_oob: from = 0x044c0000, len = 64
[   18.976775] marvell-nfc pxa3xx-nand: 
[   18.976775] NDCR:  0x9d079fff
[   18.976775] NDCB0: 0x000d3000
[   18.976775] NDCB1: 0x89800000
[   18.976775] NDCB2: 0x00000000
[   18.976775] NDCB3: 0x00000000
[   18.995706] nand: nand_do_read_oob: from = 0x044e0000, len = 64
[   19.001914] marvell-nfc pxa3xx-nand: 
[   19.001914] NDCR:  0x9d079fff
[   19.001914] NDCB0: 0x000d3000
[   19.001914] NDCB1: 0x89c00000
[   19.001914] NDCB2: 0x00000000
[   19.001914] NDCB3: 0x00000000
[   19.020852] nand: nand_do_read_oob: from = 0x04500000, len = 64
[   19.026882] marvell-nfc pxa3xx-nand: 
[   19.026882] NDCR:  0x9d079fff
[   19.026882] NDCB0: 0x000d3000
[   19.026882] NDCB1: 0x8a000000
[   19.026882] NDCB2: 0x00000000
[   19.026882] NDCB3: 0x00000000
[   19.045816] nand: nand_do_read_oob: from = 0x04520000, len = 64
[   19.052021] marvell-nfc pxa3xx-nand: 
[   19.052021] NDCR:  0x9d079fff
[   19.052021] NDCB0: 0x000d3000
[   19.052021] NDCB1: 0x8a400000
[   19.052021] NDCB2: 0x00000000
[   19.052021] NDCB3: 0x00000000
[   19.070947] nand: nand_do_read_oob: from = 0x04540000, len = 64
[   19.076981] marvell-nfc pxa3xx-nand: 
[   19.076981] NDCR:  0x9d079fff
[   19.076981] NDCB0: 0x000d3000
[   19.076981] NDCB1: 0x8a800000
[   19.076981] NDCB2: 0x00000000
[   19.076981] NDCB3: 0x00000000
[   19.095913] nand: nand_do_read_oob: from = 0x04560000, len = 64
[   19.102117] marvell-nfc pxa3xx-nand: 
[   19.102117] NDCR:  0x9d079fff
[   19.102117] NDCB0: 0x000d3000
[   19.102117] NDCB1: 0x8ac00000
[   19.102117] NDCB2: 0x00000000
[   19.102117] NDCB3: 0x00000000
[   19.121062] nand: nand_do_read_oob: from = 0x04580000, len = 64
[   19.127097] marvell-nfc pxa3xx-nand: 
[   19.127097] NDCR:  0x9d079fff
[   19.127097] NDCB0: 0x000d3000
[   19.127097] NDCB1: 0x8b000000
[   19.127097] NDCB2: 0x00000000
[   19.127097] NDCB3: 0x00000000
[   19.146031] nand: nand_do_read_oob: from = 0x045a0000, len = 64
[   19.152232] marvell-nfc pxa3xx-nand: 
[   19.152232] NDCR:  0x9d079fff
[   19.152232] NDCB0: 0x000d3000
[   19.152232] NDCB1: 0x8b400000
[   19.152232] NDCB2: 0x00000000
[   19.152232] NDCB3: 0x00000000
[   19.171165] nand: nand_do_read_oob: from = 0x045c0000, len = 64
[   19.177195] marvell-nfc pxa3xx-nand: 
[   19.177195] NDCR:  0x9d079fff
[   19.177195] NDCB0: 0x000d3000
[   19.177195] NDCB1: 0x8b800000
[   19.177195] NDCB2: 0x00000000
[   19.177195] NDCB3: 0x00000000
[   19.196127] nand: nand_do_read_oob: from = 0x045e0000, len = 64
[   19.202330] marvell-nfc pxa3xx-nand: 
[   19.202330] NDCR:  0x9d079fff
[   19.202330] NDCB0: 0x000d3000
[   19.202330] NDCB1: 0x8bc00000
[   19.202330] NDCB2: 0x00000000
[   19.202330] NDCB3: 0x00000000
[   19.221261] nand: nand_do_read_oob: from = 0x04600000, len = 64
[   19.227293] marvell-nfc pxa3xx-nand: 
[   19.227293] NDCR:  0x9d079fff
[   19.227293] NDCB0: 0x000d3000
[   19.227293] NDCB1: 0x8c000000
[   19.227293] NDCB2: 0x00000000
[   19.227293] NDCB3: 0x00000000
[   19.246223] nand: nand_do_read_oob: from = 0x04620000, len = 64
[   19.252421] marvell-nfc pxa3xx-nand: 
[   19.252421] NDCR:  0x9d079fff
[   19.252421] NDCB0: 0x000d3000
[   19.252421] NDCB1: 0x8c400000
[   19.252421] NDCB2: 0x00000000
[   19.252421] NDCB3: 0x00000000
[   19.271348] nand: nand_do_read_oob: from = 0x04640000, len = 64
[   19.277383] marvell-nfc pxa3xx-nand: 
[   19.277383] NDCR:  0x9d079fff
[   19.277383] NDCB0: 0x000d3000
[   19.277383] NDCB1: 0x8c800000
[   19.277383] NDCB2: 0x00000000
[   19.277383] NDCB3: 0x00000000
[   19.296316] nand: nand_do_read_oob: from = 0x04660000, len = 64
[   19.302521] marvell-nfc pxa3xx-nand: 
[   19.302521] NDCR:  0x9d079fff
[   19.302521] NDCB0: 0x000d3000
[   19.302521] NDCB1: 0x8cc00000
[   19.302521] NDCB2: 0x00000000
[   19.302521] NDCB3: 0x00000000
[   19.321450] nand: nand_do_read_oob: from = 0x04680000, len = 64
[   19.327482] marvell-nfc pxa3xx-nand: 
[   19.327482] NDCR:  0x9d079fff
[   19.327482] NDCB0: 0x000d3000
[   19.327482] NDCB1: 0x8d000000
[   19.327482] NDCB2: 0x00000000
[   19.327482] NDCB3: 0x00000000
[   19.346415] nand: nand_do_read_oob: from = 0x046a0000, len = 64
[   19.352619] marvell-nfc pxa3xx-nand: 
[   19.352619] NDCR:  0x9d079fff
[   19.352619] NDCB0: 0x000d3000
[   19.352619] NDCB1: 0x8d400000
[   19.352619] NDCB2: 0x00000000
[   19.352619] NDCB3: 0x00000000
[   19.371548] nand: nand_do_read_oob: from = 0x046c0000, len = 64
[   19.377579] marvell-nfc pxa3xx-nand: 
[   19.377579] NDCR:  0x9d079fff
[   19.377579] NDCB0: 0x000d3000
[   19.377579] NDCB1: 0x8d800000
[   19.377579] NDCB2: 0x00000000
[   19.377579] NDCB3: 0x00000000
[   19.396512] nand: nand_do_read_oob: from = 0x046e0000, len = 64
[   19.402716] marvell-nfc pxa3xx-nand: 
[   19.402716] NDCR:  0x9d079fff
[   19.402716] NDCB0: 0x000d3000
[   19.402716] NDCB1: 0x8dc00000
[   19.402716] NDCB2: 0x00000000
[   19.402716] NDCB3: 0x00000000
[   19.421645] nand: nand_do_read_oob: from = 0x04700000, len = 64
[   19.427679] marvell-nfc pxa3xx-nand: 
[   19.427679] NDCR:  0x9d079fff
[   19.427679] NDCB0: 0x000d3000
[   19.427679] NDCB1: 0x8e000000
[   19.427679] NDCB2: 0x00000000
[   19.427679] NDCB3: 0x00000000
[   19.446611] nand: nand_do_read_oob: from = 0x04720000, len = 64
[   19.452815] marvell-nfc pxa3xx-nand: 
[   19.452815] NDCR:  0x9d079fff
[   19.452815] NDCB0: 0x000d3000
[   19.452815] NDCB1: 0x8e400000
[   19.452815] NDCB2: 0x00000000
[   19.452815] NDCB3: 0x00000000
[   19.471747] nand: nand_do_read_oob: from = 0x04740000, len = 64
[   19.477777] marvell-nfc pxa3xx-nand: 
[   19.477777] NDCR:  0x9d079fff
[   19.477777] NDCB0: 0x000d3000
[   19.477777] NDCB1: 0x8e800000
[   19.477777] NDCB2: 0x00000000
[   19.477777] NDCB3: 0x00000000
[   19.496711] nand: nand_do_read_oob: from = 0x04760000, len = 64
[   19.502915] marvell-nfc pxa3xx-nand: 
[   19.502915] NDCR:  0x9d079fff
[   19.502915] NDCB0: 0x000d3000
[   19.502915] NDCB1: 0x8ec00000
[   19.502915] NDCB2: 0x00000000
[   19.502915] NDCB3: 0x00000000
[   19.521847] nand: nand_do_read_oob: from = 0x04780000, len = 64
[   19.527875] marvell-nfc pxa3xx-nand: 
[   19.527875] NDCR:  0x9d079fff
[   19.527875] NDCB0: 0x000d3000
[   19.527875] NDCB1: 0x8f000000
[   19.527875] NDCB2: 0x00000000
[   19.527875] NDCB3: 0x00000000
[   19.546811] nand: nand_do_read_oob: from = 0x047a0000, len = 64
[   19.553012] marvell-nfc pxa3xx-nand: 
[   19.553012] NDCR:  0x9d079fff
[   19.553012] NDCB0: 0x000d3000
[   19.553012] NDCB1: 0x8f400000
[   19.553012] NDCB2: 0x00000000
[   19.553012] NDCB3: 0x00000000
[   19.571940] nand: nand_do_read_oob: from = 0x047c0000, len = 64
[   19.577974] marvell-nfc pxa3xx-nand: 
[   19.577974] NDCR:  0x9d079fff
[   19.577974] NDCB0: 0x000d3000
[   19.577974] NDCB1: 0x8f800000
[   19.577974] NDCB2: 0x00000000
[   19.577974] NDCB3: 0x00000000
[   19.596905] nand: nand_do_read_oob: from = 0x047e0000, len = 64
[   19.603111] marvell-nfc pxa3xx-nand: 
[   19.603111] NDCR:  0x9d079fff
[   19.603111] NDCB0: 0x000d3000
[   19.603111] NDCB1: 0x8fc00000
[   19.603111] NDCB2: 0x00000000
[   19.603111] NDCB3: 0x00000000
[   19.622041] nand: nand_do_read_oob: from = 0x04800000, len = 64
[   19.628071] marvell-nfc pxa3xx-nand: 
[   19.628071] NDCR:  0x9d079fff
[   19.628071] NDCB0: 0x000d3000
[   19.628071] NDCB1: 0x90000000
[   19.628071] NDCB2: 0x00000000
[   19.628071] NDCB3: 0x00000000
[   19.647004] nand: nand_do_read_oob: from = 0x04820000, len = 64
[   19.653208] marvell-nfc pxa3xx-nand: 
[   19.653208] NDCR:  0x9d079fff
[   19.653208] NDCB0: 0x000d3000
[   19.653208] NDCB1: 0x90400000
[   19.653208] NDCB2: 0x00000000
[   19.653208] NDCB3: 0x00000000
[   19.672139] nand: nand_do_read_oob: from = 0x04840000, len = 64
[   19.678169] marvell-nfc pxa3xx-nand: 
[   19.678169] NDCR:  0x9d079fff
[   19.678169] NDCB0: 0x000d3000
[   19.678169] NDCB1: 0x90800000
[   19.678169] NDCB2: 0x00000000
[   19.678169] NDCB3: 0x00000000
[   19.697104] nand: nand_do_read_oob: from = 0x04860000, len = 64
[   19.703307] marvell-nfc pxa3xx-nand: 
[   19.703307] NDCR:  0x9d079fff
[   19.703307] NDCB0: 0x000d3000
[   19.703307] NDCB1: 0x90c00000
[   19.703307] NDCB2: 0x00000000
[   19.703307] NDCB3: 0x00000000
[   19.722237] nand: nand_do_read_oob: from = 0x04880000, len = 64
[   19.728270] marvell-nfc pxa3xx-nand: 
[   19.728270] NDCR:  0x9d079fff
[   19.728270] NDCB0: 0x000d3000
[   19.728270] NDCB1: 0x91000000
[   19.728270] NDCB2: 0x00000000
[   19.728270] NDCB3: 0x00000000
[   19.747203] nand: nand_do_read_oob: from = 0x048a0000, len = 64
[   19.753406] marvell-nfc pxa3xx-nand: 
[   19.753406] NDCR:  0x9d079fff
[   19.753406] NDCB0: 0x000d3000
[   19.753406] NDCB1: 0x91400000
[   19.753406] NDCB2: 0x00000000
[   19.753406] NDCB3: 0x00000000
[   19.772354] nand: nand_do_read_oob: from = 0x048c0000, len = 64
[   19.778384] marvell-nfc pxa3xx-nand: 
[   19.778384] NDCR:  0x9d079fff
[   19.778384] NDCB0: 0x000d3000
[   19.778384] NDCB1: 0x91800000
[   19.778384] NDCB2: 0x00000000
[   19.778384] NDCB3: 0x00000000
[   19.797319] nand: nand_do_read_oob: from = 0x048e0000, len = 64
[   19.803522] marvell-nfc pxa3xx-nand: 
[   19.803522] NDCR:  0x9d079fff
[   19.803522] NDCB0: 0x000d3000
[   19.803522] NDCB1: 0x91c00000
[   19.803522] NDCB2: 0x00000000
[   19.803522] NDCB3: 0x00000000
[   19.822451] nand: nand_do_read_oob: from = 0x04900000, len = 64
[   19.828483] marvell-nfc pxa3xx-nand: 
[   19.828483] NDCR:  0x9d079fff
[   19.828483] NDCB0: 0x000d3000
[   19.828483] NDCB1: 0x92000000
[   19.828483] NDCB2: 0x00000000
[   19.828483] NDCB3: 0x00000000
[   19.847415] nand: nand_do_read_oob: from = 0x04920000, len = 64
[   19.853622] marvell-nfc pxa3xx-nand: 
[   19.853622] NDCR:  0x9d079fff
[   19.853622] NDCB0: 0x000d3000
[   19.853622] NDCB1: 0x92400000
[   19.853622] NDCB2: 0x00000000
[   19.853622] NDCB3: 0x00000000
[   19.872550] nand: nand_do_read_oob: from = 0x04940000, len = 64
[   19.878582] marvell-nfc pxa3xx-nand: 
[   19.878582] NDCR:  0x9d079fff
[   19.878582] NDCB0: 0x000d3000
[   19.878582] NDCB1: 0x92800000
[   19.878582] NDCB2: 0x00000000
[   19.878582] NDCB3: 0x00000000
[   19.897623] nand: nand_do_read_oob: from = 0x04960000, len = 64
[   19.903821] marvell-nfc pxa3xx-nand: 
[   19.903821] NDCR:  0x9d079fff
[   19.903821] NDCB0: 0x000d3000
[   19.903821] NDCB1: 0x92c00000
[   19.903821] NDCB2: 0x00000000
[   19.903821] NDCB3: 0x00000000
[   19.922750] nand: nand_do_read_oob: from = 0x04980000, len = 64
[   19.928953] marvell-nfc pxa3xx-nand: 
[   19.928953] NDCR:  0x9d079fff
[   19.928953] NDCB0: 0x000d3000
[   19.928953] NDCB1: 0x93000000
[   19.928953] NDCB2: 0x00000000
[   19.928953] NDCB3: 0x00000000
[   19.947873] nand: nand_do_read_oob: from = 0x049a0000, len = 64
[   19.954076] marvell-nfc pxa3xx-nand: 
[   19.954076] NDCR:  0x9d079fff
[   19.954076] NDCB0: 0x000d3000
[   19.954076] NDCB1: 0x93400000
[   19.954076] NDCB2: 0x00000000
[   19.954076] NDCB3: 0x00000000
[   19.973005] nand: nand_do_read_oob: from = 0x049c0000, len = 64
[   19.979207] marvell-nfc pxa3xx-nand: 
[   19.979207] NDCR:  0x9d079fff
[   19.979207] NDCB0: 0x000d3000
[   19.979207] NDCB1: 0x93800000
[   19.979207] NDCB2: 0x00000000
[   19.979207] NDCB3: 0x00000000
[   19.998127] nand: nand_do_read_oob: from = 0x049e0000, len = 64
[   20.004328] marvell-nfc pxa3xx-nand: 
[   20.004328] NDCR:  0x9d079fff
[   20.004328] NDCB0: 0x000d3000
[   20.004328] NDCB1: 0x93c00000
[   20.004328] NDCB2: 0x00000000
[   20.004328] NDCB3: 0x00000000
[   20.023259] nand: nand_do_read_oob: from = 0x04a00000, len = 64
[   20.029461] marvell-nfc pxa3xx-nand: 
[   20.029461] NDCR:  0x9d079fff
[   20.029461] NDCB0: 0x000d3000
[   20.029461] NDCB1: 0x94000000
[   20.029461] NDCB2: 0x00000000
[   20.029461] NDCB3: 0x00000000
[   20.048382] nand: nand_do_read_oob: from = 0x04a20000, len = 64
[   20.054584] marvell-nfc pxa3xx-nand: 
[   20.054584] NDCR:  0x9d079fff
[   20.054584] NDCB0: 0x000d3000
[   20.054584] NDCB1: 0x94400000
[   20.054584] NDCB2: 0x00000000
[   20.054584] NDCB3: 0x00000000
[   20.073513] nand: nand_do_read_oob: from = 0x04a40000, len = 64
[   20.079714] marvell-nfc pxa3xx-nand: 
[   20.079714] NDCR:  0x9d079fff
[   20.079714] NDCB0: 0x000d3000
[   20.079714] NDCB1: 0x94800000
[   20.079714] NDCB2: 0x00000000
[   20.079714] NDCB3: 0x00000000
[   20.099204] nand: nand_do_read_oob: from = 0x04a60000, len = 64
[   20.105249] marvell-nfc pxa3xx-nand: 
[   20.105249] NDCR:  0x9d079fff
[   20.105249] NDCB0: 0x000d3000
[   20.105249] NDCB1: 0x94c00000
[   20.105249] NDCB2: 0x00000000
[   20.105249] NDCB3: 0x00000000
[   20.124202] nand: nand_do_read_oob: from = 0x04a80000, len = 64
[   20.130406] marvell-nfc pxa3xx-nand: 
[   20.130406] NDCR:  0x9d079fff
[   20.130406] NDCB0: 0x000d3000
[   20.130406] NDCB1: 0x95000000
[   20.130406] NDCB2: 0x00000000
[   20.130406] NDCB3: 0x00000000
[   20.149339] nand: nand_do_read_oob: from = 0x04aa0000, len = 64
[   20.155367] marvell-nfc pxa3xx-nand: 
[   20.155367] NDCR:  0x9d079fff
[   20.155367] NDCB0: 0x000d3000
[   20.155367] NDCB1: 0x95400000
[   20.155367] NDCB2: 0x00000000
[   20.155367] NDCB3: 0x00000000
[   20.174300] nand: nand_do_read_oob: from = 0x04ac0000, len = 64
[   20.180506] marvell-nfc pxa3xx-nand: 
[   20.180506] NDCR:  0x9d079fff
[   20.180506] NDCB0: 0x000d3000
[   20.180506] NDCB1: 0x95800000
[   20.180506] NDCB2: 0x00000000
[   20.180506] NDCB3: 0x00000000
[   20.199435] nand: nand_do_read_oob: from = 0x04ae0000, len = 64
[   20.205466] marvell-nfc pxa3xx-nand: 
[   20.205466] NDCR:  0x9d079fff
[   20.205466] NDCB0: 0x000d3000
[   20.205466] NDCB1: 0x95c00000
[   20.205466] NDCB2: 0x00000000
[   20.205466] NDCB3: 0x00000000
[   20.224398] nand: nand_do_read_oob: from = 0x04b00000, len = 64
[   20.230595] marvell-nfc pxa3xx-nand: 
[   20.230595] NDCR:  0x9d079fff
[   20.230595] NDCB0: 0x000d3000
[   20.230595] NDCB1: 0x96000000
[   20.230595] NDCB2: 0x00000000
[   20.230595] NDCB3: 0x00000000
[   20.249526] nand: nand_do_read_oob: from = 0x04b20000, len = 64
[   20.255556] marvell-nfc pxa3xx-nand: 
[   20.255556] NDCR:  0x9d079fff
[   20.255556] NDCB0: 0x000d3000
[   20.255556] NDCB1: 0x96400000
[   20.255556] NDCB2: 0x00000000
[   20.255556] NDCB3: 0x00000000
[   20.274489] nand: nand_do_read_oob: from = 0x04b40000, len = 64
[   20.280694] marvell-nfc pxa3xx-nand: 
[   20.280694] NDCR:  0x9d079fff
[   20.280694] NDCB0: 0x000d3000
[   20.280694] NDCB1: 0x96800000
[   20.280694] NDCB2: 0x00000000
[   20.280694] NDCB3: 0x00000000
[   20.299624] nand: nand_do_read_oob: from = 0x04b60000, len = 64
[   20.305656] marvell-nfc pxa3xx-nand: 
[   20.305656] NDCR:  0x9d079fff
[   20.305656] NDCB0: 0x000d3000
[   20.305656] NDCB1: 0x96c00000
[   20.305656] NDCB2: 0x00000000
[   20.305656] NDCB3: 0x00000000
[   20.324591] nand: nand_do_read_oob: from = 0x04b80000, len = 64
[   20.330794] marvell-nfc pxa3xx-nand: 
[   20.330794] NDCR:  0x9d079fff
[   20.330794] NDCB0: 0x000d3000
[   20.330794] NDCB1: 0x97000000
[   20.330794] NDCB2: 0x00000000
[   20.330794] NDCB3: 0x00000000
[   20.349743] nand: nand_do_read_oob: from = 0x04ba0000, len = 64
[   20.355778] marvell-nfc pxa3xx-nand: 
[   20.355778] NDCR:  0x9d079fff
[   20.355778] NDCB0: 0x000d3000
[   20.355778] NDCB1: 0x97400000
[   20.355778] NDCB2: 0x00000000
[   20.355778] NDCB3: 0x00000000
[   20.374714] nand: nand_do_read_oob: from = 0x04bc0000, len = 64
[   20.380920] marvell-nfc pxa3xx-nand: 
[   20.380920] NDCR:  0x9d079fff
[   20.380920] NDCB0: 0x000d3000
[   20.380920] NDCB1: 0x97800000
[   20.380920] NDCB2: 0x00000000
[   20.380920] NDCB3: 0x00000000
[   20.399846] nand: nand_do_read_oob: from = 0x04be0000, len = 64
[   20.405878] marvell-nfc pxa3xx-nand: 
[   20.405878] NDCR:  0x9d079fff
[   20.405878] NDCB0: 0x000d3000
[   20.405878] NDCB1: 0x97c00000
[   20.405878] NDCB2: 0x00000000
[   20.405878] NDCB3: 0x00000000
[   20.424811] nand: nand_do_read_oob: from = 0x04c00000, len = 64
[   20.431017] marvell-nfc pxa3xx-nand: 
[   20.431017] NDCR:  0x9d079fff
[   20.431017] NDCB0: 0x000d3000
[   20.431017] NDCB1: 0x98000000
[   20.431017] NDCB2: 0x00000000
[   20.431017] NDCB3: 0x00000000
[   20.449946] nand: nand_do_read_oob: from = 0x04c20000, len = 64
[   20.455976] marvell-nfc pxa3xx-nand: 
[   20.455976] NDCR:  0x9d079fff
[   20.455976] NDCB0: 0x000d3000
[   20.455976] NDCB1: 0x98400000
[   20.455976] NDCB2: 0x00000000
[   20.455976] NDCB3: 0x00000000
[   20.474907] nand: nand_do_read_oob: from = 0x04c40000, len = 64
[   20.481105] marvell-nfc pxa3xx-nand: 
[   20.481105] NDCR:  0x9d079fff
[   20.481105] NDCB0: 0x000d3000
[   20.481105] NDCB1: 0x98800000
[   20.481105] NDCB2: 0x00000000
[   20.481105] NDCB3: 0x00000000
[   20.500035] nand: nand_do_read_oob: from = 0x04c60000, len = 64
[   20.506065] marvell-nfc pxa3xx-nand: 
[   20.506065] NDCR:  0x9d079fff
[   20.506065] NDCB0: 0x000d3000
[   20.506065] NDCB1: 0x98c00000
[   20.506065] NDCB2: 0x00000000
[   20.506065] NDCB3: 0x00000000
[   20.525001] nand: nand_do_read_oob: from = 0x04c80000, len = 64
[   20.531206] marvell-nfc pxa3xx-nand: 
[   20.531206] NDCR:  0x9d079fff
[   20.531206] NDCB0: 0x000d3000
[   20.531206] NDCB1: 0x99000000
[   20.531206] NDCB2: 0x00000000
[   20.531206] NDCB3: 0x00000000
[   20.550132] nand: nand_do_read_oob: from = 0x04ca0000, len = 64
[   20.556164] marvell-nfc pxa3xx-nand: 
[   20.556164] NDCR:  0x9d079fff
[   20.556164] NDCB0: 0x000d3000
[   20.556164] NDCB1: 0x99400000
[   20.556164] NDCB2: 0x00000000
[   20.556164] NDCB3: 0x00000000
[   20.575095] nand: nand_do_read_oob: from = 0x04cc0000, len = 64
[   20.581301] marvell-nfc pxa3xx-nand: 
[   20.581301] NDCR:  0x9d079fff
[   20.581301] NDCB0: 0x000d3000
[   20.581301] NDCB1: 0x99800000
[   20.581301] NDCB2: 0x00000000
[   20.581301] NDCB3: 0x00000000
[   20.600230] nand: nand_do_read_oob: from = 0x04ce0000, len = 64
[   20.606263] marvell-nfc pxa3xx-nand: 
[   20.606263] NDCR:  0x9d079fff
[   20.606263] NDCB0: 0x000d3000
[   20.606263] NDCB1: 0x99c00000
[   20.606263] NDCB2: 0x00000000
[   20.606263] NDCB3: 0x00000000
[   20.625194] nand: nand_do_read_oob: from = 0x04d00000, len = 64
[   20.631401] marvell-nfc pxa3xx-nand: 
[   20.631401] NDCR:  0x9d079fff
[   20.631401] NDCB0: 0x000d3000
[   20.631401] NDCB1: 0x9a000000
[   20.631401] NDCB2: 0x00000000
[   20.631401] NDCB3: 0x00000000
[   20.650328] nand: nand_do_read_oob: from = 0x04d20000, len = 64
[   20.656361] marvell-nfc pxa3xx-nand: 
[   20.656361] NDCR:  0x9d079fff
[   20.656361] NDCB0: 0x000d3000
[   20.656361] NDCB1: 0x9a400000
[   20.656361] NDCB2: 0x00000000
[   20.656361] NDCB3: 0x00000000
[   20.675294] nand: nand_do_read_oob: from = 0x04d40000, len = 64
[   20.681497] marvell-nfc pxa3xx-nand: 
[   20.681497] NDCR:  0x9d079fff
[   20.681497] NDCB0: 0x000d3000
[   20.681497] NDCB1: 0x9a800000
[   20.681497] NDCB2: 0x00000000
[   20.681497] NDCB3: 0x00000000
[   20.700426] nand: nand_do_read_oob: from = 0x04d60000, len = 64
[   20.706460] marvell-nfc pxa3xx-nand: 
[   20.706460] NDCR:  0x9d079fff
[   20.706460] NDCB0: 0x000d3000
[   20.706460] NDCB1: 0x9ac00000
[   20.706460] NDCB2: 0x00000000
[   20.706460] NDCB3: 0x00000000
[   20.725393] nand: nand_do_read_oob: from = 0x04d80000, len = 64
[   20.731598] marvell-nfc pxa3xx-nand: 
[   20.731598] NDCR:  0x9d079fff
[   20.731598] NDCB0: 0x000d3000
[   20.731598] NDCB1: 0x9b000000
[   20.731598] NDCB2: 0x00000000
[   20.731598] NDCB3: 0x00000000
[   20.750528] nand: nand_do_read_oob: from = 0x04da0000, len = 64
[   20.756559] marvell-nfc pxa3xx-nand: 
[   20.756559] NDCR:  0x9d079fff
[   20.756559] NDCB0: 0x000d3000
[   20.756559] NDCB1: 0x9b400000
[   20.756559] NDCB2: 0x00000000
[   20.756559] NDCB3: 0x00000000
[   20.775492] nand: nand_do_read_oob: from = 0x04dc0000, len = 64
[   20.781697] marvell-nfc pxa3xx-nand: 
[   20.781697] NDCR:  0x9d079fff
[   20.781697] NDCB0: 0x000d3000
[   20.781697] NDCB1: 0x9b800000
[   20.781697] NDCB2: 0x00000000
[   20.781697] NDCB3: 0x00000000
[   20.800624] nand: nand_do_read_oob: from = 0x04de0000, len = 64
[   20.806657] marvell-nfc pxa3xx-nand: 
[   20.806657] NDCR:  0x9d079fff
[   20.806657] NDCB0: 0x000d3000
[   20.806657] NDCB1: 0x9bc00000
[   20.806657] NDCB2: 0x00000000
[   20.806657] NDCB3: 0x00000000
[   20.825589] nand: nand_do_read_oob: from = 0x04e00000, len = 64
[   20.831793] marvell-nfc pxa3xx-nand: 
[   20.831793] NDCR:  0x9d079fff
[   20.831793] NDCB0: 0x000d3000
[   20.831793] NDCB1: 0x9c000000
[   20.831793] NDCB2: 0x00000000
[   20.831793] NDCB3: 0x00000000
[   20.850723] nand: nand_do_read_oob: from = 0x04e20000, len = 64
[   20.856756] marvell-nfc pxa3xx-nand: 
[   20.856756] NDCR:  0x9d079fff
[   20.856756] NDCB0: 0x000d3000
[   20.856756] NDCB1: 0x9c400000
[   20.856756] NDCB2: 0x00000000
[   20.856756] NDCB3: 0x00000000
[   20.875687] nand: nand_do_read_oob: from = 0x04e40000, len = 64
[   20.881891] marvell-nfc pxa3xx-nand: 
[   20.881891] NDCR:  0x9d079fff
[   20.881891] NDCB0: 0x000d3000
[   20.881891] NDCB1: 0x9c800000
[   20.881891] NDCB2: 0x00000000
[   20.881891] NDCB3: 0x00000000
[   20.900823] nand: nand_do_read_oob: from = 0x04e60000, len = 64
[   20.906854] marvell-nfc pxa3xx-nand: 
[   20.906854] NDCR:  0x9d079fff
[   20.906854] NDCB0: 0x000d3000
[   20.906854] NDCB1: 0x9cc00000
[   20.906854] NDCB2: 0x00000000
[   20.906854] NDCB3: 0x00000000
[   20.925784] nand: nand_do_read_oob: from = 0x04e80000, len = 64
[   20.931982] marvell-nfc pxa3xx-nand: 
[   20.931982] NDCR:  0x9d079fff
[   20.931982] NDCB0: 0x000d3000
[   20.931982] NDCB1: 0x9d000000
[   20.931982] NDCB2: 0x00000000
[   20.931982] NDCB3: 0x00000000
[   20.950911] nand: nand_do_read_oob: from = 0x04ea0000, len = 64
[   20.956944] marvell-nfc pxa3xx-nand: 
[   20.956944] NDCR:  0x9d079fff
[   20.956944] NDCB0: 0x000d3000
[   20.956944] NDCB1: 0x9d400000
[   20.956944] NDCB2: 0x00000000
[   20.956944] NDCB3: 0x00000000
[   20.975876] nand: nand_do_read_oob: from = 0x04ec0000, len = 64
[   20.982081] marvell-nfc pxa3xx-nand: 
[   20.982081] NDCR:  0x9d079fff
[   20.982081] NDCB0: 0x000d3000
[   20.982081] NDCB1: 0x9d800000
[   20.982081] NDCB2: 0x00000000
[   20.982081] NDCB3: 0x00000000
[   21.001026] nand: nand_do_read_oob: from = 0x04ee0000, len = 64
[   21.007059] marvell-nfc pxa3xx-nand: 
[   21.007059] NDCR:  0x9d079fff
[   21.007059] NDCB0: 0x000d3000
[   21.007059] NDCB1: 0x9dc00000
[   21.007059] NDCB2: 0x00000000
[   21.007059] NDCB3: 0x00000000
[   21.026003] nand: nand_do_read_oob: from = 0x04f00000, len = 64
[   21.032208] marvell-nfc pxa3xx-nand: 
[   21.032208] NDCR:  0x9d079fff
[   21.032208] NDCB0: 0x000d3000
[   21.032208] NDCB1: 0x9e000000
[   21.032208] NDCB2: 0x00000000
[   21.032208] NDCB3: 0x00000000
[   21.051135] nand: nand_do_read_oob: from = 0x04f20000, len = 64
[   21.057166] marvell-nfc pxa3xx-nand: 
[   21.057166] NDCR:  0x9d079fff
[   21.057166] NDCB0: 0x000d3000
[   21.057166] NDCB1: 0x9e400000
[   21.057166] NDCB2: 0x00000000
[   21.057166] NDCB3: 0x00000000
[   21.076100] nand: nand_do_read_oob: from = 0x04f40000, len = 64
[   21.082305] marvell-nfc pxa3xx-nand: 
[   21.082305] NDCR:  0x9d079fff
[   21.082305] NDCB0: 0x000d3000
[   21.082305] NDCB1: 0x9e800000
[   21.082305] NDCB2: 0x00000000
[   21.082305] NDCB3: 0x00000000
[   21.101232] nand: nand_do_read_oob: from = 0x04f60000, len = 64
[   21.107264] marvell-nfc pxa3xx-nand: 
[   21.107264] NDCR:  0x9d079fff
[   21.107264] NDCB0: 0x000d3000
[   21.107264] NDCB1: 0x9ec00000
[   21.107264] NDCB2: 0x00000000
[   21.107264] NDCB3: 0x00000000
[   21.126199] nand: nand_do_read_oob: from = 0x04f80000, len = 64
[   21.132404] marvell-nfc pxa3xx-nand: 
[   21.132404] NDCR:  0x9d079fff
[   21.132404] NDCB0: 0x000d3000
[   21.132404] NDCB1: 0x9f000000
[   21.132404] NDCB2: 0x00000000
[   21.132404] NDCB3: 0x00000000
[   21.151330] nand: nand_do_read_oob: from = 0x04fa0000, len = 64
[   21.157363] marvell-nfc pxa3xx-nand: 
[   21.157363] NDCR:  0x9d079fff
[   21.157363] NDCB0: 0x000d3000
[   21.157363] NDCB1: 0x9f400000
[   21.157363] NDCB2: 0x00000000
[   21.157363] NDCB3: 0x00000000
[   21.176296] nand: nand_do_read_oob: from = 0x04fc0000, len = 64
[   21.182504] marvell-nfc pxa3xx-nand: 
[   21.182504] NDCR:  0x9d079fff
[   21.182504] NDCB0: 0x000d3000
[   21.182504] NDCB1: 0x9f800000
[   21.182504] NDCB2: 0x00000000
[   21.182504] NDCB3: 0x00000000
[   21.201429] nand: nand_do_read_oob: from = 0x04fe0000, len = 64
[   21.207462] marvell-nfc pxa3xx-nand: 
[   21.207462] NDCR:  0x9d079fff
[   21.207462] NDCB0: 0x000d3000
[   21.207462] NDCB1: 0x9fc00000
[   21.207462] NDCB2: 0x00000000
[   21.207462] NDCB3: 0x00000000
[   21.226393] nand: nand_do_read_oob: from = 0x05000000, len = 64
[   21.232601] marvell-nfc pxa3xx-nand: 
[   21.232601] NDCR:  0x9d079fff
[   21.232601] NDCB0: 0x000d3000
[   21.232601] NDCB1: 0xa0000000
[   21.232601] NDCB2: 0x00000000
[   21.232601] NDCB3: 0x00000000
[   21.251528] nand: nand_do_read_oob: from = 0x05020000, len = 64
[   21.257559] marvell-nfc pxa3xx-nand: 
[   21.257559] NDCR:  0x9d079fff
[   21.257559] NDCB0: 0x000d3000
[   21.257559] NDCB1: 0xa0400000
[   21.257559] NDCB2: 0x00000000
[   21.257559] NDCB3: 0x00000000
[   21.276492] nand: nand_do_read_oob: from = 0x05040000, len = 64
[   21.282698] marvell-nfc pxa3xx-nand: 
[   21.282698] NDCR:  0x9d079fff
[   21.282698] NDCB0: 0x000d3000
[   21.282698] NDCB1: 0xa0800000
[   21.282698] NDCB2: 0x00000000
[   21.282698] NDCB3: 0x00000000
[   21.301627] nand: nand_do_read_oob: from = 0x05060000, len = 64
[   21.307657] marvell-nfc pxa3xx-nand: 
[   21.307657] NDCR:  0x9d079fff
[   21.307657] NDCB0: 0x000d3000
[   21.307657] NDCB1: 0xa0c00000
[   21.307657] NDCB2: 0x00000000
[   21.307657] NDCB3: 0x00000000
[   21.326591] nand: nand_do_read_oob: from = 0x05080000, len = 64
[   21.332799] marvell-nfc pxa3xx-nand: 
[   21.332799] NDCR:  0x9d079fff
[   21.332799] NDCB0: 0x000d3000
[   21.332799] NDCB1: 0xa1000000
[   21.332799] NDCB2: 0x00000000
[   21.332799] NDCB3: 0x00000000
[   21.351724] nand: nand_do_read_oob: from = 0x050a0000, len = 64
[   21.357757] marvell-nfc pxa3xx-nand: 
[   21.357757] NDCR:  0x9d079fff
[   21.357757] NDCB0: 0x000d3000
[   21.357757] NDCB1: 0xa1400000
[   21.357757] NDCB2: 0x00000000
[   21.357757] NDCB3: 0x00000000
[   21.376688] nand: nand_do_read_oob: from = 0x050c0000, len = 64
[   21.382895] marvell-nfc pxa3xx-nand: 
[   21.382895] NDCR:  0x9d079fff
[   21.382895] NDCB0: 0x000d3000
[   21.382895] NDCB1: 0xa1800000
[   21.382895] NDCB2: 0x00000000
[   21.382895] NDCB3: 0x00000000
[   21.401823] nand: nand_do_read_oob: from = 0x050e0000, len = 64
[   21.407856] marvell-nfc pxa3xx-nand: 
[   21.407856] NDCR:  0x9d079fff
[   21.407856] NDCB0: 0x000d3000
[   21.407856] NDCB1: 0xa1c00000
[   21.407856] NDCB2: 0x00000000
[   21.407856] NDCB3: 0x00000000
[   21.426787] nand: nand_do_read_oob: from = 0x05100000, len = 64
[   21.432994] marvell-nfc pxa3xx-nand: 
[   21.432994] NDCR:  0x9d079fff
[   21.432994] NDCB0: 0x000d3000
[   21.432994] NDCB1: 0xa2000000
[   21.432994] NDCB2: 0x00000000
[   21.432994] NDCB3: 0x00000000
[   21.451923] nand: nand_do_read_oob: from = 0x05120000, len = 64
[   21.457953] marvell-nfc pxa3xx-nand: 
[   21.457953] NDCR:  0x9d079fff
[   21.457953] NDCB0: 0x000d3000
[   21.457953] NDCB1: 0xa2400000
[   21.457953] NDCB2: 0x00000000
[   21.457953] NDCB3: 0x00000000
[   21.476885] nand: nand_do_read_oob: from = 0x05140000, len = 64
[   21.483093] marvell-nfc pxa3xx-nand: 
[   21.483093] NDCR:  0x9d079fff
[   21.483093] NDCB0: 0x000d3000
[   21.483093] NDCB1: 0xa2800000
[   21.483093] NDCB2: 0x00000000
[   21.483093] NDCB3: 0x00000000
[   21.502021] nand: nand_do_read_oob: from = 0x05160000, len = 64
[   21.508052] marvell-nfc pxa3xx-nand: 
[   21.508052] NDCR:  0x9d079fff
[   21.508052] NDCB0: 0x000d3000
[   21.508052] NDCB1: 0xa2c00000
[   21.508052] NDCB2: 0x00000000
[   21.508052] NDCB3: 0x00000000
[   21.526984] nand: nand_do_read_oob: from = 0x05180000, len = 64
[   21.533192] marvell-nfc pxa3xx-nand: 
[   21.533192] NDCR:  0x9d079fff
[   21.533192] NDCB0: 0x000d3000
[   21.533192] NDCB1: 0xa3000000
[   21.533192] NDCB2: 0x00000000
[   21.533192] NDCB3: 0x00000000
[   21.552119] nand: nand_do_read_oob: from = 0x051a0000, len = 64
[   21.558151] marvell-nfc pxa3xx-nand: 
[   21.558151] NDCR:  0x9d079fff
[   21.558151] NDCB0: 0x000d3000
[   21.558151] NDCB1: 0xa3400000
[   21.558151] NDCB2: 0x00000000
[   21.558151] NDCB3: 0x00000000
[   21.577083] nand: nand_do_read_oob: from = 0x051c0000, len = 64
[   21.583289] marvell-nfc pxa3xx-nand: 
[   21.583289] NDCR:  0x9d079fff
[   21.583289] NDCB0: 0x000d3000
[   21.583289] NDCB1: 0xa3800000
[   21.583289] NDCB2: 0x00000000
[   21.583289] NDCB3: 0x00000000
[   21.602219] nand: nand_do_read_oob: from = 0x051e0000, len = 64
[   21.608249] marvell-nfc pxa3xx-nand: 
[   21.608249] NDCR:  0x9d079fff
[   21.608249] NDCB0: 0x000d3000
[   21.608249] NDCB1: 0xa3c00000
[   21.608249] NDCB2: 0x00000000
[   21.608249] NDCB3: 0x00000000
[   21.627182] nand: nand_do_read_oob: from = 0x05200000, len = 64
[   21.633406] marvell-nfc pxa3xx-nand: 
[   21.633406] NDCR:  0x9d079fff
[   21.633406] NDCB0: 0x000d3000
[   21.633406] NDCB1: 0xa4000000
[   21.633406] NDCB2: 0x00000000
[   21.633406] NDCB3: 0x00000000
[   21.652336] nand: nand_do_read_oob: from = 0x05220000, len = 64
[   21.658364] marvell-nfc pxa3xx-nand: 
[   21.658364] NDCR:  0x9d079fff
[   21.658364] NDCB0: 0x000d3000
[   21.658364] NDCB1: 0xa4400000
[   21.658364] NDCB2: 0x00000000
[   21.658364] NDCB3: 0x00000000
[   21.677298] nand: nand_do_read_oob: from = 0x05240000, len = 64
[   21.683503] marvell-nfc pxa3xx-nand: 
[   21.683503] NDCR:  0x9d079fff
[   21.683503] NDCB0: 0x000d3000
[   21.683503] NDCB1: 0xa4800000
[   21.683503] NDCB2: 0x00000000
[   21.683503] NDCB3: 0x00000000
[   21.702432] nand: nand_do_read_oob: from = 0x05260000, len = 64
[   21.708462] marvell-nfc pxa3xx-nand: 
[   21.708462] NDCR:  0x9d079fff
[   21.708462] NDCB0: 0x000d3000
[   21.708462] NDCB1: 0xa4c00000
[   21.708462] NDCB2: 0x00000000
[   21.708462] NDCB3: 0x00000000
[   21.727395] nand: nand_do_read_oob: from = 0x05280000, len = 64
[   21.733601] marvell-nfc pxa3xx-nand: 
[   21.733601] NDCR:  0x9d079fff
[   21.733601] NDCB0: 0x000d3000
[   21.733601] NDCB1: 0xa5000000
[   21.733601] NDCB2: 0x00000000
[   21.733601] NDCB3: 0x00000000
[   21.752532] nand: nand_do_read_oob: from = 0x052a0000, len = 64
[   21.758561] marvell-nfc pxa3xx-nand: 
[   21.758561] NDCR:  0x9d079fff
[   21.758561] NDCB0: 0x000d3000
[   21.758561] NDCB1: 0xa5400000
[   21.758561] NDCB2: 0x00000000
[   21.758561] NDCB3: 0x00000000
[   21.777495] nand: nand_do_read_oob: from = 0x052c0000, len = 64
[   21.783700] marvell-nfc pxa3xx-nand: 
[   21.783700] NDCR:  0x9d079fff
[   21.783700] NDCB0: 0x000d3000
[   21.783700] NDCB1: 0xa5800000
[   21.783700] NDCB2: 0x00000000
[   21.783700] NDCB3: 0x00000000
[   21.802630] nand: nand_do_read_oob: from = 0x052e0000, len = 64
[   21.808831] marvell-nfc pxa3xx-nand: 
[   21.808831] NDCR:  0x9d079fff
[   21.808831] NDCB0: 0x000d3000
[   21.808831] NDCB1: 0xa5c00000
[   21.808831] NDCB2: 0x00000000
[   21.808831] NDCB3: 0x00000000
[   21.827742] nand: nand_do_read_oob: from = 0x05300000, len = 64
[   21.833943] marvell-nfc pxa3xx-nand: 
[   21.833943] NDCR:  0x9d079fff
[   21.833943] NDCB0: 0x000d3000
[   21.833943] NDCB1: 0xa6000000
[   21.833943] NDCB2: 0x00000000
[   21.833943] NDCB3: 0x00000000
[   21.852875] nand: nand_do_read_oob: from = 0x05320000, len = 64
[   21.859075] marvell-nfc pxa3xx-nand: 
[   21.859075] NDCR:  0x9d079fff
[   21.859075] NDCB0: 0x000d3000
[   21.859075] NDCB1: 0xa6400000
[   21.859075] NDCB2: 0x00000000
[   21.859075] NDCB3: 0x00000000
[   21.877997] nand: nand_do_read_oob: from = 0x05340000, len = 64
[   21.884198] marvell-nfc pxa3xx-nand: 
[   21.884198] NDCR:  0x9d079fff
[   21.884198] NDCB0: 0x000d3000
[   21.884198] NDCB1: 0xa6800000
[   21.884198] NDCB2: 0x00000000
[   21.884198] NDCB3: 0x00000000
[   21.903130] nand: nand_do_read_oob: from = 0x05360000, len = 64
[   21.909328] marvell-nfc pxa3xx-nand: 
[   21.909328] NDCR:  0x9d079fff
[   21.909328] NDCB0: 0x000d3000
[   21.909328] NDCB1: 0xa6c00000
[   21.909328] NDCB2: 0x00000000
[   21.909328] NDCB3: 0x00000000
[   21.928250] nand: nand_do_read_oob: from = 0x05380000, len = 64
[   21.934453] marvell-nfc pxa3xx-nand: 
[   21.934453] NDCR:  0x9d079fff
[   21.934453] NDCB0: 0x000d3000
[   21.934453] NDCB1: 0xa7000000
[   21.934453] NDCB2: 0x00000000
[   21.934453] NDCB3: 0x00000000
[   21.953384] nand: nand_do_read_oob: from = 0x053a0000, len = 64
[   21.959583] marvell-nfc pxa3xx-nand: 
[   21.959583] NDCR:  0x9d079fff
[   21.959583] NDCB0: 0x000d3000
[   21.959583] NDCB1: 0xa7400000
[   21.959583] NDCB2: 0x00000000
[   21.959583] NDCB3: 0x00000000
[   21.978503] nand: nand_do_read_oob: from = 0x053c0000, len = 64
[   21.984706] marvell-nfc pxa3xx-nand: 
[   21.984706] NDCR:  0x9d079fff
[   21.984706] NDCB0: 0x000d3000
[   21.984706] NDCB1: 0xa7800000
[   21.984706] NDCB2: 0x00000000
[   21.984706] NDCB3: 0x00000000
[   22.003635] nand: nand_do_read_oob: from = 0x053e0000, len = 64
[   22.009842] marvell-nfc pxa3xx-nand: 
[   22.009842] NDCR:  0x9d079fff
[   22.009842] NDCB0: 0x000d3000
[   22.009842] NDCB1: 0xa7c00000
[   22.009842] NDCB2: 0x00000000
[   22.009842] NDCB3: 0x00000000
[   22.028841] nand: nand_do_read_oob: from = 0x05400000, len = 64
[   22.034878] marvell-nfc pxa3xx-nand: 
[   22.034878] NDCR:  0x9d079fff
[   22.034878] NDCB0: 0x000d3000
[   22.034878] NDCB1: 0xa8000000
[   22.034878] NDCB2: 0x00000000
[   22.034878] NDCB3: 0x00000000
[   22.053811] nand: nand_do_read_oob: from = 0x05420000, len = 64
[   22.060013] marvell-nfc pxa3xx-nand: 
[   22.060013] NDCR:  0x9d079fff
[   22.060013] NDCB0: 0x000d3000
[   22.060013] NDCB1: 0xa8400000
[   22.060013] NDCB2: 0x00000000
[   22.060013] NDCB3: 0x00000000
[   22.079132] nand: nand_do_read_oob: from = 0x05440000, len = 64
[   22.085172] marvell-nfc pxa3xx-nand: 
[   22.085172] NDCR:  0x9d079fff
[   22.085172] NDCB0: 0x000d3000
[   22.085172] NDCB1: 0xa8800000
[   22.085172] NDCB2: 0x00000000
[   22.085172] NDCB3: 0x00000000
[   22.104450] nand: nand_do_read_oob: from = 0x05460000, len = 64
[   22.110686] marvell-nfc pxa3xx-nand: 
[   22.110686] NDCR:  0x9d079fff
[   22.110686] NDCB0: 0x000d3000
[   22.110686] NDCB1: 0xa8c00000
[   22.110686] NDCB2: 0x00000000
[   22.110686] NDCB3: 0x00000000
[   22.129626] nand: nand_do_read_oob: from = 0x05480000, len = 64
[   22.135656] marvell-nfc pxa3xx-nand: 
[   22.135656] NDCR:  0x9d079fff
[   22.135656] NDCB0: 0x000d3000
[   22.135656] NDCB1: 0xa9000000
[   22.135656] NDCB2: 0x00000000
[   22.135656] NDCB3: 0x00000000
[   22.154590] nand: nand_do_read_oob: from = 0x054a0000, len = 64
[   22.160794] marvell-nfc pxa3xx-nand: 
[   22.160794] NDCR:  0x9d079fff
[   22.160794] NDCB0: 0x000d3000
[   22.160794] NDCB1: 0xa9400000
[   22.160794] NDCB2: 0x00000000
[   22.160794] NDCB3: 0x00000000
[   22.179727] nand: nand_do_read_oob: from = 0x054c0000, len = 64
[   22.185755] marvell-nfc pxa3xx-nand: 
[   22.185755] NDCR:  0x9d079fff
[   22.185755] NDCB0: 0x000d3000
[   22.185755] NDCB1: 0xa9800000
[   22.185755] NDCB2: 0x00000000
[   22.185755] NDCB3: 0x00000000
[   22.204688] nand: nand_do_read_oob: from = 0x054e0000, len = 64
[   22.210917] marvell-nfc pxa3xx-nand: 
[   22.210917] NDCR:  0x9d079fff
[   22.210917] NDCB0: 0x000d3000
[   22.210917] NDCB1: 0xa9c00000
[   22.210917] NDCB2: 0x00000000
[   22.210917] NDCB3: 0x00000000
[   22.229850] nand: nand_do_read_oob: from = 0x05500000, len = 64
[   22.235880] marvell-nfc pxa3xx-nand: 
[   22.235880] NDCR:  0x9d079fff
[   22.235880] NDCB0: 0x000d3000
[   22.235880] NDCB1: 0xaa000000
[   22.235880] NDCB2: 0x00000000
[   22.235880] NDCB3: 0x00000000
[   22.254813] nand: nand_do_read_oob: from = 0x05520000, len = 64
[   22.261019] marvell-nfc pxa3xx-nand: 
[   22.261019] NDCR:  0x9d079fff
[   22.261019] NDCB0: 0x000d3000
[   22.261019] NDCB1: 0xaa400000
[   22.261019] NDCB2: 0x00000000
[   22.261019] NDCB3: 0x00000000
[   22.279948] nand: nand_do_read_oob: from = 0x05540000, len = 64
[   22.285978] marvell-nfc pxa3xx-nand: 
[   22.285978] NDCR:  0x9d079fff
[   22.285978] NDCB0: 0x000d3000
[   22.285978] NDCB1: 0xaa800000
[   22.285978] NDCB2: 0x00000000
[   22.285978] NDCB3: 0x00000000
[   22.304912] nand: nand_do_read_oob: from = 0x05560000, len = 64
[   22.311116] marvell-nfc pxa3xx-nand: 
[   22.311116] NDCR:  0x9d079fff
[   22.311116] NDCB0: 0x000d3000
[   22.311116] NDCB1: 0xaac00000
[   22.311116] NDCB2: 0x00000000
[   22.311116] NDCB3: 0x00000000
[   22.330047] nand: nand_do_read_oob: from = 0x05580000, len = 64
[   22.336076] marvell-nfc pxa3xx-nand: 
[   22.336076] NDCR:  0x9d079fff
[   22.336076] NDCB0: 0x000d3000
[   22.336076] NDCB1: 0xab000000
[   22.336076] NDCB2: 0x00000000
[   22.336076] NDCB3: 0x00000000
[   22.355012] nand: nand_do_read_oob: from = 0x055a0000, len = 64
[   22.361214] marvell-nfc pxa3xx-nand: 
[   22.361214] NDCR:  0x9d079fff
[   22.361214] NDCB0: 0x000d3000
[   22.361214] NDCB1: 0xab400000
[   22.361214] NDCB2: 0x00000000
[   22.361214] NDCB3: 0x00000000
[   22.380143] nand: nand_do_read_oob: from = 0x055c0000, len = 64
[   22.386175] marvell-nfc pxa3xx-nand: 
[   22.386175] NDCR:  0x9d079fff
[   22.386175] NDCB0: 0x000d3000
[   22.386175] NDCB1: 0xab800000
[   22.386175] NDCB2: 0x00000000
[   22.386175] NDCB3: 0x00000000
[   22.405106] nand: nand_do_read_oob: from = 0x055e0000, len = 64
[   22.411303] marvell-nfc pxa3xx-nand: 
[   22.411303] NDCR:  0x9d079fff
[   22.411303] NDCB0: 0x000d3000
[   22.411303] NDCB1: 0xabc00000
[   22.411303] NDCB2: 0x00000000
[   22.411303] NDCB3: 0x00000000
[   22.430224] nand: nand_do_read_oob: from = 0x05600000, len = 64
[   22.436256] marvell-nfc pxa3xx-nand: 
[   22.436256] NDCR:  0x9d079fff
[   22.436256] NDCB0: 0x000d3000
[   22.436256] NDCB1: 0xac000000
[   22.436256] NDCB2: 0x00000000
[   22.436256] NDCB3: 0x00000000
[   22.455189] nand: nand_do_read_oob: from = 0x05620000, len = 64
[   22.461395] marvell-nfc pxa3xx-nand: 
[   22.461395] NDCR:  0x9d079fff
[   22.461395] NDCB0: 0x000d3000
[   22.461395] NDCB1: 0xac400000
[   22.461395] NDCB2: 0x00000000
[   22.461395] NDCB3: 0x00000000
[   22.480324] nand: nand_do_read_oob: from = 0x05640000, len = 64
[   22.486355] marvell-nfc pxa3xx-nand: 
[   22.486355] NDCR:  0x9d079fff
[   22.486355] NDCB0: 0x000d3000
[   22.486355] NDCB1: 0xac800000
[   22.486355] NDCB2: 0x00000000
[   22.486355] NDCB3: 0x00000000
[   22.505288] nand: nand_do_read_oob: from = 0x05660000, len = 64
[   22.511493] marvell-nfc pxa3xx-nand: 
[   22.511493] NDCR:  0x9d079fff
[   22.511493] NDCB0: 0x000d3000
[   22.511493] NDCB1: 0xacc00000
[   22.511493] NDCB2: 0x00000000
[   22.511493] NDCB3: 0x00000000
[   22.530421] nand: nand_do_read_oob: from = 0x05680000, len = 64
[   22.536453] marvell-nfc pxa3xx-nand: 
[   22.536453] NDCR:  0x9d079fff
[   22.536453] NDCB0: 0x000d3000
[   22.536453] NDCB1: 0xad000000
[   22.536453] NDCB2: 0x00000000
[   22.536453] NDCB3: 0x00000000
[   22.555387] nand: nand_do_read_oob: from = 0x056a0000, len = 64
[   22.561591] marvell-nfc pxa3xx-nand: 
[   22.561591] NDCR:  0x9d079fff
[   22.561591] NDCB0: 0x000d3000
[   22.561591] NDCB1: 0xad400000
[   22.561591] NDCB2: 0x00000000
[   22.561591] NDCB3: 0x00000000
[   22.580520] nand: nand_do_read_oob: from = 0x056c0000, len = 64
[   22.586552] marvell-nfc pxa3xx-nand: 
[   22.586552] NDCR:  0x9d079fff
[   22.586552] NDCB0: 0x000d3000
[   22.586552] NDCB1: 0xad800000
[   22.586552] NDCB2: 0x00000000
[   22.586552] NDCB3: 0x00000000
[   22.605486] nand: nand_do_read_oob: from = 0x056e0000, len = 64
[   22.611689] marvell-nfc pxa3xx-nand: 
[   22.611689] NDCR:  0x9d079fff
[   22.611689] NDCB0: 0x000d3000
[   22.611689] NDCB1: 0xadc00000
[   22.611689] NDCB2: 0x00000000
[   22.611689] NDCB3: 0x00000000
[   22.630620] nand: nand_do_read_oob: from = 0x05700000, len = 64
[   22.636650] marvell-nfc pxa3xx-nand: 
[   22.636650] NDCR:  0x9d079fff
[   22.636650] NDCB0: 0x000d3000
[   22.636650] NDCB1: 0xae000000
[   22.636650] NDCB2: 0x00000000
[   22.636650] NDCB3: 0x00000000
[   22.655583] nand: nand_do_read_oob: from = 0x05720000, len = 64
[   22.661789] marvell-nfc pxa3xx-nand: 
[   22.661789] NDCR:  0x9d079fff
[   22.661789] NDCB0: 0x000d3000
[   22.661789] NDCB1: 0xae400000
[   22.661789] NDCB2: 0x00000000
[   22.661789] NDCB3: 0x00000000
[   22.680718] nand: nand_do_read_oob: from = 0x05740000, len = 64
[   22.686748] marvell-nfc pxa3xx-nand: 
[   22.686748] NDCR:  0x9d079fff
[   22.686748] NDCB0: 0x000d3000
[   22.686748] NDCB1: 0xae800000
[   22.686748] NDCB2: 0x00000000
[   22.686748] NDCB3: 0x00000000
[   22.705687] nand: nand_do_read_oob: from = 0x05760000, len = 64
[   22.711887] marvell-nfc pxa3xx-nand: 
[   22.711887] NDCR:  0x9d079fff
[   22.711887] NDCB0: 0x000d3000
[   22.711887] NDCB1: 0xaec00000
[   22.711887] NDCB2: 0x00000000
[   22.711887] NDCB3: 0x00000000
[   22.730816] nand: nand_do_read_oob: from = 0x05780000, len = 64
[   22.736846] marvell-nfc pxa3xx-nand: 
[   22.736846] NDCR:  0x9d079fff
[   22.736846] NDCB0: 0x000d3000
[   22.736846] NDCB1: 0xaf000000
[   22.736846] NDCB2: 0x00000000
[   22.736846] NDCB3: 0x00000000
[   22.755779] nand: nand_do_read_oob: from = 0x057a0000, len = 64
[   22.761985] marvell-nfc pxa3xx-nand: 
[   22.761985] NDCR:  0x9d079fff
[   22.761985] NDCB0: 0x000d3000
[   22.761985] NDCB1: 0xaf400000
[   22.761985] NDCB2: 0x00000000
[   22.761985] NDCB3: 0x00000000
[   22.780915] nand: nand_do_read_oob: from = 0x057c0000, len = 64
[   22.786945] marvell-nfc pxa3xx-nand: 
[   22.786945] NDCR:  0x9d079fff
[   22.786945] NDCB0: 0x000d3000
[   22.786945] NDCB1: 0xaf800000
[   22.786945] NDCB2: 0x00000000
[   22.786945] NDCB3: 0x00000000
[   22.805881] nand: nand_do_read_oob: from = 0x057e0000, len = 64
[   22.812084] marvell-nfc pxa3xx-nand: 
[   22.812084] NDCR:  0x9d079fff
[   22.812084] NDCB0: 0x000d3000
[   22.812084] NDCB1: 0xafc00000
[   22.812084] NDCB2: 0x00000000
[   22.812084] NDCB3: 0x00000000
[   22.831015] nand: nand_do_read_oob: from = 0x05800000, len = 64
[   22.837043] marvell-nfc pxa3xx-nand: 
[   22.837043] NDCR:  0x9d079fff
[   22.837043] NDCB0: 0x000d3000
[   22.837043] NDCB1: 0xb0000000
[   22.837043] NDCB2: 0x00000000
[   22.837043] NDCB3: 0x00000000
[   22.855995] nand: nand_do_read_oob: from = 0x05820000, len = 64
[   22.862200] marvell-nfc pxa3xx-nand: 
[   22.862200] NDCR:  0x9d079fff
[   22.862200] NDCB0: 0x000d3000
[   22.862200] NDCB1: 0xb0400000
[   22.862200] NDCB2: 0x00000000
[   22.862200] NDCB3: 0x00000000
[   22.881131] nand: nand_do_read_oob: from = 0x05840000, len = 64
[   22.887159] marvell-nfc pxa3xx-nand: 
[   22.887159] NDCR:  0x9d079fff
[   22.887159] NDCB0: 0x000d3000
[   22.887159] NDCB1: 0xb0800000
[   22.887159] NDCB2: 0x00000000
[   22.887159] NDCB3: 0x00000000
[   22.906094] nand: nand_do_read_oob: from = 0x05860000, len = 64
[   22.912298] marvell-nfc pxa3xx-nand: 
[   22.912298] NDCR:  0x9d079fff
[   22.912298] NDCB0: 0x000d3000
[   22.912298] NDCB1: 0xb0c00000
[   22.912298] NDCB2: 0x00000000
[   22.912298] NDCB3: 0x00000000
[   22.931228] nand: nand_do_read_oob: from = 0x05880000, len = 64
[   22.937259] marvell-nfc pxa3xx-nand: 
[   22.937259] NDCR:  0x9d079fff
[   22.937259] NDCB0: 0x000d3000
[   22.937259] NDCB1: 0xb1000000
[   22.937259] NDCB2: 0x00000000
[   22.937259] NDCB3: 0x00000000
[   22.956190] nand: nand_do_read_oob: from = 0x058a0000, len = 64
[   22.962397] marvell-nfc pxa3xx-nand: 
[   22.962397] NDCR:  0x9d079fff
[   22.962397] NDCB0: 0x000d3000
[   22.962397] NDCB1: 0xb1400000
[   22.962397] NDCB2: 0x00000000
[   22.962397] NDCB3: 0x00000000
[   22.981325] nand: nand_do_read_oob: from = 0x058c0000, len = 64
[   22.987356] marvell-nfc pxa3xx-nand: 
[   22.987356] NDCR:  0x9d079fff
[   22.987356] NDCB0: 0x000d3000
[   22.987356] NDCB1: 0xb1800000
[   22.987356] NDCB2: 0x00000000
[   22.987356] NDCB3: 0x00000000
[   23.006291] nand: nand_do_read_oob: from = 0x058e0000, len = 64
[   23.012504] marvell-nfc pxa3xx-nand: 
[   23.012504] NDCR:  0x9d079fff
[   23.012504] NDCB0: 0x000d3000
[   23.012504] NDCB1: 0xb1c00000
[   23.012504] NDCB2: 0x00000000
[   23.012504] NDCB3: 0x00000000
[   23.031434] nand: nand_do_read_oob: from = 0x05900000, len = 64
[   23.037464] marvell-nfc pxa3xx-nand: 
[   23.037464] NDCR:  0x9d079fff
[   23.037464] NDCB0: 0x000d3000
[   23.037464] NDCB1: 0xb2000000
[   23.037464] NDCB2: 0x00000000
[   23.037464] NDCB3: 0x00000000
[   23.056397] nand: nand_do_read_oob: from = 0x05920000, len = 64
[   23.062602] marvell-nfc pxa3xx-nand: 
[   23.062602] NDCR:  0x9d079fff
[   23.062602] NDCB0: 0x000d3000
[   23.062602] NDCB1: 0xb2400000
[   23.062602] NDCB2: 0x00000000
[   23.062602] NDCB3: 0x00000000
[   23.081530] nand: nand_do_read_oob: from = 0x05940000, len = 64
[   23.087563] marvell-nfc pxa3xx-nand: 
[   23.087563] NDCR:  0x9d079fff
[   23.087563] NDCB0: 0x000d3000
[   23.087563] NDCB1: 0xb2800000
[   23.087563] NDCB2: 0x00000000
[   23.087563] NDCB3: 0x00000000
[   23.106495] nand: nand_do_read_oob: from = 0x05960000, len = 64
[   23.112698] marvell-nfc pxa3xx-nand: 
[   23.112698] NDCR:  0x9d079fff
[   23.112698] NDCB0: 0x000d3000
[   23.112698] NDCB1: 0xb2c00000
[   23.112698] NDCB2: 0x00000000
[   23.112698] NDCB3: 0x00000000
[   23.131629] nand: nand_do_read_oob: from = 0x05980000, len = 64
[   23.137661] marvell-nfc pxa3xx-nand: 
[   23.137661] NDCR:  0x9d079fff
[   23.137661] NDCB0: 0x000d3000
[   23.137661] NDCB1: 0xb3000000
[   23.137661] NDCB2: 0x00000000
[   23.137661] NDCB3: 0x00000000
[   23.156593] nand: nand_do_read_oob: from = 0x059a0000, len = 64
[   23.162801] marvell-nfc pxa3xx-nand: 
[   23.162801] NDCR:  0x9d079fff
[   23.162801] NDCB0: 0x000d3000
[   23.162801] NDCB1: 0xb3400000
[   23.162801] NDCB2: 0x00000000
[   23.162801] NDCB3: 0x00000000
[   23.181727] nand: nand_do_read_oob: from = 0x059c0000, len = 64
[   23.187758] marvell-nfc pxa3xx-nand: 
[   23.187758] NDCR:  0x9d079fff
[   23.187758] NDCB0: 0x000d3000
[   23.187758] NDCB1: 0xb3800000
[   23.187758] NDCB2: 0x00000000
[   23.187758] NDCB3: 0x00000000
[   23.206692] nand: nand_do_read_oob: from = 0x059e0000, len = 64
[   23.212897] marvell-nfc pxa3xx-nand: 
[   23.212897] NDCR:  0x9d079fff
[   23.212897] NDCB0: 0x000d3000
[   23.212897] NDCB1: 0xb3c00000
[   23.212897] NDCB2: 0x00000000
[   23.212897] NDCB3: 0x00000000
[   23.231825] nand: nand_do_read_oob: from = 0x05a00000, len = 64
[   23.237859] marvell-nfc pxa3xx-nand: 
[   23.237859] NDCR:  0x9d079fff
[   23.237859] NDCB0: 0x000d3000
[   23.237859] NDCB1: 0xb4000000
[   23.237859] NDCB2: 0x00000000
[   23.237859] NDCB3: 0x00000000
[   23.256787] nand: nand_do_read_oob: from = 0x05a20000, len = 64
[   23.262986] marvell-nfc pxa3xx-nand: 
[   23.262986] NDCR:  0x9d079fff
[   23.262986] NDCB0: 0x000d3000
[   23.262986] NDCB1: 0xb4400000
[   23.262986] NDCB2: 0x00000000
[   23.262986] NDCB3: 0x00000000
[   23.281915] nand: nand_do_read_oob: from = 0x05a40000, len = 64
[   23.287948] marvell-nfc pxa3xx-nand: 
[   23.287948] NDCR:  0x9d079fff
[   23.287948] NDCB0: 0x000d3000
[   23.287948] NDCB1: 0xb4800000
[   23.287948] NDCB2: 0x00000000
[   23.287948] NDCB3: 0x00000000
[   23.306880] nand: nand_do_read_oob: from = 0x05a60000, len = 64
[   23.313086] marvell-nfc pxa3xx-nand: 
[   23.313086] NDCR:  0x9d079fff
[   23.313086] NDCB0: 0x000d3000
[   23.313086] NDCB1: 0xb4c00000
[   23.313086] NDCB2: 0x00000000
[   23.313086] NDCB3: 0x00000000
[   23.332015] nand: nand_do_read_oob: from = 0x05a80000, len = 64
[   23.338046] marvell-nfc pxa3xx-nand: 
[   23.338046] NDCR:  0x9d079fff
[   23.338046] NDCB0: 0x000d3000
[   23.338046] NDCB1: 0xb5000000
[   23.338046] NDCB2: 0x00000000
[   23.338046] NDCB3: 0x00000000
[   23.356978] nand: nand_do_read_oob: from = 0x05aa0000, len = 64
[   23.363184] marvell-nfc pxa3xx-nand: 
[   23.363184] NDCR:  0x9d079fff
[   23.363184] NDCB0: 0x000d3000
[   23.363184] NDCB1: 0xb5400000
[   23.363184] NDCB2: 0x00000000
[   23.363184] NDCB3: 0x00000000
[   23.382113] nand: nand_do_read_oob: from = 0x05ac0000, len = 64
[   23.388145] marvell-nfc pxa3xx-nand: 
[   23.388145] NDCR:  0x9d079fff
[   23.388145] NDCB0: 0x000d3000
[   23.388145] NDCB1: 0xb5800000
[   23.388145] NDCB2: 0x00000000
[   23.388145] NDCB3: 0x00000000
[   23.407075] nand: nand_do_read_oob: from = 0x05ae0000, len = 64
[   23.413274] marvell-nfc pxa3xx-nand: 
[   23.413274] NDCR:  0x9d079fff
[   23.413274] NDCB0: 0x000d3000
[   23.413274] NDCB1: 0xb5c00000
[   23.413274] NDCB2: 0x00000000
[   23.413274] NDCB3: 0x00000000
[   23.432201] nand: nand_do_read_oob: from = 0x05b00000, len = 64
[   23.438234] marvell-nfc pxa3xx-nand: 
[   23.438234] NDCR:  0x9d079fff
[   23.438234] NDCB0: 0x000d3000
[   23.438234] NDCB1: 0xb6000000
[   23.438234] NDCB2: 0x00000000
[   23.438234] NDCB3: 0x00000000
[   23.457167] nand: nand_do_read_oob: from = 0x05b20000, len = 64
[   23.463372] marvell-nfc pxa3xx-nand: 
[   23.463372] NDCR:  0x9d079fff
[   23.463372] NDCB0: 0x000d3000
[   23.463372] NDCB1: 0xb6400000
[   23.463372] NDCB2: 0x00000000
[   23.463372] NDCB3: 0x00000000
[   23.482301] nand: nand_do_read_oob: from = 0x05b40000, len = 64
[   23.488332] marvell-nfc pxa3xx-nand: 
[   23.488332] NDCR:  0x9d079fff
[   23.488332] NDCB0: 0x000d3000
[   23.488332] NDCB1: 0xb6800000
[   23.488332] NDCB2: 0x00000000
[   23.488332] NDCB3: 0x00000000
[   23.507285] nand: nand_do_read_oob: from = 0x05b60000, len = 64
[   23.513489] marvell-nfc pxa3xx-nand: 
[   23.513489] NDCR:  0x9d079fff
[   23.513489] NDCB0: 0x000d3000
[   23.513489] NDCB1: 0xb6c00000
[   23.513489] NDCB2: 0x00000000
[   23.513489] NDCB3: 0x00000000
[   23.532416] nand: nand_do_read_oob: from = 0x05b80000, len = 64
[   23.538449] marvell-nfc pxa3xx-nand: 
[   23.538449] NDCR:  0x9d079fff
[   23.538449] NDCB0: 0x000d3000
[   23.538449] NDCB1: 0xb7000000
[   23.538449] NDCB2: 0x00000000
[   23.538449] NDCB3: 0x00000000
[   23.557381] nand: nand_do_read_oob: from = 0x05ba0000, len = 64
[   23.563587] marvell-nfc pxa3xx-nand: 
[   23.563587] NDCR:  0x9d079fff
[   23.563587] NDCB0: 0x000d3000
[   23.563587] NDCB1: 0xb7400000
[   23.563587] NDCB2: 0x00000000
[   23.563587] NDCB3: 0x00000000
[   23.582513] nand: nand_do_read_oob: from = 0x05bc0000, len = 64
[   23.588548] marvell-nfc pxa3xx-nand: 
[   23.588548] NDCR:  0x9d079fff
[   23.588548] NDCB0: 0x000d3000
[   23.588548] NDCB1: 0xb7800000
[   23.588548] NDCB2: 0x00000000
[   23.588548] NDCB3: 0x00000000
[   23.607479] nand: nand_do_read_oob: from = 0x05be0000, len = 64
[   23.613687] marvell-nfc pxa3xx-nand: 
[   23.613687] NDCR:  0x9d079fff
[   23.613687] NDCB0: 0x000d3000
[   23.613687] NDCB1: 0xb7c00000
[   23.613687] NDCB2: 0x00000000
[   23.613687] NDCB3: 0x00000000
[   23.632614] nand: nand_do_read_oob: from = 0x05c00000, len = 64
[   23.638819] marvell-nfc pxa3xx-nand: 
[   23.638819] NDCR:  0x9d079fff
[   23.638819] NDCB0: 0x000d3000
[   23.638819] NDCB1: 0xb8000000
[   23.638819] NDCB2: 0x00000000
[   23.638819] NDCB3: 0x00000000
[   23.657722] nand: nand_do_read_oob: from = 0x05c20000, len = 64
[   23.663920] marvell-nfc pxa3xx-nand: 
[   23.663920] NDCR:  0x9d079fff
[   23.663920] NDCB0: 0x000d3000
[   23.663920] NDCB1: 0xb8400000
[   23.663920] NDCB2: 0x00000000
[   23.663920] NDCB3: 0x00000000
[   23.682847] nand: nand_do_read_oob: from = 0x05c40000, len = 64
[   23.689054] marvell-nfc pxa3xx-nand: 
[   23.689054] NDCR:  0x9d079fff
[   23.689054] NDCB0: 0x000d3000
[   23.689054] NDCB1: 0xb8800000
[   23.689054] NDCB2: 0x00000000
[   23.689054] NDCB3: 0x00000000
[   23.707971] nand: nand_do_read_oob: from = 0x05c60000, len = 64
[   23.714176] marvell-nfc pxa3xx-nand: 
[   23.714176] NDCR:  0x9d079fff
[   23.714176] NDCB0: 0x000d3000
[   23.714176] NDCB1: 0xb8c00000
[   23.714176] NDCB2: 0x00000000
[   23.714176] NDCB3: 0x00000000
[   23.733103] nand: nand_do_read_oob: from = 0x05c80000, len = 64
[   23.739307] marvell-nfc pxa3xx-nand: 
[   23.739307] NDCR:  0x9d079fff
[   23.739307] NDCB0: 0x000d3000
[   23.739307] NDCB1: 0xb9000000
[   23.739307] NDCB2: 0x00000000
[   23.739307] NDCB3: 0x00000000
[   23.758224] nand: nand_do_read_oob: from = 0x05ca0000, len = 64
[   23.764430] marvell-nfc pxa3xx-nand: 
[   23.764430] NDCR:  0x9d079fff
[   23.764430] NDCB0: 0x000d3000
[   23.764430] NDCB1: 0xb9400000
[   23.764430] NDCB2: 0x00000000
[   23.764430] NDCB3: 0x00000000
[   23.783358] nand: nand_do_read_oob: from = 0x05cc0000, len = 64
[   23.789559] marvell-nfc pxa3xx-nand: 
[   23.789559] NDCR:  0x9d079fff
[   23.789559] NDCB0: 0x000d3000
[   23.789559] NDCB1: 0xb9800000
[   23.789559] NDCB2: 0x00000000
[   23.789559] NDCB3: 0x00000000
[   23.808477] nand: nand_do_read_oob: from = 0x05ce0000, len = 64
[   23.814682] marvell-nfc pxa3xx-nand: 
[   23.814682] NDCR:  0x9d079fff
[   23.814682] NDCB0: 0x000d3000
[   23.814682] NDCB1: 0xb9c00000
[   23.814682] NDCB2: 0x00000000
[   23.814682] NDCB3: 0x00000000
[   23.833610] nand: nand_do_read_oob: from = 0x05d00000, len = 64
[   23.839813] marvell-nfc pxa3xx-nand: 
[   23.839813] NDCR:  0x9d079fff
[   23.839813] NDCB0: 0x000d3000
[   23.839813] NDCB1: 0xba000000
[   23.839813] NDCB2: 0x00000000
[   23.839813] NDCB3: 0x00000000
[   23.858935] nand: nand_do_read_oob: from = 0x05d20000, len = 64
[   23.864979] marvell-nfc pxa3xx-nand: 
[   23.864979] NDCR:  0x9d079fff
[   23.864979] NDCB0: 0x000d3000
[   23.864979] NDCB1: 0xba400000
[   23.864979] NDCB2: 0x00000000
[   23.864979] NDCB3: 0x00000000
[   23.883928] nand: nand_do_read_oob: from = 0x05d40000, len = 64
[   23.890127] marvell-nfc pxa3xx-nand: 
[   23.890127] NDCR:  0x9d079fff
[   23.890127] NDCB0: 0x000d3000
[   23.890127] NDCB1: 0xba800000
[   23.890127] NDCB2: 0x00000000
[   23.890127] NDCB3: 0x00000000
[   23.909053] nand: nand_do_read_oob: from = 0x05d60000, len = 64
[   23.915087] marvell-nfc pxa3xx-nand: 
[   23.915087] NDCR:  0x9d079fff
[   23.915087] NDCB0: 0x000d3000
[   23.915087] NDCB1: 0xbac00000
[   23.915087] NDCB2: 0x00000000
[   23.915087] NDCB3: 0x00000000
[   23.934020] nand: nand_do_read_oob: from = 0x05d80000, len = 64
[   23.940224] marvell-nfc pxa3xx-nand: 
[   23.940224] NDCR:  0x9d079fff
[   23.940224] NDCB0: 0x000d3000
[   23.940224] NDCB1: 0xbb000000
[   23.940224] NDCB2: 0x00000000
[   23.940224] NDCB3: 0x00000000
[   23.959150] nand: nand_do_read_oob: from = 0x05da0000, len = 64
[   23.965186] marvell-nfc pxa3xx-nand: 
[   23.965186] NDCR:  0x9d079fff
[   23.965186] NDCB0: 0x000d3000
[   23.965186] NDCB1: 0xbb400000
[   23.965186] NDCB2: 0x00000000
[   23.965186] NDCB3: 0x00000000
[   23.984117] nand: nand_do_read_oob: from = 0x05dc0000, len = 64
[   23.990323] marvell-nfc pxa3xx-nand: 
[   23.990323] NDCR:  0x9d079fff
[   23.990323] NDCB0: 0x000d3000
[   23.990323] NDCB1: 0xbb800000
[   23.990323] NDCB2: 0x00000000
[   23.990323] NDCB3: 0x00000000
[   24.009262] nand: nand_do_read_oob: from = 0x05de0000, len = 64
[   24.015293] marvell-nfc pxa3xx-nand: 
[   24.015293] NDCR:  0x9d079fff
[   24.015293] NDCB0: 0x000d3000
[   24.015293] NDCB1: 0xbbc00000
[   24.015293] NDCB2: 0x00000000
[   24.015293] NDCB3: 0x00000000
[   24.034223] nand: nand_do_read_oob: from = 0x05e00000, len = 64
[   24.040423] marvell-nfc pxa3xx-nand: 
[   24.040423] NDCR:  0x9d079fff
[   24.040423] NDCB0: 0x000d3000
[   24.040423] NDCB1: 0xbc000000
[   24.040423] NDCB2: 0x00000000
[   24.040423] NDCB3: 0x00000000
[   24.059348] nand: nand_do_read_oob: from = 0x05e20000, len = 64
[   24.065383] marvell-nfc pxa3xx-nand: 
[   24.065383] NDCR:  0x9d079fff
[   24.065383] NDCB0: 0x000d3000
[   24.065383] NDCB1: 0xbc400000
[   24.065383] NDCB2: 0x00000000
[   24.065383] NDCB3: 0x00000000
[   24.084334] nand: nand_do_read_oob: from = 0x05e40000, len = 64
[   24.090926] marvell-nfc pxa3xx-nand: 
[   24.090926] NDCR:  0x9d079fff
[   24.090926] NDCB0: 0x000d3000
[   24.090926] NDCB1: 0xbc800000
[   24.090926] NDCB2: 0x00000000
[   24.090926] NDCB3: 0x00000000
[   24.109932] nand: nand_do_read_oob: from = 0x05e60000, len = 64
[   24.115963] marvell-nfc pxa3xx-nand: 
[   24.115963] NDCR:  0x9d079fff
[   24.115963] NDCB0: 0x000d3000
[   24.115963] NDCB1: 0xbcc00000
[   24.115963] NDCB2: 0x00000000
[   24.115963] NDCB3: 0x00000000
[   24.134899] nand: nand_do_read_oob: from = 0x05e80000, len = 64
[   24.141102] marvell-nfc pxa3xx-nand: 
[   24.141102] NDCR:  0x9d079fff
[   24.141102] NDCB0: 0x000d3000
[   24.141102] NDCB1: 0xbd000000
[   24.141102] NDCB2: 0x00000000
[   24.141102] NDCB3: 0x00000000
[   24.160031] nand: nand_do_read_oob: from = 0x05ea0000, len = 64
[   24.166062] marvell-nfc pxa3xx-nand: 
[   24.166062] NDCR:  0x9d079fff
[   24.166062] NDCB0: 0x000d3000
[   24.166062] NDCB1: 0xbd400000
[   24.166062] NDCB2: 0x00000000
[   24.166062] NDCB3: 0x00000000
[   24.184995] nand: nand_do_read_oob: from = 0x05ec0000, len = 64
[   24.191201] marvell-nfc pxa3xx-nand: 
[   24.191201] NDCR:  0x9d079fff
[   24.191201] NDCB0: 0x000d3000
[   24.191201] NDCB1: 0xbd800000
[   24.191201] NDCB2: 0x00000000
[   24.191201] NDCB3: 0x00000000
[   24.210128] nand: nand_do_read_oob: from = 0x05ee0000, len = 64
[   24.216161] marvell-nfc pxa3xx-nand: 
[   24.216161] NDCR:  0x9d079fff
[   24.216161] NDCB0: 0x000d3000
[   24.216161] NDCB1: 0xbdc00000
[   24.216161] NDCB2: 0x00000000
[   24.216161] NDCB3: 0x00000000
[   24.235092] nand: nand_do_read_oob: from = 0x05f00000, len = 64
[   24.241301] marvell-nfc pxa3xx-nand: 
[   24.241301] NDCR:  0x9d079fff
[   24.241301] NDCB0: 0x000d3000
[   24.241301] NDCB1: 0xbe000000
[   24.241301] NDCB2: 0x00000000
[   24.241301] NDCB3: 0x00000000
[   24.260227] nand: nand_do_read_oob: from = 0x05f20000, len = 64
[   24.266259] marvell-nfc pxa3xx-nand: 
[   24.266259] NDCR:  0x9d079fff
[   24.266259] NDCB0: 0x000d3000
[   24.266259] NDCB1: 0xbe400000
[   24.266259] NDCB2: 0x00000000
[   24.266259] NDCB3: 0x00000000
[   24.285192] nand: nand_do_read_oob: from = 0x05f40000, len = 64
[   24.291397] marvell-nfc pxa3xx-nand: 
[   24.291397] NDCR:  0x9d079fff
[   24.291397] NDCB0: 0x000d3000
[   24.291397] NDCB1: 0xbe800000
[   24.291397] NDCB2: 0x00000000
[   24.291397] NDCB3: 0x00000000
[   24.310331] nand: nand_do_read_oob: from = 0x05f60000, len = 64
[   24.316365] marvell-nfc pxa3xx-nand: 
[   24.316365] NDCR:  0x9d079fff
[   24.316365] NDCB0: 0x000d3000
[   24.316365] NDCB1: 0xbec00000
[   24.316365] NDCB2: 0x00000000
[   24.316365] NDCB3: 0x00000000
[   24.335304] nand: nand_do_read_oob: from = 0x05f80000, len = 64
[   24.341505] marvell-nfc pxa3xx-nand: 
[   24.341505] NDCR:  0x9d079fff
[   24.341505] NDCB0: 0x000d3000
[   24.341505] NDCB1: 0xbf000000
[   24.341505] NDCB2: 0x00000000
[   24.341505] NDCB3: 0x00000000
[   24.360432] nand: nand_do_read_oob: from = 0x05fa0000, len = 64
[   24.366466] marvell-nfc pxa3xx-nand: 
[   24.366466] NDCR:  0x9d079fff
[   24.366466] NDCB0: 0x000d3000
[   24.366466] NDCB1: 0xbf400000
[   24.366466] NDCB2: 0x00000000
[   24.366466] NDCB3: 0x00000000
[   24.385399] nand: nand_do_read_oob: from = 0x05fc0000, len = 64
[   24.391604] marvell-nfc pxa3xx-nand: 
[   24.391604] NDCR:  0x9d079fff
[   24.391604] NDCB0: 0x000d3000
[   24.391604] NDCB1: 0xbf800000
[   24.391604] NDCB2: 0x00000000
[   24.391604] NDCB3: 0x00000000
[   24.410533] nand: nand_do_read_oob: from = 0x05fe0000, len = 64
[   24.416563] marvell-nfc pxa3xx-nand: 
[   24.416563] NDCR:  0x9d079fff
[   24.416563] NDCB0: 0x000d3000
[   24.416563] NDCB1: 0xbfc00000
[   24.416563] NDCB2: 0x00000000
[   24.416563] NDCB3: 0x00000000
[   24.435496] nand: nand_do_read_oob: from = 0x06000000, len = 64
[   24.441701] marvell-nfc pxa3xx-nand: 
[   24.441701] NDCR:  0x9d079fff
[   24.441701] NDCB0: 0x000d3000
[   24.441701] NDCB1: 0xc0000000
[   24.441701] NDCB2: 0x00000000
[   24.441701] NDCB3: 0x00000000
[   24.460628] nand: nand_do_read_oob: from = 0x06020000, len = 64
[   24.466661] marvell-nfc pxa3xx-nand: 
[   24.466661] NDCR:  0x9d079fff
[   24.466661] NDCB0: 0x000d3000
[   24.466661] NDCB1: 0xc0400000
[   24.466661] NDCB2: 0x00000000
[   24.466661] NDCB3: 0x00000000
[   24.485592] nand: nand_do_read_oob: from = 0x06040000, len = 64
[   24.491792] marvell-nfc pxa3xx-nand: 
[   24.491792] NDCR:  0x9d079fff
[   24.491792] NDCB0: 0x000d3000
[   24.491792] NDCB1: 0xc0800000
[   24.491792] NDCB2: 0x00000000
[   24.491792] NDCB3: 0x00000000
[   24.510721] nand: nand_do_read_oob: from = 0x06060000, len = 64
[   24.516751] marvell-nfc pxa3xx-nand: 
[   24.516751] NDCR:  0x9d079fff
[   24.516751] NDCB0: 0x000d3000
[   24.516751] NDCB1: 0xc0c00000
[   24.516751] NDCB2: 0x00000000
[   24.516751] NDCB3: 0x00000000
[   24.535687] nand: nand_do_read_oob: from = 0x06080000, len = 64
[   24.541891] marvell-nfc pxa3xx-nand: 
[   24.541891] NDCR:  0x9d079fff
[   24.541891] NDCB0: 0x000d3000
[   24.541891] NDCB1: 0xc1000000
[   24.541891] NDCB2: 0x00000000
[   24.541891] NDCB3: 0x00000000
[   24.560820] nand: nand_do_read_oob: from = 0x060a0000, len = 64
[   24.566849] marvell-nfc pxa3xx-nand: 
[   24.566849] NDCR:  0x9d079fff
[   24.566849] NDCB0: 0x000d3000
[   24.566849] NDCB1: 0xc1400000
[   24.566849] NDCB2: 0x00000000
[   24.566849] NDCB3: 0x00000000
[   24.585782] nand: nand_do_read_oob: from = 0x060c0000, len = 64
[   24.591989] marvell-nfc pxa3xx-nand: 
[   24.591989] NDCR:  0x9d079fff
[   24.591989] NDCB0: 0x000d3000
[   24.591989] NDCB1: 0xc1800000
[   24.591989] NDCB2: 0x00000000
[   24.591989] NDCB3: 0x00000000
[   24.610918] nand: nand_do_read_oob: from = 0x060e0000, len = 64
[   24.616951] marvell-nfc pxa3xx-nand: 
[   24.616951] NDCR:  0x9d079fff
[   24.616951] NDCB0: 0x000d3000
[   24.616951] NDCB1: 0xc1c00000
[   24.616951] NDCB2: 0x00000000
[   24.616951] NDCB3: 0x00000000
[   24.635888] nand: nand_do_read_oob: from = 0x06100000, len = 64
[   24.642096] marvell-nfc pxa3xx-nand: 
[   24.642096] NDCR:  0x9d079fff
[   24.642096] NDCB0: 0x000d3000
[   24.642096] NDCB1: 0xc2000000
[   24.642096] NDCB2: 0x00000000
[   24.642096] NDCB3: 0x00000000
[   24.661026] nand: nand_do_read_oob: from = 0x06120000, len = 64
[   24.667054] marvell-nfc pxa3xx-nand: 
[   24.667054] NDCR:  0x9d079fff
[   24.667054] NDCB0: 0x000d3000
[   24.667054] NDCB1: 0xc2400000
[   24.667054] NDCB2: 0x00000000
[   24.667054] NDCB3: 0x00000000
[   24.685988] nand: nand_do_read_oob: from = 0x06140000, len = 64
[   24.692192] marvell-nfc pxa3xx-nand: 
[   24.692192] NDCR:  0x9d079fff
[   24.692192] NDCB0: 0x000d3000
[   24.692192] NDCB1: 0xc2800000
[   24.692192] NDCB2: 0x00000000
[   24.692192] NDCB3: 0x00000000
[   24.711122] nand: nand_do_read_oob: from = 0x06160000, len = 64
[   24.717153] marvell-nfc pxa3xx-nand: 
[   24.717153] NDCR:  0x9d079fff
[   24.717153] NDCB0: 0x000d3000
[   24.717153] NDCB1: 0xc2c00000
[   24.717153] NDCB2: 0x00000000
[   24.717153] NDCB3: 0x00000000
[   24.736108] nand: nand_do_read_oob: from = 0x06180000, len = 64
[   24.742309] marvell-nfc pxa3xx-nand: 
[   24.742309] NDCR:  0x9d079fff
[   24.742309] NDCB0: 0x000d3000
[   24.742309] NDCB1: 0xc3000000
[   24.742309] NDCB2: 0x00000000
[   24.742309] NDCB3: 0x00000000
[   24.761239] nand: nand_do_read_oob: from = 0x061a0000, len = 64
[   24.767270] marvell-nfc pxa3xx-nand: 
[   24.767270] NDCR:  0x9d079fff
[   24.767270] NDCB0: 0x000d3000
[   24.767270] NDCB1: 0xc3400000
[   24.767270] NDCB2: 0x00000000
[   24.767270] NDCB3: 0x00000000
[   24.786202] nand: nand_do_read_oob: from = 0x061c0000, len = 64
[   24.792407] marvell-nfc pxa3xx-nand: 
[   24.792407] NDCR:  0x9d079fff
[   24.792407] NDCB0: 0x000d3000
[   24.792407] NDCB1: 0xc3800000
[   24.792407] NDCB2: 0x00000000
[   24.792407] NDCB3: 0x00000000
[   24.811339] nand: nand_do_read_oob: from = 0x061e0000, len = 64
[   24.817367] marvell-nfc pxa3xx-nand: 
[   24.817367] NDCR:  0x9d079fff
[   24.817367] NDCB0: 0x000d3000
[   24.817367] NDCB1: 0xc3c00000
[   24.817367] NDCB2: 0x00000000
[   24.817367] NDCB3: 0x00000000
[   24.836302] nand: nand_do_read_oob: from = 0x06200000, len = 64
[   24.842506] marvell-nfc pxa3xx-nand: 
[   24.842506] NDCR:  0x9d079fff
[   24.842506] NDCB0: 0x000d3000
[   24.842506] NDCB1: 0xc4000000
[   24.842506] NDCB2: 0x00000000
[   24.842506] NDCB3: 0x00000000
[   24.861437] nand: nand_do_read_oob: from = 0x06220000, len = 64
[   24.867467] marvell-nfc pxa3xx-nand: 
[   24.867467] NDCR:  0x9d079fff
[   24.867467] NDCB0: 0x000d3000
[   24.867467] NDCB1: 0xc4400000
[   24.867467] NDCB2: 0x00000000
[   24.867467] NDCB3: 0x00000000
[   24.886399] nand: nand_do_read_oob: from = 0x06240000, len = 64
[   24.892604] marvell-nfc pxa3xx-nand: 
[   24.892604] NDCR:  0x9d079fff
[   24.892604] NDCB0: 0x000d3000
[   24.892604] NDCB1: 0xc4800000
[   24.892604] NDCB2: 0x00000000
[   24.892604] NDCB3: 0x00000000
[   24.911533] nand: nand_do_read_oob: from = 0x06260000, len = 64
[   24.917564] marvell-nfc pxa3xx-nand: 
[   24.917564] NDCR:  0x9d079fff
[   24.917564] NDCB0: 0x000d3000
[   24.917564] NDCB1: 0xc4c00000
[   24.917564] NDCB2: 0x00000000
[   24.917564] NDCB3: 0x00000000
[   24.936498] nand: nand_do_read_oob: from = 0x06280000, len = 64
[   24.942701] marvell-nfc pxa3xx-nand: 
[   24.942701] NDCR:  0x9d079fff
[   24.942701] NDCB0: 0x000d3000
[   24.942701] NDCB1: 0xc5000000
[   24.942701] NDCB2: 0x00000000
[   24.942701] NDCB3: 0x00000000
[   24.961631] nand: nand_do_read_oob: from = 0x062a0000, len = 64
[   24.967664] marvell-nfc pxa3xx-nand: 
[   24.967664] NDCR:  0x9d079fff
[   24.967664] NDCB0: 0x000d3000
[   24.967664] NDCB1: 0xc5400000
[   24.967664] NDCB2: 0x00000000
[   24.967664] NDCB3: 0x00000000
[   24.986598] nand: nand_do_read_oob: from = 0x062c0000, len = 64
[   24.992800] marvell-nfc pxa3xx-nand: 
[   24.992800] NDCR:  0x9d079fff
[   24.992800] NDCB0: 0x000d3000
[   24.992800] NDCB1: 0xc5800000
[   24.992800] NDCB2: 0x00000000
[   24.992800] NDCB3: 0x00000000
[   25.011742] nand: nand_do_read_oob: from = 0x062e0000, len = 64
[   25.017771] marvell-nfc pxa3xx-nand: 
[   25.017771] NDCR:  0x9d079fff
[   25.017771] NDCB0: 0x000d3000
[   25.017771] NDCB1: 0xc5c00000
[   25.017771] NDCB2: 0x00000000
[   25.017771] NDCB3: 0x00000000
[   25.036704] nand: nand_do_read_oob: from = 0x06300000, len = 64
[   25.042909] marvell-nfc pxa3xx-nand: 
[   25.042909] NDCR:  0x9d079fff
[   25.042909] NDCB0: 0x000d3000
[   25.042909] NDCB1: 0xc6000000
[   25.042909] NDCB2: 0x00000000
[   25.042909] NDCB3: 0x00000000
[   25.061840] nand: nand_do_read_oob: from = 0x06320000, len = 64
[   25.067868] marvell-nfc pxa3xx-nand: 
[   25.067868] NDCR:  0x9d079fff
[   25.067868] NDCB0: 0x000d3000
[   25.067868] NDCB1: 0xc6400000
[   25.067868] NDCB2: 0x00000000
[   25.067868] NDCB3: 0x00000000
[   25.086807] nand: nand_do_read_oob: from = 0x06340000, len = 64
[   25.093007] marvell-nfc pxa3xx-nand: 
[   25.093007] NDCR:  0x9d079fff
[   25.093007] NDCB0: 0x000d3000
[   25.093007] NDCB1: 0xc6800000
[   25.093007] NDCB2: 0x00000000
[   25.093007] NDCB3: 0x00000000
[   25.111938] nand: nand_do_read_oob: from = 0x06360000, len = 64
[   25.117967] marvell-nfc pxa3xx-nand: 
[   25.117967] NDCR:  0x9d079fff
[   25.117967] NDCB0: 0x000d3000
[   25.117967] NDCB1: 0xc6c00000
[   25.117967] NDCB2: 0x00000000
[   25.117967] NDCB3: 0x00000000
[   25.136901] nand: nand_do_read_oob: from = 0x06380000, len = 64
[   25.143106] marvell-nfc pxa3xx-nand: 
[   25.143106] NDCR:  0x9d079fff
[   25.143106] NDCB0: 0x000d3000
[   25.143106] NDCB1: 0xc7000000
[   25.143106] NDCB2: 0x00000000
[   25.143106] NDCB3: 0x00000000
[   25.162036] nand: nand_do_read_oob: from = 0x063a0000, len = 64
[   25.168067] marvell-nfc pxa3xx-nand: 
[   25.168067] NDCR:  0x9d079fff
[   25.168067] NDCB0: 0x000d3000
[   25.168067] NDCB1: 0xc7400000
[   25.168067] NDCB2: 0x00000000
[   25.168067] NDCB3: 0x00000000
[   25.187002] nand: nand_do_read_oob: from = 0x063c0000, len = 64
[   25.193203] marvell-nfc pxa3xx-nand: 
[   25.193203] NDCR:  0x9d079fff
[   25.193203] NDCB0: 0x000d3000
[   25.193203] NDCB1: 0xc7800000
[   25.193203] NDCB2: 0x00000000
[   25.193203] NDCB3: 0x00000000
[   25.212134] nand: nand_do_read_oob: from = 0x063e0000, len = 64
[   25.218164] marvell-nfc pxa3xx-nand: 
[   25.218164] NDCR:  0x9d079fff
[   25.218164] NDCB0: 0x000d3000
[   25.218164] NDCB1: 0xc7c00000
[   25.218164] NDCB2: 0x00000000
[   25.218164] NDCB3: 0x00000000
[   25.237097] nand: nand_do_read_oob: from = 0x06400000, len = 64
[   25.243303] marvell-nfc pxa3xx-nand: 
[   25.243303] NDCR:  0x9d079fff
[   25.243303] NDCB0: 0x000d3000
[   25.243303] NDCB1: 0xc8000000
[   25.243303] NDCB2: 0x00000000
[   25.243303] NDCB3: 0x00000000
[   25.262230] nand: nand_do_read_oob: from = 0x06420000, len = 64
[   25.268262] marvell-nfc pxa3xx-nand: 
[   25.268262] NDCR:  0x9d079fff
[   25.268262] NDCB0: 0x000d3000
[   25.268262] NDCB1: 0xc8400000
[   25.268262] NDCB2: 0x00000000
[   25.268262] NDCB3: 0x00000000
[   25.287196] nand: nand_do_read_oob: from = 0x06440000, len = 64
[   25.293401] marvell-nfc pxa3xx-nand: 
[   25.293401] NDCR:  0x9d079fff
[   25.293401] NDCB0: 0x000d3000
[   25.293401] NDCB1: 0xc8800000
[   25.293401] NDCB2: 0x00000000
[   25.293401] NDCB3: 0x00000000
[   25.312330] nand: nand_do_read_oob: from = 0x06460000, len = 64
[   25.318361] marvell-nfc pxa3xx-nand: 
[   25.318361] NDCR:  0x9d079fff
[   25.318361] NDCB0: 0x000d3000
[   25.318361] NDCB1: 0xc8c00000
[   25.318361] NDCB2: 0x00000000
[   25.318361] NDCB3: 0x00000000
[   25.337293] nand: nand_do_read_oob: from = 0x06480000, len = 64
[   25.343499] marvell-nfc pxa3xx-nand: 
[   25.343499] NDCR:  0x9d079fff
[   25.343499] NDCB0: 0x000d3000
[   25.343499] NDCB1: 0xc9000000
[   25.343499] NDCB2: 0x00000000
[   25.343499] NDCB3: 0x00000000
[   25.362446] nand: nand_do_read_oob: from = 0x064a0000, len = 64
[   25.368478] marvell-nfc pxa3xx-nand: 
[   25.368478] NDCR:  0x9d079fff
[   25.368478] NDCB0: 0x000d3000
[   25.368478] NDCB1: 0xc9400000
[   25.368478] NDCB2: 0x00000000
[   25.368478] NDCB3: 0x00000000
[   25.387413] nand: nand_do_read_oob: from = 0x064c0000, len = 64
[   25.393617] marvell-nfc pxa3xx-nand: 
[   25.393617] NDCR:  0x9d079fff
[   25.393617] NDCB0: 0x000d3000
[   25.393617] NDCB1: 0xc9800000
[   25.393617] NDCB2: 0x00000000
[   25.393617] NDCB3: 0x00000000
[   25.412545] nand: nand_do_read_oob: from = 0x064e0000, len = 64
[   25.418575] marvell-nfc pxa3xx-nand: 
[   25.418575] NDCR:  0x9d079fff
[   25.418575] NDCB0: 0x000d3000
[   25.418575] NDCB1: 0xc9c00000
[   25.418575] NDCB2: 0x00000000
[   25.418575] NDCB3: 0x00000000
[   25.437618] nand: nand_do_read_oob: from = 0x06500000, len = 64
[   25.443823] marvell-nfc pxa3xx-nand: 
[   25.443823] NDCR:  0x9d079fff
[   25.443823] NDCB0: 0x000d3000
[   25.443823] NDCB1: 0xca000000
[   25.443823] NDCB2: 0x00000000
[   25.443823] NDCB3: 0x00000000
[   25.462756] nand: nand_do_read_oob: from = 0x06520000, len = 64
[   25.468956] marvell-nfc pxa3xx-nand: 
[   25.468956] NDCR:  0x9d079fff
[   25.468956] NDCB0: 0x000d3000
[   25.468956] NDCB1: 0xca400000
[   25.468956] NDCB2: 0x00000000
[   25.468956] NDCB3: 0x00000000
[   25.487878] nand: nand_do_read_oob: from = 0x06540000, len = 64
[   25.494080] marvell-nfc pxa3xx-nand: 
[   25.494080] NDCR:  0x9d079fff
[   25.494080] NDCB0: 0x000d3000
[   25.494080] NDCB1: 0xca800000
[   25.494080] NDCB2: 0x00000000
[   25.494080] NDCB3: 0x00000000
[   25.513008] nand: nand_do_read_oob: from = 0x06560000, len = 64
[   25.519209] marvell-nfc pxa3xx-nand: 
[   25.519209] NDCR:  0x9d079fff
[   25.519209] NDCB0: 0x000d3000
[   25.519209] NDCB1: 0xcac00000
[   25.519209] NDCB2: 0x00000000
[   25.519209] NDCB3: 0x00000000
[   25.538130] nand: nand_do_read_oob: from = 0x06580000, len = 64
[   25.544332] marvell-nfc pxa3xx-nand: 
[   25.544332] NDCR:  0x9d079fff
[   25.544332] NDCB0: 0x000d3000
[   25.544332] NDCB1: 0xcb000000
[   25.544332] NDCB2: 0x00000000
[   25.544332] NDCB3: 0x00000000
[   25.563262] nand: nand_do_read_oob: from = 0x065a0000, len = 64
[   25.569461] marvell-nfc pxa3xx-nand: 
[   25.569461] NDCR:  0x9d079fff
[   25.569461] NDCB0: 0x000d3000
[   25.569461] NDCB1: 0xcb400000
[   25.569461] NDCB2: 0x00000000
[   25.569461] NDCB3: 0x00000000
[   25.588383] nand: nand_do_read_oob: from = 0x065c0000, len = 64
[   25.594587] marvell-nfc pxa3xx-nand: 
[   25.594587] NDCR:  0x9d079fff
[   25.594587] NDCB0: 0x000d3000
[   25.594587] NDCB1: 0xcb800000
[   25.594587] NDCB2: 0x00000000
[   25.594587] NDCB3: 0x00000000
[   25.613516] nand: nand_do_read_oob: from = 0x065e0000, len = 64
[   25.619718] marvell-nfc pxa3xx-nand: 
[   25.619718] NDCR:  0x9d079fff
[   25.619718] NDCB0: 0x000d3000
[   25.619718] NDCB1: 0xcbc00000
[   25.619718] NDCB2: 0x00000000
[   25.619718] NDCB3: 0x00000000
[   25.638638] nand: nand_do_read_oob: from = 0x06600000, len = 64
[   25.644824] marvell-nfc pxa3xx-nand: 
[   25.644824] NDCR:  0x9d079fff
[   25.644824] NDCB0: 0x000d3000
[   25.644824] NDCB1: 0xcc000000
[   25.644824] NDCB2: 0x00000000
[   25.644824] NDCB3: 0x00000000
[   25.663739] nand: nand_do_read_oob: from = 0x06620000, len = 64
[   25.669943] marvell-nfc pxa3xx-nand: 
[   25.669943] NDCR:  0x9d079fff
[   25.669943] NDCB0: 0x000d3000
[   25.669943] NDCB1: 0xcc400000
[   25.669943] NDCB2: 0x00000000
[   25.669943] NDCB3: 0x00000000
[   25.688899] nand: nand_do_read_oob: from = 0x06640000, len = 64
[   25.694935] marvell-nfc pxa3xx-nand: 
[   25.694935] NDCR:  0x9d079fff
[   25.694935] NDCB0: 0x000d3000
[   25.694935] NDCB1: 0xcc800000
[   25.694935] NDCB2: 0x00000000
[   25.694935] NDCB3: 0x00000000
[   25.713873] nand: nand_do_read_oob: from = 0x06660000, len = 64
[   25.720078] marvell-nfc pxa3xx-nand: 
[   25.720078] NDCR:  0x9d079fff
[   25.720078] NDCB0: 0x000d3000
[   25.720078] NDCB1: 0xccc00000
[   25.720078] NDCB2: 0x00000000
[   25.720078] NDCB3: 0x00000000
[   25.739046] nand: nand_do_read_oob: from = 0x06680000, len = 64
[   25.745080] marvell-nfc pxa3xx-nand: 
[   25.745080] NDCR:  0x9d079fff
[   25.745080] NDCB0: 0x000d3000
[   25.745080] NDCB1: 0xcd000000
[   25.745080] NDCB2: 0x00000000
[   25.745080] NDCB3: 0x00000000
[   25.764014] nand: nand_do_read_oob: from = 0x066a0000, len = 64
[   25.770220] marvell-nfc pxa3xx-nand: 
[   25.770220] NDCR:  0x9d079fff
[   25.770220] NDCB0: 0x000d3000
[   25.770220] NDCB1: 0xcd400000
[   25.770220] NDCB2: 0x00000000
[   25.770220] NDCB3: 0x00000000
[   25.789144] nand: nand_do_read_oob: from = 0x066c0000, len = 64
[   25.795180] marvell-nfc pxa3xx-nand: 
[   25.795180] NDCR:  0x9d079fff
[   25.795180] NDCB0: 0x000d3000
[   25.795180] NDCB1: 0xcd800000
[   25.795180] NDCB2: 0x00000000
[   25.795180] NDCB3: 0x00000000
[   25.814114] nand: nand_do_read_oob: from = 0x066e0000, len = 64
[   25.820318] marvell-nfc pxa3xx-nand: 
[   25.820318] NDCR:  0x9d079fff
[   25.820318] NDCB0: 0x000d3000
[   25.820318] NDCB1: 0xcdc00000
[   25.820318] NDCB2: 0x00000000
[   25.820318] NDCB3: 0x00000000
[   25.839247] nand: nand_do_read_oob: from = 0x06700000, len = 64
[   25.845278] marvell-nfc pxa3xx-nand: 
[   25.845278] NDCR:  0x9d079fff
[   25.845278] NDCB0: 0x000d3000
[   25.845278] NDCB1: 0xce000000
[   25.845278] NDCB2: 0x00000000
[   25.845278] NDCB3: 0x00000000
[   25.864211] nand: nand_do_read_oob: from = 0x06720000, len = 64
[   25.870419] marvell-nfc pxa3xx-nand: 
[   25.870419] NDCR:  0x9d079fff
[   25.870419] NDCB0: 0x000d3000
[   25.870419] NDCB1: 0xce400000
[   25.870419] NDCB2: 0x00000000
[   25.870419] NDCB3: 0x00000000
[   25.889351] nand: nand_do_read_oob: from = 0x06740000, len = 64
[   25.895386] marvell-nfc pxa3xx-nand: 
[   25.895386] NDCR:  0x9d079fff
[   25.895386] NDCB0: 0x000d3000
[   25.895386] NDCB1: 0xce800000
[   25.895386] NDCB2: 0x00000000
[   25.895386] NDCB3: 0x00000000
[   25.914320] nand: nand_do_read_oob: from = 0x06760000, len = 64
[   25.920524] marvell-nfc pxa3xx-nand: 
[   25.920524] NDCR:  0x9d079fff
[   25.920524] NDCB0: 0x000d3000
[   25.920524] NDCB1: 0xcec00000
[   25.920524] NDCB2: 0x00000000
[   25.920524] NDCB3: 0x00000000
[   25.939469] nand: nand_do_read_oob: from = 0x06780000, len = 64
[   25.945500] marvell-nfc pxa3xx-nand: 
[   25.945500] NDCR:  0x9d079fff
[   25.945500] NDCB0: 0x000d3000
[   25.945500] NDCB1: 0xcf000000
[   25.945500] NDCB2: 0x00000000
[   25.945500] NDCB3: 0x00000000
[   25.964434] nand: nand_do_read_oob: from = 0x067a0000, len = 64
[   25.970641] marvell-nfc pxa3xx-nand: 
[   25.970641] NDCR:  0x9d079fff
[   25.970641] NDCB0: 0x000d3000
[   25.970641] NDCB1: 0xcf400000
[   25.970641] NDCB2: 0x00000000
[   25.970641] NDCB3: 0x00000000
[   25.989570] nand: nand_do_read_oob: from = 0x067c0000, len = 64
[   25.995599] marvell-nfc pxa3xx-nand: 
[   25.995599] NDCR:  0x9d079fff
[   25.995599] NDCB0: 0x000d3000
[   25.995599] NDCB1: 0xcf800000
[   25.995599] NDCB2: 0x00000000
[   25.995599] NDCB3: 0x00000000
[   26.014541] nand: nand_do_read_oob: from = 0x067e0000, len = 64
[   26.020747] marvell-nfc pxa3xx-nand: 
[   26.020747] NDCR:  0x9d079fff
[   26.020747] NDCB0: 0x000d3000
[   26.020747] NDCB1: 0xcfc00000
[   26.020747] NDCB2: 0x00000000
[   26.020747] NDCB3: 0x00000000
[   26.039677] nand: nand_do_read_oob: from = 0x06800000, len = 64
[   26.045706] marvell-nfc pxa3xx-nand: 
[   26.045706] NDCR:  0x9d079fff
[   26.045706] NDCB0: 0x000d3000
[   26.045706] NDCB1: 0xd0000000
[   26.045706] NDCB2: 0x00000000
[   26.045706] NDCB3: 0x00000000
[   26.064637] nand: nand_do_read_oob: from = 0x06820000, len = 64
[   26.070836] marvell-nfc pxa3xx-nand: 
[   26.070836] NDCR:  0x9d079fff
[   26.070836] NDCB0: 0x000d3000
[   26.070836] NDCB1: 0xd0400000
[   26.070836] NDCB2: 0x00000000
[   26.070836] NDCB3: 0x00000000
[   26.090106] nand: nand_do_read_oob: from = 0x06840000, len = 64
[   26.096145] marvell-nfc pxa3xx-nand: 
[   26.096145] NDCR:  0x9d079fff
[   26.096145] NDCB0: 0x000d3000
[   26.096145] NDCB1: 0xd0800000
[   26.096145] NDCB2: 0x00000000
[   26.096145] NDCB3: 0x00000000
[   26.115109] nand: nand_do_read_oob: from = 0x06860000, len = 64
[   26.121313] marvell-nfc pxa3xx-nand: 
[   26.121313] NDCR:  0x9d079fff
[   26.121313] NDCB0: 0x000d3000
[   26.121313] NDCB1: 0xd0c00000
[   26.121313] NDCB2: 0x00000000
[   26.121313] NDCB3: 0x00000000
[   26.140243] nand: nand_do_read_oob: from = 0x06880000, len = 64
[   26.146272] marvell-nfc pxa3xx-nand: 
[   26.146272] NDCR:  0x9d079fff
[   26.146272] NDCB0: 0x000d3000
[   26.146272] NDCB1: 0xd1000000
[   26.146272] NDCB2: 0x00000000
[   26.146272] NDCB3: 0x00000000
[   26.165208] nand: nand_do_read_oob: from = 0x068a0000, len = 64
[   26.171411] marvell-nfc pxa3xx-nand: 
[   26.171411] NDCR:  0x9d079fff
[   26.171411] NDCB0: 0x000d3000
[   26.171411] NDCB1: 0xd1400000
[   26.171411] NDCB2: 0x00000000
[   26.171411] NDCB3: 0x00000000
[   26.190341] nand: nand_do_read_oob: from = 0x068c0000, len = 64
[   26.196372] marvell-nfc pxa3xx-nand: 
[   26.196372] NDCR:  0x9d079fff
[   26.196372] NDCB0: 0x000d3000
[   26.196372] NDCB1: 0xd1800000
[   26.196372] NDCB2: 0x00000000
[   26.196372] NDCB3: 0x00000000
[   26.215306] nand: nand_do_read_oob: from = 0x068e0000, len = 64
[   26.221511] marvell-nfc pxa3xx-nand: 
[   26.221511] NDCR:  0x9d079fff
[   26.221511] NDCB0: 0x000d3000
[   26.221511] NDCB1: 0xd1c00000
[   26.221511] NDCB2: 0x00000000
[   26.221511] NDCB3: 0x00000000
[   26.240439] nand: nand_do_read_oob: from = 0x06900000, len = 64
[   26.246471] marvell-nfc pxa3xx-nand: 
[   26.246471] NDCR:  0x9d079fff
[   26.246471] NDCB0: 0x000d3000
[   26.246471] NDCB1: 0xd2000000
[   26.246471] NDCB2: 0x00000000
[   26.246471] NDCB3: 0x00000000
[   26.265403] nand: nand_do_read_oob: from = 0x06920000, len = 64
[   26.271608] marvell-nfc pxa3xx-nand: 
[   26.271608] NDCR:  0x9d079fff
[   26.271608] NDCB0: 0x000d3000
[   26.271608] NDCB1: 0xd2400000
[   26.271608] NDCB2: 0x00000000
[   26.271608] NDCB3: 0x00000000
[   26.290538] nand: nand_do_read_oob: from = 0x06940000, len = 64
[   26.296569] marvell-nfc pxa3xx-nand: 
[   26.296569] NDCR:  0x9d079fff
[   26.296569] NDCB0: 0x000d3000
[   26.296569] NDCB1: 0xd2800000
[   26.296569] NDCB2: 0x00000000
[   26.296569] NDCB3: 0x00000000
[   26.315502] nand: nand_do_read_oob: from = 0x06960000, len = 64
[   26.321707] marvell-nfc pxa3xx-nand: 
[   26.321707] NDCR:  0x9d079fff
[   26.321707] NDCB0: 0x000d3000
[   26.321707] NDCB1: 0xd2c00000
[   26.321707] NDCB2: 0x00000000
[   26.321707] NDCB3: 0x00000000
[   26.340635] nand: nand_do_read_oob: from = 0x06980000, len = 64
[   26.346669] marvell-nfc pxa3xx-nand: 
[   26.346669] NDCR:  0x9d079fff
[   26.346669] NDCB0: 0x000d3000
[   26.346669] NDCB1: 0xd3000000
[   26.346669] NDCB2: 0x00000000
[   26.346669] NDCB3: 0x00000000
[   26.365601] nand: nand_do_read_oob: from = 0x069a0000, len = 64
[   26.371806] marvell-nfc pxa3xx-nand: 
[   26.371806] NDCR:  0x9d079fff
[   26.371806] NDCB0: 0x000d3000
[   26.371806] NDCB1: 0xd3400000
[   26.371806] NDCB2: 0x00000000
[   26.371806] NDCB3: 0x00000000
[   26.390734] nand: nand_do_read_oob: from = 0x069c0000, len = 64
[   26.396767] marvell-nfc pxa3xx-nand: 
[   26.396767] NDCR:  0x9d079fff
[   26.396767] NDCB0: 0x000d3000
[   26.396767] NDCB1: 0xd3800000
[   26.396767] NDCB2: 0x00000000
[   26.396767] NDCB3: 0x00000000
[   26.415698] nand: nand_do_read_oob: from = 0x069e0000, len = 64
[   26.421904] marvell-nfc pxa3xx-nand: 
[   26.421904] NDCR:  0x9d079fff
[   26.421904] NDCB0: 0x000d3000
[   26.421904] NDCB1: 0xd3c00000
[   26.421904] NDCB2: 0x00000000
[   26.421904] NDCB3: 0x00000000
[   26.440832] nand: nand_do_read_oob: from = 0x06a00000, len = 64
[   26.446863] marvell-nfc pxa3xx-nand: 
[   26.446863] NDCR:  0x9d079fff
[   26.446863] NDCB0: 0x000d3000
[   26.446863] NDCB1: 0xd4000000
[   26.446863] NDCB2: 0x00000000
[   26.446863] NDCB3: 0x00000000
[   26.465798] nand: nand_do_read_oob: from = 0x06a20000, len = 64
[   26.472002] marvell-nfc pxa3xx-nand: 
[   26.472002] NDCR:  0x9d079fff
[   26.472002] NDCB0: 0x000d3000
[   26.472002] NDCB1: 0xd4400000
[   26.472002] NDCB2: 0x00000000
[   26.472002] NDCB3: 0x00000000
[   26.490930] nand: nand_do_read_oob: from = 0x06a40000, len = 64
[   26.496963] marvell-nfc pxa3xx-nand: 
[   26.496963] NDCR:  0x9d079fff
[   26.496963] NDCB0: 0x000d3000
[   26.496963] NDCB1: 0xd4800000
[   26.496963] NDCB2: 0x00000000
[   26.496963] NDCB3: 0x00000000
[   26.515894] nand: nand_do_read_oob: from = 0x06a60000, len = 64
[   26.522092] marvell-nfc pxa3xx-nand: 
[   26.522092] NDCR:  0x9d079fff
[   26.522092] NDCB0: 0x000d3000
[   26.522092] NDCB1: 0xd4c00000
[   26.522092] NDCB2: 0x00000000
[   26.522092] NDCB3: 0x00000000
[   26.541022] nand: nand_do_read_oob: from = 0x06a80000, len = 64
[   26.547052] marvell-nfc pxa3xx-nand: 
[   26.547052] NDCR:  0x9d079fff
[   26.547052] NDCB0: 0x000d3000
[   26.547052] NDCB1: 0xd5000000
[   26.547052] NDCB2: 0x00000000
[   26.547052] NDCB3: 0x00000000
[   26.565986] nand: nand_do_read_oob: from = 0x06aa0000, len = 64
[   26.572194] marvell-nfc pxa3xx-nand: 
[   26.572194] NDCR:  0x9d079fff
[   26.572194] NDCB0: 0x000d3000
[   26.572194] NDCB1: 0xd5400000
[   26.572194] NDCB2: 0x00000000
[   26.572194] NDCB3: 0x00000000
[   26.591141] nand: nand_do_read_oob: from = 0x06ac0000, len = 64
[   26.597178] marvell-nfc pxa3xx-nand: 
[   26.597178] NDCR:  0x9d079fff
[   26.597178] NDCB0: 0x000d3000
[   26.597178] NDCB1: 0xd5800000
[   26.597178] NDCB2: 0x00000000
[   26.597178] NDCB3: 0x00000000
[   26.616109] nand: nand_do_read_oob: from = 0x06ae0000, len = 64
[   26.622316] marvell-nfc pxa3xx-nand: 
[   26.622316] NDCR:  0x9d079fff
[   26.622316] NDCB0: 0x000d3000
[   26.622316] NDCB1: 0xd5c00000
[   26.622316] NDCB2: 0x00000000
[   26.622316] NDCB3: 0x00000000
[   26.641244] nand: nand_do_read_oob: from = 0x06b00000, len = 64
[   26.647276] marvell-nfc pxa3xx-nand: 
[   26.647276] NDCR:  0x9d079fff
[   26.647276] NDCB0: 0x000d3000
[   26.647276] NDCB1: 0xd6000000
[   26.647276] NDCB2: 0x00000000
[   26.647276] NDCB3: 0x00000000
[   26.666208] nand: nand_do_read_oob: from = 0x06b20000, len = 64
[   26.672412] marvell-nfc pxa3xx-nand: 
[   26.672412] NDCR:  0x9d079fff
[   26.672412] NDCB0: 0x000d3000
[   26.672412] NDCB1: 0xd6400000
[   26.672412] NDCB2: 0x00000000
[   26.672412] NDCB3: 0x00000000
[   26.691343] nand: nand_do_read_oob: from = 0x06b40000, len = 64
[   26.697375] marvell-nfc pxa3xx-nand: 
[   26.697375] NDCR:  0x9d079fff
[   26.697375] NDCB0: 0x000d3000
[   26.697375] NDCB1: 0xd6800000
[   26.697375] NDCB2: 0x00000000
[   26.697375] NDCB3: 0x00000000
[   26.716310] nand: nand_do_read_oob: from = 0x06b60000, len = 64
[   26.722513] marvell-nfc pxa3xx-nand: 
[   26.722513] NDCR:  0x9d079fff
[   26.722513] NDCB0: 0x000d3000
[   26.722513] NDCB1: 0xd6c00000
[   26.722513] NDCB2: 0x00000000
[   26.722513] NDCB3: 0x00000000
[   26.741440] nand: nand_do_read_oob: from = 0x06b80000, len = 64
[   26.747474] marvell-nfc pxa3xx-nand: 
[   26.747474] NDCR:  0x9d079fff
[   26.747474] NDCB0: 0x000d3000
[   26.747474] NDCB1: 0xd7000000
[   26.747474] NDCB2: 0x00000000
[   26.747474] NDCB3: 0x00000000
[   26.766408] nand: nand_do_read_oob: from = 0x06ba0000, len = 64
[   26.772613] marvell-nfc pxa3xx-nand: 
[   26.772613] NDCR:  0x9d079fff
[   26.772613] NDCB0: 0x000d3000
[   26.772613] NDCB1: 0xd7400000
[   26.772613] NDCB2: 0x00000000
[   26.772613] NDCB3: 0x00000000
[   26.791540] nand: nand_do_read_oob: from = 0x06bc0000, len = 64
[   26.797571] marvell-nfc pxa3xx-nand: 
[   26.797571] NDCR:  0x9d079fff
[   26.797571] NDCB0: 0x000d3000
[   26.797571] NDCB1: 0xd7800000
[   26.797571] NDCB2: 0x00000000
[   26.797571] NDCB3: 0x00000000
[   26.816504] nand: nand_do_read_oob: from = 0x06be0000, len = 64
[   26.822709] marvell-nfc pxa3xx-nand: 
[   26.822709] NDCR:  0x9d079fff
[   26.822709] NDCB0: 0x000d3000
[   26.822709] NDCB1: 0xd7c00000
[   26.822709] NDCB2: 0x00000000
[   26.822709] NDCB3: 0x00000000
[   26.841637] nand: nand_do_read_oob: from = 0x06c00000, len = 64
[   26.847670] marvell-nfc pxa3xx-nand: 
[   26.847670] NDCR:  0x9d079fff
[   26.847670] NDCB0: 0x000d3000
[   26.847670] NDCB1: 0xd8000000
[   26.847670] NDCB2: 0x00000000
[   26.847670] NDCB3: 0x00000000
[   26.866601] nand: nand_do_read_oob: from = 0x06c20000, len = 64
[   26.872810] marvell-nfc pxa3xx-nand: 
[   26.872810] NDCR:  0x9d079fff
[   26.872810] NDCB0: 0x000d3000
[   26.872810] NDCB1: 0xd8400000
[   26.872810] NDCB2: 0x00000000
[   26.872810] NDCB3: 0x00000000
[   26.891738] nand: nand_do_read_oob: from = 0x06c40000, len = 64
[   26.897767] marvell-nfc pxa3xx-nand: 
[   26.897767] NDCR:  0x9d079fff
[   26.897767] NDCB0: 0x000d3000
[   26.897767] NDCB1: 0xd8800000
[   26.897767] NDCB2: 0x00000000
[   26.897767] NDCB3: 0x00000000
[   26.916703] nand: nand_do_read_oob: from = 0x06c60000, len = 64
[   26.922905] marvell-nfc pxa3xx-nand: 
[   26.922905] NDCR:  0x9d079fff
[   26.922905] NDCB0: 0x000d3000
[   26.922905] NDCB1: 0xd8c00000
[   26.922905] NDCB2: 0x00000000
[   26.922905] NDCB3: 0x00000000
[   26.941834] nand: nand_do_read_oob: from = 0x06c80000, len = 64
[   26.947867] marvell-nfc pxa3xx-nand: 
[   26.947867] NDCR:  0x9d079fff
[   26.947867] NDCB0: 0x000d3000
[   26.947867] NDCB1: 0xd9000000
[   26.947867] NDCB2: 0x00000000
[   26.947867] NDCB3: 0x00000000
[   26.966798] nand: nand_do_read_oob: from = 0x06ca0000, len = 64
[   26.973006] marvell-nfc pxa3xx-nand: 
[   26.973006] NDCR:  0x9d079fff
[   26.973006] NDCB0: 0x000d3000
[   26.973006] NDCB1: 0xd9400000
[   26.973006] NDCB2: 0x00000000
[   26.973006] NDCB3: 0x00000000
[   26.991934] nand: nand_do_read_oob: from = 0x06cc0000, len = 64
[   26.997965] marvell-nfc pxa3xx-nand: 
[   26.997965] NDCR:  0x9d079fff
[   26.997965] NDCB0: 0x000d3000
[   26.997965] NDCB1: 0xd9800000
[   26.997965] NDCB2: 0x00000000
[   26.997965] NDCB3: 0x00000000
[   27.016907] nand: nand_do_read_oob: from = 0x06ce0000, len = 64
[   27.023114] marvell-nfc pxa3xx-nand: 
[   27.023114] NDCR:  0x9d079fff
[   27.023114] NDCB0: 0x000d3000
[   27.023114] NDCB1: 0xd9c00000
[   27.023114] NDCB2: 0x00000000
[   27.023114] NDCB3: 0x00000000
[   27.042039] nand: nand_do_read_oob: from = 0x06d00000, len = 64
[   27.048071] marvell-nfc pxa3xx-nand: 
[   27.048071] NDCR:  0x9d079fff
[   27.048071] NDCB0: 0x000d3000
[   27.048071] NDCB1: 0xda000000
[   27.048071] NDCB2: 0x00000000
[   27.048071] NDCB3: 0x00000000
[   27.067005] nand: nand_do_read_oob: from = 0x06d20000, len = 64
[   27.073211] marvell-nfc pxa3xx-nand: 
[   27.073211] NDCR:  0x9d079fff
[   27.073211] NDCB0: 0x000d3000
[   27.073211] NDCB1: 0xda400000
[   27.073211] NDCB2: 0x00000000
[   27.073211] NDCB3: 0x00000000
[   27.092136] nand: nand_do_read_oob: from = 0x06d40000, len = 64
[   27.098171] marvell-nfc pxa3xx-nand: 
[   27.098171] NDCR:  0x9d079fff
[   27.098171] NDCB0: 0x000d3000
[   27.098171] NDCB1: 0xda800000
[   27.098171] NDCB2: 0x00000000
[   27.098171] NDCB3: 0x00000000
[   27.117101] nand: nand_do_read_oob: from = 0x06d60000, len = 64
[   27.123300] marvell-nfc pxa3xx-nand: 
[   27.123300] NDCR:  0x9d079fff
[   27.123300] NDCB0: 0x000d3000
[   27.123300] NDCB1: 0xdac00000
[   27.123300] NDCB2: 0x00000000
[   27.123300] NDCB3: 0x00000000
[   27.142227] nand: nand_do_read_oob: from = 0x06d80000, len = 64
[   27.148260] marvell-nfc pxa3xx-nand: 
[   27.148260] NDCR:  0x9d079fff
[   27.148260] NDCB0: 0x000d3000
[   27.148260] NDCB1: 0xdb000000
[   27.148260] NDCB2: 0x00000000
[   27.148260] NDCB3: 0x00000000
[   27.167192] nand: nand_do_read_oob: from = 0x06da0000, len = 64
[   27.173398] marvell-nfc pxa3xx-nand: 
[   27.173398] NDCR:  0x9d079fff
[   27.173398] NDCB0: 0x000d3000
[   27.173398] NDCB1: 0xdb400000
[   27.173398] NDCB2: 0x00000000
[   27.173398] NDCB3: 0x00000000
[   27.192326] nand: nand_do_read_oob: from = 0x06dc0000, len = 64
[   27.198359] marvell-nfc pxa3xx-nand: 
[   27.198359] NDCR:  0x9d079fff
[   27.198359] NDCB0: 0x000d3000
[   27.198359] NDCB1: 0xdb800000
[   27.198359] NDCB2: 0x00000000
[   27.198359] NDCB3: 0x00000000
[   27.217290] nand: nand_do_read_oob: from = 0x06de0000, len = 64
[   27.223517] marvell-nfc pxa3xx-nand: 
[   27.223517] NDCR:  0x9d079fff
[   27.223517] NDCB0: 0x000d3000
[   27.223517] NDCB1: 0xdbc00000
[   27.223517] NDCB2: 0x00000000
[   27.223517] NDCB3: 0x00000000
[   27.242446] nand: nand_do_read_oob: from = 0x06e00000, len = 64
[   27.248475] marvell-nfc pxa3xx-nand: 
[   27.248475] NDCR:  0x9d079fff
[   27.248475] NDCB0: 0x000d3000
[   27.248475] NDCB1: 0xdc000000
[   27.248475] NDCB2: 0x00000000
[   27.248475] NDCB3: 0x00000000
[   27.267405] nand: nand_do_read_oob: from = 0x06e20000, len = 64
[   27.273605] marvell-nfc pxa3xx-nand: 
[   27.273605] NDCR:  0x9d079fff
[   27.273605] NDCB0: 0x000d3000
[   27.273605] NDCB1: 0xdc400000
[   27.273605] NDCB2: 0x00000000
[   27.273605] NDCB3: 0x00000000
[   27.292532] nand: nand_do_read_oob: from = 0x06e40000, len = 64
[   27.298563] marvell-nfc pxa3xx-nand: 
[   27.298563] NDCR:  0x9d079fff
[   27.298563] NDCB0: 0x000d3000
[   27.298563] NDCB1: 0xdc800000
[   27.298563] NDCB2: 0x00000000
[   27.298563] NDCB3: 0x00000000
[   27.317497] nand: nand_do_read_oob: from = 0x06e60000, len = 64
[   27.323702] marvell-nfc pxa3xx-nand: 
[   27.323702] NDCR:  0x9d079fff
[   27.323702] NDCB0: 0x000d3000
[   27.323702] NDCB1: 0xdcc00000
[   27.323702] NDCB2: 0x00000000
[   27.323702] NDCB3: 0x00000000
[   27.342630] nand: nand_do_read_oob: from = 0x06e80000, len = 64
[   27.348836] marvell-nfc pxa3xx-nand: 
[   27.348836] NDCR:  0x9d079fff
[   27.348836] NDCB0: 0x000d3000
[   27.348836] NDCB1: 0xdd000000
[   27.348836] NDCB2: 0x00000000
[   27.348836] NDCB3: 0x00000000
[   27.367746] nand: nand_do_read_oob: from = 0x06ea0000, len = 64
[   27.373948] marvell-nfc pxa3xx-nand: 
[   27.373948] NDCR:  0x9d079fff
[   27.373948] NDCB0: 0x000d3000
[   27.373948] NDCB1: 0xdd400000
[   27.373948] NDCB2: 0x00000000
[   27.373948] NDCB3: 0x00000000
[   27.392877] nand: nand_do_read_oob: from = 0x06ec0000, len = 64
[   27.399076] marvell-nfc pxa3xx-nand: 
[   27.399076] NDCR:  0x9d079fff
[   27.399076] NDCB0: 0x000d3000
[   27.399076] NDCB1: 0xdd800000
[   27.399076] NDCB2: 0x00000000
[   27.399076] NDCB3: 0x00000000
[   27.417998] nand: nand_do_read_oob: from = 0x06ee0000, len = 64
[   27.424199] marvell-nfc pxa3xx-nand: 
[   27.424199] NDCR:  0x9d079fff
[   27.424199] NDCB0: 0x000d3000
[   27.424199] NDCB1: 0xddc00000
[   27.424199] NDCB2: 0x00000000
[   27.424199] NDCB3: 0x00000000
[   27.443130] nand: nand_do_read_oob: from = 0x06f00000, len = 64
[   27.449332] marvell-nfc pxa3xx-nand: 
[   27.449332] NDCR:  0x9d079fff
[   27.449332] NDCB0: 0x000d3000
[   27.449332] NDCB1: 0xde000000
[   27.449332] NDCB2: 0x00000000
[   27.449332] NDCB3: 0x00000000
[   27.468253] nand: nand_do_read_oob: from = 0x06f20000, len = 64
[   27.474454] marvell-nfc pxa3xx-nand: 
[   27.474454] NDCR:  0x9d079fff
[   27.474454] NDCB0: 0x000d3000
[   27.474454] NDCB1: 0xde400000
[   27.474454] NDCB2: 0x00000000
[   27.474454] NDCB3: 0x00000000
[   27.493384] nand: nand_do_read_oob: from = 0x06f40000, len = 64
[   27.499585] marvell-nfc pxa3xx-nand: 
[   27.499585] NDCR:  0x9d079fff
[   27.499585] NDCB0: 0x000d3000
[   27.499585] NDCB1: 0xde800000
[   27.499585] NDCB2: 0x00000000
[   27.499585] NDCB3: 0x00000000
[   27.518504] nand: nand_do_read_oob: from = 0x06f60000, len = 64
[   27.524707] marvell-nfc pxa3xx-nand: 
[   27.524707] NDCR:  0x9d079fff
[   27.524707] NDCB0: 0x000d3000
[   27.524707] NDCB1: 0xdec00000
[   27.524707] NDCB2: 0x00000000
[   27.524707] NDCB3: 0x00000000
[   27.543638] nand: nand_do_read_oob: from = 0x06f80000, len = 64
[   27.549837] marvell-nfc pxa3xx-nand: 
[   27.549837] NDCR:  0x9d079fff
[   27.549837] NDCB0: 0x000d3000
[   27.549837] NDCB1: 0xdf000000
[   27.549837] NDCB2: 0x00000000
[   27.549837] NDCB3: 0x00000000
[   27.568841] nand: nand_do_read_oob: from = 0x06fa0000, len = 64
[   27.574880] marvell-nfc pxa3xx-nand: 
[   27.574880] NDCR:  0x9d079fff
[   27.574880] NDCB0: 0x000d3000
[   27.574880] NDCB1: 0xdf400000
[   27.574880] NDCB2: 0x00000000
[   27.574880] NDCB3: 0x00000000
[   27.593809] nand: nand_do_read_oob: from = 0x06fc0000, len = 64
[   27.600018] marvell-nfc pxa3xx-nand: 
[   27.600018] NDCR:  0x9d079fff
[   27.600018] NDCB0: 0x000d3000
[   27.600018] NDCB1: 0xdf800000
[   27.600018] NDCB2: 0x00000000
[   27.600018] NDCB3: 0x00000000
[   27.619130] nand: nand_do_read_oob: from = 0x06fe0000, len = 64
[   27.625167] marvell-nfc pxa3xx-nand: 
[   27.625167] NDCR:  0x9d079fff
[   27.625167] NDCB0: 0x000d3000
[   27.625167] NDCB1: 0xdfc00000
[   27.625167] NDCB2: 0x00000000
[   27.625167] NDCB3: 0x00000000
[   27.644107] nand: nand_do_read_oob: from = 0x07000000, len = 64
[   27.650314] marvell-nfc pxa3xx-nand: 
[   27.650314] NDCR:  0x9d079fff
[   27.650314] NDCB0: 0x000d3000
[   27.650314] NDCB1: 0xe0000000
[   27.650314] NDCB2: 0x00000000
[   27.650314] NDCB3: 0x00000000
[   27.669240] nand: nand_do_read_oob: from = 0x07020000, len = 64
[   27.675272] marvell-nfc pxa3xx-nand: 
[   27.675272] NDCR:  0x9d079fff
[   27.675272] NDCB0: 0x000d3000
[   27.675272] NDCB1: 0xe0400000
[   27.675272] NDCB2: 0x00000000
[   27.675272] NDCB3: 0x00000000
[   27.694205] nand: nand_do_read_oob: from = 0x07040000, len = 64
[   27.700411] marvell-nfc pxa3xx-nand: 
[   27.700411] NDCR:  0x9d079fff
[   27.700411] NDCB0: 0x000d3000
[   27.700411] NDCB1: 0xe0800000
[   27.700411] NDCB2: 0x00000000
[   27.700411] NDCB3: 0x00000000
[   27.719337] nand: nand_do_read_oob: from = 0x07060000, len = 64
[   27.725370] marvell-nfc pxa3xx-nand: 
[   27.725370] NDCR:  0x9d079fff
[   27.725370] NDCB0: 0x000d3000
[   27.725370] NDCB1: 0xe0c00000
[   27.725370] NDCB2: 0x00000000
[   27.725370] NDCB3: 0x00000000
[   27.744301] nand: nand_do_read_oob: from = 0x07080000, len = 64
[   27.750500] marvell-nfc pxa3xx-nand: 
[   27.750500] NDCR:  0x9d079fff
[   27.750500] NDCB0: 0x000d3000
[   27.750500] NDCB1: 0xe1000000
[   27.750500] NDCB2: 0x00000000
[   27.750500] NDCB3: 0x00000000
[   27.769428] nand: nand_do_read_oob: from = 0x070a0000, len = 64
[   27.775460] marvell-nfc pxa3xx-nand: 
[   27.775460] NDCR:  0x9d079fff
[   27.775460] NDCB0: 0x000d3000
[   27.775460] NDCB1: 0xe1400000
[   27.775460] NDCB2: 0x00000000
[   27.775460] NDCB3: 0x00000000
[   27.794390] nand: nand_do_read_oob: from = 0x070c0000, len = 64
[   27.800612] marvell-nfc pxa3xx-nand: 
[   27.800612] NDCR:  0x9d079fff
[   27.800612] NDCB0: 0x000d3000
[   27.800612] NDCB1: 0xe1800000
[   27.800612] NDCB2: 0x00000000
[   27.800612] NDCB3: 0x00000000
[   27.819547] nand: nand_do_read_oob: from = 0x070e0000, len = 64
[   27.825576] marvell-nfc pxa3xx-nand: 
[   27.825576] NDCR:  0x9d079fff
[   27.825576] NDCB0: 0x000d3000
[   27.825576] NDCB1: 0xe1c00000
[   27.825576] NDCB2: 0x00000000
[   27.825576] NDCB3: 0x00000000
[   27.844508] nand: nand_do_read_oob: from = 0x07100000, len = 64
[   27.850714] marvell-nfc pxa3xx-nand: 
[   27.850714] NDCR:  0x9d079fff
[   27.850714] NDCB0: 0x000d3000
[   27.850714] NDCB1: 0xe2000000
[   27.850714] NDCB2: 0x00000000
[   27.850714] NDCB3: 0x00000000
[   27.869641] nand: nand_do_read_oob: from = 0x07120000, len = 64
[   27.875675] marvell-nfc pxa3xx-nand: 
[   27.875675] NDCR:  0x9d079fff
[   27.875675] NDCB0: 0x000d3000
[   27.875675] NDCB1: 0xe2400000
[   27.875675] NDCB2: 0x00000000
[   27.875675] NDCB3: 0x00000000
[   27.894604] nand: nand_do_read_oob: from = 0x07140000, len = 64
[   27.900803] marvell-nfc pxa3xx-nand: 
[   27.900803] NDCR:  0x9d079fff
[   27.900803] NDCB0: 0x000d3000
[   27.900803] NDCB1: 0xe2800000
[   27.900803] NDCB2: 0x00000000
[   27.900803] NDCB3: 0x00000000
[   27.919734] nand: nand_do_read_oob: from = 0x07160000, len = 64
[   27.925764] marvell-nfc pxa3xx-nand: 
[   27.925764] NDCR:  0x9d079fff
[   27.925764] NDCB0: 0x000d3000
[   27.925764] NDCB1: 0xe2c00000
[   27.925764] NDCB2: 0x00000000
[   27.925764] NDCB3: 0x00000000
[   27.944696] nand: nand_do_read_oob: from = 0x07180000, len = 64
[   27.950902] marvell-nfc pxa3xx-nand: 
[   27.950902] NDCR:  0x9d079fff
[   27.950902] NDCB0: 0x000d3000
[   27.950902] NDCB1: 0xe3000000
[   27.950902] NDCB2: 0x00000000
[   27.950902] NDCB3: 0x00000000
[   27.969831] nand: nand_do_read_oob: from = 0x071a0000, len = 64
[   27.975860] marvell-nfc pxa3xx-nand: 
[   27.975860] NDCR:  0x9d079fff
[   27.975860] NDCB0: 0x000d3000
[   27.975860] NDCB1: 0xe3400000
[   27.975860] NDCB2: 0x00000000
[   27.975860] NDCB3: 0x00000000
[   27.994796] nand: nand_do_read_oob: from = 0x071c0000, len = 64
[   28.000998] marvell-nfc pxa3xx-nand: 
[   28.000998] NDCR:  0x9d079fff
[   28.000998] NDCB0: 0x000d3000
[   28.000998] NDCB1: 0xe3800000
[   28.000998] NDCB2: 0x00000000
[   28.000998] NDCB3: 0x00000000
[   28.019940] nand: nand_do_read_oob: from = 0x071e0000, len = 64
[   28.025971] marvell-nfc pxa3xx-nand: 
[   28.025971] NDCR:  0x9d079fff
[   28.025971] NDCB0: 0x000d3000
[   28.025971] NDCB1: 0xe3c00000
[   28.025971] NDCB2: 0x00000000
[   28.025971] NDCB3: 0x00000000
[   28.044903] nand: nand_do_read_oob: from = 0x07200000, len = 64
[   28.051109] marvell-nfc pxa3xx-nand: 
[   28.051109] NDCR:  0x9d079fff
[   28.051109] NDCB0: 0x000d3000
[   28.051109] NDCB1: 0xe4000000
[   28.051109] NDCB2: 0x00000000
[   28.051109] NDCB3: 0x00000000
[   28.070037] nand: nand_do_read_oob: from = 0x07220000, len = 64
[   28.076068] marvell-nfc pxa3xx-nand: 
[   28.076068] NDCR:  0x9d079fff
[   28.076068] NDCB0: 0x000d3000
[   28.076068] NDCB1: 0xe4400000
[   28.076068] NDCB2: 0x00000000
[   28.076068] NDCB3: 0x00000000
[   28.095434] nand: nand_do_read_oob: from = 0x07240000, len = 64
[   28.101671] marvell-nfc pxa3xx-nand: 
[   28.101671] NDCR:  0x9d079fff
[   28.101671] NDCB0: 0x000d3000
[   28.101671] NDCB1: 0xe4800000
[   28.101671] NDCB2: 0x00000000
[   28.101671] NDCB3: 0x00000000
[   28.120611] nand: nand_do_read_oob: from = 0x07260000, len = 64
[   28.126640] marvell-nfc pxa3xx-nand: 
[   28.126640] NDCR:  0x9d079fff
[   28.126640] NDCB0: 0x000d3000
[   28.126640] NDCB1: 0xe4c00000
[   28.126640] NDCB2: 0x00000000
[   28.126640] NDCB3: 0x00000000
[   28.145571] nand: nand_do_read_oob: from = 0x07280000, len = 64
[   28.151769] marvell-nfc pxa3xx-nand: 
[   28.151769] NDCR:  0x9d079fff
[   28.151769] NDCB0: 0x000d3000
[   28.151769] NDCB1: 0xe5000000
[   28.151769] NDCB2: 0x00000000
[   28.151769] NDCB3: 0x00000000
[   28.170698] nand: nand_do_read_oob: from = 0x072a0000, len = 64
[   28.176731] marvell-nfc pxa3xx-nand: 
[   28.176731] NDCR:  0x9d079fff
[   28.176731] NDCB0: 0x000d3000
[   28.176731] NDCB1: 0xe5400000
[   28.176731] NDCB2: 0x00000000
[   28.176731] NDCB3: 0x00000000
[   28.195663] nand: nand_do_read_oob: from = 0x072c0000, len = 64
[   28.201868] marvell-nfc pxa3xx-nand: 
[   28.201868] NDCR:  0x9d079fff
[   28.201868] NDCB0: 0x000d3000
[   28.201868] NDCB1: 0xe5800000
[   28.201868] NDCB2: 0x00000000
[   28.201868] NDCB3: 0x00000000
[   28.220798] nand: nand_do_read_oob: from = 0x072e0000, len = 64
[   28.226829] marvell-nfc pxa3xx-nand: 
[   28.226829] NDCR:  0x9d079fff
[   28.226829] NDCB0: 0x000d3000
[   28.226829] NDCB1: 0xe5c00000
[   28.226829] NDCB2: 0x00000000
[   28.226829] NDCB3: 0x00000000
[   28.245763] nand: nand_do_read_oob: from = 0x07300000, len = 64
[   28.251966] marvell-nfc pxa3xx-nand: 
[   28.251966] NDCR:  0x9d079fff
[   28.251966] NDCB0: 0x000d3000
[   28.251966] NDCB1: 0xe6000000
[   28.251966] NDCB2: 0x00000000
[   28.251966] NDCB3: 0x00000000
[   28.270902] nand: nand_do_read_oob: from = 0x07320000, len = 64
[   28.276935] marvell-nfc pxa3xx-nand: 
[   28.276935] NDCR:  0x9d079fff
[   28.276935] NDCB0: 0x000d3000
[   28.276935] NDCB1: 0xe6400000
[   28.276935] NDCB2: 0x00000000
[   28.276935] NDCB3: 0x00000000
[   28.295873] nand: nand_do_read_oob: from = 0x07340000, len = 64
[   28.302075] marvell-nfc pxa3xx-nand: 
[   28.302075] NDCR:  0x9d079fff
[   28.302075] NDCB0: 0x000d3000
[   28.302075] NDCB1: 0xe6800000
[   28.302075] NDCB2: 0x00000000
[   28.302075] NDCB3: 0x00000000
[   28.321004] nand: nand_do_read_oob: from = 0x07360000, len = 64
[   28.327035] marvell-nfc pxa3xx-nand: 
[   28.327035] NDCR:  0x9d079fff
[   28.327035] NDCB0: 0x000d3000
[   28.327035] NDCB1: 0xe6c00000
[   28.327035] NDCB2: 0x00000000
[   28.327035] NDCB3: 0x00000000
[   28.345967] nand: nand_do_read_oob: from = 0x07380000, len = 64
[   28.352174] marvell-nfc pxa3xx-nand: 
[   28.352174] NDCR:  0x9d079fff
[   28.352174] NDCB0: 0x000d3000
[   28.352174] NDCB1: 0xe7000000
[   28.352174] NDCB2: 0x00000000
[   28.352174] NDCB3: 0x00000000
[   28.371103] nand: nand_do_read_oob: from = 0x073a0000, len = 64
[   28.377134] marvell-nfc pxa3xx-nand: 
[   28.377134] NDCR:  0x9d079fff
[   28.377134] NDCB0: 0x000d3000
[   28.377134] NDCB1: 0xe7400000
[   28.377134] NDCB2: 0x00000000
[   28.377134] NDCB3: 0x00000000
[   28.396067] nand: nand_do_read_oob: from = 0x073c0000, len = 64
[   28.402271] marvell-nfc pxa3xx-nand: 
[   28.402271] NDCR:  0x9d079fff
[   28.402271] NDCB0: 0x000d3000
[   28.402271] NDCB1: 0xe7800000
[   28.402271] NDCB2: 0x00000000
[   28.402271] NDCB3: 0x00000000
[   28.421201] nand: nand_do_read_oob: from = 0x073e0000, len = 64
[   28.427231] marvell-nfc pxa3xx-nand: 
[   28.427231] NDCR:  0x9d079fff
[   28.427231] NDCB0: 0x000d3000
[   28.427231] NDCB1: 0xe7c00000
[   28.427231] NDCB2: 0x00000000
[   28.427231] NDCB3: 0x00000000
[   28.446189] nand: nand_do_read_oob: from = 0x07400000, len = 64
[   28.452395] marvell-nfc pxa3xx-nand: 
[   28.452395] NDCR:  0x9d079fff
[   28.452395] NDCB0: 0x000d3000
[   28.452395] NDCB1: 0xe8000000
[   28.452395] NDCB2: 0x00000000
[   28.452395] NDCB3: 0x00000000
[   28.471327] nand: nand_do_read_oob: from = 0x07420000, len = 64
[   28.477365] marvell-nfc pxa3xx-nand: 
[   28.477365] NDCR:  0x9d079fff
[   28.477365] NDCB0: 0x000d3000
[   28.477365] NDCB1: 0xe8400000
[   28.477365] NDCB2: 0x00000000
[   28.477365] NDCB3: 0x00000000
[   28.496300] nand: nand_do_read_oob: from = 0x07440000, len = 64
[   28.502502] marvell-nfc pxa3xx-nand: 
[   28.502502] NDCR:  0x9d079fff
[   28.502502] NDCB0: 0x000d3000
[   28.502502] NDCB1: 0xe8800000
[   28.502502] NDCB2: 0x00000000
[   28.502502] NDCB3: 0x00000000
[   28.521431] nand: nand_do_read_oob: from = 0x07460000, len = 64
[   28.527463] marvell-nfc pxa3xx-nand: 
[   28.527463] NDCR:  0x9d079fff
[   28.527463] NDCB0: 0x000d3000
[   28.527463] NDCB1: 0xe8c00000
[   28.527463] NDCB2: 0x00000000
[   28.527463] NDCB3: 0x00000000
[   28.546395] nand: nand_do_read_oob: from = 0x07480000, len = 64
[   28.552599] marvell-nfc pxa3xx-nand: 
[   28.552599] NDCR:  0x9d079fff
[   28.552599] NDCB0: 0x000d3000
[   28.552599] NDCB1: 0xe9000000
[   28.552599] NDCB2: 0x00000000
[   28.552599] NDCB3: 0x00000000
[   28.571530] nand: nand_do_read_oob: from = 0x074a0000, len = 64
[   28.577562] marvell-nfc pxa3xx-nand: 
[   28.577562] NDCR:  0x9d079fff
[   28.577562] NDCB0: 0x000d3000
[   28.577562] NDCB1: 0xe9400000
[   28.577562] NDCB2: 0x00000000
[   28.577562] NDCB3: 0x00000000
[   28.596495] nand: nand_do_read_oob: from = 0x074c0000, len = 64
[   28.602698] marvell-nfc pxa3xx-nand: 
[   28.602698] NDCR:  0x9d079fff
[   28.602698] NDCB0: 0x000d3000
[   28.602698] NDCB1: 0xe9800000
[   28.602698] NDCB2: 0x00000000
[   28.602698] NDCB3: 0x00000000
[   28.621629] nand: nand_do_read_oob: from = 0x074e0000, len = 64
[   28.627660] marvell-nfc pxa3xx-nand: 
[   28.627660] NDCR:  0x9d079fff
[   28.627660] NDCB0: 0x000d3000
[   28.627660] NDCB1: 0xe9c00000
[   28.627660] NDCB2: 0x00000000
[   28.627660] NDCB3: 0x00000000
[   28.646593] nand: nand_do_read_oob: from = 0x07500000, len = 64
[   28.652797] marvell-nfc pxa3xx-nand: 
[   28.652797] NDCR:  0x9d079fff
[   28.652797] NDCB0: 0x000d3000
[   28.652797] NDCB1: 0xea000000
[   28.652797] NDCB2: 0x00000000
[   28.652797] NDCB3: 0x00000000
[   28.671727] nand: nand_do_read_oob: from = 0x07520000, len = 64
[   28.677758] marvell-nfc pxa3xx-nand: 
[   28.677758] NDCR:  0x9d079fff
[   28.677758] NDCB0: 0x000d3000
[   28.677758] NDCB1: 0xea400000
[   28.677758] NDCB2: 0x00000000
[   28.677758] NDCB3: 0x00000000
[   28.696690] nand: nand_do_read_oob: from = 0x07540000, len = 64
[   28.702896] marvell-nfc pxa3xx-nand: 
[   28.702896] NDCR:  0x9d079fff
[   28.702896] NDCB0: 0x000d3000
[   28.702896] NDCB1: 0xea800000
[   28.702896] NDCB2: 0x00000000
[   28.702896] NDCB3: 0x00000000
[   28.721826] nand: nand_do_read_oob: from = 0x07560000, len = 64
[   28.727857] marvell-nfc pxa3xx-nand: 
[   28.727857] NDCR:  0x9d079fff
[   28.727857] NDCB0: 0x000d3000
[   28.727857] NDCB1: 0xeac00000
[   28.727857] NDCB2: 0x00000000
[   28.727857] NDCB3: 0x00000000
[   28.746788] nand: nand_do_read_oob: from = 0x07580000, len = 64
[   28.752993] marvell-nfc pxa3xx-nand: 
[   28.752993] NDCR:  0x9d079fff
[   28.752993] NDCB0: 0x000d3000
[   28.752993] NDCB1: 0xeb000000
[   28.752993] NDCB2: 0x00000000
[   28.752993] NDCB3: 0x00000000
[   28.771924] nand: nand_do_read_oob: from = 0x075a0000, len = 64
[   28.777955] marvell-nfc pxa3xx-nand: 
[   28.777955] NDCR:  0x9d079fff
[   28.777955] NDCB0: 0x000d3000
[   28.777955] NDCB1: 0xeb400000
[   28.777955] NDCB2: 0x00000000
[   28.777955] NDCB3: 0x00000000
[   28.796887] nand: nand_do_read_oob: from = 0x075c0000, len = 64
[   28.803092] marvell-nfc pxa3xx-nand: 
[   28.803092] NDCR:  0x9d079fff
[   28.803092] NDCB0: 0x000d3000
[   28.803092] NDCB1: 0xeb800000
[   28.803092] NDCB2: 0x00000000
[   28.803092] NDCB3: 0x00000000
[   28.822020] nand: nand_do_read_oob: from = 0x075e0000, len = 64
[   28.828053] marvell-nfc pxa3xx-nand: 
[   28.828053] NDCR:  0x9d079fff
[   28.828053] NDCB0: 0x000d3000
[   28.828053] NDCB1: 0xebc00000
[   28.828053] NDCB2: 0x00000000
[   28.828053] NDCB3: 0x00000000
[   28.846987] nand: nand_do_read_oob: from = 0x07600000, len = 64
[   28.853193] marvell-nfc pxa3xx-nand: 
[   28.853193] NDCR:  0x9d079fff
[   28.853193] NDCB0: 0x000d3000
[   28.853193] NDCB1: 0xec000000
[   28.853193] NDCB2: 0x00000000
[   28.853193] NDCB3: 0x00000000
[   28.872122] nand: nand_do_read_oob: from = 0x07620000, len = 64
[   28.878151] marvell-nfc pxa3xx-nand: 
[   28.878151] NDCR:  0x9d079fff
[   28.878151] NDCB0: 0x000d3000
[   28.878151] NDCB1: 0xec400000
[   28.878151] NDCB2: 0x00000000
[   28.878151] NDCB3: 0x00000000
[   28.897086] nand: nand_do_read_oob: from = 0x07640000, len = 64
[   28.903291] marvell-nfc pxa3xx-nand: 
[   28.903291] NDCR:  0x9d079fff
[   28.903291] NDCB0: 0x000d3000
[   28.903291] NDCB1: 0xec800000
[   28.903291] NDCB2: 0x00000000
[   28.903291] NDCB3: 0x00000000
[   28.922220] nand: nand_do_read_oob: from = 0x07660000, len = 64
[   28.928250] marvell-nfc pxa3xx-nand: 
[   28.928250] NDCR:  0x9d079fff
[   28.928250] NDCB0: 0x000d3000
[   28.928250] NDCB1: 0xecc00000
[   28.928250] NDCB2: 0x00000000
[   28.928250] NDCB3: 0x00000000
[   28.947184] nand: nand_do_read_oob: from = 0x07680000, len = 64
[   28.953390] marvell-nfc pxa3xx-nand: 
[   28.953390] NDCR:  0x9d079fff
[   28.953390] NDCB0: 0x000d3000
[   28.953390] NDCB1: 0xed000000
[   28.953390] NDCB2: 0x00000000
[   28.953390] NDCB3: 0x00000000
[   28.972318] nand: nand_do_read_oob: from = 0x076a0000, len = 64
[   28.978348] marvell-nfc pxa3xx-nand: 
[   28.978348] NDCR:  0x9d079fff
[   28.978348] NDCB0: 0x000d3000
[   28.978348] NDCB1: 0xed400000
[   28.978348] NDCB2: 0x00000000
[   28.978348] NDCB3: 0x00000000
[   28.997279] nand: nand_do_read_oob: from = 0x076c0000, len = 64
[   29.003476] marvell-nfc pxa3xx-nand: 
[   29.003476] NDCR:  0x9d079fff
[   29.003476] NDCB0: 0x000d3000
[   29.003476] NDCB1: 0xed800000
[   29.003476] NDCB2: 0x00000000
[   29.003476] NDCB3: 0x00000000
[   29.022420] nand: nand_do_read_oob: from = 0x076e0000, len = 64
[   29.028448] marvell-nfc pxa3xx-nand: 
[   29.028448] NDCR:  0x9d079fff
[   29.028448] NDCB0: 0x000d3000
[   29.028448] NDCB1: 0xedc00000
[   29.028448] NDCB2: 0x00000000
[   29.028448] NDCB3: 0x00000000
[   29.047381] nand: nand_do_read_oob: from = 0x07700000, len = 64
[   29.053585] marvell-nfc pxa3xx-nand: 
[   29.053585] NDCR:  0x9d079fff
[   29.053585] NDCB0: 0x000d3000
[   29.053585] NDCB1: 0xee000000
[   29.053585] NDCB2: 0x00000000
[   29.053585] NDCB3: 0x00000000
[   29.072517] nand: nand_do_read_oob: from = 0x07720000, len = 64
[   29.078545] marvell-nfc pxa3xx-nand: 
[   29.078545] NDCR:  0x9d079fff
[   29.078545] NDCB0: 0x000d3000
[   29.078545] NDCB1: 0xee400000
[   29.078545] NDCB2: 0x00000000
[   29.078545] NDCB3: 0x00000000
[   29.097499] nand: nand_do_read_oob: from = 0x07740000, len = 64
[   29.103703] marvell-nfc pxa3xx-nand: 
[   29.103703] NDCR:  0x9d079fff
[   29.103703] NDCB0: 0x000d3000
[   29.103703] NDCB1: 0xee800000
[   29.103703] NDCB2: 0x00000000
[   29.103703] NDCB3: 0x00000000
[   29.122630] nand: nand_do_read_oob: from = 0x07760000, len = 64
[   29.128834] marvell-nfc pxa3xx-nand: 
[   29.128834] NDCR:  0x9d079fff
[   29.128834] NDCB0: 0x000d3000
[   29.128834] NDCB1: 0xeec00000
[   29.128834] NDCB2: 0x00000000
[   29.128834] NDCB3: 0x00000000
[   29.147744] nand: nand_do_read_oob: from = 0x07780000, len = 64
[   29.153944] marvell-nfc pxa3xx-nand: 
[   29.153944] NDCR:  0x9d079fff
[   29.153944] NDCB0: 0x000d3000
[   29.153944] NDCB1: 0xef000000
[   29.153944] NDCB2: 0x00000000
[   29.153944] NDCB3: 0x00000000
[   29.172876] nand: nand_do_read_oob: from = 0x077a0000, len = 64
[   29.179077] marvell-nfc pxa3xx-nand: 
[   29.179077] NDCR:  0x9d079fff
[   29.179077] NDCB0: 0x000d3000
[   29.179077] NDCB1: 0xef400000
[   29.179077] NDCB2: 0x00000000
[   29.179077] NDCB3: 0x00000000
[   29.197999] nand: nand_do_read_oob: from = 0x077c0000, len = 64
[   29.204198] marvell-nfc pxa3xx-nand: 
[   29.204198] NDCR:  0x9d079fff
[   29.204198] NDCB0: 0x000d3000
[   29.204198] NDCB1: 0xef800000
[   29.204198] NDCB2: 0x00000000
[   29.204198] NDCB3: 0x00000000
[   29.223128] nand: nand_do_read_oob: from = 0x077e0000, len = 64
[   29.229328] marvell-nfc pxa3xx-nand: 
[   29.229328] NDCR:  0x9d079fff
[   29.229328] NDCB0: 0x000d3000
[   29.229328] NDCB1: 0xefc00000
[   29.229328] NDCB2: 0x00000000
[   29.229328] NDCB3: 0x00000000
[   29.248252] nand: nand_do_read_oob: from = 0x07800000, len = 64
[   29.254452] marvell-nfc pxa3xx-nand: 
[   29.254452] NDCR:  0x9d079fff
[   29.254452] NDCB0: 0x000d3000
[   29.254452] NDCB1: 0xf0000000
[   29.254452] NDCB2: 0x00000000
[   29.254452] NDCB3: 0x00000000
[   29.273384] nand: nand_do_read_oob: from = 0x07820000, len = 64
[   29.279582] marvell-nfc pxa3xx-nand: 
[   29.279582] NDCR:  0x9d079fff
[   29.279582] NDCB0: 0x000d3000
[   29.279582] NDCB1: 0xf0400000
[   29.279582] NDCB2: 0x00000000
[   29.279582] NDCB3: 0x00000000
[   29.298824] nand: nand_do_read_oob: from = 0x07840000, len = 64
[   29.304868] marvell-nfc pxa3xx-nand: 
[   29.304868] NDCR:  0x9d079fff
[   29.304868] NDCB0: 0x000d3000
[   29.304868] NDCB1: 0xf0800000
[   29.304868] NDCB2: 0x00000000
[   29.304868] NDCB3: 0x00000000
[   29.323796] nand: nand_do_read_oob: from = 0x07860000, len = 64
[   29.330003] marvell-nfc pxa3xx-nand: 
[   29.330003] NDCR:  0x9d079fff
[   29.330003] NDCB0: 0x000d3000
[   29.330003] NDCB1: 0xf0c00000
[   29.330003] NDCB2: 0x00000000
[   29.330003] NDCB3: 0x00000000
[   29.348991] nand: nand_do_read_oob: from = 0x07880000, len = 64
[   29.355023] marvell-nfc pxa3xx-nand: 
[   29.355023] NDCR:  0x9d079fff
[   29.355023] NDCB0: 0x000d3000
[   29.355023] NDCB1: 0xf1000000
[   29.355023] NDCB2: 0x00000000
[   29.355023] NDCB3: 0x00000000
[   29.373955] nand: nand_do_read_oob: from = 0x078a0000, len = 64
[   29.380161] marvell-nfc pxa3xx-nand: 
[   29.380161] NDCR:  0x9d079fff
[   29.380161] NDCB0: 0x000d3000
[   29.380161] NDCB1: 0xf1400000
[   29.380161] NDCB2: 0x00000000
[   29.380161] NDCB3: 0x00000000
[   29.399089] nand: nand_do_read_oob: from = 0x078c0000, len = 64
[   29.405120] marvell-nfc pxa3xx-nand: 
[   29.405120] NDCR:  0x9d079fff
[   29.405120] NDCB0: 0x000d3000
[   29.405120] NDCB1: 0xf1800000
[   29.405120] NDCB2: 0x00000000
[   29.405120] NDCB3: 0x00000000
[   29.424052] nand: nand_do_read_oob: from = 0x078e0000, len = 64
[   29.430260] marvell-nfc pxa3xx-nand: 
[   29.430260] NDCR:  0x9d079fff
[   29.430260] NDCB0: 0x000d3000
[   29.430260] NDCB1: 0xf1c00000
[   29.430260] NDCB2: 0x00000000
[   29.430260] NDCB3: 0x00000000
[   29.449188] nand: nand_do_read_oob: from = 0x07900000, len = 64
[   29.455218] marvell-nfc pxa3xx-nand: 
[   29.455218] NDCR:  0x9d079fff
[   29.455218] NDCB0: 0x000d3000
[   29.455218] NDCB1: 0xf2000000
[   29.455218] NDCB2: 0x00000000
[   29.455218] NDCB3: 0x00000000
[   29.474151] nand: nand_do_read_oob: from = 0x07920000, len = 64
[   29.480357] marvell-nfc pxa3xx-nand: 
[   29.480357] NDCR:  0x9d079fff
[   29.480357] NDCB0: 0x000d3000
[   29.480357] NDCB1: 0xf2400000
[   29.480357] NDCB2: 0x00000000
[   29.480357] NDCB3: 0x00000000
[   29.499286] nand: nand_do_read_oob: from = 0x07940000, len = 64
[   29.505317] marvell-nfc pxa3xx-nand: 
[   29.505317] NDCR:  0x9d079fff
[   29.505317] NDCB0: 0x000d3000
[   29.505317] NDCB1: 0xf2800000
[   29.505317] NDCB2: 0x00000000
[   29.505317] NDCB3: 0x00000000
[   29.524250] nand: nand_do_read_oob: from = 0x07960000, len = 64
[   29.530454] marvell-nfc pxa3xx-nand: 
[   29.530454] NDCR:  0x9d079fff
[   29.530454] NDCB0: 0x000d3000
[   29.530454] NDCB1: 0xf2c00000
[   29.530454] NDCB2: 0x00000000
[   29.530454] NDCB3: 0x00000000
[   29.549385] nand: nand_do_read_oob: from = 0x07980000, len = 64
[   29.555416] marvell-nfc pxa3xx-nand: 
[   29.555416] NDCR:  0x9d079fff
[   29.555416] NDCB0: 0x000d3000
[   29.555416] NDCB1: 0xf3000000
[   29.555416] NDCB2: 0x00000000
[   29.555416] NDCB3: 0x00000000
[   29.574347] nand: nand_do_read_oob: from = 0x079a0000, len = 64
[   29.580546] marvell-nfc pxa3xx-nand: 
[   29.580546] NDCR:  0x9d079fff
[   29.580546] NDCB0: 0x000d3000
[   29.580546] NDCB1: 0xf3400000
[   29.580546] NDCB2: 0x00000000
[   29.580546] NDCB3: 0x00000000
[   29.599474] nand: nand_do_read_oob: from = 0x079c0000, len = 64
[   29.605507] marvell-nfc pxa3xx-nand: 
[   29.605507] NDCR:  0x9d079fff
[   29.605507] NDCB0: 0x000d3000
[   29.605507] NDCB1: 0xf3800000
[   29.605507] NDCB2: 0x00000000
[   29.605507] NDCB3: 0x00000000
[   29.624438] nand: nand_do_read_oob: from = 0x079e0000, len = 64
[   29.630643] marvell-nfc pxa3xx-nand: 
[   29.630643] NDCR:  0x9d079fff
[   29.630643] NDCB0: 0x000d3000
[   29.630643] NDCB1: 0xf3c00000
[   29.630643] NDCB2: 0x00000000
[   29.630643] NDCB3: 0x00000000
[   29.649573] nand: nand_do_read_oob: from = 0x07a00000, len = 64
[   29.655605] marvell-nfc pxa3xx-nand: 
[   29.655605] NDCR:  0x9d079fff
[   29.655605] NDCB0: 0x000d3000
[   29.655605] NDCB1: 0xf4000000
[   29.655605] NDCB2: 0x00000000
[   29.655605] NDCB3: 0x00000000
[   29.674557] nand: nand_do_read_oob: from = 0x07a20000, len = 64
[   29.680759] marvell-nfc pxa3xx-nand: 
[   29.680759] NDCR:  0x9d079fff
[   29.680759] NDCB0: 0x000d3000
[   29.680759] NDCB1: 0xf4400000
[   29.680759] NDCB2: 0x00000000
[   29.680759] NDCB3: 0x00000000
[   29.699688] nand: nand_do_read_oob: from = 0x07a40000, len = 64
[   29.705720] marvell-nfc pxa3xx-nand: 
[   29.705720] NDCR:  0x9d079fff
[   29.705720] NDCB0: 0x000d3000
[   29.705720] NDCB1: 0xf4800000
[   29.705720] NDCB2: 0x00000000
[   29.705720] NDCB3: 0x00000000
[   29.724651] nand: nand_do_read_oob: from = 0x07a60000, len = 64
[   29.730851] marvell-nfc pxa3xx-nand: 
[   29.730851] NDCR:  0x9d079fff
[   29.730851] NDCB0: 0x000d3000
[   29.730851] NDCB1: 0xf4c00000
[   29.730851] NDCB2: 0x00000000
[   29.730851] NDCB3: 0x00000000
[   29.749779] nand: nand_do_read_oob: from = 0x07a80000, len = 64
[   29.755808] marvell-nfc pxa3xx-nand: 
[   29.755808] NDCR:  0x9d079fff
[   29.755808] NDCB0: 0x000d3000
[   29.755808] NDCB1: 0xf5000000
[   29.755808] NDCB2: 0x00000000
[   29.755808] NDCB3: 0x00000000
[   29.774743] nand: nand_do_read_oob: from = 0x07aa0000, len = 64
[   29.780949] marvell-nfc pxa3xx-nand: 
[   29.780949] NDCR:  0x9d079fff
[   29.780949] NDCB0: 0x000d3000
[   29.780949] NDCB1: 0xf5400000
[   29.780949] NDCB2: 0x00000000
[   29.780949] NDCB3: 0x00000000
[   29.799876] nand: nand_do_read_oob: from = 0x07ac0000, len = 64
[   29.805909] marvell-nfc pxa3xx-nand: 
[   29.805909] NDCR:  0x9d079fff
[   29.805909] NDCB0: 0x000d3000
[   29.805909] NDCB1: 0xf5800000
[   29.805909] NDCB2: 0x00000000
[   29.805909] NDCB3: 0x00000000
[   29.824842] nand: nand_do_read_oob: from = 0x07ae0000, len = 64
[   29.831048] marvell-nfc pxa3xx-nand: 
[   29.831048] NDCR:  0x9d079fff
[   29.831048] NDCB0: 0x000d3000
[   29.831048] NDCB1: 0xf5c00000
[   29.831048] NDCB2: 0x00000000
[   29.831048] NDCB3: 0x00000000
[   29.849975] nand: nand_do_read_oob: from = 0x07b00000, len = 64
[   29.856007] marvell-nfc pxa3xx-nand: 
[   29.856007] NDCR:  0x9d079fff
[   29.856007] NDCB0: 0x000d3000
[   29.856007] NDCB1: 0xf6000000
[   29.856007] NDCB2: 0x00000000
[   29.856007] NDCB3: 0x00000000
[   29.874944] nand: nand_do_read_oob: from = 0x07b20000, len = 64
[   29.881147] marvell-nfc pxa3xx-nand: 
[   29.881147] NDCR:  0x9d079fff
[   29.881147] NDCB0: 0x000d3000
[   29.881147] NDCB1: 0xf6400000
[   29.881147] NDCB2: 0x00000000
[   29.881147] NDCB3: 0x00000000
[   29.900075] nand: nand_do_read_oob: from = 0x07b40000, len = 64
[   29.906105] marvell-nfc pxa3xx-nand: 
[   29.906105] NDCR:  0x9d079fff
[   29.906105] NDCB0: 0x000d3000
[   29.906105] NDCB1: 0xf6800000
[   29.906105] NDCB2: 0x00000000
[   29.906105] NDCB3: 0x00000000
[   29.925038] nand: nand_do_read_oob: from = 0x07b60000, len = 64
[   29.931245] marvell-nfc pxa3xx-nand: 
[   29.931245] NDCR:  0x9d079fff
[   29.931245] NDCB0: 0x000d3000
[   29.931245] NDCB1: 0xf6c00000
[   29.931245] NDCB2: 0x00000000
[   29.931245] NDCB3: 0x00000000
[   29.950173] nand: nand_do_read_oob: from = 0x07b80000, len = 64
[   29.956205] marvell-nfc pxa3xx-nand: 
[   29.956205] NDCR:  0x9d079fff
[   29.956205] NDCB0: 0x000d3000
[   29.956205] NDCB1: 0xf7000000
[   29.956205] NDCB2: 0x00000000
[   29.956205] NDCB3: 0x00000000
[   29.975136] nand: nand_do_read_oob: from = 0x07ba0000, len = 64
[   29.981341] marvell-nfc pxa3xx-nand: 
[   29.981341] NDCR:  0x9d079fff
[   29.981341] NDCB0: 0x000d3000
[   29.981341] NDCB1: 0xf7400000
[   29.981341] NDCB2: 0x00000000
[   29.981341] NDCB3: 0x00000000
[   30.000271] nand: nand_do_read_oob: from = 0x07bc0000, len = 64
[   30.006303] marvell-nfc pxa3xx-nand: 
[   30.006303] NDCR:  0x9d079fff
[   30.006303] NDCB0: 0x000d3000
[   30.006303] NDCB1: 0xf7800000
[   30.006303] NDCB2: 0x00000000
[   30.006303] NDCB3: 0x00000000
[   30.025242] nand: nand_do_read_oob: from = 0x07be0000, len = 64
[   30.031450] marvell-nfc pxa3xx-nand: 
[   30.031450] NDCR:  0x9d079fff
[   30.031450] NDCB0: 0x000d3000
[   30.031450] NDCB1: 0xf7c00000
[   30.031450] NDCB2: 0x00000000
[   30.031450] NDCB3: 0x00000000
[   30.050378] nand: nand_do_read_oob: from = 0x07c00000, len = 64
[   30.056409] marvell-nfc pxa3xx-nand: 
[   30.056409] NDCR:  0x9d079fff
[   30.056409] NDCB0: 0x000d3000
[   30.056409] NDCB1: 0xf8000000
[   30.056409] NDCB2: 0x00000000
[   30.056409] NDCB3: 0x00000000
[   30.075347] nand: nand_do_read_oob: from = 0x07c20000, len = 64
[   30.081549] marvell-nfc pxa3xx-nand: 
[   30.081549] NDCR:  0x9d079fff
[   30.081549] NDCB0: 0x000d3000
[   30.081549] NDCB1: 0xf8400000
[   30.081549] NDCB2: 0x00000000
[   30.081549] NDCB3: 0x00000000
[   30.100810] nand: nand_do_read_oob: from = 0x07c40000, len = 64
[   30.106850] marvell-nfc pxa3xx-nand: 
[   30.106850] NDCR:  0x9d079fff
[   30.106850] NDCB0: 0x000d3000
[   30.106850] NDCB1: 0xf8800000
[   30.106850] NDCB2: 0x00000000
[   30.106850] NDCB3: 0x00000000
[   30.125809] nand: nand_do_read_oob: from = 0x07c60000, len = 64
[   30.132009] marvell-nfc pxa3xx-nand: 
[   30.132009] NDCR:  0x9d079fff
[   30.132009] NDCB0: 0x000d3000
[   30.132009] NDCB1: 0xf8c00000
[   30.132009] NDCB2: 0x00000000
[   30.132009] NDCB3: 0x00000000
[   30.150936] nand: nand_do_read_oob: from = 0x07c80000, len = 64
[   30.156969] marvell-nfc pxa3xx-nand: 
[   30.156969] NDCR:  0x9d079fff
[   30.156969] NDCB0: 0x000d3000
[   30.156969] NDCB1: 0xf9000000
[   30.156969] NDCB2: 0x00000000
[   30.156969] NDCB3: 0x00000000
[   30.175903] nand: nand_do_read_oob: from = 0x07ca0000, len = 64
[   30.182106] marvell-nfc pxa3xx-nand: 
[   30.182106] NDCR:  0x9d079fff
[   30.182106] NDCB0: 0x000d3000
[   30.182106] NDCB1: 0xf9400000
[   30.182106] NDCB2: 0x00000000
[   30.182106] NDCB3: 0x00000000
[   30.201034] nand: nand_do_read_oob: from = 0x07cc0000, len = 64
[   30.207066] marvell-nfc pxa3xx-nand: 
[   30.207066] NDCR:  0x9d079fff
[   30.207066] NDCB0: 0x000d3000
[   30.207066] NDCB1: 0xf9800000
[   30.207066] NDCB2: 0x00000000
[   30.207066] NDCB3: 0x00000000
[   30.225997] nand: nand_do_read_oob: from = 0x07ce0000, len = 64
[   30.232197] marvell-nfc pxa3xx-nand: 
[   30.232197] NDCR:  0x9d079fff
[   30.232197] NDCB0: 0x000d3000
[   30.232197] NDCB1: 0xf9c00000
[   30.232197] NDCB2: 0x00000000
[   30.232197] NDCB3: 0x00000000
[   30.251124] nand: nand_do_read_oob: from = 0x07d00000, len = 64
[   30.257156] marvell-nfc pxa3xx-nand: 
[   30.257156] NDCR:  0x9d079fff
[   30.257156] NDCB0: 0x000d3000
[   30.257156] NDCB1: 0xfa000000
[   30.257156] NDCB2: 0x00000000
[   30.257156] NDCB3: 0x00000000
[   30.276087] nand: nand_do_read_oob: from = 0x07d20000, len = 64
[   30.282295] marvell-nfc pxa3xx-nand: 
[   30.282295] NDCR:  0x9d079fff
[   30.282295] NDCB0: 0x000d3000
[   30.282295] NDCB1: 0xfa400000
[   30.282295] NDCB2: 0x00000000
[   30.282295] NDCB3: 0x00000000
[   30.301223] nand: nand_do_read_oob: from = 0x07d40000, len = 64
[   30.307254] marvell-nfc pxa3xx-nand: 
[   30.307254] NDCR:  0x9d079fff
[   30.307254] NDCB0: 0x000d3000
[   30.307254] NDCB1: 0xfa800000
[   30.307254] NDCB2: 0x00000000
[   30.307254] NDCB3: 0x00000000
[   30.326208] nand: nand_do_read_oob: from = 0x07d60000, len = 64
[   30.332412] marvell-nfc pxa3xx-nand: 
[   30.332412] NDCR:  0x9d079fff
[   30.332412] NDCB0: 0x000d3000
[   30.332412] NDCB1: 0xfac00000
[   30.332412] NDCB2: 0x00000000
[   30.332412] NDCB3: 0x00000000
[   30.351339] nand: nand_do_read_oob: from = 0x07d80000, len = 64
[   30.357370] marvell-nfc pxa3xx-nand: 
[   30.357370] NDCR:  0x9d079fff
[   30.357370] NDCB0: 0x000d3000
[   30.357370] NDCB1: 0xfb000000
[   30.357370] NDCB2: 0x00000000
[   30.357370] NDCB3: 0x00000000
[   30.376303] nand: nand_do_read_oob: from = 0x07da0000, len = 64
[   30.382509] marvell-nfc pxa3xx-nand: 
[   30.382509] NDCR:  0x9d079fff
[   30.382509] NDCB0: 0x000d3000
[   30.382509] NDCB1: 0xfb400000
[   30.382509] NDCB2: 0x00000000
[   30.382509] NDCB3: 0x00000000
[   30.401437] nand: nand_do_read_oob: from = 0x07dc0000, len = 64
[   30.407468] marvell-nfc pxa3xx-nand: 
[   30.407468] NDCR:  0x9d079fff
[   30.407468] NDCB0: 0x000d3000
[   30.407468] NDCB1: 0xfb800000
[   30.407468] NDCB2: 0x00000000
[   30.407468] NDCB3: 0x00000000
[   30.426400] nand: nand_do_read_oob: from = 0x07de0000, len = 64
[   30.432608] marvell-nfc pxa3xx-nand: 
[   30.432608] NDCR:  0x9d079fff
[   30.432608] NDCB0: 0x000d3000
[   30.432608] NDCB1: 0xfbc00000
[   30.432608] NDCB2: 0x00000000
[   30.432608] NDCB3: 0x00000000
[   30.451537] nand: nand_do_read_oob: from = 0x07e00000, len = 64
[   30.457568] marvell-nfc pxa3xx-nand: 
[   30.457568] NDCR:  0x9d079fff
[   30.457568] NDCB0: 0x000d3000
[   30.457568] NDCB1: 0xfc000000
[   30.457568] NDCB2: 0x00000000
[   30.457568] NDCB3: 0x00000000
[   30.476498] nand: nand_do_read_oob: from = 0x07e20000, len = 64
[   30.482695] marvell-nfc pxa3xx-nand: 
[   30.482695] NDCR:  0x9d079fff
[   30.482695] NDCB0: 0x000d3000
[   30.482695] NDCB1: 0xfc400000
[   30.482695] NDCB2: 0x00000000
[   30.482695] NDCB3: 0x00000000
[   30.501625] nand: nand_do_read_oob: from = 0x07e40000, len = 64
[   30.507657] marvell-nfc pxa3xx-nand: 
[   30.507657] NDCR:  0x9d079fff
[   30.507657] NDCB0: 0x000d3000
[   30.507657] NDCB1: 0xfc800000
[   30.507657] NDCB2: 0x00000000
[   30.507657] NDCB3: 0x00000000
[   30.526589] nand: nand_do_read_oob: from = 0x07e60000, len = 64
[   30.532794] marvell-nfc pxa3xx-nand: 
[   30.532794] NDCR:  0x9d079fff
[   30.532794] NDCB0: 0x000d3000
[   30.532794] NDCB1: 0xfcc00000
[   30.532794] NDCB2: 0x00000000
[   30.532794] NDCB3: 0x00000000
[   30.551723] nand: nand_do_read_oob: from = 0x07e80000, len = 64
[   30.557755] marvell-nfc pxa3xx-nand: 
[   30.557755] NDCR:  0x9d079fff
[   30.557755] NDCB0: 0x000d3000
[   30.557755] NDCB1: 0xfd000000
[   30.557755] NDCB2: 0x00000000
[   30.557755] NDCB3: 0x00000000
[   30.576689] nand: nand_do_read_oob: from = 0x07ea0000, len = 64
[   30.582895] marvell-nfc pxa3xx-nand: 
[   30.582895] NDCR:  0x9d079fff
[   30.582895] NDCB0: 0x000d3000
[   30.582895] NDCB1: 0xfd400000
[   30.582895] NDCB2: 0x00000000
[   30.582895] NDCB3: 0x00000000
[   30.601822] nand: nand_do_read_oob: from = 0x07ec0000, len = 64
[   30.607855] marvell-nfc pxa3xx-nand: 
[   30.607855] NDCR:  0x9d079fff
[   30.607855] NDCB0: 0x000d3000
[   30.607855] NDCB1: 0xfd800000
[   30.607855] NDCB2: 0x00000000
[   30.607855] NDCB3: 0x00000000
[   30.626788] nand: nand_do_read_oob: from = 0x07ee0000, len = 64
[   30.632994] marvell-nfc pxa3xx-nand: 
[   30.632994] NDCR:  0x9d079fff
[   30.632994] NDCB0: 0x000d3000
[   30.632994] NDCB1: 0xfdc00000
[   30.632994] NDCB2: 0x00000000
[   30.632994] NDCB3: 0x00000000
[   30.651920] nand: nand_do_read_oob: from = 0x07f00000, len = 64
[   30.657953] marvell-nfc pxa3xx-nand: 
[   30.657953] NDCR:  0x9d079fff
[   30.657953] NDCB0: 0x000d3000
[   30.657953] NDCB1: 0xfe000000
[   30.657953] NDCB2: 0x00000000
[   30.657953] NDCB3: 0x00000000
[   30.676890] nand: nand_do_read_oob: from = 0x07f20000, len = 64
[   30.683091] marvell-nfc pxa3xx-nand: 
[   30.683091] NDCR:  0x9d079fff
[   30.683091] NDCB0: 0x000d3000
[   30.683091] NDCB1: 0xfe400000
[   30.683091] NDCB2: 0x00000000
[   30.683091] NDCB3: 0x00000000
[   30.702019] nand: nand_do_read_oob: from = 0x07f40000, len = 64
[   30.708052] marvell-nfc pxa3xx-nand: 
[   30.708052] NDCR:  0x9d079fff
[   30.708052] NDCB0: 0x000d3000
[   30.708052] NDCB1: 0xfe800000
[   30.708052] NDCB2: 0x00000000
[   30.708052] NDCB3: 0x00000000
[   30.726984] nand: nand_do_read_oob: from = 0x07f60000, len = 64
[   30.733194] marvell-nfc pxa3xx-nand: 
[   30.733194] NDCR:  0x9d079fff
[   30.733194] NDCB0: 0x000d3000
[   30.733194] NDCB1: 0xfec00000
[   30.733194] NDCB2: 0x00000000
[   30.733194] NDCB3: 0x00000000
[   30.752117] nand: nand_do_read_oob: from = 0x07f80000, len = 64
[   30.758150] marvell-nfc pxa3xx-nand: 
[   30.758150] NDCR:  0x9d079fff
[   30.758150] NDCB0: 0x000d3000
[   30.758150] NDCB1: 0xff000000
[   30.758150] NDCB2: 0x00000000
[   30.758150] NDCB3: 0x00000000
[   30.777082] nand: nand_do_read_oob: from = 0x07fa0000, len = 64
[   30.783289] marvell-nfc pxa3xx-nand: 
[   30.783289] NDCR:  0x9d079fff
[   30.783289] NDCB0: 0x000d3000
[   30.783289] NDCB1: 0xff400000
[   30.783289] NDCB2: 0x00000000
[   30.783289] NDCB3: 0x00000000
[   30.802215] nand: nand_do_read_oob: from = 0x07fc0000, len = 64
[   30.808248] marvell-nfc pxa3xx-nand: 
[   30.808248] NDCR:  0x9d079fff
[   30.808248] NDCB0: 0x000d3000
[   30.808248] NDCB1: 0xff800000
[   30.808248] NDCB2: 0x00000000
[   30.808248] NDCB3: 0x00000000
[   30.827180] nand: nand_do_read_oob: from = 0x07fe0000, len = 64
[   30.833387] marvell-nfc pxa3xx-nand: 
[   30.833387] NDCR:  0x9d079fff
[   30.833387] NDCB0: 0x000d3000
[   30.833387] NDCB1: 0xffc00000
[   30.833387] NDCB2: 0x00000000
[   30.833387] NDCB3: 0x00000000
[   30.852314] nand: nand_do_read_oob: from = 0x08000000, len = 64
[   30.858343] marvell-nfc pxa3xx-nand: 
[   30.858343] NDCR:  0x9d079fff
[   30.858343] NDCB0: 0x000d3000
[   30.858343] NDCB1: 0x00000000
[   30.858343] NDCB2: 0x00000001
[   30.858343] NDCB3: 0x00000000
[   30.877280] nand: nand_do_read_oob: from = 0x08020000, len = 64
[   30.883486] marvell-nfc pxa3xx-nand: 
[   30.883486] NDCR:  0x9d079fff
[   30.883486] NDCB0: 0x000d3000
[   30.883486] NDCB1: 0x00400000
[   30.883486] NDCB2: 0x00000001
[   30.883486] NDCB3: 0x00000000
[   30.902417] nand: nand_do_read_oob: from = 0x08040000, len = 64
[   30.908445] marvell-nfc pxa3xx-nand: 
[   30.908445] NDCR:  0x9d079fff
[   30.908445] NDCB0: 0x000d3000
[   30.908445] NDCB1: 0x00800000
[   30.908445] NDCB2: 0x00000001
[   30.908445] NDCB3: 0x00000000
[   30.927379] nand: nand_do_read_oob: from = 0x08060000, len = 64
[   30.933580] marvell-nfc pxa3xx-nand: 
[   30.933580] NDCR:  0x9d079fff
[   30.933580] NDCB0: 0x000d3000
[   30.933580] NDCB1: 0x00c00000
[   30.933580] NDCB2: 0x00000001
[   30.933580] NDCB3: 0x00000000
[   30.952528] nand: nand_do_read_oob: from = 0x08080000, len = 64
[   30.958561] marvell-nfc pxa3xx-nand: 
[   30.958561] NDCR:  0x9d079fff
[   30.958561] NDCB0: 0x000d3000
[   30.958561] NDCB1: 0x01000000
[   30.958561] NDCB2: 0x00000001
[   30.958561] NDCB3: 0x00000000
[   30.977494] nand: nand_do_read_oob: from = 0x080a0000, len = 64
[   30.983701] marvell-nfc pxa3xx-nand: 
[   30.983701] NDCR:  0x9d079fff
[   30.983701] NDCB0: 0x000d3000
[   30.983701] NDCB1: 0x01400000
[   30.983701] NDCB2: 0x00000001
[   30.983701] NDCB3: 0x00000000
[   31.002627] nand: nand_do_read_oob: from = 0x080c0000, len = 64
[   31.008841] marvell-nfc pxa3xx-nand: 
[   31.008841] NDCR:  0x9d079fff
[   31.008841] NDCB0: 0x000d3000
[   31.008841] NDCB1: 0x01800000
[   31.008841] NDCB2: 0x00000001
[   31.008841] NDCB3: 0x00000000
[   31.027751] nand: nand_do_read_oob: from = 0x080e0000, len = 64
[   31.033952] marvell-nfc pxa3xx-nand: 
[   31.033952] NDCR:  0x9d079fff
[   31.033952] NDCB0: 0x000d3000
[   31.033952] NDCB1: 0x01c00000
[   31.033952] NDCB2: 0x00000001
[   31.033952] NDCB3: 0x00000000
[   31.052881] nand: nand_do_read_oob: from = 0x08100000, len = 64
[   31.059081] marvell-nfc pxa3xx-nand: 
[   31.059081] NDCR:  0x9d079fff
[   31.059081] NDCB0: 0x000d3000
[   31.059081] NDCB1: 0x02000000
[   31.059081] NDCB2: 0x00000001
[   31.059081] NDCB3: 0x00000000
[   31.078003] nand: nand_do_read_oob: from = 0x08120000, len = 64
[   31.084204] marvell-nfc pxa3xx-nand: 
[   31.084204] NDCR:  0x9d079fff
[   31.084204] NDCB0: 0x000d3000
[   31.084204] NDCB1: 0x02400000
[   31.084204] NDCB2: 0x00000001
[   31.084204] NDCB3: 0x00000000
[   31.103138] nand: nand_do_read_oob: from = 0x08140000, len = 64
[   31.109336] marvell-nfc pxa3xx-nand: 
[   31.109336] NDCR:  0x9d079fff
[   31.109336] NDCB0: 0x000d3000
[   31.109336] NDCB1: 0x02800000
[   31.109336] NDCB2: 0x00000001
[   31.109336] NDCB3: 0x00000000
[   31.128257] nand: nand_do_read_oob: from = 0x08160000, len = 64
[   31.134456] marvell-nfc pxa3xx-nand: 
[   31.134456] NDCR:  0x9d079fff
[   31.134456] NDCB0: 0x000d3000
[   31.134456] NDCB1: 0x02c00000
[   31.134456] NDCB2: 0x00000001
[   31.134456] NDCB3: 0x00000000
[   31.153388] nand: nand_do_read_oob: from = 0x08180000, len = 64
[   31.159590] marvell-nfc pxa3xx-nand: 
[   31.159590] NDCR:  0x9d079fff
[   31.159590] NDCB0: 0x000d3000
[   31.159590] NDCB1: 0x03000000
[   31.159590] NDCB2: 0x00000001
[   31.159590] NDCB3: 0x00000000
[   31.178511] nand: nand_do_read_oob: from = 0x081a0000, len = 64
[   31.184711] marvell-nfc pxa3xx-nand: 
[   31.184711] NDCR:  0x9d079fff
[   31.184711] NDCB0: 0x000d3000
[   31.184711] NDCB1: 0x03400000
[   31.184711] NDCB2: 0x00000001
[   31.184711] NDCB3: 0x00000000
[   31.203642] nand: nand_do_read_oob: from = 0x081c0000, len = 64
[   31.210027] marvell-nfc pxa3xx-nand: 
[   31.210027] NDCR:  0x9d079fff
[   31.210027] NDCB0: 0x000d3000
[   31.210027] NDCB1: 0x03800000
[   31.210027] NDCB2: 0x00000001
[   31.210027] NDCB3: 0x00000000
[   31.229051] nand: nand_do_read_oob: from = 0x081e0000, len = 64
[   31.235077] marvell-nfc pxa3xx-nand: 
[   31.235077] NDCR:  0x9d079fff
[   31.235077] NDCB0: 0x000d3000
[   31.235077] NDCB1: 0x03c00000
[   31.235077] NDCB2: 0x00000001
[   31.235077] NDCB3: 0x00000000
[   31.254015] nand: nand_do_read_oob: from = 0x08200000, len = 64
[   31.260215] marvell-nfc pxa3xx-nand: 
[   31.260215] NDCR:  0x9d079fff
[   31.260215] NDCB0: 0x000d3000
[   31.260215] NDCB1: 0x04000000
[   31.260215] NDCB2: 0x00000001
[   31.260215] NDCB3: 0x00000000
[   31.279136] nand: nand_do_read_oob: from = 0x08220000, len = 64
[   31.285169] marvell-nfc pxa3xx-nand: 
[   31.285169] NDCR:  0x9d079fff
[   31.285169] NDCB0: 0x000d3000
[   31.285169] NDCB1: 0x04400000
[   31.285169] NDCB2: 0x00000001
[   31.285169] NDCB3: 0x00000000
[   31.304103] nand: nand_do_read_oob: from = 0x08240000, len = 64
[   31.310308] marvell-nfc pxa3xx-nand: 
[   31.310308] NDCR:  0x9d079fff
[   31.310308] NDCB0: 0x000d3000
[   31.310308] NDCB1: 0x04800000
[   31.310308] NDCB2: 0x00000001
[   31.310308] NDCB3: 0x00000000
[   31.329239] nand: nand_do_read_oob: from = 0x08260000, len = 64
[   31.335267] marvell-nfc pxa3xx-nand: 
[   31.335267] NDCR:  0x9d079fff
[   31.335267] NDCB0: 0x000d3000
[   31.335267] NDCB1: 0x04c00000
[   31.335267] NDCB2: 0x00000001
[   31.335267] NDCB3: 0x00000000
[   31.354200] nand: nand_do_read_oob: from = 0x08280000, len = 64
[   31.360406] marvell-nfc pxa3xx-nand: 
[   31.360406] NDCR:  0x9d079fff
[   31.360406] NDCB0: 0x000d3000
[   31.360406] NDCB1: 0x05000000
[   31.360406] NDCB2: 0x00000001
[   31.360406] NDCB3: 0x00000000
[   31.379335] nand: nand_do_read_oob: from = 0x082a0000, len = 64
[   31.385365] marvell-nfc pxa3xx-nand: 
[   31.385365] NDCR:  0x9d079fff
[   31.385365] NDCB0: 0x000d3000
[   31.385365] NDCB1: 0x05400000
[   31.385365] NDCB2: 0x00000001
[   31.385365] NDCB3: 0x00000000
[   31.404300] nand: nand_do_read_oob: from = 0x082c0000, len = 64
[   31.410506] marvell-nfc pxa3xx-nand: 
[   31.410506] NDCR:  0x9d079fff
[   31.410506] NDCB0: 0x000d3000
[   31.410506] NDCB1: 0x05800000
[   31.410506] NDCB2: 0x00000001
[   31.410506] NDCB3: 0x00000000
[   31.429434] nand: nand_do_read_oob: from = 0x082e0000, len = 64
[   31.435464] marvell-nfc pxa3xx-nand: 
[   31.435464] NDCR:  0x9d079fff
[   31.435464] NDCB0: 0x000d3000
[   31.435464] NDCB1: 0x05c00000
[   31.435464] NDCB2: 0x00000001
[   31.435464] NDCB3: 0x00000000
[   31.454406] nand: nand_do_read_oob: from = 0x08300000, len = 64
[   31.460611] marvell-nfc pxa3xx-nand: 
[   31.460611] NDCR:  0x9d079fff
[   31.460611] NDCB0: 0x000d3000
[   31.460611] NDCB1: 0x06000000
[   31.460611] NDCB2: 0x00000001
[   31.460611] NDCB3: 0x00000000
[   31.479540] nand: nand_do_read_oob: from = 0x08320000, len = 64
[   31.485571] marvell-nfc pxa3xx-nand: 
[   31.485571] NDCR:  0x9d079fff
[   31.485571] NDCB0: 0x000d3000
[   31.485571] NDCB1: 0x06400000
[   31.485571] NDCB2: 0x00000001
[   31.485571] NDCB3: 0x00000000
[   31.504506] nand: nand_do_read_oob: from = 0x08340000, len = 64
[   31.510709] marvell-nfc pxa3xx-nand: 
[   31.510709] NDCR:  0x9d079fff
[   31.510709] NDCB0: 0x000d3000
[   31.510709] NDCB1: 0x06800000
[   31.510709] NDCB2: 0x00000001
[   31.510709] NDCB3: 0x00000000
[   31.529640] nand: nand_do_read_oob: from = 0x08360000, len = 64
[   31.535669] marvell-nfc pxa3xx-nand: 
[   31.535669] NDCR:  0x9d079fff
[   31.535669] NDCB0: 0x000d3000
[   31.535669] NDCB1: 0x06c00000
[   31.535669] NDCB2: 0x00000001
[   31.535669] NDCB3: 0x00000000
[   31.554628] nand: nand_do_read_oob: from = 0x08380000, len = 64
[   31.560835] marvell-nfc pxa3xx-nand: 
[   31.560835] NDCR:  0x9d079fff
[   31.560835] NDCB0: 0x000d3000
[   31.560835] NDCB1: 0x07000000
[   31.560835] NDCB2: 0x00000001
[   31.560835] NDCB3: 0x00000000
[   31.579763] nand: nand_do_read_oob: from = 0x083a0000, len = 64
[   31.585793] marvell-nfc pxa3xx-nand: 
[   31.585793] NDCR:  0x9d079fff
[   31.585793] NDCB0: 0x000d3000
[   31.585793] NDCB1: 0x07400000
[   31.585793] NDCB2: 0x00000001
[   31.585793] NDCB3: 0x00000000
[   31.604727] nand: nand_do_read_oob: from = 0x083c0000, len = 64
[   31.610934] marvell-nfc pxa3xx-nand: 
[   31.610934] NDCR:  0x9d079fff
[   31.610934] NDCB0: 0x000d3000
[   31.610934] NDCB1: 0x07800000
[   31.610934] NDCB2: 0x00000001
[   31.610934] NDCB3: 0x00000000
[   31.629862] nand: nand_do_read_oob: from = 0x083e0000, len = 64
[   31.635893] marvell-nfc pxa3xx-nand: 
[   31.635893] NDCR:  0x9d079fff
[   31.635893] NDCB0: 0x000d3000
[   31.635893] NDCB1: 0x07c00000
[   31.635893] NDCB2: 0x00000001
[   31.635893] NDCB3: 0x00000000
[   31.654828] nand: nand_do_read_oob: from = 0x08400000, len = 64
[   31.661031] marvell-nfc pxa3xx-nand: 
[   31.661031] NDCR:  0x9d079fff
[   31.661031] NDCB0: 0x000d3000
[   31.661031] NDCB1: 0x08000000
[   31.661031] NDCB2: 0x00000001
[   31.661031] NDCB3: 0x00000000
[   31.679962] nand: nand_do_read_oob: from = 0x08420000, len = 64
[   31.685992] marvell-nfc pxa3xx-nand: 
[   31.685992] NDCR:  0x9d079fff
[   31.685992] NDCB0: 0x000d3000
[   31.685992] NDCB1: 0x08400000
[   31.685992] NDCB2: 0x00000001
[   31.685992] NDCB3: 0x00000000
[   31.704925] nand: nand_do_read_oob: from = 0x08440000, len = 64
[   31.711130] marvell-nfc pxa3xx-nand: 
[   31.711130] NDCR:  0x9d079fff
[   31.711130] NDCB0: 0x000d3000
[   31.711130] NDCB1: 0x08800000
[   31.711130] NDCB2: 0x00000001
[   31.711130] NDCB3: 0x00000000
[   31.730058] nand: nand_do_read_oob: from = 0x08460000, len = 64
[   31.736090] marvell-nfc pxa3xx-nand: 
[   31.736090] NDCR:  0x9d079fff
[   31.736090] NDCB0: 0x000d3000
[   31.736090] NDCB1: 0x08c00000
[   31.736090] NDCB2: 0x00000001
[   31.736090] NDCB3: 0x00000000
[   31.755025] nand: nand_do_read_oob: from = 0x08480000, len = 64
[   31.761229] marvell-nfc pxa3xx-nand: 
[   31.761229] NDCR:  0x9d079fff
[   31.761229] NDCB0: 0x000d3000
[   31.761229] NDCB1: 0x09000000
[   31.761229] NDCB2: 0x00000001
[   31.761229] NDCB3: 0x00000000
[   31.780159] nand: nand_do_read_oob: from = 0x084a0000, len = 64
[   31.786189] marvell-nfc pxa3xx-nand: 
[   31.786189] NDCR:  0x9d079fff
[   31.786189] NDCB0: 0x000d3000
[   31.786189] NDCB1: 0x09400000
[   31.786189] NDCB2: 0x00000001
[   31.786189] NDCB3: 0x00000000
[   31.805120] nand: nand_do_read_oob: from = 0x084c0000, len = 64
[   31.811325] marvell-nfc pxa3xx-nand: 
[   31.811325] NDCR:  0x9d079fff
[   31.811325] NDCB0: 0x000d3000
[   31.811325] NDCB1: 0x09800000
[   31.811325] NDCB2: 0x00000001
[   31.811325] NDCB3: 0x00000000
[   31.830258] nand: nand_do_read_oob: from = 0x084e0000, len = 64
[   31.836287] marvell-nfc pxa3xx-nand: 
[   31.836287] NDCR:  0x9d079fff
[   31.836287] NDCB0: 0x000d3000
[   31.836287] NDCB1: 0x09c00000
[   31.836287] NDCB2: 0x00000001
[   31.836287] NDCB3: 0x00000000
[   31.855221] nand: nand_do_read_oob: from = 0x08500000, len = 64
[   31.861425] marvell-nfc pxa3xx-nand: 
[   31.861425] NDCR:  0x9d079fff
[   31.861425] NDCB0: 0x000d3000
[   31.861425] NDCB1: 0x0a000000
[   31.861425] NDCB2: 0x00000001
[   31.861425] NDCB3: 0x00000000
[   31.880356] nand: nand_do_read_oob: from = 0x08520000, len = 64
[   31.886384] marvell-nfc pxa3xx-nand: 
[   31.886384] NDCR:  0x9d079fff
[   31.886384] NDCB0: 0x000d3000
[   31.886384] NDCB1: 0x0a400000
[   31.886384] NDCB2: 0x00000001
[   31.886384] NDCB3: 0x00000000
[   31.905319] nand: nand_do_read_oob: from = 0x08540000, len = 64
[   31.911523] marvell-nfc pxa3xx-nand: 
[   31.911523] NDCR:  0x9d079fff
[   31.911523] NDCB0: 0x000d3000
[   31.911523] NDCB1: 0x0a800000
[   31.911523] NDCB2: 0x00000001
[   31.911523] NDCB3: 0x00000000
[   31.930451] nand: nand_do_read_oob: from = 0x08560000, len = 64
[   31.936483] marvell-nfc pxa3xx-nand: 
[   31.936483] NDCR:  0x9d079fff
[   31.936483] NDCB0: 0x000d3000
[   31.936483] NDCB1: 0x0ac00000
[   31.936483] NDCB2: 0x00000001
[   31.936483] NDCB3: 0x00000000
[   31.955416] nand: nand_do_read_oob: from = 0x08580000, len = 64
[   31.961620] marvell-nfc pxa3xx-nand: 
[   31.961620] NDCR:  0x9d079fff
[   31.961620] NDCB0: 0x000d3000
[   31.961620] NDCB1: 0x0b000000
[   31.961620] NDCB2: 0x00000001
[   31.961620] NDCB3: 0x00000000
[   31.980541] nand: nand_do_read_oob: from = 0x085a0000, len = 64
[   31.986575] marvell-nfc pxa3xx-nand: 
[   31.986575] NDCR:  0x9d079fff
[   31.986575] NDCB0: 0x000d3000
[   31.986575] NDCB1: 0x0b400000
[   31.986575] NDCB2: 0x00000001
[   31.986575] NDCB3: 0x00000000
[   32.005507] nand: nand_do_read_oob: from = 0x085c0000, len = 64
[   32.011723] marvell-nfc pxa3xx-nand: 
[   32.011723] NDCR:  0x9d079fff
[   32.011723] NDCB0: 0x000d3000
[   32.011723] NDCB1: 0x0b800000
[   32.011723] NDCB2: 0x00000001
[   32.011723] NDCB3: 0x00000000
[   32.030652] nand: nand_do_read_oob: from = 0x085e0000, len = 64
[   32.036680] marvell-nfc pxa3xx-nand: 
[   32.036680] NDCR:  0x9d079fff
[   32.036680] NDCB0: 0x000d3000
[   32.036680] NDCB1: 0x0bc00000
[   32.036680] NDCB2: 0x00000001
[   32.036680] NDCB3: 0x00000000
[   32.055615] nand: nand_do_read_oob: from = 0x08600000, len = 64
[   32.061819] marvell-nfc pxa3xx-nand: 
[   32.061819] NDCR:  0x9d079fff
[   32.061819] NDCB0: 0x000d3000
[   32.061819] NDCB1: 0x0c000000
[   32.061819] NDCB2: 0x00000001
[   32.061819] NDCB3: 0x00000000
[   32.080747] nand: nand_do_read_oob: from = 0x08620000, len = 64
[   32.086778] marvell-nfc pxa3xx-nand: 
[   32.086778] NDCR:  0x9d079fff
[   32.086778] NDCB0: 0x000d3000
[   32.086778] NDCB1: 0x0c400000
[   32.086778] NDCB2: 0x00000001
[   32.086778] NDCB3: 0x00000000
[   32.106146] nand: nand_do_read_oob: from = 0x08640000, len = 64
[   32.112385] marvell-nfc pxa3xx-nand: 
[   32.112385] NDCR:  0x9d079fff
[   32.112385] NDCB0: 0x000d3000
[   32.112385] NDCB1: 0x0c800000
[   32.112385] NDCB2: 0x00000001
[   32.112385] NDCB3: 0x00000000
[   32.131320] nand: nand_do_read_oob: from = 0x08660000, len = 64
[   32.137351] marvell-nfc pxa3xx-nand: 
[   32.137351] NDCR:  0x9d079fff
[   32.137351] NDCB0: 0x000d3000
[   32.137351] NDCB1: 0x0cc00000
[   32.137351] NDCB2: 0x00000001
[   32.137351] NDCB3: 0x00000000
[   32.156286] nand: nand_do_read_oob: from = 0x08680000, len = 64
[   32.162490] marvell-nfc pxa3xx-nand: 
[   32.162490] NDCR:  0x9d079fff
[   32.162490] NDCB0: 0x000d3000
[   32.162490] NDCB1: 0x0d000000
[   32.162490] NDCB2: 0x00000001
[   32.162490] NDCB3: 0x00000000
[   32.181420] nand: nand_do_read_oob: from = 0x086a0000, len = 64
[   32.187450] marvell-nfc pxa3xx-nand: 
[   32.187450] NDCR:  0x9d079fff
[   32.187450] NDCB0: 0x000d3000
[   32.187450] NDCB1: 0x0d400000
[   32.187450] NDCB2: 0x00000001
[   32.187450] NDCB3: 0x00000000
[   32.206405] nand: nand_do_read_oob: from = 0x086c0000, len = 64
[   32.212607] marvell-nfc pxa3xx-nand: 
[   32.212607] NDCR:  0x9d079fff
[   32.212607] NDCB0: 0x000d3000
[   32.212607] NDCB1: 0x0d800000
[   32.212607] NDCB2: 0x00000001
[   32.212607] NDCB3: 0x00000000
[   32.231534] nand: nand_do_read_oob: from = 0x086e0000, len = 64
[   32.237566] marvell-nfc pxa3xx-nand: 
[   32.237566] NDCR:  0x9d079fff
[   32.237566] NDCB0: 0x000d3000
[   32.237566] NDCB1: 0x0dc00000
[   32.237566] NDCB2: 0x00000001
[   32.237566] NDCB3: 0x00000000
[   32.256503] nand: nand_do_read_oob: from = 0x08700000, len = 64
[   32.262705] marvell-nfc pxa3xx-nand: 
[   32.262705] NDCR:  0x9d079fff
[   32.262705] NDCB0: 0x000d3000
[   32.262705] NDCB1: 0x0e000000
[   32.262705] NDCB2: 0x00000001
[   32.262705] NDCB3: 0x00000000
[   32.281635] nand: nand_do_read_oob: from = 0x08720000, len = 64
[   32.287665] marvell-nfc pxa3xx-nand: 
[   32.287665] NDCR:  0x9d079fff
[   32.287665] NDCB0: 0x000d3000
[   32.287665] NDCB1: 0x0e400000
[   32.287665] NDCB2: 0x00000001
[   32.287665] NDCB3: 0x00000000
[   32.306597] nand: nand_do_read_oob: from = 0x08740000, len = 64
[   32.312804] marvell-nfc pxa3xx-nand: 
[   32.312804] NDCR:  0x9d079fff
[   32.312804] NDCB0: 0x000d3000
[   32.312804] NDCB1: 0x0e800000
[   32.312804] NDCB2: 0x00000001
[   32.312804] NDCB3: 0x00000000
[   32.331734] nand: nand_do_read_oob: from = 0x08760000, len = 64
[   32.337762] marvell-nfc pxa3xx-nand: 
[   32.337762] NDCR:  0x9d079fff
[   32.337762] NDCB0: 0x000d3000
[   32.337762] NDCB1: 0x0ec00000
[   32.337762] NDCB2: 0x00000001
[   32.337762] NDCB3: 0x00000000
[   32.356700] nand: nand_do_read_oob: from = 0x08780000, len = 64
[   32.362900] marvell-nfc pxa3xx-nand: 
[   32.362900] NDCR:  0x9d079fff
[   32.362900] NDCB0: 0x000d3000
[   32.362900] NDCB1: 0x0f000000
[   32.362900] NDCB2: 0x00000001
[   32.362900] NDCB3: 0x00000000
[   32.381831] nand: nand_do_read_oob: from = 0x087a0000, len = 64
[   32.387860] marvell-nfc pxa3xx-nand: 
[   32.387860] NDCR:  0x9d079fff
[   32.387860] NDCB0: 0x000d3000
[   32.387860] NDCB1: 0x0f400000
[   32.387860] NDCB2: 0x00000001
[   32.387860] NDCB3: 0x00000000
[   32.406794] nand: nand_do_read_oob: from = 0x087c0000, len = 64
[   32.412999] marvell-nfc pxa3xx-nand: 
[   32.412999] NDCR:  0x9d079fff
[   32.412999] NDCB0: 0x000d3000
[   32.412999] NDCB1: 0x0f800000
[   32.412999] NDCB2: 0x00000001
[   32.412999] NDCB3: 0x00000000
[   32.431929] nand: nand_do_read_oob: from = 0x087e0000, len = 64
[   32.437959] marvell-nfc pxa3xx-nand: 
[   32.437959] NDCR:  0x9d079fff
[   32.437959] NDCB0: 0x000d3000
[   32.437959] NDCB1: 0x0fc00000
[   32.437959] NDCB2: 0x00000001
[   32.437959] NDCB3: 0x00000000
[   32.456892] nand: nand_do_read_oob: from = 0x08800000, len = 64
[   32.463097] marvell-nfc pxa3xx-nand: 
[   32.463097] NDCR:  0x9d079fff
[   32.463097] NDCB0: 0x000d3000
[   32.463097] NDCB1: 0x10000000
[   32.463097] NDCB2: 0x00000001
[   32.463097] NDCB3: 0x00000000
[   32.482027] nand: nand_do_read_oob: from = 0x08820000, len = 64
[   32.488057] marvell-nfc pxa3xx-nand: 
[   32.488057] NDCR:  0x9d079fff
[   32.488057] NDCB0: 0x000d3000
[   32.488057] NDCB1: 0x10400000
[   32.488057] NDCB2: 0x00000001
[   32.488057] NDCB3: 0x00000000
[   32.506990] nand: nand_do_read_oob: from = 0x08840000, len = 64
[   32.513196] marvell-nfc pxa3xx-nand: 
[   32.513196] NDCR:  0x9d079fff
[   32.513196] NDCB0: 0x000d3000
[   32.513196] NDCB1: 0x10800000
[   32.513196] NDCB2: 0x00000001
[   32.513196] NDCB3: 0x00000000
[   32.532126] nand: nand_do_read_oob: from = 0x08860000, len = 64
[   32.538157] marvell-nfc pxa3xx-nand: 
[   32.538157] NDCR:  0x9d079fff
[   32.538157] NDCB0: 0x000d3000
[   32.538157] NDCB1: 0x10c00000
[   32.538157] NDCB2: 0x00000001
[   32.538157] NDCB3: 0x00000000
[   32.557089] nand: nand_do_read_oob: from = 0x08880000, len = 64
[   32.563296] marvell-nfc pxa3xx-nand: 
[   32.563296] NDCR:  0x9d079fff
[   32.563296] NDCB0: 0x000d3000
[   32.563296] NDCB1: 0x11000000
[   32.563296] NDCB2: 0x00000001
[   32.563296] NDCB3: 0x00000000
[   32.582223] nand: nand_do_read_oob: from = 0x088a0000, len = 64
[   32.588256] marvell-nfc pxa3xx-nand: 
[   32.588256] NDCR:  0x9d079fff
[   32.588256] NDCB0: 0x000d3000
[   32.588256] NDCB1: 0x11400000
[   32.588256] NDCB2: 0x00000001
[   32.588256] NDCB3: 0x00000000
[   32.607188] nand: nand_do_read_oob: from = 0x088c0000, len = 64
[   32.613393] marvell-nfc pxa3xx-nand: 
[   32.613393] NDCR:  0x9d079fff
[   32.613393] NDCB0: 0x000d3000
[   32.613393] NDCB1: 0x11800000
[   32.613393] NDCB2: 0x00000001
[   32.613393] NDCB3: 0x00000000
[   32.632322] nand: nand_do_read_oob: from = 0x088e0000, len = 64
[   32.638353] marvell-nfc pxa3xx-nand: 
[   32.638353] NDCR:  0x9d079fff
[   32.638353] NDCB0: 0x000d3000
[   32.638353] NDCB1: 0x11c00000
[   32.638353] NDCB2: 0x00000001
[   32.638353] NDCB3: 0x00000000
[   32.657286] nand: nand_do_read_oob: from = 0x08900000, len = 64
[   32.663491] marvell-nfc pxa3xx-nand: 
[   32.663491] NDCR:  0x9d079fff
[   32.663491] NDCB0: 0x000d3000
[   32.663491] NDCB1: 0x12000000
[   32.663491] NDCB2: 0x00000001
[   32.663491] NDCB3: 0x00000000
[   32.682418] nand: nand_do_read_oob: from = 0x08920000, len = 64
[   32.688451] marvell-nfc pxa3xx-nand: 
[   32.688451] NDCR:  0x9d079fff
[   32.688451] NDCB0: 0x000d3000
[   32.688451] NDCB1: 0x12400000
[   32.688451] NDCB2: 0x00000001
[   32.688451] NDCB3: 0x00000000
[   32.707383] nand: nand_do_read_oob: from = 0x08940000, len = 64
[   32.713581] marvell-nfc pxa3xx-nand: 
[   32.713581] NDCR:  0x9d079fff
[   32.713581] NDCB0: 0x000d3000
[   32.713581] NDCB1: 0x12800000
[   32.713581] NDCB2: 0x00000001
[   32.713581] NDCB3: 0x00000000
[   32.732510] nand: nand_do_read_oob: from = 0x08960000, len = 64
[   32.738543] marvell-nfc pxa3xx-nand: 
[   32.738543] NDCR:  0x9d079fff
[   32.738543] NDCB0: 0x000d3000
[   32.738543] NDCB1: 0x12c00000
[   32.738543] NDCB2: 0x00000001
[   32.738543] NDCB3: 0x00000000
[   32.757474] nand: nand_do_read_oob: from = 0x08980000, len = 64
[   32.763681] marvell-nfc pxa3xx-nand: 
[   32.763681] NDCR:  0x9d079fff
[   32.763681] NDCB0: 0x000d3000
[   32.763681] NDCB1: 0x13000000
[   32.763681] NDCB2: 0x00000001
[   32.763681] NDCB3: 0x00000000
[   32.782609] nand: nand_do_read_oob: from = 0x089a0000, len = 64
[   32.788814] marvell-nfc pxa3xx-nand: 
[   32.788814] NDCR:  0x9d079fff
[   32.788814] NDCB0: 0x000d3000
[   32.788814] NDCB1: 0x13400000
[   32.788814] NDCB2: 0x00000001
[   32.788814] NDCB3: 0x00000000
[   32.807719] nand: nand_do_read_oob: from = 0x089c0000, len = 64
[   32.813926] marvell-nfc pxa3xx-nand: 
[   32.813926] NDCR:  0x9d079fff
[   32.813926] NDCB0: 0x000d3000
[   32.813926] NDCB1: 0x13800000
[   32.813926] NDCB2: 0x00000001
[   32.813926] NDCB3: 0x00000000
[   32.832870] nand: nand_do_read_oob: from = 0x089e0000, len = 64
[   32.839074] marvell-nfc pxa3xx-nand: 
[   32.839074] NDCR:  0x9d079fff
[   32.839074] NDCB0: 0x000d3000
[   32.839074] NDCB1: 0x13c00000
[   32.839074] NDCB2: 0x00000001
[   32.839074] NDCB3: 0x00000000
[   32.857994] nand: nand_do_read_oob: from = 0x08a00000, len = 64
[   32.864195] marvell-nfc pxa3xx-nand: 
[   32.864195] NDCR:  0x9d079fff
[   32.864195] NDCB0: 0x000d3000
[   32.864195] NDCB1: 0x14000000
[   32.864195] NDCB2: 0x00000001
[   32.864195] NDCB3: 0x00000000
[   32.883123] nand: nand_do_read_oob: from = 0x08a20000, len = 64
[   32.889325] marvell-nfc pxa3xx-nand: 
[   32.889325] NDCR:  0x9d079fff
[   32.889325] NDCB0: 0x000d3000
[   32.889325] NDCB1: 0x14400000
[   32.889325] NDCB2: 0x00000001
[   32.889325] NDCB3: 0x00000000
[   32.908245] nand: nand_do_read_oob: from = 0x08a40000, len = 64
[   32.914448] marvell-nfc pxa3xx-nand: 
[   32.914448] NDCR:  0x9d079fff
[   32.914448] NDCB0: 0x000d3000
[   32.914448] NDCB1: 0x14800000
[   32.914448] NDCB2: 0x00000001
[   32.914448] NDCB3: 0x00000000
[   32.933376] nand: nand_do_read_oob: from = 0x08a60000, len = 64
[   32.939580] marvell-nfc pxa3xx-nand: 
[   32.939580] NDCR:  0x9d079fff
[   32.939580] NDCB0: 0x000d3000
[   32.939580] NDCB1: 0x14c00000
[   32.939580] NDCB2: 0x00000001
[   32.939580] NDCB3: 0x00000000
[   32.958499] nand: nand_do_read_oob: from = 0x08a80000, len = 64
[   32.964701] marvell-nfc pxa3xx-nand: 
[   32.964701] NDCR:  0x9d079fff
[   32.964701] NDCB0: 0x000d3000
[   32.964701] NDCB1: 0x15000000
[   32.964701] NDCB2: 0x00000001
[   32.964701] NDCB3: 0x00000000
[   32.983631] nand: nand_do_read_oob: from = 0x08aa0000, len = 64
[   32.989833] marvell-nfc pxa3xx-nand: 
[   32.989833] NDCR:  0x9d079fff
[   32.989833] NDCB0: 0x000d3000
[   32.989833] NDCB1: 0x15400000
[   32.989833] NDCB2: 0x00000001
[   32.989833] NDCB3: 0x00000000
[   33.008852] nand: nand_do_read_oob: from = 0x08ac0000, len = 64
[   33.014885] marvell-nfc pxa3xx-nand: 
[   33.014885] NDCR:  0x9d079fff
[   33.014885] NDCB0: 0x000d3000
[   33.014885] NDCB1: 0x15800000
[   33.014885] NDCB2: 0x00000001
[   33.014885] NDCB3: 0x00000000
[   33.033814] nand: nand_do_read_oob: from = 0x08ae0000, len = 64
[   33.040021] marvell-nfc pxa3xx-nand: 
[   33.040021] NDCR:  0x9d079fff
[   33.040021] NDCB0: 0x000d3000
[   33.040021] NDCB1: 0x15c00000
[   33.040021] NDCB2: 0x00000001
[   33.040021] NDCB3: 0x00000000
[   33.059139] nand: nand_do_read_oob: from = 0x08b00000, len = 64
[   33.065180] marvell-nfc pxa3xx-nand: 
[   33.065180] NDCR:  0x9d079fff
[   33.065180] NDCB0: 0x000d3000
[   33.065180] NDCB1: 0x16000000
[   33.065180] NDCB2: 0x00000001
[   33.065180] NDCB3: 0x00000000
[   33.084130] nand: nand_do_read_oob: from = 0x08b20000, len = 64
[   33.090334] marvell-nfc pxa3xx-nand: 
[   33.090334] NDCR:  0x9d079fff
[   33.090334] NDCB0: 0x000d3000
[   33.090334] NDCB1: 0x16400000
[   33.090334] NDCB2: 0x00000001
[   33.090334] NDCB3: 0x00000000
[   33.109260] nand: nand_do_read_oob: from = 0x08b40000, len = 64
[   33.115293] marvell-nfc pxa3xx-nand: 
[   33.115293] NDCR:  0x9d079fff
[   33.115293] NDCB0: 0x000d3000
[   33.115293] NDCB1: 0x16800000
[   33.115293] NDCB2: 0x00000001
[   33.115293] NDCB3: 0x00000000
[   33.134226] nand: nand_do_read_oob: from = 0x08b60000, len = 64
[   33.140431] marvell-nfc pxa3xx-nand: 
[   33.140431] NDCR:  0x9d079fff
[   33.140431] NDCB0: 0x000d3000
[   33.140431] NDCB1: 0x16c00000
[   33.140431] NDCB2: 0x00000001
[   33.140431] NDCB3: 0x00000000
[   33.159357] nand: nand_do_read_oob: from = 0x08b80000, len = 64
[   33.165393] marvell-nfc pxa3xx-nand: 
[   33.165393] NDCR:  0x9d079fff
[   33.165393] NDCB0: 0x000d3000
[   33.165393] NDCB1: 0x17000000
[   33.165393] NDCB2: 0x00000001
[   33.165393] NDCB3: 0x00000000
[   33.184323] nand: nand_do_read_oob: from = 0x08ba0000, len = 64
[   33.190529] marvell-nfc pxa3xx-nand: 
[   33.190529] NDCR:  0x9d079fff
[   33.190529] NDCB0: 0x000d3000
[   33.190529] NDCB1: 0x17400000
[   33.190529] NDCB2: 0x00000001
[   33.190529] NDCB3: 0x00000000
[   33.209457] nand: nand_do_read_oob: from = 0x08bc0000, len = 64
[   33.215489] marvell-nfc pxa3xx-nand: 
[   33.215489] NDCR:  0x9d079fff
[   33.215489] NDCB0: 0x000d3000
[   33.215489] NDCB1: 0x17800000
[   33.215489] NDCB2: 0x00000001
[   33.215489] NDCB3: 0x00000000
[   33.234423] nand: nand_do_read_oob: from = 0x08be0000, len = 64
[   33.240628] marvell-nfc pxa3xx-nand: 
[   33.240628] NDCR:  0x9d079fff
[   33.240628] NDCB0: 0x000d3000
[   33.240628] NDCB1: 0x17c00000
[   33.240628] NDCB2: 0x00000001
[   33.240628] NDCB3: 0x00000000
[   33.259556] nand: nand_do_read_oob: from = 0x08c00000, len = 64
[   33.265587] marvell-nfc pxa3xx-nand: 
[   33.265587] NDCR:  0x9d079fff
[   33.265587] NDCB0: 0x000d3000
[   33.265587] NDCB1: 0x18000000
[   33.265587] NDCB2: 0x00000001
[   33.265587] NDCB3: 0x00000000
[   33.284521] nand: nand_do_read_oob: from = 0x08c20000, len = 64
[   33.290727] marvell-nfc pxa3xx-nand: 
[   33.290727] NDCR:  0x9d079fff
[   33.290727] NDCB0: 0x000d3000
[   33.290727] NDCB1: 0x18400000
[   33.290727] NDCB2: 0x00000001
[   33.290727] NDCB3: 0x00000000
[   33.309653] nand: nand_do_read_oob: from = 0x08c40000, len = 64
[   33.315686] marvell-nfc pxa3xx-nand: 
[   33.315686] NDCR:  0x9d079fff
[   33.315686] NDCB0: 0x000d3000
[   33.315686] NDCB1: 0x18800000
[   33.315686] NDCB2: 0x00000001
[   33.315686] NDCB3: 0x00000000
[   33.334618] nand: nand_do_read_oob: from = 0x08c60000, len = 64
[   33.340825] marvell-nfc pxa3xx-nand: 
[   33.340825] NDCR:  0x9d079fff
[   33.340825] NDCB0: 0x000d3000
[   33.340825] NDCB1: 0x18c00000
[   33.340825] NDCB2: 0x00000001
[   33.340825] NDCB3: 0x00000000
[   33.359752] nand: nand_do_read_oob: from = 0x08c80000, len = 64
[   33.365785] marvell-nfc pxa3xx-nand: 
[   33.365785] NDCR:  0x9d079fff
[   33.365785] NDCB0: 0x000d3000
[   33.365785] NDCB1: 0x19000000
[   33.365785] NDCB2: 0x00000001
[   33.365785] NDCB3: 0x00000000
[   33.384714] nand: nand_do_read_oob: from = 0x08ca0000, len = 64
[   33.390914] marvell-nfc pxa3xx-nand: 
[   33.390914] NDCR:  0x9d079fff
[   33.390914] NDCB0: 0x000d3000
[   33.390914] NDCB1: 0x19400000
[   33.390914] NDCB2: 0x00000001
[   33.390914] NDCB3: 0x00000000
[   33.409864] nand: nand_do_read_oob: from = 0x08cc0000, len = 64
[   33.415892] marvell-nfc pxa3xx-nand: 
[   33.415892] NDCR:  0x9d079fff
[   33.415892] NDCB0: 0x000d3000
[   33.415892] NDCB1: 0x19800000
[   33.415892] NDCB2: 0x00000001
[   33.415892] NDCB3: 0x00000000
[   33.434822] nand: nand_do_read_oob: from = 0x08ce0000, len = 64
[   33.441022] marvell-nfc pxa3xx-nand: 
[   33.441022] NDCR:  0x9d079fff
[   33.441022] NDCB0: 0x000d3000
[   33.441022] NDCB1: 0x19c00000
[   33.441022] NDCB2: 0x00000001
[   33.441022] NDCB3: 0x00000000
[   33.459949] nand: nand_do_read_oob: from = 0x08d00000, len = 64
[   33.465981] marvell-nfc pxa3xx-nand: 
[   33.465981] NDCR:  0x9d079fff
[   33.465981] NDCB0: 0x000d3000
[   33.465981] NDCB1: 0x1a000000
[   33.465981] NDCB2: 0x00000001
[   33.465981] NDCB3: 0x00000000
[   33.484914] nand: nand_do_read_oob: from = 0x08d20000, len = 64
[   33.491119] marvell-nfc pxa3xx-nand: 
[   33.491119] NDCR:  0x9d079fff
[   33.491119] NDCB0: 0x000d3000
[   33.491119] NDCB1: 0x1a400000
[   33.491119] NDCB2: 0x00000001
[   33.491119] NDCB3: 0x00000000
[   33.510047] nand: nand_do_read_oob: from = 0x08d40000, len = 64
[   33.516081] marvell-nfc pxa3xx-nand: 
[   33.516081] NDCR:  0x9d079fff
[   33.516081] NDCB0: 0x000d3000
[   33.516081] NDCB1: 0x1a800000
[   33.516081] NDCB2: 0x00000001
[   33.516081] NDCB3: 0x00000000
[   33.535011] nand: nand_do_read_oob: from = 0x08d60000, len = 64
[   33.541219] marvell-nfc pxa3xx-nand: 
[   33.541219] NDCR:  0x9d079fff
[   33.541219] NDCB0: 0x000d3000
[   33.541219] NDCB1: 0x1ac00000
[   33.541219] NDCB2: 0x00000001
[   33.541219] NDCB3: 0x00000000
[   33.560144] nand: nand_do_read_oob: from = 0x08d80000, len = 64
[   33.566179] marvell-nfc pxa3xx-nand: 
[   33.566179] NDCR:  0x9d079fff
[   33.566179] NDCB0: 0x000d3000
[   33.566179] NDCB1: 0x1b000000
[   33.566179] NDCB2: 0x00000001
[   33.566179] NDCB3: 0x00000000
[   33.585109] nand: nand_do_read_oob: from = 0x08da0000, len = 64
[   33.591310] marvell-nfc pxa3xx-nand: 
[   33.591310] NDCR:  0x9d079fff
[   33.591310] NDCB0: 0x000d3000
[   33.591310] NDCB1: 0x1b400000
[   33.591310] NDCB2: 0x00000001
[   33.591310] NDCB3: 0x00000000
[   33.610236] nand: nand_do_read_oob: from = 0x08dc0000, len = 64
[   33.616269] marvell-nfc pxa3xx-nand: 
[   33.616269] NDCR:  0x9d079fff
[   33.616269] NDCB0: 0x000d3000
[   33.616269] NDCB1: 0x1b800000
[   33.616269] NDCB2: 0x00000001
[   33.616269] NDCB3: 0x00000000
[   33.635198] nand: nand_do_read_oob: from = 0x08de0000, len = 64
[   33.641395] marvell-nfc pxa3xx-nand: 
[   33.641395] NDCR:  0x9d079fff
[   33.641395] NDCB0: 0x000d3000
[   33.641395] NDCB1: 0x1bc00000
[   33.641395] NDCB2: 0x00000001
[   33.641395] NDCB3: 0x00000000
[   33.660317] nand: nand_do_read_oob: from = 0x08e00000, len = 64
[   33.666350] marvell-nfc pxa3xx-nand: 
[   33.666350] NDCR:  0x9d079fff
[   33.666350] NDCB0: 0x000d3000
[   33.666350] NDCB1: 0x1c000000
[   33.666350] NDCB2: 0x00000001
[   33.666350] NDCB3: 0x00000000
[   33.685280] nand: nand_do_read_oob: from = 0x08e20000, len = 64
[   33.691480] marvell-nfc pxa3xx-nand: 
[   33.691480] NDCR:  0x9d079fff
[   33.691480] NDCB0: 0x000d3000
[   33.691480] NDCB1: 0x1c400000
[   33.691480] NDCB2: 0x00000001
[   33.691480] NDCB3: 0x00000000
[   33.710406] nand: nand_do_read_oob: from = 0x08e40000, len = 64
[   33.716441] marvell-nfc pxa3xx-nand: 
[   33.716441] NDCR:  0x9d079fff
[   33.716441] NDCB0: 0x000d3000
[   33.716441] NDCB1: 0x1c800000
[   33.716441] NDCB2: 0x00000001
[   33.716441] NDCB3: 0x00000000
[   33.735371] nand: nand_do_read_oob: from = 0x08e60000, len = 64
[   33.741567] marvell-nfc pxa3xx-nand: 
[   33.741567] NDCR:  0x9d079fff
[   33.741567] NDCB0: 0x000d3000
[   33.741567] NDCB1: 0x1cc00000
[   33.741567] NDCB2: 0x00000001
[   33.741567] NDCB3: 0x00000000
[   33.760498] nand: nand_do_read_oob: from = 0x08e80000, len = 64
[   33.766528] marvell-nfc pxa3xx-nand: 
[   33.766528] NDCR:  0x9d079fff
[   33.766528] NDCB0: 0x000d3000
[   33.766528] NDCB1: 0x1d000000
[   33.766528] NDCB2: 0x00000001
[   33.766528] NDCB3: 0x00000000
[   33.785461] nand: nand_do_read_oob: from = 0x08ea0000, len = 64
[   33.791669] marvell-nfc pxa3xx-nand: 
[   33.791669] NDCR:  0x9d079fff
[   33.791669] NDCB0: 0x000d3000
[   33.791669] NDCB1: 0x1d400000
[   33.791669] NDCB2: 0x00000001
[   33.791669] NDCB3: 0x00000000
[   33.810595] nand: nand_do_read_oob: from = 0x08ec0000, len = 64
[   33.816628] marvell-nfc pxa3xx-nand: 
[   33.816628] NDCR:  0x9d079fff
[   33.816628] NDCB0: 0x000d3000
[   33.816628] NDCB1: 0x1d800000
[   33.816628] NDCB2: 0x00000001
[   33.816628] NDCB3: 0x00000000
[   33.835559] nand: nand_do_read_oob: from = 0x08ee0000, len = 64
[   33.841767] marvell-nfc pxa3xx-nand: 
[   33.841767] NDCR:  0x9d079fff
[   33.841767] NDCB0: 0x000d3000
[   33.841767] NDCB1: 0x1dc00000
[   33.841767] NDCB2: 0x00000001
[   33.841767] NDCB3: 0x00000000
[   33.860697] nand: nand_do_read_oob: from = 0x08f00000, len = 64
[   33.866727] marvell-nfc pxa3xx-nand: 
[   33.866727] NDCR:  0x9d079fff
[   33.866727] NDCB0: 0x000d3000
[   33.866727] NDCB1: 0x1e000000
[   33.866727] NDCB2: 0x00000001
[   33.866727] NDCB3: 0x00000000
[   33.885660] nand: nand_do_read_oob: from = 0x08f20000, len = 64
[   33.891866] marvell-nfc pxa3xx-nand: 
[   33.891866] NDCR:  0x9d079fff
[   33.891866] NDCB0: 0x000d3000
[   33.891866] NDCB1: 0x1e400000
[   33.891866] NDCB2: 0x00000001
[   33.891866] NDCB3: 0x00000000
[   33.910793] nand: nand_do_read_oob: from = 0x08f40000, len = 64
[   33.916827] marvell-nfc pxa3xx-nand: 
[   33.916827] NDCR:  0x9d079fff
[   33.916827] NDCB0: 0x000d3000
[   33.916827] NDCB1: 0x1e800000
[   33.916827] NDCB2: 0x00000001
[   33.916827] NDCB3: 0x00000000
[   33.935755] nand: nand_do_read_oob: from = 0x08f60000, len = 64
[   33.941955] marvell-nfc pxa3xx-nand: 
[   33.941955] NDCR:  0x9d079fff
[   33.941955] NDCB0: 0x000d3000
[   33.941955] NDCB1: 0x1ec00000
[   33.941955] NDCB2: 0x00000001
[   33.941955] NDCB3: 0x00000000
[   33.960883] nand: nand_do_read_oob: from = 0x08f80000, len = 64
[   33.966914] marvell-nfc pxa3xx-nand: 
[   33.966914] NDCR:  0x9d079fff
[   33.966914] NDCB0: 0x000d3000
[   33.966914] NDCB1: 0x1f000000
[   33.966914] NDCB2: 0x00000001
[   33.966914] NDCB3: 0x00000000
[   33.985845] nand: nand_do_read_oob: from = 0x08fa0000, len = 64
[   33.992043] marvell-nfc pxa3xx-nand: 
[   33.992043] NDCR:  0x9d079fff
[   33.992043] NDCB0: 0x000d3000
[   33.992043] NDCB1: 0x1f400000
[   33.992043] NDCB2: 0x00000001
[   33.992043] NDCB3: 0x00000000
[   34.010983] nand: nand_do_read_oob: from = 0x08fc0000, len = 64
[   34.017014] marvell-nfc pxa3xx-nand: 
[   34.017014] NDCR:  0x9d079fff
[   34.017014] NDCB0: 0x000d3000
[   34.017014] NDCB1: 0x1f800000
[   34.017014] NDCB2: 0x00000001
[   34.017014] NDCB3: 0x00000000
[   34.035945] nand: nand_do_read_oob: from = 0x08fe0000, len = 64
[   34.042153] marvell-nfc pxa3xx-nand: 
[   34.042153] NDCR:  0x9d079fff
[   34.042153] NDCB0: 0x000d3000
[   34.042153] NDCB1: 0x1fc00000
[   34.042153] NDCB2: 0x00000001
[   34.042153] NDCB3: 0x00000000
[   34.061101] nand: nand_do_read_oob: from = 0x09000000, len = 64
[   34.067138] marvell-nfc pxa3xx-nand: 
[   34.067138] NDCR:  0x9d079fff
[   34.067138] NDCB0: 0x000d3000
[   34.067138] NDCB1: 0x20000000
[   34.067138] NDCB2: 0x00000001
[   34.067138] NDCB3: 0x00000000
[   34.086073] nand: nand_do_read_oob: from = 0x09020000, len = 64
[   34.092563] marvell-nfc pxa3xx-nand: 
[   34.092563] NDCR:  0x9d079fff
[   34.092563] NDCB0: 0x000d3000
[   34.092563] NDCB1: 0x20400000
[   34.092563] NDCB2: 0x00000001
[   34.092563] NDCB3: 0x00000000
[   34.111561] nand: nand_do_read_oob: from = 0x09040000, len = 64
[   34.117591] marvell-nfc pxa3xx-nand: 
[   34.117591] NDCR:  0x9d079fff
[   34.117591] NDCB0: 0x000d3000
[   34.117591] NDCB1: 0x20800000
[   34.117591] NDCB2: 0x00000001
[   34.117591] NDCB3: 0x00000000
[   34.136523] nand: nand_do_read_oob: from = 0x09060000, len = 64
[   34.142727] marvell-nfc pxa3xx-nand: 
[   34.142727] NDCR:  0x9d079fff
[   34.142727] NDCB0: 0x000d3000
[   34.142727] NDCB1: 0x20c00000
[   34.142727] NDCB2: 0x00000001
[   34.142727] NDCB3: 0x00000000
[   34.161657] nand: nand_do_read_oob: from = 0x09080000, len = 64
[   34.167691] marvell-nfc pxa3xx-nand: 
[   34.167691] NDCR:  0x9d079fff
[   34.167691] NDCB0: 0x000d3000
[   34.167691] NDCB1: 0x21000000
[   34.167691] NDCB2: 0x00000001
[   34.167691] NDCB3: 0x00000000
[   34.186632] nand: nand_do_read_oob: from = 0x090a0000, len = 64
[   34.192836] marvell-nfc pxa3xx-nand: 
[   34.192836] NDCR:  0x9d079fff
[   34.192836] NDCB0: 0x000d3000
[   34.192836] NDCB1: 0x21400000
[   34.192836] NDCB2: 0x00000001
[   34.192836] NDCB3: 0x00000000
[   34.211766] nand: nand_do_read_oob: from = 0x090c0000, len = 64
[   34.217794] marvell-nfc pxa3xx-nand: 
[   34.217794] NDCR:  0x9d079fff
[   34.217794] NDCB0: 0x000d3000
[   34.217794] NDCB1: 0x21800000
[   34.217794] NDCB2: 0x00000001
[   34.217794] NDCB3: 0x00000000
[   34.236728] nand: nand_do_read_oob: from = 0x090e0000, len = 64
[   34.242933] marvell-nfc pxa3xx-nand: 
[   34.242933] NDCR:  0x9d079fff
[   34.242933] NDCB0: 0x000d3000
[   34.242933] NDCB1: 0x21c00000
[   34.242933] NDCB2: 0x00000001
[   34.242933] NDCB3: 0x00000000
[   34.261864] nand: nand_do_read_oob: from = 0x09100000, len = 64
[   34.267892] marvell-nfc pxa3xx-nand: 
[   34.267892] NDCR:  0x9d079fff
[   34.267892] NDCB0: 0x000d3000
[   34.267892] NDCB1: 0x22000000
[   34.267892] NDCB2: 0x00000001
[   34.267892] NDCB3: 0x00000000
[   34.286828] nand: nand_do_read_oob: from = 0x09120000, len = 64
[   34.293031] marvell-nfc pxa3xx-nand: 
[   34.293031] NDCR:  0x9d079fff
[   34.293031] NDCB0: 0x000d3000
[   34.293031] NDCB1: 0x22400000
[   34.293031] NDCB2: 0x00000001
[   34.293031] NDCB3: 0x00000000
[   34.311960] nand: nand_do_read_oob: from = 0x09140000, len = 64
[   34.317992] marvell-nfc pxa3xx-nand: 
[   34.317992] NDCR:  0x9d079fff
[   34.317992] NDCB0: 0x000d3000
[   34.317992] NDCB1: 0x22800000
[   34.317992] NDCB2: 0x00000001
[   34.317992] NDCB3: 0x00000000
[   34.336926] nand: nand_do_read_oob: from = 0x09160000, len = 64
[   34.343129] marvell-nfc pxa3xx-nand: 
[   34.343129] NDCR:  0x9d079fff
[   34.343129] NDCB0: 0x000d3000
[   34.343129] NDCB1: 0x22c00000
[   34.343129] NDCB2: 0x00000001
[   34.343129] NDCB3: 0x00000000
[   34.362057] nand: nand_do_read_oob: from = 0x09180000, len = 64
[   34.368089] marvell-nfc pxa3xx-nand: 
[   34.368089] NDCR:  0x9d079fff
[   34.368089] NDCB0: 0x000d3000
[   34.368089] NDCB1: 0x23000000
[   34.368089] NDCB2: 0x00000001
[   34.368089] NDCB3: 0x00000000
[   34.387023] nand: nand_do_read_oob: from = 0x091a0000, len = 64
[   34.393227] marvell-nfc pxa3xx-nand: 
[   34.393227] NDCR:  0x9d079fff
[   34.393227] NDCB0: 0x000d3000
[   34.393227] NDCB1: 0x23400000
[   34.393227] NDCB2: 0x00000001
[   34.393227] NDCB3: 0x00000000
[   34.412160] nand: nand_do_read_oob: from = 0x091c0000, len = 64
[   34.418187] marvell-nfc pxa3xx-nand: 
[   34.418187] NDCR:  0x9d079fff
[   34.418187] NDCB0: 0x000d3000
[   34.418187] NDCB1: 0x23800000
[   34.418187] NDCB2: 0x00000001
[   34.418187] NDCB3: 0x00000000
[   34.437121] nand: nand_do_read_oob: from = 0x091e0000, len = 64
[   34.443326] marvell-nfc pxa3xx-nand: 
[   34.443326] NDCR:  0x9d079fff
[   34.443326] NDCB0: 0x000d3000
[   34.443326] NDCB1: 0x23c00000
[   34.443326] NDCB2: 0x00000001
[   34.443326] NDCB3: 0x00000000
[   34.462258] nand: nand_do_read_oob: from = 0x09200000, len = 64
[   34.468286] marvell-nfc pxa3xx-nand: 
[   34.468286] NDCR:  0x9d079fff
[   34.468286] NDCB0: 0x000d3000
[   34.468286] NDCB1: 0x24000000
[   34.468286] NDCB2: 0x00000001
[   34.468286] NDCB3: 0x00000000
[   34.487219] nand: nand_do_read_oob: from = 0x09220000, len = 64
[   34.493425] marvell-nfc pxa3xx-nand: 
[   34.493425] NDCR:  0x9d079fff
[   34.493425] NDCB0: 0x000d3000
[   34.493425] NDCB1: 0x24400000
[   34.493425] NDCB2: 0x00000001
[   34.493425] NDCB3: 0x00000000
[   34.512356] nand: nand_do_read_oob: from = 0x09240000, len = 64
[   34.518384] marvell-nfc pxa3xx-nand: 
[   34.518384] NDCR:  0x9d079fff
[   34.518384] NDCB0: 0x000d3000
[   34.518384] NDCB1: 0x24800000
[   34.518384] NDCB2: 0x00000001
[   34.518384] NDCB3: 0x00000000
[   34.537317] nand: nand_do_read_oob: from = 0x09260000, len = 64
[   34.543522] marvell-nfc pxa3xx-nand: 
[   34.543522] NDCR:  0x9d079fff
[   34.543522] NDCB0: 0x000d3000
[   34.543522] NDCB1: 0x24c00000
[   34.543522] NDCB2: 0x00000001
[   34.543522] NDCB3: 0x00000000
[   34.562454] nand: nand_do_read_oob: from = 0x09280000, len = 64
[   34.568484] marvell-nfc pxa3xx-nand: 
[   34.568484] NDCR:  0x9d079fff
[   34.568484] NDCB0: 0x000d3000
[   34.568484] NDCB1: 0x25000000
[   34.568484] NDCB2: 0x00000001
[   34.568484] NDCB3: 0x00000000
[   34.587416] nand: nand_do_read_oob: from = 0x092a0000, len = 64
[   34.593623] marvell-nfc pxa3xx-nand: 
[   34.593623] NDCR:  0x9d079fff
[   34.593623] NDCB0: 0x000d3000
[   34.593623] NDCB1: 0x25400000
[   34.593623] NDCB2: 0x00000001
[   34.593623] NDCB3: 0x00000000
[   34.612553] nand: nand_do_read_oob: from = 0x092c0000, len = 64
[   34.618581] marvell-nfc pxa3xx-nand: 
[   34.618581] NDCR:  0x9d079fff
[   34.618581] NDCB0: 0x000d3000
[   34.618581] NDCB1: 0x25800000
[   34.618581] NDCB2: 0x00000001
[   34.618581] NDCB3: 0x00000000
[   34.637625] nand: nand_do_read_oob: from = 0x092e0000, len = 64
[   34.643833] marvell-nfc pxa3xx-nand: 
[   34.643833] NDCR:  0x9d079fff
[   34.643833] NDCB0: 0x000d3000
[   34.643833] NDCB1: 0x25c00000
[   34.643833] NDCB2: 0x00000001
[   34.643833] NDCB3: 0x00000000
[   34.662763] nand: nand_do_read_oob: from = 0x09300000, len = 64
[   34.668963] marvell-nfc pxa3xx-nand: 
[   34.668963] NDCR:  0x9d079fff
[   34.668963] NDCB0: 0x000d3000
[   34.668963] NDCB1: 0x26000000
[   34.668963] NDCB2: 0x00000001
[   34.668963] NDCB3: 0x00000000
[   34.687904] nand: nand_do_read_oob: from = 0x09320000, len = 64
[   34.694104] marvell-nfc pxa3xx-nand: 
[   34.694104] NDCR:  0x9d079fff
[   34.694104] NDCB0: 0x000d3000
[   34.694104] NDCB1: 0x26400000
[   34.694104] NDCB2: 0x00000001
[   34.694104] NDCB3: 0x00000000
[   34.713035] nand: nand_do_read_oob: from = 0x09340000, len = 64
[   34.719235] marvell-nfc pxa3xx-nand: 
[   34.719235] NDCR:  0x9d079fff
[   34.719235] NDCB0: 0x000d3000
[   34.719235] NDCB1: 0x26800000
[   34.719235] NDCB2: 0x00000001
[   34.719235] NDCB3: 0x00000000
[   34.738155] nand: nand_do_read_oob: from = 0x09360000, len = 64
[   34.744356] marvell-nfc pxa3xx-nand: 
[   34.744356] NDCR:  0x9d079fff
[   34.744356] NDCB0: 0x000d3000
[   34.744356] NDCB1: 0x26c00000
[   34.744356] NDCB2: 0x00000001
[   34.744356] NDCB3: 0x00000000
[   34.763288] nand: nand_do_read_oob: from = 0x09380000, len = 64
[   34.769488] marvell-nfc pxa3xx-nand: 
[   34.769488] NDCR:  0x9d079fff
[   34.769488] NDCB0: 0x000d3000
[   34.769488] NDCB1: 0x27000000
[   34.769488] NDCB2: 0x00000001
[   34.769488] NDCB3: 0x00000000
[   34.788408] nand: nand_do_read_oob: from = 0x093a0000, len = 64
[   34.794608] marvell-nfc pxa3xx-nand: 
[   34.794608] NDCR:  0x9d079fff
[   34.794608] NDCB0: 0x000d3000
[   34.794608] NDCB1: 0x27400000
[   34.794608] NDCB2: 0x00000001
[   34.794608] NDCB3: 0x00000000
[   34.813541] nand: nand_do_read_oob: from = 0x093c0000, len = 64
[   34.819740] marvell-nfc pxa3xx-nand: 
[   34.819740] NDCR:  0x9d079fff
[   34.819740] NDCB0: 0x000d3000
[   34.819740] NDCB1: 0x27800000
[   34.819740] NDCB2: 0x00000001
[   34.819740] NDCB3: 0x00000000
[   34.838761] nand: nand_do_read_oob: from = 0x093e0000, len = 64
[   34.844800] marvell-nfc pxa3xx-nand: 
[   34.844800] NDCR:  0x9d079fff
[   34.844800] NDCB0: 0x000d3000
[   34.844800] NDCB1: 0x27c00000
[   34.844800] NDCB2: 0x00000001
[   34.844800] NDCB3: 0x00000000
[   34.863716] nand: nand_do_read_oob: from = 0x09400000, len = 64
[   34.869919] marvell-nfc pxa3xx-nand: 
[   34.869919] NDCR:  0x9d079fff
[   34.869919] NDCB0: 0x000d3000
[   34.869919] NDCB1: 0x28000000
[   34.869919] NDCB2: 0x00000001
[   34.869919] NDCB3: 0x00000000
[   34.888900] nand: nand_do_read_oob: from = 0x09420000, len = 64
[   34.894933] marvell-nfc pxa3xx-nand: 
[   34.894933] NDCR:  0x9d079fff
[   34.894933] NDCB0: 0x000d3000
[   34.894933] NDCB1: 0x28400000
[   34.894933] NDCB2: 0x00000001
[   34.894933] NDCB3: 0x00000000
[   34.913873] nand: nand_do_read_oob: from = 0x09440000, len = 64
[   34.920075] marvell-nfc pxa3xx-nand: 
[   34.920075] NDCR:  0x9d079fff
[   34.920075] NDCB0: 0x000d3000
[   34.920075] NDCB1: 0x28800000
[   34.920075] NDCB2: 0x00000001
[   34.920075] NDCB3: 0x00000000
[   34.939043] nand: nand_do_read_oob: from = 0x09460000, len = 64
[   34.945071] marvell-nfc pxa3xx-nand: 
[   34.945071] NDCR:  0x9d079fff
[   34.945071] NDCB0: 0x000d3000
[   34.945071] NDCB1: 0x28c00000
[   34.945071] NDCB2: 0x00000001
[   34.945071] NDCB3: 0x00000000
[   34.964004] nand: nand_do_read_oob: from = 0x09480000, len = 64
[   34.970209] marvell-nfc pxa3xx-nand: 
[   34.970209] NDCR:  0x9d079fff
[   34.970209] NDCB0: 0x000d3000
[   34.970209] NDCB1: 0x29000000
[   34.970209] NDCB2: 0x00000001
[   34.970209] NDCB3: 0x00000000
[   34.989138] nand: nand_do_read_oob: from = 0x094a0000, len = 64
[   34.995170] marvell-nfc pxa3xx-nand: 
[   34.995170] NDCR:  0x9d079fff
[   34.995170] NDCB0: 0x000d3000
[   34.995170] NDCB1: 0x29400000
[   34.995170] NDCB2: 0x00000001
[   34.995170] NDCB3: 0x00000000
[   35.014111] nand: nand_do_read_oob: from = 0x094c0000, len = 64
[   35.020319] marvell-nfc pxa3xx-nand: 
[   35.020319] NDCR:  0x9d079fff
[   35.020319] NDCB0: 0x000d3000
[   35.020319] NDCB1: 0x29800000
[   35.020319] NDCB2: 0x00000001
[   35.020319] NDCB3: 0x00000000
[   35.039246] nand: nand_do_read_oob: from = 0x094e0000, len = 64
[   35.045275] marvell-nfc pxa3xx-nand: 
[   35.045275] NDCR:  0x9d079fff
[   35.045275] NDCB0: 0x000d3000
[   35.045275] NDCB1: 0x29c00000
[   35.045275] NDCB2: 0x00000001
[   35.045275] NDCB3: 0x00000000
[   35.064210] nand: nand_do_read_oob: from = 0x09500000, len = 64
[   35.070415] marvell-nfc pxa3xx-nand: 
[   35.070415] NDCR:  0x9d079fff
[   35.070415] NDCB0: 0x000d3000
[   35.070415] NDCB1: 0x2a000000
[   35.070415] NDCB2: 0x00000001
[   35.070415] NDCB3: 0x00000000
[   35.089346] nand: nand_do_read_oob: from = 0x09520000, len = 64
[   35.095375] marvell-nfc pxa3xx-nand: 
[   35.095375] NDCR:  0x9d079fff
[   35.095375] NDCB0: 0x000d3000
[   35.095375] NDCB1: 0x2a400000
[   35.095375] NDCB2: 0x00000001
[   35.095375] NDCB3: 0x00000000
[   35.114308] nand: nand_do_read_oob: from = 0x09540000, len = 64
[   35.120514] marvell-nfc pxa3xx-nand: 
[   35.120514] NDCR:  0x9d079fff
[   35.120514] NDCB0: 0x000d3000
[   35.120514] NDCB1: 0x2a800000
[   35.120514] NDCB2: 0x00000001
[   35.120514] NDCB3: 0x00000000
[   35.139442] nand: nand_do_read_oob: from = 0x09560000, len = 64
[   35.145473] marvell-nfc pxa3xx-nand: 
[   35.145473] NDCR:  0x9d079fff
[   35.145473] NDCB0: 0x000d3000
[   35.145473] NDCB1: 0x2ac00000
[   35.145473] NDCB2: 0x00000001
[   35.145473] NDCB3: 0x00000000
[   35.164408] nand: nand_do_read_oob: from = 0x09580000, len = 64
[   35.170614] marvell-nfc pxa3xx-nand: 
[   35.170614] NDCR:  0x9d079fff
[   35.170614] NDCB0: 0x000d3000
[   35.170614] NDCB1: 0x2b000000
[   35.170614] NDCB2: 0x00000001
[   35.170614] NDCB3: 0x00000000
[   35.189544] nand: nand_do_read_oob: from = 0x095a0000, len = 64
[   35.195571] marvell-nfc pxa3xx-nand: 
[   35.195571] NDCR:  0x9d079fff
[   35.195571] NDCB0: 0x000d3000
[   35.195571] NDCB1: 0x2b400000
[   35.195571] NDCB2: 0x00000001
[   35.195571] NDCB3: 0x00000000
[   35.214506] nand: nand_do_read_oob: from = 0x095c0000, len = 64
[   35.220710] marvell-nfc pxa3xx-nand: 
[   35.220710] NDCR:  0x9d079fff
[   35.220710] NDCB0: 0x000d3000
[   35.220710] NDCB1: 0x2b800000
[   35.220710] NDCB2: 0x00000001
[   35.220710] NDCB3: 0x00000000
[   35.239640] nand: nand_do_read_oob: from = 0x095e0000, len = 64
[   35.245669] marvell-nfc pxa3xx-nand: 
[   35.245669] NDCR:  0x9d079fff
[   35.245669] NDCB0: 0x000d3000
[   35.245669] NDCB1: 0x2bc00000
[   35.245669] NDCB2: 0x00000001
[   35.245669] NDCB3: 0x00000000
[   35.264602] nand: nand_do_read_oob: from = 0x09600000, len = 64
[   35.270820] marvell-nfc pxa3xx-nand: 
[   35.270820] NDCR:  0x9d079fff
[   35.270820] NDCB0: 0x000d3000
[   35.270820] NDCB1: 0x2c000000
[   35.270820] NDCB2: 0x00000001
[   35.270820] NDCB3: 0x00000000
[   35.289750] nand: nand_do_read_oob: from = 0x09620000, len = 64
[   35.295777] marvell-nfc pxa3xx-nand: 
[   35.295777] NDCR:  0x9d079fff
[   35.295777] NDCB0: 0x000d3000
[   35.295777] NDCB1: 0x2c400000
[   35.295777] NDCB2: 0x00000001
[   35.295777] NDCB3: 0x00000000
[   35.314712] nand: nand_do_read_oob: from = 0x09640000, len = 64
[   35.320915] marvell-nfc pxa3xx-nand: 
[   35.320915] NDCR:  0x9d079fff
[   35.320915] NDCB0: 0x000d3000
[   35.320915] NDCB1: 0x2c800000
[   35.320915] NDCB2: 0x00000001
[   35.320915] NDCB3: 0x00000000
[   35.339848] nand: nand_do_read_oob: from = 0x09660000, len = 64
[   35.345875] marvell-nfc pxa3xx-nand: 
[   35.345875] NDCR:  0x9d079fff
[   35.345875] NDCB0: 0x000d3000
[   35.345875] NDCB1: 0x2cc00000
[   35.345875] NDCB2: 0x00000001
[   35.345875] NDCB3: 0x00000000
[   35.364810] nand: nand_do_read_oob: from = 0x09680000, len = 64
[   35.371014] marvell-nfc pxa3xx-nand: 
[   35.371014] NDCR:  0x9d079fff
[   35.371014] NDCB0: 0x000d3000
[   35.371014] NDCB1: 0x2d000000
[   35.371014] NDCB2: 0x00000001
[   35.371014] NDCB3: 0x00000000
[   35.389943] nand: nand_do_read_oob: from = 0x096a0000, len = 64
[   35.395975] marvell-nfc pxa3xx-nand: 
[   35.395975] NDCR:  0x9d079fff
[   35.395975] NDCB0: 0x000d3000
[   35.395975] NDCB1: 0x2d400000
[   35.395975] NDCB2: 0x00000001
[   35.395975] NDCB3: 0x00000000
[   35.414909] nand: nand_do_read_oob: from = 0x096c0000, len = 64
[   35.421113] marvell-nfc pxa3xx-nand: 
[   35.421113] NDCR:  0x9d079fff
[   35.421113] NDCB0: 0x000d3000
[   35.421113] NDCB1: 0x2d800000
[   35.421113] NDCB2: 0x00000001
[   35.421113] NDCB3: 0x00000000
[   35.440046] nand: nand_do_read_oob: from = 0x096e0000, len = 64
[   35.446080] marvell-nfc pxa3xx-nand: 
[   35.446080] NDCR:  0x9d079fff
[   35.446080] NDCB0: 0x000d3000
[   35.446080] NDCB1: 0x2dc00000
[   35.446080] NDCB2: 0x00000001
[   35.446080] NDCB3: 0x00000000
[   35.465018] nand: nand_do_read_oob: from = 0x09700000, len = 64
[   35.471220] marvell-nfc pxa3xx-nand: 
[   35.471220] NDCR:  0x9d079fff
[   35.471220] NDCB0: 0x000d3000
[   35.471220] NDCB1: 0x2e000000
[   35.471220] NDCB2: 0x00000001
[   35.471220] NDCB3: 0x00000000
[   35.490151] nand: nand_do_read_oob: from = 0x09720000, len = 64
[   35.496179] marvell-nfc pxa3xx-nand: 
[   35.496179] NDCR:  0x9d079fff
[   35.496179] NDCB0: 0x000d3000
[   35.496179] NDCB1: 0x2e400000
[   35.496179] NDCB2: 0x00000001
[   35.496179] NDCB3: 0x00000000
[   35.515111] nand: nand_do_read_oob: from = 0x09740000, len = 64
[   35.521320] marvell-nfc pxa3xx-nand: 
[   35.521320] NDCR:  0x9d079fff
[   35.521320] NDCB0: 0x000d3000
[   35.521320] NDCB1: 0x2e800000
[   35.521320] NDCB2: 0x00000001
[   35.521320] NDCB3: 0x00000000
[   35.540249] nand: nand_do_read_oob: from = 0x09760000, len = 64
[   35.546277] marvell-nfc pxa3xx-nand: 
[   35.546277] NDCR:  0x9d079fff
[   35.546277] NDCB0: 0x000d3000
[   35.546277] NDCB1: 0x2ec00000
[   35.546277] NDCB2: 0x00000001
[   35.546277] NDCB3: 0x00000000
[   35.565211] nand: nand_do_read_oob: from = 0x09780000, len = 64
[   35.571416] marvell-nfc pxa3xx-nand: 
[   35.571416] NDCR:  0x9d079fff
[   35.571416] NDCB0: 0x000d3000
[   35.571416] NDCB1: 0x2f000000
[   35.571416] NDCB2: 0x00000001
[   35.571416] NDCB3: 0x00000000
[   35.590347] nand: nand_do_read_oob: from = 0x097a0000, len = 64
[   35.596376] marvell-nfc pxa3xx-nand: 
[   35.596376] NDCR:  0x9d079fff
[   35.596376] NDCB0: 0x000d3000
[   35.596376] NDCB1: 0x2f400000
[   35.596376] NDCB2: 0x00000001
[   35.596376] NDCB3: 0x00000000
[   35.615311] nand: nand_do_read_oob: from = 0x097c0000, len = 64
[   35.621514] marvell-nfc pxa3xx-nand: 
[   35.621514] NDCR:  0x9d079fff
[   35.621514] NDCB0: 0x000d3000
[   35.621514] NDCB1: 0x2f800000
[   35.621514] NDCB2: 0x00000001
[   35.621514] NDCB3: 0x00000000
[   35.640446] nand: nand_do_read_oob: from = 0x097e0000, len = 64
[   35.646475] marvell-nfc pxa3xx-nand: 
[   35.646475] NDCR:  0x9d079fff
[   35.646475] NDCB0: 0x000d3000
[   35.646475] NDCB1: 0x2fc00000
[   35.646475] NDCB2: 0x00000001
[   35.646475] NDCB3: 0x00000000
[   35.665411] nand: nand_do_read_oob: from = 0x09800000, len = 64
[   35.671612] marvell-nfc pxa3xx-nand: 
[   35.671612] NDCR:  0x9d079fff
[   35.671612] NDCB0: 0x000d3000
[   35.671612] NDCB1: 0x30000000
[   35.671612] NDCB2: 0x00000001
[   35.671612] NDCB3: 0x00000000
[   35.690545] nand: nand_do_read_oob: from = 0x09820000, len = 64
[   35.696573] marvell-nfc pxa3xx-nand: 
[   35.696573] NDCR:  0x9d079fff
[   35.696573] NDCB0: 0x000d3000
[   35.696573] NDCB1: 0x30400000
[   35.696573] NDCB2: 0x00000001
[   35.696573] NDCB3: 0x00000000
[   35.715507] nand: nand_do_read_oob: from = 0x09840000, len = 64
[   35.721712] marvell-nfc pxa3xx-nand: 
[   35.721712] NDCR:  0x9d079fff
[   35.721712] NDCB0: 0x000d3000
[   35.721712] NDCB1: 0x30800000
[   35.721712] NDCB2: 0x00000001
[   35.721712] NDCB3: 0x00000000
[   35.740641] nand: nand_do_read_oob: from = 0x09860000, len = 64
[   35.746673] marvell-nfc pxa3xx-nand: 
[   35.746673] NDCR:  0x9d079fff
[   35.746673] NDCB0: 0x000d3000
[   35.746673] NDCB1: 0x30c00000
[   35.746673] NDCB2: 0x00000001
[   35.746673] NDCB3: 0x00000000
[   35.765607] nand: nand_do_read_oob: from = 0x09880000, len = 64
[   35.771811] marvell-nfc pxa3xx-nand: 
[   35.771811] NDCR:  0x9d079fff
[   35.771811] NDCB0: 0x000d3000
[   35.771811] NDCB1: 0x31000000
[   35.771811] NDCB2: 0x00000001
[   35.771811] NDCB3: 0x00000000
[   35.790740] nand: nand_do_read_oob: from = 0x098a0000, len = 64
[   35.796771] marvell-nfc pxa3xx-nand: 
[   35.796771] NDCR:  0x9d079fff
[   35.796771] NDCB0: 0x000d3000
[   35.796771] NDCB1: 0x31400000
[   35.796771] NDCB2: 0x00000001
[   35.796771] NDCB3: 0x00000000
[   35.815706] nand: nand_do_read_oob: from = 0x098c0000, len = 64
[   35.821908] marvell-nfc pxa3xx-nand: 
[   35.821908] NDCR:  0x9d079fff
[   35.821908] NDCB0: 0x000d3000
[   35.821908] NDCB1: 0x31800000
[   35.821908] NDCB2: 0x00000001
[   35.821908] NDCB3: 0x00000000
[   35.840839] nand: nand_do_read_oob: from = 0x098e0000, len = 64
[   35.846869] marvell-nfc pxa3xx-nand: 
[   35.846869] NDCR:  0x9d079fff
[   35.846869] NDCB0: 0x000d3000
[   35.846869] NDCB1: 0x31c00000
[   35.846869] NDCB2: 0x00000001
[   35.846869] NDCB3: 0x00000000
[   35.865801] nand: nand_do_read_oob: from = 0x09900000, len = 64
[   35.872006] marvell-nfc pxa3xx-nand: 
[   35.872006] NDCR:  0x9d079fff
[   35.872006] NDCB0: 0x000d3000
[   35.872006] NDCB1: 0x32000000
[   35.872006] NDCB2: 0x00000001
[   35.872006] NDCB3: 0x00000000
[   35.890935] nand: nand_do_read_oob: from = 0x09920000, len = 64
[   35.896967] marvell-nfc pxa3xx-nand: 
[   35.896967] NDCR:  0x9d079fff
[   35.896967] NDCB0: 0x000d3000
[   35.896967] NDCB1: 0x32400000
[   35.896967] NDCB2: 0x00000001
[   35.896967] NDCB3: 0x00000000
[   35.915916] nand: nand_do_read_oob: from = 0x09940000, len = 64
[   35.922125] marvell-nfc pxa3xx-nand: 
[   35.922125] NDCR:  0x9d079fff
[   35.922125] NDCB0: 0x000d3000
[   35.922125] NDCB1: 0x32800000
[   35.922125] NDCB2: 0x00000001
[   35.922125] NDCB3: 0x00000000
[   35.941052] nand: nand_do_read_oob: from = 0x09960000, len = 64
[   35.947084] marvell-nfc pxa3xx-nand: 
[   35.947084] NDCR:  0x9d079fff
[   35.947084] NDCB0: 0x000d3000
[   35.947084] NDCB1: 0x32c00000
[   35.947084] NDCB2: 0x00000001
[   35.947084] NDCB3: 0x00000000
[   35.966015] nand: nand_do_read_oob: from = 0x09980000, len = 64
[   35.972215] marvell-nfc pxa3xx-nand: 
[   35.972215] NDCR:  0x9d079fff
[   35.972215] NDCB0: 0x000d3000
[   35.972215] NDCB1: 0x33000000
[   35.972215] NDCB2: 0x00000001
[   35.972215] NDCB3: 0x00000000
[   35.991142] nand: nand_do_read_oob: from = 0x099a0000, len = 64
[   35.997172] marvell-nfc pxa3xx-nand: 
[   35.997172] NDCR:  0x9d079fff
[   35.997172] NDCB0: 0x000d3000
[   35.997172] NDCB1: 0x33400000
[   35.997172] NDCB2: 0x00000001
[   35.997172] NDCB3: 0x00000000
[   36.016114] nand: nand_do_read_oob: from = 0x099c0000, len = 64
[   36.022320] marvell-nfc pxa3xx-nand: 
[   36.022320] NDCR:  0x9d079fff
[   36.022320] NDCB0: 0x000d3000
[   36.022320] NDCB1: 0x33800000
[   36.022320] NDCB2: 0x00000001
[   36.022320] NDCB3: 0x00000000
[   36.041247] nand: nand_do_read_oob: from = 0x099e0000, len = 64
[   36.047280] marvell-nfc pxa3xx-nand: 
[   36.047280] NDCR:  0x9d079fff
[   36.047280] NDCB0: 0x000d3000
[   36.047280] NDCB1: 0x33c00000
[   36.047280] NDCB2: 0x00000001
[   36.047280] NDCB3: 0x00000000
[   36.066215] nand: nand_do_read_oob: from = 0x09a00000, len = 64
[   36.072419] marvell-nfc pxa3xx-nand: 
[   36.072419] NDCR:  0x9d079fff
[   36.072419] NDCB0: 0x000d3000
[   36.072419] NDCB1: 0x34000000
[   36.072419] NDCB2: 0x00000001
[   36.072419] NDCB3: 0x00000000
[   36.091682] nand: nand_do_read_oob: from = 0x09a20000, len = 64
[   36.097730] marvell-nfc pxa3xx-nand: 
[   36.097730] NDCR:  0x9d079fff
[   36.097730] NDCB0: 0x000d3000
[   36.097730] NDCB1: 0x34400000
[   36.097730] NDCB2: 0x00000001
[   36.097730] NDCB3: 0x00000000
[   36.116690] nand: nand_do_read_oob: from = 0x09a40000, len = 64
[   36.122887] marvell-nfc pxa3xx-nand: 
[   36.122887] NDCR:  0x9d079fff
[   36.122887] NDCB0: 0x000d3000
[   36.122887] NDCB1: 0x34800000
[   36.122887] NDCB2: 0x00000001
[   36.122887] NDCB3: 0x00000000
[   36.141817] nand: nand_do_read_oob: from = 0x09a60000, len = 64
[   36.147849] marvell-nfc pxa3xx-nand: 
[   36.147849] NDCR:  0x9d079fff
[   36.147849] NDCB0: 0x000d3000
[   36.147849] NDCB1: 0x34c00000
[   36.147849] NDCB2: 0x00000001
[   36.147849] NDCB3: 0x00000000
[   36.166783] nand: nand_do_read_oob: from = 0x09a80000, len = 64
[   36.172987] marvell-nfc pxa3xx-nand: 
[   36.172987] NDCR:  0x9d079fff
[   36.172987] NDCB0: 0x000d3000
[   36.172987] NDCB1: 0x35000000
[   36.172987] NDCB2: 0x00000001
[   36.172987] NDCB3: 0x00000000
[   36.191915] nand: nand_do_read_oob: from = 0x09aa0000, len = 64
[   36.197947] marvell-nfc pxa3xx-nand: 
[   36.197947] NDCR:  0x9d079fff
[   36.197947] NDCB0: 0x000d3000
[   36.197947] NDCB1: 0x35400000
[   36.197947] NDCB2: 0x00000001
[   36.197947] NDCB3: 0x00000000
[   36.216879] nand: nand_do_read_oob: from = 0x09ac0000, len = 64
[   36.223085] marvell-nfc pxa3xx-nand: 
[   36.223085] NDCR:  0x9d079fff
[   36.223085] NDCB0: 0x000d3000
[   36.223085] NDCB1: 0x35800000
[   36.223085] NDCB2: 0x00000001
[   36.223085] NDCB3: 0x00000000
[   36.242014] nand: nand_do_read_oob: from = 0x09ae0000, len = 64
[   36.248045] marvell-nfc pxa3xx-nand: 
[   36.248045] NDCR:  0x9d079fff
[   36.248045] NDCB0: 0x000d3000
[   36.248045] NDCB1: 0x35c00000
[   36.248045] NDCB2: 0x00000001
[   36.248045] NDCB3: 0x00000000
[   36.266980] nand: nand_do_read_oob: from = 0x09b00000, len = 64
[   36.273183] marvell-nfc pxa3xx-nand: 
[   36.273183] NDCR:  0x9d079fff
[   36.273183] NDCB0: 0x000d3000
[   36.273183] NDCB1: 0x36000000
[   36.273183] NDCB2: 0x00000001
[   36.273183] NDCB3: 0x00000000
[   36.292111] nand: nand_do_read_oob: from = 0x09b20000, len = 64
[   36.298145] marvell-nfc pxa3xx-nand: 
[   36.298145] NDCR:  0x9d079fff
[   36.298145] NDCB0: 0x000d3000
[   36.298145] NDCB1: 0x36400000
[   36.298145] NDCB2: 0x00000001
[   36.298145] NDCB3: 0x00000000
[   36.317079] nand: nand_do_read_oob: from = 0x09b40000, len = 64
[   36.323283] marvell-nfc pxa3xx-nand: 
[   36.323283] NDCR:  0x9d079fff
[   36.323283] NDCB0: 0x000d3000
[   36.323283] NDCB1: 0x36800000
[   36.323283] NDCB2: 0x00000001
[   36.323283] NDCB3: 0x00000000
[   36.342211] nand: nand_do_read_oob: from = 0x09b60000, len = 64
[   36.348241] marvell-nfc pxa3xx-nand: 
[   36.348241] NDCR:  0x9d079fff
[   36.348241] NDCB0: 0x000d3000
[   36.348241] NDCB1: 0x36c00000
[   36.348241] NDCB2: 0x00000001
[   36.348241] NDCB3: 0x00000000
[   36.367173] nand: nand_do_read_oob: from = 0x09b80000, len = 64
[   36.373371] marvell-nfc pxa3xx-nand: 
[   36.373371] NDCR:  0x9d079fff
[   36.373371] NDCB0: 0x000d3000
[   36.373371] NDCB1: 0x37000000
[   36.373371] NDCB2: 0x00000001
[   36.373371] NDCB3: 0x00000000
[   36.392299] nand: nand_do_read_oob: from = 0x09ba0000, len = 64
[   36.398332] marvell-nfc pxa3xx-nand: 
[   36.398332] NDCR:  0x9d079fff
[   36.398332] NDCB0: 0x000d3000
[   36.398332] NDCB1: 0x37400000
[   36.398332] NDCB2: 0x00000001
[   36.398332] NDCB3: 0x00000000
[   36.417264] nand: nand_do_read_oob: from = 0x09bc0000, len = 64
[   36.423471] marvell-nfc pxa3xx-nand: 
[   36.423471] NDCR:  0x9d079fff
[   36.423471] NDCB0: 0x000d3000
[   36.423471] NDCB1: 0x37800000
[   36.423471] NDCB2: 0x00000001
[   36.423471] NDCB3: 0x00000000
[   36.442400] nand: nand_do_read_oob: from = 0x09be0000, len = 64
[   36.448429] marvell-nfc pxa3xx-nand: 
[   36.448429] NDCR:  0x9d079fff
[   36.448429] NDCB0: 0x000d3000
[   36.448429] NDCB1: 0x37c00000
[   36.448429] NDCB2: 0x00000001
[   36.448429] NDCB3: 0x00000000
[   36.467366] nand: nand_do_read_oob: from = 0x09c00000, len = 64
[   36.473569] marvell-nfc pxa3xx-nand: 
[   36.473569] NDCR:  0x9d079fff
[   36.473569] NDCB0: 0x000d3000
[   36.473569] NDCB1: 0x38000000
[   36.473569] NDCB2: 0x00000001
[   36.473569] NDCB3: 0x00000000
[   36.492498] nand: nand_do_read_oob: from = 0x09c20000, len = 64
[   36.498529] marvell-nfc pxa3xx-nand: 
[   36.498529] NDCR:  0x9d079fff
[   36.498529] NDCB0: 0x000d3000
[   36.498529] NDCB1: 0x38400000
[   36.498529] NDCB2: 0x00000001
[   36.498529] NDCB3: 0x00000000
[   36.517459] nand: nand_do_read_oob: from = 0x09c40000, len = 64
[   36.523659] marvell-nfc pxa3xx-nand: 
[   36.523659] NDCR:  0x9d079fff
[   36.523659] NDCB0: 0x000d3000
[   36.523659] NDCB1: 0x38800000
[   36.523659] NDCB2: 0x00000001
[   36.523659] NDCB3: 0x00000000
[   36.542587] nand: nand_do_read_oob: from = 0x09c60000, len = 64
[   36.548618] marvell-nfc pxa3xx-nand: 
[   36.548618] NDCR:  0x9d079fff
[   36.548618] NDCB0: 0x000d3000
[   36.548618] NDCB1: 0x38c00000
[   36.548618] NDCB2: 0x00000001
[   36.548618] NDCB3: 0x00000000
[   36.567690] nand: nand_do_read_oob: from = 0x09c80000, len = 64
[   36.573895] marvell-nfc pxa3xx-nand: 
[   36.573895] NDCR:  0x9d079fff
[   36.573895] NDCB0: 0x000d3000
[   36.573895] NDCB1: 0x39000000
[   36.573895] NDCB2: 0x00000001
[   36.573895] NDCB3: 0x00000000
[   36.592823] nand: nand_do_read_oob: from = 0x09ca0000, len = 64
[   36.599025] marvell-nfc pxa3xx-nand: 
[   36.599025] NDCR:  0x9d079fff
[   36.599025] NDCB0: 0x000d3000
[   36.599025] NDCB1: 0x39400000
[   36.599025] NDCB2: 0x00000001
[   36.599025] NDCB3: 0x00000000
[   36.617945] nand: nand_do_read_oob: from = 0x09cc0000, len = 64
[   36.624147] marvell-nfc pxa3xx-nand: 
[   36.624147] NDCR:  0x9d079fff
[   36.624147] NDCB0: 0x000d3000
[   36.624147] NDCB1: 0x39800000
[   36.624147] NDCB2: 0x00000001
[   36.624147] NDCB3: 0x00000000
[   36.643076] nand: nand_do_read_oob: from = 0x09ce0000, len = 64
[   36.649278] marvell-nfc pxa3xx-nand: 
[   36.649278] NDCR:  0x9d079fff
[   36.649278] NDCB0: 0x000d3000
[   36.649278] NDCB1: 0x39c00000
[   36.649278] NDCB2: 0x00000001
[   36.649278] NDCB3: 0x00000000
[   36.668199] nand: nand_do_read_oob: from = 0x09d00000, len = 64
[   36.674401] marvell-nfc pxa3xx-nand: 
[   36.674401] NDCR:  0x9d079fff
[   36.674401] NDCB0: 0x000d3000
[   36.674401] NDCB1: 0x3a000000
[   36.674401] NDCB2: 0x00000001
[   36.674401] NDCB3: 0x00000000
[   36.693332] nand: nand_do_read_oob: from = 0x09d20000, len = 64
[   36.699531] marvell-nfc pxa3xx-nand: 
[   36.699531] NDCR:  0x9d079fff
[   36.699531] NDCB0: 0x000d3000
[   36.699531] NDCB1: 0x3a400000
[   36.699531] NDCB2: 0x00000001
[   36.699531] NDCB3: 0x00000000
[   36.718454] nand: nand_do_read_oob: from = 0x09d40000, len = 64
[   36.724654] marvell-nfc pxa3xx-nand: 
[   36.724654] NDCR:  0x9d079fff
[   36.724654] NDCB0: 0x000d3000
[   36.724654] NDCB1: 0x3a800000
[   36.724654] NDCB2: 0x00000001
[   36.724654] NDCB3: 0x00000000
[   36.743583] nand: nand_do_read_oob: from = 0x09d60000, len = 64
[   36.749786] marvell-nfc pxa3xx-nand: 
[   36.749786] NDCR:  0x9d079fff
[   36.749786] NDCB0: 0x000d3000
[   36.749786] NDCB1: 0x3ac00000
[   36.749786] NDCB2: 0x00000001
[   36.749786] NDCB3: 0x00000000
[   36.768912] nand: nand_do_read_oob: from = 0x09d80000, len = 64
[   36.774959] marvell-nfc pxa3xx-nand: 
[   36.774959] NDCR:  0x9d079fff
[   36.774959] NDCB0: 0x000d3000
[   36.774959] NDCB1: 0x3b000000
[   36.774959] NDCB2: 0x00000001
[   36.774959] NDCB3: 0x00000000
[   36.793907] nand: nand_do_read_oob: from = 0x09da0000, len = 64
[   36.800109] marvell-nfc pxa3xx-nand: 
[   36.800109] NDCR:  0x9d079fff
[   36.800109] NDCB0: 0x000d3000
[   36.800109] NDCB1: 0x3b400000
[   36.800109] NDCB2: 0x00000001
[   36.800109] NDCB3: 0x00000000
[   36.819035] nand: nand_do_read_oob: from = 0x09dc0000, len = 64
[   36.825070] marvell-nfc pxa3xx-nand: 
[   36.825070] NDCR:  0x9d079fff
[   36.825070] NDCB0: 0x000d3000
[   36.825070] NDCB1: 0x3b800000
[   36.825070] NDCB2: 0x00000001
[   36.825070] NDCB3: 0x00000000
[   36.844002] nand: nand_do_read_oob: from = 0x09de0000, len = 64
[   36.850208] marvell-nfc pxa3xx-nand: 
[   36.850208] NDCR:  0x9d079fff
[   36.850208] NDCB0: 0x000d3000
[   36.850208] NDCB1: 0x3bc00000
[   36.850208] NDCB2: 0x00000001
[   36.850208] NDCB3: 0x00000000
[   36.869133] nand: nand_do_read_oob: from = 0x09e00000, len = 64
[   36.875168] marvell-nfc pxa3xx-nand: 
[   36.875168] NDCR:  0x9d079fff
[   36.875168] NDCB0: 0x000d3000
[   36.875168] NDCB1: 0x3c000000
[   36.875168] NDCB2: 0x00000001
[   36.875168] NDCB3: 0x00000000
[   36.894099] nand: nand_do_read_oob: from = 0x09e20000, len = 64
[   36.900295] marvell-nfc pxa3xx-nand: 
[   36.900295] NDCR:  0x9d079fff
[   36.900295] NDCB0: 0x000d3000
[   36.900295] NDCB1: 0x3c400000
[   36.900295] NDCB2: 0x00000001
[   36.900295] NDCB3: 0x00000000
[   36.919223] nand: nand_do_read_oob: from = 0x09e40000, len = 64
[   36.925258] marvell-nfc pxa3xx-nand: 
[   36.925258] NDCR:  0x9d079fff
[   36.925258] NDCB0: 0x000d3000
[   36.925258] NDCB1: 0x3c800000
[   36.925258] NDCB2: 0x00000001
[   36.925258] NDCB3: 0x00000000
[   36.944188] nand: nand_do_read_oob: from = 0x09e60000, len = 64
[   36.950386] marvell-nfc pxa3xx-nand: 
[   36.950386] NDCR:  0x9d079fff
[   36.950386] NDCB0: 0x000d3000
[   36.950386] NDCB1: 0x3cc00000
[   36.950386] NDCB2: 0x00000001
[   36.950386] NDCB3: 0x00000000
[   36.969314] nand: nand_do_read_oob: from = 0x09e80000, len = 64
[   36.975347] marvell-nfc pxa3xx-nand: 
[   36.975347] NDCR:  0x9d079fff
[   36.975347] NDCB0: 0x000d3000
[   36.975347] NDCB1: 0x3d000000
[   36.975347] NDCB2: 0x00000001
[   36.975347] NDCB3: 0x00000000
[   36.994281] nand: nand_do_read_oob: from = 0x09ea0000, len = 64
[   37.000486] marvell-nfc pxa3xx-nand: 
[   37.000486] NDCR:  0x9d079fff
[   37.000486] NDCB0: 0x000d3000
[   37.000486] NDCB1: 0x3d400000
[   37.000486] NDCB2: 0x00000001
[   37.000486] NDCB3: 0x00000000
[   37.019428] nand: nand_do_read_oob: from = 0x09ec0000, len = 64
[   37.025464] marvell-nfc pxa3xx-nand: 
[   37.025464] NDCR:  0x9d079fff
[   37.025464] NDCB0: 0x000d3000
[   37.025464] NDCB1: 0x3d800000
[   37.025464] NDCB2: 0x00000001
[   37.025464] NDCB3: 0x00000000
[   37.044401] nand: nand_do_read_oob: from = 0x09ee0000, len = 64
[   37.050603] marvell-nfc pxa3xx-nand: 
[   37.050603] NDCR:  0x9d079fff
[   37.050603] NDCB0: 0x000d3000
[   37.050603] NDCB1: 0x3dc00000
[   37.050603] NDCB2: 0x00000001
[   37.050603] NDCB3: 0x00000000
[   37.069528] nand: nand_do_read_oob: from = 0x09f00000, len = 64
[   37.075561] marvell-nfc pxa3xx-nand: 
[   37.075561] NDCR:  0x9d079fff
[   37.075561] NDCB0: 0x000d3000
[   37.075561] NDCB1: 0x3e000000
[   37.075561] NDCB2: 0x00000001
[   37.075561] NDCB3: 0x00000000
[   37.094492] nand: nand_do_read_oob: from = 0x09f20000, len = 64
[   37.100701] marvell-nfc pxa3xx-nand: 
[   37.100701] NDCR:  0x9d079fff
[   37.100701] NDCB0: 0x000d3000
[   37.100701] NDCB1: 0x3e400000
[   37.100701] NDCB2: 0x00000001
[   37.100701] NDCB3: 0x00000000
[   37.119627] nand: nand_do_read_oob: from = 0x09f40000, len = 64
[   37.125661] marvell-nfc pxa3xx-nand: 
[   37.125661] NDCR:  0x9d079fff
[   37.125661] NDCB0: 0x000d3000
[   37.125661] NDCB1: 0x3e800000
[   37.125661] NDCB2: 0x00000001
[   37.125661] NDCB3: 0x00000000
[   37.144615] nand: nand_do_read_oob: from = 0x09f60000, len = 64
[   37.150818] marvell-nfc pxa3xx-nand: 
[   37.150818] NDCR:  0x9d079fff
[   37.150818] NDCB0: 0x000d3000
[   37.150818] NDCB1: 0x3ec00000
[   37.150818] NDCB2: 0x00000001
[   37.150818] NDCB3: 0x00000000
[   37.169746] nand: nand_do_read_oob: from = 0x09f80000, len = 64
[   37.175775] marvell-nfc pxa3xx-nand: 
[   37.175775] NDCR:  0x9d079fff
[   37.175775] NDCB0: 0x000d3000
[   37.175775] NDCB1: 0x3f000000
[   37.175775] NDCB2: 0x00000001
[   37.175775] NDCB3: 0x00000000
[   37.194708] nand: nand_do_read_oob: from = 0x09fa0000, len = 64
[   37.200914] marvell-nfc pxa3xx-nand: 
[   37.200914] NDCR:  0x9d079fff
[   37.200914] NDCB0: 0x000d3000
[   37.200914] NDCB1: 0x3f400000
[   37.200914] NDCB2: 0x00000001
[   37.200914] NDCB3: 0x00000000
[   37.219841] nand: nand_do_read_oob: from = 0x09fc0000, len = 64
[   37.225873] marvell-nfc pxa3xx-nand: 
[   37.225873] NDCR:  0x9d079fff
[   37.225873] NDCB0: 0x000d3000
[   37.225873] NDCB1: 0x3f800000
[   37.225873] NDCB2: 0x00000001
[   37.225873] NDCB3: 0x00000000
[   37.244805] nand: nand_do_read_oob: from = 0x09fe0000, len = 64
[   37.251015] marvell-nfc pxa3xx-nand: 
[   37.251015] NDCR:  0x9d079fff
[   37.251015] NDCB0: 0x000d3000
[   37.251015] NDCB1: 0x3fc00000
[   37.251015] NDCB2: 0x00000001
[   37.251015] NDCB3: 0x00000000
[   37.269942] nand: nand_do_read_oob: from = 0x0a000000, len = 64
[   37.275972] marvell-nfc pxa3xx-nand: 
[   37.275972] NDCR:  0x9d079fff
[   37.275972] NDCB0: 0x000d3000
[   37.275972] NDCB1: 0x40000000
[   37.275972] NDCB2: 0x00000001
[   37.275972] NDCB3: 0x00000000
[   37.294904] nand: nand_do_read_oob: from = 0x0a020000, len = 64
[   37.301112] marvell-nfc pxa3xx-nand: 
[   37.301112] NDCR:  0x9d079fff
[   37.301112] NDCB0: 0x000d3000
[   37.301112] NDCB1: 0x40400000
[   37.301112] NDCB2: 0x00000001
[   37.301112] NDCB3: 0x00000000
[   37.320038] nand: nand_do_read_oob: from = 0x0a040000, len = 64
[   37.326070] marvell-nfc pxa3xx-nand: 
[   37.326070] NDCR:  0x9d079fff
[   37.326070] NDCB0: 0x000d3000
[   37.326070] NDCB1: 0x40800000
[   37.326070] NDCB2: 0x00000001
[   37.326070] NDCB3: 0x00000000
[   37.345001] nand: nand_do_read_oob: from = 0x0a060000, len = 64
[   37.351202] marvell-nfc pxa3xx-nand: 
[   37.351202] NDCR:  0x9d079fff
[   37.351202] NDCB0: 0x000d3000
[   37.351202] NDCB1: 0x40c00000
[   37.351202] NDCB2: 0x00000001
[   37.351202] NDCB3: 0x00000000
[   37.370131] nand: nand_do_read_oob: from = 0x0a080000, len = 64
[   37.376160] marvell-nfc pxa3xx-nand: 
[   37.376160] NDCR:  0x9d079fff
[   37.376160] NDCB0: 0x000d3000
[   37.376160] NDCB1: 0x41000000
[   37.376160] NDCB2: 0x00000001
[   37.376160] NDCB3: 0x00000000
[   37.395091] nand: nand_do_read_oob: from = 0x0a0a0000, len = 64
[   37.401299] marvell-nfc pxa3xx-nand: 
[   37.401299] NDCR:  0x9d079fff
[   37.401299] NDCB0: 0x000d3000
[   37.401299] NDCB1: 0x41400000
[   37.401299] NDCB2: 0x00000001
[   37.401299] NDCB3: 0x00000000
[   37.420226] nand: nand_do_read_oob: from = 0x0a0c0000, len = 64
[   37.426258] marvell-nfc pxa3xx-nand: 
[   37.426258] NDCR:  0x9d079fff
[   37.426258] NDCB0: 0x000d3000
[   37.426258] NDCB1: 0x41800000
[   37.426258] NDCB2: 0x00000001
[   37.426258] NDCB3: 0x00000000
[   37.445191] nand: nand_do_read_oob: from = 0x0a0e0000, len = 64
[   37.451388] marvell-nfc pxa3xx-nand: 
[   37.451388] NDCR:  0x9d079fff
[   37.451388] NDCB0: 0x000d3000
[   37.451388] NDCB1: 0x41c00000
[   37.451388] NDCB2: 0x00000001
[   37.451388] NDCB3: 0x00000000
[   37.470319] nand: nand_do_read_oob: from = 0x0a100000, len = 64
[   37.476349] marvell-nfc pxa3xx-nand: 
[   37.476349] NDCR:  0x9d079fff
[   37.476349] NDCB0: 0x000d3000
[   37.476349] NDCB1: 0x42000000
[   37.476349] NDCB2: 0x00000001
[   37.476349] NDCB3: 0x00000000
[   37.495281] nand: nand_do_read_oob: from = 0x0a120000, len = 64
[   37.501487] marvell-nfc pxa3xx-nand: 
[   37.501487] NDCR:  0x9d079fff
[   37.501487] NDCB0: 0x000d3000
[   37.501487] NDCB1: 0x42400000
[   37.501487] NDCB2: 0x00000001
[   37.501487] NDCB3: 0x00000000
[   37.520417] nand: nand_do_read_oob: from = 0x0a140000, len = 64
[   37.526448] marvell-nfc pxa3xx-nand: 
[   37.526448] NDCR:  0x9d079fff
[   37.526448] NDCB0: 0x000d3000
[   37.526448] NDCB1: 0x42800000
[   37.526448] NDCB2: 0x00000001
[   37.526448] NDCB3: 0x00000000
[   37.545379] nand: nand_do_read_oob: from = 0x0a160000, len = 64
[   37.551584] marvell-nfc pxa3xx-nand: 
[   37.551584] NDCR:  0x9d079fff
[   37.551584] NDCB0: 0x000d3000
[   37.551584] NDCB1: 0x42c00000
[   37.551584] NDCB2: 0x00000001
[   37.551584] NDCB3: 0x00000000
[   37.570514] nand: nand_do_read_oob: from = 0x0a180000, len = 64
[   37.576546] marvell-nfc pxa3xx-nand: 
[   37.576546] NDCR:  0x9d079fff
[   37.576546] NDCB0: 0x000d3000
[   37.576546] NDCB1: 0x43000000
[   37.576546] NDCB2: 0x00000001
[   37.576546] NDCB3: 0x00000000
[   37.595477] nand: nand_do_read_oob: from = 0x0a1a0000, len = 64
[   37.601676] marvell-nfc pxa3xx-nand: 
[   37.601676] NDCR:  0x9d079fff
[   37.601676] NDCB0: 0x000d3000
[   37.601676] NDCB1: 0x43400000
[   37.601676] NDCB2: 0x00000001
[   37.601676] NDCB3: 0x00000000
[   37.620605] nand: nand_do_read_oob: from = 0x0a1c0000, len = 64
[   37.626635] marvell-nfc pxa3xx-nand: 
[   37.626635] NDCR:  0x9d079fff
[   37.626635] NDCB0: 0x000d3000
[   37.626635] NDCB1: 0x43800000
[   37.626635] NDCB2: 0x00000001
[   37.626635] NDCB3: 0x00000000
[   37.645567] nand: nand_do_read_oob: from = 0x0a1e0000, len = 64
[   37.651764] marvell-nfc pxa3xx-nand: 
[   37.651764] NDCR:  0x9d079fff
[   37.651764] NDCB0: 0x000d3000
[   37.651764] NDCB1: 0x43c00000
[   37.651764] NDCB2: 0x00000001
[   37.651764] NDCB3: 0x00000000
[   37.670692] nand: nand_do_read_oob: from = 0x0a200000, len = 64
[   37.676724] marvell-nfc pxa3xx-nand: 
[   37.676724] NDCR:  0x9d079fff
[   37.676724] NDCB0: 0x000d3000
[   37.676724] NDCB1: 0x44000000
[   37.676724] NDCB2: 0x00000001
[   37.676724] NDCB3: 0x00000000
[   37.695659] nand: nand_do_read_oob: from = 0x0a220000, len = 64
[   37.701863] marvell-nfc pxa3xx-nand: 
[   37.701863] NDCR:  0x9d079fff
[   37.701863] NDCB0: 0x000d3000
[   37.701863] NDCB1: 0x44400000
[   37.701863] NDCB2: 0x00000001
[   37.701863] NDCB3: 0x00000000
[   37.720792] nand: nand_do_read_oob: from = 0x0a240000, len = 64
[   37.726824] marvell-nfc pxa3xx-nand: 
[   37.726824] NDCR:  0x9d079fff
[   37.726824] NDCB0: 0x000d3000
[   37.726824] NDCB1: 0x44800000
[   37.726824] NDCB2: 0x00000001
[   37.726824] NDCB3: 0x00000000
[   37.745757] nand: nand_do_read_oob: from = 0x0a260000, len = 64
[   37.751963] marvell-nfc pxa3xx-nand: 
[   37.751963] NDCR:  0x9d079fff
[   37.751963] NDCB0: 0x000d3000
[   37.751963] NDCB1: 0x44c00000
[   37.751963] NDCB2: 0x00000001
[   37.751963] NDCB3: 0x00000000
[   37.770891] nand: nand_do_read_oob: from = 0x0a280000, len = 64
[   37.776922] marvell-nfc pxa3xx-nand: 
[   37.776922] NDCR:  0x9d079fff
[   37.776922] NDCB0: 0x000d3000
[   37.776922] NDCB1: 0x45000000
[   37.776922] NDCB2: 0x00000001
[   37.776922] NDCB3: 0x00000000
[   37.795872] nand: nand_do_read_oob: from = 0x0a2a0000, len = 64
[   37.802078] marvell-nfc pxa3xx-nand: 
[   37.802078] NDCR:  0x9d079fff
[   37.802078] NDCB0: 0x000d3000
[   37.802078] NDCB1: 0x45400000
[   37.802078] NDCB2: 0x00000001
[   37.802078] NDCB3: 0x00000000
[   37.821010] nand: nand_do_read_oob: from = 0x0a2c0000, len = 64
[   37.827038] marvell-nfc pxa3xx-nand: 
[   37.827038] NDCR:  0x9d079fff
[   37.827038] NDCB0: 0x000d3000
[   37.827038] NDCB1: 0x45800000
[   37.827038] NDCB2: 0x00000001
[   37.827038] NDCB3: 0x00000000
[   37.845971] nand: nand_do_read_oob: from = 0x0a2e0000, len = 64
[   37.852176] marvell-nfc pxa3xx-nand: 
[   37.852176] NDCR:  0x9d079fff
[   37.852176] NDCB0: 0x000d3000
[   37.852176] NDCB1: 0x45c00000
[   37.852176] NDCB2: 0x00000001
[   37.852176] NDCB3: 0x00000000
[   37.871105] nand: nand_do_read_oob: from = 0x0a300000, len = 64
[   37.877136] marvell-nfc pxa3xx-nand: 
[   37.877136] NDCR:  0x9d079fff
[   37.877136] NDCB0: 0x000d3000
[   37.877136] NDCB1: 0x46000000
[   37.877136] NDCB2: 0x00000001
[   37.877136] NDCB3: 0x00000000
[   37.896069] nand: nand_do_read_oob: from = 0x0a320000, len = 64
[   37.902275] marvell-nfc pxa3xx-nand: 
[   37.902275] NDCR:  0x9d079fff
[   37.902275] NDCB0: 0x000d3000
[   37.902275] NDCB1: 0x46400000
[   37.902275] NDCB2: 0x00000001
[   37.902275] NDCB3: 0x00000000
[   37.921202] nand: nand_do_read_oob: from = 0x0a340000, len = 64
[   37.927235] marvell-nfc pxa3xx-nand: 
[   37.927235] NDCR:  0x9d079fff
[   37.927235] NDCB0: 0x000d3000
[   37.927235] NDCB1: 0x46800000
[   37.927235] NDCB2: 0x00000001
[   37.927235] NDCB3: 0x00000000
[   37.946167] nand: nand_do_read_oob: from = 0x0a360000, len = 64
[   37.952371] marvell-nfc pxa3xx-nand: 
[   37.952371] NDCR:  0x9d079fff
[   37.952371] NDCB0: 0x000d3000
[   37.952371] NDCB1: 0x46c00000
[   37.952371] NDCB2: 0x00000001
[   37.952371] NDCB3: 0x00000000
[   37.971303] nand: nand_do_read_oob: from = 0x0a380000, len = 64
[   37.977334] marvell-nfc pxa3xx-nand: 
[   37.977334] NDCR:  0x9d079fff
[   37.977334] NDCB0: 0x000d3000
[   37.977334] NDCB1: 0x47000000
[   37.977334] NDCB2: 0x00000001
[   37.977334] NDCB3: 0x00000000
[   37.996265] nand: nand_do_read_oob: from = 0x0a3a0000, len = 64
[   38.002463] marvell-nfc pxa3xx-nand: 
[   38.002463] NDCR:  0x9d079fff
[   38.002463] NDCB0: 0x000d3000
[   38.002463] NDCB1: 0x47400000
[   38.002463] NDCB2: 0x00000001
[   38.002463] NDCB3: 0x00000000
[   38.021403] nand: nand_do_read_oob: from = 0x0a3c0000, len = 64
[   38.027442] marvell-nfc pxa3xx-nand: 
[   38.027442] NDCR:  0x9d079fff
[   38.027442] NDCB0: 0x000d3000
[   38.027442] NDCB1: 0x47800000
[   38.027442] NDCB2: 0x00000001
[   38.027442] NDCB3: 0x00000000
[   38.046374] nand: nand_do_read_oob: from = 0x0a3e0000, len = 64
[   38.052579] marvell-nfc pxa3xx-nand: 
[   38.052579] NDCR:  0x9d079fff
[   38.052579] NDCB0: 0x000d3000
[   38.052579] NDCB1: 0x47c00000
[   38.052579] NDCB2: 0x00000001
[   38.052579] NDCB3: 0x00000000
[   38.071508] nand: nand_do_read_oob: from = 0x0a400000, len = 64
[   38.077538] marvell-nfc pxa3xx-nand: 
[   38.077538] NDCR:  0x9d079fff
[   38.077538] NDCB0: 0x000d3000
[   38.077538] NDCB1: 0x48000000
[   38.077538] NDCB2: 0x00000001
[   38.077538] NDCB3: 0x00000000
[   38.096902] nand: nand_do_read_oob: from = 0x0a420000, len = 64
[   38.103144] marvell-nfc pxa3xx-nand: 
[   38.103144] NDCR:  0x9d079fff
[   38.103144] NDCB0: 0x000d3000
[   38.103144] NDCB1: 0x48400000
[   38.103144] NDCB2: 0x00000001
[   38.103144] NDCB3: 0x00000000
[   38.122080] nand: nand_do_read_oob: from = 0x0a440000, len = 64
[   38.128111] marvell-nfc pxa3xx-nand: 
[   38.128111] NDCR:  0x9d079fff
[   38.128111] NDCB0: 0x000d3000
[   38.128111] NDCB1: 0x48800000
[   38.128111] NDCB2: 0x00000001
[   38.128111] NDCB3: 0x00000000
[   38.147043] nand: nand_do_read_oob: from = 0x0a460000, len = 64
[   38.153250] marvell-nfc pxa3xx-nand: 
[   38.153250] NDCR:  0x9d079fff
[   38.153250] NDCB0: 0x000d3000
[   38.153250] NDCB1: 0x48c00000
[   38.153250] NDCB2: 0x00000001
[   38.153250] NDCB3: 0x00000000
[   38.172179] nand: nand_do_read_oob: from = 0x0a480000, len = 64
[   38.178209] marvell-nfc pxa3xx-nand: 
[   38.178209] NDCR:  0x9d079fff
[   38.178209] NDCB0: 0x000d3000
[   38.178209] NDCB1: 0x49000000
[   38.178209] NDCB2: 0x00000001
[   38.178209] NDCB3: 0x00000000
[   38.197142] nand: nand_do_read_oob: from = 0x0a4a0000, len = 64
[   38.203349] marvell-nfc pxa3xx-nand: 
[   38.203349] NDCR:  0x9d079fff
[   38.203349] NDCB0: 0x000d3000
[   38.203349] NDCB1: 0x49400000
[   38.203349] NDCB2: 0x00000001
[   38.203349] NDCB3: 0x00000000
[   38.222277] nand: nand_do_read_oob: from = 0x0a4c0000, len = 64
[   38.228307] marvell-nfc pxa3xx-nand: 
[   38.228307] NDCR:  0x9d079fff
[   38.228307] NDCB0: 0x000d3000
[   38.228307] NDCB1: 0x49800000
[   38.228307] NDCB2: 0x00000001
[   38.228307] NDCB3: 0x00000000
[   38.247241] nand: nand_do_read_oob: from = 0x0a4e0000, len = 64
[   38.253447] marvell-nfc pxa3xx-nand: 
[   38.253447] NDCR:  0x9d079fff
[   38.253447] NDCB0: 0x000d3000
[   38.253447] NDCB1: 0x49c00000
[   38.253447] NDCB2: 0x00000001
[   38.253447] NDCB3: 0x00000000
[   38.272377] nand: nand_do_read_oob: from = 0x0a500000, len = 64
[   38.278406] marvell-nfc pxa3xx-nand: 
[   38.278406] NDCR:  0x9d079fff
[   38.278406] NDCB0: 0x000d3000
[   38.278406] NDCB1: 0x4a000000
[   38.278406] NDCB2: 0x00000001
[   38.278406] NDCB3: 0x00000000
[   38.297339] nand: nand_do_read_oob: from = 0x0a520000, len = 64
[   38.303545] marvell-nfc pxa3xx-nand: 
[   38.303545] NDCR:  0x9d079fff
[   38.303545] NDCB0: 0x000d3000
[   38.303545] NDCB1: 0x4a400000
[   38.303545] NDCB2: 0x00000001
[   38.303545] NDCB3: 0x00000000
[   38.322475] nand: nand_do_read_oob: from = 0x0a540000, len = 64
[   38.328505] marvell-nfc pxa3xx-nand: 
[   38.328505] NDCR:  0x9d079fff
[   38.328505] NDCB0: 0x000d3000
[   38.328505] NDCB1: 0x4a800000
[   38.328505] NDCB2: 0x00000001
[   38.328505] NDCB3: 0x00000000
[   38.347438] nand: nand_do_read_oob: from = 0x0a560000, len = 64
[   38.353645] marvell-nfc pxa3xx-nand: 
[   38.353645] NDCR:  0x9d079fff
[   38.353645] NDCB0: 0x000d3000
[   38.353645] NDCB1: 0x4ac00000
[   38.353645] NDCB2: 0x00000001
[   38.353645] NDCB3: 0x00000000
[   38.372572] nand: nand_do_read_oob: from = 0x0a580000, len = 64
[   38.378603] marvell-nfc pxa3xx-nand: 
[   38.378603] NDCR:  0x9d079fff
[   38.378603] NDCB0: 0x000d3000
[   38.378603] NDCB1: 0x4b000000
[   38.378603] NDCB2: 0x00000001
[   38.378603] NDCB3: 0x00000000
[   38.397645] nand: nand_do_read_oob: from = 0x0a5a0000, len = 64
[   38.403844] marvell-nfc pxa3xx-nand: 
[   38.403844] NDCR:  0x9d079fff
[   38.403844] NDCB0: 0x000d3000
[   38.403844] NDCB1: 0x4b400000
[   38.403844] NDCB2: 0x00000001
[   38.403844] NDCB3: 0x00000000
[   38.422795] nand: nand_do_read_oob: from = 0x0a5c0000, len = 64
[   38.429001] marvell-nfc pxa3xx-nand: 
[   38.429001] NDCR:  0x9d079fff
[   38.429001] NDCB0: 0x000d3000
[   38.429001] NDCB1: 0x4b800000
[   38.429001] NDCB2: 0x00000001
[   38.429001] NDCB3: 0x00000000
[   38.447922] nand: nand_do_read_oob: from = 0x0a5e0000, len = 64
[   38.454123] marvell-nfc pxa3xx-nand: 
[   38.454123] NDCR:  0x9d079fff
[   38.454123] NDCB0: 0x000d3000
[   38.454123] NDCB1: 0x4bc00000
[   38.454123] NDCB2: 0x00000001
[   38.454123] NDCB3: 0x00000000
[   38.473053] nand: nand_do_read_oob: from = 0x0a600000, len = 64
[   38.479255] marvell-nfc pxa3xx-nand: 
[   38.479255] NDCR:  0x9d079fff
[   38.479255] NDCB0: 0x000d3000
[   38.479255] NDCB1: 0x4c000000
[   38.479255] NDCB2: 0x00000001
[   38.479255] NDCB3: 0x00000000
[   38.498176] nand: nand_do_read_oob: from = 0x0a620000, len = 64
[   38.504375] marvell-nfc pxa3xx-nand: 
[   38.504375] NDCR:  0x9d079fff
[   38.504375] NDCB0: 0x000d3000
[   38.504375] NDCB1: 0x4c400000
[   38.504375] NDCB2: 0x00000001
[   38.504375] NDCB3: 0x00000000
[   38.523300] nand: nand_do_read_oob: from = 0x0a640000, len = 64
[   38.529501] marvell-nfc pxa3xx-nand: 
[   38.529501] NDCR:  0x9d079fff
[   38.529501] NDCB0: 0x000d3000
[   38.529501] NDCB1: 0x4c800000
[   38.529501] NDCB2: 0x00000001
[   38.529501] NDCB3: 0x00000000
[   38.548419] nand: nand_do_read_oob: from = 0x0a660000, len = 64
[   38.554621] marvell-nfc pxa3xx-nand: 
[   38.554621] NDCR:  0x9d079fff
[   38.554621] NDCB0: 0x000d3000
[   38.554621] NDCB1: 0x4cc00000
[   38.554621] NDCB2: 0x00000001
[   38.554621] NDCB3: 0x00000000
[   38.573555] nand: nand_do_read_oob: from = 0x0a680000, len = 64
[   38.579753] marvell-nfc pxa3xx-nand: 
[   38.579753] NDCR:  0x9d079fff
[   38.579753] NDCB0: 0x000d3000
[   38.579753] NDCB1: 0x4d000000
[   38.579753] NDCB2: 0x00000001
[   38.579753] NDCB3: 0x00000000
[   38.598772] nand: nand_do_read_oob: from = 0x0a6a0000, len = 64
[   38.604805] marvell-nfc pxa3xx-nand: 
[   38.604805] NDCR:  0x9d079fff
[   38.604805] NDCB0: 0x000d3000
[   38.604805] NDCB1: 0x4d400000
[   38.604805] NDCB2: 0x00000001
[   38.604805] NDCB3: 0x00000000
[   38.623728] nand: nand_do_read_oob: from = 0x0a6c0000, len = 64
[   38.629930] marvell-nfc pxa3xx-nand: 
[   38.629930] NDCR:  0x9d079fff
[   38.629930] NDCB0: 0x000d3000
[   38.629930] NDCB1: 0x4d800000
[   38.629930] NDCB2: 0x00000001
[   38.629930] NDCB3: 0x00000000
[   38.648899] nand: nand_do_read_oob: from = 0x0a6e0000, len = 64
[   38.654937] marvell-nfc pxa3xx-nand: 
[   38.654937] NDCR:  0x9d079fff
[   38.654937] NDCB0: 0x000d3000
[   38.654937] NDCB1: 0x4dc00000
[   38.654937] NDCB2: 0x00000001
[   38.654937] NDCB3: 0x00000000
[   38.673877] nand: nand_do_read_oob: from = 0x0a700000, len = 64
[   38.680080] marvell-nfc pxa3xx-nand: 
[   38.680080] NDCR:  0x9d079fff
[   38.680080] NDCB0: 0x000d3000
[   38.680080] NDCB1: 0x4e000000
[   38.680080] NDCB2: 0x00000001
[   38.680080] NDCB3: 0x00000000
[   38.699048] nand: nand_do_read_oob: from = 0x0a720000, len = 64
[   38.705084] marvell-nfc pxa3xx-nand: 
[   38.705084] NDCR:  0x9d079fff
[   38.705084] NDCB0: 0x000d3000
[   38.705084] NDCB1: 0x4e400000
[   38.705084] NDCB2: 0x00000001
[   38.705084] NDCB3: 0x00000000
[   38.724019] nand: nand_do_read_oob: from = 0x0a740000, len = 64
[   38.730222] marvell-nfc pxa3xx-nand: 
[   38.730222] NDCR:  0x9d079fff
[   38.730222] NDCB0: 0x000d3000
[   38.730222] NDCB1: 0x4e800000
[   38.730222] NDCB2: 0x00000001
[   38.730222] NDCB3: 0x00000000
[   38.749149] nand: nand_do_read_oob: from = 0x0a760000, len = 64
[   38.755183] marvell-nfc pxa3xx-nand: 
[   38.755183] NDCR:  0x9d079fff
[   38.755183] NDCB0: 0x000d3000
[   38.755183] NDCB1: 0x4ec00000
[   38.755183] NDCB2: 0x00000001
[   38.755183] NDCB3: 0x00000000
[   38.774115] nand: nand_do_read_oob: from = 0x0a780000, len = 64
[   38.780322] marvell-nfc pxa3xx-nand: 
[   38.780322] NDCR:  0x9d079fff
[   38.780322] NDCB0: 0x000d3000
[   38.780322] NDCB1: 0x4f000000
[   38.780322] NDCB2: 0x00000001
[   38.780322] NDCB3: 0x00000000
[   38.799251] nand: nand_do_read_oob: from = 0x0a7a0000, len = 64
[   38.805280] marvell-nfc pxa3xx-nand: 
[   38.805280] NDCR:  0x9d079fff
[   38.805280] NDCB0: 0x000d3000
[   38.805280] NDCB1: 0x4f400000
[   38.805280] NDCB2: 0x00000001
[   38.805280] NDCB3: 0x00000000
[   38.824215] nand: nand_do_read_oob: from = 0x0a7c0000, len = 64
[   38.830420] marvell-nfc pxa3xx-nand: 
[   38.830420] NDCR:  0x9d079fff
[   38.830420] NDCB0: 0x000d3000
[   38.830420] NDCB1: 0x4f800000
[   38.830420] NDCB2: 0x00000001
[   38.830420] NDCB3: 0x00000000
[   38.849349] nand: nand_do_read_oob: from = 0x0a7e0000, len = 64
[   38.855378] marvell-nfc pxa3xx-nand: 
[   38.855378] NDCR:  0x9d079fff
[   38.855378] NDCB0: 0x000d3000
[   38.855378] NDCB1: 0x4fc00000
[   38.855378] NDCB2: 0x00000001
[   38.855378] NDCB3: 0x00000000
[   38.874311] nand: nand_do_read_oob: from = 0x0a800000, len = 64
[   38.880517] marvell-nfc pxa3xx-nand: 
[   38.880517] NDCR:  0x9d079fff
[   38.880517] NDCB0: 0x000d3000
[   38.880517] NDCB1: 0x50000000
[   38.880517] NDCB2: 0x00000001
[   38.880517] NDCB3: 0x00000000
[   38.899447] nand: nand_do_read_oob: from = 0x0a820000, len = 64
[   38.905478] marvell-nfc pxa3xx-nand: 
[   38.905478] NDCR:  0x9d079fff
[   38.905478] NDCB0: 0x000d3000
[   38.905478] NDCB1: 0x50400000
[   38.905478] NDCB2: 0x00000001
[   38.905478] NDCB3: 0x00000000
[   38.924410] nand: nand_do_read_oob: from = 0x0a840000, len = 64
[   38.930616] marvell-nfc pxa3xx-nand: 
[   38.930616] NDCR:  0x9d079fff
[   38.930616] NDCB0: 0x000d3000
[   38.930616] NDCB1: 0x50800000
[   38.930616] NDCB2: 0x00000001
[   38.930616] NDCB3: 0x00000000
[   38.949543] nand: nand_do_read_oob: from = 0x0a860000, len = 64
[   38.955576] marvell-nfc pxa3xx-nand: 
[   38.955576] NDCR:  0x9d079fff
[   38.955576] NDCB0: 0x000d3000
[   38.955576] NDCB1: 0x50c00000
[   38.955576] NDCB2: 0x00000001
[   38.955576] NDCB3: 0x00000000
[   38.974508] nand: nand_do_read_oob: from = 0x0a880000, len = 64
[   38.980714] marvell-nfc pxa3xx-nand: 
[   38.980714] NDCR:  0x9d079fff
[   38.980714] NDCB0: 0x000d3000
[   38.980714] NDCB1: 0x51000000
[   38.980714] NDCB2: 0x00000001
[   38.980714] NDCB3: 0x00000000
[   38.999659] nand: nand_do_read_oob: from = 0x0a8a0000, len = 64
[   39.005692] marvell-nfc pxa3xx-nand: 
[   39.005692] NDCR:  0x9d079fff
[   39.005692] NDCB0: 0x000d3000
[   39.005692] NDCB1: 0x51400000
[   39.005692] NDCB2: 0x00000001
[   39.005692] NDCB3: 0x00000000
[   39.024633] nand: nand_do_read_oob: from = 0x0a8c0000, len = 64
[   39.030840] marvell-nfc pxa3xx-nand: 
[   39.030840] NDCR:  0x9d079fff
[   39.030840] NDCB0: 0x000d3000
[   39.030840] NDCB1: 0x51800000
[   39.030840] NDCB2: 0x00000001
[   39.030840] NDCB3: 0x00000000
[   39.049768] nand: nand_do_read_oob: from = 0x0a8e0000, len = 64
[   39.055799] marvell-nfc pxa3xx-nand: 
[   39.055799] NDCR:  0x9d079fff
[   39.055799] NDCB0: 0x000d3000
[   39.055799] NDCB1: 0x51c00000
[   39.055799] NDCB2: 0x00000001
[   39.055799] NDCB3: 0x00000000
[   39.074734] nand: nand_do_read_oob: from = 0x0a900000, len = 64
[   39.080938] marvell-nfc pxa3xx-nand: 
[   39.080938] NDCR:  0x9d079fff
[   39.080938] NDCB0: 0x000d3000
[   39.080938] NDCB1: 0x52000000
[   39.080938] NDCB2: 0x00000001
[   39.080938] NDCB3: 0x00000000
[   39.099865] nand: nand_do_read_oob: from = 0x0a920000, len = 64
[   39.105898] marvell-nfc pxa3xx-nand: 
[   39.105898] NDCR:  0x9d079fff
[   39.105898] NDCB0: 0x000d3000
[   39.105898] NDCB1: 0x52400000
[   39.105898] NDCB2: 0x00000001
[   39.105898] NDCB3: 0x00000000
[   39.124831] nand: nand_do_read_oob: from = 0x0a940000, len = 64
[   39.131037] marvell-nfc pxa3xx-nand: 
[   39.131037] NDCR:  0x9d079fff
[   39.131037] NDCB0: 0x000d3000
[   39.131037] NDCB1: 0x52800000
[   39.131037] NDCB2: 0x00000001
[   39.131037] NDCB3: 0x00000000
[   39.149964] nand: nand_do_read_oob: from = 0x0a960000, len = 64
[   39.155996] marvell-nfc pxa3xx-nand: 
[   39.155996] NDCR:  0x9d079fff
[   39.155996] NDCB0: 0x000d3000
[   39.155996] NDCB1: 0x52c00000
[   39.155996] NDCB2: 0x00000001
[   39.155996] NDCB3: 0x00000000
[   39.174928] nand: nand_do_read_oob: from = 0x0a980000, len = 64
[   39.181134] marvell-nfc pxa3xx-nand: 
[   39.181134] NDCR:  0x9d079fff
[   39.181134] NDCB0: 0x000d3000
[   39.181134] NDCB1: 0x53000000
[   39.181134] NDCB2: 0x00000001
[   39.181134] NDCB3: 0x00000000
[   39.200063] nand: nand_do_read_oob: from = 0x0a9a0000, len = 64
[   39.206094] marvell-nfc pxa3xx-nand: 
[   39.206094] NDCR:  0x9d079fff
[   39.206094] NDCB0: 0x000d3000
[   39.206094] NDCB1: 0x53400000
[   39.206094] NDCB2: 0x00000001
[   39.206094] NDCB3: 0x00000000
[   39.225030] nand: nand_do_read_oob: from = 0x0a9c0000, len = 64
[   39.231233] marvell-nfc pxa3xx-nand: 
[   39.231233] NDCR:  0x9d079fff
[   39.231233] NDCB0: 0x000d3000
[   39.231233] NDCB1: 0x53800000
[   39.231233] NDCB2: 0x00000001
[   39.231233] NDCB3: 0x00000000
[   39.250160] nand: nand_do_read_oob: from = 0x0a9e0000, len = 64
[   39.256192] marvell-nfc pxa3xx-nand: 
[   39.256192] NDCR:  0x9d079fff
[   39.256192] NDCB0: 0x000d3000
[   39.256192] NDCB1: 0x53c00000
[   39.256192] NDCB2: 0x00000001
[   39.256192] NDCB3: 0x00000000
[   39.275126] nand: nand_do_read_oob: from = 0x0aa00000, len = 64
[   39.281332] marvell-nfc pxa3xx-nand: 
[   39.281332] NDCR:  0x9d079fff
[   39.281332] NDCB0: 0x000d3000
[   39.281332] NDCB1: 0x54000000
[   39.281332] NDCB2: 0x00000001
[   39.281332] NDCB3: 0x00000000
[   39.300261] nand: nand_do_read_oob: from = 0x0aa20000, len = 64
[   39.306291] marvell-nfc pxa3xx-nand: 
[   39.306291] NDCR:  0x9d079fff
[   39.306291] NDCB0: 0x000d3000
[   39.306291] NDCB1: 0x54400000
[   39.306291] NDCB2: 0x00000001
[   39.306291] NDCB3: 0x00000000
[   39.325224] nand: nand_do_read_oob: from = 0x0aa40000, len = 64
[   39.331429] marvell-nfc pxa3xx-nand: 
[   39.331429] NDCR:  0x9d079fff
[   39.331429] NDCB0: 0x000d3000
[   39.331429] NDCB1: 0x54800000
[   39.331429] NDCB2: 0x00000001
[   39.331429] NDCB3: 0x00000000
[   39.350358] nand: nand_do_read_oob: from = 0x0aa60000, len = 64
[   39.356391] marvell-nfc pxa3xx-nand: 
[   39.356391] NDCR:  0x9d079fff
[   39.356391] NDCB0: 0x000d3000
[   39.356391] NDCB1: 0x54c00000
[   39.356391] NDCB2: 0x00000001
[   39.356391] NDCB3: 0x00000000
[   39.375321] nand: nand_do_read_oob: from = 0x0aa80000, len = 64
[   39.381520] marvell-nfc pxa3xx-nand: 
[   39.381520] NDCR:  0x9d079fff
[   39.381520] NDCB0: 0x000d3000
[   39.381520] NDCB1: 0x55000000
[   39.381520] NDCB2: 0x00000001
[   39.381520] NDCB3: 0x00000000
[   39.400448] nand: nand_do_read_oob: from = 0x0aaa0000, len = 64
[   39.406480] marvell-nfc pxa3xx-nand: 
[   39.406480] NDCR:  0x9d079fff
[   39.406480] NDCB0: 0x000d3000
[   39.406480] NDCB1: 0x55400000
[   39.406480] NDCB2: 0x00000001
[   39.406480] NDCB3: 0x00000000
[   39.425416] nand: nand_do_read_oob: from = 0x0aac0000, len = 64
[   39.431618] marvell-nfc pxa3xx-nand: 
[   39.431618] NDCR:  0x9d079fff
[   39.431618] NDCB0: 0x000d3000
[   39.431618] NDCB1: 0x55800000
[   39.431618] NDCB2: 0x00000001
[   39.431618] NDCB3: 0x00000000
[   39.450547] nand: nand_do_read_oob: from = 0x0aae0000, len = 64
[   39.456578] marvell-nfc pxa3xx-nand: 
[   39.456578] NDCR:  0x9d079fff
[   39.456578] NDCB0: 0x000d3000
[   39.456578] NDCB1: 0x55c00000
[   39.456578] NDCB2: 0x00000001
[   39.456578] NDCB3: 0x00000000
[   39.475509] nand: nand_do_read_oob: from = 0x0ab00000, len = 64
[   39.481708] marvell-nfc pxa3xx-nand: 
[   39.481708] NDCR:  0x9d079fff
[   39.481708] NDCB0: 0x000d3000
[   39.481708] NDCB1: 0x56000000
[   39.481708] NDCB2: 0x00000001
[   39.481708] NDCB3: 0x00000000
[   39.500634] nand: nand_do_read_oob: from = 0x0ab20000, len = 64
[   39.506668] marvell-nfc pxa3xx-nand: 
[   39.506668] NDCR:  0x9d079fff
[   39.506668] NDCB0: 0x000d3000
[   39.506668] NDCB1: 0x56400000
[   39.506668] NDCB2: 0x00000001
[   39.506668] NDCB3: 0x00000000
[   39.525600] nand: nand_do_read_oob: from = 0x0ab40000, len = 64
[   39.531806] marvell-nfc pxa3xx-nand: 
[   39.531806] NDCR:  0x9d079fff
[   39.531806] NDCB0: 0x000d3000
[   39.531806] NDCB1: 0x56800000
[   39.531806] NDCB2: 0x00000001
[   39.531806] NDCB3: 0x00000000
[   39.550734] nand: nand_do_read_oob: from = 0x0ab60000, len = 64
[   39.556766] marvell-nfc pxa3xx-nand: 
[   39.556766] NDCR:  0x9d079fff
[   39.556766] NDCB0: 0x000d3000
[   39.556766] NDCB1: 0x56c00000
[   39.556766] NDCB2: 0x00000001
[   39.556766] NDCB3: 0x00000000
[   39.575697] nand: nand_do_read_oob: from = 0x0ab80000, len = 64
[   39.581895] marvell-nfc pxa3xx-nand: 
[   39.581895] NDCR:  0x9d079fff
[   39.581895] NDCB0: 0x000d3000
[   39.581895] NDCB1: 0x57000000
[   39.581895] NDCB2: 0x00000001
[   39.581895] NDCB3: 0x00000000
[   39.600822] nand: nand_do_read_oob: from = 0x0aba0000, len = 64
[   39.606855] marvell-nfc pxa3xx-nand: 
[   39.606855] NDCR:  0x9d079fff
[   39.606855] NDCB0: 0x000d3000
[   39.606855] NDCB1: 0x57400000
[   39.606855] NDCB2: 0x00000001
[   39.606855] NDCB3: 0x00000000
[   39.625789] nand: nand_do_read_oob: from = 0x0abc0000, len = 64
[   39.631992] marvell-nfc pxa3xx-nand: 
[   39.631992] NDCR:  0x9d079fff
[   39.631992] NDCB0: 0x000d3000
[   39.631992] NDCB1: 0x57800000
[   39.631992] NDCB2: 0x00000001
[   39.631992] NDCB3: 0x00000000
[   39.650939] nand: nand_do_read_oob: from = 0x0abe0000, len = 64
[   39.656971] marvell-nfc pxa3xx-nand: 
[   39.656971] NDCR:  0x9d079fff
[   39.656971] NDCB0: 0x000d3000
[   39.656971] NDCB1: 0x57c00000
[   39.656971] NDCB2: 0x00000001
[   39.656971] NDCB3: 0x00000000
[   39.675903] nand: nand_do_read_oob: from = 0x0ac00000, len = 64
[   39.682101] marvell-nfc pxa3xx-nand: 
[   39.682101] NDCR:  0x9d079fff
[   39.682101] NDCB0: 0x000d3000
[   39.682101] NDCB1: 0x58000000
[   39.682101] NDCB2: 0x00000001
[   39.682101] NDCB3: 0x00000000
[   39.701028] nand: nand_do_read_oob: from = 0x0ac20000, len = 64
[   39.707061] marvell-nfc pxa3xx-nand: 
[   39.707061] NDCR:  0x9d079fff
[   39.707061] NDCB0: 0x000d3000
[   39.707061] NDCB1: 0x58400000
[   39.707061] NDCB2: 0x00000001
[   39.707061] NDCB3: 0x00000000
[   39.725994] nand: nand_do_read_oob: from = 0x0ac40000, len = 64
[   39.732201] marvell-nfc pxa3xx-nand: 
[   39.732201] NDCR:  0x9d079fff
[   39.732201] NDCB0: 0x000d3000
[   39.732201] NDCB1: 0x58800000
[   39.732201] NDCB2: 0x00000001
[   39.732201] NDCB3: 0x00000000
[   39.751128] nand: nand_do_read_oob: from = 0x0ac60000, len = 64
[   39.757161] marvell-nfc pxa3xx-nand: 
[   39.757161] NDCR:  0x9d079fff
[   39.757161] NDCB0: 0x000d3000
[   39.757161] NDCB1: 0x58c00000
[   39.757161] NDCB2: 0x00000001
[   39.757161] NDCB3: 0x00000000
[   39.776092] nand: nand_do_read_oob: from = 0x0ac80000, len = 64
[   39.782289] marvell-nfc pxa3xx-nand: 
[   39.782289] NDCR:  0x9d079fff
[   39.782289] NDCB0: 0x000d3000
[   39.782289] NDCB1: 0x59000000
[   39.782289] NDCB2: 0x00000001
[   39.782289] NDCB3: 0x00000000
[   39.801217] nand: nand_do_read_oob: from = 0x0aca0000, len = 64
[   39.807248] marvell-nfc pxa3xx-nand: 
[   39.807248] NDCR:  0x9d079fff
[   39.807248] NDCB0: 0x000d3000
[   39.807248] NDCB1: 0x59400000
[   39.807248] NDCB2: 0x00000001
[   39.807248] NDCB3: 0x00000000
[   39.826180] nand: nand_do_read_oob: from = 0x0acc0000, len = 64
[   39.832380] marvell-nfc pxa3xx-nand: 
[   39.832380] NDCR:  0x9d079fff
[   39.832380] NDCB0: 0x000d3000
[   39.832380] NDCB1: 0x59800000
[   39.832380] NDCB2: 0x00000001
[   39.832380] NDCB3: 0x00000000
[   39.851310] nand: nand_do_read_oob: from = 0x0ace0000, len = 64
[   39.857339] marvell-nfc pxa3xx-nand: 
[   39.857339] NDCR:  0x9d079fff
[   39.857339] NDCB0: 0x000d3000
[   39.857339] NDCB1: 0x59c00000
[   39.857339] NDCB2: 0x00000001
[   39.857339] NDCB3: 0x00000000
[   39.876270] nand: nand_do_read_oob: from = 0x0ad00000, len = 64
[   39.882468] marvell-nfc pxa3xx-nand: 
[   39.882468] NDCR:  0x9d079fff
[   39.882468] NDCB0: 0x000d3000
[   39.882468] NDCB1: 0x5a000000
[   39.882468] NDCB2: 0x00000001
[   39.882468] NDCB3: 0x00000000
[   39.901398] nand: nand_do_read_oob: from = 0x0ad20000, len = 64
[   39.907430] marvell-nfc pxa3xx-nand: 
[   39.907430] NDCR:  0x9d079fff
[   39.907430] NDCB0: 0x000d3000
[   39.907430] NDCB1: 0x5a400000
[   39.907430] NDCB2: 0x00000001
[   39.907430] NDCB3: 0x00000000
[   39.926360] nand: nand_do_read_oob: from = 0x0ad40000, len = 64
[   39.932559] marvell-nfc pxa3xx-nand: 
[   39.932559] NDCR:  0x9d079fff
[   39.932559] NDCB0: 0x000d3000
[   39.932559] NDCB1: 0x5a800000
[   39.932559] NDCB2: 0x00000001
[   39.932559] NDCB3: 0x00000000
[   39.951489] nand: nand_do_read_oob: from = 0x0ad60000, len = 64
[   39.957520] marvell-nfc pxa3xx-nand: 
[   39.957520] NDCR:  0x9d079fff
[   39.957520] NDCB0: 0x000d3000
[   39.957520] NDCB1: 0x5ac00000
[   39.957520] NDCB2: 0x00000001
[   39.957520] NDCB3: 0x00000000
[   39.976451] nand: nand_do_read_oob: from = 0x0ad80000, len = 64
[   39.982649] marvell-nfc pxa3xx-nand: 
[   39.982649] NDCR:  0x9d079fff
[   39.982649] NDCB0: 0x000d3000
[   39.982649] NDCB1: 0x5b000000
[   39.982649] NDCB2: 0x00000001
[   39.982649] NDCB3: 0x00000000
[   40.001578] nand: nand_do_read_oob: from = 0x0ada0000, len = 64
[   40.007608] marvell-nfc pxa3xx-nand: 
[   40.007608] NDCR:  0x9d079fff
[   40.007608] NDCB0: 0x000d3000
[   40.007608] NDCB1: 0x5b400000
[   40.007608] NDCB2: 0x00000001
[   40.007608] NDCB3: 0x00000000
[   40.026551] nand: nand_do_read_oob: from = 0x0adc0000, len = 64
[   40.032756] marvell-nfc pxa3xx-nand: 
[   40.032756] NDCR:  0x9d079fff
[   40.032756] NDCB0: 0x000d3000
[   40.032756] NDCB1: 0x5b800000
[   40.032756] NDCB2: 0x00000001
[   40.032756] NDCB3: 0x00000000
[   40.051686] nand: nand_do_read_oob: from = 0x0ade0000, len = 64
[   40.057715] marvell-nfc pxa3xx-nand: 
[   40.057715] NDCR:  0x9d079fff
[   40.057715] NDCB0: 0x000d3000
[   40.057715] NDCB1: 0x5bc00000
[   40.057715] NDCB2: 0x00000001
[   40.057715] NDCB3: 0x00000000
[   40.076649] nand: nand_do_read_oob: from = 0x0ae00000, len = 64
[   40.082853] marvell-nfc pxa3xx-nand: 
[   40.082853] NDCR:  0x9d079fff
[   40.082853] NDCB0: 0x000d3000
[   40.082853] NDCB1: 0x5c000000
[   40.082853] NDCB2: 0x00000001
[   40.082853] NDCB3: 0x00000000
[   40.102129] nand: nand_do_read_oob: from = 0x0ae20000, len = 64
[   40.108173] marvell-nfc pxa3xx-nand: 
[   40.108173] NDCR:  0x9d079fff
[   40.108173] NDCB0: 0x000d3000
[   40.108173] NDCB1: 0x5c400000
[   40.108173] NDCB2: 0x00000001
[   40.108173] NDCB3: 0x00000000
[   40.127132] nand: nand_do_read_oob: from = 0x0ae40000, len = 64
[   40.133331] marvell-nfc pxa3xx-nand: 
[   40.133331] NDCR:  0x9d079fff
[   40.133331] NDCB0: 0x000d3000
[   40.133331] NDCB1: 0x5c800000
[   40.133331] NDCB2: 0x00000001
[   40.133331] NDCB3: 0x00000000
[   40.152260] nand: nand_do_read_oob: from = 0x0ae60000, len = 64
[   40.158294] marvell-nfc pxa3xx-nand: 
[   40.158294] NDCR:  0x9d079fff
[   40.158294] NDCB0: 0x000d3000
[   40.158294] NDCB1: 0x5cc00000
[   40.158294] NDCB2: 0x00000001
[   40.158294] NDCB3: 0x00000000
[   40.177228] nand: nand_do_read_oob: from = 0x0ae80000, len = 64
[   40.183432] marvell-nfc pxa3xx-nand: 
[   40.183432] NDCR:  0x9d079fff
[   40.183432] NDCB0: 0x000d3000
[   40.183432] NDCB1: 0x5d000000
[   40.183432] NDCB2: 0x00000001
[   40.183432] NDCB3: 0x00000000
[   40.202360] nand: nand_do_read_oob: from = 0x0aea0000, len = 64
[   40.208391] marvell-nfc pxa3xx-nand: 
[   40.208391] NDCR:  0x9d079fff
[   40.208391] NDCB0: 0x000d3000
[   40.208391] NDCB1: 0x5d400000
[   40.208391] NDCB2: 0x00000001
[   40.208391] NDCB3: 0x00000000
[   40.227328] nand: nand_do_read_oob: from = 0x0aec0000, len = 64
[   40.233529] marvell-nfc pxa3xx-nand: 
[   40.233529] NDCR:  0x9d079fff
[   40.233529] NDCB0: 0x000d3000
[   40.233529] NDCB1: 0x5d800000
[   40.233529] NDCB2: 0x00000001
[   40.233529] NDCB3: 0x00000000
[   40.252458] nand: nand_do_read_oob: from = 0x0aee0000, len = 64
[   40.258490] marvell-nfc pxa3xx-nand: 
[   40.258490] NDCR:  0x9d079fff
[   40.258490] NDCB0: 0x000d3000
[   40.258490] NDCB1: 0x5dc00000
[   40.258490] NDCB2: 0x00000001
[   40.258490] NDCB3: 0x00000000
[   40.277423] nand: nand_do_read_oob: from = 0x0af00000, len = 64
[   40.283653] marvell-nfc pxa3xx-nand: 
[   40.283653] NDCR:  0x9d079fff
[   40.283653] NDCB0: 0x000d3000
[   40.283653] NDCB1: 0x5e000000
[   40.283653] NDCB2: 0x00000001
[   40.283653] NDCB3: 0x00000000
[   40.302581] nand: nand_do_read_oob: from = 0x0af20000, len = 64
[   40.308612] marvell-nfc pxa3xx-nand: 
[   40.308612] NDCR:  0x9d079fff
[   40.308612] NDCB0: 0x000d3000
[   40.308612] NDCB1: 0x5e400000
[   40.308612] NDCB2: 0x00000001
[   40.308612] NDCB3: 0x00000000
[   40.327655] nand: nand_do_read_oob: from = 0x0af40000, len = 64
[   40.333856] marvell-nfc pxa3xx-nand: 
[   40.333856] NDCR:  0x9d079fff
[   40.333856] NDCB0: 0x000d3000
[   40.333856] NDCB1: 0x5e800000
[   40.333856] NDCB2: 0x00000001
[   40.333856] NDCB3: 0x00000000
[   40.352781] nand: nand_do_read_oob: from = 0x0af60000, len = 64
[   40.358986] marvell-nfc pxa3xx-nand: 
[   40.358986] NDCR:  0x9d079fff
[   40.358986] NDCB0: 0x000d3000
[   40.358986] NDCB1: 0x5ec00000
[   40.358986] NDCB2: 0x00000001
[   40.358986] NDCB3: 0x00000000
[   40.377905] nand: nand_do_read_oob: from = 0x0af80000, len = 64
[   40.384108] marvell-nfc pxa3xx-nand: 
[   40.384108] NDCR:  0x9d079fff
[   40.384108] NDCB0: 0x000d3000
[   40.384108] NDCB1: 0x5f000000
[   40.384108] NDCB2: 0x00000001
[   40.384108] NDCB3: 0x00000000
[   40.403036] nand: nand_do_read_oob: from = 0x0afa0000, len = 64
[   40.409239] marvell-nfc pxa3xx-nand: 
[   40.409239] NDCR:  0x9d079fff
[   40.409239] NDCB0: 0x000d3000
[   40.409239] NDCB1: 0x5f400000
[   40.409239] NDCB2: 0x00000001
[   40.409239] NDCB3: 0x00000000
[   40.428158] nand: nand_do_read_oob: from = 0x0afc0000, len = 64
[   40.434362] marvell-nfc pxa3xx-nand: 
[   40.434362] NDCR:  0x9d079fff
[   40.434362] NDCB0: 0x000d3000
[   40.434362] NDCB1: 0x5f800000
[   40.434362] NDCB2: 0x00000001
[   40.434362] NDCB3: 0x00000000
[   40.453288] nand: nand_do_read_oob: from = 0x0afe0000, len = 64
[   40.459495] marvell-nfc pxa3xx-nand: 
[   40.459495] NDCR:  0x9d079fff
[   40.459495] NDCB0: 0x000d3000
[   40.459495] NDCB1: 0x5fc00000
[   40.459495] NDCB2: 0x00000001
[   40.459495] NDCB3: 0x00000000
[   40.478411] nand: nand_do_read_oob: from = 0x0b000000, len = 64
[   40.484616] marvell-nfc pxa3xx-nand: 
[   40.484616] NDCR:  0x9d079fff
[   40.484616] NDCB0: 0x000d3000
[   40.484616] NDCB1: 0x60000000
[   40.484616] NDCB2: 0x00000001
[   40.484616] NDCB3: 0x00000000
[   40.503546] nand: nand_do_read_oob: from = 0x0b020000, len = 64
[   40.509745] marvell-nfc pxa3xx-nand: 
[   40.509745] NDCR:  0x9d079fff
[   40.509745] NDCB0: 0x000d3000
[   40.509745] NDCB1: 0x60400000
[   40.509745] NDCB2: 0x00000001
[   40.509745] NDCB3: 0x00000000
[   40.528764] nand: nand_do_read_oob: from = 0x0b040000, len = 64
[   40.534800] marvell-nfc pxa3xx-nand: 
[   40.534800] NDCR:  0x9d079fff
[   40.534800] NDCB0: 0x000d3000
[   40.534800] NDCB1: 0x60800000
[   40.534800] NDCB2: 0x00000001
[   40.534800] NDCB3: 0x00000000
[   40.553712] nand: nand_do_read_oob: from = 0x0b060000, len = 64
[   40.559912] marvell-nfc pxa3xx-nand: 
[   40.559912] NDCR:  0x9d079fff
[   40.559912] NDCB0: 0x000d3000
[   40.559912] NDCB1: 0x60c00000
[   40.559912] NDCB2: 0x00000001
[   40.559912] NDCB3: 0x00000000
[   40.578902] nand: nand_do_read_oob: from = 0x0b080000, len = 64
[   40.584939] marvell-nfc pxa3xx-nand: 
[   40.584939] NDCR:  0x9d079fff
[   40.584939] NDCB0: 0x000d3000
[   40.584939] NDCB1: 0x61000000
[   40.584939] NDCB2: 0x00000001
[   40.584939] NDCB3: 0x00000000
[   40.603877] nand: nand_do_read_oob: from = 0x0b0a0000, len = 64
[   40.610082] marvell-nfc pxa3xx-nand: 
[   40.610082] NDCR:  0x9d079fff
[   40.610082] NDCB0: 0x000d3000
[   40.610082] NDCB1: 0x61400000
[   40.610082] NDCB2: 0x00000001
[   40.610082] NDCB3: 0x00000000
[   40.629049] nand: nand_do_read_oob: from = 0x0b0c0000, len = 64
[   40.635076] marvell-nfc pxa3xx-nand: 
[   40.635076] NDCR:  0x9d079fff
[   40.635076] NDCB0: 0x000d3000
[   40.635076] NDCB1: 0x61800000
[   40.635076] NDCB2: 0x00000001
[   40.635076] NDCB3: 0x00000000
[   40.654007] nand: nand_do_read_oob: from = 0x0b0e0000, len = 64
[   40.660206] marvell-nfc pxa3xx-nand: 
[   40.660206] NDCR:  0x9d079fff
[   40.660206] NDCB0: 0x000d3000
[   40.660206] NDCB1: 0x61c00000
[   40.660206] NDCB2: 0x00000001
[   40.660206] NDCB3: 0x00000000
[   40.679134] nand: nand_do_read_oob: from = 0x0b100000, len = 64
[   40.685166] marvell-nfc pxa3xx-nand: 
[   40.685166] NDCR:  0x9d079fff
[   40.685166] NDCB0: 0x000d3000
[   40.685166] NDCB1: 0x62000000
[   40.685166] NDCB2: 0x00000001
[   40.685166] NDCB3: 0x00000000
[   40.704098] nand: nand_do_read_oob: from = 0x0b120000, len = 64
[   40.710295] marvell-nfc pxa3xx-nand: 
[   40.710295] NDCR:  0x9d079fff
[   40.710295] NDCB0: 0x000d3000
[   40.710295] NDCB1: 0x62400000
[   40.710295] NDCB2: 0x00000001
[   40.710295] NDCB3: 0x00000000
[   40.729225] nand: nand_do_read_oob: from = 0x0b140000, len = 64
[   40.735255] marvell-nfc pxa3xx-nand: 
[   40.735255] NDCR:  0x9d079fff
[   40.735255] NDCB0: 0x000d3000
[   40.735255] NDCB1: 0x62800000
[   40.735255] NDCB2: 0x00000001
[   40.735255] NDCB3: 0x00000000
[   40.754188] nand: nand_do_read_oob: from = 0x0b160000, len = 64
[   40.760393] marvell-nfc pxa3xx-nand: 
[   40.760393] NDCR:  0x9d079fff
[   40.760393] NDCB0: 0x000d3000
[   40.760393] NDCB1: 0x62c00000
[   40.760393] NDCB2: 0x00000001
[   40.760393] NDCB3: 0x00000000
[   40.779321] nand: nand_do_read_oob: from = 0x0b180000, len = 64
[   40.785355] marvell-nfc pxa3xx-nand: 
[   40.785355] NDCR:  0x9d079fff
[   40.785355] NDCB0: 0x000d3000
[   40.785355] NDCB1: 0x63000000
[   40.785355] NDCB2: 0x00000001
[   40.785355] NDCB3: 0x00000000
[   40.804288] nand: nand_do_read_oob: from = 0x0b1a0000, len = 64
[   40.810494] marvell-nfc pxa3xx-nand: 
[   40.810494] NDCR:  0x9d079fff
[   40.810494] NDCB0: 0x000d3000
[   40.810494] NDCB1: 0x63400000
[   40.810494] NDCB2: 0x00000001
[   40.810494] NDCB3: 0x00000000
[   40.829421] nand: nand_do_read_oob: from = 0x0b1c0000, len = 64
[   40.835452] marvell-nfc pxa3xx-nand: 
[   40.835452] NDCR:  0x9d079fff
[   40.835452] NDCB0: 0x000d3000
[   40.835452] NDCB1: 0x63800000
[   40.835452] NDCB2: 0x00000001
[   40.835452] NDCB3: 0x00000000
[   40.854384] nand: nand_do_read_oob: from = 0x0b1e0000, len = 64
[   40.860609] marvell-nfc pxa3xx-nand: 
[   40.860609] NDCR:  0x9d079fff
[   40.860609] NDCB0: 0x000d3000
[   40.860609] NDCB1: 0x63c00000
[   40.860609] NDCB2: 0x00000001
[   40.860609] NDCB3: 0x00000000
[   40.879540] nand: nand_do_read_oob: from = 0x0b200000, len = 64
[   40.885567] marvell-nfc pxa3xx-nand: 
[   40.885567] NDCR:  0x9d079fff
[   40.885567] NDCB0: 0x000d3000
[   40.885567] NDCB1: 0x64000000
[   40.885567] NDCB2: 0x00000001
[   40.885567] NDCB3: 0x00000000
[   40.904499] nand: nand_do_read_oob: from = 0x0b220000, len = 64
[   40.910695] marvell-nfc pxa3xx-nand: 
[   40.910695] NDCR:  0x9d079fff
[   40.910695] NDCB0: 0x000d3000
[   40.910695] NDCB1: 0x64400000
[   40.910695] NDCB2: 0x00000001
[   40.910695] NDCB3: 0x00000000
[   40.929627] nand: nand_do_read_oob: from = 0x0b240000, len = 64
[   40.935657] marvell-nfc pxa3xx-nand: 
[   40.935657] NDCR:  0x9d079fff
[   40.935657] NDCB0: 0x000d3000
[   40.935657] NDCB1: 0x64800000
[   40.935657] NDCB2: 0x00000001
[   40.935657] NDCB3: 0x00000000
[   40.954592] nand: nand_do_read_oob: from = 0x0b260000, len = 64
[   40.960798] marvell-nfc pxa3xx-nand: 
[   40.960798] NDCR:  0x9d079fff
[   40.960798] NDCB0: 0x000d3000
[   40.960798] NDCB1: 0x64c00000
[   40.960798] NDCB2: 0x00000001
[   40.960798] NDCB3: 0x00000000
[   40.979726] nand: nand_do_read_oob: from = 0x0b280000, len = 64
[   40.985756] marvell-nfc pxa3xx-nand: 
[   40.985756] NDCR:  0x9d079fff
[   40.985756] NDCB0: 0x000d3000
[   40.985756] NDCB1: 0x65000000
[   40.985756] NDCB2: 0x00000001
[   40.985756] NDCB3: 0x00000000
[   41.004694] nand: nand_do_read_oob: from = 0x0b2a0000, len = 64
[   41.010903] marvell-nfc pxa3xx-nand: 
[   41.010903] NDCR:  0x9d079fff
[   41.010903] NDCB0: 0x000d3000
[   41.010903] NDCB1: 0x65400000
[   41.010903] NDCB2: 0x00000001
[   41.010903] NDCB3: 0x00000000
[   41.029835] nand: nand_do_read_oob: from = 0x0b2c0000, len = 64
[   41.035862] marvell-nfc pxa3xx-nand: 
[   41.035862] NDCR:  0x9d079fff
[   41.035862] NDCB0: 0x000d3000
[   41.035862] NDCB1: 0x65800000
[   41.035862] NDCB2: 0x00000001
[   41.035862] NDCB3: 0x00000000
[   41.054798] nand: nand_do_read_oob: from = 0x0b2e0000, len = 64
[   41.061002] marvell-nfc pxa3xx-nand: 
[   41.061002] NDCR:  0x9d079fff
[   41.061002] NDCB0: 0x000d3000
[   41.061002] NDCB1: 0x65c00000
[   41.061002] NDCB2: 0x00000001
[   41.061002] NDCB3: 0x00000000
[   41.079930] nand: nand_do_read_oob: from = 0x0b300000, len = 64
[   41.085962] marvell-nfc pxa3xx-nand: 
[   41.085962] NDCR:  0x9d079fff
[   41.085962] NDCB0: 0x000d3000
[   41.085962] NDCB1: 0x66000000
[   41.085962] NDCB2: 0x00000001
[   41.085962] NDCB3: 0x00000000
[   41.104899] nand: nand_do_read_oob: from = 0x0b320000, len = 64
[   41.111100] marvell-nfc pxa3xx-nand: 
[   41.111100] NDCR:  0x9d079fff
[   41.111100] NDCB0: 0x000d3000
[   41.111100] NDCB1: 0x66400000
[   41.111100] NDCB2: 0x00000001
[   41.111100] NDCB3: 0x00000000
[   41.130032] nand: nand_do_read_oob: from = 0x0b340000, len = 64
[   41.136060] marvell-nfc pxa3xx-nand: 
[   41.136060] NDCR:  0x9d079fff
[   41.136060] NDCB0: 0x000d3000
[   41.136060] NDCB1: 0x66800000
[   41.136060] NDCB2: 0x00000001
[   41.136060] NDCB3: 0x00000000
[   41.154993] nand: nand_do_read_oob: from = 0x0b360000, len = 64
[   41.161199] marvell-nfc pxa3xx-nand: 
[   41.161199] NDCR:  0x9d079fff
[   41.161199] NDCB0: 0x000d3000
[   41.161199] NDCB1: 0x66c00000
[   41.161199] NDCB2: 0x00000001
[   41.161199] NDCB3: 0x00000000
[   41.180129] nand: nand_do_read_oob: from = 0x0b380000, len = 64
[   41.186158] marvell-nfc pxa3xx-nand: 
[   41.186158] NDCR:  0x9d079fff
[   41.186158] NDCB0: 0x000d3000
[   41.186158] NDCB1: 0x67000000
[   41.186158] NDCB2: 0x00000001
[   41.186158] NDCB3: 0x00000000
[   41.205093] nand: nand_do_read_oob: from = 0x0b3a0000, len = 64
[   41.211299] marvell-nfc pxa3xx-nand: 
[   41.211299] NDCR:  0x9d079fff
[   41.211299] NDCB0: 0x000d3000
[   41.211299] NDCB1: 0x67400000
[   41.211299] NDCB2: 0x00000001
[   41.211299] NDCB3: 0x00000000
[   41.230229] nand: nand_do_read_oob: from = 0x0b3c0000, len = 64
[   41.236258] marvell-nfc pxa3xx-nand: 
[   41.236258] NDCR:  0x9d079fff
[   41.236258] NDCB0: 0x000d3000
[   41.236258] NDCB1: 0x67800000
[   41.236258] NDCB2: 0x00000001
[   41.236258] NDCB3: 0x00000000
[   41.255191] nand: nand_do_read_oob: from = 0x0b3e0000, len = 64
[   41.261395] marvell-nfc pxa3xx-nand: 
[   41.261395] NDCR:  0x9d079fff
[   41.261395] NDCB0: 0x000d3000
[   41.261395] NDCB1: 0x67c00000
[   41.261395] NDCB2: 0x00000001
[   41.261395] NDCB3: 0x00000000
[   41.280327] nand: nand_do_read_oob: from = 0x0b400000, len = 64
[   41.286357] marvell-nfc pxa3xx-nand: 
[   41.286357] NDCR:  0x9d079fff
[   41.286357] NDCB0: 0x000d3000
[   41.286357] NDCB1: 0x68000000
[   41.286357] NDCB2: 0x00000001
[   41.286357] NDCB3: 0x00000000
[   41.305290] nand: nand_do_read_oob: from = 0x0b420000, len = 64
[   41.311494] marvell-nfc pxa3xx-nand: 
[   41.311494] NDCR:  0x9d079fff
[   41.311494] NDCB0: 0x000d3000
[   41.311494] NDCB1: 0x68400000
[   41.311494] NDCB2: 0x00000001
[   41.311494] NDCB3: 0x00000000
[   41.330425] nand: nand_do_read_oob: from = 0x0b440000, len = 64
[   41.336454] marvell-nfc pxa3xx-nand: 
[   41.336454] NDCR:  0x9d079fff
[   41.336454] NDCB0: 0x000d3000
[   41.336454] NDCB1: 0x68800000
[   41.336454] NDCB2: 0x00000001
[   41.336454] NDCB3: 0x00000000
[   41.355388] nand: nand_do_read_oob: from = 0x0b460000, len = 64
[   41.361591] marvell-nfc pxa3xx-nand: 
[   41.361591] NDCR:  0x9d079fff
[   41.361591] NDCB0: 0x000d3000
[   41.361591] NDCB1: 0x68c00000
[   41.361591] NDCB2: 0x00000001
[   41.361591] NDCB3: 0x00000000
[   41.380522] nand: nand_do_read_oob: from = 0x0b480000, len = 64
[   41.386553] marvell-nfc pxa3xx-nand: 
[   41.386553] NDCR:  0x9d079fff
[   41.386553] NDCB0: 0x000d3000
[   41.386553] NDCB1: 0x69000000
[   41.386553] NDCB2: 0x00000001
[   41.386553] NDCB3: 0x00000000
[   41.405484] nand: nand_do_read_oob: from = 0x0b4a0000, len = 64
[   41.411682] marvell-nfc pxa3xx-nand: 
[   41.411682] NDCR:  0x9d079fff
[   41.411682] NDCB0: 0x000d3000
[   41.411682] NDCB1: 0x69400000
[   41.411682] NDCB2: 0x00000001
[   41.411682] NDCB3: 0x00000000
[   41.430614] nand: nand_do_read_oob: from = 0x0b4c0000, len = 64
[   41.436643] marvell-nfc pxa3xx-nand: 
[   41.436643] NDCR:  0x9d079fff
[   41.436643] NDCB0: 0x000d3000
[   41.436643] NDCB1: 0x69800000
[   41.436643] NDCB2: 0x00000001
[   41.436643] NDCB3: 0x00000000
[   41.455579] nand: nand_do_read_oob: from = 0x0b4e0000, len = 64
[   41.461779] marvell-nfc pxa3xx-nand: 
[   41.461779] NDCR:  0x9d079fff
[   41.461779] NDCB0: 0x000d3000
[   41.461779] NDCB1: 0x69c00000
[   41.461779] NDCB2: 0x00000001
[   41.461779] NDCB3: 0x00000000
[   41.480710] nand: nand_do_read_oob: from = 0x0b500000, len = 64
[   41.486740] marvell-nfc pxa3xx-nand: 
[   41.486740] NDCR:  0x9d079fff
[   41.486740] NDCB0: 0x000d3000
[   41.486740] NDCB1: 0x6a000000
[   41.486740] NDCB2: 0x00000001
[   41.486740] NDCB3: 0x00000000
[   41.505693] nand: nand_do_read_oob: from = 0x0b520000, len = 64
[   41.511897] marvell-nfc pxa3xx-nand: 
[   41.511897] NDCR:  0x9d079fff
[   41.511897] NDCB0: 0x000d3000
[   41.511897] NDCB1: 0x6a400000
[   41.511897] NDCB2: 0x00000001
[   41.511897] NDCB3: 0x00000000
[   41.530827] nand: nand_do_read_oob: from = 0x0b540000, len = 64
[   41.536856] marvell-nfc pxa3xx-nand: 
[   41.536856] NDCR:  0x9d079fff
[   41.536856] NDCB0: 0x000d3000
[   41.536856] NDCB1: 0x6a800000
[   41.536856] NDCB2: 0x00000001
[   41.536856] NDCB3: 0x00000000
[   41.555792] nand: nand_do_read_oob: from = 0x0b560000, len = 64
[   41.561995] marvell-nfc pxa3xx-nand: 
[   41.561995] NDCR:  0x9d079fff
[   41.561995] NDCB0: 0x000d3000
[   41.561995] NDCB1: 0x6ac00000
[   41.561995] NDCB2: 0x00000001
[   41.561995] NDCB3: 0x00000000
[   41.580926] nand: nand_do_read_oob: from = 0x0b580000, len = 64
[   41.586956] marvell-nfc pxa3xx-nand: 
[   41.586956] NDCR:  0x9d079fff
[   41.586956] NDCB0: 0x000d3000
[   41.586956] NDCB1: 0x6b000000
[   41.586956] NDCB2: 0x00000001
[   41.586956] NDCB3: 0x00000000
[   41.605888] nand: nand_do_read_oob: from = 0x0b5a0000, len = 64
[   41.612093] marvell-nfc pxa3xx-nand: 
[   41.612093] NDCR:  0x9d079fff
[   41.612093] NDCB0: 0x000d3000
[   41.612093] NDCB1: 0x6b400000
[   41.612093] NDCB2: 0x00000001
[   41.612093] NDCB3: 0x00000000
[   41.631022] nand: nand_do_read_oob: from = 0x0b5c0000, len = 64
[   41.637055] marvell-nfc pxa3xx-nand: 
[   41.637055] NDCR:  0x9d079fff
[   41.637055] NDCB0: 0x000d3000
[   41.637055] NDCB1: 0x6b800000
[   41.637055] NDCB2: 0x00000001
[   41.637055] NDCB3: 0x00000000
[   41.655984] nand: nand_do_read_oob: from = 0x0b5e0000, len = 64
[   41.662182] marvell-nfc pxa3xx-nand: 
[   41.662182] NDCR:  0x9d079fff
[   41.662182] NDCB0: 0x000d3000
[   41.662182] NDCB1: 0x6bc00000
[   41.662182] NDCB2: 0x00000001
[   41.662182] NDCB3: 0x00000000
[   41.681112] nand: nand_do_read_oob: from = 0x0b600000, len = 64
[   41.687144] marvell-nfc pxa3xx-nand: 
[   41.687144] NDCR:  0x9d079fff
[   41.687144] NDCB0: 0x000d3000
[   41.687144] NDCB1: 0x6c000000
[   41.687144] NDCB2: 0x00000001
[   41.687144] NDCB3: 0x00000000
[   41.706076] nand: nand_do_read_oob: from = 0x0b620000, len = 64
[   41.712272] marvell-nfc pxa3xx-nand: 
[   41.712272] NDCR:  0x9d079fff
[   41.712272] NDCB0: 0x000d3000
[   41.712272] NDCB1: 0x6c400000
[   41.712272] NDCB2: 0x00000001
[   41.712272] NDCB3: 0x00000000
[   41.731202] nand: nand_do_read_oob: from = 0x0b640000, len = 64
[   41.737232] marvell-nfc pxa3xx-nand: 
[   41.737232] NDCR:  0x9d079fff
[   41.737232] NDCB0: 0x000d3000
[   41.737232] NDCB1: 0x6c800000
[   41.737232] NDCB2: 0x00000001
[   41.737232] NDCB3: 0x00000000
[   41.756168] nand: nand_do_read_oob: from = 0x0b660000, len = 64
[   41.762374] marvell-nfc pxa3xx-nand: 
[   41.762374] NDCR:  0x9d079fff
[   41.762374] NDCB0: 0x000d3000
[   41.762374] NDCB1: 0x6cc00000
[   41.762374] NDCB2: 0x00000001
[   41.762374] NDCB3: 0x00000000
[   41.781301] nand: nand_do_read_oob: from = 0x0b680000, len = 64
[   41.787332] marvell-nfc pxa3xx-nand: 
[   41.787332] NDCR:  0x9d079fff
[   41.787332] NDCB0: 0x000d3000
[   41.787332] NDCB1: 0x6d000000
[   41.787332] NDCB2: 0x00000001
[   41.787332] NDCB3: 0x00000000
[   41.806269] nand: nand_do_read_oob: from = 0x0b6a0000, len = 64
[   41.812470] marvell-nfc pxa3xx-nand: 
[   41.812470] NDCR:  0x9d079fff
[   41.812470] NDCB0: 0x000d3000
[   41.812470] NDCB1: 0x6d400000
[   41.812470] NDCB2: 0x00000001
[   41.812470] NDCB3: 0x00000000
[   41.831399] nand: nand_do_read_oob: from = 0x0b6c0000, len = 64
[   41.837430] marvell-nfc pxa3xx-nand: 
[   41.837430] NDCR:  0x9d079fff
[   41.837430] NDCB0: 0x000d3000
[   41.837430] NDCB1: 0x6d800000
[   41.837430] NDCB2: 0x00000001
[   41.837430] NDCB3: 0x00000000
[   41.856366] nand: nand_do_read_oob: from = 0x0b6e0000, len = 64
[   41.862570] marvell-nfc pxa3xx-nand: 
[   41.862570] NDCR:  0x9d079fff
[   41.862570] NDCB0: 0x000d3000
[   41.862570] NDCB1: 0x6dc00000
[   41.862570] NDCB2: 0x00000001
[   41.862570] NDCB3: 0x00000000
[   41.881497] nand: nand_do_read_oob: from = 0x0b700000, len = 64
[   41.887529] marvell-nfc pxa3xx-nand: 
[   41.887529] NDCR:  0x9d079fff
[   41.887529] NDCB0: 0x000d3000
[   41.887529] NDCB1: 0x6e000000
[   41.887529] NDCB2: 0x00000001
[   41.887529] NDCB3: 0x00000000
[   41.906462] nand: nand_do_read_oob: from = 0x0b720000, len = 64
[   41.912666] marvell-nfc pxa3xx-nand: 
[   41.912666] NDCR:  0x9d079fff
[   41.912666] NDCB0: 0x000d3000
[   41.912666] NDCB1: 0x6e400000
[   41.912666] NDCB2: 0x00000001
[   41.912666] NDCB3: 0x00000000
[   41.931596] nand: nand_do_read_oob: from = 0x0b740000, len = 64
[   41.937626] marvell-nfc pxa3xx-nand: 
[   41.937626] NDCR:  0x9d079fff
[   41.937626] NDCB0: 0x000d3000
[   41.937626] NDCB1: 0x6e800000
[   41.937626] NDCB2: 0x00000001
[   41.937626] NDCB3: 0x00000000
[   41.956559] nand: nand_do_read_oob: from = 0x0b760000, len = 64
[   41.962757] marvell-nfc pxa3xx-nand: 
[   41.962757] NDCR:  0x9d079fff
[   41.962757] NDCB0: 0x000d3000
[   41.962757] NDCB1: 0x6ec00000
[   41.962757] NDCB2: 0x00000001
[   41.962757] NDCB3: 0x00000000
[   41.981685] nand: nand_do_read_oob: from = 0x0b780000, len = 64
[   41.987717] marvell-nfc pxa3xx-nand: 
[   41.987717] NDCR:  0x9d079fff
[   41.987717] NDCB0: 0x000d3000
[   41.987717] NDCB1: 0x6f000000
[   41.987717] NDCB2: 0x00000001
[   41.987717] NDCB3: 0x00000000
[   42.006651] nand: nand_do_read_oob: from = 0x0b7a0000, len = 64
[   42.012862] marvell-nfc pxa3xx-nand: 
[   42.012862] NDCR:  0x9d079fff
[   42.012862] NDCB0: 0x000d3000
[   42.012862] NDCB1: 0x6f400000
[   42.012862] NDCB2: 0x00000001
[   42.012862] NDCB3: 0x00000000
[   42.031798] nand: nand_do_read_oob: from = 0x0b7c0000, len = 64
[   42.037834] marvell-nfc pxa3xx-nand: 
[   42.037834] NDCR:  0x9d079fff
[   42.037834] NDCB0: 0x000d3000
[   42.037834] NDCB1: 0x6f800000
[   42.037834] NDCB2: 0x00000001
[   42.037834] NDCB3: 0x00000000
[   42.056765] nand: nand_do_read_oob: from = 0x0b7e0000, len = 64
[   42.062971] marvell-nfc pxa3xx-nand: 
[   42.062971] NDCR:  0x9d079fff
[   42.062971] NDCB0: 0x000d3000
[   42.062971] NDCB1: 0x6fc00000
[   42.062971] NDCB2: 0x00000001
[   42.062971] NDCB3: 0x00000000
[   42.081901] nand: nand_do_read_oob: from = 0x0b800000, len = 64
[   42.087932] marvell-nfc pxa3xx-nand: 
[   42.087932] NDCR:  0x9d079fff
[   42.087932] NDCB0: 0x000d3000
[   42.087932] NDCB1: 0x70000000
[   42.087932] NDCB2: 0x00000001
[   42.087932] NDCB3: 0x00000000
[   42.107299] nand: nand_do_read_oob: from = 0x0b820000, len = 64
[   42.113537] marvell-nfc pxa3xx-nand: 
[   42.113537] NDCR:  0x9d079fff
[   42.113537] NDCB0: 0x000d3000
[   42.113537] NDCB1: 0x70400000
[   42.113537] NDCB2: 0x00000001
[   42.113537] NDCB3: 0x00000000
[   42.132471] nand: nand_do_read_oob: from = 0x0b840000, len = 64
[   42.138504] marvell-nfc pxa3xx-nand: 
[   42.138504] NDCR:  0x9d079fff
[   42.138504] NDCB0: 0x000d3000
[   42.138504] NDCB1: 0x70800000
[   42.138504] NDCB2: 0x00000001
[   42.138504] NDCB3: 0x00000000
[   42.157462] nand: nand_do_read_oob: from = 0x0b860000, len = 64
[   42.163667] marvell-nfc pxa3xx-nand: 
[   42.163667] NDCR:  0x9d079fff
[   42.163667] NDCB0: 0x000d3000
[   42.163667] NDCB1: 0x70c00000
[   42.163667] NDCB2: 0x00000001
[   42.163667] NDCB3: 0x00000000
[   42.182596] nand: nand_do_read_oob: from = 0x0b880000, len = 64
[   42.188630] marvell-nfc pxa3xx-nand: 
[   42.188630] NDCR:  0x9d079fff
[   42.188630] NDCB0: 0x000d3000
[   42.188630] NDCB1: 0x71000000
[   42.188630] NDCB2: 0x00000001
[   42.188630] NDCB3: 0x00000000
[   42.207679] nand: nand_do_read_oob: from = 0x0b8a0000, len = 64
[   42.213879] marvell-nfc pxa3xx-nand: 
[   42.213879] NDCR:  0x9d079fff
[   42.213879] NDCB0: 0x000d3000
[   42.213879] NDCB1: 0x71400000
[   42.213879] NDCB2: 0x00000001
[   42.213879] NDCB3: 0x00000000
[   42.232808] nand: nand_do_read_oob: from = 0x0b8c0000, len = 64
[   42.239009] marvell-nfc pxa3xx-nand: 
[   42.239009] NDCR:  0x9d079fff
[   42.239009] NDCB0: 0x000d3000
[   42.239009] NDCB1: 0x71800000
[   42.239009] NDCB2: 0x00000001
[   42.239009] NDCB3: 0x00000000
[   42.257930] nand: nand_do_read_oob: from = 0x0b8e0000, len = 64
[   42.264130] marvell-nfc pxa3xx-nand: 
[   42.264130] NDCR:  0x9d079fff
[   42.264130] NDCB0: 0x000d3000
[   42.264130] NDCB1: 0x71c00000
[   42.264130] NDCB2: 0x00000001
[   42.264130] NDCB3: 0x00000000
[   42.283062] nand: nand_do_read_oob: from = 0x0b900000, len = 64
[   42.289262] marvell-nfc pxa3xx-nand: 
[   42.289262] NDCR:  0x9d079fff
[   42.289262] NDCB0: 0x000d3000
[   42.289262] NDCB1: 0x72000000
[   42.289262] NDCB2: 0x00000001
[   42.289262] NDCB3: 0x00000000
[   42.308182] nand: nand_do_read_oob: from = 0x0b920000, len = 64
[   42.314386] marvell-nfc pxa3xx-nand: 
[   42.314386] NDCR:  0x9d079fff
[   42.314386] NDCB0: 0x000d3000
[   42.314386] NDCB1: 0x72400000
[   42.314386] NDCB2: 0x00000001
[   42.314386] NDCB3: 0x00000000
[   42.333315] nand: nand_do_read_oob: from = 0x0b940000, len = 64
[   42.339516] marvell-nfc pxa3xx-nand: 
[   42.339516] NDCR:  0x9d079fff
[   42.339516] NDCB0: 0x000d3000
[   42.339516] NDCB1: 0x72800000
[   42.339516] NDCB2: 0x00000001
[   42.339516] NDCB3: 0x00000000
[   42.358435] nand: nand_do_read_oob: from = 0x0b960000, len = 64
[   42.364639] marvell-nfc pxa3xx-nand: 
[   42.364639] NDCR:  0x9d079fff
[   42.364639] NDCB0: 0x000d3000
[   42.364639] NDCB1: 0x72c00000
[   42.364639] NDCB2: 0x00000001
[   42.364639] NDCB3: 0x00000000
[   42.383567] nand: nand_do_read_oob: from = 0x0b980000, len = 64
[   42.389770] marvell-nfc pxa3xx-nand: 
[   42.389770] NDCR:  0x9d079fff
[   42.389770] NDCB0: 0x000d3000
[   42.389770] NDCB1: 0x73000000
[   42.389770] NDCB2: 0x00000001
[   42.389770] NDCB3: 0x00000000
[   42.408784] nand: nand_do_read_oob: from = 0x0b9a0000, len = 64
[   42.414819] marvell-nfc pxa3xx-nand: 
[   42.414819] NDCR:  0x9d079fff
[   42.414819] NDCB0: 0x000d3000
[   42.414819] NDCB1: 0x73400000
[   42.414819] NDCB2: 0x00000001
[   42.414819] NDCB3: 0x00000000
[   42.433736] nand: nand_do_read_oob: from = 0x0b9c0000, len = 64
[   42.439937] marvell-nfc pxa3xx-nand: 
[   42.439937] NDCR:  0x9d079fff
[   42.439937] NDCB0: 0x000d3000
[   42.439937] NDCB1: 0x73800000
[   42.439937] NDCB2: 0x00000001
[   42.439937] NDCB3: 0x00000000
[   42.458900] nand: nand_do_read_oob: from = 0x0b9e0000, len = 64
[   42.464937] marvell-nfc pxa3xx-nand: 
[   42.464937] NDCR:  0x9d079fff
[   42.464937] NDCB0: 0x000d3000
[   42.464937] NDCB1: 0x73c00000
[   42.464937] NDCB2: 0x00000001
[   42.464937] NDCB3: 0x00000000
[   42.483875] nand: nand_do_read_oob: from = 0x0ba00000, len = 64
[   42.490079] marvell-nfc pxa3xx-nand: 
[   42.490079] NDCR:  0x9d079fff
[   42.490079] NDCB0: 0x000d3000
[   42.490079] NDCB1: 0x74000000
[   42.490079] NDCB2: 0x00000001
[   42.490079] NDCB3: 0x00000000
[   42.509044] nand: nand_do_read_oob: from = 0x0ba20000, len = 64
[   42.515075] marvell-nfc pxa3xx-nand: 
[   42.515075] NDCR:  0x9d079fff
[   42.515075] NDCB0: 0x000d3000
[   42.515075] NDCB1: 0x74400000
[   42.515075] NDCB2: 0x00000001
[   42.515075] NDCB3: 0x00000000
[   42.534005] nand: nand_do_read_oob: from = 0x0ba40000, len = 64
[   42.540203] marvell-nfc pxa3xx-nand: 
[   42.540203] NDCR:  0x9d079fff
[   42.540203] NDCB0: 0x000d3000
[   42.540203] NDCB1: 0x74800000
[   42.540203] NDCB2: 0x00000001
[   42.540203] NDCB3: 0x00000000
[   42.559132] nand: nand_do_read_oob: from = 0x0ba60000, len = 64
[   42.565165] marvell-nfc pxa3xx-nand: 
[   42.565165] NDCR:  0x9d079fff
[   42.565165] NDCB0: 0x000d3000
[   42.565165] NDCB1: 0x74c00000
[   42.565165] NDCB2: 0x00000001
[   42.565165] NDCB3: 0x00000000
[   42.584096] nand: nand_do_read_oob: from = 0x0ba80000, len = 64
[   42.590305] marvell-nfc pxa3xx-nand: 
[   42.590305] NDCR:  0x9d079fff
[   42.590305] NDCB0: 0x000d3000
[   42.590305] NDCB1: 0x75000000
[   42.590305] NDCB2: 0x00000001
[   42.590305] NDCB3: 0x00000000
[   42.609234] nand: nand_do_read_oob: from = 0x0baa0000, len = 64
[   42.615262] marvell-nfc pxa3xx-nand: 
[   42.615262] NDCR:  0x9d079fff
[   42.615262] NDCB0: 0x000d3000
[   42.615262] NDCB1: 0x75400000
[   42.615262] NDCB2: 0x00000001
[   42.615262] NDCB3: 0x00000000
[   42.634199] nand: nand_do_read_oob: from = 0x0bac0000, len = 64
[   42.640399] marvell-nfc pxa3xx-nand: 
[   42.640399] NDCR:  0x9d079fff
[   42.640399] NDCB0: 0x000d3000
[   42.640399] NDCB1: 0x75800000
[   42.640399] NDCB2: 0x00000001
[   42.640399] NDCB3: 0x00000000
[   42.659330] nand: nand_do_read_oob: from = 0x0bae0000, len = 64
[   42.665362] marvell-nfc pxa3xx-nand: 
[   42.665362] NDCR:  0x9d079fff
[   42.665362] NDCB0: 0x000d3000
[   42.665362] NDCB1: 0x75c00000
[   42.665362] NDCB2: 0x00000001
[   42.665362] NDCB3: 0x00000000
[   42.684295] nand: nand_do_read_oob: from = 0x0bb00000, len = 64
[   42.690500] marvell-nfc pxa3xx-nand: 
[   42.690500] NDCR:  0x9d079fff
[   42.690500] NDCB0: 0x000d3000
[   42.690500] NDCB1: 0x76000000
[   42.690500] NDCB2: 0x00000001
[   42.690500] NDCB3: 0x00000000
[   42.709428] nand: nand_do_read_oob: from = 0x0bb20000, len = 64
[   42.715459] marvell-nfc pxa3xx-nand: 
[   42.715459] NDCR:  0x9d079fff
[   42.715459] NDCB0: 0x000d3000
[   42.715459] NDCB1: 0x76400000
[   42.715459] NDCB2: 0x00000001
[   42.715459] NDCB3: 0x00000000
[   42.734407] nand: nand_do_read_oob: from = 0x0bb40000, len = 64
[   42.740606] marvell-nfc pxa3xx-nand: 
[   42.740606] NDCR:  0x9d079fff
[   42.740606] NDCB0: 0x000d3000
[   42.740606] NDCB1: 0x76800000
[   42.740606] NDCB2: 0x00000001
[   42.740606] NDCB3: 0x00000000
[   42.759533] nand: nand_do_read_oob: from = 0x0bb60000, len = 64
[   42.765567] marvell-nfc pxa3xx-nand: 
[   42.765567] NDCR:  0x9d079fff
[   42.765567] NDCB0: 0x000d3000
[   42.765567] NDCB1: 0x76c00000
[   42.765567] NDCB2: 0x00000001
[   42.765567] NDCB3: 0x00000000
[   42.784499] nand: nand_do_read_oob: from = 0x0bb80000, len = 64
[   42.790706] marvell-nfc pxa3xx-nand: 
[   42.790706] NDCR:  0x9d079fff
[   42.790706] NDCB0: 0x000d3000
[   42.790706] NDCB1: 0x77000000
[   42.790706] NDCB2: 0x00000001
[   42.790706] NDCB3: 0x00000000
[   42.809636] nand: nand_do_read_oob: from = 0x0bba0000, len = 64
[   42.815674] marvell-nfc pxa3xx-nand: 
[   42.815674] NDCR:  0x9d079fff
[   42.815674] NDCB0: 0x000d3000
[   42.815674] NDCB1: 0x77400000
[   42.815674] NDCB2: 0x00000001
[   42.815674] NDCB3: 0x00000000
[   42.834607] nand: nand_do_read_oob: from = 0x0bbc0000, len = 64
[   42.840811] marvell-nfc pxa3xx-nand: 
[   42.840811] NDCR:  0x9d079fff
[   42.840811] NDCB0: 0x000d3000
[   42.840811] NDCB1: 0x77800000
[   42.840811] NDCB2: 0x00000001
[   42.840811] NDCB3: 0x00000000
[   42.859740] nand: nand_do_read_oob: from = 0x0bbe0000, len = 64
[   42.865773] marvell-nfc pxa3xx-nand: 
[   42.865773] NDCR:  0x9d079fff
[   42.865773] NDCB0: 0x000d3000
[   42.865773] NDCB1: 0x77c00000
[   42.865773] NDCB2: 0x00000001
[   42.865773] NDCB3: 0x00000000
[   42.884703] nand: nand_do_read_oob: from = 0x0bc00000, len = 64
[   42.890911] marvell-nfc pxa3xx-nand: 
[   42.890911] NDCR:  0x9d079fff
[   42.890911] NDCB0: 0x000d3000
[   42.890911] NDCB1: 0x78000000
[   42.890911] NDCB2: 0x00000001
[   42.890911] NDCB3: 0x00000000
[   42.909838] nand: nand_do_read_oob: from = 0x0bc20000, len = 64
[   42.915871] marvell-nfc pxa3xx-nand: 
[   42.915871] NDCR:  0x9d079fff
[   42.915871] NDCB0: 0x000d3000
[   42.915871] NDCB1: 0x78400000
[   42.915871] NDCB2: 0x00000001
[   42.915871] NDCB3: 0x00000000
[   42.934803] nand: nand_do_read_oob: from = 0x0bc40000, len = 64
[   42.941010] marvell-nfc pxa3xx-nand: 
[   42.941010] NDCR:  0x9d079fff
[   42.941010] NDCB0: 0x000d3000
[   42.941010] NDCB1: 0x78800000
[   42.941010] NDCB2: 0x00000001
[   42.941010] NDCB3: 0x00000000
[   42.959937] nand: nand_do_read_oob: from = 0x0bc60000, len = 64
[   42.965968] marvell-nfc pxa3xx-nand: 
[   42.965968] NDCR:  0x9d079fff
[   42.965968] NDCB0: 0x000d3000
[   42.965968] NDCB1: 0x78c00000
[   42.965968] NDCB2: 0x00000001
[   42.965968] NDCB3: 0x00000000
[   42.984902] nand: nand_do_read_oob: from = 0x0bc80000, len = 64
[   42.991106] marvell-nfc pxa3xx-nand: 
[   42.991106] NDCR:  0x9d079fff
[   42.991106] NDCB0: 0x000d3000
[   42.991106] NDCB1: 0x79000000
[   42.991106] NDCB2: 0x00000001
[   42.991106] NDCB3: 0x00000000
[   43.010048] nand: nand_do_read_oob: from = 0x0bca0000, len = 64
[   43.016076] marvell-nfc pxa3xx-nand: 
[   43.016076] NDCR:  0x9d079fff
[   43.016076] NDCB0: 0x000d3000
[   43.016076] NDCB1: 0x79400000
[   43.016076] NDCB2: 0x00000001
[   43.016076] NDCB3: 0x00000000
[   43.035007] nand: nand_do_read_oob: from = 0x0bcc0000, len = 64
[   43.041214] marvell-nfc pxa3xx-nand: 
[   43.041214] NDCR:  0x9d079fff
[   43.041214] NDCB0: 0x000d3000
[   43.041214] NDCB1: 0x79800000
[   43.041214] NDCB2: 0x00000001
[   43.041214] NDCB3: 0x00000000
[   43.060141] nand: nand_do_read_oob: from = 0x0bce0000, len = 64
[   43.066175] marvell-nfc pxa3xx-nand: 
[   43.066175] NDCR:  0x9d079fff
[   43.066175] NDCB0: 0x000d3000
[   43.066175] NDCB1: 0x79c00000
[   43.066175] NDCB2: 0x00000001
[   43.066175] NDCB3: 0x00000000
[   43.085105] nand: nand_do_read_oob: from = 0x0bd00000, len = 64
[   43.091314] marvell-nfc pxa3xx-nand: 
[   43.091314] NDCR:  0x9d079fff
[   43.091314] NDCB0: 0x000d3000
[   43.091314] NDCB1: 0x7a000000
[   43.091314] NDCB2: 0x00000001
[   43.091314] NDCB3: 0x00000000
[   43.110240] nand: nand_do_read_oob: from = 0x0bd20000, len = 64
[   43.116272] marvell-nfc pxa3xx-nand: 
[   43.116272] NDCR:  0x9d079fff
[   43.116272] NDCB0: 0x000d3000
[   43.116272] NDCB1: 0x7a400000
[   43.116272] NDCB2: 0x00000001
[   43.116272] NDCB3: 0x00000000
[   43.135204] nand: nand_do_read_oob: from = 0x0bd40000, len = 64
[   43.141411] marvell-nfc pxa3xx-nand: 
[   43.141411] NDCR:  0x9d079fff
[   43.141411] NDCB0: 0x000d3000
[   43.141411] NDCB1: 0x7a800000
[   43.141411] NDCB2: 0x00000001
[   43.141411] NDCB3: 0x00000000
[   43.160337] nand: nand_do_read_oob: from = 0x0bd60000, len = 64
[   43.166371] marvell-nfc pxa3xx-nand: 
[   43.166371] NDCR:  0x9d079fff
[   43.166371] NDCB0: 0x000d3000
[   43.166371] NDCB1: 0x7ac00000
[   43.166371] NDCB2: 0x00000001
[   43.166371] NDCB3: 0x00000000
[   43.185303] nand: nand_do_read_oob: from = 0x0bd80000, len = 64
[   43.191510] marvell-nfc pxa3xx-nand: 
[   43.191510] NDCR:  0x9d079fff
[   43.191510] NDCB0: 0x000d3000
[   43.191510] NDCB1: 0x7b000000
[   43.191510] NDCB2: 0x00000001
[   43.191510] NDCB3: 0x00000000
[   43.210440] nand: nand_do_read_oob: from = 0x0bda0000, len = 64
[   43.216470] marvell-nfc pxa3xx-nand: 
[   43.216470] NDCR:  0x9d079fff
[   43.216470] NDCB0: 0x000d3000
[   43.216470] NDCB1: 0x7b400000
[   43.216470] NDCB2: 0x00000001
[   43.216470] NDCB3: 0x00000000
[   43.235401] nand: nand_do_read_oob: from = 0x0bdc0000, len = 64
[   43.241609] marvell-nfc pxa3xx-nand: 
[   43.241609] NDCR:  0x9d079fff
[   43.241609] NDCB0: 0x000d3000
[   43.241609] NDCB1: 0x7b800000
[   43.241609] NDCB2: 0x00000001
[   43.241609] NDCB3: 0x00000000
[   43.260534] nand: nand_do_read_oob: from = 0x0bde0000, len = 64
[   43.266567] marvell-nfc pxa3xx-nand: 
[   43.266567] NDCR:  0x9d079fff
[   43.266567] NDCB0: 0x000d3000
[   43.266567] NDCB1: 0x7bc00000
[   43.266567] NDCB2: 0x00000001
[   43.266567] NDCB3: 0x00000000
[   43.285500] nand: nand_do_read_oob: from = 0x0be00000, len = 64
[   43.291706] marvell-nfc pxa3xx-nand: 
[   43.291706] NDCR:  0x9d079fff
[   43.291706] NDCB0: 0x000d3000
[   43.291706] NDCB1: 0x7c000000
[   43.291706] NDCB2: 0x00000001
[   43.291706] NDCB3: 0x00000000
[   43.310634] nand: nand_do_read_oob: from = 0x0be20000, len = 64
[   43.316667] marvell-nfc pxa3xx-nand: 
[   43.316667] NDCR:  0x9d079fff
[   43.316667] NDCB0: 0x000d3000
[   43.316667] NDCB1: 0x7c400000
[   43.316667] NDCB2: 0x00000001
[   43.316667] NDCB3: 0x00000000
[   43.335599] nand: nand_do_read_oob: from = 0x0be40000, len = 64
[   43.341803] marvell-nfc pxa3xx-nand: 
[   43.341803] NDCR:  0x9d079fff
[   43.341803] NDCB0: 0x000d3000
[   43.341803] NDCB1: 0x7c800000
[   43.341803] NDCB2: 0x00000001
[   43.341803] NDCB3: 0x00000000
[   43.360751] nand: nand_do_read_oob: from = 0x0be60000, len = 64
[   43.366783] marvell-nfc pxa3xx-nand: 
[   43.366783] NDCR:  0x9d079fff
[   43.366783] NDCB0: 0x000d3000
[   43.366783] NDCB1: 0x7cc00000
[   43.366783] NDCB2: 0x00000001
[   43.366783] NDCB3: 0x00000000
[   43.385715] nand: nand_do_read_oob: from = 0x0be80000, len = 64
[   43.391921] marvell-nfc pxa3xx-nand: 
[   43.391921] NDCR:  0x9d079fff
[   43.391921] NDCB0: 0x000d3000
[   43.391921] NDCB1: 0x7d000000
[   43.391921] NDCB2: 0x00000001
[   43.391921] NDCB3: 0x00000000
[   43.410851] nand: nand_do_read_oob: from = 0x0bea0000, len = 64
[   43.416881] marvell-nfc pxa3xx-nand: 
[   43.416881] NDCR:  0x9d079fff
[   43.416881] NDCB0: 0x000d3000
[   43.416881] NDCB1: 0x7d400000
[   43.416881] NDCB2: 0x00000001
[   43.416881] NDCB3: 0x00000000
[   43.435815] nand: nand_do_read_oob: from = 0x0bec0000, len = 64
[   43.442018] marvell-nfc pxa3xx-nand: 
[   43.442018] NDCR:  0x9d079fff
[   43.442018] NDCB0: 0x000d3000
[   43.442018] NDCB1: 0x7d800000
[   43.442018] NDCB2: 0x00000001
[   43.442018] NDCB3: 0x00000000
[   43.460946] nand: nand_do_read_oob: from = 0x0bee0000, len = 64
[   43.466980] marvell-nfc pxa3xx-nand: 
[   43.466980] NDCR:  0x9d079fff
[   43.466980] NDCB0: 0x000d3000
[   43.466980] NDCB1: 0x7dc00000
[   43.466980] NDCB2: 0x00000001
[   43.466980] NDCB3: 0x00000000
[   43.485911] nand: nand_do_read_oob: from = 0x0bf00000, len = 64
[   43.492120] marvell-nfc pxa3xx-nand: 
[   43.492120] NDCR:  0x9d079fff
[   43.492120] NDCB0: 0x000d3000
[   43.492120] NDCB1: 0x7e000000
[   43.492120] NDCB2: 0x00000001
[   43.492120] NDCB3: 0x00000000
[   43.511044] nand: nand_do_read_oob: from = 0x0bf20000, len = 64
[   43.517078] marvell-nfc pxa3xx-nand: 
[   43.517078] NDCR:  0x9d079fff
[   43.517078] NDCB0: 0x000d3000
[   43.517078] NDCB1: 0x7e400000
[   43.517078] NDCB2: 0x00000001
[   43.517078] NDCB3: 0x00000000
[   43.536008] nand: nand_do_read_oob: from = 0x0bf40000, len = 64
[   43.542207] marvell-nfc pxa3xx-nand: 
[   43.542207] NDCR:  0x9d079fff
[   43.542207] NDCB0: 0x000d3000
[   43.542207] NDCB1: 0x7e800000
[   43.542207] NDCB2: 0x00000001
[   43.542207] NDCB3: 0x00000000
[   43.561135] nand: nand_do_read_oob: from = 0x0bf60000, len = 64
[   43.567167] marvell-nfc pxa3xx-nand: 
[   43.567167] NDCR:  0x9d079fff
[   43.567167] NDCB0: 0x000d3000
[   43.567167] NDCB1: 0x7ec00000
[   43.567167] NDCB2: 0x00000001
[   43.567167] NDCB3: 0x00000000
[   43.586098] nand: nand_do_read_oob: from = 0x0bf80000, len = 64
[   43.592300] marvell-nfc pxa3xx-nand: 
[   43.592300] NDCR:  0x9d079fff
[   43.592300] NDCB0: 0x000d3000
[   43.592300] NDCB1: 0x7f000000
[   43.592300] NDCB2: 0x00000001
[   43.592300] NDCB3: 0x00000000
[   43.611226] nand: nand_do_read_oob: from = 0x0bfa0000, len = 64
[   43.617256] marvell-nfc pxa3xx-nand: 
[   43.617256] NDCR:  0x9d079fff
[   43.617256] NDCB0: 0x000d3000
[   43.617256] NDCB1: 0x7f400000
[   43.617256] NDCB2: 0x00000001
[   43.617256] NDCB3: 0x00000000
[   43.636191] nand: nand_do_read_oob: from = 0x0bfc0000, len = 64
[   43.642397] marvell-nfc pxa3xx-nand: 
[   43.642397] NDCR:  0x9d079fff
[   43.642397] NDCB0: 0x000d3000
[   43.642397] NDCB1: 0x7f800000
[   43.642397] NDCB2: 0x00000001
[   43.642397] NDCB3: 0x00000000
[   43.661323] nand: nand_do_read_oob: from = 0x0bfe0000, len = 64
[   43.667356] marvell-nfc pxa3xx-nand: 
[   43.667356] NDCR:  0x9d079fff
[   43.667356] NDCB0: 0x000d3000
[   43.667356] NDCB1: 0x7fc00000
[   43.667356] NDCB2: 0x00000001
[   43.667356] NDCB3: 0x00000000
[   43.686286] nand: nand_do_read_oob: from = 0x0c000000, len = 64
[   43.692484] marvell-nfc pxa3xx-nand: 
[   43.692484] NDCR:  0x9d079fff
[   43.692484] NDCB0: 0x000d3000
[   43.692484] NDCB1: 0x80000000
[   43.692484] NDCB2: 0x00000001
[   43.692484] NDCB3: 0x00000000
[   43.711411] nand: nand_do_read_oob: from = 0x0c020000, len = 64
[   43.717447] marvell-nfc pxa3xx-nand: 
[   43.717447] NDCR:  0x9d079fff
[   43.717447] NDCB0: 0x000d3000
[   43.717447] NDCB1: 0x80400000
[   43.717447] NDCB2: 0x00000001
[   43.717447] NDCB3: 0x00000000
[   43.736375] nand: nand_do_read_oob: from = 0x0c040000, len = 64
[   43.742575] marvell-nfc pxa3xx-nand: 
[   43.742575] NDCR:  0x9d079fff
[   43.742575] NDCB0: 0x000d3000
[   43.742575] NDCB1: 0x80800000
[   43.742575] NDCB2: 0x00000001
[   43.742575] NDCB3: 0x00000000
[   43.761504] nand: nand_do_read_oob: from = 0x0c060000, len = 64
[   43.767534] marvell-nfc pxa3xx-nand: 
[   43.767534] NDCR:  0x9d079fff
[   43.767534] NDCB0: 0x000d3000
[   43.767534] NDCB1: 0x80c00000
[   43.767534] NDCB2: 0x00000001
[   43.767534] NDCB3: 0x00000000
[   43.786468] nand: nand_do_read_oob: from = 0x0c080000, len = 64
[   43.792673] marvell-nfc pxa3xx-nand: 
[   43.792673] NDCR:  0x9d079fff
[   43.792673] NDCB0: 0x000d3000
[   43.792673] NDCB1: 0x81000000
[   43.792673] NDCB2: 0x00000001
[   43.792673] NDCB3: 0x00000000
[   43.811602] nand: nand_do_read_oob: from = 0x0c0a0000, len = 64
[   43.817633] marvell-nfc pxa3xx-nand: 
[   43.817633] NDCR:  0x9d079fff
[   43.817633] NDCB0: 0x000d3000
[   43.817633] NDCB1: 0x81400000
[   43.817633] NDCB2: 0x00000001
[   43.817633] NDCB3: 0x00000000
[   43.836567] nand: nand_do_read_oob: from = 0x0c0c0000, len = 64
[   43.842772] marvell-nfc pxa3xx-nand: 
[   43.842772] NDCR:  0x9d079fff
[   43.842772] NDCB0: 0x000d3000
[   43.842772] NDCB1: 0x81800000
[   43.842772] NDCB2: 0x00000001
[   43.842772] NDCB3: 0x00000000
[   43.861701] nand: nand_do_read_oob: from = 0x0c0e0000, len = 64
[   43.867731] marvell-nfc pxa3xx-nand: 
[   43.867731] NDCR:  0x9d079fff
[   43.867731] NDCB0: 0x000d3000
[   43.867731] NDCB1: 0x81c00000
[   43.867731] NDCB2: 0x00000001
[   43.867731] NDCB3: 0x00000000
[   43.886666] nand: nand_do_read_oob: from = 0x0c100000, len = 64
[   43.892870] marvell-nfc pxa3xx-nand: 
[   43.892870] NDCR:  0x9d079fff
[   43.892870] NDCB0: 0x000d3000
[   43.892870] NDCB1: 0x82000000
[   43.892870] NDCB2: 0x00000001
[   43.892870] NDCB3: 0x00000000
[   43.911796] nand: nand_do_read_oob: from = 0x0c120000, len = 64
[   43.917831] marvell-nfc pxa3xx-nand: 
[   43.917831] NDCR:  0x9d079fff
[   43.917831] NDCB0: 0x000d3000
[   43.917831] NDCB1: 0x82400000
[   43.917831] NDCB2: 0x00000001
[   43.917831] NDCB3: 0x00000000
[   43.936765] nand: nand_do_read_oob: from = 0x0c140000, len = 64
[   43.942969] marvell-nfc pxa3xx-nand: 
[   43.942969] NDCR:  0x9d079fff
[   43.942969] NDCB0: 0x000d3000
[   43.942969] NDCB1: 0x82800000
[   43.942969] NDCB2: 0x00000001
[   43.942969] NDCB3: 0x00000000
[   43.961898] nand: nand_do_read_oob: from = 0x0c160000, len = 64
[   43.967929] marvell-nfc pxa3xx-nand: 
[   43.967929] NDCR:  0x9d079fff
[   43.967929] NDCB0: 0x000d3000
[   43.967929] NDCB1: 0x82c00000
[   43.967929] NDCB2: 0x00000001
[   43.967929] NDCB3: 0x00000000
[   43.986862] nand: nand_do_read_oob: from = 0x0c180000, len = 64
[   43.993066] marvell-nfc pxa3xx-nand: 
[   43.993066] NDCR:  0x9d079fff
[   43.993066] NDCB0: 0x000d3000
[   43.993066] NDCB1: 0x83000000
[   43.993066] NDCB2: 0x00000001
[   43.993066] NDCB3: 0x00000000
[   44.012024] nand: nand_do_read_oob: from = 0x0c1a0000, len = 64
[   44.018054] marvell-nfc pxa3xx-nand: 
[   44.018054] NDCR:  0x9d079fff
[   44.018054] NDCB0: 0x000d3000
[   44.018054] NDCB1: 0x83400000
[   44.018054] NDCB2: 0x00000001
[   44.018054] NDCB3: 0x00000000
[   44.036985] nand: nand_do_read_oob: from = 0x0c1c0000, len = 64
[   44.043183] marvell-nfc pxa3xx-nand: 
[   44.043183] NDCR:  0x9d079fff
[   44.043183] NDCB0: 0x000d3000
[   44.043183] NDCB1: 0x83800000
[   44.043183] NDCB2: 0x00000001
[   44.043183] NDCB3: 0x00000000
[   44.062110] nand: nand_do_read_oob: from = 0x0c1e0000, len = 64
[   44.068142] marvell-nfc pxa3xx-nand: 
[   44.068142] NDCR:  0x9d079fff
[   44.068142] NDCB0: 0x000d3000
[   44.068142] NDCB1: 0x83c00000
[   44.068142] NDCB2: 0x00000001
[   44.068142] NDCB3: 0x00000000
[   44.087075] nand: nand_do_read_oob: from = 0x0c200000, len = 64
[   44.093561] marvell-nfc pxa3xx-nand: 
[   44.093561] NDCR:  0x9d079fff
[   44.093561] NDCB0: 0x000d3000
[   44.093561] NDCB1: 0x84000000
[   44.093561] NDCB2: 0x00000001
[   44.093561] NDCB3: 0x00000000
[   44.112559] nand: nand_do_read_oob: from = 0x0c220000, len = 64
[   44.118595] marvell-nfc pxa3xx-nand: 
[   44.118595] NDCR:  0x9d079fff
[   44.118595] NDCB0: 0x000d3000
[   44.118595] NDCB1: 0x84400000
[   44.118595] NDCB2: 0x00000001
[   44.118595] NDCB3: 0x00000000
[   44.137638] nand: nand_do_read_oob: from = 0x0c240000, len = 64
[   44.143845] marvell-nfc pxa3xx-nand: 
[   44.143845] NDCR:  0x9d079fff
[   44.143845] NDCB0: 0x000d3000
[   44.143845] NDCB1: 0x84800000
[   44.143845] NDCB2: 0x00000001
[   44.143845] NDCB3: 0x00000000
[   44.162773] nand: nand_do_read_oob: from = 0x0c260000, len = 64
[   44.168976] marvell-nfc pxa3xx-nand: 
[   44.168976] NDCR:  0x9d079fff
[   44.168976] NDCB0: 0x000d3000
[   44.168976] NDCB1: 0x84c00000
[   44.168976] NDCB2: 0x00000001
[   44.168976] NDCB3: 0x00000000
[   44.187900] nand: nand_do_read_oob: from = 0x0c280000, len = 64
[   44.194099] marvell-nfc pxa3xx-nand: 
[   44.194099] NDCR:  0x9d079fff
[   44.194099] NDCB0: 0x000d3000
[   44.194099] NDCB1: 0x85000000
[   44.194099] NDCB2: 0x00000001
[   44.194099] NDCB3: 0x00000000
[   44.213029] nand: nand_do_read_oob: from = 0x0c2a0000, len = 64
[   44.219229] marvell-nfc pxa3xx-nand: 
[   44.219229] NDCR:  0x9d079fff
[   44.219229] NDCB0: 0x000d3000
[   44.219229] NDCB1: 0x85400000
[   44.219229] NDCB2: 0x00000001
[   44.219229] NDCB3: 0x00000000
[   44.238150] nand: nand_do_read_oob: from = 0x0c2c0000, len = 64
[   44.244354] marvell-nfc pxa3xx-nand: 
[   44.244354] NDCR:  0x9d079fff
[   44.244354] NDCB0: 0x000d3000
[   44.244354] NDCB1: 0x85800000
[   44.244354] NDCB2: 0x00000001
[   44.244354] NDCB3: 0x00000000
[   44.263283] nand: nand_do_read_oob: from = 0x0c2e0000, len = 64
[   44.269484] marvell-nfc pxa3xx-nand: 
[   44.269484] NDCR:  0x9d079fff
[   44.269484] NDCB0: 0x000d3000
[   44.269484] NDCB1: 0x85c00000
[   44.269484] NDCB2: 0x00000001
[   44.269484] NDCB3: 0x00000000
[   44.288402] nand: nand_do_read_oob: from = 0x0c300000, len = 64
[   44.294605] marvell-nfc pxa3xx-nand: 
[   44.294605] NDCR:  0x9d079fff
[   44.294605] NDCB0: 0x000d3000
[   44.294605] NDCB1: 0x86000000
[   44.294605] NDCB2: 0x00000001
[   44.294605] NDCB3: 0x00000000
[   44.313536] nand: nand_do_read_oob: from = 0x0c320000, len = 64
[   44.319735] marvell-nfc pxa3xx-nand: 
[   44.319735] NDCR:  0x9d079fff
[   44.319735] NDCB0: 0x000d3000
[   44.319735] NDCB1: 0x86400000
[   44.319735] NDCB2: 0x00000001
[   44.319735] NDCB3: 0x00000000
[   44.338760] nand: nand_do_read_oob: from = 0x0c340000, len = 64
[   44.344797] marvell-nfc pxa3xx-nand: 
[   44.344797] NDCR:  0x9d079fff
[   44.344797] NDCB0: 0x000d3000
[   44.344797] NDCB1: 0x86800000
[   44.344797] NDCB2: 0x00000001
[   44.344797] NDCB3: 0x00000000
[   44.363708] nand: nand_do_read_oob: from = 0x0c360000, len = 64
[   44.369912] marvell-nfc pxa3xx-nand: 
[   44.369912] NDCR:  0x9d079fff
[   44.369912] NDCB0: 0x000d3000
[   44.369912] NDCB1: 0x86c00000
[   44.369912] NDCB2: 0x00000001
[   44.369912] NDCB3: 0x00000000
[   44.388900] nand: nand_do_read_oob: from = 0x0c380000, len = 64
[   44.394936] marvell-nfc pxa3xx-nand: 
[   44.394936] NDCR:  0x9d079fff
[   44.394936] NDCB0: 0x000d3000
[   44.394936] NDCB1: 0x87000000
[   44.394936] NDCB2: 0x00000001
[   44.394936] NDCB3: 0x00000000
[   44.413878] nand: nand_do_read_oob: from = 0x0c3a0000, len = 64
[   44.420079] marvell-nfc pxa3xx-nand: 
[   44.420079] NDCR:  0x9d079fff
[   44.420079] NDCB0: 0x000d3000
[   44.420079] NDCB1: 0x87400000
[   44.420079] NDCB2: 0x00000001
[   44.420079] NDCB3: 0x00000000
[   44.439048] nand: nand_do_read_oob: from = 0x0c3c0000, len = 64
[   44.445083] marvell-nfc pxa3xx-nand: 
[   44.445083] NDCR:  0x9d079fff
[   44.445083] NDCB0: 0x000d3000
[   44.445083] NDCB1: 0x87800000
[   44.445083] NDCB2: 0x00000001
[   44.445083] NDCB3: 0x00000000
[   44.464017] nand: nand_do_read_oob: from = 0x0c3e0000, len = 64
[   44.470222] marvell-nfc pxa3xx-nand: 
[   44.470222] NDCR:  0x9d079fff
[   44.470222] NDCB0: 0x000d3000
[   44.470222] NDCB1: 0x87c00000
[   44.470222] NDCB2: 0x00000001
[   44.470222] NDCB3: 0x00000000
[   44.489150] nand: nand_do_read_oob: from = 0x0c400000, len = 64
[   44.495182] marvell-nfc pxa3xx-nand: 
[   44.495182] NDCR:  0x9d079fff
[   44.495182] NDCB0: 0x000d3000
[   44.495182] NDCB1: 0x88000000
[   44.495182] NDCB2: 0x00000001
[   44.495182] NDCB3: 0x00000000
[   44.514115] nand: nand_do_read_oob: from = 0x0c420000, len = 64
[   44.520320] marvell-nfc pxa3xx-nand: 
[   44.520320] NDCR:  0x9d079fff
[   44.520320] NDCB0: 0x000d3000
[   44.520320] NDCB1: 0x88400000
[   44.520320] NDCB2: 0x00000001
[   44.520320] NDCB3: 0x00000000
[   44.539252] nand: nand_do_read_oob: from = 0x0c440000, len = 64
[   44.545279] marvell-nfc pxa3xx-nand: 
[   44.545279] NDCR:  0x9d079fff
[   44.545279] NDCB0: 0x000d3000
[   44.545279] NDCB1: 0x88800000
[   44.545279] NDCB2: 0x00000001
[   44.545279] NDCB3: 0x00000000
[   44.564215] nand: nand_do_read_oob: from = 0x0c460000, len = 64
[   44.570419] marvell-nfc pxa3xx-nand: 
[   44.570419] NDCR:  0x9d079fff
[   44.570419] NDCB0: 0x000d3000
[   44.570419] NDCB1: 0x88c00000
[   44.570419] NDCB2: 0x00000001
[   44.570419] NDCB3: 0x00000000
[   44.589370] nand: nand_do_read_oob: from = 0x0c480000, len = 64
[   44.595403] marvell-nfc pxa3xx-nand: 
[   44.595403] NDCR:  0x9d079fff
[   44.595403] NDCB0: 0x000d3000
[   44.595403] NDCB1: 0x89000000
[   44.595403] NDCB2: 0x00000001
[   44.595403] NDCB3: 0x00000000
[   44.614338] nand: nand_do_read_oob: from = 0x0c4a0000, len = 64
[   44.620542] marvell-nfc pxa3xx-nand: 
[   44.620542] NDCR:  0x9d079fff
[   44.620542] NDCB0: 0x000d3000
[   44.620542] NDCB1: 0x89400000
[   44.620542] NDCB2: 0x00000001
[   44.620542] NDCB3: 0x00000000
[   44.639473] nand: nand_do_read_oob: from = 0x0c4c0000, len = 64
[   44.645503] marvell-nfc pxa3xx-nand: 
[   44.645503] NDCR:  0x9d079fff
[   44.645503] NDCB0: 0x000d3000
[   44.645503] NDCB1: 0x89800000
[   44.645503] NDCB2: 0x00000001
[   44.645503] NDCB3: 0x00000000
[   44.664626] nand: nand_do_read_oob: from = 0x0c4e0000, len = 64
[   44.670844] marvell-nfc pxa3xx-nand: 
[   44.670844] NDCR:  0x9d079fff
[   44.670844] NDCB0: 0x000d3000
[   44.670844] NDCB1: 0x89c00000
[   44.670844] NDCB2: 0x00000001
[   44.670844] NDCB3: 0x00000000
[   44.689782] nand: nand_do_read_oob: from = 0x0c500000, len = 64
[   44.695808] marvell-nfc pxa3xx-nand: 
[   44.695808] NDCR:  0x9d079fff
[   44.695808] NDCB0: 0x000d3000
[   44.695808] NDCB1: 0x8a000000
[   44.695808] NDCB2: 0x00000001
[   44.695808] NDCB3: 0x00000000
[   44.714743] nand: nand_do_read_oob: from = 0x0c520000, len = 64
[   44.720945] marvell-nfc pxa3xx-nand: 
[   44.720945] NDCR:  0x9d079fff
[   44.720945] NDCB0: 0x000d3000
[   44.720945] NDCB1: 0x8a400000
[   44.720945] NDCB2: 0x00000001
[   44.720945] NDCB3: 0x00000000
[   44.739875] nand: nand_do_read_oob: from = 0x0c540000, len = 64
[   44.745907] marvell-nfc pxa3xx-nand: 
[   44.745907] NDCR:  0x9d079fff
[   44.745907] NDCB0: 0x000d3000
[   44.745907] NDCB1: 0x8a800000
[   44.745907] NDCB2: 0x00000001
[   44.745907] NDCB3: 0x00000000
[   44.764840] nand: nand_do_read_oob: from = 0x0c560000, len = 64
[   44.771043] marvell-nfc pxa3xx-nand: 
[   44.771043] NDCR:  0x9d079fff
[   44.771043] NDCB0: 0x000d3000
[   44.771043] NDCB1: 0x8ac00000
[   44.771043] NDCB2: 0x00000001
[   44.771043] NDCB3: 0x00000000
[   44.789974] nand: nand_do_read_oob: from = 0x0c580000, len = 64
[   44.796005] marvell-nfc pxa3xx-nand: 
[   44.796005] NDCR:  0x9d079fff
[   44.796005] NDCB0: 0x000d3000
[   44.796005] NDCB1: 0x8b000000
[   44.796005] NDCB2: 0x00000001
[   44.796005] NDCB3: 0x00000000
[   44.814939] nand: nand_do_read_oob: from = 0x0c5a0000, len = 64
[   44.821143] marvell-nfc pxa3xx-nand: 
[   44.821143] NDCR:  0x9d079fff
[   44.821143] NDCB0: 0x000d3000
[   44.821143] NDCB1: 0x8b400000
[   44.821143] NDCB2: 0x00000001
[   44.821143] NDCB3: 0x00000000
[   44.840074] nand: nand_do_read_oob: from = 0x0c5c0000, len = 64
[   44.846103] marvell-nfc pxa3xx-nand: 
[   44.846103] NDCR:  0x9d079fff
[   44.846103] NDCB0: 0x000d3000
[   44.846103] NDCB1: 0x8b800000
[   44.846103] NDCB2: 0x00000001
[   44.846103] NDCB3: 0x00000000
[   44.865038] nand: nand_do_read_oob: from = 0x0c5e0000, len = 64
[   44.871241] marvell-nfc pxa3xx-nand: 
[   44.871241] NDCR:  0x9d079fff
[   44.871241] NDCB0: 0x000d3000
[   44.871241] NDCB1: 0x8bc00000
[   44.871241] NDCB2: 0x00000001
[   44.871241] NDCB3: 0x00000000
[   44.890170] nand: nand_do_read_oob: from = 0x0c600000, len = 64
[   44.896201] marvell-nfc pxa3xx-nand: 
[   44.896201] NDCR:  0x9d079fff
[   44.896201] NDCB0: 0x000d3000
[   44.896201] NDCB1: 0x8c000000
[   44.896201] NDCB2: 0x00000001
[   44.896201] NDCB3: 0x00000000
[   44.915137] nand: nand_do_read_oob: from = 0x0c620000, len = 64
[   44.921341] marvell-nfc pxa3xx-nand: 
[   44.921341] NDCR:  0x9d079fff
[   44.921341] NDCB0: 0x000d3000
[   44.921341] NDCB1: 0x8c400000
[   44.921341] NDCB2: 0x00000001
[   44.921341] NDCB3: 0x00000000
[   44.940269] nand: nand_do_read_oob: from = 0x0c640000, len = 64
[   44.946300] marvell-nfc pxa3xx-nand: 
[   44.946300] NDCR:  0x9d079fff
[   44.946300] NDCB0: 0x000d3000
[   44.946300] NDCB1: 0x8c800000
[   44.946300] NDCB2: 0x00000001
[   44.946300] NDCB3: 0x00000000
[   44.965235] nand: nand_do_read_oob: from = 0x0c660000, len = 64
[   44.971437] marvell-nfc pxa3xx-nand: 
[   44.971437] NDCR:  0x9d079fff
[   44.971437] NDCB0: 0x000d3000
[   44.971437] NDCB1: 0x8cc00000
[   44.971437] NDCB2: 0x00000001
[   44.971437] NDCB3: 0x00000000
[   44.990370] nand: nand_do_read_oob: from = 0x0c680000, len = 64
[   44.996399] marvell-nfc pxa3xx-nand: 
[   44.996399] NDCR:  0x9d079fff
[   44.996399] NDCB0: 0x000d3000
[   44.996399] NDCB1: 0x8d000000
[   44.996399] NDCB2: 0x00000001
[   44.996399] NDCB3: 0x00000000
[   45.015345] nand: nand_do_read_oob: from = 0x0c6a0000, len = 64
[   45.021547] marvell-nfc pxa3xx-nand: 
[   45.021547] NDCR:  0x9d079fff
[   45.021547] NDCB0: 0x000d3000
[   45.021547] NDCB1: 0x8d400000
[   45.021547] NDCB2: 0x00000001
[   45.021547] NDCB3: 0x00000000
[   45.040477] nand: nand_do_read_oob: from = 0x0c6c0000, len = 64
[   45.046508] marvell-nfc pxa3xx-nand: 
[   45.046508] NDCR:  0x9d079fff
[   45.046508] NDCB0: 0x000d3000
[   45.046508] NDCB1: 0x8d800000
[   45.046508] NDCB2: 0x00000001
[   45.046508] NDCB3: 0x00000000
[   45.065439] nand: nand_do_read_oob: from = 0x0c6e0000, len = 64
[   45.071644] marvell-nfc pxa3xx-nand: 
[   45.071644] NDCR:  0x9d079fff
[   45.071644] NDCB0: 0x000d3000
[   45.071644] NDCB1: 0x8dc00000
[   45.071644] NDCB2: 0x00000001
[   45.071644] NDCB3: 0x00000000
[   45.090573] nand: nand_do_read_oob: from = 0x0c700000, len = 64
[   45.096603] marvell-nfc pxa3xx-nand: 
[   45.096603] NDCR:  0x9d079fff
[   45.096603] NDCB0: 0x000d3000
[   45.096603] NDCB1: 0x8e000000
[   45.096603] NDCB2: 0x00000001
[   45.096603] NDCB3: 0x00000000
[   45.115543] nand: nand_do_read_oob: from = 0x0c720000, len = 64
[   45.121743] marvell-nfc pxa3xx-nand: 
[   45.121743] NDCR:  0x9d079fff
[   45.121743] NDCB0: 0x000d3000
[   45.121743] NDCB1: 0x8e400000
[   45.121743] NDCB2: 0x00000001
[   45.121743] NDCB3: 0x00000000
[   45.140672] nand: nand_do_read_oob: from = 0x0c740000, len = 64
[   45.146702] marvell-nfc pxa3xx-nand: 
[   45.146702] NDCR:  0x9d079fff
[   45.146702] NDCB0: 0x000d3000
[   45.146702] NDCB1: 0x8e800000
[   45.146702] NDCB2: 0x00000001
[   45.146702] NDCB3: 0x00000000
[   45.165636] nand: nand_do_read_oob: from = 0x0c760000, len = 64
[   45.171839] marvell-nfc pxa3xx-nand: 
[   45.171839] NDCR:  0x9d079fff
[   45.171839] NDCB0: 0x000d3000
[   45.171839] NDCB1: 0x8ec00000
[   45.171839] NDCB2: 0x00000001
[   45.171839] NDCB3: 0x00000000
[   45.190770] nand: nand_do_read_oob: from = 0x0c780000, len = 64
[   45.196802] marvell-nfc pxa3xx-nand: 
[   45.196802] NDCR:  0x9d079fff
[   45.196802] NDCB0: 0x000d3000
[   45.196802] NDCB1: 0x8f000000
[   45.196802] NDCB2: 0x00000001
[   45.196802] NDCB3: 0x00000000
[   45.215735] nand: nand_do_read_oob: from = 0x0c7a0000, len = 64
[   45.221962] marvell-nfc pxa3xx-nand: 
[   45.221962] NDCR:  0x9d079fff
[   45.221962] NDCB0: 0x000d3000
[   45.221962] NDCB1: 0x8f400000
[   45.221962] NDCB2: 0x00000001
[   45.221962] NDCB3: 0x00000000
[   45.240890] nand: nand_do_read_oob: from = 0x0c7c0000, len = 64
[   45.246926] marvell-nfc pxa3xx-nand: 
[   45.246926] NDCR:  0x9d079fff
[   45.246926] NDCB0: 0x000d3000
[   45.246926] NDCB1: 0x8f800000
[   45.246926] NDCB2: 0x00000001
[   45.246926] NDCB3: 0x00000000
[   45.265858] nand: nand_do_read_oob: from = 0x0c7e0000, len = 64
[   45.272055] marvell-nfc pxa3xx-nand: 
[   45.272055] NDCR:  0x9d079fff
[   45.272055] NDCB0: 0x000d3000
[   45.272055] NDCB1: 0x8fc00000
[   45.272055] NDCB2: 0x00000001
[   45.272055] NDCB3: 0x00000000
[   45.290986] nand: nand_do_read_oob: from = 0x0c800000, len = 64
[   45.297017] marvell-nfc pxa3xx-nand: 
[   45.297017] NDCR:  0x9d079fff
[   45.297017] NDCB0: 0x000d3000
[   45.297017] NDCB1: 0x90000000
[   45.297017] NDCB2: 0x00000001
[   45.297017] NDCB3: 0x00000000
[   45.315951] nand: nand_do_read_oob: from = 0x0c820000, len = 64
[   45.322155] marvell-nfc pxa3xx-nand: 
[   45.322155] NDCR:  0x9d079fff
[   45.322155] NDCB0: 0x000d3000
[   45.322155] NDCB1: 0x90400000
[   45.322155] NDCB2: 0x00000001
[   45.322155] NDCB3: 0x00000000
[   45.341083] nand: nand_do_read_oob: from = 0x0c840000, len = 64
[   45.347114] marvell-nfc pxa3xx-nand: 
[   45.347114] NDCR:  0x9d079fff
[   45.347114] NDCB0: 0x000d3000
[   45.347114] NDCB1: 0x90800000
[   45.347114] NDCB2: 0x00000001
[   45.347114] NDCB3: 0x00000000
[   45.366048] nand: nand_do_read_oob: from = 0x0c860000, len = 64
[   45.372252] marvell-nfc pxa3xx-nand: 
[   45.372252] NDCR:  0x9d079fff
[   45.372252] NDCB0: 0x000d3000
[   45.372252] NDCB1: 0x90c00000
[   45.372252] NDCB2: 0x00000001
[   45.372252] NDCB3: 0x00000000
[   45.391181] nand: nand_do_read_oob: from = 0x0c880000, len = 64
[   45.397214] marvell-nfc pxa3xx-nand: 
[   45.397214] NDCR:  0x9d079fff
[   45.397214] NDCB0: 0x000d3000
[   45.397214] NDCB1: 0x91000000
[   45.397214] NDCB2: 0x00000001
[   45.397214] NDCB3: 0x00000000
[   45.416144] nand: nand_do_read_oob: from = 0x0c8a0000, len = 64
[   45.422344] marvell-nfc pxa3xx-nand: 
[   45.422344] NDCR:  0x9d079fff
[   45.422344] NDCB0: 0x000d3000
[   45.422344] NDCB1: 0x91400000
[   45.422344] NDCB2: 0x00000001
[   45.422344] NDCB3: 0x00000000
[   45.441271] nand: nand_do_read_oob: from = 0x0c8c0000, len = 64
[   45.447303] marvell-nfc pxa3xx-nand: 
[   45.447303] NDCR:  0x9d079fff
[   45.447303] NDCB0: 0x000d3000
[   45.447303] NDCB1: 0x91800000
[   45.447303] NDCB2: 0x00000001
[   45.447303] NDCB3: 0x00000000
[   45.466236] nand: nand_do_read_oob: from = 0x0c8e0000, len = 64
[   45.472441] marvell-nfc pxa3xx-nand: 
[   45.472441] NDCR:  0x9d079fff
[   45.472441] NDCB0: 0x000d3000
[   45.472441] NDCB1: 0x91c00000
[   45.472441] NDCB2: 0x00000001
[   45.472441] NDCB3: 0x00000000
[   45.491370] nand: nand_do_read_oob: from = 0x0c900000, len = 64
[   45.497400] marvell-nfc pxa3xx-nand: 
[   45.497400] NDCR:  0x9d079fff
[   45.497400] NDCB0: 0x000d3000
[   45.497400] NDCB1: 0x92000000
[   45.497400] NDCB2: 0x00000001
[   45.497400] NDCB3: 0x00000000
[   45.516333] nand: nand_do_read_oob: from = 0x0c920000, len = 64
[   45.522540] marvell-nfc pxa3xx-nand: 
[   45.522540] NDCR:  0x9d079fff
[   45.522540] NDCB0: 0x000d3000
[   45.522540] NDCB1: 0x92400000
[   45.522540] NDCB2: 0x00000001
[   45.522540] NDCB3: 0x00000000
[   45.541466] nand: nand_do_read_oob: from = 0x0c940000, len = 64
[   45.547499] marvell-nfc pxa3xx-nand: 
[   45.547499] NDCR:  0x9d079fff
[   45.547499] NDCB0: 0x000d3000
[   45.547499] NDCB1: 0x92800000
[   45.547499] NDCB2: 0x00000001
[   45.547499] NDCB3: 0x00000000
[   45.566431] nand: nand_do_read_oob: from = 0x0c960000, len = 64
[   45.572640] marvell-nfc pxa3xx-nand: 
[   45.572640] NDCR:  0x9d079fff
[   45.572640] NDCB0: 0x000d3000
[   45.572640] NDCB1: 0x92c00000
[   45.572640] NDCB2: 0x00000001
[   45.572640] NDCB3: 0x00000000
[   45.591565] nand: nand_do_read_oob: from = 0x0c980000, len = 64
[   45.597597] marvell-nfc pxa3xx-nand: 
[   45.597597] NDCR:  0x9d079fff
[   45.597597] NDCB0: 0x000d3000
[   45.597597] NDCB1: 0x93000000
[   45.597597] NDCB2: 0x00000001
[   45.597597] NDCB3: 0x00000000
[   45.616531] nand: nand_do_read_oob: from = 0x0c9a0000, len = 64
[   45.622738] marvell-nfc pxa3xx-nand: 
[   45.622738] NDCR:  0x9d079fff
[   45.622738] NDCB0: 0x000d3000
[   45.622738] NDCB1: 0x93400000
[   45.622738] NDCB2: 0x00000001
[   45.622738] NDCB3: 0x00000000
[   45.641664] nand: nand_do_read_oob: from = 0x0c9c0000, len = 64
[   45.647698] marvell-nfc pxa3xx-nand: 
[   45.647698] NDCR:  0x9d079fff
[   45.647698] NDCB0: 0x000d3000
[   45.647698] NDCB1: 0x93800000
[   45.647698] NDCB2: 0x00000001
[   45.647698] NDCB3: 0x00000000
[   45.666628] nand: nand_do_read_oob: from = 0x0c9e0000, len = 64
[   45.672826] marvell-nfc pxa3xx-nand: 
[   45.672826] NDCR:  0x9d079fff
[   45.672826] NDCB0: 0x000d3000
[   45.672826] NDCB1: 0x93c00000
[   45.672826] NDCB2: 0x00000001
[   45.672826] NDCB3: 0x00000000
[   45.691753] nand: nand_do_read_oob: from = 0x0ca00000, len = 64
[   45.697787] marvell-nfc pxa3xx-nand: 
[   45.697787] NDCR:  0x9d079fff
[   45.697787] NDCB0: 0x000d3000
[   45.697787] NDCB1: 0x94000000
[   45.697787] NDCB2: 0x00000001
[   45.697787] NDCB3: 0x00000000
[   45.716719] nand: nand_do_read_oob: from = 0x0ca20000, len = 64
[   45.722924] marvell-nfc pxa3xx-nand: 
[   45.722924] NDCR:  0x9d079fff
[   45.722924] NDCB0: 0x000d3000
[   45.722924] NDCB1: 0x94400000
[   45.722924] NDCB2: 0x00000001
[   45.722924] NDCB3: 0x00000000
[   45.741853] nand: nand_do_read_oob: from = 0x0ca40000, len = 64
[   45.747886] marvell-nfc pxa3xx-nand: 
[   45.747886] NDCR:  0x9d079fff
[   45.747886] NDCB0: 0x000d3000
[   45.747886] NDCB1: 0x94800000
[   45.747886] NDCB2: 0x00000001
[   45.747886] NDCB3: 0x00000000
[   45.766817] nand: nand_do_read_oob: from = 0x0ca60000, len = 64
[   45.773022] marvell-nfc pxa3xx-nand: 
[   45.773022] NDCR:  0x9d079fff
[   45.773022] NDCB0: 0x000d3000
[   45.773022] NDCB1: 0x94c00000
[   45.773022] NDCB2: 0x00000001
[   45.773022] NDCB3: 0x00000000
[   45.791951] nand: nand_do_read_oob: from = 0x0ca80000, len = 64
[   45.797983] marvell-nfc pxa3xx-nand: 
[   45.797983] NDCR:  0x9d079fff
[   45.797983] NDCB0: 0x000d3000
[   45.797983] NDCB1: 0x95000000
[   45.797983] NDCB2: 0x00000001
[   45.797983] NDCB3: 0x00000000
[   45.816918] nand: nand_do_read_oob: from = 0x0caa0000, len = 64
[   45.823121] marvell-nfc pxa3xx-nand: 
[   45.823121] NDCR:  0x9d079fff
[   45.823121] NDCB0: 0x000d3000
[   45.823121] NDCB1: 0x95400000
[   45.823121] NDCB2: 0x00000001
[   45.823121] NDCB3: 0x00000000
[   45.842051] nand: nand_do_read_oob: from = 0x0cac0000, len = 64
[   45.848082] marvell-nfc pxa3xx-nand: 
[   45.848082] NDCR:  0x9d079fff
[   45.848082] NDCB0: 0x000d3000
[   45.848082] NDCB1: 0x95800000
[   45.848082] NDCB2: 0x00000001
[   45.848082] NDCB3: 0x00000000
[   45.867030] nand: nand_do_read_oob: from = 0x0cae0000, len = 64
[   45.873241] marvell-nfc pxa3xx-nand: 
[   45.873241] NDCR:  0x9d079fff
[   45.873241] NDCB0: 0x000d3000
[   45.873241] NDCB1: 0x95c00000
[   45.873241] NDCB2: 0x00000001
[   45.873241] NDCB3: 0x00000000
[   45.892165] nand: nand_do_read_oob: from = 0x0cb00000, len = 64
[   45.898198] marvell-nfc pxa3xx-nand: 
[   45.898198] NDCR:  0x9d079fff
[   45.898198] NDCB0: 0x000d3000
[   45.898198] NDCB1: 0x96000000
[   45.898198] NDCB2: 0x00000001
[   45.898198] NDCB3: 0x00000000
[   45.917130] nand: nand_do_read_oob: from = 0x0cb20000, len = 64
[   45.923335] marvell-nfc pxa3xx-nand: 
[   45.923335] NDCR:  0x9d079fff
[   45.923335] NDCB0: 0x000d3000
[   45.923335] NDCB1: 0x96400000
[   45.923335] NDCB2: 0x00000001
[   45.923335] NDCB3: 0x00000000
[   45.942263] nand: nand_do_read_oob: from = 0x0cb40000, len = 64
[   45.948295] marvell-nfc pxa3xx-nand: 
[   45.948295] NDCR:  0x9d079fff
[   45.948295] NDCB0: 0x000d3000
[   45.948295] NDCB1: 0x96800000
[   45.948295] NDCB2: 0x00000001
[   45.948295] NDCB3: 0x00000000
[   45.967227] nand: nand_do_read_oob: from = 0x0cb60000, len = 64
[   45.973433] marvell-nfc pxa3xx-nand: 
[   45.973433] NDCR:  0x9d079fff
[   45.973433] NDCB0: 0x000d3000
[   45.973433] NDCB1: 0x96c00000
[   45.973433] NDCB2: 0x00000001
[   45.973433] NDCB3: 0x00000000
[   45.992362] nand: nand_do_read_oob: from = 0x0cb80000, len = 64
[   45.998395] marvell-nfc pxa3xx-nand: 
[   45.998395] NDCR:  0x9d079fff
[   45.998395] NDCB0: 0x000d3000
[   45.998395] NDCB1: 0x97000000
[   45.998395] NDCB2: 0x00000001
[   45.998395] NDCB3: 0x00000000
[   46.017334] nand: nand_do_read_oob: from = 0x0cba0000, len = 64
[   46.023535] marvell-nfc pxa3xx-nand: 
[   46.023535] NDCR:  0x9d079fff
[   46.023535] NDCB0: 0x000d3000
[   46.023535] NDCB1: 0x97400000
[   46.023535] NDCB2: 0x00000001
[   46.023535] NDCB3: 0x00000000
[   46.042461] nand: nand_do_read_oob: from = 0x0cbc0000, len = 64
[   46.048492] marvell-nfc pxa3xx-nand: 
[   46.048492] NDCR:  0x9d079fff
[   46.048492] NDCB0: 0x000d3000
[   46.048492] NDCB1: 0x97800000
[   46.048492] NDCB2: 0x00000001
[   46.048492] NDCB3: 0x00000000
[   46.067425] nand: nand_do_read_oob: from = 0x0cbe0000, len = 64
[   46.073630] marvell-nfc pxa3xx-nand: 
[   46.073630] NDCR:  0x9d079fff
[   46.073630] NDCB0: 0x000d3000
[   46.073630] NDCB1: 0x97c00000
[   46.073630] NDCB2: 0x00000001
[   46.073630] NDCB3: 0x00000000
[   46.092889] nand: nand_do_read_oob: from = 0x0cc00000, len = 64
[   46.099125] marvell-nfc pxa3xx-nand: 
[   46.099125] NDCR:  0x9d079fff
[   46.099125] NDCB0: 0x000d3000
[   46.099125] NDCB1: 0x98000000
[   46.099125] NDCB2: 0x00000001
[   46.099125] NDCB3: 0x00000000
[   46.118047] nand: nand_do_read_oob: from = 0x0cc20000, len = 64
[   46.124245] marvell-nfc pxa3xx-nand: 
[   46.124245] NDCR:  0x9d079fff
[   46.124245] NDCB0: 0x000d3000
[   46.124245] NDCB1: 0x98400000
[   46.124245] NDCB2: 0x00000001
[   46.124245] NDCB3: 0x00000000
[   46.143177] nand: nand_do_read_oob: from = 0x0cc40000, len = 64
[   46.149376] marvell-nfc pxa3xx-nand: 
[   46.149376] NDCR:  0x9d079fff
[   46.149376] NDCB0: 0x000d3000
[   46.149376] NDCB1: 0x98800000
[   46.149376] NDCB2: 0x00000001
[   46.149376] NDCB3: 0x00000000
[   46.168296] nand: nand_do_read_oob: from = 0x0cc60000, len = 64
[   46.174499] marvell-nfc pxa3xx-nand: 
[   46.174499] NDCR:  0x9d079fff
[   46.174499] NDCB0: 0x000d3000
[   46.174499] NDCB1: 0x98c00000
[   46.174499] NDCB2: 0x00000001
[   46.174499] NDCB3: 0x00000000
[   46.193429] nand: nand_do_read_oob: from = 0x0cc80000, len = 64
[   46.199629] marvell-nfc pxa3xx-nand: 
[   46.199629] NDCR:  0x9d079fff
[   46.199629] NDCB0: 0x000d3000
[   46.199629] NDCB1: 0x99000000
[   46.199629] NDCB2: 0x00000001
[   46.199629] NDCB3: 0x00000000
[   46.218551] nand: nand_do_read_oob: from = 0x0cca0000, len = 64
[   46.224752] marvell-nfc pxa3xx-nand: 
[   46.224752] NDCR:  0x9d079fff
[   46.224752] NDCB0: 0x000d3000
[   46.224752] NDCB1: 0x99400000
[   46.224752] NDCB2: 0x00000001
[   46.224752] NDCB3: 0x00000000
[   46.243681] nand: nand_do_read_oob: from = 0x0ccc0000, len = 64
[   46.249884] marvell-nfc pxa3xx-nand: 
[   46.249884] NDCR:  0x9d079fff
[   46.249884] NDCB0: 0x000d3000
[   46.249884] NDCB1: 0x99800000
[   46.249884] NDCB2: 0x00000001
[   46.249884] NDCB3: 0x00000000
[   46.268877] nand: nand_do_read_oob: from = 0x0cce0000, len = 64
[   46.274909] marvell-nfc pxa3xx-nand: 
[   46.274909] NDCR:  0x9d079fff
[   46.274909] NDCB0: 0x000d3000
[   46.274909] NDCB1: 0x99c00000
[   46.274909] NDCB2: 0x00000001
[   46.274909] NDCB3: 0x00000000
[   46.293845] nand: nand_do_read_oob: from = 0x0cd00000, len = 64
[   46.300044] marvell-nfc pxa3xx-nand: 
[   46.300044] NDCR:  0x9d079fff
[   46.300044] NDCB0: 0x000d3000
[   46.300044] NDCB1: 0x9a000000
[   46.300044] NDCB2: 0x00000001
[   46.300044] NDCB3: 0x00000000
[   46.319009] nand: nand_do_read_oob: from = 0x0cd20000, len = 64
[   46.325037] marvell-nfc pxa3xx-nand: 
[   46.325037] NDCR:  0x9d079fff
[   46.325037] NDCB0: 0x000d3000
[   46.325037] NDCB1: 0x9a400000
[   46.325037] NDCB2: 0x00000001
[   46.325037] NDCB3: 0x00000000
[   46.343971] nand: nand_do_read_oob: from = 0x0cd40000, len = 64
[   46.350177] marvell-nfc pxa3xx-nand: 
[   46.350177] NDCR:  0x9d079fff
[   46.350177] NDCB0: 0x000d3000
[   46.350177] NDCB1: 0x9a800000
[   46.350177] NDCB2: 0x00000001
[   46.350177] NDCB3: 0x00000000
[   46.369103] nand: nand_do_read_oob: from = 0x0cd60000, len = 64
[   46.375136] marvell-nfc pxa3xx-nand: 
[   46.375136] NDCR:  0x9d079fff
[   46.375136] NDCB0: 0x000d3000
[   46.375136] NDCB1: 0x9ac00000
[   46.375136] NDCB2: 0x00000001
[   46.375136] NDCB3: 0x00000000
[   46.394070] nand: nand_do_read_oob: from = 0x0cd80000, len = 64
[   46.400273] marvell-nfc pxa3xx-nand: 
[   46.400273] NDCR:  0x9d079fff
[   46.400273] NDCB0: 0x000d3000
[   46.400273] NDCB1: 0x9b000000
[   46.400273] NDCB2: 0x00000001
[   46.400273] NDCB3: 0x00000000
[   46.419204] nand: nand_do_read_oob: from = 0x0cda0000, len = 64
[   46.425235] marvell-nfc pxa3xx-nand: 
[   46.425235] NDCR:  0x9d079fff
[   46.425235] NDCB0: 0x000d3000
[   46.425235] NDCB1: 0x9b400000
[   46.425235] NDCB2: 0x00000001
[   46.425235] NDCB3: 0x00000000
[   46.444165] nand: nand_do_read_oob: from = 0x0cdc0000, len = 64
[   46.450364] marvell-nfc pxa3xx-nand: 
[   46.450364] NDCR:  0x9d079fff
[   46.450364] NDCB0: 0x000d3000
[   46.450364] NDCB1: 0x9b800000
[   46.450364] NDCB2: 0x00000001
[   46.450364] NDCB3: 0x00000000
[   46.469315] nand: nand_do_read_oob: from = 0x0cde0000, len = 64
[   46.475343] marvell-nfc pxa3xx-nand: 
[   46.475343] NDCR:  0x9d079fff
[   46.475343] NDCB0: 0x000d3000
[   46.475343] NDCB1: 0x9bc00000
[   46.475343] NDCB2: 0x00000001
[   46.475343] NDCB3: 0x00000000
[   46.494275] nand: nand_do_read_oob: from = 0x0ce00000, len = 64
[   46.500479] marvell-nfc pxa3xx-nand: 
[   46.500479] NDCR:  0x9d079fff
[   46.500479] NDCB0: 0x000d3000
[   46.500479] NDCB1: 0x9c000000
[   46.500479] NDCB2: 0x00000001
[   46.500479] NDCB3: 0x00000000
[   46.519408] nand: nand_do_read_oob: from = 0x0ce20000, len = 64
[   46.525441] marvell-nfc pxa3xx-nand: 
[   46.525441] NDCR:  0x9d079fff
[   46.525441] NDCB0: 0x000d3000
[   46.525441] NDCB1: 0x9c400000
[   46.525441] NDCB2: 0x00000001
[   46.525441] NDCB3: 0x00000000
[   46.544374] nand: nand_do_read_oob: from = 0x0ce40000, len = 64
[   46.550580] marvell-nfc pxa3xx-nand: 
[   46.550580] NDCR:  0x9d079fff
[   46.550580] NDCB0: 0x000d3000
[   46.550580] NDCB1: 0x9c800000
[   46.550580] NDCB2: 0x00000001
[   46.550580] NDCB3: 0x00000000
[   46.569509] nand: nand_do_read_oob: from = 0x0ce60000, len = 64
[   46.575539] marvell-nfc pxa3xx-nand: 
[   46.575539] NDCR:  0x9d079fff
[   46.575539] NDCB0: 0x000d3000
[   46.575539] NDCB1: 0x9cc00000
[   46.575539] NDCB2: 0x00000001
[   46.575539] NDCB3: 0x00000000
[   46.594475] nand: nand_do_read_oob: from = 0x0ce80000, len = 64
[   46.600677] marvell-nfc pxa3xx-nand: 
[   46.600677] NDCR:  0x9d079fff
[   46.600677] NDCB0: 0x000d3000
[   46.600677] NDCB1: 0x9d000000
[   46.600677] NDCB2: 0x00000001
[   46.600677] NDCB3: 0x00000000
[   46.619606] nand: nand_do_read_oob: from = 0x0cea0000, len = 64
[   46.625638] marvell-nfc pxa3xx-nand: 
[   46.625638] NDCR:  0x9d079fff
[   46.625638] NDCB0: 0x000d3000
[   46.625638] NDCB1: 0x9d400000
[   46.625638] NDCB2: 0x00000001
[   46.625638] NDCB3: 0x00000000
[   46.644572] nand: nand_do_read_oob: from = 0x0cec0000, len = 64
[   46.650775] marvell-nfc pxa3xx-nand: 
[   46.650775] NDCR:  0x9d079fff
[   46.650775] NDCB0: 0x000d3000
[   46.650775] NDCB1: 0x9d800000
[   46.650775] NDCB2: 0x00000001
[   46.650775] NDCB3: 0x00000000
[   46.669706] nand: nand_do_read_oob: from = 0x0cee0000, len = 64
[   46.675737] marvell-nfc pxa3xx-nand: 
[   46.675737] NDCR:  0x9d079fff
[   46.675737] NDCB0: 0x000d3000
[   46.675737] NDCB1: 0x9dc00000
[   46.675737] NDCB2: 0x00000001
[   46.675737] NDCB3: 0x00000000
[   46.694670] nand: nand_do_read_oob: from = 0x0cf00000, len = 64
[   46.700875] marvell-nfc pxa3xx-nand: 
[   46.700875] NDCR:  0x9d079fff
[   46.700875] NDCB0: 0x000d3000
[   46.700875] NDCB1: 0x9e000000
[   46.700875] NDCB2: 0x00000001
[   46.700875] NDCB3: 0x00000000
[   46.719802] nand: nand_do_read_oob: from = 0x0cf20000, len = 64
[   46.725834] marvell-nfc pxa3xx-nand: 
[   46.725834] NDCR:  0x9d079fff
[   46.725834] NDCB0: 0x000d3000
[   46.725834] NDCB1: 0x9e400000
[   46.725834] NDCB2: 0x00000001
[   46.725834] NDCB3: 0x00000000
[   46.744765] nand: nand_do_read_oob: from = 0x0cf40000, len = 64
[   46.750964] marvell-nfc pxa3xx-nand: 
[   46.750964] NDCR:  0x9d079fff
[   46.750964] NDCB0: 0x000d3000
[   46.750964] NDCB1: 0x9e800000
[   46.750964] NDCB2: 0x00000001
[   46.750964] NDCB3: 0x00000000
[   46.769892] nand: nand_do_read_oob: from = 0x0cf60000, len = 64
[   46.775924] marvell-nfc pxa3xx-nand: 
[   46.775924] NDCR:  0x9d079fff
[   46.775924] NDCB0: 0x000d3000
[   46.775924] NDCB1: 0x9ec00000
[   46.775924] NDCB2: 0x00000001
[   46.775924] NDCB3: 0x00000000
[   46.794855] nand: nand_do_read_oob: from = 0x0cf80000, len = 64
[   46.801062] marvell-nfc pxa3xx-nand: 
[   46.801062] NDCR:  0x9d079fff
[   46.801062] NDCB0: 0x000d3000
[   46.801062] NDCB1: 0x9f000000
[   46.801062] NDCB2: 0x00000001
[   46.801062] NDCB3: 0x00000000
[   46.819990] nand: nand_do_read_oob: from = 0x0cfa0000, len = 64
[   46.826022] marvell-nfc pxa3xx-nand: 
[   46.826022] NDCR:  0x9d079fff
[   46.826022] NDCB0: 0x000d3000
[   46.826022] NDCB1: 0x9f400000
[   46.826022] NDCB2: 0x00000001
[   46.826022] NDCB3: 0x00000000
[   46.844955] nand: nand_do_read_oob: from = 0x0cfc0000, len = 64
[   46.851162] marvell-nfc pxa3xx-nand: 
[   46.851162] NDCR:  0x9d079fff
[   46.851162] NDCB0: 0x000d3000
[   46.851162] NDCB1: 0x9f800000
[   46.851162] NDCB2: 0x00000001
[   46.851162] NDCB3: 0x00000000
[   46.870089] nand: nand_do_read_oob: from = 0x0cfe0000, len = 64
[   46.876122] marvell-nfc pxa3xx-nand: 
[   46.876122] NDCR:  0x9d079fff
[   46.876122] NDCB0: 0x000d3000
[   46.876122] NDCB1: 0x9fc00000
[   46.876122] NDCB2: 0x00000001
[   46.876122] NDCB3: 0x00000000
[   46.895054] nand: nand_do_read_oob: from = 0x0d000000, len = 64
[   46.901262] marvell-nfc pxa3xx-nand: 
[   46.901262] NDCR:  0x9d079fff
[   46.901262] NDCB0: 0x000d3000
[   46.901262] NDCB1: 0xa0000000
[   46.901262] NDCB2: 0x00000001
[   46.901262] NDCB3: 0x00000000
[   46.920188] nand: nand_do_read_oob: from = 0x0d020000, len = 64
[   46.926220] marvell-nfc pxa3xx-nand: 
[   46.926220] NDCR:  0x9d079fff
[   46.926220] NDCB0: 0x000d3000
[   46.926220] NDCB1: 0xa0400000
[   46.926220] NDCB2: 0x00000001
[   46.926220] NDCB3: 0x00000000
[   46.945153] nand: nand_do_read_oob: from = 0x0d040000, len = 64
[   46.951358] marvell-nfc pxa3xx-nand: 
[   46.951358] NDCR:  0x9d079fff
[   46.951358] NDCB0: 0x000d3000
[   46.951358] NDCB1: 0xa0800000
[   46.951358] NDCB2: 0x00000001
[   46.951358] NDCB3: 0x00000000
[   46.970287] nand: nand_do_read_oob: from = 0x0d060000, len = 64
[   46.976316] marvell-nfc pxa3xx-nand: 
[   46.976316] NDCR:  0x9d079fff
[   46.976316] NDCB0: 0x000d3000
[   46.976316] NDCB1: 0xa0c00000
[   46.976316] NDCB2: 0x00000001
[   46.976316] NDCB3: 0x00000000
[   46.995250] nand: nand_do_read_oob: from = 0x0d080000, len = 64
[   47.001447] marvell-nfc pxa3xx-nand: 
[   47.001447] NDCR:  0x9d079fff
[   47.001447] NDCB0: 0x000d3000
[   47.001447] NDCB1: 0xa1000000
[   47.001447] NDCB2: 0x00000001
[   47.001447] NDCB3: 0x00000000
[   47.020390] nand: nand_do_read_oob: from = 0x0d0a0000, len = 64
[   47.026425] marvell-nfc pxa3xx-nand: 
[   47.026425] NDCR:  0x9d079fff
[   47.026425] NDCB0: 0x000d3000
[   47.026425] NDCB1: 0xa1400000
[   47.026425] NDCB2: 0x00000001
[   47.026425] NDCB3: 0x00000000
[   47.045358] nand: nand_do_read_oob: from = 0x0d0c0000, len = 64
[   47.051563] marvell-nfc pxa3xx-nand: 
[   47.051563] NDCR:  0x9d079fff
[   47.051563] NDCB0: 0x000d3000
[   47.051563] NDCB1: 0xa1800000
[   47.051563] NDCB2: 0x00000001
[   47.051563] NDCB3: 0x00000000
[   47.070492] nand: nand_do_read_oob: from = 0x0d0e0000, len = 64
[   47.076524] marvell-nfc pxa3xx-nand: 
[   47.076524] NDCR:  0x9d079fff
[   47.076524] NDCB0: 0x000d3000
[   47.076524] NDCB1: 0xa1c00000
[   47.076524] NDCB2: 0x00000001
[   47.076524] NDCB3: 0x00000000
[   47.095455] nand: nand_do_read_oob: from = 0x0d100000, len = 64
[   47.101681] marvell-nfc pxa3xx-nand: 
[   47.101681] NDCR:  0x9d079fff
[   47.101681] NDCB0: 0x000d3000
[   47.101681] NDCB1: 0xa2000000
[   47.101681] NDCB2: 0x00000001
[   47.101681] NDCB3: 0x00000000
[   47.120608] nand: nand_do_read_oob: from = 0x0d120000, len = 64
[   47.126638] marvell-nfc pxa3xx-nand: 
[   47.126638] NDCR:  0x9d079fff
[   47.126638] NDCB0: 0x000d3000
[   47.126638] NDCB1: 0xa2400000
[   47.126638] NDCB2: 0x00000001
[   47.126638] NDCB3: 0x00000000
[   47.145573] nand: nand_do_read_oob: from = 0x0d140000, len = 64
[   47.151778] marvell-nfc pxa3xx-nand: 
[   47.151778] NDCR:  0x9d079fff
[   47.151778] NDCB0: 0x000d3000
[   47.151778] NDCB1: 0xa2800000
[   47.151778] NDCB2: 0x00000001
[   47.151778] NDCB3: 0x00000000
[   47.170706] nand: nand_do_read_oob: from = 0x0d160000, len = 64
[   47.176739] marvell-nfc pxa3xx-nand: 
[   47.176739] NDCR:  0x9d079fff
[   47.176739] NDCB0: 0x000d3000
[   47.176739] NDCB1: 0xa2c00000
[   47.176739] NDCB2: 0x00000001
[   47.176739] NDCB3: 0x00000000
[   47.195671] nand: nand_do_read_oob: from = 0x0d180000, len = 64
[   47.201875] marvell-nfc pxa3xx-nand: 
[   47.201875] NDCR:  0x9d079fff
[   47.201875] NDCB0: 0x000d3000
[   47.201875] NDCB1: 0xa3000000
[   47.201875] NDCB2: 0x00000001
[   47.201875] NDCB3: 0x00000000
[   47.220807] nand: nand_do_read_oob: from = 0x0d1a0000, len = 64
[   47.226835] marvell-nfc pxa3xx-nand: 
[   47.226835] NDCR:  0x9d079fff
[   47.226835] NDCB0: 0x000d3000
[   47.226835] NDCB1: 0xa3400000
[   47.226835] NDCB2: 0x00000001
[   47.226835] NDCB3: 0x00000000
[   47.245769] nand: nand_do_read_oob: from = 0x0d1c0000, len = 64
[   47.251975] marvell-nfc pxa3xx-nand: 
[   47.251975] NDCR:  0x9d079fff
[   47.251975] NDCB0: 0x000d3000
[   47.251975] NDCB1: 0xa3800000
[   47.251975] NDCB2: 0x00000001
[   47.251975] NDCB3: 0x00000000
[   47.270905] nand: nand_do_read_oob: from = 0x0d1e0000, len = 64
[   47.276935] marvell-nfc pxa3xx-nand: 
[   47.276935] NDCR:  0x9d079fff
[   47.276935] NDCB0: 0x000d3000
[   47.276935] NDCB1: 0xa3c00000
[   47.276935] NDCB2: 0x00000001
[   47.276935] NDCB3: 0x00000000
[   47.295866] nand: nand_do_read_oob: from = 0x0d200000, len = 64
[   47.302062] marvell-nfc pxa3xx-nand: 
[   47.302062] NDCR:  0x9d079fff
[   47.302062] NDCB0: 0x000d3000
[   47.302062] NDCB1: 0xa4000000
[   47.302062] NDCB2: 0x00000001
[   47.302062] NDCB3: 0x00000000
[   47.320993] nand: nand_do_read_oob: from = 0x0d220000, len = 64
[   47.327024] marvell-nfc pxa3xx-nand: 
[   47.327024] NDCR:  0x9d079fff
[   47.327024] NDCB0: 0x000d3000
[   47.327024] NDCB1: 0xa4400000
[   47.327024] NDCB2: 0x00000001
[   47.327024] NDCB3: 0x00000000
[   47.345960] nand: nand_do_read_oob: from = 0x0d240000, len = 64
[   47.352161] marvell-nfc pxa3xx-nand: 
[   47.352161] NDCR:  0x9d079fff
[   47.352161] NDCB0: 0x000d3000
[   47.352161] NDCB1: 0xa4800000
[   47.352161] NDCB2: 0x00000001
[   47.352161] NDCB3: 0x00000000
[   47.371096] nand: nand_do_read_oob: from = 0x0d260000, len = 64
[   47.377132] marvell-nfc pxa3xx-nand: 
[   47.377132] NDCR:  0x9d079fff
[   47.377132] NDCB0: 0x000d3000
[   47.377132] NDCB1: 0xa4c00000
[   47.377132] NDCB2: 0x00000001
[   47.377132] NDCB3: 0x00000000
[   47.396069] nand: nand_do_read_oob: from = 0x0d280000, len = 64
[   47.402268] marvell-nfc pxa3xx-nand: 
[   47.402268] NDCR:  0x9d079fff
[   47.402268] NDCB0: 0x000d3000
[   47.402268] NDCB1: 0xa5000000
[   47.402268] NDCB2: 0x00000001
[   47.402268] NDCB3: 0x00000000
[   47.421197] nand: nand_do_read_oob: from = 0x0d2a0000, len = 64
[   47.427230] marvell-nfc pxa3xx-nand: 
[   47.427230] NDCR:  0x9d079fff
[   47.427230] NDCB0: 0x000d3000
[   47.427230] NDCB1: 0xa5400000
[   47.427230] NDCB2: 0x00000001
[   47.427230] NDCB3: 0x00000000
[   47.446163] nand: nand_do_read_oob: from = 0x0d2c0000, len = 64
[   47.452369] marvell-nfc pxa3xx-nand: 
[   47.452369] NDCR:  0x9d079fff
[   47.452369] NDCB0: 0x000d3000
[   47.452369] NDCB1: 0xa5800000
[   47.452369] NDCB2: 0x00000001
[   47.452369] NDCB3: 0x00000000
[   47.471297] nand: nand_do_read_oob: from = 0x0d2e0000, len = 64
[   47.477328] marvell-nfc pxa3xx-nand: 
[   47.477328] NDCR:  0x9d079fff
[   47.477328] NDCB0: 0x000d3000
[   47.477328] NDCB1: 0xa5c00000
[   47.477328] NDCB2: 0x00000001
[   47.477328] NDCB3: 0x00000000
[   47.496261] nand: nand_do_read_oob: from = 0x0d300000, len = 64
[   47.502465] marvell-nfc pxa3xx-nand: 
[   47.502465] NDCR:  0x9d079fff
[   47.502465] NDCB0: 0x000d3000
[   47.502465] NDCB1: 0xa6000000
[   47.502465] NDCB2: 0x00000001
[   47.502465] NDCB3: 0x00000000
[   47.521396] nand: nand_do_read_oob: from = 0x0d320000, len = 64
[   47.527426] marvell-nfc pxa3xx-nand: 
[   47.527426] NDCR:  0x9d079fff
[   47.527426] NDCB0: 0x000d3000
[   47.527426] NDCB1: 0xa6400000
[   47.527426] NDCB2: 0x00000001
[   47.527426] NDCB3: 0x00000000
[   47.546361] nand: nand_do_read_oob: from = 0x0d340000, len = 64
[   47.552565] marvell-nfc pxa3xx-nand: 
[   47.552565] NDCR:  0x9d079fff
[   47.552565] NDCB0: 0x000d3000
[   47.552565] NDCB1: 0xa6800000
[   47.552565] NDCB2: 0x00000001
[   47.552565] NDCB3: 0x00000000
[   47.571495] nand: nand_do_read_oob: from = 0x0d360000, len = 64
[   47.577527] marvell-nfc pxa3xx-nand: 
[   47.577527] NDCR:  0x9d079fff
[   47.577527] NDCB0: 0x000d3000
[   47.577527] NDCB1: 0xa6c00000
[   47.577527] NDCB2: 0x00000001
[   47.577527] NDCB3: 0x00000000
[   47.596461] nand: nand_do_read_oob: from = 0x0d380000, len = 64
[   47.602663] marvell-nfc pxa3xx-nand: 
[   47.602663] NDCR:  0x9d079fff
[   47.602663] NDCB0: 0x000d3000
[   47.602663] NDCB1: 0xa7000000
[   47.602663] NDCB2: 0x00000001
[   47.602663] NDCB3: 0x00000000
[   47.621592] nand: nand_do_read_oob: from = 0x0d3a0000, len = 64
[   47.627622] marvell-nfc pxa3xx-nand: 
[   47.627622] NDCR:  0x9d079fff
[   47.627622] NDCB0: 0x000d3000
[   47.627622] NDCB1: 0xa7400000
[   47.627622] NDCB2: 0x00000001
[   47.627622] NDCB3: 0x00000000
[   47.646556] nand: nand_do_read_oob: from = 0x0d3c0000, len = 64
[   47.652754] marvell-nfc pxa3xx-nand: 
[   47.652754] NDCR:  0x9d079fff
[   47.652754] NDCB0: 0x000d3000
[   47.652754] NDCB1: 0xa7800000
[   47.652754] NDCB2: 0x00000001
[   47.652754] NDCB3: 0x00000000
[   47.671681] nand: nand_do_read_oob: from = 0x0d3e0000, len = 64
[   47.677713] marvell-nfc pxa3xx-nand: 
[   47.677713] NDCR:  0x9d079fff
[   47.677713] NDCB0: 0x000d3000
[   47.677713] NDCB1: 0xa7c00000
[   47.677713] NDCB2: 0x00000001
[   47.677713] NDCB3: 0x00000000
[   47.696648] nand: nand_do_read_oob: from = 0x0d400000, len = 64
[   47.702852] marvell-nfc pxa3xx-nand: 
[   47.702852] NDCR:  0x9d079fff
[   47.702852] NDCB0: 0x000d3000
[   47.702852] NDCB1: 0xa8000000
[   47.702852] NDCB2: 0x00000001
[   47.702852] NDCB3: 0x00000000
[   47.721782] nand: nand_do_read_oob: from = 0x0d420000, len = 64
[   47.727812] marvell-nfc pxa3xx-nand: 
[   47.727812] NDCR:  0x9d079fff
[   47.727812] NDCB0: 0x000d3000
[   47.727812] NDCB1: 0xa8400000
[   47.727812] NDCB2: 0x00000001
[   47.727812] NDCB3: 0x00000000
[   47.746762] nand: nand_do_read_oob: from = 0x0d440000, len = 64
[   47.752970] marvell-nfc pxa3xx-nand: 
[   47.752970] NDCR:  0x9d079fff
[   47.752970] NDCB0: 0x000d3000
[   47.752970] NDCB1: 0xa8800000
[   47.752970] NDCB2: 0x00000001
[   47.752970] NDCB3: 0x00000000
[   47.771898] nand: nand_do_read_oob: from = 0x0d460000, len = 64
[   47.777928] marvell-nfc pxa3xx-nand: 
[   47.777928] NDCR:  0x9d079fff
[   47.777928] NDCB0: 0x000d3000
[   47.777928] NDCB1: 0xa8c00000
[   47.777928] NDCB2: 0x00000001
[   47.777928] NDCB3: 0x00000000
[   47.796859] nand: nand_do_read_oob: from = 0x0d480000, len = 64
[   47.803055] marvell-nfc pxa3xx-nand: 
[   47.803055] NDCR:  0x9d079fff
[   47.803055] NDCB0: 0x000d3000
[   47.803055] NDCB1: 0xa9000000
[   47.803055] NDCB2: 0x00000001
[   47.803055] NDCB3: 0x00000000
[   47.821987] nand: nand_do_read_oob: from = 0x0d4a0000, len = 64
[   47.828016] marvell-nfc pxa3xx-nand: 
[   47.828016] NDCR:  0x9d079fff
[   47.828016] NDCB0: 0x000d3000
[   47.828016] NDCB1: 0xa9400000
[   47.828016] NDCB2: 0x00000001
[   47.828016] NDCB3: 0x00000000
[   47.846948] nand: nand_do_read_oob: from = 0x0d4c0000, len = 64
[   47.853146] marvell-nfc pxa3xx-nand: 
[   47.853146] NDCR:  0x9d079fff
[   47.853146] NDCB0: 0x000d3000
[   47.853146] NDCB1: 0xa9800000
[   47.853146] NDCB2: 0x00000001
[   47.853146] NDCB3: 0x00000000
[   47.872076] nand: nand_do_read_oob: from = 0x0d4e0000, len = 64
[   47.878107] marvell-nfc pxa3xx-nand: 
[   47.878107] NDCR:  0x9d079fff
[   47.878107] NDCB0: 0x000d3000
[   47.878107] NDCB1: 0xa9c00000
[   47.878107] NDCB2: 0x00000001
[   47.878107] NDCB3: 0x00000000
[   47.897041] nand: nand_do_read_oob: from = 0x0d500000, len = 64
[   47.903247] marvell-nfc pxa3xx-nand: 
[   47.903247] NDCR:  0x9d079fff
[   47.903247] NDCB0: 0x000d3000
[   47.903247] NDCB1: 0xaa000000
[   47.903247] NDCB2: 0x00000001
[   47.903247] NDCB3: 0x00000000
[   47.922175] nand: nand_do_read_oob: from = 0x0d520000, len = 64
[   47.928205] marvell-nfc pxa3xx-nand: 
[   47.928205] NDCR:  0x9d079fff
[   47.928205] NDCB0: 0x000d3000
[   47.928205] NDCB1: 0xaa400000
[   47.928205] NDCB2: 0x00000001
[   47.928205] NDCB3: 0x00000000
[   47.947139] nand: nand_do_read_oob: from = 0x0d540000, len = 64
[   47.953342] marvell-nfc pxa3xx-nand: 
[   47.953342] NDCR:  0x9d079fff
[   47.953342] NDCB0: 0x000d3000
[   47.953342] NDCB1: 0xaa800000
[   47.953342] NDCB2: 0x00000001
[   47.953342] NDCB3: 0x00000000
[   47.972274] nand: nand_do_read_oob: from = 0x0d560000, len = 64
[   47.978303] marvell-nfc pxa3xx-nand: 
[   47.978303] NDCR:  0x9d079fff
[   47.978303] NDCB0: 0x000d3000
[   47.978303] NDCB1: 0xaac00000
[   47.978303] NDCB2: 0x00000001
[   47.978303] NDCB3: 0x00000000
[   47.997236] nand: nand_do_read_oob: from = 0x0d580000, len = 64
[   48.003442] marvell-nfc pxa3xx-nand: 
[   48.003442] NDCR:  0x9d079fff
[   48.003442] NDCB0: 0x000d3000
[   48.003442] NDCB1: 0xab000000
[   48.003442] NDCB2: 0x00000001
[   48.003442] NDCB3: 0x00000000
[   48.022381] nand: nand_do_read_oob: from = 0x0d5a0000, len = 64
[   48.028411] marvell-nfc pxa3xx-nand: 
[   48.028411] NDCR:  0x9d079fff
[   48.028411] NDCB0: 0x000d3000
[   48.028411] NDCB1: 0xab400000
[   48.028411] NDCB2: 0x00000001
[   48.028411] NDCB3: 0x00000000
[   48.047345] nand: nand_do_read_oob: from = 0x0d5c0000, len = 64
[   48.053549] marvell-nfc pxa3xx-nand: 
[   48.053549] NDCR:  0x9d079fff
[   48.053549] NDCB0: 0x000d3000
[   48.053549] NDCB1: 0xab800000
[   48.053549] NDCB2: 0x00000001
[   48.053549] NDCB3: 0x00000000
[   48.072476] nand: nand_do_read_oob: from = 0x0d5e0000, len = 64
[   48.078509] marvell-nfc pxa3xx-nand: 
[   48.078509] NDCR:  0x9d079fff
[   48.078509] NDCB0: 0x000d3000
[   48.078509] NDCB1: 0xabc00000
[   48.078509] NDCB2: 0x00000001
[   48.078509] NDCB3: 0x00000000
[   48.097879] nand: nand_do_read_oob: from = 0x0d600000, len = 64
[   48.104114] marvell-nfc pxa3xx-nand: 
[   48.104114] NDCR:  0x9d079fff
[   48.104114] NDCB0: 0x000d3000
[   48.104114] NDCB1: 0xac000000
[   48.104114] NDCB2: 0x00000001
[   48.104114] NDCB3: 0x00000000
[   48.123053] nand: nand_do_read_oob: from = 0x0d620000, len = 64
[   48.129253] marvell-nfc pxa3xx-nand: 
[   48.129253] NDCR:  0x9d079fff
[   48.129253] NDCB0: 0x000d3000
[   48.129253] NDCB1: 0xac400000
[   48.129253] NDCB2: 0x00000001
[   48.129253] NDCB3: 0x00000000
[   48.148175] nand: nand_do_read_oob: from = 0x0d640000, len = 64
[   48.154376] marvell-nfc pxa3xx-nand: 
[   48.154376] NDCR:  0x9d079fff
[   48.154376] NDCB0: 0x000d3000
[   48.154376] NDCB1: 0xac800000
[   48.154376] NDCB2: 0x00000001
[   48.154376] NDCB3: 0x00000000
[   48.173310] nand: nand_do_read_oob: from = 0x0d660000, len = 64
[   48.179516] marvell-nfc pxa3xx-nand: 
[   48.179516] NDCR:  0x9d079fff
[   48.179516] NDCB0: 0x000d3000
[   48.179516] NDCB1: 0xacc00000
[   48.179516] NDCB2: 0x00000001
[   48.179516] NDCB3: 0x00000000
[   48.198437] nand: nand_do_read_oob: from = 0x0d680000, len = 64
[   48.204636] marvell-nfc pxa3xx-nand: 
[   48.204636] NDCR:  0x9d079fff
[   48.204636] NDCB0: 0x000d3000
[   48.204636] NDCB1: 0xad000000
[   48.204636] NDCB2: 0x00000001
[   48.204636] NDCB3: 0x00000000
[   48.223568] nand: nand_do_read_oob: from = 0x0d6a0000, len = 64
[   48.229769] marvell-nfc pxa3xx-nand: 
[   48.229769] NDCR:  0x9d079fff
[   48.229769] NDCB0: 0x000d3000
[   48.229769] NDCB1: 0xad400000
[   48.229769] NDCB2: 0x00000001
[   48.229769] NDCB3: 0x00000000
[   48.248784] nand: nand_do_read_oob: from = 0x0d6c0000, len = 64
[   48.254819] marvell-nfc pxa3xx-nand: 
[   48.254819] NDCR:  0x9d079fff
[   48.254819] NDCB0: 0x000d3000
[   48.254819] NDCB1: 0xad800000
[   48.254819] NDCB2: 0x00000001
[   48.254819] NDCB3: 0x00000000
[   48.273742] nand: nand_do_read_oob: from = 0x0d6e0000, len = 64
[   48.279946] marvell-nfc pxa3xx-nand: 
[   48.279946] NDCR:  0x9d079fff
[   48.279946] NDCB0: 0x000d3000
[   48.279946] NDCB1: 0xadc00000
[   48.279946] NDCB2: 0x00000001
[   48.279946] NDCB3: 0x00000000
[   48.298898] nand: nand_do_read_oob: from = 0x0d700000, len = 64
[   48.304935] marvell-nfc pxa3xx-nand: 
[   48.304935] NDCR:  0x9d079fff
[   48.304935] NDCB0: 0x000d3000
[   48.304935] NDCB1: 0xae000000
[   48.304935] NDCB2: 0x00000001
[   48.304935] NDCB3: 0x00000000
[   48.323875] nand: nand_do_read_oob: from = 0x0d720000, len = 64
[   48.330079] marvell-nfc pxa3xx-nand: 
[   48.330079] NDCR:  0x9d079fff
[   48.330079] NDCB0: 0x000d3000
[   48.330079] NDCB1: 0xae400000
[   48.330079] NDCB2: 0x00000001
[   48.330079] NDCB3: 0x00000000
[   48.349067] nand: nand_do_read_oob: from = 0x0d740000, len = 64
[   48.355098] marvell-nfc pxa3xx-nand: 
[   48.355098] NDCR:  0x9d079fff
[   48.355098] NDCB0: 0x000d3000
[   48.355098] NDCB1: 0xae800000
[   48.355098] NDCB2: 0x00000001
[   48.355098] NDCB3: 0x00000000
[   48.374031] nand: nand_do_read_oob: from = 0x0d760000, len = 64
[   48.380237] marvell-nfc pxa3xx-nand: 
[   48.380237] NDCR:  0x9d079fff
[   48.380237] NDCB0: 0x000d3000
[   48.380237] NDCB1: 0xaec00000
[   48.380237] NDCB2: 0x00000001
[   48.380237] NDCB3: 0x00000000
[   48.399163] nand: nand_do_read_oob: from = 0x0d780000, len = 64
[   48.405197] marvell-nfc pxa3xx-nand: 
[   48.405197] NDCR:  0x9d079fff
[   48.405197] NDCB0: 0x000d3000
[   48.405197] NDCB1: 0xaf000000
[   48.405197] NDCB2: 0x00000001
[   48.405197] NDCB3: 0x00000000
[   48.424134] nand: nand_do_read_oob: from = 0x0d7a0000, len = 64
[   48.430336] marvell-nfc pxa3xx-nand: 
[   48.430336] NDCR:  0x9d079fff
[   48.430336] NDCB0: 0x000d3000
[   48.430336] NDCB1: 0xaf400000
[   48.430336] NDCB2: 0x00000001
[   48.430336] NDCB3: 0x00000000
[   48.449263] nand: nand_do_read_oob: from = 0x0d7c0000, len = 64
[   48.455295] marvell-nfc pxa3xx-nand: 
[   48.455295] NDCR:  0x9d079fff
[   48.455295] NDCB0: 0x000d3000
[   48.455295] NDCB1: 0xaf800000
[   48.455295] NDCB2: 0x00000001
[   48.455295] NDCB3: 0x00000000
[   48.474226] nand: nand_do_read_oob: from = 0x0d7e0000, len = 64
[   48.480426] marvell-nfc pxa3xx-nand: 
[   48.480426] NDCR:  0x9d079fff
[   48.480426] NDCB0: 0x000d3000
[   48.480426] NDCB1: 0xafc00000
[   48.480426] NDCB2: 0x00000001
[   48.480426] NDCB3: 0x00000000
[   48.499354] nand: nand_do_read_oob: from = 0x0d800000, len = 64
[   48.505386] marvell-nfc pxa3xx-nand: 
[   48.505386] NDCR:  0x9d079fff
[   48.505386] NDCB0: 0x000d3000
[   48.505386] NDCB1: 0xb0000000
[   48.505386] NDCB2: 0x00000001
[   48.505386] NDCB3: 0x00000000
[   48.524317] nand: nand_do_read_oob: from = 0x0d820000, len = 64
[   48.530523] marvell-nfc pxa3xx-nand: 
[   48.530523] NDCR:  0x9d079fff
[   48.530523] NDCB0: 0x000d3000
[   48.530523] NDCB1: 0xb0400000
[   48.530523] NDCB2: 0x00000001
[   48.530523] NDCB3: 0x00000000
[   48.549450] nand: nand_do_read_oob: from = 0x0d840000, len = 64
[   48.555484] marvell-nfc pxa3xx-nand: 
[   48.555484] NDCR:  0x9d079fff
[   48.555484] NDCB0: 0x000d3000
[   48.555484] NDCB1: 0xb0800000
[   48.555484] NDCB2: 0x00000001
[   48.555484] NDCB3: 0x00000000
[   48.574414] nand: nand_do_read_oob: from = 0x0d860000, len = 64
[   48.580613] marvell-nfc pxa3xx-nand: 
[   48.580613] NDCR:  0x9d079fff
[   48.580613] NDCB0: 0x000d3000
[   48.580613] NDCB1: 0xb0c00000
[   48.580613] NDCB2: 0x00000001
[   48.580613] NDCB3: 0x00000000
[   48.599540] nand: nand_do_read_oob: from = 0x0d880000, len = 64
[   48.605573] marvell-nfc pxa3xx-nand: 
[   48.605573] NDCR:  0x9d079fff
[   48.605573] NDCB0: 0x000d3000
[   48.605573] NDCB1: 0xb1000000
[   48.605573] NDCB2: 0x00000001
[   48.605573] NDCB3: 0x00000000
[   48.624507] nand: nand_do_read_oob: from = 0x0d8a0000, len = 64
[   48.630712] marvell-nfc pxa3xx-nand: 
[   48.630712] NDCR:  0x9d079fff
[   48.630712] NDCB0: 0x000d3000
[   48.630712] NDCB1: 0xb1400000
[   48.630712] NDCB2: 0x00000001
[   48.630712] NDCB3: 0x00000000
[   48.649636] nand: nand_do_read_oob: from = 0x0d8c0000, len = 64
[   48.655671] marvell-nfc pxa3xx-nand: 
[   48.655671] NDCR:  0x9d079fff
[   48.655671] NDCB0: 0x000d3000
[   48.655671] NDCB1: 0xb1800000
[   48.655671] NDCB2: 0x00000001
[   48.655671] NDCB3: 0x00000000
[   48.674606] nand: nand_do_read_oob: from = 0x0d8e0000, len = 64
[   48.680811] marvell-nfc pxa3xx-nand: 
[   48.680811] NDCR:  0x9d079fff
[   48.680811] NDCB0: 0x000d3000
[   48.680811] NDCB1: 0xb1c00000
[   48.680811] NDCB2: 0x00000001
[   48.680811] NDCB3: 0x00000000
[   48.699737] nand: nand_do_read_oob: from = 0x0d900000, len = 64
[   48.705771] marvell-nfc pxa3xx-nand: 
[   48.705771] NDCR:  0x9d079fff
[   48.705771] NDCB0: 0x000d3000
[   48.705771] NDCB1: 0xb2000000
[   48.705771] NDCB2: 0x00000001
[   48.705771] NDCB3: 0x00000000
[   48.724702] nand: nand_do_read_oob: from = 0x0d920000, len = 64
[   48.730909] marvell-nfc pxa3xx-nand: 
[   48.730909] NDCR:  0x9d079fff
[   48.730909] NDCB0: 0x000d3000
[   48.730909] NDCB1: 0xb2400000
[   48.730909] NDCB2: 0x00000001
[   48.730909] NDCB3: 0x00000000
[   48.749835] nand: nand_do_read_oob: from = 0x0d940000, len = 64
[   48.755867] marvell-nfc pxa3xx-nand: 
[   48.755867] NDCR:  0x9d079fff
[   48.755867] NDCB0: 0x000d3000
[   48.755867] NDCB1: 0xb2800000
[   48.755867] NDCB2: 0x00000001
[   48.755867] NDCB3: 0x00000000
[   48.774801] nand: nand_do_read_oob: from = 0x0d960000, len = 64
[   48.781008] marvell-nfc pxa3xx-nand: 
[   48.781008] NDCR:  0x9d079fff
[   48.781008] NDCB0: 0x000d3000
[   48.781008] NDCB1: 0xb2c00000
[   48.781008] NDCB2: 0x00000001
[   48.781008] NDCB3: 0x00000000
[   48.799934] nand: nand_do_read_oob: from = 0x0d980000, len = 64
[   48.805966] marvell-nfc pxa3xx-nand: 
[   48.805966] NDCR:  0x9d079fff
[   48.805966] NDCB0: 0x000d3000
[   48.805966] NDCB1: 0xb3000000
[   48.805966] NDCB2: 0x00000001
[   48.805966] NDCB3: 0x00000000
[   48.824900] nand: nand_do_read_oob: from = 0x0d9a0000, len = 64
[   48.831106] marvell-nfc pxa3xx-nand: 
[   48.831106] NDCR:  0x9d079fff
[   48.831106] NDCB0: 0x000d3000
[   48.831106] NDCB1: 0xb3400000
[   48.831106] NDCB2: 0x00000001
[   48.831106] NDCB3: 0x00000000
[   48.850033] nand: nand_do_read_oob: from = 0x0d9c0000, len = 64
[   48.856066] marvell-nfc pxa3xx-nand: 
[   48.856066] NDCR:  0x9d079fff
[   48.856066] NDCB0: 0x000d3000
[   48.856066] NDCB1: 0xb3800000
[   48.856066] NDCB2: 0x00000001
[   48.856066] NDCB3: 0x00000000
[   48.874996] nand: nand_do_read_oob: from = 0x0d9e0000, len = 64
[   48.881196] marvell-nfc pxa3xx-nand: 
[   48.881196] NDCR:  0x9d079fff
[   48.881196] NDCB0: 0x000d3000
[   48.881196] NDCB1: 0xb3c00000
[   48.881196] NDCB2: 0x00000001
[   48.881196] NDCB3: 0x00000000
[   48.900126] nand: nand_do_read_oob: from = 0x0da00000, len = 64
[   48.906155] marvell-nfc pxa3xx-nand: 
[   48.906155] NDCR:  0x9d079fff
[   48.906155] NDCB0: 0x000d3000
[   48.906155] NDCB1: 0xb4000000
[   48.906155] NDCB2: 0x00000001
[   48.906155] NDCB3: 0x00000000
[   48.925088] nand: nand_do_read_oob: from = 0x0da20000, len = 64
[   48.931293] marvell-nfc pxa3xx-nand: 
[   48.931293] NDCR:  0x9d079fff
[   48.931293] NDCB0: 0x000d3000
[   48.931293] NDCB1: 0xb4400000
[   48.931293] NDCB2: 0x00000001
[   48.931293] NDCB3: 0x00000000
[   48.950222] nand: nand_do_read_oob: from = 0x0da40000, len = 64
[   48.956253] marvell-nfc pxa3xx-nand: 
[   48.956253] NDCR:  0x9d079fff
[   48.956253] NDCB0: 0x000d3000
[   48.956253] NDCB1: 0xb4800000
[   48.956253] NDCB2: 0x00000001
[   48.956253] NDCB3: 0x00000000
[   48.975194] nand: nand_do_read_oob: from = 0x0da60000, len = 64
[   48.981412] marvell-nfc pxa3xx-nand: 
[   48.981412] NDCR:  0x9d079fff
[   48.981412] NDCB0: 0x000d3000
[   48.981412] NDCB1: 0xb4c00000
[   48.981412] NDCB2: 0x00000001
[   48.981412] NDCB3: 0x00000000
[   49.000340] nand: nand_do_read_oob: from = 0x0da80000, len = 64
[   49.006369] marvell-nfc pxa3xx-nand: 
[   49.006369] NDCR:  0x9d079fff
[   49.006369] NDCB0: 0x000d3000
[   49.006369] NDCB1: 0xb5000000
[   49.006369] NDCB2: 0x00000001
[   49.006369] NDCB3: 0x00000000
[   49.025312] nand: nand_do_read_oob: from = 0x0daa0000, len = 64
[   49.031521] marvell-nfc pxa3xx-nand: 
[   49.031521] NDCR:  0x9d079fff
[   49.031521] NDCB0: 0x000d3000
[   49.031521] NDCB1: 0xb5400000
[   49.031521] NDCB2: 0x00000001
[   49.031521] NDCB3: 0x00000000
[   49.050446] nand: nand_do_read_oob: from = 0x0dac0000, len = 64
[   49.056477] marvell-nfc pxa3xx-nand: 
[   49.056477] NDCR:  0x9d079fff
[   49.056477] NDCB0: 0x000d3000
[   49.056477] NDCB1: 0xb5800000
[   49.056477] NDCB2: 0x00000001
[   49.056477] NDCB3: 0x00000000
[   49.075410] nand: nand_do_read_oob: from = 0x0dae0000, len = 64
[   49.081617] marvell-nfc pxa3xx-nand: 
[   49.081617] NDCR:  0x9d079fff
[   49.081617] NDCB0: 0x000d3000
[   49.081617] NDCB1: 0xb5c00000
[   49.081617] NDCB2: 0x00000001
[   49.081617] NDCB3: 0x00000000
[   49.100544] nand: nand_do_read_oob: from = 0x0db00000, len = 64
[   49.106576] marvell-nfc pxa3xx-nand: 
[   49.106576] NDCR:  0x9d079fff
[   49.106576] NDCB0: 0x000d3000
[   49.106576] NDCB1: 0xb6000000
[   49.106576] NDCB2: 0x00000001
[   49.106576] NDCB3: 0x00000000
[   49.125510] nand: nand_do_read_oob: from = 0x0db20000, len = 64
[   49.131714] marvell-nfc pxa3xx-nand: 
[   49.131714] NDCR:  0x9d079fff
[   49.131714] NDCB0: 0x000d3000
[   49.131714] NDCB1: 0xb6400000
[   49.131714] NDCB2: 0x00000001
[   49.131714] NDCB3: 0x00000000
[   49.150639] nand: nand_do_read_oob: from = 0x0db40000, len = 64
[   49.156675] marvell-nfc pxa3xx-nand: 
[   49.156675] NDCR:  0x9d079fff
[   49.156675] NDCB0: 0x000d3000
[   49.156675] NDCB1: 0xb6800000
[   49.156675] NDCB2: 0x00000001
[   49.156675] NDCB3: 0x00000000
[   49.175608] nand: nand_do_read_oob: from = 0x0db60000, len = 64
[   49.181812] marvell-nfc pxa3xx-nand: 
[   49.181812] NDCR:  0x9d079fff
[   49.181812] NDCB0: 0x000d3000
[   49.181812] NDCB1: 0xb6c00000
[   49.181812] NDCB2: 0x00000001
[   49.181812] NDCB3: 0x00000000
[   49.200741] nand: nand_do_read_oob: from = 0x0db80000, len = 64
[   49.206771] marvell-nfc pxa3xx-nand: 
[   49.206771] NDCR:  0x9d079fff
[   49.206771] NDCB0: 0x000d3000
[   49.206771] NDCB1: 0xb7000000
[   49.206771] NDCB2: 0x00000001
[   49.206771] NDCB3: 0x00000000
[   49.225705] nand: nand_do_read_oob: from = 0x0dba0000, len = 64
[   49.231911] marvell-nfc pxa3xx-nand: 
[   49.231911] NDCR:  0x9d079fff
[   49.231911] NDCB0: 0x000d3000
[   49.231911] NDCB1: 0xb7400000
[   49.231911] NDCB2: 0x00000001
[   49.231911] NDCB3: 0x00000000
[   49.250839] nand: nand_do_read_oob: from = 0x0dbc0000, len = 64
[   49.256871] marvell-nfc pxa3xx-nand: 
[   49.256871] NDCR:  0x9d079fff
[   49.256871] NDCB0: 0x000d3000
[   49.256871] NDCB1: 0xb7800000
[   49.256871] NDCB2: 0x00000001
[   49.256871] NDCB3: 0x00000000
[   49.275804] nand: nand_do_read_oob: from = 0x0dbe0000, len = 64
[   49.282010] marvell-nfc pxa3xx-nand: 
[   49.282010] NDCR:  0x9d079fff
[   49.282010] NDCB0: 0x000d3000
[   49.282010] NDCB1: 0xb7c00000
[   49.282010] NDCB2: 0x00000001
[   49.282010] NDCB3: 0x00000000
[   49.300936] nand: nand_do_read_oob: from = 0x0dc00000, len = 64
[   49.306970] marvell-nfc pxa3xx-nand: 
[   49.306970] NDCR:  0x9d079fff
[   49.306970] NDCB0: 0x000d3000
[   49.306970] NDCB1: 0xb8000000
[   49.306970] NDCB2: 0x00000001
[   49.306970] NDCB3: 0x00000000
[   49.325901] nand: nand_do_read_oob: from = 0x0dc20000, len = 64
[   49.332108] marvell-nfc pxa3xx-nand: 
[   49.332108] NDCR:  0x9d079fff
[   49.332108] NDCB0: 0x000d3000
[   49.332108] NDCB1: 0xb8400000
[   49.332108] NDCB2: 0x00000001
[   49.332108] NDCB3: 0x00000000
[   49.351034] nand: nand_do_read_oob: from = 0x0dc40000, len = 64
[   49.357067] marvell-nfc pxa3xx-nand: 
[   49.357067] NDCR:  0x9d079fff
[   49.357067] NDCB0: 0x000d3000
[   49.357067] NDCB1: 0xb8800000
[   49.357067] NDCB2: 0x00000001
[   49.357067] NDCB3: 0x00000000
[   49.376000] nand: nand_do_read_oob: from = 0x0dc60000, len = 64
[   49.382207] marvell-nfc pxa3xx-nand: 
[   49.382207] NDCR:  0x9d079fff
[   49.382207] NDCB0: 0x000d3000
[   49.382207] NDCB1: 0xb8c00000
[   49.382207] NDCB2: 0x00000001
[   49.382207] NDCB3: 0x00000000
[   49.401132] nand: nand_do_read_oob: from = 0x0dc80000, len = 64
[   49.407166] marvell-nfc pxa3xx-nand: 
[   49.407166] NDCR:  0x9d079fff
[   49.407166] NDCB0: 0x000d3000
[   49.407166] NDCB1: 0xb9000000
[   49.407166] NDCB2: 0x00000001
[   49.407166] NDCB3: 0x00000000
[   49.426098] nand: nand_do_read_oob: from = 0x0dca0000, len = 64
[   49.432305] marvell-nfc pxa3xx-nand: 
[   49.432305] NDCR:  0x9d079fff
[   49.432305] NDCB0: 0x000d3000
[   49.432305] NDCB1: 0xb9400000
[   49.432305] NDCB2: 0x00000001
[   49.432305] NDCB3: 0x00000000
[   49.451232] nand: nand_do_read_oob: from = 0x0dcc0000, len = 64
[   49.457265] marvell-nfc pxa3xx-nand: 
[   49.457265] NDCR:  0x9d079fff
[   49.457265] NDCB0: 0x000d3000
[   49.457265] NDCB1: 0xb9800000
[   49.457265] NDCB2: 0x00000001
[   49.457265] NDCB3: 0x00000000
[   49.476197] nand: nand_do_read_oob: from = 0x0dce0000, len = 64
[   49.482403] marvell-nfc pxa3xx-nand: 
[   49.482403] NDCR:  0x9d079fff
[   49.482403] NDCB0: 0x000d3000
[   49.482403] NDCB1: 0xb9c00000
[   49.482403] NDCB2: 0x00000001
[   49.482403] NDCB3: 0x00000000
[   49.501331] nand: nand_do_read_oob: from = 0x0dd00000, len = 64
[   49.507364] marvell-nfc pxa3xx-nand: 
[   49.507364] NDCR:  0x9d079fff
[   49.507364] NDCB0: 0x000d3000
[   49.507364] NDCB1: 0xba000000
[   49.507364] NDCB2: 0x00000001
[   49.507364] NDCB3: 0x00000000
[   49.526296] nand: nand_do_read_oob: from = 0x0dd20000, len = 64
[   49.532502] marvell-nfc pxa3xx-nand: 
[   49.532502] NDCR:  0x9d079fff
[   49.532502] NDCB0: 0x000d3000
[   49.532502] NDCB1: 0xba400000
[   49.532502] NDCB2: 0x00000001
[   49.532502] NDCB3: 0x00000000
[   49.551430] nand: nand_do_read_oob: from = 0x0dd40000, len = 64
[   49.557461] marvell-nfc pxa3xx-nand: 
[   49.557461] NDCR:  0x9d079fff
[   49.557461] NDCB0: 0x000d3000
[   49.557461] NDCB1: 0xba800000
[   49.557461] NDCB2: 0x00000001
[   49.557461] NDCB3: 0x00000000
[   49.576397] nand: nand_do_read_oob: from = 0x0dd60000, len = 64
[   49.582599] marvell-nfc pxa3xx-nand: 
[   49.582599] NDCR:  0x9d079fff
[   49.582599] NDCB0: 0x000d3000
[   49.582599] NDCB1: 0xbac00000
[   49.582599] NDCB2: 0x00000001
[   49.582599] NDCB3: 0x00000000
[   49.601527] nand: nand_do_read_oob: from = 0x0dd80000, len = 64
[   49.607560] marvell-nfc pxa3xx-nand: 
[   49.607560] NDCR:  0x9d079fff
[   49.607560] NDCB0: 0x000d3000
[   49.607560] NDCB1: 0xbb000000
[   49.607560] NDCB2: 0x00000001
[   49.607560] NDCB3: 0x00000000
[   49.626508] nand: nand_do_read_oob: from = 0x0dda0000, len = 64
[   49.632715] marvell-nfc pxa3xx-nand: 
[   49.632715] NDCR:  0x9d079fff
[   49.632715] NDCB0: 0x000d3000
[   49.632715] NDCB1: 0xbb400000
[   49.632715] NDCB2: 0x00000001
[   49.632715] NDCB3: 0x00000000
[   49.651645] nand: nand_do_read_oob: from = 0x0ddc0000, len = 64
[   49.657676] marvell-nfc pxa3xx-nand: 
[   49.657676] NDCR:  0x9d079fff
[   49.657676] NDCB0: 0x000d3000
[   49.657676] NDCB1: 0xbb800000
[   49.657676] NDCB2: 0x00000001
[   49.657676] NDCB3: 0x00000000
[   49.676607] nand: nand_do_read_oob: from = 0x0dde0000, len = 64
[   49.682815] marvell-nfc pxa3xx-nand: 
[   49.682815] NDCR:  0x9d079fff
[   49.682815] NDCB0: 0x000d3000
[   49.682815] NDCB1: 0xbbc00000
[   49.682815] NDCB2: 0x00000001
[   49.682815] NDCB3: 0x00000000
[   49.701742] nand: nand_do_read_oob: from = 0x0de00000, len = 64
[   49.707775] marvell-nfc pxa3xx-nand: 
[   49.707775] NDCR:  0x9d079fff
[   49.707775] NDCB0: 0x000d3000
[   49.707775] NDCB1: 0xbc000000
[   49.707775] NDCB2: 0x00000001
[   49.707775] NDCB3: 0x00000000
[   49.726707] nand: nand_do_read_oob: from = 0x0de20000, len = 64
[   49.732912] marvell-nfc pxa3xx-nand: 
[   49.732912] NDCR:  0x9d079fff
[   49.732912] NDCB0: 0x000d3000
[   49.732912] NDCB1: 0xbc400000
[   49.732912] NDCB2: 0x00000001
[   49.732912] NDCB3: 0x00000000
[   49.751842] nand: nand_do_read_oob: from = 0x0de40000, len = 64
[   49.757873] marvell-nfc pxa3xx-nand: 
[   49.757873] NDCR:  0x9d079fff
[   49.757873] NDCB0: 0x000d3000
[   49.757873] NDCB1: 0xbc800000
[   49.757873] NDCB2: 0x00000001
[   49.757873] NDCB3: 0x00000000
[   49.776811] nand: nand_do_read_oob: from = 0x0de60000, len = 64
[   49.783011] marvell-nfc pxa3xx-nand: 
[   49.783011] NDCR:  0x9d079fff
[   49.783011] NDCB0: 0x000d3000
[   49.783011] NDCB1: 0xbcc00000
[   49.783011] NDCB2: 0x00000001
[   49.783011] NDCB3: 0x00000000
[   49.801941] nand: nand_do_read_oob: from = 0x0de80000, len = 64
[   49.807971] marvell-nfc pxa3xx-nand: 
[   49.807971] NDCR:  0x9d079fff
[   49.807971] NDCB0: 0x000d3000
[   49.807971] NDCB1: 0xbd000000
[   49.807971] NDCB2: 0x00000001
[   49.807971] NDCB3: 0x00000000
[   49.826904] nand: nand_do_read_oob: from = 0x0dea0000, len = 64
[   49.833112] marvell-nfc pxa3xx-nand: 
[   49.833112] NDCR:  0x9d079fff
[   49.833112] NDCB0: 0x000d3000
[   49.833112] NDCB1: 0xbd400000
[   49.833112] NDCB2: 0x00000001
[   49.833112] NDCB3: 0x00000000
[   49.852038] nand: nand_do_read_oob: from = 0x0dec0000, len = 64
[   49.858069] marvell-nfc pxa3xx-nand: 
[   49.858069] NDCR:  0x9d079fff
[   49.858069] NDCB0: 0x000d3000
[   49.858069] NDCB1: 0xbd800000
[   49.858069] NDCB2: 0x00000001
[   49.858069] NDCB3: 0x00000000
[   49.877001] nand: nand_do_read_oob: from = 0x0dee0000, len = 64
[   49.883209] marvell-nfc pxa3xx-nand: 
[   49.883209] NDCR:  0x9d079fff
[   49.883209] NDCB0: 0x000d3000
[   49.883209] NDCB1: 0xbdc00000
[   49.883209] NDCB2: 0x00000001
[   49.883209] NDCB3: 0x00000000
[   49.902136] nand: nand_do_read_oob: from = 0x0df00000, len = 64
[   49.908168] marvell-nfc pxa3xx-nand: 
[   49.908168] NDCR:  0x9d079fff
[   49.908168] NDCB0: 0x000d3000
[   49.908168] NDCB1: 0xbe000000
[   49.908168] NDCB2: 0x00000001
[   49.908168] NDCB3: 0x00000000
[   49.927100] nand: nand_do_read_oob: from = 0x0df20000, len = 64
[   49.933306] marvell-nfc pxa3xx-nand: 
[   49.933306] NDCR:  0x9d079fff
[   49.933306] NDCB0: 0x000d3000
[   49.933306] NDCB1: 0xbe400000
[   49.933306] NDCB2: 0x00000001
[   49.933306] NDCB3: 0x00000000
[   49.952236] nand: nand_do_read_oob: from = 0x0df40000, len = 64
[   49.958267] marvell-nfc pxa3xx-nand: 
[   49.958267] NDCR:  0x9d079fff
[   49.958267] NDCB0: 0x000d3000
[   49.958267] NDCB1: 0xbe800000
[   49.958267] NDCB2: 0x00000001
[   49.958267] NDCB3: 0x00000000
[   49.977199] nand: nand_do_read_oob: from = 0x0df60000, len = 64
[   49.983404] marvell-nfc pxa3xx-nand: 
[   49.983404] NDCR:  0x9d079fff
[   49.983404] NDCB0: 0x000d3000
[   49.983404] NDCB1: 0xbec00000
[   49.983404] NDCB2: 0x00000001
[   49.983404] NDCB3: 0x00000000
[   50.002333] nand: nand_do_read_oob: from = 0x0df80000, len = 64
[   50.008365] marvell-nfc pxa3xx-nand: 
[   50.008365] NDCR:  0x9d079fff
[   50.008365] NDCB0: 0x000d3000
[   50.008365] NDCB1: 0xbf000000
[   50.008365] NDCB2: 0x00000001
[   50.008365] NDCB3: 0x00000000
[   50.027305] nand: nand_do_read_oob: from = 0x0dfa0000, len = 64
[   50.033512] marvell-nfc pxa3xx-nand: 
[   50.033512] NDCR:  0x9d079fff
[   50.033512] NDCB0: 0x000d3000
[   50.033512] NDCB1: 0xbf400000
[   50.033512] NDCB2: 0x00000001
[   50.033512] NDCB3: 0x00000000
[   50.052439] nand: nand_do_read_oob: from = 0x0dfc0000, len = 64
[   50.058472] marvell-nfc pxa3xx-nand: 
[   50.058472] NDCR:  0x9d079fff
[   50.058472] NDCB0: 0x000d3000
[   50.058472] NDCB1: 0xbf800000
[   50.058472] NDCB2: 0x00000001
[   50.058472] NDCB3: 0x00000000
[   50.077402] nand: nand_do_read_oob: from = 0x0dfe0000, len = 64
[   50.083603] marvell-nfc pxa3xx-nand: 
[   50.083603] NDCR:  0x9d079fff
[   50.083603] NDCB0: 0x000d3000
[   50.083603] NDCB1: 0xbfc00000
[   50.083603] NDCB2: 0x00000001
[   50.083603] NDCB3: 0x00000000
[   50.102870] nand: nand_do_read_oob: from = 0x0e000000, len = 64
[   50.109105] marvell-nfc pxa3xx-nand: 
[   50.109105] NDCR:  0x9d079fff
[   50.109105] NDCB0: 0x000d3000
[   50.109105] NDCB1: 0xc0000000
[   50.109105] NDCB2: 0x00000001
[   50.109105] NDCB3: 0x00000000
[   50.128026] nand: nand_do_read_oob: from = 0x0e020000, len = 64
[   50.134225] marvell-nfc pxa3xx-nand: 
[   50.134225] NDCR:  0x9d079fff
[   50.134225] NDCB0: 0x000d3000
[   50.134225] NDCB1: 0xc0400000
[   50.134225] NDCB2: 0x00000001
[   50.134225] NDCB3: 0x00000000
[   50.153157] nand: nand_do_read_oob: from = 0x0e040000, len = 64
[   50.159358] marvell-nfc pxa3xx-nand: 
[   50.159358] NDCR:  0x9d079fff
[   50.159358] NDCB0: 0x000d3000
[   50.159358] NDCB1: 0xc0800000
[   50.159358] NDCB2: 0x00000001
[   50.159358] NDCB3: 0x00000000
[   50.178275] nand: nand_do_read_oob: from = 0x0e060000, len = 64
[   50.184478] marvell-nfc pxa3xx-nand: 
[   50.184478] NDCR:  0x9d079fff
[   50.184478] NDCB0: 0x000d3000
[   50.184478] NDCB1: 0xc0c00000
[   50.184478] NDCB2: 0x00000001
[   50.184478] NDCB3: 0x00000000
[   50.203407] nand: nand_do_read_oob: from = 0x0e080000, len = 64
[   50.209610] marvell-nfc pxa3xx-nand: 
[   50.209610] NDCR:  0x9d079fff
[   50.209610] NDCB0: 0x000d3000
[   50.209610] NDCB1: 0xc1000000
[   50.209610] NDCB2: 0x00000001
[   50.209610] NDCB3: 0x00000000
[   50.228530] nand: nand_do_read_oob: from = 0x0e0a0000, len = 64
[   50.234753] marvell-nfc pxa3xx-nand: 
[   50.234753] NDCR:  0x9d079fff
[   50.234753] NDCB0: 0x000d3000
[   50.234753] NDCB1: 0xc1400000
[   50.234753] NDCB2: 0x00000001
[   50.234753] NDCB3: 0x00000000
[   50.253682] nand: nand_do_read_oob: from = 0x0e0c0000, len = 64
[   50.259880] marvell-nfc pxa3xx-nand: 
[   50.259880] NDCR:  0x9d079fff
[   50.259880] NDCB0: 0x000d3000
[   50.259880] NDCB1: 0xc1800000
[   50.259880] NDCB2: 0x00000001
[   50.259880] NDCB3: 0x00000000
[   50.278879] nand: nand_do_read_oob: from = 0x0e0e0000, len = 64
[   50.284914] marvell-nfc pxa3xx-nand: 
[   50.284914] NDCR:  0x9d079fff
[   50.284914] NDCB0: 0x000d3000
[   50.284914] NDCB1: 0xc1c00000
[   50.284914] NDCB2: 0x00000001
[   50.284914] NDCB3: 0x00000000
[   50.303848] nand: nand_do_read_oob: from = 0x0e100000, len = 64
[   50.310048] marvell-nfc pxa3xx-nand: 
[   50.310048] NDCR:  0x9d079fff
[   50.310048] NDCB0: 0x000d3000
[   50.310048] NDCB1: 0xc2000000
[   50.310048] NDCB2: 0x00000001
[   50.310048] NDCB3: 0x00000000
[   50.329015] nand: nand_do_read_oob: from = 0x0e120000, len = 64
[   50.335042] marvell-nfc pxa3xx-nand: 
[   50.335042] NDCR:  0x9d079fff
[   50.335042] NDCB0: 0x000d3000
[   50.335042] NDCB1: 0xc2400000
[   50.335042] NDCB2: 0x00000001
[   50.335042] NDCB3: 0x00000000
[   50.353979] nand: nand_do_read_oob: from = 0x0e140000, len = 64
[   50.360180] marvell-nfc pxa3xx-nand: 
[   50.360180] NDCR:  0x9d079fff
[   50.360180] NDCB0: 0x000d3000
[   50.360180] NDCB1: 0xc2800000
[   50.360180] NDCB2: 0x00000001
[   50.360180] NDCB3: 0x00000000
[   50.379109] nand: nand_do_read_oob: from = 0x0e160000, len = 64
[   50.385142] marvell-nfc pxa3xx-nand: 
[   50.385142] NDCR:  0x9d079fff
[   50.385142] NDCB0: 0x000d3000
[   50.385142] NDCB1: 0xc2c00000
[   50.385142] NDCB2: 0x00000001
[   50.385142] NDCB3: 0x00000000
[   50.404072] nand: nand_do_read_oob: from = 0x0e180000, len = 64
[   50.410271] marvell-nfc pxa3xx-nand: 
[   50.410271] NDCR:  0x9d079fff
[   50.410271] NDCB0: 0x000d3000
[   50.410271] NDCB1: 0xc3000000
[   50.410271] NDCB2: 0x00000001
[   50.410271] NDCB3: 0x00000000
[   50.429199] nand: nand_do_read_oob: from = 0x0e1a0000, len = 64
[   50.435230] marvell-nfc pxa3xx-nand: 
[   50.435230] NDCR:  0x9d079fff
[   50.435230] NDCB0: 0x000d3000
[   50.435230] NDCB1: 0xc3400000
[   50.435230] NDCB2: 0x00000001
[   50.435230] NDCB3: 0x00000000
[   50.454164] nand: nand_do_read_oob: from = 0x0e1c0000, len = 64
[   50.460370] marvell-nfc pxa3xx-nand: 
[   50.460370] NDCR:  0x9d079fff
[   50.460370] NDCB0: 0x000d3000
[   50.460370] NDCB1: 0xc3800000
[   50.460370] NDCB2: 0x00000001
[   50.460370] NDCB3: 0x00000000
[   50.479300] nand: nand_do_read_oob: from = 0x0e1e0000, len = 64
[   50.485329] marvell-nfc pxa3xx-nand: 
[   50.485329] NDCR:  0x9d079fff
[   50.485329] NDCB0: 0x000d3000
[   50.485329] NDCB1: 0xc3c00000
[   50.485329] NDCB2: 0x00000001
[   50.485329] NDCB3: 0x00000000
[   50.504265] nand: nand_do_read_oob: from = 0x0e200000, len = 64
[   50.510470] marvell-nfc pxa3xx-nand: 
[   50.510470] NDCR:  0x9d079fff
[   50.510470] NDCB0: 0x000d3000
[   50.510470] NDCB1: 0xc4000000
[   50.510470] NDCB2: 0x00000001
[   50.510470] NDCB3: 0x00000000
[   50.529395] nand: nand_do_read_oob: from = 0x0e220000, len = 64
[   50.535427] marvell-nfc pxa3xx-nand: 
[   50.535427] NDCR:  0x9d079fff
[   50.535427] NDCB0: 0x000d3000
[   50.535427] NDCB1: 0xc4400000
[   50.535427] NDCB2: 0x00000001
[   50.535427] NDCB3: 0x00000000
[   50.554363] nand: nand_do_read_oob: from = 0x0e240000, len = 64
[   50.560565] marvell-nfc pxa3xx-nand: 
[   50.560565] NDCR:  0x9d079fff
[   50.560565] NDCB0: 0x000d3000
[   50.560565] NDCB1: 0xc4800000
[   50.560565] NDCB2: 0x00000001
[   50.560565] NDCB3: 0x00000000
[   50.579496] nand: nand_do_read_oob: from = 0x0e260000, len = 64
[   50.585525] marvell-nfc pxa3xx-nand: 
[   50.585525] NDCR:  0x9d079fff
[   50.585525] NDCB0: 0x000d3000
[   50.585525] NDCB1: 0xc4c00000
[   50.585525] NDCB2: 0x00000001
[   50.585525] NDCB3: 0x00000000
[   50.604458] nand: nand_do_read_oob: from = 0x0e280000, len = 64
[   50.610657] marvell-nfc pxa3xx-nand: 
[   50.610657] NDCR:  0x9d079fff
[   50.610657] NDCB0: 0x000d3000
[   50.610657] NDCB1: 0xc5000000
[   50.610657] NDCB2: 0x00000001
[   50.610657] NDCB3: 0x00000000
[   50.629584] nand: nand_do_read_oob: from = 0x0e2a0000, len = 64
[   50.635616] marvell-nfc pxa3xx-nand: 
[   50.635616] NDCR:  0x9d079fff
[   50.635616] NDCB0: 0x000d3000
[   50.635616] NDCB1: 0xc5400000
[   50.635616] NDCB2: 0x00000001
[   50.635616] NDCB3: 0x00000000
[   50.654551] nand: nand_do_read_oob: from = 0x0e2c0000, len = 64
[   50.660752] marvell-nfc pxa3xx-nand: 
[   50.660752] NDCR:  0x9d079fff
[   50.660752] NDCB0: 0x000d3000
[   50.660752] NDCB1: 0xc5800000
[   50.660752] NDCB2: 0x00000001
[   50.660752] NDCB3: 0x00000000
[   50.679685] nand: nand_do_read_oob: from = 0x0e2e0000, len = 64
[   50.685714] marvell-nfc pxa3xx-nand: 
[   50.685714] NDCR:  0x9d079fff
[   50.685714] NDCB0: 0x000d3000
[   50.685714] NDCB1: 0xc5c00000
[   50.685714] NDCB2: 0x00000001
[   50.685714] NDCB3: 0x00000000
[   50.704647] nand: nand_do_read_oob: from = 0x0e300000, len = 64
[   50.710853] marvell-nfc pxa3xx-nand: 
[   50.710853] NDCR:  0x9d079fff
[   50.710853] NDCB0: 0x000d3000
[   50.710853] NDCB1: 0xc6000000
[   50.710853] NDCB2: 0x00000001
[   50.710853] NDCB3: 0x00000000
[   50.729782] nand: nand_do_read_oob: from = 0x0e320000, len = 64
[   50.735814] marvell-nfc pxa3xx-nand: 
[   50.735814] NDCR:  0x9d079fff
[   50.735814] NDCB0: 0x000d3000
[   50.735814] NDCB1: 0xc6400000
[   50.735814] NDCB2: 0x00000001
[   50.735814] NDCB3: 0x00000000
[   50.754747] nand: nand_do_read_oob: from = 0x0e340000, len = 64
[   50.760952] marvell-nfc pxa3xx-nand: 
[   50.760952] NDCR:  0x9d079fff
[   50.760952] NDCB0: 0x000d3000
[   50.760952] NDCB1: 0xc6800000
[   50.760952] NDCB2: 0x00000001
[   50.760952] NDCB3: 0x00000000
[   50.779882] nand: nand_do_read_oob: from = 0x0e360000, len = 64
[   50.785911] marvell-nfc pxa3xx-nand: 
[   50.785911] NDCR:  0x9d079fff
[   50.785911] NDCB0: 0x000d3000
[   50.785911] NDCB1: 0xc6c00000
[   50.785911] NDCB2: 0x00000001
[   50.785911] NDCB3: 0x00000000
[   50.804846] nand: nand_do_read_oob: from = 0x0e380000, len = 64
[   50.811050] marvell-nfc pxa3xx-nand: 
[   50.811050] NDCR:  0x9d079fff
[   50.811050] NDCB0: 0x000d3000
[   50.811050] NDCB1: 0xc7000000
[   50.811050] NDCB2: 0x00000001
[   50.811050] NDCB3: 0x00000000
[   50.829978] nand: nand_do_read_oob: from = 0x0e3a0000, len = 64
[   50.836010] marvell-nfc pxa3xx-nand: 
[   50.836010] NDCR:  0x9d079fff
[   50.836010] NDCB0: 0x000d3000
[   50.836010] NDCB1: 0xc7400000
[   50.836010] NDCB2: 0x00000001
[   50.836010] NDCB3: 0x00000000
[   50.854943] nand: nand_do_read_oob: from = 0x0e3c0000, len = 64
[   50.861166] marvell-nfc pxa3xx-nand: 
[   50.861166] NDCR:  0x9d079fff
[   50.861166] NDCB0: 0x000d3000
[   50.861166] NDCB1: 0xc7800000
[   50.861166] NDCB2: 0x00000001
[   50.861166] NDCB3: 0x00000000
[   50.880096] nand: nand_do_read_oob: from = 0x0e3e0000, len = 64
[   50.886126] marvell-nfc pxa3xx-nand: 
[   50.886126] NDCR:  0x9d079fff
[   50.886126] NDCB0: 0x000d3000
[   50.886126] NDCB1: 0xc7c00000
[   50.886126] NDCB2: 0x00000001
[   50.886126] NDCB3: 0x00000000
[   50.905060] nand: nand_do_read_oob: from = 0x0e400000, len = 64
[   50.911264] marvell-nfc pxa3xx-nand: 
[   50.911264] NDCR:  0x9d079fff
[   50.911264] NDCB0: 0x000d3000
[   50.911264] NDCB1: 0xc8000000
[   50.911264] NDCB2: 0x00000001
[   50.911264] NDCB3: 0x00000000
[   50.930194] nand: nand_do_read_oob: from = 0x0e420000, len = 64
[   50.936224] marvell-nfc pxa3xx-nand: 
[   50.936224] NDCR:  0x9d079fff
[   50.936224] NDCB0: 0x000d3000
[   50.936224] NDCB1: 0xc8400000
[   50.936224] NDCB2: 0x00000001
[   50.936224] NDCB3: 0x00000000
[   50.955157] nand: nand_do_read_oob: from = 0x0e440000, len = 64
[   50.961362] marvell-nfc pxa3xx-nand: 
[   50.961362] NDCR:  0x9d079fff
[   50.961362] NDCB0: 0x000d3000
[   50.961362] NDCB1: 0xc8800000
[   50.961362] NDCB2: 0x00000001
[   50.961362] NDCB3: 0x00000000
[   50.980292] nand: nand_do_read_oob: from = 0x0e460000, len = 64
[   50.986323] marvell-nfc pxa3xx-nand: 
[   50.986323] NDCR:  0x9d079fff
[   50.986323] NDCB0: 0x000d3000
[   50.986323] NDCB1: 0xc8c00000
[   50.986323] NDCB2: 0x00000001
[   50.986323] NDCB3: 0x00000000
[   51.005257] nand: nand_do_read_oob: from = 0x0e480000, len = 64
[   51.011468] marvell-nfc pxa3xx-nand: 
[   51.011468] NDCR:  0x9d079fff
[   51.011468] NDCB0: 0x000d3000
[   51.011468] NDCB1: 0xc9000000
[   51.011468] NDCB2: 0x00000001
[   51.011468] NDCB3: 0x00000000
[   51.030401] nand: nand_do_read_oob: from = 0x0e4a0000, len = 64
[   51.036430] marvell-nfc pxa3xx-nand: 
[   51.036430] NDCR:  0x9d079fff
[   51.036430] NDCB0: 0x000d3000
[   51.036430] NDCB1: 0xc9400000
[   51.036430] NDCB2: 0x00000001
[   51.036430] NDCB3: 0x00000000
[   51.055367] nand: nand_do_read_oob: from = 0x0e4c0000, len = 64
[   51.061570] marvell-nfc pxa3xx-nand: 
[   51.061570] NDCR:  0x9d079fff
[   51.061570] NDCB0: 0x000d3000
[   51.061570] NDCB1: 0xc9800000
[   51.061570] NDCB2: 0x00000001
[   51.061570] NDCB3: 0x00000000
[   51.080498] nand: nand_do_read_oob: from = 0x0e4e0000, len = 64
[   51.086528] marvell-nfc pxa3xx-nand: 
[   51.086528] NDCR:  0x9d079fff
[   51.086528] NDCB0: 0x000d3000
[   51.086528] NDCB1: 0xc9c00000
[   51.086528] NDCB2: 0x00000001
[   51.086528] NDCB3: 0x00000000
[   51.105463] nand: nand_do_read_oob: from = 0x0e500000, len = 64
[   51.111667] marvell-nfc pxa3xx-nand: 
[   51.111667] NDCR:  0x9d079fff
[   51.111667] NDCB0: 0x000d3000
[   51.111667] NDCB1: 0xca000000
[   51.111667] NDCB2: 0x00000001
[   51.111667] NDCB3: 0x00000000
[   51.130596] nand: nand_do_read_oob: from = 0x0e520000, len = 64
[   51.136626] marvell-nfc pxa3xx-nand: 
[   51.136626] NDCR:  0x9d079fff
[   51.136626] NDCB0: 0x000d3000
[   51.136626] NDCB1: 0xca400000
[   51.136626] NDCB2: 0x00000001
[   51.136626] NDCB3: 0x00000000
[   51.155559] nand: nand_do_read_oob: from = 0x0e540000, len = 64
[   51.161765] marvell-nfc pxa3xx-nand: 
[   51.161765] NDCR:  0x9d079fff
[   51.161765] NDCB0: 0x000d3000
[   51.161765] NDCB1: 0xca800000
[   51.161765] NDCB2: 0x00000001
[   51.161765] NDCB3: 0x00000000
[   51.180695] nand: nand_do_read_oob: from = 0x0e560000, len = 64
[   51.186726] marvell-nfc pxa3xx-nand: 
[   51.186726] NDCR:  0x9d079fff
[   51.186726] NDCB0: 0x000d3000
[   51.186726] NDCB1: 0xcac00000
[   51.186726] NDCB2: 0x00000001
[   51.186726] NDCB3: 0x00000000
[   51.205657] nand: nand_do_read_oob: from = 0x0e580000, len = 64
[   51.211865] marvell-nfc pxa3xx-nand: 
[   51.211865] NDCR:  0x9d079fff
[   51.211865] NDCB0: 0x000d3000
[   51.211865] NDCB1: 0xcb000000
[   51.211865] NDCB2: 0x00000001
[   51.211865] NDCB3: 0x00000000
[   51.230792] nand: nand_do_read_oob: from = 0x0e5a0000, len = 64
[   51.236823] marvell-nfc pxa3xx-nand: 
[   51.236823] NDCR:  0x9d079fff
[   51.236823] NDCB0: 0x000d3000
[   51.236823] NDCB1: 0xcb400000
[   51.236823] NDCB2: 0x00000001
[   51.236823] NDCB3: 0x00000000
[   51.255758] nand: nand_do_read_oob: from = 0x0e5c0000, len = 64
[   51.261963] marvell-nfc pxa3xx-nand: 
[   51.261963] NDCR:  0x9d079fff
[   51.261963] NDCB0: 0x000d3000
[   51.261963] NDCB1: 0xcb800000
[   51.261963] NDCB2: 0x00000001
[   51.261963] NDCB3: 0x00000000
[   51.280891] nand: nand_do_read_oob: from = 0x0e5e0000, len = 64
[   51.286921] marvell-nfc pxa3xx-nand: 
[   51.286921] NDCR:  0x9d079fff
[   51.286921] NDCB0: 0x000d3000
[   51.286921] NDCB1: 0xcbc00000
[   51.286921] NDCB2: 0x00000001
[   51.286921] NDCB3: 0x00000000
[   51.305858] nand: nand_do_read_oob: from = 0x0e600000, len = 64
[   51.312061] marvell-nfc pxa3xx-nand: 
[   51.312061] NDCR:  0x9d079fff
[   51.312061] NDCB0: 0x000d3000
[   51.312061] NDCB1: 0xcc000000
[   51.312061] NDCB2: 0x00000001
[   51.312061] NDCB3: 0x00000000
[   51.330992] nand: nand_do_read_oob: from = 0x0e620000, len = 64
[   51.337020] marvell-nfc pxa3xx-nand: 
[   51.337020] NDCR:  0x9d079fff
[   51.337020] NDCB0: 0x000d3000
[   51.337020] NDCB1: 0xcc400000
[   51.337020] NDCB2: 0x00000001
[   51.337020] NDCB3: 0x00000000
[   51.355959] nand: nand_do_read_oob: from = 0x0e640000, len = 64
[   51.362159] marvell-nfc pxa3xx-nand: 
[   51.362159] NDCR:  0x9d079fff
[   51.362159] NDCB0: 0x000d3000
[   51.362159] NDCB1: 0xcc800000
[   51.362159] NDCB2: 0x00000001
[   51.362159] NDCB3: 0x00000000
[   51.381089] nand: nand_do_read_oob: from = 0x0e660000, len = 64
[   51.387120] marvell-nfc pxa3xx-nand: 
[   51.387120] NDCR:  0x9d079fff
[   51.387120] NDCB0: 0x000d3000
[   51.387120] NDCB1: 0xccc00000
[   51.387120] NDCB2: 0x00000001
[   51.387120] NDCB3: 0x00000000
[   51.406052] nand: nand_do_read_oob: from = 0x0e680000, len = 64
[   51.412256] marvell-nfc pxa3xx-nand: 
[   51.412256] NDCR:  0x9d079fff
[   51.412256] NDCB0: 0x000d3000
[   51.412256] NDCB1: 0xcd000000
[   51.412256] NDCB2: 0x00000001
[   51.412256] NDCB3: 0x00000000
[   51.431186] nand: nand_do_read_oob: from = 0x0e6a0000, len = 64
[   51.437219] marvell-nfc pxa3xx-nand: 
[   51.437219] NDCR:  0x9d079fff
[   51.437219] NDCB0: 0x000d3000
[   51.437219] NDCB1: 0xcd400000
[   51.437219] NDCB2: 0x00000001
[   51.437219] NDCB3: 0x00000000
[   51.456155] nand: nand_do_read_oob: from = 0x0e6c0000, len = 64
[   51.462355] marvell-nfc pxa3xx-nand: 
[   51.462355] NDCR:  0x9d079fff
[   51.462355] NDCB0: 0x000d3000
[   51.462355] NDCB1: 0xcd800000
[   51.462355] NDCB2: 0x00000001
[   51.462355] NDCB3: 0x00000000
[   51.481284] nand: nand_do_read_oob: from = 0x0e6e0000, len = 64
[   51.487317] marvell-nfc pxa3xx-nand: 
[   51.487317] NDCR:  0x9d079fff
[   51.487317] NDCB0: 0x000d3000
[   51.487317] NDCB1: 0xcdc00000
[   51.487317] NDCB2: 0x00000001
[   51.487317] NDCB3: 0x00000000
[   51.506269] nand: nand_do_read_oob: from = 0x0e700000, len = 64
[   51.512474] marvell-nfc pxa3xx-nand: 
[   51.512474] NDCR:  0x9d079fff
[   51.512474] NDCB0: 0x000d3000
[   51.512474] NDCB1: 0xce000000
[   51.512474] NDCB2: 0x00000001
[   51.512474] NDCB3: 0x00000000
[   51.531400] nand: nand_do_read_oob: from = 0x0e720000, len = 64
[   51.537433] marvell-nfc pxa3xx-nand: 
[   51.537433] NDCR:  0x9d079fff
[   51.537433] NDCB0: 0x000d3000
[   51.537433] NDCB1: 0xce400000
[   51.537433] NDCB2: 0x00000001
[   51.537433] NDCB3: 0x00000000
[   51.556367] nand: nand_do_read_oob: from = 0x0e740000, len = 64
[   51.562568] marvell-nfc pxa3xx-nand: 
[   51.562568] NDCR:  0x9d079fff
[   51.562568] NDCB0: 0x000d3000
[   51.562568] NDCB1: 0xce800000
[   51.562568] NDCB2: 0x00000001
[   51.562568] NDCB3: 0x00000000
[   51.581499] nand: nand_do_read_oob: from = 0x0e760000, len = 64
[   51.587529] marvell-nfc pxa3xx-nand: 
[   51.587529] NDCR:  0x9d079fff
[   51.587529] NDCB0: 0x000d3000
[   51.587529] NDCB1: 0xcec00000
[   51.587529] NDCB2: 0x00000001
[   51.587529] NDCB3: 0x00000000
[   51.606465] nand: nand_do_read_oob: from = 0x0e780000, len = 64
[   51.612668] marvell-nfc pxa3xx-nand: 
[   51.612668] NDCR:  0x9d079fff
[   51.612668] NDCB0: 0x000d3000
[   51.612668] NDCB1: 0xcf000000
[   51.612668] NDCB2: 0x00000001
[   51.612668] NDCB3: 0x00000000
[   51.631598] nand: nand_do_read_oob: from = 0x0e7a0000, len = 64
[   51.637628] marvell-nfc pxa3xx-nand: 
[   51.637628] NDCR:  0x9d079fff
[   51.637628] NDCB0: 0x000d3000
[   51.637628] NDCB1: 0xcf400000
[   51.637628] NDCB2: 0x00000001
[   51.637628] NDCB3: 0x00000000
[   51.656560] nand: nand_do_read_oob: from = 0x0e7c0000, len = 64
[   51.662759] marvell-nfc pxa3xx-nand: 
[   51.662759] NDCR:  0x9d079fff
[   51.662759] NDCB0: 0x000d3000
[   51.662759] NDCB1: 0xcf800000
[   51.662759] NDCB2: 0x00000001
[   51.662759] NDCB3: 0x00000000
[   51.681686] nand: nand_do_read_oob: from = 0x0e7e0000, len = 64
[   51.687718] marvell-nfc pxa3xx-nand: 
[   51.687718] NDCR:  0x9d079fff
[   51.687718] NDCB0: 0x000d3000
[   51.687718] NDCB1: 0xcfc00000
[   51.687718] NDCB2: 0x00000001
[   51.687718] NDCB3: 0x00000000
[   51.706651] nand: nand_do_read_oob: from = 0x0e800000, len = 64
[   51.712858] marvell-nfc pxa3xx-nand: 
[   51.712858] NDCR:  0x9d079fff
[   51.712858] NDCB0: 0x000d3000
[   51.712858] NDCB1: 0xd0000000
[   51.712858] NDCB2: 0x00000001
[   51.712858] NDCB3: 0x00000000
[   51.731786] nand: nand_do_read_oob: from = 0x0e820000, len = 64
[   51.737817] marvell-nfc pxa3xx-nand: 
[   51.737817] NDCR:  0x9d079fff
[   51.737817] NDCB0: 0x000d3000
[   51.737817] NDCB1: 0xd0400000
[   51.737817] NDCB2: 0x00000001
[   51.737817] NDCB3: 0x00000000
[   51.756749] nand: nand_do_read_oob: from = 0x0e840000, len = 64
[   51.762947] marvell-nfc pxa3xx-nand: 
[   51.762947] NDCR:  0x9d079fff
[   51.762947] NDCB0: 0x000d3000
[   51.762947] NDCB1: 0xd0800000
[   51.762947] NDCB2: 0x00000001
[   51.762947] NDCB3: 0x00000000
[   51.781875] nand: nand_do_read_oob: from = 0x0e860000, len = 64
[   51.787906] marvell-nfc pxa3xx-nand: 
[   51.787906] NDCR:  0x9d079fff
[   51.787906] NDCB0: 0x000d3000
[   51.787906] NDCB1: 0xd0c00000
[   51.787906] NDCB2: 0x00000001
[   51.787906] NDCB3: 0x00000000
[   51.806840] nand: nand_do_read_oob: from = 0x0e880000, len = 64
[   51.813043] marvell-nfc pxa3xx-nand: 
[   51.813043] NDCR:  0x9d079fff
[   51.813043] NDCB0: 0x000d3000
[   51.813043] NDCB1: 0xd1000000
[   51.813043] NDCB2: 0x00000001
[   51.813043] NDCB3: 0x00000000
[   51.831972] nand: nand_do_read_oob: from = 0x0e8a0000, len = 64
[   51.838006] marvell-nfc pxa3xx-nand: 
[   51.838006] NDCR:  0x9d079fff
[   51.838006] NDCB0: 0x000d3000
[   51.838006] NDCB1: 0xd1400000
[   51.838006] NDCB2: 0x00000001
[   51.838006] NDCB3: 0x00000000
[   51.856936] nand: nand_do_read_oob: from = 0x0e8c0000, len = 64
[   51.863135] marvell-nfc pxa3xx-nand: 
[   51.863135] NDCR:  0x9d079fff
[   51.863135] NDCB0: 0x000d3000
[   51.863135] NDCB1: 0xd1800000
[   51.863135] NDCB2: 0x00000001
[   51.863135] NDCB3: 0x00000000
[   51.882062] nand: nand_do_read_oob: from = 0x0e8e0000, len = 64
[   51.888096] marvell-nfc pxa3xx-nand: 
[   51.888096] NDCR:  0x9d079fff
[   51.888096] NDCB0: 0x000d3000
[   51.888096] NDCB1: 0xd1c00000
[   51.888096] NDCB2: 0x00000001
[   51.888096] NDCB3: 0x00000000
[   51.907026] nand: nand_do_read_oob: from = 0x0e900000, len = 64
[   51.913225] marvell-nfc pxa3xx-nand: 
[   51.913225] NDCR:  0x9d079fff
[   51.913225] NDCB0: 0x000d3000
[   51.913225] NDCB1: 0xd2000000
[   51.913225] NDCB2: 0x00000001
[   51.913225] NDCB3: 0x00000000
[   51.932154] nand: nand_do_read_oob: from = 0x0e920000, len = 64
[   51.938185] marvell-nfc pxa3xx-nand: 
[   51.938185] NDCR:  0x9d079fff
[   51.938185] NDCB0: 0x000d3000
[   51.938185] NDCB1: 0xd2400000
[   51.938185] NDCB2: 0x00000001
[   51.938185] NDCB3: 0x00000000
[   51.957117] nand: nand_do_read_oob: from = 0x0e940000, len = 64
[   51.963323] marvell-nfc pxa3xx-nand: 
[   51.963323] NDCR:  0x9d079fff
[   51.963323] NDCB0: 0x000d3000
[   51.963323] NDCB1: 0xd2800000
[   51.963323] NDCB2: 0x00000001
[   51.963323] NDCB3: 0x00000000
[   51.982250] nand: nand_do_read_oob: from = 0x0e960000, len = 64
[   51.988282] marvell-nfc pxa3xx-nand: 
[   51.988282] NDCR:  0x9d079fff
[   51.988282] NDCB0: 0x000d3000
[   51.988282] NDCB1: 0xd2c00000
[   51.988282] NDCB2: 0x00000001
[   51.988282] NDCB3: 0x00000000
[   52.007215] nand: nand_do_read_oob: from = 0x0e980000, len = 64
[   52.013419] marvell-nfc pxa3xx-nand: 
[   52.013419] NDCR:  0x9d079fff
[   52.013419] NDCB0: 0x000d3000
[   52.013419] NDCB1: 0xd3000000
[   52.013419] NDCB2: 0x00000001
[   52.013419] NDCB3: 0x00000000
[   52.032349] nand: nand_do_read_oob: from = 0x0e9a0000, len = 64
[   52.038381] marvell-nfc pxa3xx-nand: 
[   52.038381] NDCR:  0x9d079fff
[   52.038381] NDCB0: 0x000d3000
[   52.038381] NDCB1: 0xd3400000
[   52.038381] NDCB2: 0x00000001
[   52.038381] NDCB3: 0x00000000
[   52.057315] nand: nand_do_read_oob: from = 0x0e9c0000, len = 64
[   52.063519] marvell-nfc pxa3xx-nand: 
[   52.063519] NDCR:  0x9d079fff
[   52.063519] NDCB0: 0x000d3000
[   52.063519] NDCB1: 0xd3800000
[   52.063519] NDCB2: 0x00000001
[   52.063519] NDCB3: 0x00000000
[   52.082449] nand: nand_do_read_oob: from = 0x0e9e0000, len = 64
[   52.088481] marvell-nfc pxa3xx-nand: 
[   52.088481] NDCR:  0x9d079fff
[   52.088481] NDCB0: 0x000d3000
[   52.088481] NDCB1: 0xd3c00000
[   52.088481] NDCB2: 0x00000001
[   52.088481] NDCB3: 0x00000000
[   52.107846] nand: nand_do_read_oob: from = 0x0ea00000, len = 64
[   52.114087] marvell-nfc pxa3xx-nand: 
[   52.114087] NDCR:  0x9d079fff
[   52.114087] NDCB0: 0x000d3000
[   52.114087] NDCB1: 0xd4000000
[   52.114087] NDCB2: 0x00000001
[   52.114087] NDCB3: 0x00000000
[   52.133019] nand: nand_do_read_oob: from = 0x0ea20000, len = 64
[   52.139247] marvell-nfc pxa3xx-nand: 
[   52.139247] NDCR:  0x9d079fff
[   52.139247] NDCB0: 0x000d3000
[   52.139247] NDCB1: 0xd4400000
[   52.139247] NDCB2: 0x00000001
[   52.139247] NDCB3: 0x00000000
[   52.158171] nand: nand_do_read_oob: from = 0x0ea40000, len = 64
[   52.164373] marvell-nfc pxa3xx-nand: 
[   52.164373] NDCR:  0x9d079fff
[   52.164373] NDCB0: 0x000d3000
[   52.164373] NDCB1: 0xd4800000
[   52.164373] NDCB2: 0x00000001
[   52.164373] NDCB3: 0x00000000
[   52.183302] nand: nand_do_read_oob: from = 0x0ea60000, len = 64
[   52.189503] marvell-nfc pxa3xx-nand: 
[   52.189503] NDCR:  0x9d079fff
[   52.189503] NDCB0: 0x000d3000
[   52.189503] NDCB1: 0xd4c00000
[   52.189503] NDCB2: 0x00000001
[   52.189503] NDCB3: 0x00000000
[   52.208421] nand: nand_do_read_oob: from = 0x0ea80000, len = 64
[   52.214626] marvell-nfc pxa3xx-nand: 
[   52.214626] NDCR:  0x9d079fff
[   52.214626] NDCB0: 0x000d3000
[   52.214626] NDCB1: 0xd5000000
[   52.214626] NDCB2: 0x00000001
[   52.214626] NDCB3: 0x00000000
[   52.233553] nand: nand_do_read_oob: from = 0x0eaa0000, len = 64
[   52.239759] marvell-nfc pxa3xx-nand: 
[   52.239759] NDCR:  0x9d079fff
[   52.239759] NDCB0: 0x000d3000
[   52.239759] NDCB1: 0xd5400000
[   52.239759] NDCB2: 0x00000001
[   52.239759] NDCB3: 0x00000000
[   52.258771] nand: nand_do_read_oob: from = 0x0eac0000, len = 64
[   52.264806] marvell-nfc pxa3xx-nand: 
[   52.264806] NDCR:  0x9d079fff
[   52.264806] NDCB0: 0x000d3000
[   52.264806] NDCB1: 0xd5800000
[   52.264806] NDCB2: 0x00000001
[   52.264806] NDCB3: 0x00000000
[   52.283726] nand: nand_do_read_oob: from = 0x0eae0000, len = 64
[   52.289932] marvell-nfc pxa3xx-nand: 
[   52.289932] NDCR:  0x9d079fff
[   52.289932] NDCB0: 0x000d3000
[   52.289932] NDCB1: 0xd5c00000
[   52.289932] NDCB2: 0x00000001
[   52.289932] NDCB3: 0x00000000
[   52.308900] nand: nand_do_read_oob: from = 0x0eb00000, len = 64
[   52.314939] marvell-nfc pxa3xx-nand: 
[   52.314939] NDCR:  0x9d079fff
[   52.314939] NDCB0: 0x000d3000
[   52.314939] NDCB1: 0xd6000000
[   52.314939] NDCB2: 0x00000001
[   52.314939] NDCB3: 0x00000000
[   52.333881] nand: nand_do_read_oob: from = 0x0eb20000, len = 64
[   52.340084] marvell-nfc pxa3xx-nand: 
[   52.340084] NDCR:  0x9d079fff
[   52.340084] NDCB0: 0x000d3000
[   52.340084] NDCB1: 0xd6400000
[   52.340084] NDCB2: 0x00000001
[   52.340084] NDCB3: 0x00000000
[   52.359049] nand: nand_do_read_oob: from = 0x0eb40000, len = 64
[   52.365087] marvell-nfc pxa3xx-nand: 
[   52.365087] NDCR:  0x9d079fff
[   52.365087] NDCB0: 0x000d3000
[   52.365087] NDCB1: 0xd6800000
[   52.365087] NDCB2: 0x00000001
[   52.365087] NDCB3: 0x00000000
[   52.384021] nand: nand_do_read_oob: from = 0x0eb60000, len = 64
[   52.390225] marvell-nfc pxa3xx-nand: 
[   52.390225] NDCR:  0x9d079fff
[   52.390225] NDCB0: 0x000d3000
[   52.390225] NDCB1: 0xd6c00000
[   52.390225] NDCB2: 0x00000001
[   52.390225] NDCB3: 0x00000000
[   52.409151] nand: nand_do_read_oob: from = 0x0eb80000, len = 64
[   52.415185] marvell-nfc pxa3xx-nand: 
[   52.415185] NDCR:  0x9d079fff
[   52.415185] NDCB0: 0x000d3000
[   52.415185] NDCB1: 0xd7000000
[   52.415185] NDCB2: 0x00000001
[   52.415185] NDCB3: 0x00000000
[   52.434116] nand: nand_do_read_oob: from = 0x0eba0000, len = 64
[   52.440325] marvell-nfc pxa3xx-nand: 
[   52.440325] NDCR:  0x9d079fff
[   52.440325] NDCB0: 0x000d3000
[   52.440325] NDCB1: 0xd7400000
[   52.440325] NDCB2: 0x00000001
[   52.440325] NDCB3: 0x00000000
[   52.459252] nand: nand_do_read_oob: from = 0x0ebc0000, len = 64
[   52.465283] marvell-nfc pxa3xx-nand: 
[   52.465283] NDCR:  0x9d079fff
[   52.465283] NDCB0: 0x000d3000
[   52.465283] NDCB1: 0xd7800000
[   52.465283] NDCB2: 0x00000001
[   52.465283] NDCB3: 0x00000000
[   52.484215] nand: nand_do_read_oob: from = 0x0ebe0000, len = 64
[   52.490422] marvell-nfc pxa3xx-nand: 
[   52.490422] NDCR:  0x9d079fff
[   52.490422] NDCB0: 0x000d3000
[   52.490422] NDCB1: 0xd7c00000
[   52.490422] NDCB2: 0x00000001
[   52.490422] NDCB3: 0x00000000
[   52.509349] nand: nand_do_read_oob: from = 0x0ec00000, len = 64
[   52.515381] marvell-nfc pxa3xx-nand: 
[   52.515381] NDCR:  0x9d079fff
[   52.515381] NDCB0: 0x000d3000
[   52.515381] NDCB1: 0xd8000000
[   52.515381] NDCB2: 0x00000001
[   52.515381] NDCB3: 0x00000000
[   52.534312] nand: nand_do_read_oob: from = 0x0ec20000, len = 64
[   52.540512] marvell-nfc pxa3xx-nand: 
[   52.540512] NDCR:  0x9d079fff
[   52.540512] NDCB0: 0x000d3000
[   52.540512] NDCB1: 0xd8400000
[   52.540512] NDCB2: 0x00000001
[   52.540512] NDCB3: 0x00000000
[   52.559436] nand: nand_do_read_oob: from = 0x0ec40000, len = 64
[   52.565472] marvell-nfc pxa3xx-nand: 
[   52.565472] NDCR:  0x9d079fff
[   52.565472] NDCB0: 0x000d3000
[   52.565472] NDCB1: 0xd8800000
[   52.565472] NDCB2: 0x00000001
[   52.565472] NDCB3: 0x00000000
[   52.584403] nand: nand_do_read_oob: from = 0x0ec60000, len = 64
[   52.590602] marvell-nfc pxa3xx-nand: 
[   52.590602] NDCR:  0x9d079fff
[   52.590602] NDCB0: 0x000d3000
[   52.590602] NDCB1: 0xd8c00000
[   52.590602] NDCB2: 0x00000001
[   52.590602] NDCB3: 0x00000000
[   52.609529] nand: nand_do_read_oob: from = 0x0ec80000, len = 64
[   52.615561] marvell-nfc pxa3xx-nand: 
[   52.615561] NDCR:  0x9d079fff
[   52.615561] NDCB0: 0x000d3000
[   52.615561] NDCB1: 0xd9000000
[   52.615561] NDCB2: 0x00000001
[   52.615561] NDCB3: 0x00000000
[   52.634492] nand: nand_do_read_oob: from = 0x0eca0000, len = 64
[   52.640691] marvell-nfc pxa3xx-nand: 
[   52.640691] NDCR:  0x9d079fff
[   52.640691] NDCB0: 0x000d3000
[   52.640691] NDCB1: 0xd9400000
[   52.640691] NDCB2: 0x00000001
[   52.640691] NDCB3: 0x00000000
[   52.659619] nand: nand_do_read_oob: from = 0x0ecc0000, len = 64
[   52.665651] marvell-nfc pxa3xx-nand: 
[   52.665651] NDCR:  0x9d079fff
[   52.665651] NDCB0: 0x000d3000
[   52.665651] NDCB1: 0xd9800000
[   52.665651] NDCB2: 0x00000001
[   52.665651] NDCB3: 0x00000000
[   52.684583] nand: nand_do_read_oob: from = 0x0ece0000, len = 64
[   52.690780] marvell-nfc pxa3xx-nand: 
[   52.690780] NDCR:  0x9d079fff
[   52.690780] NDCB0: 0x000d3000
[   52.690780] NDCB1: 0xd9c00000
[   52.690780] NDCB2: 0x00000001
[   52.690780] NDCB3: 0x00000000
[   52.709708] nand: nand_do_read_oob: from = 0x0ed00000, len = 64
[   52.715741] marvell-nfc pxa3xx-nand: 
[   52.715741] NDCR:  0x9d079fff
[   52.715741] NDCB0: 0x000d3000
[   52.715741] NDCB1: 0xda000000
[   52.715741] NDCB2: 0x00000001
[   52.715741] NDCB3: 0x00000000
[   52.734673] nand: nand_do_read_oob: from = 0x0ed20000, len = 64
[   52.740899] marvell-nfc pxa3xx-nand: 
[   52.740899] NDCR:  0x9d079fff
[   52.740899] NDCB0: 0x000d3000
[   52.740899] NDCB1: 0xda400000
[   52.740899] NDCB2: 0x00000001
[   52.740899] NDCB3: 0x00000000
[   52.759825] nand: nand_do_read_oob: from = 0x0ed40000, len = 64
[   52.765856] marvell-nfc pxa3xx-nand: 
[   52.765856] NDCR:  0x9d079fff
[   52.765856] NDCB0: 0x000d3000
[   52.765856] NDCB1: 0xda800000
[   52.765856] NDCB2: 0x00000001
[   52.765856] NDCB3: 0x00000000
[   52.784787] nand: nand_do_read_oob: from = 0x0ed60000, len = 64
[   52.790987] marvell-nfc pxa3xx-nand: 
[   52.790987] NDCR:  0x9d079fff
[   52.790987] NDCB0: 0x000d3000
[   52.790987] NDCB1: 0xdac00000
[   52.790987] NDCB2: 0x00000001
[   52.790987] NDCB3: 0x00000000
[   52.809915] nand: nand_do_read_oob: from = 0x0ed80000, len = 64
[   52.815947] marvell-nfc pxa3xx-nand: 
[   52.815947] NDCR:  0x9d079fff
[   52.815947] NDCB0: 0x000d3000
[   52.815947] NDCB1: 0xdb000000
[   52.815947] NDCB2: 0x00000001
[   52.815947] NDCB3: 0x00000000
[   52.834878] nand: nand_do_read_oob: from = 0x0eda0000, len = 64
[   52.841087] marvell-nfc pxa3xx-nand: 
[   52.841087] NDCR:  0x9d079fff
[   52.841087] NDCB0: 0x000d3000
[   52.841087] NDCB1: 0xdb400000
[   52.841087] NDCB2: 0x00000001
[   52.841087] NDCB3: 0x00000000
[   52.860012] nand: nand_do_read_oob: from = 0x0edc0000, len = 64
[   52.866045] marvell-nfc pxa3xx-nand: 
[   52.866045] NDCR:  0x9d079fff
[   52.866045] NDCB0: 0x000d3000
[   52.866045] NDCB1: 0xdb800000
[   52.866045] NDCB2: 0x00000001
[   52.866045] NDCB3: 0x00000000
[   52.884976] nand: nand_do_read_oob: from = 0x0ede0000, len = 64
[   52.891184] marvell-nfc pxa3xx-nand: 
[   52.891184] NDCR:  0x9d079fff
[   52.891184] NDCB0: 0x000d3000
[   52.891184] NDCB1: 0xdbc00000
[   52.891184] NDCB2: 0x00000001
[   52.891184] NDCB3: 0x00000000
[   52.910112] nand: nand_do_read_oob: from = 0x0ee00000, len = 64
[   52.916144] marvell-nfc pxa3xx-nand: 
[   52.916144] NDCR:  0x9d079fff
[   52.916144] NDCB0: 0x000d3000
[   52.916144] NDCB1: 0xdc000000
[   52.916144] NDCB2: 0x00000001
[   52.916144] NDCB3: 0x00000000
[   52.935078] nand: nand_do_read_oob: from = 0x0ee20000, len = 64
[   52.941281] marvell-nfc pxa3xx-nand: 
[   52.941281] NDCR:  0x9d079fff
[   52.941281] NDCB0: 0x000d3000
[   52.941281] NDCB1: 0xdc400000
[   52.941281] NDCB2: 0x00000001
[   52.941281] NDCB3: 0x00000000
[   52.960212] nand: nand_do_read_oob: from = 0x0ee40000, len = 64
[   52.966241] marvell-nfc pxa3xx-nand: 
[   52.966241] NDCR:  0x9d079fff
[   52.966241] NDCB0: 0x000d3000
[   52.966241] NDCB1: 0xdc800000
[   52.966241] NDCB2: 0x00000001
[   52.966241] NDCB3: 0x00000000
[   52.985178] nand: nand_do_read_oob: from = 0x0ee60000, len = 64
[   52.991382] marvell-nfc pxa3xx-nand: 
[   52.991382] NDCR:  0x9d079fff
[   52.991382] NDCB0: 0x000d3000
[   52.991382] NDCB1: 0xdcc00000
[   52.991382] NDCB2: 0x00000001
[   52.991382] NDCB3: 0x00000000
[   53.010320] nand: nand_do_read_oob: from = 0x0ee80000, len = 64
[   53.016349] marvell-nfc pxa3xx-nand: 
[   53.016349] NDCR:  0x9d079fff
[   53.016349] NDCB0: 0x000d3000
[   53.016349] NDCB1: 0xdd000000
[   53.016349] NDCB2: 0x00000001
[   53.016349] NDCB3: 0x00000000
[   53.035281] nand: nand_do_read_oob: from = 0x0eea0000, len = 64
[   53.041487] marvell-nfc pxa3xx-nand: 
[   53.041487] NDCR:  0x9d079fff
[   53.041487] NDCB0: 0x000d3000
[   53.041487] NDCB1: 0xdd400000
[   53.041487] NDCB2: 0x00000001
[   53.041487] NDCB3: 0x00000000
[   53.060415] nand: nand_do_read_oob: from = 0x0eec0000, len = 64
[   53.066448] marvell-nfc pxa3xx-nand: 
[   53.066448] NDCR:  0x9d079fff
[   53.066448] NDCB0: 0x000d3000
[   53.066448] NDCB1: 0xdd800000
[   53.066448] NDCB2: 0x00000001
[   53.066448] NDCB3: 0x00000000
[   53.085382] nand: nand_do_read_oob: from = 0x0eee0000, len = 64
[   53.091586] marvell-nfc pxa3xx-nand: 
[   53.091586] NDCR:  0x9d079fff
[   53.091586] NDCB0: 0x000d3000
[   53.091586] NDCB1: 0xddc00000
[   53.091586] NDCB2: 0x00000001
[   53.091586] NDCB3: 0x00000000
[   53.110512] nand: nand_do_read_oob: from = 0x0ef00000, len = 64
[   53.116545] marvell-nfc pxa3xx-nand: 
[   53.116545] NDCR:  0x9d079fff
[   53.116545] NDCB0: 0x000d3000
[   53.116545] NDCB1: 0xde000000
[   53.116545] NDCB2: 0x00000001
[   53.116545] NDCB3: 0x00000000
[   53.135479] nand: nand_do_read_oob: from = 0x0ef20000, len = 64
[   53.141683] marvell-nfc pxa3xx-nand: 
[   53.141683] NDCR:  0x9d079fff
[   53.141683] NDCB0: 0x000d3000
[   53.141683] NDCB1: 0xde400000
[   53.141683] NDCB2: 0x00000001
[   53.141683] NDCB3: 0x00000000
[   53.160614] nand: nand_do_read_oob: from = 0x0ef40000, len = 64
[   53.166645] marvell-nfc pxa3xx-nand: 
[   53.166645] NDCR:  0x9d079fff
[   53.166645] NDCB0: 0x000d3000
[   53.166645] NDCB1: 0xde800000
[   53.166645] NDCB2: 0x00000001
[   53.166645] NDCB3: 0x00000000
[   53.185578] nand: nand_do_read_oob: from = 0x0ef60000, len = 64
[   53.191784] marvell-nfc pxa3xx-nand: 
[   53.191784] NDCR:  0x9d079fff
[   53.191784] NDCB0: 0x000d3000
[   53.191784] NDCB1: 0xdec00000
[   53.191784] NDCB2: 0x00000001
[   53.191784] NDCB3: 0x00000000
[   53.210710] nand: nand_do_read_oob: from = 0x0ef80000, len = 64
[   53.216743] marvell-nfc pxa3xx-nand: 
[   53.216743] NDCR:  0x9d079fff
[   53.216743] NDCB0: 0x000d3000
[   53.216743] NDCB1: 0xdf000000
[   53.216743] NDCB2: 0x00000001
[   53.216743] NDCB3: 0x00000000
[   53.235675] nand: nand_do_read_oob: from = 0x0efa0000, len = 64
[   53.241883] marvell-nfc pxa3xx-nand: 
[   53.241883] NDCR:  0x9d079fff
[   53.241883] NDCB0: 0x000d3000
[   53.241883] NDCB1: 0xdf400000
[   53.241883] NDCB2: 0x00000001
[   53.241883] NDCB3: 0x00000000
[   53.260808] nand: nand_do_read_oob: from = 0x0efc0000, len = 64
[   53.266844] marvell-nfc pxa3xx-nand: 
[   53.266844] NDCR:  0x9d079fff
[   53.266844] NDCB0: 0x000d3000
[   53.266844] NDCB1: 0xdf800000
[   53.266844] NDCB2: 0x00000001
[   53.266844] NDCB3: 0x00000000
[   53.285782] nand: nand_do_read_oob: from = 0x0efe0000, len = 64
[   53.291989] marvell-nfc pxa3xx-nand: 
[   53.291989] NDCR:  0x9d079fff
[   53.291989] NDCB0: 0x000d3000
[   53.291989] NDCB1: 0xdfc00000
[   53.291989] NDCB2: 0x00000001
[   53.291989] NDCB3: 0x00000000
[   53.310918] nand: nand_do_read_oob: from = 0x0f000000, len = 64
[   53.316949] marvell-nfc pxa3xx-nand: 
[   53.316949] NDCR:  0x9d079fff
[   53.316949] NDCB0: 0x000d3000
[   53.316949] NDCB1: 0xe0000000
[   53.316949] NDCB2: 0x00000001
[   53.316949] NDCB3: 0x00000000
[   53.335880] nand: nand_do_read_oob: from = 0x0f020000, len = 64
[   53.342087] marvell-nfc pxa3xx-nand: 
[   53.342087] NDCR:  0x9d079fff
[   53.342087] NDCB0: 0x000d3000
[   53.342087] NDCB1: 0xe0400000
[   53.342087] NDCB2: 0x00000001
[   53.342087] NDCB3: 0x00000000
[   53.361015] nand: nand_do_read_oob: from = 0x0f040000, len = 64
[   53.367047] marvell-nfc pxa3xx-nand: 
[   53.367047] NDCR:  0x9d079fff
[   53.367047] NDCB0: 0x000d3000
[   53.367047] NDCB1: 0xe0800000
[   53.367047] NDCB2: 0x00000001
[   53.367047] NDCB3: 0x00000000
[   53.385996] nand: nand_do_read_oob: from = 0x0f060000, len = 64
[   53.392194] marvell-nfc pxa3xx-nand: 
[   53.392194] NDCR:  0x9d079fff
[   53.392194] NDCB0: 0x000d3000
[   53.392194] NDCB1: 0xe0c00000
[   53.392194] NDCB2: 0x00000001
[   53.392194] NDCB3: 0x00000000
[   53.411122] nand: nand_do_read_oob: from = 0x0f080000, len = 64
[   53.417152] marvell-nfc pxa3xx-nand: 
[   53.417152] NDCR:  0x9d079fff
[   53.417152] NDCB0: 0x000d3000
[   53.417152] NDCB1: 0xe1000000
[   53.417152] NDCB2: 0x00000001
[   53.417152] NDCB3: 0x00000000
[   53.436087] nand: nand_do_read_oob: from = 0x0f0a0000, len = 64
[   53.442294] marvell-nfc pxa3xx-nand: 
[   53.442294] NDCR:  0x9d079fff
[   53.442294] NDCB0: 0x000d3000
[   53.442294] NDCB1: 0xe1400000
[   53.442294] NDCB2: 0x00000001
[   53.442294] NDCB3: 0x00000000
[   53.461220] nand: nand_do_read_oob: from = 0x0f0c0000, len = 64
[   53.467251] marvell-nfc pxa3xx-nand: 
[   53.467251] NDCR:  0x9d079fff
[   53.467251] NDCB0: 0x000d3000
[   53.467251] NDCB1: 0xe1800000
[   53.467251] NDCB2: 0x00000001
[   53.467251] NDCB3: 0x00000000
[   53.486185] nand: nand_do_read_oob: from = 0x0f0e0000, len = 64
[   53.492392] marvell-nfc pxa3xx-nand: 
[   53.492392] NDCR:  0x9d079fff
[   53.492392] NDCB0: 0x000d3000
[   53.492392] NDCB1: 0xe1c00000
[   53.492392] NDCB2: 0x00000001
[   53.492392] NDCB3: 0x00000000
[   53.511318] nand: nand_do_read_oob: from = 0x0f100000, len = 64
[   53.517349] marvell-nfc pxa3xx-nand: 
[   53.517349] NDCR:  0x9d079fff
[   53.517349] NDCB0: 0x000d3000
[   53.517349] NDCB1: 0xe2000000
[   53.517349] NDCB2: 0x00000001
[   53.517349] NDCB3: 0x00000000
[   53.536283] nand: nand_do_read_oob: from = 0x0f120000, len = 64
[   53.542487] marvell-nfc pxa3xx-nand: 
[   53.542487] NDCR:  0x9d079fff
[   53.542487] NDCB0: 0x000d3000
[   53.542487] NDCB1: 0xe2400000
[   53.542487] NDCB2: 0x00000001
[   53.542487] NDCB3: 0x00000000
[   53.561416] nand: nand_do_read_oob: from = 0x0f140000, len = 64
[   53.567448] marvell-nfc pxa3xx-nand: 
[   53.567448] NDCR:  0x9d079fff
[   53.567448] NDCB0: 0x000d3000
[   53.567448] NDCB1: 0xe2800000
[   53.567448] NDCB2: 0x00000001
[   53.567448] NDCB3: 0x00000000
[   53.586382] nand: nand_do_read_oob: from = 0x0f160000, len = 64
[   53.592590] marvell-nfc pxa3xx-nand: 
[   53.592590] NDCR:  0x9d079fff
[   53.592590] NDCB0: 0x000d3000
[   53.592590] NDCB1: 0xe2c00000
[   53.592590] NDCB2: 0x00000001
[   53.592590] NDCB3: 0x00000000
[   53.611520] nand: nand_do_read_oob: from = 0x0f180000, len = 64
[   53.617557] marvell-nfc pxa3xx-nand: 
[   53.617557] NDCR:  0x9d079fff
[   53.617557] NDCB0: 0x000d3000
[   53.617557] NDCB1: 0xe3000000
[   53.617557] NDCB2: 0x00000001
[   53.617557] NDCB3: 0x00000000
[   53.636488] nand: nand_do_read_oob: from = 0x0f1a0000, len = 64
[   53.642692] marvell-nfc pxa3xx-nand: 
[   53.642692] NDCR:  0x9d079fff
[   53.642692] NDCB0: 0x000d3000
[   53.642692] NDCB1: 0xe3400000
[   53.642692] NDCB2: 0x00000001
[   53.642692] NDCB3: 0x00000000
[   53.661621] nand: nand_do_read_oob: from = 0x0f1c0000, len = 64
[   53.667654] marvell-nfc pxa3xx-nand: 
[   53.667654] NDCR:  0x9d079fff
[   53.667654] NDCB0: 0x000d3000
[   53.667654] NDCB1: 0xe3800000
[   53.667654] NDCB2: 0x00000001
[   53.667654] NDCB3: 0x00000000
[   53.686588] nand: nand_do_read_oob: from = 0x0f1e0000, len = 64
[   53.692795] marvell-nfc pxa3xx-nand: 
[   53.692795] NDCR:  0x9d079fff
[   53.692795] NDCB0: 0x000d3000
[   53.692795] NDCB1: 0xe3c00000
[   53.692795] NDCB2: 0x00000001
[   53.692795] NDCB3: 0x00000000
[   53.711723] nand: nand_do_read_oob: from = 0x0f200000, len = 64
[   53.717752] marvell-nfc pxa3xx-nand: 
[   53.717752] NDCR:  0x9d079fff
[   53.717752] NDCB0: 0x000d3000
[   53.717752] NDCB1: 0xe4000000
[   53.717752] NDCB2: 0x00000001
[   53.717752] NDCB3: 0x00000000
[   53.736690] nand: nand_do_read_oob: from = 0x0f220000, len = 64
[   53.742892] marvell-nfc pxa3xx-nand: 
[   53.742892] NDCR:  0x9d079fff
[   53.742892] NDCB0: 0x000d3000
[   53.742892] NDCB1: 0xe4400000
[   53.742892] NDCB2: 0x00000001
[   53.742892] NDCB3: 0x00000000
[   53.761820] nand: nand_do_read_oob: from = 0x0f240000, len = 64
[   53.767851] marvell-nfc pxa3xx-nand: 
[   53.767851] NDCR:  0x9d079fff
[   53.767851] NDCB0: 0x000d3000
[   53.767851] NDCB1: 0xe4800000
[   53.767851] NDCB2: 0x00000001
[   53.767851] NDCB3: 0x00000000
[   53.786788] nand: nand_do_read_oob: from = 0x0f260000, len = 64
[   53.792989] marvell-nfc pxa3xx-nand: 
[   53.792989] NDCR:  0x9d079fff
[   53.792989] NDCB0: 0x000d3000
[   53.792989] NDCB1: 0xe4c00000
[   53.792989] NDCB2: 0x00000001
[   53.792989] NDCB3: 0x00000000
[   53.811919] nand: nand_do_read_oob: from = 0x0f280000, len = 64
[   53.817949] marvell-nfc pxa3xx-nand: 
[   53.817949] NDCR:  0x9d079fff
[   53.817949] NDCB0: 0x000d3000
[   53.817949] NDCB1: 0xe5000000
[   53.817949] NDCB2: 0x00000001
[   53.817949] NDCB3: 0x00000000
[   53.836886] nand: nand_do_read_oob: from = 0x0f2a0000, len = 64
[   53.843088] marvell-nfc pxa3xx-nand: 
[   53.843088] NDCR:  0x9d079fff
[   53.843088] NDCB0: 0x000d3000
[   53.843088] NDCB1: 0xe5400000
[   53.843088] NDCB2: 0x00000001
[   53.843088] NDCB3: 0x00000000
[   53.862019] nand: nand_do_read_oob: from = 0x0f2c0000, len = 64
[   53.868047] marvell-nfc pxa3xx-nand: 
[   53.868047] NDCR:  0x9d079fff
[   53.868047] NDCB0: 0x000d3000
[   53.868047] NDCB1: 0xe5800000
[   53.868047] NDCB2: 0x00000001
[   53.868047] NDCB3: 0x00000000
[   53.886984] nand: nand_do_read_oob: from = 0x0f2e0000, len = 64
[   53.893186] marvell-nfc pxa3xx-nand: 
[   53.893186] NDCR:  0x9d079fff
[   53.893186] NDCB0: 0x000d3000
[   53.893186] NDCB1: 0xe5c00000
[   53.893186] NDCB2: 0x00000001
[   53.893186] NDCB3: 0x00000000
[   53.912115] nand: nand_do_read_oob: from = 0x0f300000, len = 64
[   53.918147] marvell-nfc pxa3xx-nand: 
[   53.918147] NDCR:  0x9d079fff
[   53.918147] NDCB0: 0x000d3000
[   53.918147] NDCB1: 0xe6000000
[   53.918147] NDCB2: 0x00000001
[   53.918147] NDCB3: 0x00000000
[   53.937080] nand: nand_do_read_oob: from = 0x0f320000, len = 64
[   53.943287] marvell-nfc pxa3xx-nand: 
[   53.943287] NDCR:  0x9d079fff
[   53.943287] NDCB0: 0x000d3000
[   53.943287] NDCB1: 0xe6400000
[   53.943287] NDCB2: 0x00000001
[   53.943287] NDCB3: 0x00000000
[   53.962214] nand: nand_do_read_oob: from = 0x0f340000, len = 64
[   53.968244] marvell-nfc pxa3xx-nand: 
[   53.968244] NDCR:  0x9d079fff
[   53.968244] NDCB0: 0x000d3000
[   53.968244] NDCB1: 0xe6800000
[   53.968244] NDCB2: 0x00000001
[   53.968244] NDCB3: 0x00000000
[   53.987179] nand: nand_do_read_oob: from = 0x0f360000, len = 64
[   53.993384] marvell-nfc pxa3xx-nand: 
[   53.993384] NDCR:  0x9d079fff
[   53.993384] NDCB0: 0x000d3000
[   53.993384] NDCB1: 0xe6c00000
[   53.993384] NDCB2: 0x00000001
[   53.993384] NDCB3: 0x00000000
[   54.012322] nand: nand_do_read_oob: from = 0x0f380000, len = 64
[   54.018353] marvell-nfc pxa3xx-nand: 
[   54.018353] NDCR:  0x9d079fff
[   54.018353] NDCB0: 0x000d3000
[   54.018353] NDCB1: 0xe7000000
[   54.018353] NDCB2: 0x00000001
[   54.018353] NDCB3: 0x00000000
[   54.037302] nand: nand_do_read_oob: from = 0x0f3a0000, len = 64
[   54.043507] marvell-nfc pxa3xx-nand: 
[   54.043507] NDCR:  0x9d079fff
[   54.043507] NDCB0: 0x000d3000
[   54.043507] NDCB1: 0xe7400000
[   54.043507] NDCB2: 0x00000001
[   54.043507] NDCB3: 0x00000000
[   54.062437] nand: nand_do_read_oob: from = 0x0f3c0000, len = 64
[   54.068467] marvell-nfc pxa3xx-nand: 
[   54.068467] NDCR:  0x9d079fff
[   54.068467] NDCB0: 0x000d3000
[   54.068467] NDCB1: 0xe7800000
[   54.068467] NDCB2: 0x00000001
[   54.068467] NDCB3: 0x00000000
[   54.087400] nand: nand_do_read_oob: from = 0x0f3e0000, len = 64
[   54.093890] marvell-nfc pxa3xx-nand: 
[   54.093890] NDCR:  0x9d079fff
[   54.093890] NDCB0: 0x000d3000
[   54.093890] NDCB1: 0xe7c00000
[   54.093890] NDCB2: 0x00000001
[   54.093890] NDCB3: 0x00000000
[   54.112895] nand: nand_do_read_oob: from = 0x0f400000, len = 64
[   54.119100] marvell-nfc pxa3xx-nand: 
[   54.119100] NDCR:  0x9d079fff
[   54.119100] NDCB0: 0x000d3000
[   54.119100] NDCB1: 0xe8000000
[   54.119100] NDCB2: 0x00000001
[   54.119100] NDCB3: 0x00000000
[   54.138017] nand: nand_do_read_oob: from = 0x0f420000, len = 64
[   54.144219] marvell-nfc pxa3xx-nand: 
[   54.144219] NDCR:  0x9d079fff
[   54.144219] NDCB0: 0x000d3000
[   54.144219] NDCB1: 0xe8400000
[   54.144219] NDCB2: 0x00000001
[   54.144219] NDCB3: 0x00000000
[   54.163151] nand: nand_do_read_oob: from = 0x0f440000, len = 64
[   54.169352] marvell-nfc pxa3xx-nand: 
[   54.169352] NDCR:  0x9d079fff
[   54.169352] NDCB0: 0x000d3000
[   54.169352] NDCB1: 0xe8800000
[   54.169352] NDCB2: 0x00000001
[   54.169352] NDCB3: 0x00000000
[   54.188273] nand: nand_do_read_oob: from = 0x0f460000, len = 64
[   54.194475] marvell-nfc pxa3xx-nand: 
[   54.194475] NDCR:  0x9d079fff
[   54.194475] NDCB0: 0x000d3000
[   54.194475] NDCB1: 0xe8c00000
[   54.194475] NDCB2: 0x00000001
[   54.194475] NDCB3: 0x00000000
[   54.213406] nand: nand_do_read_oob: from = 0x0f480000, len = 64
[   54.219604] marvell-nfc pxa3xx-nand: 
[   54.219604] NDCR:  0x9d079fff
[   54.219604] NDCB0: 0x000d3000
[   54.219604] NDCB1: 0xe9000000
[   54.219604] NDCB2: 0x00000001
[   54.219604] NDCB3: 0x00000000
[   54.238528] nand: nand_do_read_oob: from = 0x0f4a0000, len = 64
[   54.244729] marvell-nfc pxa3xx-nand: 
[   54.244729] NDCR:  0x9d079fff
[   54.244729] NDCB0: 0x000d3000
[   54.244729] NDCB1: 0xe9400000
[   54.244729] NDCB2: 0x00000001
[   54.244729] NDCB3: 0x00000000
[   54.263659] nand: nand_do_read_oob: from = 0x0f4c0000, len = 64
[   54.269860] marvell-nfc pxa3xx-nand: 
[   54.269860] NDCR:  0x9d079fff
[   54.269860] NDCB0: 0x000d3000
[   54.269860] NDCB1: 0xe9800000
[   54.269860] NDCB2: 0x00000001
[   54.269860] NDCB3: 0x00000000
[   54.288853] nand: nand_do_read_oob: from = 0x0f4e0000, len = 64
[   54.294892] marvell-nfc pxa3xx-nand: 
[   54.294892] NDCR:  0x9d079fff
[   54.294892] NDCB0: 0x000d3000
[   54.294892] NDCB1: 0xe9c00000
[   54.294892] NDCB2: 0x00000001
[   54.294892] NDCB3: 0x00000000
[   54.313824] nand: nand_do_read_oob: from = 0x0f500000, len = 64
[   54.320028] marvell-nfc pxa3xx-nand: 
[   54.320028] NDCR:  0x9d079fff
[   54.320028] NDCB0: 0x000d3000
[   54.320028] NDCB1: 0xea000000
[   54.320028] NDCB2: 0x00000001
[   54.320028] NDCB3: 0x00000000
[   54.338995] nand: nand_do_read_oob: from = 0x0f520000, len = 64
[   54.345031] marvell-nfc pxa3xx-nand: 
[   54.345031] NDCR:  0x9d079fff
[   54.345031] NDCB0: 0x000d3000
[   54.345031] NDCB1: 0xea400000
[   54.345031] NDCB2: 0x00000001
[   54.345031] NDCB3: 0x00000000
[   54.363965] nand: nand_do_read_oob: from = 0x0f540000, len = 64
[   54.370170] marvell-nfc pxa3xx-nand: 
[   54.370170] NDCR:  0x9d079fff
[   54.370170] NDCB0: 0x000d3000
[   54.370170] NDCB1: 0xea800000
[   54.370170] NDCB2: 0x00000001
[   54.370170] NDCB3: 0x00000000
[   54.389098] nand: nand_do_read_oob: from = 0x0f560000, len = 64
[   54.395127] marvell-nfc pxa3xx-nand: 
[   54.395127] NDCR:  0x9d079fff
[   54.395127] NDCB0: 0x000d3000
[   54.395127] NDCB1: 0xeac00000
[   54.395127] NDCB2: 0x00000001
[   54.395127] NDCB3: 0x00000000
[   54.414061] nand: nand_do_read_oob: from = 0x0f580000, len = 64
[   54.420269] marvell-nfc pxa3xx-nand: 
[   54.420269] NDCR:  0x9d079fff
[   54.420269] NDCB0: 0x000d3000
[   54.420269] NDCB1: 0xeb000000
[   54.420269] NDCB2: 0x00000001
[   54.420269] NDCB3: 0x00000000
[   54.439196] nand: nand_do_read_oob: from = 0x0f5a0000, len = 64
[   54.445227] marvell-nfc pxa3xx-nand: 
[   54.445227] NDCR:  0x9d079fff
[   54.445227] NDCB0: 0x000d3000
[   54.445227] NDCB1: 0xeb400000
[   54.445227] NDCB2: 0x00000001
[   54.445227] NDCB3: 0x00000000
[   54.464162] nand: nand_do_read_oob: from = 0x0f5c0000, len = 64
[   54.470366] marvell-nfc pxa3xx-nand: 
[   54.470366] NDCR:  0x9d079fff
[   54.470366] NDCB0: 0x000d3000
[   54.470366] NDCB1: 0xeb800000
[   54.470366] NDCB2: 0x00000001
[   54.470366] NDCB3: 0x00000000
[   54.489294] nand: nand_do_read_oob: from = 0x0f5e0000, len = 64
[   54.495326] marvell-nfc pxa3xx-nand: 
[   54.495326] NDCR:  0x9d079fff
[   54.495326] NDCB0: 0x000d3000
[   54.495326] NDCB1: 0xebc00000
[   54.495326] NDCB2: 0x00000001
[   54.495326] NDCB3: 0x00000000
[   54.514262] nand: nand_do_read_oob: from = 0x0f600000, len = 64
[   54.520463] marvell-nfc pxa3xx-nand: 
[   54.520463] NDCR:  0x9d079fff
[   54.520463] NDCB0: 0x000d3000
[   54.520463] NDCB1: 0xec000000
[   54.520463] NDCB2: 0x00000001
[   54.520463] NDCB3: 0x00000000
[   54.539399] nand: nand_do_read_oob: from = 0x0f620000, len = 64
[   54.545433] marvell-nfc pxa3xx-nand: 
[   54.545433] NDCR:  0x9d079fff
[   54.545433] NDCB0: 0x000d3000
[   54.545433] NDCB1: 0xec400000
[   54.545433] NDCB2: 0x00000001
[   54.545433] NDCB3: 0x00000000
[   54.564367] nand: nand_do_read_oob: from = 0x0f640000, len = 64
[   54.570571] marvell-nfc pxa3xx-nand: 
[   54.570571] NDCR:  0x9d079fff
[   54.570571] NDCB0: 0x000d3000
[   54.570571] NDCB1: 0xec800000
[   54.570571] NDCB2: 0x00000001
[   54.570571] NDCB3: 0x00000000
[   54.589501] nand: nand_do_read_oob: from = 0x0f660000, len = 64
[   54.595532] marvell-nfc pxa3xx-nand: 
[   54.595532] NDCR:  0x9d079fff
[   54.595532] NDCB0: 0x000d3000
[   54.595532] NDCB1: 0xecc00000
[   54.595532] NDCB2: 0x00000001
[   54.595532] NDCB3: 0x00000000
[   54.614466] nand: nand_do_read_oob: from = 0x0f680000, len = 64
[   54.620694] marvell-nfc pxa3xx-nand: 
[   54.620694] NDCR:  0x9d079fff
[   54.620694] NDCB0: 0x000d3000
[   54.620694] NDCB1: 0xed000000
[   54.620694] NDCB2: 0x00000001
[   54.620694] NDCB3: 0x00000000
[   54.639628] nand: nand_do_read_oob: from = 0x0f6a0000, len = 64
[   54.645655] marvell-nfc pxa3xx-nand: 
[   54.645655] NDCR:  0x9d079fff
[   54.645655] NDCB0: 0x000d3000
[   54.645655] NDCB1: 0xed400000
[   54.645655] NDCB2: 0x00000001
[   54.645655] NDCB3: 0x00000000
[   54.664589] nand: nand_do_read_oob: from = 0x0f6c0000, len = 64
[   54.670794] marvell-nfc pxa3xx-nand: 
[   54.670794] NDCR:  0x9d079fff
[   54.670794] NDCB0: 0x000d3000
[   54.670794] NDCB1: 0xed800000
[   54.670794] NDCB2: 0x00000001
[   54.670794] NDCB3: 0x00000000
[   54.689725] nand: nand_do_read_oob: from = 0x0f6e0000, len = 64
[   54.695755] marvell-nfc pxa3xx-nand: 
[   54.695755] NDCR:  0x9d079fff
[   54.695755] NDCB0: 0x000d3000
[   54.695755] NDCB1: 0xedc00000
[   54.695755] NDCB2: 0x00000001
[   54.695755] NDCB3: 0x00000000
[   54.714687] nand: nand_do_read_oob: from = 0x0f700000, len = 64
[   54.720893] marvell-nfc pxa3xx-nand: 
[   54.720893] NDCR:  0x9d079fff
[   54.720893] NDCB0: 0x000d3000
[   54.720893] NDCB1: 0xee000000
[   54.720893] NDCB2: 0x00000001
[   54.720893] NDCB3: 0x00000000
[   54.739822] nand: nand_do_read_oob: from = 0x0f720000, len = 64
[   54.745853] marvell-nfc pxa3xx-nand: 
[   54.745853] NDCR:  0x9d079fff
[   54.745853] NDCB0: 0x000d3000
[   54.745853] NDCB1: 0xee400000
[   54.745853] NDCB2: 0x00000001
[   54.745853] NDCB3: 0x00000000
[   54.764785] nand: nand_do_read_oob: from = 0x0f740000, len = 64
[   54.770992] marvell-nfc pxa3xx-nand: 
[   54.770992] NDCR:  0x9d079fff
[   54.770992] NDCB0: 0x000d3000
[   54.770992] NDCB1: 0xee800000
[   54.770992] NDCB2: 0x00000001
[   54.770992] NDCB3: 0x00000000
[   54.789920] nand: nand_do_read_oob: from = 0x0f760000, len = 64
[   54.795952] marvell-nfc pxa3xx-nand: 
[   54.795952] NDCR:  0x9d079fff
[   54.795952] NDCB0: 0x000d3000
[   54.795952] NDCB1: 0xeec00000
[   54.795952] NDCB2: 0x00000001
[   54.795952] NDCB3: 0x00000000
[   54.814883] nand: nand_do_read_oob: from = 0x0f780000, len = 64
[   54.821090] marvell-nfc pxa3xx-nand: 
[   54.821090] NDCR:  0x9d079fff
[   54.821090] NDCB0: 0x000d3000
[   54.821090] NDCB1: 0xef000000
[   54.821090] NDCB2: 0x00000001
[   54.821090] NDCB3: 0x00000000
[   54.840019] nand: nand_do_read_oob: from = 0x0f7a0000, len = 64
[   54.846049] marvell-nfc pxa3xx-nand: 
[   54.846049] NDCR:  0x9d079fff
[   54.846049] NDCB0: 0x000d3000
[   54.846049] NDCB1: 0xef400000
[   54.846049] NDCB2: 0x00000001
[   54.846049] NDCB3: 0x00000000
[   54.864982] nand: nand_do_read_oob: from = 0x0f7c0000, len = 64
[   54.871190] marvell-nfc pxa3xx-nand: 
[   54.871190] NDCR:  0x9d079fff
[   54.871190] NDCB0: 0x000d3000
[   54.871190] NDCB1: 0xef800000
[   54.871190] NDCB2: 0x00000001
[   54.871190] NDCB3: 0x00000000
[   54.890119] nand: nand_do_read_oob: from = 0x0f7e0000, len = 64
[   54.896150] marvell-nfc pxa3xx-nand: 
[   54.896150] NDCR:  0x9d079fff
[   54.896150] NDCB0: 0x000d3000
[   54.896150] NDCB1: 0xefc00000
[   54.896150] NDCB2: 0x00000001
[   54.896150] NDCB3: 0x00000000
[   54.915080] nand: nand_do_read_oob: from = 0x0f800000, len = 64
[   54.921285] marvell-nfc pxa3xx-nand: 
[   54.921285] NDCR:  0x9d079fff
[   54.921285] NDCB0: 0x000d3000
[   54.921285] NDCB1: 0xf0000000
[   54.921285] NDCB2: 0x00000001
[   54.921285] NDCB3: 0x00000000
[   54.940215] nand: nand_do_read_oob: from = 0x0f820000, len = 64
[   54.946248] marvell-nfc pxa3xx-nand: 
[   54.946248] NDCR:  0x9d079fff
[   54.946248] NDCB0: 0x000d3000
[   54.946248] NDCB1: 0xf0400000
[   54.946248] NDCB2: 0x00000001
[   54.946248] NDCB3: 0x00000000
[   54.965179] nand: nand_do_read_oob: from = 0x0f840000, len = 64
[   54.971385] marvell-nfc pxa3xx-nand: 
[   54.971385] NDCR:  0x9d079fff
[   54.971385] NDCB0: 0x000d3000
[   54.971385] NDCB1: 0xf0800000
[   54.971385] NDCB2: 0x00000001
[   54.971385] NDCB3: 0x00000000
[   54.990312] nand: nand_do_read_oob: from = 0x0f860000, len = 64
[   54.996345] marvell-nfc pxa3xx-nand: 
[   54.996345] NDCR:  0x9d079fff
[   54.996345] NDCB0: 0x000d3000
[   54.996345] NDCB1: 0xf0c00000
[   54.996345] NDCB2: 0x00000001
[   54.996345] NDCB3: 0x00000000
[   55.015287] nand: nand_do_read_oob: from = 0x0f880000, len = 64
[   55.021492] marvell-nfc pxa3xx-nand: 
[   55.021492] NDCR:  0x9d079fff
[   55.021492] NDCB0: 0x000d3000
[   55.021492] NDCB1: 0xf1000000
[   55.021492] NDCB2: 0x00000001
[   55.021492] NDCB3: 0x00000000
[   55.040418] nand: nand_do_read_oob: from = 0x0f8a0000, len = 64
[   55.046452] marvell-nfc pxa3xx-nand: 
[   55.046452] NDCR:  0x9d079fff
[   55.046452] NDCB0: 0x000d3000
[   55.046452] NDCB1: 0xf1400000
[   55.046452] NDCB2: 0x00000001
[   55.046452] NDCB3: 0x00000000
[   55.065384] nand: nand_do_read_oob: from = 0x0f8c0000, len = 64
[   55.071591] marvell-nfc pxa3xx-nand: 
[   55.071591] NDCR:  0x9d079fff
[   55.071591] NDCB0: 0x000d3000
[   55.071591] NDCB1: 0xf1800000
[   55.071591] NDCB2: 0x00000001
[   55.071591] NDCB3: 0x00000000
[   55.090517] nand: nand_do_read_oob: from = 0x0f8e0000, len = 64
[   55.096550] marvell-nfc pxa3xx-nand: 
[   55.096550] NDCR:  0x9d079fff
[   55.096550] NDCB0: 0x000d3000
[   55.096550] NDCB1: 0xf1c00000
[   55.096550] NDCB2: 0x00000001
[   55.096550] NDCB3: 0x00000000
[   55.115481] nand: nand_do_read_oob: from = 0x0f900000, len = 64
[   55.121681] marvell-nfc pxa3xx-nand: 
[   55.121681] NDCR:  0x9d079fff
[   55.121681] NDCB0: 0x000d3000
[   55.121681] NDCB1: 0xf2000000
[   55.121681] NDCB2: 0x00000001
[   55.121681] NDCB3: 0x00000000
[   55.140611] nand: nand_do_read_oob: from = 0x0f920000, len = 64
[   55.146641] marvell-nfc pxa3xx-nand: 
[   55.146641] NDCR:  0x9d079fff
[   55.146641] NDCB0: 0x000d3000
[   55.146641] NDCB1: 0xf2400000
[   55.146641] NDCB2: 0x00000001
[   55.146641] NDCB3: 0x00000000
[   55.165574] nand: nand_do_read_oob: from = 0x0f940000, len = 64
[   55.171777] marvell-nfc pxa3xx-nand: 
[   55.171777] NDCR:  0x9d079fff
[   55.171777] NDCB0: 0x000d3000
[   55.171777] NDCB1: 0xf2800000
[   55.171777] NDCB2: 0x00000001
[   55.171777] NDCB3: 0x00000000
[   55.190706] nand: nand_do_read_oob: from = 0x0f960000, len = 64
[   55.196739] marvell-nfc pxa3xx-nand: 
[   55.196739] NDCR:  0x9d079fff
[   55.196739] NDCB0: 0x000d3000
[   55.196739] NDCB1: 0xf2c00000
[   55.196739] NDCB2: 0x00000001
[   55.196739] NDCB3: 0x00000000
[   55.215671] nand: nand_do_read_oob: from = 0x0f980000, len = 64
[   55.221880] marvell-nfc pxa3xx-nand: 
[   55.221880] NDCR:  0x9d079fff
[   55.221880] NDCB0: 0x000d3000
[   55.221880] NDCB1: 0xf3000000
[   55.221880] NDCB2: 0x00000001
[   55.221880] NDCB3: 0x00000000
[   55.240806] nand: nand_do_read_oob: from = 0x0f9a0000, len = 64
[   55.246839] marvell-nfc pxa3xx-nand: 
[   55.246839] NDCR:  0x9d079fff
[   55.246839] NDCB0: 0x000d3000
[   55.246839] NDCB1: 0xf3400000
[   55.246839] NDCB2: 0x00000001
[   55.246839] NDCB3: 0x00000000
[   55.265786] nand: nand_do_read_oob: from = 0x0f9c0000, len = 64
[   55.271996] marvell-nfc pxa3xx-nand: 
[   55.271996] NDCR:  0x9d079fff
[   55.271996] NDCB0: 0x000d3000
[   55.271996] NDCB1: 0xf3800000
[   55.271996] NDCB2: 0x00000001
[   55.271996] NDCB3: 0x00000000
[   55.290922] nand: nand_do_read_oob: from = 0x0f9e0000, len = 64
[   55.296954] marvell-nfc pxa3xx-nand: 
[   55.296954] NDCR:  0x9d079fff
[   55.296954] NDCB0: 0x000d3000
[   55.296954] NDCB1: 0xf3c00000
[   55.296954] NDCB2: 0x00000001
[   55.296954] NDCB3: 0x00000000
[   55.315886] nand: nand_do_read_oob: from = 0x0fa00000, len = 64
[   55.322092] marvell-nfc pxa3xx-nand: 
[   55.322092] NDCR:  0x9d079fff
[   55.322092] NDCB0: 0x000d3000
[   55.322092] NDCB1: 0xf4000000
[   55.322092] NDCB2: 0x00000001
[   55.322092] NDCB3: 0x00000000
[   55.341022] nand: nand_do_read_oob: from = 0x0fa20000, len = 64
[   55.347051] marvell-nfc pxa3xx-nand: 
[   55.347051] NDCR:  0x9d079fff
[   55.347051] NDCB0: 0x000d3000
[   55.347051] NDCB1: 0xf4400000
[   55.347051] NDCB2: 0x00000001
[   55.347051] NDCB3: 0x00000000
[   55.365986] nand: nand_do_read_oob: from = 0x0fa40000, len = 64
[   55.372192] marvell-nfc pxa3xx-nand: 
[   55.372192] NDCR:  0x9d079fff
[   55.372192] NDCB0: 0x000d3000
[   55.372192] NDCB1: 0xf4800000
[   55.372192] NDCB2: 0x00000001
[   55.372192] NDCB3: 0x00000000
[   55.391120] nand: nand_do_read_oob: from = 0x0fa60000, len = 64
[   55.397152] marvell-nfc pxa3xx-nand: 
[   55.397152] NDCR:  0x9d079fff
[   55.397152] NDCB0: 0x000d3000
[   55.397152] NDCB1: 0xf4c00000
[   55.397152] NDCB2: 0x00000001
[   55.397152] NDCB3: 0x00000000
[   55.416081] nand: nand_do_read_oob: from = 0x0fa80000, len = 64
[   55.422279] marvell-nfc pxa3xx-nand: 
[   55.422279] NDCR:  0x9d079fff
[   55.422279] NDCB0: 0x000d3000
[   55.422279] NDCB1: 0xf5000000
[   55.422279] NDCB2: 0x00000001
[   55.422279] NDCB3: 0x00000000
[   55.441209] nand: nand_do_read_oob: from = 0x0faa0000, len = 64
[   55.447240] marvell-nfc pxa3xx-nand: 
[   55.447240] NDCR:  0x9d079fff
[   55.447240] NDCB0: 0x000d3000
[   55.447240] NDCB1: 0xf5400000
[   55.447240] NDCB2: 0x00000001
[   55.447240] NDCB3: 0x00000000
[   55.466174] nand: nand_do_read_oob: from = 0x0fac0000, len = 64
[   55.472379] marvell-nfc pxa3xx-nand: 
[   55.472379] NDCR:  0x9d079fff
[   55.472379] NDCB0: 0x000d3000
[   55.472379] NDCB1: 0xf5800000
[   55.472379] NDCB2: 0x00000001
[   55.472379] NDCB3: 0x00000000
[   55.491306] nand: nand_do_read_oob: from = 0x0fae0000, len = 64
[   55.497339] marvell-nfc pxa3xx-nand: 
[   55.497339] NDCR:  0x9d079fff
[   55.497339] NDCB0: 0x000d3000
[   55.497339] NDCB1: 0xf5c00000
[   55.497339] NDCB2: 0x00000001
[   55.497339] NDCB3: 0x00000000
[   55.516271] nand: nand_do_read_oob: from = 0x0fb00000, len = 64
[   55.522478] marvell-nfc pxa3xx-nand: 
[   55.522478] NDCR:  0x9d079fff
[   55.522478] NDCB0: 0x000d3000
[   55.522478] NDCB1: 0xf6000000
[   55.522478] NDCB2: 0x00000001
[   55.522478] NDCB3: 0x00000000
[   55.541407] nand: nand_do_read_oob: from = 0x0fb20000, len = 64
[   55.547436] marvell-nfc pxa3xx-nand: 
[   55.547436] NDCR:  0x9d079fff
[   55.547436] NDCB0: 0x000d3000
[   55.547436] NDCB1: 0xf6400000
[   55.547436] NDCB2: 0x00000001
[   55.547436] NDCB3: 0x00000000
[   55.566369] nand: nand_do_read_oob: from = 0x0fb40000, len = 64
[   55.572574] marvell-nfc pxa3xx-nand: 
[   55.572574] NDCR:  0x9d079fff
[   55.572574] NDCB0: 0x000d3000
[   55.572574] NDCB1: 0xf6800000
[   55.572574] NDCB2: 0x00000001
[   55.572574] NDCB3: 0x00000000
[   55.591503] nand: nand_do_read_oob: from = 0x0fb60000, len = 64
[   55.597535] marvell-nfc pxa3xx-nand: 
[   55.597535] NDCR:  0x9d079fff
[   55.597535] NDCB0: 0x000d3000
[   55.597535] NDCB1: 0xf6c00000
[   55.597535] NDCB2: 0x00000001
[   55.597535] NDCB3: 0x00000000
[   55.616468] nand: nand_do_read_oob: from = 0x0fb80000, len = 64
[   55.622672] marvell-nfc pxa3xx-nand: 
[   55.622672] NDCR:  0x9d079fff
[   55.622672] NDCB0: 0x000d3000
[   55.622672] NDCB1: 0xf7000000
[   55.622672] NDCB2: 0x00000001
[   55.622672] NDCB3: 0x00000000
[   55.641603] nand: nand_do_read_oob: from = 0x0fba0000, len = 64
[   55.647634] marvell-nfc pxa3xx-nand: 
[   55.647634] NDCR:  0x9d079fff
[   55.647634] NDCB0: 0x000d3000
[   55.647634] NDCB1: 0xf7400000
[   55.647634] NDCB2: 0x00000001
[   55.647634] NDCB3: 0x00000000
[   55.666565] nand: nand_do_read_oob: from = 0x0fbc0000, len = 64
[   55.672764] marvell-nfc pxa3xx-nand: 
[   55.672764] NDCR:  0x9d079fff
[   55.672764] NDCB0: 0x000d3000
[   55.672764] NDCB1: 0xf7800000
[   55.672764] NDCB2: 0x00000001
[   55.672764] NDCB3: 0x00000000
[   55.691692] nand: nand_do_read_oob: from = 0x0fbe0000, len = 64
[   55.697725] marvell-nfc pxa3xx-nand: 
[   55.697725] NDCR:  0x9d079fff
[   55.697725] NDCB0: 0x000d3000
[   55.697725] NDCB1: 0xf7c00000
[   55.697725] NDCB2: 0x00000001
[   55.697725] NDCB3: 0x00000000
[   55.716656] nand: nand_do_read_oob: from = 0x0fc00000, len = 64
[   55.722862] marvell-nfc pxa3xx-nand: 
[   55.722862] NDCR:  0x9d079fff
[   55.722862] NDCB0: 0x000d3000
[   55.722862] NDCB1: 0xf8000000
[   55.722862] NDCB2: 0x00000001
[   55.722862] NDCB3: 0x00000000
[   55.741788] nand: nand_do_read_oob: from = 0x0fc20000, len = 64
[   55.747822] marvell-nfc pxa3xx-nand: 
[   55.747822] NDCR:  0x9d079fff
[   55.747822] NDCB0: 0x000d3000
[   55.747822] NDCB1: 0xf8400000
[   55.747822] NDCB2: 0x00000001
[   55.747822] NDCB3: 0x00000000
[   55.766756] nand: nand_do_read_oob: from = 0x0fc40000, len = 64
[   55.772959] marvell-nfc pxa3xx-nand: 
[   55.772959] NDCR:  0x9d079fff
[   55.772959] NDCB0: 0x000d3000
[   55.772959] NDCB1: 0xf8800000
[   55.772959] NDCB2: 0x00000001
[   55.772959] NDCB3: 0x00000000
[   55.791889] nand: nand_do_read_oob: from = 0x0fc60000, len = 64
[   55.797920] marvell-nfc pxa3xx-nand: 
[   55.797920] NDCR:  0x9d079fff
[   55.797920] NDCB0: 0x000d3000
[   55.797920] NDCB1: 0xf8c00000
[   55.797920] NDCB2: 0x00000001
[   55.797920] NDCB3: 0x00000000
[   55.816853] nand: nand_do_read_oob: from = 0x0fc80000, len = 64
[   55.823050] marvell-nfc pxa3xx-nand: 
[   55.823050] NDCR:  0x9d079fff
[   55.823050] NDCB0: 0x000d3000
[   55.823050] NDCB1: 0xf9000000
[   55.823050] NDCB2: 0x00000001
[   55.823050] NDCB3: 0x00000000
[   55.841979] nand: nand_do_read_oob: from = 0x0fca0000, len = 64
[   55.848011] marvell-nfc pxa3xx-nand: 
[   55.848011] NDCR:  0x9d079fff
[   55.848011] NDCB0: 0x000d3000
[   55.848011] NDCB1: 0xf9400000
[   55.848011] NDCB2: 0x00000001
[   55.848011] NDCB3: 0x00000000
[   55.866942] nand: nand_do_read_oob: from = 0x0fcc0000, len = 64
[   55.873149] marvell-nfc pxa3xx-nand: 
[   55.873149] NDCR:  0x9d079fff
[   55.873149] NDCB0: 0x000d3000
[   55.873149] NDCB1: 0xf9800000
[   55.873149] NDCB2: 0x00000001
[   55.873149] NDCB3: 0x00000000
[   55.892074] nand: nand_do_read_oob: from = 0x0fce0000, len = 64
[   55.898109] marvell-nfc pxa3xx-nand: 
[   55.898109] NDCR:  0x9d079fff
[   55.898109] NDCB0: 0x000d3000
[   55.898109] NDCB1: 0xf9c00000
[   55.898109] NDCB2: 0x00000001
[   55.898109] NDCB3: 0x00000000
[   55.917056] nand: nand_do_read_oob: from = 0x0fd00000, len = 64
[   55.923256] marvell-nfc pxa3xx-nand: 
[   55.923256] NDCR:  0x9d079fff
[   55.923256] NDCB0: 0x000d3000
[   55.923256] NDCB1: 0xfa000000
[   55.923256] NDCB2: 0x00000001
[   55.923256] NDCB3: 0x00000000
[   55.942182] nand: nand_do_read_oob: from = 0x0fd20000, len = 64
[   55.948215] marvell-nfc pxa3xx-nand: 
[   55.948215] NDCR:  0x9d079fff
[   55.948215] NDCB0: 0x000d3000
[   55.948215] NDCB1: 0xfa400000
[   55.948215] NDCB2: 0x00000001
[   55.948215] NDCB3: 0x00000000
[   55.967147] nand: nand_do_read_oob: from = 0x0fd40000, len = 64
[   55.973353] marvell-nfc pxa3xx-nand: 
[   55.973353] NDCR:  0x9d079fff
[   55.973353] NDCB0: 0x000d3000
[   55.973353] NDCB1: 0xfa800000
[   55.973353] NDCB2: 0x00000001
[   55.973353] NDCB3: 0x00000000
[   55.992284] nand: nand_do_read_oob: from = 0x0fd60000, len = 64
[   55.998314] marvell-nfc pxa3xx-nand: 
[   55.998314] NDCR:  0x9d079fff
[   55.998314] NDCB0: 0x000d3000
[   55.998314] NDCB1: 0xfac00000
[   55.998314] NDCB2: 0x00000001
[   55.998314] NDCB3: 0x00000000
[   56.017256] nand: nand_do_read_oob: from = 0x0fd80000, len = 64
[   56.023463] marvell-nfc pxa3xx-nand: 
[   56.023463] NDCR:  0x9d079fff
[   56.023463] NDCB0: 0x000d3000
[   56.023463] NDCB1: 0xfb000000
[   56.023463] NDCB2: 0x00000001
[   56.023463] NDCB3: 0x00000000
[   56.042390] nand: nand_do_read_oob: from = 0x0fda0000, len = 64
[   56.048422] marvell-nfc pxa3xx-nand: 
[   56.048422] NDCR:  0x9d079fff
[   56.048422] NDCB0: 0x000d3000
[   56.048422] NDCB1: 0xfb400000
[   56.048422] NDCB2: 0x00000001
[   56.048422] NDCB3: 0x00000000
[   56.067354] nand: nand_do_read_oob: from = 0x0fdc0000, len = 64
[   56.073560] marvell-nfc pxa3xx-nand: 
[   56.073560] NDCR:  0x9d079fff
[   56.073560] NDCB0: 0x000d3000
[   56.073560] NDCB1: 0xfb800000
[   56.073560] NDCB2: 0x00000001
[   56.073560] NDCB3: 0x00000000
[   56.092819] nand: nand_do_read_oob: from = 0x0fde0000, len = 64
[   56.099053] marvell-nfc pxa3xx-nand: 
[   56.099053] NDCR:  0x9d079fff
[   56.099053] NDCB0: 0x000d3000
[   56.099053] NDCB1: 0xfbc00000
[   56.099053] NDCB2: 0x00000001
[   56.099053] NDCB3: 0x00000000
[   56.117975] nand: nand_do_read_oob: from = 0x0fe00000, len = 64
[   56.124175] marvell-nfc pxa3xx-nand: 
[   56.124175] NDCR:  0x9d079fff
[   56.124175] NDCB0: 0x000d3000
[   56.124175] NDCB1: 0xfc000000
[   56.124175] NDCB2: 0x00000001
[   56.124175] NDCB3: 0x00000000
[   56.143109] nand: nand_do_read_oob: from = 0x0fe20000, len = 64
[   56.149315] marvell-nfc pxa3xx-nand: 
[   56.149315] NDCR:  0x9d079fff
[   56.149315] NDCB0: 0x000d3000
[   56.149315] NDCB1: 0xfc400000
[   56.149315] NDCB2: 0x00000001
[   56.149315] NDCB3: 0x00000000
[   56.168234] nand: nand_do_read_oob: from = 0x0fe40000, len = 64
[   56.174436] marvell-nfc pxa3xx-nand: 
[   56.174436] NDCR:  0x9d079fff
[   56.174436] NDCB0: 0x000d3000
[   56.174436] NDCB1: 0xfc800000
[   56.174436] NDCB2: 0x00000001
[   56.174436] NDCB3: 0x00000000
[   56.193367] nand: nand_do_read_oob: from = 0x0fe60000, len = 64
[   56.199570] marvell-nfc pxa3xx-nand: 
[   56.199570] NDCR:  0x9d079fff
[   56.199570] NDCB0: 0x000d3000
[   56.199570] NDCB1: 0xfcc00000
[   56.199570] NDCB2: 0x00000001
[   56.199570] NDCB3: 0x00000000
[   56.218489] nand: nand_do_read_oob: from = 0x0fe80000, len = 64
[   56.224691] marvell-nfc pxa3xx-nand: 
[   56.224691] NDCR:  0x9d079fff
[   56.224691] NDCB0: 0x000d3000
[   56.224691] NDCB1: 0xfd000000
[   56.224691] NDCB2: 0x00000001
[   56.224691] NDCB3: 0x00000000
[   56.243619] nand: nand_do_read_oob: from = 0x0fea0000, len = 64
[   56.249822] marvell-nfc pxa3xx-nand: 
[   56.249822] NDCR:  0x9d079fff
[   56.249822] NDCB0: 0x000d3000
[   56.249822] NDCB1: 0xfd400000
[   56.249822] NDCB2: 0x00000001
[   56.249822] NDCB3: 0x00000000
[   56.268942] nand: nand_do_read_oob: from = 0x0fec0000, len = 64
[   56.274987] marvell-nfc pxa3xx-nand: 
[   56.274987] NDCR:  0x9d079fff
[   56.274987] NDCB0: 0x000d3000
[   56.274987] NDCB1: 0xfd800000
[   56.274987] NDCB2: 0x00000001
[   56.274987] NDCB3: 0x00000000
[   56.293934] nand: nand_do_read_oob: from = 0x0fee0000, len = 64
[   56.300135] marvell-nfc pxa3xx-nand: 
[   56.300135] NDCR:  0x9d079fff
[   56.300135] NDCB0: 0x000d3000
[   56.300135] NDCB1: 0xfdc00000
[   56.300135] NDCB2: 0x00000001
[   56.300135] NDCB3: 0x00000000
[   56.319063] nand: nand_do_read_oob: from = 0x0ff00000, len = 64
[   56.325097] marvell-nfc pxa3xx-nand: 
[   56.325097] NDCR:  0x9d079fff
[   56.325097] NDCB0: 0x000d3000
[   56.325097] NDCB1: 0xfe000000
[   56.325097] NDCB2: 0x00000001
[   56.325097] NDCB3: 0x00000000
[   56.344030] nand: nand_do_read_oob: from = 0x0ff20000, len = 64
[   56.350235] marvell-nfc pxa3xx-nand: 
[   56.350235] NDCR:  0x9d079fff
[   56.350235] NDCB0: 0x000d3000
[   56.350235] NDCB1: 0xfe400000
[   56.350235] NDCB2: 0x00000001
[   56.350235] NDCB3: 0x00000000
[   56.369162] nand: nand_do_read_oob: from = 0x0ff40000, len = 64
[   56.375195] marvell-nfc pxa3xx-nand: 
[   56.375195] NDCR:  0x9d079fff
[   56.375195] NDCB0: 0x000d3000
[   56.375195] NDCB1: 0xfe800000
[   56.375195] NDCB2: 0x00000001
[   56.375195] NDCB3: 0x00000000
[   56.394124] nand: nand_do_read_oob: from = 0x0ff60000, len = 64
[   56.400324] marvell-nfc pxa3xx-nand: 
[   56.400324] NDCR:  0x9d079fff
[   56.400324] NDCB0: 0x000d3000
[   56.400324] NDCB1: 0xfec00000
[   56.400324] NDCB2: 0x00000001
[   56.400324] NDCB3: 0x00000000
[   56.419249] nand: nand_do_read_oob: from = 0x0ff80000, len = 64
[   56.425285] marvell-nfc pxa3xx-nand: 
[   56.425285] NDCR:  0x9d079fff
[   56.425285] NDCB0: 0x000d3000
[   56.425285] NDCB1: 0xff000000
[   56.425285] NDCB2: 0x00000001
[   56.425285] NDCB3: 0x00000000
[   56.444217] nand: nand_do_read_oob: from = 0x0ffa0000, len = 64
[   56.450425] marvell-nfc pxa3xx-nand: 
[   56.450425] NDCR:  0x9d079fff
[   56.450425] NDCB0: 0x000d3000
[   56.450425] NDCB1: 0xff400000
[   56.450425] NDCB2: 0x00000001
[   56.450425] NDCB3: 0x00000000
[   56.469354] nand: nand_do_read_oob: from = 0x0ffc0000, len = 64
[   56.475383] marvell-nfc pxa3xx-nand: 
[   56.475383] NDCR:  0x9d079fff
[   56.475383] NDCB0: 0x000d3000
[   56.475383] NDCB1: 0xff800000
[   56.475383] NDCB2: 0x00000001
[   56.475383] NDCB3: 0x00000000
[   56.494314] nand: nand_do_read_oob: from = 0x0ffe0000, len = 64
[   56.500545] marvell-nfc pxa3xx-nand: 
[   56.500545] NDCR:  0x9d079fff
[   56.500545] NDCB0: 0x000d3000
[   56.500545] NDCB1: 0xffc00000
[   56.500545] NDCB2: 0x00000001
[   56.500545] NDCB3: 0x00000000
[   56.519945] nand: nand_erase_nand: start = 0x00000ffe0000, len = 131072
[   56.526615] nand: executing subop:
[   56.530231] nand:     ->CMD      [0x70]
[   56.534117] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.539238] marvell-nfc pxa3xx-nand: 
[   56.539238] NDCR:  0x9d079fff
[   56.539238] NDCB0: 0x00800070
[   56.539238] NDCB1: 0x00000000
[   56.539238] NDCB2: 0x00000000
[   56.539238] NDCB3: 0x00000000
[   56.557893] nand: executing subop:
[   56.561501] nand:     ->CMD      [0x60]
[   56.565396] nand:     ->ADDR     [3 cyc: c0 ff 01]
[   56.570353] nand:     ->CMD      [0xd0]
[   56.574233] nand:     ->WAITRDY  [max 0 ms]
[   56.578516] marvell-nfc pxa3xx-nand: 
[   56.578516] NDCR:  0x9d079fff
[   56.578516] NDCB0: 0x004bd060
[   56.578516] NDCB1: 0x0001ffc0
[   56.578516] NDCB2: 0x00000000
[   56.578516] NDCB3: 0x00000000
[   56.599314] nand: executing subop:
[   56.602787] nand:     ->CMD      [0x70]
[   56.606656] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.611790] marvell-nfc pxa3xx-nand: 
[   56.611790] NDCR:  0x9d079fff
[   56.611790] NDCB0: 0x00800070
[   56.611790] NDCB1: 0x00000000
[   56.611790] NDCB2: 0x00000000
[   56.611790] NDCB3: 0x00000000
[   56.630473] nand: executing subop:
[   56.633929] nand:     ->CMD      [0x70]
[   56.637798] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.642930] marvell-nfc pxa3xx-nand: 
[   56.642930] NDCR:  0x9d079fff
[   56.642930] NDCB0: 0x00800070
[   56.642930] NDCB1: 0x00000000
[   56.642930] NDCB2: 0x00000000
[   56.642930] NDCB3: 0x00000000
[   56.661651] marvell-nfc pxa3xx-nand: 
[   56.661651] NDCR:  0xdd079fff
[   56.661651] NDCB0: 0x002d1080
[   56.661651] NDCB1: 0xffc00000
[   56.661651] NDCB2: 0x00000001
[   56.661651] NDCB3: 0x00000000
[   56.680799] Bad block table written to 0x00000ffe0000, version 0x01
[   56.687602] nand: nand_erase_nand: start = 0x00000ffc0000, len = 131072
[   56.694420] nand: executing subop:
[   56.697873] nand:     ->CMD      [0x70]
[   56.701890] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.706879] marvell-nfc pxa3xx-nand: 
[   56.706879] NDCR:  0x9d079fff
[   56.706879] NDCB0: 0x00800070
[   56.706879] NDCB1: 0x00000000
[   56.706879] NDCB2: 0x00000000
[   56.706879] NDCB3: 0x00000000
[   56.725523] nand: executing subop:
[   56.729130] nand:     ->CMD      [0x60]
[   56.733023] nand:     ->ADDR     [3 cyc: 80 ff 01]
[   56.737835] nand:     ->CMD      [0xd0]
[   56.741847] nand:     ->WAITRDY  [max 0 ms]
[   56.746151] marvell-nfc pxa3xx-nand: 
[   56.746151] NDCR:  0x9d079fff
[   56.746151] NDCB0: 0x004bd060
[   56.746151] NDCB1: 0x0001ff80
[   56.746151] NDCB2: 0x00000000
[   56.746151] NDCB3: 0x00000000
[   56.766897] nand: executing subop:
[   56.770541] nand:     ->CMD      [0x70]
[   56.774425] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.779539] marvell-nfc pxa3xx-nand: 
[   56.779539] NDCR:  0x9d079fff
[   56.779539] NDCB0: 0x00800070
[   56.779539] NDCB1: 0x00000000
[   56.779539] NDCB2: 0x00000000
[   56.779539] NDCB3: 0x00000000
[   56.798212] nand: executing subop:
[   56.801828] nand:     ->CMD      [0x70]
[   56.805715] nand:     ->DATA_IN  [1 B, force 8-bit]
[   56.810823] marvell-nfc pxa3xx-nand: 
[   56.810823] NDCR:  0x9d079fff
[   56.810823] NDCB0: 0x00800070
[   56.810823] NDCB1: 0x00000000
[   56.810823] NDCB2: 0x00000000
[   56.810823] NDCB3: 0x00000000
[   56.829547] marvell-nfc pxa3xx-nand: 
[   56.829547] NDCR:  0xdd079fff
[   56.829547] NDCB0: 0x002d1080
[   56.829547] NDCB1: 0xff800000
[   56.829547] NDCB2: 0x00000001
[   56.829547] NDCB3: 0x00000000
[   56.848813] Bad block table written to 0x00000ffc0000, version 0x01
[   56.855656] 6 cmdlinepart partitions found on MTD device pxa3xx_nand-0
[   56.862511] Creating 6 MTD partitions on "pxa3xx_nand-0":
[   56.867999] 0x000000000000-0x000000020000 : "TIMH"
[   56.876504] 0x000000020000-0x000000040000 : "OBMI"
[   56.885961] 0x000000040000-0x000000100000 : "barebox"
[   56.895779] 0x000000100000-0x000000140000 : "barebox-env"
[   56.905831] 0x000000140000-0x000000d40000 : "kernel"
[   56.916328] 0x000000d40000-0x000003260000 : "root"
[   56.930475] smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico at fluxnic.net>
[   56.983081] smc91x smc91x.0 eth0: SMC91C11xFD (rev 2) at c4867300 IRQ 214
[   56.991231]  DMA c386d710 [nowait]
[   56.994784] smc91x smc91x.0 eth0: Ethernet addr: 00:0e:0c:a7:26:f7
[   57.007426] input: pxa27x-keypad as /devices/platform/pxa27x-keypad/input/input0
[   57.017305] pxa-rtc pxa-rtc: failed to find rtc clock source
[   57.024908] rtc rtc0: invalid alarm value: 0-1-1 0:0:0
[   57.032187] pxa-rtc pxa-rtc: rtc core: registered pxa-rtc as rtc0
[   57.042867] sa1100_wdt: SA1100/PXA2xx Watchdog Timer: timer margin 60 sec
[   57.094773] soc-audio soc-audio: ASoC: machine Zylonite should use snd_soc_register_card()
[   57.118303] wm9713-codec wm9713-codec: Control not supported for path Mic B Source -> [MPB] -> Mic B Pre Amp
[   57.130404] wm9713-codec wm9713-codec: ASoC: no dapm match for Mic B Source --> MPB --> Mic B Pre Amp
[   57.140110] wm9713-codec wm9713-codec: ASoC: Failed to add route Mic B Source -> MPB -> Mic B Pre Amp
[   57.152938] soc-audio soc-audio: wm9713-hifi <-> pxa2xx-ac97 mapping ok
[   57.162041] soc-audio soc-audio: wm9713-aux <-> pxa2xx-ac97-aux mapping ok
[   57.172444] soc-audio soc-audio: wm9713-voice <-> pxa-ssp-dai.2 mapping ok
[   57.181332] wm9713-codec wm9713-codec: ASoC: mux Sidetone Mux has no paths
[   57.220634] NET: Registered protocol family 17
[   57.225651] Key type dns_resolver registered
[   57.231634] XScale iWMMXt coprocessor detected.
[   57.243915] Loading compiled-in X.509 certificates
[   57.265044] ubi0: attaching mtd5
[   57.270836] marvell-nfc pxa3xx-nand: 
[   57.270836] NDCR:  0xdd079fff
[   57.270836] NDCB0: 0x000d3000
[   57.270836] NDCB1: 0x23400000
[   57.270836] NDCB2: 0x00000000
[   57.270836] NDCB3: 0x00000000
[   57.290323] marvell-nfc pxa3xx-nand: 
[   57.290323] NDCR:  0xdd079fff
[   57.290323] NDCB0: 0x000d3000
[   57.290323] NDCB1: 0x23410000
[   57.290323] NDCB2: 0x00000000
[   57.290323] NDCB3: 0x00000000
[   57.309578] marvell-nfc pxa3xx-nand: 
[   57.309578] NDCR:  0x9d079fff
[   57.309578] NDCB0: 0x000d3000
[   57.309578] NDCB1: 0x23410000
[   57.309578] NDCB2: 0x00000000
[   57.309578] NDCB3: 0x00000000
[   57.329455] marvell-nfc pxa3xx-nand: 
[   57.329455] NDCR:  0xdd079fff
[   57.329455] NDCB0: 0x000d3000
[   57.329455] NDCB1: 0x23800000
[   57.329455] NDCB2: 0x00000000
[   57.329455] NDCB3: 0x00000000
[   57.349043] marvell-nfc pxa3xx-nand: 
[   57.349043] NDCR:  0xdd079fff
[   57.349043] NDCB0: 0x000d3000
[   57.349043] NDCB1: 0x23810000
[   57.349043] NDCB2: 0x00000000
[   57.349043] NDCB3: 0x00000000
[   57.368067] marvell-nfc pxa3xx-nand: 
[   57.368067] NDCR:  0x9d079fff
[   57.368067] NDCB0: 0x000d3000
[   57.368067] NDCB1: 0x23810000
[   57.368067] NDCB2: 0x00000000
[   57.368067] NDCB3: 0x00000000
[   57.387203] marvell-nfc pxa3xx-nand: 
[   57.387203] NDCR:  0xdd079fff
[   57.387203] NDCB0: 0x000d3000
[   57.387203] NDCB1: 0x23c00000
[   57.387203] NDCB2: 0x00000000
[   57.387203] NDCB3: 0x00000000
[   57.406286] marvell-nfc pxa3xx-nand: 
[   57.406286] NDCR:  0xdd079fff
[   57.406286] NDCB0: 0x000d3000
[   57.406286] NDCB1: 0x23c10000
[   57.406286] NDCB2: 0x00000000
[   57.406286] NDCB3: 0x00000000
[   57.425279] marvell-nfc pxa3xx-nand: 
[   57.425279] NDCR:  0x9d079fff
[   57.425279] NDCB0: 0x000d3000
[   57.425279] NDCB1: 0x23c10000
[   57.425279] NDCB2: 0x00000000
[   57.425279] NDCB3: 0x00000000
[   57.444404] marvell-nfc pxa3xx-nand: 
[   57.444404] NDCR:  0xdd079fff
[   57.444404] NDCB0: 0x000d3000
[   57.444404] NDCB1: 0x24000000
[   57.444404] NDCB2: 0x00000000
[   57.444404] NDCB3: 0x00000000
[   57.463507] marvell-nfc pxa3xx-nand: 
[   57.463507] NDCR:  0xdd079fff
[   57.463507] NDCB0: 0x000d3000
[   57.463507] NDCB1: 0x24010000
[   57.463507] NDCB2: 0x00000000
[   57.463507] NDCB3: 0x00000000
[   57.482501] marvell-nfc pxa3xx-nand: 
[   57.482501] NDCR:  0x9d079fff
[   57.482501] NDCB0: 0x000d3000
[   57.482501] NDCB1: 0x24010000
[   57.482501] NDCB2: 0x00000000
[   57.482501] NDCB3: 0x00000000
[   57.501614] marvell-nfc pxa3xx-nand: 
[   57.501614] NDCR:  0xdd079fff
[   57.501614] NDCB0: 0x000d3000
[   57.501614] NDCB1: 0x24400000
[   57.501614] NDCB2: 0x00000000
[   57.501614] NDCB3: 0x00000000
[   57.520697] marvell-nfc pxa3xx-nand: 
[   57.520697] NDCR:  0xdd079fff
[   57.520697] NDCB0: 0x000d3000
[   57.520697] NDCB1: 0x24410000
[   57.520697] NDCB2: 0x00000000
[   57.520697] NDCB3: 0x00000000
[   57.539691] marvell-nfc pxa3xx-nand: 
[   57.539691] NDCR:  0x9d079fff
[   57.539691] NDCB0: 0x000d3000
[   57.539691] NDCB1: 0x24410000
[   57.539691] NDCB2: 0x00000000
[   57.539691] NDCB3: 0x00000000
[   57.558900] marvell-nfc pxa3xx-nand: 
[   57.558900] NDCR:  0xdd079fff
[   57.558900] NDCB0: 0x000d3000
[   57.558900] NDCB1: 0x24800000
[   57.558900] NDCB2: 0x00000000
[   57.558900] NDCB3: 0x00000000
[   57.577950] marvell-nfc pxa3xx-nand: 
[   57.577950] NDCR:  0xdd079fff
[   57.577950] NDCB0: 0x000d3000
[   57.577950] NDCB1: 0x24810000
[   57.577950] NDCB2: 0x00000000
[   57.577950] NDCB3: 0x00000000
[   57.596947] marvell-nfc pxa3xx-nand: 
[   57.596947] NDCR:  0x9d079fff
[   57.596947] NDCB0: 0x000d3000
[   57.596947] NDCB1: 0x24810000
[   57.596947] NDCB2: 0x00000000
[   57.596947] NDCB3: 0x00000000
[   57.616060] marvell-nfc pxa3xx-nand: 
[   57.616060] NDCR:  0xdd079fff
[   57.616060] NDCB0: 0x000d3000
[   57.616060] NDCB1: 0x24c00000
[   57.616060] NDCB2: 0x00000000
[   57.616060] NDCB3: 0x00000000
[   57.635131] marvell-nfc pxa3xx-nand: 
[   57.635131] NDCR:  0xdd079fff
[   57.635131] NDCB0: 0x000d3000
[   57.635131] NDCB1: 0x24c10000
[   57.635131] NDCB2: 0x00000000
[   57.635131] NDCB3: 0x00000000
[   57.654125] marvell-nfc pxa3xx-nand: 
[   57.654125] NDCR:  0x9d079fff
[   57.654125] NDCB0: 0x000d3000
[   57.654125] NDCB1: 0x24c10000
[   57.654125] NDCB2: 0x00000000
[   57.654125] NDCB3: 0x00000000
[   57.673242] marvell-nfc pxa3xx-nand: 
[   57.673242] NDCR:  0xdd079fff
[   57.673242] NDCB0: 0x000d3000
[   57.673242] NDCB1: 0x25000000
[   57.673242] NDCB2: 0x00000000
[   57.673242] NDCB3: 0x00000000
[   57.692323] marvell-nfc pxa3xx-nand: 
[   57.692323] NDCR:  0xdd079fff
[   57.692323] NDCB0: 0x000d3000
[   57.692323] NDCB1: 0x25010000
[   57.692323] NDCB2: 0x00000000
[   57.692323] NDCB3: 0x00000000
[   57.711315] marvell-nfc pxa3xx-nand: 
[   57.711315] NDCR:  0x9d079fff
[   57.711315] NDCB0: 0x000d3000
[   57.711315] NDCB1: 0x25010000
[   57.711315] NDCB2: 0x00000000
[   57.711315] NDCB3: 0x00000000
[   57.730429] marvell-nfc pxa3xx-nand: 
[   57.730429] NDCR:  0xdd079fff
[   57.730429] NDCB0: 0x000d3000
[   57.730429] NDCB1: 0x25400000
[   57.730429] NDCB2: 0x00000000
[   57.730429] NDCB3: 0x00000000
[   57.749501] marvell-nfc pxa3xx-nand: 
[   57.749501] NDCR:  0xdd079fff
[   57.749501] NDCB0: 0x000d3000
[   57.749501] NDCB1: 0x25410000
[   57.749501] NDCB2: 0x00000000
[   57.749501] NDCB3: 0x00000000
[   57.768488] marvell-nfc pxa3xx-nand: 
[   57.768488] NDCR:  0x9d079fff
[   57.768488] NDCB0: 0x000d3000
[   57.768488] NDCB1: 0x25410000
[   57.768488] NDCB2: 0x00000000
[   57.768488] NDCB3: 0x00000000
[   57.787603] marvell-nfc pxa3xx-nand: 
[   57.787603] NDCR:  0xdd079fff
[   57.787603] NDCB0: 0x000d3000
[   57.787603] NDCB1: 0x25800000
[   57.787603] NDCB2: 0x00000000
[   57.787603] NDCB3: 0x00000000
[   57.806684] marvell-nfc pxa3xx-nand: 
[   57.806684] NDCR:  0xdd079fff
[   57.806684] NDCB0: 0x000d3000
[   57.806684] NDCB1: 0x25810000
[   57.806684] NDCB2: 0x00000000
[   57.806684] NDCB3: 0x00000000
[   57.825678] marvell-nfc pxa3xx-nand: 
[   57.825678] NDCR:  0x9d079fff
[   57.825678] NDCB0: 0x000d3000
[   57.825678] NDCB1: 0x25810000
[   57.825678] NDCB2: 0x00000000
[   57.825678] NDCB3: 0x00000000
[   57.844790] marvell-nfc pxa3xx-nand: 
[   57.844790] NDCR:  0xdd079fff
[   57.844790] NDCB0: 0x000d3000
[   57.844790] NDCB1: 0x25c00000
[   57.844790] NDCB2: 0x00000000
[   57.844790] NDCB3: 0x00000000
[   57.863867] marvell-nfc pxa3xx-nand: 
[   57.863867] NDCR:  0xdd079fff
[   57.863867] NDCB0: 0x000d3000
[   57.863867] NDCB1: 0x25c10000
[   57.863867] NDCB2: 0x00000000
[   57.863867] NDCB3: 0x00000000
[   57.882866] marvell-nfc pxa3xx-nand: 
[   57.882866] NDCR:  0x9d079fff
[   57.882866] NDCB0: 0x000d3000
[   57.882866] NDCB1: 0x25c10000
[   57.882866] NDCB2: 0x00000000
[   57.882866] NDCB3: 0x00000000
[   57.901978] marvell-nfc pxa3xx-nand: 
[   57.901978] NDCR:  0xdd079fff
[   57.901978] NDCB0: 0x000d3000
[   57.901978] NDCB1: 0x26000000
[   57.901978] NDCB2: 0x00000000
[   57.901978] NDCB3: 0x00000000
[   57.921054] marvell-nfc pxa3xx-nand: 
[   57.921054] NDCR:  0xdd079fff
[   57.921054] NDCB0: 0x000d3000
[   57.921054] NDCB1: 0x26010000
[   57.921054] NDCB2: 0x00000000
[   57.921054] NDCB3: 0x00000000
[   57.940048] marvell-nfc pxa3xx-nand: 
[   57.940048] NDCR:  0x9d079fff
[   57.940048] NDCB0: 0x000d3000
[   57.940048] NDCB1: 0x26010000
[   57.940048] NDCB2: 0x00000000
[   57.940048] NDCB3: 0x00000000
[   57.959212] marvell-nfc pxa3xx-nand: 
[   57.959212] NDCR:  0xdd079fff
[   57.959212] NDCB0: 0x000d3000
[   57.959212] NDCB1: 0x26400000
[   57.959212] NDCB2: 0x00000000
[   57.959212] NDCB3: 0x00000000
[   57.978278] marvell-nfc pxa3xx-nand: 
[   57.978278] NDCR:  0xdd079fff
[   57.978278] NDCB0: 0x000d3000
[   57.978278] NDCB1: 0x26410000
[   57.978278] NDCB2: 0x00000000
[   57.978278] NDCB3: 0x00000000
[   57.997273] marvell-nfc pxa3xx-nand: 
[   57.997273] NDCR:  0x9d079fff
[   57.997273] NDCB0: 0x000d3000
[   57.997273] NDCB1: 0x26410000
[   57.997273] NDCB2: 0x00000000
[   57.997273] NDCB3: 0x00000000
[   58.016401] marvell-nfc pxa3xx-nand: 
[   58.016401] NDCR:  0xdd079fff
[   58.016401] NDCB0: 0x000d3000
[   58.016401] NDCB1: 0x26800000
[   58.016401] NDCB2: 0x00000000
[   58.016401] NDCB3: 0x00000000
[   58.035486] marvell-nfc pxa3xx-nand: 
[   58.035486] NDCR:  0xdd079fff
[   58.035486] NDCB0: 0x000d3000
[   58.035486] NDCB1: 0x26810000
[   58.035486] NDCB2: 0x00000000
[   58.035486] NDCB3: 0x00000000
[   58.054485] marvell-nfc pxa3xx-nand: 
[   58.054485] NDCR:  0x9d079fff
[   58.054485] NDCB0: 0x000d3000
[   58.054485] NDCB1: 0x26810000
[   58.054485] NDCB2: 0x00000000
[   58.054485] NDCB3: 0x00000000
[   58.073619] marvell-nfc pxa3xx-nand: 
[   58.073619] NDCR:  0xdd079fff
[   58.073619] NDCB0: 0x000d3000
[   58.073619] NDCB1: 0x26c00000
[   58.073619] NDCB2: 0x00000000
[   58.073619] NDCB3: 0x00000000
[   58.093171] marvell-nfc pxa3xx-nand: 
[   58.093171] NDCR:  0xdd079fff
[   58.093171] NDCB0: 0x000d3000
[   58.093171] NDCB1: 0x26c10000
[   58.093171] NDCB2: 0x00000000
[   58.093171] NDCB3: 0x00000000
[   58.112203] marvell-nfc pxa3xx-nand: 
[   58.112203] NDCR:  0x9d079fff
[   58.112203] NDCB0: 0x000d3000
[   58.112203] NDCB1: 0x26c10000
[   58.112203] NDCB2: 0x00000000
[   58.112203] NDCB3: 0x00000000
[   58.131344] marvell-nfc pxa3xx-nand: 
[   58.131344] NDCR:  0xdd079fff
[   58.131344] NDCB0: 0x000d3000
[   58.131344] NDCB1: 0x27000000
[   58.131344] NDCB2: 0x00000000
[   58.131344] NDCB3: 0x00000000
[   58.150423] marvell-nfc pxa3xx-nand: 
[   58.150423] NDCR:  0xdd079fff
[   58.150423] NDCB0: 0x000d3000
[   58.150423] NDCB1: 0x27010000
[   58.150423] NDCB2: 0x00000000
[   58.150423] NDCB3: 0x00000000
[   58.169420] marvell-nfc pxa3xx-nand: 
[   58.169420] NDCR:  0x9d079fff
[   58.169420] NDCB0: 0x000d3000
[   58.169420] NDCB1: 0x27010000
[   58.169420] NDCB2: 0x00000000
[   58.169420] NDCB3: 0x00000000
[   58.188528] marvell-nfc pxa3xx-nand: 
[   58.188528] NDCR:  0xdd079fff
[   58.188528] NDCB0: 0x000d3000
[   58.188528] NDCB1: 0x27400000
[   58.188528] NDCB2: 0x00000000
[   58.188528] NDCB3: 0x00000000
[   58.207610] marvell-nfc pxa3xx-nand: 
[   58.207610] NDCR:  0xdd079fff
[   58.207610] NDCB0: 0x000d3000
[   58.207610] NDCB1: 0x27410000
[   58.207610] NDCB2: 0x00000000
[   58.207610] NDCB3: 0x00000000
[   58.226605] marvell-nfc pxa3xx-nand: 
[   58.226605] NDCR:  0x9d079fff
[   58.226605] NDCB0: 0x000d3000
[   58.226605] NDCB1: 0x27410000
[   58.226605] NDCB2: 0x00000000
[   58.226605] NDCB3: 0x00000000
[   58.245752] marvell-nfc pxa3xx-nand: 
[   58.245752] NDCR:  0xdd079fff
[   58.245752] NDCB0: 0x000d3000
[   58.245752] NDCB1: 0x27800000
[   58.245752] NDCB2: 0x00000000
[   58.245752] NDCB3: 0x00000000
[   58.264840] marvell-nfc pxa3xx-nand: 
[   58.264840] NDCR:  0xdd079fff
[   58.264840] NDCB0: 0x000d3000
[   58.264840] NDCB1: 0x27810000
[   58.264840] NDCB2: 0x00000000
[   58.264840] NDCB3: 0x00000000
[   58.283945] marvell-nfc pxa3xx-nand: 
[   58.283945] NDCR:  0xdd079fff
[   58.283945] NDCB0: 0x000d3000
[   58.283945] NDCB1: 0x27c00000
[   58.283945] NDCB2: 0x00000000
[   58.283945] NDCB3: 0x00000000
[   58.303028] marvell-nfc pxa3xx-nand: 
[   58.303028] NDCR:  0xdd079fff
[   58.303028] NDCB0: 0x000d3000
[   58.303028] NDCB1: 0x27c10000
[   58.303028] NDCB2: 0x00000000
[   58.303028] NDCB3: 0x00000000
[   58.322017] marvell-nfc pxa3xx-nand: 
[   58.322017] NDCR:  0x9d079fff
[   58.322017] NDCB0: 0x000d3000
[   58.322017] NDCB1: 0x27c10000
[   58.322017] NDCB2: 0x00000000
[   58.322017] NDCB3: 0x00000000
[   58.341136] marvell-nfc pxa3xx-nand: 
[   58.341136] NDCR:  0xdd079fff
[   58.341136] NDCB0: 0x000d3000
[   58.341136] NDCB1: 0x28000000
[   58.341136] NDCB2: 0x00000000
[   58.341136] NDCB3: 0x00000000
[   58.360217] marvell-nfc pxa3xx-nand: 
[   58.360217] NDCR:  0xdd079fff
[   58.360217] NDCB0: 0x000d3000
[   58.360217] NDCB1: 0x28010000
[   58.360217] NDCB2: 0x00000000
[   58.360217] NDCB3: 0x00000000
[   58.379214] marvell-nfc pxa3xx-nand: 
[   58.379214] NDCR:  0x9d079fff
[   58.379214] NDCB0: 0x000d3000
[   58.379214] NDCB1: 0x28010000
[   58.379214] NDCB2: 0x00000000
[   58.379214] NDCB3: 0x00000000
[   58.398323] marvell-nfc pxa3xx-nand: 
[   58.398323] NDCR:  0xdd079fff
[   58.398323] NDCB0: 0x000d3000
[   58.398323] NDCB1: 0x28400000
[   58.398323] NDCB2: 0x00000000
[   58.398323] NDCB3: 0x00000000
[   58.417403] marvell-nfc pxa3xx-nand: 
[   58.417403] NDCR:  0xdd079fff
[   58.417403] NDCB0: 0x000d3000
[   58.417403] NDCB1: 0x28410000
[   58.417403] NDCB2: 0x00000000
[   58.417403] NDCB3: 0x00000000
[   58.436500] marvell-nfc pxa3xx-nand: 
[   58.436500] NDCR:  0xdd079fff
[   58.436500] NDCB0: 0x000d3000
[   58.436500] NDCB1: 0x28800000
[   58.436500] NDCB2: 0x00000000
[   58.436500] NDCB3: 0x00000000
[   58.455580] marvell-nfc pxa3xx-nand: 
[   58.455580] NDCR:  0xdd079fff
[   58.455580] NDCB0: 0x000d3000
[   58.455580] NDCB1: 0x28810000
[   58.455580] NDCB2: 0x00000000
[   58.455580] NDCB3: 0x00000000
[   58.474568] marvell-nfc pxa3xx-nand: 
[   58.474568] NDCR:  0x9d079fff
[   58.474568] NDCB0: 0x000d3000
[   58.474568] NDCB1: 0x28810000
[   58.474568] NDCB2: 0x00000000
[   58.474568] NDCB3: 0x00000000
[   58.493687] marvell-nfc pxa3xx-nand: 
[   58.493687] NDCR:  0xdd079fff
[   58.493687] NDCB0: 0x000d3000
[   58.493687] NDCB1: 0x28c00000
[   58.493687] NDCB2: 0x00000000
[   58.493687] NDCB3: 0x00000000
[   58.512769] marvell-nfc pxa3xx-nand: 
[   58.512769] NDCR:  0xdd079fff
[   58.512769] NDCB0: 0x000d3000
[   58.512769] NDCB1: 0x28c10000
[   58.512769] NDCB2: 0x00000000
[   58.512769] NDCB3: 0x00000000
[   58.531757] marvell-nfc pxa3xx-nand: 
[   58.531757] NDCR:  0x9d079fff
[   58.531757] NDCB0: 0x000d3000
[   58.531757] NDCB1: 0x28c10000
[   58.531757] NDCB2: 0x00000000
[   58.531757] NDCB3: 0x00000000
[   58.550873] marvell-nfc pxa3xx-nand: 
[   58.550873] NDCR:  0xdd079fff
[   58.550873] NDCB0: 0x000d3000
[   58.550873] NDCB1: 0x29000000
[   58.550873] NDCB2: 0x00000000
[   58.550873] NDCB3: 0x00000000
[   58.569948] marvell-nfc pxa3xx-nand: 
[   58.569948] NDCR:  0xdd079fff
[   58.569948] NDCB0: 0x000d3000
[   58.569948] NDCB1: 0x29010000
[   58.569948] NDCB2: 0x00000000
[   58.569948] NDCB3: 0x00000000
[   58.588930] marvell-nfc pxa3xx-nand: 
[   58.588930] NDCR:  0x9d079fff
[   58.588930] NDCB0: 0x000d3000
[   58.588930] NDCB1: 0x29010000
[   58.588930] NDCB2: 0x00000000
[   58.588930] NDCB3: 0x00000000
[   58.608033] marvell-nfc pxa3xx-nand: 
[   58.608033] NDCR:  0xdd079fff
[   58.608033] NDCB0: 0x000d3000
[   58.608033] NDCB1: 0x29400000
[   58.608033] NDCB2: 0x00000000
[   58.608033] NDCB3: 0x00000000
[   58.627106] marvell-nfc pxa3xx-nand: 
[   58.627106] NDCR:  0xdd079fff
[   58.627106] NDCB0: 0x000d3000
[   58.627106] NDCB1: 0x29410000
[   58.627106] NDCB2: 0x00000000
[   58.627106] NDCB3: 0x00000000
[   58.646099] marvell-nfc pxa3xx-nand: 
[   58.646099] NDCR:  0x9d079fff
[   58.646099] NDCB0: 0x000d3000
[   58.646099] NDCB1: 0x29410000
[   58.646099] NDCB2: 0x00000000
[   58.646099] NDCB3: 0x00000000
[   58.665244] marvell-nfc pxa3xx-nand: 
[   58.665244] NDCR:  0xdd079fff
[   58.665244] NDCB0: 0x000d3000
[   58.665244] NDCB1: 0x29800000
[   58.665244] NDCB2: 0x00000000
[   58.665244] NDCB3: 0x00000000
[   58.684328] marvell-nfc pxa3xx-nand: 
[   58.684328] NDCR:  0xdd079fff
[   58.684328] NDCB0: 0x000d3000
[   58.684328] NDCB1: 0x29810000
[   58.684328] NDCB2: 0x00000000
[   58.684328] NDCB3: 0x00000000
[   58.703327] marvell-nfc pxa3xx-nand: 
[   58.703327] NDCR:  0x9d079fff
[   58.703327] NDCB0: 0x000d3000
[   58.703327] NDCB1: 0x29810000
[   58.703327] NDCB2: 0x00000000
[   58.703327] NDCB3: 0x00000000
[   58.722442] marvell-nfc pxa3xx-nand: 
[   58.722442] NDCR:  0xdd079fff
[   58.722442] NDCB0: 0x000d3000
[   58.722442] NDCB1: 0x29c00000
[   58.722442] NDCB2: 0x00000000
[   58.722442] NDCB3: 0x00000000
[   58.741519] marvell-nfc pxa3xx-nand: 
[   58.741519] NDCR:  0xdd079fff
[   58.741519] NDCB0: 0x000d3000
[   58.741519] NDCB1: 0x29c10000
[   58.741519] NDCB2: 0x00000000
[   58.741519] NDCB3: 0x00000000
[   58.760513] marvell-nfc pxa3xx-nand: 
[   58.760513] NDCR:  0x9d079fff
[   58.760513] NDCB0: 0x000d3000
[   58.760513] NDCB1: 0x29c10000
[   58.760513] NDCB2: 0x00000000
[   58.760513] NDCB3: 0x00000000
[   58.779627] marvell-nfc pxa3xx-nand: 
[   58.779627] NDCR:  0xdd079fff
[   58.779627] NDCB0: 0x000d3000
[   58.779627] NDCB1: 0x2a000000
[   58.779627] NDCB2: 0x00000000
[   58.779627] NDCB3: 0x00000000
[   58.798812] marvell-nfc pxa3xx-nand: 
[   58.798812] NDCR:  0xdd079fff
[   58.798812] NDCB0: 0x000d3000
[   58.798812] NDCB1: 0x2a010000
[   58.798812] NDCB2: 0x00000000
[   58.798812] NDCB3: 0x00000000
[   58.817756] marvell-nfc pxa3xx-nand: 
[   58.817756] NDCR:  0x9d079fff
[   58.817756] NDCB0: 0x000d3000
[   58.817756] NDCB1: 0x2a010000
[   58.817756] NDCB2: 0x00000000
[   58.817756] NDCB3: 0x00000000
[   58.836867] marvell-nfc pxa3xx-nand: 
[   58.836867] NDCR:  0xdd079fff
[   58.836867] NDCB0: 0x000d3000
[   58.836867] NDCB1: 0x2a400000
[   58.836867] NDCB2: 0x00000000
[   58.836867] NDCB3: 0x00000000
[   58.855944] marvell-nfc pxa3xx-nand: 
[   58.855944] NDCR:  0xdd079fff
[   58.855944] NDCB0: 0x000d3000
[   58.855944] NDCB1: 0x2a410000
[   58.855944] NDCB2: 0x00000000
[   58.855944] NDCB3: 0x00000000
[   58.874934] marvell-nfc pxa3xx-nand: 
[   58.874934] NDCR:  0x9d079fff
[   58.874934] NDCB0: 0x000d3000
[   58.874934] NDCB1: 0x2a410000
[   58.874934] NDCB2: 0x00000000
[   58.874934] NDCB3: 0x00000000
[   58.894051] marvell-nfc pxa3xx-nand: 
[   58.894051] NDCR:  0xdd079fff
[   58.894051] NDCB0: 0x000d3000
[   58.894051] NDCB1: 0x2a800000
[   58.894051] NDCB2: 0x00000000
[   58.894051] NDCB3: 0x00000000
[   58.913132] marvell-nfc pxa3xx-nand: 
[   58.913132] NDCR:  0xdd079fff
[   58.913132] NDCB0: 0x000d3000
[   58.913132] NDCB1: 0x2a810000
[   58.913132] NDCB2: 0x00000000
[   58.913132] NDCB3: 0x00000000
[   58.932127] marvell-nfc pxa3xx-nand: 
[   58.932127] NDCR:  0x9d079fff
[   58.932127] NDCB0: 0x000d3000
[   58.932127] NDCB1: 0x2a810000
[   58.932127] NDCB2: 0x00000000
[   58.932127] NDCB3: 0x00000000
[   58.951248] marvell-nfc pxa3xx-nand: 
[   58.951248] NDCR:  0xdd079fff
[   58.951248] NDCB0: 0x000d3000
[   58.951248] NDCB1: 0x2ac00000
[   58.951248] NDCB2: 0x00000000
[   58.951248] NDCB3: 0x00000000
[   58.970320] marvell-nfc pxa3xx-nand: 
[   58.970320] NDCR:  0xdd079fff
[   58.970320] NDCB0: 0x000d3000
[   58.970320] NDCB1: 0x2ac10000
[   58.970320] NDCB2: 0x00000000
[   58.970320] NDCB3: 0x00000000
[   58.989315] marvell-nfc pxa3xx-nand: 
[   58.989315] NDCR:  0x9d079fff
[   58.989315] NDCB0: 0x000d3000
[   58.989315] NDCB1: 0x2ac10000
[   58.989315] NDCB2: 0x00000000
[   58.989315] NDCB3: 0x00000000
[   59.008432] marvell-nfc pxa3xx-nand: 
[   59.008432] NDCR:  0xdd079fff
[   59.008432] NDCB0: 0x000d3000
[   59.008432] NDCB1: 0x2b000000
[   59.008432] NDCB2: 0x00000000
[   59.008432] NDCB3: 0x00000000
[   59.027523] marvell-nfc pxa3xx-nand: 
[   59.027523] NDCR:  0xdd079fff
[   59.027523] NDCB0: 0x000d3000
[   59.027523] NDCB1: 0x2b010000
[   59.027523] NDCB2: 0x00000000
[   59.027523] NDCB3: 0x00000000
[   59.046521] marvell-nfc pxa3xx-nand: 
[   59.046521] NDCR:  0x9d079fff
[   59.046521] NDCB0: 0x000d3000
[   59.046521] NDCB1: 0x2b010000
[   59.046521] NDCB2: 0x00000000
[   59.046521] NDCB3: 0x00000000
[   59.065645] marvell-nfc pxa3xx-nand: 
[   59.065645] NDCR:  0xdd079fff
[   59.065645] NDCB0: 0x000d3000
[   59.065645] NDCB1: 0x2b400000
[   59.065645] NDCB2: 0x00000000
[   59.065645] NDCB3: 0x00000000
[   59.084725] marvell-nfc pxa3xx-nand: 
[   59.084725] NDCR:  0xdd079fff
[   59.084725] NDCB0: 0x000d3000
[   59.084725] NDCB1: 0x2b410000
[   59.084725] NDCB2: 0x00000000
[   59.084725] NDCB3: 0x00000000
[   59.103721] marvell-nfc pxa3xx-nand: 
[   59.103721] NDCR:  0x9d079fff
[   59.103721] NDCB0: 0x000d3000
[   59.103721] NDCB1: 0x2b410000
[   59.103721] NDCB2: 0x00000000
[   59.103721] NDCB3: 0x00000000
[   59.122840] marvell-nfc pxa3xx-nand: 
[   59.122840] NDCR:  0xdd079fff
[   59.122840] NDCB0: 0x000d3000
[   59.122840] NDCB1: 0x2b800000
[   59.122840] NDCB2: 0x00000000
[   59.122840] NDCB3: 0x00000000
[   59.141911] marvell-nfc pxa3xx-nand: 
[   59.141911] NDCR:  0xdd079fff
[   59.141911] NDCB0: 0x000d3000
[   59.141911] NDCB1: 0x2b810000
[   59.141911] NDCB2: 0x00000000
[   59.141911] NDCB3: 0x00000000
[   59.160907] marvell-nfc pxa3xx-nand: 
[   59.160907] NDCR:  0x9d079fff
[   59.160907] NDCB0: 0x000d3000
[   59.160907] NDCB1: 0x2b810000
[   59.160907] NDCB2: 0x00000000
[   59.160907] NDCB3: 0x00000000
[   59.180016] marvell-nfc pxa3xx-nand: 
[   59.180016] NDCR:  0xdd079fff
[   59.180016] NDCB0: 0x000d3000
[   59.180016] NDCB1: 0x2bc00000
[   59.180016] NDCB2: 0x00000000
[   59.180016] NDCB3: 0x00000000
[   59.199131] marvell-nfc pxa3xx-nand: 
[   59.199131] NDCR:  0xdd079fff
[   59.199131] NDCB0: 0x000d3000
[   59.199131] NDCB1: 0x2bc10000
[   59.199131] NDCB2: 0x00000000
[   59.199131] NDCB3: 0x00000000
[   59.218120] marvell-nfc pxa3xx-nand: 
[   59.218120] NDCR:  0x9d079fff
[   59.218120] NDCB0: 0x000d3000
[   59.218120] NDCB1: 0x2bc10000
[   59.218120] NDCB2: 0x00000000
[   59.218120] NDCB3: 0x00000000
[   59.237235] marvell-nfc pxa3xx-nand: 
[   59.237235] NDCR:  0xdd079fff
[   59.237235] NDCB0: 0x000d3000
[   59.237235] NDCB1: 0x2c000000
[   59.237235] NDCB2: 0x00000000
[   59.237235] NDCB3: 0x00000000
[   59.256311] marvell-nfc pxa3xx-nand: 
[   59.256311] NDCR:  0xdd079fff
[   59.256311] NDCB0: 0x000d3000
[   59.256311] NDCB1: 0x2c010000
[   59.256311] NDCB2: 0x00000000
[   59.256311] NDCB3: 0x00000000
[   59.275319] marvell-nfc pxa3xx-nand: 
[   59.275319] NDCR:  0x9d079fff
[   59.275319] NDCB0: 0x000d3000
[   59.275319] NDCB1: 0x2c010000
[   59.275319] NDCB2: 0x00000000
[   59.275319] NDCB3: 0x00000000
[   59.294431] marvell-nfc pxa3xx-nand: 
[   59.294431] NDCR:  0xdd079fff
[   59.294431] NDCB0: 0x000d3000
[   59.294431] NDCB1: 0x2c400000
[   59.294431] NDCB2: 0x00000000
[   59.294431] NDCB3: 0x00000000
[   59.313505] marvell-nfc pxa3xx-nand: 
[   59.313505] NDCR:  0xdd079fff
[   59.313505] NDCB0: 0x000d3000
[   59.313505] NDCB1: 0x2c410000
[   59.313505] NDCB2: 0x00000000
[   59.313505] NDCB3: 0x00000000
[   59.332498] marvell-nfc pxa3xx-nand: 
[   59.332498] NDCR:  0x9d079fff
[   59.332498] NDCB0: 0x000d3000
[   59.332498] NDCB1: 0x2c410000
[   59.332498] NDCB2: 0x00000000
[   59.332498] NDCB3: 0x00000000
[   59.351612] marvell-nfc pxa3xx-nand: 
[   59.351612] NDCR:  0xdd079fff
[   59.351612] NDCB0: 0x000d3000
[   59.351612] NDCB1: 0x2c800000
[   59.351612] NDCB2: 0x00000000
[   59.351612] NDCB3: 0x00000000
[   59.370686] marvell-nfc pxa3xx-nand: 
[   59.370686] NDCR:  0xdd079fff
[   59.370686] NDCB0: 0x000d3000
[   59.370686] NDCB1: 0x2c810000
[   59.370686] NDCB2: 0x00000000
[   59.370686] NDCB3: 0x00000000
[   59.389679] marvell-nfc pxa3xx-nand: 
[   59.389679] NDCR:  0x9d079fff
[   59.389679] NDCB0: 0x000d3000
[   59.389679] NDCB1: 0x2c810000
[   59.389679] NDCB2: 0x00000000
[   59.389679] NDCB3: 0x00000000
[   59.409773] marvell-nfc pxa3xx-nand: 
[   59.409773] NDCR:  0xdd079fff
[   59.409773] NDCB0: 0x000d3000
[   59.409773] NDCB1: 0x50800000
[   59.409773] NDCB2: 0x00000000
[   59.409773] NDCB3: 0x00000000
[   59.429029] marvell-nfc pxa3xx-nand: 
[   59.429029] NDCR:  0xdd079fff
[   59.429029] NDCB0: 0x000d3000
[   59.429029] NDCB1: 0x50810000
[   59.429029] NDCB2: 0x00000000
[   59.429029] NDCB3: 0x00000000
[   59.448042] marvell-nfc pxa3xx-nand: 
[   59.448042] NDCR:  0x9d079fff
[   59.448042] NDCB0: 0x000d3000
[   59.448042] NDCB1: 0x50810000
[   59.448042] NDCB2: 0x00000000
[   59.448042] NDCB3: 0x00000000
[   59.467164] marvell-nfc pxa3xx-nand: 
[   59.467164] NDCR:  0xdd079fff
[   59.467164] NDCB0: 0x000d3000
[   59.467164] NDCB1: 0x50c00000
[   59.467164] NDCB2: 0x00000000
[   59.467164] NDCB3: 0x00000000
[   59.486242] marvell-nfc pxa3xx-nand: 
[   59.486242] NDCR:  0xdd079fff
[   59.486242] NDCB0: 0x000d3000
[   59.486242] NDCB1: 0x50c10000
[   59.486242] NDCB2: 0x00000000
[   59.486242] NDCB3: 0x00000000
[   59.505235] marvell-nfc pxa3xx-nand: 
[   59.505235] NDCR:  0x9d079fff
[   59.505235] NDCB0: 0x000d3000
[   59.505235] NDCB1: 0x50c10000
[   59.505235] NDCB2: 0x00000000
[   59.505235] NDCB3: 0x00000000
[   59.524349] marvell-nfc pxa3xx-nand: 
[   59.524349] NDCR:  0xdd079fff
[   59.524349] NDCB0: 0x000d3000
[   59.524349] NDCB1: 0x51000000
[   59.524349] NDCB2: 0x00000000
[   59.524349] NDCB3: 0x00000000
[   59.543423] marvell-nfc pxa3xx-nand: 
[   59.543423] NDCR:  0xdd079fff
[   59.543423] NDCB0: 0x000d3000
[   59.543423] NDCB1: 0x51010000
[   59.543423] NDCB2: 0x00000000
[   59.543423] NDCB3: 0x00000000
[   59.562418] marvell-nfc pxa3xx-nand: 
[   59.562418] NDCR:  0x9d079fff
[   59.562418] NDCB0: 0x000d3000
[   59.562418] NDCB1: 0x51010000
[   59.562418] NDCB2: 0x00000000
[   59.562418] NDCB3: 0x00000000
[   59.581528] marvell-nfc pxa3xx-nand: 
[   59.581528] NDCR:  0xdd079fff
[   59.581528] NDCB0: 0x000d3000
[   59.581528] NDCB1: 0x51400000
[   59.581528] NDCB2: 0x00000000
[   59.581528] NDCB3: 0x00000000
[   59.600605] marvell-nfc pxa3xx-nand: 
[   59.600605] NDCR:  0xdd079fff
[   59.600605] NDCB0: 0x000d3000
[   59.600605] NDCB1: 0x51410000
[   59.600605] NDCB2: 0x00000000
[   59.600605] NDCB3: 0x00000000
[   59.619598] marvell-nfc pxa3xx-nand: 
[   59.619598] NDCR:  0x9d079fff
[   59.619598] NDCB0: 0x000d3000
[   59.619598] NDCB1: 0x51410000
[   59.619598] NDCB2: 0x00000000
[   59.619598] NDCB3: 0x00000000
[   59.638825] marvell-nfc pxa3xx-nand: 
[   59.638825] NDCR:  0xdd079fff
[   59.638825] NDCB0: 0x000d3000
[   59.638825] NDCB1: 0x51800000
[   59.638825] NDCB2: 0x00000000
[   59.638825] NDCB3: 0x00000000
[   59.657847] marvell-nfc pxa3xx-nand: 
[   59.657847] NDCR:  0xdd079fff
[   59.657847] NDCB0: 0x000d3000
[   59.657847] NDCB1: 0x51810000
[   59.657847] NDCB2: 0x00000000
[   59.657847] NDCB3: 0x00000000
[   59.676840] marvell-nfc pxa3xx-nand: 
[   59.676840] NDCR:  0x9d079fff
[   59.676840] NDCB0: 0x000d3000
[   59.676840] NDCB1: 0x51810000
[   59.676840] NDCB2: 0x00000000
[   59.676840] NDCB3: 0x00000000
[   59.695956] marvell-nfc pxa3xx-nand: 
[   59.695956] NDCR:  0xdd079fff
[   59.695956] NDCB0: 0x000d3000
[   59.695956] NDCB1: 0x51c00000
[   59.695956] NDCB2: 0x00000000
[   59.695956] NDCB3: 0x00000000
[   59.715039] marvell-nfc pxa3xx-nand: 
[   59.715039] NDCR:  0xdd079fff
[   59.715039] NDCB0: 0x000d3000
[   59.715039] NDCB1: 0x51c10000
[   59.715039] NDCB2: 0x00000000
[   59.715039] NDCB3: 0x00000000
[   59.734038] marvell-nfc pxa3xx-nand: 
[   59.734038] NDCR:  0x9d079fff
[   59.734038] NDCB0: 0x000d3000
[   59.734038] NDCB1: 0x51c10000
[   59.734038] NDCB2: 0x00000000
[   59.734038] NDCB3: 0x00000000
[   59.753156] marvell-nfc pxa3xx-nand: 
[   59.753156] NDCR:  0xdd079fff
[   59.753156] NDCB0: 0x000d3000
[   59.753156] NDCB1: 0x52000000
[   59.753156] NDCB2: 0x00000000
[   59.753156] NDCB3: 0x00000000
[   59.772234] marvell-nfc pxa3xx-nand: 
[   59.772234] NDCR:  0xdd079fff
[   59.772234] NDCB0: 0x000d3000
[   59.772234] NDCB1: 0x52010000
[   59.772234] NDCB2: 0x00000000
[   59.772234] NDCB3: 0x00000000
[   59.791225] marvell-nfc pxa3xx-nand: 
[   59.791225] NDCR:  0x9d079fff
[   59.791225] NDCB0: 0x000d3000
[   59.791225] NDCB1: 0x52010000
[   59.791225] NDCB2: 0x00000000
[   59.791225] NDCB3: 0x00000000
[   59.810348] marvell-nfc pxa3xx-nand: 
[   59.810348] NDCR:  0xdd079fff
[   59.810348] NDCB0: 0x000d3000
[   59.810348] NDCB1: 0x52400000
[   59.810348] NDCB2: 0x00000000
[   59.810348] NDCB3: 0x00000000
[   59.829430] marvell-nfc pxa3xx-nand: 
[   59.829430] NDCR:  0xdd079fff
[   59.829430] NDCB0: 0x000d3000
[   59.829430] NDCB1: 0x52410000
[   59.829430] NDCB2: 0x00000000
[   59.829430] NDCB3: 0x00000000
[   59.848437] marvell-nfc pxa3xx-nand: 
[   59.848437] NDCR:  0x9d079fff
[   59.848437] NDCB0: 0x000d3000
[   59.848437] NDCB1: 0x52410000
[   59.848437] NDCB2: 0x00000000
[   59.848437] NDCB3: 0x00000000
[   59.867556] marvell-nfc pxa3xx-nand: 
[   59.867556] NDCR:  0xdd079fff
[   59.867556] NDCB0: 0x000d3000
[   59.867556] NDCB1: 0x52800000
[   59.867556] NDCB2: 0x00000000
[   59.867556] NDCB3: 0x00000000
[   59.886635] marvell-nfc pxa3xx-nand: 
[   59.886635] NDCR:  0xdd079fff
[   59.886635] NDCB0: 0x000d3000
[   59.886635] NDCB1: 0x52810000
[   59.886635] NDCB2: 0x00000000
[   59.886635] NDCB3: 0x00000000
[   59.905631] marvell-nfc pxa3xx-nand: 
[   59.905631] NDCR:  0x9d079fff
[   59.905631] NDCB0: 0x000d3000
[   59.905631] NDCB1: 0x52810000
[   59.905631] NDCB2: 0x00000000
[   59.905631] NDCB3: 0x00000000
[   59.924745] marvell-nfc pxa3xx-nand: 
[   59.924745] NDCR:  0xdd079fff
[   59.924745] NDCB0: 0x000d3000
[   59.924745] NDCB1: 0x52c00000
[   59.924745] NDCB2: 0x00000000
[   59.924745] NDCB3: 0x00000000
[   59.943828] marvell-nfc pxa3xx-nand: 
[   59.943828] NDCR:  0xdd079fff
[   59.943828] NDCB0: 0x000d3000
[   59.943828] NDCB1: 0x52c10000
[   59.943828] NDCB2: 0x00000000
[   59.943828] NDCB3: 0x00000000
[   59.962826] marvell-nfc pxa3xx-nand: 
[   59.962826] NDCR:  0x9d079fff
[   59.962826] NDCB0: 0x000d3000
[   59.962826] NDCB1: 0x52c10000
[   59.962826] NDCB2: 0x00000000
[   59.962826] NDCB3: 0x00000000
[   59.981938] marvell-nfc pxa3xx-nand: 
[   59.981938] NDCR:  0xdd079fff
[   59.981938] NDCB0: 0x000d3000
[   59.981938] NDCB1: 0x53000000
[   59.981938] NDCB2: 0x00000000
[   59.981938] NDCB3: 0x00000000
[   60.001012] marvell-nfc pxa3xx-nand: 
[   60.001012] NDCR:  0xdd079fff
[   60.001012] NDCB0: 0x000d3000
[   60.001012] NDCB1: 0x53010000
[   60.001012] NDCB2: 0x00000000
[   60.001012] NDCB3: 0x00000000
[   60.020221] marvell-nfc pxa3xx-nand: 
[   60.020221] NDCR:  0x9d079fff
[   60.020221] NDCB0: 0x000d3000
[   60.020221] NDCB1: 0x53010000
[   60.020221] NDCB2: 0x00000000
[   60.020221] NDCB3: 0x00000000
[   60.039368] marvell-nfc pxa3xx-nand: 
[   60.039368] NDCR:  0xdd079fff
[   60.039368] NDCB0: 0x000d3000
[   60.039368] NDCB1: 0x53400000
[   60.039368] NDCB2: 0x00000000
[   60.039368] NDCB3: 0x00000000
[   60.058441] marvell-nfc pxa3xx-nand: 
[   60.058441] NDCR:  0xdd079fff
[   60.058441] NDCB0: 0x000d3000
[   60.058441] NDCB1: 0x53410000
[   60.058441] NDCB2: 0x00000000
[   60.058441] NDCB3: 0x00000000
[   60.077437] marvell-nfc pxa3xx-nand: 
[   60.077437] NDCR:  0x9d079fff
[   60.077437] NDCB0: 0x000d3000
[   60.077437] NDCB1: 0x53410000
[   60.077437] NDCB2: 0x00000000
[   60.077437] NDCB3: 0x00000000
[   60.097071] marvell-nfc pxa3xx-nand: 
[   60.097071] NDCR:  0xdd079fff
[   60.097071] NDCB0: 0x000d3000
[   60.097071] NDCB1: 0x53800000
[   60.097071] NDCB2: 0x00000000
[   60.097071] NDCB3: 0x00000000
[   60.116183] marvell-nfc pxa3xx-nand: 
[   60.116183] NDCR:  0xdd079fff
[   60.116183] NDCB0: 0x000d3000
[   60.116183] NDCB1: 0x53810000
[   60.116183] NDCB2: 0x00000000
[   60.116183] NDCB3: 0x00000000
[   60.135177] marvell-nfc pxa3xx-nand: 
[   60.135177] NDCR:  0x9d079fff
[   60.135177] NDCB0: 0x000d3000
[   60.135177] NDCB1: 0x53810000
[   60.135177] NDCB2: 0x00000000
[   60.135177] NDCB3: 0x00000000
[   60.154288] marvell-nfc pxa3xx-nand: 
[   60.154288] NDCR:  0xdd079fff
[   60.154288] NDCB0: 0x000d3000
[   60.154288] NDCB1: 0x53c00000
[   60.154288] NDCB2: 0x00000000
[   60.154288] NDCB3: 0x00000000
[   60.173365] marvell-nfc pxa3xx-nand: 
[   60.173365] NDCR:  0xdd079fff
[   60.173365] NDCB0: 0x000d3000
[   60.173365] NDCB1: 0x53c10000
[   60.173365] NDCB2: 0x00000000
[   60.173365] NDCB3: 0x00000000
[   60.192359] marvell-nfc pxa3xx-nand: 
[   60.192359] NDCR:  0x9d079fff
[   60.192359] NDCB0: 0x000d3000
[   60.192359] NDCB1: 0x53c10000
[   60.192359] NDCB2: 0x00000000
[   60.192359] NDCB3: 0x00000000
[   60.211474] marvell-nfc pxa3xx-nand: 
[   60.211474] NDCR:  0xdd079fff
[   60.211474] NDCB0: 0x000d3000
[   60.211474] NDCB1: 0x54000000
[   60.211474] NDCB2: 0x00000000
[   60.211474] NDCB3: 0x00000000
[   60.230556] marvell-nfc pxa3xx-nand: 
[   60.230556] NDCR:  0xdd079fff
[   60.230556] NDCB0: 0x000d3000
[   60.230556] NDCB1: 0x54010000
[   60.230556] NDCB2: 0x00000000
[   60.230556] NDCB3: 0x00000000
[   60.249556] marvell-nfc pxa3xx-nand: 
[   60.249556] NDCR:  0x9d079fff
[   60.249556] NDCB0: 0x000d3000
[   60.249556] NDCB1: 0x54010000
[   60.249556] NDCB2: 0x00000000
[   60.249556] NDCB3: 0x00000000
[   60.268799] marvell-nfc pxa3xx-nand: 
[   60.268799] NDCR:  0xdd079fff
[   60.268799] NDCB0: 0x000d3000
[   60.268799] NDCB1: 0x54400000
[   60.268799] NDCB2: 0x00000000
[   60.268799] NDCB3: 0x00000000
[   60.287813] marvell-nfc pxa3xx-nand: 
[   60.287813] NDCR:  0xdd079fff
[   60.287813] NDCB0: 0x000d3000
[   60.287813] NDCB1: 0x54410000
[   60.287813] NDCB2: 0x00000000
[   60.287813] NDCB3: 0x00000000
[   60.306813] marvell-nfc pxa3xx-nand: 
[   60.306813] NDCR:  0x9d079fff
[   60.306813] NDCB0: 0x000d3000
[   60.306813] NDCB1: 0x54410000
[   60.306813] NDCB2: 0x00000000
[   60.306813] NDCB3: 0x00000000
[   60.325931] marvell-nfc pxa3xx-nand: 
[   60.325931] NDCR:  0xdd079fff
[   60.325931] NDCB0: 0x000d3000
[   60.325931] NDCB1: 0x55000000
[   60.325931] NDCB2: 0x00000000
[   60.325931] NDCB3: 0x00000000
[   60.345007] marvell-nfc pxa3xx-nand: 
[   60.345007] NDCR:  0xdd079fff
[   60.345007] NDCB0: 0x000d3000
[   60.345007] NDCB1: 0x55010000
[   60.345007] NDCB2: 0x00000000
[   60.345007] NDCB3: 0x00000000
[   60.364001] marvell-nfc pxa3xx-nand: 
[   60.364001] NDCR:  0x9d079fff
[   60.364001] NDCB0: 0x000d3000
[   60.364001] NDCB1: 0x55010000
[   60.364001] NDCB2: 0x00000000
[   60.364001] NDCB3: 0x00000000
[   60.383116] marvell-nfc pxa3xx-nand: 
[   60.383116] NDCR:  0xdd079fff
[   60.383116] NDCB0: 0x000d3000
[   60.383116] NDCB1: 0x55400000
[   60.383116] NDCB2: 0x00000000
[   60.383116] NDCB3: 0x00000000
[   60.402197] marvell-nfc pxa3xx-nand: 
[   60.402197] NDCR:  0xdd079fff
[   60.402197] NDCB0: 0x000d3000
[   60.402197] NDCB1: 0x55410000
[   60.402197] NDCB2: 0x00000000
[   60.402197] NDCB3: 0x00000000
[   60.421190] marvell-nfc pxa3xx-nand: 
[   60.421190] NDCR:  0x9d079fff
[   60.421190] NDCB0: 0x000d3000
[   60.421190] NDCB1: 0x55410000
[   60.421190] NDCB2: 0x00000000
[   60.421190] NDCB3: 0x00000000
[   60.440302] marvell-nfc pxa3xx-nand: 
[   60.440302] NDCR:  0xdd079fff
[   60.440302] NDCB0: 0x000d3000
[   60.440302] NDCB1: 0x55800000
[   60.440302] NDCB2: 0x00000000
[   60.440302] NDCB3: 0x00000000
[   60.459400] marvell-nfc pxa3xx-nand: 
[   60.459400] NDCR:  0xdd079fff
[   60.459400] NDCB0: 0x000d3000
[   60.459400] NDCB1: 0x55810000
[   60.459400] NDCB2: 0x00000000
[   60.459400] NDCB3: 0x00000000
[   60.478391] marvell-nfc pxa3xx-nand: 
[   60.478391] NDCR:  0x9d079fff
[   60.478391] NDCB0: 0x000d3000
[   60.478391] NDCB1: 0x55810000
[   60.478391] NDCB2: 0x00000000
[   60.478391] NDCB3: 0x00000000
[   60.497507] marvell-nfc pxa3xx-nand: 
[   60.497507] NDCR:  0xdd079fff
[   60.497507] NDCB0: 0x000d3000
[   60.497507] NDCB1: 0x55c00000
[   60.497507] NDCB2: 0x00000000
[   60.497507] NDCB3: 0x00000000
[   60.516585] marvell-nfc pxa3xx-nand: 
[   60.516585] NDCR:  0xdd079fff
[   60.516585] NDCB0: 0x000d3000
[   60.516585] NDCB1: 0x55c10000
[   60.516585] NDCB2: 0x00000000
[   60.516585] NDCB3: 0x00000000
[   60.535578] marvell-nfc pxa3xx-nand: 
[   60.535578] NDCR:  0x9d079fff
[   60.535578] NDCB0: 0x000d3000
[   60.535578] NDCB1: 0x55c10000
[   60.535578] NDCB2: 0x00000000
[   60.535578] NDCB3: 0x00000000
[   60.554689] marvell-nfc pxa3xx-nand: 
[   60.554689] NDCR:  0xdd079fff
[   60.554689] NDCB0: 0x000d3000
[   60.554689] NDCB1: 0x56000000
[   60.554689] NDCB2: 0x00000000
[   60.554689] NDCB3: 0x00000000
[   60.573763] marvell-nfc pxa3xx-nand: 
[   60.573763] NDCR:  0xdd079fff
[   60.573763] NDCB0: 0x000d3000
[   60.573763] NDCB1: 0x56010000
[   60.573763] NDCB2: 0x00000000
[   60.573763] NDCB3: 0x00000000
[   60.592755] marvell-nfc pxa3xx-nand: 
[   60.592755] NDCR:  0x9d079fff
[   60.592755] NDCB0: 0x000d3000
[   60.592755] NDCB1: 0x56010000
[   60.592755] NDCB2: 0x00000000
[   60.592755] NDCB3: 0x00000000
[   60.611868] marvell-nfc pxa3xx-nand: 
[   60.611868] NDCR:  0xdd079fff
[   60.611868] NDCB0: 0x000d3000
[   60.611868] NDCB1: 0x56400000
[   60.611868] NDCB2: 0x00000000
[   60.611868] NDCB3: 0x00000000
[   60.630946] marvell-nfc pxa3xx-nand: 
[   60.630946] NDCR:  0xdd079fff
[   60.630946] NDCB0: 0x000d3000
[   60.630946] NDCB1: 0x56410000
[   60.630946] NDCB2: 0x00000000
[   60.630946] NDCB3: 0x00000000
[   60.649937] marvell-nfc pxa3xx-nand: 
[   60.649937] NDCR:  0x9d079fff
[   60.649937] NDCB0: 0x000d3000
[   60.649937] NDCB1: 0x56410000
[   60.649937] NDCB2: 0x00000000
[   60.649937] NDCB3: 0x00000000
[   60.669070] marvell-nfc pxa3xx-nand: 
[   60.669070] NDCR:  0xdd079fff
[   60.669070] NDCB0: 0x000d3000
[   60.669070] NDCB1: 0x56800000
[   60.669070] NDCB2: 0x00000000
[   60.669070] NDCB3: 0x00000000
[   60.688143] marvell-nfc pxa3xx-nand: 
[   60.688143] NDCR:  0xdd079fff
[   60.688143] NDCB0: 0x000d3000
[   60.688143] NDCB1: 0x56810000
[   60.688143] NDCB2: 0x00000000
[   60.688143] NDCB3: 0x00000000
[   60.707135] marvell-nfc pxa3xx-nand: 
[   60.707135] NDCR:  0x9d079fff
[   60.707135] NDCB0: 0x000d3000
[   60.707135] NDCB1: 0x56810000
[   60.707135] NDCB2: 0x00000000
[   60.707135] NDCB3: 0x00000000
[   60.726250] marvell-nfc pxa3xx-nand: 
[   60.726250] NDCR:  0xdd079fff
[   60.726250] NDCB0: 0x000d3000
[   60.726250] NDCB1: 0x56c00000
[   60.726250] NDCB2: 0x00000000
[   60.726250] NDCB3: 0x00000000
[   60.745333] marvell-nfc pxa3xx-nand: 
[   60.745333] NDCR:  0xdd079fff
[   60.745333] NDCB0: 0x000d3000
[   60.745333] NDCB1: 0x56c10000
[   60.745333] NDCB2: 0x00000000
[   60.745333] NDCB3: 0x00000000
[   60.764332] marvell-nfc pxa3xx-nand: 
[   60.764332] NDCR:  0x9d079fff
[   60.764332] NDCB0: 0x000d3000
[   60.764332] NDCB1: 0x56c10000
[   60.764332] NDCB2: 0x00000000
[   60.764332] NDCB3: 0x00000000
[   60.783447] marvell-nfc pxa3xx-nand: 
[   60.783447] NDCR:  0xdd079fff
[   60.783447] NDCB0: 0x000d3000
[   60.783447] NDCB1: 0x57000000
[   60.783447] NDCB2: 0x00000000
[   60.783447] NDCB3: 0x00000000
[   60.802527] marvell-nfc pxa3xx-nand: 
[   60.802527] NDCR:  0xdd079fff
[   60.802527] NDCB0: 0x000d3000
[   60.802527] NDCB1: 0x57010000
[   60.802527] NDCB2: 0x00000000
[   60.802527] NDCB3: 0x00000000
[   60.821520] marvell-nfc pxa3xx-nand: 
[   60.821520] NDCR:  0x9d079fff
[   60.821520] NDCB0: 0x000d3000
[   60.821520] NDCB1: 0x57010000
[   60.821520] NDCB2: 0x00000000
[   60.821520] NDCB3: 0x00000000
[   60.840635] marvell-nfc pxa3xx-nand: 
[   60.840635] NDCR:  0xdd079fff
[   60.840635] NDCB0: 0x000d3000
[   60.840635] NDCB1: 0x57400000
[   60.840635] NDCB2: 0x00000000
[   60.840635] NDCB3: 0x00000000
[   60.859718] marvell-nfc pxa3xx-nand: 
[   60.859718] NDCR:  0xdd079fff
[   60.859718] NDCB0: 0x000d3000
[   60.859718] NDCB1: 0x57410000
[   60.859718] NDCB2: 0x00000000
[   60.859718] NDCB3: 0x00000000
[   60.878796] marvell-nfc pxa3xx-nand: 
[   60.878796] NDCR:  0x9d079fff
[   60.878796] NDCB0: 0x000d3000
[   60.878796] NDCB1: 0x57410000
[   60.878796] NDCB2: 0x00000000
[   60.878796] NDCB3: 0x00000000
[   60.897886] marvell-nfc pxa3xx-nand: 
[   60.897886] NDCR:  0xdd079fff
[   60.897886] NDCB0: 0x000d3000
[   60.897886] NDCB1: 0x57c00000
[   60.897886] NDCB2: 0x00000000
[   60.897886] NDCB3: 0x00000000
[   60.916967] marvell-nfc pxa3xx-nand: 
[   60.916967] NDCR:  0xdd079fff
[   60.916967] NDCB0: 0x000d3000
[   60.916967] NDCB1: 0x57c10000
[   60.916967] NDCB2: 0x00000000
[   60.916967] NDCB3: 0x00000000
[   60.935957] marvell-nfc pxa3xx-nand: 
[   60.935957] NDCR:  0x9d079fff
[   60.935957] NDCB0: 0x000d3000
[   60.935957] NDCB1: 0x57c10000
[   60.935957] NDCB2: 0x00000000
[   60.935957] NDCB3: 0x00000000
[   60.955072] marvell-nfc pxa3xx-nand: 
[   60.955072] NDCR:  0xdd079fff
[   60.955072] NDCB0: 0x000d3000
[   60.955072] NDCB1: 0x58000000
[   60.955072] NDCB2: 0x00000000
[   60.955072] NDCB3: 0x00000000
[   60.974148] marvell-nfc pxa3xx-nand: 
[   60.974148] NDCR:  0xdd079fff
[   60.974148] NDCB0: 0x000d3000
[   60.974148] NDCB1: 0x58010000
[   60.974148] NDCB2: 0x00000000
[   60.974148] NDCB3: 0x00000000
[   60.993140] marvell-nfc pxa3xx-nand: 
[   60.993140] NDCR:  0x9d079fff
[   60.993140] NDCB0: 0x000d3000
[   60.993140] NDCB1: 0x58010000
[   60.993140] NDCB2: 0x00000000
[   60.993140] NDCB3: 0x00000000
[   61.012262] marvell-nfc pxa3xx-nand: 
[   61.012262] NDCR:  0xdd079fff
[   61.012262] NDCB0: 0x000d3000
[   61.012262] NDCB1: 0x58400000
[   61.012262] NDCB2: 0x00000000
[   61.012262] NDCB3: 0x00000000
[   61.031332] marvell-nfc pxa3xx-nand: 
[   61.031332] NDCR:  0xdd079fff
[   61.031332] NDCB0: 0x000d3000
[   61.031332] NDCB1: 0x58410000
[   61.031332] NDCB2: 0x00000000
[   61.031332] NDCB3: 0x00000000
[   61.050347] marvell-nfc pxa3xx-nand: 
[   61.050347] NDCR:  0x9d079fff
[   61.050347] NDCB0: 0x000d3000
[   61.050347] NDCB1: 0x58410000
[   61.050347] NDCB2: 0x00000000
[   61.050347] NDCB3: 0x00000000
[   61.069665] ubi0: scanning is finished
[   61.073622] ubi0 error: ubi_read_volume_table: the layout volume was not found
[   61.081178] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd5, error -22
[   61.088556] UBI error: cannot attach mtd5
[   61.094051] pxa-rtc pxa-rtc: setting system clock to 2000-01-01 00:01:26 UTC (946684886)
[   61.173248] smc91x smc91x.0 eth0: link down
[   63.031810] smc91x smc91x.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
[   63.088817] IP-Config: Complete:
[   63.092174]      device=eth0, hwaddr=00:0e:0c:a7:26:f7, ipaddr=192.168.1.232, mask=255.255.255.0, gw=255.255.255.255
[   63.102853]      host=192.168.1.232, domain=, nis-domain=(none)
[   63.108938]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
[   63.117215] ALSA device list:
[   63.120674]   #0: Zylonite
[   63.146191] Freeing unused kernel memory: 2396K
[   63.151134] This architecture does not have kernel memory protection.
Starting logging: OK
Loading all the available modules: modprobe: module smc91x not found in modules.dep
modprobe: module soundcore not found in modules.dep


From kdasu.kdev at gmail.com  Tue Jan  2 12:14:57 2018
From: kdasu.kdev at gmail.com (Kamal Dasu)
Date: Tue,  2 Jan 2018 15:14:57 -0500
Subject: [PATCH] mtd: brcmnand: Disable prefetch by default
Message-ID: <1514924097-1630-1-git-send-email-kdasu.kdev@gmail.com>

Brcm nand controller prefetch feature needs to be disabled
by default. Enabling effects performance on random reads as
well as dma reads.

Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
---
 drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index dd56a67..2a978d9 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 	if (ctrl->nand_version >= 0x0702)
 		tmp |= ACC_CONTROL_RD_ERASED;
 	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
-	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
-		/*
-		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
-		 * errors
-		 */
-		if (has_flash_dma(ctrl))
-			tmp &= ~ACC_CONTROL_PREFETCH;
-		else
-			tmp |= ACC_CONTROL_PREFETCH;
-	}
+	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
+		tmp &= ~ACC_CONTROL_PREFETCH;
+
 	nand_writereg(ctrl, offs, tmp);
 
 	return 0;
-- 
2.7.4



From bradleybolen at gmail.com  Tue Jan  2 18:26:09 2018
From: bradleybolen at gmail.com (Bradley Bolen)
Date: Tue,  2 Jan 2018 21:26:09 -0500
Subject: [PATCH] UBI: block: Must use a mutex when using idr_alloc/idr_remove
Message-ID: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>

This fixes a race condition where running ubiblock on multiple volumes
simultaneously produces the following splat.

kernel BUG at kernel-source/fs/sysfs/group.c:113!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
[<c01e4160>] (internal_create_group) from [<c01e43fc>]
(sysfs_create_group+0x20/0x24)
[<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
(blk_trace_init_sysfs+0x18/0x20)
[<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
(blk_register_queue+0x6c/0x154)
[<c02bc734>] (blk_register_queue) from [<c02cd610>]
(device_add_disk+0x2c8/0x450)
[<c02cd610>] (device_add_disk) from [<c0430fac>]
(ubiblock_create+0x254/0x2e4)
[<c0430fac>] (ubiblock_create) from [<c0421a3c>]
(vol_cdev_ioctl+0x3e0/0x564)
[<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
[<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
[<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
[<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)

Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
---
 drivers/mtd/ubi/block.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index b210fdb..1c12370 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -390,7 +390,9 @@ int ubiblock_create(struct ubi_volume_info *vi)
 
 	gd->fops = &ubiblock_ops;
 	gd->major = ubiblock_major;
+	mutex_lock(&devices_mutex);
 	gd->first_minor = idr_alloc(&ubiblock_minor_idr, dev, 0, 0, GFP_KERNEL);
+	mutex_unlock(&devices_mutex);
 	if (gd->first_minor < 0) {
 		dev_err(disk_to_dev(gd),
 			"block: dynamic minor allocation failed");
@@ -452,7 +454,9 @@ int ubiblock_create(struct ubi_volume_info *vi)
 out_free_tags:
 	blk_mq_free_tag_set(&dev->tag_set);
 out_remove_minor:
+	mutex_lock(&devices_mutex);
 	idr_remove(&ubiblock_minor_idr, gd->first_minor);
+	mutex_unlock(&devices_mutex);
 out_put_disk:
 	put_disk(dev->gd);
 out_free_dev:
@@ -471,7 +475,9 @@ static void ubiblock_cleanup(struct ubiblock *dev)
 	blk_cleanup_queue(dev->rq);
 	blk_mq_free_tag_set(&dev->tag_set);
 	dev_info(disk_to_dev(dev->gd), "released");
+	mutex_lock(&devices_mutex);
 	idr_remove(&ubiblock_minor_idr, dev->gd->first_minor);
+	mutex_unlock(&devices_mutex);
 	put_disk(dev->gd);
 }
 
-- 
1.9.3



From xieyisheng1 at huawei.com  Tue Jan  2 22:42:14 2018
From: xieyisheng1 at huawei.com (Yisheng Xie)
Date: Wed, 3 Jan 2018 14:42:14 +0800
Subject: [PATCH v3 00/27] kill devm_ioremap_nocache
In-Reply-To: <6c0ade63-f4d3-d44d-c622-b091eb2ba902@huawei.com>
References: <1514026525-32538-1-git-send-email-xieyisheng1@huawei.com>
 <20171223134831.GB10103@kroah.com>
 <f7632cf5-2bcc-4d74-b912-3999937a1269@roeck-us.net>
 <c28ac0bc-8bd2-3dce-3167-8c0f80ec601e@c-s.fr>
 <6c0ade63-f4d3-d44d-c622-b091eb2ba902@huawei.com>
Message-ID: <e9f6805c-2dd7-f9c6-d615-5e25cff241a3@huawei.com>

+ cris/ia64/mn10300/openrisc maintainers

On 2017/12/25 9:09, Yisheng Xie wrote:
> hi Christophe and Greg,
> 
> On 2017/12/24 16:55, christophe leroy wrote:
>>
>>
>> Le 23/12/2017 ? 16:57, Guenter Roeck a ?crit :
>>> On 12/23/2017 05:48 AM, Greg KH wrote:
>>>> On Sat, Dec 23, 2017 at 06:55:25PM +0800, Yisheng Xie wrote:
>>>>> Hi all,
>>>>>
>>>>> When I tried to use devm_ioremap function and review related code, I found
>>>>> devm_ioremap and devm_ioremap_nocache is almost the same with each other,
>>>>> except one use ioremap while the other use ioremap_nocache.
>>>>
>>>> For all arches?  Really?  Look at MIPS, and x86, they have different
>>>> functions.
>>>>
>>>
>>> Both mips and x86 end up mapping the same function, but other arches don't.
>>> mn10300 is one where ioremap and ioremap_nocache are definitely different.
>>
>> alpha: identical
>> arc: identical
>> arm: identical
>> arm64: identical
>> cris: different        <==
>> frv: identical
>> hexagone: identical
>> ia64: different        <==
>> m32r: identical
>> m68k: identical
>> metag: identical
>> microblaze: identical
>> mips: identical
>> mn10300: different     <==
>> nios: identical
>> openrisc: different    <==
>> parisc: identical
>> riscv: identical
>> s390: identical
>> sh: identical
>> sparc: identical
>> tile: identical
>> um: rely on asm/generic
>> unicore32: identical
>> x86: identical
>> asm/generic (no mmu): identical
> 
> Wow, that's correct, sorry for I have just checked the main archs, I means
> x86,arm, arm64, mips.
> 
> However, I stall have no idea about why these 4 archs want different ioremap
> function with others. Drivers seems cannot aware this? If driver call ioremap
> want he really want for there 4 archs, cache or nocache?

Could you please help about this? it is out of my knowledge.

Thanks
Yisheng

> 
>>
>> So 4 among all arches seems to have ioremap() and ioremap_nocache() being different.
>>
>> Could we have a define set by the 4 arches on which ioremap() and ioremap_nocache() are different, something like HAVE_DIFFERENT_IOREMAP_NOCACHE ?
> 
> Then, what the HAVE_DIFFERENT_IOREMAP_NOCACHE is uesed for ?
> 
> Thanks
> Yisheng
>>
>> Christophe
>>
>>>
>>> Guenter
>>>
>>>>> While ioremap's
>>>>> default function is ioremap_nocache, so devm_ioremap_nocache also have the
>>>>> same function with devm_ioremap, which can just be killed to reduce the size
>>>>> of devres.o(from 20304 bytes to 18992 bytes in my compile environment).
>>>>>
>>>>> I have posted two versions, which use macro instead of function for
>>>>> devm_ioremap_nocache[1] or devm_ioremap[2]. And Greg suggest me to kill
>>>>> devm_ioremap_nocache for no need to keep a macro around for the duplicate
>>>>> thing. So here comes v3 and please help to review.
>>>>
>>>> I don't think this can be done, what am I missing?  These functions are
>>>> not identical, sorry for missing that before.
> 
> Never mind, I should checked all the arches, sorry about that.
> 
>>>>
>>>> thanks,
>>>>
>>>> greg k-h
>>>>
>>>
>>> -- 
>>> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> ---
>> L'absence de virus dans ce courrier ?lectronique a ?t? v?rifi?e par le logiciel antivirus Avast.
>> https://www.avast.com/antivirus
>>
>>
>> .
>>
> 
> 
> .
> 



From ludovic.desroches at microchip.com  Tue Jan  2 22:51:29 2018
From: ludovic.desroches at microchip.com (ludovic.desroches at microchip.com)
Date: Wed, 3 Jan 2018 07:51:29 +0100
Subject: [PATCH 2/3] dt-bindings: mtd: atmel-quadspi: add an optional
 property 'dmacap,memcpy'
In-Reply-To: <1514920738.26695.171.camel@impinj.com>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <143542c61ca674d53da4985bbabc142e8e6ebefc.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <20171226232330.trljk2ofyvu4ly3n@rob-hp-laptop>
 <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
 <20180102102234.GG2612@rfolt0960.corp.atmel.com>
 <1514920738.26695.171.camel@impinj.com>
Message-ID: <20180103065129.GH2612@rfolt0960.corp.atmel.com>

On Tue, Jan 02, 2018 at 07:18:58PM +0000, Trent Piepho wrote:
> On Tue, 2018-01-02 at 11:22 +0100, Ludovic Desroches wrote:
> > On Wed, Dec 27, 2017 at 10:40:00PM +0100, Cyrille Pitchen wrote:
> > 
> > > Or maybe no change at all is required at the at_xdmac.c driver side: we
> > > just don't care about the provided flags in the "dmas" property, especially
> > > the "peripheral id". They would be ignored anyway when the atmel-quadspi.c
> > > driver later calls dmaengine_prep_dma_memcpy(). So I could simply set the
> > > dma cells to 0 in the device-tree?
> > > 
> > > Ludovic, what do you think about that ?
> > 
> > It may work but I won't do this. Usually, channels requested through the xlate
> > function have usually their capaiblities set to DMA_SLAVE and not DMA_MEMCPY.
> > In the at_xdmac case, it won't be an issue but if you have a controller
> > which has channels which can support only mem-to-mem or peripheral, it
> > won't work.
> 
> Maybe one could create an "AT91_XDMAC_DT_" macro to indicate a memcpy
> channel.  There are still unused bits for another flag.  It also looks
> like at_xdma uses peripheral id 0x3f for memcpy transfers (will that
> work with memcpy DMA on multiple channels at the same time?).  So
> perhaps perid 0x3f could be the indication of wanting a memcpy channel,
> rather than another flag bit.  But however it's done, one writes:
> 
> dmas = <&dma0 AT91_XDMAC_DT_MEMCPY>; dma-names = "rx-tx";
> 

If have no objection about doing that, my concerns are:
- most (all ?) of the dma controllers used the xlate function to provide
  slave channel. Does it have to provide slave channel or can we
  use it for all kind of channel? From my point of view, we can do it,
  just need the confirmation.
- this set of patches if focused on the atmel qspi controller but other
  ones may be interested in doing the same thing so they would have to
  update the behavior of the xlate function of the DMA controller they
  are using. So having the request of a DMA_MEMCPY channel inside the
  spi/qspi controller doesn't seem to be a wrong idea. Moreover, it may
  be confusing for the user who don't know the context: why do I have to
  use memcpy and not slave as usal?

Honestly I have no opinion about the way to do it. Both have pros and
cons.

> I think one could have the quadspi driver automatically fill in the dma
> cell in the dma specifier if it is not present in the device tree.  So
> one could write "dmas = <&dma0>" and the driver adds the
> AT91_XDMAC_DT_MEMCPY cell before xlating.  I'm not sure if that's a
> good idea or not.

I don't think so, there is enough black magic, let's try to not add more
:p

Regards

Ludovic


From miquel.raynal at free-electrons.com  Tue Jan  2 23:40:37 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Wed, 3 Jan 2018 08:40:37 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87d12scbiy.fsf@belgarion.home>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
Message-ID: <20180103084037.422b239a@xps13>

On Tue, 02 Jan 2018 20:21:09 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> 
> > I think the ECC issue you faced was related to pages being written
> > *and* empty. If this guess is right, the board should boot fine with
> > these changes.
> >
> > Otherwise, please add the DEBUG define as before in both the core
> > and the driver and do not hesitate to add another dump_stack()
> > where it crashes (if applicable).  
> 
> The problem looks still the same :
> [    3.560163] Bad block table not found for chip 0

Mmmmh ok.

Can you please add this patch:
http://code.bulix.org/61at9p-254626

Thanks,
Miqu?l


> 
> Cheers.
> 
> --
> Robert
> 


From zajec5 at gmail.com  Wed Jan  3 02:55:42 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed,  3 Jan 2018 11:55:42 +0100
Subject: [PATCH V6 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180102130458.16226-1-zajec5@gmail.com>
References: <20180102130458.16226-1-zajec5@gmail.com>
Message-ID: <20180103105543.17897-1-zajec5@gmail.com>

From: Brian Norris <computersforpeace at gmail.com>

Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.

It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).

This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching

V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
    Merge helpers into a single of_mtd_match_mtd_parser
V3: Add a simple comment to note we will need the best match in the future
V4: Rework new functions to pick parser with the best match
    Move new code in parse_mtd_partitions up so it has precedence over flash
    driver defaults and MTD defaults
V5: Rework matching code to start checking with the most specific string in the
    "compatibility" property.
V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
---
 drivers/mtd/mtdpart.c          | 64 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/partitions.h |  1 +
 2 files changed, 65 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index be088bccd593..b11958adcf45 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -880,6 +881,48 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 }
 
 /**
+ * mtd_part_get_parser_by_cp - find MTD parser by a compatible string
+ *
+ * @cp: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_parser_by_cp(const char *cp)
+{
+	struct mtd_part_parser *p, *ret = NULL;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->name[0] || matches->type[0] || matches->compatible[0];
+		     matches++) {
+			if (!matches->compatible[0])
+				continue;
+			if (!strcmp(matches->compatible, cp) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
+/**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
  * @types: names of partition parsers to try or %NULL
@@ -905,8 +948,29 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 			 struct mtd_part_parser_data *data)
 {
 	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *cp;
 	int ret, err = 0;
 
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	if (np) {
+		of_property_for_each_string(np, "compatible", prop, cp) {
+			parser = mtd_part_get_parser_by_cp(cp);
+			if (!parser)
+				continue;
+			ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (ret > 0) {
+				of_node_put(np);
+				return 0;
+			}
+			mtd_part_parser_put(parser);
+			if (ret < 0 && !err)
+				err = ret;
+		}
+		of_node_put(np);
+	}
+
 	if (!types)
 		types = default_mtd_part_types;
 
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70dacbd..11cb0c50cd84 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-- 
2.11.0



From zajec5 at gmail.com  Wed Jan  3 02:55:43 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed,  3 Jan 2018 11:55:43 +0100
Subject: [PATCH V6 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
In-Reply-To: <20180103105543.17897-1-zajec5@gmail.com>
References: <20180102130458.16226-1-zajec5@gmail.com>
 <20180103105543.17897-1-zajec5@gmail.com>
Message-ID: <20180103105543.17897-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).

This matches existing bindings documentation.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/ofpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e525677..92fcbac046d9 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
 	.parse_fn = parse_ofpart_partitions,
 	.name = "ofpart",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
-- 
2.11.0



From yogeshnarayan.gaur at nxp.com  Wed Jan  3 02:56:27 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Wed, 3 Jan 2018 16:26:27 +0530
Subject: [PATCH] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
Message-ID: <1514976987-14082-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
protocol. Spansion flash, s25fl512s, supports Quad read with read
capabilities as 1-4-4.

Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index c22e3eb..178e621 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -959,6 +959,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	const struct spi_nor_hwcaps hwcaps = {
 		.mask = SNOR_HWCAPS_READ_1_1_4 |
+			SNOR_HWCAPS_READ_1_4_4 |
 			SNOR_HWCAPS_PP,
 	};
 	struct device_node *np = pdev->dev.of_node;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan  3 03:00:29 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Wed, 3 Jan 2018 16:30:29 +0530
Subject: [RFC] mtd: fsl-quadspi: add support to create dynamic LUT entry
Message-ID: <1514977229-14161-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 291 ++++++++++++++++++++------------------
 1 file changed, 156 insertions(+), 135 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 178e621..19d8f03 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -194,20 +194,19 @@
 
 /* SEQID -- we can have 16 seqids at most. */
 #define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+#define SEQID_RUN_CMD		1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +367,151 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
 {
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
+{
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
+	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+	u8 read_dm, opcode;
 	int i;
 
-	struct spi_nor *nor = &q->nor[0];
-	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
+
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
+
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
+	/* Dynamic LUT */
+	lut_base = SEQID_RUN_CMD * 4;
+
+	/* Clear LUT entries for dynamic LUT entry in LUT table */
+	for (i = lut_base; i < (lut_base + 4); i++)
 		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
 
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
 
-	fsl_qspi_lock_lut(q);
-}
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		if (ops == FSL_QSPI_OPS_READ) {
+			qspi_writel(q,
+				    LUT0(DUMMY, pad_count(dummy_pad), read_dm) |
+				    LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+				    base + QUADSPI_LUT(lut_base + 1));
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				SEQID_RUN_CMD << QUADSPI_BFGENCR_SEQID_SHIFT,
+				q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	fsl_qspi_lock_lut(q);
+}
+
+static void fsl_qspi_init_lut(struct fsl_qspi *q)
+{
+	void __iomem *base = q->iobase;
+	int i;
+
+	fsl_qspi_unlock_lut(q);
+
+	/* Clear all LUT table, except LUT0. LUT0 programmed by bootloader */
+	for (i = 4; i < QUADSPI_LUT_NUM; i++)
+		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +546,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +698,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +742,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -794,9 +807,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	return 0;
 }
 
@@ -820,6 +830,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +845,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +855,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +873,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +890,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +940,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From broonie at kernel.org  Wed Jan  3 03:49:31 2018
From: broonie at kernel.org (Mark Brown)
Date: Wed, 3 Jan 2018 11:49:31 +0000
Subject: [PATCH 0/3] mtd: spi-nor: fix DMA-unsafe buffer issue between
 MTD and SPI
In-Reply-To: <1514405711.26695.67.camel@impinj.com>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <1514313927.26695.19.camel@impinj.com>
 <20171227103609.GQ1827@finisterre>
 <1514405711.26695.67.camel@impinj.com>
Message-ID: <20180103114931.GF5603@sirena.org.uk>

On Wed, Dec 27, 2017 at 08:15:11PM +0000, Trent Piepho wrote:

> A random collection of spi master drivers will accept DMA-unsafe
> buffers in some way.  In some cases a framework like spi-nor provides
> the fixup to spi-nor master drivers (none so far) and in other cases
> (atmel-quadspi), the spi-nor master driver has its own fixes.

Everything really should be DMA safe.  The thing with skimping on the
DMA safety is that things generally won't explode every single time but
they might explode.

> What exactly is caught as DMA unsafe and what is not will of course
> vary greatly from driver to driver.  Some drivers will catch highmem
> memory while other drivers will only detect vmalloc memory.  Some will
> only catch an unsafe buffer if a specific SoC known to the driver to
> have an aliasing cache is enabled.  Some will check buffers that arrive
> via the spi_flash_read interface but not via generic spi transfers,
> while others will check all spi transfer buffers.

As I keep saying here the real fix would be to have a simple API that we
could use to tell if we're dealing with something DMA safe.  Right now
it's a mess because you need to pass that information around through
every layer that references memory which is a pain.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20180103/e53db578/attachment.sig>

From broonie at kernel.org  Wed Jan  3 03:51:16 2018
From: broonie at kernel.org (Mark Brown)
Date: Wed, 3 Jan 2018 11:51:16 +0000
Subject: [PATCH 2/3] dt-bindings: mtd: atmel-quadspi: add an optional
 property 'dmacap,memcpy'
In-Reply-To: <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <143542c61ca674d53da4985bbabc142e8e6ebefc.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <20171226232330.trljk2ofyvu4ly3n@rob-hp-laptop>
 <0149ba05-64b1-2739-e61f-78d5170775fb@wedev4u.fr>
Message-ID: <20180103115116.GG5603@sirena.org.uk>

On Wed, Dec 27, 2017 at 10:40:00PM +0100, Cyrille Pitchen wrote:
> Le 27/12/2017 ? 00:23, Rob Herring a ?crit :
> > On Sun, Dec 24, 2017 at 05:36:05AM +0100, Cyrille Pitchen wrote:

> >> +Optional properties:
> >> +- dmacap,memcpy:  Reserve a DMA channel to perform DMA memcpy() between the
> >> +                  system memory and the QSPI mapped memory.

> > How is this a h/w property? Why would I not want to always enable DMA if 
> > possible?

> The number of DMA channels is limited for a given SoC. This number may be
> lower than the number of enabled controllers (spi, i2c, qspi, aes, sha,
> des, sdmmc, usart, ...).

> So we use a DT property to explicitly tell the matching drivers to request
> and reserved the DMA channels they need. This policy is not driver or even
> SoC specific but board specific. It's very common to reserved DMA channels
> for the most used or most performance dependent controllers, setting the
> relevant properties in the device-tree then restricting remaining
> controllers to their PIO mode.

Why can't we just time share the DMA channels at runtime, why do we need
this static allocation?  
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20180103/5c64fe2b/attachment.sig>

From arnd at arndb.de  Wed Jan  3 08:14:59 2018
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 3 Jan 2018 17:14:59 +0100
Subject: [PATCH v3 00/27] kill devm_ioremap_nocache
In-Reply-To: <c28ac0bc-8bd2-3dce-3167-8c0f80ec601e@c-s.fr>
References: <1514026525-32538-1-git-send-email-xieyisheng1@huawei.com>
 <20171223134831.GB10103@kroah.com>
 <f7632cf5-2bcc-4d74-b912-3999937a1269@roeck-us.net>
 <c28ac0bc-8bd2-3dce-3167-8c0f80ec601e@c-s.fr>
Message-ID: <CAK8P3a3i0bKvG56ha9_hzO=z80sVxCQhaeFn6QW3AwbwZs3HPg@mail.gmail.com>

On Sun, Dec 24, 2017 at 9:55 AM, christophe leroy
<christophe.leroy at c-s.fr> wrote:
> Le 23/12/2017 ? 16:57, Guenter Roeck a ?crit :
>>
>> On 12/23/2017 05:48 AM, Greg KH wrote:
>>>
>>> On Sat, Dec 23, 2017 at 06:55:25PM +0800, Yisheng Xie wrote:
>>>>
>>>> Hi all,
>>>>
>>>> When I tried to use devm_ioremap function and review related code, I
>>>> found
>>>> devm_ioremap and devm_ioremap_nocache is almost the same with each
>>>> other,
>>>> except one use ioremap while the other use ioremap_nocache.
>>>
>>>
>>> For all arches?  Really?  Look at MIPS, and x86, they have different
>>> functions.
>>>
>>
>> Both mips and x86 end up mapping the same function, but other arches
>> don't.
>> mn10300 is one where ioremap and ioremap_nocache are definitely different.
>
>
> alpha: identical
> arc: identical
> arm: identical
> arm64: identical
> cris: different        <==
> frv: identical
> hexagone: identical
> ia64: different        <==
> m32r: identical
> m68k: identical
> metag: identical
> microblaze: identical
> mips: identical
> mn10300: different     <==
> nios: identical
> openrisc: different    <==
> parisc: identical
> riscv: identical
> s390: identical
> sh: identical
> sparc: identical
> tile: identical
> um: rely on asm/generic
> unicore32: identical
> x86: identical
> asm/generic (no mmu): identical
>
> So 4 among all arches seems to have ioremap() and ioremap_nocache() being
> different.
>
> Could we have a define set by the 4 arches on which ioremap() and
> ioremap_nocache() are different, something like
> HAVE_DIFFERENT_IOREMAP_NOCACHE ?

I wonder if those are actually correct or not. What I found looking at
those architectures:

- openrisc only has one driver using ioremap (drivers/net/ethernet/ethoc.c)
  and that calls ioremap_nocache(). Presumably the authors went with the
  implementation for ioremap that made sense (using default attributes)
  rather than the one that actually works (using uncached).

- On ia64, ioremap() checks the attributes for the physical
  address based on firmware tables and then picks either cached
  or uncached mappings. ioremap_nocache() does the same but
  returns NULL instead of a cached mapping for anything that is
  not an MMIO address. Presumably it would just work to always
  call ioremap().

- mn10300 appears to be wrong, broken by David Howells in
  commit 83c2dc15ce82 ("MN10300: Handle cacheable PCI regions
  in pci_iomap()") for any driver calling ioremap() by to get uncached
  memory, if I understand the comment for commit 34f1bdee1910
   ("mn10300: switch to GENERIC_PCI_IOMAP") correctly: it
  seems that PCI addresses include the 'uncached' bit by default
  to get the right behavior, but dropping that bit breaks it.

- cris seems similar to mn10300 in hardware, using an phys address
  bit for uncached access. There are two callers in arch code that
  appear to rely on the cachable output of ioremap()
arch/cris/arch-v32/kernel/signal.c:
__ioremap_prot(virt_to_phys(data), PAGE_SIZE, PAGE_SIGNAL_TRAMPOLINE);
arch/cris/arch-v32/mm/intmem.c:         intmem_virtual =
ioremap(MEM_INTMEM_START + RESERVED_SIZE,
  It's unclear whether ioremap_nocache() actually has any users
  on cris, or whether it was only added for compile-time testing,
  and calling plain ioremap() would always work too (assuming we
  pass the phys address with the uncached-bit set).

       Arnd


From boris.brezillon at free-electrons.com  Wed Jan  3 08:46:14 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 3 Jan 2018 17:46:14 +0100
Subject: [PATCH v6 00/15] A SPI NAND framework under generic NAND framework
In-Reply-To: <CAAyFORK9v-V1WrJzTnKk0sAt7_f_st_PHc6nJ6dz0zTL-Jih5A@mail.gmail.com>
References: <20170529225931.226da943@bbrezillon>
 <A0FE66EC-7E17-43BE-9B66-896F112B92A0@micron.com>
 <20171205135804.478902dc@bbrezillon>
 <20171205140313.40f3f17d@bbrezillon>
 <256b4ab6-c104-4580-87cd-527178bde460@exceet.de>
 <20171213222710.32d12514@bbrezillon>
 <CAAyFORJcT1abbo21iA4cetLKmF0zE4akFGFryxPpwPO+730LDQ@mail.gmail.com>
 <20171214085036.436b4fcf@bbrezillon>
 <CAAyFOR+=JwTRTm2MXVdMy7KRPsnV8LV4t71kHUh_s=+QOsVurA@mail.gmail.com>
 <23d17416-e555-4b92-cc47-f644fbe676c6@exceet.de>
 <20171214163848.41f6d277@bbrezillon>
 <CAAyFORKeFq+=tF9AK+8hp6GYYiyp3DKcw8+LWrC3RWS2zLNU_w@mail.gmail.com>
 <CAAyFORJEuEaHDXgk+m0ax5RoZ-3cRJs6uFXw7syR4vHE1veEwQ@mail.gmail.com>
 <a06312e4-a7e6-8b7b-9eb5-8320302dcc55@exceet.de>
 <CAAyFORL6mUFXFRvku6sm=Pj2=+Bf4wSV7EoBM_7+wRdPrF-ufw@mail.gmail.com>
 <CAAyFOR+m7GvXU66XKphu+cETP9SQTJ6GuZQEZQA600MX1R6cYw@mail.gmail.com>
 <20171222145147.3697fb02@bbrezillon>
 <CAAyFORK9v-V1WrJzTnKk0sAt7_f_st_PHc6nJ6dz0zTL-Jih5A@mail.gmail.com>
Message-ID: <20180103174614.6d760b3d@bbrezillon>

On Tue, 2 Jan 2018 10:51:25 +0800
Peter Pan <peterpansjtu at gmail.com> wrote:

> Hi Boris,
> 
> 
> On Fri, Dec 22, 2017 at 9:51 PM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Fri, 22 Dec 2017 14:37:06 +0800
> > Peter Pan <peterpansjtu at gmail.com> wrote:
> >  
> >> Hi Boris and Frieder
> >>
> >> On Fri, Dec 22, 2017 at 8:49 AM, Peter Pan <peterpansjtu at gmail.com> wrote:  
> >> > Hi Frieder,
> >> >
> >> > On Thu, Dec 21, 2017 at 7:48 PM, Frieder Schrempf
> >> > <frieder.schrempf at exceet.de> wrote:  
> >> >> Hello Boris,
> >> >>  
> >> >>>>>> So shouldn't there be an spinand_die_select_op in the SPI NAND core
> >> >>>>>> that
> >> >>>>>> is executed when necessary and skipped if there's only one die.  
> >> >>>>>
> >> >>>>>
> >> >>>>> Sure, I was arguing against a ->select_chip() at the generic NAND
> >> >>>>> level. That's something you can add in the SPI NAND framework.  
> >> >>
> >> >>
> >> >> I added an op to send the die selection command and call it, where I think
> >> >> it is needed: [1]  
> >> >
> >> > I think we should add die_select_op in vendor's file and call a hook in core.c
> >> > since the die select command implementation is different by vendors.
> >> >
> >> > Thanks
> >> > Peter Pan
> >> >
> >> >  
> >> >>
> >> >> Accessing both dies on the Winbond SPI NAND works fine like this.
> >> >>
> >> >> While running tests I came across some problems:
> >> >>
> >> >> * On accessing the BBT in RAM via nanddev_bbt_[set/get]_block_status, the
> >> >> calculation of position and offset seems to be wrong.
> >> >> My fix is here: [2]
> >> >>
> >> >> * On calculating the row address for read/program/erase via
> >> >> nanddev_pos_to_row, it seems like the eraseblock_addr_shift is wrong.
> >> >>
> >> >> * Also, I'm not sure if the LUN should be taken into account when
> >> >> calculating the row address. At least when you select the LUN by issuing a
> >> >> separate command, the row address sent to the chip should only contain the
> >> >> page address.
> >> >> But I'm not sure if that's the case in general, or if some code is needed to
> >> >> differentiate.
> >> >>
> >> >> See my changes of nanddev_pos_to_row here: [3]
> >> >>
> >> >> * I run into a mutex deadlock, when spinand_write_page fails (e.g. because
> >> >> of a bad block) as the lock is not released in such cases. See my fix here:
> >> >> [4]
> >> >>
> >> >> With these fixes applied and as far as I can tell everything seems to work
> >> >> fine. I'll do some tests with UBI next and look into the ECC topic.  
> >>
> >> UBI attach failed since missing mtd->writebufsize assignment in nanddev_init()
> >> After fixing it and with Frieder's fixing, UBIFS can be mounted successfully on
> >> Zedboard with generic spi controller and Micron SPI NAND 2Gb device.
> >>
> >> Also, the code now can pass mtd read and page test. 1 error found in oob test
> >> since we don't have "past end of partition" check in part_write_oob() which I
> >> mentioned in earlier mail. Since we don't support ECC right now, I didn't try
> >> nandbiterror test.
> >>  
> >
> > Peter, Frider, I just pushed a new version to my nand/spi-nand branch
> > [1] fixing the authorship, adding/fixing/removing comments where needed.
> >
> > Can you please have a look at those changes (everything I changed
> > should appear as !fixup commits) and let me know if I did something
> > wrong.  
> 
> You forgot to initialize mtd->writebufsize and mtd->oobavail.
> For mtd->writebufsize I think we can do it in nanddev_init() like below:
> 
> --- a/drivers/mtd/nand/core.c
> +++ b/drivers/mtd/nand/core.c
> @@ -196,7 +196,9 @@ int nanddev_init(struct nand_device *nand, const
> struct nand_ops *ops,
>         mtd->flags = MTD_CAP_NANDFLASH;
>         mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock;
>         mtd->writesize = memorg->pagesize;
> +       mtd->writebufsize = mtd->writesize;
>         mtd->oobsize = memorg->oobsize;
>         mtd->size = nanddev_size(nand);
>         mtd->owner = owner;

I fixed it already, see [1]. Note that I haven't squashed fixup commits
yet.

> 
> For mtd->oobavail, I think we need to call some hooks in spinand_init(),
> and implement on-die ECC layout in vendor's file and HW ECC layout in
> controller's file.
> 
> What's your opinion?

Hm, I'm not so sure. spinand_init() should be called just before
registering the MTD device, so by that time everything should have been
setup correctly by the upper layer. This being said, I'd like to keep a
clear separation between the MTD and NAND layers, and this means
preventing any NAND sub-layer from directly manipulating the MTD device
and its fields.

Really, I don't know yet how I want to abstract ECC stuff, so let's
keep it simple for now and expose the whole OOB area (I'll fix the core
to do that if you're okay).

> 
> With the two thing fixed, we can pass UBIFS mount and mtd test.

Do you still have the problem you reported earlier (OOB test)?

Thanks,

Boris

[1]https://github.com/bbrezillon/linux-0day/commit/32eeea1c35bfdc2ac0fcea599f6a926c94b835bb



From robh+dt at kernel.org  Wed Jan  3 10:28:58 2018
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 3 Jan 2018 12:28:58 -0600
Subject: [PATCH V6 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180103105543.17897-1-zajec5@gmail.com>
References: <20180102130458.16226-1-zajec5@gmail.com>
 <20180103105543.17897-1-zajec5@gmail.com>
Message-ID: <CAL_JsqLYjUsWGAYm978oPmMAue6YDRb=K00gReZTia6iaJ6xsA@mail.gmail.com>

On Wed, Jan 3, 2018 at 4:55 AM, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Brian Norris <computersforpeace at gmail.com>
>
> Partition parsers can now provide an of_match_table to enable
> flash<-->parser matching via device tree as documented in the
> mtd/partition.txt.
>
> It works by looking for a matching parser for every string in the
> "compatibility" property (starting with the most specific one).
>
> This support is currently limited to built-in parsers as it uses
> request_module() and friends. This should be sufficient for most cases
> though as compiling parsers as modules isn't a common choice.
>
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> This is based on Brian's patches:
> [RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
> [RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
>
> V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
>     Merge helpers into a single of_mtd_match_mtd_parser
> V3: Add a simple comment to note we will need the best match in the future
> V4: Rework new functions to pick parser with the best match
>     Move new code in parse_mtd_partitions up so it has precedence over flash
>     driver defaults and MTD defaults
> V5: Rework matching code to start checking with the most specific string in the
>     "compatibility" property.
> V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
> ---
>  drivers/mtd/mtdpart.c          | 64 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/partitions.h |  1 +
>  2 files changed, 65 insertions(+)
>
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..b11958adcf45 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -30,6 +30,7 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/err.h>
> +#include <linux/of.h>
>
>  #include "mtdcore.h"
>
> @@ -880,6 +881,48 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
>  }
>
>  /**
> + * mtd_part_get_parser_by_cp - find MTD parser by a compatible string

What's "cp"? Perhaps mtd_part_get_compatible_parser.

> + *
> + * @cp: compatible string describing partitions in a device tree

"compat" would be clearer IMO

> + *
> + * MTD parsers can specify supported partitions by providing a table of
> + * compatibility strings. This function finds a parser that advertises support
> + * for a passed value of "compatible".
> + */
> +static struct mtd_part_parser *mtd_part_get_parser_by_cp(const char *cp)
> +{
> +       struct mtd_part_parser *p, *ret = NULL;
> +
> +       spin_lock(&part_parser_lock);
> +
> +       list_for_each_entry(p, &part_parsers, list) {
> +               const struct of_device_id *matches;
> +
> +               matches = p->of_match_table;
> +               if (!matches)
> +                       continue;
> +
> +               for (; matches->name[0] || matches->type[0] || matches->compatible[0];
> +                    matches++) {
> +                       if (!matches->compatible[0])
> +                               continue;

It would be simpler to just ignore name and type. Having either of
those would be an error and the only consequence if there are entries
without compatible is returning early.

> +                       if (!strcmp(matches->compatible, cp) &&
> +                           try_module_get(p->owner)) {
> +                               ret = p;
> +                               break;
> +                       }
> +               }
> +
> +               if (ret)
> +                       break;
> +       }
> +
> +       spin_unlock(&part_parser_lock);
> +
> +       return ret;
> +}
> +
> +/**
>   * parse_mtd_partitions - parse MTD partitions
>   * @master: the master partition (describes whole MTD device)
>   * @types: names of partition parsers to try or %NULL
> @@ -905,8 +948,29 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
>                          struct mtd_part_parser_data *data)
>  {
>         struct mtd_part_parser *parser;
> +       struct device_node *np;
> +       struct property *prop;
> +       const char *cp;
>         int ret, err = 0;
>
> +       np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
> +       if (np) {

You can drop this. of_property_for_each_string and of_node_put will
work if np is NULL.

> +               of_property_for_each_string(np, "compatible", prop, cp) {
> +                       parser = mtd_part_get_parser_by_cp(cp);
> +                       if (!parser)
> +                               continue;
> +                       ret = mtd_part_do_parse(parser, master, pparts, data);
> +                       if (ret > 0) {
> +                               of_node_put(np);
> +                               return 0;
> +                       }
> +                       mtd_part_parser_put(parser);
> +                       if (ret < 0 && !err)
> +                               err = ret;
> +               }
> +               of_node_put(np);
> +       }
> +
>         if (!types)
>                 types = default_mtd_part_types;
>
> diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
> index c4beb70dacbd..11cb0c50cd84 100644
> --- a/include/linux/mtd/partitions.h
> +++ b/include/linux/mtd/partitions.h
> @@ -77,6 +77,7 @@ struct mtd_part_parser {
>         struct list_head list;
>         struct module *owner;
>         const char *name;
> +       const struct of_device_id *of_match_table;

I generally like using of_device_id over just an array of strings, but
I'm wondering if there's really cases where you have multiple
compatible strings for a single parser? Perhaps a single string here
would be sufficient. And if you did have multiple matches, how would
you distinguish them later on in the parsing functions? Normally we'd
use the matched data ptr, but that's not provided here.

>         int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
>                         struct mtd_part_parser_data *);
>         void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
> --
> 2.11.0
>


From robert.jarzmik at free.fr  Wed Jan  3 11:58:29 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 03 Jan 2018 20:58:29 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180103084037.422b239a@xps13> (Miquel RAYNAL's message of "Wed, 
 3 Jan 2018 08:40:37 +0100")
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon> <877etkecig.fsf@belgarion.home>
 <20171218092535.2ca1fe13@xps13> <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon> <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon> <20171222233730.68d9cb9d@xps13>
 <87k1xdblxf.fsf@belgarion.home> <20171223155709.2ba16e95@xps13>
 <87fu81bc45.fsf@belgarion.home> <20180102120326.7a2cf1d1@xps13>
 <87d12scbiy.fsf@belgarion.home> <20180103084037.422b239a@xps13>
Message-ID: <878tded89m.fsf@belgarion.home>

Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:

> On Tue, 02 Jan 2018 20:21:09 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
>
>> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
>> 
>> > I think the ECC issue you faced was related to pages being written
>> > *and* empty. If this guess is right, the board should boot fine with
>> > these changes.
>> >
>> > Otherwise, please add the DEBUG define as before in both the core
>> > and the driver and do not hesitate to add another dump_stack()
>> > where it crashes (if applicable).  
>> 
>> The problem looks still the same :
>> [    3.560163] Bad block table not found for chip 0
>
> Mmmmh ok.
>
> Can you please add this patch:
> http://code.bulix.org/61at9p-254626

Well, it looks a bit better, see attached log in [1].
Now the BBT is detected ...
[    3.310841] Bad block table found at page 131008, version 0x01
...
[    3.354944] Bad block table found at page 130944, version 0x01

But all blocks are considered bad ... as if the bit logic was inverted for the
meaning of "bad" or "good" block, see :
[    3.379825] nand_read_bbt: bad block at 0x000000000000

Cheers.

--
Robert

[1] Dmesg
---8>---
netconsole: port not set
netconsole: registered as netconsole-1
smc91c111 smc91c1110: chip is revision= 9, version= 2
mdio_bus: miibus0: probed
eth0: got preset MAC address: 00:0e:0c:a7:26:f7
nand: NAND device: Manufacturer ID: 0x20, Chip ID: 0xba (ST Micro NAND 256MiB 1,8V 16-bit), 256MiB, page size: 2048, OOB size: 64
mrvl_nand mrvl_nand0: ECC strength 1, ECC step size 512
Bad block table found at page 131008, version 0x01
Bad block table found at page 130944, version 0x01
malloc space: 0x83700000 -> 0x83efffff (size 8 MiB)
running /env/bin/init...
magicvar: No such file or directory
magicvar: No such file or directory
magicvar: No such file or directory

Hit any key to stop autoboot:  3 2 1 0
booting net
netconsole: netconsole initialized with 255.255.255.255:6662
eth0: 100Mbps full duplex link detected
DHCP client bound to address 192.168.1.232
netconsole: netconsole initialized with 255.255.255.255:6662
could not open /mnt/tftp/none-linux-zylonite: No such file or directory
Booting net failed: No such file or directory
booting net failed: No such file or directory
boot: No such file or directory
.[1;32mbarebox at .[1;36mZylonite:/.[0m global linux.bootargs.debug=earlycon
.[1;32mbarebox at .[1;36mZylonite:/.[0m bootm /mnt/tftp/zImage_jenkins

Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
arch_number: 1233
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.15.0-rc1-00044-gb6124ba (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #825 PREEMPT Wed Jan 3 20:06:17 CET 2018
[    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] Memory policy: Data cache writeback
[    0.000000] RO Mode clock: 0.00MHz
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] System bus clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] random: fast init done
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56856K/65536K available (4225K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc04289e8   (4227 kB)
[    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
[    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
[    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
[    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
[    0.000068] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
[    0.000267] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
[    0.002138] Console: colour dummy device 80x30
[    0.002297] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
[    0.081017] pid_max: default: 32768 minimum: 301
[    0.081857] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.081957] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.085169] CPU: Testing write buffer coherency: ok
[    0.088982] Setting up static identity map for 0x80008200 - 0x80008260
[    0.089941] Hierarchical SRCU implementation.
[    0.102960] devtmpfs: initialized
[    0.113840] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.113980] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.116305] NET: Registered protocol family 16
[    0.119116] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.388612] Advanced Linux Sound Architecture Driver Initialized.
[    0.392974] clocksource: Switched to clocksource oscr0
[    0.551626] NET: Registered protocol family 2
[    0.557926] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.558151] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.558332] TCP: Hash tables configured (established 1024 bind 1024)
[    0.558869] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.559048] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.560201] NET: Registered protocol family 1
[    0.562229] RPC: Registered named UNIX socket transport module.
[    0.562327] RPC: Registered udp transport module.
[    0.562381] RPC: Registered tcp transport module.
[    0.562439] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.500715] Initialise system trusted keyrings
[    2.502868] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    2.507406] NFS: Registering the id_resolver key type
[    2.507634] Key type id_resolver registered
[    2.507695] Key type id_legacy registered
[    2.514199] Key type asymmetric registered
[    2.514303] Asymmetric key parser 'x509' registered
[    2.514462] io scheduler noop registered
[    2.514527] io scheduler deadline registered
[    2.514921] io scheduler cfq registered (default)
[    2.514992] io scheduler mq-deadline registered
[    2.515054] io scheduler kyber registered
[    2.572587] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
[    2.578330] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
[    3.053207] console [ttyS0] enabled
[    3.059557] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
[    3.072069] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
[    3.088037] nand: executing subop:
[    3.091533] nand:     ->CMD      [0xff]
[    3.098135] nand:     ->WAITRDY  [max 250 ms]
[    3.102636] marvell-nfc pxa3xx-nand: 
[    3.102636] NDCR:  0x90079fff
[    3.102636] NDCB0: 0x00a000ff
[    3.102636] NDCB1: 0x00000000
[    3.102636] NDCB2: 0x00000000
[    3.102636] NDCB3: 0x00000000
[    3.121629] nand: executing subop:
[    3.125459] nand:     ->CMD      [0x90]
[    3.129362] nand:     ->ADDR     [1 cyc: 00]
[    3.134355] nand:     ->DATA_IN  [2 B, force 8-bit]
[    3.139366] marvell-nfc pxa3xx-nand: 
[    3.139366] NDCR:  0x90079fff
[    3.139366] NDCB0: 0x00610090
[    3.139366] NDCB1: 0x00000000
[    3.139366] NDCB2: 0x00000000
[    3.139366] NDCB3: 0x00000000
[    3.158242] nand: executing subop:
[    3.161713] nand:     ->CMD      [0x90]
[    3.165930] nand:     ->ADDR     [1 cyc: 00]
[    3.170250] nand:     ->DATA_IN  [8 B, force 8-bit]
[    3.175405] marvell-nfc pxa3xx-nand: 
[    3.175405] NDCR:  0x90079fff
[    3.175405] NDCB0: 0x00610090
[    3.175405] NDCB1: 0x00000000
[    3.175405] NDCB2: 0x00000000
[    3.175405] NDCB3: 0x00000000
[    3.194083] nand: executing subop:
[    3.197532] nand:     ->CMD      [0x90]
[    3.201406] nand:     ->ADDR     [1 cyc: 20]
[    3.205851] nand:     ->DATA_IN  [4 B, force 8-bit]
[    3.210832] marvell-nfc pxa3xx-nand: 
[    3.210832] NDCR:  0x90079fff
[    3.210832] NDCB0: 0x00610090
[    3.210832] NDCB1: 0x00000020
[    3.210832] NDCB2: 0x00000000
[    3.210832] NDCB3: 0x00000000
[    3.229453] nand: executing subop:
[    3.232899] nand:     ->CMD      [0x90]
[    3.236930] nand:     ->ADDR     [1 cyc: 40]
[    3.241232] nand:     ->DATA_IN  [5 B, force 8-bit]
[    3.246335] marvell-nfc pxa3xx-nand: 
[    3.246335] NDCR:  0x90079fff
[    3.246335] NDCB0: 0x00610090
[    3.246335] NDCB1: 0x00000040
[    3.246335] NDCB2: 0x00000000
[    3.246335] NDCB3: 0x00000000
[    3.264978] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
[    3.271354] nand: ST Micro NAND 256MiB 1,8V 16-bit
[    3.276316] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    3.284055] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
[    3.291595] marvell-nfc pxa3xx-nand: 
[    3.291595] NDCR:  0xdd079fff
[    3.291595] NDCB0: 0x000d3000
[    3.291595] NDCB1: 0xffc00000
[    3.291595] NDCB2: 0x00000001
[    3.291595] NDCB3: 0x00000000
[    3.310841] Bad block table found at page 131008, version 0x01
[    3.316993] marvell-nfc pxa3xx-nand: 
[    3.316993] NDCR:  0xdd079fff
[    3.316993] NDCB0: 0x000d3000
[    3.316993] NDCB1: 0xffc00000
[    3.316993] NDCB2: 0x00000001
[    3.316993] NDCB3: 0x00000000
[    3.336013] marvell-nfc pxa3xx-nand: 
[    3.336013] NDCR:  0xdd079fff
[    3.336013] NDCB0: 0x000d3000
[    3.336013] NDCB1: 0xff800000
[    3.336013] NDCB2: 0x00000001
[    3.336013] NDCB3: 0x00000000
[    3.354944] Bad block table found at page 130944, version 0x01
[    3.360915] marvell-nfc pxa3xx-nand: 
[    3.360915] NDCR:  0xdd079fff
[    3.360915] NDCB0: 0x000d3000
[    3.360915] NDCB1: 0xffc00000
[    3.360915] NDCB2: 0x00000001
[    3.360915] NDCB3: 0x00000000
[    3.379825] nand_read_bbt: bad block at 0x000000000000
[    3.385158] nand_read_bbt: bad block at 0x000000040000
[    3.390320] nand_read_bbt: bad block at 0x000000060000
[    3.395587] nand_read_bbt: bad block at 0x000000080000
[    3.400743] nand_read_bbt: bad block at 0x0000000a0000
[    3.406009] nand_read_bbt: bad block at 0x0000000c0000
[    3.411169] nand_read_bbt: bad block at 0x0000000e0000
[    3.416434] nand_read_bbt: bad block at 0x000000100000
[    3.421593] nand_read_bbt: bad block at 0x000000140000
[    3.426859] nand_read_bbt: bad block at 0x000000160000
[    3.432018] nand_read_bbt: bad block at 0x000000180000
[    3.437283] nand_read_bbt: bad block at 0x0000001a0000
[    3.442442] nand_read_bbt: bad block at 0x0000001c0000
[    3.447707] nand_read_bbt: bad block at 0x0000001e0000
[    3.452867] nand_read_bbt: bad block at 0x000000200000
[    3.458133] nand_read_bbt: bad block at 0x000000220000
[    3.463404] nand_read_bbt: bad block at 0x000000240000
[    3.468564] nand_read_bbt: bad block at 0x000000260000
[    3.473830] nand_read_bbt: bad block at 0x000000280000
[    3.478990] nand_read_bbt: bad block at 0x0000002a0000
[    3.484253] nand_read_bbt: bad block at 0x0000002c0000
[    3.489414] nand_read_bbt: bad block at 0x0000002e0000
[    3.494680] nand_read_bbt: bad block at 0x000000300000
[    3.499838] nand_read_bbt: bad block at 0x000000320000
[    3.505104] nand_read_bbt: bad block at 0x000000340000
[    3.510262] nand_read_bbt: bad block at 0x000000360000
[    3.515529] nand_read_bbt: bad block at 0x000000380000
[    3.520687] nand_read_bbt: bad block at 0x0000003a0000
[    3.525955] nand_read_bbt: bad block at 0x0000003c0000
[    3.531121] nand_read_bbt: bad block at 0x0000003e0000
[    3.536386] nand_read_bbt: bad block at 0x000000400000
[    3.541544] nand_read_bbt: bad block at 0x000000420000
[    3.546811] nand_read_bbt: bad block at 0x000000440000
[    3.551970] nand_read_bbt: bad block at 0x000000460000
[    3.557234] nand_read_bbt: bad block at 0x000000480000
[    3.562394] nand_read_bbt: bad block at 0x0000004a0000
[    3.567659] nand_read_bbt: bad block at 0x0000004c0000
[    3.572819] nand_read_bbt: bad block at 0x0000004e0000
[    3.578087] nand_read_bbt: bad block at 0x000000500000
[    3.583367] nand_read_bbt: bad block at 0x000000520000
[    3.588524] nand_read_bbt: bad block at 0x000000540000
[    3.593788] nand_read_bbt: bad block at 0x000000560000
[    3.598951] nand_read_bbt: bad block at 0x000000580000
[    3.604213] nand_read_bbt: bad block at 0x0000005a0000
[    3.609373] nand_read_bbt: bad block at 0x0000005c0000
[    3.614639] nand_read_bbt: bad block at 0x0000005e0000
[    3.619799] nand_read_bbt: bad block at 0x000000600000
[    3.625064] nand_read_bbt: bad block at 0x000000620000
[    3.630224] nand_read_bbt: bad block at 0x000000640000
[    3.635488] nand_read_bbt: bad block at 0x000000660000
[    3.640648] nand_read_bbt: bad block at 0x000000680000
[    3.645914] nand_read_bbt: bad block at 0x0000006a0000
[    3.651071] nand_read_bbt: bad block at 0x0000006c0000
[    3.656337] nand_read_bbt: bad block at 0x0000006e0000
[    3.661497] nand_read_bbt: bad block at 0x000000700000
[    3.666774] nand_read_bbt: bad block at 0x000000d40000
[    3.671939] nand_read_bbt: bad block at 0x000000d60000
[    3.677206] nand_read_bbt: bad block at 0x000000d80000
[    3.682373] nand_read_bbt: bad block at 0x000000da0000
[    3.687638] nand_read_bbt: bad block at 0x000000dc0000
[    3.692796] nand_read_bbt: bad block at 0x000000de0000
[    3.698063] nand_read_bbt: bad block at 0x000000e00000
[    3.703334] nand_read_bbt: bad block at 0x000000e20000
[    3.708494] nand_read_bbt: bad block at 0x000000e40000
[    3.713759] nand_read_bbt: bad block at 0x000000e60000
[    3.718919] nand_read_bbt: bad block at 0x000000e80000
[    3.724183] nand_read_bbt: bad block at 0x000000ea0000
[    3.729343] nand_read_bbt: bad block at 0x000000ec0000
[    3.734608] nand_read_bbt: bad block at 0x000000ee0000
[    3.739769] nand_read_bbt: bad block at 0x000000f00000
[    3.745033] nand_read_bbt: bad block at 0x000000f20000
[    3.750192] nand_read_bbt: bad block at 0x000000f40000
[    3.755459] nand_read_bbt: bad block at 0x000000f60000
[    3.760617] nand_read_bbt: bad block at 0x000000f80000
[    3.765882] nand_read_bbt: bad block at 0x000000fa0000
[    3.771041] nand_read_bbt: bad block at 0x000000fc0000
[    3.776306] nand_read_bbt: bad block at 0x000000fe0000
[    3.781467] nand_read_bbt: bad block at 0x000001000000
[    3.786731] nand_read_bbt: bad block at 0x000001020000
[    3.791891] nand_read_bbt: bad block at 0x000001040000
[    3.797156] nand_read_bbt: bad block at 0x000001060000
[    3.802317] nand_read_bbt: bad block at 0x000001080000
[    3.807582] nand_read_bbt: bad block at 0x0000010a0000
[    3.812741] nand_read_bbt: bad block at 0x0000010c0000
[    3.818005] nand_read_bbt: bad block at 0x0000010e0000
[    3.823280] nand_read_bbt: bad block at 0x000001100000
[    3.828438] nand_read_bbt: bad block at 0x000001120000
[    3.833702] nand_read_bbt: bad block at 0x000001140000
[    3.838862] nand_read_bbt: bad block at 0x000001160000
[    3.844129] nand_read_bbt: bad block at 0x000001180000
[    3.849294] nand_read_bbt: bad block at 0x000001660000
[    3.854562] nand_read_bbt: bad block at 0x000001680000
[    3.859719] nand_read_bbt: bad block at 0x0000016a0000
[    3.864986] nand_read_bbt: bad block at 0x0000016c0000
[    3.870143] nand_read_bbt: bad block at 0x0000016e0000
[    3.875409] nand_read_bbt: bad block at 0x000001700000
[    3.880569] nand_read_bbt: bad block at 0x000001720000
[    3.885836] nand_read_bbt: bad block at 0x000001740000
[    3.890994] nand_read_bbt: bad block at 0x000001760000
[    3.896260] nand_read_bbt: bad block at 0x000001780000
[    3.901417] nand_read_bbt: bad block at 0x0000017a0000
[    3.906683] nand_read_bbt: bad block at 0x0000017c0000
[    3.911843] nand_read_bbt: bad block at 0x0000017e0000
[    3.917108] nand_read_bbt: bad block at 0x000001800000
[    3.922267] nand_read_bbt: bad block at 0x000001820000
[    3.927534] nand_read_bbt: bad block at 0x000001840000
[    3.932691] nand_read_bbt: bad block at 0x000001860000
[    3.937957] nand_read_bbt: bad block at 0x000001880000
[    3.943230] nand_read_bbt: bad block at 0x0000018a0000
[    3.948390] nand_read_bbt: bad block at 0x0000018c0000
[    3.953654] nand_read_bbt: bad block at 0x0000018e0000
[    3.958815] nand_read_bbt: bad block at 0x000001900000
[    3.964101] nand_read_bbt: bad block at 0x000001920000
[    3.969264] nand_read_bbt: bad block at 0x000001940000
[    3.974531] nand_read_bbt: bad block at 0x000001960000
[    3.979690] nand_read_bbt: bad block at 0x000001980000
[    3.984952] nand_read_bbt: bad block at 0x0000019a0000
[    3.990114] nand_read_bbt: bad block at 0x0000019c0000
[    3.995381] nand_read_bbt: bad block at 0x0000019e0000
[    4.000539] nand_read_bbt: bad block at 0x000001a00000
[    4.005804] nand_read_bbt: bad block at 0x000001a20000
[    4.010964] nand_read_bbt: bad block at 0x000001a40000
[    4.016236] nand_read_bbt: bad block at 0x000001a60000
[    4.021398] nand_read_bbt: bad block at 0x000001a80000
[    4.026664] nand_read_bbt: bad block at 0x000001aa0000
[    4.031822] nand_read_bbt: bad block at 0x000001ac0000
[    4.037086] nand_read_bbt: bad block at 0x000001ae0000
[    4.042247] nand_read_bbt: bad block at 0x000001b00000
[    4.047512] nand_read_bbt: bad block at 0x000001b20000
[    4.052672] nand_read_bbt: bad block at 0x000001b40000
[    4.057935] nand_read_bbt: bad block at 0x000001b60000
[    4.063211] nand_read_bbt: bad block at 0x000001b80000
[    4.068377] nand_read_bbt: bad block at 0x000001ba0000
[    4.073643] nand_read_bbt: bad block at 0x000001bc0000
[    4.078801] nand_read_bbt: bad block at 0x000001be0000
[    4.084068] nand_read_bbt: bad block at 0x000001c00000
[    4.089235] nand_read_bbt: bad block at 0x000001c20000
[    4.094836] nand_read_bbt: bad block at 0x000001c40000
[    4.100012] nand_read_bbt: bad block at 0x000001c60000
[    4.105327] nand_read_bbt: bad block at 0x000001c80000
[    4.110488] nand_read_bbt: bad block at 0x000001ca0000
[    4.115755] nand_read_bbt: bad block at 0x000001cc0000
[    4.120923] nand_read_bbt: bad block at 0x000001ce0000
[    4.126186] nand_read_bbt: bad block at 0x000001d00000
[    4.131347] nand_read_bbt: bad block at 0x000001d20000
[    4.136610] nand_read_bbt: bad block at 0x000001d40000
[    4.141770] nand_read_bbt: bad block at 0x000001d60000
[    4.147038] nand_read_bbt: bad block at 0x000001d80000
[    4.152204] nand_read_bbt: bad block at 0x000001da0000
[    4.157470] nand_read_bbt: bad block at 0x000001dc0000
[    4.162627] nand_read_bbt: bad block at 0x000001de0000
[    4.167894] nand_read_bbt: bad block at 0x000001e00000
[    4.173167] nand_read_bbt: bad block at 0x000001e20000
[    4.178325] nand_read_bbt: bad block at 0x000001e40000
[    4.183591] nand_read_bbt: bad block at 0x000001e60000
[    4.188752] nand_read_bbt: bad block at 0x000001e80000
[    4.194015] nand_read_bbt: bad block at 0x000001ea0000
[    4.199175] nand_read_bbt: bad block at 0x000001ec0000
[    4.204441] nand_read_bbt: bad block at 0x000001ee0000
[    4.209601] nand_read_bbt: bad block at 0x000001f00000
[    4.214865] nand_read_bbt: bad block at 0x000001f20000
[    4.220024] nand_read_bbt: bad block at 0x000001f40000
[    4.225290] nand_read_bbt: bad block at 0x000001f60000
[    4.230450] nand_read_bbt: bad block at 0x000001f80000
[    4.235713] nand_read_bbt: bad block at 0x000001fa0000
[    4.240874] nand_read_bbt: bad block at 0x000001fc0000
[    4.246138] nand_read_bbt: bad block at 0x000001fe0000
[    4.251299] nand_read_bbt: bad block at 0x000002000000
[    4.256564] nand_read_bbt: bad block at 0x000002020000
[    4.261723] nand_read_bbt: bad block at 0x000002040000
[    4.266988] nand_read_bbt: bad block at 0x000002060000
[    4.272148] nand_read_bbt: bad block at 0x000002080000
[    4.277412] nand_read_bbt: bad block at 0x0000020a0000
[    4.282572] nand_read_bbt: bad block at 0x0000020c0000
[    4.287837] nand_read_bbt: bad block at 0x0000020e0000
[    4.293111] nand_read_bbt: bad block at 0x000002100000
[    4.298278] nand_read_bbt: bad block at 0x000002120000
[    4.303545] nand_read_bbt: bad block at 0x000002140000
[    4.308703] nand_read_bbt: bad block at 0x000002160000
[    4.313967] nand_read_bbt: bad block at 0x000002180000
[    4.319128] nand_read_bbt: bad block at 0x0000021a0000
[    4.324391] nand_read_bbt: bad block at 0x0000021c0000
[    4.329552] nand_read_bbt: bad block at 0x0000021e0000
[    4.334818] nand_read_bbt: bad block at 0x000002200000
[    4.339977] nand_read_bbt: bad block at 0x000002220000
[    4.345242] nand_read_bbt: bad block at 0x000002240000
[    4.350402] nand_read_bbt: bad block at 0x000002260000
[    4.355667] nand_read_bbt: bad block at 0x000002280000
[    4.360826] nand_read_bbt: bad block at 0x0000022a0000
[    4.366091] nand_read_bbt: bad block at 0x0000022c0000
[    4.371251] nand_read_bbt: bad block at 0x0000022e0000
[    4.376515] nand_read_bbt: bad block at 0x000002300000
[    4.381674] nand_read_bbt: bad block at 0x000002320000
[    4.386941] nand_read_bbt: bad block at 0x000002340000
[    4.392101] nand_read_bbt: bad block at 0x000002360000
[    4.397365] nand_read_bbt: bad block at 0x000002380000
[    4.402523] nand_read_bbt: bad block at 0x0000023a0000
[    4.407789] nand_read_bbt: bad block at 0x0000023c0000
[    4.413062] nand_read_bbt: bad block at 0x0000023e0000
[    4.418223] nand_read_bbt: bad block at 0x000002400000
[    4.423485] nand_read_bbt: bad block at 0x000002420000
[    4.428646] nand_read_bbt: bad block at 0x000002440000
[    4.433907] nand_read_bbt: bad block at 0x000002460000
[    4.439071] nand_read_bbt: bad block at 0x000002480000
[    4.444336] nand_read_bbt: bad block at 0x0000024a0000
[    4.449496] nand_read_bbt: bad block at 0x0000024c0000
[    4.454759] nand_read_bbt: bad block at 0x0000024e0000
[    4.459922] nand_read_bbt: bad block at 0x000002500000
[    4.465187] nand_read_bbt: bad block at 0x000002520000
[    4.470344] nand_read_bbt: bad block at 0x000002540000
[    4.475609] nand_read_bbt: bad block at 0x000002560000
[    4.480771] nand_read_bbt: bad block at 0x000002580000
[    4.486033] nand_read_bbt: bad block at 0x0000025a0000
[    4.491194] nand_read_bbt: bad block at 0x0000025c0000
[    4.496458] nand_read_bbt: bad block at 0x0000025e0000
[    4.501619] nand_read_bbt: bad block at 0x000002600000
[    4.506882] nand_read_bbt: bad block at 0x000002620000
[    4.512042] nand_read_bbt: bad block at 0x000002640000
[    4.517307] nand_read_bbt: bad block at 0x000002660000
[    4.522468] nand_read_bbt: bad block at 0x000002680000
[    4.527732] nand_read_bbt: bad block at 0x0000026a0000
[    4.532891] nand_read_bbt: bad block at 0x0000026c0000
[    4.538162] nand_read_bbt: bad block at 0x0000026e0000
[    4.543428] nand_read_bbt: bad block at 0x000002700000
[    4.548590] nand_read_bbt: bad block at 0x000002720000
[    4.553857] nand_read_bbt: bad block at 0x000002740000
[    4.559014] nand_read_bbt: bad block at 0x000002760000
[    4.564280] nand_read_bbt: bad block at 0x000002780000
[    4.569438] nand_read_bbt: bad block at 0x0000027a0000
[    4.574705] nand_read_bbt: bad block at 0x0000027c0000
[    4.579863] nand_read_bbt: bad block at 0x0000027e0000
[    4.585129] nand_read_bbt: bad block at 0x000002800000
[    4.590288] nand_read_bbt: bad block at 0x000002820000
[    4.595558] nand_read_bbt: bad block at 0x000002a40000
[    4.600720] nand_read_bbt: bad block at 0x000002a60000
[    4.606012] nand_read_bbt: bad block at 0x000002bc0000
[    4.611182] nand_read_bbt: bad block at 0x000002c40000
[    4.616449] nand_read_bbt: bad block at 0x000002c60000
[    4.621614] nand_read_bbt: bad block at 0x000002c80000
[    4.626878] nand_read_bbt: bad block at 0x000002ca0000
[    4.632036] nand_read_bbt: bad block at 0x000002cc0000
[    4.637301] nand_read_bbt: bad block at 0x000002ce0000
[    4.642463] nand_read_bbt: bad block at 0x000002d00000
[    4.647726] nand_read_bbt: bad block at 0x000002d20000
[    4.652888] nand_read_bbt: bad block at 0x000002d40000
[    4.658167] nand_read_bbt: bad block at 0x000002d60000
[    4.663433] nand_read_bbt: bad block at 0x000002d80000
[    4.668593] nand_read_bbt: bad block at 0x000002da0000
[    4.673859] nand_read_bbt: bad block at 0x000002dc0000
[    4.679017] nand_read_bbt: bad block at 0x000002de0000
[    4.684282] nand_read_bbt: bad block at 0x000002e00000
[    4.689442] nand_read_bbt: bad block at 0x000002e20000
[    4.694707] nand_read_bbt: bad block at 0x000002e40000
[    4.699867] nand_read_bbt: bad block at 0x000002e60000
[    4.705133] nand_read_bbt: bad block at 0x000002e80000
[    4.710292] nand_read_bbt: bad block at 0x000002ea0000
[    4.715558] nand_read_bbt: bad block at 0x000002ec0000
[    4.720716] nand_read_bbt: bad block at 0x000002ee0000
[    4.725983] nand_read_bbt: bad block at 0x000002f00000
[    4.731141] nand_read_bbt: bad block at 0x000002f20000
[    4.736406] nand_read_bbt: bad block at 0x000002f40000
[    4.741566] nand_read_bbt: bad block at 0x000002f60000
[    4.746830] nand_read_bbt: bad block at 0x000002f80000
[    4.751991] nand_read_bbt: bad block at 0x000002fa0000
[    4.757255] nand_read_bbt: bad block at 0x000002fc0000
[    4.762415] nand_read_bbt: bad block at 0x000002fe0000
[    4.767681] nand_read_bbt: bad block at 0x000003000000
[    4.772839] nand_read_bbt: bad block at 0x000003020000
[    4.778104] nand_read_bbt: bad block at 0x000003040000
[    4.783378] nand_read_bbt: bad block at 0x000003060000
[    4.788536] nand_read_bbt: bad block at 0x000003080000
[    4.793802] nand_read_bbt: bad block at 0x0000030a0000
[    4.798962] nand_read_bbt: bad block at 0x0000030c0000
[    4.804224] nand_read_bbt: bad block at 0x0000030e0000
[    4.809387] nand_read_bbt: bad block at 0x000003100000
[    4.814650] nand_read_bbt: bad block at 0x000003120000
[    4.819809] nand_read_bbt: bad block at 0x000003140000
[    4.825075] nand_read_bbt: bad block at 0x000003160000
[    4.830235] nand_read_bbt: bad block at 0x000003180000
[    4.835499] nand_read_bbt: bad block at 0x0000031a0000
[    4.840661] nand_read_bbt: bad block at 0x0000031c0000
[    4.845924] nand_read_bbt: bad block at 0x0000031e0000
[    4.851085] nand_read_bbt: bad block at 0x000003200000
[    4.856350] nand_read_bbt: bad block at 0x000003220000
[    4.861510] nand_read_bbt: bad block at 0x000003240000
[    4.867593] 6 cmdlinepart partitions found on MTD device pxa3xx_nand-0
[    4.874441] Creating 6 MTD partitions on "pxa3xx_nand-0":
[    4.879899] 0x000000000000-0x000000020000 : "TIMH"
[    4.888233] 0x000000020000-0x000000040000 : "OBMI"
[    4.897663] 0x000000040000-0x000000100000 : "barebox"
[    4.907444] 0x000000100000-0x000000140000 : "barebox-env"
[    4.917447] 0x000000140000-0x000000d40000 : "kernel"
[    4.927958] 0x000000d40000-0x000003260000 : "root"
[    4.941349] smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico at fluxnic.net>
[    4.994377] smc91x smc91x.0 eth0: SMC91C11xFD (rev 2) at c4867300 IRQ 214
[    5.001216]  DMA c386d710 [nowait]
[    5.005891] smc91x smc91x.0 eth0: Ethernet addr: 00:0e:0c:a7:26:f7
[    5.018621] input: pxa27x-keypad as /devices/platform/pxa27x-keypad/input/input0
[    5.028503] pxa-rtc pxa-rtc: failed to find rtc clock source
[    5.036108] rtc rtc0: invalid alarm value: 0-1-1 0:0:0
[    5.043390] pxa-rtc pxa-rtc: rtc core: registered pxa-rtc as rtc0
[    5.054574] sa1100_wdt: SA1100/PXA2xx Watchdog Timer: timer margin 60 sec
[    5.106260] soc-audio soc-audio: ASoC: machine Zylonite should use snd_soc_register_card()
[    5.130166] wm9713-codec wm9713-codec: Control not supported for path Mic B Source -> [MPB] -> Mic B Pre Amp
[    5.141137] wm9713-codec wm9713-codec: ASoC: no dapm match for Mic B Source --> MPB --> Mic B Pre Amp
[    5.150835] wm9713-codec wm9713-codec: ASoC: Failed to add route Mic B Source -> MPB -> Mic B Pre Amp
[    5.164361] soc-audio soc-audio: wm9713-hifi <-> pxa2xx-ac97 mapping ok
[    5.172711] soc-audio soc-audio: wm9713-aux <-> pxa2xx-ac97-aux mapping ok
[    5.183377] soc-audio soc-audio: wm9713-voice <-> pxa-ssp-dai.2 mapping ok
[    5.191817] wm9713-codec wm9713-codec: ASoC: mux Sidetone Mux has no paths
[    5.232193] NET: Registered protocol family 17
[    5.238583] Key type dns_resolver registered
[    5.244879] XScale iWMMXt coprocessor detected.
[    5.257208] Loading compiled-in X.509 certificates
[    5.277841] ubi0: attaching mtd5
[    5.282062] marvell-nfc pxa3xx-nand: 
[    5.282062] NDCR:  0xdd079fff
[    5.282062] NDCB0: 0x000d3000
[    5.282062] NDCB1: 0x23400000
[    5.282062] NDCB2: 0x00000000
[    5.282062] NDCB3: 0x00000000
[    5.302767] marvell-nfc pxa3xx-nand: 
[    5.302767] NDCR:  0xdd079fff
[    5.302767] NDCB0: 0x000d3000
[    5.302767] NDCB1: 0x23410000
[    5.302767] NDCB2: 0x00000000
[    5.302767] NDCB3: 0x00000000
[    5.322069] marvell-nfc pxa3xx-nand: 
[    5.322069] NDCR:  0x9d079fff
[    5.322069] NDCB0: 0x000d3000
[    5.322069] NDCB1: 0x23410000
[    5.322069] NDCB2: 0x00000000
[    5.322069] NDCB3: 0x00000000
[    5.341520] marvell-nfc pxa3xx-nand: 
[    5.341520] NDCR:  0xdd079fff
[    5.341520] NDCB0: 0x000d3000
[    5.341520] NDCB1: 0x23800000
[    5.341520] NDCB2: 0x00000000
[    5.341520] NDCB3: 0x00000000
[    5.361115] marvell-nfc pxa3xx-nand: 
[    5.361115] NDCR:  0xdd079fff
[    5.361115] NDCB0: 0x000d3000
[    5.361115] NDCB1: 0x23810000
[    5.361115] NDCB2: 0x00000000
[    5.361115] NDCB3: 0x00000000
[    5.380361] marvell-nfc pxa3xx-nand: 
[    5.380361] NDCR:  0x9d079fff
[    5.380361] NDCB0: 0x000d3000
[    5.380361] NDCB1: 0x23810000
[    5.380361] NDCB2: 0x00000000
[    5.380361] NDCB3: 0x00000000
[    5.399699] marvell-nfc pxa3xx-nand: 
[    5.399699] NDCR:  0xdd079fff
[    5.399699] NDCB0: 0x000d3000
[    5.399699] NDCB1: 0x23c00000
[    5.399699] NDCB2: 0x00000000
[    5.399699] NDCB3: 0x00000000
[    5.418790] marvell-nfc pxa3xx-nand: 
[    5.418790] NDCR:  0xdd079fff
[    5.418790] NDCB0: 0x000d3000
[    5.418790] NDCB1: 0x23c10000
[    5.418790] NDCB2: 0x00000000
[    5.418790] NDCB3: 0x00000000
[    5.437771] marvell-nfc pxa3xx-nand: 
[    5.437771] NDCR:  0x9d079fff
[    5.437771] NDCB0: 0x000d3000
[    5.437771] NDCB1: 0x23c10000
[    5.437771] NDCB2: 0x00000000
[    5.437771] NDCB3: 0x00000000
[    5.456876] marvell-nfc pxa3xx-nand: 
[    5.456876] NDCR:  0xdd079fff
[    5.456876] NDCB0: 0x000d3000
[    5.456876] NDCB1: 0x24000000
[    5.456876] NDCB2: 0x00000000
[    5.456876] NDCB3: 0x00000000
[    5.475940] marvell-nfc pxa3xx-nand: 
[    5.475940] NDCR:  0xdd079fff
[    5.475940] NDCB0: 0x000d3000
[    5.475940] NDCB1: 0x24010000
[    5.475940] NDCB2: 0x00000000
[    5.475940] NDCB3: 0x00000000
[    5.494922] marvell-nfc pxa3xx-nand: 
[    5.494922] NDCR:  0x9d079fff
[    5.494922] NDCB0: 0x000d3000
[    5.494922] NDCB1: 0x24010000
[    5.494922] NDCB2: 0x00000000
[    5.494922] NDCB3: 0x00000000
[    5.514028] marvell-nfc pxa3xx-nand: 
[    5.514028] NDCR:  0xdd079fff
[    5.514028] NDCB0: 0x000d3000
[    5.514028] NDCB1: 0x24400000
[    5.514028] NDCB2: 0x00000000
[    5.514028] NDCB3: 0x00000000
[    5.533183] marvell-nfc pxa3xx-nand: 
[    5.533183] NDCR:  0xdd079fff
[    5.533183] NDCB0: 0x000d3000
[    5.533183] NDCB1: 0x24410000
[    5.533183] NDCB2: 0x00000000
[    5.533183] NDCB3: 0x00000000
[    5.552166] marvell-nfc pxa3xx-nand: 
[    5.552166] NDCR:  0x9d079fff
[    5.552166] NDCB0: 0x000d3000
[    5.552166] NDCB1: 0x24410000
[    5.552166] NDCB2: 0x00000000
[    5.552166] NDCB3: 0x00000000
[    5.571273] marvell-nfc pxa3xx-nand: 
[    5.571273] NDCR:  0xdd079fff
[    5.571273] NDCB0: 0x000d3000
[    5.571273] NDCB1: 0x24800000
[    5.571273] NDCB2: 0x00000000
[    5.571273] NDCB3: 0x00000000
[    5.590337] marvell-nfc pxa3xx-nand: 
[    5.590337] NDCR:  0xdd079fff
[    5.590337] NDCB0: 0x000d3000
[    5.590337] NDCB1: 0x24810000
[    5.590337] NDCB2: 0x00000000
[    5.590337] NDCB3: 0x00000000
[    5.609318] marvell-nfc pxa3xx-nand: 
[    5.609318] NDCR:  0x9d079fff
[    5.609318] NDCB0: 0x000d3000
[    5.609318] NDCB1: 0x24810000
[    5.609318] NDCB2: 0x00000000
[    5.609318] NDCB3: 0x00000000
[    5.628426] marvell-nfc pxa3xx-nand: 
[    5.628426] NDCR:  0xdd079fff
[    5.628426] NDCB0: 0x000d3000
[    5.628426] NDCB1: 0x24c00000
[    5.628426] NDCB2: 0x00000000
[    5.628426] NDCB3: 0x00000000
[    5.647489] marvell-nfc pxa3xx-nand: 
[    5.647489] NDCR:  0xdd079fff
[    5.647489] NDCB0: 0x000d3000
[    5.647489] NDCB1: 0x24c10000
[    5.647489] NDCB2: 0x00000000
[    5.647489] NDCB3: 0x00000000
[    5.666475] marvell-nfc pxa3xx-nand: 
[    5.666475] NDCR:  0x9d079fff
[    5.666475] NDCB0: 0x000d3000
[    5.666475] NDCB1: 0x24c10000
[    5.666475] NDCB2: 0x00000000
[    5.666475] NDCB3: 0x00000000
[    5.685575] marvell-nfc pxa3xx-nand: 
[    5.685575] NDCR:  0xdd079fff
[    5.685575] NDCB0: 0x000d3000
[    5.685575] NDCB1: 0x25000000
[    5.685575] NDCB2: 0x00000000
[    5.685575] NDCB3: 0x00000000
[    5.704632] marvell-nfc pxa3xx-nand: 
[    5.704632] NDCR:  0xdd079fff
[    5.704632] NDCB0: 0x000d3000
[    5.704632] NDCB1: 0x25010000
[    5.704632] NDCB2: 0x00000000
[    5.704632] NDCB3: 0x00000000
[    5.723609] marvell-nfc pxa3xx-nand: 
[    5.723609] NDCR:  0x9d079fff
[    5.723609] NDCB0: 0x000d3000
[    5.723609] NDCB1: 0x25010000
[    5.723609] NDCB2: 0x00000000
[    5.723609] NDCB3: 0x00000000
[    5.742713] marvell-nfc pxa3xx-nand: 
[    5.742713] NDCR:  0xdd079fff
[    5.742713] NDCB0: 0x000d3000
[    5.742713] NDCB1: 0x25400000
[    5.742713] NDCB2: 0x00000000
[    5.742713] NDCB3: 0x00000000
[    5.761769] marvell-nfc pxa3xx-nand: 
[    5.761769] NDCR:  0xdd079fff
[    5.761769] NDCB0: 0x000d3000
[    5.761769] NDCB1: 0x25410000
[    5.761769] NDCB2: 0x00000000
[    5.761769] NDCB3: 0x00000000
[    5.780750] marvell-nfc pxa3xx-nand: 
[    5.780750] NDCR:  0x9d079fff
[    5.780750] NDCB0: 0x000d3000
[    5.780750] NDCB1: 0x25410000
[    5.780750] NDCB2: 0x00000000
[    5.780750] NDCB3: 0x00000000
[    5.799855] marvell-nfc pxa3xx-nand: 
[    5.799855] NDCR:  0xdd079fff
[    5.799855] NDCB0: 0x000d3000
[    5.799855] NDCB1: 0x25800000
[    5.799855] NDCB2: 0x00000000
[    5.799855] NDCB3: 0x00000000
[    5.818918] marvell-nfc pxa3xx-nand: 
[    5.818918] NDCR:  0xdd079fff
[    5.818918] NDCB0: 0x000d3000
[    5.818918] NDCB1: 0x25810000
[    5.818918] NDCB2: 0x00000000
[    5.818918] NDCB3: 0x00000000
[    5.837903] marvell-nfc pxa3xx-nand: 
[    5.837903] NDCR:  0x9d079fff
[    5.837903] NDCB0: 0x000d3000
[    5.837903] NDCB1: 0x25810000
[    5.837903] NDCB2: 0x00000000
[    5.837903] NDCB3: 0x00000000
[    5.857009] marvell-nfc pxa3xx-nand: 
[    5.857009] NDCR:  0xdd079fff
[    5.857009] NDCB0: 0x000d3000
[    5.857009] NDCB1: 0x25c00000
[    5.857009] NDCB2: 0x00000000
[    5.857009] NDCB3: 0x00000000
[    5.876071] marvell-nfc pxa3xx-nand: 
[    5.876071] NDCR:  0xdd079fff
[    5.876071] NDCB0: 0x000d3000
[    5.876071] NDCB1: 0x25c10000
[    5.876071] NDCB2: 0x00000000
[    5.876071] NDCB3: 0x00000000
[    5.895047] marvell-nfc pxa3xx-nand: 
[    5.895047] NDCR:  0x9d079fff
[    5.895047] NDCB0: 0x000d3000
[    5.895047] NDCB1: 0x25c10000
[    5.895047] NDCB2: 0x00000000
[    5.895047] NDCB3: 0x00000000
[    5.914152] marvell-nfc pxa3xx-nand: 
[    5.914152] NDCR:  0xdd079fff
[    5.914152] NDCB0: 0x000d3000
[    5.914152] NDCB1: 0x26000000
[    5.914152] NDCB2: 0x00000000
[    5.914152] NDCB3: 0x00000000
[    5.933285] marvell-nfc pxa3xx-nand: 
[    5.933285] NDCR:  0xdd079fff
[    5.933285] NDCB0: 0x000d3000
[    5.933285] NDCB1: 0x26010000
[    5.933285] NDCB2: 0x00000000
[    5.933285] NDCB3: 0x00000000
[    5.952247] marvell-nfc pxa3xx-nand: 
[    5.952247] NDCR:  0x9d079fff
[    5.952247] NDCB0: 0x000d3000
[    5.952247] NDCB1: 0x26010000
[    5.952247] NDCB2: 0x00000000
[    5.952247] NDCB3: 0x00000000
[    5.971354] marvell-nfc pxa3xx-nand: 
[    5.971354] NDCR:  0xdd079fff
[    5.971354] NDCB0: 0x000d3000
[    5.971354] NDCB1: 0x26400000
[    5.971354] NDCB2: 0x00000000
[    5.971354] NDCB3: 0x00000000
[    5.990415] marvell-nfc pxa3xx-nand: 
[    5.990415] NDCR:  0xdd079fff
[    5.990415] NDCB0: 0x000d3000
[    5.990415] NDCB1: 0x26410000
[    5.990415] NDCB2: 0x00000000
[    5.990415] NDCB3: 0x00000000
[    6.009391] marvell-nfc pxa3xx-nand: 
[    6.009391] NDCR:  0x9d079fff
[    6.009391] NDCB0: 0x000d3000
[    6.009391] NDCB1: 0x26410000
[    6.009391] NDCB2: 0x00000000
[    6.009391] NDCB3: 0x00000000
[    6.028510] marvell-nfc pxa3xx-nand: 
[    6.028510] NDCR:  0xdd079fff
[    6.028510] NDCB0: 0x000d3000
[    6.028510] NDCB1: 0x26800000
[    6.028510] NDCB2: 0x00000000
[    6.028510] NDCB3: 0x00000000
[    6.047572] marvell-nfc pxa3xx-nand: 
[    6.047572] NDCR:  0xdd079fff
[    6.047572] NDCB0: 0x000d3000
[    6.047572] NDCB1: 0x26810000
[    6.047572] NDCB2: 0x00000000
[    6.047572] NDCB3: 0x00000000
[    6.066553] marvell-nfc pxa3xx-nand: 
[    6.066553] NDCR:  0x9d079fff
[    6.066553] NDCB0: 0x000d3000
[    6.066553] NDCB1: 0x26810000
[    6.066553] NDCB2: 0x00000000
[    6.066553] NDCB3: 0x00000000
[    6.085662] marvell-nfc pxa3xx-nand: 
[    6.085662] NDCR:  0xdd079fff
[    6.085662] NDCB0: 0x000d3000
[    6.085662] NDCB1: 0x26c00000
[    6.085662] NDCB2: 0x00000000
[    6.085662] NDCB3: 0x00000000
[    6.105275] marvell-nfc pxa3xx-nand: 
[    6.105275] NDCR:  0xdd079fff
[    6.105275] NDCB0: 0x000d3000
[    6.105275] NDCB1: 0x26c10000
[    6.105275] NDCB2: 0x00000000
[    6.105275] NDCB3: 0x00000000
[    6.124291] marvell-nfc pxa3xx-nand: 
[    6.124291] NDCR:  0x9d079fff
[    6.124291] NDCB0: 0x000d3000
[    6.124291] NDCB1: 0x26c10000
[    6.124291] NDCB2: 0x00000000
[    6.124291] NDCB3: 0x00000000
[    6.143431] marvell-nfc pxa3xx-nand: 
[    6.143431] NDCR:  0xdd079fff
[    6.143431] NDCB0: 0x000d3000
[    6.143431] NDCB1: 0x27000000
[    6.143431] NDCB2: 0x00000000
[    6.143431] NDCB3: 0x00000000
[    6.162492] marvell-nfc pxa3xx-nand: 
[    6.162492] NDCR:  0xdd079fff
[    6.162492] NDCB0: 0x000d3000
[    6.162492] NDCB1: 0x27010000
[    6.162492] NDCB2: 0x00000000
[    6.162492] NDCB3: 0x00000000
[    6.181482] marvell-nfc pxa3xx-nand: 
[    6.181482] NDCR:  0x9d079fff
[    6.181482] NDCB0: 0x000d3000
[    6.181482] NDCB1: 0x27010000
[    6.181482] NDCB2: 0x00000000
[    6.181482] NDCB3: 0x00000000
[    6.200594] marvell-nfc pxa3xx-nand: 
[    6.200594] NDCR:  0xdd079fff
[    6.200594] NDCB0: 0x000d3000
[    6.200594] NDCB1: 0x27400000
[    6.200594] NDCB2: 0x00000000
[    6.200594] NDCB3: 0x00000000
[    6.219651] marvell-nfc pxa3xx-nand: 
[    6.219651] NDCR:  0xdd079fff
[    6.219651] NDCB0: 0x000d3000
[    6.219651] NDCB1: 0x27410000
[    6.219651] NDCB2: 0x00000000
[    6.219651] NDCB3: 0x00000000
[    6.238628] marvell-nfc pxa3xx-nand: 
[    6.238628] NDCR:  0x9d079fff
[    6.238628] NDCB0: 0x000d3000
[    6.238628] NDCB1: 0x27410000
[    6.238628] NDCB2: 0x00000000
[    6.238628] NDCB3: 0x00000000
[    6.257763] marvell-nfc pxa3xx-nand: 
[    6.257763] NDCR:  0xdd079fff
[    6.257763] NDCB0: 0x000d3000
[    6.257763] NDCB1: 0x27800000
[    6.257763] NDCB2: 0x00000000
[    6.257763] NDCB3: 0x00000000
[    6.276826] marvell-nfc pxa3xx-nand: 
[    6.276826] NDCR:  0xdd079fff
[    6.276826] NDCB0: 0x000d3000
[    6.276826] NDCB1: 0x27810000
[    6.276826] NDCB2: 0x00000000
[    6.276826] NDCB3: 0x00000000
[    6.295914] marvell-nfc pxa3xx-nand: 
[    6.295914] NDCR:  0xdd079fff
[    6.295914] NDCB0: 0x000d3000
[    6.295914] NDCB1: 0x27c00000
[    6.295914] NDCB2: 0x00000000
[    6.295914] NDCB3: 0x00000000
[    6.314978] marvell-nfc pxa3xx-nand: 
[    6.314978] NDCR:  0xdd079fff
[    6.314978] NDCB0: 0x000d3000
[    6.314978] NDCB1: 0x27c10000
[    6.314978] NDCB2: 0x00000000
[    6.314978] NDCB3: 0x00000000
[    6.333957] marvell-nfc pxa3xx-nand: 
[    6.333957] NDCR:  0x9d079fff
[    6.333957] NDCB0: 0x000d3000
[    6.333957] NDCB1: 0x27c10000
[    6.333957] NDCB2: 0x00000000
[    6.333957] NDCB3: 0x00000000
[    6.353164] marvell-nfc pxa3xx-nand: 
[    6.353164] NDCR:  0xdd079fff
[    6.353164] NDCB0: 0x000d3000
[    6.353164] NDCB1: 0x28000000
[    6.353164] NDCB2: 0x00000000
[    6.353164] NDCB3: 0x00000000
[    6.372184] marvell-nfc pxa3xx-nand: 
[    6.372184] NDCR:  0xdd079fff
[    6.372184] NDCB0: 0x000d3000
[    6.372184] NDCB1: 0x28010000
[    6.372184] NDCB2: 0x00000000
[    6.372184] NDCB3: 0x00000000
[    6.391168] marvell-nfc pxa3xx-nand: 
[    6.391168] NDCR:  0x9d079fff
[    6.391168] NDCB0: 0x000d3000
[    6.391168] NDCB1: 0x28010000
[    6.391168] NDCB2: 0x00000000
[    6.391168] NDCB3: 0x00000000
[    6.410268] marvell-nfc pxa3xx-nand: 
[    6.410268] NDCR:  0xdd079fff
[    6.410268] NDCB0: 0x000d3000
[    6.410268] NDCB1: 0x28400000
[    6.410268] NDCB2: 0x00000000
[    6.410268] NDCB3: 0x00000000
[    6.429335] marvell-nfc pxa3xx-nand: 
[    6.429335] NDCR:  0xdd079fff
[    6.429335] NDCB0: 0x000d3000
[    6.429335] NDCB1: 0x28410000
[    6.429335] NDCB2: 0x00000000
[    6.429335] NDCB3: 0x00000000
[    6.448408] marvell-nfc pxa3xx-nand: 
[    6.448408] NDCR:  0xdd079fff
[    6.448408] NDCB0: 0x000d3000
[    6.448408] NDCB1: 0x28800000
[    6.448408] NDCB2: 0x00000000
[    6.448408] NDCB3: 0x00000000
[    6.467471] marvell-nfc pxa3xx-nand: 
[    6.467471] NDCR:  0xdd079fff
[    6.467471] NDCB0: 0x000d3000
[    6.467471] NDCB1: 0x28810000
[    6.467471] NDCB2: 0x00000000
[    6.467471] NDCB3: 0x00000000
[    6.486456] marvell-nfc pxa3xx-nand: 
[    6.486456] NDCR:  0x9d079fff
[    6.486456] NDCB0: 0x000d3000
[    6.486456] NDCB1: 0x28810000
[    6.486456] NDCB2: 0x00000000
[    6.486456] NDCB3: 0x00000000
[    6.505554] marvell-nfc pxa3xx-nand: 
[    6.505554] NDCR:  0xdd079fff
[    6.505554] NDCB0: 0x000d3000
[    6.505554] NDCB1: 0x28c00000
[    6.505554] NDCB2: 0x00000000
[    6.505554] NDCB3: 0x00000000
[    6.524610] marvell-nfc pxa3xx-nand: 
[    6.524610] NDCR:  0xdd079fff
[    6.524610] NDCB0: 0x000d3000
[    6.524610] NDCB1: 0x28c10000
[    6.524610] NDCB2: 0x00000000
[    6.524610] NDCB3: 0x00000000
[    6.543589] marvell-nfc pxa3xx-nand: 
[    6.543589] NDCR:  0x9d079fff
[    6.543589] NDCB0: 0x000d3000
[    6.543589] NDCB1: 0x28c10000
[    6.543589] NDCB2: 0x00000000
[    6.543589] NDCB3: 0x00000000
[    6.562688] marvell-nfc pxa3xx-nand: 
[    6.562688] NDCR:  0xdd079fff
[    6.562688] NDCB0: 0x000d3000
[    6.562688] NDCB1: 0x29000000
[    6.562688] NDCB2: 0x00000000
[    6.562688] NDCB3: 0x00000000
[    6.581750] marvell-nfc pxa3xx-nand: 
[    6.581750] NDCR:  0xdd079fff
[    6.581750] NDCB0: 0x000d3000
[    6.581750] NDCB1: 0x29010000
[    6.581750] NDCB2: 0x00000000
[    6.581750] NDCB3: 0x00000000
[    6.600735] marvell-nfc pxa3xx-nand: 
[    6.600735] NDCR:  0x9d079fff
[    6.600735] NDCB0: 0x000d3000
[    6.600735] NDCB1: 0x29010000
[    6.600735] NDCB2: 0x00000000
[    6.600735] NDCB3: 0x00000000
[    6.619839] marvell-nfc pxa3xx-nand: 
[    6.619839] NDCR:  0xdd079fff
[    6.619839] NDCB0: 0x000d3000
[    6.619839] NDCB1: 0x29400000
[    6.619839] NDCB2: 0x00000000
[    6.619839] NDCB3: 0x00000000
[    6.638902] marvell-nfc pxa3xx-nand: 
[    6.638902] NDCR:  0xdd079fff
[    6.638902] NDCB0: 0x000d3000
[    6.638902] NDCB1: 0x29410000
[    6.638902] NDCB2: 0x00000000
[    6.638902] NDCB3: 0x00000000
[    6.657879] marvell-nfc pxa3xx-nand: 
[    6.657879] NDCR:  0x9d079fff
[    6.657879] NDCB0: 0x000d3000
[    6.657879] NDCB1: 0x29410000
[    6.657879] NDCB2: 0x00000000
[    6.657879] NDCB3: 0x00000000
[    6.676983] marvell-nfc pxa3xx-nand: 
[    6.676983] NDCR:  0xdd079fff
[    6.676983] NDCB0: 0x000d3000
[    6.676983] NDCB1: 0x29800000
[    6.676983] NDCB2: 0x00000000
[    6.676983] NDCB3: 0x00000000
[    6.696050] marvell-nfc pxa3xx-nand: 
[    6.696050] NDCR:  0xdd079fff
[    6.696050] NDCB0: 0x000d3000
[    6.696050] NDCB1: 0x29810000
[    6.696050] NDCB2: 0x00000000
[    6.696050] NDCB3: 0x00000000
[    6.715033] marvell-nfc pxa3xx-nand: 
[    6.715033] NDCR:  0x9d079fff
[    6.715033] NDCB0: 0x000d3000
[    6.715033] NDCB1: 0x29810000
[    6.715033] NDCB2: 0x00000000
[    6.715033] NDCB3: 0x00000000
[    6.734141] marvell-nfc pxa3xx-nand: 
[    6.734141] NDCR:  0xdd079fff
[    6.734141] NDCB0: 0x000d3000
[    6.734141] NDCB1: 0x29c00000
[    6.734141] NDCB2: 0x00000000
[    6.734141] NDCB3: 0x00000000
[    6.753291] marvell-nfc pxa3xx-nand: 
[    6.753291] NDCR:  0xdd079fff
[    6.753291] NDCB0: 0x000d3000
[    6.753291] NDCB1: 0x29c10000
[    6.753291] NDCB2: 0x00000000
[    6.753291] NDCB3: 0x00000000
[    6.772264] marvell-nfc pxa3xx-nand: 
[    6.772264] NDCR:  0x9d079fff
[    6.772264] NDCB0: 0x000d3000
[    6.772264] NDCB1: 0x29c10000
[    6.772264] NDCB2: 0x00000000
[    6.772264] NDCB3: 0x00000000
[    6.791367] marvell-nfc pxa3xx-nand: 
[    6.791367] NDCR:  0xdd079fff
[    6.791367] NDCB0: 0x000d3000
[    6.791367] NDCB1: 0x2a000000
[    6.791367] NDCB2: 0x00000000
[    6.791367] NDCB3: 0x00000000
[    6.810425] marvell-nfc pxa3xx-nand: 
[    6.810425] NDCR:  0xdd079fff
[    6.810425] NDCB0: 0x000d3000
[    6.810425] NDCB1: 0x2a010000
[    6.810425] NDCB2: 0x00000000
[    6.810425] NDCB3: 0x00000000
[    6.829403] marvell-nfc pxa3xx-nand: 
[    6.829403] NDCR:  0x9d079fff
[    6.829403] NDCB0: 0x000d3000
[    6.829403] NDCB1: 0x2a010000
[    6.829403] NDCB2: 0x00000000
[    6.829403] NDCB3: 0x00000000
[    6.848512] marvell-nfc pxa3xx-nand: 
[    6.848512] NDCR:  0xdd079fff
[    6.848512] NDCB0: 0x000d3000
[    6.848512] NDCB1: 0x2a400000
[    6.848512] NDCB2: 0x00000000
[    6.848512] NDCB3: 0x00000000
[    6.867573] marvell-nfc pxa3xx-nand: 
[    6.867573] NDCR:  0xdd079fff
[    6.867573] NDCB0: 0x000d3000
[    6.867573] NDCB1: 0x2a410000
[    6.867573] NDCB2: 0x00000000
[    6.867573] NDCB3: 0x00000000
[    6.886550] marvell-nfc pxa3xx-nand: 
[    6.886550] NDCR:  0x9d079fff
[    6.886550] NDCB0: 0x000d3000
[    6.886550] NDCB1: 0x2a410000
[    6.886550] NDCB2: 0x00000000
[    6.886550] NDCB3: 0x00000000
[    6.905653] marvell-nfc pxa3xx-nand: 
[    6.905653] NDCR:  0xdd079fff
[    6.905653] NDCB0: 0x000d3000
[    6.905653] NDCB1: 0x2a800000
[    6.905653] NDCB2: 0x00000000
[    6.905653] NDCB3: 0x00000000
[    6.924720] marvell-nfc pxa3xx-nand: 
[    6.924720] NDCR:  0xdd079fff
[    6.924720] NDCB0: 0x000d3000
[    6.924720] NDCB1: 0x2a810000
[    6.924720] NDCB2: 0x00000000
[    6.924720] NDCB3: 0x00000000
[    6.943704] marvell-nfc pxa3xx-nand: 
[    6.943704] NDCR:  0x9d079fff
[    6.943704] NDCB0: 0x000d3000
[    6.943704] NDCB1: 0x2a810000
[    6.943704] NDCB2: 0x00000000
[    6.943704] NDCB3: 0x00000000
[    6.962806] marvell-nfc pxa3xx-nand: 
[    6.962806] NDCR:  0xdd079fff
[    6.962806] NDCB0: 0x000d3000
[    6.962806] NDCB1: 0x2ac00000
[    6.962806] NDCB2: 0x00000000
[    6.962806] NDCB3: 0x00000000
[    6.981868] marvell-nfc pxa3xx-nand: 
[    6.981868] NDCR:  0xdd079fff
[    6.981868] NDCB0: 0x000d3000
[    6.981868] NDCB1: 0x2ac10000
[    6.981868] NDCB2: 0x00000000
[    6.981868] NDCB3: 0x00000000
[    7.000848] marvell-nfc pxa3xx-nand: 
[    7.000848] NDCR:  0x9d079fff
[    7.000848] NDCB0: 0x000d3000
[    7.000848] NDCB1: 0x2ac10000
[    7.000848] NDCB2: 0x00000000
[    7.000848] NDCB3: 0x00000000
[    7.019966] marvell-nfc pxa3xx-nand: 
[    7.019966] NDCR:  0xdd079fff
[    7.019966] NDCB0: 0x000d3000
[    7.019966] NDCB1: 0x2b000000
[    7.019966] NDCB2: 0x00000000
[    7.019966] NDCB3: 0x00000000
[    7.039028] marvell-nfc pxa3xx-nand: 
[    7.039028] NDCR:  0xdd079fff
[    7.039028] NDCB0: 0x000d3000
[    7.039028] NDCB1: 0x2b010000
[    7.039028] NDCB2: 0x00000000
[    7.039028] NDCB3: 0x00000000
[    7.058002] marvell-nfc pxa3xx-nand: 
[    7.058002] NDCR:  0x9d079fff
[    7.058002] NDCB0: 0x000d3000
[    7.058002] NDCB1: 0x2b010000
[    7.058002] NDCB2: 0x00000000
[    7.058002] NDCB3: 0x00000000
[    7.077109] marvell-nfc pxa3xx-nand: 
[    7.077109] NDCR:  0xdd079fff
[    7.077109] NDCB0: 0x000d3000
[    7.077109] NDCB1: 0x2b400000
[    7.077109] NDCB2: 0x00000000
[    7.077109] NDCB3: 0x00000000
[    7.096173] marvell-nfc pxa3xx-nand: 
[    7.096173] NDCR:  0xdd079fff
[    7.096173] NDCB0: 0x000d3000
[    7.096173] NDCB1: 0x2b410000
[    7.096173] NDCB2: 0x00000000
[    7.096173] NDCB3: 0x00000000
[    7.115153] marvell-nfc pxa3xx-nand: 
[    7.115153] NDCR:  0x9d079fff
[    7.115153] NDCB0: 0x000d3000
[    7.115153] NDCB1: 0x2b410000
[    7.115153] NDCB2: 0x00000000
[    7.115153] NDCB3: 0x00000000
[    7.134255] marvell-nfc pxa3xx-nand: 
[    7.134255] NDCR:  0xdd079fff
[    7.134255] NDCB0: 0x000d3000
[    7.134255] NDCB1: 0x2b800000
[    7.134255] NDCB2: 0x00000000
[    7.134255] NDCB3: 0x00000000
[    7.153307] marvell-nfc pxa3xx-nand: 
[    7.153307] NDCR:  0xdd079fff
[    7.153307] NDCB0: 0x000d3000
[    7.153307] NDCB1: 0x2b810000
[    7.153307] NDCB2: 0x00000000
[    7.153307] NDCB3: 0x00000000
[    7.172279] marvell-nfc pxa3xx-nand: 
[    7.172279] NDCR:  0x9d079fff
[    7.172279] NDCB0: 0x000d3000
[    7.172279] NDCB1: 0x2b810000
[    7.172279] NDCB2: 0x00000000
[    7.172279] NDCB3: 0x00000000
[    7.191385] marvell-nfc pxa3xx-nand: 
[    7.191385] NDCR:  0xdd079fff
[    7.191385] NDCB0: 0x000d3000
[    7.191385] NDCB1: 0x2bc00000
[    7.191385] NDCB2: 0x00000000
[    7.191385] NDCB3: 0x00000000
[    7.210447] marvell-nfc pxa3xx-nand: 
[    7.210447] NDCR:  0xdd079fff
[    7.210447] NDCB0: 0x000d3000
[    7.210447] NDCB1: 0x2bc10000
[    7.210447] NDCB2: 0x00000000
[    7.210447] NDCB3: 0x00000000
[    7.229426] marvell-nfc pxa3xx-nand: 
[    7.229426] NDCR:  0x9d079fff
[    7.229426] NDCB0: 0x000d3000
[    7.229426] NDCB1: 0x2bc10000
[    7.229426] NDCB2: 0x00000000
[    7.229426] NDCB3: 0x00000000
[    7.248529] marvell-nfc pxa3xx-nand: 
[    7.248529] NDCR:  0xdd079fff
[    7.248529] NDCB0: 0x000d3000
[    7.248529] NDCB1: 0x2c000000
[    7.248529] NDCB2: 0x00000000
[    7.248529] NDCB3: 0x00000000
[    7.267597] marvell-nfc pxa3xx-nand: 
[    7.267597] NDCR:  0xdd079fff
[    7.267597] NDCB0: 0x000d3000
[    7.267597] NDCB1: 0x2c010000
[    7.267597] NDCB2: 0x00000000
[    7.267597] NDCB3: 0x00000000
[    7.286579] marvell-nfc pxa3xx-nand: 
[    7.286579] NDCR:  0x9d079fff
[    7.286579] NDCB0: 0x000d3000
[    7.286579] NDCB1: 0x2c010000
[    7.286579] NDCB2: 0x00000000
[    7.286579] NDCB3: 0x00000000
[    7.305683] marvell-nfc pxa3xx-nand: 
[    7.305683] NDCR:  0xdd079fff
[    7.305683] NDCB0: 0x000d3000
[    7.305683] NDCB1: 0x2c400000
[    7.305683] NDCB2: 0x00000000
[    7.305683] NDCB3: 0x00000000
[    7.324747] marvell-nfc pxa3xx-nand: 
[    7.324747] NDCR:  0xdd079fff
[    7.324747] NDCB0: 0x000d3000
[    7.324747] NDCB1: 0x2c410000
[    7.324747] NDCB2: 0x00000000
[    7.324747] NDCB3: 0x00000000
[    7.343743] marvell-nfc pxa3xx-nand: 
[    7.343743] NDCR:  0x9d079fff
[    7.343743] NDCB0: 0x000d3000
[    7.343743] NDCB1: 0x2c410000
[    7.343743] NDCB2: 0x00000000
[    7.343743] NDCB3: 0x00000000
[    7.362843] marvell-nfc pxa3xx-nand: 
[    7.362843] NDCR:  0xdd079fff
[    7.362843] NDCB0: 0x000d3000
[    7.362843] NDCB1: 0x2c800000
[    7.362843] NDCB2: 0x00000000
[    7.362843] NDCB3: 0x00000000
[    7.381905] marvell-nfc pxa3xx-nand: 
[    7.381905] NDCR:  0xdd079fff
[    7.381905] NDCB0: 0x000d3000
[    7.381905] NDCB1: 0x2c810000
[    7.381905] NDCB2: 0x00000000
[    7.381905] NDCB3: 0x00000000
[    7.400887] marvell-nfc pxa3xx-nand: 
[    7.400887] NDCR:  0x9d079fff
[    7.400887] NDCB0: 0x000d3000
[    7.400887] NDCB1: 0x2c810000
[    7.400887] NDCB2: 0x00000000
[    7.400887] NDCB3: 0x00000000
[    7.420884] marvell-nfc pxa3xx-nand: 
[    7.420884] NDCR:  0xdd079fff
[    7.420884] NDCB0: 0x000d3000
[    7.420884] NDCB1: 0x50800000
[    7.420884] NDCB2: 0x00000000
[    7.420884] NDCB3: 0x00000000
[    7.439944] marvell-nfc pxa3xx-nand: 
[    7.439944] NDCR:  0xdd079fff
[    7.439944] NDCB0: 0x000d3000
[    7.439944] NDCB1: 0x50810000
[    7.439944] NDCB2: 0x00000000
[    7.439944] NDCB3: 0x00000000
[    7.458920] marvell-nfc pxa3xx-nand: 
[    7.458920] NDCR:  0x9d079fff
[    7.458920] NDCB0: 0x000d3000
[    7.458920] NDCB1: 0x50810000
[    7.458920] NDCB2: 0x00000000
[    7.458920] NDCB3: 0x00000000
[    7.478025] marvell-nfc pxa3xx-nand: 
[    7.478025] NDCR:  0xdd079fff
[    7.478025] NDCB0: 0x000d3000
[    7.478025] NDCB1: 0x50c00000
[    7.478025] NDCB2: 0x00000000
[    7.478025] NDCB3: 0x00000000
[    7.497089] marvell-nfc pxa3xx-nand: 
[    7.497089] NDCR:  0xdd079fff
[    7.497089] NDCB0: 0x000d3000
[    7.497089] NDCB1: 0x50c10000
[    7.497089] NDCB2: 0x00000000
[    7.497089] NDCB3: 0x00000000
[    7.516067] marvell-nfc pxa3xx-nand: 
[    7.516067] NDCR:  0x9d079fff
[    7.516067] NDCB0: 0x000d3000
[    7.516067] NDCB1: 0x50c10000
[    7.516067] NDCB2: 0x00000000
[    7.516067] NDCB3: 0x00000000
[    7.535172] marvell-nfc pxa3xx-nand: 
[    7.535172] NDCR:  0xdd079fff
[    7.535172] NDCB0: 0x000d3000
[    7.535172] NDCB1: 0x51000000
[    7.535172] NDCB2: 0x00000000
[    7.535172] NDCB3: 0x00000000
[    7.554233] marvell-nfc pxa3xx-nand: 
[    7.554233] NDCR:  0xdd079fff
[    7.554233] NDCB0: 0x000d3000
[    7.554233] NDCB1: 0x51010000
[    7.554233] NDCB2: 0x00000000
[    7.554233] NDCB3: 0x00000000
[    7.573238] marvell-nfc pxa3xx-nand: 
[    7.573238] NDCR:  0x9d079fff
[    7.573238] NDCB0: 0x000d3000
[    7.573238] NDCB1: 0x51010000
[    7.573238] NDCB2: 0x00000000
[    7.573238] NDCB3: 0x00000000
[    7.592334] marvell-nfc pxa3xx-nand: 
[    7.592334] NDCR:  0xdd079fff
[    7.592334] NDCB0: 0x000d3000
[    7.592334] NDCB1: 0x51400000
[    7.592334] NDCB2: 0x00000000
[    7.592334] NDCB3: 0x00000000
[    7.611401] marvell-nfc pxa3xx-nand: 
[    7.611401] NDCR:  0xdd079fff
[    7.611401] NDCB0: 0x000d3000
[    7.611401] NDCB1: 0x51410000
[    7.611401] NDCB2: 0x00000000
[    7.611401] NDCB3: 0x00000000
[    7.630384] marvell-nfc pxa3xx-nand: 
[    7.630384] NDCR:  0x9d079fff
[    7.630384] NDCB0: 0x000d3000
[    7.630384] NDCB1: 0x51410000
[    7.630384] NDCB2: 0x00000000
[    7.630384] NDCB3: 0x00000000
[    7.649492] marvell-nfc pxa3xx-nand: 
[    7.649492] NDCR:  0xdd079fff
[    7.649492] NDCB0: 0x000d3000
[    7.649492] NDCB1: 0x51800000
[    7.649492] NDCB2: 0x00000000
[    7.649492] NDCB3: 0x00000000
[    7.668554] marvell-nfc pxa3xx-nand: 
[    7.668554] NDCR:  0xdd079fff
[    7.668554] NDCB0: 0x000d3000
[    7.668554] NDCB1: 0x51810000
[    7.668554] NDCB2: 0x00000000
[    7.668554] NDCB3: 0x00000000
[    7.687527] marvell-nfc pxa3xx-nand: 
[    7.687527] NDCR:  0x9d079fff
[    7.687527] NDCB0: 0x000d3000
[    7.687527] NDCB1: 0x51810000
[    7.687527] NDCB2: 0x00000000
[    7.687527] NDCB3: 0x00000000
[    7.706637] marvell-nfc pxa3xx-nand: 
[    7.706637] NDCR:  0xdd079fff
[    7.706637] NDCB0: 0x000d3000
[    7.706637] NDCB1: 0x51c00000
[    7.706637] NDCB2: 0x00000000
[    7.706637] NDCB3: 0x00000000
[    7.725697] marvell-nfc pxa3xx-nand: 
[    7.725697] NDCR:  0xdd079fff
[    7.725697] NDCB0: 0x000d3000
[    7.725697] NDCB1: 0x51c10000
[    7.725697] NDCB2: 0x00000000
[    7.725697] NDCB3: 0x00000000
[    7.744674] marvell-nfc pxa3xx-nand: 
[    7.744674] NDCR:  0x9d079fff
[    7.744674] NDCB0: 0x000d3000
[    7.744674] NDCB1: 0x51c10000
[    7.744674] NDCB2: 0x00000000
[    7.744674] NDCB3: 0x00000000
[    7.763781] marvell-nfc pxa3xx-nand: 
[    7.763781] NDCR:  0xdd079fff
[    7.763781] NDCB0: 0x000d3000
[    7.763781] NDCB1: 0x52000000
[    7.763781] NDCB2: 0x00000000
[    7.763781] NDCB3: 0x00000000
[    7.782838] marvell-nfc pxa3xx-nand: 
[    7.782838] NDCR:  0xdd079fff
[    7.782838] NDCB0: 0x000d3000
[    7.782838] NDCB1: 0x52010000
[    7.782838] NDCB2: 0x00000000
[    7.782838] NDCB3: 0x00000000
[    7.801814] marvell-nfc pxa3xx-nand: 
[    7.801814] NDCR:  0x9d079fff
[    7.801814] NDCB0: 0x000d3000
[    7.801814] NDCB1: 0x52010000
[    7.801814] NDCB2: 0x00000000
[    7.801814] NDCB3: 0x00000000
[    7.820919] marvell-nfc pxa3xx-nand: 
[    7.820919] NDCR:  0xdd079fff
[    7.820919] NDCB0: 0x000d3000
[    7.820919] NDCB1: 0x52400000
[    7.820919] NDCB2: 0x00000000
[    7.820919] NDCB3: 0x00000000
[    7.839984] marvell-nfc pxa3xx-nand: 
[    7.839984] NDCR:  0xdd079fff
[    7.839984] NDCB0: 0x000d3000
[    7.839984] NDCB1: 0x52410000
[    7.839984] NDCB2: 0x00000000
[    7.839984] NDCB3: 0x00000000
[    7.858968] marvell-nfc pxa3xx-nand: 
[    7.858968] NDCR:  0x9d079fff
[    7.858968] NDCB0: 0x000d3000
[    7.858968] NDCB1: 0x52410000
[    7.858968] NDCB2: 0x00000000
[    7.858968] NDCB3: 0x00000000
[    7.878070] marvell-nfc pxa3xx-nand: 
[    7.878070] NDCR:  0xdd079fff
[    7.878070] NDCB0: 0x000d3000
[    7.878070] NDCB1: 0x52800000
[    7.878070] NDCB2: 0x00000000
[    7.878070] NDCB3: 0x00000000
[    7.897127] marvell-nfc pxa3xx-nand: 
[    7.897127] NDCR:  0xdd079fff
[    7.897127] NDCB0: 0x000d3000
[    7.897127] NDCB1: 0x52810000
[    7.897127] NDCB2: 0x00000000
[    7.897127] NDCB3: 0x00000000
[    7.916104] marvell-nfc pxa3xx-nand: 
[    7.916104] NDCR:  0x9d079fff
[    7.916104] NDCB0: 0x000d3000
[    7.916104] NDCB1: 0x52810000
[    7.916104] NDCB2: 0x00000000
[    7.916104] NDCB3: 0x00000000
[    7.935231] marvell-nfc pxa3xx-nand: 
[    7.935231] NDCR:  0xdd079fff
[    7.935231] NDCB0: 0x000d3000
[    7.935231] NDCB1: 0x52c00000
[    7.935231] NDCB2: 0x00000000
[    7.935231] NDCB3: 0x00000000
[    7.954292] marvell-nfc pxa3xx-nand: 
[    7.954292] NDCR:  0xdd079fff
[    7.954292] NDCB0: 0x000d3000
[    7.954292] NDCB1: 0x52c10000
[    7.954292] NDCB2: 0x00000000
[    7.954292] NDCB3: 0x00000000
[    7.973328] marvell-nfc pxa3xx-nand: 
[    7.973328] NDCR:  0x9d079fff
[    7.973328] NDCB0: 0x000d3000
[    7.973328] NDCB1: 0x52c10000
[    7.973328] NDCB2: 0x00000000
[    7.973328] NDCB3: 0x00000000
[    7.992424] marvell-nfc pxa3xx-nand: 
[    7.992424] NDCR:  0xdd079fff
[    7.992424] NDCB0: 0x000d3000
[    7.992424] NDCB1: 0x53000000
[    7.992424] NDCB2: 0x00000000
[    7.992424] NDCB3: 0x00000000
[    8.011485] marvell-nfc pxa3xx-nand: 
[    8.011485] NDCR:  0xdd079fff
[    8.011485] NDCB0: 0x000d3000
[    8.011485] NDCB1: 0x53010000
[    8.011485] NDCB2: 0x00000000
[    8.011485] NDCB3: 0x00000000
[    8.030479] marvell-nfc pxa3xx-nand: 
[    8.030479] NDCR:  0x9d079fff
[    8.030479] NDCB0: 0x000d3000
[    8.030479] NDCB1: 0x53010000
[    8.030479] NDCB2: 0x00000000
[    8.030479] NDCB3: 0x00000000
[    8.049579] marvell-nfc pxa3xx-nand: 
[    8.049579] NDCR:  0xdd079fff
[    8.049579] NDCB0: 0x000d3000
[    8.049579] NDCB1: 0x53400000
[    8.049579] NDCB2: 0x00000000
[    8.049579] NDCB3: 0x00000000
[    8.068643] marvell-nfc pxa3xx-nand: 
[    8.068643] NDCR:  0xdd079fff
[    8.068643] NDCB0: 0x000d3000
[    8.068643] NDCB1: 0x53410000
[    8.068643] NDCB2: 0x00000000
[    8.068643] NDCB3: 0x00000000
[    8.087618] marvell-nfc pxa3xx-nand: 
[    8.087618] NDCR:  0x9d079fff
[    8.087618] NDCB0: 0x000d3000
[    8.087618] NDCB1: 0x53410000
[    8.087618] NDCB2: 0x00000000
[    8.087618] NDCB3: 0x00000000
[    8.107355] marvell-nfc pxa3xx-nand: 
[    8.107355] NDCR:  0xdd079fff
[    8.107355] NDCB0: 0x000d3000
[    8.107355] NDCB1: 0x53800000
[    8.107355] NDCB2: 0x00000000
[    8.107355] NDCB3: 0x00000000
[    8.126458] marvell-nfc pxa3xx-nand: 
[    8.126458] NDCR:  0xdd079fff
[    8.126458] NDCB0: 0x000d3000
[    8.126458] NDCB1: 0x53810000
[    8.126458] NDCB2: 0x00000000
[    8.126458] NDCB3: 0x00000000
[    8.145438] marvell-nfc pxa3xx-nand: 
[    8.145438] NDCR:  0x9d079fff
[    8.145438] NDCB0: 0x000d3000
[    8.145438] NDCB1: 0x53810000
[    8.145438] NDCB2: 0x00000000
[    8.145438] NDCB3: 0x00000000
[    8.164543] marvell-nfc pxa3xx-nand: 
[    8.164543] NDCR:  0xdd079fff
[    8.164543] NDCB0: 0x000d3000
[    8.164543] NDCB1: 0x53c00000
[    8.164543] NDCB2: 0x00000000
[    8.164543] NDCB3: 0x00000000
[    8.183607] marvell-nfc pxa3xx-nand: 
[    8.183607] NDCR:  0xdd079fff
[    8.183607] NDCB0: 0x000d3000
[    8.183607] NDCB1: 0x53c10000
[    8.183607] NDCB2: 0x00000000
[    8.183607] NDCB3: 0x00000000
[    8.202574] marvell-nfc pxa3xx-nand: 
[    8.202574] NDCR:  0x9d079fff
[    8.202574] NDCB0: 0x000d3000
[    8.202574] NDCB1: 0x53c10000
[    8.202574] NDCB2: 0x00000000
[    8.202574] NDCB3: 0x00000000
[    8.221680] marvell-nfc pxa3xx-nand: 
[    8.221680] NDCR:  0xdd079fff
[    8.221680] NDCB0: 0x000d3000
[    8.221680] NDCB1: 0x54000000
[    8.221680] NDCB2: 0x00000000
[    8.221680] NDCB3: 0x00000000
[    8.240741] marvell-nfc pxa3xx-nand: 
[    8.240741] NDCR:  0xdd079fff
[    8.240741] NDCB0: 0x000d3000
[    8.240741] NDCB1: 0x54010000
[    8.240741] NDCB2: 0x00000000
[    8.240741] NDCB3: 0x00000000
[    8.259723] marvell-nfc pxa3xx-nand: 
[    8.259723] NDCR:  0x9d079fff
[    8.259723] NDCB0: 0x000d3000
[    8.259723] NDCB1: 0x54010000
[    8.259723] NDCB2: 0x00000000
[    8.259723] NDCB3: 0x00000000
[    8.278825] marvell-nfc pxa3xx-nand: 
[    8.278825] NDCR:  0xdd079fff
[    8.278825] NDCB0: 0x000d3000
[    8.278825] NDCB1: 0x54400000
[    8.278825] NDCB2: 0x00000000
[    8.278825] NDCB3: 0x00000000
[    8.297889] marvell-nfc pxa3xx-nand: 
[    8.297889] NDCR:  0xdd079fff
[    8.297889] NDCB0: 0x000d3000
[    8.297889] NDCB1: 0x54410000
[    8.297889] NDCB2: 0x00000000
[    8.297889] NDCB3: 0x00000000
[    8.316863] marvell-nfc pxa3xx-nand: 
[    8.316863] NDCR:  0x9d079fff
[    8.316863] NDCB0: 0x000d3000
[    8.316863] NDCB1: 0x54410000
[    8.316863] NDCB2: 0x00000000
[    8.316863] NDCB3: 0x00000000
[    8.335976] marvell-nfc pxa3xx-nand: 
[    8.335976] NDCR:  0xdd079fff
[    8.335976] NDCB0: 0x000d3000
[    8.335976] NDCB1: 0x55000000
[    8.335976] NDCB2: 0x00000000
[    8.335976] NDCB3: 0x00000000
[    8.355035] marvell-nfc pxa3xx-nand: 
[    8.355035] NDCR:  0xdd079fff
[    8.355035] NDCB0: 0x000d3000
[    8.355035] NDCB1: 0x55010000
[    8.355035] NDCB2: 0x00000000
[    8.355035] NDCB3: 0x00000000
[    8.374007] marvell-nfc pxa3xx-nand: 
[    8.374007] NDCR:  0x9d079fff
[    8.374007] NDCB0: 0x000d3000
[    8.374007] NDCB1: 0x55010000
[    8.374007] NDCB2: 0x00000000
[    8.374007] NDCB3: 0x00000000
[    8.393202] marvell-nfc pxa3xx-nand: 
[    8.393202] NDCR:  0xdd079fff
[    8.393202] NDCB0: 0x000d3000
[    8.393202] NDCB1: 0x55400000
[    8.393202] NDCB2: 0x00000000
[    8.393202] NDCB3: 0x00000000
[    8.412235] marvell-nfc pxa3xx-nand: 
[    8.412235] NDCR:  0xdd079fff
[    8.412235] NDCB0: 0x000d3000
[    8.412235] NDCB1: 0x55410000
[    8.412235] NDCB2: 0x00000000
[    8.412235] NDCB3: 0x00000000
[    8.431217] marvell-nfc pxa3xx-nand: 
[    8.431217] NDCR:  0x9d079fff
[    8.431217] NDCB0: 0x000d3000
[    8.431217] NDCB1: 0x55410000
[    8.431217] NDCB2: 0x00000000
[    8.431217] NDCB3: 0x00000000
[    8.450325] marvell-nfc pxa3xx-nand: 
[    8.450325] NDCR:  0xdd079fff
[    8.450325] NDCB0: 0x000d3000
[    8.450325] NDCB1: 0x55800000
[    8.450325] NDCB2: 0x00000000
[    8.450325] NDCB3: 0x00000000
[    8.469388] marvell-nfc pxa3xx-nand: 
[    8.469388] NDCR:  0xdd079fff
[    8.469388] NDCB0: 0x000d3000
[    8.469388] NDCB1: 0x55810000
[    8.469388] NDCB2: 0x00000000
[    8.469388] NDCB3: 0x00000000
[    8.488366] marvell-nfc pxa3xx-nand: 
[    8.488366] NDCR:  0x9d079fff
[    8.488366] NDCB0: 0x000d3000
[    8.488366] NDCB1: 0x55810000
[    8.488366] NDCB2: 0x00000000
[    8.488366] NDCB3: 0x00000000
[    8.507471] marvell-nfc pxa3xx-nand: 
[    8.507471] NDCR:  0xdd079fff
[    8.507471] NDCB0: 0x000d3000
[    8.507471] NDCB1: 0x55c00000
[    8.507471] NDCB2: 0x00000000
[    8.507471] NDCB3: 0x00000000
[    8.526556] marvell-nfc pxa3xx-nand: 
[    8.526556] NDCR:  0xdd079fff
[    8.526556] NDCB0: 0x000d3000
[    8.526556] NDCB1: 0x55c10000
[    8.526556] NDCB2: 0x00000000
[    8.526556] NDCB3: 0x00000000
[    8.545537] marvell-nfc pxa3xx-nand: 
[    8.545537] NDCR:  0x9d079fff
[    8.545537] NDCB0: 0x000d3000
[    8.545537] NDCB1: 0x55c10000
[    8.545537] NDCB2: 0x00000000
[    8.545537] NDCB3: 0x00000000
[    8.564641] marvell-nfc pxa3xx-nand: 
[    8.564641] NDCR:  0xdd079fff
[    8.564641] NDCB0: 0x000d3000
[    8.564641] NDCB1: 0x56000000
[    8.564641] NDCB2: 0x00000000
[    8.564641] NDCB3: 0x00000000
[    8.583703] marvell-nfc pxa3xx-nand: 
[    8.583703] NDCR:  0xdd079fff
[    8.583703] NDCB0: 0x000d3000
[    8.583703] NDCB1: 0x56010000
[    8.583703] NDCB2: 0x00000000
[    8.583703] NDCB3: 0x00000000
[    8.602671] marvell-nfc pxa3xx-nand: 
[    8.602671] NDCR:  0x9d079fff
[    8.602671] NDCB0: 0x000d3000
[    8.602671] NDCB1: 0x56010000
[    8.602671] NDCB2: 0x00000000
[    8.602671] NDCB3: 0x00000000
[    8.621771] marvell-nfc pxa3xx-nand: 
[    8.621771] NDCR:  0xdd079fff
[    8.621771] NDCB0: 0x000d3000
[    8.621771] NDCB1: 0x56400000
[    8.621771] NDCB2: 0x00000000
[    8.621771] NDCB3: 0x00000000
[    8.640836] marvell-nfc pxa3xx-nand: 
[    8.640836] NDCR:  0xdd079fff
[    8.640836] NDCB0: 0x000d3000
[    8.640836] NDCB1: 0x56410000
[    8.640836] NDCB2: 0x00000000
[    8.640836] NDCB3: 0x00000000
[    8.659821] marvell-nfc pxa3xx-nand: 
[    8.659821] NDCR:  0x9d079fff
[    8.659821] NDCB0: 0x000d3000
[    8.659821] NDCB1: 0x56410000
[    8.659821] NDCB2: 0x00000000
[    8.659821] NDCB3: 0x00000000
[    8.678923] marvell-nfc pxa3xx-nand: 
[    8.678923] NDCR:  0xdd079fff
[    8.678923] NDCB0: 0x000d3000
[    8.678923] NDCB1: 0x56800000
[    8.678923] NDCB2: 0x00000000
[    8.678923] NDCB3: 0x00000000
[    8.697987] marvell-nfc pxa3xx-nand: 
[    8.697987] NDCR:  0xdd079fff
[    8.697987] NDCB0: 0x000d3000
[    8.697987] NDCB1: 0x56810000
[    8.697987] NDCB2: 0x00000000
[    8.697987] NDCB3: 0x00000000
[    8.716967] marvell-nfc pxa3xx-nand: 
[    8.716967] NDCR:  0x9d079fff
[    8.716967] NDCB0: 0x000d3000
[    8.716967] NDCB1: 0x56810000
[    8.716967] NDCB2: 0x00000000
[    8.716967] NDCB3: 0x00000000
[    8.736068] marvell-nfc pxa3xx-nand: 
[    8.736068] NDCR:  0xdd079fff
[    8.736068] NDCB0: 0x000d3000
[    8.736068] NDCB1: 0x56c00000
[    8.736068] NDCB2: 0x00000000
[    8.736068] NDCB3: 0x00000000
[    8.755122] marvell-nfc pxa3xx-nand: 
[    8.755122] NDCR:  0xdd079fff
[    8.755122] NDCB0: 0x000d3000
[    8.755122] NDCB1: 0x56c10000
[    8.755122] NDCB2: 0x00000000
[    8.755122] NDCB3: 0x00000000
[    8.774101] marvell-nfc pxa3xx-nand: 
[    8.774101] NDCR:  0x9d079fff
[    8.774101] NDCB0: 0x000d3000
[    8.774101] NDCB1: 0x56c10000
[    8.774101] NDCB2: 0x00000000
[    8.774101] NDCB3: 0x00000000
[    8.793417] marvell-nfc pxa3xx-nand: 
[    8.793417] NDCR:  0xdd079fff
[    8.793417] NDCB0: 0x000d3000
[    8.793417] NDCB1: 0x57000000
[    8.793417] NDCB2: 0x00000000
[    8.793417] NDCB3: 0x00000000
[    8.812493] marvell-nfc pxa3xx-nand: 
[    8.812493] NDCR:  0xdd079fff
[    8.812493] NDCB0: 0x000d3000
[    8.812493] NDCB1: 0x57010000
[    8.812493] NDCB2: 0x00000000
[    8.812493] NDCB3: 0x00000000
[    8.831475] marvell-nfc pxa3xx-nand: 
[    8.831475] NDCR:  0x9d079fff
[    8.831475] NDCB0: 0x000d3000
[    8.831475] NDCB1: 0x57010000
[    8.831475] NDCB2: 0x00000000
[    8.831475] NDCB3: 0x00000000
[    8.850578] marvell-nfc pxa3xx-nand: 
[    8.850578] NDCR:  0xdd079fff
[    8.850578] NDCB0: 0x000d3000
[    8.850578] NDCB1: 0x57400000
[    8.850578] NDCB2: 0x00000000
[    8.850578] NDCB3: 0x00000000
[    8.869639] marvell-nfc pxa3xx-nand: 
[    8.869639] NDCR:  0xdd079fff
[    8.869639] NDCB0: 0x000d3000
[    8.869639] NDCB1: 0x57410000
[    8.869639] NDCB2: 0x00000000
[    8.869639] NDCB3: 0x00000000
[    8.888614] marvell-nfc pxa3xx-nand: 
[    8.888614] NDCR:  0x9d079fff
[    8.888614] NDCB0: 0x000d3000
[    8.888614] NDCB1: 0x57410000
[    8.888614] NDCB2: 0x00000000
[    8.888614] NDCB3: 0x00000000
[    8.907721] marvell-nfc pxa3xx-nand: 
[    8.907721] NDCR:  0xdd079fff
[    8.907721] NDCB0: 0x000d3000
[    8.907721] NDCB1: 0x57c00000
[    8.907721] NDCB2: 0x00000000
[    8.907721] NDCB3: 0x00000000
[    8.926778] marvell-nfc pxa3xx-nand: 
[    8.926778] NDCR:  0xdd079fff
[    8.926778] NDCB0: 0x000d3000
[    8.926778] NDCB1: 0x57c10000
[    8.926778] NDCB2: 0x00000000
[    8.926778] NDCB3: 0x00000000
[    8.945755] marvell-nfc pxa3xx-nand: 
[    8.945755] NDCR:  0x9d079fff
[    8.945755] NDCB0: 0x000d3000
[    8.945755] NDCB1: 0x57c10000
[    8.945755] NDCB2: 0x00000000
[    8.945755] NDCB3: 0x00000000
[    8.964856] marvell-nfc pxa3xx-nand: 
[    8.964856] NDCR:  0xdd079fff
[    8.964856] NDCB0: 0x000d3000
[    8.964856] NDCB1: 0x58000000
[    8.964856] NDCB2: 0x00000000
[    8.964856] NDCB3: 0x00000000
[    8.983915] marvell-nfc pxa3xx-nand: 
[    8.983915] NDCR:  0xdd079fff
[    8.983915] NDCB0: 0x000d3000
[    8.983915] NDCB1: 0x58010000
[    8.983915] NDCB2: 0x00000000
[    8.983915] NDCB3: 0x00000000
[    9.002886] marvell-nfc pxa3xx-nand: 
[    9.002886] NDCR:  0x9d079fff
[    9.002886] NDCB0: 0x000d3000
[    9.002886] NDCB1: 0x58010000
[    9.002886] NDCB2: 0x00000000
[    9.002886] NDCB3: 0x00000000
[    9.022075] marvell-nfc pxa3xx-nand: 
[    9.022075] NDCR:  0xdd079fff
[    9.022075] NDCB0: 0x000d3000
[    9.022075] NDCB1: 0x58400000
[    9.022075] NDCB2: 0x00000000
[    9.022075] NDCB3: 0x00000000
[    9.041141] marvell-nfc pxa3xx-nand: 
[    9.041141] NDCR:  0xdd079fff
[    9.041141] NDCB0: 0x000d3000
[    9.041141] NDCB1: 0x58410000
[    9.041141] NDCB2: 0x00000000
[    9.041141] NDCB3: 0x00000000
[    9.060123] marvell-nfc pxa3xx-nand: 
[    9.060123] NDCR:  0x9d079fff
[    9.060123] NDCB0: 0x000d3000
[    9.060123] NDCB1: 0x58410000
[    9.060123] NDCB2: 0x00000000
[    9.060123] NDCB3: 0x00000000
[    9.079435] ubi0: scanning is finished
[    9.083567] ubi0 error: ubi_read_volume_table: the layout volume was not found
[    9.090953] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd5, error -22
[    9.098457] UBI error: cannot attach mtd5
[    9.103950] pxa-rtc pxa-rtc: setting system clock to 2000-01-01 00:00:34 UTC (946684834)
[    9.187568] smc91x smc91x.0 eth0: link down
[   11.136140] smc91x smc91x.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
[   11.193199] IP-Config: Complete:
[   11.196554]      device=eth0, hwaddr=00:0e:0c:a7:26:f7, ipaddr=192.168.1.232, mask=255.255.255.0, gw=255.255.255.255
[   11.207229]      host=192.168.1.232, domain=, nis-domain=(none)
[   11.213278]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
[   11.221532] ALSA device list:
[   11.224983]   #0: Zylonite
[   11.250472] Freeing unused kernel memory: 2396K
[   11.255419] This architecture does not have kernel memory protection.
Starting logging: OK
Loading all the available modules: modprobe: module smc91x not found in modules.dep
modprobe: module soundcore not found in modules.dep
modprobe: module snd not found in modules.dep
modprobe: module snd-pcm not found in modules.dep
modprobe: module fat not found in modules.dep
modprobe: module vfat not found in modules.dep
modprobe: module nfs not found in modules.dep
modprobe: module nls_cp437 not found in modules.dep
modprobe: module nls_cp850 not found in modules.dep
modprobe: module nls_ascii not found in modules.dep
modprobe: module nls_utf8 not found in modules.dep
modprobe: module fixed not found in modules.dep
modprobe: module pwm-pxa not found in modules.dep
modprobe: module cpufreq_conservative not found in modules.dep
modprobe: module cpufreq_powersave not found in modules.dep
modprobe: module cpufreq-dt not found in modules.dep
modprobe: module btusb not found in modules.dep
modprobe: module i2c-dev not found in modules.dep
modprobe: module ubi not found in modules.dep
modprobe: module mt_blkdevs not found in modules.dep
modprobe: module pxa3xx_nand not found in modules.dep
modprobe: module mtdblock not found in modules.dep
modprobe: module ofpart not found in modules.dep
modprobe: module map_rom not found in modules.dep
modprobe: module jedec_probe not found in modules.dep
modprobe: module cmdlinepart not found in modules.dep
modprobe: module redboot not found in modules.dep
modprobe: module loop not found in modules.dep
modprobe: module leds-gpio not found in modules.dep
modprobe: module jedec-class not found in modules.dep
modprobe: module pxa not found in modules.dep
modprobe: module evdev not found in modules.dep
modprobe: module soc_common not found in modules.dep
modprobe: module pwm_bl not found in modules.dep
modprobe: module fbcon not found in modules.dep
modprobe: module rtc-pxa not found in modules.dep
modprobe: module rtc-sa1100 not found in modules.dep
modprobe: module smc91x not found in modules.dep
modprobe: module pda_power not found in modules.dep
modprobe: module fixed not found in modules.dep
KO
OK
Changing smcs91x MAC address to 08:00:3e:26:0a:5b: ifconfig: SIOCSIFHWADDR: Device or resource busy
KO
OK
Initializing random number generator... done.
Starting network...
ip: RTNETLINK answers: File exists
udhcpc (v1.24.1) started
Sending discover...
Sending select for 192.168.1.232...
Lease of 192.168.1.232 obtained, lease time 86400
deleting routers
adding dns 192.168.1.1
Starting dropbear sshd: OK

Welcome to Buildroot
zylonite login: 


From cyrille.pitchen at wedev4u.fr  Wed Jan  3 12:07:18 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Wed, 3 Jan 2018 21:07:18 +0100
Subject: [PATCH] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <1514976987-14082-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1514976987-14082-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <894be40c-07d2-4676-4da8-03124169039b@wedev4u.fr>

Le 03/01/2018 ? 11:56, Yogesh Gaur a ?crit :
> Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
> protocol. Spansion flash, s25fl512s, supports Quad read with read
> capabilities as 1-4-4.
> 
> Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.
> 
> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index c22e3eb..178e621 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -959,6 +959,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  {
>  	const struct spi_nor_hwcaps hwcaps = {
>  		.mask = SNOR_HWCAPS_READ_1_1_4 |
> +			SNOR_HWCAPS_READ_1_4_4 |
>  			SNOR_HWCAPS_PP,
>  	};
>  	struct device_node *np = pdev->dev.of_node;
> 

NACK: adding the SNOR_HWCAPS_READ_1_4_4 hardware capability tells
spi_nor_scan() that the SPI (flash) controller, not the SPI flash memory,
supports the SPI 1-4-4 for Fast Read operations.

You cannot add this flag without adding real support of Fast Read 1-4-4 to
the fsl-quadspi.c driver.


From boris.brezillon at free-electrons.com  Wed Jan  3 12:10:28 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 3 Jan 2018 21:10:28 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <878tded89m.fsf@belgarion.home>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
Message-ID: <20180103211028.619cd16d@bbrezillon>

On Wed, 03 Jan 2018 20:58:29 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> 
> > On Tue, 02 Jan 2018 20:21:09 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> >>   
> >> > I think the ECC issue you faced was related to pages being written
> >> > *and* empty. If this guess is right, the board should boot fine with
> >> > these changes.
> >> >
> >> > Otherwise, please add the DEBUG define as before in both the core
> >> > and the driver and do not hesitate to add another dump_stack()
> >> > where it crashes (if applicable).    
> >> 
> >> The problem looks still the same :
> >> [    3.560163] Bad block table not found for chip 0  
> >
> > Mmmmh ok.
> >
> > Can you please add this patch:
> > http://code.bulix.org/61at9p-254626  
> 
> Well, it looks a bit better, see attached log in [1].
> Now the BBT is detected ...
> [    3.310841] Bad block table found at page 131008, version 0x01
> ...
> [    3.354944] Bad block table found at page 130944, version 0x01
> 
> But all blocks are considered bad ... as if the bit logic was inverted for the
> meaning of "bad" or "good" block, see :
> [    3.379825] nand_read_bbt: bad block at 0x000000000000

Hm, that's weird. Can you try with the old driver (pxa3xx)? My guess is
that a new BBT has been written by the new driver after a full scan,
and we've seen with your previous logs that almost all blocks are
detected bad in this case (still don't know why: BBMs should be
preserved when using Hamming on 2k pages).

Anyway, if there's still a problem with the old driver, you'll have to
scrub the blocks containing the BBT from uboot (using nand scrub) to
restore things in a working state. And we also have to figure out why
BBM scan is not working with the new driver.

BTW, thanks for helping us with that, that's really appreciated.

Boris


> 
> Cheers.
> 
> --
> Robert
> 
> [1] Dmesg
> ---8>---  
> netconsole: port not set
> netconsole: registered as netconsole-1
> smc91c111 smc91c1110: chip is revision= 9, version= 2
> mdio_bus: miibus0: probed
> eth0: got preset MAC address: 00:0e:0c:a7:26:f7
> nand: NAND device: Manufacturer ID: 0x20, Chip ID: 0xba (ST Micro NAND 256MiB 1,8V 16-bit), 256MiB, page size: 2048, OOB size: 64
> mrvl_nand mrvl_nand0: ECC strength 1, ECC step size 512
> Bad block table found at page 131008, version 0x01
> Bad block table found at page 130944, version 0x01
> malloc space: 0x83700000 -> 0x83efffff (size 8 MiB)
> running /env/bin/init...
> magicvar: No such file or directory
> magicvar: No such file or directory
> magicvar: No such file or directory
> 
> Hit any key to stop autoboot:  3 2 1 0
> booting net
> netconsole: netconsole initialized with 255.255.255.255:6662
> eth0: 100Mbps full duplex link detected
> DHCP client bound to address 192.168.1.232
> netconsole: netconsole initialized with 255.255.255.255:6662
> could not open /mnt/tftp/none-linux-zylonite: No such file or directory
> Booting net failed: No such file or directory
> booting net failed: No such file or directory
> boot: No such file or directory
> .[1;32mbarebox at .[1;36mZylonite:/.[0m global linux.bootargs.debug=earlycon
> .[1;32mbarebox at .[1;36mZylonite:/.[0m bootm /mnt/tftp/zImage_jenkins
> 
> Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
> commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
> arch_number: 1233
> Uncompressing Linux... done, booting the kernel.
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 4.15.0-rc1-00044-gb6124ba (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #825 PREEMPT Wed Jan 3 20:06:17 CET 2018
> [    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
> [    0.000000] CPU: VIVT data cache, VIVT instruction cache
> [    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
> [    0.000000] Ignoring tag cmdline (using the default kernel command line)
> [    0.000000] Memory policy: Data cache writeback
> [    0.000000] RO Mode clock: 0.00MHz
> [    0.000000] Run Mode clock: 0.00MHz
> [    0.000000] Turbo Mode clock: 0.00MHz
> [    0.000000] System bus clock: 0.00MHz
> [    0.000000] On node 0 totalpages: 16384
> [    0.000000]   Normal zone: 128 pages used for memmap
> [    0.000000]   Normal zone: 0 pages reserved
> [    0.000000]   Normal zone: 16384 pages, LIFO batch:3
> [    0.000000] random: fast init done
> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
> [    0.000000] pcpu-alloc: [0] 0 
> [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
> [    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
> [    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
> [    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
> [    0.000000] Memory: 56856K/65536K available (4225K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
> [    0.000000] Virtual kernel memory layout:
> [    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
> [    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
> [    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
> [    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
> [    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
> [    0.000000]       .text : 0xc0008000 - 0xc04289e8   (4227 kB)
> [    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
> [    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
> [    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
> [    0.000000] Preemptible hierarchical RCU implementation.
> [    0.000000] 	Tasks RCU enabled.
> [    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
> [    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
> [    0.000068] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
> [    0.000267] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
> [    0.002138] Console: colour dummy device 80x30
> [    0.002297] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
> [    0.081017] pid_max: default: 32768 minimum: 301
> [    0.081857] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.081957] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.085169] CPU: Testing write buffer coherency: ok
> [    0.088982] Setting up static identity map for 0x80008200 - 0x80008260
> [    0.089941] Hierarchical SRCU implementation.
> [    0.102960] devtmpfs: initialized
> [    0.113840] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
> [    0.113980] futex hash table entries: 256 (order: -1, 3072 bytes)
> [    0.116305] NET: Registered protocol family 16
> [    0.119116] DMA: preallocated 256 KiB pool for atomic coherent allocations
> [    0.388612] Advanced Linux Sound Architecture Driver Initialized.
> [    0.392974] clocksource: Switched to clocksource oscr0
> [    0.551626] NET: Registered protocol family 2
> [    0.557926] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.558151] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.558332] TCP: Hash tables configured (established 1024 bind 1024)
> [    0.558869] UDP hash table entries: 256 (order: 0, 4096 bytes)
> [    0.559048] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
> [    0.560201] NET: Registered protocol family 1
> [    0.562229] RPC: Registered named UNIX socket transport module.
> [    0.562327] RPC: Registered udp transport module.
> [    0.562381] RPC: Registered tcp transport module.
> [    0.562439] RPC: Registered tcp NFSv4.1 backchannel transport module.
> [    2.500715] Initialise system trusted keyrings
> [    2.502868] workingset: timestamp_bits=30 max_order=14 bucket_order=0
> [    2.507406] NFS: Registering the id_resolver key type
> [    2.507634] Key type id_resolver registered
> [    2.507695] Key type id_legacy registered
> [    2.514199] Key type asymmetric registered
> [    2.514303] Asymmetric key parser 'x509' registered
> [    2.514462] io scheduler noop registered
> [    2.514527] io scheduler deadline registered
> [    2.514921] io scheduler cfq registered (default)
> [    2.514992] io scheduler mq-deadline registered
> [    2.515054] io scheduler kyber registered
> [    2.572587] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
> [    2.578330] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
> [    3.053207] console [ttyS0] enabled
> [    3.059557] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
> [    3.072069] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
> [    3.088037] nand: executing subop:
> [    3.091533] nand:     ->CMD      [0xff]
> [    3.098135] nand:     ->WAITRDY  [max 250 ms]
> [    3.102636] marvell-nfc pxa3xx-nand: 
> [    3.102636] NDCR:  0x90079fff
> [    3.102636] NDCB0: 0x00a000ff
> [    3.102636] NDCB1: 0x00000000
> [    3.102636] NDCB2: 0x00000000
> [    3.102636] NDCB3: 0x00000000
> [    3.121629] nand: executing subop:
> [    3.125459] nand:     ->CMD      [0x90]
> [    3.129362] nand:     ->ADDR     [1 cyc: 00]
> [    3.134355] nand:     ->DATA_IN  [2 B, force 8-bit]
> [    3.139366] marvell-nfc pxa3xx-nand: 
> [    3.139366] NDCR:  0x90079fff
> [    3.139366] NDCB0: 0x00610090
> [    3.139366] NDCB1: 0x00000000
> [    3.139366] NDCB2: 0x00000000
> [    3.139366] NDCB3: 0x00000000
> [    3.158242] nand: executing subop:
> [    3.161713] nand:     ->CMD      [0x90]
> [    3.165930] nand:     ->ADDR     [1 cyc: 00]
> [    3.170250] nand:     ->DATA_IN  [8 B, force 8-bit]
> [    3.175405] marvell-nfc pxa3xx-nand: 
> [    3.175405] NDCR:  0x90079fff
> [    3.175405] NDCB0: 0x00610090
> [    3.175405] NDCB1: 0x00000000
> [    3.175405] NDCB2: 0x00000000
> [    3.175405] NDCB3: 0x00000000
> [    3.194083] nand: executing subop:
> [    3.197532] nand:     ->CMD      [0x90]
> [    3.201406] nand:     ->ADDR     [1 cyc: 20]
> [    3.205851] nand:     ->DATA_IN  [4 B, force 8-bit]
> [    3.210832] marvell-nfc pxa3xx-nand: 
> [    3.210832] NDCR:  0x90079fff
> [    3.210832] NDCB0: 0x00610090
> [    3.210832] NDCB1: 0x00000020
> [    3.210832] NDCB2: 0x00000000
> [    3.210832] NDCB3: 0x00000000
> [    3.229453] nand: executing subop:
> [    3.232899] nand:     ->CMD      [0x90]
> [    3.236930] nand:     ->ADDR     [1 cyc: 40]
> [    3.241232] nand:     ->DATA_IN  [5 B, force 8-bit]
> [    3.246335] marvell-nfc pxa3xx-nand: 
> [    3.246335] NDCR:  0x90079fff
> [    3.246335] NDCB0: 0x00610090
> [    3.246335] NDCB1: 0x00000040
> [    3.246335] NDCB2: 0x00000000
> [    3.246335] NDCB3: 0x00000000
> [    3.264978] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
> [    3.271354] nand: ST Micro NAND 256MiB 1,8V 16-bit
> [    3.276316] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> [    3.284055] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
> [    3.291595] marvell-nfc pxa3xx-nand: 
> [    3.291595] NDCR:  0xdd079fff
> [    3.291595] NDCB0: 0x000d3000
> [    3.291595] NDCB1: 0xffc00000
> [    3.291595] NDCB2: 0x00000001
> [    3.291595] NDCB3: 0x00000000
> [    3.310841] Bad block table found at page 131008, version 0x01
> [    3.316993] marvell-nfc pxa3xx-nand: 
> [    3.316993] NDCR:  0xdd079fff
> [    3.316993] NDCB0: 0x000d3000
> [    3.316993] NDCB1: 0xffc00000
> [    3.316993] NDCB2: 0x00000001
> [    3.316993] NDCB3: 0x00000000
> [    3.336013] marvell-nfc pxa3xx-nand: 
> [    3.336013] NDCR:  0xdd079fff
> [    3.336013] NDCB0: 0x000d3000
> [    3.336013] NDCB1: 0xff800000
> [    3.336013] NDCB2: 0x00000001
> [    3.336013] NDCB3: 0x00000000
> [    3.354944] Bad block table found at page 130944, version 0x01
> [    3.360915] marvell-nfc pxa3xx-nand: 
> [    3.360915] NDCR:  0xdd079fff
> [    3.360915] NDCB0: 0x000d3000
> [    3.360915] NDCB1: 0xffc00000
> [    3.360915] NDCB2: 0x00000001
> [    3.360915] NDCB3: 0x00000000
> [    3.379825] nand_read_bbt: bad block at 0x000000000000
> [    3.385158] nand_read_bbt: bad block at 0x000000040000
> [    3.390320] nand_read_bbt: bad block at 0x000000060000
> [    3.395587] nand_read_bbt: bad block at 0x000000080000
> [    3.400743] nand_read_bbt: bad block at 0x0000000a0000
> [    3.406009] nand_read_bbt: bad block at 0x0000000c0000
> [    3.411169] nand_read_bbt: bad block at 0x0000000e0000
> [    3.416434] nand_read_bbt: bad block at 0x000000100000
> [    3.421593] nand_read_bbt: bad block at 0x000000140000
> [    3.426859] nand_read_bbt: bad block at 0x000000160000
> [    3.432018] nand_read_bbt: bad block at 0x000000180000
> [    3.437283] nand_read_bbt: bad block at 0x0000001a0000
> [    3.442442] nand_read_bbt: bad block at 0x0000001c0000
> [    3.447707] nand_read_bbt: bad block at 0x0000001e0000
> [    3.452867] nand_read_bbt: bad block at 0x000000200000
> [    3.458133] nand_read_bbt: bad block at 0x000000220000
> [    3.463404] nand_read_bbt: bad block at 0x000000240000
> [    3.468564] nand_read_bbt: bad block at 0x000000260000
> [    3.473830] nand_read_bbt: bad block at 0x000000280000
> [    3.478990] nand_read_bbt: bad block at 0x0000002a0000
> [    3.484253] nand_read_bbt: bad block at 0x0000002c0000
> [    3.489414] nand_read_bbt: bad block at 0x0000002e0000
> [    3.494680] nand_read_bbt: bad block at 0x000000300000
> [    3.499838] nand_read_bbt: bad block at 0x000000320000
> [    3.505104] nand_read_bbt: bad block at 0x000000340000
> [    3.510262] nand_read_bbt: bad block at 0x000000360000
> [    3.515529] nand_read_bbt: bad block at 0x000000380000
> [    3.520687] nand_read_bbt: bad block at 0x0000003a0000
> [    3.525955] nand_read_bbt: bad block at 0x0000003c0000
> [    3.531121] nand_read_bbt: bad block at 0x0000003e0000
> [    3.536386] nand_read_bbt: bad block at 0x000000400000
> [    3.541544] nand_read_bbt: bad block at 0x000000420000
> [    3.546811] nand_read_bbt: bad block at 0x000000440000
> [    3.551970] nand_read_bbt: bad block at 0x000000460000
> [    3.557234] nand_read_bbt: bad block at 0x000000480000
> [    3.562394] nand_read_bbt: bad block at 0x0000004a0000
> [    3.567659] nand_read_bbt: bad block at 0x0000004c0000
> [    3.572819] nand_read_bbt: bad block at 0x0000004e0000
> [    3.578087] nand_read_bbt: bad block at 0x000000500000
> [    3.583367] nand_read_bbt: bad block at 0x000000520000
> [    3.588524] nand_read_bbt: bad block at 0x000000540000
> [    3.593788] nand_read_bbt: bad block at 0x000000560000
> [    3.598951] nand_read_bbt: bad block at 0x000000580000
> [    3.604213] nand_read_bbt: bad block at 0x0000005a0000
> [    3.609373] nand_read_bbt: bad block at 0x0000005c0000
> [    3.614639] nand_read_bbt: bad block at 0x0000005e0000
> [    3.619799] nand_read_bbt: bad block at 0x000000600000
> [    3.625064] nand_read_bbt: bad block at 0x000000620000
> [    3.630224] nand_read_bbt: bad block at 0x000000640000
> [    3.635488] nand_read_bbt: bad block at 0x000000660000
> [    3.640648] nand_read_bbt: bad block at 0x000000680000
> [    3.645914] nand_read_bbt: bad block at 0x0000006a0000
> [    3.651071] nand_read_bbt: bad block at 0x0000006c0000
> [    3.656337] nand_read_bbt: bad block at 0x0000006e0000
> [    3.661497] nand_read_bbt: bad block at 0x000000700000
> [    3.666774] nand_read_bbt: bad block at 0x000000d40000
> [    3.671939] nand_read_bbt: bad block at 0x000000d60000
> [    3.677206] nand_read_bbt: bad block at 0x000000d80000
> [    3.682373] nand_read_bbt: bad block at 0x000000da0000
> [    3.687638] nand_read_bbt: bad block at 0x000000dc0000
> [    3.692796] nand_read_bbt: bad block at 0x000000de0000
> [    3.698063] nand_read_bbt: bad block at 0x000000e00000
> [    3.703334] nand_read_bbt: bad block at 0x000000e20000
> [    3.708494] nand_read_bbt: bad block at 0x000000e40000
> [    3.713759] nand_read_bbt: bad block at 0x000000e60000
> [    3.718919] nand_read_bbt: bad block at 0x000000e80000
> [    3.724183] nand_read_bbt: bad block at 0x000000ea0000
> [    3.729343] nand_read_bbt: bad block at 0x000000ec0000
> [    3.734608] nand_read_bbt: bad block at 0x000000ee0000
> [    3.739769] nand_read_bbt: bad block at 0x000000f00000
> [    3.745033] nand_read_bbt: bad block at 0x000000f20000
> [    3.750192] nand_read_bbt: bad block at 0x000000f40000
> [    3.755459] nand_read_bbt: bad block at 0x000000f60000
> [    3.760617] nand_read_bbt: bad block at 0x000000f80000
> [    3.765882] nand_read_bbt: bad block at 0x000000fa0000
> [    3.771041] nand_read_bbt: bad block at 0x000000fc0000
> [    3.776306] nand_read_bbt: bad block at 0x000000fe0000
> [    3.781467] nand_read_bbt: bad block at 0x000001000000
> [    3.786731] nand_read_bbt: bad block at 0x000001020000
> [    3.791891] nand_read_bbt: bad block at 0x000001040000
> [    3.797156] nand_read_bbt: bad block at 0x000001060000
> [    3.802317] nand_read_bbt: bad block at 0x000001080000
> [    3.807582] nand_read_bbt: bad block at 0x0000010a0000
> [    3.812741] nand_read_bbt: bad block at 0x0000010c0000
> [    3.818005] nand_read_bbt: bad block at 0x0000010e0000
> [    3.823280] nand_read_bbt: bad block at 0x000001100000
> [    3.828438] nand_read_bbt: bad block at 0x000001120000
> [    3.833702] nand_read_bbt: bad block at 0x000001140000
> [    3.838862] nand_read_bbt: bad block at 0x000001160000
> [    3.844129] nand_read_bbt: bad block at 0x000001180000
> [    3.849294] nand_read_bbt: bad block at 0x000001660000
> [    3.854562] nand_read_bbt: bad block at 0x000001680000
> [    3.859719] nand_read_bbt: bad block at 0x0000016a0000
> [    3.864986] nand_read_bbt: bad block at 0x0000016c0000
> [    3.870143] nand_read_bbt: bad block at 0x0000016e0000
> [    3.875409] nand_read_bbt: bad block at 0x000001700000
> [    3.880569] nand_read_bbt: bad block at 0x000001720000
> [    3.885836] nand_read_bbt: bad block at 0x000001740000
> [    3.890994] nand_read_bbt: bad block at 0x000001760000
> [    3.896260] nand_read_bbt: bad block at 0x000001780000
> [    3.901417] nand_read_bbt: bad block at 0x0000017a0000
> [    3.906683] nand_read_bbt: bad block at 0x0000017c0000
> [    3.911843] nand_read_bbt: bad block at 0x0000017e0000
> [    3.917108] nand_read_bbt: bad block at 0x000001800000
> [    3.922267] nand_read_bbt: bad block at 0x000001820000
> [    3.927534] nand_read_bbt: bad block at 0x000001840000
> [    3.932691] nand_read_bbt: bad block at 0x000001860000
> [    3.937957] nand_read_bbt: bad block at 0x000001880000
> [    3.943230] nand_read_bbt: bad block at 0x0000018a0000
> [    3.948390] nand_read_bbt: bad block at 0x0000018c0000
> [    3.953654] nand_read_bbt: bad block at 0x0000018e0000
> [    3.958815] nand_read_bbt: bad block at 0x000001900000
> [    3.964101] nand_read_bbt: bad block at 0x000001920000
> [    3.969264] nand_read_bbt: bad block at 0x000001940000
> [    3.974531] nand_read_bbt: bad block at 0x000001960000
> [    3.979690] nand_read_bbt: bad block at 0x000001980000
> [    3.984952] nand_read_bbt: bad block at 0x0000019a0000
> [    3.990114] nand_read_bbt: bad block at 0x0000019c0000
> [    3.995381] nand_read_bbt: bad block at 0x0000019e0000
> [    4.000539] nand_read_bbt: bad block at 0x000001a00000
> [    4.005804] nand_read_bbt: bad block at 0x000001a20000
> [    4.010964] nand_read_bbt: bad block at 0x000001a40000
> [    4.016236] nand_read_bbt: bad block at 0x000001a60000
> [    4.021398] nand_read_bbt: bad block at 0x000001a80000
> [    4.026664] nand_read_bbt: bad block at 0x000001aa0000
> [    4.031822] nand_read_bbt: bad block at 0x000001ac0000
> [    4.037086] nand_read_bbt: bad block at 0x000001ae0000
> [    4.042247] nand_read_bbt: bad block at 0x000001b00000
> [    4.047512] nand_read_bbt: bad block at 0x000001b20000
> [    4.052672] nand_read_bbt: bad block at 0x000001b40000
> [    4.057935] nand_read_bbt: bad block at 0x000001b60000
> [    4.063211] nand_read_bbt: bad block at 0x000001b80000
> [    4.068377] nand_read_bbt: bad block at 0x000001ba0000
> [    4.073643] nand_read_bbt: bad block at 0x000001bc0000
> [    4.078801] nand_read_bbt: bad block at 0x000001be0000
> [    4.084068] nand_read_bbt: bad block at 0x000001c00000
> [    4.089235] nand_read_bbt: bad block at 0x000001c20000
> [    4.094836] nand_read_bbt: bad block at 0x000001c40000
> [    4.100012] nand_read_bbt: bad block at 0x000001c60000
> [    4.105327] nand_read_bbt: bad block at 0x000001c80000
> [    4.110488] nand_read_bbt: bad block at 0x000001ca0000
> [    4.115755] nand_read_bbt: bad block at 0x000001cc0000
> [    4.120923] nand_read_bbt: bad block at 0x000001ce0000
> [    4.126186] nand_read_bbt: bad block at 0x000001d00000
> [    4.131347] nand_read_bbt: bad block at 0x000001d20000
> [    4.136610] nand_read_bbt: bad block at 0x000001d40000
> [    4.141770] nand_read_bbt: bad block at 0x000001d60000
> [    4.147038] nand_read_bbt: bad block at 0x000001d80000
> [    4.152204] nand_read_bbt: bad block at 0x000001da0000
> [    4.157470] nand_read_bbt: bad block at 0x000001dc0000
> [    4.162627] nand_read_bbt: bad block at 0x000001de0000
> [    4.167894] nand_read_bbt: bad block at 0x000001e00000
> [    4.173167] nand_read_bbt: bad block at 0x000001e20000
> [    4.178325] nand_read_bbt: bad block at 0x000001e40000
> [    4.183591] nand_read_bbt: bad block at 0x000001e60000
> [    4.188752] nand_read_bbt: bad block at 0x000001e80000
> [    4.194015] nand_read_bbt: bad block at 0x000001ea0000
> [    4.199175] nand_read_bbt: bad block at 0x000001ec0000
> [    4.204441] nand_read_bbt: bad block at 0x000001ee0000
> [    4.209601] nand_read_bbt: bad block at 0x000001f00000
> [    4.214865] nand_read_bbt: bad block at 0x000001f20000
> [    4.220024] nand_read_bbt: bad block at 0x000001f40000
> [    4.225290] nand_read_bbt: bad block at 0x000001f60000
> [    4.230450] nand_read_bbt: bad block at 0x000001f80000
> [    4.235713] nand_read_bbt: bad block at 0x000001fa0000
> [    4.240874] nand_read_bbt: bad block at 0x000001fc0000
> [    4.246138] nand_read_bbt: bad block at 0x000001fe0000
> [    4.251299] nand_read_bbt: bad block at 0x000002000000
> [    4.256564] nand_read_bbt: bad block at 0x000002020000
> [    4.261723] nand_read_bbt: bad block at 0x000002040000
> [    4.266988] nand_read_bbt: bad block at 0x000002060000
> [    4.272148] nand_read_bbt: bad block at 0x000002080000
> [    4.277412] nand_read_bbt: bad block at 0x0000020a0000
> [    4.282572] nand_read_bbt: bad block at 0x0000020c0000
> [    4.287837] nand_read_bbt: bad block at 0x0000020e0000
> [    4.293111] nand_read_bbt: bad block at 0x000002100000
> [    4.298278] nand_read_bbt: bad block at 0x000002120000
> [    4.303545] nand_read_bbt: bad block at 0x000002140000
> [    4.308703] nand_read_bbt: bad block at 0x000002160000
> [    4.313967] nand_read_bbt: bad block at 0x000002180000
> [    4.319128] nand_read_bbt: bad block at 0x0000021a0000
> [    4.324391] nand_read_bbt: bad block at 0x0000021c0000
> [    4.329552] nand_read_bbt: bad block at 0x0000021e0000
> [    4.334818] nand_read_bbt: bad block at 0x000002200000
> [    4.339977] nand_read_bbt: bad block at 0x000002220000
> [    4.345242] nand_read_bbt: bad block at 0x000002240000
> [    4.350402] nand_read_bbt: bad block at 0x000002260000
> [    4.355667] nand_read_bbt: bad block at 0x000002280000
> [    4.360826] nand_read_bbt: bad block at 0x0000022a0000
> [    4.366091] nand_read_bbt: bad block at 0x0000022c0000
> [    4.371251] nand_read_bbt: bad block at 0x0000022e0000
> [    4.376515] nand_read_bbt: bad block at 0x000002300000
> [    4.381674] nand_read_bbt: bad block at 0x000002320000
> [    4.386941] nand_read_bbt: bad block at 0x000002340000
> [    4.392101] nand_read_bbt: bad block at 0x000002360000
> [    4.397365] nand_read_bbt: bad block at 0x000002380000
> [    4.402523] nand_read_bbt: bad block at 0x0000023a0000
> [    4.407789] nand_read_bbt: bad block at 0x0000023c0000
> [    4.413062] nand_read_bbt: bad block at 0x0000023e0000
> [    4.418223] nand_read_bbt: bad block at 0x000002400000
> [    4.423485] nand_read_bbt: bad block at 0x000002420000
> [    4.428646] nand_read_bbt: bad block at 0x000002440000
> [    4.433907] nand_read_bbt: bad block at 0x000002460000
> [    4.439071] nand_read_bbt: bad block at 0x000002480000
> [    4.444336] nand_read_bbt: bad block at 0x0000024a0000
> [    4.449496] nand_read_bbt: bad block at 0x0000024c0000
> [    4.454759] nand_read_bbt: bad block at 0x0000024e0000
> [    4.459922] nand_read_bbt: bad block at 0x000002500000
> [    4.465187] nand_read_bbt: bad block at 0x000002520000
> [    4.470344] nand_read_bbt: bad block at 0x000002540000
> [    4.475609] nand_read_bbt: bad block at 0x000002560000
> [    4.480771] nand_read_bbt: bad block at 0x000002580000
> [    4.486033] nand_read_bbt: bad block at 0x0000025a0000
> [    4.491194] nand_read_bbt: bad block at 0x0000025c0000
> [    4.496458] nand_read_bbt: bad block at 0x0000025e0000
> [    4.501619] nand_read_bbt: bad block at 0x000002600000
> [    4.506882] nand_read_bbt: bad block at 0x000002620000
> [    4.512042] nand_read_bbt: bad block at 0x000002640000
> [    4.517307] nand_read_bbt: bad block at 0x000002660000
> [    4.522468] nand_read_bbt: bad block at 0x000002680000
> [    4.527732] nand_read_bbt: bad block at 0x0000026a0000
> [    4.532891] nand_read_bbt: bad block at 0x0000026c0000
> [    4.538162] nand_read_bbt: bad block at 0x0000026e0000
> [    4.543428] nand_read_bbt: bad block at 0x000002700000
> [    4.548590] nand_read_bbt: bad block at 0x000002720000
> [    4.553857] nand_read_bbt: bad block at 0x000002740000
> [    4.559014] nand_read_bbt: bad block at 0x000002760000
> [    4.564280] nand_read_bbt: bad block at 0x000002780000
> [    4.569438] nand_read_bbt: bad block at 0x0000027a0000
> [    4.574705] nand_read_bbt: bad block at 0x0000027c0000
> [    4.579863] nand_read_bbt: bad block at 0x0000027e0000
> [    4.585129] nand_read_bbt: bad block at 0x000002800000
> [    4.590288] nand_read_bbt: bad block at 0x000002820000
> [    4.595558] nand_read_bbt: bad block at 0x000002a40000
> [    4.600720] nand_read_bbt: bad block at 0x000002a60000
> [    4.606012] nand_read_bbt: bad block at 0x000002bc0000
> [    4.611182] nand_read_bbt: bad block at 0x000002c40000
> [    4.616449] nand_read_bbt: bad block at 0x000002c60000
> [    4.621614] nand_read_bbt: bad block at 0x000002c80000
> [    4.626878] nand_read_bbt: bad block at 0x000002ca0000
> [    4.632036] nand_read_bbt: bad block at 0x000002cc0000
> [    4.637301] nand_read_bbt: bad block at 0x000002ce0000
> [    4.642463] nand_read_bbt: bad block at 0x000002d00000
> [    4.647726] nand_read_bbt: bad block at 0x000002d20000
> [    4.652888] nand_read_bbt: bad block at 0x000002d40000
> [    4.658167] nand_read_bbt: bad block at 0x000002d60000
> [    4.663433] nand_read_bbt: bad block at 0x000002d80000
> [    4.668593] nand_read_bbt: bad block at 0x000002da0000
> [    4.673859] nand_read_bbt: bad block at 0x000002dc0000
> [    4.679017] nand_read_bbt: bad block at 0x000002de0000
> [    4.684282] nand_read_bbt: bad block at 0x000002e00000
> [    4.689442] nand_read_bbt: bad block at 0x000002e20000
> [    4.694707] nand_read_bbt: bad block at 0x000002e40000
> [    4.699867] nand_read_bbt: bad block at 0x000002e60000
> [    4.705133] nand_read_bbt: bad block at 0x000002e80000
> [    4.710292] nand_read_bbt: bad block at 0x000002ea0000
> [    4.715558] nand_read_bbt: bad block at 0x000002ec0000
> [    4.720716] nand_read_bbt: bad block at 0x000002ee0000
> [    4.725983] nand_read_bbt: bad block at 0x000002f00000
> [    4.731141] nand_read_bbt: bad block at 0x000002f20000
> [    4.736406] nand_read_bbt: bad block at 0x000002f40000
> [    4.741566] nand_read_bbt: bad block at 0x000002f60000
> [    4.746830] nand_read_bbt: bad block at 0x000002f80000
> [    4.751991] nand_read_bbt: bad block at 0x000002fa0000
> [    4.757255] nand_read_bbt: bad block at 0x000002fc0000
> [    4.762415] nand_read_bbt: bad block at 0x000002fe0000
> [    4.767681] nand_read_bbt: bad block at 0x000003000000
> [    4.772839] nand_read_bbt: bad block at 0x000003020000
> [    4.778104] nand_read_bbt: bad block at 0x000003040000
> [    4.783378] nand_read_bbt: bad block at 0x000003060000
> [    4.788536] nand_read_bbt: bad block at 0x000003080000
> [    4.793802] nand_read_bbt: bad block at 0x0000030a0000
> [    4.798962] nand_read_bbt: bad block at 0x0000030c0000
> [    4.804224] nand_read_bbt: bad block at 0x0000030e0000
> [    4.809387] nand_read_bbt: bad block at 0x000003100000
> [    4.814650] nand_read_bbt: bad block at 0x000003120000
> [    4.819809] nand_read_bbt: bad block at 0x000003140000
> [    4.825075] nand_read_bbt: bad block at 0x000003160000
> [    4.830235] nand_read_bbt: bad block at 0x000003180000
> [    4.835499] nand_read_bbt: bad block at 0x0000031a0000
> [    4.840661] nand_read_bbt: bad block at 0x0000031c0000
> [    4.845924] nand_read_bbt: bad block at 0x0000031e0000
> [    4.851085] nand_read_bbt: bad block at 0x000003200000
> [    4.856350] nand_read_bbt: bad block at 0x000003220000
> [    4.861510] nand_read_bbt: bad block at 0x000003240000
> [    4.867593] 6 cmdlinepart partitions found on MTD device pxa3xx_nand-0
> [    4.874441] Creating 6 MTD partitions on "pxa3xx_nand-0":
> [    4.879899] 0x000000000000-0x000000020000 : "TIMH"
> [    4.888233] 0x000000020000-0x000000040000 : "OBMI"
> [    4.897663] 0x000000040000-0x000000100000 : "barebox"
> [    4.907444] 0x000000100000-0x000000140000 : "barebox-env"
> [    4.917447] 0x000000140000-0x000000d40000 : "kernel"
> [    4.927958] 0x000000d40000-0x000003260000 : "root"
> [    4.941349] smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico at fluxnic.net>
> [    4.994377] smc91x smc91x.0 eth0: SMC91C11xFD (rev 2) at c4867300 IRQ 214
> [    5.001216]  DMA c386d710 [nowait]
> [    5.005891] smc91x smc91x.0 eth0: Ethernet addr: 00:0e:0c:a7:26:f7
> [    5.018621] input: pxa27x-keypad as /devices/platform/pxa27x-keypad/input/input0
> [    5.028503] pxa-rtc pxa-rtc: failed to find rtc clock source
> [    5.036108] rtc rtc0: invalid alarm value: 0-1-1 0:0:0
> [    5.043390] pxa-rtc pxa-rtc: rtc core: registered pxa-rtc as rtc0
> [    5.054574] sa1100_wdt: SA1100/PXA2xx Watchdog Timer: timer margin 60 sec
> [    5.106260] soc-audio soc-audio: ASoC: machine Zylonite should use snd_soc_register_card()
> [    5.130166] wm9713-codec wm9713-codec: Control not supported for path Mic B Source -> [MPB] -> Mic B Pre Amp
> [    5.141137] wm9713-codec wm9713-codec: ASoC: no dapm match for Mic B Source --> MPB --> Mic B Pre Amp
> [    5.150835] wm9713-codec wm9713-codec: ASoC: Failed to add route Mic B Source -> MPB -> Mic B Pre Amp
> [    5.164361] soc-audio soc-audio: wm9713-hifi <-> pxa2xx-ac97 mapping ok
> [    5.172711] soc-audio soc-audio: wm9713-aux <-> pxa2xx-ac97-aux mapping ok
> [    5.183377] soc-audio soc-audio: wm9713-voice <-> pxa-ssp-dai.2 mapping ok
> [    5.191817] wm9713-codec wm9713-codec: ASoC: mux Sidetone Mux has no paths
> [    5.232193] NET: Registered protocol family 17
> [    5.238583] Key type dns_resolver registered
> [    5.244879] XScale iWMMXt coprocessor detected.
> [    5.257208] Loading compiled-in X.509 certificates
> [    5.277841] ubi0: attaching mtd5
> [    5.282062] marvell-nfc pxa3xx-nand: 
> [    5.282062] NDCR:  0xdd079fff
> [    5.282062] NDCB0: 0x000d3000
> [    5.282062] NDCB1: 0x23400000
> [    5.282062] NDCB2: 0x00000000
> [    5.282062] NDCB3: 0x00000000
> [    5.302767] marvell-nfc pxa3xx-nand: 
> [    5.302767] NDCR:  0xdd079fff
> [    5.302767] NDCB0: 0x000d3000
> [    5.302767] NDCB1: 0x23410000
> [    5.302767] NDCB2: 0x00000000
> [    5.302767] NDCB3: 0x00000000
> [    5.322069] marvell-nfc pxa3xx-nand: 
> [    5.322069] NDCR:  0x9d079fff
> [    5.322069] NDCB0: 0x000d3000
> [    5.322069] NDCB1: 0x23410000
> [    5.322069] NDCB2: 0x00000000
> [    5.322069] NDCB3: 0x00000000
> [    5.341520] marvell-nfc pxa3xx-nand: 
> [    5.341520] NDCR:  0xdd079fff
> [    5.341520] NDCB0: 0x000d3000
> [    5.341520] NDCB1: 0x23800000
> [    5.341520] NDCB2: 0x00000000
> [    5.341520] NDCB3: 0x00000000
> [    5.361115] marvell-nfc pxa3xx-nand: 
> [    5.361115] NDCR:  0xdd079fff
> [    5.361115] NDCB0: 0x000d3000
> [    5.361115] NDCB1: 0x23810000
> [    5.361115] NDCB2: 0x00000000
> [    5.361115] NDCB3: 0x00000000
> [    5.380361] marvell-nfc pxa3xx-nand: 
> [    5.380361] NDCR:  0x9d079fff
> [    5.380361] NDCB0: 0x000d3000
> [    5.380361] NDCB1: 0x23810000
> [    5.380361] NDCB2: 0x00000000
> [    5.380361] NDCB3: 0x00000000
> [    5.399699] marvell-nfc pxa3xx-nand: 
> [    5.399699] NDCR:  0xdd079fff
> [    5.399699] NDCB0: 0x000d3000
> [    5.399699] NDCB1: 0x23c00000
> [    5.399699] NDCB2: 0x00000000
> [    5.399699] NDCB3: 0x00000000
> [    5.418790] marvell-nfc pxa3xx-nand: 
> [    5.418790] NDCR:  0xdd079fff
> [    5.418790] NDCB0: 0x000d3000
> [    5.418790] NDCB1: 0x23c10000
> [    5.418790] NDCB2: 0x00000000
> [    5.418790] NDCB3: 0x00000000
> [    5.437771] marvell-nfc pxa3xx-nand: 
> [    5.437771] NDCR:  0x9d079fff
> [    5.437771] NDCB0: 0x000d3000
> [    5.437771] NDCB1: 0x23c10000
> [    5.437771] NDCB2: 0x00000000
> [    5.437771] NDCB3: 0x00000000
> [    5.456876] marvell-nfc pxa3xx-nand: 
> [    5.456876] NDCR:  0xdd079fff
> [    5.456876] NDCB0: 0x000d3000
> [    5.456876] NDCB1: 0x24000000
> [    5.456876] NDCB2: 0x00000000
> [    5.456876] NDCB3: 0x00000000
> [    5.475940] marvell-nfc pxa3xx-nand: 
> [    5.475940] NDCR:  0xdd079fff
> [    5.475940] NDCB0: 0x000d3000
> [    5.475940] NDCB1: 0x24010000
> [    5.475940] NDCB2: 0x00000000
> [    5.475940] NDCB3: 0x00000000
> [    5.494922] marvell-nfc pxa3xx-nand: 
> [    5.494922] NDCR:  0x9d079fff
> [    5.494922] NDCB0: 0x000d3000
> [    5.494922] NDCB1: 0x24010000
> [    5.494922] NDCB2: 0x00000000
> [    5.494922] NDCB3: 0x00000000
> [    5.514028] marvell-nfc pxa3xx-nand: 
> [    5.514028] NDCR:  0xdd079fff
> [    5.514028] NDCB0: 0x000d3000
> [    5.514028] NDCB1: 0x24400000
> [    5.514028] NDCB2: 0x00000000
> [    5.514028] NDCB3: 0x00000000
> [    5.533183] marvell-nfc pxa3xx-nand: 
> [    5.533183] NDCR:  0xdd079fff
> [    5.533183] NDCB0: 0x000d3000
> [    5.533183] NDCB1: 0x24410000
> [    5.533183] NDCB2: 0x00000000
> [    5.533183] NDCB3: 0x00000000
> [    5.552166] marvell-nfc pxa3xx-nand: 
> [    5.552166] NDCR:  0x9d079fff
> [    5.552166] NDCB0: 0x000d3000
> [    5.552166] NDCB1: 0x24410000
> [    5.552166] NDCB2: 0x00000000
> [    5.552166] NDCB3: 0x00000000
> [    5.571273] marvell-nfc pxa3xx-nand: 
> [    5.571273] NDCR:  0xdd079fff
> [    5.571273] NDCB0: 0x000d3000
> [    5.571273] NDCB1: 0x24800000
> [    5.571273] NDCB2: 0x00000000
> [    5.571273] NDCB3: 0x00000000
> [    5.590337] marvell-nfc pxa3xx-nand: 
> [    5.590337] NDCR:  0xdd079fff
> [    5.590337] NDCB0: 0x000d3000
> [    5.590337] NDCB1: 0x24810000
> [    5.590337] NDCB2: 0x00000000
> [    5.590337] NDCB3: 0x00000000
> [    5.609318] marvell-nfc pxa3xx-nand: 
> [    5.609318] NDCR:  0x9d079fff
> [    5.609318] NDCB0: 0x000d3000
> [    5.609318] NDCB1: 0x24810000
> [    5.609318] NDCB2: 0x00000000
> [    5.609318] NDCB3: 0x00000000
> [    5.628426] marvell-nfc pxa3xx-nand: 
> [    5.628426] NDCR:  0xdd079fff
> [    5.628426] NDCB0: 0x000d3000
> [    5.628426] NDCB1: 0x24c00000
> [    5.628426] NDCB2: 0x00000000
> [    5.628426] NDCB3: 0x00000000
> [    5.647489] marvell-nfc pxa3xx-nand: 
> [    5.647489] NDCR:  0xdd079fff
> [    5.647489] NDCB0: 0x000d3000
> [    5.647489] NDCB1: 0x24c10000
> [    5.647489] NDCB2: 0x00000000
> [    5.647489] NDCB3: 0x00000000
> [    5.666475] marvell-nfc pxa3xx-nand: 
> [    5.666475] NDCR:  0x9d079fff
> [    5.666475] NDCB0: 0x000d3000
> [    5.666475] NDCB1: 0x24c10000
> [    5.666475] NDCB2: 0x00000000
> [    5.666475] NDCB3: 0x00000000
> [    5.685575] marvell-nfc pxa3xx-nand: 
> [    5.685575] NDCR:  0xdd079fff
> [    5.685575] NDCB0: 0x000d3000
> [    5.685575] NDCB1: 0x25000000
> [    5.685575] NDCB2: 0x00000000
> [    5.685575] NDCB3: 0x00000000
> [    5.704632] marvell-nfc pxa3xx-nand: 
> [    5.704632] NDCR:  0xdd079fff
> [    5.704632] NDCB0: 0x000d3000
> [    5.704632] NDCB1: 0x25010000
> [    5.704632] NDCB2: 0x00000000
> [    5.704632] NDCB3: 0x00000000
> [    5.723609] marvell-nfc pxa3xx-nand: 
> [    5.723609] NDCR:  0x9d079fff
> [    5.723609] NDCB0: 0x000d3000
> [    5.723609] NDCB1: 0x25010000
> [    5.723609] NDCB2: 0x00000000
> [    5.723609] NDCB3: 0x00000000
> [    5.742713] marvell-nfc pxa3xx-nand: 
> [    5.742713] NDCR:  0xdd079fff
> [    5.742713] NDCB0: 0x000d3000
> [    5.742713] NDCB1: 0x25400000
> [    5.742713] NDCB2: 0x00000000
> [    5.742713] NDCB3: 0x00000000
> [    5.761769] marvell-nfc pxa3xx-nand: 
> [    5.761769] NDCR:  0xdd079fff
> [    5.761769] NDCB0: 0x000d3000
> [    5.761769] NDCB1: 0x25410000
> [    5.761769] NDCB2: 0x00000000
> [    5.761769] NDCB3: 0x00000000
> [    5.780750] marvell-nfc pxa3xx-nand: 
> [    5.780750] NDCR:  0x9d079fff
> [    5.780750] NDCB0: 0x000d3000
> [    5.780750] NDCB1: 0x25410000
> [    5.780750] NDCB2: 0x00000000
> [    5.780750] NDCB3: 0x00000000
> [    5.799855] marvell-nfc pxa3xx-nand: 
> [    5.799855] NDCR:  0xdd079fff
> [    5.799855] NDCB0: 0x000d3000
> [    5.799855] NDCB1: 0x25800000
> [    5.799855] NDCB2: 0x00000000
> [    5.799855] NDCB3: 0x00000000
> [    5.818918] marvell-nfc pxa3xx-nand: 
> [    5.818918] NDCR:  0xdd079fff
> [    5.818918] NDCB0: 0x000d3000
> [    5.818918] NDCB1: 0x25810000
> [    5.818918] NDCB2: 0x00000000
> [    5.818918] NDCB3: 0x00000000
> [    5.837903] marvell-nfc pxa3xx-nand: 
> [    5.837903] NDCR:  0x9d079fff
> [    5.837903] NDCB0: 0x000d3000
> [    5.837903] NDCB1: 0x25810000
> [    5.837903] NDCB2: 0x00000000
> [    5.837903] NDCB3: 0x00000000
> [    5.857009] marvell-nfc pxa3xx-nand: 
> [    5.857009] NDCR:  0xdd079fff
> [    5.857009] NDCB0: 0x000d3000
> [    5.857009] NDCB1: 0x25c00000
> [    5.857009] NDCB2: 0x00000000
> [    5.857009] NDCB3: 0x00000000
> [    5.876071] marvell-nfc pxa3xx-nand: 
> [    5.876071] NDCR:  0xdd079fff
> [    5.876071] NDCB0: 0x000d3000
> [    5.876071] NDCB1: 0x25c10000
> [    5.876071] NDCB2: 0x00000000
> [    5.876071] NDCB3: 0x00000000
> [    5.895047] marvell-nfc pxa3xx-nand: 
> [    5.895047] NDCR:  0x9d079fff
> [    5.895047] NDCB0: 0x000d3000
> [    5.895047] NDCB1: 0x25c10000
> [    5.895047] NDCB2: 0x00000000
> [    5.895047] NDCB3: 0x00000000
> [    5.914152] marvell-nfc pxa3xx-nand: 
> [    5.914152] NDCR:  0xdd079fff
> [    5.914152] NDCB0: 0x000d3000
> [    5.914152] NDCB1: 0x26000000
> [    5.914152] NDCB2: 0x00000000
> [    5.914152] NDCB3: 0x00000000
> [    5.933285] marvell-nfc pxa3xx-nand: 
> [    5.933285] NDCR:  0xdd079fff
> [    5.933285] NDCB0: 0x000d3000
> [    5.933285] NDCB1: 0x26010000
> [    5.933285] NDCB2: 0x00000000
> [    5.933285] NDCB3: 0x00000000
> [    5.952247] marvell-nfc pxa3xx-nand: 
> [    5.952247] NDCR:  0x9d079fff
> [    5.952247] NDCB0: 0x000d3000
> [    5.952247] NDCB1: 0x26010000
> [    5.952247] NDCB2: 0x00000000
> [    5.952247] NDCB3: 0x00000000
> [    5.971354] marvell-nfc pxa3xx-nand: 
> [    5.971354] NDCR:  0xdd079fff
> [    5.971354] NDCB0: 0x000d3000
> [    5.971354] NDCB1: 0x26400000
> [    5.971354] NDCB2: 0x00000000
> [    5.971354] NDCB3: 0x00000000
> [    5.990415] marvell-nfc pxa3xx-nand: 
> [    5.990415] NDCR:  0xdd079fff
> [    5.990415] NDCB0: 0x000d3000
> [    5.990415] NDCB1: 0x26410000
> [    5.990415] NDCB2: 0x00000000
> [    5.990415] NDCB3: 0x00000000
> [    6.009391] marvell-nfc pxa3xx-nand: 
> [    6.009391] NDCR:  0x9d079fff
> [    6.009391] NDCB0: 0x000d3000
> [    6.009391] NDCB1: 0x26410000
> [    6.009391] NDCB2: 0x00000000
> [    6.009391] NDCB3: 0x00000000
> [    6.028510] marvell-nfc pxa3xx-nand: 
> [    6.028510] NDCR:  0xdd079fff
> [    6.028510] NDCB0: 0x000d3000
> [    6.028510] NDCB1: 0x26800000
> [    6.028510] NDCB2: 0x00000000
> [    6.028510] NDCB3: 0x00000000
> [    6.047572] marvell-nfc pxa3xx-nand: 
> [    6.047572] NDCR:  0xdd079fff
> [    6.047572] NDCB0: 0x000d3000
> [    6.047572] NDCB1: 0x26810000
> [    6.047572] NDCB2: 0x00000000
> [    6.047572] NDCB3: 0x00000000
> [    6.066553] marvell-nfc pxa3xx-nand: 
> [    6.066553] NDCR:  0x9d079fff
> [    6.066553] NDCB0: 0x000d3000
> [    6.066553] NDCB1: 0x26810000
> [    6.066553] NDCB2: 0x00000000
> [    6.066553] NDCB3: 0x00000000
> [    6.085662] marvell-nfc pxa3xx-nand: 
> [    6.085662] NDCR:  0xdd079fff
> [    6.085662] NDCB0: 0x000d3000
> [    6.085662] NDCB1: 0x26c00000
> [    6.085662] NDCB2: 0x00000000
> [    6.085662] NDCB3: 0x00000000
> [    6.105275] marvell-nfc pxa3xx-nand: 
> [    6.105275] NDCR:  0xdd079fff
> [    6.105275] NDCB0: 0x000d3000
> [    6.105275] NDCB1: 0x26c10000
> [    6.105275] NDCB2: 0x00000000
> [    6.105275] NDCB3: 0x00000000
> [    6.124291] marvell-nfc pxa3xx-nand: 
> [    6.124291] NDCR:  0x9d079fff
> [    6.124291] NDCB0: 0x000d3000
> [    6.124291] NDCB1: 0x26c10000
> [    6.124291] NDCB2: 0x00000000
> [    6.124291] NDCB3: 0x00000000
> [    6.143431] marvell-nfc pxa3xx-nand: 
> [    6.143431] NDCR:  0xdd079fff
> [    6.143431] NDCB0: 0x000d3000
> [    6.143431] NDCB1: 0x27000000
> [    6.143431] NDCB2: 0x00000000
> [    6.143431] NDCB3: 0x00000000
> [    6.162492] marvell-nfc pxa3xx-nand: 
> [    6.162492] NDCR:  0xdd079fff
> [    6.162492] NDCB0: 0x000d3000
> [    6.162492] NDCB1: 0x27010000
> [    6.162492] NDCB2: 0x00000000
> [    6.162492] NDCB3: 0x00000000
> [    6.181482] marvell-nfc pxa3xx-nand: 
> [    6.181482] NDCR:  0x9d079fff
> [    6.181482] NDCB0: 0x000d3000
> [    6.181482] NDCB1: 0x27010000
> [    6.181482] NDCB2: 0x00000000
> [    6.181482] NDCB3: 0x00000000
> [    6.200594] marvell-nfc pxa3xx-nand: 
> [    6.200594] NDCR:  0xdd079fff
> [    6.200594] NDCB0: 0x000d3000
> [    6.200594] NDCB1: 0x27400000
> [    6.200594] NDCB2: 0x00000000
> [    6.200594] NDCB3: 0x00000000
> [    6.219651] marvell-nfc pxa3xx-nand: 
> [    6.219651] NDCR:  0xdd079fff
> [    6.219651] NDCB0: 0x000d3000
> [    6.219651] NDCB1: 0x27410000
> [    6.219651] NDCB2: 0x00000000
> [    6.219651] NDCB3: 0x00000000
> [    6.238628] marvell-nfc pxa3xx-nand: 
> [    6.238628] NDCR:  0x9d079fff
> [    6.238628] NDCB0: 0x000d3000
> [    6.238628] NDCB1: 0x27410000
> [    6.238628] NDCB2: 0x00000000
> [    6.238628] NDCB3: 0x00000000
> [    6.257763] marvell-nfc pxa3xx-nand: 
> [    6.257763] NDCR:  0xdd079fff
> [    6.257763] NDCB0: 0x000d3000
> [    6.257763] NDCB1: 0x27800000
> [    6.257763] NDCB2: 0x00000000
> [    6.257763] NDCB3: 0x00000000
> [    6.276826] marvell-nfc pxa3xx-nand: 
> [    6.276826] NDCR:  0xdd079fff
> [    6.276826] NDCB0: 0x000d3000
> [    6.276826] NDCB1: 0x27810000
> [    6.276826] NDCB2: 0x00000000
> [    6.276826] NDCB3: 0x00000000
> [    6.295914] marvell-nfc pxa3xx-nand: 
> [    6.295914] NDCR:  0xdd079fff
> [    6.295914] NDCB0: 0x000d3000
> [    6.295914] NDCB1: 0x27c00000
> [    6.295914] NDCB2: 0x00000000
> [    6.295914] NDCB3: 0x00000000
> [    6.314978] marvell-nfc pxa3xx-nand: 
> [    6.314978] NDCR:  0xdd079fff
> [    6.314978] NDCB0: 0x000d3000
> [    6.314978] NDCB1: 0x27c10000
> [    6.314978] NDCB2: 0x00000000
> [    6.314978] NDCB3: 0x00000000
> [    6.333957] marvell-nfc pxa3xx-nand: 
> [    6.333957] NDCR:  0x9d079fff
> [    6.333957] NDCB0: 0x000d3000
> [    6.333957] NDCB1: 0x27c10000
> [    6.333957] NDCB2: 0x00000000
> [    6.333957] NDCB3: 0x00000000
> [    6.353164] marvell-nfc pxa3xx-nand: 
> [    6.353164] NDCR:  0xdd079fff
> [    6.353164] NDCB0: 0x000d3000
> [    6.353164] NDCB1: 0x28000000
> [    6.353164] NDCB2: 0x00000000
> [    6.353164] NDCB3: 0x00000000
> [    6.372184] marvell-nfc pxa3xx-nand: 
> [    6.372184] NDCR:  0xdd079fff
> [    6.372184] NDCB0: 0x000d3000
> [    6.372184] NDCB1: 0x28010000
> [    6.372184] NDCB2: 0x00000000
> [    6.372184] NDCB3: 0x00000000
> [    6.391168] marvell-nfc pxa3xx-nand: 
> [    6.391168] NDCR:  0x9d079fff
> [    6.391168] NDCB0: 0x000d3000
> [    6.391168] NDCB1: 0x28010000
> [    6.391168] NDCB2: 0x00000000
> [    6.391168] NDCB3: 0x00000000
> [    6.410268] marvell-nfc pxa3xx-nand: 
> [    6.410268] NDCR:  0xdd079fff
> [    6.410268] NDCB0: 0x000d3000
> [    6.410268] NDCB1: 0x28400000
> [    6.410268] NDCB2: 0x00000000
> [    6.410268] NDCB3: 0x00000000
> [    6.429335] marvell-nfc pxa3xx-nand: 
> [    6.429335] NDCR:  0xdd079fff
> [    6.429335] NDCB0: 0x000d3000
> [    6.429335] NDCB1: 0x28410000
> [    6.429335] NDCB2: 0x00000000
> [    6.429335] NDCB3: 0x00000000
> [    6.448408] marvell-nfc pxa3xx-nand: 
> [    6.448408] NDCR:  0xdd079fff
> [    6.448408] NDCB0: 0x000d3000
> [    6.448408] NDCB1: 0x28800000
> [    6.448408] NDCB2: 0x00000000
> [    6.448408] NDCB3: 0x00000000
> [    6.467471] marvell-nfc pxa3xx-nand: 
> [    6.467471] NDCR:  0xdd079fff
> [    6.467471] NDCB0: 0x000d3000
> [    6.467471] NDCB1: 0x28810000
> [    6.467471] NDCB2: 0x00000000
> [    6.467471] NDCB3: 0x00000000
> [    6.486456] marvell-nfc pxa3xx-nand: 
> [    6.486456] NDCR:  0x9d079fff
> [    6.486456] NDCB0: 0x000d3000
> [    6.486456] NDCB1: 0x28810000
> [    6.486456] NDCB2: 0x00000000
> [    6.486456] NDCB3: 0x00000000
> [    6.505554] marvell-nfc pxa3xx-nand: 
> [    6.505554] NDCR:  0xdd079fff
> [    6.505554] NDCB0: 0x000d3000
> [    6.505554] NDCB1: 0x28c00000
> [    6.505554] NDCB2: 0x00000000
> [    6.505554] NDCB3: 0x00000000
> [    6.524610] marvell-nfc pxa3xx-nand: 
> [    6.524610] NDCR:  0xdd079fff
> [    6.524610] NDCB0: 0x000d3000
> [    6.524610] NDCB1: 0x28c10000
> [    6.524610] NDCB2: 0x00000000
> [    6.524610] NDCB3: 0x00000000
> [    6.543589] marvell-nfc pxa3xx-nand: 
> [    6.543589] NDCR:  0x9d079fff
> [    6.543589] NDCB0: 0x000d3000
> [    6.543589] NDCB1: 0x28c10000
> [    6.543589] NDCB2: 0x00000000
> [    6.543589] NDCB3: 0x00000000
> [    6.562688] marvell-nfc pxa3xx-nand: 
> [    6.562688] NDCR:  0xdd079fff
> [    6.562688] NDCB0: 0x000d3000
> [    6.562688] NDCB1: 0x29000000
> [    6.562688] NDCB2: 0x00000000
> [    6.562688] NDCB3: 0x00000000
> [    6.581750] marvell-nfc pxa3xx-nand: 
> [    6.581750] NDCR:  0xdd079fff
> [    6.581750] NDCB0: 0x000d3000
> [    6.581750] NDCB1: 0x29010000
> [    6.581750] NDCB2: 0x00000000
> [    6.581750] NDCB3: 0x00000000
> [    6.600735] marvell-nfc pxa3xx-nand: 
> [    6.600735] NDCR:  0x9d079fff
> [    6.600735] NDCB0: 0x000d3000
> [    6.600735] NDCB1: 0x29010000
> [    6.600735] NDCB2: 0x00000000
> [    6.600735] NDCB3: 0x00000000
> [    6.619839] marvell-nfc pxa3xx-nand: 
> [    6.619839] NDCR:  0xdd079fff
> [    6.619839] NDCB0: 0x000d3000
> [    6.619839] NDCB1: 0x29400000
> [    6.619839] NDCB2: 0x00000000
> [    6.619839] NDCB3: 0x00000000
> [    6.638902] marvell-nfc pxa3xx-nand: 
> [    6.638902] NDCR:  0xdd079fff
> [    6.638902] NDCB0: 0x000d3000
> [    6.638902] NDCB1: 0x29410000
> [    6.638902] NDCB2: 0x00000000
> [    6.638902] NDCB3: 0x00000000
> [    6.657879] marvell-nfc pxa3xx-nand: 
> [    6.657879] NDCR:  0x9d079fff
> [    6.657879] NDCB0: 0x000d3000
> [    6.657879] NDCB1: 0x29410000
> [    6.657879] NDCB2: 0x00000000
> [    6.657879] NDCB3: 0x00000000
> [    6.676983] marvell-nfc pxa3xx-nand: 
> [    6.676983] NDCR:  0xdd079fff
> [    6.676983] NDCB0: 0x000d3000
> [    6.676983] NDCB1: 0x29800000
> [    6.676983] NDCB2: 0x00000000
> [    6.676983] NDCB3: 0x00000000
> [    6.696050] marvell-nfc pxa3xx-nand: 
> [    6.696050] NDCR:  0xdd079fff
> [    6.696050] NDCB0: 0x000d3000
> [    6.696050] NDCB1: 0x29810000
> [    6.696050] NDCB2: 0x00000000
> [    6.696050] NDCB3: 0x00000000
> [    6.715033] marvell-nfc pxa3xx-nand: 
> [    6.715033] NDCR:  0x9d079fff
> [    6.715033] NDCB0: 0x000d3000
> [    6.715033] NDCB1: 0x29810000
> [    6.715033] NDCB2: 0x00000000
> [    6.715033] NDCB3: 0x00000000
> [    6.734141] marvell-nfc pxa3xx-nand: 
> [    6.734141] NDCR:  0xdd079fff
> [    6.734141] NDCB0: 0x000d3000
> [    6.734141] NDCB1: 0x29c00000
> [    6.734141] NDCB2: 0x00000000
> [    6.734141] NDCB3: 0x00000000
> [    6.753291] marvell-nfc pxa3xx-nand: 
> [    6.753291] NDCR:  0xdd079fff
> [    6.753291] NDCB0: 0x000d3000
> [    6.753291] NDCB1: 0x29c10000
> [    6.753291] NDCB2: 0x00000000
> [    6.753291] NDCB3: 0x00000000
> [    6.772264] marvell-nfc pxa3xx-nand: 
> [    6.772264] NDCR:  0x9d079fff
> [    6.772264] NDCB0: 0x000d3000
> [    6.772264] NDCB1: 0x29c10000
> [    6.772264] NDCB2: 0x00000000
> [    6.772264] NDCB3: 0x00000000
> [    6.791367] marvell-nfc pxa3xx-nand: 
> [    6.791367] NDCR:  0xdd079fff
> [    6.791367] NDCB0: 0x000d3000
> [    6.791367] NDCB1: 0x2a000000
> [    6.791367] NDCB2: 0x00000000
> [    6.791367] NDCB3: 0x00000000
> [    6.810425] marvell-nfc pxa3xx-nand: 
> [    6.810425] NDCR:  0xdd079fff
> [    6.810425] NDCB0: 0x000d3000
> [    6.810425] NDCB1: 0x2a010000
> [    6.810425] NDCB2: 0x00000000
> [    6.810425] NDCB3: 0x00000000
> [    6.829403] marvell-nfc pxa3xx-nand: 
> [    6.829403] NDCR:  0x9d079fff
> [    6.829403] NDCB0: 0x000d3000
> [    6.829403] NDCB1: 0x2a010000
> [    6.829403] NDCB2: 0x00000000
> [    6.829403] NDCB3: 0x00000000
> [    6.848512] marvell-nfc pxa3xx-nand: 
> [    6.848512] NDCR:  0xdd079fff
> [    6.848512] NDCB0: 0x000d3000
> [    6.848512] NDCB1: 0x2a400000
> [    6.848512] NDCB2: 0x00000000
> [    6.848512] NDCB3: 0x00000000
> [    6.867573] marvell-nfc pxa3xx-nand: 
> [    6.867573] NDCR:  0xdd079fff
> [    6.867573] NDCB0: 0x000d3000
> [    6.867573] NDCB1: 0x2a410000
> [    6.867573] NDCB2: 0x00000000
> [    6.867573] NDCB3: 0x00000000
> [    6.886550] marvell-nfc pxa3xx-nand: 
> [    6.886550] NDCR:  0x9d079fff
> [    6.886550] NDCB0: 0x000d3000
> [    6.886550] NDCB1: 0x2a410000
> [    6.886550] NDCB2: 0x00000000
> [    6.886550] NDCB3: 0x00000000
> [    6.905653] marvell-nfc pxa3xx-nand: 
> [    6.905653] NDCR:  0xdd079fff
> [    6.905653] NDCB0: 0x000d3000
> [    6.905653] NDCB1: 0x2a800000
> [    6.905653] NDCB2: 0x00000000
> [    6.905653] NDCB3: 0x00000000
> [    6.924720] marvell-nfc pxa3xx-nand: 
> [    6.924720] NDCR:  0xdd079fff
> [    6.924720] NDCB0: 0x000d3000
> [    6.924720] NDCB1: 0x2a810000
> [    6.924720] NDCB2: 0x00000000
> [    6.924720] NDCB3: 0x00000000
> [    6.943704] marvell-nfc pxa3xx-nand: 
> [    6.943704] NDCR:  0x9d079fff
> [    6.943704] NDCB0: 0x000d3000
> [    6.943704] NDCB1: 0x2a810000
> [    6.943704] NDCB2: 0x00000000
> [    6.943704] NDCB3: 0x00000000
> [    6.962806] marvell-nfc pxa3xx-nand: 
> [    6.962806] NDCR:  0xdd079fff
> [    6.962806] NDCB0: 0x000d3000
> [    6.962806] NDCB1: 0x2ac00000
> [    6.962806] NDCB2: 0x00000000
> [    6.962806] NDCB3: 0x00000000
> [    6.981868] marvell-nfc pxa3xx-nand: 
> [    6.981868] NDCR:  0xdd079fff
> [    6.981868] NDCB0: 0x000d3000
> [    6.981868] NDCB1: 0x2ac10000
> [    6.981868] NDCB2: 0x00000000
> [    6.981868] NDCB3: 0x00000000
> [    7.000848] marvell-nfc pxa3xx-nand: 
> [    7.000848] NDCR:  0x9d079fff
> [    7.000848] NDCB0: 0x000d3000
> [    7.000848] NDCB1: 0x2ac10000
> [    7.000848] NDCB2: 0x00000000
> [    7.000848] NDCB3: 0x00000000
> [    7.019966] marvell-nfc pxa3xx-nand: 
> [    7.019966] NDCR:  0xdd079fff
> [    7.019966] NDCB0: 0x000d3000
> [    7.019966] NDCB1: 0x2b000000
> [    7.019966] NDCB2: 0x00000000
> [    7.019966] NDCB3: 0x00000000
> [    7.039028] marvell-nfc pxa3xx-nand: 
> [    7.039028] NDCR:  0xdd079fff
> [    7.039028] NDCB0: 0x000d3000
> [    7.039028] NDCB1: 0x2b010000
> [    7.039028] NDCB2: 0x00000000
> [    7.039028] NDCB3: 0x00000000
> [    7.058002] marvell-nfc pxa3xx-nand: 
> [    7.058002] NDCR:  0x9d079fff
> [    7.058002] NDCB0: 0x000d3000
> [    7.058002] NDCB1: 0x2b010000
> [    7.058002] NDCB2: 0x00000000
> [    7.058002] NDCB3: 0x00000000
> [    7.077109] marvell-nfc pxa3xx-nand: 
> [    7.077109] NDCR:  0xdd079fff
> [    7.077109] NDCB0: 0x000d3000
> [    7.077109] NDCB1: 0x2b400000
> [    7.077109] NDCB2: 0x00000000
> [    7.077109] NDCB3: 0x00000000
> [    7.096173] marvell-nfc pxa3xx-nand: 
> [    7.096173] NDCR:  0xdd079fff
> [    7.096173] NDCB0: 0x000d3000
> [    7.096173] NDCB1: 0x2b410000
> [    7.096173] NDCB2: 0x00000000
> [    7.096173] NDCB3: 0x00000000
> [    7.115153] marvell-nfc pxa3xx-nand: 
> [    7.115153] NDCR:  0x9d079fff
> [    7.115153] NDCB0: 0x000d3000
> [    7.115153] NDCB1: 0x2b410000
> [    7.115153] NDCB2: 0x00000000
> [    7.115153] NDCB3: 0x00000000
> [    7.134255] marvell-nfc pxa3xx-nand: 
> [    7.134255] NDCR:  0xdd079fff
> [    7.134255] NDCB0: 0x000d3000
> [    7.134255] NDCB1: 0x2b800000
> [    7.134255] NDCB2: 0x00000000
> [    7.134255] NDCB3: 0x00000000
> [    7.153307] marvell-nfc pxa3xx-nand: 
> [    7.153307] NDCR:  0xdd079fff
> [    7.153307] NDCB0: 0x000d3000
> [    7.153307] NDCB1: 0x2b810000
> [    7.153307] NDCB2: 0x00000000
> [    7.153307] NDCB3: 0x00000000
> [    7.172279] marvell-nfc pxa3xx-nand: 
> [    7.172279] NDCR:  0x9d079fff
> [    7.172279] NDCB0: 0x000d3000
> [    7.172279] NDCB1: 0x2b810000
> [    7.172279] NDCB2: 0x00000000
> [    7.172279] NDCB3: 0x00000000
> [    7.191385] marvell-nfc pxa3xx-nand: 
> [    7.191385] NDCR:  0xdd079fff
> [    7.191385] NDCB0: 0x000d3000
> [    7.191385] NDCB1: 0x2bc00000
> [    7.191385] NDCB2: 0x00000000
> [    7.191385] NDCB3: 0x00000000
> [    7.210447] marvell-nfc pxa3xx-nand: 
> [    7.210447] NDCR:  0xdd079fff
> [    7.210447] NDCB0: 0x000d3000
> [    7.210447] NDCB1: 0x2bc10000
> [    7.210447] NDCB2: 0x00000000
> [    7.210447] NDCB3: 0x00000000
> [    7.229426] marvell-nfc pxa3xx-nand: 
> [    7.229426] NDCR:  0x9d079fff
> [    7.229426] NDCB0: 0x000d3000
> [    7.229426] NDCB1: 0x2bc10000
> [    7.229426] NDCB2: 0x00000000
> [    7.229426] NDCB3: 0x00000000
> [    7.248529] marvell-nfc pxa3xx-nand: 
> [    7.248529] NDCR:  0xdd079fff
> [    7.248529] NDCB0: 0x000d3000
> [    7.248529] NDCB1: 0x2c000000
> [    7.248529] NDCB2: 0x00000000
> [    7.248529] NDCB3: 0x00000000
> [    7.267597] marvell-nfc pxa3xx-nand: 
> [    7.267597] NDCR:  0xdd079fff
> [    7.267597] NDCB0: 0x000d3000
> [    7.267597] NDCB1: 0x2c010000
> [    7.267597] NDCB2: 0x00000000
> [    7.267597] NDCB3: 0x00000000
> [    7.286579] marvell-nfc pxa3xx-nand: 
> [    7.286579] NDCR:  0x9d079fff
> [    7.286579] NDCB0: 0x000d3000
> [    7.286579] NDCB1: 0x2c010000
> [    7.286579] NDCB2: 0x00000000
> [    7.286579] NDCB3: 0x00000000
> [    7.305683] marvell-nfc pxa3xx-nand: 
> [    7.305683] NDCR:  0xdd079fff
> [    7.305683] NDCB0: 0x000d3000
> [    7.305683] NDCB1: 0x2c400000
> [    7.305683] NDCB2: 0x00000000
> [    7.305683] NDCB3: 0x00000000
> [    7.324747] marvell-nfc pxa3xx-nand: 
> [    7.324747] NDCR:  0xdd079fff
> [    7.324747] NDCB0: 0x000d3000
> [    7.324747] NDCB1: 0x2c410000
> [    7.324747] NDCB2: 0x00000000
> [    7.324747] NDCB3: 0x00000000
> [    7.343743] marvell-nfc pxa3xx-nand: 
> [    7.343743] NDCR:  0x9d079fff
> [    7.343743] NDCB0: 0x000d3000
> [    7.343743] NDCB1: 0x2c410000
> [    7.343743] NDCB2: 0x00000000
> [    7.343743] NDCB3: 0x00000000
> [    7.362843] marvell-nfc pxa3xx-nand: 
> [    7.362843] NDCR:  0xdd079fff
> [    7.362843] NDCB0: 0x000d3000
> [    7.362843] NDCB1: 0x2c800000
> [    7.362843] NDCB2: 0x00000000
> [    7.362843] NDCB3: 0x00000000
> [    7.381905] marvell-nfc pxa3xx-nand: 
> [    7.381905] NDCR:  0xdd079fff
> [    7.381905] NDCB0: 0x000d3000
> [    7.381905] NDCB1: 0x2c810000
> [    7.381905] NDCB2: 0x00000000
> [    7.381905] NDCB3: 0x00000000
> [    7.400887] marvell-nfc pxa3xx-nand: 
> [    7.400887] NDCR:  0x9d079fff
> [    7.400887] NDCB0: 0x000d3000
> [    7.400887] NDCB1: 0x2c810000
> [    7.400887] NDCB2: 0x00000000
> [    7.400887] NDCB3: 0x00000000
> [    7.420884] marvell-nfc pxa3xx-nand: 
> [    7.420884] NDCR:  0xdd079fff
> [    7.420884] NDCB0: 0x000d3000
> [    7.420884] NDCB1: 0x50800000
> [    7.420884] NDCB2: 0x00000000
> [    7.420884] NDCB3: 0x00000000
> [    7.439944] marvell-nfc pxa3xx-nand: 
> [    7.439944] NDCR:  0xdd079fff
> [    7.439944] NDCB0: 0x000d3000
> [    7.439944] NDCB1: 0x50810000
> [    7.439944] NDCB2: 0x00000000
> [    7.439944] NDCB3: 0x00000000
> [    7.458920] marvell-nfc pxa3xx-nand: 
> [    7.458920] NDCR:  0x9d079fff
> [    7.458920] NDCB0: 0x000d3000
> [    7.458920] NDCB1: 0x50810000
> [    7.458920] NDCB2: 0x00000000
> [    7.458920] NDCB3: 0x00000000
> [    7.478025] marvell-nfc pxa3xx-nand: 
> [    7.478025] NDCR:  0xdd079fff
> [    7.478025] NDCB0: 0x000d3000
> [    7.478025] NDCB1: 0x50c00000
> [    7.478025] NDCB2: 0x00000000
> [    7.478025] NDCB3: 0x00000000
> [    7.497089] marvell-nfc pxa3xx-nand: 
> [    7.497089] NDCR:  0xdd079fff
> [    7.497089] NDCB0: 0x000d3000
> [    7.497089] NDCB1: 0x50c10000
> [    7.497089] NDCB2: 0x00000000
> [    7.497089] NDCB3: 0x00000000
> [    7.516067] marvell-nfc pxa3xx-nand: 
> [    7.516067] NDCR:  0x9d079fff
> [    7.516067] NDCB0: 0x000d3000
> [    7.516067] NDCB1: 0x50c10000
> [    7.516067] NDCB2: 0x00000000
> [    7.516067] NDCB3: 0x00000000
> [    7.535172] marvell-nfc pxa3xx-nand: 
> [    7.535172] NDCR:  0xdd079fff
> [    7.535172] NDCB0: 0x000d3000
> [    7.535172] NDCB1: 0x51000000
> [    7.535172] NDCB2: 0x00000000
> [    7.535172] NDCB3: 0x00000000
> [    7.554233] marvell-nfc pxa3xx-nand: 
> [    7.554233] NDCR:  0xdd079fff
> [    7.554233] NDCB0: 0x000d3000
> [    7.554233] NDCB1: 0x51010000
> [    7.554233] NDCB2: 0x00000000
> [    7.554233] NDCB3: 0x00000000
> [    7.573238] marvell-nfc pxa3xx-nand: 
> [    7.573238] NDCR:  0x9d079fff
> [    7.573238] NDCB0: 0x000d3000
> [    7.573238] NDCB1: 0x51010000
> [    7.573238] NDCB2: 0x00000000
> [    7.573238] NDCB3: 0x00000000
> [    7.592334] marvell-nfc pxa3xx-nand: 
> [    7.592334] NDCR:  0xdd079fff
> [    7.592334] NDCB0: 0x000d3000
> [    7.592334] NDCB1: 0x51400000
> [    7.592334] NDCB2: 0x00000000
> [    7.592334] NDCB3: 0x00000000
> [    7.611401] marvell-nfc pxa3xx-nand: 
> [    7.611401] NDCR:  0xdd079fff
> [    7.611401] NDCB0: 0x000d3000
> [    7.611401] NDCB1: 0x51410000
> [    7.611401] NDCB2: 0x00000000
> [    7.611401] NDCB3: 0x00000000
> [    7.630384] marvell-nfc pxa3xx-nand: 
> [    7.630384] NDCR:  0x9d079fff
> [    7.630384] NDCB0: 0x000d3000
> [    7.630384] NDCB1: 0x51410000
> [    7.630384] NDCB2: 0x00000000
> [    7.630384] NDCB3: 0x00000000
> [    7.649492] marvell-nfc pxa3xx-nand: 
> [    7.649492] NDCR:  0xdd079fff
> [    7.649492] NDCB0: 0x000d3000
> [    7.649492] NDCB1: 0x51800000
> [    7.649492] NDCB2: 0x00000000
> [    7.649492] NDCB3: 0x00000000
> [    7.668554] marvell-nfc pxa3xx-nand: 
> [    7.668554] NDCR:  0xdd079fff
> [    7.668554] NDCB0: 0x000d3000
> [    7.668554] NDCB1: 0x51810000
> [    7.668554] NDCB2: 0x00000000
> [    7.668554] NDCB3: 0x00000000
> [    7.687527] marvell-nfc pxa3xx-nand: 
> [    7.687527] NDCR:  0x9d079fff
> [    7.687527] NDCB0: 0x000d3000
> [    7.687527] NDCB1: 0x51810000
> [    7.687527] NDCB2: 0x00000000
> [    7.687527] NDCB3: 0x00000000
> [    7.706637] marvell-nfc pxa3xx-nand: 
> [    7.706637] NDCR:  0xdd079fff
> [    7.706637] NDCB0: 0x000d3000
> [    7.706637] NDCB1: 0x51c00000
> [    7.706637] NDCB2: 0x00000000
> [    7.706637] NDCB3: 0x00000000
> [    7.725697] marvell-nfc pxa3xx-nand: 
> [    7.725697] NDCR:  0xdd079fff
> [    7.725697] NDCB0: 0x000d3000
> [    7.725697] NDCB1: 0x51c10000
> [    7.725697] NDCB2: 0x00000000
> [    7.725697] NDCB3: 0x00000000
> [    7.744674] marvell-nfc pxa3xx-nand: 
> [    7.744674] NDCR:  0x9d079fff
> [    7.744674] NDCB0: 0x000d3000
> [    7.744674] NDCB1: 0x51c10000
> [    7.744674] NDCB2: 0x00000000
> [    7.744674] NDCB3: 0x00000000
> [    7.763781] marvell-nfc pxa3xx-nand: 
> [    7.763781] NDCR:  0xdd079fff
> [    7.763781] NDCB0: 0x000d3000
> [    7.763781] NDCB1: 0x52000000
> [    7.763781] NDCB2: 0x00000000
> [    7.763781] NDCB3: 0x00000000
> [    7.782838] marvell-nfc pxa3xx-nand: 
> [    7.782838] NDCR:  0xdd079fff
> [    7.782838] NDCB0: 0x000d3000
> [    7.782838] NDCB1: 0x52010000
> [    7.782838] NDCB2: 0x00000000
> [    7.782838] NDCB3: 0x00000000
> [    7.801814] marvell-nfc pxa3xx-nand: 
> [    7.801814] NDCR:  0x9d079fff
> [    7.801814] NDCB0: 0x000d3000
> [    7.801814] NDCB1: 0x52010000
> [    7.801814] NDCB2: 0x00000000
> [    7.801814] NDCB3: 0x00000000
> [    7.820919] marvell-nfc pxa3xx-nand: 
> [    7.820919] NDCR:  0xdd079fff
> [    7.820919] NDCB0: 0x000d3000
> [    7.820919] NDCB1: 0x52400000
> [    7.820919] NDCB2: 0x00000000
> [    7.820919] NDCB3: 0x00000000
> [    7.839984] marvell-nfc pxa3xx-nand: 
> [    7.839984] NDCR:  0xdd079fff
> [    7.839984] NDCB0: 0x000d3000
> [    7.839984] NDCB1: 0x52410000
> [    7.839984] NDCB2: 0x00000000
> [    7.839984] NDCB3: 0x00000000
> [    7.858968] marvell-nfc pxa3xx-nand: 
> [    7.858968] NDCR:  0x9d079fff
> [    7.858968] NDCB0: 0x000d3000
> [    7.858968] NDCB1: 0x52410000
> [    7.858968] NDCB2: 0x00000000
> [    7.858968] NDCB3: 0x00000000
> [    7.878070] marvell-nfc pxa3xx-nand: 
> [    7.878070] NDCR:  0xdd079fff
> [    7.878070] NDCB0: 0x000d3000
> [    7.878070] NDCB1: 0x52800000
> [    7.878070] NDCB2: 0x00000000
> [    7.878070] NDCB3: 0x00000000
> [    7.897127] marvell-nfc pxa3xx-nand: 
> [    7.897127] NDCR:  0xdd079fff
> [    7.897127] NDCB0: 0x000d3000
> [    7.897127] NDCB1: 0x52810000
> [    7.897127] NDCB2: 0x00000000
> [    7.897127] NDCB3: 0x00000000
> [    7.916104] marvell-nfc pxa3xx-nand: 
> [    7.916104] NDCR:  0x9d079fff
> [    7.916104] NDCB0: 0x000d3000
> [    7.916104] NDCB1: 0x52810000
> [    7.916104] NDCB2: 0x00000000
> [    7.916104] NDCB3: 0x00000000
> [    7.935231] marvell-nfc pxa3xx-nand: 
> [    7.935231] NDCR:  0xdd079fff
> [    7.935231] NDCB0: 0x000d3000
> [    7.935231] NDCB1: 0x52c00000
> [    7.935231] NDCB2: 0x00000000
> [    7.935231] NDCB3: 0x00000000
> [    7.954292] marvell-nfc pxa3xx-nand: 
> [    7.954292] NDCR:  0xdd079fff
> [    7.954292] NDCB0: 0x000d3000
> [    7.954292] NDCB1: 0x52c10000
> [    7.954292] NDCB2: 0x00000000
> [    7.954292] NDCB3: 0x00000000
> [    7.973328] marvell-nfc pxa3xx-nand: 
> [    7.973328] NDCR:  0x9d079fff
> [    7.973328] NDCB0: 0x000d3000
> [    7.973328] NDCB1: 0x52c10000
> [    7.973328] NDCB2: 0x00000000
> [    7.973328] NDCB3: 0x00000000
> [    7.992424] marvell-nfc pxa3xx-nand: 
> [    7.992424] NDCR:  0xdd079fff
> [    7.992424] NDCB0: 0x000d3000
> [    7.992424] NDCB1: 0x53000000
> [    7.992424] NDCB2: 0x00000000
> [    7.992424] NDCB3: 0x00000000
> [    8.011485] marvell-nfc pxa3xx-nand: 
> [    8.011485] NDCR:  0xdd079fff
> [    8.011485] NDCB0: 0x000d3000
> [    8.011485] NDCB1: 0x53010000
> [    8.011485] NDCB2: 0x00000000
> [    8.011485] NDCB3: 0x00000000
> [    8.030479] marvell-nfc pxa3xx-nand: 
> [    8.030479] NDCR:  0x9d079fff
> [    8.030479] NDCB0: 0x000d3000
> [    8.030479] NDCB1: 0x53010000
> [    8.030479] NDCB2: 0x00000000
> [    8.030479] NDCB3: 0x00000000
> [    8.049579] marvell-nfc pxa3xx-nand: 
> [    8.049579] NDCR:  0xdd079fff
> [    8.049579] NDCB0: 0x000d3000
> [    8.049579] NDCB1: 0x53400000
> [    8.049579] NDCB2: 0x00000000
> [    8.049579] NDCB3: 0x00000000
> [    8.068643] marvell-nfc pxa3xx-nand: 
> [    8.068643] NDCR:  0xdd079fff
> [    8.068643] NDCB0: 0x000d3000
> [    8.068643] NDCB1: 0x53410000
> [    8.068643] NDCB2: 0x00000000
> [    8.068643] NDCB3: 0x00000000
> [    8.087618] marvell-nfc pxa3xx-nand: 
> [    8.087618] NDCR:  0x9d079fff
> [    8.087618] NDCB0: 0x000d3000
> [    8.087618] NDCB1: 0x53410000
> [    8.087618] NDCB2: 0x00000000
> [    8.087618] NDCB3: 0x00000000
> [    8.107355] marvell-nfc pxa3xx-nand: 
> [    8.107355] NDCR:  0xdd079fff
> [    8.107355] NDCB0: 0x000d3000
> [    8.107355] NDCB1: 0x53800000
> [    8.107355] NDCB2: 0x00000000
> [    8.107355] NDCB3: 0x00000000
> [    8.126458] marvell-nfc pxa3xx-nand: 
> [    8.126458] NDCR:  0xdd079fff
> [    8.126458] NDCB0: 0x000d3000
> [    8.126458] NDCB1: 0x53810000
> [    8.126458] NDCB2: 0x00000000
> [    8.126458] NDCB3: 0x00000000
> [    8.145438] marvell-nfc pxa3xx-nand: 
> [    8.145438] NDCR:  0x9d079fff
> [    8.145438] NDCB0: 0x000d3000
> [    8.145438] NDCB1: 0x53810000
> [    8.145438] NDCB2: 0x00000000
> [    8.145438] NDCB3: 0x00000000
> [    8.164543] marvell-nfc pxa3xx-nand: 
> [    8.164543] NDCR:  0xdd079fff
> [    8.164543] NDCB0: 0x000d3000
> [    8.164543] NDCB1: 0x53c00000
> [    8.164543] NDCB2: 0x00000000
> [    8.164543] NDCB3: 0x00000000
> [    8.183607] marvell-nfc pxa3xx-nand: 
> [    8.183607] NDCR:  0xdd079fff
> [    8.183607] NDCB0: 0x000d3000
> [    8.183607] NDCB1: 0x53c10000
> [    8.183607] NDCB2: 0x00000000
> [    8.183607] NDCB3: 0x00000000
> [    8.202574] marvell-nfc pxa3xx-nand: 
> [    8.202574] NDCR:  0x9d079fff
> [    8.202574] NDCB0: 0x000d3000
> [    8.202574] NDCB1: 0x53c10000
> [    8.202574] NDCB2: 0x00000000
> [    8.202574] NDCB3: 0x00000000
> [    8.221680] marvell-nfc pxa3xx-nand: 
> [    8.221680] NDCR:  0xdd079fff
> [    8.221680] NDCB0: 0x000d3000
> [    8.221680] NDCB1: 0x54000000
> [    8.221680] NDCB2: 0x00000000
> [    8.221680] NDCB3: 0x00000000
> [    8.240741] marvell-nfc pxa3xx-nand: 
> [    8.240741] NDCR:  0xdd079fff
> [    8.240741] NDCB0: 0x000d3000
> [    8.240741] NDCB1: 0x54010000
> [    8.240741] NDCB2: 0x00000000
> [    8.240741] NDCB3: 0x00000000
> [    8.259723] marvell-nfc pxa3xx-nand: 
> [    8.259723] NDCR:  0x9d079fff
> [    8.259723] NDCB0: 0x000d3000
> [    8.259723] NDCB1: 0x54010000
> [    8.259723] NDCB2: 0x00000000
> [    8.259723] NDCB3: 0x00000000
> [    8.278825] marvell-nfc pxa3xx-nand: 
> [    8.278825] NDCR:  0xdd079fff
> [    8.278825] NDCB0: 0x000d3000
> [    8.278825] NDCB1: 0x54400000
> [    8.278825] NDCB2: 0x00000000
> [    8.278825] NDCB3: 0x00000000
> [    8.297889] marvell-nfc pxa3xx-nand: 
> [    8.297889] NDCR:  0xdd079fff
> [    8.297889] NDCB0: 0x000d3000
> [    8.297889] NDCB1: 0x54410000
> [    8.297889] NDCB2: 0x00000000
> [    8.297889] NDCB3: 0x00000000
> [    8.316863] marvell-nfc pxa3xx-nand: 
> [    8.316863] NDCR:  0x9d079fff
> [    8.316863] NDCB0: 0x000d3000
> [    8.316863] NDCB1: 0x54410000
> [    8.316863] NDCB2: 0x00000000
> [    8.316863] NDCB3: 0x00000000
> [    8.335976] marvell-nfc pxa3xx-nand: 
> [    8.335976] NDCR:  0xdd079fff
> [    8.335976] NDCB0: 0x000d3000
> [    8.335976] NDCB1: 0x55000000
> [    8.335976] NDCB2: 0x00000000
> [    8.335976] NDCB3: 0x00000000
> [    8.355035] marvell-nfc pxa3xx-nand: 
> [    8.355035] NDCR:  0xdd079fff
> [    8.355035] NDCB0: 0x000d3000
> [    8.355035] NDCB1: 0x55010000
> [    8.355035] NDCB2: 0x00000000
> [    8.355035] NDCB3: 0x00000000
> [    8.374007] marvell-nfc pxa3xx-nand: 
> [    8.374007] NDCR:  0x9d079fff
> [    8.374007] NDCB0: 0x000d3000
> [    8.374007] NDCB1: 0x55010000
> [    8.374007] NDCB2: 0x00000000
> [    8.374007] NDCB3: 0x00000000
> [    8.393202] marvell-nfc pxa3xx-nand: 
> [    8.393202] NDCR:  0xdd079fff
> [    8.393202] NDCB0: 0x000d3000
> [    8.393202] NDCB1: 0x55400000
> [    8.393202] NDCB2: 0x00000000
> [    8.393202] NDCB3: 0x00000000
> [    8.412235] marvell-nfc pxa3xx-nand: 
> [    8.412235] NDCR:  0xdd079fff
> [    8.412235] NDCB0: 0x000d3000
> [    8.412235] NDCB1: 0x55410000
> [    8.412235] NDCB2: 0x00000000
> [    8.412235] NDCB3: 0x00000000
> [    8.431217] marvell-nfc pxa3xx-nand: 
> [    8.431217] NDCR:  0x9d079fff
> [    8.431217] NDCB0: 0x000d3000
> [    8.431217] NDCB1: 0x55410000
> [    8.431217] NDCB2: 0x00000000
> [    8.431217] NDCB3: 0x00000000
> [    8.450325] marvell-nfc pxa3xx-nand: 
> [    8.450325] NDCR:  0xdd079fff
> [    8.450325] NDCB0: 0x000d3000
> [    8.450325] NDCB1: 0x55800000
> [    8.450325] NDCB2: 0x00000000
> [    8.450325] NDCB3: 0x00000000
> [    8.469388] marvell-nfc pxa3xx-nand: 
> [    8.469388] NDCR:  0xdd079fff
> [    8.469388] NDCB0: 0x000d3000
> [    8.469388] NDCB1: 0x55810000
> [    8.469388] NDCB2: 0x00000000
> [    8.469388] NDCB3: 0x00000000
> [    8.488366] marvell-nfc pxa3xx-nand: 
> [    8.488366] NDCR:  0x9d079fff
> [    8.488366] NDCB0: 0x000d3000
> [    8.488366] NDCB1: 0x55810000
> [    8.488366] NDCB2: 0x00000000
> [    8.488366] NDCB3: 0x00000000
> [    8.507471] marvell-nfc pxa3xx-nand: 
> [    8.507471] NDCR:  0xdd079fff
> [    8.507471] NDCB0: 0x000d3000
> [    8.507471] NDCB1: 0x55c00000
> [    8.507471] NDCB2: 0x00000000
> [    8.507471] NDCB3: 0x00000000
> [    8.526556] marvell-nfc pxa3xx-nand: 
> [    8.526556] NDCR:  0xdd079fff
> [    8.526556] NDCB0: 0x000d3000
> [    8.526556] NDCB1: 0x55c10000
> [    8.526556] NDCB2: 0x00000000
> [    8.526556] NDCB3: 0x00000000
> [    8.545537] marvell-nfc pxa3xx-nand: 
> [    8.545537] NDCR:  0x9d079fff
> [    8.545537] NDCB0: 0x000d3000
> [    8.545537] NDCB1: 0x55c10000
> [    8.545537] NDCB2: 0x00000000
> [    8.545537] NDCB3: 0x00000000
> [    8.564641] marvell-nfc pxa3xx-nand: 
> [    8.564641] NDCR:  0xdd079fff
> [    8.564641] NDCB0: 0x000d3000
> [    8.564641] NDCB1: 0x56000000
> [    8.564641] NDCB2: 0x00000000
> [    8.564641] NDCB3: 0x00000000
> [    8.583703] marvell-nfc pxa3xx-nand: 
> [    8.583703] NDCR:  0xdd079fff
> [    8.583703] NDCB0: 0x000d3000
> [    8.583703] NDCB1: 0x56010000
> [    8.583703] NDCB2: 0x00000000
> [    8.583703] NDCB3: 0x00000000
> [    8.602671] marvell-nfc pxa3xx-nand: 
> [    8.602671] NDCR:  0x9d079fff
> [    8.602671] NDCB0: 0x000d3000
> [    8.602671] NDCB1: 0x56010000
> [    8.602671] NDCB2: 0x00000000
> [    8.602671] NDCB3: 0x00000000
> [    8.621771] marvell-nfc pxa3xx-nand: 
> [    8.621771] NDCR:  0xdd079fff
> [    8.621771] NDCB0: 0x000d3000
> [    8.621771] NDCB1: 0x56400000
> [    8.621771] NDCB2: 0x00000000
> [    8.621771] NDCB3: 0x00000000
> [    8.640836] marvell-nfc pxa3xx-nand: 
> [    8.640836] NDCR:  0xdd079fff
> [    8.640836] NDCB0: 0x000d3000
> [    8.640836] NDCB1: 0x56410000
> [    8.640836] NDCB2: 0x00000000
> [    8.640836] NDCB3: 0x00000000
> [    8.659821] marvell-nfc pxa3xx-nand: 
> [    8.659821] NDCR:  0x9d079fff
> [    8.659821] NDCB0: 0x000d3000
> [    8.659821] NDCB1: 0x56410000
> [    8.659821] NDCB2: 0x00000000
> [    8.659821] NDCB3: 0x00000000
> [    8.678923] marvell-nfc pxa3xx-nand: 
> [    8.678923] NDCR:  0xdd079fff
> [    8.678923] NDCB0: 0x000d3000
> [    8.678923] NDCB1: 0x56800000
> [    8.678923] NDCB2: 0x00000000
> [    8.678923] NDCB3: 0x00000000
> [    8.697987] marvell-nfc pxa3xx-nand: 
> [    8.697987] NDCR:  0xdd079fff
> [    8.697987] NDCB0: 0x000d3000
> [    8.697987] NDCB1: 0x56810000
> [    8.697987] NDCB2: 0x00000000
> [    8.697987] NDCB3: 0x00000000
> [    8.716967] marvell-nfc pxa3xx-nand: 
> [    8.716967] NDCR:  0x9d079fff
> [    8.716967] NDCB0: 0x000d3000
> [    8.716967] NDCB1: 0x56810000
> [    8.716967] NDCB2: 0x00000000
> [    8.716967] NDCB3: 0x00000000
> [    8.736068] marvell-nfc pxa3xx-nand: 
> [    8.736068] NDCR:  0xdd079fff
> [    8.736068] NDCB0: 0x000d3000
> [    8.736068] NDCB1: 0x56c00000
> [    8.736068] NDCB2: 0x00000000
> [    8.736068] NDCB3: 0x00000000
> [    8.755122] marvell-nfc pxa3xx-nand: 
> [    8.755122] NDCR:  0xdd079fff
> [    8.755122] NDCB0: 0x000d3000
> [    8.755122] NDCB1: 0x56c10000
> [    8.755122] NDCB2: 0x00000000
> [    8.755122] NDCB3: 0x00000000
> [    8.774101] marvell-nfc pxa3xx-nand: 
> [    8.774101] NDCR:  0x9d079fff
> [    8.774101] NDCB0: 0x000d3000
> [    8.774101] NDCB1: 0x56c10000
> [    8.774101] NDCB2: 0x00000000
> [    8.774101] NDCB3: 0x00000000
> [    8.793417] marvell-nfc pxa3xx-nand: 
> [    8.793417] NDCR:  0xdd079fff
> [    8.793417] NDCB0: 0x000d3000
> [    8.793417] NDCB1: 0x57000000
> [    8.793417] NDCB2: 0x00000000
> [    8.793417] NDCB3: 0x00000000
> [    8.812493] marvell-nfc pxa3xx-nand: 
> [    8.812493] NDCR:  0xdd079fff
> [    8.812493] NDCB0: 0x000d3000
> [    8.812493] NDCB1: 0x57010000
> [    8.812493] NDCB2: 0x00000000
> [    8.812493] NDCB3: 0x00000000
> [    8.831475] marvell-nfc pxa3xx-nand: 
> [    8.831475] NDCR:  0x9d079fff
> [    8.831475] NDCB0: 0x000d3000
> [    8.831475] NDCB1: 0x57010000
> [    8.831475] NDCB2: 0x00000000
> [    8.831475] NDCB3: 0x00000000
> [    8.850578] marvell-nfc pxa3xx-nand: 
> [    8.850578] NDCR:  0xdd079fff
> [    8.850578] NDCB0: 0x000d3000
> [    8.850578] NDCB1: 0x57400000
> [    8.850578] NDCB2: 0x00000000
> [    8.850578] NDCB3: 0x00000000
> [    8.869639] marvell-nfc pxa3xx-nand: 
> [    8.869639] NDCR:  0xdd079fff
> [    8.869639] NDCB0: 0x000d3000
> [    8.869639] NDCB1: 0x57410000
> [    8.869639] NDCB2: 0x00000000
> [    8.869639] NDCB3: 0x00000000
> [    8.888614] marvell-nfc pxa3xx-nand: 
> [    8.888614] NDCR:  0x9d079fff
> [    8.888614] NDCB0: 0x000d3000
> [    8.888614] NDCB1: 0x57410000
> [    8.888614] NDCB2: 0x00000000
> [    8.888614] NDCB3: 0x00000000
> [    8.907721] marvell-nfc pxa3xx-nand: 
> [    8.907721] NDCR:  0xdd079fff
> [    8.907721] NDCB0: 0x000d3000
> [    8.907721] NDCB1: 0x57c00000
> [    8.907721] NDCB2: 0x00000000
> [    8.907721] NDCB3: 0x00000000
> [    8.926778] marvell-nfc pxa3xx-nand: 
> [    8.926778] NDCR:  0xdd079fff
> [    8.926778] NDCB0: 0x000d3000
> [    8.926778] NDCB1: 0x57c10000
> [    8.926778] NDCB2: 0x00000000
> [    8.926778] NDCB3: 0x00000000
> [    8.945755] marvell-nfc pxa3xx-nand: 
> [    8.945755] NDCR:  0x9d079fff
> [    8.945755] NDCB0: 0x000d3000
> [    8.945755] NDCB1: 0x57c10000
> [    8.945755] NDCB2: 0x00000000
> [    8.945755] NDCB3: 0x00000000
> [    8.964856] marvell-nfc pxa3xx-nand: 
> [    8.964856] NDCR:  0xdd079fff
> [    8.964856] NDCB0: 0x000d3000
> [    8.964856] NDCB1: 0x58000000
> [    8.964856] NDCB2: 0x00000000
> [    8.964856] NDCB3: 0x00000000
> [    8.983915] marvell-nfc pxa3xx-nand: 
> [    8.983915] NDCR:  0xdd079fff
> [    8.983915] NDCB0: 0x000d3000
> [    8.983915] NDCB1: 0x58010000
> [    8.983915] NDCB2: 0x00000000
> [    8.983915] NDCB3: 0x00000000
> [    9.002886] marvell-nfc pxa3xx-nand: 
> [    9.002886] NDCR:  0x9d079fff
> [    9.002886] NDCB0: 0x000d3000
> [    9.002886] NDCB1: 0x58010000
> [    9.002886] NDCB2: 0x00000000
> [    9.002886] NDCB3: 0x00000000
> [    9.022075] marvell-nfc pxa3xx-nand: 
> [    9.022075] NDCR:  0xdd079fff
> [    9.022075] NDCB0: 0x000d3000
> [    9.022075] NDCB1: 0x58400000
> [    9.022075] NDCB2: 0x00000000
> [    9.022075] NDCB3: 0x00000000
> [    9.041141] marvell-nfc pxa3xx-nand: 
> [    9.041141] NDCR:  0xdd079fff
> [    9.041141] NDCB0: 0x000d3000
> [    9.041141] NDCB1: 0x58410000
> [    9.041141] NDCB2: 0x00000000
> [    9.041141] NDCB3: 0x00000000
> [    9.060123] marvell-nfc pxa3xx-nand: 
> [    9.060123] NDCR:  0x9d079fff
> [    9.060123] NDCB0: 0x000d3000
> [    9.060123] NDCB1: 0x58410000
> [    9.060123] NDCB2: 0x00000000
> [    9.060123] NDCB3: 0x00000000
> [    9.079435] ubi0: scanning is finished
> [    9.083567] ubi0 error: ubi_read_volume_table: the layout volume was not found
> [    9.090953] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd5, error -22
> [    9.098457] UBI error: cannot attach mtd5
> [    9.103950] pxa-rtc pxa-rtc: setting system clock to 2000-01-01 00:00:34 UTC (946684834)
> [    9.187568] smc91x smc91x.0 eth0: link down
> [   11.136140] smc91x smc91x.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
> [   11.193199] IP-Config: Complete:
> [   11.196554]      device=eth0, hwaddr=00:0e:0c:a7:26:f7, ipaddr=192.168.1.232, mask=255.255.255.0, gw=255.255.255.255
> [   11.207229]      host=192.168.1.232, domain=, nis-domain=(none)
> [   11.213278]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
> [   11.221532] ALSA device list:
> [   11.224983]   #0: Zylonite
> [   11.250472] Freeing unused kernel memory: 2396K
> [   11.255419] This architecture does not have kernel memory protection.
> Starting logging: OK
> Loading all the available modules: modprobe: module smc91x not found in modules.dep
> modprobe: module soundcore not found in modules.dep
> modprobe: module snd not found in modules.dep
> modprobe: module snd-pcm not found in modules.dep
> modprobe: module fat not found in modules.dep
> modprobe: module vfat not found in modules.dep
> modprobe: module nfs not found in modules.dep
> modprobe: module nls_cp437 not found in modules.dep
> modprobe: module nls_cp850 not found in modules.dep
> modprobe: module nls_ascii not found in modules.dep
> modprobe: module nls_utf8 not found in modules.dep
> modprobe: module fixed not found in modules.dep
> modprobe: module pwm-pxa not found in modules.dep
> modprobe: module cpufreq_conservative not found in modules.dep
> modprobe: module cpufreq_powersave not found in modules.dep
> modprobe: module cpufreq-dt not found in modules.dep
> modprobe: module btusb not found in modules.dep
> modprobe: module i2c-dev not found in modules.dep
> modprobe: module ubi not found in modules.dep
> modprobe: module mt_blkdevs not found in modules.dep
> modprobe: module pxa3xx_nand not found in modules.dep
> modprobe: module mtdblock not found in modules.dep
> modprobe: module ofpart not found in modules.dep
> modprobe: module map_rom not found in modules.dep
> modprobe: module jedec_probe not found in modules.dep
> modprobe: module cmdlinepart not found in modules.dep
> modprobe: module redboot not found in modules.dep
> modprobe: module loop not found in modules.dep
> modprobe: module leds-gpio not found in modules.dep
> modprobe: module jedec-class not found in modules.dep
> modprobe: module pxa not found in modules.dep
> modprobe: module evdev not found in modules.dep
> modprobe: module soc_common not found in modules.dep
> modprobe: module pwm_bl not found in modules.dep
> modprobe: module fbcon not found in modules.dep
> modprobe: module rtc-pxa not found in modules.dep
> modprobe: module rtc-sa1100 not found in modules.dep
> modprobe: module smc91x not found in modules.dep
> modprobe: module pda_power not found in modules.dep
> modprobe: module fixed not found in modules.dep
> KO
> OK
> Changing smcs91x MAC address to 08:00:3e:26:0a:5b: ifconfig: SIOCSIFHWADDR: Device or resource busy
> KO
> OK
> Initializing random number generator... done.
> Starting network...
> ip: RTNETLINK answers: File exists
> udhcpc (v1.24.1) started
> Sending discover...
> Sending select for 192.168.1.232...
> Lease of 192.168.1.232 obtained, lease time 86400
> deleting routers
> adding dns 192.168.1.1
> Starting dropbear sshd: OK
> 
> Welcome to Buildroot
> zylonite login: 



From boris.brezillon at free-electrons.com  Wed Jan  3 12:52:06 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 3 Jan 2018 21:52:06 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180103211028.619cd16d@bbrezillon>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
 <20180103211028.619cd16d@bbrezillon>
Message-ID: <20180103215206.5d85b41b@bbrezillon>

On Wed, 3 Jan 2018 21:10:28 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Wed, 03 Jan 2018 20:58:29 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> 
> > Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> >   
> > > On Tue, 02 Jan 2018 20:21:09 +0100
> > > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> > >    
> > >> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> > >>     
> > >> > I think the ECC issue you faced was related to pages being written
> > >> > *and* empty. If this guess is right, the board should boot fine with
> > >> > these changes.
> > >> >
> > >> > Otherwise, please add the DEBUG define as before in both the core
> > >> > and the driver and do not hesitate to add another dump_stack()
> > >> > where it crashes (if applicable).      
> > >> 
> > >> The problem looks still the same :
> > >> [    3.560163] Bad block table not found for chip 0    
> > >
> > > Mmmmh ok.
> > >
> > > Can you please add this patch:
> > > http://code.bulix.org/61at9p-254626    
> > 
> > Well, it looks a bit better, see attached log in [1].
> > Now the BBT is detected ...
> > [    3.310841] Bad block table found at page 131008, version 0x01
> > ...
> > [    3.354944] Bad block table found at page 130944, version 0x01
> > 
> > But all blocks are considered bad ... as if the bit logic was inverted for the
> > meaning of "bad" or "good" block, see :
> > [    3.379825] nand_read_bbt: bad block at 0x000000000000  
> 
> Hm, that's weird. Can you try with the old driver (pxa3xx)?

Alternatively, you can type 'nand bad' from uboot to check if it
detects the same bad blocks.


From elfring at users.sourceforge.net  Wed Jan  3 12:52:07 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Wed, 3 Jan 2018 21:52:07 +0100
Subject: [PATCH] mtd/inftlmount: Delete error messages for a failed memory
 allocation in two functions
Message-ID: <dd43ad50-ecc0-15b2-619d-da3a5b46dc91@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Wed, 3 Jan 2018 21:45:19 +0100

Omit extra messages for a memory allocation failure in these functions.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/inftlmount.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 8d6bb189ea8e..e5dd55021602 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -273,19 +273,12 @@ static int find_boot_record(struct INFTLrecord *inftl)
 
 		/* Memory alloc */
 		inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-		if (!inftl->PUtable) {
-			printk(KERN_WARNING "INFTL: allocation of PUtable "
-				"failed (%zd bytes)\n",
-				inftl->nb_blocks * sizeof(u16));
+		if (!inftl->PUtable)
 			return -ENOMEM;
-		}
 
 		inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
 		if (!inftl->VUtable) {
 			kfree(inftl->PUtable);
-			printk(KERN_WARNING "INFTL: allocation of VUtable "
-				"failed (%zd bytes)\n",
-				inftl->nb_blocks * sizeof(u16));
 			return -ENOMEM;
 		}
 
@@ -562,12 +555,8 @@ int INFTL_mount(struct INFTLrecord *s)
 
 	/* Temporary buffer to store ANAC numbers. */
 	ANACtable = kcalloc(s->nb_blocks, sizeof(u8), GFP_KERNEL);
-	if (!ANACtable) {
-		printk(KERN_WARNING "INFTL: allocation of ANACtable "
-				"failed (%zd bytes)\n",
-				s->nb_blocks * sizeof(u8));
+	if (!ANACtable)
 		return -ENOMEM;
-	}
 
 	/*
 	 * First pass is to explore each physical unit, and construct the
-- 
2.15.1



From prabhakar.kushwaha at nxp.com  Wed Jan  3 17:33:51 2018
From: prabhakar.kushwaha at nxp.com (Prabhakar Kushwaha)
Date: Thu, 4 Jan 2018 01:33:51 +0000
Subject: [RFC 0/3] mtd: spi-nor: Add support of Sector Map Parameter Table
In-Reply-To: <1514548432-13302-1-git-send-email-prabhakar.kushwaha@nxp.com>
References: <1514548432-13302-1-git-send-email-prabhakar.kushwaha@nxp.com>
Message-ID: <HE1PR04MB12417BAC1260587074962FFD971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>

Hi Cyrille,


> -----Original Message-----
> From: Prabhakar Kushwaha [mailto:prabhakar.kushwaha at nxp.com]
> Sent: Friday, December 29, 2017 5:24 PM
> To: linux-mtd at lists.infradead.org
> Cc: computersforpeace at gmail.com; boris.brezillon at free-electrons.com;
> marek.vasut at gmail.com; cyrille.pitchen at wedev4u.fr; Poonam Aggrwal
> <poonam.aggrwal at nxp.com>; Suresh Gupta <suresh.gupta at nxp.com>; Ashish
> Kumar <ashish.kumar at nxp.com>; Yogesh Narayan Gaur
> <yogeshnarayan.gaur at nxp.com>; Rajat Srivastava <rajat.srivastava at nxp.com>;
> Fabio Estevam <fabio.estevam at nxp.com>; Prabhakar Kushwaha
> <prabhakar.kushwaha at nxp.com>
> Subject: [RFC 0/3] mtd: spi-nor: Add support of Sector Map Parameter Table
> 
> JESD216B defines Sector Map Parameter Table. It identifies the
> location and size of sectors within the main data array of the
> flash memory device and identifies which Erase Types are supported
> by each sector. This table is used when a memory device has sectors
> of more than one size Or, does not allow all Erase Type commands to
> be applied to all sectors.
> 
> This patch-set add support of Sector Map Parameter Table parsing.
> It also update framework to support read/write anyreg commands
> required by S25FS512S flash.
> 
> Tested with "S25FS512S" flash and by over-riding fsl_qspi_read_anyreg()
> return with desired configuration id i.e. 0x05. Flash was
> pre-programmed for Uniform 256-kB sectors via non-volatile registers.
> 
> Prabhakar Kushwaha (3):
>   mtd: spi-nor: Add support of read/write any reg commands
>   mtd: spi-nor: Implement anyreg functions for fsl-quadspi
>   mtd: spi-nor: Add support of Sector Map Parameter Table
> 
>  drivers/mtd/spi-nor/fsl-quadspi.c |  18 +++
>  drivers/mtd/spi-nor/spi-nor.c     | 266
> +++++++++++++++++++++++++++++++++++++-
>  include/linux/mtd/spi-nor.h       |  21 +++
>  3 files changed, 302 insertions(+), 3 deletions(-)
> 

Can you please review this patch-set. 
I want to incorporate review comments for the v1 patch.

Thanks
-pk



From peterpansjtu at gmail.com  Wed Jan  3 18:01:57 2018
From: peterpansjtu at gmail.com (Peter Pan)
Date: Thu, 4 Jan 2018 10:01:57 +0800
Subject: [PATCH v6 00/15] A SPI NAND framework under generic NAND framework
In-Reply-To: <20180103174614.6d760b3d@bbrezillon>
References: <20170529225931.226da943@bbrezillon>
 <A0FE66EC-7E17-43BE-9B66-896F112B92A0@micron.com>
 <20171205135804.478902dc@bbrezillon> <20171205140313.40f3f17d@bbrezillon>
 <256b4ab6-c104-4580-87cd-527178bde460@exceet.de>
 <20171213222710.32d12514@bbrezillon>
 <CAAyFORJcT1abbo21iA4cetLKmF0zE4akFGFryxPpwPO+730LDQ@mail.gmail.com>
 <20171214085036.436b4fcf@bbrezillon>
 <CAAyFOR+=JwTRTm2MXVdMy7KRPsnV8LV4t71kHUh_s=+QOsVurA@mail.gmail.com>
 <23d17416-e555-4b92-cc47-f644fbe676c6@exceet.de>
 <20171214163848.41f6d277@bbrezillon>
 <CAAyFORKeFq+=tF9AK+8hp6GYYiyp3DKcw8+LWrC3RWS2zLNU_w@mail.gmail.com>
 <CAAyFORJEuEaHDXgk+m0ax5RoZ-3cRJs6uFXw7syR4vHE1veEwQ@mail.gmail.com>
 <a06312e4-a7e6-8b7b-9eb5-8320302dcc55@exceet.de>
 <CAAyFORL6mUFXFRvku6sm=Pj2=+Bf4wSV7EoBM_7+wRdPrF-ufw@mail.gmail.com>
 <CAAyFOR+m7GvXU66XKphu+cETP9SQTJ6GuZQEZQA600MX1R6cYw@mail.gmail.com>
 <20171222145147.3697fb02@bbrezillon>
 <CAAyFORK9v-V1WrJzTnKk0sAt7_f_st_PHc6nJ6dz0zTL-Jih5A@mail.gmail.com>
 <20180103174614.6d760b3d@bbrezillon>
Message-ID: <CAAyFORKfQ-82=HhnjQcaU3n8VkmqQ9VHCXoMh=47BSzMc8en3Q@mail.gmail.com>

Boris,

On Thu, Jan 4, 2018 at 12:46 AM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Tue, 2 Jan 2018 10:51:25 +0800
> Peter Pan <peterpansjtu at gmail.com> wrote:
>
>> Hi Boris,
>>
>>
>> On Fri, Dec 22, 2017 at 9:51 PM, Boris Brezillon
>> <boris.brezillon at free-electrons.com> wrote:
>> > On Fri, 22 Dec 2017 14:37:06 +0800
>> > Peter Pan <peterpansjtu at gmail.com> wrote:
>> >
>> >> Hi Boris and Frieder
>> >>
>> >> On Fri, Dec 22, 2017 at 8:49 AM, Peter Pan <peterpansjtu at gmail.com> wrote:
>> >> > Hi Frieder,
>> >> >
>> >> > On Thu, Dec 21, 2017 at 7:48 PM, Frieder Schrempf
>> >> > <frieder.schrempf at exceet.de> wrote:
>> >> >> Hello Boris,
>> >> >>
>> >> >>>>>> So shouldn't there be an spinand_die_select_op in the SPI NAND core
>> >> >>>>>> that
>> >> >>>>>> is executed when necessary and skipped if there's only one die.
>> >> >>>>>
>> >> >>>>>
>> >> >>>>> Sure, I was arguing against a ->select_chip() at the generic NAND
>> >> >>>>> level. That's something you can add in the SPI NAND framework.
>> >> >>
>> >> >>
>> >> >> I added an op to send the die selection command and call it, where I think
>> >> >> it is needed: [1]
>> >> >
>> >> > I think we should add die_select_op in vendor's file and call a hook in core.c
>> >> > since the die select command implementation is different by vendors.
>> >> >
>> >> > Thanks
>> >> > Peter Pan
>> >> >
>> >> >
>> >> >>
>> >> >> Accessing both dies on the Winbond SPI NAND works fine like this.
>> >> >>
>> >> >> While running tests I came across some problems:
>> >> >>
>> >> >> * On accessing the BBT in RAM via nanddev_bbt_[set/get]_block_status, the
>> >> >> calculation of position and offset seems to be wrong.
>> >> >> My fix is here: [2]
>> >> >>
>> >> >> * On calculating the row address for read/program/erase via
>> >> >> nanddev_pos_to_row, it seems like the eraseblock_addr_shift is wrong.
>> >> >>
>> >> >> * Also, I'm not sure if the LUN should be taken into account when
>> >> >> calculating the row address. At least when you select the LUN by issuing a
>> >> >> separate command, the row address sent to the chip should only contain the
>> >> >> page address.
>> >> >> But I'm not sure if that's the case in general, or if some code is needed to
>> >> >> differentiate.
>> >> >>
>> >> >> See my changes of nanddev_pos_to_row here: [3]
>> >> >>
>> >> >> * I run into a mutex deadlock, when spinand_write_page fails (e.g. because
>> >> >> of a bad block) as the lock is not released in such cases. See my fix here:
>> >> >> [4]
>> >> >>
>> >> >> With these fixes applied and as far as I can tell everything seems to work
>> >> >> fine. I'll do some tests with UBI next and look into the ECC topic.
>> >>
>> >> UBI attach failed since missing mtd->writebufsize assignment in nanddev_init()
>> >> After fixing it and with Frieder's fixing, UBIFS can be mounted successfully on
>> >> Zedboard with generic spi controller and Micron SPI NAND 2Gb device.
>> >>
>> >> Also, the code now can pass mtd read and page test. 1 error found in oob test
>> >> since we don't have "past end of partition" check in part_write_oob() which I
>> >> mentioned in earlier mail. Since we don't support ECC right now, I didn't try
>> >> nandbiterror test.
>> >>
>> >
>> > Peter, Frider, I just pushed a new version to my nand/spi-nand branch
>> > [1] fixing the authorship, adding/fixing/removing comments where needed.
>> >
>> > Can you please have a look at those changes (everything I changed
>> > should appear as !fixup commits) and let me know if I did something
>> > wrong.
>>
>> You forgot to initialize mtd->writebufsize and mtd->oobavail.
>> For mtd->writebufsize I think we can do it in nanddev_init() like below:
>>
>> --- a/drivers/mtd/nand/core.c
>> +++ b/drivers/mtd/nand/core.c
>> @@ -196,7 +196,9 @@ int nanddev_init(struct nand_device *nand, const
>> struct nand_ops *ops,
>>         mtd->flags = MTD_CAP_NANDFLASH;
>>         mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock;
>>         mtd->writesize = memorg->pagesize;
>> +       mtd->writebufsize = mtd->writesize;
>>         mtd->oobsize = memorg->oobsize;
>>         mtd->size = nanddev_size(nand);
>>         mtd->owner = owner;
>
> I fixed it already, see [1]. Note that I haven't squashed fixup commits
> yet.

Noted.

>
>>
>> For mtd->oobavail, I think we need to call some hooks in spinand_init(),
>> and implement on-die ECC layout in vendor's file and HW ECC layout in
>> controller's file.
>>
>> What's your opinion?
>
> Hm, I'm not so sure. spinand_init() should be called just before
> registering the MTD device, so by that time everything should have been
> setup correctly by the upper layer. This being said, I'd like to keep a
> clear separation between the MTD and NAND layers, and this means
> preventing any NAND sub-layer from directly manipulating the MTD device
> and its fields.
>
> Really, I don't know yet how I want to abstract ECC stuff, so let's
> keep it simple for now and expose the whole OOB area (I'll fix the core
> to do that if you're okay).

OK.

>
>>
>> With the two thing fixed, we can pass UBIFS mount and mtd test.
>
> Do you still have the problem you reported earlier (OOB test)?

I forgot to reply that mail :(. Actually there is no problem because
mtd_write_oob() already has mtd_check_oob_ops() to check it.
That failure in OOB test occurs because mtd->oobavail is zero.

Thanks
Peter Pan

>
> Thanks,
>
> Boris
>
> [1]https://github.com/bbrezillon/linux-0day/commit/32eeea1c35bfdc2ac0fcea599f6a926c94b835bb
>


From peterpansjtu at gmail.com  Wed Jan  3 18:06:03 2018
From: peterpansjtu at gmail.com (Peter Pan)
Date: Thu, 4 Jan 2018 10:06:03 +0800
Subject: [PATCH v3 3/4] mtd: Stop directly calling master ->_xxx() hooks
 from mtdpart code
In-Reply-To: <20171222093750.0c49abec@bbrezillon>
References: <20171215123954.30017-1-boris.brezillon@free-electrons.com>
 <20171215123954.30017-4-boris.brezillon@free-electrons.com>
 <CAAyFORLBhxpn5cFHztrY5OHt9FCfbDkQzUCsLf2Wyp2aGzPGnA@mail.gmail.com>
 <20171222093750.0c49abec@bbrezillon>
Message-ID: <CAAyFORJTUcynGNVAgH35Xzjik5Zp-b_Uik2nH5s0JUNRZjGJPQ@mail.gmail.com>

Boris,

On Fri, Dec 22, 2017 at 4:37 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Fri, 22 Dec 2017 13:40:26 +0800
> Peter Pan <peterpansjtu at gmail.com> wrote:
>
>> Hi Boris,
>>
>> On Fri, Dec 15, 2017 at 8:39 PM, Boris Brezillon
>> <boris.brezillon at free-electrons.com> wrote:
>> > The MTD layer provides several wrappers around mtd->_xxx() hooks. Call
>> > these wrappers instead of directly dereferencing the associated ->_xxx()
>> > pointer.
>> >
>> > This change has been motivated by another rework letting the core
>> > handle the case where ->_read/write_oob() are implemented but not
>> > ->_read/write(). In this case, we want mtd_read/write() to fall back to
>> > ->_read/write_oob() when ->_read/write() are NULL. The problem is,
>> > mtdpart is directly calling the ->_xxx() instead of using the wrappers,
>> > thus leading to a NULL pointer exception.
>> >
>> > Even though we only need to do the change for part_read/write(), going
>> > through those wrappers for all kind of part -> master operation
>> > propagation is a good thing, because other wrappers might become
>> > smarter over time, and the duplicated check overhead (parameters will
>> > be checked at the partition and master level instead of only at the
>> > partition level) should be negligible.
>> >
>> > Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
>> > ---
>> > Changes in v3:
>> > - unconditionally assign part wrappers as suggested by Brian
>> >
>> > Changes in v2:
>> > - new patch needed to fix a NULL pointer dereference BUG
>> > ---
>> >  drivers/mtd/mtdpart.c | 141 +++++++++++++++++++-------------------------------
>> >  1 file changed, 53 insertions(+), 88 deletions(-)
>> >
>> > diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
>> > index be088bccd593..e83c9d870b11 100644
>> > --- a/drivers/mtd/mtdpart.c
>> > +++ b/drivers/mtd/mtdpart.c
>> > @@ -74,8 +74,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
>> >         int res;
>> >
>>
>> This is not about your modification. But shouldn't we add check to prevent
>> part_read/write/write_oob from accessing  past the end of partition?
>> There is a check in part_read_oob() only.
>
> You should not call part_xxx() directly, and mtd_read/write{_oob}()
> should already check that. If that's not the case, we should fix them.
>
> Can you give a bit more details about what is wrong?

Sorry for late reply. My failure is due to failed to assign mtd->oobavail.
We don't have problem in OOB ops checking.
But since we already check it in mtd_read/write_oob(), shouln't we
remove the check in part_read/write_oob() ?

Thanks
Peter Pan


>
> Thanks,
>
> Boris
>
>>
>> Thanks
>> Peter Pan
>>
>> >         stats = part->parent->ecc_stats;
>> > -       res = part->parent->_read(part->parent, from + part->offset, len,
>> > -                                 retlen, buf);
>> > +       res = mtd_read(part->parent, from + part->offset, len, retlen, buf);
>> >         if (unlikely(mtd_is_eccerr(res)))
>> >                 mtd->ecc_stats.failed +=
>> >                         part->parent->ecc_stats.failed - stats.failed;
>> > @@ -90,15 +89,15 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> >
>> > -       return part->parent->_point(part->parent, from + part->offset, len,
>> > -                                   retlen, virt, phys);
>> > +       return mtd_point(part->parent, from + part->offset, len, retlen, virt,
>> > +                        phys);
>> >  }
>> >
>> >  static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> >
>> > -       return part->parent->_unpoint(part->parent, from + part->offset, len);
>> > +       return mtd_unpoint(part->parent, from + part->offset, len);
>> >  }
>> >
>> >  static int part_read_oob(struct mtd_info *mtd, loff_t from,
>> > @@ -126,7 +125,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>> >                         return -EINVAL;
>> >         }
>> >
>> > -       res = part->parent->_read_oob(part->parent, from + part->offset, ops);
>> > +       res = mtd_read_oob(part->parent, from + part->offset, ops);
>> >         if (unlikely(res)) {
>> >                 if (mtd_is_bitflip(res))
>> >                         mtd->ecc_stats.corrected++;
>> > @@ -140,48 +139,43 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
>> >                 size_t len, size_t *retlen, u_char *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_read_user_prot_reg(part->parent, from, len,
>> > -                                                retlen, buf);
>> > +       return mtd_read_user_prot_reg(part->parent, from, len, retlen, buf);
>> >  }
>> >
>> >  static int part_get_user_prot_info(struct mtd_info *mtd, size_t len,
>> >                                    size_t *retlen, struct otp_info *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_get_user_prot_info(part->parent, len, retlen,
>> > -                                                buf);
>> > +       return mtd_get_user_prot_info(part->parent, len, retlen, buf);
>> >  }
>> >
>> >  static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
>> >                 size_t len, size_t *retlen, u_char *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_read_fact_prot_reg(part->parent, from, len,
>> > -                                                retlen, buf);
>> > +       return mtd_read_fact_prot_reg(part->parent, from, len, retlen, buf);
>> >  }
>> >
>> >  static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len,
>> >                                    size_t *retlen, struct otp_info *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_get_fact_prot_info(part->parent, len, retlen,
>> > -                                                buf);
>> > +       return mtd_get_fact_prot_info(part->parent, len, retlen, buf);
>> >  }
>> >
>> >  static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
>> >                 size_t *retlen, const u_char *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_write(part->parent, to + part->offset, len,
>> > -                                   retlen, buf);
>> > +       return mtd_write(part->parent, to + part->offset, len, retlen, buf);
>> >  }
>> >
>> >  static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
>> >                 size_t *retlen, const u_char *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_panic_write(part->parent, to + part->offset, len,
>> > -                                         retlen, buf);
>> > +       return mtd_panic_write(part->parent, to + part->offset, len, retlen,
>> > +                              buf);
>> >  }
>> >
>> >  static int part_write_oob(struct mtd_info *mtd, loff_t to,
>> > @@ -193,30 +187,29 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
>> >                 return -EINVAL;
>> >         if (ops->datbuf && to + ops->len > mtd->size)
>> >                 return -EINVAL;
>> > -       return part->parent->_write_oob(part->parent, to + part->offset, ops);
>> > +       return mtd_write_oob(part->parent, to + part->offset, ops);
>> >  }
>> >
>> >  static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
>> >                 size_t len, size_t *retlen, u_char *buf)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_write_user_prot_reg(part->parent, from, len,
>> > -                                                 retlen, buf);
>> > +       return mtd_write_user_prot_reg(part->parent, from, len, retlen, buf);
>> >  }
>> >
>> >  static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
>> >                 size_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_lock_user_prot_reg(part->parent, from, len);
>> > +       return mtd_lock_user_prot_reg(part->parent, from, len);
>> >  }
>> >
>> >  static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
>> >                 unsigned long count, loff_t to, size_t *retlen)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_writev(part->parent, vecs, count,
>> > -                                    to + part->offset, retlen);
>> > +       return mtd_writev(part->parent, vecs, count, to + part->offset,
>> > +                         retlen);
>> >  }
>> >
>> >  static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
>> > @@ -225,7 +218,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
>> >         int ret;
>> >
>> >         instr->addr += part->offset;
>> > -       ret = part->parent->_erase(part->parent, instr);
>> > +       ret = mtd_erase(part->parent, instr);
>> >         if (ret) {
>> >                 if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
>> >                         instr->fail_addr -= part->offset;
>> > @@ -251,51 +244,51 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
>> >  static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_lock(part->parent, ofs + part->offset, len);
>> > +       return mtd_lock(part->parent, ofs + part->offset, len);
>> >  }
>> >
>> >  static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_unlock(part->parent, ofs + part->offset, len);
>> > +       return mtd_unlock(part->parent, ofs + part->offset, len);
>> >  }
>> >
>> >  static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_is_locked(part->parent, ofs + part->offset, len);
>> > +       return mtd_is_locked(part->parent, ofs + part->offset, len);
>> >  }
>> >
>> >  static void part_sync(struct mtd_info *mtd)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       part->parent->_sync(part->parent);
>> > +       mtd_sync(part->parent);
>> >  }
>> >
>> >  static int part_suspend(struct mtd_info *mtd)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_suspend(part->parent);
>> > +       return mtd_suspend(part->parent);
>> >  }
>> >
>> >  static void part_resume(struct mtd_info *mtd)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       part->parent->_resume(part->parent);
>> > +       mtd_resume(part->parent);
>> >  }
>> >
>> >  static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> >         ofs += part->offset;
>> > -       return part->parent->_block_isreserved(part->parent, ofs);
>> > +       return mtd_block_isreserved(part->parent, ofs);
>> >  }
>> >
>> >  static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> >         ofs += part->offset;
>> > -       return part->parent->_block_isbad(part->parent, ofs);
>> > +       return mtd_block_isbad(part->parent, ofs);
>> >  }
>> >
>> >  static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
>> > @@ -304,7 +297,7 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
>> >         int res;
>> >
>> >         ofs += part->offset;
>> > -       res = part->parent->_block_markbad(part->parent, ofs);
>> > +       res = mtd_block_markbad(part->parent, ofs);
>> >         if (!res)
>> >                 mtd->ecc_stats.badblocks++;
>> >         return res;
>> > @@ -313,13 +306,13 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
>> >  static int part_get_device(struct mtd_info *mtd)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       return part->parent->_get_device(part->parent);
>> > +       return __get_mtd_device(part->parent);
>> >  }
>> >
>> >  static void part_put_device(struct mtd_info *mtd)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> > -       part->parent->_put_device(part->parent);
>> > +       __put_mtd_device(part->parent);
>> >  }
>> >
>> >  static int part_ooblayout_ecc(struct mtd_info *mtd, int section,
>> > @@ -347,8 +340,7 @@ static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
>> >  {
>> >         struct mtd_part *part = mtd_to_part(mtd);
>> >
>> > -       return part->parent->_max_bad_blocks(part->parent,
>> > -                                            ofs + part->offset, len);
>> > +       return mtd_max_bad_blocks(part->parent, ofs + part->offset, len);
>> >  }
>> >
>> >  static inline void free_partition(struct mtd_part *p)
>> > @@ -437,59 +429,32 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
>> >
>> >         slave->mtd._read = part_read;
>> >         slave->mtd._write = part_write;
>> > -
>> > -       if (parent->_panic_write)
>> > -               slave->mtd._panic_write = part_panic_write;
>> > -
>> > -       if (parent->_point && parent->_unpoint) {
>> > -               slave->mtd._point = part_point;
>> > -               slave->mtd._unpoint = part_unpoint;
>> > -       }
>> > -
>> > -       if (parent->_read_oob)
>> > -               slave->mtd._read_oob = part_read_oob;
>> > -       if (parent->_write_oob)
>> > -               slave->mtd._write_oob = part_write_oob;
>> > -       if (parent->_read_user_prot_reg)
>> > -               slave->mtd._read_user_prot_reg = part_read_user_prot_reg;
>> > -       if (parent->_read_fact_prot_reg)
>> > -               slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg;
>> > -       if (parent->_write_user_prot_reg)
>> > -               slave->mtd._write_user_prot_reg = part_write_user_prot_reg;
>> > -       if (parent->_lock_user_prot_reg)
>> > -               slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg;
>> > -       if (parent->_get_user_prot_info)
>> > -               slave->mtd._get_user_prot_info = part_get_user_prot_info;
>> > -       if (parent->_get_fact_prot_info)
>> > -               slave->mtd._get_fact_prot_info = part_get_fact_prot_info;
>> > -       if (parent->_sync)
>> > -               slave->mtd._sync = part_sync;
>> > -       if (!partno && !parent->dev.class && parent->_suspend &&
>> > -           parent->_resume) {
>> > +       slave->mtd._panic_write = part_panic_write;
>> > +       slave->mtd._point = part_point;
>> > +       slave->mtd._unpoint = part_unpoint;
>> > +       slave->mtd._read_oob = part_read_oob;
>> > +       slave->mtd._write_oob = part_write_oob;
>> > +       slave->mtd._read_user_prot_reg = part_read_user_prot_reg;
>> > +       slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg;
>> > +       slave->mtd._write_user_prot_reg = part_write_user_prot_reg;
>> > +       slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg;
>> > +       slave->mtd._get_user_prot_info = part_get_user_prot_info;
>> > +       slave->mtd._get_fact_prot_info = part_get_fact_prot_info;
>> > +       slave->mtd._sync = part_sync;
>> > +       if (!partno && !parent->dev.class) {
>> >                 slave->mtd._suspend = part_suspend;
>> >                 slave->mtd._resume = part_resume;
>> >         }
>> > -       if (parent->_writev)
>> > -               slave->mtd._writev = part_writev;
>> > -       if (parent->_lock)
>> > -               slave->mtd._lock = part_lock;
>> > -       if (parent->_unlock)
>> > -               slave->mtd._unlock = part_unlock;
>> > -       if (parent->_is_locked)
>> > -               slave->mtd._is_locked = part_is_locked;
>> > -       if (parent->_block_isreserved)
>> > -               slave->mtd._block_isreserved = part_block_isreserved;
>> > -       if (parent->_block_isbad)
>> > -               slave->mtd._block_isbad = part_block_isbad;
>> > -       if (parent->_block_markbad)
>> > -               slave->mtd._block_markbad = part_block_markbad;
>> > -       if (parent->_max_bad_blocks)
>> > -               slave->mtd._max_bad_blocks = part_max_bad_blocks;
>> > -
>> > -       if (parent->_get_device)
>> > -               slave->mtd._get_device = part_get_device;
>> > -       if (parent->_put_device)
>> > -               slave->mtd._put_device = part_put_device;
>> > +       slave->mtd._writev = part_writev;
>> > +       slave->mtd._lock = part_lock;
>> > +       slave->mtd._unlock = part_unlock;
>> > +       slave->mtd._is_locked = part_is_locked;
>> > +       slave->mtd._block_isreserved = part_block_isreserved;
>> > +       slave->mtd._block_isbad = part_block_isbad;
>> > +       slave->mtd._block_markbad = part_block_markbad;
>> > +       slave->mtd._max_bad_blocks = part_max_bad_blocks;
>> > +       slave->mtd._get_device = part_get_device;
>> > +       slave->mtd._put_device = part_put_device;
>> >
>> >         slave->mtd._erase = part_erase;
>> >         slave->parent = parent;
>> > --
>> > 2.11.0
>> >
>


From rafal at milecki.pl  Wed Jan  3 22:32:36 2018
From: rafal at milecki.pl (=?UTF-8?Q?Rafa=C5=82_Mi=C5=82ecki?=)
Date: Thu, 04 Jan 2018 07:32:36 +0100
Subject: [PATCH V6 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <CAL_JsqLYjUsWGAYm978oPmMAue6YDRb=K00gReZTia6iaJ6xsA@mail.gmail.com>
References: <20180102130458.16226-1-zajec5@gmail.com>
 <20180103105543.17897-1-zajec5@gmail.com>
 <CAL_JsqLYjUsWGAYm978oPmMAue6YDRb=K00gReZTia6iaJ6xsA@mail.gmail.com>
Message-ID: <9a799300a0730a0103fe744878fb1a9f@milecki.pl>

On 2018-01-03 19:28, Rob Herring wrote:
> On Wed, Jan 3, 2018 at 4:55 AM, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>> From: Brian Norris <computersforpeace at gmail.com>
>> 
>> Partition parsers can now provide an of_match_table to enable
>> flash<-->parser matching via device tree as documented in the
>> mtd/partition.txt.
>> 
>> It works by looking for a matching parser for every string in the
>> "compatibility" property (starting with the most specific one).
>> 
>> This support is currently limited to built-in parsers as it uses
>> request_module() and friends. This should be sufficient for most cases
>> though as compiling parsers as modules isn't a common choice.
>> 
>> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>> This is based on Brian's patches:
>> [RFC PATCH 4/7] mtd: add of_match_mtd_parser() and 
>> of_mtd_match_mtd_parser() helpers
>> [RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
>> 
>> V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
>>     Merge helpers into a single of_mtd_match_mtd_parser
>> V3: Add a simple comment to note we will need the best match in the 
>> future
>> V4: Rework new functions to pick parser with the best match
>>     Move new code in parse_mtd_partitions up so it has precedence over 
>> flash
>>     driver defaults and MTD defaults
>> V5: Rework matching code to start checking with the most specific 
>> string in the
>>     "compatibility" property.
>> V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
>> ---
>>  drivers/mtd/mtdpart.c          | 64 
>> ++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/mtd/partitions.h |  1 +
>>  2 files changed, 65 insertions(+)
>> 
>> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
>> index be088bccd593..b11958adcf45 100644
>> --- a/drivers/mtd/mtdpart.c
>> +++ b/drivers/mtd/mtdpart.c
>> @@ -30,6 +30,7 @@
>>  #include <linux/mtd/mtd.h>
>>  #include <linux/mtd/partitions.h>
>>  #include <linux/err.h>
>> +#include <linux/of.h>
>> 
>>  #include "mtdcore.h"
>> 
>> @@ -880,6 +881,48 @@ static int mtd_part_do_parse(struct 
>> mtd_part_parser *parser,
>>  }
>> 
>>  /**
>> + * mtd_part_get_parser_by_cp - find MTD parser by a compatible string
> 
> What's "cp"? Perhaps mtd_part_get_compatible_parser.

That's what some base of functions use internally, like
__of_device_is_compatible (cp)
of_modalias_node (cplen)
but using "compatible" for the function name sounds better.


>> + *
>> + * @cp: compatible string describing partitions in a device tree
> 
> "compat" would be clearer IMO
> 
>> + *
>> + * MTD parsers can specify supported partitions by providing a table 
>> of
>> + * compatibility strings. This function finds a parser that 
>> advertises support
>> + * for a passed value of "compatible".
>> + */
>> +static struct mtd_part_parser *mtd_part_get_parser_by_cp(const char 
>> *cp)
>> +{
>> +       struct mtd_part_parser *p, *ret = NULL;
>> +
>> +       spin_lock(&part_parser_lock);
>> +
>> +       list_for_each_entry(p, &part_parsers, list) {
>> +               const struct of_device_id *matches;
>> +
>> +               matches = p->of_match_table;
>> +               if (!matches)
>> +                       continue;
>> +
>> +               for (; matches->name[0] || matches->type[0] || 
>> matches->compatible[0];
>> +                    matches++) {
>> +                       if (!matches->compatible[0])
>> +                               continue;
> 
> It would be simpler to just ignore name and type. Having either of
> those would be an error and the only consequence if there are entries
> without compatible is returning early.

OK, thanks. I guess I misused pattern I saw in the __of_match_node.


>> +                       if (!strcmp(matches->compatible, cp) &&
>> +                           try_module_get(p->owner)) {
>> +                               ret = p;
>> +                               break;
>> +                       }
>> +               }
>> +
>> +               if (ret)
>> +                       break;
>> +       }
>> +
>> +       spin_unlock(&part_parser_lock);
>> +
>> +       return ret;
>> +}
>> +
>> +/**
>>   * parse_mtd_partitions - parse MTD partitions
>>   * @master: the master partition (describes whole MTD device)
>>   * @types: names of partition parsers to try or %NULL
>> @@ -905,8 +948,29 @@ int parse_mtd_partitions(struct mtd_info *master, 
>> const char *const *types,
>>                          struct mtd_part_parser_data *data)
>>  {
>>         struct mtd_part_parser *parser;
>> +       struct device_node *np;
>> +       struct property *prop;
>> +       const char *cp;
>>         int ret, err = 0;
>> 
>> +       np = of_get_child_by_name(mtd_get_of_node(master), 
>> "partitions");
>> +       if (np) {
> 
> You can drop this. of_property_for_each_string and of_node_put will
> work if np is NULL.
> 
>> +               of_property_for_each_string(np, "compatible", prop, 
>> cp) {
>> +                       parser = mtd_part_get_parser_by_cp(cp);
>> +                       if (!parser)
>> +                               continue;
>> +                       ret = mtd_part_do_parse(parser, master, 
>> pparts, data);
>> +                       if (ret > 0) {
>> +                               of_node_put(np);
>> +                               return 0;
>> +                       }
>> +                       mtd_part_parser_put(parser);
>> +                       if (ret < 0 && !err)
>> +                               err = ret;
>> +               }
>> +               of_node_put(np);
>> +       }
>> +
>>         if (!types)
>>                 types = default_mtd_part_types;
>> 
>> diff --git a/include/linux/mtd/partitions.h 
>> b/include/linux/mtd/partitions.h
>> index c4beb70dacbd..11cb0c50cd84 100644
>> --- a/include/linux/mtd/partitions.h
>> +++ b/include/linux/mtd/partitions.h
>> @@ -77,6 +77,7 @@ struct mtd_part_parser {
>>         struct list_head list;
>>         struct module *owner;
>>         const char *name;
>> +       const struct of_device_id *of_match_table;
> 
> I generally like using of_device_id over just an array of strings, but
> I'm wondering if there's really cases where you have multiple
> compatible strings for a single parser? Perhaps a single string here
> would be sufficient. And if you did have multiple matches, how would
> you distinguish them later on in the parsing functions? Normally we'd
> use the matched data ptr, but that's not provided here.

I think we may need some flash parsers to support multiple strings in
the future. For example image tag parser (bcm63xxpart.c) handles
Broadcom's tag that has few versions (see struct bcm_tag and its
version field).

Later we may want to add support for matching partitions parsers (like
trx) which also can have multple versions support. For example TRX v1
and TRX v2 differ by a single field in the header and it makes sense to
use the same parser for them.

While this may be not a perfect solution with data ptr, we can always do
of_device_is_compatible(&mtd->dev, "foo")


>>         int (*parse_fn)(struct mtd_info *, const struct mtd_partition 
>> **,
>>                         struct mtd_part_parser_data *);
>>         void (*cleanup)(const struct mtd_partition *pparts, int 
>> nr_parts);
>> --
>> 2.11.0
>> 


From zajec5 at gmail.com  Wed Jan  3 23:05:33 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  4 Jan 2018 08:05:33 +0100
Subject: [PATCH V7 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180103105543.17897-1-zajec5@gmail.com>
References: <20180103105543.17897-1-zajec5@gmail.com>
Message-ID: <20180104070534.16248-1-zajec5@gmail.com>

From: Brian Norris <computersforpeace at gmail.com>

Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.

It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).

This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching

V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
    Merge helpers into a single of_mtd_match_mtd_parser
V3: Add a simple comment to note we will need the best match in the future
V4: Rework new functions to pick parser with the best match
    Move new code in parse_mtd_partitions up so it has precedence over flash
    driver defaults and MTD defaults
V5: Rework matching code to start checking with the most specific string in the
    "compatibility" property.
V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
V7: Rename function "mtd_part_get_parser_by_cp" to use "_compatible_"
    Rename "cp" variable to "compat"
    Drop unneeded if (np) check from the parse_mtd_partitions
---
 drivers/mtd/mtdpart.c          | 59 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/partitions.h |  1 +
 2 files changed, 60 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index be088bccd593..76e12fb81563 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -880,6 +881,45 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 }
 
 /**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+	struct mtd_part_parser *p, *ret = NULL;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->compatible[0]; matches++) {
+			if (!strcmp(matches->compatible, compat) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
+/**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
  * @types: names of partition parsers to try or %NULL
@@ -905,8 +945,27 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 			 struct mtd_part_parser_data *data)
 {
 	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *compat;
 	int ret, err = 0;
 
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	of_property_for_each_string(np, "compatible", prop, compat) {
+		parser = mtd_part_get_compatible_parser(compat);
+		if (!parser)
+			continue;
+		ret = mtd_part_do_parse(parser, master, pparts, data);
+		if (ret > 0) {
+			of_node_put(np);
+			return 0;
+		}
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+	of_node_put(np);
+
 	if (!types)
 		types = default_mtd_part_types;
 
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70dacbd..11cb0c50cd84 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-- 
2.11.0



From zajec5 at gmail.com  Wed Jan  3 23:05:34 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  4 Jan 2018 08:05:34 +0100
Subject: [PATCH V7 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
In-Reply-To: <20180104070534.16248-1-zajec5@gmail.com>
References: <20180103105543.17897-1-zajec5@gmail.com>
 <20180104070534.16248-1-zajec5@gmail.com>
Message-ID: <20180104070534.16248-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).

This matches existing bindings documentation.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/ofpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e525677..92fcbac046d9 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
 	.parse_fn = parse_ofpart_partitions,
 	.name = "ofpart",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
-- 
2.11.0



From christophe.leroy at c-s.fr  Thu Jan  4 00:05:45 2018
From: christophe.leroy at c-s.fr (Christophe LEROY)
Date: Thu, 4 Jan 2018 09:05:45 +0100
Subject: [PATCH v3 00/27] kill devm_ioremap_nocache
In-Reply-To: <8dd19411-5b06-0aa4-fd0e-e5b112c25dcb@huawei.com>
References: <1514026525-32538-1-git-send-email-xieyisheng1@huawei.com>
 <20171223134831.GB10103@kroah.com>
 <b8ff7f17-7f2c-f220-9833-7ae5bd7343d5@c-s.fr>
 <8dd19411-5b06-0aa4-fd0e-e5b112c25dcb@huawei.com>
Message-ID: <1eb206ed-95e9-5839-485d-0e549ff3f505@c-s.fr>



Le 25/12/2017 ? 02:34, Yisheng Xie a ?crit?:
> 
> 
> On 2017/12/24 17:05, christophe leroy wrote:
>>
>>
>> Le 23/12/2017 ? 14:48, Greg KH a ?crit :
>>> On Sat, Dec 23, 2017 at 06:55:25PM +0800, Yisheng Xie wrote:
>>>> Hi all,
>>>>
>>>> When I tried to use devm_ioremap function and review related code, I found
>>>> devm_ioremap and devm_ioremap_nocache is almost the same with each other,
>>>> except one use ioremap while the other use ioremap_nocache.
>>>
>>> For all arches?  Really?  Look at MIPS, and x86, they have different
>>> functions.
>>>
>>>> While ioremap's
>>>> default function is ioremap_nocache, so devm_ioremap_nocache also have the
>>>> same function with devm_ioremap, which can just be killed to reduce the size
>>>> of devres.o(from 20304 bytes to 18992 bytes in my compile environment).
>>>>
>>>> I have posted two versions, which use macro instead of function for
>>>> devm_ioremap_nocache[1] or devm_ioremap[2]. And Greg suggest me to kill
>>>> devm_ioremap_nocache for no need to keep a macro around for the duplicate
>>>> thing. So here comes v3 and please help to review.
>>>
>>> I don't think this can be done, what am I missing?  These functions are
>>> not identical, sorry for missing that before.
>>
>> devm_ioremap() and devm_ioremap_nocache() are quite similar, both use devm_ioremap_release() for the release, why not just defining:
>>
>> static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
>>                 resource_size_t size, bool nocache)
>> {
>> [...]
>>      if (nocache)
>>          addr = ioremap_nocache(offset, size);
>>      else
>>          addr = ioremap(offset, size);
>> [...]
>> }
>>
>> then in include/linux/io.h
>>
>> static inline void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
>>                 resource_size_t size)
>> {return __devm_ioremap(dev, offset, size, false);}
>>
>> static inline void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
>>                     resource_size_t size);
>> {return __devm_ioremap(dev, offset, size, true);}
> 
> Yeah, this seems good to me, right now we have devm_ioremap, devm_ioremap_wc, devm_ioremap_nocache
> May be we can use an enum like:
> typedef enum {
> 	DEVM_IOREMAP = 0,
> 	DEVM_IOREMAP_NOCACHE,
> 	DEVM_IOREMAP_WC,
> } devm_ioremap_type;
> 
> static inline void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
>                  resource_size_t size)
>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP);}
> 
>   static inline void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
>                      resource_size_t size);
>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NOCACHE);}
> 
>   static inline void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
>                      resource_size_t size);
>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC);}
> 
>   static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
>                  resource_size_t size, devm_ioremap_type type)
>   {
>       void __iomem **ptr, *addr = NULL;
>   [...]
>       switch (type){
>       case DEVM_IOREMAP:
>           addr = ioremap(offset, size);
>           break;
>       case DEVM_IOREMAP_NOCACHE:
>           addr = ioremap_nocache(offset, size);
>           break;
>       case DEVM_IOREMAP_WC:
>           addr = ioremap_wc(offset, size);
>           break;
>       }
>   [...]
>   }


That looks good to me, will you submit a v4 ?

Christophe

> 
> Thanks
> Yisheng
> 
>>
>> Christophe
>>
>>>
>>> thanks,
>>>
>>> greg k-h
>>> -- 
>>> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>> ---
>> L'absence de virus dans ce courrier ?lectronique a ?t? v?rifi?e par le logiciel antivirus Avast.
>> https://www.avast.com/antivirus
>>
>>
>> .
>>


From mika.westerberg at linux.intel.com  Thu Jan  4 01:07:42 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu,  4 Jan 2018 12:07:42 +0300
Subject: [PATCH 1/3] spi-nor: intel-spi: Prefer WREN over other write enables
Message-ID: <20180104090744.67654-1-mika.westerberg@linux.intel.com>

On many older systems using SW sequencer the PREOP_OPTYPE register
contains two preopcodes as following:

  PREOP_OPTYPE=0xf2785006

The last two bytes are the opcodes decoded to:

  0x50 - Write enable for volatile status register
  0x06 - Write enable

The former is used to modify volatile bits in the status register. For
non-volatile bits the latter is needed. Preopcodes are used in SW
sequencer to send one command "atomically" without anything else
interfering the transfer. The sequence that gets executed is:

  - Send preopcode (write enable) from PREOP_OPTYPE register
  - Send the actual SPI command
  - Poll busy bit in the status register (0x05, RDSR)

Commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
programmed by BIOS") enabled atomic sequence handling but because both
preopcodes are programmed, the following happens:

  if (preop >> 8)
  	val |= SSFSTS_CTL_SPOP;

Since on these systems preop >> 8 == 0x50 we end up picking volatile
write enable instead. Because of this the actual write command is pretty
much NOP unless there is a WREN latched in the chip already.

Fix this by preferring WREN over other write enable preopcodes.

Fixes: 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
Cc: stable at vger.kernel.org
---
 drivers/mtd/spi-nor/intel-spi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
index ef034d898a23..bba762aa0c8d 100644
--- a/drivers/mtd/spi-nor/intel-spi.c
+++ b/drivers/mtd/spi-nor/intel-spi.c
@@ -498,9 +498,17 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, int len,
 	val |= SSFSTS_CTL_SCGO;
 	preop = readw(ispi->sregs + PREOP_OPTYPE);
 	if (preop) {
-		val |= SSFSTS_CTL_ACS;
-		if (preop >> 8)
-			val |= SSFSTS_CTL_SPOP;
+		switch (optype) {
+		case OPTYPE_WRITE_NO_ADDR:
+		case OPTYPE_WRITE_WITH_ADDR:
+			/*
+			 * For writes prefer WREN over other write enable
+			 * opcodes.
+			 */
+			val |= SSFSTS_CTL_ACS;
+			if ((preop >> 8) == SPINOR_OP_WREN)
+				val |= SSFSTS_CTL_SPOP;
+		}
 	}
 	writel(val, ispi->sregs + SSFSTS_CTL);
 
-- 
2.15.1



From mika.westerberg at linux.intel.com  Thu Jan  4 01:07:44 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu,  4 Jan 2018 12:07:44 +0300
Subject: [PATCH 3/3] spi-nor: intel-spi: Remove unused preopcodes field
In-Reply-To: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
Message-ID: <20180104090744.67654-3-mika.westerberg@linux.intel.com>

This field is not used in the driver anymore so remove it.

Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
---
 drivers/mtd/spi-nor/intel-spi.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
index bba762aa0c8d..8d54da46da30 100644
--- a/drivers/mtd/spi-nor/intel-spi.c
+++ b/drivers/mtd/spi-nor/intel-spi.c
@@ -138,7 +138,6 @@
  * @erase_64k: 64k erase supported
  * @opcodes: Opcodes which are supported. This are programmed by BIOS
  *           before it locks down the controller.
- * @preopcodes: Preopcodes which are supported.
  */
 struct intel_spi {
 	struct device *dev;
@@ -155,7 +154,6 @@ struct intel_spi {
 	bool swseq_erase;
 	bool erase_64k;
 	u8 opcodes[8];
-	u8 preopcodes[2];
 };
 
 static bool writeable;
@@ -400,10 +398,6 @@ static int intel_spi_init(struct intel_spi *ispi)
 				ispi->opcodes[i] = opmenu0 >> i * 8;
 				ispi->opcodes[i + 4] = opmenu1 >> i * 8;
 			}
-
-			val = readl(ispi->sregs + PREOP_OPTYPE);
-			ispi->preopcodes[0] = val;
-			ispi->preopcodes[1] = val >> 8;
 		}
 	}
 
-- 
2.15.1



From mika.westerberg at linux.intel.com  Thu Jan  4 01:07:43 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu,  4 Jan 2018 12:07:43 +0300
Subject: [PATCH 2/3] spi-nor: intel-spi: Explicitly mark the driver as
 dangerous in Kconfig
In-Reply-To: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
Message-ID: <20180104090744.67654-2-mika.westerberg@linux.intel.com>

The driver is not meant for normal users at all but instead such users
who really know what they are doing and are able to build their own
kernel to enable it. Mark both driver Kconfig entries as dangerous to
make sure the driver is not accidentally enabled without understanding
possible issues in doing so.

Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
---
 drivers/mtd/spi-nor/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 89da88e59121..f480b227a6b8 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -90,7 +90,7 @@ config SPI_INTEL_SPI
 	tristate
 
 config SPI_INTEL_SPI_PCI
-	tristate "Intel PCH/PCU SPI flash PCI driver"
+	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
 	depends on X86 && PCI
 	select SPI_INTEL_SPI
 	help
@@ -106,7 +106,7 @@ config SPI_INTEL_SPI_PCI
 	  will be called intel-spi-pci.
 
 config SPI_INTEL_SPI_PLATFORM
-	tristate "Intel PCH/PCU SPI flash platform driver"
+	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
 	depends on X86
 	select SPI_INTEL_SPI
 	help
-- 
2.15.1



From yogeshnarayan.gaur at nxp.com  Thu Jan  4 01:11:01 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Narayan Gaur)
Date: Thu, 4 Jan 2018 09:11:01 +0000
Subject: [PATCH] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <894be40c-07d2-4676-4da8-03124169039b@wedev4u.fr>
References: <1514976987-14082-1-git-send-email-yogeshnarayan.gaur@nxp.com>
 <894be40c-07d2-4676-4da8-03124169039b@wedev4u.fr>
Message-ID: <DB6PR0402MB283897C99F5580D87A4088CB991F0@DB6PR0402MB2838.eurprd04.prod.outlook.com>

Hello Cyrille,

My mistake, I was planning to send this patch along with the patch
https://patchwork.ozlabs.org/patch/854967/ in which have done changes in fsl-quadspi.c driver to have run-time LUT creation support.

Apologies for that.

Would send new patch series, marking these as v1, v2.

--
Regards
Yogesh Gaur.

> -----Original Message-----
> From: Cyrille Pitchen [mailto:cyrille.pitchen at wedev4u.fr]
> Sent: Thursday, January 04, 2018 1:37 AM
> To: Yogesh Narayan Gaur <yogeshnarayan.gaur at nxp.com>; linux-
> mtd at lists.infradead.org
> Cc: boris.brezillon at free-electrons.com; computersforpeace at gmail.com; Han
> Xu <han.xu at nxp.com>; festevam at gmail.com; Prabhakar Kushwaha
> <prabhakar.kushwaha at nxp.com>; Suresh Gupta <suresh.gupta at nxp.com>
> Subject: Re: [PATCH] mtd: fsl-quadspi: update hwcaps read capabilities as
> READ_1_4_4
> 
> Le 03/01/2018 ? 11:56, Yogesh Gaur a ?crit :
> > Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
> > protocol. Spansion flash, s25fl512s, supports Quad read with read
> > capabilities as 1-4-4.
> >
> > Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.
> >
> > Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
> > ---
> >  drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> > b/drivers/mtd/spi-nor/fsl-quadspi.c
> > index c22e3eb..178e621 100644
> > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > @@ -959,6 +959,7 @@ static int fsl_qspi_probe(struct platform_device
> > *pdev)  {
> >  	const struct spi_nor_hwcaps hwcaps = {
> >  		.mask = SNOR_HWCAPS_READ_1_1_4 |
> > +			SNOR_HWCAPS_READ_1_4_4 |
> >  			SNOR_HWCAPS_PP,
> >  	};
> >  	struct device_node *np = pdev->dev.of_node;
> >
> 
> NACK: adding the SNOR_HWCAPS_READ_1_4_4 hardware capability tells
> spi_nor_scan() that the SPI (flash) controller, not the SPI flash memory, supports
> the SPI 1-4-4 for Fast Read operations.
> 
> You cannot add this flag without adding real support of Fast Read 1-4-4 to the
> fsl-quadspi.c driver.

From elfring at users.sourceforge.net  Thu Jan  4 02:52:27 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 11:52:27 +0100
Subject: [PATCH 2/2] mtd/maps/sun_uflash: Improve a size determination in
 uflash_devinit()
In-Reply-To: <30c07f5a-578c-0e53-b80f-675fb24e6223@users.sourceforge.net>
References: <30c07f5a-578c-0e53-b80f-675fb24e6223@users.sourceforge.net>
Message-ID: <1c70e16b-f34c-d655-fdd4-67730f17a680@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 11:38:28 +0100

Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/maps/sun_uflash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 80a253cc72e2..16a4f16a2680 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -61,7 +61,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)
 		return -ENODEV;
 	}
 
-	up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
+	up = kzalloc(sizeof(*up), GFP_KERNEL);
 	if (!up)
 		return -ENOMEM;
 
-- 
2.15.1



From elfring at users.sourceforge.net  Thu Jan  4 02:50:14 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 11:50:14 +0100
Subject: [PATCH 0/2] mtd/maps/sun_uflash: Adjustments for uflash_devinit()
Message-ID: <30c07f5a-578c-0e53-b80f-675fb24e6223@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 11:45:54 +0100

Two update suggestions were taken into account
from static source code analysis.

Markus Elfring (2):
  Delete an error message for a failed memory allocation
  Improve a size determination

 drivers/mtd/maps/sun_uflash.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

-- 
2.15.1



From elfring at users.sourceforge.net  Thu Jan  4 02:51:17 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 11:51:17 +0100
Subject: [PATCH 1/2] mtd/maps/sun_uflash: Delete an error message for a failed
 memory allocation in uflash_devinit()
In-Reply-To: <30c07f5a-578c-0e53-b80f-675fb24e6223@users.sourceforge.net>
References: <30c07f5a-578c-0e53-b80f-675fb24e6223@users.sourceforge.net>
Message-ID: <7417f52d-ddba-e8f8-0014-31bc787213db@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 10:20:14 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/maps/sun_uflash.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 1e73bba6e286..80a253cc72e2 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -62,10 +62,8 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)
 	}
 
 	up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
-	if (!up) {
-		printk(KERN_ERR PFX "Cannot allocate struct uflash_dev\n");
+	if (!up)
 		return -ENOMEM;
-	}
 
 	/* copy defaults and tweak parameters */
 	memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
-- 
2.15.1



From yogeshnarayan.gaur at nxp.com  Thu Jan  4 03:12:13 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 4 Jan 2018 16:42:13 +0530
Subject: [PATCH 1/2] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1515064334-509-2-git-send-email-yogeshnarayan.gaur@nxp.com>

Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
protocol. Spansion flash, s25fl512s, supports Quad read with read
capabilities as 1-4-4.

Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index c22e3eb..178e621 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -959,6 +959,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	const struct spi_nor_hwcaps hwcaps = {
 		.mask = SNOR_HWCAPS_READ_1_1_4 |
+			SNOR_HWCAPS_READ_1_4_4 |
 			SNOR_HWCAPS_PP,
 	};
 	struct device_node *np = pdev->dev.of_node;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Thu Jan  4 03:12:12 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 4 Jan 2018 16:42:12 +0530
Subject: [PATCH 0/2] mtd: fsl-quadspi: add support to create dynamic LUT entry
Message-ID: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has limitation in number of LUT entries, max 16.
Also different flash devices can run on different cmds.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also update read capabilities as 1-4-4.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4
  mtd: fsl-quadspi: add support to create dynamic LUT entry

 drivers/mtd/spi-nor/fsl-quadspi.c | 292 ++++++++++++++++++++------------------
 1 file changed, 157 insertions(+), 135 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Thu Jan  4 03:12:14 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 4 Jan 2018 16:42:14 +0530
Subject: [PATCH 2/2] mtd: fsl-quadspi: add support to create dynamic LUT entry
In-Reply-To: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1515064334-509-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 291 ++++++++++++++++++++------------------
 1 file changed, 156 insertions(+), 135 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 178e621..19d8f03 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -194,20 +194,19 @@
 
 /* SEQID -- we can have 16 seqids at most. */
 #define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+#define SEQID_RUN_CMD		1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +367,151 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
 {
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
+{
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
+	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+	u8 read_dm, opcode;
 	int i;
 
-	struct spi_nor *nor = &q->nor[0];
-	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
+
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
+
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
+	/* Dynamic LUT */
+	lut_base = SEQID_RUN_CMD * 4;
+
+	/* Clear LUT entries for dynamic LUT entry in LUT table */
+	for (i = lut_base; i < (lut_base + 4); i++)
 		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
 
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
 
-	fsl_qspi_lock_lut(q);
-}
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		if (ops == FSL_QSPI_OPS_READ) {
+			qspi_writel(q,
+				    LUT0(DUMMY, pad_count(dummy_pad), read_dm) |
+				    LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+				    base + QUADSPI_LUT(lut_base + 1));
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				SEQID_RUN_CMD << QUADSPI_BFGENCR_SEQID_SHIFT,
+				q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	fsl_qspi_lock_lut(q);
+}
+
+static void fsl_qspi_init_lut(struct fsl_qspi *q)
+{
+	void __iomem *base = q->iobase;
+	int i;
+
+	fsl_qspi_unlock_lut(q);
+
+	/* Clear all LUT table, except LUT0. LUT0 programmed by bootloader */
+	for (i = 4; i < QUADSPI_LUT_NUM; i++)
+		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +546,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +698,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +742,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -794,9 +807,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	return 0;
 }
 
@@ -820,6 +830,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +845,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +855,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +873,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +890,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +940,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From elfring at users.sourceforge.net  Thu Jan  4 06:03:55 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 15:03:55 +0100
Subject: [PATCH] mtd/maps/vmu-flash: Delete an error message for a failed
 memory allocation in maple_vmu_read_block()
Message-ID: <efc677c8-35c6-dd97-2091-8daa91576602@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 14:54:08 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/maps/vmu-flash.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
index 6b223cfe92b7..a76a5ff402e1 100644
--- a/drivers/mtd/maps/vmu-flash.c
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -130,9 +130,6 @@ static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
 	if (!pcache->buffer) {
 		pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
 		if (!pcache->buffer) {
-			dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
-				" to lack of memory\n", mdev->port,
-				mdev->unit);
 			error = -ENOMEM;
 			goto outB;
 		}
-- 
2.15.1



From prabhakar.kushwaha at nxp.com  Thu Jan  4 06:08:42 2018
From: prabhakar.kushwaha at nxp.com (Prabhakar Kushwaha)
Date: Thu, 4 Jan 2018 14:08:42 +0000
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
Message-ID: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>

Hi All,

Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial NOR(Die #0) and Serial NAND(Die #1) flash. 
Means both NOR, NAND flashes are placed in W25M161AW controlled by single chip-select. 

"Software Die Select (C2h)" command is being used to switch die or flash. 
 
It looks to be quite unique chip and wondering if any kind framework or work in progress available to handle it. 
I know that SPI-NAND framework discussions is still in progress.   

Regards,
Prabhakar



From dhowells at redhat.com  Thu Jan  4 06:52:54 2018
From: dhowells at redhat.com (David Howells)
Date: Thu, 04 Jan 2018 14:52:54 +0000
Subject: [PATCH v3 00/27] kill devm_ioremap_nocache
In-Reply-To: <CAK8P3a3i0bKvG56ha9_hzO=z80sVxCQhaeFn6QW3AwbwZs3HPg@mail.gmail.com>
References: <CAK8P3a3i0bKvG56ha9_hzO=z80sVxCQhaeFn6QW3AwbwZs3HPg@mail.gmail.com>
 <1514026525-32538-1-git-send-email-xieyisheng1@huawei.com>
 <20171223134831.GB10103@kroah.com>
 <f7632cf5-2bcc-4d74-b912-3999937a1269@roeck-us.net>
 <c28ac0bc-8bd2-3dce-3167-8c0f80ec601e@c-s.fr>
Message-ID: <20289.1515077574@warthog.procyon.org.uk>

Arnd Bergmann <arnd at arndb.de> wrote:

> - mn10300 appears to be wrong, broken by David Howells in
>   commit 83c2dc15ce82 ("MN10300: Handle cacheable PCI regions
>   in pci_iomap()") for any driver calling ioremap() by to get uncached
>   memory,

It's not clear what the right thing to do was, given that there's an ioremap()
and an ioremap_uncached().

But the asb2305's pci_iomap() will use ioremap() (the cacheable window) if
IORESOURCE_CACHEABLE is set, but IORESOURCE_IO is not and ioremap_uncached()
otherwise.

The other supported units don't have PCI buses.

> if I understand the comment for commit 34f1bdee1910 ("mn10300: switch to
> GENERIC_PCI_IOMAP") correctly: it seems that PCI addresses include the
> 'uncached' bit by default to get the right behavior, but dropping that bit
> breaks it.

Not exactly.  The CPU has a window in the range 0xa0000000-0xbfffffff which is
an uncached view of its hardware buses.  It has another window in the range
0x80000000-0x9fffffff which is a cached view of that region.  These windows
cannot be changed and addresses above 0x80000000 are statically mapped and are
only accessible by the kernel (this is hardwired in the MMU).

So the arch has two subwindows to the PCI bus, one cached and one uncached.
These subwindows are further subdivided into ioport and iomem spaces, an SRAM
and some control registers for the CPU-PCI bridge.

David


From boris.brezillon at free-electrons.com  Thu Jan  4 09:47:22 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 4 Jan 2018 18:47:22 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
Message-ID: <20180104184722.551ca6aa@bbrezillon>

+MTD maintainers.

On Thu, 4 Jan 2018 14:08:42 +0000
Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:

> Hi All,
> 
> Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial NOR(Die #0) and Serial NAND(Die #1) flash. 
> Means both NOR, NAND flashes are placed in W25M161AW controlled by single chip-select. 
> 
> "Software Die Select (C2h)" command is being used to switch die or flash.

Why are they so mean to us?! :-)
 
>  
> It looks to be quite unique chip and wondering if any kind framework or work in progress available to handle it. 
> I know that SPI-NAND framework discussions is still in progress.

Well, nothing impossible to handle, we just need to declare 2 MTD
devices (one NAND and one NOR). This being said, it looks like we'll
need this spi-flash abstraction we have been talking about with Marek
and Cyrille to properly support these use cases: flash devices will be
exposed through different sub-layers (spi-nor or spi-nand), but we need
a common way to detect those spi-flash chips. I looked at a few SPI
NAND and SPI NOR chips, and from what I've seen so far they were quite
different (the opcodes and CMD+ADDR+DATA sequences were quite
different) so I thought we were safe to start with a completely
unconnected SPI NAND framework and merge some bits in a spi-flash layer
afterwards, but this chip proves me wrong :-/.


From harjoc at gmail.com  Thu Jan  4 10:02:26 2018
From: harjoc at gmail.com (Bogdan Harjoc)
Date: Thu, 4 Jan 2018 20:02:26 +0200
Subject: Read errors after an UBIFS update
Message-ID: <CAF4+tmpp_kYqFVgdz+HhVPR61m10k7ZyjNKBq6fRZw0eDVfYhA@mail.gmail.com>

I am encountering these messages after creating an UBIFS filesystem in
a new UBI volume on an existing UBI partition.

The rate of reproduction is one in about 20 sequences of: ubirmvol,
ubimkvol (256MB), unpack a rootfs.tgz (20MB, 40MB unpacked) in the
mounted UBIFS, umount, ubidetach, sync, reboot. There are no xattrs
created. No power cuts happen during the tests. I realize ubiupdatevol
may be better suited, I will consider using it instead of
rmvol+mkvol+tar although the update script is already flashed on
boards.

The board runs a 3.18.80 kernel on an ARM board. I tested other
identical test boards where only the NAND chip manufacturer was
different.

I had CONFIG_MTD_UBI_FASTMAP enabled when the error occured, but I
used no explicit fastmap boot cmdline option. I tried mounting the
ubifs with a rebuilt kernel that had the config option disabled after
the issue reproduced, but the read error still occured. I will test
with the no-fastmap kernel to see if the issue still happens.

I also tried mounting with a kernel that had "ubifs: Fix journal
replay wrt. xattr nodes" patch [1] applied, after reading some older
threads on linux-mtd, but once reproduced on a NAND, the read error
persisted.

[1] https://patchwork.ozlabs.org/patch/713213/

Is there some special requirement except just umount, ubidetach and
sync before running reboot, or regarding free space fixup ? Would
creating the fs image offline with mkfs.ubifs instead of unpacking it
via tar make a difference here ? Would it help to try to test with the
cherry picked 5-10 commits from linux 3.18.80 to 4.14 that touch
fs/ubifs ?

Thanks,
Bogdan

----

UBI-0: ubi_attach_mtd_dev:default fastmap pool size: 190
UBI-0: ubi_attach_mtd_dev:default fastmap WL pool size: 25
UBI-0: ubi_attach_mtd_dev:attaching mtd3 to ubi0
UBI-0: scan_all:scanning is finished
UBI-0: ubi_attach_mtd_dev:attached mtd3 (name "data", size 3824 MiB)
UBI-0: ubi_attach_mtd_dev:PEB size: 1048576 bytes (1024 KiB), LEB
size: 1040384 bytes
UBI-0: ubi_attach_mtd_dev:min./max. I/O unit sizes: 4096/4096,
sub-page size 4096
UBI-0: ubi_attach_mtd_dev:VID header offset: 4096 (aligned 4096), data
offset: 8192
UBI-0: ubi_attach_mtd_dev:good PEBs: 3816, bad PEBs: 8, corrupted PEBs: 0
UBI-0: ubi_attach_mtd_dev:user volume: 6, internal volumes: 1, max.
volumes count: 128
UBI-0: ubi_attach_mtd_dev:max/mean erase counter: 4/2, WL threshold:
4096, image sequence number: 1362948729
UBI-0: ubi_attach_mtd_dev:available PEBs: 2313, total reserved PEBs:
1503, PEBs reserved for bad PEB handling: 72
UBI-0: ubi_thread:background thread "ubi_bgt0d" started, PID 419
UBIFS: mounted UBI device 0, volume 6, name "slot1", R/O mode
UBIFS: LEB size: 1040384 bytes (1016 KiB), min./max. I/O unit sizes:
4096 bytes/4096 bytes
UBIFS: FS size: 259055616 bytes (247 MiB, 249 LEBs), journal size
12484608 bytes (11 MiB, 12 LEBs)
UBIFS: reserved for root: 4952683 bytes (4836 KiB)
UBIFS: media format: w4/r0 (latest is w4/r0), UUID
92C7B251-2666-4717-B735-5539900FE749, small LPT model

----

UBIFS error (pid 1810): ubifs_read_node: bad node type (255 but expected 1)
UBIFS error (pid 1810): ubifs_read_node: bad node at LEB 33:967120,
LEB mapping status 0
Not a node, first 24 bytes:
00000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff
CPU: 0 PID: 1810 Comm: tar Tainted: P           O   3.18.80 #3
Backtrace:
 [<8001b664>] (dump_backtrace) from [<8001b880>] (show_stack+0x18/0x1c)
 r7:00000000 r6:00000000 r5:80000013 r4:80566cbc
 [<8001b868>] (show_stack) from [<801d77e0>] (dump_stack+0x88/0xa4)
 [<801d7758>] (dump_stack) from [<80171608>] (ubifs_read_node+0x1fc/0x2b8)
  r7:00000021 r6:00000712 r5:000ec1d0 r4:bd59d000
 [<8017140c>] (ubifs_read_node) from [<8018b654>]
(ubifs_tnc_read_node+0x88/0x124)
  r10:00000000 r9:b4f9fdb0 r8:bd59d264 r7:00000001 r6:b71e6000 r5:bd59d000
  r4:b6126148
 [<8018b5cc>] (ubifs_tnc_read_node) from [<80174690>]
(ubifs_tnc_locate+0x108/0x1e0)
  r7:00000001 r6:b71e6000 r5:00000001 r4:bd59d000
 [<80174588>] (ubifs_tnc_locate) from [<80168200>] (do_readpage+0x1c0/0x39c)
  r10:bd59d000 r9:000005b1 r8:00000000 r7:bd258710 r6:a5914000 r5:b71e6000
  r4:be09e280
 [<80168040>] (do_readpage) from [<80169398>] (ubifs_readpage+0x44/0x424)
  r10:00000000 r9:00000000 r8:bd59d000 r7:be09e280 r6:00000000 r5:bd258710
  r4:00000000
 [<80169354>] (ubifs_readpage) from [<80089654>]
(generic_file_read_iter+0x48c/0x5d8)
  r10:00000000 r9:00000000 r8:00000000 r7:be09e280 r6:bd2587d4 r5:bd5379e0
  r4:00000000
 [<800891c8>] (generic_file_read_iter) from [<800bbd60>]
(new_sync_read+0x84/0xa8)
  r10:00000000 r9:b4f9e000 r8:80008e24 r7:bd6437a0 r6:bd5379e0 r5:b4f9ff80
  r4:00001000
 [<800bbcdc>] (new_sync_read) from [<800bc85c>] (__vfs_read+0x20/0x54)
  r7:b4f9ff80 r6:7ec2d800 r5:00001000 r4:800bbcdc
 [<800bc83c>] (__vfs_read) from [<800bc91c>] (vfs_read+0x8c/0xf4)
  r5:00001000 r4:bd5379e0
 [<800bc890>] (vfs_read) from [<800bc9cc>] (SyS_read+0x48/0x80)
  r9:b4f9e000 r8:80008e24 r7:00001000 r6:7ec2d800 r5:bd5379e0 r4:bd5379e0
 [<800bc984>] (SyS_read) from [<80008c80>] (ret_fast_syscall+0x0/0x3c)
  r7:00000003 r6:7ec2d800 r5:00000008 r4:00082a08
UBIFS error (pid 1811): do_readpage: cannot read page 0 of inode 1457, error -22


From harjoc at gmail.com  Thu Jan  4 10:11:48 2018
From: harjoc at gmail.com (Bogdan Harjoc)
Date: Thu, 4 Jan 2018 20:11:48 +0200
Subject: Read errors after an UBIFS update
In-Reply-To: <CAF4+tmpp_kYqFVgdz+HhVPR61m10k7ZyjNKBq6fRZw0eDVfYhA@mail.gmail.com>
References: <CAF4+tmpp_kYqFVgdz+HhVPR61m10k7ZyjNKBq6fRZw0eDVfYhA@mail.gmail.com>
Message-ID: <CAF4+tmo8C=YWb6p7KMjOG871ydZnxWR+ND7SqfOduBgXsd9HtQ@mail.gmail.com>

> Would it help to try to test with the cherry picked 5-10 commits from
> linux 3.18.80 to 4.14 that touch fs/ubifs ?

I meant commits that touch fs/ubifs/tnc.c which was related to the
xattr fixes. I just realized there are hundreds of commits in fs/ubifs
since 2015. Sorry about that,

Bogdan


From elfring at users.sourceforge.net  Thu Jan  4 11:28:52 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 20:28:52 +0100
Subject: [PATCH 0/2] mtdconcat: Adjustments for two function implementations
Message-ID: <07947bdd-2b30-e4b5-82f7-d98b62df858e@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 20:24:56 +0100

Two update suggestions were taken into account
from static source code analysis.

Markus Elfring (2):
  Delete an error message for a failed memory allocation in mtd_concat_create()
  Improve a size determination in concat_erase()

 drivers/mtd/mtdconcat.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

-- 
2.15.1



From elfring at users.sourceforge.net  Thu Jan  4 11:29:49 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 20:29:49 +0100
Subject: [PATCH 1/2] mtdconcat: Delete an error message for a failed memory
 allocation in mtd_concat_create()
In-Reply-To: <07947bdd-2b30-e4b5-82f7-d98b62df858e@users.sourceforge.net>
References: <07947bdd-2b30-e4b5-82f7-d98b62df858e@users.sourceforge.net>
Message-ID: <53f3fdb5-c216-c4b1-cb9f-c5945ec56749@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 19:55:10 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/mtdconcat.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 60bf53df5454..f1a60c55a126 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -668,12 +668,9 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],	/* subdevices to c
 	/* allocate the device structure */
 	size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
 	concat = kzalloc(size, GFP_KERNEL);
-	if (!concat) {
-		printk
-		    ("memory allocation error while creating concatenated device \"%s\"\n",
-		     name);
+	if (!concat)
 		return NULL;
-	}
+
 	concat->subdev = (struct mtd_info **) (concat + 1);
 
 	/*
-- 
2.15.1



From elfring at users.sourceforge.net  Thu Jan  4 11:30:49 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 20:30:49 +0100
Subject: [PATCH 2/2] mtdconcat: Improve a size determination in concat_erase()
In-Reply-To: <07947bdd-2b30-e4b5-82f7-d98b62df858e@users.sourceforge.net>
References: <07947bdd-2b30-e4b5-82f7-d98b62df858e@users.sourceforge.net>
Message-ID: <8a90314d-dead-5723-b8dd-b97a38eab9f2@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 20:00:27 +0100

Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/mtdconcat.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index f1a60c55a126..67d39e562c0f 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -428,8 +428,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 	}
 
 	/* make a local copy of instr to avoid modifying the caller's struct */
-	erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
-
+	erase = kmalloc(sizeof(*erase), GFP_KERNEL);
 	if (!erase)
 		return -ENOMEM;
 
-- 
2.15.1



From elfring at users.sourceforge.net  Thu Jan  4 12:24:12 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Thu, 4 Jan 2018 21:24:12 +0100
Subject: [PATCH] mtdoops: Delete an error message for a failed memory
 allocation in two functions
Message-ID: <c3d061ff-1f96-cee5-17ea-036eb80a3da4@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Thu, 4 Jan 2018 21:10:56 +0100

Omit an extra message for a memory allocation failure in these functions.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/mtdoops.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 97bb8f6304d4..ea8619ec970b 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -352,10 +352,8 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
 	/* oops_page_used is a bit field */
 	cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages,
 			BITS_PER_LONG) * sizeof(unsigned long));
-	if (!cxt->oops_page_used) {
-		printk(KERN_ERR "mtdoops: could not allocate page array\n");
+	if (!cxt->oops_page_used)
 		return;
-	}
 
 	cxt->dump.max_reason = KMSG_DUMP_OOPS;
 	cxt->dump.dump = mtdoops_do_dump;
@@ -420,10 +418,9 @@ static int __init mtdoops_init(void)
 		cxt->mtd_index = mtd_index;
 
 	cxt->oops_buf = vmalloc(record_size);
-	if (!cxt->oops_buf) {
-		printk(KERN_ERR "mtdoops: failed to allocate buffer workspace\n");
+	if (!cxt->oops_buf)
 		return -ENOMEM;
-	}
+
 	memset(cxt->oops_buf, 0xff, record_size);
 
 	INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase);
-- 
2.15.1



From prabhakar.kushwaha at nxp.com  Fri Jan  5 02:21:48 2018
From: prabhakar.kushwaha at nxp.com (Prabhakar Kushwaha)
Date: Fri, 5 Jan 2018 10:21:48 +0000
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180104184722.551ca6aa@bbrezillon>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
Message-ID: <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>

Thanks Boris for the encouragement. 

> -----Original Message-----
> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> Sent: Thursday, January 04, 2018 11:17 PM
> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>;
> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>; Brian
> Norris <computersforpeace at gmail.com>
> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> and NAND flash
> 
> +MTD maintainers.
> 
> On Thu, 4 Jan 2018 14:08:42 +0000
> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> 
> > Hi All,
> >
> > Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial
> NOR(Die #0) and Serial NAND(Die #1) flash.
> > Means both NOR, NAND flashes are placed in W25M161AW controlled by
> single chip-select.
> >
> > "Software Die Select (C2h)" command is being used to switch die or flash.
> 
> Why are they so mean to us?! :-)
> 
> >
> > It looks to be quite unique chip and wondering if any kind framework or work in
> progress available to handle it.
> > I know that SPI-NAND framework discussions is still in progress.
> 
> Well, nothing impossible to handle, we just need to declare 2 MTD
> devices (one NAND and one NOR). This being said, it looks like we'll
> need this spi-flash abstraction we have been talking about with Marek
> and Cyrille to properly support these use cases: flash devices will be
> exposed through different sub-layers (spi-nor or spi-nand), but we need
> a common way to detect those spi-flash chips. I looked at a few SPI
> NAND and SPI NOR chips, and from what I've seen so far they were quite
> different (the opcodes and CMD+ADDR+DATA sequences were quite
> different) so I thought we were safe to start with a completely
> unconnected SPI NAND framework and merge some bits in a spi-flash layer
> afterwards, but this chip proves me wrong :-/.

I am thinking of following changes with fsl_qspi.c as controller

&qspi {
	num-cs = <2>;
	bus-num = <0>;
	status = "okay";
	compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated compatibility for drivers
	qflash0: w25q16fw @0 {
		#address-cells = <1>;
		#size-cells = <1>;
		spi-max-frequency = <20000000>;
		reg = <0>;
		type = "serial-nor"   <-- Proposed New binding
		is-hybrid <-- Proposed New binding
		die-num <-- Proposed New binding
	};

	qflash1: w25n01gw at 1 {
		#address-cells = <1>;
		#size-cells = <1>;
		spi-max-frequency = <20000000>;
		reg = <1>;
		type = "serial-nand" <-- Proposed New binding
		is-hybrid <-- Proposed New binding
 		die-num <-- Proposed New binding
	}
};
};

struct spi_nor {
    --
    --
   u8 is_hybrid
   u8 select_die_opcode
   u8 die_num;
   --
   --
}

struct spinand_device {
    --
    --
   u8 is_hybrid
   u8 die_num;
}

struct spinand_manufacturer_ops {   <-- this will be populated in flash file like drivers/mtd/nand/spi/winbond.c
	int (*die_select)(struct spinand_device *spinand);
}  


fsl_qspi.c  <-- existing file to handle NOR
fsl_qspinandc <--  proposed file to handler NAND

fsl_qspi.c
	 probe() 
  		 for_each_available_child_of_node(dev->of_node, np)
       			- if type == "serial-nor"
 				spi_nor_scan()
     			 - if (is_hybrid)
				Set is_hybrid , select_die_opcode and die-num  field of struct spi_nor
fsl_qspinand.c
	 probe() 
  		 for_each_available_child_of_node(dev->of_node, np)
       			- if type == "serial-nand"
 				spinand_init()
     			 - if (is_hybrid)
				Set is_hybrid and die-num  field of struct spinand_device

Whenever read/write/erase come from MTD layer
  - if is_hybrid
	Change the die using select_die_opcode or die_select function pointer

--pk





From boris.brezillon at free-electrons.com  Fri Jan  5 05:35:06 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 5 Jan 2018 14:35:06 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
Message-ID: <20180105143506.0d1db1e8@bbrezillon>

+Peter and Frieder who are working on the SPI NAND aspects.

On Fri, 5 Jan 2018 10:21:48 +0000
Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:

> Thanks Boris for the encouragement. 
> 
> > -----Original Message-----
> > From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> > Sent: Thursday, January 04, 2018 11:17 PM
> > To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> > Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>;
> > Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>; Brian
> > Norris <computersforpeace at gmail.com>
> > Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> > and NAND flash
> > 
> > +MTD maintainers.
> > 
> > On Thu, 4 Jan 2018 14:08:42 +0000
> > Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> >   
> > > Hi All,
> > >
> > > Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial  
> > NOR(Die #0) and Serial NAND(Die #1) flash.  
> > > Means both NOR, NAND flashes are placed in W25M161AW controlled by  
> > single chip-select.  
> > >
> > > "Software Die Select (C2h)" command is being used to switch die or flash.  
> > 
> > Why are they so mean to us?! :-)
> >   
> > >
> > > It looks to be quite unique chip and wondering if any kind framework or work in  
> > progress available to handle it.  
> > > I know that SPI-NAND framework discussions is still in progress.  
> > 
> > Well, nothing impossible to handle, we just need to declare 2 MTD
> > devices (one NAND and one NOR). This being said, it looks like we'll
> > need this spi-flash abstraction we have been talking about with Marek
> > and Cyrille to properly support these use cases: flash devices will be
> > exposed through different sub-layers (spi-nor or spi-nand), but we need
> > a common way to detect those spi-flash chips. I looked at a few SPI
> > NAND and SPI NOR chips, and from what I've seen so far they were quite
> > different (the opcodes and CMD+ADDR+DATA sequences were quite
> > different) so I thought we were safe to start with a completely
> > unconnected SPI NAND framework and merge some bits in a spi-flash layer
> > afterwards, but this chip proves me wrong :-/.  
> 
> I am thinking of following changes with fsl_qspi.c as controller
> 
> &qspi {
> 	num-cs = <2>;
> 	bus-num = <0>;
> 	status = "okay";
> 	compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated compatibility for drivers

Nope, "fsl,ls1021a-qspi" should be enough. The fact that this
controller is able to control SPI NAND chips is just an internal detail
(actually, I hope all QSPI controllers are able to support both NOR and
NAND devices, but I wouldn't be surprised if some vendors hardcode the
set of commands they support in their controller :-/)

> 	qflash0: w25q16fw @0 {
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		spi-max-frequency = <20000000>;
> 		reg = <0>;
> 		type = "serial-nor"   <-- Proposed New binding

No, this should be placed in a compatible:

		compatible = "jedec,spi-nor";

> 		is-hybrid <-- Proposed New binding
> 		die-num <-- Proposed New binding
> 	};
> 
> 	qflash1: w25n01gw at 1 {
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		spi-max-frequency = <20000000>;
> 		reg = <1>;

This is wrong, the NAND and NOR dies use the same CS line.

> 		type = "serial-nand" <-- Proposed New binding
> 		is-hybrid <-- Proposed New binding
>  		die-num <-- Proposed New binding
> 	}
> };
> };

Not really the DT representation I had in mind. Let's try to keep
things as simple as possible. How about:

&qspi {
	/* compatible is unchanged and has been defined in a dtsi */
	/* same goes for #size-cells, #address-cells, ... */
 	status = "okay";

	qflash0: w25m161aw at 0 {
		/*
		 * Thanks to this compatible, the spi-flash logic will
		 * know that this chip is an hybrid flash exposing a
		 * NOR and a NAND, that the NOR is assigned id 0 an
		 * the NAND id 1.
		 */
		compatible = "winbond,w25m161aw";
		reg = <0>;
	};
};


> 
> struct spi_nor {
>     --
>     --
>    u8 is_hybrid
>    u8 select_die_opcode
>    u8 die_num;
>    --
>    --
> }
> 
> struct spinand_device {
>     --
>     --
>    u8 is_hybrid
>    u8 die_num;
> }
> 
> struct spinand_manufacturer_ops {   <-- this will be populated in flash file like drivers/mtd/nand/spi/winbond.c
> 	int (*die_select)(struct spinand_device *spinand);
> } 

Frieder is working on such a ->select_die() interface, but that's not
sufficient for this kind of hybrid chips. We need a lock to prevent
the spi-nor and spi-nand layer from stepping on each other's toes:
when an operation is done on the NAND die, the NOR layer should not
try to select the NOR die.
 
> 
> 
> fsl_qspi.c  <-- existing file to handle NOR
> fsl_qspinandc <--  proposed file to handler NAND

Hm, not sure this is a good idea. Let's keep one driver and add support
for NAND in there.

> 
> fsl_qspi.c
> 	 probe() 
>   		 for_each_available_child_of_node(dev->of_node, np)
>        			- if type == "serial-nor"

Should be based on the compatible.

>  				spi_nor_scan()
>      			 - if (is_hybrid)
> 				Set is_hybrid , select_die_opcode and die-num  field of struct spi_nor
> fsl_qspinand.c
> 	 probe() 
>   		 for_each_available_child_of_node(dev->of_node, np)
>        			- if type == "serial-nand"
>  				spinand_init()
>      			 - if (is_hybrid)
> 				Set is_hybrid and die-num  field of struct spinand_device

Hm, I really hate this situation. What we should be doing is declare a
qspi controller that embeds a SPI NOR and a SPI NAND controller and
then let the core register each chip, deciding which one is a NAND (and
should be attached to the NAND logic) and which one is a NOR (and
should be attached to the NOR logic).

> 
> Whenever read/write/erase come from MTD layer
>   - if is_hybrid
> 	Change the die using select_die_opcode or die_select function pointer


As said above, that's not enough: you need a lock to prevent concurrent
accesses from the NOR and NAND logic.

Regards,

Boris


From jonas.gorski at gmail.com  Fri Jan  5 05:38:48 2018
From: jonas.gorski at gmail.com (Jonas Gorski)
Date: Fri, 5 Jan 2018 14:38:48 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
Message-ID: <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>

On 5 January 2018 at 11:21, Prabhakar Kushwaha
<prabhakar.kushwaha at nxp.com> wrote:
> Thanks Boris for the encouragement.
>
>> -----Original Message-----
>> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
>> Sent: Thursday, January 04, 2018 11:17 PM
>> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
>> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>;
>> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>; Brian
>> Norris <computersforpeace at gmail.com>
>> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
>> and NAND flash
>>
>> +MTD maintainers.
>>
>> On Thu, 4 Jan 2018 14:08:42 +0000
>> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
>>
>> > Hi All,
>> >
>> > Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial
>> NOR(Die #0) and Serial NAND(Die #1) flash.
>> > Means both NOR, NAND flashes are placed in W25M161AW controlled by
>> single chip-select.
>> >
>> > "Software Die Select (C2h)" command is being used to switch die or flash.
>>
>> Why are they so mean to us?! :-)
>>
>> >
>> > It looks to be quite unique chip and wondering if any kind framework or work in
>> progress available to handle it.
>> > I know that SPI-NAND framework discussions is still in progress.
>>
>> Well, nothing impossible to handle, we just need to declare 2 MTD
>> devices (one NAND and one NOR). This being said, it looks like we'll
>> need this spi-flash abstraction we have been talking about with Marek
>> and Cyrille to properly support these use cases: flash devices will be
>> exposed through different sub-layers (spi-nor or spi-nand), but we need
>> a common way to detect those spi-flash chips. I looked at a few SPI
>> NAND and SPI NOR chips, and from what I've seen so far they were quite
>> different (the opcodes and CMD+ADDR+DATA sequences were quite
>> different) so I thought we were safe to start with a completely
>> unconnected SPI NAND framework and merge some bits in a spi-flash layer
>> afterwards, but this chip proves me wrong :-/.
>
> I am thinking of following changes with fsl_qspi.c as controller
>
> &qspi {
>         num-cs = <2>;
>         bus-num = <0>;
>         status = "okay";
>         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated compatibility for drivers
>         qflash0: w25q16fw @0 {
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 spi-max-frequency = <20000000>;
>                 reg = <0>;
>                 type = "serial-nor"   <-- Proposed New binding
>                 is-hybrid <-- Proposed New binding
>                 die-num <-- Proposed New binding
>         };
>
>         qflash1: w25n01gw at 1 {
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 spi-max-frequency = <20000000>;
>                 reg = <1>;
>                 type = "serial-nand" <-- Proposed New binding
>                 is-hybrid <-- Proposed New binding
>                 die-num <-- Proposed New binding
>         }
> };

assuming the NOR and NAND parts behave like "normal" SPI-NOR /
SPI-NAND chips when selected, a more appropriate binding might be

&qspi {
    ...
        qflash0: dual-flash at 0 {
                compatible = "winbond,w25q16fw";
                reg = <0>;
                spi-max-frequency = <20000000>;
                #address-cells = <1>;
                #size-cells = <0>;

                nor at 0 {
                                compatible = "jedec,spi-nor";
                                reg = <0>;
                                #address-cells = <1>;
                                #size-cells = <1>;

                                partitions {
                                                ...
                                };
                };

                nand at 1 {
                                compatible = "jedec,spi-nand"; /* or
whatever the correct nand-compatible would be */
                                reg = <1>;
                                #address-cells = <1>;
                                #size-cells = <1>;

                                partitions {
                                                ...
                                };
                };

    };
};

with the "windbond,w25q16fw" driver modeled as a simple
"spi-multiplexer" that registers its own virtual spi-bus. Then when
spi-nor or spi-nand tries to communicate with their appropriate die,
it sends the Software Die Select command if needed and then passes on
the message to its parent bus.

That way there should be no changes needed for spi-nor / spi-nand
themselves. (The devil is probably in the details ;-)


Regards
Jonas


From boris.brezillon at free-electrons.com  Fri Jan  5 05:44:44 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 5 Jan 2018 14:44:44 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
Message-ID: <20180105144444.338c2cdc@bbrezillon>

On Fri, 5 Jan 2018 14:38:48 +0100
Jonas Gorski <jonas.gorski at gmail.com> wrote:

> On 5 January 2018 at 11:21, Prabhakar Kushwaha
> <prabhakar.kushwaha at nxp.com> wrote:
> > Thanks Boris for the encouragement.
> >  
> >> -----Original Message-----
> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> >> Sent: Thursday, January 04, 2018 11:17 PM
> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>;
> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>; Brian
> >> Norris <computersforpeace at gmail.com>
> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> >> and NAND flash
> >>
> >> +MTD maintainers.
> >>
> >> On Thu, 4 Jan 2018 14:08:42 +0000
> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> >>  
> >> > Hi All,
> >> >
> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial  
> >> NOR(Die #0) and Serial NAND(Die #1) flash.  
> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled by  
> >> single chip-select.  
> >> >
> >> > "Software Die Select (C2h)" command is being used to switch die or flash.  
> >>
> >> Why are they so mean to us?! :-)
> >>  
> >> >
> >> > It looks to be quite unique chip and wondering if any kind framework or work in  
> >> progress available to handle it.  
> >> > I know that SPI-NAND framework discussions is still in progress.  
> >>
> >> Well, nothing impossible to handle, we just need to declare 2 MTD
> >> devices (one NAND and one NOR). This being said, it looks like we'll
> >> need this spi-flash abstraction we have been talking about with Marek
> >> and Cyrille to properly support these use cases: flash devices will be
> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
> >> a common way to detect those spi-flash chips. I looked at a few SPI
> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
> >> different) so I thought we were safe to start with a completely
> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
> >> afterwards, but this chip proves me wrong :-/.  
> >
> > I am thinking of following changes with fsl_qspi.c as controller
> >
> > &qspi {
> >         num-cs = <2>;
> >         bus-num = <0>;
> >         status = "okay";
> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated compatibility for drivers
> >         qflash0: w25q16fw @0 {
> >                 #address-cells = <1>;
> >                 #size-cells = <1>;
> >                 spi-max-frequency = <20000000>;
> >                 reg = <0>;
> >                 type = "serial-nor"   <-- Proposed New binding
> >                 is-hybrid <-- Proposed New binding
> >                 die-num <-- Proposed New binding
> >         };
> >
> >         qflash1: w25n01gw at 1 {
> >                 #address-cells = <1>;
> >                 #size-cells = <1>;
> >                 spi-max-frequency = <20000000>;
> >                 reg = <1>;
> >                 type = "serial-nand" <-- Proposed New binding
> >                 is-hybrid <-- Proposed New binding
> >                 die-num <-- Proposed New binding
> >         }
> > };  
> 
> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
> SPI-NAND chips when selected, a more appropriate binding might be
> 
> &qspi {
>     ...
>         qflash0: dual-flash at 0 {
>                 compatible = "winbond,w25q16fw";
>                 reg = <0>;
>                 spi-max-frequency = <20000000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> 
>                 nor at 0 {
>                                 compatible = "jedec,spi-nor";
>                                 reg = <0>;
>                                 #address-cells = <1>;
>                                 #size-cells = <1>;
> 
>                                 partitions {
>                                                 ...
>                                 };
>                 };
> 
>                 nand at 1 {
>                                 compatible = "jedec,spi-nand"; /* or
> whatever the correct nand-compatible would be */
>                                 reg = <1>;
>                                 #address-cells = <1>;
>                                 #size-cells = <1>;
> 
>                                 partitions {
>                                                 ...
>                                 };
>                 };
> 
>     };
> };
> 
> with the "windbond,w25q16fw" driver modeled as a simple
> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> spi-nor or spi-nand tries to communicate with their appropriate die,
> it sends the Software Die Select command if needed and then passes on
> the message to its parent bus.
> 
> That way there should be no changes needed for spi-nor / spi-nand
> themselves. (The devil is probably in the details ;-)

Yep, I thought about this approach, and it's indeed quite elegant, but
we're missing the lock I was mentioning in my previous reply. We need
to prevent die selection not only for the time we're sending a single
SPI message, but for the whole operation (which can be formed of
several SPI messages). Or maybe I'm wrong, and operations can actually
be interleaved, but I wouldn't bet on that ;-).

> 
> 
> Regards
> Jonas



From jonas.gorski at gmail.com  Fri Jan  5 05:58:25 2018
From: jonas.gorski at gmail.com (Jonas Gorski)
Date: Fri, 5 Jan 2018 14:58:25 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180105144444.338c2cdc@bbrezillon>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
 <20180105144444.338c2cdc@bbrezillon>
Message-ID: <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>

On 5 January 2018 at 14:44, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Fri, 5 Jan 2018 14:38:48 +0100
> Jonas Gorski <jonas.gorski at gmail.com> wrote:
>
>> On 5 January 2018 at 11:21, Prabhakar Kushwaha
>> <prabhakar.kushwaha at nxp.com> wrote:
>> > Thanks Boris for the encouragement.
>> >
>> >> -----Original Message-----
>> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
>> >> Sent: Thursday, January 04, 2018 11:17 PM
>> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
>> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>;
>> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>; Brian
>> >> Norris <computersforpeace at gmail.com>
>> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
>> >> and NAND flash
>> >>
>> >> +MTD maintainers.
>> >>
>> >> On Thu, 4 Jan 2018 14:08:42 +0000
>> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
>> >>
>> >> > Hi All,
>> >> >
>> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of Serial
>> >> NOR(Die #0) and Serial NAND(Die #1) flash.
>> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled by
>> >> single chip-select.
>> >> >
>> >> > "Software Die Select (C2h)" command is being used to switch die or flash.
>> >>
>> >> Why are they so mean to us?! :-)
>> >>
>> >> >
>> >> > It looks to be quite unique chip and wondering if any kind framework or work in
>> >> progress available to handle it.
>> >> > I know that SPI-NAND framework discussions is still in progress.
>> >>
>> >> Well, nothing impossible to handle, we just need to declare 2 MTD
>> >> devices (one NAND and one NOR). This being said, it looks like we'll
>> >> need this spi-flash abstraction we have been talking about with Marek
>> >> and Cyrille to properly support these use cases: flash devices will be
>> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
>> >> a common way to detect those spi-flash chips. I looked at a few SPI
>> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
>> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
>> >> different) so I thought we were safe to start with a completely
>> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
>> >> afterwards, but this chip proves me wrong :-/.
>> >
>> > I am thinking of following changes with fsl_qspi.c as controller
>> >
>> > &qspi {
>> >         num-cs = <2>;
>> >         bus-num = <0>;
>> >         status = "okay";
>> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated compatibility for drivers
>> >         qflash0: w25q16fw @0 {
>> >                 #address-cells = <1>;
>> >                 #size-cells = <1>;
>> >                 spi-max-frequency = <20000000>;
>> >                 reg = <0>;
>> >                 type = "serial-nor"   <-- Proposed New binding
>> >                 is-hybrid <-- Proposed New binding
>> >                 die-num <-- Proposed New binding
>> >         };
>> >
>> >         qflash1: w25n01gw at 1 {
>> >                 #address-cells = <1>;
>> >                 #size-cells = <1>;
>> >                 spi-max-frequency = <20000000>;
>> >                 reg = <1>;
>> >                 type = "serial-nand" <-- Proposed New binding
>> >                 is-hybrid <-- Proposed New binding
>> >                 die-num <-- Proposed New binding
>> >         }
>> > };
>>
>> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
>> SPI-NAND chips when selected, a more appropriate binding might be
>>
>> &qspi {
>>     ...
>>         qflash0: dual-flash at 0 {
>>                 compatible = "winbond,w25q16fw";
>>                 reg = <0>;
>>                 spi-max-frequency = <20000000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>>
>>                 nor at 0 {
>>                                 compatible = "jedec,spi-nor";
>>                                 reg = <0>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>>
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
>>
>>                 nand at 1 {
>>                                 compatible = "jedec,spi-nand"; /* or
>> whatever the correct nand-compatible would be */
>>                                 reg = <1>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>>
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
>>
>>     };
>> };
>>
>> with the "windbond,w25q16fw" driver modeled as a simple
>> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>> spi-nor or spi-nand tries to communicate with their appropriate die,
>> it sends the Software Die Select command if needed and then passes on
>> the message to its parent bus.
>>
>> That way there should be no changes needed for spi-nor / spi-nand
>> themselves. (The devil is probably in the details ;-)
>
> Yep, I thought about this approach, and it's indeed quite elegant, but
> we're missing the lock I was mentioning in my previous reply. We need
> to prevent die selection not only for the time we're sending a single
> SPI message, but for the whole operation (which can be formed of
> several SPI messages). Or maybe I'm wrong, and operations can actually
> be interleaved, but I wouldn't bet on that ;-).

Ah, I missed that. I thought about it, and then tried to hand wave it
away with the "if they behave like normal chips" ;-)

The mdio-bus supports nested locking, so you can do something like this:

mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
bus->write();
bus->read();
mutex_unlock(bus->mdio_lock);

without worrying someone else using the bus in between. [1] for an example user.

So going a similar approach with flagging the appropriate chips in
spi-nor/spi-nand as needing nested locking and then doing it for the
appropriate commands should solve that issue.


Regards
Jonas

[1] http://elixir.free-electrons.com/linux/v4.15-rc6/source/drivers/net/dsa/qca8k.c#L148


From boris.brezillon at free-electrons.com  Fri Jan  5 07:13:21 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 5 Jan 2018 16:13:21 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <20171222172853.27710-2-miquel.raynal@free-electrons.com>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
Message-ID: <20180105161321.44218e4e@bbrezillon>

On Fri, 22 Dec 2017 18:28:52 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Choosing ONFI timings when ->onfi_set/get_features() calls are supported
> by the NAND chip is a matter of reading the chip's ONFI parameter page
> and telling the chip the chosen mode (between all of the supported ones)
> with ->onfi_set_feature().
> 
> Add a check on whether the chip "acked" the timing mode or not.
> 
> This can be a problem for NAND chips that do not follow entirely the
> ONFI specification. These chips actually support other modes than
> "mode 0", but do not update the parameter page once a timing mode has
> been selected. This issue will be addressed in another patch that will
> add the feature to overwrite NAND chips features within the parameter
> page, from the NAND chip driver.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/nand_base.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 96c97588e1ba..ea862be6a803 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -1236,6 +1236,18 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
>  				tmode_param);
>  		if (ret)
>  			goto err;
> +
> +		ret = chip->onfi_get_features(mtd, chip,
> +					      ONFI_FEATURE_ADDR_TIMING_MODE,
> +					      tmode_param);
> +		if (ret)
> +			goto err;
> +
> +		if (tmode_param[0] != chip->onfi_timing_mode_default) {
> +			pr_warn("timings mode %d not acknowledged by the NAND chip\n",
> +				chip->onfi_timing_mode_default);
> +			goto err;
> +		}

Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
is applied as soon the CS line is released after a
SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
guarantee that the CS will be kept low by the controller after
->onfi_set_features() returns we must assume the new mode has been
applied and call ->setup_data_interface() to instruct the controller
to apply new timings.

If you want to check if the mode has really been applied, you should
release the CS (->select_chip(-1)), re-acquire it
(->select_chip(X)), and call
->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears that
the mode has not been applied, you should restore timing mode 0 and
issue a RESET.

>  	}
>  
>  	ret = chip->setup_data_interface(mtd, chipnr, &chip->data_interface);



From miquel.raynal at free-electrons.com  Fri Jan  5 07:42:39 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Fri, 5 Jan 2018 16:42:39 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <20180105161321.44218e4e@bbrezillon>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>
Message-ID: <20180105164239.79d7980c@xps13>

Hello,

> Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
> is applied as soon the CS line is released after a
> SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
> guarantee that the CS will be kept low by the controller after
> ->onfi_set_features() returns we must assume the new mode has been  
> applied and call ->setup_data_interface() to instruct the controller
> to apply new timings.
> 
> If you want to check if the mode has really been applied, you should
> release the CS (->select_chip(-1)), re-acquire it
> (->select_chip(X)), and call
> ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears
> that the mode has not been applied, you should restore timing mode 0
> and issue a RESET.

Boris, thanks for the comment, I will fix that.

Han, could I have your input on this series? Aside Boris' comment of
course.

Thank you very much,
Miqu?l


From ebiggers3 at gmail.com  Fri Jan  5 10:37:44 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri, 5 Jan 2018 10:37:44 -0800
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <20171129204317.91205-1-ebiggers3@gmail.com>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
Message-ID: <20180105183744.GA44929@gmail.com>

On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> This series switches ubifs to use the fscrypt helper functions for
> open/link/rename/lookup/setattr introduced in v4.15.
> 
> These patches were originally sent in "[PATCH 00/25] fscrypt: add some
> higher-level helper functions".  I've rebased them onto v4.15-rc1.
> 
> Eric Biggers (5):
>   ubifs: switch to fscrypt_file_open()
>   ubifs: switch to fscrypt_prepare_link()
>   ubifs: switch to fscrypt_prepare_rename()
>   ubifs: switch to fscrypt_prepare_lookup()
>   ubifs: switch to fscrypt_prepare_setattr()
> 
>  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
>  fs/ubifs/file.c | 41 ++++-------------------------------------
>  2 files changed, 17 insertions(+), 67 deletions(-)
> 
> -- 
> 2.15.0.531.g2ccb3012c9-goog
> 

Richard, can you take these for UBIFS for v4.16?

Eric


From ebiggers3 at gmail.com  Fri Jan  5 10:44:51 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:51 -0800
Subject: [PATCH v2 00/11] fscrypt: symlink helpers and fscrypt.h cleanup
Message-ID: <20180105184502.48473-1-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

This series introduces helper functions in fscrypt that filesystems can
call to simplify handling of encrypted symlinks.  The helpers also fix a
couple subtle bugs, such as incorrectly rejecting symlinks that are very
close to the maximum length, and accidentally leaving the "." and ".."
symlink targets unencrypted (they need to be special in directory
entries, but not in symlink targets).

Patches 1-9 are mostly cleanup to trim down fscrypt.h, moving stuff into
more appropriate places depending on whether it is needed only
internally by fscrypt, or only by filesystems supporting encryption,
etc.  I was going to send these out as a separate series, but there is a
dependency because the symlink helpers depend on
fscrypt_dummy_context_enabled() having been fixed to work correctly in
the "notsupp" case.

Patch 10 introduces the helpers for ->symlink() and patch 11 introduces
a helper for ->get_link().

The patches to switch ext4, f2fs, and ubifs over to use the helper
functions were included in v1 of this patchset
(https://marc.info/?l=linux-ext4&m=151336000031869).  They are not
included now since I'm planning to get them picked up by the individual
filesystem maintainers after this goes in.

Changed since v1:

    - Fixed __fscrypt_prepare_symlink() to work correctly with
      test_dummy_encryption mode in the case where the directory is
      unencrypted and has not yet had its ->i_crypt_info set up.

Eric Biggers (11):
  fscrypt: move fscrypt_has_encryption_key() to supp/notsupp headers
  fscrypt: move fscrypt_control_page() to supp/notsupp headers
  fscrypt: move fscrypt_info_cachep declaration to fscrypt_private.h
  fscrypt: move fscrypt_ctx declaration to fscrypt_supp.h
  fscrypt: split fscrypt_dummy_context_enabled() into supp/notsupp
    versions
  fscrypt: move fscrypt_operations declaration to fscrypt_supp.h
  fscrypt: move fscrypt_valid_enc_modes() to fscrypt_private.h
  fscrypt: move fscrypt_is_dot_dotdot() to fs/crypto/fname.c
  fscrypt: trim down fscrypt.h includes
  fscrypt: new helper functions for ->symlink()
  fscrypt: new helper function - fscrypt_get_symlink()

 fs/crypto/crypto.c              |   1 +
 fs/crypto/fname.c               |  20 ++++-
 fs/crypto/fscrypt_private.h     |  19 +++++
 fs/crypto/hooks.c               | 163 +++++++++++++++++++++++++++++++++++++++
 fs/crypto/keyinfo.c             |   1 +
 include/linux/fscrypt.h         | 165 ++++++++++++++++------------------------
 include/linux/fscrypt_notsupp.h |  39 ++++++++++
 include/linux/fscrypt_supp.h    |  63 ++++++++++++++-
 8 files changed, 369 insertions(+), 102 deletions(-)

-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:58 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:58 -0800
Subject: [PATCH v2 07/11] fscrypt: move fscrypt_valid_enc_modes() to
 fscrypt_private.h
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-8-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

The encryption modes are validated by fs/crypto/, not by individual
filesystems.  Therefore, move fscrypt_valid_enc_modes() from fscrypt.h
to fscrypt_private.h.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/fscrypt_private.h | 14 ++++++++++++++
 include/linux/fscrypt.h     | 14 --------------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 823c43a00bf7..2b848e7c92f0 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -71,6 +71,20 @@ typedef enum {
 #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL		0x00000001
 #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
 
+static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
+					   u32 filenames_mode)
+{
+	if (contents_mode == FS_ENCRYPTION_MODE_AES_128_CBC &&
+	    filenames_mode == FS_ENCRYPTION_MODE_AES_128_CTS)
+		return true;
+
+	if (contents_mode == FS_ENCRYPTION_MODE_AES_256_XTS &&
+	    filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
+		return true;
+
+	return false;
+}
+
 /* crypto.c */
 extern struct kmem_cache *fscrypt_info_cachep;
 extern int fscrypt_initialize(unsigned int cop_flags);
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 33b95a91f720..2e4dce0365cf 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -57,20 +57,6 @@ struct fscrypt_name {
 /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
 #define FSCRYPT_SET_CONTEXT_MAX_SIZE	28
 
-static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
-					u32 filenames_mode)
-{
-	if (contents_mode == FS_ENCRYPTION_MODE_AES_128_CBC &&
-	    filenames_mode == FS_ENCRYPTION_MODE_AES_128_CTS)
-		return true;
-
-	if (contents_mode == FS_ENCRYPTION_MODE_AES_256_XTS &&
-	    filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
-		return true;
-
-	return false;
-}
-
 static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
 {
 	if (str->len == 1 && str->name[0] == '.')
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:52 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:52 -0800
Subject: [PATCH v2 01/11] fscrypt: move fscrypt_has_encryption_key() to
 supp/notsupp headers
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-2-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

fscrypt_has_encryption_key() is already split into two versions
depending on whether the filesystem is being built with encryption
support or not.  Move them into the appropriate headers.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/fscrypt.h         | 10 ----------
 include/linux/fscrypt_notsupp.h |  5 +++++
 include/linux/fscrypt_supp.h    |  5 +++++
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 08b4b40c5aa8..d1c891b5bd9c 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -129,11 +129,6 @@ static inline struct page *fscrypt_control_page(struct page *page)
 	return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
 }
 
-static inline bool fscrypt_has_encryption_key(const struct inode *inode)
-{
-	return (inode->i_crypt_info != NULL);
-}
-
 #include <linux/fscrypt_supp.h>
 
 #else /* !__FS_HAS_ENCRYPTION */
@@ -144,11 +139,6 @@ static inline struct page *fscrypt_control_page(struct page *page)
 	return ERR_PTR(-EINVAL);
 }
 
-static inline bool fscrypt_has_encryption_key(const struct inode *inode)
-{
-	return 0;
-}
-
 #include <linux/fscrypt_notsupp.h>
 #endif /* __FS_HAS_ENCRYPTION */
 
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 63e58808519a..52e330285457 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -14,6 +14,11 @@
 #ifndef _LINUX_FSCRYPT_NOTSUPP_H
 #define _LINUX_FSCRYPT_NOTSUPP_H
 
+static inline bool fscrypt_has_encryption_key(const struct inode *inode)
+{
+	return false;
+}
+
 /* crypto.c */
 static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
 						  gfp_t gfp_flags)
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index cf9e9fc02f0a..79bb8beae018 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -11,6 +11,11 @@
 #ifndef _LINUX_FSCRYPT_SUPP_H
 #define _LINUX_FSCRYPT_SUPP_H
 
+static inline bool fscrypt_has_encryption_key(const struct inode *inode)
+{
+	return (inode->i_crypt_info != NULL);
+}
+
 /* crypto.c */
 extern struct kmem_cache *fscrypt_info_cachep;
 extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:54 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:54 -0800
Subject: [PATCH v2 03/11] fscrypt: move fscrypt_info_cachep declaration to
 fscrypt_private.h
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-4-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

The fscrypt_info kmem_cache is internal to fscrypt; filesystems don't
need to access it.  So move its declaration into fscrypt_private.h.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/fscrypt_private.h  | 1 +
 include/linux/fscrypt_supp.h | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index c0b4f5597e1a..823c43a00bf7 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -72,6 +72,7 @@ typedef enum {
 #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
 
 /* crypto.c */
+extern struct kmem_cache *fscrypt_info_cachep;
 extern int fscrypt_initialize(unsigned int cop_flags);
 extern struct workqueue_struct *fscrypt_read_workqueue;
 extern int fscrypt_do_page_crypto(const struct inode *inode,
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index ad40780d4653..33d641e27c18 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -17,7 +17,6 @@ static inline bool fscrypt_has_encryption_key(const struct inode *inode)
 }
 
 /* crypto.c */
-extern struct kmem_cache *fscrypt_info_cachep;
 extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
 extern void fscrypt_release_ctx(struct fscrypt_ctx *);
 extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:57 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:57 -0800
Subject: [PATCH v2 06/11] fscrypt: move fscrypt_operations declaration to
 fscrypt_supp.h
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-7-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

Filesystems now only define their fscrypt_operations when they are
compiled with encryption support, so move the fscrypt_operations
declaration from fscrypt.h to fscrypt_supp.h.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/fscrypt.h      | 18 ------------------
 include/linux/fscrypt_supp.h | 18 ++++++++++++++++++
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index b671a4eef47f..33b95a91f720 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -54,24 +54,6 @@ struct fscrypt_name {
 #define fname_name(p)		((p)->disk_name.name)
 #define fname_len(p)		((p)->disk_name.len)
 
-/*
- * fscrypt superblock flags
- */
-#define FS_CFLG_OWN_PAGES (1U << 1)
-
-/*
- * crypto opertions for filesystems
- */
-struct fscrypt_operations {
-	unsigned int flags;
-	const char *key_prefix;
-	int (*get_context)(struct inode *, void *, size_t);
-	int (*set_context)(struct inode *, const void *, size_t, void *);
-	bool (*dummy_context)(struct inode *);
-	bool (*empty_dir)(struct inode *);
-	unsigned (*max_namelen)(struct inode *);
-};
-
 /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
 #define FSCRYPT_SET_CONTEXT_MAX_SIZE	28
 
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index e7dfa2974906..ce61caf26f40 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -11,6 +11,24 @@
 #ifndef _LINUX_FSCRYPT_SUPP_H
 #define _LINUX_FSCRYPT_SUPP_H
 
+/*
+ * fscrypt superblock flags
+ */
+#define FS_CFLG_OWN_PAGES (1U << 1)
+
+/*
+ * crypto operations for filesystems
+ */
+struct fscrypt_operations {
+	unsigned int flags;
+	const char *key_prefix;
+	int (*get_context)(struct inode *, void *, size_t);
+	int (*set_context)(struct inode *, const void *, size_t, void *);
+	bool (*dummy_context)(struct inode *);
+	bool (*empty_dir)(struct inode *);
+	unsigned (*max_namelen)(struct inode *);
+};
+
 struct fscrypt_ctx {
 	union {
 		struct {
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:53 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:53 -0800
Subject: [PATCH v2 02/11] fscrypt: move fscrypt_control_page() to supp/notsupp
 headers
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-3-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

fscrypt_control_page() is already split into two versions depending on
whether the filesystem is being built with encryption support or not.
Move them into the appropriate headers.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/fscrypt.h         | 18 ++----------------
 include/linux/fscrypt_notsupp.h |  5 +++++
 include/linux/fscrypt_supp.h    |  6 ++++++
 3 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index d1c891b5bd9c..c23b2f16129a 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -123,24 +123,10 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
 }
 
 #if __FS_HAS_ENCRYPTION
-
-static inline struct page *fscrypt_control_page(struct page *page)
-{
-	return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
-}
-
 #include <linux/fscrypt_supp.h>
-
-#else /* !__FS_HAS_ENCRYPTION */
-
-static inline struct page *fscrypt_control_page(struct page *page)
-{
-	WARN_ON_ONCE(1);
-	return ERR_PTR(-EINVAL);
-}
-
+#else
 #include <linux/fscrypt_notsupp.h>
-#endif /* __FS_HAS_ENCRYPTION */
+#endif
 
 /**
  * fscrypt_require_key - require an inode's encryption key
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 52e330285457..812dc701a5b3 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -48,6 +48,11 @@ static inline int fscrypt_decrypt_page(const struct inode *inode,
 	return -EOPNOTSUPP;
 }
 
+static inline struct page *fscrypt_control_page(struct page *page)
+{
+	WARN_ON_ONCE(1);
+	return ERR_PTR(-EINVAL);
+}
 
 static inline void fscrypt_restore_control_page(struct page *page)
 {
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 79bb8beae018..ad40780d4653 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -25,6 +25,12 @@ extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
 						u64, gfp_t);
 extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
 				unsigned int, u64);
+
+static inline struct page *fscrypt_control_page(struct page *page)
+{
+	return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
+}
+
 extern void fscrypt_restore_control_page(struct page *);
 
 extern const struct dentry_operations fscrypt_d_ops;
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:45:01 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:45:01 -0800
Subject: [PATCH v2 10/11] fscrypt: new helper functions for ->symlink()
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-11-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

Currently, filesystems supporting fscrypt need to implement some tricky
logic when creating encrypted symlinks, including handling a peculiar
on-disk format (struct fscrypt_symlink_data) and correctly calculating
the size of the encrypted symlink.  Introduce helper functions to make
things a bit easier:

- fscrypt_prepare_symlink() computes and validates the size the symlink
  target will require on-disk.
- fscrypt_encrypt_symlink() creates the encrypted target if needed.

The new helpers actually fix some subtle bugs.  First, when checking
whether the symlink target was too long, filesystems didn't account for
the fact that the NUL padding is meant to be truncated if it would cause
the maximum length to be exceeded, as is done for filenames in
directories.  Consequently users would receive ENAMETOOLONG when
creating symlinks close to what is supposed to be the maximum length.
For example, with EXT4 with a 4K block size, the maximum symlink target
length in an encrypted directory is supposed to be 4093 bytes (in
comparison to 4095 in an unencrypted directory), but in
FS_POLICY_FLAGS_PAD_32-mode only up to 4064 bytes were accepted.

Second, symlink targets of "." and ".." were not being encrypted, even
though they should be, as these names are special in *directory entries*
but not in symlink targets.  Fortunately, we can fix this simply by
starting to encrypt them, as old kernels already accept them in
encrypted form.

Third, the output string length the filesystems were providing when
doing the actual encryption was incorrect, as it was forgotten to
exclude 'sizeof(struct fscrypt_symlink_data)'.  Fortunately though, this
bug didn't make a difference.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/fname.c               |  8 ++--
 fs/crypto/fscrypt_private.h     |  4 ++
 fs/crypto/hooks.c               | 90 +++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt.h         | 64 +++++++++++++++++++++++++++++
 include/linux/fscrypt_notsupp.h | 16 ++++++++
 include/linux/fscrypt_supp.h    |  6 +++
 6 files changed, 185 insertions(+), 3 deletions(-)

diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 52d4dbe1e8e7..62f13d533439 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -34,8 +34,8 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
  *
  * Return: 0 on success, -errno on failure
  */
-static int fname_encrypt(struct inode *inode,
-			const struct qstr *iname, struct fscrypt_str *oname)
+int fname_encrypt(struct inode *inode,
+		  const struct qstr *iname, struct fscrypt_str *oname)
 {
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
@@ -56,9 +56,11 @@ static int fname_encrypt(struct inode *inode,
 	 * Copy the filename to the output buffer for encrypting in-place and
 	 * pad it with the needed number of NUL bytes.
 	 */
+	if (WARN_ON(oname->len < iname->len))
+		return -ENOBUFS;
 	cryptlen = max_t(unsigned int, iname->len, FS_CRYPTO_BLOCK_SIZE);
 	cryptlen = round_up(cryptlen, padding);
-	cryptlen = min(cryptlen, lim);
+	cryptlen = min3(cryptlen, lim, oname->len);
 	memcpy(oname->name, iname->name, iname->len);
 	memset(oname->name + iname->len, 0, cryptlen - iname->len);
 
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 2b848e7c92f0..6995bca5006b 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -98,6 +98,10 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
 extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
 					      gfp_t gfp_flags);
 
+/* fname.c */
+extern int fname_encrypt(struct inode *inode,
+			 const struct qstr *iname, struct fscrypt_str *oname);
+
 /* keyinfo.c */
 extern void __exit fscrypt_essiv_cleanup(void);
 
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 9f5fb2eb9cf7..4b83e4af2e41 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -110,3 +110,93 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup);
+
+int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
+			      unsigned int max_len,
+			      struct fscrypt_str *disk_link)
+{
+	int err;
+
+	/*
+	 * To calculate the size of the encrypted symlink target we need to know
+	 * the amount of NUL padding, which is determined by the flags set in
+	 * the encryption policy which will be inherited from the directory.
+	 * The easiest way to get access to this is to just load the directory's
+	 * fscrypt_info, since we'll need it to create the dir_entry anyway.
+	 *
+	 * Note: in test_dummy_encryption mode, @dir may be unencrypted.
+	 */
+	err = fscrypt_get_encryption_info(dir);
+	if (err)
+		return err;
+	if (!fscrypt_has_encryption_key(dir))
+		return -ENOKEY;
+
+	/*
+	 * Calculate the size of the encrypted symlink and verify it won't
+	 * exceed max_len.  Note that for historical reasons, encrypted symlink
+	 * targets are prefixed with the ciphertext length, despite this
+	 * actually being redundant with i_size.  This decreases by 2 bytes the
+	 * longest symlink target we can accept.
+	 *
+	 * We could recover 1 byte by not counting a null terminator, but
+	 * counting it (even though it is meaningless for ciphertext) is simpler
+	 * for now since filesystems will assume it is there and subtract it.
+	 */
+	if (sizeof(struct fscrypt_symlink_data) + len > max_len)
+		return -ENAMETOOLONG;
+	disk_link->len = min_t(unsigned int,
+			       sizeof(struct fscrypt_symlink_data) +
+					fscrypt_fname_encrypted_size(dir, len),
+			       max_len);
+	disk_link->name = NULL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__fscrypt_prepare_symlink);
+
+int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
+			      unsigned int len, struct fscrypt_str *disk_link)
+{
+	int err;
+	struct qstr iname = { .name = target, .len = len };
+	struct fscrypt_symlink_data *sd;
+	unsigned int ciphertext_len;
+	struct fscrypt_str oname;
+
+	err = fscrypt_require_key(inode);
+	if (err)
+		return err;
+
+	if (disk_link->name) {
+		/* filesystem-provided buffer */
+		sd = (struct fscrypt_symlink_data *)disk_link->name;
+	} else {
+		sd = kmalloc(disk_link->len, GFP_NOFS);
+		if (!sd)
+			return -ENOMEM;
+	}
+	ciphertext_len = disk_link->len - sizeof(*sd);
+	sd->len = cpu_to_le16(ciphertext_len);
+
+	oname.name = sd->encrypted_path;
+	oname.len = ciphertext_len;
+	err = fname_encrypt(inode, &iname, &oname);
+	if (err) {
+		if (!disk_link->name)
+			kfree(sd);
+		return err;
+	}
+	BUG_ON(oname.len != ciphertext_len);
+
+	/*
+	 * Null-terminating the ciphertext doesn't make sense, but we still
+	 * count the null terminator in the length, so we might as well
+	 * initialize it just in case the filesystem writes it out.
+	 */
+	sd->encrypted_path[ciphertext_len] = '\0';
+
+	if (!disk_link->name)
+		disk_link->name = (unsigned char *)sd;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__fscrypt_encrypt_symlink);
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 071ebabfc287..6a678d0e956a 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -196,4 +196,68 @@ static inline int fscrypt_prepare_setattr(struct dentry *dentry,
 	return 0;
 }
 
+/**
+ * fscrypt_prepare_symlink - prepare to create a possibly-encrypted symlink
+ * @dir: directory in which the symlink is being created
+ * @target: plaintext symlink target
+ * @len: length of @target excluding null terminator
+ * @max_len: space the filesystem has available to store the symlink target
+ * @disk_link: (out) the on-disk symlink target being prepared
+ *
+ * This function computes the size the symlink target will require on-disk,
+ * stores it in @disk_link->len, and validates it against @max_len.  An
+ * encrypted symlink may be longer than the original.
+ *
+ * Additionally, @disk_link->name is set to @target if the symlink will be
+ * unencrypted, but left NULL if the symlink will be encrypted.  For encrypted
+ * symlinks, the filesystem must call fscrypt_encrypt_symlink() to create the
+ * on-disk target later.  (The reason for the two-step process is that some
+ * filesystems need to know the size of the symlink target before creating the
+ * inode, e.g. to determine whether it will be a "fast" or "slow" symlink.)
+ *
+ * Return: 0 on success, -ENAMETOOLONG if the symlink target is too long,
+ * -ENOKEY if the encryption key is missing, or another -errno code if a problem
+ * occurred while setting up the encryption key.
+ */
+static inline int fscrypt_prepare_symlink(struct inode *dir,
+					  const char *target,
+					  unsigned int len,
+					  unsigned int max_len,
+					  struct fscrypt_str *disk_link)
+{
+	if (IS_ENCRYPTED(dir) || fscrypt_dummy_context_enabled(dir))
+		return __fscrypt_prepare_symlink(dir, len, max_len, disk_link);
+
+	disk_link->name = (unsigned char *)target;
+	disk_link->len = len + 1;
+	if (disk_link->len > max_len)
+		return -ENAMETOOLONG;
+	return 0;
+}
+
+/**
+ * fscrypt_encrypt_symlink - encrypt the symlink target if needed
+ * @inode: symlink inode
+ * @target: plaintext symlink target
+ * @len: length of @target excluding null terminator
+ * @disk_link: (in/out) the on-disk symlink target being prepared
+ *
+ * If the symlink target needs to be encrypted, then this function encrypts it
+ * into @disk_link->name.  fscrypt_prepare_symlink() must have been called
+ * previously to compute @disk_link->len.  If the filesystem did not allocate a
+ * buffer for @disk_link->name after calling fscrypt_prepare_link(), then one
+ * will be kmalloc()'ed and the filesystem will be responsible for freeing it.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static inline int fscrypt_encrypt_symlink(struct inode *inode,
+					  const char *target,
+					  unsigned int len,
+					  struct fscrypt_str *disk_link)
+{
+	if (IS_ENCRYPTED(inode))
+		return __fscrypt_encrypt_symlink(inode, target, len, disk_link);
+	return 0;
+}
+
 #endif	/* _LINUX_FSCRYPT_H */
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 81e02201b215..02ec0aa894d8 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -223,4 +223,20 @@ static inline int __fscrypt_prepare_lookup(struct inode *dir,
 	return -EOPNOTSUPP;
 }
 
+static inline int __fscrypt_prepare_symlink(struct inode *dir,
+					    unsigned int len,
+					    unsigned int max_len,
+					    struct fscrypt_str *disk_link)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int __fscrypt_encrypt_symlink(struct inode *inode,
+					    const char *target,
+					    unsigned int len,
+					    struct fscrypt_str *disk_link)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif	/* _LINUX_FSCRYPT_NOTSUPP_H */
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 562a9bc04560..7e0b67ccd816 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -205,5 +205,11 @@ extern int __fscrypt_prepare_rename(struct inode *old_dir,
 				    struct dentry *new_dentry,
 				    unsigned int flags);
 extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
+extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
+				     unsigned int max_len,
+				     struct fscrypt_str *disk_link);
+extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
+				     unsigned int len,
+				     struct fscrypt_str *disk_link);
 
 #endif	/* _LINUX_FSCRYPT_SUPP_H */
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:59 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:59 -0800
Subject: [PATCH v2 08/11] fscrypt: move fscrypt_is_dot_dotdot() to
 fs/crypto/fname.c
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-9-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

Only fs/crypto/fname.c cares about treating the "." and ".." filenames
specially with regards to encryption, so move fscrypt_is_dot_dotdot()
from fscrypt.h to there.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/fname.c       | 11 +++++++++++
 include/linux/fscrypt.h | 11 -----------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 305541bcd108..b8c5061553b1 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -15,6 +15,17 @@
 #include <linux/ratelimit.h>
 #include "fscrypt_private.h"
 
+static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
+{
+	if (str->len == 1 && str->name[0] == '.')
+		return true;
+
+	if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
+		return true;
+
+	return false;
+}
+
 /**
  * fname_encrypt() - encrypt a filename
  *
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 2e4dce0365cf..3045fc49d3ca 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -57,17 +57,6 @@ struct fscrypt_name {
 /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
 #define FSCRYPT_SET_CONTEXT_MAX_SIZE	28
 
-static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
-{
-	if (str->len == 1 && str->name[0] == '.')
-		return true;
-
-	if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
-		return true;
-
-	return false;
-}
-
 #if __FS_HAS_ENCRYPTION
 #include <linux/fscrypt_supp.h>
 #else
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:55 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:55 -0800
Subject: [PATCH v2 04/11] fscrypt: move fscrypt_ctx declaration to
 fscrypt_supp.h
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-5-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

Filesystems only ever access 'struct fscrypt_ctx' through fscrypt
functions.  But when a filesystem is built without encryption support,
these functions are all stubbed out, so the declaration of fscrypt_ctx
is unneeded.  Therefore, move it from fscrypt.h to fscrypt_supp.h.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/fscrypt.h      | 16 +---------------
 include/linux/fscrypt_supp.h | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index c23b2f16129a..0f94d087a6d1 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -24,23 +24,9 @@
 
 #define FS_CRYPTO_BLOCK_SIZE		16
 
+struct fscrypt_ctx;
 struct fscrypt_info;
 
-struct fscrypt_ctx {
-	union {
-		struct {
-			struct page *bounce_page;	/* Ciphertext page */
-			struct page *control_page;	/* Original page  */
-		} w;
-		struct {
-			struct bio *bio;
-			struct work_struct work;
-		} r;
-		struct list_head free_list;	/* Free list */
-	};
-	u8 flags;				/* Flags */
-};
-
 /**
  * For encrypted symlinks, the ciphertext length is stored at the beginning
  * of the string in little-endian format.
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 33d641e27c18..fd6ee089ced0 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -11,6 +11,21 @@
 #ifndef _LINUX_FSCRYPT_SUPP_H
 #define _LINUX_FSCRYPT_SUPP_H
 
+struct fscrypt_ctx {
+	union {
+		struct {
+			struct page *bounce_page;	/* Ciphertext page */
+			struct page *control_page;	/* Original page  */
+		} w;
+		struct {
+			struct bio *bio;
+			struct work_struct work;
+		} r;
+		struct list_head free_list;	/* Free list */
+	};
+	u8 flags;				/* Flags */
+};
+
 static inline bool fscrypt_has_encryption_key(const struct inode *inode)
 {
 	return (inode->i_crypt_info != NULL);
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:44:56 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:44:56 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled() into
 supp/notsupp versions
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-6-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
when the filesystem is built with encryption support.  This didn't
actually matter because no filesystems called it.  However, it will
start being used soon, so fix it by moving it from fscrypt.h to
fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/fscrypt.h         | 8 --------
 include/linux/fscrypt_notsupp.h | 5 +++++
 include/linux/fscrypt_supp.h    | 6 ++++++
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 0f94d087a6d1..b671a4eef47f 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -75,14 +75,6 @@ struct fscrypt_operations {
 /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
 #define FSCRYPT_SET_CONTEXT_MAX_SIZE	28
 
-static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
-{
-	if (inode->i_sb->s_cop->dummy_context &&
-				inode->i_sb->s_cop->dummy_context(inode))
-		return true;
-	return false;
-}
-
 static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
 					u32 filenames_mode)
 {
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 812dc701a5b3..81e02201b215 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -19,6 +19,11 @@ static inline bool fscrypt_has_encryption_key(const struct inode *inode)
 	return false;
 }
 
+static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
+{
+	return false;
+}
+
 /* crypto.c */
 static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
 						  gfp_t gfp_flags)
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index fd6ee089ced0..e7dfa2974906 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -31,6 +31,12 @@ static inline bool fscrypt_has_encryption_key(const struct inode *inode)
 	return (inode->i_crypt_info != NULL);
 }
 
+static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
+{
+	return inode->i_sb->s_cop->dummy_context &&
+		inode->i_sb->s_cop->dummy_context(inode);
+}
+
 /* crypto.c */
 extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
 extern void fscrypt_release_ctx(struct fscrypt_ctx *);
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:45:00 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:45:00 -0800
Subject: [PATCH v2 09/11] fscrypt: trim down fscrypt.h includes
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-10-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

fscrypt.h included way too many other headers, given that it is included
by filesystems both with and without encryption support.  Trim down the
includes list by moving the needed includes into more appropriate
places, and removing the unneeded ones.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/crypto.c           | 1 +
 fs/crypto/fname.c            | 1 +
 fs/crypto/keyinfo.c          | 1 +
 include/linux/fscrypt.h      | 6 ------
 include/linux/fscrypt_supp.h | 3 +++
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 732a786cce9d..ce654526c0fb 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -27,6 +27,7 @@
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <crypto/aes.h>
+#include <crypto/skcipher.h>
 #include "fscrypt_private.h"
 
 static unsigned int num_prealloc_crypto_pages = 32;
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index b8c5061553b1..52d4dbe1e8e7 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -13,6 +13,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/ratelimit.h>
+#include <crypto/skcipher.h>
 #include "fscrypt_private.h"
 
 static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 5e6e846f5a24..c115eac4b4cf 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -14,6 +14,7 @@
 #include <linux/ratelimit.h>
 #include <crypto/aes.h>
 #include <crypto/sha.h>
+#include <crypto/skcipher.h>
 #include "fscrypt_private.h"
 
 static struct crypto_shash *essiv_hash_tfm;
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 3045fc49d3ca..071ebabfc287 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -14,13 +14,7 @@
 #ifndef _LINUX_FSCRYPT_H
 #define _LINUX_FSCRYPT_H
 
-#include <linux/key.h>
 #include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/bio.h>
-#include <linux/dcache.h>
-#include <crypto/skcipher.h>
-#include <uapi/linux/fs.h>
 
 #define FS_CRYPTO_BLOCK_SIZE		16
 
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index ce61caf26f40..562a9bc04560 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -11,6 +11,9 @@
 #ifndef _LINUX_FSCRYPT_SUPP_H
 #define _LINUX_FSCRYPT_SUPP_H
 
+#include <linux/mm.h>
+#include <linux/slab.h>
+
 /*
  * fscrypt superblock flags
  */
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 10:45:02 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 10:45:02 -0800
Subject: [PATCH v2 11/11] fscrypt: new helper function - fscrypt_get_symlink()
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180105184502.48473-12-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

Filesystems also have duplicate code to support ->get_link() on
encrypted symlinks.  Factor it out into a new function
fscrypt_get_symlink().  It takes in the contents of the encrypted
symlink on-disk and provides the target (decrypted or encoded) that
should be returned from ->get_link().

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/hooks.c               | 73 +++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt_notsupp.h |  8 +++++
 include/linux/fscrypt_supp.h    |  3 ++
 3 files changed, 84 insertions(+)

diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 4b83e4af2e41..8900e348ba6e 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -200,3 +200,76 @@ int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(__fscrypt_encrypt_symlink);
+
+/**
+ * fscrypt_get_symlink - get the target of an encrypted symlink
+ * @inode: the symlink inode
+ * @caddr: the on-disk contents of the symlink
+ * @max_size: size of @caddr buffer
+ * @done: if successful, will be set up to free the returned target
+ *
+ * If the symlink's encryption key is available, we decrypt its target.
+ * Otherwise, we encode its target for presentation.
+ *
+ * This may sleep, so the filesystem must have dropped out of RCU mode already.
+ *
+ * Return: the presentable symlink target or an ERR_PTR()
+ */
+const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
+				unsigned int max_size,
+				struct delayed_call *done)
+{
+	const struct fscrypt_symlink_data *sd;
+	struct fscrypt_str cstr, pstr;
+	int err;
+
+	/* This is for encrypted symlinks only */
+	if (WARN_ON(!IS_ENCRYPTED(inode)))
+		return ERR_PTR(-EINVAL);
+
+	/*
+	 * Try to set up the symlink's encryption key, but we can continue
+	 * regardless of whether the key is available or not.
+	 */
+	err = fscrypt_get_encryption_info(inode);
+	if (err)
+		return ERR_PTR(err);
+
+	/*
+	 * For historical reasons, encrypted symlink targets are prefixed with
+	 * the ciphertext length, even though this is redundant with i_size.
+	 */
+
+	if (max_size < sizeof(*sd))
+		return ERR_PTR(-EUCLEAN);
+	sd = caddr;
+	cstr.name = (unsigned char *)sd->encrypted_path;
+	cstr.len = le16_to_cpu(sd->len);
+
+	if (cstr.len == 0)
+		return ERR_PTR(-EUCLEAN);
+
+	if (cstr.len + sizeof(*sd) - 1 > max_size)
+		return ERR_PTR(-EUCLEAN);
+
+	err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
+	if (err)
+		return ERR_PTR(err);
+
+	err = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
+	if (err)
+		goto err_kfree;
+
+	err = -EUCLEAN;
+	if (pstr.name[0] == '\0')
+		goto err_kfree;
+
+	pstr.name[pstr.len] = '\0';
+	set_delayed_call(done, kfree_link, pstr.name);
+	return pstr.name;
+
+err_kfree:
+	kfree(pstr.name);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(fscrypt_get_symlink);
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 02ec0aa894d8..dd106640c6ea 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -239,4 +239,12 @@ static inline int __fscrypt_encrypt_symlink(struct inode *inode,
 	return -EOPNOTSUPP;
 }
 
+static inline const char *fscrypt_get_symlink(struct inode *inode,
+					      const void *caddr,
+					      unsigned int max_size,
+					      struct delayed_call *done)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
 #endif	/* _LINUX_FSCRYPT_NOTSUPP_H */
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 7e0b67ccd816..dc2babf3f7d3 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -211,5 +211,8 @@ extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
 extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
 				     unsigned int len,
 				     struct fscrypt_str *disk_link);
+extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
+				       unsigned int max_size,
+				       struct delayed_call *done);
 
 #endif	/* _LINUX_FSCRYPT_SUPP_H */
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From ebiggers3 at gmail.com  Fri Jan  5 11:30:03 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri,  5 Jan 2018 11:30:03 -0800
Subject: [PATCH v2] ubifs: free the encrypted symlink target
Message-ID: <20180105193003.118283-1-ebiggers3@gmail.com>

From: Eric Biggers <ebiggers at google.com>

ubifs_symlink() forgot to free the kmalloc()'ed buffer holding the
encrypted symlink target, creating a memory leak.  Fix it.

(UBIFS could actually encrypt directly into ui->data, removing the
temporary buffer, but that is left for the patch that switches to use
the symlink helper functions.)

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: <stable at vger.kernel.org> # v4.10+
Signed-off-by: Eric Biggers <ebiggers at google.com>
---

No changes since v1, just resent as standalone patch.
	
 fs/ubifs/dir.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 417fe0b29f23..ef820f803176 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1216,10 +1216,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
 		ostr.len = disk_link.len;
 
 		err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr);
-		if (err) {
-			kfree(sd);
+		if (err)
 			goto out_inode;
-		}
 
 		sd->len = cpu_to_le16(ostr.len);
 		disk_link.name = (char *)sd;
@@ -1251,11 +1249,10 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
 		goto out_cancel;
 	mutex_unlock(&dir_ui->ui_mutex);
 
-	ubifs_release_budget(c, &req);
 	insert_inode_hash(inode);
 	d_instantiate(dentry, inode);
-	fscrypt_free_filename(&nm);
-	return 0;
+	err = 0;
+	goto out_fname;
 
 out_cancel:
 	dir->i_size -= sz_change;
@@ -1268,6 +1265,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
 	fscrypt_free_filename(&nm);
 out_budg:
 	ubifs_release_budget(c, &req);
+	kfree(sd);
 	return err;
 }
 
-- 
2.16.0.rc0.223.g4a4ac83678-goog



From festevam at gmail.com  Fri Jan  5 11:46:00 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Fri,  5 Jan 2018 17:46:00 -0200
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1515181560-1410-1-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "fsl-quadspi.0"
mtd1: 01000000 00010000 "fsl-quadspi.1"

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index f17d224..7712c63 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, mtd_index = 0;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1047,6 +1047,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		nor = &q->nor[i];
 		mtd = &nor->mtd;
 
+		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "fsl-quadspi.%d",
+					   mtd_index);
+		if (!mtd->name) {
+			ret = -ENOMEM;
+			goto mutex_failed;
+		}
+
 		nor->dev = dev;
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
@@ -1098,6 +1105,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 			nor->page_size = q->devtype_data->txfifo;
 
 		i++;
+		mtd_index++;
 	}
 
 	/* finish the rest init. */
-- 
2.7.4



From festevam at gmail.com  Fri Jan  5 12:02:55 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Fri,  5 Jan 2018 18:02:55 -0200
Subject: [PATCH 1/2] mtd: qcom_nandc: Add a NULL check for devm_kasprintf()
Message-ID: <1515182576-2704-1-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at nxp.com>

devm_kasprintf() may fail, so we should better add a NULL check
and propagate an error on failure.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
 drivers/mtd/nand/qcom_nandc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 245d0f3..3fe2ff8 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -2639,6 +2639,8 @@ static int qcom_nand_host_init(struct qcom_nand_controller *nandc,
 
 	nand_set_flash_node(chip, dn);
 	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "qcom_nand.%d", host->cs);
+	if (!mtd->name)
+		return -ENOMEM;
 	mtd->owner = THIS_MODULE;
 	mtd->dev.parent = dev;
 
-- 
2.7.4



From festevam at gmail.com  Fri Jan  5 12:02:56 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Fri,  5 Jan 2018 18:02:56 -0200
Subject: [PATCH 2/2] mtd: brcmnand: Add a NULL check for devm_kasprintf()
In-Reply-To: <1515182576-2704-1-git-send-email-festevam@gmail.com>
References: <1515182576-2704-1-git-send-email-festevam@gmail.com>
Message-ID: <1515182576-2704-2-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at nxp.com>

devm_kasprintf() may fail, so we should better add a NULL check
and propagate an error on failure.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
 drivers/mtd/nand/brcmnand/brcmnand.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index 3310e14..8942aa6 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -2237,6 +2237,8 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 	nand_set_controller_data(chip, host);
 	mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d",
 				   host->cs);
+	if (!mtd->name)
+		return -ENOMEM;
 	mtd->owner = THIS_MODULE;
 	mtd->dev.parent = &pdev->dev;
 
-- 
2.7.4



From elfring at users.sourceforge.net  Fri Jan  5 12:27:36 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 21:27:36 +0100
Subject: [PATCH 0/3] mtd/nand/ams-delta: Adjustments for three function
 implementations
Message-ID: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 21:21:12 +0100

Three update suggestions were taken into account
from static source code analysis.

Markus Elfring (3):
  Delete an error message for a failed memory allocation in ams_delta_init()
  Improve a size determination in ams_delta_init()
  Add some spaces for better code readability

 drivers/mtd/nand/ams-delta.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

-- 
2.15.1



From elfring at users.sourceforge.net  Fri Jan  5 12:28:58 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 21:28:58 +0100
Subject: [PATCH 1/3] mtd/nand/ams-delta: Delete an error message for a failed
 memory allocation in ams_delta_init()
In-Reply-To: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
References: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
Message-ID: <0ab36d19-fb5b-ab7f-5821-7c0574f9589f@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 21:01:18 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/ams-delta.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index d60ada45c549..effaecff0f2e 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -185,7 +185,6 @@ static int ams_delta_init(struct platform_device *pdev)
 	/* Allocate memory for MTD device structure and private data */
 	this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
 	if (!this) {
-		printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n");
 		err = -ENOMEM;
 		goto out;
 	}
-- 
2.15.1



From elfring at users.sourceforge.net  Fri Jan  5 12:30:00 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 21:30:00 +0100
Subject: [PATCH 2/3] mtd/nand/ams-delta: Improve a size determination in
 ams_delta_init()
In-Reply-To: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
References: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
Message-ID: <4df8f355-b072-f0a6-1314-354a6bafe772@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 21:03:20 +0100

Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/ams-delta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index effaecff0f2e..4f5fc104c510 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -183,7 +183,7 @@ static int ams_delta_init(struct platform_device *pdev)
 		return -ENXIO;
 
 	/* Allocate memory for MTD device structure and private data */
-	this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
+	this = kzalloc(sizeof(*this), GFP_KERNEL);
 	if (!this) {
 		err = -ENOMEM;
 		goto out;
-- 
2.15.1



From elfring at users.sourceforge.net  Fri Jan  5 12:31:30 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 21:31:30 +0100
Subject: [PATCH 3/3] mtd/nand/ams-delta: Add some spaces for better code
 readability
In-Reply-To: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
References: <8f678424-3ce1-3a4c-1b0d-f3ac9a226f00@users.sourceforge.net>
Message-ID: <9e8454a8-41aa-9afc-e2b9-c1824028f91f@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 21:14:20 +0100

Use space characters at some source code places according to
the Linux coding style convention.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/ams-delta.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 4f5fc104c510..9ea61271fee6 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -94,7 +94,7 @@ static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf,
 {
 	int i;
 
-	for (i=0; i<len; i++)
+	for (i = 0; i < len; i++)
 		ams_delta_write_byte(mtd, buf[i]);
 }
 
@@ -102,7 +102,7 @@ static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
 	int i;
 
-	for (i=0; i<len; i++)
+	for (i = 0; i < len; i++)
 		buf[i] = ams_delta_read_byte(mtd);
 }
 
-- 
2.15.1



From jaegeuk at kernel.org  Fri Jan  5 12:40:09 2018
From: jaegeuk at kernel.org (Jaegeuk Kim)
Date: Fri, 5 Jan 2018 12:40:09 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180105184502.48473-6-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
Message-ID: <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>

On 01/05, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
> when the filesystem is built with encryption support.  This didn't
> actually matter because no filesystems called it.  However, it will
> start being used soon, so fix it by moving it from fscrypt.h to
> fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.

Ted, do we have a chance to get rid of this dummy_context? If there exists
backward compatibility issue, please never mind tho.

Thanks,

> 
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  include/linux/fscrypt.h         | 8 --------
>  include/linux/fscrypt_notsupp.h | 5 +++++
>  include/linux/fscrypt_supp.h    | 6 ++++++
>  3 files changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index 0f94d087a6d1..b671a4eef47f 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -75,14 +75,6 @@ struct fscrypt_operations {
>  /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
>  #define FSCRYPT_SET_CONTEXT_MAX_SIZE	28
>  
> -static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
> -{
> -	if (inode->i_sb->s_cop->dummy_context &&
> -				inode->i_sb->s_cop->dummy_context(inode))
> -		return true;
> -	return false;
> -}
> -
>  static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
>  					u32 filenames_mode)
>  {
> diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
> index 812dc701a5b3..81e02201b215 100644
> --- a/include/linux/fscrypt_notsupp.h
> +++ b/include/linux/fscrypt_notsupp.h
> @@ -19,6 +19,11 @@ static inline bool fscrypt_has_encryption_key(const struct inode *inode)
>  	return false;
>  }
>  
> +static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
> +{
> +	return false;
> +}
> +
>  /* crypto.c */
>  static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
>  						  gfp_t gfp_flags)
> diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
> index fd6ee089ced0..e7dfa2974906 100644
> --- a/include/linux/fscrypt_supp.h
> +++ b/include/linux/fscrypt_supp.h
> @@ -31,6 +31,12 @@ static inline bool fscrypt_has_encryption_key(const struct inode *inode)
>  	return (inode->i_crypt_info != NULL);
>  }
>  
> +static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
> +{
> +	return inode->i_sb->s_cop->dummy_context &&
> +		inode->i_sb->s_cop->dummy_context(inode);
> +}
> +
>  /* crypto.c */
>  extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
>  extern void fscrypt_release_ctx(struct fscrypt_ctx *);
> -- 
> 2.16.0.rc0.223.g4a4ac83678-goog


From elfring at users.sourceforge.net  Fri Jan  5 12:55:28 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 21:55:28 +0100
Subject: [PATCH] mtd/nand/atmel: Delete an error message for a failed memory
 allocation in two functions
Message-ID: <81cadb76-8c67-9289-1375-2d4a55a4adfa@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 21:45:04 +0100

Omit an extra message for a memory allocation failure in these functions.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/atmel/nand-controller.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
index 90a71a56bc23..a41b999229c9 100644
--- a/drivers/mtd/nand/atmel/nand-controller.c
+++ b/drivers/mtd/nand/atmel/nand-controller.c
@@ -1612,10 +1612,8 @@ static int atmel_nand_register(struct atmel_nand *nand)
 		mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL,
 					   "%s:nand.%d", dev_name(nc->dev),
 					   nand->cs[0].id);
-		if (!mtd->name) {
-			dev_err(nc->dev, "Failed to allocate mtd->name\n");
+		if (!mtd->name)
 			return -ENOMEM;
-		}
 	}
 
 	ret = nand_scan_tail(mtd);
@@ -1654,10 +1652,8 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
 	nand = devm_kzalloc(nc->dev,
 			    sizeof(*nand) + (numcs * sizeof(*nand->cs)),
 			    GFP_KERNEL);
-	if (!nand) {
-		dev_err(nc->dev, "Failed to allocate NAND object\n");
+	if (!nand)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	nand->numcs = numcs;
 
-- 
2.15.1



From elfring at users.sourceforge.net  Fri Jan  5 13:15:47 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 22:15:47 +0100
Subject: [PATCH] mtd/nand/omap2: Delete an error message for a failed memory
 allocation in omap_nand_probe()
Message-ID: <4b92ade2-5fcd-3213-bf1b-110a1e03472c@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 22:10:39 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/omap2.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index dad438c4906a..5c96c291426b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1947,10 +1947,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if (!mtd->name) {
 		mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 					   "omap2-nand.%d", info->gpmc_cs);
-		if (!mtd->name) {
-			dev_err(&pdev->dev, "Failed to set MTD name\n");
+		if (!mtd->name)
 			return -ENOMEM;
-		}
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
2.15.1



From ebiggers3 at gmail.com  Fri Jan  5 13:18:39 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri, 5 Jan 2018 13:18:39 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
 <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
Message-ID: <20180105211839.GB44929@gmail.com>

On Fri, Jan 05, 2018 at 12:40:09PM -0800, Jaegeuk Kim wrote:
> On 01/05, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers at google.com>
> > 
> > fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
> > when the filesystem is built with encryption support.  This didn't
> > actually matter because no filesystems called it.  However, it will
> > start being used soon, so fix it by moving it from fscrypt.h to
> > fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.
> 
> Ted, do we have a chance to get rid of this dummy_context? If there exists
> backward compatibility issue, please never mind tho.
> 

It's used to implement the test_dummy_encryption mount option for ext4, which is
used by the 'ext4/encrypt' config for gce-xfstests.  Its purpose is to cause all
new files (directories, regular files, and symlinks) to be automatically
encrypted with a default key, so that the encrypted I/O paths are tested more
thoroughly than by just running the 'encrypt' group tests.

There are no backward compatibility concerns with changing or removing the
test_dummy_encryption mount option; we just don't have a better solution yet.

Ideally, instead of using test_dummy_encryption we would encrypt the root
directory of the filesystem immediately after it is formatted.  However, that
doesn't work for ext4 because the lost+found directory has to be located in the
root directory, and must be unencrypted, and the lost+found directory entry must
be unencrypted.

So I think getting rid of test_dummy_encryption depends on a solution to the
lost+found problem.

An alternative would be to add support for "inherit-only" encryption policies,
then set such a policy on the root directory of the filesystem.  But, there
haven't been any requests for such a feature yet outside of this specific
testing-only use case, so I've been hesitant to add it.

Eric


From elfring at users.sourceforge.net  Fri Jan  5 13:34:33 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Fri, 5 Jan 2018 22:34:33 +0100
Subject: [PATCH] mtd/nand/sunxi: Delete an error message for a failed memory
 allocation in sunxi_nand_chip_init()
Message-ID: <9a6e9845-23f0-0eb8-3c5b-d877e9874a1d@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Fri, 5 Jan 2018 22:27:09 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nand/sunxi_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 82244be3e766..ebfa130a9285 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -2019,10 +2019,8 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
 			    sizeof(*chip) +
 			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
 			    GFP_KERNEL);
-	if (!chip) {
-		dev_err(dev, "could not allocate chip\n");
+	if (!chip)
 		return -ENOMEM;
-	}
 
 	chip->nsels = nsels;
 	chip->selected = -1;
-- 
2.15.1



From jaegeuk at kernel.org  Fri Jan  5 13:36:08 2018
From: jaegeuk at kernel.org (Jaegeuk Kim)
Date: Fri, 5 Jan 2018 13:36:08 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180105211839.GB44929@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
 <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105211839.GB44929@gmail.com>
Message-ID: <20180105213608.GB72343@jaegeuk-macbookpro.roam.corp.google.com>

On 01/05, Eric Biggers wrote:
> On Fri, Jan 05, 2018 at 12:40:09PM -0800, Jaegeuk Kim wrote:
> > On 01/05, Eric Biggers wrote:
> > > From: Eric Biggers <ebiggers at google.com>
> > > 
> > > fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
> > > when the filesystem is built with encryption support.  This didn't
> > > actually matter because no filesystems called it.  However, it will
> > > start being used soon, so fix it by moving it from fscrypt.h to
> > > fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.
> > 
> > Ted, do we have a chance to get rid of this dummy_context? If there exists
> > backward compatibility issue, please never mind tho.
> > 
> 
> It's used to implement the test_dummy_encryption mount option for ext4, which is
> used by the 'ext4/encrypt' config for gce-xfstests.  Its purpose is to cause all
> new files (directories, regular files, and symlinks) to be automatically
> encrypted with a default key, so that the encrypted I/O paths are tested more
> thoroughly than by just running the 'encrypt' group tests.
> 
> There are no backward compatibility concerns with changing or removing the
> test_dummy_encryption mount option; we just don't have a better solution yet.
> 
> Ideally, instead of using test_dummy_encryption we would encrypt the root
> directory of the filesystem immediately after it is formatted.  However, that
> doesn't work for ext4 because the lost+found directory has to be located in the
> root directory, and must be unencrypted, and the lost+found directory entry must
> be unencrypted.
> 
> So I think getting rid of test_dummy_encryption depends on a solution to the
> lost+found problem.

Thank you for the explanation. Actually, I've got used to encrypt the root dir
in f2fs for such the testing purpose, since it's indeed empty. If it's the only
matter of lost_found in ext4, how about setting the encryption bit and dummy
context in root inode by mke2fs or tune2fs?

Thanks,

> 
> An alternative would be to add support for "inherit-only" encryption policies,
> then set such a policy on the root directory of the filesystem.  But, there
> haven't been any requests for such a feature yet outside of this specific
> testing-only use case, so I've been hesitant to add it.
> 
> Eric


From ebiggers3 at gmail.com  Fri Jan  5 14:01:49 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Fri, 5 Jan 2018 14:01:49 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180105213608.GB72343@jaegeuk-macbookpro.roam.corp.google.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
 <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105211839.GB44929@gmail.com>
 <20180105213608.GB72343@jaegeuk-macbookpro.roam.corp.google.com>
Message-ID: <20180105220149.GD44929@gmail.com>

On Fri, Jan 05, 2018 at 01:36:08PM -0800, Jaegeuk Kim wrote:
> On 01/05, Eric Biggers wrote:
> > On Fri, Jan 05, 2018 at 12:40:09PM -0800, Jaegeuk Kim wrote:
> > > On 01/05, Eric Biggers wrote:
> > > > From: Eric Biggers <ebiggers at google.com>
> > > > 
> > > > fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
> > > > when the filesystem is built with encryption support.  This didn't
> > > > actually matter because no filesystems called it.  However, it will
> > > > start being used soon, so fix it by moving it from fscrypt.h to
> > > > fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.
> > > 
> > > Ted, do we have a chance to get rid of this dummy_context? If there exists
> > > backward compatibility issue, please never mind tho.
> > > 
> > 
> > It's used to implement the test_dummy_encryption mount option for ext4, which is
> > used by the 'ext4/encrypt' config for gce-xfstests.  Its purpose is to cause all
> > new files (directories, regular files, and symlinks) to be automatically
> > encrypted with a default key, so that the encrypted I/O paths are tested more
> > thoroughly than by just running the 'encrypt' group tests.
> > 
> > There are no backward compatibility concerns with changing or removing the
> > test_dummy_encryption mount option; we just don't have a better solution yet.
> > 
> > Ideally, instead of using test_dummy_encryption we would encrypt the root
> > directory of the filesystem immediately after it is formatted.  However, that
> > doesn't work for ext4 because the lost+found directory has to be located in the
> > root directory, and must be unencrypted, and the lost+found directory entry must
> > be unencrypted.
> > 
> > So I think getting rid of test_dummy_encryption depends on a solution to the
> > lost+found problem.
> 
> Thank you for the explanation. Actually, I've got used to encrypt the root dir
> in f2fs for such the testing purpose, since it's indeed empty. If it's the only
> matter of lost_found in ext4, how about setting the encryption bit and dummy
> context in root inode by mke2fs or tune2fs?
> 

You can't mark a nonempty directory as encrypted.  First, you can't have an
unencrypted file *name* in an encrypted directory, because then all the
operations on that filename won't work, because the filesystem will think it is
encrypted.  Second, you cannot have an unencrypted file in an encrypted
directory because that violates the constraint that all files in an encrypted
directory are encrypted -- and by design that is verified on ->lookup().

So to get it to actually work in ext4 we'd need to add extra special-case logic
around the lost+found directory -- probably allowing both the directory entry
and directory itself to be unencrypted, despite existing in an encrypted
directory.  And I think that solution would be more complicated than the
test_dummy_encryption mount option we have now.

It may be worth reconsidering if people start asking for the ability to encrypt
the root directory for other reasons, though.  (Although, that use case is
largely redundant with dm-crypt.)

Eric


From richard at nod.at  Fri Jan  5 14:11:00 2018
From: richard at nod.at (Richard Weinberger)
Date: Fri, 05 Jan 2018 23:11:00 +0100
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <20180105183744.GA44929@gmail.com>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
 <20180105183744.GA44929@gmail.com>
Message-ID: <2774377.VZm18AqBqi@blindfold>

Eric,

Am Freitag, 5. Januar 2018, 19:37:44 CET schrieb Eric Biggers:
> On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers at google.com>
> > 
> > This series switches ubifs to use the fscrypt helper functions for
> > open/link/rename/lookup/setattr introduced in v4.15.
> > 
> > These patches were originally sent in "[PATCH 00/25] fscrypt: add some
> > higher-level helper functions".  I've rebased them onto v4.15-rc1.
> > 
> > Eric Biggers (5):
> >   ubifs: switch to fscrypt_file_open()
> >   ubifs: switch to fscrypt_prepare_link()
> >   ubifs: switch to fscrypt_prepare_rename()
> >   ubifs: switch to fscrypt_prepare_lookup()
> >   ubifs: switch to fscrypt_prepare_setattr()
> >  
> >  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
> >  fs/ubifs/file.c | 41 ++++-------------------------------------
> >  2 files changed, 17 insertions(+), 67 deletions(-)
> 
> Richard, can you take these for UBIFS for v4.16?

Yes. Thanks a lot for cleaning this up.

Thanks,
//richard



From jaegeuk at kernel.org  Fri Jan  5 16:39:50 2018
From: jaegeuk at kernel.org (Jaegeuk Kim)
Date: Fri, 5 Jan 2018 16:39:50 -0800
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180105220149.GD44929@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
 <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105211839.GB44929@gmail.com>
 <20180105213608.GB72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105220149.GD44929@gmail.com>
Message-ID: <20180106003950.GC72343@jaegeuk-macbookpro.roam.corp.google.com>

On 01/05, Eric Biggers wrote:
> On Fri, Jan 05, 2018 at 01:36:08PM -0800, Jaegeuk Kim wrote:
> > On 01/05, Eric Biggers wrote:
> > > On Fri, Jan 05, 2018 at 12:40:09PM -0800, Jaegeuk Kim wrote:
> > > > On 01/05, Eric Biggers wrote:
> > > > > From: Eric Biggers <ebiggers at google.com>
> > > > > 
> > > > > fscrypt_dummy_context_enabled() accesses ->s_cop, which now is only set
> > > > > when the filesystem is built with encryption support.  This didn't
> > > > > actually matter because no filesystems called it.  However, it will
> > > > > start being used soon, so fix it by moving it from fscrypt.h to
> > > > > fscrypt_supp.h and stubbing it out in fscrypt_notsupp.h.
> > > > 
> > > > Ted, do we have a chance to get rid of this dummy_context? If there exists
> > > > backward compatibility issue, please never mind tho.
> > > > 
> > > 
> > > It's used to implement the test_dummy_encryption mount option for ext4, which is
> > > used by the 'ext4/encrypt' config for gce-xfstests.  Its purpose is to cause all
> > > new files (directories, regular files, and symlinks) to be automatically
> > > encrypted with a default key, so that the encrypted I/O paths are tested more
> > > thoroughly than by just running the 'encrypt' group tests.
> > > 
> > > There are no backward compatibility concerns with changing or removing the
> > > test_dummy_encryption mount option; we just don't have a better solution yet.
> > > 
> > > Ideally, instead of using test_dummy_encryption we would encrypt the root
> > > directory of the filesystem immediately after it is formatted.  However, that
> > > doesn't work for ext4 because the lost+found directory has to be located in the
> > > root directory, and must be unencrypted, and the lost+found directory entry must
> > > be unencrypted.
> > > 
> > > So I think getting rid of test_dummy_encryption depends on a solution to the
> > > lost+found problem.
> > 
> > Thank you for the explanation. Actually, I've got used to encrypt the root dir
> > in f2fs for such the testing purpose, since it's indeed empty. If it's the only
> > matter of lost_found in ext4, how about setting the encryption bit and dummy
> > context in root inode by mke2fs or tune2fs?
> > 
> 
> You can't mark a nonempty directory as encrypted.  First, you can't have an
> unencrypted file *name* in an encrypted directory, because then all the
> operations on that filename won't work, because the filesystem will think it is
> encrypted.  Second, you cannot have an unencrypted file in an encrypted
> directory because that violates the constraint that all files in an encrypted
> directory are encrypted -- and by design that is verified on ->lookup().
> 
> So to get it to actually work in ext4 we'd need to add extra special-case logic
> around the lost+found directory -- probably allowing both the directory entry
> and directory itself to be unencrypted, despite existing in an encrypted
> directory.  And I think that solution would be more complicated than the
> test_dummy_encryption mount option we have now.

Agreed that dummy'd be easy to go for now tho, doesn't it give any security
concern at all, even only for ext4 testing purpose? Is there a chance to hack
the mount option in runtime? BTW, it may be doable to build an encrypt root
inode having encrypted dentry of lost_found, given dummy_context in mke2fs.
I'm just curious whether or not it'd be worth to do.

Thanks,

> 
> It may be worth reconsidering if people start asking for the ability to encrypt
> the root directory for other reasons, though.  (Although, that use case is
> largely redundant with dm-crypt.)
> 
> Eric


From tytso at mit.edu  Fri Jan  5 18:49:44 2018
From: tytso at mit.edu (Theodore Ts'o)
Date: Fri, 5 Jan 2018 21:49:44 -0500
Subject: [PATCH v2 05/11] fscrypt: split fscrypt_dummy_context_enabled()
 into supp/notsupp versions
In-Reply-To: <20180106003950.GC72343@jaegeuk-macbookpro.roam.corp.google.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
 <20180105184502.48473-6-ebiggers3@gmail.com>
 <20180105204009.GA72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105211839.GB44929@gmail.com>
 <20180105213608.GB72343@jaegeuk-macbookpro.roam.corp.google.com>
 <20180105220149.GD44929@gmail.com>
 <20180106003950.GC72343@jaegeuk-macbookpro.roam.corp.google.com>
Message-ID: <20180106024944.GA2404@thunk.org>

On Fri, Jan 05, 2018 at 04:39:50PM -0800, Jaegeuk Kim wrote:
> 
> Agreed that dummy'd be easy to go for now tho, doesn't it give any security
> concern at all, even only for ext4 testing purpose? Is there a chance to hack
> the mount option in runtime? BTW, it may be doable to build an encrypt root
> inode having encrypted dentry of lost_found, given dummy_context in mke2fs.
> I'm just curious whether or not it'd be worth to do.

It requires root to manipulate the mount option; and if you don't
trust root, you've got other problems.

The problem is that e2fsck needs to be able to repair a file system
without having access to any of the file system keys.  And so if there
is an orphaned inode (e.g., an inode which is not attached to any
directory), we need to put it somewhere, and that's /lost+found.

I've considered making lost+found a magic directory which isn't
directly linked into the root directory, and have a magic namei
lookup.  There are downsides though; that would mean that the
/lost+found filename has to be magic --- what to do if the user tries
to create a lost+found directory, or rename the magic lost+found
directory.

Ultimately, i decided it wasn't worth the semantic and
implementational complexity, especially since none of the primary use
cases (Android, Chromeos, etc.) needed an encrypted root directory.

      			  	       	  	    - Ted


From boris.brezillon at free-electrons.com  Sat Jan  6 01:12:33 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 10:12:33 +0100
Subject: [PATCH v2] mtd: nand: vf610: fix error handling in
 vf610_nfc_probe()
In-Reply-To: <1514056706-25136-1-git-send-email-khoroshilov@ispras.ru>
References: <20171222225724.1e26bc38@bbrezillon>
 <1514056706-25136-1-git-send-email-khoroshilov@ispras.ru>
Message-ID: <20180106101233.771c574e@bbrezillon>

On Sat, 23 Dec 2017 22:18:26 +0300
Alexey Khoroshilov <khoroshilov at ispras.ru> wrote:

> vf610_nfc_probe() misses error handling of mtd_device_register().
> 
> Found by Linux Driver Verification project (linuxtesting.org).
> 
> Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
> ---
> v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
> 
>  drivers/mtd/nand/vf610_nfc.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> index 8037d4b48a05..2dac25a8ccbf 100644
> --- a/drivers/mtd/nand/vf610_nfc.c
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  				dev_err(nfc->dev,
>  					"Only one NAND chip supported!\n");
>  				err = -EINVAL;
> -				goto error;
> +				goto err_node;
>  			}
>  
>  			nand_set_flash_node(chip, child);
> @@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
>  	if (err) {
>  		dev_err(nfc->dev, "Error requesting IRQ!\n");
> -		goto error;
> +		goto err_node;
>  	}
>  
>  	vf610_nfc_preinit_controller(nfc);
> @@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* first scan to find the device and get the page size */
>  	err = nand_scan_ident(mtd, 1, NULL);
>  	if (err)
> -		goto error;
> +		goto err_node;
>  
>  	vf610_nfc_init_controller(nfc);
>  
> @@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
>  		dev_err(nfc->dev, "Unsupported flash page size\n");
>  		err = -ENXIO;
> -		goto error;
> +		goto err_node;
>  	}
>  
>  	if (chip->ecc.mode == NAND_ECC_HW) {
>  		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
>  			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		if (chip->ecc.size != mtd->writesize) {
>  			dev_err(nfc->dev, "Step size needs to be page size\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		/* Only 64 byte ECC layouts known */
> @@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  		} else {
>  			dev_err(nfc->dev, "Unsupported ECC strength\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		chip->ecc.read_page = vf610_nfc_read_page;
> @@ -777,14 +777,19 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* second phase scan */
>  	err = nand_scan_tail(mtd);
>  	if (err)
> -		goto error;
> +		goto err_node;
>  
>  	platform_set_drvdata(pdev, mtd);
>  
>  	/* Register device in MTD */
> -	return mtd_device_register(mtd, NULL, 0);
> +	err = mtd_device_register(mtd, NULL, 0);
> +	if (err)
> +		goto err_nand;
> +	return 0;
>  
> -error:
> +err_nand:
> +	nand_cleanup(chip);
> +err_node:
>  	of_node_put(nand_get_flash_node(chip));

Can you use clearer err labels, like err_put_node and err_cleanup_nand?

>  err_clk:
>  	clk_disable_unprepare(nfc->clk);



From boris.brezillon at free-electrons.com  Sat Jan  6 01:25:41 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 10:25:41 +0100
Subject: [PATCH v2] mtd: nand: vf610: fix error handling in
 vf610_nfc_probe()
In-Reply-To: <1514056706-25136-1-git-send-email-khoroshilov@ispras.ru>
References: <20171222225724.1e26bc38@bbrezillon>
 <1514056706-25136-1-git-send-email-khoroshilov@ispras.ru>
Message-ID: <20180106102541.75ff546d@bbrezillon>

On Sat, 23 Dec 2017 22:18:26 +0300
Alexey Khoroshilov <khoroshilov at ispras.ru> wrote:

> vf610_nfc_probe() misses error handling of mtd_device_register().
> 
> Found by Linux Driver Verification project (linuxtesting.org).
> 
> Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
> ---
> v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
> 
>  drivers/mtd/nand/vf610_nfc.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> index 8037d4b48a05..2dac25a8ccbf 100644
> --- a/drivers/mtd/nand/vf610_nfc.c
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  				dev_err(nfc->dev,
>  					"Only one NAND chip supported!\n");
>  				err = -EINVAL;
> -				goto error;
> +				goto err_node;
>  			}
>  
>  			nand_set_flash_node(chip, child);
> @@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
>  	if (err) {
>  		dev_err(nfc->dev, "Error requesting IRQ!\n");
> -		goto error;
> +		goto err_node;
>  	}
>  
>  	vf610_nfc_preinit_controller(nfc);
> @@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* first scan to find the device and get the page size */
>  	err = nand_scan_ident(mtd, 1, NULL);
>  	if (err)
> -		goto error;
> +		goto err_node;
>  
>  	vf610_nfc_init_controller(nfc);
>  
> @@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
>  		dev_err(nfc->dev, "Unsupported flash page size\n");
>  		err = -ENXIO;
> -		goto error;
> +		goto err_node;
>  	}
>  
>  	if (chip->ecc.mode == NAND_ECC_HW) {
>  		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
>  			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		if (chip->ecc.size != mtd->writesize) {
>  			dev_err(nfc->dev, "Step size needs to be page size\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		/* Only 64 byte ECC layouts known */
> @@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  		} else {
>  			dev_err(nfc->dev, "Unsupported ECC strength\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_node;
>  		}
>  
>  		chip->ecc.read_page = vf610_nfc_read_page;
> @@ -777,14 +777,19 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* second phase scan */
>  	err = nand_scan_tail(mtd);
>  	if (err)
> -		goto error;
> +		goto err_node;
>  
>  	platform_set_drvdata(pdev, mtd);
>  
>  	/* Register device in MTD */
> -	return mtd_device_register(mtd, NULL, 0);
> +	err = mtd_device_register(mtd, NULL, 0);
> +	if (err)
> +		goto err_nand;
> +	return 0;
>  
> -error:
> +err_nand:
> +	nand_cleanup(chip);
> +err_node:
>  	of_node_put(nand_get_flash_node(chip));

I also realize calling of_node_put() here is wrong because nothing in
this code retains a reference to the DT node.

>  err_clk:
>  	clk_disable_unprepare(nfc->clk);



From boris.brezillon at free-electrons.com  Sat Jan  6 01:32:43 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 10:32:43 +0100
Subject: [PATCH] mtd: brcmnand: Disable prefetch by default
In-Reply-To: <1514924097-1630-1-git-send-email-kdasu.kdev@gmail.com>
References: <1514924097-1630-1-git-send-email-kdasu.kdev@gmail.com>
Message-ID: <20180106103243.0ebf1561@bbrezillon>

Hi Kamal,

The prefix should be "mtd: nand: brcmnand: ".

On Tue,  2 Jan 2018 15:14:57 -0500
Kamal Dasu <kdasu.kdev at gmail.com> wrote:

> Brcm nand controller prefetch feature needs to be disabled
> by default. Enabling effects performance on random reads as

		       ^ affects ?

> well as dma reads.
> 
> Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>

Maybe Fixes and CC-stable tags would be relevant here, unless you don't
consider this patch as a fix and don't want to backport it to stable
kernels.

> ---
>  drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
> index dd56a67..2a978d9 100644
> --- a/drivers/mtd/nand/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/brcmnand/brcmnand.c
> @@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>  	if (ctrl->nand_version >= 0x0702)
>  		tmp |= ACC_CONTROL_RD_ERASED;
>  	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
> -	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
> -		/*
> -		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
> -		 * errors
> -		 */
> -		if (has_flash_dma(ctrl))
> -			tmp &= ~ACC_CONTROL_PREFETCH;
> -		else
> -			tmp |= ACC_CONTROL_PREFETCH;
> -	}
> +	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
> +		tmp &= ~ACC_CONTROL_PREFETCH;
> +
>  	nand_writereg(ctrl, offs, tmp);
>  
>  	return 0;



From boris.brezillon at free-electrons.com  Sat Jan  6 01:35:57 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 10:35:57 +0100
Subject: [PATCH 2/2] mtd: brcmnand: Add a NULL check for devm_kasprintf()
In-Reply-To: <1515182576-2704-2-git-send-email-festevam@gmail.com>
References: <1515182576-2704-1-git-send-email-festevam@gmail.com>
 <1515182576-2704-2-git-send-email-festevam@gmail.com>
Message-ID: <20180106103557.6612a12c@bbrezillon>

Hi Fabio,

The prefix should be "mtd: nand: brcmnand: ".

No need to resend, I'll fix it when applying.

Thanks,

Boris

On Fri,  5 Jan 2018 18:02:56 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> devm_kasprintf() may fail, so we should better add a NULL check
> and propagate an error on failure.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
>  drivers/mtd/nand/brcmnand/brcmnand.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
> index 3310e14..8942aa6 100644
> --- a/drivers/mtd/nand/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/brcmnand/brcmnand.c
> @@ -2237,6 +2237,8 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
>  	nand_set_controller_data(chip, host);
>  	mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d",
>  				   host->cs);
> +	if (!mtd->name)
> +		return -ENOMEM;
>  	mtd->owner = THIS_MODULE;
>  	mtd->dev.parent = &pdev->dev;
>  



From boris.brezillon at free-electrons.com  Sat Jan  6 02:03:04 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 11:03:04 +0100
Subject: [PATCH v2] mtd: nand: gpmi: Release DMA channels on failure
In-Reply-To: <1514485078-19762-1-git-send-email-festevam@gmail.com>
References: <1514485078-19762-1-git-send-email-festevam@gmail.com>
Message-ID: <20180106110304.6bf8df65@bbrezillon>

On Thu, 28 Dec 2017 16:17:58 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> release_dma_channels() should be called in the case of error in
> gpmi_init() or bch_set_geometry(), because acquire_dma_channels() has
> been called previously.

I'm really not sure this is a good idea. According to [1], the error
code returned by PM hooks is not taken into account, and the device
will be considered as functional by the system even if
->suspend() returns an error. This means, next time we enter suspend,
gpmi_pm_suspend() will be called which will lead to an unbalanced
release_dma_channels()/acquire_dma_channels().

> 
> Handle the error cases correctly.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
> Changes since v1:
> - Remove extra blank line
> 
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 2ef8979..db0d924 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -2137,20 +2137,24 @@ static int gpmi_pm_resume(struct device *dev)
>  	ret = gpmi_init(this);
>  	if (ret) {
>  		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
> -		return ret;
> +		goto release_dma_channels;
>  	}
>  
>  	/* re-init the BCH registers */
>  	ret = bch_set_geometry(this);
>  	if (ret) {
>  		dev_err(this->dev, "Error setting BCH : %d\n", ret);
> -		return ret;
> +		goto release_dma_channels;
>  	}
>  
>  	/* re-init others */
>  	gpmi_extra_init(this);
>  
>  	return 0;
> +
> +release_dma_channels:
> +	release_dma_channels(this);
> +	return ret;
>  }
>  #endif /* CONFIG_PM_SLEEP */
>  

[1]https://elixir.free-electrons.com/linux/v4.15-rc6/source/include/linux/pm.h#L262


From boris.brezillon at free-electrons.com  Sat Jan  6 02:24:31 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 11:24:31 +0100
Subject: [PATCH 2/2] mtd: nand: gpmi: Support ->setup_data_interface()
In-Reply-To: <20171222172853.27710-3-miquel.raynal@free-electrons.com>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-3-miquel.raynal@free-electrons.com>
Message-ID: <20180106112431.706f857f@bbrezillon>

On Fri, 22 Dec 2017 18:28:53 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Until now the GPMI driver had its own timings logic while the core
> already handles that and request the NAND controller drivers to support
> the ->setup_data_interface() hook. Implement that hook by reusing the
> already existing function. No real glue is necessary between core timing
> delays and GPMI registers because the driver already translates the
> ONFI timing modes into register values.
> 
> Make use of the core's tREA, tRLOH and tRHOH values that allow computing
> more precise timings for mode [0-3] and get significantly better values
> (+20% with an i.MX6 Sabre Auto board). Otherwise use the existing logic.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 266 ++++++++++-----------------------
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  33 ++--
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 146 +++++++++---------
>  3 files changed, 168 insertions(+), 277 deletions(-)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> index 97787246af41..ae47cd8414bf 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> @@ -151,8 +151,15 @@ static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
>  	return ret;
>  }
>  
> -#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
> -#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
> +inline int gpmi_enable_clk(struct gpmi_nand_data *this)

Drop the inline here.

> +{
> +	return __gpmi_enable_clk(this, true);
> +}
> +
> +inline int gpmi_disable_clk(struct gpmi_nand_data *this)

Ditto.

> +{
> +	return __gpmi_enable_clk(this, false);
> +}
>  
>  int gpmi_init(struct gpmi_nand_data *this)
>  {
> @@ -326,11 +333,11 @@ static unsigned int ns_to_cycles(unsigned int time,
>  #define DEF_MIN_PROP_DELAY	5
>  #define DEF_MAX_PROP_DELAY	9
>  /* Apply timing to current hardware conditions. */
> -static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
> -					struct gpmi_nfc_hardware_timing *hw)
> +static void
> +gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
>  {
> +	struct gpmi_nfc_hardware_timing *hw = &this->hw;
>  	struct timing_threshold *nfc = &timing_default_threshold;
> -	struct resources *r = &this->resources;
>  	struct nand_chip *nand = &this->nand;
>  	struct nand_timing target = this->timing;
>  	bool improved_timing_is_available;
> @@ -349,6 +356,9 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>  	unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY;
>  	unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY;
>  
> +	/* Clock rate for non-EDO modes */
> +	hw->clk_rate = 22000000;
> +
>  	/*
>  	 * If there are multiple chips, we need to relax the timings to allow
>  	 * for signal distortion due to higher capacitance.
> @@ -363,14 +373,8 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>  		target.address_setup_in_ns += 5;
>  	}
>  
> -	/* Check if improved timing information is available. */
> -	improved_timing_is_available =
> -		(target.tREA_in_ns  >= 0) &&
> -		(target.tRLOH_in_ns >= 0) &&
> -		(target.tRHOH_in_ns >= 0);
> -
>  	/* Inspect the clock. */
> -	nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
> +	nfc->clock_frequency_in_hz = hw->clk_rate;
>  	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
>  	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
>  
> @@ -482,65 +486,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>  	}
>  
>  	/*
> -	 * Check if improved timing information is available. If not, we have to
> -	 * use a less-sophisticated algorithm.
> -	 */
> -	if (!improved_timing_is_available) {
> -		/*
> -		 * Fold the read setup time required by the NFC into the ideal
> -		 * sample delay.
> -		 */
> -		ideal_sample_delay_in_ns = target.gpmi_sample_delay_in_ns +
> -						nfc->internal_data_setup_in_ns;
> -
> -		/*
> -		 * The ideal sample delay may be greater than the maximum
> -		 * allowed by the NFC. If so, we can trade off sample delay time
> -		 * for more data setup time.
> -		 *
> -		 * In each iteration of the following loop, we add a cycle to
> -		 * the data setup time and subtract a corresponding amount from
> -		 * the sample delay until we've satisified the constraints or
> -		 * can't do any better.
> -		 */
> -		while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
> -			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
> -
> -			data_setup_in_cycles++;
> -			ideal_sample_delay_in_ns -= clock_period_in_ns;
> -
> -			if (ideal_sample_delay_in_ns < 0)
> -				ideal_sample_delay_in_ns = 0;
> -
> -		}
> -
> -		/*
> -		 * Compute the sample delay factor that corresponds most closely
> -		 * to the ideal sample delay. If the result is too large for the
> -		 * NFC, use the maximum value.
> -		 *
> -		 * Notice that we use the ns_to_cycles function to compute the
> -		 * sample delay factor. We do this because the form of the
> -		 * computation is the same as that for calculating cycles.
> -		 */
> -		sample_delay_factor =
> -			ns_to_cycles(
> -				ideal_sample_delay_in_ns << dll_delay_shift,
> -							clock_period_in_ns, 0);
> -
> -		if (sample_delay_factor > nfc->max_sample_delay_factor)
> -			sample_delay_factor = nfc->max_sample_delay_factor;
> -
> -		/* Skip to the part where we return our results. */
> -		goto return_results;
> -	}
> -
> -	/*
> -	 * If control arrives here, we have more detailed timing information,
> -	 * so we can use a better algorithm.
> -	 */
> -
> -	/*
>  	 * Fold the read setup time required by the NFC into the maximum
>  	 * propagation delay.
>  	 */
> @@ -760,8 +705,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>  			sample_delay_factor = nfc->max_sample_delay_factor;
>  	}
>  
> -	/* Control arrives here when we're ready to return our results. */
> -return_results:
>  	hw->data_setup_in_cycles    = data_setup_in_cycles;
>  	hw->data_hold_in_cycles     = data_hold_in_cycles;
>  	hw->address_setup_in_cycles = address_setup_in_cycles;
> @@ -769,9 +712,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>  	hw->sample_delay_factor     = sample_delay_factor;
>  	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
>  	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
> -
> -	/* Return success. */
> -	return 0;
>  }
>  
>  /*
> @@ -857,12 +797,9 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
>   *       So we only support the mode 4 and mode 5. It is no need to
>   *       support other modes.
>   */
> -static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
> -			struct gpmi_nfc_hardware_timing *hw)
> +static void gpmi_nfc_compute_edo_timings(struct gpmi_nand_data *this)
>  {
> -	struct resources *r = &this->resources;
> -	unsigned long rate = clk_get_rate(r->clock[0]);
> -	int mode = this->timing_mode;
> +	struct gpmi_nfc_hardware_timing *hw = &this->hw;
>  	int dll_threshold = this->devdata->max_chain_delay;
>  	unsigned long delay;
>  	unsigned long clk_period;
> @@ -871,6 +808,9 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
>  	int t_rp;
>  	int rp;
>  
> +	/* Set the main clock to: 100MHz (mode 5) or 80MHz (mode 4) */
> +	hw->clk_rate = (hw->timing_mode == 5) ? 100000000 : 80000000;
> +
>  	/*
>  	 * [1] for GPMI_HW_GPMI_TIMING0:
>  	 *     The async mode requires 40MHz for mode 4, 50MHz for mode 5.
> @@ -880,7 +820,7 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
>  	 */
>  	hw->data_setup_in_cycles = 1;
>  	hw->data_hold_in_cycles = 1;
> -	hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
> +	hw->address_setup_in_cycles = (hw->timing_mode == 5) ? 1 : 0;
>  
>  	/* [2] for GPMI_HW_GPMI_TIMING1 */
>  	hw->device_busy_timeout = 0x9000;
> @@ -892,9 +832,9 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
>  	 * Enlarge 10 times for the numerator and denominator in {3}.
>  	 * This make us to get more accurate result.
>  	 */
> -	clk_period = NSEC_PER_SEC / (rate / 10);
> +	clk_period = NSEC_PER_SEC / (hw->clk_rate / 10);
>  	dll_threshold *= 10;
> -	t_rea = ((mode == 5) ? 16 : 20) * 10;
> +	t_rea = (hw->timing_mode == 5 ? 16 : 20) * 10;

Why don't you use the tREA_max value provided in nand_sdr_timings?

>  	c *= 10;
>  
>  	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
> @@ -917,123 +857,36 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
>  	hw->sample_delay_factor = delay;
>  }
>  
> -static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
> -{
> -	struct resources  *r = &this->resources;
> -	struct nand_chip *nand = &this->nand;
> -	struct mtd_info	 *mtd = nand_to_mtd(nand);
> -	uint8_t *feature;
> -	unsigned long rate;
> -	int ret;
> -
> -	feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
> -	if (!feature)
> -		return -ENOMEM;
> -
> -	nand->select_chip(mtd, 0);
> -
> -	/* [1] send SET FEATURE command to NAND */
> -	feature[0] = mode;
> -	ret = nand->onfi_set_features(mtd, nand,
> -				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
> -	if (ret)
> -		goto err_out;
> -
> -	/* [2] send GET FEATURE command to double-check the timing mode */
> -	memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
> -	ret = nand->onfi_get_features(mtd, nand,
> -				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
> -	if (ret || feature[0] != mode)
> -		goto err_out;
> -
> -	nand->select_chip(mtd, -1);
> -
> -	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
> -	rate = (mode == 5) ? 100000000 : 80000000;
> -	clk_set_rate(r->clock[0], rate);
> -
> -	/* Let the gpmi_begin() re-compute the timing again. */
> -	this->flags &= ~GPMI_TIMING_INIT_OK;
> -
> -	this->flags |= GPMI_ASYNC_EDO_ENABLED;
> -	this->timing_mode = mode;
> -	kfree(feature);
> -	dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
> -	return 0;
> -
> -err_out:
> -	nand->select_chip(mtd, -1);
> -	kfree(feature);
> -	dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
> -	return -EINVAL;
> -}
> -
> -int gpmi_extra_init(struct gpmi_nand_data *this)
> -{
> -	struct nand_chip *chip = &this->nand;
> -
> -	/* Enable the asynchronous EDO feature. */
> -	if (GPMI_IS_MX6(this) && chip->onfi_version) {
> -		int mode = onfi_get_async_timing_mode(chip);
> -
> -		/* We only support the timing mode 4 and mode 5. */
> -		if (mode & ONFI_TIMING_MODE_5)
> -			mode = 5;
> -		else if (mode & ONFI_TIMING_MODE_4)
> -			mode = 4;
> -		else
> -			return 0;
> -
> -		return enable_edo_mode(this, mode);
> -	}
> -	return 0;
> -}
> -
>  /* Begin the I/O */
> -void gpmi_begin(struct gpmi_nand_data *this)
> +void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
>  {
> +	struct gpmi_nfc_hardware_timing *hw = &this->hw;
>  	struct resources *r = &this->resources;
>  	void __iomem *gpmi_regs = r->gpmi_regs;
>  	unsigned int   clock_period_in_ns;
>  	uint32_t       reg;
>  	unsigned int   dll_wait_time_in_us;
> -	struct gpmi_nfc_hardware_timing  hw;
> -	int ret;
> -
> -	/* Enable the clock. */
> -	ret = gpmi_enable_clk(this);
> -	if (ret) {
> -		dev_err(this->dev, "We failed in enable the clk\n");
> -		goto err_out;
> -	}
>  
> -	/* Only initialize the timing once */
> -	if (this->flags & GPMI_TIMING_INIT_OK)
> -		return;
> -	this->flags |= GPMI_TIMING_INIT_OK;
> -
> -	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
> -		gpmi_compute_edo_timing(this, &hw);
> -	else
> -		gpmi_nfc_compute_hardware_timing(this, &hw);
> +	/* [0] Set the main clock rate */
> +	clk_set_rate(r->clock[0], hw->clk_rate);
>  
>  	/* [1] Set HW_GPMI_TIMING0 */
> -	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
> -		BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
> -		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
> +	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw->address_setup_in_cycles) |
> +		BF_GPMI_TIMING0_DATA_HOLD(hw->data_hold_in_cycles) |
> +		BF_GPMI_TIMING0_DATA_SETUP(hw->data_setup_in_cycles);
>  
>  	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
>  
>  	/* [2] Set HW_GPMI_TIMING1 */
> -	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
> -		gpmi_regs + HW_GPMI_TIMING1);
> +	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw->device_busy_timeout),
> +	       gpmi_regs + HW_GPMI_TIMING1);
>  
>  	/* [3] The following code is to set the HW_GPMI_CTRL1. */
>  
>  	/* Set the WRN_DLY_SEL */
>  	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
> -	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
> -					gpmi_regs + HW_GPMI_CTRL1_SET);
> +	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw->wrn_dly_sel),
> +	       gpmi_regs + HW_GPMI_CTRL1_SET);
>  
>  	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
>  	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
> @@ -1043,12 +896,12 @@ void gpmi_begin(struct gpmi_nand_data *this)
>  	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
>  
>  	/* If no sample delay is called for, return immediately. */
> -	if (!hw.sample_delay_factor)
> +	if (!hw->sample_delay_factor)
>  		return;
>  
>  	/* Set RDN_DELAY or HALF_PERIOD. */
> -	reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
> -		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
> +	reg = ((hw->use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
> +		| BF_GPMI_CTRL1_RDN_DELAY(hw->sample_delay_factor);
>  
>  	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
>  
> @@ -1060,7 +913,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
>  	 * we can use the GPMI. Calculate the amount of time we need to wait,
>  	 * in microseconds.
>  	 */
> -	clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
> +	clock_period_in_ns = NSEC_PER_SEC / hw->clk_rate;
>  	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
>  
>  	if (!dll_wait_time_in_us)
> @@ -1068,14 +921,45 @@ void gpmi_begin(struct gpmi_nand_data *this)
>  
>  	/* Wait for the DLL to settle. */
>  	udelay(dll_wait_time_in_us);
> -
> -err_out:
> -	return;
>  }
>  
> -void gpmi_end(struct gpmi_nand_data *this)
> +int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
> +			      const struct nand_data_interface *conf)
>  {
> -	gpmi_disable_clk(this);
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct gpmi_nand_data *this = nand_get_controller_data(chip);
> +	const struct nand_sdr_timings *sdr;
> +
> +	if (chip->onfi_timing_mode_default < 0 ||
> +	    chip->onfi_timing_mode_default > 5)
> +		return -ENOTSUPP;

I'd prefer if you could check conf instead of
->onfi_timing_mode_default. I still hope that one day we'll support
per-chip timings for those chips that are not ONFI compliant, and that
means ->onfi_timing_mode_default will be invalid in this case.

> +
> +	/* Only MX6 GPMI controller can reach EDO timings */
> +	if (chip->onfi_timing_mode_default >= 4 && !GPMI_IS_MX6(this))
> +		return -ENOTSUPP;

Ditto: base your check on tRC/tWC.

> +
> +	if (chipnr < 0)
> +		return 0;
> +
> +	this->hw.timing_mode = chip->onfi_timing_mode_default;

Do you really need to keep a copy of the ONFI timing mode?

> +
> +	sdr = nand_get_sdr_timings(conf);
> +	if (IS_ERR(sdr))
> +		return PTR_ERR(sdr);
> +
> +	this->timing.tREA_in_ns = sdr->tREA_max / 1000;
> +	this->timing.tRLOH_in_ns = sdr->tRLOH_min / 1000;
> +	this->timing.tRHOH_in_ns = sdr->tRHOH_min / 1000;
> +
> +	/* Compute GPMI parameters depending on the mode */
> +	if (this->hw.timing_mode >= 4)
> +		gpmi_nfc_compute_edo_timings(this);
> +	else
> +		gpmi_nfc_compute_hardware_timings(this);
> +
> +	gpmi_nfc_apply_timings(this);

Please add a comment saying that this gpmi_nfc_apply_timings()
call should be moved to ->select_chip() if we want to support multiple
NAND chips with different timings. Actually, if that's not to much
effort, I'd prefer to have this moved in gpmi_select_chip() now.

> +
> +	return 0;
>  }
>  
>  /* Clears a BCH interrupt. */
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index b51db8c85405..04986cd89c99 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -938,11 +938,23 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
>  {
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct gpmi_nand_data *this = nand_get_controller_data(chip);
> +	int ret;
>  
> -	if ((this->current_chip < 0) && (chipnr >= 0))
> -		gpmi_begin(this);
> -	else if ((this->current_chip >= 0) && (chipnr < 0))
> -		gpmi_end(this);
> +	/*
> +	 * This driver currently supports only one NAND chip. So once timings
> +	 * have been decided, they will not change. Furthermore, dies share the
> +	 * same configuration, so for power consumption matters, we only
> +	 * disable/enable the clock.
> +	 */
> +	if (this->current_chip < 0 && chipnr >= 0) {
> +		ret = gpmi_enable_clk(this);
> +		if (ret)
> +			dev_err(this->dev, "Failed to enable the clock\n");
> +	} else if (this->current_chip >= 0 && chipnr < 0) {
> +		ret = gpmi_disable_clk(this);
> +		if (ret)
> +			dev_err(this->dev, "Failed to disable the clock\n");
> +	}
>  
>  	this->current_chip = chipnr;
>  }
> @@ -1947,14 +1959,6 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
>  		chip->options |= NAND_SUBPAGE_READ;
>  	}
>  
> -	/*
> -	 * Can we enable the extra features? such as EDO or Sync mode.
> -	 *
> -	 * We do not check the return value now. That's means if we fail in
> -	 * enable the extra features, we still can run in the normal way.
> -	 */
> -	gpmi_extra_init(this);
> -
>  	return 0;
>  }
>  
> @@ -1975,6 +1979,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
>  	nand_set_controller_data(chip, this);
>  	nand_set_flash_node(chip, this->pdev->dev.of_node);
>  	chip->select_chip	= gpmi_select_chip;
> +	chip->setup_data_interface = gpmi_setup_data_interface;
>  	chip->cmd_ctrl		= gpmi_cmd_ctrl;
>  	chip->dev_ready		= gpmi_dev_ready;
>  	chip->read_byte		= gpmi_read_byte;
> @@ -2133,7 +2138,6 @@ static int gpmi_pm_resume(struct device *dev)
>  		return ret;
>  
>  	/* re-init the GPMI registers */
> -	this->flags &= ~GPMI_TIMING_INIT_OK;
>  	ret = gpmi_init(this);
>  	if (ret) {
>  		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
> @@ -2147,9 +2151,6 @@ static int gpmi_pm_resume(struct device *dev)
>  		return ret;
>  	}
>  
> -	/* re-init others */
> -	gpmi_extra_init(this);
> -
>  	return 0;
>  }
>  #endif /* CONFIG_PM_SLEEP */
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> index 06c1f993912c..4890e1378475 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> @@ -135,11 +135,77 @@ struct gpmi_devdata {
>  	const int clks_count;
>  };
>  
> +/**
> + * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
> + * @timing_mode:               The timing mode to comply with.
> + * @clk_rate:                  The clock rate that must be used to derive the
> + *                             following parameters.
> + * @data_setup_in_cycles:      The data setup time, in cycles.
> + * @data_hold_in_cycles:       The data hold time, in cycles.
> + * @address_setup_in_cycles:   The address setup time, in cycles.
> + * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
> + *                             this value is the number of cycles multiplied
> + *                             by 4096.
> + * @use_half_periods:          Indicates the clock is running slowly, so the
> + *                             NFC DLL should use half-periods.
> + * @sample_delay_factor:       The sample delay factor.
> + * @wrn_dly_sel:               The delay on the GPMI write strobe.
> + */
> +struct gpmi_nfc_hardware_timing {
> +	unsigned int timing_mode;
> +	unsigned long int clk_rate;
> +
> +	/* for HW_GPMI_TIMING0 */
> +	u8 data_setup_in_cycles;
> +	u8 data_hold_in_cycles;
> +	u8 address_setup_in_cycles;
> +
> +	/* for HW_GPMI_TIMING1 */
> +	u16 device_busy_timeout;
> +#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
> +
> +	/* for HW_GPMI_CTRL1 */
> +	bool use_half_periods;
> +	u8 sample_delay_factor;
> +	u8 wrn_dly_sel;

Hm, why not having 3 u32 fields containing the values to program in
TIMING0, TIMING1 and CTRL1?

> +};
> +
> +/**
> + * struct timing_threshold - Timing threshold
> + * @max_data_setup_cycles:       The maximum number of data setup cycles that
> + *                               can be expressed in the hardware.
> + * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
> + *                               for data read internal setup. In the Reference
> + *                               Manual, see the chapter "High-Speed NAND
> + *                               Timing" for more details.
> + * @max_sample_delay_factor:     The maximum sample delay factor that can be
> + *                               expressed in the hardware.
> + * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
> + *                               sample delay DLL hardware can possibly work
> + *                               with (the DLL is unusable with longer periods).
> + *                               If the full-cycle period is greater than HALF
> + *                               this value, the DLL must be configured to use
> + *                               half-periods.
> + * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
> + *                               DLL can implement.
> + * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
> + *                               I/O transaction. If no I/O transaction is in
> + *                               progress, this is the clock frequency during
> + *                               the most recent I/O transaction.
> + */
> +struct timing_threshold {
> +	const unsigned int      max_chip_count;
> +	const unsigned int      max_data_setup_cycles;
> +	const unsigned int      internal_data_setup_in_ns;
> +	const unsigned int      max_sample_delay_factor;
> +	const unsigned int      max_dll_clock_period_in_ns;
> +	const unsigned int      max_dll_delay_in_ns;
> +	unsigned long           clock_frequency_in_hz;
> +
> +};

Not sure why you're moving this definition here.

> +
>  struct gpmi_nand_data {
> -	/* flags */
> -#define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
> -#define GPMI_TIMING_INIT_OK	(1 << 1)
> -	int			flags;
> +	/* Devdata */
>  	const struct gpmi_devdata *devdata;
>  
>  	/* System Interface */
> @@ -152,6 +218,7 @@ struct gpmi_nand_data {
>  	/* Flash Hardware */
>  	struct nand_timing	timing;
>  	int			timing_mode;
> +	struct gpmi_nfc_hardware_timing hw;
>  
>  	/* BCH */
>  	struct bch_geometry	bch_geometry;
> @@ -204,69 +271,6 @@ struct gpmi_nand_data {
>  	void			*private;
>  };
>  
> -/**
> - * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
> - * @data_setup_in_cycles:      The data setup time, in cycles.
> - * @data_hold_in_cycles:       The data hold time, in cycles.
> - * @address_setup_in_cycles:   The address setup time, in cycles.
> - * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
> - *                             this value is the number of cycles multiplied
> - *                             by 4096.
> - * @use_half_periods:          Indicates the clock is running slowly, so the
> - *                             NFC DLL should use half-periods.
> - * @sample_delay_factor:       The sample delay factor.
> - * @wrn_dly_sel:               The delay on the GPMI write strobe.
> - */
> -struct gpmi_nfc_hardware_timing {
> -	/* for HW_GPMI_TIMING0 */
> -	uint8_t  data_setup_in_cycles;
> -	uint8_t  data_hold_in_cycles;
> -	uint8_t  address_setup_in_cycles;
> -
> -	/* for HW_GPMI_TIMING1 */
> -	uint16_t device_busy_timeout;
> -#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
> -
> -	/* for HW_GPMI_CTRL1 */
> -	bool     use_half_periods;
> -	uint8_t  sample_delay_factor;
> -	uint8_t  wrn_dly_sel;
> -};
> -
> -/**
> - * struct timing_threshold - Timing threshold
> - * @max_data_setup_cycles:       The maximum number of data setup cycles that
> - *                               can be expressed in the hardware.
> - * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
> - *                               for data read internal setup. In the Reference
> - *                               Manual, see the chapter "High-Speed NAND
> - *                               Timing" for more details.
> - * @max_sample_delay_factor:     The maximum sample delay factor that can be
> - *                               expressed in the hardware.
> - * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
> - *                               sample delay DLL hardware can possibly work
> - *                               with (the DLL is unusable with longer periods).
> - *                               If the full-cycle period is greater than HALF
> - *                               this value, the DLL must be configured to use
> - *                               half-periods.
> - * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
> - *                               DLL can implement.
> - * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
> - *                               I/O transaction. If no I/O transaction is in
> - *                               progress, this is the clock frequency during
> - *                               the most recent I/O transaction.
> - */
> -struct timing_threshold {
> -	const unsigned int      max_chip_count;
> -	const unsigned int      max_data_setup_cycles;
> -	const unsigned int      internal_data_setup_in_ns;
> -	const unsigned int      max_sample_delay_factor;
> -	const unsigned int      max_dll_clock_period_in_ns;
> -	const unsigned int      max_dll_delay_in_ns;
> -	unsigned long           clock_frequency_in_hz;
> -
> -};
> -
>  /* Common Services */
>  int common_nfc_set_geometry(struct gpmi_nand_data *);
>  struct dma_chan *get_dma_chan(struct gpmi_nand_data *);
> @@ -279,14 +283,16 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *,
>  
>  /* GPMI-NAND helper function library */
>  int gpmi_init(struct gpmi_nand_data *);
> -int gpmi_extra_init(struct gpmi_nand_data *);
>  void gpmi_clear_bch(struct gpmi_nand_data *);
>  void gpmi_dump_info(struct gpmi_nand_data *);
>  int bch_set_geometry(struct gpmi_nand_data *);
>  int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
>  int gpmi_send_command(struct gpmi_nand_data *);
> -void gpmi_begin(struct gpmi_nand_data *);
> -void gpmi_end(struct gpmi_nand_data *);
> +int gpmi_enable_clk(struct gpmi_nand_data *this);
> +int gpmi_disable_clk(struct gpmi_nand_data *this);
> +int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
> +			      const struct nand_data_interface *conf);
> +void gpmi_nfc_apply_timings(struct gpmi_nand_data *this);
>  int gpmi_read_data(struct gpmi_nand_data *);
>  int gpmi_send_data(struct gpmi_nand_data *);
>  int gpmi_send_page(struct gpmi_nand_data *,



From elfring at users.sourceforge.net  Sat Jan  6 04:44:31 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 13:44:31 +0100
Subject: [PATCH 0/3] mtd/nftlmount: Adjustments for seven function
 implementations
Message-ID: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 13:38:32 +0100

Three update suggestions were taken into account
from static source code analysis.

Markus Elfring (3):
  Delete two error messages for a failed memory allocation in find_boot_record()
  Delete eight unwanted spaces behind function names
  Add some spaces for better code readability

 drivers/mtd/nftlmount.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 04:45:35 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 13:45:35 +0100
Subject: [PATCH 1/3] mtd/nftlmount: Delete two error messages for a failed
 memory allocation in find_boot_record()
In-Reply-To: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
References: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
Message-ID: <e07f94b5-3589-2fe3-3058-8fcf83a77af0@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 11:04:59 +0100

Omit extra messages for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nftlmount.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 184c8fbfe465..6b9634a70229 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -201,15 +201,12 @@ device is already correct.
 
 		/* memory alloc */
 		nftl->EUNtable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-		if (!nftl->EUNtable) {
-			printk(KERN_NOTICE "NFTL: allocation of EUNtable failed\n");
+		if (!nftl->EUNtable)
 			return -ENOMEM;
-		}
 
 		nftl->ReplUnitTable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL);
 		if (!nftl->ReplUnitTable) {
 			kfree(nftl->EUNtable);
-			printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
 			return -ENOMEM;
 		}
 
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 04:46:39 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 13:46:39 +0100
Subject: [PATCH 2/3] mtd/nftlmount: Delete eight unwanted spaces behind
 function names
In-Reply-To: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
References: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
Message-ID: <0095db26-a0ff-a400-3509-6085d701ecab@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 12:55:23 +0100

The script "checkpatch.pl" pointed information out like the following.

WARNING: space prohibited between function name and open parenthesis '('

Thus fix the affected source code places.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nftlmount.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 6b9634a70229..d1eaa87c88ba 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -314,7 +314,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
 			  8, &retlen, (char *)&uci) < 0)
 		goto default_uci1;
 
-	erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1));
+	erase_mark = le16_to_cpu(uci.EraseMark | uci.EraseMark1);
 	if (erase_mark != ERASE_MARK) {
 	default_uci1:
 		uci.EraseMark = cpu_to_le16(ERASE_MARK);
@@ -501,11 +501,12 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 			  &retlen, (char *)&h1) < 0)
 		return -1;
 
-	erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
+	erase_mark = le16_to_cpu(h1.EraseMark | h1.EraseMark1);
 	if (erase_mark != ERASE_MARK) {
 		/* if no erase mark, the block must be totally free. This is
 		   possible in two cases : empty filesystem or interrupted erase (very unlikely) */
-		if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0)
+		if (check_free_sectors(nftl, block * nftl->EraseSize,
+				       nftl->EraseSize, 1) != 0)
 			return -1;
 
 		/* free block : write erase mark */
@@ -521,8 +522,9 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 		/* if erase mark present, need to skip it when doing check */
 		for (i = 0; i < nftl->EraseSize; i += SECTORSIZE) {
 			/* check free sector */
-			if (check_free_sectors (nftl, block * nftl->EraseSize + i,
-						SECTORSIZE, 0) != 0)
+			if (check_free_sectors(nftl,
+					       block * nftl->EraseSize + i,
+					       SECTORSIZE, 0) != 0)
 				return -1;
 
 			if (nftl_read_oob(mtd, block * nftl->EraseSize + i,
@@ -608,10 +610,13 @@ int NFTL_mount(struct NFTLrecord *s)
 					break;
 				}
 
-				logical_block = le16_to_cpu ((h0.VirtUnitNum | h0.SpareVirtUnitNum));
-				rep_block = le16_to_cpu ((h0.ReplUnitNum | h0.SpareReplUnitNum));
-				nb_erases = le32_to_cpu (h1.WearInfo);
-				erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
+				logical_block = le16_to_cpu(h0.VirtUnitNum |
+							    h0.SpareVirtUnitNum);
+				rep_block = le16_to_cpu(h0.ReplUnitNum |
+							h0.SpareReplUnitNum);
+				nb_erases = le32_to_cpu(h1.WearInfo);
+				erase_mark = le16_to_cpu(h1.EraseMark |
+							 h1.EraseMark1);
 
 				is_first_block = !(logical_block >> 15);
 				logical_block = logical_block & 0x7fff;
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 04:47:37 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 13:47:37 +0100
Subject: [PATCH 3/3] mtd/nftlmount: Add some spaces for better code readability
In-Reply-To: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
References: <57d4cbcf-c99c-f3d5-e2bf-f67873f321ea@users.sourceforge.net>
Message-ID: <a0ebf648-a73a-e3ff-5ca9-e84598d4196c@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 12:58:37 +0100

Use space characters at some source code places according to
the Linux coding style convention.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/nftlmount.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index d1eaa87c88ba..457f3572c582 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -253,7 +253,7 @@ The new DiskOnChip driver already scanned the bad block table.  Just query it.
 
 	} /* foreach (block) */
 
-	return boot_record_count?0:-1;
+	return boot_record_count ? 0 : -1;
 }
 
 static int memcmpb(void *a, int c, int n)
@@ -282,8 +282,8 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
 			return -1;
 
 		if (check_oob) {
-			if(nftl_read_oob(mtd, address, mtd->oobsize,
-					 &retlen, &buf[SECTORSIZE]) < 0)
+			if (nftl_read_oob(mtd, address, mtd->oobsize,
+					  &retlen, &buf[SECTORSIZE]) < 0)
 				return -1;
 			if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
 				return -1;
@@ -389,7 +389,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
 			else
 				status = bci.Status | bci.Status1;
 
-			switch(status) {
+			switch (status) {
 			case SECTOR_FREE:
 				/* verify that the sector is really free. If not, mark
 				   as ignore */
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:06:37 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:06:37 +0100
Subject: [PATCH 0/5] mtd/rfd_ftl: Adjustments for some function implementations
Message-ID: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 16:00:01 +0100

A few update suggestions were taken into account
from static source code analysis.

Markus Elfring (5):
  Delete an error message for a failed memory allocation in scan_header()
  Less function calls in scan_header() after error detection
  Improve a size determination in two functions
  Return directly after a failed kmalloc() in erase_block()
  Add some spaces for better code readability

 drivers/mtd/rfd_ftl.c | 45 +++++++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:07:45 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:07:45 +0100
Subject: [PATCH 1/5] mtd/rfd_ftl: Delete an error message for a failed memory
 allocation in scan_header()
In-Reply-To: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
References: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
Message-ID: <90d58d5f-73e4-b47e-d013-19cd84c4ccda@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 14:07:31 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/rfd_ftl.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index d1cbf26db2c0..efff25f15d5b 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -190,11 +190,8 @@ static int scan_header(struct partition *part)
 		goto err;
 
 	part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
-	if (!part->sector_map) {
-		printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
-			"sector map", part->mbd.mtd->name);
+	if (!part->sector_map)
 		goto err;
-	}
 
 	for (i=0; i<part->sector_count; i++)
 		part->sector_map[i] = -1;
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:08:51 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:08:51 +0100
Subject: [PATCH 2/5] mtd/rfd_ftl: Less function calls in scan_header() after
 error detection
In-Reply-To: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
References: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
Message-ID: <6f10248e-d2c9-3c48-922c-be95ac5caba9@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 14:50:58 +0100

The functions "kfree" and "vfree" were called in three cases
by the scan_header() function during error handling even if
the passed data structure member contained a null pointer.

Adjust jump targets according to the Linux coding style convention.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/rfd_ftl.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index efff25f15d5b..19e14f909dc6 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -182,16 +182,16 @@ static int scan_header(struct partition *part)
 
 	part->header_cache = kmalloc(part->header_size, GFP_KERNEL);
 	if (!part->header_cache)
-		goto err;
+		return -ENOMEM;
 
 	part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
 			GFP_KERNEL);
 	if (!part->blocks)
-		goto err;
+		goto free_cache;
 
 	part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
 	if (!part->sector_map)
-		goto err;
+		goto free_blocks;
 
 	for (i=0; i<part->sector_count; i++)
 		part->sector_map[i] = -1;
@@ -229,9 +229,10 @@ static int scan_header(struct partition *part)
 
 err:
 	vfree(part->sector_map);
-	kfree(part->header_cache);
+free_blocks:
 	kfree(part->blocks);
-
+free_cache:
+	kfree(part->header_cache);
 	return rc;
 }
 
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:09:44 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:09:44 +0100
Subject: [PATCH 3/5] mtd/rfd_ftl: Improve a size determination in two functions
In-Reply-To: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
References: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
Message-ID: <dc2790d6-6c96-65e4-5407-a2440f5a97e8@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 15:03:29 +0100

Replace the specification of data structures by pointer dereferences
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/rfd_ftl.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 19e14f909dc6..dcf1b88e1193 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -323,10 +323,9 @@ static void erase_callback(struct erase_info *erase)
 
 static int erase_block(struct partition *part, int block)
 {
-	struct erase_info *erase;
 	int rc = -ENOMEM;
+	struct erase_info *erase = kmalloc(sizeof(*erase), GFP_KERNEL);
 
-	erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
 	if (!erase)
 		goto err;
 
@@ -759,7 +758,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	if (mtd->type != MTD_NORFLASH || mtd->size > UINT_MAX)
 		return;
 
-	part = kzalloc(sizeof(struct partition), GFP_KERNEL);
+	part = kzalloc(sizeof(*part), GFP_KERNEL);
 	if (!part)
 		return;
 
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:10:40 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:10:40 +0100
Subject: [PATCH 4/5] mtd/rfd_ftl: Return directly after a failed kmalloc() in
 erase_block()
In-Reply-To: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
References: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
Message-ID: <7b381eef-c54f-d2c9-7281-a90d519c22f1@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 15:18:28 +0100

* Return directly after a call of the function "kmalloc" failed
  at the beginning.

* Delete an initialisation for the variable "rc" and the jump label "err"
  which became unnecessary with this refactoring.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/rfd_ftl.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index dcf1b88e1193..e3155ec4be64 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -323,11 +323,11 @@ static void erase_callback(struct erase_info *erase)
 
 static int erase_block(struct partition *part, int block)
 {
-	int rc = -ENOMEM;
+	int rc;
 	struct erase_info *erase = kmalloc(sizeof(*erase), GFP_KERNEL);
 
 	if (!erase)
-		goto err;
+		return -ENOMEM;
 
 	erase->mtd = part->mbd.mtd;
 	erase->callback = erase_callback;
@@ -346,8 +346,6 @@ static int erase_block(struct partition *part, int block)
 				(unsigned long long)erase->len, part->mbd.mtd->name);
 		kfree(erase);
 	}
-
-err:
 	return rc;
 }
 
-- 
2.15.1



From elfring at users.sourceforge.net  Sat Jan  6 07:11:38 2018
From: elfring at users.sourceforge.net (SF Markus Elfring)
Date: Sat, 6 Jan 2018 16:11:38 +0100
Subject: [PATCH 5/5] mtd/rfd_ftl: Add some spaces for better code readability
In-Reply-To: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
References: <a595376a-c343-33ea-8607-370b88e19c61@users.sourceforge.net>
Message-ID: <847904e4-c5a2-0716-24ae-c2ac085fe3a3@users.sourceforge.net>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Sat, 6 Jan 2018 15:47:01 +0100

Use space characters at some source code places according to
the Linux coding style convention.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/mtd/rfd_ftl.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index e3155ec4be64..b6cc3690b9ed 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -103,7 +103,7 @@ static int build_block_map(struct partition *part, int block_no)
 
 	block->state = BLOCK_OK;
 
-	for (i=0; i<part->data_sectors_per_block; i++) {
+	for (i = 0; i < part->data_sectors_per_block; i++) {
 		u16 entry;
 
 		entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
@@ -193,10 +193,10 @@ static int scan_header(struct partition *part)
 	if (!part->sector_map)
 		goto free_blocks;
 
-	for (i=0; i<part->sector_count; i++)
+	for (i = 0; i < part->sector_count; i++)
 		part->sector_map[i] = -1;
 
-	for (i=0, blocks_found=0; i<part->total_blocks; i++) {
+	for (i = 0, blocks_found = 0; i < part->total_blocks; i++) {
 		rc = mtd_read(part->mbd.mtd, i * part->block_size,
 			      part->header_size, &retlen,
 			      (u_char *)part->header_cache);
@@ -380,7 +380,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
 		goto err;
 	}
 
-	for (i=0; i<part->data_sectors_per_block; i++) {
+	for (i = 0; i < part->data_sectors_per_block; i++) {
 		u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]);
 		u_long addr;
 
@@ -452,7 +452,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
 	else
 		old_sector_block = -1;
 
-	for (block=0; block<part->total_blocks; block++) {
+	for (block = 0; block < part->total_blocks; block++) {
 		int this_score;
 
 		if (block == part->reserved_block)
@@ -625,8 +625,7 @@ static int find_free_sector(const struct partition *part, const struct block *bl
 
 		if (++i == part->data_sectors_per_block)
 			i = 0;
-	}
-	while(i != stop);
+	} while (i != stop);
 
 	return -1;
 }
@@ -718,7 +717,7 @@ static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *
 
 	old_addr = part->sector_map[sector];
 
-	for (i=0; i<SECTOR_SIZE; i++) {
+	for (i = 0; i < SECTOR_SIZE; i++) {
 		if (!buf[i])
 			continue;
 
@@ -799,10 +798,9 @@ static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
 	struct partition *part = (struct partition*)dev;
 	int i;
 
-	for (i=0; i<part->total_blocks; i++) {
+	for (i = 0; i < part->total_blocks; i++)
 		pr_debug("rfd_ftl_remove_dev:'%s': erase unit #%02d: %d erases\n",
 			part->mbd.mtd->name, i, part->blocks[i].erases);
-	}
 
 	del_mtd_blktrans_dev(dev);
 	vfree(part->sector_map);
-- 
2.15.1



From boris.brezillon at free-electrons.com  Sat Jan  6 12:40:00 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 21:40:00 +0100
Subject: [PATCH 2/2] mtd: brcmnand: Add a NULL check for devm_kasprintf()
In-Reply-To: <20180106103557.6612a12c@bbrezillon>
References: <1515182576-2704-1-git-send-email-festevam@gmail.com>
 <1515182576-2704-2-git-send-email-festevam@gmail.com>
 <20180106103557.6612a12c@bbrezillon>
Message-ID: <20180106214000.4d75c709@bbrezillon>

On Sat, 6 Jan 2018 10:35:57 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hi Fabio,
> 
> The prefix should be "mtd: nand: brcmnand: ".
> 
> No need to resend, I'll fix it when applying.
> 
> Thanks,
> 
> Boris
> 
> On Fri,  5 Jan 2018 18:02:56 -0200
> Fabio Estevam <festevam at gmail.com> wrote:
> 
> > From: Fabio Estevam <fabio.estevam at nxp.com>
> > 
> > devm_kasprintf() may fail, so we should better add a NULL check
> > and propagate an error on failure.
> > 
> > Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>

Applied.

Thanks,

Boris

> > ---
> >  drivers/mtd/nand/brcmnand/brcmnand.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
> > index 3310e14..8942aa6 100644
> > --- a/drivers/mtd/nand/brcmnand/brcmnand.c
> > +++ b/drivers/mtd/nand/brcmnand/brcmnand.c
> > @@ -2237,6 +2237,8 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
> >  	nand_set_controller_data(chip, host);
> >  	mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d",
> >  				   host->cs);
> > +	if (!mtd->name)
> > +		return -ENOMEM;
> >  	mtd->owner = THIS_MODULE;
> >  	mtd->dev.parent = &pdev->dev;
> >    
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From boris.brezillon at free-electrons.com  Sat Jan  6 12:40:34 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 21:40:34 +0100
Subject: [PATCH] mtd: nand: Fix unfinished comment in
 nand_init_data_interface()
In-Reply-To: <20171222171241.27416-1-miquel.raynal@free-electrons.com>
References: <20171222171241.27416-1-miquel.raynal@free-electrons.com>
Message-ID: <20180106214034.109858db@bbrezillon>

On Fri, 22 Dec 2017 18:12:41 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Give an unfinished comment a meaning.

Applied.

Thanks,

Boris

> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/nand_base.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index ab8ad9e8a8d8..96c97588e1ba 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -1284,7 +1284,10 @@ static int nand_init_data_interface(struct nand_chip *chip)
>  		if (ret)
>  			continue;
>  
> -		/* Pass -1 to only */
> +		/*
> +		 * Pass NAND_DATA_IFACE_CHECK_ONLY to only check if the
> +		 * controller supports the requested timings.
> +		 */
>  		ret = chip->setup_data_interface(mtd,
>  						 NAND_DATA_IFACE_CHECK_ONLY,
>  						 &chip->data_interface);



From boris.brezillon at free-electrons.com  Sat Jan  6 12:43:41 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 21:43:41 +0100
Subject: [PATCH v3 0/4] mtd: Preparation patches for the SPI NAND framework
In-Reply-To: <20171215123954.30017-1-boris.brezillon@free-electrons.com>
References: <20171215123954.30017-1-boris.brezillon@free-electrons.com>
Message-ID: <20180106214341.606213db@bbrezillon>

On Fri, 15 Dec 2017 13:39:50 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hello,
> 
> Here is a set of patches to prepare the introduction of the generic
> NAND and SPI frameworks.
> 
> The last 2 patches have already been submitted here [1], and the first
> two are new, and should also help simplify other drivers/frameworks
> in providing generic code for already existing logic.
> 
> If you want to see the overall picture of the SPI NAND framework you can
> have a look at this branch [2].
> 
> Regards,
> 
> Boris
> 
> [1]https://patchwork.ozlabs.org/patch/780477/
> [2]https://github.com/bbrezillon/linux-0day/commits/nand/spi-nand-squashed
> 
> Boris Brezillon (4):
>   mtd: Do not allow MTD devices with inconsistent erase properties
>   mtd: Add an helper to make erase request aligned on ->erasesize
>   mtd: Stop directly calling master ->_xxx() hooks from mtdpart code
>   mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing

Applied the whole series. I'm preparing a patch to remove unneeded
checks done in part_read/write_oob() (as suggested by Peter).

> 
>  drivers/mtd/devices/docg3.c        |  65 -----------------
>  drivers/mtd/mtdcore.c              |  36 +++++++++-
>  drivers/mtd/mtdpart.c              | 141 ++++++++++++++-----------------------
>  drivers/mtd/nand/nand_base.c       |  56 ---------------
>  drivers/mtd/onenand/onenand_base.c |  63 -----------------
>  include/linux/mtd/mtd.h            |  28 ++++++++
>  6 files changed, 115 insertions(+), 274 deletions(-)
> 



From boris.brezillon at free-electrons.com  Sat Jan  6 12:44:13 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 6 Jan 2018 21:44:13 +0100
Subject: [PATCH -next] mtd: sharpslpart: make local function
 sharpsl_nand_cleanup_ftl() static
In-Reply-To: <CAAQYJAuOy65Obc+HmtmvwSLB5js-rvLZ5D=6kcDgcxDZQYKebQ@mail.gmail.com>
References: <1513748736-165067-1-git-send-email-weiyongjun1@huawei.com>
 <CAAQYJAuOy65Obc+HmtmvwSLB5js-rvLZ5D=6kcDgcxDZQYKebQ@mail.gmail.com>
Message-ID: <20180106214413.7a8f9eea@bbrezillon>

On Fri, 22 Dec 2017 11:09:15 +0100
Andrea Adami <andrea.adami at gmail.com> wrote:

> On Wed, Dec 20, 2017 at 6:45 AM, Wei Yongjun <weiyongjun1 at huawei.com> wrote:
> > Fixes the following sparse warnings:
> >
> > drivers/mtd/parsers/sharpslpart.c:222:6: warning:
> >  symbol 'sharpsl_nand_cleanup_ftl' was not declared. Should it be static?
> >
> > Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
> > ---
> >  drivers/mtd/parsers/sharpslpart.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/mtd/parsers/sharpslpart.c b/drivers/mtd/parsers/sharpslpart.c
> > index 0ddb79a..8893dc8 100644
> > --- a/drivers/mtd/parsers/sharpslpart.c
> > +++ b/drivers/mtd/parsers/sharpslpart.c
> > @@ -219,7 +219,7 @@ static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl)
> >         return ret;
> >  }
> >
> > -void sharpsl_nand_cleanup_ftl(struct sharpsl_ftl *ftl)
> > +static void sharpsl_nand_cleanup_ftl(struct sharpsl_ftl *ftl)
> >  {
> >         kfree(ftl->log2phy);
> >  }
> >  
> 
> Thanks, this should be indeed static like the other functions.
> 
> Acked-by: Andrea Adami <andrea.adami at gmail.com>
> 

Applied.

Thanks,

Boris

> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From boris.brezillon at free-electrons.com  Sat Jan  6 12:49:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat,  6 Jan 2018 21:49:17 +0100
Subject: [PATCH] mtd: Remove unneeded checks in part_{read,write}_oob()
Message-ID: <20180106204917.1266-1-boris.brezillon@free-electrons.com>

mtd_{read,write}_oob() are already checking parameters consistency,
remove the checks done in part_{read,write}_oob().

Suggested-by: Peter Pan <peterpansjtu at gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 drivers/mtd/mtdpart.c | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 4d1140c23ead..88f94d672e40 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -117,25 +117,6 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 	struct mtd_part *part = mtd_to_part(mtd);
 	int res;
 
-	if (from >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && from + ops->len > mtd->size)
-		return -EINVAL;
-
-	/*
-	 * If OOB is also requested, make sure that we do not read past the end
-	 * of this partition.
-	 */
-	if (ops->oobbuf) {
-		size_t len, pages;
-
-		len = mtd_oobavail(mtd, ops);
-		pages = mtd_div_by_ws(mtd->size, mtd);
-		pages -= mtd_div_by_ws(from, mtd);
-		if (ops->ooboffs + ops->ooblen > pages * len)
-			return -EINVAL;
-	}
-
 	res = mtd_read_oob(part->parent, from + part->offset, ops);
 	if (unlikely(res)) {
 		if (mtd_is_bitflip(res))
@@ -194,10 +175,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
 	struct mtd_part *part = mtd_to_part(mtd);
 
-	if (to >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && to + ops->len > mtd->size)
-		return -EINVAL;
 	return mtd_write_oob(part->parent, to + part->offset, ops);
 }
 
-- 
2.11.0



From richard at nod.at  Sun Jan  7 01:36:18 2018
From: richard at nod.at (Richard Weinberger)
Date: Sun, 07 Jan 2018 10:36:18 +0100
Subject: [GIT PULL] final MTD fixes for v4.15
Message-ID: <5737666.9mBnCfRmi7@blindfold>

Linus,

The following changes since commit 30a7acd573899fd8b8ac39236eff6468b195ac7d:

  Linux 4.15-rc6 (2017-12-31 14:47:43 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/for-linus-20180107

for you to fetch changes up to fee4380f368e84ed216b62ccd2fbc4126f2bf40b:

  mtd: nand: pxa3xx: Fix READOOB implementation (2018-01-06 23:06:58 +0100)

----------------------------------------------------------------
This pull request contains a single fix for the pxa3xx NAND driver.

----------------------------------------------------------------
Boris Brezillon (1):
      mtd: nand: pxa3xx: Fix READOOB implementation

 drivers/mtd/nand/pxa3xx_nand.c | 1 +
 1 file changed, 1 insertion(+)



From boris.brezillon at free-electrons.com  Sun Jan  7 02:04:59 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 11:04:59 +0100
Subject: [PATCH 1/2] mtd: qcom_nandc: Add a NULL check for devm_kasprintf()
In-Reply-To: <1515182576-2704-1-git-send-email-festevam@gmail.com>
References: <1515182576-2704-1-git-send-email-festevam@gmail.com>
Message-ID: <20180107110459.01beed46@bbrezillon>

On Fri,  5 Jan 2018 18:02:55 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> devm_kasprintf() may fail, so we should better add a NULL check
> and propagate an error on failure.

Applied (also fixed the subject prefix).

Thanks,

Boris

> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
>  drivers/mtd/nand/qcom_nandc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
> index 245d0f3..3fe2ff8 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -2639,6 +2639,8 @@ static int qcom_nand_host_init(struct qcom_nand_controller *nandc,
>  
>  	nand_set_flash_node(chip, dn);
>  	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "qcom_nand.%d", host->cs);
> +	if (!mtd->name)
> +		return -ENOMEM;
>  	mtd->owner = THIS_MODULE;
>  	mtd->dev.parent = dev;
>  



From boris.brezillon at free-electrons.com  Sun Jan  7 02:16:47 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 11:16:47 +0100
Subject: [PATCH] mtd: Remove unneeded checks in part_{read,write}_oob()
In-Reply-To: <20180106204917.1266-1-boris.brezillon@free-electrons.com>
References: <20180106204917.1266-1-boris.brezillon@free-electrons.com>
Message-ID: <20180107111647.191e2a7b@bbrezillon>

On Sat,  6 Jan 2018 21:49:17 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> mtd_{read,write}_oob() are already checking parameters consistency,
> remove the checks done in part_{read,write}_oob().

Please ignore this patch. I realized I had already submitted a patch
removing redundant checks in various drivers/sub-layers [1], so I'll
just prepare a v2 of this patch integrating the mtdpart changes.

Regards,

Boris

[1]http://patchwork.ozlabs.org/patch/781354/

> 
> Suggested-by: Peter Pan <peterpansjtu at gmail.com>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
>  drivers/mtd/mtdpart.c | 23 -----------------------
>  1 file changed, 23 deletions(-)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index 4d1140c23ead..88f94d672e40 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -117,25 +117,6 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  	struct mtd_part *part = mtd_to_part(mtd);
>  	int res;
>  
> -	if (from >= mtd->size)
> -		return -EINVAL;
> -	if (ops->datbuf && from + ops->len > mtd->size)
> -		return -EINVAL;
> -
> -	/*
> -	 * If OOB is also requested, make sure that we do not read past the end
> -	 * of this partition.
> -	 */
> -	if (ops->oobbuf) {
> -		size_t len, pages;
> -
> -		len = mtd_oobavail(mtd, ops);
> -		pages = mtd_div_by_ws(mtd->size, mtd);
> -		pages -= mtd_div_by_ws(from, mtd);
> -		if (ops->ooboffs + ops->ooblen > pages * len)
> -			return -EINVAL;
> -	}
> -
>  	res = mtd_read_oob(part->parent, from + part->offset, ops);
>  	if (unlikely(res)) {
>  		if (mtd_is_bitflip(res))
> @@ -194,10 +175,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
>  {
>  	struct mtd_part *part = mtd_to_part(mtd);
>  
> -	if (to >= mtd->size)
> -		return -EINVAL;
> -	if (ops->datbuf && to + ops->len > mtd->size)
> -		return -EINVAL;
>  	return mtd_write_oob(part->parent, to + part->offset, ops);
>  }
>  



From boris.brezillon at free-electrons.com  Sun Jan  7 02:18:43 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun,  7 Jan 2018 11:18:43 +0100
Subject: [PATCH v2] mtd: Remove duplicate checks on mtd_oob_ops parameter
Message-ID: <20180107101843.11315-1-boris.brezillon@free-electrons.com>

Some of the check done in custom ->_read/write_oob() implementation are
already done by the core (in mtd_check_oob_ops()).

Suggested-by: Peter Pan <peterpansjtu at gmail.com>
[Remove redundant checks done in mtdpart.c]
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes in v2:
- Merge "mtd: Remove unneeded checks in part_{read,write}_oob()" into
  this commit
---
 drivers/mtd/devices/docg3.c        |  5 -----
 drivers/mtd/mtdpart.c              | 23 -----------------------
 drivers/mtd/nand/nand_base.c       | 31 -------------------------------
 drivers/mtd/onenand/onenand_base.c | 18 ------------------
 4 files changed, 77 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 5fb5e93d1547..a85af236b44d 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -904,9 +904,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	if (ooblen % DOC_LAYOUT_OOB_SIZE)
 		return -EINVAL;
 
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	ops->oobretlen = 0;
 	ops->retlen = 0;
 	ret = 0;
@@ -1441,8 +1438,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 	if (len && ooblen &&
 	    (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta))
 		return -EINVAL;
-	if (ofs + len > mtd->size)
-		return -EINVAL;
 
 	ops->oobretlen = 0;
 	ops->retlen = 0;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index e83c9d870b11..979bf568a622 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -106,25 +106,6 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 	struct mtd_part *part = mtd_to_part(mtd);
 	int res;
 
-	if (from >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && from + ops->len > mtd->size)
-		return -EINVAL;
-
-	/*
-	 * If OOB is also requested, make sure that we do not read past the end
-	 * of this partition.
-	 */
-	if (ops->oobbuf) {
-		size_t len, pages;
-
-		len = mtd_oobavail(mtd, ops);
-		pages = mtd_div_by_ws(mtd->size, mtd);
-		pages -= mtd_div_by_ws(from, mtd);
-		if (ops->ooboffs + ops->ooblen > pages * len)
-			return -EINVAL;
-	}
-
 	res = mtd_read_oob(part->parent, from + part->offset, ops);
 	if (unlikely(res)) {
 		if (mtd_is_bitflip(res))
@@ -183,10 +164,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
 	struct mtd_part *part = mtd_to_part(mtd);
 
-	if (to >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && to + ops->len > mtd->size)
-		return -EINVAL;
 	return mtd_write_oob(part->parent, to + part->offset, ops);
 }
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 889ceadbf607..61eeac233683 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2187,21 +2187,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 
 	len = mtd_oobavail(mtd, ops);
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start read outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
-					(from >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to read beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(from >> chip->chip_shift);
 	chip->select_chip(mtd, chipnr);
 
@@ -2820,22 +2805,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start write outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow write past end of device */
-	if (unlikely(to >= mtd->size ||
-		     ops->ooboffs + ops->ooblen >
-			((mtd->size >> chip->page_shift) -
-			 (to >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to write beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(to >> chip->chip_shift);
 
 	/*
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 050ba8a87543..979f4031f23c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1383,15 +1383,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (from >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to read beyond end of device\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	stats = mtd->ecc_stats;
 
 	readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
@@ -2024,15 +2015,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(to >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (to >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to write past end of device\n",
-		       __func__);
-		return -EINVAL;
-	}
-
 	oobbuf = this->oob_buf;
 
 	oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
-- 
2.11.0



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 10:02:57 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 19:02:57 +0100
Subject: [PATCH v2 1/2] mtd: spi-nor: cadence-quadspi: Refactor indirect
 read/write sequence.
In-Reply-To: <20171229091103.14436-2-vigneshr@ti.com>
References: <20171229091103.14436-1-vigneshr@ti.com>
 <20171229091103.14436-2-vigneshr@ti.com>
Message-ID: <7388af06-8638-1d4f-7d28-464d23df43b2@wedev4u.fr>

Le 29/12/2017 ? 10:11, Vignesh R a ?crit?:
> Move configuring of indirect read/write start address to
> cqspi_indirect_*_execute() function and rename cqspi_indirect_*_setup()
> function. This will help to reuse cqspi_indirect_*_setup() function for
> supporting direct access mode.
> 
> Signed-off-by: Vignesh R <vigneshr at ti.com>

Applied to the spi-nor/next branch of linux-mtd after removing the one
too many empty line in cqspi_read_setup() (see below).

Thanks!

> ---
> 
> v2: No changes.
> 
>  drivers/mtd/spi-nor/cadence-quadspi.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index 75a2bc447a99..becc7d714ab8 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -450,8 +450,7 @@ static int cqspi_command_write_addr(struct spi_nor *nor,
>  	return cqspi_exec_flash_cmd(cqspi, reg);
>  }
>  
> -static int cqspi_indirect_read_setup(struct spi_nor *nor,
> -				     const unsigned int from_addr)
> +static int cqspi_read_setup(struct spi_nor *nor)
>  {
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	struct cqspi_st *cqspi = f_pdata->cqspi;
> @@ -459,7 +458,6 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
>  	unsigned int dummy_clk = 0;
>  	unsigned int reg;
>  
> -	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
> 

removed the above empty line ;)
 
>  	reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>  	reg |= cqspi_calc_rdreg(nor, nor->read_opcode);
> @@ -493,8 +491,8 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
>  	return 0;
>  }
>  
> -static int cqspi_indirect_read_execute(struct spi_nor *nor,
> -				       u8 *rxbuf, const unsigned n_rx)
> +static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> +				       loff_t from_addr, const size_t n_rx)
>  {
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
>  	struct cqspi_st *cqspi = f_pdata->cqspi;
> @@ -504,6 +502,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor,
>  	unsigned int bytes_to_read = 0;
>  	int ret = 0;
>  
> +	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
>  	writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
>  
>  	/* Clear all interrupts. */
> @@ -570,8 +569,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor,
>  	return ret;
>  }
>  
> -static int cqspi_indirect_write_setup(struct spi_nor *nor,
> -				      const unsigned int to_addr)
> +static int cqspi_write_setup(struct spi_nor *nor)
>  {
>  	unsigned int reg;
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
> @@ -584,8 +582,6 @@ static int cqspi_indirect_write_setup(struct spi_nor *nor,
>  	reg = cqspi_calc_rdreg(nor, nor->program_opcode);
>  	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>  
> -	writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
> -
>  	reg = readl(reg_base + CQSPI_REG_SIZE);
>  	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>  	reg |= (nor->addr_width - 1);
> @@ -593,8 +589,8 @@ static int cqspi_indirect_write_setup(struct spi_nor *nor,
>  	return 0;
>  }
>  
> -static int cqspi_indirect_write_execute(struct spi_nor *nor,
> -					const u8 *txbuf, const unsigned n_tx)
> +static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
> +					const u8 *txbuf, const size_t n_tx)
>  {
>  	const unsigned int page_size = nor->page_size;
>  	struct cqspi_flash_pdata *f_pdata = nor->priv;
> @@ -604,6 +600,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor,
>  	unsigned int write_bytes;
>  	int ret;
>  
> +	writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
>  	writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
>  
>  	/* Clear all interrupts. */
> @@ -900,11 +897,11 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_setup(nor, to);
> +	ret = cqspi_write_setup(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_execute(nor, buf, len);
> +	ret = cqspi_indirect_write_execute(nor, to, buf, len);
>  	if (ret)
>  		return ret;
>  
> @@ -920,11 +917,11 @@ static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_setup(nor, from);
> +	ret = cqspi_read_setup(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_execute(nor, buf, len);
> +	ret = cqspi_indirect_read_execute(nor, buf, from, len);
>  	if (ret)
>  		return ret;
>  
> 



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 10:03:46 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 19:03:46 +0100
Subject: [PATCH v2 2/2] mtd: spi-nor: cadence-quadspi: Add support for
 direct access mode
In-Reply-To: <20171229091103.14436-3-vigneshr@ti.com>
References: <20171229091103.14436-1-vigneshr@ti.com>
 <20171229091103.14436-3-vigneshr@ti.com>
Message-ID: <e4162aac-ebbf-9949-8d4b-24a314e44c48@wedev4u.fr>

Le 29/12/2017 ? 10:11, Vignesh R a ?crit?:
> Cadence QSPI controller provides direct access mode through which flash
> can be accessed in a memory-mapped IO mode. This enables read/write to
> flash using memcpy*() functions. This mode provides higher throughput
> for both read/write operations when compared to current indirect mode of
> operation.
> 
> This patch therefore adds support to use QSPI in direct mode. If the
> window reserved in SoC's memory map for MMIO access is less that of
> flash size(like on most SoCFPGA variants), then the driver falls back
> to indirect mode of operation.
> 
> On TI's 66AK2G SoC, with ARM running at 600MHz and QSPI at 96MHz
> switching to direct mode improves read throughput from 3MB/s to 8MB/s.
> 
> Signed-off-by: Vignesh R <vigneshr at ti.com>

Applied to the spi-nor/next branch of linux-mtd

Thanks!

> ---
> 
> v2: enable direct access controller during controller init.
> 
>  drivers/mtd/spi-nor/cadence-quadspi.c | 31 +++++++++++++++++++++++++++++--
>  1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index becc7d714ab8..f693a57ebbd6 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -58,6 +58,7 @@ struct cqspi_flash_pdata {
>  	u8		data_width;
>  	u8		cs;
>  	bool		registered;
> +	bool		use_direct_mode;
>  };
>  
>  struct cqspi_st {
> @@ -68,6 +69,7 @@ struct cqspi_st {
>  
>  	void __iomem		*iobase;
>  	void __iomem		*ahb_base;
> +	resource_size_t		ahb_size;
>  	struct completion	transfer_complete;
>  	struct mutex		bus_mutex;
>  
> @@ -103,6 +105,7 @@ struct cqspi_st {
>  /* Register map */
>  #define CQSPI_REG_CONFIG			0x00
>  #define CQSPI_REG_CONFIG_ENABLE_MASK		BIT(0)
> +#define CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL	BIT(7)
>  #define CQSPI_REG_CONFIG_DECODE_MASK		BIT(9)
>  #define CQSPI_REG_CONFIG_CHIPSELECT_LSB		10
>  #define CQSPI_REG_CONFIG_DMA_MASK		BIT(15)
> @@ -891,6 +894,8 @@ static int cqspi_set_protocol(struct spi_nor *nor, const int read)
>  static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  			   size_t len, const u_char *buf)
>  {
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
> +	struct cqspi_st *cqspi = f_pdata->cqspi;
>  	int ret;
>  
>  	ret = cqspi_set_protocol(nor, 0);
> @@ -901,7 +906,10 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_write_execute(nor, to, buf, len);
> +	if (f_pdata->use_direct_mode)
> +		memcpy_toio(cqspi->ahb_base + to, buf, len);
> +	else
> +		ret = cqspi_indirect_write_execute(nor, to, buf, len);
>  	if (ret)
>  		return ret;
>  
> @@ -911,6 +919,8 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>  static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  			  size_t len, u_char *buf)
>  {
> +	struct cqspi_flash_pdata *f_pdata = nor->priv;
> +	struct cqspi_st *cqspi = f_pdata->cqspi;
>  	int ret;
>  
>  	ret = cqspi_set_protocol(nor, 1);
> @@ -921,7 +931,10 @@ static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>  	if (ret)
>  		return ret;
>  
> -	ret = cqspi_indirect_read_execute(nor, buf, from, len);
> +	if (f_pdata->use_direct_mode)
> +		memcpy_fromio(buf, cqspi->ahb_base + from, len);
> +	else
> +		ret = cqspi_indirect_read_execute(nor, buf, from, len);
>  	if (ret)
>  		return ret;
>  
> @@ -1056,6 +1069,8 @@ static int cqspi_of_get_pdata(struct platform_device *pdev)
>  
>  static void cqspi_controller_init(struct cqspi_st *cqspi)
>  {
> +	u32 reg;
> +
>  	cqspi_controller_enable(cqspi, 0);
>  
>  	/* Configure the remap address register, no remap */
> @@ -1078,6 +1093,11 @@ static void cqspi_controller_init(struct cqspi_st *cqspi)
>  	writel(cqspi->fifo_depth * cqspi->fifo_width / 8,
>  	       cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK);
>  
> +	/* Enable Direct Access Controller */
> +	reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
> +	reg |= CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL;
> +	writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
> +
>  	cqspi_controller_enable(cqspi, 1);
>  }
>  
> @@ -1153,6 +1173,12 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
>  			goto err;
>  
>  		f_pdata->registered = true;
> +
> +		if (mtd->size <= cqspi->ahb_size) {
> +			f_pdata->use_direct_mode = true;
> +			dev_dbg(nor->dev, "using direct mode for %s\n",
> +				mtd->name);
> +		}
>  	}
>  
>  	return 0;
> @@ -1212,6 +1238,7 @@ static int cqspi_probe(struct platform_device *pdev)
>  		dev_err(dev, "Cannot remap AHB address.\n");
>  		return PTR_ERR(cqspi->ahb_base);
>  	}
> +	cqspi->ahb_size = resource_size(res_ahb);
>  
>  	init_completion(&cqspi->transfer_complete);
>  
> 



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 10:08:19 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 19:08:19 +0100
Subject: [PATCH 09/12] mtd: fsl-quadspi: account for const type of
 of_device_id.data
In-Reply-To: <1514899688-27844-10-git-send-email-Julia.Lawall@lip6.fr>
References: <1514899688-27844-1-git-send-email-Julia.Lawall@lip6.fr>
 <1514899688-27844-10-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <865dd318-e30e-e747-ea9f-8bbb549d4471@wedev4u.fr>

Le 02/01/2018 ? 14:28, Julia Lawall a ?crit?:
> This driver creates a number of const structures that it stores in the
> data field of an of_device_id array.
> 
> The data field of an of_device_id structure has type const void *, so
> there is no need for a const-discarding cast when putting const values
> into such a structure.
> 
> Done using Coccinelle.
> 
> Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>
> 

Applied to the spi-nor/next branch of linux-mtd

Thanks!

> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff -u -p a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -801,10 +801,10 @@ static int fsl_qspi_nor_setup_last(struc
>  }
>  
>  static const struct of_device_id fsl_qspi_dt_ids[] = {
> -	{ .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
> -	{ .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
> -	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
> -	{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
> +	{ .compatible = "fsl,vf610-qspi", .data = &vybrid_data, },
> +	{ .compatible = "fsl,imx6sx-qspi", .data = &imx6sx_data, },
> +	{ .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, },
> +	{ .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, },
>  	{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
>  	{ /* sentinel */ }
>  };
> 
> 



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 10:19:08 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 19:19:08 +0100
Subject: [PATCH 1/2] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <1515064334-509-2-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515064334-509-1-git-send-email-yogeshnarayan.gaur@nxp.com>
 <1515064334-509-2-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <62931ed6-4c64-9750-c9e0-177c9bf30e28@wedev4u.fr>

Hi Yogesh,

Le 04/01/2018 ? 12:12, Yogesh Gaur a ?crit?:
> Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
> protocol. Spansion flash, s25fl512s, supports Quad read with read
> capabilities as 1-4-4.
> 
> Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.
> 
> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index c22e3eb..178e621 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -959,6 +959,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  {
>  	const struct spi_nor_hwcaps hwcaps = {
>  		.mask = SNOR_HWCAPS_READ_1_1_4 |
> +			SNOR_HWCAPS_READ_1_4_4 |

Sorry but I still don't agree on this patch: it should be squashed into
the patch adding a proper support to Fast Read 1-4-4 commands.

I understand this patch belongs to a series but even individual patches of
a series should not introduce bug. Like this, the spi_nor_scan() could
select the SPI 1-4-4 protocol for Fast Read operation.
However fsl_qspi_get_seqid() still only cares about the SPINOR_OP_READ_1_1_4
op code but not about the SPINOR_OP_READ_1_4_4. So it's not correct.

When looking for a bug, we need to be able to bissect. However testing right
after this patch would fail with SPI flash memories supporting Fast Read
1-4-4.

Best regards,

Cyrille

>  			SNOR_HWCAPS_PP,
>  	};
>  	struct device_node *np = pdev->dev.of_node;
> 



From boris.brezillon at free-electrons.com  Sun Jan  7 12:07:03 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 21:07:03 +0100
Subject: [PATCH 1/3] mtd: spi-nor: add optional DMA-safe bounce buffer
 for data transfer
In-Reply-To: <ae977280-28b4-d746-da4b-0f807dad609d@wedev4u.fr>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <fc2440c6f52877f28286d89691049e5cba10e6a7.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <1126731d-cbf7-8fbf-34ab-8ccf1cc8241f@ti.com>
 <ae977280-28b4-d746-da4b-0f807dad609d@wedev4u.fr>
Message-ID: <20180107210703.31fdf0a0@bbrezillon>

On Tue, 26 Dec 2017 14:59:00 +0100
Cyrille Pitchen <cyrille.pitchen at wedev4u.fr> wrote:

> Hi Vignesh
> 
> Le 26/12/2017 ? 14:42, Vignesh R a ?crit?:
> > Hi Cyrille,
> > 
> > Thanks for doing this series! One comment below.
> > 
> > On 24-Dec-17 10:06 AM, Cyrille Pitchen wrote:
> > [...]  
> >> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> >> index 8bafd462f0ae..59f9fbd45234 100644
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> @@ -14,8 +14,10 @@
> >>  #include <linux/errno.h>
> >>  #include <linux/module.h>
> >>  #include <linux/device.h>
> >> +#include <linux/highmem.h>
> >>  #include <linux/mutex.h>
> >>  #include <linux/math64.h>
> >> +#include <linux/mm.h>
> >>  #include <linux/sizes.h>
> >>  #include <linux/slab.h>
> >>  
> >> @@ -1232,6 +1234,56 @@ static const struct flash_info spi_nor_ids[] = {
> >>  	{ },
> >>  };
> >>  
> >> +static bool spi_nor_is_dma_safe(const void *buf)
> >> +{
> >> +	if (is_vmalloc_addr(buf))
> >> +		return false;
> >> +
> >> +#ifdef CONFIG_HIGHMEM
> >> +	if ((unsigned long)buf >= PKMAP_BASE &&
> >> +	    (unsigned long)buf < (PKMAP_BASE + (LAST_PKMAP * PAGE_SIZE)))
> >> +		return false;
> >> +#endif
> >> +
> >> +	return true;
> >> +}
> >> +  
> > 
> > Better way would be to use virt_addr_valid():
> > static bool spi_nor_is_dma_safe(const void *buf)
> > {
> > 	return virt_addr_valid(buf);
> > }
> > 
> > Regards
> > Vignesh
> >   
> 
> Thanks for the advice :)
> 
> https://patchwork.kernel.org/patch/9768341/
> Maybe I could check both virt_addr_valid() and object_is_on_stack() too ?

Yep, see the explanation given here [1].

[1]http://elixir.free-electrons.com/linux/v4.15-rc6/source/Documentation/DMA-API-HOWTO.txt#L132


From cyrille.pitchen at wedev4u.fr  Sun Jan  7 12:24:26 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 21:24:26 +0100
Subject: [PATCH 3/3] spi-nor: intel-spi: Remove unused preopcodes field
In-Reply-To: <20180104090744.67654-3-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180104090744.67654-3-mika.westerberg@linux.intel.com>
Message-ID: <daa6bd0b-c029-a8ab-7309-4604a926a7db@wedev4u.fr>

Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> This field is not used in the driver anymore so remove it.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>

Applied to the spi-nor/next branch of linux-mtd

Thanks!

> ---
>  drivers/mtd/spi-nor/intel-spi.c | 6 ------
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
> index bba762aa0c8d..8d54da46da30 100644
> --- a/drivers/mtd/spi-nor/intel-spi.c
> +++ b/drivers/mtd/spi-nor/intel-spi.c
> @@ -138,7 +138,6 @@
>   * @erase_64k: 64k erase supported
>   * @opcodes: Opcodes which are supported. This are programmed by BIOS
>   *           before it locks down the controller.
> - * @preopcodes: Preopcodes which are supported.
>   */
>  struct intel_spi {
>  	struct device *dev;
> @@ -155,7 +154,6 @@ struct intel_spi {
>  	bool swseq_erase;
>  	bool erase_64k;
>  	u8 opcodes[8];
> -	u8 preopcodes[2];
>  };
>  
>  static bool writeable;
> @@ -400,10 +398,6 @@ static int intel_spi_init(struct intel_spi *ispi)
>  				ispi->opcodes[i] = opmenu0 >> i * 8;
>  				ispi->opcodes[i + 4] = opmenu1 >> i * 8;
>  			}
> -
> -			val = readl(ispi->sregs + PREOP_OPTYPE);
> -			ispi->preopcodes[0] = val;
> -			ispi->preopcodes[1] = val >> 8;
>  		}
>  	}
>  
> 



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 12:32:46 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 7 Jan 2018 21:32:46 +0100
Subject: [PATCH 2/3] spi-nor: intel-spi: Explicitly mark the driver as
 dangerous in Kconfig
In-Reply-To: <20180104090744.67654-2-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180104090744.67654-2-mika.westerberg@linux.intel.com>
Message-ID: <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>

Hi Mika,

Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> The driver is not meant for normal users at all but instead such users
> who really know what they are doing and are able to build their own
> kernel to enable it. Mark both driver Kconfig entries as dangerous to
> make sure the driver is not accidentally enabled without understanding
> possible issues in doing so.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> ---
>  drivers/mtd/spi-nor/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
> index 89da88e59121..f480b227a6b8 100644
> --- a/drivers/mtd/spi-nor/Kconfig
> +++ b/drivers/mtd/spi-nor/Kconfig
> @@ -90,7 +90,7 @@ config SPI_INTEL_SPI
>  	tristate
>  
>  config SPI_INTEL_SPI_PCI
> -	tristate "Intel PCH/PCU SPI flash PCI driver"
> +	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"

I guess it might be even better and safer to add "default n" too, don't
you agree? Adding only the "DANGEROUS" word would not prevent build
scripts to select this driver when creating a kernel config from scratch.

Best regards,

Cyrille

>  	depends on X86 && PCI
>  	select SPI_INTEL_SPI
>  	help
> @@ -106,7 +106,7 @@ config SPI_INTEL_SPI_PCI
>  	  will be called intel-spi-pci.
>  
>  config SPI_INTEL_SPI_PLATFORM
> -	tristate "Intel PCH/PCU SPI flash platform driver"
> +	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
>  	depends on X86
>  	select SPI_INTEL_SPI
>  	help
> 



From boris.brezillon at free-electrons.com  Sun Jan  7 12:49:00 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 21:49:00 +0100
Subject: [PATCH 1/3] mtd: spi-nor: add optional DMA-safe bounce buffer
 for data transfer
In-Reply-To: <fc2440c6f52877f28286d89691049e5cba10e6a7.1514087323.git.cyrille.pitchen@wedev4u.fr>
References: <cover.1514087323.git.cyrille.pitchen@wedev4u.fr>
 <fc2440c6f52877f28286d89691049e5cba10e6a7.1514087323.git.cyrille.pitchen@wedev4u.fr>
Message-ID: <20180107214900.21bfed26@bbrezillon>

Hi Cyrille,

On Sun, 24 Dec 2017 05:36:04 +0100
Cyrille Pitchen <cyrille.pitchen at wedev4u.fr> wrote:

> This patch has two purposes:
> 
> 1 - To fix the compatible issue between the MTD and SPI sub-systems
> 
> The MTD sub-system has no particular requirement about the memory areas it
> uses. Especially, ubifs is well known for using vmalloc'ed buffers, which
> then are not DMA-safe. There are reasons behind that, so we have to deal
> with it.

Well, the only reason is that it's easier to deal with
virtually contiguous memory region, and since the LEB/PEB size can be
quite big (especially for NAND devices) we have to allocate it with
vmalloc() to prevent memory fragmentation.

The solution would be to allocate an array of ubi->min_io_size buffers
using kzalloc() and write/read to/from the MTD device using this
granularity, but this approach would require quite a few changes and
that's not the topic here.

> 
> On the other hand, the SPI sub-system clearly states in the kernel doc for
> 'struct spi-transfer' (include/linux/spi/spi.h) that both .tx_buf and
> .rx_buf must point into "dma-safe memory". This requirement has not been
> taken into account by the m25p80.c driver, at the border between MTD and
> SPI, for a long time now. So it's high time to fix this issue.

I agree, even if I guess the MTD layer is not the only offender and
having this bounce buffer logic at the SPI level would be even better
IMO. But let's solve the problem in the SPI-NOR layer for now.

> 
> 2 - To help other SPI flash controller drivers to perform DMA transfers
> 
> Those controller drivers suffer the same issue as those behind the
> m25p80.c driver in the SPI sub-system: They may be provided by the MTD
> sub-system with buffers not suited to DMA operations. We want to avoid
> each controller to implement its own bounce buffer so we offer them some
> optional bounce buffer, allocated and managed by the spi-nor framework
> itself, as an helper to add support to DMA transfers.
> 
> Then the patch adds two hardware capabilities for SPI flash controllers,
> SNOR_HWCAPS_WR_BOUNCE and SNOR_HWCAPS_RD_BOUNCE.

Do you have good reasons to handle the read/write path independently? I
mean, if you need a bounce buffer for one of them it's likely that
you'll need it for both.

> 
> SPI flash controller drivers are supposed to use them to request the
> spi-nor framework to allocate an optional bounce buffer in some
> DMA-safe memory area then to use it in some cases during (Fast) Read
> and/or Page Program operations.
> 
> More precisely, the bounce buffer is used if and only if two conditions
> are met:
> 1 - The SPI flash controller driver has declared the
>     SNOR_HWCAPS_RD_BOUNCE, resp. SNOR_HWCAPS_WR_BOUNCE for (Fast) Read,
>     resp. Page Program operations.
> 2 - The buffer provided by the above MTD layer is not already in a
>     DMA-safe area.
> 
> This policy avoid using the bounce buffer when not explicitly requested
> or when not needed, hence limiting the performance penalty.
> 
> Besides, the bounce buffer is allocated once for all at the very first
> time it is actually needed.

Hm, I think it would be better to allocate the buffer at detection/probe
time, when you have all the information you need (sector_size?). My
fear is that you might not be able to kmalloc() a large buffer the
first time a read/write operation is performed, and that means the
operation might randomly fail/succeed depending on when the first IO
operation is done. If you do it at probe time, you'll be able to detect
the allocation failure early and stop the MTD dev registration when
this is the case.

> This means that as long as all buffers
> provided by the above MTD layer are allocated in some DMA-safe areas, the
> bounce buffer itself is never allocated.
> 
> Finally, the bounce buffer size is limited to 256KiB, the currently known
> maximum erase sector size. This tradeoff should still provide good
> performances even if new memory parts come with even larger erase sector
> sizes, limiting the memory footprint at the same time.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at wedev4u.fr>
> ---
>  drivers/mtd/devices/m25p80.c  |   4 +-
>  drivers/mtd/spi-nor/spi-nor.c | 136 +++++++++++++++++++++++++++++++++++++++---
>  include/linux/mtd/spi-nor.h   |   8 +++
>  3 files changed, 139 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index a4e18f6aaa33..60878c62a654 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -239,7 +239,9 @@ static int m25p_probe(struct spi_device *spi)
>  	struct spi_nor_hwcaps hwcaps = {
>  		.mask = SNOR_HWCAPS_READ |
>  			SNOR_HWCAPS_READ_FAST |
> -			SNOR_HWCAPS_PP,
> +			SNOR_HWCAPS_PP |
> +			SNOR_HWCAPS_RD_BOUNCE |
> +			SNOR_HWCAPS_WR_BOUNCE,
>  	};
>  	char *flash_name;
>  	int ret;
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 8bafd462f0ae..59f9fbd45234 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -14,8 +14,10 @@
>  #include <linux/errno.h>
>  #include <linux/module.h>
>  #include <linux/device.h>
> +#include <linux/highmem.h>
>  #include <linux/mutex.h>
>  #include <linux/math64.h>
> +#include <linux/mm.h>
>  #include <linux/sizes.h>
>  #include <linux/slab.h>
>  
> @@ -1232,6 +1234,56 @@ static const struct flash_info spi_nor_ids[] = {
>  	{ },
>  };
>  
> +static bool spi_nor_is_dma_safe(const void *buf)
> +{
> +	if (is_vmalloc_addr(buf))
> +		return false;
> +
> +#ifdef CONFIG_HIGHMEM
> +	if ((unsigned long)buf >= PKMAP_BASE &&
> +	    (unsigned long)buf < (PKMAP_BASE + (LAST_PKMAP * PAGE_SIZE)))
> +		return false;
> +#endif
> +
> +	return true;
> +}
> +
> +static int spi_nor_get_bounce_buffer(struct spi_nor *nor,
> +				     u_char **buffer,
> +				     size_t *buffer_size)
> +{
> +	const struct flash_info *info = nor->info;
> +	/*
> +	 * Limit the size of the bounce buffer to 256KB: this is currently
> +	 * the largest known erase sector size (> page size) and should be
> +	 * enough to still reach good performances if some day new memory
> +	 * parts use even larger erase sector sizes.
> +	 */
> +	size_t size = min_t(size_t, info->sector_size, SZ_256K);

Wow! That's a huge max size for a buffer allocated with kmalloc. Are
you sure you shouldn't shrink it a bit? Don't know what the usual
sector_size is, but AFAIU sector_size is the ->erasesize, and read/write
operations are done at a ->writesize or ->writebufsize granularity.

> +
> +	/*
> +	 * Allocate the bounce buffer once for all at the first time it is
> +	 * actually needed. This prevents wasting some precious memory
> +	 * in cases where it would never be needed.
> +	 */
> +	if (unlikely(!nor->bounce_buffer)) {

I've been told that unlikely/likely() specifiers are not so useful
these days and are sometime doing worse than when nothing is specified.
I must admit I never went as far as evaluating it myself, but I don't
think it's really needed here (the time spent doing this check is
likely to be negligible compared to the IO operation).

> +		nor->bounce_buffer = devm_kmalloc(nor->dev, size, GFP_KERNEL);

Nope, devm_kmalloc() is not DMA-safe (see this thread [1]).

> +
> +		/*
> +		 * The SPI flash controller driver has required and expects to
> +		 * use the DMA-safe bounce buffer, so we can't recover from
> +		 * this allocation failure.
> +		 */
> +		if (!nor->bounce_buffer)
> +			return -ENOMEM;
> +	}
> +
> +	*buffer = nor->bounce_buffer;
> +	*buffer_size = size;
> +
> +	return 0;
> +}
> +

Regards,

Boris

[1]http://linux-arm-kernel.infradead.narkive.com/vyJqy0RQ/question-devm-kmalloc-for-dma


From robert.jarzmik at free.fr  Sun Jan  7 12:55:33 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sun, 07 Jan 2018 21:55:33 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180103215206.5d85b41b@bbrezillon> (Boris Brezillon's message
 of "Wed, 3 Jan 2018 21:52:06 +0100")
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon> <877etkecig.fsf@belgarion.home>
 <20171218092535.2ca1fe13@xps13> <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon> <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon> <20171222233730.68d9cb9d@xps13>
 <87k1xdblxf.fsf@belgarion.home> <20171223155709.2ba16e95@xps13>
 <87fu81bc45.fsf@belgarion.home> <20180102120326.7a2cf1d1@xps13>
 <87d12scbiy.fsf@belgarion.home> <20180103084037.422b239a@xps13>
 <878tded89m.fsf@belgarion.home> <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
Message-ID: <874lnxcrsq.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> On Wed, 3 Jan 2018 21:10:28 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
>> Hm, that's weird. Can you try with the old driver (pxa3xx)?
Ah you're right, my NAND was damaged ...

> Alternatively, you can type 'nand bad' from uboot to check if it
> detects the same bad blocks.
Mmmh no, the SPL is barebox in my case. Do you have a command in linux or
barebox to do the same thing ?

Cheers.

-- 
Robert


From boris.brezillon at free-electrons.com  Sun Jan  7 13:06:31 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 22:06:31 +0100
Subject: [PATCH 2/3] spi-nor: intel-spi: Explicitly mark the driver as
 dangerous in Kconfig
In-Reply-To: <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180104090744.67654-2-mika.westerberg@linux.intel.com>
 <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>
Message-ID: <20180107220631.73f303b6@bbrezillon>

On Sun, 7 Jan 2018 21:32:46 +0100
Cyrille Pitchen <cyrille.pitchen at wedev4u.fr> wrote:

> Hi Mika,
> 
> Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> > The driver is not meant for normal users at all but instead such users
> > who really know what they are doing and are able to build their own
> > kernel to enable it. Mark both driver Kconfig entries as dangerous to
> > make sure the driver is not accidentally enabled without understanding
> > possible issues in doing so.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> > ---
> >  drivers/mtd/spi-nor/Kconfig | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
> > index 89da88e59121..f480b227a6b8 100644
> > --- a/drivers/mtd/spi-nor/Kconfig
> > +++ b/drivers/mtd/spi-nor/Kconfig
> > @@ -90,7 +90,7 @@ config SPI_INTEL_SPI
> >  	tristate
> >  
> >  config SPI_INTEL_SPI_PCI
> > -	tristate "Intel PCH/PCU SPI flash PCI driver"
> > +	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"  
> 
> I guess it might be even better and safer to add "default n" too, don't
> you agree? Adding only the "DANGEROUS" word would not prevent build
> scripts to select this driver when creating a kernel config from scratch.

How about adding

	depends on EXPERT

?

> 
> Best regards,
> 
> Cyrille
> 
> >  	depends on X86 && PCI
> >  	select SPI_INTEL_SPI
> >  	help
> > @@ -106,7 +106,7 @@ config SPI_INTEL_SPI_PCI
> >  	  will be called intel-spi-pci.
> >  
> >  config SPI_INTEL_SPI_PLATFORM
> > -	tristate "Intel PCH/PCU SPI flash platform driver"
> > +	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
> >  	depends on X86
> >  	select SPI_INTEL_SPI
> >  	help
> >   
> 



From miquel.raynal at free-electrons.com  Sun Jan  7 13:09:11 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Sun, 7 Jan 2018 22:09:11 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <874lnxcrsq.fsf@belgarion.home>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
 <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
 <874lnxcrsq.fsf@belgarion.home>
Message-ID: <20180107220911.31844b3a@xps13>

Hi Robert,

On Sun, 07 Jan 2018 21:55:33 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > On Wed, 3 Jan 2018 21:10:28 +0100
> > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:  
> >> Hm, that's weird. Can you try with the old driver (pxa3xx)?  
> Ah you're right, my NAND was damaged ...
> 
> > Alternatively, you can type 'nand bad' from uboot to check if it
> > detects the same bad blocks.  
> Mmmh no, the SPL is barebox in my case. Do you have a command in
> linux or barebox to do the same thing ?

Not sure, but nand -i should do the trick.
https://www.barebox.org/doc/latest/commands/hwmanip/nand.html

But I am not sure this is still relevant now we know the NAND was
damaged by the previous experiments (sorry about that). Can you put the
NAND in a clean state and report us if it is still failing?

Thanks for your help,
Miqu?l


From boris.brezillon at free-electrons.com  Sun Jan  7 13:19:11 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 22:19:11 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180107220911.31844b3a@xps13>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
 <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
 <874lnxcrsq.fsf@belgarion.home> <20180107220911.31844b3a@xps13>
Message-ID: <20180107221911.51115566@bbrezillon>

On Sun, 7 Jan 2018 22:09:11 +0100
Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:

> Hi Robert,
> 
> On Sun, 07 Jan 2018 21:55:33 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> 
> > Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> >   
> > > On Wed, 3 Jan 2018 21:10:28 +0100
> > > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:    
> > >> Hm, that's weird. Can you try with the old driver (pxa3xx)?    
> > Ah you're right, my NAND was damaged ...
> >   
> > > Alternatively, you can type 'nand bad' from uboot to check if it
> > > detects the same bad blocks.    
> > Mmmh no, the SPL is barebox in my case. Do you have a command in
> > linux or barebox to do the same thing ?  
> 
> Not sure, but nand -i should do the trick.
> https://www.barebox.org/doc/latest/commands/hwmanip/nand.html
> 
> But I am not sure this is still relevant now we know the NAND was
> damaged by the previous experiments (sorry about that). Can you put the
> NAND in a clean state and report us if it is still failing?

In order to do that you'll have to scrub the blocks storing the BBT, and
I'm not sure barebox supports that. Linux does not, for sure, so if you
want to forcibly erase bad blocks from linux, you'll have to comment
these lines [1].

[1]http://elixir.free-electrons.com/linux/v4.15-rc6/source/drivers/mtd/nand/nand_base.c#L3056


From boris.brezillon at free-electrons.com  Sun Jan  7 13:26:05 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 7 Jan 2018 22:26:05 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180107221911.51115566@bbrezillon>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
 <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
 <874lnxcrsq.fsf@belgarion.home> <20180107220911.31844b3a@xps13>
 <20180107221911.51115566@bbrezillon>
Message-ID: <20180107222605.6dd739b3@bbrezillon>

On Sun, 7 Jan 2018 22:19:11 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Sun, 7 Jan 2018 22:09:11 +0100
> Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> 
> > Hi Robert,
> > 
> > On Sun, 07 Jan 2018 21:55:33 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >   
> > > Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> > >     
> > > > On Wed, 3 Jan 2018 21:10:28 +0100
> > > > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:      
> > > >> Hm, that's weird. Can you try with the old driver (pxa3xx)?      
> > > Ah you're right, my NAND was damaged ...
> > >     
> > > > Alternatively, you can type 'nand bad' from uboot to check if it
> > > > detects the same bad blocks.      
> > > Mmmh no, the SPL is barebox in my case. Do you have a command in
> > > linux or barebox to do the same thing ?    
> > 
> > Not sure, but nand -i should do the trick.
> > https://www.barebox.org/doc/latest/commands/hwmanip/nand.html
> > 
> > But I am not sure this is still relevant now we know the NAND was
> > damaged by the previous experiments (sorry about that). Can you put the
> > NAND in a clean state and report us if it is still failing?  
> 
> In order to do that you'll have to scrub the blocks storing the BBT, and
> I'm not sure barebox supports that. Linux does not, for sure, so if you
> want to forcibly erase bad blocks from linux, you'll have to comment
> these lines [1].

Apparently there's a "nand -g <offs>" command to mark a block good in
barebox. After doing that you should be able to erase the blocks storing
the BBT (it should be placed in the last 2 blocks of the NAND).

> 
> [1]http://elixir.free-electrons.com/linux/v4.15-rc6/source/drivers/mtd/nand/nand_base.c#L3056


From miquel.raynal at free-electrons.com  Sun Jan  7 13:43:20 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Sun, 7 Jan 2018 22:43:20 +0100
Subject: [PATCH v2 1/5] dt-bindings: mtd: add Marvell NAND controller
 documentation
In-Reply-To: <20171220210511.ty2e7mkiktvn4een@rob-hp-laptop>
References: <20171219132942.27433-1-miquel.raynal@free-electrons.com>
 <20171219132942.27433-2-miquel.raynal@free-electrons.com>
 <20171220210511.ty2e7mkiktvn4een@rob-hp-laptop>
Message-ID: <20180107224320.597c3a51@xps13>

Hi Rob,

On Wed, 20 Dec 2017 15:05:11 -0600
Rob Herring <robh at kernel.org> wrote:

> On Tue, Dec 19, 2017 at 02:29:38PM +0100, Miquel Raynal wrote:
> > Document the legacy and the new bindings for Marvell NAND
> > controller.
> > 
> > The pxa3xx_nand.c driver does only support legacy bindings, which
> > are incomplete and inaccurate. A rework of this controller (called
> > marvell_nand.c) does support both.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> > ---
> >  .../devicetree/bindings/mtd/marvell-nand.txt       | 123
> > +++++++++++++++++++++ 1 file changed, 123 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/mtd/marvell-nand.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/mtd/marvell-nand.txt
> > b/Documentation/devicetree/bindings/mtd/marvell-nand.txt new file
> > mode 100644 index 000000000000..aa6a1ed045b2
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mtd/marvell-nand.txt
> > @@ -0,0 +1,123 @@
> > +Marvell NAND Flash Controller (NFC)
> > +
> > +Required properties:
> > +- compatible: can be one of the following:
> > +    * "marvell,armada-8k-nand-controller"
> > +    * "marvell,armada370-nand-controller"
> > +    * "marvell,pxa3xx-nand-controller"
> > +    * "marvell,armada-8k-nand" (deprecated)
> > +    * "marvell,armada370-nand" (deprecated)
> > +    * "marvell,pxa3xx-nand" (deprecated)
> > +  Compatibles marked deprecated support only the old bindings
> > described
> > +  at the bottom.
> > +- reg: NAND flash controller memory area.
> > +- #address-cells: shall be set to 1. Encode the NAND CS.
> > +- #size-cells: shall be set to 0.
> > +- interrupts: shall define the NAND controller interrupt.
> > +- clocks: shall reference the NAND controller clock.
> > +- marvell,system-controller: Set to retrieve the syscon node that
> > handles
> > +  NAND controller related registers (only required with the
> > +  "marvell,armada-8k-nand[-controller]" compatibles).
> > +
> > +Optional properties:
> > +- label: see partition.txt. New platforms shall omit this property.
> > +- dmas: shall reference DMA channel associated to the NAND
> > controller.
> > +  This property is only used with
> > "marvell,pxa3xx-nand[-controller]"
> > +  compatible strings.
> > +- dma-names: shall be "rxtx".
> > +  This property is only used with
> > "marvell,pxa3xx-nand[-controller]"
> > +  compatible strings.
> > +
> > +Optional children nodes:
> > +Children nodes represent the available NAND chips.
> > +
> > +Required properties:
> > +- reg: shall contain the native Chip Select ids (0-3)
> > +- marvell,rb: shall contain the native Ready/Busy ids (0-1)  
> 
> We already have at least 2 other <vendor>,rb properties. Let's not
> add a 3rd and make a common one instead.

I switched to "nand-rb", added this property in nand.txt (in another
commit) and updated all the DT accordingly.

> 
> > +
> > +Optional properties:
> > +- marvell,nand-keep-config: orders the driver not to take the
> > timings
> > +  from the core and leaving them completely untouched. Bootloader
> > +  timings will then be used.
> > +- label: MTD name.
> > +- nand-on-flash-bbt: see nand.txt.
> > +- nand-ecc-mode: see nand.txt. Will use hardware ECC if not
> > specified. +- nand-ecc-algo: see nand.txt. This property may be
> > added when using
> > +  hardware ECC for clarification but will be ignored by the driver
> > +  because ECC mode is chosen depending on the page size and the
> > strength
> > +  required by the NAND chip. This value may be overwritten with
> > +  nand-ecc-strength property.  
> 
> If not used, then drop it.

Well, nand-ecc-algo will be useful when not using the ECC
engine, so it cannot be removed. I tried to explain better the
situation.

> 
> > +- nand-ecc-strength: see nand.txt.
> > +- nand-ecc-step-size: see nand.txt. This has no effect and will be
> > +  ignored by the driver when using hardware ECC because Marvell's
> > NAND
> > +  flash controller does use fixed strength (1-bit for Hamming,
> > 16-bit
> > +  for BCH), so the step size will shrink or grow in order to fit
> > the
> > +  required strength. Step sizes are not completely random for all
> > and
> > +  follow certain patterns described in AN-379, "Marvell SoC NFC
> > ECC".  
> 
> Same here.

The comment about being ignored was not accurate, I simply removed
that part.

Thanks,
Miqu?l


From miquel.raynal at free-electrons.com  Sun Jan  7 13:46:43 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Sun, 7 Jan 2018 22:46:43 +0100
Subject: [PATCH v2 2/5] mtd: nand: add reworked Marvell NAND controller
 driver
In-Reply-To: <20171221111428.0aa3e65e@bbrezillon>
References: <20171219132942.27433-1-miquel.raynal@free-electrons.com>
 <20171219132942.27433-3-miquel.raynal@free-electrons.com>
 <20171221111428.0aa3e65e@bbrezillon>
Message-ID: <20180107224643.760eac74@xps13>

Hi Boris,

On Thu, 21 Dec 2017 11:14:28 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hi Miquel,
> 
> On Tue, 19 Dec 2017 14:29:39 +0100
> Miquel Raynal <miquel.raynal at free-electrons.com> wrote:
> 
> > Add marvell_nand driver which aims at replacing the existing
> > pxa3xx_nand driver.
> > 
> > The new driver intends to be easier to understand and follows the
> > brand new NAND framework rules by implementing hooks for every
> > pattern the controller might support and referencing them inside a
> > parser object that will be given to the core at each ->exec_op()
> > call.
> > 
> > Raw accessors are implemented, useful to test/debug
> > memory/filesystem corruptions. Userspace binaries contained in the
> > mtd-utils package may now be used and their output trusted.
> > 
> > Timings may not be kept from the bootloader anymore, the timings
> > used for instance in U-Boot were not optimal and it supposed to
> > have NAND support (and initialized) in the bootloader.  
> 
> Hm, AFAIR the old driver was able to dynamically adjust the timings
> when the NAND was ONFI compliant.
> 
> > 
> > Thanks to the improved timings, implementation of ONFI mode 5
> > support (with EDO managed by adding a delay on data sampling),
> > merging the commands together and optimizing writes in the command
> > registers, the new driver may achieve faster throughputs in both
> > directions. Measurements show an improvement of about +23% read
> > throughput and +24% write throughput. These measurements have been
> > done with an Armada-385-DB-AP (4kiB NAND pages forced in 4-bit
> > strength BCH ECC correction) using the userspace tool 'flash_speed'
> > from the MTD test suite.
> > 
> > Besides these important topics, the new driver addresses several
> > unsolved known issues in the old driver which:
> > - did not work with ECC soft neither with ECC none ;
> > - relied on naked read/write (which is unchanged) while the NFCv1
> >   embedded in the pxa3xx platforms do not implement it, so several
> >   NAND commands did not actually ever work without any notice (like
> >   reading the ONFI PARAM_PAGE or SET/GET_FEATURES) ;
> > - wrote the OOB data correctly, but was not able to read it
> > correctly past the first OOB data chunk ;
> > - did not displayed ECC bytes ;  
> 
> 	    ^display
> 
> and I'm not even sure display is the right term here. How about
> 'retrieve'.
> 
> > - used device tree bindings that did not allow more than one NAND
> > chip, and did not allow to choose the correct chip select if not
> >   incrementing from 0. Plus, the Ready/Busy line used had to be 0.
> > 
> > Old device tree bindings are still supported but deprecated. A more
> > hierarchical view has to be used to keep the controller and the NAND
> > chip structures clearly separated both inside the device tree and
> > also in the driver code.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> > Tested-by: Sean Nyekjaer <sean.nyekjaer at prevas.dk>
> > Tested-by: Willy Tarreau <w at 1wt.eu>
> > ---


I made all the changes you requested, let me the time to do further
tests and I will send a v3.

Thanks,
Miqu?l


From Chris.Packham at alliedtelesis.co.nz  Sun Jan  7 14:35:04 2018
From: Chris.Packham at alliedtelesis.co.nz (Chris Packham)
Date: Sun, 7 Jan 2018 22:35:04 +0000
Subject: [PATCHv4 1/1] mtd: nand: pxa3xx: Set FORCE_CSX bit to ARMADA370
 variants
References: <20171221231904.21140-1-chris.packham@alliedtelesis.co.nz>
 <20171221231904.21140-2-chris.packham@alliedtelesis.co.nz>
 <20171222165308.10f2fe15@xps13>
 <CAAEAJfDzZJKVX+3f69o0UF6DgcQEW-UEmp-VG9bPkFd2dybYkQ@mail.gmail.com>
Message-ID: <c0b5230388814eb39b32575612152fbe@svr-chch-ex1.atlnz.lc>

Hi Miquel, Ezequiel,

On 23/12/17 05:56, Ezequiel Garcia wrote:
> On 22 December 2017 at 12:53, Miquel RAYNAL
> <miquel.raynal at free-electrons.com> wrote:
>> Hello Chris,
>>
>> On Fri, 22 Dec 2017 12:19:04 +1300
>> Chris Packham <chris.packham at alliedtelesis.co.nz> wrote:
>>
>>> From: Kalyan Kinthada <kalyan.kinthada at alliedtelesis.co.nz>
>>>
>>> The Armada-370 based SoCs support arbitration between the NAND Flash
>>> interface and NOR (i.e. devbus) on the same chip select. However there
>>> are two guidelines that must be followed to avoid data corruption in
>>> this scenario.
>>
>> Sorry to bother you again with that but, do you actually face any
>> issue/data corruption with this scenario?
>>
> 
> Indeed. We need a description of a real world problem this patch is fixing.
> 

I totally agree. The Marvell FAE used words like "data corruption" hence 
my re-newed interest in this. I had hoped these patches would pique the 
interest of someone from Marvell's engineering team with some more info 
on how the data corruption exhibits.

I've been running some of the mtd-utils tests on my hardware and haven't 
detected any failures yet.

I think the key would be to be doing interleaved accesses between nand 
and the parallel device. I've just kicked off something I think should 
do this on my hardware but I'm unsure as to how long I should wait for 
an issue to present itself.

I'll leave it running for as long as I can today. If I find a failure 
I'll report back otherwise we can leave this patch for the mailing list 
archives waiting for an issue to be seen.



From cyrille.pitchen at wedev4u.fr  Sun Jan  7 15:29:58 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Mon, 8 Jan 2018 00:29:58 +0100
Subject: [PATCH 1/3] spi-nor: intel-spi: Prefer WREN over other write
 enables
In-Reply-To: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
Message-ID: <e5406b68-c283-cedc-74bf-80e8a1f4da1c@wedev4u.fr>

Hi Mika,

Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> On many older systems using SW sequencer the PREOP_OPTYPE register
> contains two preopcodes as following:
> 
>   PREOP_OPTYPE=0xf2785006
> 
> The last two bytes are the opcodes decoded to:
> 
>   0x50 - Write enable for volatile status register
>   0x06 - Write enable
> 
> The former is used to modify volatile bits in the status register. For
> non-volatile bits the latter is needed. Preopcodes are used in SW
> sequencer to send one command "atomically" without anything else
> interfering the transfer. The sequence that gets executed is:
> 
>   - Send preopcode (write enable) from PREOP_OPTYPE register
>   - Send the actual SPI command
>   - Poll busy bit in the status register (0x05, RDSR)
> 
> Commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
> programmed by BIOS") enabled atomic sequence handling but because both
> preopcodes are programmed, the following happens:
> 
>   if (preop >> 8)
>   	val |= SSFSTS_CTL_SPOP;
> 
> Since on these systems preop >> 8 == 0x50 we end up picking volatile
> write enable instead. Because of this the actual write command is pretty
> much NOP unless there is a WREN latched in the chip already.
>

I agree with you but doesn't it mean that the Sector/Block Erase command that should
have been sent before the Page Program commands was discarded too?
If so, the BIOS should not have been corrupted at all.

Honestly, I don't really understand what is the real root cause of the BIOS corruption
reported by Ubuntu users. This is the issue your patch is trying to fix, isn't it?

Does the BIOS corruption occur just by probing the SPI controller and its SPI flash
memory during the boot or does some userspace program is involved too?

> Fix this by preferring WREN over other write enable preopcodes.
> 
> Fixes: 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> Cc: stable at vger.kernel.org
> ---
>  drivers/mtd/spi-nor/intel-spi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
> index ef034d898a23..bba762aa0c8d 100644
> --- a/drivers/mtd/spi-nor/intel-spi.c
> +++ b/drivers/mtd/spi-nor/intel-spi.c
> @@ -498,9 +498,17 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, int len,
>  	val |= SSFSTS_CTL_SCGO;
>  	preop = readw(ispi->sregs + PREOP_OPTYPE);
>  	if (preop) {
> -		val |= SSFSTS_CTL_ACS;
> -		if (preop >> 8)
> -			val |= SSFSTS_CTL_SPOP;
> +		switch (optype) {
> +		case OPTYPE_WRITE_NO_ADDR:
> +		case OPTYPE_WRITE_WITH_ADDR:
> +			/*
> +			 * For writes prefer WREN over other write enable
> +			 * opcodes.
> +			 */
> +			val |= SSFSTS_CTL_ACS;
> +			if ((preop >> 8) == SPINOR_OP_WREN)
> +				val |= SSFSTS_CTL_SPOP;
> +		}
>  	}
>  	writel(val, ispi->sregs + SSFSTS_CTL);
>  
> 

I guess I have figured out how the SPI controller works but just to be sure, what are
SSFSTS_CTL_SPOP and SSFSTS_CTL_ACS used for?

Why before commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
programmed by BIOS") were they not used at all? Does it mean that before Bin's patch,
when the controller was locked (by the BIOS?), the Linux driver never sent any Write Enable
command as pre op code, hence the SPI flash memory was read-only?

Why is ispi->locked not tested inside intel_spi_sw_cycle() at the same time as the preop
value? Do you try now to allow Page Program and Sector/Block Erase operations also when
ispi->lock is true?

Best regards,

Cyrille


From Wenyou.Yang at Microchip.com  Sun Jan  7 16:58:21 2018
From: Wenyou.Yang at Microchip.com (Yang, Wenyou)
Date: Mon, 8 Jan 2018 08:58:21 +0800
Subject: [PATCH] mtd/nand/atmel: Delete an error message for a failed
 memory allocation in two functions
In-Reply-To: <81cadb76-8c67-9289-1375-2d4a55a4adfa@users.sourceforge.net>
References: <81cadb76-8c67-9289-1375-2d4a55a4adfa@users.sourceforge.net>
Message-ID: <09e98604-00ec-64be-665a-a101b31028b1@Microchip.com>



On 2018/1/6 4:55, SF Markus Elfring wrote:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Fri, 5 Jan 2018 21:45:04 +0100
>
> Omit an extra message for a memory allocation failure in these functions.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> ---

Acked-by: Wenyou Yang <wenyou.yang at microchip.com>
>   drivers/mtd/nand/atmel/nand-controller.c | 8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
> index 90a71a56bc23..a41b999229c9 100644
> --- a/drivers/mtd/nand/atmel/nand-controller.c
> +++ b/drivers/mtd/nand/atmel/nand-controller.c
> @@ -1612,10 +1612,8 @@ static int atmel_nand_register(struct atmel_nand *nand)
>   		mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL,
>   					   "%s:nand.%d", dev_name(nc->dev),
>   					   nand->cs[0].id);
> -		if (!mtd->name) {
> -			dev_err(nc->dev, "Failed to allocate mtd->name\n");
> +		if (!mtd->name)
>   			return -ENOMEM;
> -		}
>   	}
>   
>   	ret = nand_scan_tail(mtd);
> @@ -1654,10 +1652,8 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
>   	nand = devm_kzalloc(nc->dev,
>   			    sizeof(*nand) + (numcs * sizeof(*nand->cs)),
>   			    GFP_KERNEL);
> -	if (!nand) {
> -		dev_err(nc->dev, "Failed to allocate NAND object\n");
> +	if (!nand)
>   		return ERR_PTR(-ENOMEM);
> -	}
>   
>   	nand->numcs = numcs;
>   

Best Regards,
Wenyou Yang


From guochun.mao at mediatek.com  Sun Jan  7 18:19:18 2018
From: guochun.mao at mediatek.com (Guochun Mao)
Date: Mon, 8 Jan 2018 10:19:18 +0800
Subject: [PATCH] mtd: mtk-nor: modify functions' name more generally
In-Reply-To: <1513561655-10570-2-git-send-email-guochun.mao@mediatek.com>
References: <1513561655-10570-1-git-send-email-guochun.mao@mediatek.com>
 <1513561655-10570-2-git-send-email-guochun.mao@mediatek.com>
Message-ID: <1515377958.8823.1.camel@mhfsdcap03>

Hi Cyrille,

Gentle ping...

BR,
Guochun

On Mon, 2017-12-18 at 09:47 +0800, Guochun Mao wrote:
> Since more and more Mediatek's SoC can use this driver to
> control spi-nor flash, functions' name with "mt8173_" is
> no longer properly. Replacing "mt8173_" with "mtk_" will
> be more accurate to describe these functions' usable scope.
> 
> Signed-off-by: Guochun Mao <guochun.mao at mediatek.com>
> ---
>  drivers/mtd/spi-nor/mtk-quadspi.c |  240 ++++++++++++++++++-------------------
>  1 file changed, 120 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
> index abe455c..5442993 100644
> --- a/drivers/mtd/spi-nor/mtk-quadspi.c
> +++ b/drivers/mtd/spi-nor/mtk-quadspi.c
> @@ -110,7 +110,7 @@
>  #define MTK_NOR_PRG_REG(n)		(MTK_NOR_PRGDATA0_REG + 4 * (n))
>  #define MTK_NOR_SHREG(n)		(MTK_NOR_SHREG0_REG + 4 * (n))
>  
> -struct mt8173_nor {
> +struct mtk_nor {
>  	struct spi_nor nor;
>  	struct device *dev;
>  	void __iomem *base;	/* nor flash base address */
> @@ -118,48 +118,48 @@ struct mt8173_nor {
>  	struct clk *nor_clk;
>  };
>  
> -static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor)
>  {
> -	struct spi_nor *nor = &mt8173_nor->nor;
> +	struct spi_nor *nor = &mtk_nor->nor;
>  
>  	switch (nor->read_proto) {
>  	case SNOR_PROTO_1_1_1:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA3_REG);
> -		writeb(MTK_NOR_FAST_READ, mt8173_nor->base +
> +		writeb(MTK_NOR_FAST_READ, mtk_nor->base +
>  		       MTK_NOR_CFG1_REG);
>  		break;
>  	case SNOR_PROTO_1_1_2:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA3_REG);
> -		writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base +
> +		writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	case SNOR_PROTO_1_1_4:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA4_REG);
> -		writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base +
> +		writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	default:
> -		writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base +
> +		writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	}
>  }
>  
> -static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval)
> +static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval)
>  {
>  	int reg;
>  	u8 val = cmdval & 0x1f;
>  
> -	writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG);
> -	return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg,
> +	writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG);
> +	return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg,
>  				  !(reg & val), 100, 10000);
>  }
>  
> -static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
> -			       u8 *tx, int txlen, u8 *rx, int rxlen)
> +static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op,
> +			    u8 *tx, int txlen, u8 *rx, int rxlen)
>  {
>  	int len = 1 + txlen + rxlen;
>  	int i, ret, idx;
> @@ -167,26 +167,26 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
>  	if (len > MTK_NOR_MAX_SHIFT)
>  		return -EINVAL;
>  
> -	writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG);
> +	writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG);
>  
>  	/* start at PRGDATA5, go down to PRGDATA0 */
>  	idx = MTK_NOR_MAX_RX_TX_SHIFT - 1;
>  
>  	/* opcode */
> -	writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +	writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  	idx--;
>  
>  	/* program TX data */
>  	for (i = 0; i < txlen; i++, idx--)
> -		writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +		writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  
>  	/* clear out rest of TX registers */
>  	while (idx >= 0) {
> -		writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +		writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  		idx--;
>  	}
>  
> -	ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD);
> +	ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD);
>  	if (ret)
>  		return ret;
>  
> @@ -195,20 +195,20 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
>  
>  	/* read out RX data */
>  	for (i = 0; i < rxlen; i++, idx--)
> -		rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx));
> +		rx[i] = readb(mtk_nor->base + MTK_NOR_SHREG(idx));
>  
>  	return 0;
>  }
>  
>  /* Do a WRSR (Write Status Register) command */
> -static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr)
> +static int mtk_nor_wr_sr(struct mtk_nor *mtk_nor, u8 sr)
>  {
> -	writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG);
> -	writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG);
> -	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD);
> +	writeb(sr, mtk_nor->base + MTK_NOR_PRGDATA5_REG);
> +	writeb(8, mtk_nor->base + MTK_NOR_CNT_REG);
> +	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WRSR_CMD);
>  }
>  
> -static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_write_buffer_enable(struct mtk_nor *mtk_nor)
>  {
>  	u8 reg;
>  
> @@ -216,27 +216,27 @@ static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
>  	 * 0: pre-fetch buffer use for read
>  	 * 1: pre-fetch buffer use for page program
>  	 */
> -	writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
> -	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
> +	writel(MTK_NOR_WR_BUF_ENABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
> +	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
>  				  0x01 == (reg & 0x01), 100, 10000);
>  }
>  
> -static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_write_buffer_disable(struct mtk_nor *mtk_nor)
>  {
>  	u8 reg;
>  
> -	writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
> -	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
> +	writel(MTK_NOR_WR_BUF_DISABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
> +	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
>  				  MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100,
>  				  10000);
>  }
>  
> -static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_set_addr_width(struct mtk_nor *mtk_nor)
>  {
>  	u8 val;
> -	struct spi_nor *nor = &mt8173_nor->nor;
> +	struct spi_nor *nor = &mtk_nor->nor;
>  
> -	val = readb(mt8173_nor->base + MTK_NOR_DUAL_REG);
> +	val = readb(mtk_nor->base + MTK_NOR_DUAL_REG);
>  
>  	switch (nor->addr_width) {
>  	case 3:
> @@ -246,115 +246,115 @@ static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
>  		val |= MTK_NOR_4B_ADDR_EN;
>  		break;
>  	default:
> -		dev_warn(mt8173_nor->dev, "Unexpected address width %u.\n",
> +		dev_warn(mtk_nor->dev, "Unexpected address width %u.\n",
>  			 nor->addr_width);
>  		break;
>  	}
>  
> -	writeb(val, mt8173_nor->base + MTK_NOR_DUAL_REG);
> +	writeb(val, mtk_nor->base + MTK_NOR_DUAL_REG);
>  }
>  
> -static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr)
> +static void mtk_nor_set_addr(struct mtk_nor *mtk_nor, u32 addr)
>  {
>  	int i;
>  
> -	mt8173_nor_set_addr_width(mt8173_nor);
> +	mtk_nor_set_addr_width(mtk_nor);
>  
>  	for (i = 0; i < 3; i++) {
> -		writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4);
> +		writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR0_REG + i * 4);
>  		addr >>= 8;
>  	}
>  	/* Last register is non-contiguous */
> -	writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG);
> +	writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR3_REG);
>  }
>  
> -static ssize_t mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length,
> -			       u_char *buffer)
> +static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
> +			    u_char *buffer)
>  {
>  	int i, ret;
>  	int addr = (int)from;
>  	u8 *buf = (u8 *)buffer;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	/* set mode for fast read mode ,dual mode or quad mode */
> -	mt8173_nor_set_read_mode(mt8173_nor);
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_read_mode(mtk_nor);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	for (i = 0; i < length; i++) {
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
>  		if (ret < 0)
>  			return ret;
> -		buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG);
> +		buf[i] = readb(mtk_nor->base + MTK_NOR_RDATA_REG);
>  	}
>  	return length;
>  }
>  
> -static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor,
> -					int addr, int length, u8 *data)
> +static int mtk_nor_write_single_byte(struct mtk_nor *mtk_nor,
> +				     int addr, int length, u8 *data)
>  {
>  	int i, ret;
>  
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	for (i = 0; i < length; i++) {
> -		writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG);
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD);
> +		writeb(*data++, mtk_nor->base + MTK_NOR_WDATA_REG);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_WR_CMD);
>  		if (ret < 0)
>  			return ret;
>  	}
>  	return 0;
>  }
>  
> -static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr,
> -				   const u8 *buf)
> +static int mtk_nor_write_buffer(struct mtk_nor *mtk_nor, int addr,
> +				const u8 *buf)
>  {
>  	int i, bufidx, data;
>  
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	bufidx = 0;
>  	for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) {
>  		data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 |
>  		       buf[bufidx + 1]<<8 | buf[bufidx];
>  		bufidx += 4;
> -		writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG);
> +		writel(data, mtk_nor->base + MTK_NOR_PP_DATA_REG);
>  	}
> -	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD);
> +	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WR_CMD);
>  }
>  
> -static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
> -				const u_char *buf)
> +static ssize_t mtk_nor_write(struct spi_nor *nor, loff_t to, size_t len,
> +			     const u_char *buf)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  	size_t i;
>  
> -	ret = mt8173_nor_write_buffer_enable(mt8173_nor);
> +	ret = mtk_nor_write_buffer_enable(mtk_nor);
>  	if (ret < 0) {
> -		dev_warn(mt8173_nor->dev, "write buffer enable failed!\n");
> +		dev_warn(mtk_nor->dev, "write buffer enable failed!\n");
>  		return ret;
>  	}
>  
>  	for (i = 0; i + SFLASH_WRBUF_SIZE <= len; i += SFLASH_WRBUF_SIZE) {
> -		ret = mt8173_nor_write_buffer(mt8173_nor, to, buf);
> +		ret = mtk_nor_write_buffer(mtk_nor, to, buf);
>  		if (ret < 0) {
> -			dev_err(mt8173_nor->dev, "write buffer failed!\n");
> +			dev_err(mtk_nor->dev, "write buffer failed!\n");
>  			return ret;
>  		}
>  		to += SFLASH_WRBUF_SIZE;
>  		buf += SFLASH_WRBUF_SIZE;
>  	}
> -	ret = mt8173_nor_write_buffer_disable(mt8173_nor);
> +	ret = mtk_nor_write_buffer_disable(mtk_nor);
>  	if (ret < 0) {
> -		dev_warn(mt8173_nor->dev, "write buffer disable failed!\n");
> +		dev_warn(mtk_nor->dev, "write buffer disable failed!\n");
>  		return ret;
>  	}
>  
>  	if (i < len) {
> -		ret = mt8173_nor_write_single_byte(mt8173_nor, to,
> -						   (int)(len - i), (u8 *)buf);
> +		ret = mtk_nor_write_single_byte(mtk_nor, to,
> +						(int)(len - i), (u8 *)buf);
>  		if (ret < 0) {
> -			dev_err(mt8173_nor->dev, "write single byte failed!\n");
> +			dev_err(mtk_nor->dev, "write single byte failed!\n");
>  			return ret;
>  		}
>  	}
> @@ -362,72 +362,72 @@ static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
>  	return len;
>  }
>  
> -static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
> +static int mtk_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	switch (opcode) {
>  	case SPINOR_OP_RDSR:
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_RDSR_CMD);
>  		if (ret < 0)
>  			return ret;
>  		if (len == 1)
> -			*buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG);
> +			*buf = readb(mtk_nor->base + MTK_NOR_RDSR_REG);
>  		else
> -			dev_err(mt8173_nor->dev, "len should be 1 for read status!\n");
> +			dev_err(mtk_nor->dev, "len should be 1 for read status!\n");
>  		break;
>  	default:
> -		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len);
> +		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, NULL, 0, buf, len);
>  		break;
>  	}
>  	return ret;
>  }
>  
> -static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
> -				int len)
> +static int mtk_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
> +			     int len)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	switch (opcode) {
>  	case SPINOR_OP_WRSR:
>  		/* We only handle 1 byte */
> -		ret = mt8173_nor_wr_sr(mt8173_nor, *buf);
> +		ret = mtk_nor_wr_sr(mtk_nor, *buf);
>  		break;
>  	default:
> -		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0);
> +		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, buf, len, NULL, 0);
>  		if (ret)
> -			dev_warn(mt8173_nor->dev, "write reg failure!\n");
> +			dev_warn(mtk_nor->dev, "write reg failure!\n");
>  		break;
>  	}
>  	return ret;
>  }
>  
> -static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_disable_clk(struct mtk_nor *mtk_nor)
>  {
> -	clk_disable_unprepare(mt8173_nor->spi_clk);
> -	clk_disable_unprepare(mt8173_nor->nor_clk);
> +	clk_disable_unprepare(mtk_nor->spi_clk);
> +	clk_disable_unprepare(mtk_nor->nor_clk);
>  }
>  
> -static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_enable_clk(struct mtk_nor *mtk_nor)
>  {
>  	int ret;
>  
> -	ret = clk_prepare_enable(mt8173_nor->spi_clk);
> +	ret = clk_prepare_enable(mtk_nor->spi_clk);
>  	if (ret)
>  		return ret;
>  
> -	ret = clk_prepare_enable(mt8173_nor->nor_clk);
> +	ret = clk_prepare_enable(mtk_nor->nor_clk);
>  	if (ret) {
> -		clk_disable_unprepare(mt8173_nor->spi_clk);
> +		clk_disable_unprepare(mtk_nor->spi_clk);
>  		return ret;
>  	}
>  
>  	return 0;
>  }
>  
> -static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
> +static int mtk_nor_init(struct mtk_nor *mtk_nor,
>  			struct device_node *flash_node)
>  {
>  	const struct spi_nor_hwcaps hwcaps = {
> @@ -439,18 +439,18 @@ static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
>  	struct spi_nor *nor;
>  
>  	/* initialize controller to accept commands */
> -	writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG);
> +	writel(MTK_NOR_ENABLE_SF_CMD, mtk_nor->base + MTK_NOR_WRPROT_REG);
>  
> -	nor = &mt8173_nor->nor;
> -	nor->dev = mt8173_nor->dev;
> -	nor->priv = mt8173_nor;
> +	nor = &mtk_nor->nor;
> +	nor->dev = mtk_nor->dev;
> +	nor->priv = mtk_nor;
>  	spi_nor_set_flash_node(nor, flash_node);
>  
>  	/* fill the hooks to spi nor */
> -	nor->read = mt8173_nor_read;
> -	nor->read_reg = mt8173_nor_read_reg;
> -	nor->write = mt8173_nor_write;
> -	nor->write_reg = mt8173_nor_write_reg;
> +	nor->read = mtk_nor_read;
> +	nor->read_reg = mtk_nor_read_reg;
> +	nor->write = mtk_nor_write;
> +	nor->write_reg = mtk_nor_write_reg;
>  	nor->mtd.name = "mtk_nor";
>  	/* initialized with NULL */
>  	ret = spi_nor_scan(nor, NULL, &hwcaps);
> @@ -465,34 +465,34 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>  	struct device_node *flash_np;
>  	struct resource *res;
>  	int ret;
> -	struct mt8173_nor *mt8173_nor;
> +	struct mtk_nor *mtk_nor;
>  
>  	if (!pdev->dev.of_node) {
>  		dev_err(&pdev->dev, "No DT found\n");
>  		return -EINVAL;
>  	}
>  
> -	mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL);
> -	if (!mt8173_nor)
> +	mtk_nor = devm_kzalloc(&pdev->dev, sizeof(*mtk_nor), GFP_KERNEL);
> +	if (!mtk_nor)
>  		return -ENOMEM;
> -	platform_set_drvdata(pdev, mt8173_nor);
> +	platform_set_drvdata(pdev, mtk_nor);
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res);
> -	if (IS_ERR(mt8173_nor->base))
> -		return PTR_ERR(mt8173_nor->base);
> +	mtk_nor->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(mtk_nor->base))
> +		return PTR_ERR(mtk_nor->base);
>  
> -	mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
> -	if (IS_ERR(mt8173_nor->spi_clk))
> -		return PTR_ERR(mt8173_nor->spi_clk);
> +	mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
> +	if (IS_ERR(mtk_nor->spi_clk))
> +		return PTR_ERR(mtk_nor->spi_clk);
>  
> -	mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
> -	if (IS_ERR(mt8173_nor->nor_clk))
> -		return PTR_ERR(mt8173_nor->nor_clk);
> +	mtk_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
> +	if (IS_ERR(mtk_nor->nor_clk))
> +		return PTR_ERR(mtk_nor->nor_clk);
>  
> -	mt8173_nor->dev = &pdev->dev;
> +	mtk_nor->dev = &pdev->dev;
>  
> -	ret = mt8173_nor_enable_clk(mt8173_nor);
> +	ret = mtk_nor_enable_clk(mtk_nor);
>  	if (ret)
>  		return ret;
>  
> @@ -503,20 +503,20 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>  		ret = -ENODEV;
>  		goto nor_free;
>  	}
> -	ret = mtk_nor_init(mt8173_nor, flash_np);
> +	ret = mtk_nor_init(mtk_nor, flash_np);
>  
>  nor_free:
>  	if (ret)
> -		mt8173_nor_disable_clk(mt8173_nor);
> +		mtk_nor_disable_clk(mtk_nor);
>  
>  	return ret;
>  }
>  
>  static int mtk_nor_drv_remove(struct platform_device *pdev)
>  {
> -	struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
> +	struct mtk_nor *mtk_nor = platform_get_drvdata(pdev);
>  
> -	mt8173_nor_disable_clk(mt8173_nor);
> +	mtk_nor_disable_clk(mtk_nor);
>  
>  	return 0;
>  }
> @@ -524,18 +524,18 @@ static int mtk_nor_drv_remove(struct platform_device *pdev)
>  #ifdef CONFIG_PM_SLEEP
>  static int mtk_nor_suspend(struct device *dev)
>  {
> -	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
> +	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
>  
> -	mt8173_nor_disable_clk(mt8173_nor);
> +	mtk_nor_disable_clk(mtk_nor);
>  
>  	return 0;
>  }
>  
>  static int mtk_nor_resume(struct device *dev)
>  {
> -	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
> +	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
>  
> -	return mt8173_nor_enable_clk(mt8173_nor);
> +	return mtk_nor_enable_clk(mtk_nor);
>  }
>  
>  static const struct dev_pm_ops mtk_nor_dev_pm_ops = {




From mika.westerberg at linux.intel.com  Sun Jan  7 20:00:38 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 8 Jan 2018 06:00:38 +0200
Subject: [PATCH 2/3] spi-nor: intel-spi: Explicitly mark the driver as
 dangerous in Kconfig
In-Reply-To: <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180104090744.67654-2-mika.westerberg@linux.intel.com>
 <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>
Message-ID: <20180108040038.GH27654@lahna.fi.intel.com>

On Sun, Jan 07, 2018 at 09:32:46PM +0100, Cyrille Pitchen wrote:
> Hi Mika,
> 
> Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> > The driver is not meant for normal users at all but instead such users
> > who really know what they are doing and are able to build their own
> > kernel to enable it. Mark both driver Kconfig entries as dangerous to
> > make sure the driver is not accidentally enabled without understanding
> > possible issues in doing so.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> > ---
> >  drivers/mtd/spi-nor/Kconfig | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
> > index 89da88e59121..f480b227a6b8 100644
> > --- a/drivers/mtd/spi-nor/Kconfig
> > +++ b/drivers/mtd/spi-nor/Kconfig
> > @@ -90,7 +90,7 @@ config SPI_INTEL_SPI
> >  	tristate
> >  
> >  config SPI_INTEL_SPI_PCI
> > -	tristate "Intel PCH/PCU SPI flash PCI driver"
> > +	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
> 
> I guess it might be even better and safer to add "default n" too, don't
> you agree? Adding only the "DANGEROUS" word would not prevent build
> scripts to select this driver when creating a kernel config from scratch.

But isn't it always "default n" unless otherwise stated?


From mika.westerberg at linux.intel.com  Sun Jan  7 20:02:41 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 8 Jan 2018 06:02:41 +0200
Subject: [PATCH 2/3] spi-nor: intel-spi: Explicitly mark the driver as
 dangerous in Kconfig
In-Reply-To: <20180107220631.73f303b6@bbrezillon>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180104090744.67654-2-mika.westerberg@linux.intel.com>
 <22d53b77-7c57-e86b-e8f5-465513382647@wedev4u.fr>
 <20180107220631.73f303b6@bbrezillon>
Message-ID: <20180108040241.GI27654@lahna.fi.intel.com>

On Sun, Jan 07, 2018 at 10:06:31PM +0100, Boris Brezillon wrote:
> On Sun, 7 Jan 2018 21:32:46 +0100
> Cyrille Pitchen <cyrille.pitchen at wedev4u.fr> wrote:
> 
> > Hi Mika,
> > 
> > Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> > > The driver is not meant for normal users at all but instead such users
> > > who really know what they are doing and are able to build their own
> > > kernel to enable it. Mark both driver Kconfig entries as dangerous to
> > > make sure the driver is not accidentally enabled without understanding
> > > possible issues in doing so.
> > > 
> > > Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> > > ---
> > >  drivers/mtd/spi-nor/Kconfig | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
> > > index 89da88e59121..f480b227a6b8 100644
> > > --- a/drivers/mtd/spi-nor/Kconfig
> > > +++ b/drivers/mtd/spi-nor/Kconfig
> > > @@ -90,7 +90,7 @@ config SPI_INTEL_SPI
> > >  	tristate
> > >  
> > >  config SPI_INTEL_SPI_PCI
> > > -	tristate "Intel PCH/PCU SPI flash PCI driver"
> > > +	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"  
> > 
> > I guess it might be even better and safer to add "default n" too, don't
> > you agree? Adding only the "DANGEROUS" word would not prevent build
> > scripts to select this driver when creating a kernel config from scratch.
> 
> How about adding
> 
> 	depends on EXPERT
> 
> ?

It used to be like that but then it was pointed out by Arnd Bergman that
EXPERT is not about hiding drivers and got removed by b8cc0012917d
("spi-nor: intel-spi: Remove EXPERT dependency").


From Chris.Packham at alliedtelesis.co.nz  Sun Jan  7 20:06:59 2018
From: Chris.Packham at alliedtelesis.co.nz (Chris Packham)
Date: Mon, 8 Jan 2018 04:06:59 +0000
Subject: [PATCHv4 1/1] mtd: nand: pxa3xx: Set FORCE_CSX bit to ARMADA370
 variants
References: <20171221231904.21140-1-chris.packham@alliedtelesis.co.nz>
 <20171221231904.21140-2-chris.packham@alliedtelesis.co.nz>
 <20171222165308.10f2fe15@xps13>
 <CAAEAJfDzZJKVX+3f69o0UF6DgcQEW-UEmp-VG9bPkFd2dybYkQ@mail.gmail.com>
 <c0b5230388814eb39b32575612152fbe@svr-chch-ex1.atlnz.lc>
Message-ID: <62666eec18c24419bcb9379f33776ba1@svr-chch-ex1.atlnz.lc>

On 08/01/18 11:35, Chris Packham wrote:
> Hi Miquel, Ezequiel,
> 
> On 23/12/17 05:56, Ezequiel Garcia wrote:
>> On 22 December 2017 at 12:53, Miquel RAYNAL
>> <miquel.raynal at free-electrons.com> wrote:
>>> Hello Chris,
>>>
>>> On Fri, 22 Dec 2017 12:19:04 +1300
>>> Chris Packham <chris.packham at alliedtelesis.co.nz> wrote:
>>>
>>>> From: Kalyan Kinthada <kalyan.kinthada at alliedtelesis.co.nz>
>>>>
>>>> The Armada-370 based SoCs support arbitration between the NAND Flash
>>>> interface and NOR (i.e. devbus) on the same chip select. However there
>>>> are two guidelines that must be followed to avoid data corruption in
>>>> this scenario.
>>>
>>> Sorry to bother you again with that but, do you actually face any
>>> issue/data corruption with this scenario?
>>>
>>
>> Indeed. We need a description of a real world problem this patch is fixing.
>>
> 
> I totally agree. The Marvell FAE used words like "data corruption" hence
> my re-newed interest in this. I had hoped these patches would pique the
> interest of someone from Marvell's engineering team with some more info
> on how the data corruption exhibits.
> 
> I've been running some of the mtd-utils tests on my hardware and haven't
> detected any failures yet.
> 
> I think the key would be to be doing interleaved accesses between nand
> and the parallel device. I've just kicked off something I think should
> do this on my hardware but I'm unsure as to how long I should wait for
> an issue to present itself.
> 
> I'll leave it running for as long as I can today. If I find a failure
> I'll report back otherwise we can leave this patch for the mailing list
> archives waiting for an issue to be seen.
> 

I've been running my test for several hours an no obvious problem has 
presented itself so I'm happy to leave it there until such time as a 
problem is observed or Marvell provide a reproduction.



From mika.westerberg at linux.intel.com  Sun Jan  7 20:28:48 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 8 Jan 2018 06:28:48 +0200
Subject: [PATCH 1/3] spi-nor: intel-spi: Prefer WREN over other write
 enables
In-Reply-To: <e5406b68-c283-cedc-74bf-80e8a1f4da1c@wedev4u.fr>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <e5406b68-c283-cedc-74bf-80e8a1f4da1c@wedev4u.fr>
Message-ID: <20180108042848.GJ27654@lahna.fi.intel.com>

On Mon, Jan 08, 2018 at 12:29:58AM +0100, Cyrille Pitchen wrote:
> Hi Mika,
> 
> Le 04/01/2018 ? 10:07, Mika Westerberg a ?crit?:
> > On many older systems using SW sequencer the PREOP_OPTYPE register
> > contains two preopcodes as following:
> > 
> >   PREOP_OPTYPE=0xf2785006
> > 
> > The last two bytes are the opcodes decoded to:
> > 
> >   0x50 - Write enable for volatile status register
> >   0x06 - Write enable
> > 
> > The former is used to modify volatile bits in the status register. For
> > non-volatile bits the latter is needed. Preopcodes are used in SW
> > sequencer to send one command "atomically" without anything else
> > interfering the transfer. The sequence that gets executed is:
> > 
> >   - Send preopcode (write enable) from PREOP_OPTYPE register
> >   - Send the actual SPI command
> >   - Poll busy bit in the status register (0x05, RDSR)
> > 
> > Commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
> > programmed by BIOS") enabled atomic sequence handling but because both
> > preopcodes are programmed, the following happens:
> > 
> >   if (preop >> 8)
> >   	val |= SSFSTS_CTL_SPOP;
> > 
> > Since on these systems preop >> 8 == 0x50 we end up picking volatile
> > write enable instead. Because of this the actual write command is pretty
> > much NOP unless there is a WREN latched in the chip already.
> >
> 
> I agree with you but doesn't it mean that the Sector/Block Erase command that should
> have been sent before the Page Program commands was discarded too?

Yes

> If so, the BIOS should not have been corrupted at all.

Correct and there was never any BIOS corruption.

> Honestly, I don't really understand what is the real root cause of the BIOS corruption
> reported by Ubuntu users. This is the issue your patch is trying to fix, isn't it?

No, this patch does not try to fix that issue because it has
already been fixed with 9d63f17661e2 ("spi-nor: intel-spi: Fix broken
software sequencing codes") in september.

The root cause is explained here:

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1734147/comments/330

To summarize. The BIOS programs all allowable opcodes to OPMENU0/1
registers and then locks them down. One of the opcodes was WRSR (Write
Status register) which is already against any recommendations
to have it there in the first place.

Nevertheless Linux clears the first status register when
SPI_NOR_HAS_LOCK is set for the serial flash. Because of the bug that
was fixed with 9d63f17661e2 we accidentally write an additional byte
from the FIFO (which is second byte of the JEDEC ID we just read) that
then goes to the second status register (because WRSR allows to write
all of them at once). If the second byte of the JEDEC ID happens to have
bit 6 set it means that now the serial flash CMP (complement) bit is
set. CMP=1 and BP0/1/2=0 means the whole flash is write protected.

The BIOS in question then cannot save settings anymore.

So the issue is actually not about any corruption but simply that the
chip is set to write protected from the status register.

Also note that it did not affect all the systems, mostly because of the
missing WREN handling. Normally the WRSR write would have been discarded
but if the BIOS before it handed of to the OS did WREN the write from
our WRSR took place and set the CMP bit to 1.

This is all fixable by software and in fact in the launcpad bug there
is another pre-built kernel image where we explictly clear both status
registers (it includes this patch) to make sure CMP is set back to 0.
That has recovered most of the affected systems AFAIK.

What this patch actually is about is to properly handle the WREN+WRSR
atomic sequence.

> Does the BIOS corruption occur just by probing the SPI controller and its SPI flash
> memory during the boot or does some userspace program is involved too?

See above.

> 
> > Fix this by preferring WREN over other write enable preopcodes.
> > 
> > Fixes: 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
> > Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/mtd/spi-nor/intel-spi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
> > index ef034d898a23..bba762aa0c8d 100644
> > --- a/drivers/mtd/spi-nor/intel-spi.c
> > +++ b/drivers/mtd/spi-nor/intel-spi.c
> > @@ -498,9 +498,17 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, int len,
> >  	val |= SSFSTS_CTL_SCGO;
> >  	preop = readw(ispi->sregs + PREOP_OPTYPE);
> >  	if (preop) {
> > -		val |= SSFSTS_CTL_ACS;
> > -		if (preop >> 8)
> > -			val |= SSFSTS_CTL_SPOP;
> > +		switch (optype) {
> > +		case OPTYPE_WRITE_NO_ADDR:
> > +		case OPTYPE_WRITE_WITH_ADDR:
> > +			/*
> > +			 * For writes prefer WREN over other write enable
> > +			 * opcodes.
> > +			 */
> > +			val |= SSFSTS_CTL_ACS;
> > +			if ((preop >> 8) == SPINOR_OP_WREN)
> > +				val |= SSFSTS_CTL_SPOP;
> > +		}
> >  	}
> >  	writel(val, ispi->sregs + SSFSTS_CTL);
> >  
> > 
> 
> I guess I have figured out how the SPI controller works but just to be sure, what are
> SSFSTS_CTL_SPOP and SSFSTS_CTL_ACS used for?

_SPOP selects preopcode from two available (WREN and something else)

_ACS enables atomic sequence i.e execute preopcode + opcode + wait for
busy.

> Why before commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
> programmed by BIOS") were they not used at all? Does it mean that before Bin's patch,
> when the controller was locked (by the BIOS?), the Linux driver never sent any Write Enable
> command as pre op code, hence the SPI flash memory was read-only?

Yes.

> Why is ispi->locked not tested inside intel_spi_sw_cycle() at the same time as the preop
> value? Do you try now to allow Page Program and Sector/Block Erase operations also when
> ispi->lock is true?

ispi->locked is never changed and it is not about write protection to
the serial flash but it means that certain controller registers (like
the OPMENU0/1) cannot be modified.


From boris.brezillon at free-electrons.com  Mon Jan  8 00:18:31 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 09:18:31 +0100
Subject: [PATCH] mtd/nand/atmel: Delete an error message for a failed
 memory allocation in two functions
In-Reply-To: <09e98604-00ec-64be-665a-a101b31028b1@Microchip.com>
References: <81cadb76-8c67-9289-1375-2d4a55a4adfa@users.sourceforge.net>
 <09e98604-00ec-64be-665a-a101b31028b1@Microchip.com>
Message-ID: <20180108091831.64d54599@bbrezillon>

[private message]
Hi Wenyou,

On Mon, 8 Jan 2018 08:58:21 +0800
"Yang, Wenyou" <Wenyou.Yang at Microchip.com> wrote:

> On 2018/1/6 4:55, SF Markus Elfring wrote:
> > From: Markus Elfring <elfring at users.sourceforge.net>
> > Date: Fri, 5 Jan 2018 21:45:04 +0100
> >
> > Omit an extra message for a memory allocation failure in these functions.
> >
> > This issue was detected by using the Coccinelle software.
> >
> > Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> > ---  
> 
> Acked-by: Wenyou Yang <wenyou.yang at microchip.com>

Please don't encourage Markus to send more patches. The MTD maintainers
(like other maintainers) have decided to ignore his contributions.

If you want to know why, just google his name and you should have a
pretty good idea.

Thanks,

Boris

> >   drivers/mtd/nand/atmel/nand-controller.c | 8 ++------
> >   1 file changed, 2 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
> > index 90a71a56bc23..a41b999229c9 100644
> > --- a/drivers/mtd/nand/atmel/nand-controller.c
> > +++ b/drivers/mtd/nand/atmel/nand-controller.c
> > @@ -1612,10 +1612,8 @@ static int atmel_nand_register(struct atmel_nand *nand)
> >   		mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL,
> >   					   "%s:nand.%d", dev_name(nc->dev),
> >   					   nand->cs[0].id);
> > -		if (!mtd->name) {
> > -			dev_err(nc->dev, "Failed to allocate mtd->name\n");
> > +		if (!mtd->name)
> >   			return -ENOMEM;
> > -		}
> >   	}
> >   
> >   	ret = nand_scan_tail(mtd);
> > @@ -1654,10 +1652,8 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
> >   	nand = devm_kzalloc(nc->dev,
> >   			    sizeof(*nand) + (numcs * sizeof(*nand->cs)),
> >   			    GFP_KERNEL);
> > -	if (!nand) {
> > -		dev_err(nc->dev, "Failed to allocate NAND object\n");
> > +	if (!nand)
> >   		return ERR_PTR(-ENOMEM);
> > -	}
> >   
> >   	nand->numcs = numcs;
> >     
> 
> Best Regards,
> Wenyou Yang



From boris.brezillon at free-electrons.com  Mon Jan  8 00:33:37 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 09:33:37 +0100
Subject: [PATCH] mtd/nand/atmel: Delete an error message for a failed
 memory allocation in two functions
In-Reply-To: <20180108091831.64d54599@bbrezillon>
References: <81cadb76-8c67-9289-1375-2d4a55a4adfa@users.sourceforge.net>
 <09e98604-00ec-64be-665a-a101b31028b1@Microchip.com>
 <20180108091831.64d54599@bbrezillon>
Message-ID: <20180108093337.3a9cb292@bbrezillon>

On Mon, 8 Jan 2018 09:18:31 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> [private message]

Oops, not so private :-).

> Hi Wenyou,
> 
> On Mon, 8 Jan 2018 08:58:21 +0800
> "Yang, Wenyou" <Wenyou.Yang at Microchip.com> wrote:
> 
> > On 2018/1/6 4:55, SF Markus Elfring wrote:  
> > > From: Markus Elfring <elfring at users.sourceforge.net>
> > > Date: Fri, 5 Jan 2018 21:45:04 +0100
> > >
> > > Omit an extra message for a memory allocation failure in these functions.
> > >
> > > This issue was detected by using the Coccinelle software.
> > >
> > > Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> > > ---    
> > 
> > Acked-by: Wenyou Yang <wenyou.yang at microchip.com>  
> 
> Please don't encourage Markus to send more patches. The MTD maintainers
> (like other maintainers) have decided to ignore his contributions.
> 
> If you want to know why, just google his name and you should have a
> pretty good idea.
> 
> Thanks,
> 
> Boris
> 
> > >   drivers/mtd/nand/atmel/nand-controller.c | 8 ++------
> > >   1 file changed, 2 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
> > > index 90a71a56bc23..a41b999229c9 100644
> > > --- a/drivers/mtd/nand/atmel/nand-controller.c
> > > +++ b/drivers/mtd/nand/atmel/nand-controller.c
> > > @@ -1612,10 +1612,8 @@ static int atmel_nand_register(struct atmel_nand *nand)
> > >   		mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL,
> > >   					   "%s:nand.%d", dev_name(nc->dev),
> > >   					   nand->cs[0].id);
> > > -		if (!mtd->name) {
> > > -			dev_err(nc->dev, "Failed to allocate mtd->name\n");
> > > +		if (!mtd->name)
> > >   			return -ENOMEM;
> > > -		}
> > >   	}
> > >   
> > >   	ret = nand_scan_tail(mtd);
> > > @@ -1654,10 +1652,8 @@ static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
> > >   	nand = devm_kzalloc(nc->dev,
> > >   			    sizeof(*nand) + (numcs * sizeof(*nand->cs)),
> > >   			    GFP_KERNEL);
> > > -	if (!nand) {
> > > -		dev_err(nc->dev, "Failed to allocate NAND object\n");
> > > +	if (!nand)
> > >   		return ERR_PTR(-ENOMEM);
> > > -	}
> > >   
> > >   	nand->numcs = numcs;
> > >       
> > 
> > Best Regards,
> > Wenyou Yang  
> 



From prabhakar.kushwaha at nxp.com  Mon Jan  8 00:42:32 2018
From: prabhakar.kushwaha at nxp.com (Prabhakar Kushwaha)
Date: Mon, 8 Jan 2018 08:42:32 +0000
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
 <20180105144444.338c2cdc@bbrezillon>
 <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>
Message-ID: <HE1PR04MB1241F9507EDB679098CDA13197130@HE1PR04MB1241.eurprd04.prod.outlook.com>

Thanks Jonas, Boris,

Let me try to put my understanding and some proposal based on discussions.

> -----Original Message-----
> From: Jonas Gorski [mailto:jonas.gorski at gmail.com]
> Sent: Friday, January 05, 2018 7:28 PM
> To: Boris Brezillon <boris.brezillon at free-electrons.com>
> Cc: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Marek Vasut
> <marex at denx.de>; Richard Weinberger <richard at nod.at>; Brian Norris
> <computersforpeace at gmail.com>; linux-mtd at lists.infradead.org; Cyrille
> Pitchen <cyrille.pitchen at wedev4u.fr>
> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> and NAND flash
> 
> On 5 January 2018 at 14:44, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Fri, 5 Jan 2018 14:38:48 +0100
> > Jonas Gorski <jonas.gorski at gmail.com> wrote:
> >
> >> On 5 January 2018 at 11:21, Prabhakar Kushwaha
> >> <prabhakar.kushwaha at nxp.com> wrote:
> >> > Thanks Boris for the encouragement.
> >> >
> >> >> -----Original Message-----
> >> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> >> >> Sent: Thursday, January 04, 2018 11:17 PM
> >> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> >> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen
> <cyrille.pitchen at wedev4u.fr>;
> >> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>;
> Brian
> >> >> Norris <computersforpeace at gmail.com>
> >> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both
> NOR
> >> >> and NAND flash
> >> >>
> >> >> +MTD maintainers.
> >> >>
> >> >> On Thu, 4 Jan 2018 14:08:42 +0000
> >> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> >> >>
> >> >> > Hi All,
> >> >> >
> >> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of
> Serial
> >> >> NOR(Die #0) and Serial NAND(Die #1) flash.
> >> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled
> by
> >> >> single chip-select.
> >> >> >
> >> >> > "Software Die Select (C2h)" command is being used to switch die or flash.
> >> >>
> >> >> Why are they so mean to us?! :-)
> >> >>
> >> >> >
> >> >> > It looks to be quite unique chip and wondering if any kind framework or
> work in
> >> >> progress available to handle it.
> >> >> > I know that SPI-NAND framework discussions is still in progress.
> >> >>
> >> >> Well, nothing impossible to handle, we just need to declare 2 MTD
> >> >> devices (one NAND and one NOR). This being said, it looks like we'll
> >> >> need this spi-flash abstraction we have been talking about with Marek
> >> >> and Cyrille to properly support these use cases: flash devices will be
> >> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
> >> >> a common way to detect those spi-flash chips. I looked at a few SPI
> >> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
> >> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
> >> >> different) so I thought we were safe to start with a completely
> >> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
> >> >> afterwards, but this chip proves me wrong :-/.
> >> >
> >> > I am thinking of following changes with fsl_qspi.c as controller
> >> >
> >> > &qspi {
> >> >         num-cs = <2>;
> >> >         bus-num = <0>;
> >> >         status = "okay";
> >> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated
> compatibility for drivers
> >> >         qflash0: w25q16fw @0 {
> >> >                 #address-cells = <1>;
> >> >                 #size-cells = <1>;
> >> >                 spi-max-frequency = <20000000>;
> >> >                 reg = <0>;
> >> >                 type = "serial-nor"   <-- Proposed New binding
> >> >                 is-hybrid <-- Proposed New binding
> >> >                 die-num <-- Proposed New binding
> >> >         };
> >> >
> >> >         qflash1: w25n01gw at 1 {
> >> >                 #address-cells = <1>;
> >> >                 #size-cells = <1>;
> >> >                 spi-max-frequency = <20000000>;
> >> >                 reg = <1>;
> >> >                 type = "serial-nand" <-- Proposed New binding
> >> >                 is-hybrid <-- Proposed New binding
> >> >                 die-num <-- Proposed New binding
> >> >         }
> >> > };
> >>
> >> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
> >> SPI-NAND chips when selected, a more appropriate binding might be
> >>
> >> &qspi {
> >>     ...
> >>         qflash0: dual-flash at 0 {
> >>                 compatible = "winbond,w25q16fw";
> >>                 reg = <0>;
> >>                 spi-max-frequency = <20000000>;
> >>                 #address-cells = <1>;
> >>                 #size-cells = <0>;
> >>
> >>                 nor at 0 {
> >>                                 compatible = "jedec,spi-nor";
> >>                                 reg = <0>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >>
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };
> >>
> >>                 nand at 1 {
> >>                                 compatible = "jedec,spi-nand"; /* or
> >> whatever the correct nand-compatible would be */
> >>                                 reg = <1>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >>
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };
> >>
> >>     };
> >> };
> >>
> >> with the "windbond,w25q16fw" driver modeled as a simple
> >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> >> spi-nor or spi-nand tries to communicate with their appropriate die,
> >> it sends the Software Die Select command if needed and then passes on
> >> the message to its parent bus.
> >>
> >> That way there should be no changes needed for spi-nor / spi-nand
> >> themselves. (The devil is probably in the details ;-)
> >
> > Yep, I thought about this approach, and it's indeed quite elegant, but
> > we're missing the lock I was mentioning in my previous reply. We need
> > to prevent die selection not only for the time we're sending a single
> > SPI message, but for the whole operation (which can be formed of
> > several SPI messages). Or maybe I'm wrong, and operations can actually
> > be interleaved, but I wouldn't bet on that ;-).
> 
> Ah, I missed that. I thought about it, and then tried to hand wave it
> away with the "if they behave like normal chips" ;-)
> 
> The mdio-bus supports nested locking, so you can do something like this:
> 
> mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
> bus->write();
> bus->read();
> mutex_unlock(bus->mdio_lock);
> 
> without worrying someone else using the bus in between. [1] for an example
> user.
> 
> So going a similar approach with flagging the appropriate chips in
> spi-nor/spi-nand as needing nested locking and then doing it for the
> appropriate commands should solve that issue.
> 
> 

Device tree update:-

&qspi {
    ...
        qflash0: dual-flash at 0 {
                compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value
                reg = <0>;
                spi-max-frequency = <20000000>;
                #address-cells = <1>;
                #size-cells = <0>;

                nor at 0 {
                                compatible = "jedec,spi-nor";
                                reg = <0>;
                                #address-cells = <1>;
                                #size-cells = <1>;

                                partitions {
                                                ...
                                };
                };

                nand at 1 {
                                compatible = "jedec,spi-nand"; /* or
whatever the correct nand-compatible would be */
                                reg = <1>;
                                #address-cells = <1>;
                                #size-cells = <1>;

                                partitions {
                                                ...
                                };
                };

    };
};


There will be only one file i.e. fsl_qspi.c handing NOR and NAND. QSPI controller will have SPI NOR and a SPI NAND controller embedded.
Question: What should be the location of this file?  driver/mtd/spi-nor definitely is not right place??


Change in Data structures
----------------------------------

struct mtd_info {
	----
	struct mutex *hybrid_flock;
 	---
}

struct fsl_qspi {
	---
	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
	struct spinand_device spinand[FSL_QSPI_MAX_CHIP];
	---
}

Function implementation
----------------------------------

fsl_qspi.c
	 probe() {
		--
		--
  		 for_each_available_child_of_node(dev->of_node, np) {
			if compatible "hybrid" {
				hybrid_flock = malloc(sizeof(struct mutex));
       				- if compatible "jedec,spi-nor" 
					spi_nor_scan()
       				- if compatible "jedec,spi-nand"
					spinand_init()
				
				mtd_device_config_hybrid_lock(spi_nor->mtd, hybrid_flock);
				mtd_device_config_hybrid_lock(spinand->mtd, hybrid_flock);
								
			} else {
       				- if compatible "jedec,spi-nor"
					spi_nor_scan()
       				- if compatible "jedec,spi-nand"
					spinand_init()
			}
		}
  		--
		--	
	}


Whenever read/write/erase come from MTD layer , Take MTD layer lock in function definition i.e. mtd->_read_oob, mtd->_write_oob. mtd->_erase... 
For eg. 
spi_nor_read (struct mtd_info *mtd ...) {
	
	if (hybrid_flock)
		mutex_lock(&mtd-> hybrid_flock);
	spi_nor_lock_and_prep();
	--
	--
	spi_nor_unlock_and_unprep();
	if (hybrid_flock)
		mutex_unlock(&mtd-> hybrid_flock);
}

static int spinand_mtd_read(struct mtd_info *mtd, ...)
{
	if (hybrid_flock)
		mutex_lock(&mtd-> hybrid_flock);

	mutex_lock(&spinand->lock);

	---
	---

	mutex_unlock(&spinand->lock);
	if (hybrid_flock)
		mutex_unlock(&mtd-> hybrid_flock);
}

Please let me know your view on this. 

--pk

From boris.brezillon at free-electrons.com  Mon Jan  8 01:14:47 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 10:14:47 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <HE1PR04MB1241F9507EDB679098CDA13197130@HE1PR04MB1241.eurprd04.prod.outlook.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
 <20180105144444.338c2cdc@bbrezillon>
 <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>
 <HE1PR04MB1241F9507EDB679098CDA13197130@HE1PR04MB1241.eurprd04.prod.outlook.com>
Message-ID: <20180108101447.1d9ab212@bbrezillon>

On Mon, 8 Jan 2018 08:42:32 +0000
Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:

> Thanks Jonas, Boris,
> 
> Let me try to put my understanding and some proposal based on discussions.
> 
> > -----Original Message-----
> > From: Jonas Gorski [mailto:jonas.gorski at gmail.com]
> > Sent: Friday, January 05, 2018 7:28 PM
> > To: Boris Brezillon <boris.brezillon at free-electrons.com>
> > Cc: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Marek Vasut
> > <marex at denx.de>; Richard Weinberger <richard at nod.at>; Brian Norris
> > <computersforpeace at gmail.com>; linux-mtd at lists.infradead.org; Cyrille
> > Pitchen <cyrille.pitchen at wedev4u.fr>
> > Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> > and NAND flash
> > 
> > On 5 January 2018 at 14:44, Boris Brezillon
> > <boris.brezillon at free-electrons.com> wrote:  
> > > On Fri, 5 Jan 2018 14:38:48 +0100
> > > Jonas Gorski <jonas.gorski at gmail.com> wrote:
> > >  
> > >> On 5 January 2018 at 11:21, Prabhakar Kushwaha
> > >> <prabhakar.kushwaha at nxp.com> wrote:  
> > >> > Thanks Boris for the encouragement.
> > >> >  
> > >> >> -----Original Message-----
> > >> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> > >> >> Sent: Thursday, January 04, 2018 11:17 PM
> > >> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> > >> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen  
> > <cyrille.pitchen at wedev4u.fr>;  
> > >> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>;  
> > Brian  
> > >> >> Norris <computersforpeace at gmail.com>
> > >> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both  
> > NOR  
> > >> >> and NAND flash
> > >> >>
> > >> >> +MTD maintainers.
> > >> >>
> > >> >> On Thu, 4 Jan 2018 14:08:42 +0000
> > >> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> > >> >>  
> > >> >> > Hi All,
> > >> >> >
> > >> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of  
> > Serial  
> > >> >> NOR(Die #0) and Serial NAND(Die #1) flash.  
> > >> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled  
> > by  
> > >> >> single chip-select.  
> > >> >> >
> > >> >> > "Software Die Select (C2h)" command is being used to switch die or flash.  
> > >> >>
> > >> >> Why are they so mean to us?! :-)
> > >> >>  
> > >> >> >
> > >> >> > It looks to be quite unique chip and wondering if any kind framework or  
> > work in  
> > >> >> progress available to handle it.  
> > >> >> > I know that SPI-NAND framework discussions is still in progress.  
> > >> >>
> > >> >> Well, nothing impossible to handle, we just need to declare 2 MTD
> > >> >> devices (one NAND and one NOR). This being said, it looks like we'll
> > >> >> need this spi-flash abstraction we have been talking about with Marek
> > >> >> and Cyrille to properly support these use cases: flash devices will be
> > >> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
> > >> >> a common way to detect those spi-flash chips. I looked at a few SPI
> > >> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
> > >> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
> > >> >> different) so I thought we were safe to start with a completely
> > >> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
> > >> >> afterwards, but this chip proves me wrong :-/.  
> > >> >
> > >> > I am thinking of following changes with fsl_qspi.c as controller
> > >> >
> > >> > &qspi {
> > >> >         num-cs = <2>;
> > >> >         bus-num = <0>;
> > >> >         status = "okay";
> > >> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated  
> > compatibility for drivers  
> > >> >         qflash0: w25q16fw @0 {
> > >> >                 #address-cells = <1>;
> > >> >                 #size-cells = <1>;
> > >> >                 spi-max-frequency = <20000000>;
> > >> >                 reg = <0>;
> > >> >                 type = "serial-nor"   <-- Proposed New binding
> > >> >                 is-hybrid <-- Proposed New binding
> > >> >                 die-num <-- Proposed New binding
> > >> >         };
> > >> >
> > >> >         qflash1: w25n01gw at 1 {
> > >> >                 #address-cells = <1>;
> > >> >                 #size-cells = <1>;
> > >> >                 spi-max-frequency = <20000000>;
> > >> >                 reg = <1>;
> > >> >                 type = "serial-nand" <-- Proposed New binding
> > >> >                 is-hybrid <-- Proposed New binding
> > >> >                 die-num <-- Proposed New binding
> > >> >         }
> > >> > };  
> > >>
> > >> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
> > >> SPI-NAND chips when selected, a more appropriate binding might be
> > >>
> > >> &qspi {
> > >>     ...
> > >>         qflash0: dual-flash at 0 {
> > >>                 compatible = "winbond,w25q16fw";
> > >>                 reg = <0>;
> > >>                 spi-max-frequency = <20000000>;
> > >>                 #address-cells = <1>;
> > >>                 #size-cells = <0>;
> > >>
> > >>                 nor at 0 {
> > >>                                 compatible = "jedec,spi-nor";
> > >>                                 reg = <0>;
> > >>                                 #address-cells = <1>;
> > >>                                 #size-cells = <1>;
> > >>
> > >>                                 partitions {
> > >>                                                 ...
> > >>                                 };
> > >>                 };
> > >>
> > >>                 nand at 1 {
> > >>                                 compatible = "jedec,spi-nand"; /* or
> > >> whatever the correct nand-compatible would be */
> > >>                                 reg = <1>;
> > >>                                 #address-cells = <1>;
> > >>                                 #size-cells = <1>;
> > >>
> > >>                                 partitions {
> > >>                                                 ...
> > >>                                 };
> > >>                 };
> > >>
> > >>     };
> > >> };
> > >>
> > >> with the "windbond,w25q16fw" driver modeled as a simple
> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
> > >> it sends the Software Die Select command if needed and then passes on
> > >> the message to its parent bus.
> > >>
> > >> That way there should be no changes needed for spi-nor / spi-nand
> > >> themselves. (The devil is probably in the details ;-)  
> > >
> > > Yep, I thought about this approach, and it's indeed quite elegant, but
> > > we're missing the lock I was mentioning in my previous reply. We need
> > > to prevent die selection not only for the time we're sending a single
> > > SPI message, but for the whole operation (which can be formed of
> > > several SPI messages). Or maybe I'm wrong, and operations can actually
> > > be interleaved, but I wouldn't bet on that ;-).  
> > 
> > Ah, I missed that. I thought about it, and then tried to hand wave it
> > away with the "if they behave like normal chips" ;-)
> > 
> > The mdio-bus supports nested locking, so you can do something like this:
> > 
> > mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
> > bus->write();
> > bus->read();
> > mutex_unlock(bus->mdio_lock);
> > 
> > without worrying someone else using the bus in between. [1] for an example
> > user.
> > 
> > So going a similar approach with flagging the appropriate chips in
> > spi-nor/spi-nand as needing nested locking and then doing it for the
> > appropriate commands should solve that issue.
> > 
> >   
> 
> Device tree update:-
> 
> &qspi {
>     ...
>         qflash0: dual-flash at 0 {
>                 compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value

"hybrid" is not needed, you know that the flash is hybrid with the
"winbond,w25q16fw" string.

>                 reg = <0>;
>                 spi-max-frequency = <20000000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> 
>                 nor at 0 {
>                                 compatible = "jedec,spi-nor";
>                                 reg = <0>;
>                                 #address-cells = <1>;
>                                 #size-cells = <1>;
> 
>                                 partitions {
>                                                 ...
>                                 };
>                 };
> 
>                 nand at 1 {
>                                 compatible = "jedec,spi-nand"; /* or
> whatever the correct nand-compatible would be */
>                                 reg = <1>;
>                                 #address-cells = <1>;
>                                 #size-cells = <1>;
> 
>                                 partitions {
>                                                 ...
>                                 };
>                 };

Not sure exposing the dies in the DT is such a good idea. You should
have a specific handling for "winbond,w25q16fw" which registers one
NAND and one NOR.

> 
>     };
> };



> 
> 
> There will be only one file i.e. fsl_qspi.c handing NOR and NAND. QSPI controller will have SPI NOR and a SPI NAND controller embedded.
> Question: What should be the location of this file?  driver/mtd/spi-nor definitely is not right place??

It stay in driver/mtd/spi-nor until we create a spi-flash layer
(driver/mtd/spi-flash).

> 
> 
> Change in Data structures
> ----------------------------------
> 
> struct mtd_info {
> 	----
> 	struct mutex *hybrid_flock;
>  	---
> }

Nope, the hybrid_flock should not be in mtd_info. We should create an
hybrid_spi_flash struct containing this lock and an array of SPI flash.

struct hybrid_spi_flash;

enum spi_flash_type {
	SPI_NOR,
	SPI_NAND,
};

struct spi_flash {
	enum spi_flash_type type;
	struct hybrid_spi_flash *master;
};

struct hybrid_spi_flash {
	struct mutex lock;
	struct spi_flash **subdevs;
};

struct spinand_device {
	struct spi_flash spiflash;
	...
};

struct spi_nor {
	struct spi_flash spiflash;
	...
};

static inline void spi_flash_master_lock(struct spi_flash *flash)
{
	if (flash->master)
		mutex_lock(&flash->master->lock);
}

static inline void spi_flash_master_unlock(struct spi_flash *flash)
{
	if (flash->master)
		mutex_unlock(&flash->master->lock);
}

> 
> struct fsl_qspi {
> 	---
> 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
> 	struct spinand_device spinand[FSL_QSPI_MAX_CHIP];

	struct spi_flash *flashes[FSL_QSPI_MAX_CHIP];

> 	---
> }
> 
> Function implementation
> ----------------------------------
> 
> fsl_qspi.c
> 	 probe() {
> 		--
> 		--
>   		 for_each_available_child_of_node(dev->of_node, np) {
> 			if compatible "hybrid" {
> 				hybrid_flock = malloc(sizeof(struct mutex));
>        				- if compatible "jedec,spi-nor" 
> 					spi_nor_scan()
>        				- if compatible "jedec,spi-nand"
> 					spinand_init()
> 				
> 				mtd_device_config_hybrid_lock(spi_nor->mtd, hybrid_flock);
> 				mtd_device_config_hybrid_lock(spinand->mtd, hybrid_flock);
> 								
> 			} else {
>        				- if compatible "jedec,spi-nor"
> 					spi_nor_scan()
>        				- if compatible "jedec,spi-nand"
> 					spinand_init()
> 			}

No, the parsing and hybrid flash creation should be done in some common
code, otherwise we'll have to duplicate it in each an every controller
driver that needs to support this kind of chip.

> 		}
>   		--
> 		--	
> 	}
> 
> 
> Whenever read/write/erase come from MTD layer , Take MTD layer lock in function definition i.e. mtd->_read_oob, mtd->_write_oob. mtd->_erase... 
> For eg. 
> spi_nor_read (struct mtd_info *mtd ...) {
> 	
> 	if (hybrid_flock)
> 		mutex_lock(&mtd-> hybrid_flock);


	spi_flash_master_lock(&spinor->spiflash);

> 	spi_nor_lock_and_prep();
> 	--
> 	--
> 	spi_nor_unlock_and_unprep();
> 	if (hybrid_flock)
> 		mutex_unlock(&mtd-> hybrid_flock);

	spi_flash_master_unlock(&spinor->spiflash);

> }
> 
> static int spinand_mtd_read(struct mtd_info *mtd, ...)
> {
> 	if (hybrid_flock)
> 		mutex_lock(&mtd-> hybrid_flock);

	spi_flash_master_lock(&spinand->spiflash);

> 
> 	mutex_lock(&spinand->lock);
> 
> 	---
> 	---
> 
> 	mutex_unlock(&spinand->lock);
> 	if (hybrid_flock)
> 		mutex_unlock(&mtd-> hybrid_flock);

	spi_flash_master_unlock(&spinand->spiflash);

> }
> 
> Please let me know your view on this. 
> 
> --pk



From jonas.gorski at gmail.com  Mon Jan  8 01:39:19 2018
From: jonas.gorski at gmail.com (Jonas Gorski)
Date: Mon, 8 Jan 2018 10:39:19 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180108101447.1d9ab212@bbrezillon>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
 <20180105144444.338c2cdc@bbrezillon>
 <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>
 <HE1PR04MB1241F9507EDB679098CDA13197130@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180108101447.1d9ab212@bbrezillon>
Message-ID: <CAOiHx=kQP2tok=G-utWBY-ivC2j2UX39Dsvwnu0rwJYXxsmwVA@mail.gmail.com>

On 8 January 2018 at 10:14, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Mon, 8 Jan 2018 08:42:32 +0000
> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
>
>> Thanks Jonas, Boris,
>>
>> Let me try to put my understanding and some proposal based on discussions.
>>
>> > -----Original Message-----
>> > From: Jonas Gorski [mailto:jonas.gorski at gmail.com]
>> > Sent: Friday, January 05, 2018 7:28 PM
>> > To: Boris Brezillon <boris.brezillon at free-electrons.com>
>> > Cc: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Marek Vasut
>> > <marex at denx.de>; Richard Weinberger <richard at nod.at>; Brian Norris
>> > <computersforpeace at gmail.com>; linux-mtd at lists.infradead.org; Cyrille
>> > Pitchen <cyrille.pitchen at wedev4u.fr>
>> > Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
>> > and NAND flash
>> >
>> > On 5 January 2018 at 14:44, Boris Brezillon
>> > <boris.brezillon at free-electrons.com> wrote:
>> > > On Fri, 5 Jan 2018 14:38:48 +0100
>> > > Jonas Gorski <jonas.gorski at gmail.com> wrote:
>> > >
>> > >> On 5 January 2018 at 11:21, Prabhakar Kushwaha
>> > >> <prabhakar.kushwaha at nxp.com> wrote:
>> > >> > Thanks Boris for the encouragement.
>> > >> >
>> > >> >> -----Original Message-----
>> > >> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
>> > >> >> Sent: Thursday, January 04, 2018 11:17 PM
>> > >> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
>> > >> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen
>> > <cyrille.pitchen at wedev4u.fr>;
>> > >> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>;
>> > Brian
>> > >> >> Norris <computersforpeace at gmail.com>
>> > >> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both
>> > NOR
>> > >> >> and NAND flash
>> > >> >>
>> > >> >> +MTD maintainers.
>> > >> >>
>> > >> >> On Thu, 4 Jan 2018 14:08:42 +0000
>> > >> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
>> > >> >>
>> > >> >> > Hi All,
>> > >> >> >
>> > >> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of
>> > Serial
>> > >> >> NOR(Die #0) and Serial NAND(Die #1) flash.
>> > >> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled
>> > by
>> > >> >> single chip-select.
>> > >> >> >
>> > >> >> > "Software Die Select (C2h)" command is being used to switch die or flash.
>> > >> >>
>> > >> >> Why are they so mean to us?! :-)
>> > >> >>
>> > >> >> >
>> > >> >> > It looks to be quite unique chip and wondering if any kind framework or
>> > work in
>> > >> >> progress available to handle it.
>> > >> >> > I know that SPI-NAND framework discussions is still in progress.
>> > >> >>
>> > >> >> Well, nothing impossible to handle, we just need to declare 2 MTD
>> > >> >> devices (one NAND and one NOR). This being said, it looks like we'll
>> > >> >> need this spi-flash abstraction we have been talking about with Marek
>> > >> >> and Cyrille to properly support these use cases: flash devices will be
>> > >> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
>> > >> >> a common way to detect those spi-flash chips. I looked at a few SPI
>> > >> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
>> > >> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
>> > >> >> different) so I thought we were safe to start with a completely
>> > >> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
>> > >> >> afterwards, but this chip proves me wrong :-/.
>> > >> >
>> > >> > I am thinking of following changes with fsl_qspi.c as controller
>> > >> >
>> > >> > &qspi {
>> > >> >         num-cs = <2>;
>> > >> >         bus-num = <0>;
>> > >> >         status = "okay";
>> > >> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated
>> > compatibility for drivers
>> > >> >         qflash0: w25q16fw @0 {
>> > >> >                 #address-cells = <1>;
>> > >> >                 #size-cells = <1>;
>> > >> >                 spi-max-frequency = <20000000>;
>> > >> >                 reg = <0>;
>> > >> >                 type = "serial-nor"   <-- Proposed New binding
>> > >> >                 is-hybrid <-- Proposed New binding
>> > >> >                 die-num <-- Proposed New binding
>> > >> >         };
>> > >> >
>> > >> >         qflash1: w25n01gw at 1 {
>> > >> >                 #address-cells = <1>;
>> > >> >                 #size-cells = <1>;
>> > >> >                 spi-max-frequency = <20000000>;
>> > >> >                 reg = <1>;
>> > >> >                 type = "serial-nand" <-- Proposed New binding
>> > >> >                 is-hybrid <-- Proposed New binding
>> > >> >                 die-num <-- Proposed New binding
>> > >> >         }
>> > >> > };
>> > >>
>> > >> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
>> > >> SPI-NAND chips when selected, a more appropriate binding might be
>> > >>
>> > >> &qspi {
>> > >>     ...
>> > >>         qflash0: dual-flash at 0 {
>> > >>                 compatible = "winbond,w25q16fw";
>> > >>                 reg = <0>;
>> > >>                 spi-max-frequency = <20000000>;
>> > >>                 #address-cells = <1>;
>> > >>                 #size-cells = <0>;
>> > >>
>> > >>                 nor at 0 {
>> > >>                                 compatible = "jedec,spi-nor";
>> > >>                                 reg = <0>;
>> > >>                                 #address-cells = <1>;
>> > >>                                 #size-cells = <1>;
>> > >>
>> > >>                                 partitions {
>> > >>                                                 ...
>> > >>                                 };
>> > >>                 };
>> > >>
>> > >>                 nand at 1 {
>> > >>                                 compatible = "jedec,spi-nand"; /* or
>> > >> whatever the correct nand-compatible would be */
>> > >>                                 reg = <1>;
>> > >>                                 #address-cells = <1>;
>> > >>                                 #size-cells = <1>;
>> > >>
>> > >>                                 partitions {
>> > >>                                                 ...
>> > >>                                 };
>> > >>                 };
>> > >>
>> > >>     };
>> > >> };
>> > >>
>> > >> with the "windbond,w25q16fw" driver modeled as a simple
>> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
>> > >> it sends the Software Die Select command if needed and then passes on
>> > >> the message to its parent bus.
>> > >>
>> > >> That way there should be no changes needed for spi-nor / spi-nand
>> > >> themselves. (The devil is probably in the details ;-)
>> > >
>> > > Yep, I thought about this approach, and it's indeed quite elegant, but
>> > > we're missing the lock I was mentioning in my previous reply. We need
>> > > to prevent die selection not only for the time we're sending a single
>> > > SPI message, but for the whole operation (which can be formed of
>> > > several SPI messages). Or maybe I'm wrong, and operations can actually
>> > > be interleaved, but I wouldn't bet on that ;-).
>> >
>> > Ah, I missed that. I thought about it, and then tried to hand wave it
>> > away with the "if they behave like normal chips" ;-)
>> >
>> > The mdio-bus supports nested locking, so you can do something like this:
>> >
>> > mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
>> > bus->write();
>> > bus->read();
>> > mutex_unlock(bus->mdio_lock);
>> >
>> > without worrying someone else using the bus in between. [1] for an example
>> > user.
>> >
>> > So going a similar approach with flagging the appropriate chips in
>> > spi-nor/spi-nand as needing nested locking and then doing it for the
>> > appropriate commands should solve that issue.
>> >
>> >
>>
>> Device tree update:-
>>
>> &qspi {
>>     ...
>>         qflash0: dual-flash at 0 {
>>                 compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value
>
> "hybrid" is not needed, you know that the flash is hybrid with the
> "winbond,w25q16fw" string.
>
>>                 reg = <0>;
>>                 spi-max-frequency = <20000000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>>
>>                 nor at 0 {
>>                                 compatible = "jedec,spi-nor";
>>                                 reg = <0>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>>
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
>>
>>                 nand at 1 {
>>                                 compatible = "jedec,spi-nand"; /* or
>> whatever the correct nand-compatible would be */
>>                                 reg = <1>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>>
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
>
> Not sure exposing the dies in the DT is such a good idea. You should
> have a specific handling for "winbond,w25q16fw" which registers one
> NAND and one NOR.

How would you define (fixed) partitions in the dts then? This was one
of my main motivations of having them there.


Regards
Jonas


From boris.brezillon at free-electrons.com  Mon Jan  8 01:47:58 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 10:47:58 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <CAOiHx=kQP2tok=G-utWBY-ivC2j2UX39Dsvwnu0rwJYXxsmwVA@mail.gmail.com>
References: <HE1PR04MB1241937FF43AAA64AE7EE776971F0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180104184722.551ca6aa@bbrezillon>
 <HE1PR04MB12410ABF9189334C4CDE512A971C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <CAOiHx==at9hRbzEyyo3FpOHrQJS7jy-wSF9Fg=EkS4r11qZVNw@mail.gmail.com>
 <20180105144444.338c2cdc@bbrezillon>
 <CAOiHx=mpNQhWEXeGOqBU=oD8MOV=L9CBbJxGosnRL72LFwWYhg@mail.gmail.com>
 <HE1PR04MB1241F9507EDB679098CDA13197130@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <20180108101447.1d9ab212@bbrezillon>
 <CAOiHx=kQP2tok=G-utWBY-ivC2j2UX39Dsvwnu0rwJYXxsmwVA@mail.gmail.com>
Message-ID: <20180108104758.0a0f4226@bbrezillon>

On Mon, 8 Jan 2018 10:39:19 +0100
Jonas Gorski <jonas.gorski at gmail.com> wrote:

> On 8 January 2018 at 10:14, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Mon, 8 Jan 2018 08:42:32 +0000
> > Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> >  
> >> Thanks Jonas, Boris,
> >>
> >> Let me try to put my understanding and some proposal based on discussions.
> >>  
> >> > -----Original Message-----
> >> > From: Jonas Gorski [mailto:jonas.gorski at gmail.com]
> >> > Sent: Friday, January 05, 2018 7:28 PM
> >> > To: Boris Brezillon <boris.brezillon at free-electrons.com>
> >> > Cc: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Marek Vasut
> >> > <marex at denx.de>; Richard Weinberger <richard at nod.at>; Brian Norris
> >> > <computersforpeace at gmail.com>; linux-mtd at lists.infradead.org; Cyrille
> >> > Pitchen <cyrille.pitchen at wedev4u.fr>
> >> > Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
> >> > and NAND flash
> >> >
> >> > On 5 January 2018 at 14:44, Boris Brezillon
> >> > <boris.brezillon at free-electrons.com> wrote:  
> >> > > On Fri, 5 Jan 2018 14:38:48 +0100
> >> > > Jonas Gorski <jonas.gorski at gmail.com> wrote:
> >> > >  
> >> > >> On 5 January 2018 at 11:21, Prabhakar Kushwaha
> >> > >> <prabhakar.kushwaha at nxp.com> wrote:  
> >> > >> > Thanks Boris for the encouragement.
> >> > >> >  
> >> > >> >> -----Original Message-----
> >> > >> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
> >> > >> >> Sent: Thursday, January 04, 2018 11:17 PM
> >> > >> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> >> > >> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen  
> >> > <cyrille.pitchen at wedev4u.fr>;  
> >> > >> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>;  
> >> > Brian  
> >> > >> >> Norris <computersforpeace at gmail.com>
> >> > >> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both  
> >> > NOR  
> >> > >> >> and NAND flash
> >> > >> >>
> >> > >> >> +MTD maintainers.
> >> > >> >>
> >> > >> >> On Thu, 4 Jan 2018 14:08:42 +0000
> >> > >> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> >> > >> >>  
> >> > >> >> > Hi All,
> >> > >> >> >
> >> > >> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of  
> >> > Serial  
> >> > >> >> NOR(Die #0) and Serial NAND(Die #1) flash.  
> >> > >> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled  
> >> > by  
> >> > >> >> single chip-select.  
> >> > >> >> >
> >> > >> >> > "Software Die Select (C2h)" command is being used to switch die or flash.  
> >> > >> >>
> >> > >> >> Why are they so mean to us?! :-)
> >> > >> >>  
> >> > >> >> >
> >> > >> >> > It looks to be quite unique chip and wondering if any kind framework or  
> >> > work in  
> >> > >> >> progress available to handle it.  
> >> > >> >> > I know that SPI-NAND framework discussions is still in progress.  
> >> > >> >>
> >> > >> >> Well, nothing impossible to handle, we just need to declare 2 MTD
> >> > >> >> devices (one NAND and one NOR). This being said, it looks like we'll
> >> > >> >> need this spi-flash abstraction we have been talking about with Marek
> >> > >> >> and Cyrille to properly support these use cases: flash devices will be
> >> > >> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
> >> > >> >> a common way to detect those spi-flash chips. I looked at a few SPI
> >> > >> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
> >> > >> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
> >> > >> >> different) so I thought we were safe to start with a completely
> >> > >> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
> >> > >> >> afterwards, but this chip proves me wrong :-/.  
> >> > >> >
> >> > >> > I am thinking of following changes with fsl_qspi.c as controller
> >> > >> >
> >> > >> > &qspi {
> >> > >> >         num-cs = <2>;
> >> > >> >         bus-num = <0>;
> >> > >> >         status = "okay";
> >> > >> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated  
> >> > compatibility for drivers  
> >> > >> >         qflash0: w25q16fw @0 {
> >> > >> >                 #address-cells = <1>;
> >> > >> >                 #size-cells = <1>;
> >> > >> >                 spi-max-frequency = <20000000>;
> >> > >> >                 reg = <0>;
> >> > >> >                 type = "serial-nor"   <-- Proposed New binding
> >> > >> >                 is-hybrid <-- Proposed New binding
> >> > >> >                 die-num <-- Proposed New binding
> >> > >> >         };
> >> > >> >
> >> > >> >         qflash1: w25n01gw at 1 {
> >> > >> >                 #address-cells = <1>;
> >> > >> >                 #size-cells = <1>;
> >> > >> >                 spi-max-frequency = <20000000>;
> >> > >> >                 reg = <1>;
> >> > >> >                 type = "serial-nand" <-- Proposed New binding
> >> > >> >                 is-hybrid <-- Proposed New binding
> >> > >> >                 die-num <-- Proposed New binding
> >> > >> >         }
> >> > >> > };  
> >> > >>
> >> > >> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
> >> > >> SPI-NAND chips when selected, a more appropriate binding might be
> >> > >>
> >> > >> &qspi {
> >> > >>     ...
> >> > >>         qflash0: dual-flash at 0 {
> >> > >>                 compatible = "winbond,w25q16fw";
> >> > >>                 reg = <0>;
> >> > >>                 spi-max-frequency = <20000000>;
> >> > >>                 #address-cells = <1>;
> >> > >>                 #size-cells = <0>;
> >> > >>
> >> > >>                 nor at 0 {
> >> > >>                                 compatible = "jedec,spi-nor";
> >> > >>                                 reg = <0>;
> >> > >>                                 #address-cells = <1>;
> >> > >>                                 #size-cells = <1>;
> >> > >>
> >> > >>                                 partitions {
> >> > >>                                                 ...
> >> > >>                                 };
> >> > >>                 };
> >> > >>
> >> > >>                 nand at 1 {
> >> > >>                                 compatible = "jedec,spi-nand"; /* or
> >> > >> whatever the correct nand-compatible would be */
> >> > >>                                 reg = <1>;
> >> > >>                                 #address-cells = <1>;
> >> > >>                                 #size-cells = <1>;
> >> > >>
> >> > >>                                 partitions {
> >> > >>                                                 ...
> >> > >>                                 };
> >> > >>                 };
> >> > >>
> >> > >>     };
> >> > >> };
> >> > >>
> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
> >> > >> it sends the Software Die Select command if needed and then passes on
> >> > >> the message to its parent bus.
> >> > >>
> >> > >> That way there should be no changes needed for spi-nor / spi-nand
> >> > >> themselves. (The devil is probably in the details ;-)  
> >> > >
> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
> >> > > we're missing the lock I was mentioning in my previous reply. We need
> >> > > to prevent die selection not only for the time we're sending a single
> >> > > SPI message, but for the whole operation (which can be formed of
> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
> >> > > be interleaved, but I wouldn't bet on that ;-).  
> >> >
> >> > Ah, I missed that. I thought about it, and then tried to hand wave it
> >> > away with the "if they behave like normal chips" ;-)
> >> >
> >> > The mdio-bus supports nested locking, so you can do something like this:
> >> >
> >> > mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
> >> > bus->write();
> >> > bus->read();
> >> > mutex_unlock(bus->mdio_lock);
> >> >
> >> > without worrying someone else using the bus in between. [1] for an example
> >> > user.
> >> >
> >> > So going a similar approach with flagging the appropriate chips in
> >> > spi-nor/spi-nand as needing nested locking and then doing it for the
> >> > appropriate commands should solve that issue.
> >> >
> >> >  
> >>
> >> Device tree update:-
> >>
> >> &qspi {
> >>     ...
> >>         qflash0: dual-flash at 0 {
> >>                 compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value  
> >
> > "hybrid" is not needed, you know that the flash is hybrid with the
> > "winbond,w25q16fw" string.
> >  
> >>                 reg = <0>;
> >>                 spi-max-frequency = <20000000>;
> >>                 #address-cells = <1>;
> >>                 #size-cells = <0>;
> >>
> >>                 nor at 0 {
> >>                                 compatible = "jedec,spi-nor";
> >>                                 reg = <0>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >>
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };
> >>
> >>                 nand at 1 {
> >>                                 compatible = "jedec,spi-nand"; /* or
> >> whatever the correct nand-compatible would be */
> >>                                 reg = <1>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >>
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };  
> >
> > Not sure exposing the dies in the DT is such a good idea. You should
> > have a specific handling for "winbond,w25q16fw" which registers one
> > NAND and one NOR.  
> 
> How would you define (fixed) partitions in the dts then? This was one
> of my main motivations of having them there.

You're right. So let's keep the subnodes describing the NAND and NOR
dies.


From frieder.schrempf at exceet.de  Mon Jan  8 03:02:19 2018
From: frieder.schrempf at exceet.de (Frieder Schrempf)
Date: Mon, 8 Jan 2018 12:02:19 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180108101447.1d9ab212@bbrezillon>
References: <20180108101447.1d9ab212@bbrezillon>
Message-ID: <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>

Hi Boris,

> On Mon, 8 Jan 2018 08:42:32 +0000
> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
> 
>> Thanks Jonas, Boris,
>> 
>> Let me try to put my understanding and some proposal based on discussions.
>> 
>> > -----Original Message-----
>> > From: Jonas Gorski [mailto:jonas.gorski at gmail.com]
>> > Sent: Friday, January 05, 2018 7:28 PM
>> > To: Boris Brezillon <boris.brezillon at free-electrons.com>
>> > Cc: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Marek Vasut
>> > <marex at denx.de>; Richard Weinberger <richard at nod.at>; Brian Norris
>> > <computersforpeace at gmail.com>; linux-mtd at lists.infradead.org; Cyrille
>> > Pitchen <cyrille.pitchen at wedev4u.fr>
>> > Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both NOR
>> > and NAND flash
>> > 
>> > On 5 January 2018 at 14:44, Boris Brezillon
>> > <boris.brezillon at free-electrons.com> wrote:  
>> > > On Fri, 5 Jan 2018 14:38:48 +0100
>> > > Jonas Gorski <jonas.gorski at gmail.com> wrote:
>> > >  
>> > >> On 5 January 2018 at 11:21, Prabhakar Kushwaha
>> > >> <prabhakar.kushwaha at nxp.com> wrote:  
>> > >> > Thanks Boris for the encouragement.
>> > >> >  
>> > >> >> -----Original Message-----
>> > >> >> From: Boris Brezillon [mailto:boris.brezillon at free-electrons.com]
>> > >> >> Sent: Thursday, January 04, 2018 11:17 PM
>> > >> >> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
>> > >> >> Cc: linux-mtd at lists.infradead.org; Cyrille Pitchen  
>> > <cyrille.pitchen at wedev4u.fr>;  
>> > >> >> Richard Weinberger <richard at nod.at>; Marek Vasut <marex at denx.de>;  
>> > Brian  
>> > >> >> Norris <computersforpeace at gmail.com>
>> > >> >> Subject: Re: mtd layer: support of hybrid flash(W25M161AW) having both  
>> > NOR  
>> > >> >> and NAND flash
>> > >> >>
>> > >> >> +MTD maintainers.
>> > >> >>
>> > >> >> On Thu, 4 Jan 2018 14:08:42 +0000
>> > >> >> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com> wrote:
>> > >> >>  
>> > >> >> > Hi All,
>> > >> >> >
>> > >> >> > Winbond has come up with special flash i.e.  W25M161AW. It consist of  
>> > Serial  
>> > >> >> NOR(Die #0) and Serial NAND(Die #1) flash.  
>> > >> >> > Means both NOR, NAND flashes are placed in W25M161AW controlled  
>> > by  
>> > >> >> single chip-select.  
>> > >> >> >
>> > >> >> > "Software Die Select (C2h)" command is being used to switch die or flash.  
>> > >> >>
>> > >> >> Why are they so mean to us?! :-)
>> > >> >>  
>> > >> >> >
>> > >> >> > It looks to be quite unique chip and wondering if any kind framework or  
>> > work in  
>> > >> >> progress available to handle it.  
>> > >> >> > I know that SPI-NAND framework discussions is still in progress.  
>> > >> >>
>> > >> >> Well, nothing impossible to handle, we just need to declare 2 MTD
>> > >> >> devices (one NAND and one NOR). This being said, it looks like we'll
>> > >> >> need this spi-flash abstraction we have been talking about with Marek
>> > >> >> and Cyrille to properly support these use cases: flash devices will be
>> > >> >> exposed through different sub-layers (spi-nor or spi-nand), but we need
>> > >> >> a common way to detect those spi-flash chips. I looked at a few SPI
>> > >> >> NAND and SPI NOR chips, and from what I've seen so far they were quite
>> > >> >> different (the opcodes and CMD+ADDR+DATA sequences were quite
>> > >> >> different) so I thought we were safe to start with a completely
>> > >> >> unconnected SPI NAND framework and merge some bits in a spi-flash layer
>> > >> >> afterwards, but this chip proves me wrong :-/.  
>> > >> >
>> > >> > I am thinking of following changes with fsl_qspi.c as controller
>> > >> >
>> > >> > &qspi {
>> > >> >         num-cs = <2>;
>> > >> >         bus-num = <0>;
>> > >> >         status = "okay";
>> > >> >         compatible = " fsl,ls1021a-qspi ", "fsl,ls1021a-qspi-nand"; <-- updated  
>> > compatibility for drivers  
>> > >> >         qflash0: w25q16fw @0 {
>> > >> >                 #address-cells = <1>;
>> > >> >                 #size-cells = <1>;
>> > >> >                 spi-max-frequency = <20000000>;
>> > >> >                 reg = <0>;
>> > >> >                 type = "serial-nor"   <-- Proposed New binding
>> > >> >                 is-hybrid <-- Proposed New binding
>> > >> >                 die-num <-- Proposed New binding
>> > >> >         };
>> > >> >
>> > >> >         qflash1: w25n01gw at 1 {
>> > >> >                 #address-cells = <1>;
>> > >> >                 #size-cells = <1>;
>> > >> >                 spi-max-frequency = <20000000>;
>> > >> >                 reg = <1>;
>> > >> >                 type = "serial-nand" <-- Proposed New binding
>> > >> >                 is-hybrid <-- Proposed New binding
>> > >> >                 die-num <-- Proposed New binding
>> > >> >         }
>> > >> > };  
>> > >>
>> > >> assuming the NOR and NAND parts behave like "normal" SPI-NOR /
>> > >> SPI-NAND chips when selected, a more appropriate binding might be
>> > >>
>> > >> &qspi {
>> > >>     ...
>> > >>         qflash0: dual-flash at 0 {
>> > >>                 compatible = "winbond,w25q16fw";
>> > >>                 reg = <0>;
>> > >>                 spi-max-frequency = <20000000>;
>> > >>                 #address-cells = <1>;
>> > >>                 #size-cells = <0>;
>> > >>
>> > >>                 nor at 0 {
>> > >>                                 compatible = "jedec,spi-nor";
>> > >>                                 reg = <0>;
>> > >>                                 #address-cells = <1>;
>> > >>                                 #size-cells = <1>;
>> > >>
>> > >>                                 partitions {
>> > >>                                                 ...
>> > >>                                 };
>> > >>                 };
>> > >>
>> > >>                 nand at 1 {
>> > >>                                 compatible = "jedec,spi-nand"; /* or
>> > >> whatever the correct nand-compatible would be */
>> > >>                                 reg = <1>;
>> > >>                                 #address-cells = <1>;
>> > >>                                 #size-cells = <1>;
>> > >>
>> > >>                                 partitions {
>> > >>                                                 ...
>> > >>                                 };
>> > >>                 };
>> > >>
>> > >>     };
>> > >> };
>> > >>
>> > >> with the "windbond,w25q16fw" driver modeled as a simple
>> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
>> > >> it sends the Software Die Select command if needed and then passes on
>> > >> the message to its parent bus.
>> > >>
>> > >> That way there should be no changes needed for spi-nor / spi-nand
>> > >> themselves. (The devil is probably in the details ;-)  
>> > >
>> > > Yep, I thought about this approach, and it's indeed quite elegant, but
>> > > we're missing the lock I was mentioning in my previous reply. We need
>> > > to prevent die selection not only for the time we're sending a single
>> > > SPI message, but for the whole operation (which can be formed of
>> > > several SPI messages). Or maybe I'm wrong, and operations can actually
>> > > be interleaved, but I wouldn't bet on that ;-).  

With operations, that consist of several SPI messages, do you mean 
something like NAND page program?

Because I'm quite sure something like this should be possible (and all 
of these commands consist only of one spi message, don't they?):
1. Select second (NAND) die
2. Send data to the NAND page buffer (PROGRAM)
3. Select first (NOR) die
4. Program data to a NOR block
5. Select second (NAND) die
6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)

>> > 
>> > Ah, I missed that. I thought about it, and then tried to hand wave it
>> > away with the "if they behave like normal chips" ;-)
>> > 
>> > The mdio-bus supports nested locking, so you can do something like this:
>> > 
>> > mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
>> > bus->write();
>> > bus->read();
>> > mutex_unlock(bus->mdio_lock);
>> > 
>> > without worrying someone else using the bus in between. [1] for an example
>> > user.
>> > 
>> > So going a similar approach with flagging the appropriate chips in
>> > spi-nor/spi-nand as needing nested locking and then doing it for the
>> > appropriate commands should solve that issue.
>> > 
>> >   
>> 
>> Device tree update:-
>> 
>> &qspi {
>>     ...
>>         qflash0: dual-flash at 0 {
>>                 compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value
> 
> "hybrid" is not needed, you know that the flash is hybrid with the
> "winbond,w25q16fw" string.
> 
>>                 reg = <0>;
>>                 spi-max-frequency = <20000000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>> 
>>                 nor at 0 {
>>                                 compatible = "jedec,spi-nor";
>>                                 reg = <0>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>> 
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
>> 
>>                 nand at 1 {
>>                                 compatible = "jedec,spi-nand"; /* or
>> whatever the correct nand-compatible would be */
>>                                 reg = <1>;
>>                                 #address-cells = <1>;
>>                                 #size-cells = <1>;
>> 
>>                                 partitions {
>>                                                 ...
>>                                 };
>>                 };
> 
> Not sure exposing the dies in the DT is such a good idea. You should
> have a specific handling for "winbond,w25q16fw" which registers one
> NAND and one NOR.
> 
>> 
>>     };
>> };
> 
> 
> 
>> 
>> 
>> There will be only one file i.e. fsl_qspi.c handing NOR and NAND. QSPI controller will have SPI NOR and a SPI NAND controller embedded.
>> Question: What should be the location of this file?  driver/mtd/spi-nor definitely is not right place??
> 
> It stay in driver/mtd/spi-nor until we create a spi-flash layer
> (driver/mtd/spi-flash).

Can it really stay there even if it would have NAND support implemented 
and be used by the SPI NAND framework?

How does the longterm plan for implementing SPI NAND, FSL QSPI NAND/NOR 
and spi-flash layer look like?

I would propose something like this, but I'm not sure if this is 
appropriate:

1. Adding SPI NAND framework (with Micron and generic SPI)
2. Adding FSL QSPI as a SPI NAND controller in mtd/nand/spi/controllers
3. Merging FSL QSPI NAND driver from mtd/nand/spi/controllers with NOR 
driver at mtd/spi-nor/fsl_quadspi.c
4. Creating spi-flash layer and move FSL QSPI NOR/NAND driver to 
mtd/spi-flash

The support for hybrid NAND/NOR chips would not be available until the 
spi-flash layer is done, right?

> 
>> 
>> 
>> Change in Data structures
>> ----------------------------------
>> 
>> struct mtd_info {
>> 	----
>> 	struct mutex *hybrid_flock;
>>  	---
>> }
> 
> Nope, the hybrid_flock should not be in mtd_info. We should create an
> hybrid_spi_flash struct containing this lock and an array of SPI flash.
> 
> struct hybrid_spi_flash;
> 
> enum spi_flash_type {
> 	SPI_NOR,
> 	SPI_NAND,
> };
> 
> struct spi_flash {
> 	enum spi_flash_type type;
> 	struct hybrid_spi_flash *master;
> };
> 
> struct hybrid_spi_flash {
> 	struct mutex lock;
> 	struct spi_flash **subdevs;
> };
> 
> struct spinand_device {
> 	struct spi_flash spiflash;
> 	...
> };
> 
> struct spi_nor {
> 	struct spi_flash spiflash;
> 	...
> };
> 
> static inline void spi_flash_master_lock(struct spi_flash *flash)
> {
> 	if (flash->master)
> 		mutex_lock(&flash->master->lock);
> }
> 
> static inline void spi_flash_master_unlock(struct spi_flash *flash)
> {
> 	if (flash->master)
> 		mutex_unlock(&flash->master->lock);
> }
> 
>> 
>> struct fsl_qspi {
>> 	---
>> 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
>> 	struct spinand_device spinand[FSL_QSPI_MAX_CHIP];
> 
> 	struct spi_flash *flashes[FSL_QSPI_MAX_CHIP];
> 
>> 	---
>> }
>> 
>> Function implementation
>> ----------------------------------
>> 
>> fsl_qspi.c
>> 	 probe() {
>> 		--
>> 		--
>>   		 for_each_available_child_of_node(dev->of_node, np) {
>> 			if compatible "hybrid" {
>> 				hybrid_flock = malloc(sizeof(struct mutex));
>>        				- if compatible "jedec,spi-nor" 
>> 					spi_nor_scan()
>>        				- if compatible "jedec,spi-nand"
>> 					spinand_init()
>> 				
>> 				mtd_device_config_hybrid_lock(spi_nor->mtd, hybrid_flock);
>> 				mtd_device_config_hybrid_lock(spinand->mtd, hybrid_flock);
>> 								
>> 			} else {
>>        				- if compatible "jedec,spi-nor"
>> 					spi_nor_scan()
>>        				- if compatible "jedec,spi-nand"
>> 					spinand_init()
>> 			}
> 
> No, the parsing and hybrid flash creation should be done in some common
> code, otherwise we'll have to duplicate it in each an every controller
> driver that needs to support this kind of chip.
> 
>> 		}
>>   		--
>> 		--	
>> 	}
>> 
>> 
>> Whenever read/write/erase come from MTD layer , Take MTD layer lock in function definition i.e. mtd->_read_oob, mtd->_write_oob. mtd->_erase... 
>> For eg. 
>> spi_nor_read (struct mtd_info *mtd ...) {
>> 	
>> 	if (hybrid_flock)
>> 		mutex_lock(&mtd-> hybrid_flock);
> 
> 
> 	spi_flash_master_lock(&spinor->spiflash);
> 
>> 	spi_nor_lock_and_prep();
>> 	--
>> 	--
>> 	spi_nor_unlock_and_unprep();
>> 	if (hybrid_flock)
>> 		mutex_unlock(&mtd-> hybrid_flock);
> 
> 	spi_flash_master_unlock(&spinor->spiflash);
> 
>> }
>> 
>> static int spinand_mtd_read(struct mtd_info *mtd, ...)
>> {
>> 	if (hybrid_flock)
>> 		mutex_lock(&mtd-> hybrid_flock);
> 
> 	spi_flash_master_lock(&spinand->spiflash);
> 
>> 
>> 	mutex_lock(&spinand->lock);
>> 
>> 	---
>> 	---
>> 
>> 	mutex_unlock(&spinand->lock);
>> 	if (hybrid_flock)
>> 		mutex_unlock(&mtd-> hybrid_flock);
> 
> 	spi_flash_master_unlock(&spinand->spiflash);
> 
>> }
>> 
>> Please let me know your view on this. 
>> 
>> --pk
Thanks,

Frieder


From boris.brezillon at free-electrons.com  Mon Jan  8 04:31:18 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 13:31:18 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
Message-ID: <20180108133118.02086991@bbrezillon>

Hi Frieder,

On Mon, 8 Jan 2018 12:02:19 +0100
Frieder Schrempf <frieder.schrempf at exceet.de> wrote:

> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
> >> > >> it sends the Software Die Select command if needed and then passes on
> >> > >> the message to its parent bus.
> >> > >>
> >> > >> That way there should be no changes needed for spi-nor / spi-nand
> >> > >> themselves. (The devil is probably in the details ;-)    
> >> > >
> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
> >> > > we're missing the lock I was mentioning in my previous reply. We need
> >> > > to prevent die selection not only for the time we're sending a single
> >> > > SPI message, but for the whole operation (which can be formed of
> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
> >> > > be interleaved, but I wouldn't bet on that ;-).    
> 
> With operations, that consist of several SPI messages, do you mean 
> something like NAND page program?

Yep.

> 
> Because I'm quite sure something like this should be possible (and all 
> of these commands consist only of one spi message, don't they?):
> 1. Select second (NAND) die
> 2. Send data to the NAND page buffer (PROGRAM)
> 3. Select first (NOR) die
> 4. Program data to a NOR block
> 5. Select second (NAND) die
> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)

Yes, and that's the problem, if you don't have a lock, the sequence you
describe above could be re-ordered like this:

1. Select second (NAND) die
2. Select first (NOR) die
3. Send data to the NAND page buffer (PROGRAM)
4. Program data to a NOR block
...

> 
> >> > 
> >> > Ah, I missed that. I thought about it, and then tried to hand wave it
> >> > away with the "if they behave like normal chips" ;-)
> >> > 
> >> > The mdio-bus supports nested locking, so you can do something like this:
> >> > 
> >> > mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
> >> > bus->write();
> >> > bus->read();
> >> > mutex_unlock(bus->mdio_lock);
> >> > 
> >> > without worrying someone else using the bus in between. [1] for an example
> >> > user.
> >> > 
> >> > So going a similar approach with flagging the appropriate chips in
> >> > spi-nor/spi-nand as needing nested locking and then doing it for the
> >> > appropriate commands should solve that issue.
> >> > 
> >> >     
> >> 
> >> Device tree update:-
> >> 
> >> &qspi {
> >>     ...
> >>         qflash0: dual-flash at 0 {
> >>                 compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value  
> > 
> > "hybrid" is not needed, you know that the flash is hybrid with the
> > "winbond,w25q16fw" string.
> >   
> >>                 reg = <0>;
> >>                 spi-max-frequency = <20000000>;
> >>                 #address-cells = <1>;
> >>                 #size-cells = <0>;
> >> 
> >>                 nor at 0 {
> >>                                 compatible = "jedec,spi-nor";
> >>                                 reg = <0>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >> 
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };
> >> 
> >>                 nand at 1 {
> >>                                 compatible = "jedec,spi-nand"; /* or
> >> whatever the correct nand-compatible would be */
> >>                                 reg = <1>;
> >>                                 #address-cells = <1>;
> >>                                 #size-cells = <1>;
> >> 
> >>                                 partitions {
> >>                                                 ...
> >>                                 };
> >>                 };  
> > 
> > Not sure exposing the dies in the DT is such a good idea. You should
> > have a specific handling for "winbond,w25q16fw" which registers one
> > NAND and one NOR.
> >   
> >> 
> >>     };
> >> };  
> > 
> > 
> >   
> >> 
> >> 
> >> There will be only one file i.e. fsl_qspi.c handing NOR and NAND. QSPI controller will have SPI NOR and a SPI NAND controller embedded.
> >> Question: What should be the location of this file?  driver/mtd/spi-nor definitely is not right place??  
> > 
> > It stay in driver/mtd/spi-nor until we create a spi-flash layer
> > (driver/mtd/spi-flash).  
> 
> Can it really stay there even if it would have NAND support implemented 
> and be used by the SPI NAND framework?

Yes, as long as this is a temporary situation.

> 
> How does the longterm plan for implementing SPI NAND, FSL QSPI NAND/NOR 
> and spi-flash layer look like?
> 
> I would propose something like this, but I'm not sure if this is 
> appropriate:
> 
> 1. Adding SPI NAND framework (with Micron and generic SPI)

Yep, that's the first step, and I think we should move on with what we
have and work on improving the situation (to share more code between
SPI NOR and SPI NAND) in parallel.

> 2. Adding FSL QSPI as a SPI NAND controller in mtd/nand/spi/controllers
> 3. Merging FSL QSPI NAND driver from mtd/nand/spi/controllers with NOR 
> driver at mtd/spi-nor/fsl_quadspi.c

I'd really prefer to have a single driver supporting both NOR and NAND
devices. What's the problem with adding SPI NAND support to the
mtd/spi-nor/fsl_quadspi.c?

> 4. Creating spi-flash layer and move FSL QSPI NOR/NAND driver to 
> mtd/spi-flash

Yep, that's the long term goal.

> 
> The support for hybrid NAND/NOR chips would not be available until the 
> spi-flash layer is done, right?

Exactly.

Regards,

Boris


From boris.brezillon at free-electrons.com  Mon Jan  8 05:04:29 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 14:04:29 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <20180105164239.79d7980c@xps13>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>
 <20180105164239.79d7980c@xps13>
Message-ID: <20180108140429.79f67a83@bbrezillon>

On Fri, 5 Jan 2018 16:42:39 +0100
Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:

> Hello,
> 
> > Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
> > is applied as soon the CS line is released after a
> > SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
> > guarantee that the CS will be kept low by the controller after  
> > ->onfi_set_features() returns we must assume the new mode has been    
> > applied and call ->setup_data_interface() to instruct the controller
> > to apply new timings.
> > 
> > If you want to check if the mode has really been applied, you should
> > release the CS (->select_chip(-1)), re-acquire it
> > (->select_chip(X)), and call  
> > ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears  
> > that the mode has not been applied, you should restore timing mode 0
> > and issue a RESET.  
> 
> Boris, thanks for the comment, I will fix that.
> 
> Han, could I have your input on this series? Aside Boris' comment of
> course.

Han, we really need your feedback on this series since you were the one
complaining that ONFI mode should be checked back after applying a new
mode. Miquel is reworking the framework to mimic what the GPMI driver,
but we need to be sure that you'll accept to transition to the generic
->setup_data_interface() solution.

Thanks,

Boris


From frieder.schrempf at exceet.de  Mon Jan  8 05:14:03 2018
From: frieder.schrempf at exceet.de (Frieder Schrempf)
Date: Mon, 8 Jan 2018 14:14:03 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180108133118.02086991@bbrezillon>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
 <20180108133118.02086991@bbrezillon>
Message-ID: <d688b07f-ddcf-9051-7f74-12c35b63c126@exceet.de>

Hi Boris,

On 08.01.2018 13:31, Boris Brezillon wrote:
> Hi Frieder,
> 
> On Mon, 8 Jan 2018 12:02:19 +0100
> Frieder Schrempf <frieder.schrempf at exceet.de> wrote:
> 
>>>>>>> with the "windbond,w25q16fw" driver modeled as a simple
>>>>>>> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>>>>>>> spi-nor or spi-nand tries to communicate with their appropriate die,
>>>>>>> it sends the Software Die Select command if needed and then passes on
>>>>>>> the message to its parent bus.
>>>>>>>
>>>>>>> That way there should be no changes needed for spi-nor / spi-nand
>>>>>>> themselves. (The devil is probably in the details ;-)
>>>>>>
>>>>>> Yep, I thought about this approach, and it's indeed quite elegant, but
>>>>>> we're missing the lock I was mentioning in my previous reply. We need
>>>>>> to prevent die selection not only for the time we're sending a single
>>>>>> SPI message, but for the whole operation (which can be formed of
>>>>>> several SPI messages). Or maybe I'm wrong, and operations can actually
>>>>>> be interleaved, but I wouldn't bet on that ;-).
>>
>> With operations, that consist of several SPI messages, do you mean
>> something like NAND page program?
> 
> Yep.
> 
>>
>> Because I'm quite sure something like this should be possible (and all
>> of these commands consist only of one spi message, don't they?):
>> 1. Select second (NAND) die
>> 2. Send data to the NAND page buffer (PROGRAM)
>> 3. Select first (NOR) die
>> 4. Program data to a NOR block
>> 5. Select second (NAND) die
>> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)
> 
> Yes, and that's the problem, if you don't have a lock, the sequence you
> describe above could be re-ordered like this:
> 
> 1. Select second (NAND) die
> 2. Select first (NOR) die
> 3. Send data to the NAND page buffer (PROGRAM)
> 4. Program data to a NOR block
> ...

Ok thanks. Now I got the problem.

> 
>>
>>>>>
>>>>> Ah, I missed that. I thought about it, and then tried to hand wave it
>>>>> away with the "if they behave like normal chips" ;-)
>>>>>
>>>>> The mdio-bus supports nested locking, so you can do something like this:
>>>>>
>>>>> mutex_lock_nested(bus->mdio_lock, MDIO_BUS_NESTED);
>>>>> bus->write();
>>>>> bus->read();
>>>>> mutex_unlock(bus->mdio_lock);
>>>>>
>>>>> without worrying someone else using the bus in between. [1] for an example
>>>>> user.
>>>>>
>>>>> So going a similar approach with flagging the appropriate chips in
>>>>> spi-nor/spi-nand as needing nested locking and then doing it for the
>>>>> appropriate commands should solve that issue.
>>>>>
>>>>>      
>>>>
>>>> Device tree update:-
>>>>
>>>> &qspi {
>>>>      ...
>>>>          qflash0: dual-flash at 0 {
>>>>                  compatible = "winbond,w25q16fw", "hybrid"; <-- new compatibility value
>>>
>>> "hybrid" is not needed, you know that the flash is hybrid with the
>>> "winbond,w25q16fw" string.
>>>    
>>>>                  reg = <0>;
>>>>                  spi-max-frequency = <20000000>;
>>>>                  #address-cells = <1>;
>>>>                  #size-cells = <0>;
>>>>
>>>>                  nor at 0 {
>>>>                                  compatible = "jedec,spi-nor";
>>>>                                  reg = <0>;
>>>>                                  #address-cells = <1>;
>>>>                                  #size-cells = <1>;
>>>>
>>>>                                  partitions {
>>>>                                                  ...
>>>>                                  };
>>>>                  };
>>>>
>>>>                  nand at 1 {
>>>>                                  compatible = "jedec,spi-nand"; /* or
>>>> whatever the correct nand-compatible would be */
>>>>                                  reg = <1>;
>>>>                                  #address-cells = <1>;
>>>>                                  #size-cells = <1>;
>>>>
>>>>                                  partitions {
>>>>                                                  ...
>>>>                                  };
>>>>                  };
>>>
>>> Not sure exposing the dies in the DT is such a good idea. You should
>>> have a specific handling for "winbond,w25q16fw" which registers one
>>> NAND and one NOR.
>>>    
>>>>
>>>>      };
>>>> };
>>>
>>>
>>>    
>>>>
>>>>
>>>> There will be only one file i.e. fsl_qspi.c handing NOR and NAND. QSPI controller will have SPI NOR and a SPI NAND controller embedded.
>>>> Question: What should be the location of this file?  driver/mtd/spi-nor definitely is not right place??
>>>
>>> It stay in driver/mtd/spi-nor until we create a spi-flash layer
>>> (driver/mtd/spi-flash).
>>
>> Can it really stay there even if it would have NAND support implemented
>> and be used by the SPI NAND framework?
> 
> Yes, as long as this is a temporary situation.

Ok.

> 
>>
>> How does the longterm plan for implementing SPI NAND, FSL QSPI NAND/NOR
>> and spi-flash layer look like?
>>
>> I would propose something like this, but I'm not sure if this is
>> appropriate:
>>
>> 1. Adding SPI NAND framework (with Micron and generic SPI)
> 
> Yep, that's the first step, and I think we should move on with what we
> have and work on improving the situation (to share more code between
> SPI NOR and SPI NAND) in parallel.

Ok.

> 
>> 2. Adding FSL QSPI as a SPI NAND controller in mtd/nand/spi/controllers
>> 3. Merging FSL QSPI NAND driver from mtd/nand/spi/controllers with NOR
>> driver at mtd/spi-nor/fsl_quadspi.c
> 
> I'd really prefer to have a single driver supporting both NOR and NAND
> devices. What's the problem with adding SPI NAND support to the
> mtd/spi-nor/fsl_quadspi.c?

There's not really a problem. I will see if can adapt my FSL QSPI NAND 
code to fit into the NOR driver.

> 
>> 4. Creating spi-flash layer and move FSL QSPI NOR/NAND driver to
>> mtd/spi-flash
> 
> Yep, that's the long term goal.
> 
>>
>> The support for hybrid NAND/NOR chips would not be available until the
>> spi-flash layer is done, right?
> 
> Exactly.
> 
> Regards,
> 
> Boris
> 

Thanks and regards,

Frieder


From arnd at arndb.de  Mon Jan  8 05:16:25 2018
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 8 Jan 2018 14:16:25 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8
 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
Message-ID: <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>

On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:
>
> stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
> Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
> Tree: stable-rc
> Branch: linux-4.4.y
> Git Describe: v4.4.110-18-g5da3d9af3a4b
> Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
> Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> Built: 4 unique architectures
>
> Build Failures Detected:
>
> arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
> cm_x300_defconfig FAIL
> mvebu_v7_defconfig FAIL
> pxa3xx_defconfig FAIL
> raumfeld_defconfig FAIL
>
> mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
>
> Errors:
> drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
> drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here

Hi Greg,

Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
apparently backported in error, it looks like it should just be
dropped here in 4.4.y.

The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
ECC BCH support")', that commit was merged into v4.14, so backporting the
fix further is probably not appropriate for 4.9 or earlier kernels either.

The duplicate case statement only happens before linux-4.6, as commit
c2cdace755b5 ("mtd: nand: pxa3xx_nand: add support for partial chunks")'
removed a previous 'case READOOB' statement in this driver, so the build
regression appears only in 4.4 but not 4.9.

       Arnd


From gregkh at linuxfoundation.org  Mon Jan  8 05:44:15 2018
From: gregkh at linuxfoundation.org (gregkh)
Date: Mon, 8 Jan 2018 14:44:15 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8
 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
 <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
Message-ID: <20180108134415.GA11707@kroah.com>

On Mon, Jan 08, 2018 at 02:16:25PM +0100, Arnd Bergmann wrote:
> On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:
> >
> > stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
> > Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
> > Tree: stable-rc
> > Branch: linux-4.4.y
> > Git Describe: v4.4.110-18-g5da3d9af3a4b
> > Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
> > Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> > Built: 4 unique architectures
> >
> > Build Failures Detected:
> >
> > arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
> > cm_x300_defconfig FAIL
> > mvebu_v7_defconfig FAIL
> > pxa3xx_defconfig FAIL
> > raumfeld_defconfig FAIL
> >
> > mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
> >
> > Errors:
> > drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
> > drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here
> 
> Hi Greg,
> 
> Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
> apparently backported in error, it looks like it should just be
> dropped here in 4.4.y.
> 
> The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
> ECC BCH support")', that commit was merged into v4.14, so backporting the
> fix further is probably not appropriate for 4.9 or earlier kernels either.

$ git describe --contains 43bcfd2bb24a
v3.14-rc1~65^2~127

That is why I backported these patches this far.

I'll drop the patch now, but the Fixes line is the problem here :)

thanks,

greg k-h


From jonas.gorski at gmail.com  Mon Jan  8 05:43:56 2018
From: jonas.gorski at gmail.com (Jonas Gorski)
Date: Mon, 8 Jan 2018 14:43:56 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180108133118.02086991@bbrezillon>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
 <20180108133118.02086991@bbrezillon>
Message-ID: <CAOiHx=kw=L-H1yCwnzhfJhg3vUeXiTz_39n4_Wq3qbKMdDCitA@mail.gmail.com>

On 8 January 2018 at 13:31, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> Hi Frieder,
>
> On Mon, 8 Jan 2018 12:02:19 +0100
> Frieder Schrempf <frieder.schrempf at exceet.de> wrote:
>
>> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
>> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
>> >> > >> it sends the Software Die Select command if needed and then passes on
>> >> > >> the message to its parent bus.
>> >> > >>
>> >> > >> That way there should be no changes needed for spi-nor / spi-nand
>> >> > >> themselves. (The devil is probably in the details ;-)
>> >> > >
>> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
>> >> > > we're missing the lock I was mentioning in my previous reply. We need
>> >> > > to prevent die selection not only for the time we're sending a single
>> >> > > SPI message, but for the whole operation (which can be formed of
>> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
>> >> > > be interleaved, but I wouldn't bet on that ;-).
>>
>> With operations, that consist of several SPI messages, do you mean
>> something like NAND page program?
>
> Yep.
>
>>
>> Because I'm quite sure something like this should be possible (and all
>> of these commands consist only of one spi message, don't they?):
>> 1. Select second (NAND) die
>> 2. Send data to the NAND page buffer (PROGRAM)
>> 3. Select first (NOR) die
>> 4. Program data to a NOR block
>> 5. Select second (NAND) die
>> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)
>
> Yes, and that's the problem, if you don't have a lock, the sequence you
> describe above could be re-ordered like this:
>
> 1. Select second (NAND) die
> 2. Select first (NOR) die
> 3. Send data to the NAND page buffer (PROGRAM)
> 4. Program data to a NOR block
> ...

At least with what I was thinking of (with the spi-multiplexer) this
should be impossible, as the (virtual) spi bus message pump should
ensure that any messages from spi-nand and spi-nor are properly
serialized so they could only end up as in Frieder's example, unless
I'm overlooking something.

So my virtual's spi implementation would look like this:

struct W25M161AW {
        struct spi_device *spi; /* we at the parent bus */
};

int W25M161AW_transfer_one_message(master, message)
{
        W25M161AW *w = spi_master_get_devdata(master);
        spi_device *spi = message->spi;

        W25M161AW_send_die_select(w->spi, spi->chip_select);

        /* pass on the message to the parent bus */
        spi_sync(w->spi, msg);
        spi_finalize_current_message(master);

        return 0;
}

(this is a very simplified version, of course we can't pass on the
message directly to the parent bus but need to clone it)

This way AFAICT there should be a guarantee that there can be no other
message to the flash scheduled between the die select and the message
to the die.

Of course if we need to ensure that there is no die change between the
PROGRAM and the PROGRAM EXECUTE we need the extra bus lock. Without a
public datasheet I can't tell though.


Regards
Jonas


From arnd at arndb.de  Mon Jan  8 06:01:38 2018
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 8 Jan 2018 15:01:38 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8
 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <20180108134415.GA11707@kroah.com>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
 <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
 <20180108134415.GA11707@kroah.com>
Message-ID: <CAK8P3a2YFJmdiw=0BgG1JkoQYLiD=em6N97AgB_4=Z2DDkY5dg@mail.gmail.com>

On Mon, Jan 8, 2018 at 2:44 PM, gregkh <gregkh at linuxfoundation.org> wrote:
> On Mon, Jan 08, 2018 at 02:16:25PM +0100, Arnd Bergmann wrote:
>> On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:
>> >
>> > stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
>> > Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
>> > Tree: stable-rc
>> > Branch: linux-4.4.y
>> > Git Describe: v4.4.110-18-g5da3d9af3a4b
>> > Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
>> > Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
>> > Built: 4 unique architectures
>> >
>> > Build Failures Detected:
>> >
>> > arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
>> > cm_x300_defconfig FAIL
>> > mvebu_v7_defconfig FAIL
>> > pxa3xx_defconfig FAIL
>> > raumfeld_defconfig FAIL
>> >
>> > mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
>> >
>> > Errors:
>> > drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
>> > drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here
>>
>> Hi Greg,
>>
>> Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
>> apparently backported in error, it looks like it should just be
>> dropped here in 4.4.y.
>>
>> The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
>> ECC BCH support")', that commit was merged into v4.14, so backporting the
>> fix further is probably not appropriate for 4.9 or earlier kernels either.
>
> $ git describe --contains 43bcfd2bb24a
> v3.14-rc1~65^2~127
>
> That is why I backported these patches this far.
>
> I'll drop the patch now, but the Fixes line is the problem here :)

I think my mistake in the report was misreading v3.14 as v4.14. That means we
still need the fix, just as Boris explained, it just needs to be done
differently
for older kernels.

        Arnd


From boris.brezillon at free-electrons.com  Mon Jan  8 06:32:49 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 15:32:49 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <CAOiHx=kw=L-H1yCwnzhfJhg3vUeXiTz_39n4_Wq3qbKMdDCitA@mail.gmail.com>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
 <20180108133118.02086991@bbrezillon>
 <CAOiHx=kw=L-H1yCwnzhfJhg3vUeXiTz_39n4_Wq3qbKMdDCitA@mail.gmail.com>
Message-ID: <20180108153249.24d05341@bbrezillon>

On Mon, 8 Jan 2018 14:43:56 +0100
Jonas Gorski <jonas.gorski at gmail.com> wrote:

> On 8 January 2018 at 13:31, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > Hi Frieder,
> >
> > On Mon, 8 Jan 2018 12:02:19 +0100
> > Frieder Schrempf <frieder.schrempf at exceet.de> wrote:
> >  
> >> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
> >> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> >> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
> >> >> > >> it sends the Software Die Select command if needed and then passes on
> >> >> > >> the message to its parent bus.
> >> >> > >>
> >> >> > >> That way there should be no changes needed for spi-nor / spi-nand
> >> >> > >> themselves. (The devil is probably in the details ;-)  
> >> >> > >
> >> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
> >> >> > > we're missing the lock I was mentioning in my previous reply. We need
> >> >> > > to prevent die selection not only for the time we're sending a single
> >> >> > > SPI message, but for the whole operation (which can be formed of
> >> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
> >> >> > > be interleaved, but I wouldn't bet on that ;-).  
> >>
> >> With operations, that consist of several SPI messages, do you mean
> >> something like NAND page program?  
> >
> > Yep.
> >  
> >>
> >> Because I'm quite sure something like this should be possible (and all
> >> of these commands consist only of one spi message, don't they?):
> >> 1. Select second (NAND) die
> >> 2. Send data to the NAND page buffer (PROGRAM)
> >> 3. Select first (NOR) die
> >> 4. Program data to a NOR block
> >> 5. Select second (NAND) die
> >> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)  
> >
> > Yes, and that's the problem, if you don't have a lock, the sequence you
> > describe above could be re-ordered like this:
> >
> > 1. Select second (NAND) die
> > 2. Select first (NOR) die
> > 3. Send data to the NAND page buffer (PROGRAM)
> > 4. Program data to a NOR block
> > ...  
> 
> At least with what I was thinking of (with the spi-multiplexer) this
> should be impossible, as the (virtual) spi bus message pump should
> ensure that any messages from spi-nand and spi-nor are properly
> serialized so they could only end up as in Frieder's example, unless
> I'm overlooking something.
> 
> So my virtual's spi implementation would look like this:
> 
> struct W25M161AW {
>         struct spi_device *spi; /* we at the parent bus */
> };
> 
> int W25M161AW_transfer_one_message(master, message)
> {
>         W25M161AW *w = spi_master_get_devdata(master);
>         spi_device *spi = message->spi;
> 
>         W25M161AW_send_die_select(w->spi, spi->chip_select);
> 
>         /* pass on the message to the parent bus */
>         spi_sync(w->spi, msg);
>         spi_finalize_current_message(master);
> 
>         return 0;
> }

I wish all QSPI controllers were exposed as regular SPI controllers with
QSPI capabilities, unfortunately most of them are standalone drivers
that simply does not implement the generic SPI interface and instead
directly register to their flash devices to SPI NOR layer, thus
preventing the generic logic you're proposing here :-(.

> 
> (this is a very simplified version, of course we can't pass on the
> message directly to the parent bus but need to clone it)
> 
> This way AFAICT there should be a guarantee that there can be no other
> message to the flash scheduled between the die select and the message
> to the die.
> 
> Of course if we need to ensure that there is no die change between the
> PROGRAM and the PROGRAM EXECUTE we need the extra bus lock. Without a
> public datasheet I can't tell though.

I found this one [1] if you want to have a look.

Regards,

Boris

[1]http://www.winbond.com.tw/resource-files/w25m161av%20combo%20reva%20091317%20mod%20final.pdf


From jonas.gorski at gmail.com  Mon Jan  8 07:18:33 2018
From: jonas.gorski at gmail.com (Jonas Gorski)
Date: Mon, 8 Jan 2018 16:18:33 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR and
 NAND flash
In-Reply-To: <20180108153249.24d05341@bbrezillon>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
 <20180108133118.02086991@bbrezillon>
 <CAOiHx=kw=L-H1yCwnzhfJhg3vUeXiTz_39n4_Wq3qbKMdDCitA@mail.gmail.com>
 <20180108153249.24d05341@bbrezillon>
Message-ID: <CAOiHx=k+7nZMmLQPCGpyKpuF0y2NjvjQrg2vtu+k4hWL0S_Rmg@mail.gmail.com>

On 8 January 2018 at 15:32, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Mon, 8 Jan 2018 14:43:56 +0100
> Jonas Gorski <jonas.gorski at gmail.com> wrote:
>
>> On 8 January 2018 at 13:31, Boris Brezillon
>> <boris.brezillon at free-electrons.com> wrote:
>> > Hi Frieder,
>> >
>> > On Mon, 8 Jan 2018 12:02:19 +0100
>> > Frieder Schrempf <frieder.schrempf at exceet.de> wrote:
>> >
>> >> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
>> >> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
>> >> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
>> >> >> > >> it sends the Software Die Select command if needed and then passes on
>> >> >> > >> the message to its parent bus.
>> >> >> > >>
>> >> >> > >> That way there should be no changes needed for spi-nor / spi-nand
>> >> >> > >> themselves. (The devil is probably in the details ;-)
>> >> >> > >
>> >> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
>> >> >> > > we're missing the lock I was mentioning in my previous reply. We need
>> >> >> > > to prevent die selection not only for the time we're sending a single
>> >> >> > > SPI message, but for the whole operation (which can be formed of
>> >> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
>> >> >> > > be interleaved, but I wouldn't bet on that ;-).
>> >>
>> >> With operations, that consist of several SPI messages, do you mean
>> >> something like NAND page program?
>> >
>> > Yep.
>> >
>> >>
>> >> Because I'm quite sure something like this should be possible (and all
>> >> of these commands consist only of one spi message, don't they?):
>> >> 1. Select second (NAND) die
>> >> 2. Send data to the NAND page buffer (PROGRAM)
>> >> 3. Select first (NOR) die
>> >> 4. Program data to a NOR block
>> >> 5. Select second (NAND) die
>> >> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)
>> >
>> > Yes, and that's the problem, if you don't have a lock, the sequence you
>> > describe above could be re-ordered like this:
>> >
>> > 1. Select second (NAND) die
>> > 2. Select first (NOR) die
>> > 3. Send data to the NAND page buffer (PROGRAM)
>> > 4. Program data to a NOR block
>> > ...
>>
>> At least with what I was thinking of (with the spi-multiplexer) this
>> should be impossible, as the (virtual) spi bus message pump should
>> ensure that any messages from spi-nand and spi-nor are properly
>> serialized so they could only end up as in Frieder's example, unless
>> I'm overlooking something.
>>
>> So my virtual's spi implementation would look like this:
>>
>> struct W25M161AW {
>>         struct spi_device *spi; /* we at the parent bus */
>> };
>>
>> int W25M161AW_transfer_one_message(master, message)
>> {
>>         W25M161AW *w = spi_master_get_devdata(master);
>>         spi_device *spi = message->spi;
>>
>>         W25M161AW_send_die_select(w->spi, spi->chip_select);
>>
>>         /* pass on the message to the parent bus */
>>         spi_sync(w->spi, msg);
>>         spi_finalize_current_message(master);
>>
>>         return 0;
>> }
>
> I wish all QSPI controllers were exposed as regular SPI controllers with
> QSPI capabilities, unfortunately most of them are standalone drivers
> that simply does not implement the generic SPI interface and instead
> directly register to their flash devices to SPI NOR layer, thus
> preventing the generic logic you're proposing here :-(.
>
>>
>> (this is a very simplified version, of course we can't pass on the
>> message directly to the parent bus but need to clone it)
>>
>> This way AFAICT there should be a guarantee that there can be no other
>> message to the flash scheduled between the die select and the message
>> to the die.
>>
>> Of course if we need to ensure that there is no die change between the
>> PROGRAM and the PROGRAM EXECUTE we need the extra bus lock. Without a
>> public datasheet I can't tell though.
>
> I found this one [1] if you want to have a look.
>
> Regards,
>
> Boris
>
> [1]http://www.winbond.com.tw/resource-files/w25m161av%20combo%20reva%20091317%20mod%20final.pdf

Thanks, that helped a lot. If I understand it correctly, we don't need
to care about interleaving e.g. the PROGRAM and PROGRAM EXECUTE with
NOR commands. "5. CONCURRENT OPERATION DESCRIPTIONS" (Page 7) says:

"However, the
inactive/idle die can still perform internal Program/Erase operation
which was initiated when the die was
active. Therefore, ?Read (on Active die) while Program/Erase (on Idle
die)? and ?Multi-die Program/Erase
(both Active & Idle dice)? concurrent operations are feasible in the
SpiStack ? series. ?Software Die Select
(C2h)? instruction will only change the active/idle status of the
stacked dice, and it will not interrupt any on-
going Program/Erase operations."

So we shouldn't need to lock the bus for multiple related SPI messages.

Also since the Software Die Select command takes an 8-bit die id, it
might make sense to model the dies with an address that matches the
die id.


Regards
Jonas


From boris.brezillon at free-electrons.com  Mon Jan  8 07:30:29 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 16:30:29 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed,
 8 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <CAK8P3a2YFJmdiw=0BgG1JkoQYLiD=em6N97AgB_4=Z2DDkY5dg@mail.gmail.com>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
 <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
 <20180108134415.GA11707@kroah.com>
 <CAK8P3a2YFJmdiw=0BgG1JkoQYLiD=em6N97AgB_4=Z2DDkY5dg@mail.gmail.com>
Message-ID: <20180108163029.369f8041@bbrezillon>

On Mon, 8 Jan 2018 15:01:38 +0100
Arnd Bergmann <arnd at arndb.de> wrote:

> On Mon, Jan 8, 2018 at 2:44 PM, gregkh <gregkh at linuxfoundation.org> wrote:
> > On Mon, Jan 08, 2018 at 02:16:25PM +0100, Arnd Bergmann wrote:  
> >> On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:  
> >> >
> >> > stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
> >> > Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
> >> > Tree: stable-rc
> >> > Branch: linux-4.4.y
> >> > Git Describe: v4.4.110-18-g5da3d9af3a4b
> >> > Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
> >> > Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> >> > Built: 4 unique architectures
> >> >
> >> > Build Failures Detected:
> >> >
> >> > arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
> >> > cm_x300_defconfig FAIL
> >> > mvebu_v7_defconfig FAIL
> >> > pxa3xx_defconfig FAIL
> >> > raumfeld_defconfig FAIL
> >> >
> >> > mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
> >> >
> >> > Errors:
> >> > drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
> >> > drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here  
> >>
> >> Hi Greg,
> >>
> >> Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
> >> apparently backported in error, it looks like it should just be
> >> dropped here in 4.4.y.
> >>
> >> The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
> >> ECC BCH support")', that commit was merged into v4.14, so backporting the
> >> fix further is probably not appropriate for 4.9 or earlier kernels either.  
> >
> > $ git describe --contains 43bcfd2bb24a
> > v3.14-rc1~65^2~127
> >
> > That is why I backported these patches this far.
> >
> > I'll drop the patch now, but the Fixes line is the problem here :)  
> 
> I think my mistake in the report was misreading v3.14 as v4.14. That means we
> still need the fix, just as Boris explained, it just needs to be done
> differently
> for older kernels.

Hm, actually I was wrong with my Fixes tag, it seems the bug has been
introduced by 'c2cdace755b5 ("mtd: nand: pxa3xx_nand: add support for
partial chunks")', so the fix is not needed for pre-4.6 kernels.


From boris.brezillon at free-electrons.com  Mon Jan  8 05:35:05 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 14:35:05 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed,
 8 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
 <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
Message-ID: <20180108143505.209fa2b2@bbrezillon>

Hi Arnd,

On Mon, 8 Jan 2018 14:16:25 +0100
Arnd Bergmann <arnd at arndb.de> wrote:

> On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:
> >
> > stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
> > Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
> > Tree: stable-rc
> > Branch: linux-4.4.y
> > Git Describe: v4.4.110-18-g5da3d9af3a4b
> > Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
> > Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> > Built: 4 unique architectures
> >
> > Build Failures Detected:
> >
> > arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
> > cm_x300_defconfig FAIL
> > mvebu_v7_defconfig FAIL
> > pxa3xx_defconfig FAIL
> > raumfeld_defconfig FAIL
> >
> > mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
> >
> > Errors:
> > drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
> > drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here  
> 
> Hi Greg,
> 
> Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
> apparently backported in error, it looks like it should just be
> dropped here in 4.4.y.
> 
> The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
> ECC BCH support")', that commit was merged into v4.14,

git tag --contains says commit 43bcfd2bb24a has been merged in 3.14.

> so backporting the
> fix further is probably not appropriate for 4.9 or earlier kernels either.
> 
> The duplicate case statement only happens before linux-4.6, as commit
> c2cdace755b5 ("mtd: nand: pxa3xx_nand: add support for partial chunks")'
> removed a previous 'case READOOB' statement in this driver, so the build
> regression appears only in 4.4 but not 4.9.

Crap, I didn't notice the NAND_READOOB case was handled before 4.6.
Still, the fix is needed, which means we'll have to revert this version
and create a custom one for 4.4.

Thanks for this report.

Boris


From boris.brezillon at free-electrons.com  Mon Jan  8 07:45:32 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 16:45:32 +0100
Subject: mtd layer: support of hybrid flash(W25M161AW) having both NOR
 and NAND flash
In-Reply-To: <CAOiHx=k+7nZMmLQPCGpyKpuF0y2NjvjQrg2vtu+k4hWL0S_Rmg@mail.gmail.com>
References: <20180108101447.1d9ab212@bbrezillon>
 <dbefefbb-7e0e-2a25-00b5-d9bcffa91a4b@exceet.de>
 <20180108133118.02086991@bbrezillon>
 <CAOiHx=kw=L-H1yCwnzhfJhg3vUeXiTz_39n4_Wq3qbKMdDCitA@mail.gmail.com>
 <20180108153249.24d05341@bbrezillon>
 <CAOiHx=k+7nZMmLQPCGpyKpuF0y2NjvjQrg2vtu+k4hWL0S_Rmg@mail.gmail.com>
Message-ID: <20180108164532.374f38f8@bbrezillon>

On Mon, 8 Jan 2018 16:18:33 +0100
Jonas Gorski <jonas.gorski at gmail.com> wrote:

> On 8 January 2018 at 15:32, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Mon, 8 Jan 2018 14:43:56 +0100
> > Jonas Gorski <jonas.gorski at gmail.com> wrote:
> >  
> >> On 8 January 2018 at 13:31, Boris Brezillon
> >> <boris.brezillon at free-electrons.com> wrote:  
> >> > Hi Frieder,
> >> >
> >> > On Mon, 8 Jan 2018 12:02:19 +0100
> >> > Frieder Schrempf <frieder.schrempf at exceet.de> wrote:
> >> >  
> >> >> >> > >> with the "windbond,w25q16fw" driver modeled as a simple
> >> >> >> > >> "spi-multiplexer" that registers its own virtual spi-bus. Then when
> >> >> >> > >> spi-nor or spi-nand tries to communicate with their appropriate die,
> >> >> >> > >> it sends the Software Die Select command if needed and then passes on
> >> >> >> > >> the message to its parent bus.
> >> >> >> > >>
> >> >> >> > >> That way there should be no changes needed for spi-nor / spi-nand
> >> >> >> > >> themselves. (The devil is probably in the details ;-)  
> >> >> >> > >
> >> >> >> > > Yep, I thought about this approach, and it's indeed quite elegant, but
> >> >> >> > > we're missing the lock I was mentioning in my previous reply. We need
> >> >> >> > > to prevent die selection not only for the time we're sending a single
> >> >> >> > > SPI message, but for the whole operation (which can be formed of
> >> >> >> > > several SPI messages). Or maybe I'm wrong, and operations can actually
> >> >> >> > > be interleaved, but I wouldn't bet on that ;-).  
> >> >>
> >> >> With operations, that consist of several SPI messages, do you mean
> >> >> something like NAND page program?  
> >> >
> >> > Yep.
> >> >  
> >> >>
> >> >> Because I'm quite sure something like this should be possible (and all
> >> >> of these commands consist only of one spi message, don't they?):
> >> >> 1. Select second (NAND) die
> >> >> 2. Send data to the NAND page buffer (PROGRAM)
> >> >> 3. Select first (NOR) die
> >> >> 4. Program data to a NOR block
> >> >> 5. Select second (NAND) die
> >> >> 6. Send command to transfer page buffer to flash (PROGRAM EXECUTE)  
> >> >
> >> > Yes, and that's the problem, if you don't have a lock, the sequence you
> >> > describe above could be re-ordered like this:
> >> >
> >> > 1. Select second (NAND) die
> >> > 2. Select first (NOR) die
> >> > 3. Send data to the NAND page buffer (PROGRAM)
> >> > 4. Program data to a NOR block
> >> > ...  
> >>
> >> At least with what I was thinking of (with the spi-multiplexer) this
> >> should be impossible, as the (virtual) spi bus message pump should
> >> ensure that any messages from spi-nand and spi-nor are properly
> >> serialized so they could only end up as in Frieder's example, unless
> >> I'm overlooking something.
> >>
> >> So my virtual's spi implementation would look like this:
> >>
> >> struct W25M161AW {
> >>         struct spi_device *spi; /* we at the parent bus */
> >> };
> >>
> >> int W25M161AW_transfer_one_message(master, message)
> >> {
> >>         W25M161AW *w = spi_master_get_devdata(master);
> >>         spi_device *spi = message->spi;
> >>
> >>         W25M161AW_send_die_select(w->spi, spi->chip_select);
> >>
> >>         /* pass on the message to the parent bus */
> >>         spi_sync(w->spi, msg);
> >>         spi_finalize_current_message(master);
> >>
> >>         return 0;
> >> }  
> >
> > I wish all QSPI controllers were exposed as regular SPI controllers with
> > QSPI capabilities, unfortunately most of them are standalone drivers
> > that simply does not implement the generic SPI interface and instead
> > directly register to their flash devices to SPI NOR layer, thus
> > preventing the generic logic you're proposing here :-(.
> >  
> >>
> >> (this is a very simplified version, of course we can't pass on the
> >> message directly to the parent bus but need to clone it)
> >>
> >> This way AFAICT there should be a guarantee that there can be no other
> >> message to the flash scheduled between the die select and the message
> >> to the die.
> >>
> >> Of course if we need to ensure that there is no die change between the
> >> PROGRAM and the PROGRAM EXECUTE we need the extra bus lock. Without a
> >> public datasheet I can't tell though.  
> >
> > I found this one [1] if you want to have a look.
> >
> > Regards,
> >
> > Boris
> >
> > [1]http://www.winbond.com.tw/resource-files/w25m161av%20combo%20reva%20091317%20mod%20final.pdf  
> 
> Thanks, that helped a lot. If I understand it correctly, we don't need
> to care about interleaving e.g. the PROGRAM and PROGRAM EXECUTE with
> NOR commands. "5. CONCURRENT OPERATION DESCRIPTIONS" (Page 7) says:
> 
> "However, the
> inactive/idle die can still perform internal Program/Erase operation
> which was initiated when the die was
> active. Therefore, ?Read (on Active die) while Program/Erase (on Idle
> die)? and ?Multi-die Program/Erase
> (both Active & Idle dice)? concurrent operations are feasible in the
> SpiStack ? series. ?Software Die Select
> (C2h)? instruction will only change the active/idle status of the
> stacked dice, and it will not interrupt any on-
> going Program/Erase operations."
> 
> So we shouldn't need to lock the bus for multiple related SPI messages.
> 
> Also since the Software Die Select command takes an 8-bit die id, it
> might make sense to model the dies with an address that matches the
> die id.

Sure, and I thinks that's what you and Prabhakar suggested. I just
overlooked the case where partitions are defined in the DT, hence my
initial suggestion to not define dies in the DT. So, in the end, the
following looks like a valid representation:

&qspi {
	...
	qflash0: dual-flash at 0 {
		compatible = "winbond,w25q16fw";
		reg = <0>;
		spi-max-frequency = <20000000>;
		#address-cells = <1>;
		#size-cells = <0>;

		nor at 0 {
			compatible = "jedec,spi-nor";
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <1>;

			partitions {
				...
			};
		};

		nand at 1 {
			compatible = "spi-nand";
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <1>;

			partitions {
				...
			};
		};
	};
};



From gregkh at linuxfoundation.org  Mon Jan  8 08:34:10 2018
From: gregkh at linuxfoundation.org (gregkh)
Date: Mon, 8 Jan 2018 17:34:10 +0100
Subject: stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8
 errors (v4.4.110-18-g5da3d9af3a4b)
In-Reply-To: <20180108163029.369f8041@bbrezillon>
References: <5a535545.93b5df0a.a7ca3.53c1@mx.google.com>
 <CAK8P3a1U9Q2RzXiE2qdD-zU0u+=fm66V6Aw8RR8YSXd5Gbiq3A@mail.gmail.com>
 <20180108134415.GA11707@kroah.com>
 <CAK8P3a2YFJmdiw=0BgG1JkoQYLiD=em6N97AgB_4=Z2DDkY5dg@mail.gmail.com>
 <20180108163029.369f8041@bbrezillon>
Message-ID: <20180108163410.GF26214@kroah.com>

On Mon, Jan 08, 2018 at 04:30:29PM +0100, Boris Brezillon wrote:
> On Mon, 8 Jan 2018 15:01:38 +0100
> Arnd Bergmann <arnd at arndb.de> wrote:
> 
> > On Mon, Jan 8, 2018 at 2:44 PM, gregkh <gregkh at linuxfoundation.org> wrote:
> > > On Mon, Jan 08, 2018 at 02:16:25PM +0100, Arnd Bergmann wrote:  
> > >> On Mon, Jan 8, 2018 at 12:25 PM, kernelci.org bot <bot at kernelci.org> wrote:  
> > >> >
> > >> > stable-rc/linux-4.4.y build: 178 builds: 4 failed, 174 passed, 8 errors (v4.4.110-18-g5da3d9af3a4b)
> > >> > Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.4.y/kernel/v4.4.110-18-g5da3d9af3a4b/
> > >> > Tree: stable-rc
> > >> > Branch: linux-4.4.y
> > >> > Git Describe: v4.4.110-18-g5da3d9af3a4b
> > >> > Git Commit: 5da3d9af3a4b90d3c5ab19f9ad1dbb7d237edcf9
> > >> > Git URL: http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> > >> > Built: 4 unique architectures
> > >> >
> > >> > Build Failures Detected:
> > >> >
> > >> > arm: gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)
> > >> > cm_x300_defconfig FAIL
> > >> > mvebu_v7_defconfig FAIL
> > >> > pxa3xx_defconfig FAIL
> > >> > raumfeld_defconfig FAIL
> > >> >
> > >> > mvebu_v7_defconfig (arm) ? FAIL, 2 errors, 0 warnings, 0 section mismatches
> > >> >
> > >> > Errors:
> > >> > drivers/mtd/nand/pxa3xx_nand.c:918:2: error: duplicate case value
> > >> > drivers/mtd/nand/pxa3xx_nand.c:915:2: error: previously used here  
> > >>
> > >> Hi Greg,
> > >>
> > >> Commit fee4380f368e ("mtd: nand: pxa3xx: Fix READOOB implementation") was
> > >> apparently backported in error, it looks like it should just be
> > >> dropped here in 4.4.y.
> > >>
> > >> The commit lists 'Fixes: 43bcfd2bb24a ("mtd: nand: pxa3xx: Add driver-specific
> > >> ECC BCH support")', that commit was merged into v4.14, so backporting the
> > >> fix further is probably not appropriate for 4.9 or earlier kernels either.  
> > >
> > > $ git describe --contains 43bcfd2bb24a
> > > v3.14-rc1~65^2~127
> > >
> > > That is why I backported these patches this far.
> > >
> > > I'll drop the patch now, but the Fixes line is the problem here :)  
> > 
> > I think my mistake in the report was misreading v3.14 as v4.14. That means we
> > still need the fix, just as Boris explained, it just needs to be done
> > differently
> > for older kernels.
> 
> Hm, actually I was wrong with my Fixes tag, it seems the bug has been
> introduced by 'c2cdace755b5 ("mtd: nand: pxa3xx_nand: add support for
> partial chunks")', so the fix is not needed for pre-4.6 kernels.

oops, also dropped it from 4.9, so I put it back there.

thanks,

greg k-h


From han.xu at nxp.com  Mon Jan  8 09:13:17 2018
From: han.xu at nxp.com (Han Xu)
Date: Mon, 8 Jan 2018 17:13:17 +0000
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1515181560-1410-1-git-send-email-festevam@gmail.com>
References: <1515181560-1410-1-git-send-email-festevam@gmail.com>
Message-ID: <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>


________________________________________
From: Fabio Estevam <festevam at gmail.com>
Sent: Friday, January 5, 2018 1:46 PM
To: Han Xu
Cc: cyrille.pitchen at wedev4u.fr; David Wolfe; Frank Li; linux-mtd at lists.infradead.org; Fabio Estevam
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names

From: Fabio Estevam <fabio.estevam at nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "fsl-quadspi.0"
mtd1: 01000000 00010000 "fsl-quadspi.1"

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index f17d224..7712c63 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
        struct resource *res;
        struct spi_nor *nor;
        struct mtd_info *mtd;
-       int ret, i = 0;
+       int ret, i = 0, mtd_index = 0;

        q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
        if (!q)
@@ -1047,6 +1047,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
                nor = &q->nor[i];
                mtd = &nor->mtd;

+               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "fsl-quadspi.%d",
+                                          mtd_index);
+               if (!mtd->name) {
+                       ret = -ENOMEM;
+                       goto mutex_failed;
+               }
+
                nor->dev = dev;
                spi_nor_set_flash_node(nor, np);
                nor->priv = q;
@@ -1098,6 +1105,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
                        nor->page_size = q->devtype_data->txfifo;

                i++;
+               mtd_index++;
        }

        /* finish the rest init. */
--
2.7.4

Acked-by: Han Xu <han.xu at nxp.com>


From kdasu.kdev at gmail.com  Mon Jan  8 12:06:13 2018
From: kdasu.kdev at gmail.com (Kamal Dasu)
Date: Mon,  8 Jan 2018 15:06:13 -0500
Subject: [PATCH v2] mtd: nand: brcmnand: Disable prefetch by default
Message-ID: <1515441973-30753-1-git-send-email-kdasu.kdev@gmail.com>

Brcm nand controller prefetch feature needs to be disabled
by default. Enabling affects performance on random reads as
well as dma reads.

Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
Cc: stable at vger.kernel.org
---
 drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index dd56a67..2a978d9 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 	if (ctrl->nand_version >= 0x0702)
 		tmp |= ACC_CONTROL_RD_ERASED;
 	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
-	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
-		/*
-		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
-		 * errors
-		 */
-		if (has_flash_dma(ctrl))
-			tmp &= ~ACC_CONTROL_PREFETCH;
-		else
-			tmp |= ACC_CONTROL_PREFETCH;
-	}
+	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
+		tmp &= ~ACC_CONTROL_PREFETCH;
+
 	nand_writereg(ctrl, offs, tmp);
 
 	return 0;
-- 
2.7.4



From boris.brezillon at free-electrons.com  Mon Jan  8 12:15:40 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 21:15:40 +0100
Subject: [PATCH v2] mtd: nand: brcmnand: Disable prefetch by default
In-Reply-To: <1515441973-30753-1-git-send-email-kdasu.kdev@gmail.com>
References: <1515441973-30753-1-git-send-email-kdasu.kdev@gmail.com>
Message-ID: <20180108211540.131f938a@bbrezillon>

On Mon,  8 Jan 2018 15:06:13 -0500
Kamal Dasu <kdasu.kdev at gmail.com> wrote:

> Brcm nand controller prefetch feature needs to be disabled
> by default. Enabling affects performance on random reads as
> well as dma reads.
> 
> Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
> Cc: stable at vger.kernel.org

Fixes:????

> ---
>  drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
> index dd56a67..2a978d9 100644
> --- a/drivers/mtd/nand/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/brcmnand/brcmnand.c
> @@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>  	if (ctrl->nand_version >= 0x0702)
>  		tmp |= ACC_CONTROL_RD_ERASED;
>  	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
> -	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
> -		/*
> -		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
> -		 * errors
> -		 */
> -		if (has_flash_dma(ctrl))
> -			tmp &= ~ACC_CONTROL_PREFETCH;
> -		else
> -			tmp |= ACC_CONTROL_PREFETCH;
> -	}
> +	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
> +		tmp &= ~ACC_CONTROL_PREFETCH;
> +
>  	nand_writereg(ctrl, offs, tmp);
>  
>  	return 0;



From kdasu.kdev at gmail.com  Mon Jan  8 12:36:48 2018
From: kdasu.kdev at gmail.com (Kamal Dasu)
Date: Mon,  8 Jan 2018 15:36:48 -0500
Subject: [PATCH v3] mtd: nand: brcmnand: Disable prefetch by default
Message-ID: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>

Brcm nand controller prefetch feature needs to be disabled
by default. Enabling affects performance on random reads as
well as dma reads.

Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
Cc: stable at vger.kernel.org
---
 drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index dd56a67..2a978d9 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 	if (ctrl->nand_version >= 0x0702)
 		tmp |= ACC_CONTROL_RD_ERASED;
 	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
-	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
-		/*
-		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
-		 * errors
-		 */
-		if (has_flash_dma(ctrl))
-			tmp &= ~ACC_CONTROL_PREFETCH;
-		else
-			tmp |= ACC_CONTROL_PREFETCH;
-	}
+	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
+		tmp &= ~ACC_CONTROL_PREFETCH;
+
 	nand_writereg(ctrl, offs, tmp);
 
 	return 0;
-- 
2.7.4



From f.fainelli at gmail.com  Mon Jan  8 12:37:38 2018
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 8 Jan 2018 12:37:38 -0800
Subject: [PATCH v3] mtd: nand: brcmnand: Disable prefetch by default
In-Reply-To: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
References: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
Message-ID: <c06a78aa-1285-8b93-9440-af9770ffdd91@gmail.com>

On 01/08/2018 12:36 PM, Kamal Dasu wrote:
> Brcm nand controller prefetch feature needs to be disabled
> by default. Enabling affects performance on random reads as
> well as dma reads.
> 
> Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
> Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
> Cc: stable at vger.kernel.org

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From boris.brezillon at free-electrons.com  Mon Jan  8 12:46:56 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 21:46:56 +0100
Subject: [PATCH v3 3/4] mtd: Stop directly calling master ->_xxx() hooks
 from mtdpart code
In-Reply-To: <20171215123954.30017-4-boris.brezillon@free-electrons.com>
References: <20171215123954.30017-1-boris.brezillon@free-electrons.com>
 <20171215123954.30017-4-boris.brezillon@free-electrons.com>
Message-ID: <20180108214656.35f26b27@bbrezillon>

+Ladislav

On Fri, 15 Dec 2017 13:39:53 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> The MTD layer provides several wrappers around mtd->_xxx() hooks. Call
> these wrappers instead of directly dereferencing the associated ->_xxx()
> pointer.
> 
> This change has been motivated by another rework letting the core
> handle the case where ->_read/write_oob() are implemented but not
> ->_read/write(). In this case, we want mtd_read/write() to fall back to
> ->_read/write_oob() when ->_read/write() are NULL. The problem is,  
> mtdpart is directly calling the ->_xxx() instead of using the wrappers,
> thus leading to a NULL pointer exception.
> 
> Even though we only need to do the change for part_read/write(), going
> through those wrappers for all kind of part -> master operation
> propagation is a good thing, because other wrappers might become
> smarter over time, and the duplicated check overhead (parameters will
> be checked at the partition and master level instead of only at the
> partition level) should be negligible.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
> Changes in v3:
> - unconditionally assign part wrappers as suggested by Brian
> 
> Changes in v2:
> - new patch needed to fix a NULL pointer dereference BUG
> ---
>  drivers/mtd/mtdpart.c | 141 +++++++++++++++++++-------------------------------
>  1 file changed, 53 insertions(+), 88 deletions(-)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..e83c9d870b11 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -74,8 +74,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
>  	int res;
>  
>  	stats = part->parent->ecc_stats;
> -	res = part->parent->_read(part->parent, from + part->offset, len,
> -				  retlen, buf);
> +	res = mtd_read(part->parent, from + part->offset, len, retlen, buf);

This change introduced a regression (reported by Ladislav) because
mtd_read() does not return the number of bitflips and instead returns 0
if we are below ->bitflips_threshold and -EUCLEAN if we're equal
or above. That's a problem in 2 situations:
1/ when ->bitflips_threshold is customized for a specific partition,
   the custom value is ignored in favor of the one set on the master MTD
   device
2/ when PARTITIONED_MASTER is not defined, ->bitflip_threshold is not
   initialized (->bitflip_threshold = 0), thus triggering -EUCLEAN
   every time we read a page

I fear this patch might introduce other subtle regression so I plan to
drop it entirely.

Regards,

Boris

>  	if (unlikely(mtd_is_eccerr(res)))
>  		mtd->ecc_stats.failed +=
>  			part->parent->ecc_stats.failed - stats.failed;


From boris.brezillon at free-electrons.com  Mon Jan  8 13:11:28 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 22:11:28 +0100
Subject: [PATCH v3 4/4] mtd: Fallback to ->_read/write_oob() when
 ->_read/write() is missing
In-Reply-To: <20171215123954.30017-5-boris.brezillon@free-electrons.com>
References: <20171215123954.30017-1-boris.brezillon@free-electrons.com>
 <20171215123954.30017-5-boris.brezillon@free-electrons.com>
Message-ID: <20180108221128.471f5f96@bbrezillon>

On Fri, 15 Dec 2017 13:39:54 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Some MTD sublayers/drivers are implementing ->_read/write_oob() and
> provide dummy wrappers for their ->_read/write() implementations.
> Let the core handle this case instead of duplicating the logic.

Also dropped this patch since it depends on patch 3. I'll send a new
version soon.

> 
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>
> Acked-by: Brian Norris <computersforpeace at gmail.com>
> ---
> Changes in v3:
> - none
> 
> Changes in v2:
> - none
> ---
>  drivers/mtd/devices/docg3.c        | 65 --------------------------------------
>  drivers/mtd/mtdcore.c              | 31 ++++++++++++++++--
>  drivers/mtd/nand/nand_base.c       | 56 --------------------------------
>  drivers/mtd/onenand/onenand_base.c | 63 ------------------------------------
>  4 files changed, 29 insertions(+), 186 deletions(-)
> 
> diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
> index 0806f72102c0..5fb5e93d1547 100644
> --- a/drivers/mtd/devices/docg3.c
> +++ b/drivers/mtd/devices/docg3.c
> @@ -990,36 +990,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
>  	goto out;
>  }
>  
> -/**
> - * doc_read - Read bytes from flash
> - * @mtd: the device
> - * @from: the offset from first block and first page, in bytes, aligned on page
> - *        size
> - * @len: the number of bytes to read (must be a multiple of 4)
> - * @retlen: the number of bytes actually read
> - * @buf: the filled in buffer
> - *
> - * Reads flash memory pages. This function does not read the OOB chunk, but only
> - * the page data.
> - *
> - * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred
> - */
> -static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
> -	     size_t *retlen, u_char *buf)
> -{
> -	struct mtd_oob_ops ops;
> -	size_t ret;
> -
> -	memset(&ops, 0, sizeof(ops));
> -	ops.datbuf = buf;
> -	ops.len = len;
> -	ops.mode = MTD_OPS_AUTO_OOB;
> -
> -	ret = doc_read_oob(mtd, from, &ops);
> -	*retlen = ops.retlen;
> -	return ret;
> -}
> -
>  static int doc_reload_bbt(struct docg3 *docg3)
>  {
>  	int block = DOC_LAYOUT_BLOCK_BBT;
> @@ -1513,39 +1483,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
>  	return ret;
>  }
>  
> -/**
> - * doc_write - Write a buffer to the chip
> - * @mtd: the device
> - * @to: the offset from first block and first page, in bytes, aligned on page
> - *      size
> - * @len: the number of bytes to write (must be a full page size, ie. 512)
> - * @retlen: the number of bytes actually written (0 or 512)
> - * @buf: the buffer to get bytes from
> - *
> - * Writes data to the chip.
> - *
> - * Returns 0 if write successful, -EIO if write error
> - */
> -static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
> -		     size_t *retlen, const u_char *buf)
> -{
> -	struct docg3 *docg3 = mtd->priv;
> -	int ret;
> -	struct mtd_oob_ops ops;
> -
> -	doc_dbg("doc_write(to=%lld, len=%zu)\n", to, len);
> -	ops.datbuf = (char *)buf;
> -	ops.len = len;
> -	ops.mode = MTD_OPS_PLACE_OOB;
> -	ops.oobbuf = NULL;
> -	ops.ooblen = 0;
> -	ops.ooboffs = 0;
> -
> -	ret = doc_write_oob(mtd, to, &ops);
> -	*retlen = ops.retlen;
> -	return ret;
> -}
> -
>  static struct docg3 *sysfs_dev2docg3(struct device *dev,
>  				     struct device_attribute *attr)
>  {
> @@ -1866,8 +1803,6 @@ static int __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
>  	mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
>  	mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
>  	mtd->_erase = doc_erase;
> -	mtd->_read = doc_read;
> -	mtd->_write = doc_write;
>  	mtd->_read_oob = doc_read_oob;
>  	mtd->_write_oob = doc_write_oob;
>  	mtd->_block_isbad = doc_block_isbad;
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 642c35dde686..d7ab091b36b2 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -1058,7 +1058,20 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
>  	 * representing the maximum number of bitflips that were corrected on
>  	 * any one ecc region (if applicable; zero otherwise).
>  	 */
> -	ret_code = mtd->_read(mtd, from, len, retlen, buf);
> +	if (mtd->_read) {
> +		ret_code = mtd->_read(mtd, from, len, retlen, buf);
> +	} else if (mtd->_read_oob) {
> +		struct mtd_oob_ops ops = {
> +			.len = len,
> +			.datbuf = buf,
> +		};
> +
> +		ret_code = mtd->_read_oob(mtd, from, &ops);
> +		*retlen = ops.retlen;
> +	} else {
> +		return -ENOTSUPP;
> +	}
> +
>  	if (unlikely(ret_code < 0))
>  		return ret_code;
>  	if (mtd->ecc_strength == 0)
> @@ -1073,11 +1086,25 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
>  	*retlen = 0;
>  	if (to < 0 || to >= mtd->size || len > mtd->size - to)
>  		return -EINVAL;
> -	if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
> +	if ((!mtd->_write && !mtd->_write_oob) ||
> +	    !(mtd->flags & MTD_WRITEABLE))
>  		return -EROFS;
>  	if (!len)
>  		return 0;
>  	ledtrig_mtd_activity();
> +
> +	if (!mtd->_write) {
> +		struct mtd_oob_ops ops = {
> +			.len = len,
> +			.datbuf = (u8 *)buf,
> +		};
> +		int ret;
> +
> +		ret = mtd->_write_oob(mtd, to, &ops);
> +		*retlen = ops.retlen;
> +		return ret;
> +	}
> +
>  	return mtd->_write(mtd, to, len, retlen, buf);
>  }
>  EXPORT_SYMBOL_GPL(mtd_write);
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 6135d007a068..889ceadbf607 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2027,33 +2027,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
>  }
>  
>  /**
> - * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
> - * @mtd: MTD device structure
> - * @from: offset to read from
> - * @len: number of bytes to read
> - * @retlen: pointer to variable to store the number of read bytes
> - * @buf: the databuffer to put data
> - *
> - * Get hold of the chip and call nand_do_read.
> - */
> -static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
> -		     size_t *retlen, uint8_t *buf)
> -{
> -	struct mtd_oob_ops ops;
> -	int ret;
> -
> -	nand_get_device(mtd, FL_READING);
> -	memset(&ops, 0, sizeof(ops));
> -	ops.len = len;
> -	ops.datbuf = buf;
> -	ops.mode = MTD_OPS_PLACE_OOB;
> -	ret = nand_do_read_ops(mtd, from, &ops);
> -	*retlen = ops.retlen;
> -	nand_release_device(mtd);
> -	return ret;
> -}
> -
> -/**
>   * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
>   * @mtd: mtd info structure
>   * @chip: nand chip info structure
> @@ -2822,33 +2795,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
>  }
>  
>  /**
> - * nand_write - [MTD Interface] NAND write with ECC
> - * @mtd: MTD device structure
> - * @to: offset to write to
> - * @len: number of bytes to write
> - * @retlen: pointer to variable to store the number of written bytes
> - * @buf: the data to write
> - *
> - * NAND write with ECC.
> - */
> -static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
> -			  size_t *retlen, const uint8_t *buf)
> -{
> -	struct mtd_oob_ops ops;
> -	int ret;
> -
> -	nand_get_device(mtd, FL_WRITING);
> -	memset(&ops, 0, sizeof(ops));
> -	ops.len = len;
> -	ops.datbuf = (uint8_t *)buf;
> -	ops.mode = MTD_OPS_PLACE_OOB;
> -	ret = nand_do_write_ops(mtd, to, &ops);
> -	*retlen = ops.retlen;
> -	nand_release_device(mtd);
> -	return ret;
> -}
> -
> -/**
>   * nand_do_write_oob - [MTD Interface] NAND write out-of-band
>   * @mtd: MTD device structure
>   * @to: offset to write to
> @@ -4917,8 +4863,6 @@ int nand_scan_tail(struct mtd_info *mtd)
>  	mtd->_erase = nand_erase;
>  	mtd->_point = NULL;
>  	mtd->_unpoint = NULL;
> -	mtd->_read = nand_read;
> -	mtd->_write = nand_write;
>  	mtd->_panic_write = panic_nand_write;
>  	mtd->_read_oob = nand_read_oob;
>  	mtd->_write_oob = nand_write_oob;
> diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
> index 1a6d0e367b89..050ba8a87543 100644
> --- a/drivers/mtd/onenand/onenand_base.c
> +++ b/drivers/mtd/onenand/onenand_base.c
> @@ -1448,38 +1448,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
>  }
>  
>  /**
> - * onenand_read - [MTD Interface] Read data from flash
> - * @param mtd		MTD device structure
> - * @param from		offset to read from
> - * @param len		number of bytes to read
> - * @param retlen	pointer to variable to store the number of read bytes
> - * @param buf		the databuffer to put data
> - *
> - * Read with ecc
> -*/
> -static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
> -	size_t *retlen, u_char *buf)
> -{
> -	struct onenand_chip *this = mtd->priv;
> -	struct mtd_oob_ops ops = {
> -		.len	= len,
> -		.ooblen	= 0,
> -		.datbuf	= buf,
> -		.oobbuf	= NULL,
> -	};
> -	int ret;
> -
> -	onenand_get_device(mtd, FL_READING);
> -	ret = ONENAND_IS_4KB_PAGE(this) ?
> -		onenand_mlc_read_ops_nolock(mtd, from, &ops) :
> -		onenand_read_ops_nolock(mtd, from, &ops);
> -	onenand_release_device(mtd);
> -
> -	*retlen = ops.retlen;
> -	return ret;
> -}
> -
> -/**
>   * onenand_read_oob - [MTD Interface] Read main and/or out-of-band
>   * @param mtd:		MTD device structure
>   * @param from:		offset to read from
> @@ -2129,35 +2097,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
>  }
>  
>  /**
> - * onenand_write - [MTD Interface] write buffer to FLASH
> - * @param mtd		MTD device structure
> - * @param to		offset to write to
> - * @param len		number of bytes to write
> - * @param retlen	pointer to variable to store the number of written bytes
> - * @param buf		the data to write
> - *
> - * Write with ECC
> - */
> -static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
> -	size_t *retlen, const u_char *buf)
> -{
> -	struct mtd_oob_ops ops = {
> -		.len	= len,
> -		.ooblen	= 0,
> -		.datbuf	= (u_char *) buf,
> -		.oobbuf	= NULL,
> -	};
> -	int ret;
> -
> -	onenand_get_device(mtd, FL_WRITING);
> -	ret = onenand_write_ops_nolock(mtd, to, &ops);
> -	onenand_release_device(mtd);
> -
> -	*retlen = ops.retlen;
> -	return ret;
> -}
> -
> -/**
>   * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
>   * @param mtd:		MTD device structure
>   * @param to:		offset to write
> @@ -4038,8 +3977,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
>  	mtd->_erase = onenand_erase;
>  	mtd->_point = NULL;
>  	mtd->_unpoint = NULL;
> -	mtd->_read = onenand_read;
> -	mtd->_write = onenand_write;
>  	mtd->_read_oob = onenand_read_oob;
>  	mtd->_write_oob = onenand_write_oob;
>  	mtd->_panic_write = onenand_panic_write;



From boris.brezillon at free-electrons.com  Mon Jan  8 13:15:40 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon,  8 Jan 2018 22:15:40 +0100
Subject: [PATCH v4 1/3] mtd: mtdpart: Make ECC stat handling consistent
In-Reply-To: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
Message-ID: <20180108211542.11891-2-boris.brezillon@free-electrons.com>

part_read() and part_read_oob() where counting ECC failures and
bitflips differently. Adjust part_read_oob() to mimic what is done in
part_read(). This is in needed to use ->_read_oob() as a fallback when
when ->_read() is not implemented.

Note that bitflips and ECC failure accounting on MTD partitions is
broken by design, because nothing prevents concurrent accesses to the
underlying master MTD device between the moment we save the stats in a
local variable and the moment master->_read[_oob]() returns. It's not
something that can easily be fixed, so leave it like that for now.

Suggested-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes in v4:
- new patch
---
 drivers/mtd/mtdpart.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index be088bccd593..283e8526713b 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 		struct mtd_oob_ops *ops)
 {
 	struct mtd_part *part = mtd_to_part(mtd);
+	struct mtd_ecc_stats stats;
 	int res;
 
 	if (from >= mtd->size)
@@ -127,12 +128,12 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 	}
 
 	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
-	if (unlikely(res)) {
-		if (mtd_is_bitflip(res))
-			mtd->ecc_stats.corrected++;
-		if (mtd_is_eccerr(res))
-			mtd->ecc_stats.failed++;
-	}
+	if (unlikely(mtd_is_eccerr(res)))
+		mtd->ecc_stats.failed +=
+			part->parent->ecc_stats.failed - stats.failed;
+	else
+		mtd->ecc_stats.corrected +=
+			part->parent->ecc_stats.corrected - stats.corrected;
 	return res;
 }
 
-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan  8 13:15:39 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon,  8 Jan 2018 22:15:39 +0100
Subject: [PATCH v4 0/4] mtd: Preparation patches for the SPI NAND framework
Message-ID: <20180108211542.11891-1-boris.brezillon@free-electrons.com>

Hello,

Here is a set of patches preparing the introduction of the generic
NAND and SPI frameworks.

If you want to see the overall picture of the SPI NAND framework you can
have a look at this branch [2].

Regards,

Boris

Change in v4:
- add "mtd: mtdpart: Make ECC stat handling consistent" and
- integrate "mtd: Remove duplicate checks on mtd_oob_ops parameter"
  into this series
- drop "mtd: Stop directly calling master ->_xxx() hooks from mtdpart
  code"

Boris Brezillon (3):
  mtd: mtdpart: Make ECC stat handling consistent
  mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
  mtd: Remove duplicate checks on mtd_oob_ops parameter

 drivers/mtd/devices/docg3.c        | 70 ------------------------------
 drivers/mtd/mtdcore.c              | 31 +++++++++++++-
 drivers/mtd/mtdpart.c              | 42 +++++-------------
 drivers/mtd/nand/nand_base.c       | 87 --------------------------------------
 drivers/mtd/onenand/onenand_base.c | 81 -----------------------------------
 5 files changed, 40 insertions(+), 271 deletions(-)

-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan  8 13:15:42 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon,  8 Jan 2018 22:15:42 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops parameter
In-Reply-To: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
Message-ID: <20180108211542.11891-4-boris.brezillon@free-electrons.com>

Some of the check done in custom ->_read/write_oob() implementation are
already done by the core (in mtd_check_oob_ops()).

Suggested-by: Peter Pan <peterpansjtu at gmail.com>
[Remove redundant checks done in mtdpart.c]
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes in v4:
- integrated into the SPI NAND preparation patchset

Changes in v3:
- Rebased on mtd/next after "mtd: Stop directly calling master ->_xxx()
  hooks from mtdpart code" had been dropped

Changes in v2:
- Merge "mtd: Remove unneeded checks in part_{read,write}_oob()" into
  this commit
---
 drivers/mtd/devices/docg3.c        |  5 -----
 drivers/mtd/mtdpart.c              | 23 -----------------------
 drivers/mtd/nand/nand_base.c       | 31 -------------------------------
 drivers/mtd/onenand/onenand_base.c | 18 ------------------
 4 files changed, 77 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 5fb5e93d1547..a85af236b44d 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -904,9 +904,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	if (ooblen % DOC_LAYOUT_OOB_SIZE)
 		return -EINVAL;
 
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	ops->oobretlen = 0;
 	ops->retlen = 0;
 	ret = 0;
@@ -1441,8 +1438,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 	if (len && ooblen &&
 	    (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta))
 		return -EINVAL;
-	if (ofs + len > mtd->size)
-		return -EINVAL;
 
 	ops->oobretlen = 0;
 	ops->retlen = 0;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 07ef168ded98..131bb1d52871 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -108,25 +108,6 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 	struct mtd_ecc_stats stats;
 	int res;
 
-	if (from >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && from + ops->len > mtd->size)
-		return -EINVAL;
-
-	/*
-	 * If OOB is also requested, make sure that we do not read past the end
-	 * of this partition.
-	 */
-	if (ops->oobbuf) {
-		size_t len, pages;
-
-		len = mtd_oobavail(mtd, ops);
-		pages = mtd_div_by_ws(mtd->size, mtd);
-		pages -= mtd_div_by_ws(from, mtd);
-		if (ops->ooboffs + ops->ooblen > pages * len)
-			return -EINVAL;
-	}
-
 	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
 	if (unlikely(mtd_is_eccerr(res)))
 		mtd->ecc_stats.failed +=
@@ -190,10 +171,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
 	struct mtd_part *part = mtd_to_part(mtd);
 
-	if (to >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && to + ops->len > mtd->size)
-		return -EINVAL;
 	return part->parent->_write_oob(part->parent, to + part->offset, ops);
 }
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 889ceadbf607..61eeac233683 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2187,21 +2187,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 
 	len = mtd_oobavail(mtd, ops);
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start read outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
-					(from >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to read beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(from >> chip->chip_shift);
 	chip->select_chip(mtd, chipnr);
 
@@ -2820,22 +2805,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start write outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow write past end of device */
-	if (unlikely(to >= mtd->size ||
-		     ops->ooboffs + ops->ooblen >
-			((mtd->size >> chip->page_shift) -
-			 (to >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to write beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(to >> chip->chip_shift);
 
 	/*
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 050ba8a87543..979f4031f23c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1383,15 +1383,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (from >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to read beyond end of device\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	stats = mtd->ecc_stats;
 
 	readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
@@ -2024,15 +2015,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(to >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (to >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to write past end of device\n",
-		       __func__);
-		return -EINVAL;
-	}
-
 	oobbuf = this->oob_buf;
 
 	oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan  8 13:15:41 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon,  8 Jan 2018 22:15:41 +0100
Subject: [PATCH v4 2/3] mtd: Fallback to ->_read/write_oob() when
 ->_read/write() is missing
In-Reply-To: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
Message-ID: <20180108211542.11891-3-boris.brezillon@free-electrons.com>

Some MTD sublayers/drivers are implementing ->_read/write_oob() and
provide dummy wrappers for their ->_read/write() implementations.
Let the core handle this case instead of duplicating the logic.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>
Acked-by: Brian Norris <computersforpeace at gmail.com>
Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
Changes in v4:
- Update mtdpart.c to assign slave->_read/_write() only if the master
  has ->_read/_write != NULL

Changes in v3:
- none

Changes in v2:
- none
---
 drivers/mtd/devices/docg3.c        | 65 --------------------------------------
 drivers/mtd/mtdcore.c              | 31 ++++++++++++++++--
 drivers/mtd/mtdpart.c              |  6 ++--
 drivers/mtd/nand/nand_base.c       | 56 --------------------------------
 drivers/mtd/onenand/onenand_base.c | 63 ------------------------------------
 5 files changed, 33 insertions(+), 188 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 0806f72102c0..5fb5e93d1547 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -990,36 +990,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	goto out;
 }
 
-/**
- * doc_read - Read bytes from flash
- * @mtd: the device
- * @from: the offset from first block and first page, in bytes, aligned on page
- *        size
- * @len: the number of bytes to read (must be a multiple of 4)
- * @retlen: the number of bytes actually read
- * @buf: the filled in buffer
- *
- * Reads flash memory pages. This function does not read the OOB chunk, but only
- * the page data.
- *
- * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred
- */
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-	     size_t *retlen, u_char *buf)
-{
-	struct mtd_oob_ops ops;
-	size_t ret;
-
-	memset(&ops, 0, sizeof(ops));
-	ops.datbuf = buf;
-	ops.len = len;
-	ops.mode = MTD_OPS_AUTO_OOB;
-
-	ret = doc_read_oob(mtd, from, &ops);
-	*retlen = ops.retlen;
-	return ret;
-}
-
 static int doc_reload_bbt(struct docg3 *docg3)
 {
 	int block = DOC_LAYOUT_BLOCK_BBT;
@@ -1513,39 +1483,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 	return ret;
 }
 
-/**
- * doc_write - Write a buffer to the chip
- * @mtd: the device
- * @to: the offset from first block and first page, in bytes, aligned on page
- *      size
- * @len: the number of bytes to write (must be a full page size, ie. 512)
- * @retlen: the number of bytes actually written (0 or 512)
- * @buf: the buffer to get bytes from
- *
- * Writes data to the chip.
- *
- * Returns 0 if write successful, -EIO if write error
- */
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-		     size_t *retlen, const u_char *buf)
-{
-	struct docg3 *docg3 = mtd->priv;
-	int ret;
-	struct mtd_oob_ops ops;
-
-	doc_dbg("doc_write(to=%lld, len=%zu)\n", to, len);
-	ops.datbuf = (char *)buf;
-	ops.len = len;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ops.oobbuf = NULL;
-	ops.ooblen = 0;
-	ops.ooboffs = 0;
-
-	ret = doc_write_oob(mtd, to, &ops);
-	*retlen = ops.retlen;
-	return ret;
-}
-
 static struct docg3 *sysfs_dev2docg3(struct device *dev,
 				     struct device_attribute *attr)
 {
@@ -1866,8 +1803,6 @@ static int __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
 	mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
 	mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
 	mtd->_erase = doc_erase;
-	mtd->_read = doc_read;
-	mtd->_write = doc_write;
 	mtd->_read_oob = doc_read_oob;
 	mtd->_write_oob = doc_write_oob;
 	mtd->_block_isbad = doc_block_isbad;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 642c35dde686..d7ab091b36b2 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1058,7 +1058,20 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
 	 * representing the maximum number of bitflips that were corrected on
 	 * any one ecc region (if applicable; zero otherwise).
 	 */
-	ret_code = mtd->_read(mtd, from, len, retlen, buf);
+	if (mtd->_read) {
+		ret_code = mtd->_read(mtd, from, len, retlen, buf);
+	} else if (mtd->_read_oob) {
+		struct mtd_oob_ops ops = {
+			.len = len,
+			.datbuf = buf,
+		};
+
+		ret_code = mtd->_read_oob(mtd, from, &ops);
+		*retlen = ops.retlen;
+	} else {
+		return -ENOTSUPP;
+	}
+
 	if (unlikely(ret_code < 0))
 		return ret_code;
 	if (mtd->ecc_strength == 0)
@@ -1073,11 +1086,25 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
 	*retlen = 0;
 	if (to < 0 || to >= mtd->size || len > mtd->size - to)
 		return -EINVAL;
-	if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
+	if ((!mtd->_write && !mtd->_write_oob) ||
+	    !(mtd->flags & MTD_WRITEABLE))
 		return -EROFS;
 	if (!len)
 		return 0;
 	ledtrig_mtd_activity();
+
+	if (!mtd->_write) {
+		struct mtd_oob_ops ops = {
+			.len = len,
+			.datbuf = (u8 *)buf,
+		};
+		int ret;
+
+		ret = mtd->_write_oob(mtd, to, &ops);
+		*retlen = ops.retlen;
+		return ret;
+	}
+
 	return mtd->_write(mtd, to, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_write);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 283e8526713b..07ef168ded98 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -436,8 +436,10 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 				parent->dev.parent;
 	slave->mtd.dev.of_node = part->of_node;
 
-	slave->mtd._read = part_read;
-	slave->mtd._write = part_write;
+	if (parent->_read)
+		slave->mtd._read = part_read;
+	if (parent->_write)
+		slave->mtd._write = part_write;
 
 	if (parent->_panic_write)
 		slave->mtd._panic_write = part_panic_write;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6135d007a068..889ceadbf607 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2027,33 +2027,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 }
 
 /**
- * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
- * @mtd: MTD device structure
- * @from: offset to read from
- * @len: number of bytes to read
- * @retlen: pointer to variable to store the number of read bytes
- * @buf: the databuffer to put data
- *
- * Get hold of the chip and call nand_do_read.
- */
-static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, uint8_t *buf)
-{
-	struct mtd_oob_ops ops;
-	int ret;
-
-	nand_get_device(mtd, FL_READING);
-	memset(&ops, 0, sizeof(ops));
-	ops.len = len;
-	ops.datbuf = buf;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ret = nand_do_read_ops(mtd, from, &ops);
-	*retlen = ops.retlen;
-	nand_release_device(mtd);
-	return ret;
-}
-
-/**
  * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
  * @mtd: mtd info structure
  * @chip: nand chip info structure
@@ -2822,33 +2795,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 }
 
 /**
- * nand_write - [MTD Interface] NAND write with ECC
- * @mtd: MTD device structure
- * @to: offset to write to
- * @len: number of bytes to write
- * @retlen: pointer to variable to store the number of written bytes
- * @buf: the data to write
- *
- * NAND write with ECC.
- */
-static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
-			  size_t *retlen, const uint8_t *buf)
-{
-	struct mtd_oob_ops ops;
-	int ret;
-
-	nand_get_device(mtd, FL_WRITING);
-	memset(&ops, 0, sizeof(ops));
-	ops.len = len;
-	ops.datbuf = (uint8_t *)buf;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ret = nand_do_write_ops(mtd, to, &ops);
-	*retlen = ops.retlen;
-	nand_release_device(mtd);
-	return ret;
-}
-
-/**
  * nand_do_write_oob - [MTD Interface] NAND write out-of-band
  * @mtd: MTD device structure
  * @to: offset to write to
@@ -4917,8 +4863,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->_erase = nand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
-	mtd->_read = nand_read;
-	mtd->_write = nand_write;
 	mtd->_panic_write = panic_nand_write;
 	mtd->_read_oob = nand_read_oob;
 	mtd->_write_oob = nand_write_oob;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 1a6d0e367b89..050ba8a87543 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1448,38 +1448,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 }
 
 /**
- * onenand_read - [MTD Interface] Read data from flash
- * @param mtd		MTD device structure
- * @param from		offset to read from
- * @param len		number of bytes to read
- * @param retlen	pointer to variable to store the number of read bytes
- * @param buf		the databuffer to put data
- *
- * Read with ecc
-*/
-static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-	size_t *retlen, u_char *buf)
-{
-	struct onenand_chip *this = mtd->priv;
-	struct mtd_oob_ops ops = {
-		.len	= len,
-		.ooblen	= 0,
-		.datbuf	= buf,
-		.oobbuf	= NULL,
-	};
-	int ret;
-
-	onenand_get_device(mtd, FL_READING);
-	ret = ONENAND_IS_4KB_PAGE(this) ?
-		onenand_mlc_read_ops_nolock(mtd, from, &ops) :
-		onenand_read_ops_nolock(mtd, from, &ops);
-	onenand_release_device(mtd);
-
-	*retlen = ops.retlen;
-	return ret;
-}
-
-/**
  * onenand_read_oob - [MTD Interface] Read main and/or out-of-band
  * @param mtd:		MTD device structure
  * @param from:		offset to read from
@@ -2129,35 +2097,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 }
 
 /**
- * onenand_write - [MTD Interface] write buffer to FLASH
- * @param mtd		MTD device structure
- * @param to		offset to write to
- * @param len		number of bytes to write
- * @param retlen	pointer to variable to store the number of written bytes
- * @param buf		the data to write
- *
- * Write with ECC
- */
-static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
-	size_t *retlen, const u_char *buf)
-{
-	struct mtd_oob_ops ops = {
-		.len	= len,
-		.ooblen	= 0,
-		.datbuf	= (u_char *) buf,
-		.oobbuf	= NULL,
-	};
-	int ret;
-
-	onenand_get_device(mtd, FL_WRITING);
-	ret = onenand_write_ops_nolock(mtd, to, &ops);
-	onenand_release_device(mtd);
-
-	*retlen = ops.retlen;
-	return ret;
-}
-
-/**
  * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
  * @param mtd:		MTD device structure
  * @param to:		offset to write
@@ -4038,8 +3977,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	mtd->_erase = onenand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
-	mtd->_read = onenand_read;
-	mtd->_write = onenand_write;
 	mtd->_read_oob = onenand_read_oob;
 	mtd->_write_oob = onenand_write_oob;
 	mtd->_panic_write = onenand_panic_write;
-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan  8 13:17:51 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 22:17:51 +0100
Subject: [PATCH v4 0/4] mtd: Preparation patches for the SPI NAND framework
In-Reply-To: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
Message-ID: <20180108221751.6cc5c21a@bbrezillon>

Should be [PATCH v4 *0/3*].

On Mon,  8 Jan 2018 22:15:39 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hello,
> 
> Here is a set of patches preparing the introduction of the generic
> NAND and SPI frameworks.
> 
> If you want to see the overall picture of the SPI NAND framework you can
> have a look at this branch [2].
> 
> Regards,
> 
> Boris
> 
> Change in v4:
> - add "mtd: mtdpart: Make ECC stat handling consistent" and
> - integrate "mtd: Remove duplicate checks on mtd_oob_ops parameter"
>   into this series
> - drop "mtd: Stop directly calling master ->_xxx() hooks from mtdpart
>   code"
> 
> Boris Brezillon (3):
>   mtd: mtdpart: Make ECC stat handling consistent
>   mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
>   mtd: Remove duplicate checks on mtd_oob_ops parameter
> 
>  drivers/mtd/devices/docg3.c        | 70 ------------------------------
>  drivers/mtd/mtdcore.c              | 31 +++++++++++++-
>  drivers/mtd/mtdpart.c              | 42 +++++-------------
>  drivers/mtd/nand/nand_base.c       | 87 --------------------------------------
>  drivers/mtd/onenand/onenand_base.c | 81 -----------------------------------
>  5 files changed, 40 insertions(+), 271 deletions(-)
> 



From boris.brezillon at free-electrons.com  Mon Jan  8 13:25:24 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 22:25:24 +0100
Subject: [PATCH v4 1/3] mtd: mtdpart: Make ECC stat handling consistent
In-Reply-To: <20180108211542.11891-2-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-2-boris.brezillon@free-electrons.com>
Message-ID: <20180108222524.6bf00481@bbrezillon>

On Mon,  8 Jan 2018 22:15:40 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> part_read() and part_read_oob() where counting ECC failures and
> bitflips differently. Adjust part_read_oob() to mimic what is done in
> part_read(). This is in needed to use ->_read_oob() as a fallback when
> when ->_read() is not implemented.
> 
> Note that bitflips and ECC failure accounting on MTD partitions is
> broken by design, because nothing prevents concurrent accesses to the
> underlying master MTD device between the moment we save the stats in a
> local variable and the moment master->_read[_oob]() returns. It's not
> something that can easily be fixed, so leave it like that for now.
> 
> Suggested-by: Brian Norris <computersforpeace at gmail.com>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
> Changes in v4:
> - new patch
> ---
>  drivers/mtd/mtdpart.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..283e8526713b 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  		struct mtd_oob_ops *ops)
>  {
>  	struct mtd_part *part = mtd_to_part(mtd);
> +	struct mtd_ecc_stats stats;
>  	int res;
>  
>  	if (from >= mtd->size)
> @@ -127,12 +128,12 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  	}
>  

Missing

	stats = part->parent->ecc_stats;

here.

I'll send a new version. Sorry for the inconvenience.

>  	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
> -	if (unlikely(res)) {
> -		if (mtd_is_bitflip(res))
> -			mtd->ecc_stats.corrected++;
> -		if (mtd_is_eccerr(res))
> -			mtd->ecc_stats.failed++;
> -	}
> +	if (unlikely(mtd_is_eccerr(res)))
> +		mtd->ecc_stats.failed +=
> +			part->parent->ecc_stats.failed - stats.failed;
> +	else
> +		mtd->ecc_stats.corrected +=
> +			part->parent->ecc_stats.corrected - stats.corrected;
>  	return res;
>  }
>  



From ladis at linux-mips.org  Mon Jan  8 13:48:19 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Mon, 8 Jan 2018 22:48:19 +0100
Subject: [PATCH v4 0/4] mtd: Preparation patches for the SPI NAND framework
In-Reply-To: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
Message-ID: <20180108214819.GA16174@lenoch>

On Mon, Jan 08, 2018 at 10:15:39PM +0100, Boris Brezillon wrote:
> Hello,
> 
> Here is a set of patches preparing the introduction of the generic
> NAND and SPI frameworks.

Tested on IGEPv2 Rev. B (TI OMAP3530) with Muxed OneNAND(DDP) 512MB 1.8V
16-bit (0x58) after fixing PATCH v4 1/3.

Tested-by: Ladislav Michl <ladis at linux-mips.org>

> If you want to see the overall picture of the SPI NAND framework you can
> have a look at this branch [2].
> 
> Regards,
> 
> Boris
> 
> Change in v4:
> - add "mtd: mtdpart: Make ECC stat handling consistent" and
> - integrate "mtd: Remove duplicate checks on mtd_oob_ops parameter"
>   into this series
> - drop "mtd: Stop directly calling master ->_xxx() hooks from mtdpart
>   code"
> 
> Boris Brezillon (3):
>   mtd: mtdpart: Make ECC stat handling consistent
>   mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
>   mtd: Remove duplicate checks on mtd_oob_ops parameter
> 
>  drivers/mtd/devices/docg3.c        | 70 ------------------------------
>  drivers/mtd/mtdcore.c              | 31 +++++++++++++-
>  drivers/mtd/mtdpart.c              | 42 +++++-------------
>  drivers/mtd/nand/nand_base.c       | 87 --------------------------------------
>  drivers/mtd/onenand/onenand_base.c | 81 -----------------------------------
>  5 files changed, 40 insertions(+), 271 deletions(-)
> 
> -- 
> 2.11.0


From miquel.raynal at free-electrons.com  Mon Jan  8 14:04:55 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Mon, 8 Jan 2018 23:04:55 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops
 parameter
In-Reply-To: <20180108211542.11891-4-boris.brezillon@free-electrons.com>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-4-boris.brezillon@free-electrons.com>
Message-ID: <20180108230455.10c0cb83@xps13>

Hello Boris,

On Mon,  8 Jan 2018 22:15:42 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Some of the check done in custom ->_read/write_oob() implementation
> are already done by the core (in mtd_check_oob_ops()).

Not sure this is relevant here as your series introduces changes for
the SPI NAND framework, but there are other places where these checks
are, IMHO, also redundant and could be removed. The "past end" string
when grepped in the MTD folder core returns a few more hits.

In the NAND core:
  - nand_do_read_oob()
  - nand_read_oob()
  - nand_do_write_oob()
  - nand_write_oob()
Maybe also in onenand_base.c, but I am less confident for this one:
  - onenand_bbt_read_oob()

What do you think?

Thanks,
Miqu?l

> 
> Suggested-by: Peter Pan <peterpansjtu at gmail.com>
> [Remove redundant checks done in mtdpart.c]
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
> Changes in v4:
> - integrated into the SPI NAND preparation patchset
> 
> Changes in v3:
> - Rebased on mtd/next after "mtd: Stop directly calling master
> ->_xxx() hooks from mtdpart code" had been dropped
> 
> Changes in v2:
> - Merge "mtd: Remove unneeded checks in part_{read,write}_oob()" into
>   this commit
> ---
>  drivers/mtd/devices/docg3.c        |  5 -----
>  drivers/mtd/mtdpart.c              | 23 -----------------------
>  drivers/mtd/nand/nand_base.c       | 31
> ------------------------------- drivers/mtd/onenand/onenand_base.c |
> 18 ------------------ 4 files changed, 77 deletions(-)
> 
> diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
> index 5fb5e93d1547..a85af236b44d 100644
> --- a/drivers/mtd/devices/docg3.c
> +++ b/drivers/mtd/devices/docg3.c
> @@ -904,9 +904,6 @@ static int doc_read_oob(struct mtd_info *mtd,
> loff_t from, if (ooblen % DOC_LAYOUT_OOB_SIZE)
>  		return -EINVAL;
>  
> -	if (from + len > mtd->size)
> -		return -EINVAL;
> -
>  	ops->oobretlen = 0;
>  	ops->retlen = 0;
>  	ret = 0;
> @@ -1441,8 +1438,6 @@ static int doc_write_oob(struct mtd_info *mtd,
> loff_t ofs, if (len && ooblen &&
>  	    (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta))
>  		return -EINVAL;
> -	if (ofs + len > mtd->size)
> -		return -EINVAL;
>  
>  	ops->oobretlen = 0;
>  	ops->retlen = 0;
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index 07ef168ded98..131bb1d52871 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -108,25 +108,6 @@ static int part_read_oob(struct mtd_info *mtd,
> loff_t from, struct mtd_ecc_stats stats;
>  	int res;
>  
> -	if (from >= mtd->size)
> -		return -EINVAL;
> -	if (ops->datbuf && from + ops->len > mtd->size)
> -		return -EINVAL;
> -
> -	/*
> -	 * If OOB is also requested, make sure that we do not read
> past the end
> -	 * of this partition.
> -	 */
> -	if (ops->oobbuf) {
> -		size_t len, pages;
> -
> -		len = mtd_oobavail(mtd, ops);
> -		pages = mtd_div_by_ws(mtd->size, mtd);
> -		pages -= mtd_div_by_ws(from, mtd);
> -		if (ops->ooboffs + ops->ooblen > pages * len)
> -			return -EINVAL;
> -	}
> -
>  	res = part->parent->_read_oob(part->parent, from +
> part->offset, ops); if (unlikely(mtd_is_eccerr(res)))
>  		mtd->ecc_stats.failed +=
> @@ -190,10 +171,6 @@ static int part_write_oob(struct mtd_info *mtd,
> loff_t to, {
>  	struct mtd_part *part = mtd_to_part(mtd);
>  
> -	if (to >= mtd->size)
> -		return -EINVAL;
> -	if (ops->datbuf && to + ops->len > mtd->size)
> -		return -EINVAL;
>  	return part->parent->_write_oob(part->parent, to +
> part->offset, ops); }
>  
> diff --git a/drivers/mtd/nand/nand_base.c
> b/drivers/mtd/nand/nand_base.c index 889ceadbf607..61eeac233683 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2187,21 +2187,6 @@ static int nand_do_read_oob(struct mtd_info
> *mtd, loff_t from, 
>  	len = mtd_oobavail(mtd, ops);
>  
> -	if (unlikely(ops->ooboffs >= len)) {
> -		pr_debug("%s: attempt to start read outside oob\n",
> -				__func__);
> -		return -EINVAL;
> -	}
> -
> -	/* Do not allow reads past end of device */
> -	if (unlikely(from >= mtd->size ||
> -		     ops->ooboffs + readlen > ((mtd->size >>
> chip->page_shift) -
> -					(from >> chip->page_shift))
> * len)) {
> -		pr_debug("%s: attempt to read beyond end of
> device\n",
> -				__func__);
> -		return -EINVAL;
> -	}
> -
>  	chipnr = (int)(from >> chip->chip_shift);
>  	chip->select_chip(mtd, chipnr);
>  
> @@ -2820,22 +2805,6 @@ static int nand_do_write_oob(struct mtd_info
> *mtd, loff_t to, return -EINVAL;
>  	}
>  
> -	if (unlikely(ops->ooboffs >= len)) {
> -		pr_debug("%s: attempt to start write outside oob\n",
> -				__func__);
> -		return -EINVAL;
> -	}
> -
> -	/* Do not allow write past end of device */
> -	if (unlikely(to >= mtd->size ||
> -		     ops->ooboffs + ops->ooblen >
> -			((mtd->size >> chip->page_shift) -
> -			 (to >> chip->page_shift)) * len)) {
> -		pr_debug("%s: attempt to write beyond end of
> device\n",
> -				__func__);
> -		return -EINVAL;
> -	}
> -
>  	chipnr = (int)(to >> chip->chip_shift);
>  
>  	/*
> diff --git a/drivers/mtd/onenand/onenand_base.c
> b/drivers/mtd/onenand/onenand_base.c index 050ba8a87543..979f4031f23c
> 100644 --- a/drivers/mtd/onenand/onenand_base.c
> +++ b/drivers/mtd/onenand/onenand_base.c
> @@ -1383,15 +1383,6 @@ static int onenand_read_oob_nolock(struct
> mtd_info *mtd, loff_t from, return -EINVAL;
>  	}
>  
> -	/* Do not allow reads past end of device */
> -	if (unlikely(from >= mtd->size ||
> -		     column + len > ((mtd->size >> this->page_shift)
> -
> -				     (from >> this->page_shift)) *
> oobsize)) {
> -		printk(KERN_ERR "%s: Attempted to read beyond end of
> device\n",
> -			__func__);
> -		return -EINVAL;
> -	}
> -
>  	stats = mtd->ecc_stats;
>  
>  	readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ :
> ONENAND_CMD_READOOB; @@ -2024,15 +2015,6 @@ static int
> onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, return
> -EINVAL; }
>  
> -	/* Do not allow reads past end of device */
> -	if (unlikely(to >= mtd->size ||
> -		     column + len > ((mtd->size >> this->page_shift)
> -
> -				     (to >> this->page_shift)) *
> oobsize)) {
> -		printk(KERN_ERR "%s: Attempted to write past end of
> device\n",
> -		       __func__);
> -		return -EINVAL;
> -	}
> -
>  	oobbuf = this->oob_buf;
>  
>  	oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG :
> ONENAND_CMD_PROGOOB;



-- 
Miquel Raynal, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From boris.brezillon at free-electrons.com  Mon Jan  8 14:07:00 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 23:07:00 +0100
Subject: [PATCH v6 00/15] A SPI NAND framework under generic NAND framework
In-Reply-To: <CAAyFORKfQ-82=HhnjQcaU3n8VkmqQ9VHCXoMh=47BSzMc8en3Q@mail.gmail.com>
References: <20170529225931.226da943@bbrezillon>
 <20171205140313.40f3f17d@bbrezillon>
 <256b4ab6-c104-4580-87cd-527178bde460@exceet.de>
 <20171213222710.32d12514@bbrezillon>
 <CAAyFORJcT1abbo21iA4cetLKmF0zE4akFGFryxPpwPO+730LDQ@mail.gmail.com>
 <20171214085036.436b4fcf@bbrezillon>
 <CAAyFOR+=JwTRTm2MXVdMy7KRPsnV8LV4t71kHUh_s=+QOsVurA@mail.gmail.com>
 <23d17416-e555-4b92-cc47-f644fbe676c6@exceet.de>
 <20171214163848.41f6d277@bbrezillon>
 <CAAyFORKeFq+=tF9AK+8hp6GYYiyp3DKcw8+LWrC3RWS2zLNU_w@mail.gmail.com>
 <CAAyFORJEuEaHDXgk+m0ax5RoZ-3cRJs6uFXw7syR4vHE1veEwQ@mail.gmail.com>
 <a06312e4-a7e6-8b7b-9eb5-8320302dcc55@exceet.de>
 <CAAyFORL6mUFXFRvku6sm=Pj2=+Bf4wSV7EoBM_7+wRdPrF-ufw@mail.gmail.com>
 <CAAyFOR+m7GvXU66XKphu+cETP9SQTJ6GuZQEZQA600MX1R6cYw@mail.gmail.com>
 <20171222145147.3697fb02@bbrezillon>
 <CAAyFORK9v-V1WrJzTnKk0sAt7_f_st_PHc6nJ6dz0zTL-Jih5A@mail.gmail.com>
 <20180103174614.6d760b3d@bbrezillon>
 <CAAyFORKfQ-82=HhnjQcaU3n8VkmqQ9VHCXoMh=47BSzMc8en3Q@mail.gmail.com>
Message-ID: <20180108230700.15e32d03@bbrezillon>

On Thu, 4 Jan 2018 10:01:57 +0800
Peter Pan <peterpansjtu at gmail.com> wrote:

> Boris,
> 
> On Thu, Jan 4, 2018 at 12:46 AM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Tue, 2 Jan 2018 10:51:25 +0800
> > Peter Pan <peterpansjtu at gmail.com> wrote:
> >  
> >> Hi Boris,
> >>
> >>
> >> On Fri, Dec 22, 2017 at 9:51 PM, Boris Brezillon
> >> <boris.brezillon at free-electrons.com> wrote:  
> >> > On Fri, 22 Dec 2017 14:37:06 +0800
> >> > Peter Pan <peterpansjtu at gmail.com> wrote:
> >> >  
> >> >> Hi Boris and Frieder
> >> >>
> >> >> On Fri, Dec 22, 2017 at 8:49 AM, Peter Pan <peterpansjtu at gmail.com> wrote:  
> >> >> > Hi Frieder,
> >> >> >
> >> >> > On Thu, Dec 21, 2017 at 7:48 PM, Frieder Schrempf
> >> >> > <frieder.schrempf at exceet.de> wrote:  
> >> >> >> Hello Boris,
> >> >> >>  
> >> >> >>>>>> So shouldn't there be an spinand_die_select_op in the SPI NAND core
> >> >> >>>>>> that
> >> >> >>>>>> is executed when necessary and skipped if there's only one die.  
> >> >> >>>>>
> >> >> >>>>>
> >> >> >>>>> Sure, I was arguing against a ->select_chip() at the generic NAND
> >> >> >>>>> level. That's something you can add in the SPI NAND framework.  
> >> >> >>
> >> >> >>
> >> >> >> I added an op to send the die selection command and call it, where I think
> >> >> >> it is needed: [1]  
> >> >> >
> >> >> > I think we should add die_select_op in vendor's file and call a hook in core.c
> >> >> > since the die select command implementation is different by vendors.
> >> >> >
> >> >> > Thanks
> >> >> > Peter Pan
> >> >> >
> >> >> >  
> >> >> >>
> >> >> >> Accessing both dies on the Winbond SPI NAND works fine like this.
> >> >> >>
> >> >> >> While running tests I came across some problems:
> >> >> >>
> >> >> >> * On accessing the BBT in RAM via nanddev_bbt_[set/get]_block_status, the
> >> >> >> calculation of position and offset seems to be wrong.
> >> >> >> My fix is here: [2]
> >> >> >>
> >> >> >> * On calculating the row address for read/program/erase via
> >> >> >> nanddev_pos_to_row, it seems like the eraseblock_addr_shift is wrong.
> >> >> >>
> >> >> >> * Also, I'm not sure if the LUN should be taken into account when
> >> >> >> calculating the row address. At least when you select the LUN by issuing a
> >> >> >> separate command, the row address sent to the chip should only contain the
> >> >> >> page address.
> >> >> >> But I'm not sure if that's the case in general, or if some code is needed to
> >> >> >> differentiate.
> >> >> >>
> >> >> >> See my changes of nanddev_pos_to_row here: [3]
> >> >> >>
> >> >> >> * I run into a mutex deadlock, when spinand_write_page fails (e.g. because
> >> >> >> of a bad block) as the lock is not released in such cases. See my fix here:
> >> >> >> [4]
> >> >> >>
> >> >> >> With these fixes applied and as far as I can tell everything seems to work
> >> >> >> fine. I'll do some tests with UBI next and look into the ECC topic.  
> >> >>
> >> >> UBI attach failed since missing mtd->writebufsize assignment in nanddev_init()
> >> >> After fixing it and with Frieder's fixing, UBIFS can be mounted successfully on
> >> >> Zedboard with generic spi controller and Micron SPI NAND 2Gb device.
> >> >>
> >> >> Also, the code now can pass mtd read and page test. 1 error found in oob test
> >> >> since we don't have "past end of partition" check in part_write_oob() which I
> >> >> mentioned in earlier mail. Since we don't support ECC right now, I didn't try
> >> >> nandbiterror test.
> >> >>  
> >> >
> >> > Peter, Frider, I just pushed a new version to my nand/spi-nand branch
> >> > [1] fixing the authorship, adding/fixing/removing comments where needed.
> >> >
> >> > Can you please have a look at those changes (everything I changed
> >> > should appear as !fixup commits) and let me know if I did something
> >> > wrong.  
> >>
> >> You forgot to initialize mtd->writebufsize and mtd->oobavail.
> >> For mtd->writebufsize I think we can do it in nanddev_init() like below:
> >>
> >> --- a/drivers/mtd/nand/core.c
> >> +++ b/drivers/mtd/nand/core.c
> >> @@ -196,7 +196,9 @@ int nanddev_init(struct nand_device *nand, const
> >> struct nand_ops *ops,
> >>         mtd->flags = MTD_CAP_NANDFLASH;
> >>         mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock;
> >>         mtd->writesize = memorg->pagesize;
> >> +       mtd->writebufsize = mtd->writesize;
> >>         mtd->oobsize = memorg->oobsize;
> >>         mtd->size = nanddev_size(nand);
> >>         mtd->owner = owner;  
> >
> > I fixed it already, see [1]. Note that I haven't squashed fixup commits
> > yet.  
> 
> Noted.
> 
> >  
> >>
> >> For mtd->oobavail, I think we need to call some hooks in spinand_init(),
> >> and implement on-die ECC layout in vendor's file and HW ECC layout in
> >> controller's file.
> >>
> >> What's your opinion?  
> >
> > Hm, I'm not so sure. spinand_init() should be called just before
> > registering the MTD device, so by that time everything should have been
> > setup correctly by the upper layer. This being said, I'd like to keep a
> > clear separation between the MTD and NAND layers, and this means
> > preventing any NAND sub-layer from directly manipulating the MTD device
> > and its fields.
> >
> > Really, I don't know yet how I want to abstract ECC stuff, so let's
> > keep it simple for now and expose the whole OOB area (I'll fix the core
> > to do that if you're okay).  
> 
> OK.
> 
> >  
> >>
> >> With the two thing fixed, we can pass UBIFS mount and mtd test.  
> >
> > Do you still have the problem you reported earlier (OOB test)?  
> 
> I forgot to reply that mail :(. Actually there is no problem because
> mtd_write_oob() already has mtd_check_oob_ops() to check it.
> That failure in OOB test occurs because mtd->oobavail is zero.

I reconsidered what I said earlier, and I think it's safer to set
->oobavail to 0 are for now, otherwise we might end up with setups that
start using some of it and we'll break things as soon as we'll add
support for ECC.


From boris.brezillon at free-electrons.com  Mon Jan  8 14:30:10 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 8 Jan 2018 23:30:10 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops
 parameter
In-Reply-To: <20180108230455.10c0cb83@xps13>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-4-boris.brezillon@free-electrons.com>
 <20180108230455.10c0cb83@xps13>
Message-ID: <20180108233010.5d7e7c3f@bbrezillon>

On Mon, 8 Jan 2018 23:04:55 +0100
Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:

> Hello Boris,
> 
> On Mon,  8 Jan 2018 22:15:42 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > Some of the check done in custom ->_read/write_oob() implementation
> > are already done by the core (in mtd_check_oob_ops()).  
> 
> Not sure this is relevant here as your series introduces changes for
> the SPI NAND framework, but there are other places where these checks
> are, IMHO, also redundant and could be removed. The "past end" string
> when grepped in the MTD folder core returns a few more hits.
> 
> In the NAND core:
>   - nand_do_read_oob()
>   - nand_read_oob()
>   - nand_do_write_oob()
>   - nand_write_oob()

That's true for nand_read/write_oob(). The one in nand_do_write_oob()
is still needed because mtd_check_oob_ops() allows OOB writes crossing a
page boundary. Finally, I don't see any boundary checks in
nand_do_read_oob().

> Maybe also in onenand_base.c, but I am less confident for this one:
>   - onenand_bbt_read_oob()

Unfortunately no, this function is directly called from onenand_bbt.c,
which means the MTD layer layer is completely bypassed. I also found
boundary checks in onenand_mlc_read_ops_nolock(), but again, this
function is called from do_otp_read() which is not going through
mtd_check_oob_ops().

> 
> What do you think?

I'll remove the extra checks in nand_read/write_oob(). For the other
ones, one solution would be to expose mtd_check_oob_ops(), but I'll keep
that for later.


From ladis at linux-mips.org  Mon Jan  8 15:48:37 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 00:48:37 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
Message-ID: <20180108234837.GA15913@lenoch>

Samsung E-die SLC NAND manufactured using 21nm process supports only
1 partial program cycle, so disable subpage writes for it.
Manufacturing process is stored in lowest two bits of 5th ID byte.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
---
 Note: Patch generated and tested against next-20180108 on at91sam9g20
       board with K9F1G08U0E.

 drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
index f6b0a63a068c..9400b4a84243 100644
--- a/drivers/mtd/nand/nand_samsung.c
+++ b/drivers/mtd/nand/nand_samsung.c
@@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 	} else {
 		nand_decode_ext_id(chip);
 
-		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
-		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
-			chip->ecc_step_ds = 512;
-			chip->ecc_strength_ds = 1;
+		if (nand_is_slc(chip)) {
+			/* K9F4G08U0D-S[I|C]B0(T00) */
+			if (chip->id.data[1] == 0xDC) {
+				chip->ecc_step_ds = 512;
+				chip->ecc_strength_ds = 1;
+			}
+
+			/* 21nm chips do not support partial page write */
+			if (chip->id.len > 4 &&
+			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
+				chip->options |= NAND_NO_SUBPAGE_WRITE;
 		}
 	}
 }
-- 
2.15.1



From miquel.raynal at free-electrons.com  Mon Jan  8 23:19:53 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Tue, 9 Jan 2018 08:19:53 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops
 parameter
In-Reply-To: <20180108233010.5d7e7c3f@bbrezillon>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-4-boris.brezillon@free-electrons.com>
 <20180108230455.10c0cb83@xps13>
 <20180108233010.5d7e7c3f@bbrezillon>
Message-ID: <20180109081953.01b204ea@xps13>

Hello Boris,

On Mon, 8 Jan 2018 23:30:10 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Mon, 8 Jan 2018 23:04:55 +0100
> Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> 
> > Hello Boris,
> > 
> > On Mon,  8 Jan 2018 22:15:42 +0100
> > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> >   
> > > Some of the check done in custom ->_read/write_oob()
> > > implementation are already done by the core (in
> > > mtd_check_oob_ops()).    
> > 
> > Not sure this is relevant here as your series introduces changes for
> > the SPI NAND framework, but there are other places where these
> > checks are, IMHO, also redundant and could be removed. The "past
> > end" string when grepped in the MTD folder core returns a few more
> > hits.
> > 
> > In the NAND core:
> >   - nand_do_read_oob()
> >   - nand_read_oob()
> >   - nand_do_write_oob()
> >   - nand_write_oob()  
> 
> That's true for nand_read/write_oob(). The one in nand_do_write_oob()
> is still needed because mtd_check_oob_ops() allows OOB writes
> crossing a page boundary. Finally, I don't see any boundary checks in
> nand_do_read_oob().

I forgot that crossing page boundaries was not a use case of
mtd_check_oob_ops(), thanks for pointing it. However in
nand_do_read/write_oob(), the comment and the code really state the
checked boundary is the end of the device. So are you sure these two
checks are needed?

[1]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2226
[2]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2886

> 
> > Maybe also in onenand_base.c, but I am less confident for this one:
> >   - onenand_bbt_read_oob()  
> 
> Unfortunately no, this function is directly called from onenand_bbt.c,
> which means the MTD layer layer is completely bypassed. I also found
> boundary checks in onenand_mlc_read_ops_nolock(), but again, this
> function is called from do_otp_read() which is not going through
> mtd_check_oob_ops().
> 
> > 
> > What do you think?  
> 
> I'll remove the extra checks in nand_read/write_oob(). For the other
> ones, one solution would be to expose mtd_check_oob_ops(), but I'll
> keep that for later.

Ok.

Thanks,
Miqu?l


From robert.jarzmik at free.fr  Mon Jan  8 23:57:59 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 09 Jan 2018 08:57:59 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180103215206.5d85b41b@bbrezillon> (Boris Brezillon's message
 of "Wed, 3 Jan 2018 21:52:06 +0100")
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon> <877etkecig.fsf@belgarion.home>
 <20171218092535.2ca1fe13@xps13> <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon> <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon> <20171222233730.68d9cb9d@xps13>
 <87k1xdblxf.fsf@belgarion.home> <20171223155709.2ba16e95@xps13>
 <87fu81bc45.fsf@belgarion.home> <20180102120326.7a2cf1d1@xps13>
 <87d12scbiy.fsf@belgarion.home> <20180103084037.422b239a@xps13>
 <878tded89m.fsf@belgarion.home> <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
Message-ID: <87zi5nbh14.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

Ok I recovered my NAND.

For the next try, I'd like you to provide another "temporary patch" to disable
BBT actual writing, just to be sure. Once the driver is working properly, I'll
make another try without the temporary patch.

Tell me when a branch I can pull is ready.

Cheers.

-- 
Robert


From boris.brezillon at free-electrons.com  Tue Jan  9 00:11:21 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 09:11:21 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops
 parameter
In-Reply-To: <20180109081953.01b204ea@xps13>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-4-boris.brezillon@free-electrons.com>
 <20180108230455.10c0cb83@xps13>
 <20180108233010.5d7e7c3f@bbrezillon>
 <20180109081953.01b204ea@xps13>
Message-ID: <20180109091121.118304a7@bbrezillon>

On Tue, 9 Jan 2018 08:19:53 +0100
Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:

> Hello Boris,
> 
> On Mon, 8 Jan 2018 23:30:10 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > On Mon, 8 Jan 2018 23:04:55 +0100
> > Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> >   
> > > Hello Boris,
> > > 
> > > On Mon,  8 Jan 2018 22:15:42 +0100
> > > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> > >     
> > > > Some of the check done in custom ->_read/write_oob()
> > > > implementation are already done by the core (in
> > > > mtd_check_oob_ops()).      
> > > 
> > > Not sure this is relevant here as your series introduces changes for
> > > the SPI NAND framework, but there are other places where these
> > > checks are, IMHO, also redundant and could be removed. The "past
> > > end" string when grepped in the MTD folder core returns a few more
> > > hits.
> > > 
> > > In the NAND core:
> > >   - nand_do_read_oob()
> > >   - nand_read_oob()
> > >   - nand_do_write_oob()
> > >   - nand_write_oob()    
> > 
> > That's true for nand_read/write_oob(). The one in nand_do_write_oob()
> > is still needed because mtd_check_oob_ops() allows OOB writes
> > crossing a page boundary. Finally, I don't see any boundary checks in
> > nand_do_read_oob().  
> 
> I forgot that crossing page boundaries was not a use case of
> mtd_check_oob_ops(), thanks for pointing it. However in
> nand_do_read/write_oob(), the comment and the code really state the
> checked boundary is the end of the device. So are you sure these two
> checks are needed?
> 
> [1]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2226
> [2]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2886

You mean, the lines I remove in this patch? :P

> 
> >   
> > > Maybe also in onenand_base.c, but I am less confident for this one:
> > >   - onenand_bbt_read_oob()    
> > 
> > Unfortunately no, this function is directly called from onenand_bbt.c,
> > which means the MTD layer layer is completely bypassed. I also found
> > boundary checks in onenand_mlc_read_ops_nolock(), but again, this
> > function is called from do_otp_read() which is not going through
> > mtd_check_oob_ops().
> >   
> > > 
> > > What do you think?    
> > 
> > I'll remove the extra checks in nand_read/write_oob(). For the other
> > ones, one solution would be to expose mtd_check_oob_ops(), but I'll
> > keep that for later.  
> 
> Ok.
> 
> Thanks,
> Miqu?l



From miquel.raynal at free-electrons.com  Tue Jan  9 00:19:08 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Tue, 9 Jan 2018 09:19:08 +0100
Subject: [PATCH v4 3/3] mtd: Remove duplicate checks on mtd_oob_ops
 parameter
In-Reply-To: <20180109091121.118304a7@bbrezillon>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-4-boris.brezillon@free-electrons.com>
 <20180108230455.10c0cb83@xps13>
 <20180108233010.5d7e7c3f@bbrezillon>
 <20180109081953.01b204ea@xps13>
 <20180109091121.118304a7@bbrezillon>
Message-ID: <20180109091908.0fc07914@xps13>

On Tue, 9 Jan 2018 09:11:21 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Tue, 9 Jan 2018 08:19:53 +0100
> Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> 
> > Hello Boris,
> > 
> > On Mon, 8 Jan 2018 23:30:10 +0100
> > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> >   
> > > On Mon, 8 Jan 2018 23:04:55 +0100
> > > Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> > >     
> > > > Hello Boris,
> > > > 
> > > > On Mon,  8 Jan 2018 22:15:42 +0100
> > > > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> > > >       
> > > > > Some of the check done in custom ->_read/write_oob()
> > > > > implementation are already done by the core (in
> > > > > mtd_check_oob_ops()).        
> > > > 
> > > > Not sure this is relevant here as your series introduces
> > > > changes for the SPI NAND framework, but there are other places
> > > > where these checks are, IMHO, also redundant and could be
> > > > removed. The "past end" string when grepped in the MTD folder
> > > > core returns a few more hits.
> > > > 
> > > > In the NAND core:
> > > >   - nand_do_read_oob()
> > > >   - nand_read_oob()
> > > >   - nand_do_write_oob()
> > > >   - nand_write_oob()      
> > > 
> > > That's true for nand_read/write_oob(). The one in
> > > nand_do_write_oob() is still needed because mtd_check_oob_ops()
> > > allows OOB writes crossing a page boundary. Finally, I don't see
> > > any boundary checks in nand_do_read_oob().    
> > 
> > I forgot that crossing page boundaries was not a use case of
> > mtd_check_oob_ops(), thanks for pointing it. However in
> > nand_do_read/write_oob(), the comment and the code really state the
> > checked boundary is the end of the device. So are you sure these two
> > checks are needed?
> > 
> > [1]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2226
> > [2]http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nand/nand_base.c#L2886  
> 
> You mean, the lines I remove in this patch? :P

Oops, sorry for the noise then!

Thanks,
Miqu?l


From boris.brezillon at free-electrons.com  Tue Jan  9 00:46:21 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 09:46:21 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180108234837.GA15913@lenoch>
References: <20180108234837.GA15913@lenoch>
Message-ID: <20180109094621.23a5e368@bbrezillon>

On Tue, 9 Jan 2018 00:48:37 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> Samsung E-die SLC NAND manufactured using 21nm process supports only

I would add the chip name here (K9F1G08U0E).

> 1 partial program cycle, so disable subpage writes for it.

Which means it does not support partial page programming, so how about
rewording it like that:

Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
does not support partial page programming, so disable subpage writes
for it.

> Manufacturing process is stored in lowest two bits of 5th ID byte.
> 
> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> ---
>  Note: Patch generated and tested against next-20180108 on at91sam9g20
>        board with K9F1G08U0E.

Just out of curiosity, what are the symptoms when you don't have this
flag set?

> 
>  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> index f6b0a63a068c..9400b4a84243 100644
> --- a/drivers/mtd/nand/nand_samsung.c
> +++ b/drivers/mtd/nand/nand_samsung.c
> @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
>  	} else {
>  		nand_decode_ext_id(chip);
>  
> -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> -			chip->ecc_step_ds = 512;
> -			chip->ecc_strength_ds = 1;
> +		if (nand_is_slc(chip)) {
> +			/* K9F4G08U0D-S[I|C]B0(T00) */
> +			if (chip->id.data[1] == 0xDC) {
> +				chip->ecc_step_ds = 512;
> +				chip->ecc_strength_ds = 1;
> +			}
> +
> +			/* 21nm chips do not support partial page write */
> +			if (chip->id.len > 4 &&
> +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)

NAND vendors tend to change their ID decoding scheme a lot, so maybe we
should be more restrictive here: replace "chip->id.len > 4" by
"chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.

> +				chip->options |= NAND_NO_SUBPAGE_WRITE;
>  		}
>  	}
>  }



From boris.brezillon at free-electrons.com  Tue Jan  9 00:50:33 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue,  9 Jan 2018 09:50:33 +0100
Subject: [PATCH v5 1/3] mtd: mtdpart: Make ECC stat handling consistent
Message-ID: <20180109085035.12438-1-boris.brezillon@free-electrons.com>

part_read() and part_read_oob() where counting ECC failures and
bitflips differently. Adjust part_read_oob() to mimic what is done in
part_read(). This is in needed to use ->_read_oob() as a fallback when
when ->_read() is not implemented.

Note that bitflips and ECC failure accounting on MTD partitions is
broken by design, because nothing prevents concurrent accesses to the
underlying master MTD device between the moment we save the stats in a
local variable and the moment master->_read[_oob]() returns. It's not
something that can easily be fixed, so leave it like that for now.

Suggested-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Tested-by: Ladislav Michl <ladis at linux-mips.org>
---
Changes in v5:
- save master's ECC stats before calling ->_read_oob()

Changes in v4:
- new patch
---
 drivers/mtd/mtdpart.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index be088bccd593..79bf1f61c7a0 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 		struct mtd_oob_ops *ops)
 {
 	struct mtd_part *part = mtd_to_part(mtd);
+	struct mtd_ecc_stats stats;
 	int res;
 
 	if (from >= mtd->size)
@@ -126,13 +127,14 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 			return -EINVAL;
 	}
 
+	stats = part->parent->ecc_stats;
 	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
-	if (unlikely(res)) {
-		if (mtd_is_bitflip(res))
-			mtd->ecc_stats.corrected++;
-		if (mtd_is_eccerr(res))
-			mtd->ecc_stats.failed++;
-	}
+	if (unlikely(mtd_is_eccerr(res)))
+		mtd->ecc_stats.failed +=
+			part->parent->ecc_stats.failed - stats.failed;
+	else
+		mtd->ecc_stats.corrected +=
+			part->parent->ecc_stats.corrected - stats.corrected;
 	return res;
 }
 
-- 
2.11.0



From boris.brezillon at free-electrons.com  Tue Jan  9 00:50:35 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue,  9 Jan 2018 09:50:35 +0100
Subject: [PATCH v5 3/3] mtd: Remove duplicate checks on mtd_oob_ops parameter
In-Reply-To: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
References: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
Message-ID: <20180109085035.12438-3-boris.brezillon@free-electrons.com>

Some of the check done in custom ->_read/write_oob() implementation are
already done by the core (in mtd_check_oob_ops()).

Suggested-by: Peter Pan <peterpansjtu at gmail.com>
[Remove redundant checks done in mtdpart.c]
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Tested-by: Ladislav Michl <ladis at linux-mips.org>
---
Changes in v5:
- Remove more checks in nand_base.c

Changes in v4:
- Integrated into the SPI NAND preparation patchset

Changes in v3:
- Rebased on mtd/next after "mtd: Stop directly calling master ->_xxx()
  hooks from mtdpart code" had been dropped

Changes in v2:
- Merge "mtd: Remove unneeded checks in part_{read,write}_oob()" into
  this commit
---
 drivers/mtd/devices/docg3.c        |  5 -----
 drivers/mtd/mtdpart.c              | 23 -------------------
 drivers/mtd/nand/nand_base.c       | 45 --------------------------------------
 drivers/mtd/onenand/onenand_base.c | 18 ---------------
 4 files changed, 91 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 5fb5e93d1547..a85af236b44d 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -904,9 +904,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	if (ooblen % DOC_LAYOUT_OOB_SIZE)
 		return -EINVAL;
 
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	ops->oobretlen = 0;
 	ops->retlen = 0;
 	ret = 0;
@@ -1441,8 +1438,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 	if (len && ooblen &&
 	    (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta))
 		return -EINVAL;
-	if (ofs + len > mtd->size)
-		return -EINVAL;
 
 	ops->oobretlen = 0;
 	ops->retlen = 0;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index dd28cb0de2c8..76cd21d1171b 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -108,25 +108,6 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 	struct mtd_ecc_stats stats;
 	int res;
 
-	if (from >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && from + ops->len > mtd->size)
-		return -EINVAL;
-
-	/*
-	 * If OOB is also requested, make sure that we do not read past the end
-	 * of this partition.
-	 */
-	if (ops->oobbuf) {
-		size_t len, pages;
-
-		len = mtd_oobavail(mtd, ops);
-		pages = mtd_div_by_ws(mtd->size, mtd);
-		pages -= mtd_div_by_ws(from, mtd);
-		if (ops->ooboffs + ops->ooblen > pages * len)
-			return -EINVAL;
-	}
-
 	stats = part->parent->ecc_stats;
 	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
 	if (unlikely(mtd_is_eccerr(res)))
@@ -191,10 +172,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
 	struct mtd_part *part = mtd_to_part(mtd);
 
-	if (to >= mtd->size)
-		return -EINVAL;
-	if (ops->datbuf && to + ops->len > mtd->size)
-		return -EINVAL;
 	return part->parent->_write_oob(part->parent, to + part->offset, ops);
 }
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 889ceadbf607..e7ec55b1d368 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2187,21 +2187,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 
 	len = mtd_oobavail(mtd, ops);
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start read outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
-					(from >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to read beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(from >> chip->chip_shift);
 	chip->select_chip(mtd, chipnr);
 
@@ -2272,13 +2257,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 
 	ops->retlen = 0;
 
-	/* Do not allow reads past end of device */
-	if (ops->datbuf && (from + ops->len) > mtd->size) {
-		pr_debug("%s: attempt to read beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	if (ops->mode != MTD_OPS_PLACE_OOB &&
 	    ops->mode != MTD_OPS_AUTO_OOB &&
 	    ops->mode != MTD_OPS_RAW)
@@ -2820,22 +2798,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	if (unlikely(ops->ooboffs >= len)) {
-		pr_debug("%s: attempt to start write outside oob\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Do not allow write past end of device */
-	if (unlikely(to >= mtd->size ||
-		     ops->ooboffs + ops->ooblen >
-			((mtd->size >> chip->page_shift) -
-			 (to >> chip->page_shift)) * len)) {
-		pr_debug("%s: attempt to write beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	chipnr = (int)(to >> chip->chip_shift);
 
 	/*
@@ -2891,13 +2853,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 
 	ops->retlen = 0;
 
-	/* Do not allow writes past end of device */
-	if (ops->datbuf && (to + ops->len) > mtd->size) {
-		pr_debug("%s: attempt to write beyond end of device\n",
-				__func__);
-		return -EINVAL;
-	}
-
 	nand_get_device(mtd, FL_WRITING);
 
 	switch (ops->mode) {
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 050ba8a87543..979f4031f23c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1383,15 +1383,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(from >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (from >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to read beyond end of device\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	stats = mtd->ecc_stats;
 
 	readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
@@ -2024,15 +2015,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 		return -EINVAL;
 	}
 
-	/* Do not allow reads past end of device */
-	if (unlikely(to >= mtd->size ||
-		     column + len > ((mtd->size >> this->page_shift) -
-				     (to >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "%s: Attempted to write past end of device\n",
-		       __func__);
-		return -EINVAL;
-	}
-
 	oobbuf = this->oob_buf;
 
 	oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
-- 
2.11.0



From boris.brezillon at free-electrons.com  Tue Jan  9 00:50:34 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue,  9 Jan 2018 09:50:34 +0100
Subject: [PATCH v5 2/3] mtd: Fallback to ->_read/write_oob() when
 ->_read/write() is missing
In-Reply-To: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
References: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
Message-ID: <20180109085035.12438-2-boris.brezillon@free-electrons.com>

Some MTD sublayers/drivers are implementing ->_read/write_oob() and
provide dummy wrappers for their ->_read/write() implementations.
Let the core handle this case instead of duplicating the logic.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>
Acked-by: Brian Norris <computersforpeace at gmail.com>
Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>
Tested-by: Ladislav Michl <ladis at linux-mips.org>
---
Changes in v5:
- none

Changes in v4:
- Update mtdpart.c to assign slave->_read/_write() only if the master
  has ->_read/_write != NULL

Changes in v3:
- none

Changes in v2:
- none
---
 drivers/mtd/devices/docg3.c        | 65 --------------------------------------
 drivers/mtd/mtdcore.c              | 31 ++++++++++++++++--
 drivers/mtd/mtdpart.c              |  6 ++--
 drivers/mtd/nand/nand_base.c       | 56 --------------------------------
 drivers/mtd/onenand/onenand_base.c | 63 ------------------------------------
 5 files changed, 33 insertions(+), 188 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 0806f72102c0..5fb5e93d1547 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -990,36 +990,6 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	goto out;
 }
 
-/**
- * doc_read - Read bytes from flash
- * @mtd: the device
- * @from: the offset from first block and first page, in bytes, aligned on page
- *        size
- * @len: the number of bytes to read (must be a multiple of 4)
- * @retlen: the number of bytes actually read
- * @buf: the filled in buffer
- *
- * Reads flash memory pages. This function does not read the OOB chunk, but only
- * the page data.
- *
- * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred
- */
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-	     size_t *retlen, u_char *buf)
-{
-	struct mtd_oob_ops ops;
-	size_t ret;
-
-	memset(&ops, 0, sizeof(ops));
-	ops.datbuf = buf;
-	ops.len = len;
-	ops.mode = MTD_OPS_AUTO_OOB;
-
-	ret = doc_read_oob(mtd, from, &ops);
-	*retlen = ops.retlen;
-	return ret;
-}
-
 static int doc_reload_bbt(struct docg3 *docg3)
 {
 	int block = DOC_LAYOUT_BLOCK_BBT;
@@ -1513,39 +1483,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 	return ret;
 }
 
-/**
- * doc_write - Write a buffer to the chip
- * @mtd: the device
- * @to: the offset from first block and first page, in bytes, aligned on page
- *      size
- * @len: the number of bytes to write (must be a full page size, ie. 512)
- * @retlen: the number of bytes actually written (0 or 512)
- * @buf: the buffer to get bytes from
- *
- * Writes data to the chip.
- *
- * Returns 0 if write successful, -EIO if write error
- */
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-		     size_t *retlen, const u_char *buf)
-{
-	struct docg3 *docg3 = mtd->priv;
-	int ret;
-	struct mtd_oob_ops ops;
-
-	doc_dbg("doc_write(to=%lld, len=%zu)\n", to, len);
-	ops.datbuf = (char *)buf;
-	ops.len = len;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ops.oobbuf = NULL;
-	ops.ooblen = 0;
-	ops.ooboffs = 0;
-
-	ret = doc_write_oob(mtd, to, &ops);
-	*retlen = ops.retlen;
-	return ret;
-}
-
 static struct docg3 *sysfs_dev2docg3(struct device *dev,
 				     struct device_attribute *attr)
 {
@@ -1866,8 +1803,6 @@ static int __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
 	mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
 	mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
 	mtd->_erase = doc_erase;
-	mtd->_read = doc_read;
-	mtd->_write = doc_write;
 	mtd->_read_oob = doc_read_oob;
 	mtd->_write_oob = doc_write_oob;
 	mtd->_block_isbad = doc_block_isbad;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 642c35dde686..d7ab091b36b2 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1058,7 +1058,20 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
 	 * representing the maximum number of bitflips that were corrected on
 	 * any one ecc region (if applicable; zero otherwise).
 	 */
-	ret_code = mtd->_read(mtd, from, len, retlen, buf);
+	if (mtd->_read) {
+		ret_code = mtd->_read(mtd, from, len, retlen, buf);
+	} else if (mtd->_read_oob) {
+		struct mtd_oob_ops ops = {
+			.len = len,
+			.datbuf = buf,
+		};
+
+		ret_code = mtd->_read_oob(mtd, from, &ops);
+		*retlen = ops.retlen;
+	} else {
+		return -ENOTSUPP;
+	}
+
 	if (unlikely(ret_code < 0))
 		return ret_code;
 	if (mtd->ecc_strength == 0)
@@ -1073,11 +1086,25 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
 	*retlen = 0;
 	if (to < 0 || to >= mtd->size || len > mtd->size - to)
 		return -EINVAL;
-	if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
+	if ((!mtd->_write && !mtd->_write_oob) ||
+	    !(mtd->flags & MTD_WRITEABLE))
 		return -EROFS;
 	if (!len)
 		return 0;
 	ledtrig_mtd_activity();
+
+	if (!mtd->_write) {
+		struct mtd_oob_ops ops = {
+			.len = len,
+			.datbuf = (u8 *)buf,
+		};
+		int ret;
+
+		ret = mtd->_write_oob(mtd, to, &ops);
+		*retlen = ops.retlen;
+		return ret;
+	}
+
 	return mtd->_write(mtd, to, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_write);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 79bf1f61c7a0..dd28cb0de2c8 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -437,8 +437,10 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 				parent->dev.parent;
 	slave->mtd.dev.of_node = part->of_node;
 
-	slave->mtd._read = part_read;
-	slave->mtd._write = part_write;
+	if (parent->_read)
+		slave->mtd._read = part_read;
+	if (parent->_write)
+		slave->mtd._write = part_write;
 
 	if (parent->_panic_write)
 		slave->mtd._panic_write = part_panic_write;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6135d007a068..889ceadbf607 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2027,33 +2027,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 }
 
 /**
- * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
- * @mtd: MTD device structure
- * @from: offset to read from
- * @len: number of bytes to read
- * @retlen: pointer to variable to store the number of read bytes
- * @buf: the databuffer to put data
- *
- * Get hold of the chip and call nand_do_read.
- */
-static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, uint8_t *buf)
-{
-	struct mtd_oob_ops ops;
-	int ret;
-
-	nand_get_device(mtd, FL_READING);
-	memset(&ops, 0, sizeof(ops));
-	ops.len = len;
-	ops.datbuf = buf;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ret = nand_do_read_ops(mtd, from, &ops);
-	*retlen = ops.retlen;
-	nand_release_device(mtd);
-	return ret;
-}
-
-/**
  * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
  * @mtd: mtd info structure
  * @chip: nand chip info structure
@@ -2822,33 +2795,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 }
 
 /**
- * nand_write - [MTD Interface] NAND write with ECC
- * @mtd: MTD device structure
- * @to: offset to write to
- * @len: number of bytes to write
- * @retlen: pointer to variable to store the number of written bytes
- * @buf: the data to write
- *
- * NAND write with ECC.
- */
-static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
-			  size_t *retlen, const uint8_t *buf)
-{
-	struct mtd_oob_ops ops;
-	int ret;
-
-	nand_get_device(mtd, FL_WRITING);
-	memset(&ops, 0, sizeof(ops));
-	ops.len = len;
-	ops.datbuf = (uint8_t *)buf;
-	ops.mode = MTD_OPS_PLACE_OOB;
-	ret = nand_do_write_ops(mtd, to, &ops);
-	*retlen = ops.retlen;
-	nand_release_device(mtd);
-	return ret;
-}
-
-/**
  * nand_do_write_oob - [MTD Interface] NAND write out-of-band
  * @mtd: MTD device structure
  * @to: offset to write to
@@ -4917,8 +4863,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->_erase = nand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
-	mtd->_read = nand_read;
-	mtd->_write = nand_write;
 	mtd->_panic_write = panic_nand_write;
 	mtd->_read_oob = nand_read_oob;
 	mtd->_write_oob = nand_write_oob;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 1a6d0e367b89..050ba8a87543 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1448,38 +1448,6 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 }
 
 /**
- * onenand_read - [MTD Interface] Read data from flash
- * @param mtd		MTD device structure
- * @param from		offset to read from
- * @param len		number of bytes to read
- * @param retlen	pointer to variable to store the number of read bytes
- * @param buf		the databuffer to put data
- *
- * Read with ecc
-*/
-static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-	size_t *retlen, u_char *buf)
-{
-	struct onenand_chip *this = mtd->priv;
-	struct mtd_oob_ops ops = {
-		.len	= len,
-		.ooblen	= 0,
-		.datbuf	= buf,
-		.oobbuf	= NULL,
-	};
-	int ret;
-
-	onenand_get_device(mtd, FL_READING);
-	ret = ONENAND_IS_4KB_PAGE(this) ?
-		onenand_mlc_read_ops_nolock(mtd, from, &ops) :
-		onenand_read_ops_nolock(mtd, from, &ops);
-	onenand_release_device(mtd);
-
-	*retlen = ops.retlen;
-	return ret;
-}
-
-/**
  * onenand_read_oob - [MTD Interface] Read main and/or out-of-band
  * @param mtd:		MTD device structure
  * @param from:		offset to read from
@@ -2129,35 +2097,6 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 }
 
 /**
- * onenand_write - [MTD Interface] write buffer to FLASH
- * @param mtd		MTD device structure
- * @param to		offset to write to
- * @param len		number of bytes to write
- * @param retlen	pointer to variable to store the number of written bytes
- * @param buf		the data to write
- *
- * Write with ECC
- */
-static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
-	size_t *retlen, const u_char *buf)
-{
-	struct mtd_oob_ops ops = {
-		.len	= len,
-		.ooblen	= 0,
-		.datbuf	= (u_char *) buf,
-		.oobbuf	= NULL,
-	};
-	int ret;
-
-	onenand_get_device(mtd, FL_WRITING);
-	ret = onenand_write_ops_nolock(mtd, to, &ops);
-	onenand_release_device(mtd);
-
-	*retlen = ops.retlen;
-	return ret;
-}
-
-/**
  * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
  * @param mtd:		MTD device structure
  * @param to:		offset to write
@@ -4038,8 +3977,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	mtd->_erase = onenand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
-	mtd->_read = onenand_read;
-	mtd->_write = onenand_write;
 	mtd->_read_oob = onenand_read_oob;
 	mtd->_write_oob = onenand_write_oob;
 	mtd->_panic_write = onenand_panic_write;
-- 
2.11.0



From ladis at linux-mips.org  Tue Jan  9 01:08:45 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 10:08:45 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109094621.23a5e368@bbrezillon>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
Message-ID: <20180109090845.GA22600@lenoch>

On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:
> On Tue, 9 Jan 2018 00:48:37 +0100
> Ladislav Michl <ladis at linux-mips.org> wrote:
> 
> > Samsung E-die SLC NAND manufactured using 21nm process supports only
> 
> I would add the chip name here (K9F1G08U0E).

Ok.

> > 1 partial program cycle, so disable subpage writes for it.
> 
> Which means it does not support partial page programming, so how about
> rewording it like that:
> 
> Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> does not support partial page programming, so disable subpage writes
> for it.

Yes, will post v2 eventually, but see bellow.

> > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > 
> > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > ---
> >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> >        board with K9F1G08U0E.
> 
> Just out of curiosity, what are the symptoms when you don't have this
> flag set?

Device is identified as:
nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
nand: Samsung NAND 128MiB 3,3V 8-bit
nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64

Short test:
# flash_erase /dev/mtd4 0 0
Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
flash_erase: Skipping bad block at 07fa0000
flash_erase: Skipping bad block at 07fc0000
flash_erase: Skipping bad block at 07fe0000
Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
# ubiformat /dev/mtd4
ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 1023 -- 100 % complete  
ubiformat: 1020 eraseblocks are supposedly empty
ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
ubiformat: formatting eraseblock 1023 -- 100 % complete  
# ubiattach -m 4
ubi0: default fastmap pool size: 50
ubi0: default fastmap WL pool size: 25
ubi0: attaching mtd4
ubi0: scanning is finished
ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
ubi0: background thread "ubi_bgt0d" started, PID 716
UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
# ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
# ubiupdatevol /dev/ubi0_0 linuximage 
__nand_correct_data: uncorrectable ECC error
ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
__nand_correct_data: uncorrectable ECC error
ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
__nand_correct_data: uncorrectable ECC error
ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
__nand_correct_data: uncorrectable ECC error
ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
Hardware name: Atmel AT91SAM9
[<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
[<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
[<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
[<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
[<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
[<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
[<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
[<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
[<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
[<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted

There's another patchset to deal with this issue:
http://thread.gmane.org/gmane.linux.drivers.mtd/54167

And it brings a problem to us as those patches are mutually exclusive.
Once no subpage write patch is applied UBI's VID header offset changes to 2048
from 512, so on flash filesystem is no longer readable if we wish to give
optimize subpage writes a chance later.

I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
patch worth considering again?

> >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > index f6b0a63a068c..9400b4a84243 100644
> > --- a/drivers/mtd/nand/nand_samsung.c
> > +++ b/drivers/mtd/nand/nand_samsung.c
> > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> >  	} else {
> >  		nand_decode_ext_id(chip);
> >  
> > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > -			chip->ecc_step_ds = 512;
> > -			chip->ecc_strength_ds = 1;
> > +		if (nand_is_slc(chip)) {
> > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > +			if (chip->id.data[1] == 0xDC) {
> > +				chip->ecc_step_ds = 512;
> > +				chip->ecc_strength_ds = 1;
> > +			}
> > +
> > +			/* 21nm chips do not support partial page write */
> > +			if (chip->id.len > 4 &&
> > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
> 
> NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> should be more restrictive here: replace "chip->id.len > 4" by
> "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.

Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
seems to be a good idea.

> > +				chip->options |= NAND_NO_SUBPAGE_WRITE;
> >  		}
> >  	}
> >  }

Best regards,
	ladis


From s.hauer at pengutronix.de  Tue Jan  9 01:09:38 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 10:09:38 +0100
Subject: [PATCH] mtd: tests: nandbiterrs: Fix read_page return value
Message-ID: <20180109090938.29760-1-s.hauer@pengutronix.de>

The number of corrected bitflips is not correctly reported by
the test until the bitflip threshold is reached.

read_page() shall return the number of corrected bitflips, but
mtd_read() returns 0 or a negative error, so we can't forward
its return value. In the absence of an error we always have
calculate the number of bitflips ourselves.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/tests/nandbiterrs.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
index 5f03b8c885a9..11e39ab4a810 100644
--- a/drivers/mtd/tests/nandbiterrs.c
+++ b/drivers/mtd/tests/nandbiterrs.c
@@ -152,15 +152,16 @@ static int read_page(int log)
 
 	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
 	if (err == -EUCLEAN)
-		err = mtd->ecc_stats.corrected - oldstats.corrected;
+		err = 0;
 
 	if (err < 0 || read != mtd->writesize) {
 		pr_err("error: read failed at %#llx\n", (long long)offset);
 		if (err >= 0)
 			err = -EIO;
+		return err;
 	}
 
-	return err;
+	return mtd->ecc_stats.corrected - oldstats.corrected;
 }
 
 /* Verifies rbuffer against random sequence */
-- 
2.11.0



From boris.brezillon at free-electrons.com  Tue Jan  9 01:27:04 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 10:27:04 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109090845.GA22600@lenoch>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
 <20180109090845.GA22600@lenoch>
Message-ID: <20180109102704.62ba7fc9@bbrezillon>

On Tue, 9 Jan 2018 10:08:45 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:
> > On Tue, 9 Jan 2018 00:48:37 +0100
> > Ladislav Michl <ladis at linux-mips.org> wrote:
> >   
> > > Samsung E-die SLC NAND manufactured using 21nm process supports only  
> > 
> > I would add the chip name here (K9F1G08U0E).  
> 
> Ok.
> 
> > > 1 partial program cycle, so disable subpage writes for it.  
> > 
> > Which means it does not support partial page programming, so how about
> > rewording it like that:
> > 
> > Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> > does not support partial page programming, so disable subpage writes
> > for it.  
> 
> Yes, will post v2 eventually, but see bellow.
> 
> > > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > > 
> > > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > > ---
> > >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> > >        board with K9F1G08U0E.  
> > 
> > Just out of curiosity, what are the symptoms when you don't have this
> > flag set?  
> 
> Device is identified as:
> nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
> nand: Samsung NAND 128MiB 3,3V 8-bit
> nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> 
> Short test:
> # flash_erase /dev/mtd4 0 0
> Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
> flash_erase: Skipping bad block at 07fa0000
> flash_erase: Skipping bad block at 07fc0000
> flash_erase: Skipping bad block at 07fe0000
> Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
> # ubiformat /dev/mtd4
> ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
> libscan: scanning eraseblock 1023 -- 100 % complete  
> ubiformat: 1020 eraseblocks are supposedly empty
> ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
> ubiformat: formatting eraseblock 1023 -- 100 % complete  
> # ubiattach -m 4
> ubi0: default fastmap pool size: 50
> ubi0: default fastmap WL pool size: 25
> ubi0: attaching mtd4
> ubi0: scanning is finished
> ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
> ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
> ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
> ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
> ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
> ubi0: background thread "ubi_bgt0d" started, PID 716
> UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
> # ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
> Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
> # ubiupdatevol /dev/ubi0_0 linuximage 
> __nand_correct_data: uncorrectable ECC error
> ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> __nand_correct_data: uncorrectable ECC error
> ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> __nand_correct_data: uncorrectable ECC error
> ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> __nand_correct_data: uncorrectable ECC error
> ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
> CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
> Hardware name: Atmel AT91SAM9
> [<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
> [<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
> [<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
> [<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
> [<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
> [<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
> [<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
> [<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
> [<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
> [<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
> ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
> ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted
> 
> There's another patchset to deal with this issue:
> http://thread.gmane.org/gmane.linux.drivers.mtd/54167

Are you sure it fixes your problem??? Did you try it?

> 
> And it brings a problem to us as those patches are mutually exclusive.
> Once no subpage write patch is applied UBI's VID header offset changes to 2048
> from 512, so on flash filesystem is no longer readable if we wish to give
> optimize subpage writes a chance later.

If your NAND does not support subpage writes, you have to expose a
min_io_size of a page not a subpage. AFAICT, the patchset you're
referring to won't fix your problem.

> 
> I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
> patch worth considering again?

Incompatibility with what? The datasheet clearly says that the chip
does not support subpage writes.

> 
> > >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > > index f6b0a63a068c..9400b4a84243 100644
> > > --- a/drivers/mtd/nand/nand_samsung.c
> > > +++ b/drivers/mtd/nand/nand_samsung.c
> > > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> > >  	} else {
> > >  		nand_decode_ext_id(chip);
> > >  
> > > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > > -			chip->ecc_step_ds = 512;
> > > -			chip->ecc_strength_ds = 1;
> > > +		if (nand_is_slc(chip)) {
> > > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > > +			if (chip->id.data[1] == 0xDC) {
> > > +				chip->ecc_step_ds = 512;
> > > +				chip->ecc_strength_ds = 1;
> > > +			}
> > > +
> > > +			/* 21nm chips do not support partial page write */
> > > +			if (chip->id.len > 4 &&
> > > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)  
> > 
> > NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> > should be more restrictive here: replace "chip->id.len > 4" by
> > "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.  
> 
> Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
> seems to be a good idea.

That's not what the datasheet says :-/. What's the value of
chip->id.data[5]?

> 
> > > +				chip->options |= NAND_NO_SUBPAGE_WRITE;
> > >  		}
> > >  	}
> > >  }  
> 
> Best regards,
> 	ladis



From boris.brezillon at free-electrons.com  Tue Jan  9 01:31:12 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 10:31:12 +0100
Subject: [PATCH] mtd: tests: nandbiterrs: Fix read_page return value
In-Reply-To: <20180109090938.29760-1-s.hauer@pengutronix.de>
References: <20180109090938.29760-1-s.hauer@pengutronix.de>
Message-ID: <20180109103112.2cc8681c@bbrezillon>

On Tue,  9 Jan 2018 10:09:38 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> The number of corrected bitflips is not correctly reported by
> the test until the bitflip threshold is reached.
> 
> read_page() shall return the number of corrected bitflips, but
> mtd_read() returns 0 or a negative error, so we can't forward
> its return value. In the absence of an error we always have
> calculate the number of bitflips ourselves.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/tests/nandbiterrs.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
> index 5f03b8c885a9..11e39ab4a810 100644
> --- a/drivers/mtd/tests/nandbiterrs.c
> +++ b/drivers/mtd/tests/nandbiterrs.c
> @@ -152,15 +152,16 @@ static int read_page(int log)
>  
>  	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
>  	if (err == -EUCLEAN)

Why not just replacing the above test by

	if (!err || err == -EUCLEAN)

> -		err = mtd->ecc_stats.corrected - oldstats.corrected;
> +		err = 0;
>  
>  	if (err < 0 || read != mtd->writesize) {
>  		pr_err("error: read failed at %#llx\n", (long long)offset);
>  		if (err >= 0)
>  			err = -EIO;
> +		return err;
>  	}
>  
> -	return err;
> +	return mtd->ecc_stats.corrected - oldstats.corrected;
>  }
>  
>  /* Verifies rbuffer against random sequence */



From boris.brezillon at free-electrons.com  Tue Jan  9 01:42:45 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 10:42:45 +0100
Subject: [PATCH V6 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <9a799300a0730a0103fe744878fb1a9f@milecki.pl>
References: <20180102130458.16226-1-zajec5@gmail.com>
 <20180103105543.17897-1-zajec5@gmail.com>
 <CAL_JsqLYjUsWGAYm978oPmMAue6YDRb=K00gReZTia6iaJ6xsA@mail.gmail.com>
 <9a799300a0730a0103fe744878fb1a9f@milecki.pl>
Message-ID: <20180109104245.0f8cf097@bbrezillon>

On Thu, 04 Jan 2018 07:32:36 +0100
Rafa? Mi?ecki <rafal at milecki.pl> wrote:

> On 2018-01-03 19:28, Rob Herring wrote:
> > On Wed, Jan 3, 2018 at 4:55 AM, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:  
> >> From: Brian Norris <computersforpeace at gmail.com>
> >> 
> >> Partition parsers can now provide an of_match_table to enable
> >> flash<-->parser matching via device tree as documented in the
> >> mtd/partition.txt.
> >> 
> >> It works by looking for a matching parser for every string in the
> >> "compatibility" property (starting with the most specific one).
> >> 
> >> This support is currently limited to built-in parsers as it uses
> >> request_module() and friends. This should be sufficient for most cases
> >> though as compiling parsers as modules isn't a common choice.
> >> 
> >> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> >> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> >> ---
> >> This is based on Brian's patches:
> >> [RFC PATCH 4/7] mtd: add of_match_mtd_parser() and 
> >> of_mtd_match_mtd_parser() helpers
> >> [RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
> >> 
> >> V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
> >>     Merge helpers into a single of_mtd_match_mtd_parser
> >> V3: Add a simple comment to note we will need the best match in the 
> >> future
> >> V4: Rework new functions to pick parser with the best match
> >>     Move new code in parse_mtd_partitions up so it has precedence over 
> >> flash
> >>     driver defaults and MTD defaults
> >> V5: Rework matching code to start checking with the most specific 
> >> string in the
> >>     "compatibility" property.
> >> V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
> >> ---
> >>  drivers/mtd/mtdpart.c          | 64 
> >> ++++++++++++++++++++++++++++++++++++++++++
> >>  include/linux/mtd/partitions.h |  1 +
> >>  2 files changed, 65 insertions(+)
> >> 
> >> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> >> index be088bccd593..b11958adcf45 100644
> >> --- a/drivers/mtd/mtdpart.c
> >> +++ b/drivers/mtd/mtdpart.c
> >> @@ -30,6 +30,7 @@
> >>  #include <linux/mtd/mtd.h>
> >>  #include <linux/mtd/partitions.h>
> >>  #include <linux/err.h>
> >> +#include <linux/of.h>
> >> 
> >>  #include "mtdcore.h"
> >> 
> >> @@ -880,6 +881,48 @@ static int mtd_part_do_parse(struct 
> >> mtd_part_parser *parser,
> >>  }
> >> 
> >>  /**
> >> + * mtd_part_get_parser_by_cp - find MTD parser by a compatible string  
> > 
> > What's "cp"? Perhaps mtd_part_get_compatible_parser.  
> 
> That's what some base of functions use internally, like
> __of_device_is_compatible (cp)
> of_modalias_node (cplen)
> but using "compatible" for the function name sounds better.
> 
> 
> >> + *
> >> + * @cp: compatible string describing partitions in a device tree  
> > 
> > "compat" would be clearer IMO
> >   
> >> + *
> >> + * MTD parsers can specify supported partitions by providing a table 
> >> of
> >> + * compatibility strings. This function finds a parser that 
> >> advertises support
> >> + * for a passed value of "compatible".
> >> + */
> >> +static struct mtd_part_parser *mtd_part_get_parser_by_cp(const char 
> >> *cp)
> >> +{
> >> +       struct mtd_part_parser *p, *ret = NULL;
> >> +
> >> +       spin_lock(&part_parser_lock);
> >> +
> >> +       list_for_each_entry(p, &part_parsers, list) {
> >> +               const struct of_device_id *matches;
> >> +
> >> +               matches = p->of_match_table;
> >> +               if (!matches)
> >> +                       continue;
> >> +
> >> +               for (; matches->name[0] || matches->type[0] || 
> >> matches->compatible[0];
> >> +                    matches++) {
> >> +                       if (!matches->compatible[0])
> >> +                               continue;  
> > 
> > It would be simpler to just ignore name and type. Having either of
> > those would be an error and the only consequence if there are entries
> > without compatible is returning early.  
> 
> OK, thanks. I guess I misused pattern I saw in the __of_match_node.
> 
> 
> >> +                       if (!strcmp(matches->compatible, cp) &&
> >> +                           try_module_get(p->owner)) {
> >> +                               ret = p;
> >> +                               break;
> >> +                       }
> >> +               }
> >> +
> >> +               if (ret)
> >> +                       break;
> >> +       }
> >> +
> >> +       spin_unlock(&part_parser_lock);
> >> +
> >> +       return ret;
> >> +}
> >> +
> >> +/**
> >>   * parse_mtd_partitions - parse MTD partitions
> >>   * @master: the master partition (describes whole MTD device)
> >>   * @types: names of partition parsers to try or %NULL
> >> @@ -905,8 +948,29 @@ int parse_mtd_partitions(struct mtd_info *master, 
> >> const char *const *types,
> >>                          struct mtd_part_parser_data *data)
> >>  {
> >>         struct mtd_part_parser *parser;
> >> +       struct device_node *np;
> >> +       struct property *prop;
> >> +       const char *cp;
> >>         int ret, err = 0;
> >> 
> >> +       np = of_get_child_by_name(mtd_get_of_node(master), 
> >> "partitions");
> >> +       if (np) {  
> > 
> > You can drop this. of_property_for_each_string and of_node_put will
> > work if np is NULL.
> >   
> >> +               of_property_for_each_string(np, "compatible", prop, 
> >> cp) {
> >> +                       parser = mtd_part_get_parser_by_cp(cp);
> >> +                       if (!parser)
> >> +                               continue;
> >> +                       ret = mtd_part_do_parse(parser, master, 
> >> pparts, data);
> >> +                       if (ret > 0) {
> >> +                               of_node_put(np);
> >> +                               return 0;
> >> +                       }
> >> +                       mtd_part_parser_put(parser);
> >> +                       if (ret < 0 && !err)
> >> +                               err = ret;
> >> +               }
> >> +               of_node_put(np);
> >> +       }
> >> +
> >>         if (!types)
> >>                 types = default_mtd_part_types;
> >> 
> >> diff --git a/include/linux/mtd/partitions.h 
> >> b/include/linux/mtd/partitions.h
> >> index c4beb70dacbd..11cb0c50cd84 100644
> >> --- a/include/linux/mtd/partitions.h
> >> +++ b/include/linux/mtd/partitions.h
> >> @@ -77,6 +77,7 @@ struct mtd_part_parser {
> >>         struct list_head list;
> >>         struct module *owner;
> >>         const char *name;
> >> +       const struct of_device_id *of_match_table;  
> > 
> > I generally like using of_device_id over just an array of strings, but
> > I'm wondering if there's really cases where you have multiple
> > compatible strings for a single parser? Perhaps a single string here
> > would be sufficient. And if you did have multiple matches, how would
> > you distinguish them later on in the parsing functions? Normally we'd
> > use the matched data ptr, but that's not provided here.  
> 
> I think we may need some flash parsers to support multiple strings in
> the future. For example image tag parser (bcm63xxpart.c) handles
> Broadcom's tag that has few versions (see struct bcm_tag and its
> version field).
> 
> Later we may want to add support for matching partitions parsers (like
> trx) which also can have multple versions support. For example TRX v1
> and TRX v2 differ by a single field in the header and it makes sense to
> use the same parser for them.
> 
> While this may be not a perfect solution with data ptr, we can always do
> of_device_is_compatible(&mtd->dev, "foo")

Well, if we ever need to extract per-compatible driver data, we could
easily add a field to the mtd_part_parser_data struct (void *of_data).

Rafal, I had a look at your v7 and it looks sane, so I'll queue it for
4.16 unless Rob has other concerns.

Thanks for your patience.

Boris

> 
> 
> >>         int (*parse_fn)(struct mtd_info *, const struct mtd_partition 
> >> **,
> >>                         struct mtd_part_parser_data *);
> >>         void (*cleanup)(const struct mtd_partition *pparts, int 
> >> nr_parts);
> >> --
> >> 2.11.0
> >>   



From s.hauer at pengutronix.de  Tue Jan  9 01:47:02 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 10:47:02 +0100
Subject: [PATCH v2] mtd: tests: nandbiterrs: Fix read_page return value
Message-ID: <20180109094702.21488-1-s.hauer@pengutronix.de>

The number of corrected bitflips is not correctly reported by
the test until the bitflip threshold is reached.

read_page() shall return the number of corrected bitflips, but
mtd_read() returns 0 or a negative error, so we can't forward
its return value. In the absence of an error we always have
calculate the number of bitflips ourselves.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/tests/nandbiterrs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
index 5f03b8c885a9..cde19c99e77b 100644
--- a/drivers/mtd/tests/nandbiterrs.c
+++ b/drivers/mtd/tests/nandbiterrs.c
@@ -151,7 +151,7 @@ static int read_page(int log)
 	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
 
 	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
-	if (err == -EUCLEAN)
+	if (!err || err == -EUCLEAN)
 		err = mtd->ecc_stats.corrected - oldstats.corrected;
 
 	if (err < 0 || read != mtd->writesize) {
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 01:47:32 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 9 Jan 2018 10:47:32 +0100
Subject: [PATCH] mtd: tests: nandbiterrs: Fix read_page return value
In-Reply-To: <20180109103112.2cc8681c@bbrezillon>
References: <20180109090938.29760-1-s.hauer@pengutronix.de>
 <20180109103112.2cc8681c@bbrezillon>
Message-ID: <20180109094732.3gir5acacsu3ce5a@pengutronix.de>

On Tue, Jan 09, 2018 at 10:31:12AM +0100, Boris Brezillon wrote:
> On Tue,  9 Jan 2018 10:09:38 +0100
> Sascha Hauer <s.hauer at pengutronix.de> wrote:
> 
> > The number of corrected bitflips is not correctly reported by
> > the test until the bitflip threshold is reached.
> > 
> > read_page() shall return the number of corrected bitflips, but
> > mtd_read() returns 0 or a negative error, so we can't forward
> > its return value. In the absence of an error we always have
> > calculate the number of bitflips ourselves.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/mtd/tests/nandbiterrs.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
> > index 5f03b8c885a9..11e39ab4a810 100644
> > --- a/drivers/mtd/tests/nandbiterrs.c
> > +++ b/drivers/mtd/tests/nandbiterrs.c
> > @@ -152,15 +152,16 @@ static int read_page(int log)
> >  
> >  	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
> >  	if (err == -EUCLEAN)
> 
> Why not just replacing the above test by
> 
> 	if (!err || err == -EUCLEAN)

Looks better indeed. I just sent an update.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From boris.brezillon at free-electrons.com  Tue Jan  9 01:51:08 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 10:51:08 +0100
Subject: [PATCH v2] mtd: tests: nandbiterrs: Fix read_page return value
In-Reply-To: <20180109094702.21488-1-s.hauer@pengutronix.de>
References: <20180109094702.21488-1-s.hauer@pengutronix.de>
Message-ID: <20180109105108.4ece18cf@bbrezillon>

On Tue,  9 Jan 2018 10:47:02 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> The number of corrected bitflips is not correctly reported by
> the test until the bitflip threshold is reached.
> 
> read_page() shall return the number of corrected bitflips, but
> mtd_read() returns 0 or a negative error, so we can't forward
> its return value. In the absence of an error we always have
> calculate the number of bitflips ourselves.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>

I'll apply this patch, but you should really start using the userspace
tests provided by mtd-utils, because I still plan to remove the
in-kernel test modules at some point ;-).

> ---
>  drivers/mtd/tests/nandbiterrs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
> index 5f03b8c885a9..cde19c99e77b 100644
> --- a/drivers/mtd/tests/nandbiterrs.c
> +++ b/drivers/mtd/tests/nandbiterrs.c
> @@ -151,7 +151,7 @@ static int read_page(int log)
>  	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
>  
>  	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
> -	if (err == -EUCLEAN)
> +	if (!err || err == -EUCLEAN)
>  		err = mtd->ecc_stats.corrected - oldstats.corrected;
>  
>  	if (err < 0 || read != mtd->writesize) {



From ladis at linux-mips.org  Tue Jan  9 01:58:03 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 10:58:03 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109102704.62ba7fc9@bbrezillon>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
 <20180109090845.GA22600@lenoch>
 <20180109102704.62ba7fc9@bbrezillon>
Message-ID: <20180109095803.GA6798@lenoch>

On Tue, Jan 09, 2018 at 10:27:04AM +0100, Boris Brezillon wrote:
> On Tue, 9 Jan 2018 10:08:45 +0100
> Ladislav Michl <ladis at linux-mips.org> wrote:
> 
> > On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:
> > > On Tue, 9 Jan 2018 00:48:37 +0100
> > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > >   
> > > > Samsung E-die SLC NAND manufactured using 21nm process supports only  
> > > 
> > > I would add the chip name here (K9F1G08U0E).  
> > 
> > Ok.
> > 
> > > > 1 partial program cycle, so disable subpage writes for it.  
> > > 
> > > Which means it does not support partial page programming, so how about
> > > rewording it like that:
> > > 
> > > Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> > > does not support partial page programming, so disable subpage writes
> > > for it.  
> > 
> > Yes, will post v2 eventually, but see bellow.
> > 
> > > > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > > > 
> > > > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > > > ---
> > > >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> > > >        board with K9F1G08U0E.  
> > > 
> > > Just out of curiosity, what are the symptoms when you don't have this
> > > flag set?  
> > 
> > Device is identified as:
> > nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
> > nand: Samsung NAND 128MiB 3,3V 8-bit
> > nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > 
> > Short test:
> > # flash_erase /dev/mtd4 0 0
> > Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
> > flash_erase: Skipping bad block at 07fa0000
> > flash_erase: Skipping bad block at 07fc0000
> > flash_erase: Skipping bad block at 07fe0000
> > Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
> > # ubiformat /dev/mtd4
> > ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
> > libscan: scanning eraseblock 1023 -- 100 % complete  
> > ubiformat: 1020 eraseblocks are supposedly empty
> > ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
> > ubiformat: formatting eraseblock 1023 -- 100 % complete  
> > # ubiattach -m 4
> > ubi0: default fastmap pool size: 50
> > ubi0: default fastmap WL pool size: 25
> > ubi0: attaching mtd4
> > ubi0: scanning is finished
> > ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
> > ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> > ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> > ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> > ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
> > ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
> > ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
> > ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
> > ubi0: background thread "ubi_bgt0d" started, PID 716
> > UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
> > # ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
> > Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
> > # ubiupdatevol /dev/ubi0_0 linuximage 
> > __nand_correct_data: uncorrectable ECC error
> > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > __nand_correct_data: uncorrectable ECC error
> > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > __nand_correct_data: uncorrectable ECC error
> > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > __nand_correct_data: uncorrectable ECC error
> > ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
> > CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
> > Hardware name: Atmel AT91SAM9
> > [<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
> > [<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
> > [<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
> > [<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
> > [<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
> > [<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
> > [<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
> > [<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
> > [<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
> > [<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
> > ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
> > ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted
> > 
> > There's another patchset to deal with this issue:
> > http://thread.gmane.org/gmane.linux.drivers.mtd/54167
> 
> Are you sure it fixes your problem??? Did you try it?

Just forward ported them to -next yesterday. Will give it a try for sure.

> > And it brings a problem to us as those patches are mutually exclusive.
> > Once no subpage write patch is applied UBI's VID header offset changes to 2048
> > from 512, so on flash filesystem is no longer readable if we wish to give
> > optimize subpage writes a chance later.
> 
> If your NAND does not support subpage writes, you have to expose a
> min_io_size of a page not a subpage. AFAICT, the patchset you're
> referring to won't fix your problem.
> 
> > 
> > I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
> > patch worth considering again?
> 
> Incompatibility with what? The datasheet clearly says that the chip
> does not support subpage writes.
> 
> > 
> > > >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> > > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > > > index f6b0a63a068c..9400b4a84243 100644
> > > > --- a/drivers/mtd/nand/nand_samsung.c
> > > > +++ b/drivers/mtd/nand/nand_samsung.c
> > > > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> > > >  	} else {
> > > >  		nand_decode_ext_id(chip);
> > > >  
> > > > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > > > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > > > -			chip->ecc_step_ds = 512;
> > > > -			chip->ecc_strength_ds = 1;
> > > > +		if (nand_is_slc(chip)) {
> > > > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > > > +			if (chip->id.data[1] == 0xDC) {
> > > > +				chip->ecc_step_ds = 512;
> > > > +				chip->ecc_strength_ds = 1;
> > > > +			}
> > > > +
> > > > +			/* 21nm chips do not support partial page write */
> > > > +			if (chip->id.len > 4 &&
> > > > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)  
> > > 
> > > NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> > > should be more restrictive here: replace "chip->id.len > 4" by
> > > "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.  
> > 
> > Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
> > seems to be a good idea.
> 
> That's not what the datasheet says :-/. What's the value of
> chip->id.data[5]?

The result of
printk("id_len %d, id_data4 %x, id_data5 %x\n",
	chip->id.len, chip->id.data[4], chip->id.data[5]);
is
id_len 6, id_data4 41, id_data5 ec

> > > > +				chip->options |= NAND_NO_SUBPAGE_WRITE;
> > > >  		}
> > > >  	}
> > > >  }  
> > 
> > Best regards,
> > 	ladis


From boris.brezillon at free-electrons.com  Tue Jan  9 02:06:30 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 11:06:30 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109095803.GA6798@lenoch>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
 <20180109090845.GA22600@lenoch>
 <20180109102704.62ba7fc9@bbrezillon> <20180109095803.GA6798@lenoch>
Message-ID: <20180109110630.24a26735@bbrezillon>

On Tue, 9 Jan 2018 10:58:03 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> On Tue, Jan 09, 2018 at 10:27:04AM +0100, Boris Brezillon wrote:
> > On Tue, 9 Jan 2018 10:08:45 +0100
> > Ladislav Michl <ladis at linux-mips.org> wrote:
> >   
> > > On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:  
> > > > On Tue, 9 Jan 2018 00:48:37 +0100
> > > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > > >     
> > > > > Samsung E-die SLC NAND manufactured using 21nm process supports only    
> > > > 
> > > > I would add the chip name here (K9F1G08U0E).    
> > > 
> > > Ok.
> > >   
> > > > > 1 partial program cycle, so disable subpage writes for it.    
> > > > 
> > > > Which means it does not support partial page programming, so how about
> > > > rewording it like that:
> > > > 
> > > > Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> > > > does not support partial page programming, so disable subpage writes
> > > > for it.    
> > > 
> > > Yes, will post v2 eventually, but see bellow.
> > >   
> > > > > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > > > > 
> > > > > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > > > > ---
> > > > >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> > > > >        board with K9F1G08U0E.    
> > > > 
> > > > Just out of curiosity, what are the symptoms when you don't have this
> > > > flag set?    
> > > 
> > > Device is identified as:
> > > nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
> > > nand: Samsung NAND 128MiB 3,3V 8-bit
> > > nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > 
> > > Short test:
> > > # flash_erase /dev/mtd4 0 0
> > > Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
> > > flash_erase: Skipping bad block at 07fa0000
> > > flash_erase: Skipping bad block at 07fc0000
> > > flash_erase: Skipping bad block at 07fe0000
> > > Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
> > > # ubiformat /dev/mtd4
> > > ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
> > > libscan: scanning eraseblock 1023 -- 100 % complete  
> > > ubiformat: 1020 eraseblocks are supposedly empty
> > > ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
> > > ubiformat: formatting eraseblock 1023 -- 100 % complete  
> > > # ubiattach -m 4
> > > ubi0: default fastmap pool size: 50
> > > ubi0: default fastmap WL pool size: 25
> > > ubi0: attaching mtd4
> > > ubi0: scanning is finished
> > > ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
> > > ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> > > ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> > > ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> > > ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
> > > ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
> > > ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
> > > ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
> > > ubi0: background thread "ubi_bgt0d" started, PID 716
> > > UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
> > > # ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
> > > Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
> > > # ubiupdatevol /dev/ubi0_0 linuximage 
> > > __nand_correct_data: uncorrectable ECC error
> > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > __nand_correct_data: uncorrectable ECC error
> > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > __nand_correct_data: uncorrectable ECC error
> > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > __nand_correct_data: uncorrectable ECC error
> > > ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
> > > CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
> > > Hardware name: Atmel AT91SAM9
> > > [<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
> > > [<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
> > > [<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
> > > [<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
> > > [<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
> > > [<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
> > > [<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
> > > [<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
> > > [<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
> > > [<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
> > > ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
> > > ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted
> > > 
> > > There's another patchset to deal with this issue:
> > > http://thread.gmane.org/gmane.linux.drivers.mtd/54167  
> > 
> > Are you sure it fixes your problem??? Did you try it?  
> 
> Just forward ported them to -next yesterday. Will give it a try for sure.
> 
> > > And it brings a problem to us as those patches are mutually exclusive.
> > > Once no subpage write patch is applied UBI's VID header offset changes to 2048
> > > from 512, so on flash filesystem is no longer readable if we wish to give
> > > optimize subpage writes a chance later.  
> > 
> > If your NAND does not support subpage writes, you have to expose a
> > min_io_size of a page not a subpage. AFAICT, the patchset you're
> > referring to won't fix your problem.
> >   
> > > 
> > > I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
> > > patch worth considering again?  
> > 
> > Incompatibility with what? The datasheet clearly says that the chip
> > does not support subpage writes.
> >   
> > >   
> > > > >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> > > > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > > > > index f6b0a63a068c..9400b4a84243 100644
> > > > > --- a/drivers/mtd/nand/nand_samsung.c
> > > > > +++ b/drivers/mtd/nand/nand_samsung.c
> > > > > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> > > > >  	} else {
> > > > >  		nand_decode_ext_id(chip);
> > > > >  
> > > > > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > > > > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > > > > -			chip->ecc_step_ds = 512;
> > > > > -			chip->ecc_strength_ds = 1;
> > > > > +		if (nand_is_slc(chip)) {
> > > > > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > > > > +			if (chip->id.data[1] == 0xDC) {
> > > > > +				chip->ecc_step_ds = 512;
> > > > > +				chip->ecc_strength_ds = 1;
> > > > > +			}
> > > > > +
> > > > > +			/* 21nm chips do not support partial page write */
> > > > > +			if (chip->id.len > 4 &&
> > > > > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)    
> > > > 
> > > > NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> > > > should be more restrictive here: replace "chip->id.len > 4" by
> > > > "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.    
> > > 
> > > Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
> > > seems to be a good idea.  
> > 
> > That's not what the datasheet says :-/. What's the value of
> > chip->id.data[5]?  
> 
> The result of
> printk("id_len %d, id_data4 %x, id_data5 %x\n",
> 	chip->id.len, chip->id.data[4], chip->id.data[5]);
> is
> id_len 6, id_data4 41, id_data5 ec

So id.data[5] == id.data[0], can you print id.data[6] and id.data[7]?


From s.hauer at pengutronix.de  Tue Jan  9 02:11:40 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:40 +0100
Subject: mxc_nand controller fixes
Message-ID: <20180109101148.13728-1-s.hauer@pengutronix.de>

This series fixes several problems in the mxc_nand driver.

- Raw support does not work since hardware ECC is unconditionally
  enabled
- The v2/v3 controller code returns the number of corrected
  bitflips for the whole page for each subpage leading to 
  results for times too high
- The v1 controller code returns the number of corrected bitflips
  only for the last subpage. On 2k page NANDs bitflips in the
  first three subpages remain uncovered

This series fixes these issues. Tested with the mtd test modules
mtd_nandbiterrs, mtd_oobtest, mtd_pagetest and mtd_readtest on
a i.MX27 board which is a v1 controller and a i.MX25 board which
is a v2 controller. Boris, and yes, I just tried some of the userspace
mtd tests aswell, namely nandtest, nandsubpagetest and nandbiterrs
;)

Based on nand/next.

Sascha

----------------------------------------------------------------
Sascha Hauer (8):
      mtd: nand: mxc: reorder functions to avoid forward declarations
      mtd: nand: mxc: Add function to control hardware ECC
      mtd: nand: mxc: Add buffer argument to copy_spare
      mtd: nand: mxc: Fix failed/corrected values for v2/v3 controllers
      mtd: nand: mxc: Fix failed/corrected values for v1 controllers
      mtd: nand: mxc: Add own write_page
      mtd: nand: mxc: Drop now unnecessary functions
      mtd: nand: mxc: remove now unused code

 drivers/mtd/nand/mxc_nand.c | 519 +++++++++++++++++++++++++++-----------------
 1 file changed, 322 insertions(+), 197 deletions(-)


From s.hauer at pengutronix.de  Tue Jan  9 02:11:41 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:41 +0100
Subject: [PATCH 1/8] mtd: nand: mxc: reorder functions to avoid forward
 declarations
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-2-s.hauer@pengutronix.de>

We'll call copy_spare() and mxc_do_addr_cycle() from another place
during the next patches, so move functions up to avoid forward
declarations.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 206 ++++++++++++++++++++++----------------------
 1 file changed, 103 insertions(+), 103 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index f3be0b2a8869..6741af990dc4 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -252,6 +252,109 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size)
 		__raw_writew(*s++, t++);
 }
 
+/*
+ * The controller splits a page into data chunks of 512 bytes + partial oob.
+ * There are writesize / 512 such chunks, the size of the partial oob parts is
+ * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
+ * contains additionally the byte lost by rounding (if any).
+ * This function handles the needed shuffling between host->data_buf (which
+ * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
+ * spare) and the NFC buffer.
+ */
+static void copy_spare(struct mtd_info *mtd, bool bfrom)
+{
+	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(this);
+	u16 i, oob_chunk_size;
+	u16 num_chunks = mtd->writesize / 512;
+
+	u8 *d = host->data_buf + mtd->writesize;
+	u8 __iomem *s = host->spare0;
+	u16 sparebuf_size = host->devtype_data->spare_len;
+
+	/* size of oob chunk for all but possibly the last one */
+	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
+
+	if (bfrom) {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_fromio(d + i * oob_chunk_size,
+					s + i * sparebuf_size,
+					oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_fromio(d + i * oob_chunk_size,
+				s + i * sparebuf_size,
+				host->used_oobsize - i * oob_chunk_size);
+	} else {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_toio(&s[i * sparebuf_size],
+				      &d[i * oob_chunk_size],
+				      oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_toio(&s[i * sparebuf_size],
+			      &d[i * oob_chunk_size],
+			      host->used_oobsize - i * oob_chunk_size);
+	}
+}
+
+/*
+ * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
+ * the upper layers perform a read/write buf operation, the saved column address
+ * is used to index into the full page. So usually this function is called with
+ * column == 0 (unless no column cycle is needed indicated by column == -1)
+ */
+static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+
+	/* Write out column address, if necessary */
+	if (column != -1) {
+		host->devtype_data->send_addr(host, column & 0xff,
+					      page_addr == -1);
+		if (mtd->writesize > 512)
+			/* another col addr cycle for 2k page */
+			host->devtype_data->send_addr(host,
+						      (column >> 8) & 0xff,
+						      false);
+	}
+
+	/* Write out page address, if necessary */
+	if (page_addr != -1) {
+		/* paddr_0 - p_addr_7 */
+		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
+
+		if (mtd->writesize > 512) {
+			if (mtd->size >= 0x10000000) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		} else {
+			if (nand_chip->options & NAND_ROW_ADDR_3) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		}
+	}
+}
+
 static int check_int_v3(struct mxc_nand_host *host)
 {
 	uint32_t tmp;
@@ -772,109 +875,6 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip)
 	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 }
 
-/*
- * The controller splits a page into data chunks of 512 bytes + partial oob.
- * There are writesize / 512 such chunks, the size of the partial oob parts is
- * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
- * contains additionally the byte lost by rounding (if any).
- * This function handles the needed shuffling between host->data_buf (which
- * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
- * spare) and the NFC buffer.
- */
-static void copy_spare(struct mtd_info *mtd, bool bfrom)
-{
-	struct nand_chip *this = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(this);
-	u16 i, oob_chunk_size;
-	u16 num_chunks = mtd->writesize / 512;
-
-	u8 *d = host->data_buf + mtd->writesize;
-	u8 __iomem *s = host->spare0;
-	u16 sparebuf_size = host->devtype_data->spare_len;
-
-	/* size of oob chunk for all but possibly the last one */
-	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
-
-	if (bfrom) {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_fromio(d + i * oob_chunk_size,
-					s + i * sparebuf_size,
-					oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_fromio(d + i * oob_chunk_size,
-				s + i * sparebuf_size,
-				host->used_oobsize - i * oob_chunk_size);
-	} else {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_toio(&s[i * sparebuf_size],
-				      &d[i * oob_chunk_size],
-				      oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_toio(&s[i * sparebuf_size],
-			      &d[i * oob_chunk_size],
-			      host->used_oobsize - i * oob_chunk_size);
-	}
-}
-
-/*
- * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
- * the upper layers perform a read/write buf operation, the saved column address
- * is used to index into the full page. So usually this function is called with
- * column == 0 (unless no column cycle is needed indicated by column == -1)
- */
-static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
-{
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
-
-	/* Write out column address, if necessary */
-	if (column != -1) {
-		host->devtype_data->send_addr(host, column & 0xff,
-					      page_addr == -1);
-		if (mtd->writesize > 512)
-			/* another col addr cycle for 2k page */
-			host->devtype_data->send_addr(host,
-						      (column >> 8) & 0xff,
-						      false);
-	}
-
-	/* Write out page address, if necessary */
-	if (page_addr != -1) {
-		/* paddr_0 - p_addr_7 */
-		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
-
-		if (mtd->writesize > 512) {
-			if (mtd->size >= 0x10000000) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		} else {
-			if (nand_chip->options & NAND_ROW_ADDR_3) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		}
-	}
-}
-
 #define MXC_V1_ECCBYTES		5
 
 static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:45 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:45 +0100
Subject: [PATCH 5/8] mtd: nand: mxc: Fix failed/corrected values for v1
 controllers
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-6-s.hauer@pengutronix.de>

The v1 controller code has several flaws:
- We do not forward the number of corrected bitflips to the upper layers
- For 2k page NAND chips only the status results from the fourth subpage
  read are evaluated, so ECC failures in the other subpages remain
  uncovered
- When there are uncorrectable errors we have to increase the statistics
  counter, but still have to return successfully. Currently we return
  an error

This patch fixes this by introducing a v1 specific read_page function.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 78 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 62 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index d698f7c6666c..83bb01ab7079 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -738,22 +738,68 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
+	return 0;
+}
+
+static int mxc_nand_read_page_v1(struct mtd_info *mtd, struct nand_chip *chip,
+				 void *buf, void *oob, bool ecc, int page)
+{
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int max_bitflips = 0;
+	int no_subpages;
+	int i;
 
-	/*
-	 * 1-Bit errors are automatically corrected in HW.  No need for
-	 * additional correction.  2-Bit errors cannot be corrected by
-	 * HW ECC, so we need to return failure
-	 */
-	uint16_t ecc_status = get_ecc_status_v1(host);
+	host->devtype_data->enable_hwecc(nand_chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true);
 
-	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
-		dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n");
-		return -EBADMSG;
+	no_subpages = mtd->writesize >> 9;
+
+	for (i = 0; i < no_subpages; i++) {
+		int flips = 0;
+		uint16_t ecc_stats;
+
+		/* NANDFC buffer 0 is used for page read/write */
+		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
+
+		writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2);
+
+		/* Wait for operation to complete */
+		wait_op_done(host, true);
+
+		ecc_stats = get_ecc_status_v1(host);
+
+		ecc_stats >>= 2;
+
+		if (buf && ecc) {
+			switch (ecc_stats & 0x3) {
+			case 0:
+			default:
+				break;
+			case 1:
+				mtd->ecc_stats.corrected++;
+				flips++;
+				break;
+			case 2:
+				mtd->ecc_stats.failed++;
+				break;
+			}
+		}
+
+		max_bitflips = max_t(unsigned int, max_bitflips, flips);
 	}
 
-	return 0;
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
+	return max_bitflips;
 }
 
 static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
@@ -1494,6 +1540,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 /* v1 + irqpending_quirk: i.MX21 */
 static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1518,6 +1565,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 /* v1 + !irqpending_quirk: i.MX27, i.MX31 */
 static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1856,11 +1904,9 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
-		if (host->devtype_data->read_page) {
-			this->ecc.read_page = mxc_nand_read_page;
-			this->ecc.read_page_raw = mxc_nand_read_page_raw;
-			this->ecc.read_oob = mxc_nand_read_oob;
-		}
+		this->ecc.read_page = mxc_nand_read_page;
+		this->ecc.read_page_raw = mxc_nand_read_page_raw;
+		this->ecc.read_oob = mxc_nand_read_oob;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From yogeshnarayan.gaur at nxp.com  Tue Jan  9 02:26:40 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 9 Jan 2018 15:56:40 +0530
Subject: [PATCH v1 0/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
Message-ID: <1515493602-19626-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has limitation in number of LUT entries, max 16.
Also different flash devices can run on different cmds.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also update read capabilities as 1-4-4.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: add support to create dynamic LUT entry
  mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4

 drivers/mtd/spi-nor/fsl-quadspi.c | 292 ++++++++++++++++++++------------------
 1 file changed, 157 insertions(+), 135 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan  9 02:26:42 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 9 Jan 2018 15:56:42 +0530
Subject: [PATCH v1 2/2] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <1515493602-19626-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515493602-19626-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1515493602-19626-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
protocol. Spansion flash, s25fl512s, supports Quad read with read
capabilities as 1-4-4.

Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>

V1: Swap patch sequences in the series to solve git bissect issue.
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index bb3e087..19d8f03 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -980,6 +980,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	const struct spi_nor_hwcaps hwcaps = {
 		.mask = SNOR_HWCAPS_READ_1_1_4 |
+			SNOR_HWCAPS_READ_1_4_4 |
 			SNOR_HWCAPS_PP,
 	};
 	struct device_node *np = pdev->dev.of_node;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan  9 02:26:41 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 9 Jan 2018 15:56:41 +0530
Subject: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
In-Reply-To: <1515493602-19626-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515493602-19626-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1515493602-19626-2-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>

V1: Swap patch sequences in the series to solve git bissect issue.
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 291 ++++++++++++++++++++------------------
 1 file changed, 156 insertions(+), 135 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index c22e3eb..bb3e087 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -194,20 +194,19 @@
 
 /* SEQID -- we can have 16 seqids at most. */
 #define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+#define SEQID_RUN_CMD		1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +367,151 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
 {
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
+{
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
+	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+	u8 read_dm, opcode;
 	int i;
 
-	struct spi_nor *nor = &q->nor[0];
-	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
+
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
+
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
+	/* Dynamic LUT */
+	lut_base = SEQID_RUN_CMD * 4;
+
+	/* Clear LUT entries for dynamic LUT entry in LUT table */
+	for (i = lut_base; i < (lut_base + 4); i++)
 		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
 
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
 
-	fsl_qspi_lock_lut(q);
-}
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		if (ops == FSL_QSPI_OPS_READ) {
+			qspi_writel(q,
+				    LUT0(DUMMY, pad_count(dummy_pad), read_dm) |
+				    LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+				    base + QUADSPI_LUT(lut_base + 1));
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				SEQID_RUN_CMD << QUADSPI_BFGENCR_SEQID_SHIFT,
+				q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	fsl_qspi_lock_lut(q);
+}
+
+static void fsl_qspi_init_lut(struct fsl_qspi *q)
+{
+	void __iomem *base = q->iobase;
+	int i;
+
+	fsl_qspi_unlock_lut(q);
+
+	/* Clear all LUT table, except LUT0. LUT0 programmed by bootloader */
+	for (i = 4; i < QUADSPI_LUT_NUM; i++)
+		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +546,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +698,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +742,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -794,9 +807,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	return 0;
 }
 
@@ -820,6 +830,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +845,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +855,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +873,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +890,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +940,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:31 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:31 +0100
Subject: [PATCH v3 1/7] dt-bindings: mtd: document new nand-rb property
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-2-miquel.raynal@free-electrons.com>

There are already an atmel,rb and an allwinner,rb properties, let's not
make other ones and instead use a generic term: nand-rb to define NAND
chips Ready/Busy lines.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 Documentation/devicetree/bindings/mtd/nand.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt
index 133f3813719c..8bb11d809429 100644
--- a/Documentation/devicetree/bindings/mtd/nand.txt
+++ b/Documentation/devicetree/bindings/mtd/nand.txt
@@ -43,6 +43,7 @@ Optional NAND chip properties:
 		     This is particularly useful when only the in-band area is
 		     used by the upper layers, and you want to make your NAND
 		     as reliable as possible.
+- nand-rb: shall contain the native Ready/Busy ids.
 
 The ECC strength and ECC step size properties define the correction capability
 of a controller. Together, they say a controller can correct "{strength} bit
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:34 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:34 +0100
Subject: [PATCH v3 4/7] mtd: nand: use reworked NAND controller driver with
 Marvell EBU SoCs
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-5-miquel.raynal@free-electrons.com>

Choose to compile and embed marvell_nand.c as NAND controller driver
instead of the legacy pxa3xx_nand.c for platforms with Marvell EBU
SoCs.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 arch/arm/configs/mvebu_v7_defconfig | 2 +-
 arch/arm64/configs/defconfig        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index 69553704f2dc..4b6e4fd47e5d 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -57,7 +57,7 @@ CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_SRAM=y
 CONFIG_MTD_UBI=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6356c6da34ea..b20fa9b31efe 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -161,7 +161,7 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:32 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:32 +0100
Subject: [PATCH v3 2/7] dt-bindings: mtd: add Marvell NAND controller
 documentation
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-3-miquel.raynal@free-electrons.com>

Document the legacy and the new bindings for Marvell NAND controller.

The pxa3xx_nand.c driver does only support legacy bindings, which are
incomplete and inaccurate. A rework of this controller (called
marvell_nand.c) does support both.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 .../devicetree/bindings/mtd/marvell-nand.txt       | 123 +++++++++++++++++++++
 1 file changed, 123 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/marvell-nand.txt b/Documentation/devicetree/bindings/mtd/marvell-nand.txt
new file mode 100644
index 000000000000..c08fb477b3c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/marvell-nand.txt
@@ -0,0 +1,123 @@
+Marvell NAND Flash Controller (NFC)
+
+Required properties:
+- compatible: can be one of the following:
+    * "marvell,armada-8k-nand-controller"
+    * "marvell,armada370-nand-controller"
+    * "marvell,pxa3xx-nand-controller"
+    * "marvell,armada-8k-nand" (deprecated)
+    * "marvell,armada370-nand" (deprecated)
+    * "marvell,pxa3xx-nand" (deprecated)
+  Compatibles marked deprecated support only the old bindings described
+  at the bottom.
+- reg: NAND flash controller memory area.
+- #address-cells: shall be set to 1. Encode the NAND CS.
+- #size-cells: shall be set to 0.
+- interrupts: shall define the NAND controller interrupt.
+- clocks: shall reference the NAND controller clock.
+- marvell,system-controller: Set to retrieve the syscon node that handles
+  NAND controller related registers (only required with the
+  "marvell,armada-8k-nand[-controller]" compatibles).
+
+Optional properties:
+- label: see partition.txt. New platforms shall omit this property.
+- dmas: shall reference DMA channel associated to the NAND controller.
+  This property is only used with "marvell,pxa3xx-nand[-controller]"
+  compatible strings.
+- dma-names: shall be "rxtx".
+  This property is only used with "marvell,pxa3xx-nand[-controller]"
+  compatible strings.
+
+Optional children nodes:
+Children nodes represent the available NAND chips.
+
+Required properties:
+- reg: shall contain the native Chip Select ids (0-3).
+- nand-rb: see nand.txt (0-1).
+
+Optional properties:
+- marvell,nand-keep-config: orders the driver not to take the timings
+  from the core and leaving them completely untouched. Bootloader
+  timings will then be used.
+- label: MTD name.
+- nand-on-flash-bbt: see nand.txt.
+- nand-ecc-mode: see nand.txt. Will use hardware ECC if not specified.
+- nand-ecc-algo: see nand.txt. This property is essentially useful when
+  not using hardware ECC. Howerver, it may be added when using hardware
+  ECC for clarification but will be ignored by the driver because ECC
+  mode is chosen depending on the page size and the strength required by
+  the NAND chip. This value may be overwritten with nand-ecc-strength
+  property.
+- nand-ecc-strength: see nand.txt.
+- nand-ecc-step-size: see nand.txt. Marvell's NAND flash controller does
+  use fixed strength (1-bit for Hamming, 16-bit for BCH), so the actual
+  step size will shrink or grow in order to fit the required strength.
+  Step sizes are not completely random for all and follow certain
+  patterns described in AN-379, "Marvell SoC NFC ECC".
+
+See Documentation/devicetree/bindings/mtd/nand.txt for more details on
+generic bindings.
+
+
+Example:
+nand_controller: nand-controller at d0000 {
+	compatible = "marvell,armada370-nand-controller";
+	reg = <0xd0000 0x54>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&coredivclk 0>;
+
+	nand at 0 {
+		reg = <0>;
+		label = "main-storage";
+		nand-rb = <0>;
+		nand-ecc-mode = "hw";
+		marvell,nand-keep-config;
+		nand-on-flash-bbt;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "Rootfs";
+				reg = <0x00000000 0x40000000>;
+			};
+		};
+	};
+};
+
+
+Note on legacy bindings: One can find, in not-updated device trees,
+bindings slightly different than described above with other properties
+described below as well as the partitions node at the root of a so
+called "nand" node (without clear controller/chip separation).
+
+Legacy properties:
+- marvell,nand-enable-arbiter: To enable the arbiter, all boards blindly
+  used it, this bit was set by the bootloader for many boards and even if
+  it is marked reserved in several datasheets, it might be needed to set
+  it (otherwise it is harmless) so whether or not this property is set,
+  the bit is selected by the driver.
+- num-cs: Number of chip-select lines to use, all boards blindly set 1
+  to this and for a reason, other values would have failed. The value of
+  this property is ignored.
+
+Example:
+
+	nand0: nand at 43100000 {
+		compatible = "marvell,pxa3xx-nand";
+		reg = <0x43100000 90>;
+		interrupts = <45>;
+		dmas = <&pdma 97 0>;
+		dma-names = "rxtx";
+		#address-cells = <1>;
+		marvell,nand-keep-config;
+		marvell,nand-enable-arbiter;
+		num-cs = <1>;
+		/* Partitions (optional) */
+       };
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:30 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:30 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
Message-ID: <20180109103637.23798-1-miquel.raynal@free-electrons.com>

Hi,

After the addition of the NAND framework ->exec_op() interface (see [1]
for the series preparing it and [2] for the last version of the
core-side implementation of ->exec_op() itself), this series replaces
the current Marvell NAND controller driver pxa3xx_nand.c with a rework
called marvell_nand.c.

Aside the fact that it drops the big state machine, improves the overall
speed and implements raw accesses, it is the first driver-side
implementation of the ->exec_op() interface and may be used as reference
for latter reworks of the same type.

One may find more detail about why a completely new driver is needed in
the commit log of:

    "mtd: nand: add reworked Marvell NAND controller driver"

Device tree NAND node definition for all platforms referring to the
Marvell driver using the new bindings have already been accepted by the
MVEBU DT maintainers and will be merged after the driver. They are more
hierarchical and fit the real organization of the hardware, by having
NAND partitions that are part of NAND chip nodes, themselves part of the
NAND controller node.

These changes have been tested on:
   - PXA3xx platform with a CM-X300 board (2kiB page NAND, 1b/512B
     strength, Hamming ECC engine) [32 bits]
   - Armada 385 DB AP (4kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
   - Armada 398 DB (4kiB page NAND, 8b/512B, BCH ECC engine using a layout
     with a last chunk different than the others) [32 bits]
   - Armada 7040 DB and Armada 8040 DB (4kiB page NAND, 4b/512B, BCH ECC
     engine) [64 bits]
   - Triax dvb-tc board (2kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]

This version is known not to be stable yet with a Zylonite based setup but
otherwise looks good for Marvell EBU platforms.

For people who would like to test it easily, a branch ready to be tested
is available at [3]. It is based on nand/next and has all the changes
brought by the previously mentionned series as well as this one.

Thank you,
Miqu?l


[1] https://www.spinics.net/lists/arm-kernel/msg619633.html
[2] http://lists.infradead.org/pipermail/linux-mtd/2017-December/077965.html
[3] https://github.com/miquelraynal/linux/tree/marvell/nand-next/nfc


Changes since v2:
  - Added a patch to create the nand-rb property in the Documentation
  - Rewording in the Documentation according to Rob's comments
  - Moved from marvell,rb to nand-rb property in the code
  - Disociated using this driver with Marvell EBU platforms than using
    it with PXA ones
  - Fixed the handling of 16-bit buses
  - Fixed SPDX comment style
  - Reorganized registers offsets/bit fields definitions as requested
  - Moved to Kernel doc
  - Changed the logic in ->select_chip() to use a prepared value of NDCR
    only instead of recalculating it
  - Fixed the presence of the SPARE_EN bit, reworked a bit the
    hmg_do_read/write() helpers
  - Fixed the OOB layouts that were unusable (all spare data first, then
    all ECC bytes)
  - Additional check on mtd->writesize when using NFCv1 (all sizes not
    supported)
  - Various typos/rewording

Changes since v1:
  - Rewording
  - Fixed BCH ->read/write_page() hooks for 2kiB pages NAND chips
  - Removed license text, used SPDX tag instead
  - Removed read_page_data()
  - Enhanced the DT bindings document with the label property and the
    deprecated bindings.
  - Simplified the read_chunk() helper (OOB always read).
  - Simplified the ->bch_read_page() hook by removing the addition raw
    read to get ECC bytes.
  - Fixed the ->correct() function that did not check for bitflips in
    ECC bytes in erased pages.


Miquel Raynal (7):
  dt-bindings: mtd: document new nand-rb property
  dt-bindings: mtd: add Marvell NAND controller documentation
  mtd: nand: add reworked Marvell NAND controller driver
  mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
  mtd: nand: use Marvell reworked NAND controller driver with all
    platforms
  dt-bindings: mtd: remove pxa3xx NAND controller documentation
  mtd: nand: remove useless fields from pxa3xx NAND platform data

 .../devicetree/bindings/mtd/marvell-nand.txt       |  123 +
 Documentation/devicetree/bindings/mtd/nand.txt     |    1 +
 .../devicetree/bindings/mtd/pxa3xx-nand.txt        |   50 -
 arch/arm/configs/cm_x300_defconfig                 |    2 +-
 arch/arm/configs/mvebu_v7_defconfig                |    2 +-
 arch/arm/configs/pxa3xx_defconfig                  |    3 +-
 arch/arm/configs/pxa_defconfig                     |    2 +-
 arch/arm/configs/raumfeld_defconfig                |    2 +-
 arch/arm/mach-mmp/ttc_dkb.c                        |    4 +-
 arch/arm/mach-pxa/cm-x300.c                        |    8 +-
 arch/arm/mach-pxa/colibri-pxa3xx.c                 |    8 +-
 arch/arm/mach-pxa/colibri.h                        |    2 +-
 arch/arm/mach-pxa/littleton.c                      |   10 +-
 arch/arm/mach-pxa/mxm8x10.c                        |   10 +-
 arch/arm/mach-pxa/raumfeld.c                       |    6 +-
 arch/arm/mach-pxa/zylonite.c                       |   10 +-
 arch/arm64/configs/defconfig                       |    2 +-
 drivers/mtd/nand/Kconfig                           |   18 +-
 drivers/mtd/nand/Makefile                          |    2 +-
 drivers/mtd/nand/marvell_nand.c                    | 2896 ++++++++++++++++++++
 drivers/mtd/nand/pxa3xx_nand.c                     | 2104 --------------
 include/linux/platform_data/mtd-nand-pxa3xx.h      |   43 +-
 22 files changed, 3072 insertions(+), 2236 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
 create mode 100644 drivers/mtd/nand/marvell_nand.c
 delete mode 100644 drivers/mtd/nand/pxa3xx_nand.c

-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:36 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:36 +0100
Subject: [PATCH v3 6/7] dt-bindings: mtd: remove pxa3xx NAND controller
 documentation
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-7-miquel.raynal@free-electrons.com>

The deprecated pxa3xx_nand.c driver does not exist anymore, it has been
replaced by marvell_nand.c which has its own up-to-date documentation.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/mtd/pxa3xx-nand.txt        | 50 ----------------------
 1 file changed, 50 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
deleted file mode 100644
index d4ee4da58463..000000000000
--- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-PXA3xx NAND DT bindings
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-			marvell,pxa3xx-nand
-			marvell,armada370-nand
-			marvell,armada-8k-nand
- - reg: 		The register base for the controller
- - interrupts:		The interrupt to map
- - #address-cells:	Set to <1> if the node includes partitions
- - marvell,system-controller: Set to retrieve the syscon node that handles
-			NAND controller related registers (only required
-			with marvell,armada-8k-nand compatible).
-
-Optional properties:
-
- - dmas:			dma data channel, see dma.txt binding doc
- - marvell,nand-enable-arbiter:	Set to enable the bus arbiter
- - marvell,nand-keep-config:	Set to keep the NAND controller config as set
-				by the bootloader
- - num-cs:			Number of chipselect lines to use
- - nand-on-flash-bbt: 		boolean to enable on flash bbt option if
-				not present false
- - nand-ecc-strength:           number of bits to correct per ECC step
- - nand-ecc-step-size:          number of data bytes covered by a single ECC step
-
-The following ECC strength and step size are currently supported:
-
- - nand-ecc-strength = <1>, nand-ecc-step-size = <512>
- - nand-ecc-strength = <4>, nand-ecc-step-size = <512>
- - nand-ecc-strength = <8>, nand-ecc-step-size = <512>
-
-Example:
-
-	nand0: nand at 43100000 {
-		compatible = "marvell,pxa3xx-nand";
-		reg = <0x43100000 90>;
-		interrupts = <45>;
-		dmas = <&pdma 97 0>;
-		dma-names = "data";
-		#address-cells = <1>;
-
-		marvell,nand-enable-arbiter;
-		marvell,nand-keep-config;
-		num-cs = <1>;
-
-		/* partitions (optional) */
-	};
-
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:37 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:37 +0100
Subject: [PATCH v3 7/7] mtd: nand: remove useless fields from pxa3xx NAND
 platform data
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-8-miquel.raynal@free-electrons.com>

The "enable arbiter" bit is available only for pxa3xx based platforms
but it was experimentally shown that even if this bit is reserved,
some Marvell platforms (64-bit) actually need it to be set. The driver
always set this bit regardless of this property, which is harmless.
Then this property is not needed.

The "num_cs" field is always 1 and for a good reason, the old driver
(pxa3xx_nand.c) could only handle one. The new driver that replaces it
(marvell_nand.c) can handle more, but better use device tree for such
description. As there is only one available chip select, there is no
need for an array of partitions neither an array of partition numbers.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 arch/arm/mach-pxa/cm-x300.c                   |  6 ++--
 arch/arm/mach-pxa/colibri-pxa3xx.c            |  6 ++--
 arch/arm/mach-pxa/littleton.c                 |  6 ++--
 arch/arm/mach-pxa/mxm8x10.c                   |  6 ++--
 arch/arm/mach-pxa/raumfeld.c                  |  6 ++--
 arch/arm/mach-pxa/zylonite.c                  |  6 ++--
 drivers/mtd/nand/marvell_nand.c               |  3 +-
 include/linux/platform_data/mtd-nand-pxa3xx.h | 43 ++++++++-------------------
 8 files changed, 25 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index fe1c76bca212..0ac130bbf935 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -429,11 +429,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= cm_x300_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(cm_x300_nand_partitions),
+	.parts		= cm_x300_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(cm_x300_nand_partitions),
 };
 
 static void __init cm_x300_init_nand(void)
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 3018eafd723e..e31a591e949f 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -138,11 +138,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data colibri_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= colibri_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(colibri_nand_partitions),
+	.parts		= colibri_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(colibri_nand_partitions),
 };
 
 void __init colibri_pxa3xx_init_nand(void)
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 380b07a15ef9..48912d60c630 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -328,10 +328,8 @@ static struct mtd_partition littleton_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data littleton_nand_info = {
-	.enable_arbiter	= 1,
-	.num_cs		= 1,
-	.parts[0]	= littleton_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(littleton_nand_partitions),
+	.parts		= littleton_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(littleton_nand_partitions),
 };
 
 static void __init littleton_init_nand(void)
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index 743d983fc222..d81b20a85ca7 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -389,11 +389,9 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= mxm_8x10_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(mxm_8x10_nand_partitions)
+	.parts		= mxm_8x10_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(mxm_8x10_nand_partitions)
 };
 
 static void __init mxm_8x10_nand_init(void)
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 9d662fed03ec..af72e79a7ffa 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -346,11 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= raumfeld_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(raumfeld_nand_partitions),
+	.parts		= raumfeld_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(raumfeld_nand_partitions),
 };
 
 /**
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 3a99fc054e96..d69de312d8d9 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -376,10 +376,8 @@ static struct mtd_partition zylonite_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data zylonite_nand_info = {
-	.enable_arbiter	= 1,
-	.num_cs		= 1,
-	.parts[0]	= zylonite_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(zylonite_nand_partitions),
+	.parts		= zylonite_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(zylonite_nand_partitions),
 };
 
 static void __init zylonite_init_nand(void)
diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
index 9d01120d97c5..ea05ed8091df 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -2519,8 +2519,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
 
 	if (pdata)
 		/* Legacy bindings support only one chip */
-		ret = mtd_device_register(mtd, pdata->parts[0],
-					  pdata->nr_parts[0]);
+		ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
 	else
 		ret = mtd_device_register(mtd, NULL, 0);
 	if (ret) {
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h
index b42ad83cbc20..4fd0f592a2d2 100644
--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
+++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
@@ -6,41 +6,22 @@
 #include <linux/mtd/partitions.h>
 
 /*
- * Current pxa3xx_nand controller has two chip select which
- * both be workable.
- *
- * Notice should be taken that:
- * When you want to use this feature, you should not enable the
- * keep configuration feature, for two chip select could be
- * attached with different nand chip. The different page size
- * and timing requirement make the keep configuration impossible.
+ * Current pxa3xx_nand controller has two chip select which both be workable but
+ * historically all platforms remaining on platform data used only one. Switch
+ * to device tree if you need more.
  */
-
-/* The max num of chip select current support */
-#define NUM_CHIP_SELECT		(2)
 struct pxa3xx_nand_platform_data {
-
-	/* the data flash bus is shared between the Static Memory
-	 * Controller and the Data Flash Controller,  the arbiter
-	 * controls the ownership of the bus
-	 */
-	int	enable_arbiter;
-
-	/* allow platform code to keep OBM/bootloader defined NFC config */
-	int	keep_config;
-
-	/* indicate how many chip selects will be used */
-	int	num_cs;
-
-	/* use an flash-based bad block table */
-	bool	flash_bbt;
-
-	/* requested ECC strength and ECC step size */
+	/* Keep OBM/bootloader NFC timing configuration */
+	bool keep_config;
+	/* Use a flash-based bad block table */
+	bool flash_bbt;
+	/* Requested ECC strength and ECC step size */
 	int ecc_strength, ecc_step_size;
-
-	const struct mtd_partition		*parts[NUM_CHIP_SELECT];
-	unsigned int				nr_parts[NUM_CHIP_SELECT];
+	/* Partitions */
+	const struct mtd_partition *parts;
+	unsigned int nr_parts;
 };
 
 extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
+
 #endif /* __ASM_ARCH_PXA3XX_NAND_H */
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:33 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:33 +0100
Subject: [PATCH v3 3/7] mtd: nand: add reworked Marvell NAND controller driver
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-4-miquel.raynal@free-electrons.com>

Add marvell_nand driver which aims at replacing the existing pxa3xx_nand
driver.

The new driver intends to be easier to understand and follows the brand
new NAND framework rules by implementing hooks for every pattern the
controller might support and referencing them inside a parser object
that will be given to the core at each ->exec_op() call.

Raw accessors are implemented, useful to test/debug memory/filesystem
corruptions. Userspace binaries contained in the mtd-utils package may
now be used and their output trusted.

Most of the DT nodes using the old driver kept non-optimal timings from
the bootloader (even if there was some mechanisms to derive them if the
chip was ONFI compliant). The new default is to implement
->setup_data_interface() and follow the core's decision regarding the
chip.

Thanks to the improved timings, implementation of ONFI mode 5 support
(with EDO managed by adding a delay on data sampling), merging the
commands together and optimizing writes in the command registers, the
new driver may achieve faster throughputs in both directions.
Measurements show an improvement of about +23% read throughput and +24%
write throughput. These measurements have been done with an
Armada-385-DB-AP (4kiB NAND pages forced in 4-bit strength BCH ECC
correction) using the userspace tool 'flash_speed' from the MTD test
suite.

Besides these important topics, the new driver addresses several
unsolved known issues in the old driver which:
- did not work with ECC soft neither with ECC none ;
- relied on naked read/write (which is unchanged) while the NFCv1
  embedded in the pxa3xx platforms do not implement it, so several
  NAND commands did not actually ever work without any notice (like
  reading the ONFI PARAM_PAGE or SET/GET_FEATURES) ;
- wrote the OOB data correctly, but was not able to read it correctly
  past the first OOB data chunk ;
- did not retrieve ECC bytes ;
- used device tree bindings that did not allow more than one NAND chip,
  and did not allow to choose the correct chip select if not
  incrementing from 0. Plus, the Ready/Busy line used had to be 0.

Old device tree bindings are still supported but deprecated. A more
hierarchical view has to be used to keep the controller and the NAND
chip structures clearly separated both inside the device tree and also
in the driver code.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
Tested-by: Sean Nyekjaer <sean.nyekjaer at prevas.dk>
Tested-by: Willy Tarreau <w at 1wt.eu>
---
 drivers/mtd/nand/Kconfig        |   13 +
 drivers/mtd/nand/Makefile       |    1 +
 drivers/mtd/nand/marvell_nand.c | 2897 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 2911 insertions(+)
 create mode 100644 drivers/mtd/nand/marvell_nand.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 859eb7790c46..e6b8c59f2c0d 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -315,6 +315,7 @@ config MTD_NAND_ATMEL
 
 config MTD_NAND_PXA3xx
 	tristate "NAND support on PXA3xx and Armada 370/XP"
+	depends on !MTD_NAND_MARVELL
 	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU
 	help
 
@@ -323,6 +324,18 @@ config MTD_NAND_PXA3xx
 	  platforms (XP, 370, 375, 38x, 39x) and 64-bit Armada
 	  platforms (7K, 8K) (NFCv2).
 
+config MTD_NAND_MARVELL
+	tristate "NAND controller support on Marvell boards"
+	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
+		   COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This enables the NAND flash controller driver for Marvell boards,
+	  including:
+	  - PXA3xx processors (NFCv1)
+	  - 32-bit Armada platforms (XP, 37x, 38x, 39x) (NFCv2)
+	  - 64-bit Aramda platforms (7k, 8k) (NFCv2)
+
 config MTD_NAND_SLC_LPC32XX
 	tristate "NXP LPC32xx SLC Controller"
 	depends on ARCH_LPC32XX
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 118a1349aad3..921634ba400c 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2_nand.o
 obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD)	+= omap_elm.o
 obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
 obj-$(CONFIG_MTD_NAND_PXA3xx)		+= pxa3xx_nand.o
+obj-$(CONFIG_MTD_NAND_MARVELL)		+= marvell_nand.o
 obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
 obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
 obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
new file mode 100644
index 000000000000..9d01120d97c5
--- /dev/null
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -0,0 +1,2897 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Marvell NAND flash controller driver
+ *
+ * Copyright (C) 2017 Marvell
+ * Author: Miquel RAYNAL <miquel.raynal at free-electrons.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/of_platform.h>
+#include <linux/iopoll.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <asm/unaligned.h>
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/pxa-dma.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+
+/* Data FIFO granularity, FIFO reads/writes must be a multiple of this length */
+#define FIFO_DEPTH		8
+#define FIFO_REP(x)		(x / sizeof(u32))
+#define BCH_SEQ_READS		(32 / FIFO_DEPTH)
+/* NFC does not support transfers of larger chunks at a time */
+#define MAX_CHUNK_SIZE		2112
+/* NFCv1 cannot read more that 7 bytes of ID */
+#define NFCV1_READID_LEN	7
+/* Polling is done at a pace of POLL_PERIOD us until POLL_TIMEOUT is reached */
+#define POLL_PERIOD		0
+#define POLL_TIMEOUT		100000
+/* Interrupt maximum wait period in ms */
+#define IRQ_TIMEOUT		1000
+/* Latency in clock cycles between SoC pins and NFC logic */
+#define MIN_RD_DEL_CNT		3
+/* Maximum number of contiguous address cycles */
+#define MAX_ADDRESS_CYC_NFCV1	5
+#define MAX_ADDRESS_CYC_NFCV2	7
+/* System control registers/bits to enable the NAND controller on some SoCs */
+#define GENCONF_SOC_DEVICE_MUX	0x208
+#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0)
+#define GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST BIT(20)
+#define GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST BIT(21)
+#define GENCONF_SOC_DEVICE_MUX_NFC_INT_EN BIT(25)
+#define GENCONF_CLK_GATING_CTRL	0x220
+#define GENCONF_CLK_GATING_CTRL_ND_GATE BIT(2)
+#define GENCONF_ND_CLK_CTRL	0x700
+#define GENCONF_ND_CLK_CTRL_EN	BIT(0)
+
+/* NAND controller data flash control register */
+#define NDCR			0x00
+#define NDCR_ALL_INT		GENMASK(11, 0)
+#define NDCR_CS1_CMDDM		BIT(7)
+#define NDCR_CS0_CMDDM		BIT(8)
+#define NDCR_RDYM		BIT(11)
+#define NDCR_ND_ARB_EN		BIT(12)
+#define NDCR_RA_START		BIT(15)
+#define NDCR_RD_ID_CNT(x)	(min_t(unsigned int, x, 0x7) << 16)
+#define NDCR_PAGE_SZ(x)		(x >= 2048 ? BIT(24) : 0)
+#define NDCR_DWIDTH_M		BIT(26)
+#define NDCR_DWIDTH_C		BIT(27)
+#define NDCR_ND_RUN		BIT(28)
+#define NDCR_DMA_EN		BIT(29)
+#define NDCR_ECC_EN		BIT(30)
+#define NDCR_SPARE_EN		BIT(31)
+
+/* NAND interface timing parameter 0 register */
+#define NDTR0			0x04
+#define NDTR0_TRP(x)		((min_t(unsigned int, x, 0xF) & 0x7) << 0)
+#define NDTR0_TRH(x)		(min_t(unsigned int, x, 0x7) << 3)
+#define NDTR0_ETRP(x)		((min_t(unsigned int, x, 0xF) & 0x8) << 3)
+#define NDTR0_SEL_NRE_EDGE	BIT(7)
+#define NDTR0_TWP(x)		(min_t(unsigned int, x, 0x7) << 8)
+#define NDTR0_TWH(x)		(min_t(unsigned int, x, 0x7) << 11)
+#define NDTR0_TCS(x)		(min_t(unsigned int, x, 0x7) << 16)
+#define NDTR0_TCH(x)		(min_t(unsigned int, x, 0x7) << 19)
+#define NDTR0_RD_CNT_DEL(x)	(min_t(unsigned int, x, 0xF) << 22)
+#define NDTR0_SELCNTR		BIT(26)
+#define NDTR0_TADL(x)		(min_t(unsigned int, x, 0x1F) << 27)
+
+/* NAND interface timing parameter 1 register */
+#define NDTR1			0x0C
+#define NDTR1_TAR(x)		(min_t(unsigned int, x, 0xF) << 0)
+#define NDTR1_TWHR(x)		(min_t(unsigned int, x, 0xF) << 4)
+#define NDTR1_TRHW(x)		(min_t(unsigned int, x / 16, 0x3) << 8)
+#define NDTR1_PRESCALE		BIT(14)
+#define NDTR1_WAIT_MODE		BIT(15)
+#define NDTR1_TR(x)		(min_t(unsigned int, x, 0xFFFF) << 16)
+
+/* NAND controller status register */
+#define NDSR			0x14
+#define NDSR_WRCMDREQ		BIT(0)
+#define NDSR_RDDREQ		BIT(1)
+#define NDSR_WRDREQ		BIT(2)
+#define NDSR_CORERR		BIT(3)
+#define NDSR_UNCERR		BIT(4)
+#define NDSR_CMDD(cs)		BIT(8 - cs)
+#define NDSR_RDY(rb)		BIT(11 + rb)
+#define NDSR_ERRCNT(x)		((x >> 16) & 0x1F)
+
+/* NAND ECC control register */
+#define NDECCCTRL		0x28
+#define NDECCCTRL_BCH_EN	BIT(0)
+
+/* NAND controller data buffer register */
+#define NDDB			0x40
+
+/* NAND controller command buffer 0 register */
+#define NDCB0			0x48
+#define NDCB0_CMD1(x)		((x & 0xFF) << 0)
+#define NDCB0_CMD2(x)		((x & 0xFF) << 8)
+#define NDCB0_ADDR_CYC(x)	((x & 0x7) << 16)
+#define NDCB0_DBC		BIT(19)
+#define NDCB0_CMD_TYPE(x)	((x & 0x7) << 21)
+#define NDCB0_CSEL		BIT(24)
+#define NDCB0_RDY_BYP		BIT(27)
+#define NDCB0_LEN_OVRD		BIT(28)
+#define NDCB0_CMD_XTYPE(x)	((x & 0x7) << 29)
+
+/* NAND controller command buffer 1 register */
+#define NDCB1			0x4C
+#define NDCB1_COLS(x)		((x & 0xFFFF) << 0)
+#define NDCB1_ADDRS_PAGE(x)	(x << 16)
+
+/* NAND controller command buffer 2 register */
+#define NDCB2			0x50
+#define NDCB2_ADDR5_PAGE(x)	(((x >> 16) & 0xFF) << 0)
+#define NDCB2_ADDR5_CYC(x)	((x & 0xFF) << 0)
+
+/* NAND controller command buffer 3 register */
+#define NDCB3			0x54
+#define NDCB3_ADDR6_CYC(x)	((x & 0xFF) << 16)
+#define NDCB3_ADDR7_CYC(x)	((x & 0xFF) << 24)
+
+/* NAND controller command buffer 0 register 'type' and 'xtype' fields */
+#define TYPE_READ		0
+#define TYPE_WRITE		1
+#define TYPE_ERASE		2
+#define TYPE_READ_ID		3
+#define TYPE_STATUS		4
+#define TYPE_RESET		5
+#define TYPE_NAKED_CMD		6
+#define TYPE_NAKED_ADDR		7
+#define TYPE_MASK		7
+#define XTYPE_MONOLITHIC_RW	0
+#define XTYPE_LAST_NAKED_RW	1
+#define XTYPE_FINAL_COMMAND	3
+#define XTYPE_READ		4
+#define XTYPE_WRITE_DISPATCH	4
+#define XTYPE_NAKED_RW		5
+#define XTYPE_COMMAND_DISPATCH	6
+#define XTYPE_MASK		7
+
+/**
+ * Marvell ECC engine works differently than the others, in order to limit the
+ * size of the IP, hardware engineers chose to set a fixed strength at 16 bits
+ * per subpage, and depending on a the desired strength needed by the NAND chip,
+ * a particular layout mixing data/spare/ecc is defined, with a possible last
+ * chunk smaller that the others.
+ *
+ * @writesize:		Full page size on which the layout applies
+ * @chunk:		Desired ECC chunk size on which the layout applies
+ * @strength:		Desired ECC strength (per chunk size bytes) on which the
+ *			layout applies
+ * @nchunks:		Total number of chunks
+ * @full_chunk_cnt:	Number of full-sized chunks, which is the number of
+ *			repetitions of the pattern:
+ *			(data_bytes + spare_bytes + ecc_bytes).
+ * @data_bytes:		Number of data bytes per chunk
+ * @spare_bytes:	Number of spare bytes per chunk
+ * @ecc_bytes:		Number of ecc bytes per chunk
+ * @last_data_bytes:	Number of data bytes in the last chunk
+ * @last_spare_bytes:	Number of spare bytes in the last chunk
+ * @last_ecc_bytes:	Number of ecc bytes in the last chunk
+ */
+struct marvell_hw_ecc_layout {
+	/* Constraints */
+	int writesize;
+	int chunk;
+	int strength;
+	/* Corresponding layout */
+	int nchunks;
+	int full_chunk_cnt;
+	int data_bytes;
+	int spare_bytes;
+	int ecc_bytes;
+	int last_data_bytes;
+	int last_spare_bytes;
+	int last_ecc_bytes;
+};
+
+#define MARVELL_LAYOUT(ws, dc, ds, nc, fcc, db, sb, eb, ldb, lsb, leb)	\
+	{								\
+		.writesize = ws,					\
+		.chunk = dc,						\
+		.strength = ds,						\
+		.nchunks = nc,						\
+		.full_chunk_cnt = fcc,					\
+		.data_bytes = db,					\
+		.spare_bytes = sb,					\
+		.ecc_bytes = eb,					\
+		.last_data_bytes = ldb,					\
+		.last_spare_bytes = lsb,				\
+		.last_ecc_bytes = leb,					\
+	}
+
+/* Layouts explained in AN-379_Marvell_SoC_NFC_ECC */
+static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = {
+	MARVELL_LAYOUT(  512,   512,  1,  1,  1,  512,  8,  8,  0,  0,  0),
+	MARVELL_LAYOUT( 2048,   512,  1,  1,  1, 2048, 40, 24,  0,  0,  0),
+	MARVELL_LAYOUT( 2048,   512,  4,  1,  1, 2048, 32, 30,  0,  0,  0),
+	MARVELL_LAYOUT( 4096,   512,  4,  2,  2, 2048, 32, 30,  0,  0,  0),
+	MARVELL_LAYOUT( 4096,   512,  8,  5,  4, 1024,  0, 30,  0, 64, 30),
+};
+
+/**
+ * The Nand Flash Controller has up to 4 CE and 2 RB pins. The CE selection
+ * is made by a field in NDCB0 register, and in another field in NDCB2 register.
+ * The datasheet describes the logic with an error: ADDR5 field is once
+ * declared at the beginning of NDCB2, and another time at its end. Because the
+ * ADDR5 field of NDCB2 may be used by other bytes, it would be more logical
+ * to use the last bit of this field instead of the first ones.
+ *
+ * @cs:			Wanted CE lane.
+ * @ndcb0_csel:		Value of the NDCB0 register with or without the flag
+ *			selecting the wanted CE lane. This is set once when
+ *			the Device Tree is probed.
+ * @rb:			Ready/Busy pin for the flash chip
+ */
+struct marvell_nand_chip_sel {
+	unsigned int cs;
+	u32 ndcb0_csel;
+	unsigned int rb;
+};
+
+/**
+ * NAND chip structure: stores NAND chip device related information
+ *
+ * @chip:		Base NAND chip structure
+ * @node:		Used to store NAND chips into a list
+ * @layout		NAND layout when using hardware ECC
+ * @ndcr:		Controller register value for this NAND chip
+ * @ndtr0:		Timing registers 0 value for this NAND chip
+ * @ndtr1:		Timing registers 1 value for this NAND chip
+ * @selected_die:	Current active CS
+ * @nsels:		Number of CS lines required by the NAND chip
+ * @sels:		Array of CS lines descriptions
+ */
+struct marvell_nand_chip {
+	struct nand_chip chip;
+	struct list_head node;
+	const struct marvell_hw_ecc_layout *layout;
+	u32 ndcr;
+	u32 ndtr0;
+	u32 ndtr1;
+	int addr_cyc;
+	int selected_die;
+	unsigned int nsels;
+	struct marvell_nand_chip_sel sels[0];
+};
+
+static inline struct marvell_nand_chip *to_marvell_nand(struct nand_chip *chip)
+{
+	return container_of(chip, struct marvell_nand_chip, chip);
+}
+
+static inline struct marvell_nand_chip_sel *to_nand_sel(struct marvell_nand_chip
+							*nand)
+{
+	return &nand->sels[nand->selected_die];
+}
+
+/**
+ * NAND controller capabilities for distinction between compatible strings
+ *
+ * @max_cs_nb:		Number of Chip Select lines available
+ * @max_rb_nb:		Number of Ready/Busy lines available
+ * @need_system_controller: Indicates if the SoC needs to have access to the
+ *                      system controller (ie. to enable the NAND controller)
+ * @legacy_of_bindings:	Indicates if DT parsing must be done using the old
+ *			fashion way
+ * @is_nfcv2:		NFCv2 has numerous enhancements compared to NFCv1, ie.
+ *			BCH error detection and correction algorithm,
+ *			NDCB3 register has been added
+ * @use_dma:		Use dma for data transfers
+ */
+struct marvell_nfc_caps {
+	unsigned int max_cs_nb;
+	unsigned int max_rb_nb;
+	bool need_system_controller;
+	bool legacy_of_bindings;
+	bool is_nfcv2;
+	bool use_dma;
+};
+
+/**
+ * NAND controller structure: stores Marvell NAND controller information
+ *
+ * @controller:		Base controller structure
+ * @dev:		Parent device (used to print error messages)
+ * @regs:		NAND controller registers
+ * @ecc_clk:		ECC block clock, two times the NAND controller clock
+ * @complete:		Completion object to wait for NAND controller events
+ * @assigned_cs:	Bitmask describing already assigned CS lines
+ * @chips:		List containing all the NAND chips attached to
+ *			this NAND controller
+ * @caps:		NAND controller capabilities for each compatible string
+ * @dma_chan:		DMA channel (NFCv1 only)
+ * @dma_buf:		32-bit aligned buffer for DMA transfers (NFCv1 only)
+ */
+struct marvell_nfc {
+	struct nand_hw_control controller;
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *ecc_clk;
+	struct completion complete;
+	unsigned long assigned_cs;
+	struct list_head chips;
+	struct nand_chip *selected_chip;
+	const struct marvell_nfc_caps *caps;
+
+	/* DMA (NFCv1 only) */
+	bool use_dma;
+	struct dma_chan *dma_chan;
+	u8 *dma_buf;
+};
+
+static inline struct marvell_nfc *to_marvell_nfc(struct nand_hw_control *ctrl)
+{
+	return container_of(ctrl, struct marvell_nfc, controller);
+}
+
+/**
+ * NAND controller timings expressed in NAND Controller clock cycles
+ *
+ * @tRP:		ND_nRE pulse width
+ * @tRH:		ND_nRE high duration
+ * @tWP:		ND_nWE pulse time
+ * @tWH:		ND_nWE high duration
+ * @tCS:		Enable signal setup time
+ * @tCH:		Enable signal hold time
+ * @tADL:		Address to write data delay
+ * @tAR:		ND_ALE low to ND_nRE low delay
+ * @tWHR:		ND_nWE high to ND_nRE low for status read
+ * @tRHW:		ND_nRE high duration, read to write delay
+ * @tR:			ND_nWE high to ND_nRE low for read
+ */
+struct marvell_nfc_timings {
+	/* NDTR0 fields */
+	unsigned int tRP;
+	unsigned int tRH;
+	unsigned int tWP;
+	unsigned int tWH;
+	unsigned int tCS;
+	unsigned int tCH;
+	unsigned int tADL;
+	/* NDTR1 fields */
+	unsigned int tAR;
+	unsigned int tWHR;
+	unsigned int tRHW;
+	unsigned int tR;
+};
+
+/**
+ * Derives a duration in numbers of clock cycles.
+ *
+ * @ps: Duration in pico-seconds
+ * @period_ns:  Clock period in nano-seconds
+ *
+ * Convert the duration in nano-seconds, then divide by the period and
+ * return the number of clock periods.
+ */
+#define TO_CYCLES(ps, period_ns) (DIV_ROUND_UP(ps / 1000, period_ns))
+
+/**
+ * NAND driver structure filled during the parsing of the ->exec_op() subop
+ * subset of instructions.
+ *
+ * @ndcb:		Array of values written to NDCBx registers
+ * @cle_ale_delay_ns:	Optional delay after the last CMD or ADDR cycle
+ * @rdy_timeout_ms:	Timeout for waits on Ready/Busy pin
+ * @rdy_delay_ns:	Optional delay after waiting for the RB pin
+ * @data_delay_ns:	Optional delay after the data xfer
+ * @data_instr_idx:	Index of the data instruction in the subop
+ * @data_instr:		Pointer to the data instruction in the subop
+ */
+struct marvell_nfc_op {
+	u32 ndcb[4];
+	unsigned int cle_ale_delay_ns;
+	unsigned int rdy_timeout_ms;
+	unsigned int rdy_delay_ns;
+	unsigned int data_delay_ns;
+	unsigned int data_instr_idx;
+	const struct nand_op_instr *data_instr;
+};
+
+/*
+ * Internal helper to conditionnally apply a delay (from the above structure,
+ * most of the time).
+ */
+static void cond_delay(unsigned int ns)
+{
+	if (!ns)
+		return;
+
+	if (ns < 10000)
+		ndelay(ns);
+	else
+		udelay(DIV_ROUND_UP(ns, 1000));
+}
+
+/*
+ * The controller has many flags that could generate interrupts, most of them
+ * are disabled and polling is used. For the very slow signals, using interrupts
+ * may relax the CPU charge.
+ */
+static void marvell_nfc_disable_int(struct marvell_nfc *nfc, u32 int_mask)
+{
+	u32 reg;
+
+	/* Writing 1 disables the interrupt */
+	reg = readl_relaxed(nfc->regs + NDCR);
+	writel_relaxed(reg | int_mask, nfc->regs + NDCR);
+}
+
+static void marvell_nfc_enable_int(struct marvell_nfc *nfc, u32 int_mask)
+{
+	u32 reg;
+
+	/* Writing 0 enables the interrupt */
+	reg = readl_relaxed(nfc->regs + NDCR);
+	writel_relaxed(reg & ~int_mask, nfc->regs + NDCR);
+}
+
+static void marvell_nfc_clear_int(struct marvell_nfc *nfc, u32 int_mask)
+{
+	writel_relaxed(int_mask, nfc->regs + NDSR);
+}
+
+static void marvell_nfc_force_byte_access(struct nand_chip *chip,
+					  bool force_8bit)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 ndcr;
+
+	/*
+	 * Callers of this function do not verify if the NAND is using a 16-bit
+	 * an 8-bit bus for normal operations, so we need to take care of that
+	 * here by leaving the configuration unchanged if the NAND does not have
+	 * the NAND_BUSWIDTH_16 flag set.
+	 */
+	if (!(chip->options & NAND_BUSWIDTH_16))
+		return;
+
+	ndcr = readl_relaxed(nfc->regs + NDCR);
+
+	if (force_8bit)
+		ndcr &= ~(NDCR_DWIDTH_M | NDCR_DWIDTH_C);
+	else
+		ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
+
+	writel_relaxed(ndcr, nfc->regs + NDCR);
+}
+
+static int marvell_nfc_wait_ndrun(struct nand_chip *chip)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 val;
+	int ret;
+
+	/*
+	 * The command is being processed, wait for the ND_RUN bit to be
+	 * cleared by the NFC. If not, we must clear it by hand.
+	 */
+	ret = readl_relaxed_poll_timeout(nfc->regs + NDCR, val,
+					 (val & NDCR_ND_RUN) == 0,
+					 POLL_PERIOD, POLL_TIMEOUT);
+	if (ret) {
+		dev_err(nfc->dev, "Timeout on NAND controller run mode\n");
+		writel_relaxed(readl(nfc->regs + NDCR) & ~NDCR_ND_RUN,
+			       nfc->regs + NDCR);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Any time a command has to be sent to the controller, the following sequence
+ * has to be followed:
+ * - call marvell_nfc_prepare_cmd()
+ *      -> activate the ND_RUN bit that will kind of 'start a job'
+ *      -> wait the signal indicating the NFC is waiting for a command
+ * - send the command (cmd and address cycles)
+ * - enventually send or receive the data
+ * - call marvell_nfc_end_cmd() with the corresponding flag
+ *      -> wait the flag to be triggered or cancel the job with a timeout
+ *
+ * The following helpers are here to factorize the code a bit so that
+ * specialized functions responsible for executing the actual NAND
+ * operations do not have to replicate the same code blocks.
+ */
+static int marvell_nfc_prepare_cmd(struct nand_chip *chip)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 ndcr, val;
+	int ret;
+
+	/* Poll ND_RUN and clear NDSR before issuing any command */
+	ret = marvell_nfc_wait_ndrun(chip);
+	if (ret) {
+		dev_err(nfc->dev, "Last operation did not suceed\n");
+		return ret;
+	}
+
+	ndcr = readl_relaxed(nfc->regs + NDCR);
+	writel_relaxed(readl(nfc->regs + NDSR), nfc->regs + NDSR);
+
+	/* Assert ND_RUN bit and wait the NFC to be ready */
+	writel_relaxed(ndcr | NDCR_ND_RUN, nfc->regs + NDCR);
+	ret = readl_relaxed_poll_timeout(nfc->regs + NDSR, val,
+					 val & NDSR_WRCMDREQ,
+					 POLL_PERIOD, POLL_TIMEOUT);
+	if (ret) {
+		dev_err(nfc->dev, "Timeout on WRCMDRE\n");
+		return -ETIMEDOUT;
+	}
+
+	/* Command may be written, clear WRCMDREQ status bit */
+	writel_relaxed(NDSR_WRCMDREQ, nfc->regs + NDSR);
+
+	return 0;
+}
+
+static void marvell_nfc_send_cmd(struct nand_chip *chip,
+				 struct marvell_nfc_op *nfc_op)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+
+	dev_dbg(nfc->dev, "\nNDCR:  0x%08x\n"
+		"NDCB0: 0x%08x\nNDCB1: 0x%08x\nNDCB2: 0x%08x\nNDCB3: 0x%08x\n",
+		(u32)readl_relaxed(nfc->regs + NDCR), nfc_op->ndcb[0],
+		nfc_op->ndcb[1], nfc_op->ndcb[2], nfc_op->ndcb[3]);
+
+	writel_relaxed(to_nand_sel(marvell_nand)->ndcb0_csel | nfc_op->ndcb[0],
+		       nfc->regs + NDCB0);
+	writel_relaxed(nfc_op->ndcb[1], nfc->regs + NDCB0);
+	writel(nfc_op->ndcb[2], nfc->regs + NDCB0);
+
+	/*
+	 * Write NDCB0 four times only if LEN_OVRD is set or if ADDR6 or ADDR7
+	 * fields are used (only available on NFCv2).
+	 */
+	if (nfc_op->ndcb[0] & NDCB0_LEN_OVRD ||
+	    (nfc_op->ndcb[0] & NDCB0_ADDR_CYC(6)) == NDCB0_ADDR_CYC(6)) {
+		if (nfc->caps->is_nfcv2)
+			writel(nfc_op->ndcb[3], nfc->regs + NDCB0);
+		else
+			dev_err(nfc->dev,
+				"NDCB3 does not exist on NFCv1 and should not be written\n");
+	}
+}
+
+static int marvell_nfc_end_cmd(struct nand_chip *chip, int flag,
+			       const char *label)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 val;
+	int ret;
+
+	ret = readl_relaxed_poll_timeout(nfc->regs + NDSR, val,
+					 val & flag,
+					 POLL_PERIOD, POLL_TIMEOUT);
+
+	if (ret) {
+		dev_err(nfc->dev, "Timeout on %s (NDSR: 0x%08x)\n",
+			label, val);
+		if (nfc->dma_chan)
+			dmaengine_terminate_all(nfc->dma_chan);
+		return ret;
+	}
+
+	/*
+	 * DMA function uses this helper to poll on CMDD bits without wanting
+	 * them to be bleared.
+	 */
+	if (nfc->use_dma && (readl_relaxed(nfc->regs + NDCR) & NDCR_DMA_EN))
+		return 0;
+
+	writel_relaxed(flag, nfc->regs + NDSR);
+
+	return 0;
+}
+
+static int marvell_nfc_wait_cmdd(struct nand_chip *chip)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	int cs_flag = NDSR_CMDD(to_nand_sel(marvell_nand)->ndcb0_csel);
+
+	return marvell_nfc_end_cmd(chip, cs_flag, "CMDD");
+}
+
+static int marvell_nfc_wait_op(struct nand_chip *chip, unsigned int timeout_ms)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	int ret;
+
+	/* Timeout is expressed in ms */
+	if (!timeout_ms)
+		timeout_ms = IRQ_TIMEOUT;
+
+	init_completion(&nfc->complete);
+
+	marvell_nfc_enable_int(nfc, NDCR_RDYM);
+	ret = wait_for_completion_timeout(&nfc->complete,
+					  msecs_to_jiffies(timeout_ms));
+	marvell_nfc_disable_int(nfc, NDCR_RDYM);
+	marvell_nfc_clear_int(nfc, NDSR_RDY(0) | NDSR_RDY(1));
+	if (!ret) {
+		dev_err(nfc->dev, "Timeout waiting for RB signal\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static void marvell_nfc_select_chip(struct mtd_info *mtd, int die_nr)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+
+	if (chip == nfc->selected_chip && die_nr == marvell_nand->selected_die)
+		return;
+
+	if (die_nr < 0 || die_nr >= marvell_nand->nsels) {
+		nfc->selected_chip = NULL;
+		marvell_nand->selected_die = -1;
+		return;
+	}
+
+	/*
+	 * Do not change the timing registers when using the DT property
+	 * marvell,nand-keep-config; in that case ->ndtr0 and ->ndtr1 from the
+	 * marvell_nand structure are supposedly empty.
+	 */
+	if (marvell_nand->ndtr0 && marvell_nand->ndtr1) {
+		writel_relaxed(marvell_nand->ndtr0, nfc->regs + NDTR0);
+		writel_relaxed(marvell_nand->ndtr1, nfc->regs + NDTR1);
+	}
+
+	/* Reset the NDCR register to a clean state for this particular chip */
+	if (marvell_nand->ndcr)
+		writel_relaxed(marvell_nand->ndcr, nfc->regs + NDCR);
+
+	/* Also reset the interrupt status register */
+	marvell_nfc_clear_int(nfc, NDCR_ALL_INT);
+
+	nfc->selected_chip = chip;
+	marvell_nand->selected_die = die_nr;
+}
+
+static irqreturn_t marvell_nfc_isr(int irq, void *dev_id)
+{
+	struct marvell_nfc *nfc = dev_id;
+	u32 st = readl_relaxed(nfc->regs + NDSR);
+	u32 ien = (~readl_relaxed(nfc->regs + NDCR)) & NDCR_ALL_INT;
+
+	/*
+	 * RDY interrupt mask is one bit in NDCR while there are two status
+	 * bit in NDSR (RDY[cs0/cs2] and RDY[cs1/cs3]).
+	 */
+	if (st & NDSR_RDY(1))
+		st |= NDSR_RDY(0);
+
+	if (!(st & ien))
+		return IRQ_NONE;
+
+	marvell_nfc_disable_int(nfc, st & NDCR_ALL_INT);
+
+	if (!(st & (NDSR_RDDREQ | NDSR_WRDREQ | NDSR_WRCMDREQ)))
+		complete(&nfc->complete);
+
+	return IRQ_HANDLED;
+}
+
+/* HW ECC related functions */
+static void marvell_nfc_enable_hw_ecc(struct nand_chip *chip)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 ndcr = readl_relaxed(nfc->regs + NDCR);
+
+	if (!(ndcr & NDCR_ECC_EN)) {
+		writel_relaxed(ndcr | NDCR_ECC_EN, nfc->regs + NDCR);
+
+		/*
+		 * When enabling BCH, set threshold to 0 to always know the
+		 * number of corrected bitflips.
+		 */
+		if (chip->ecc.algo == NAND_ECC_BCH)
+			writel_relaxed(NDECCCTRL_BCH_EN, nfc->regs + NDECCCTRL);
+	}
+}
+
+static void marvell_nfc_disable_hw_ecc(struct nand_chip *chip)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	u32 ndcr = readl_relaxed(nfc->regs + NDCR);
+
+	if (ndcr & NDCR_ECC_EN) {
+		writel_relaxed(ndcr & ~NDCR_ECC_EN, nfc->regs + NDCR);
+		if (chip->ecc.algo == NAND_ECC_BCH)
+			writel_relaxed(0, nfc->regs + NDECCCTRL);
+	}
+}
+
+/* DMA related helpers */
+static void marvell_nfc_enable_dma(struct marvell_nfc *nfc)
+{
+	u32 reg;
+
+	reg = readl_relaxed(nfc->regs + NDCR);
+	writel_relaxed(reg | NDCR_DMA_EN, nfc->regs + NDCR);
+}
+
+static void marvell_nfc_disable_dma(struct marvell_nfc *nfc)
+{
+	u32 reg;
+
+	reg = readl_relaxed(nfc->regs + NDCR);
+	writel_relaxed(reg & ~NDCR_DMA_EN, nfc->regs + NDCR);
+}
+
+/* Read/write PIO/DMA accessors */
+static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,
+				     enum dma_data_direction direction,
+				     unsigned int len)
+{
+	unsigned int dma_len = min_t(int, ALIGN(len, 32), MAX_CHUNK_SIZE);
+	struct dma_async_tx_descriptor *tx;
+	struct scatterlist sg;
+	dma_cookie_t cookie;
+	int ret;
+
+	marvell_nfc_enable_dma(nfc);
+	/* Prepare the DMA transfer */
+	sg_init_one(&sg, nfc->dma_buf, dma_len);
+	dma_map_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+	tx = dmaengine_prep_slave_sg(nfc->dma_chan, &sg, 1,
+				     direction == DMA_FROM_DEVICE ?
+				     DMA_DEV_TO_MEM : DMA_MEM_TO_DEV,
+				     DMA_PREP_INTERRUPT);
+	if (!tx) {
+		dev_err(nfc->dev, "Could not prepare DMA S/G list\n");
+		return -ENXIO;
+	}
+
+	/* Do the task and wait for it to finish */
+	cookie = dmaengine_submit(tx);
+	ret = dma_submit_error(cookie);
+	if (ret)
+		return -EIO;
+
+	dma_async_issue_pending(nfc->dma_chan);
+	ret = marvell_nfc_wait_cmdd(nfc->selected_chip);
+	dma_unmap_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+	marvell_nfc_disable_dma(nfc);
+	if (ret) {
+		dev_err(nfc->dev, "Timeout waiting for DMA (status: %d)\n",
+			dmaengine_tx_status(nfc->dma_chan, cookie, NULL));
+		dmaengine_terminate_all(nfc->dma_chan);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int marvell_nfc_xfer_data_in_pio(struct marvell_nfc *nfc, u8 *in,
+					unsigned int len)
+{
+	unsigned int last_len = len % FIFO_DEPTH;
+	unsigned int last_full_offset = round_down(len, FIFO_DEPTH);
+	int i;
+
+	for (i = 0; i < last_full_offset; i += FIFO_DEPTH)
+		ioread32_rep(nfc->regs + NDDB, in + i, FIFO_REP(FIFO_DEPTH));
+
+	if (last_len) {
+		u8 tmp_buf[FIFO_DEPTH];
+
+		ioread32_rep(nfc->regs + NDDB, tmp_buf, FIFO_REP(FIFO_DEPTH));
+		memcpy(in + last_full_offset, tmp_buf, last_len);
+	}
+
+	return 0;
+}
+
+static int marvell_nfc_xfer_data_out_pio(struct marvell_nfc *nfc, const u8 *out,
+					 unsigned int len)
+{
+	unsigned int last_len = len % FIFO_DEPTH;
+	unsigned int last_full_offset = round_down(len, FIFO_DEPTH);
+	int i;
+
+	for (i = 0; i < last_full_offset; i += FIFO_DEPTH)
+		iowrite32_rep(nfc->regs + NDDB, out + i, FIFO_REP(FIFO_DEPTH));
+
+	if (last_len) {
+		u8 tmp_buf[FIFO_DEPTH];
+
+		memcpy(tmp_buf, out + last_full_offset, last_len);
+		iowrite32_rep(nfc->regs + NDDB, tmp_buf, FIFO_REP(FIFO_DEPTH));
+	}
+
+	return 0;
+}
+
+static void marvell_nfc_check_empty_chunk(struct nand_chip *chip,
+					  u8 *data, int data_len,
+					  u8 *spare, int spare_len,
+					  u8 *ecc, int ecc_len,
+					  unsigned int *max_bitflips)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int bf;
+
+	/*
+	 * Blank pages (all 0xFF) that have not been written may be recognized
+	 * as bad if bitflips occur, so whenever an uncorrectable error occurs,
+	 * check if the entire page (with ECC bytes) is actually blank or not.
+	 */
+	if (!data)
+		data_len = 0;
+	if (!spare)
+		spare_len = 0;
+	if (!ecc)
+		ecc_len = 0;
+
+	bf = nand_check_erased_ecc_chunk(data, data_len, ecc, ecc_len,
+					 spare, spare_len, chip->ecc.strength);
+	if (bf < 0) {
+		mtd->ecc_stats.failed++;
+		return;
+	}
+
+	/* Update the stats and max_bitflips */
+	mtd->ecc_stats.corrected += bf;
+	*max_bitflips = max_t(unsigned int, *max_bitflips, bf);
+}
+
+/*
+ * Check a chunk is correct or not according to hardware ECC engine.
+ * mtd->ecc_stats.corrected is updated, as well as max_bitflips, however
+ * mtd->ecc_stats.failure is not, the function will instead return a non-zero
+ * value indicating that a check on the emptyness of the subpage must be
+ * performed before declaring the subpage corrupted.
+ */
+static int marvell_nfc_hw_ecc_correct(struct nand_chip *chip,
+				      unsigned int *max_bitflips)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	int bf = 0;
+	u32 ndsr;
+
+	ndsr = readl_relaxed(nfc->regs + NDSR);
+
+	/* Check uncorrectable error flag */
+	if (ndsr & NDSR_UNCERR) {
+		writel_relaxed(ndsr, nfc->regs + NDSR);
+
+		/*
+		 * Do not increment ->ecc_stats.failed now, instead, return a
+		 * non-zero value to indicate that this chunk was apparently
+		 * bad, and it should be check to see if it empty or not. If
+		 * the chunk (with ECC bytes) is not declared empty, the calling
+		 * function must increment the failure count.
+		 */
+		return -EBADMSG;
+	}
+
+	/* Check correctable error flag */
+	if (ndsr & NDSR_CORERR) {
+		writel_relaxed(ndsr, nfc->regs + NDSR);
+
+		if (chip->ecc.algo == NAND_ECC_BCH)
+			bf = NDSR_ERRCNT(ndsr);
+		else
+			bf = 1;
+	}
+
+	/* Update the stats and max_bitflips */
+	mtd->ecc_stats.corrected += bf;
+	*max_bitflips = max_t(unsigned int, *max_bitflips, bf);
+
+	return 0;
+}
+
+/* Hamming read helpers */
+static int marvell_nfc_hw_ecc_hmg_do_read_page(struct nand_chip *chip,
+					       u8 *data_buf, u8 *oob_buf,
+					       bool raw, int page)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	struct marvell_nfc_op nfc_op = {
+		.ndcb[0] = NDCB0_CMD_TYPE(TYPE_READ) |
+			   NDCB0_ADDR_CYC(marvell_nand->addr_cyc) |
+			   NDCB0_DBC |
+			   NDCB0_CMD1(NAND_CMD_READ0) |
+			   NDCB0_CMD2(NAND_CMD_READSTART),
+		.ndcb[1] = NDCB1_ADDRS_PAGE(page),
+		.ndcb[2] = NDCB2_ADDR5_PAGE(page),
+	};
+	unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
+	int ret;
+
+	/* NFCv2 needs more information about the operation being executed */
+	if (nfc->caps->is_nfcv2)
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_RDDREQ,
+				  "RDDREQ while draining FIFO (data/oob)");
+	if (ret)
+		return ret;
+
+	/*
+	 * Read the page then the OOB area. Unlike what is shown in current
+	 * documentation, spare bytes are protected by the ECC engine, and must
+	 * be at the beginning of the OOB area or running this driver on legacy
+	 * systems will prevent the discovery of the BBM/BBT.
+	 */
+	if (nfc->use_dma) {
+		marvell_nfc_xfer_data_dma(nfc, DMA_FROM_DEVICE,
+					  lt->data_bytes + oob_bytes);
+		memcpy(data_buf, nfc->dma_buf, lt->data_bytes);
+		memcpy(oob_buf, nfc->dma_buf + lt->data_bytes, oob_bytes);
+	} else {
+		marvell_nfc_xfer_data_in_pio(nfc, data_buf, lt->data_bytes);
+		marvell_nfc_xfer_data_in_pio(nfc, oob_buf, oob_bytes);
+	}
+
+	ret = marvell_nfc_wait_cmdd(chip);
+
+	return ret;
+}
+
+static int marvell_nfc_hw_ecc_hmg_read_page_raw(struct mtd_info *mtd,
+						struct nand_chip *chip, u8 *buf,
+						int oob_required, int page)
+{
+	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi,
+						   true, page);
+}
+
+static int marvell_nfc_hw_ecc_hmg_read_page(struct mtd_info *mtd,
+					    struct nand_chip *chip,
+					    u8 *buf, int oob_required,
+					    int page)
+{
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	unsigned int full_sz = lt->data_bytes + lt->spare_bytes + lt->ecc_bytes;
+	int max_bitflips = 0, ret;
+	u8 *raw_buf;
+
+	marvell_nfc_enable_hw_ecc(chip);
+	marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, false,
+					    page);
+	ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips);
+	marvell_nfc_disable_hw_ecc(chip);
+
+	if (!ret)
+		return max_bitflips;
+
+	/*
+	 * When ECC failures are detected, check if the full page has been
+	 * written or not. Ignore the failure if it is actually empty.
+	 */
+	raw_buf = kmalloc(full_sz, GFP_KERNEL);
+	if (!raw_buf)
+		return -ENOMEM;
+
+	marvell_nfc_hw_ecc_hmg_do_read_page(chip, raw_buf, raw_buf +
+					    lt->data_bytes, true, page);
+	marvell_nfc_check_empty_chunk(chip, raw_buf, full_sz, NULL, 0, NULL, 0,
+				      &max_bitflips);
+	kfree(raw_buf);
+
+	return max_bitflips;
+}
+
+/*
+ * Spare area in Hamming layouts is not protected by the ECC engine (even if
+ * it appears before the ECC bytes when reading), the ->read_oob_raw() function
+ * also stands for ->read_oob().
+ */
+static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct mtd_info *mtd,
+					       struct nand_chip *chip, int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, chip->data_buf,
+						   chip->oob_poi, true, page);
+}
+
+/* Hamming write helpers */
+static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
+						const u8 *data_buf,
+						const u8 *oob_buf, bool raw,
+						int page)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	struct marvell_nfc_op nfc_op = {
+		.ndcb[0] = NDCB0_CMD_TYPE(TYPE_WRITE) |
+			   NDCB0_ADDR_CYC(marvell_nand->addr_cyc) |
+			   NDCB0_CMD1(NAND_CMD_SEQIN) |
+			   NDCB0_CMD2(NAND_CMD_PAGEPROG) |
+			   NDCB0_DBC,
+		.ndcb[1] = NDCB1_ADDRS_PAGE(page),
+		.ndcb[2] = NDCB2_ADDR5_PAGE(page),
+	};
+	unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
+	int ret;
+
+	/* NFCv2 needs more information about the operation being executed */
+	if (nfc->caps->is_nfcv2)
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_WRDREQ,
+				  "WRDREQ while loading FIFO (data)");
+	if (ret)
+		return ret;
+
+	/* Write the page then the OOB area */
+	if (nfc->use_dma) {
+		memcpy(nfc->dma_buf, data_buf, lt->data_bytes);
+		memcpy(nfc->dma_buf + lt->data_bytes, oob_buf, oob_bytes);
+		marvell_nfc_xfer_data_dma(nfc, DMA_TO_DEVICE, lt->data_bytes +
+					  lt->ecc_bytes + lt->spare_bytes);
+	} else {
+		marvell_nfc_xfer_data_out_pio(nfc, data_buf, lt->data_bytes);
+		marvell_nfc_xfer_data_out_pio(nfc, oob_buf, oob_bytes);
+	}
+
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	ret = marvell_nfc_wait_op(chip,
+				  chip->data_interface.timings.sdr.tPROG_max);
+	return ret;
+}
+
+static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct mtd_info *mtd,
+						 struct nand_chip *chip,
+						 const u8 *buf,
+						 int oob_required, int page)
+{
+	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
+						    true, page);
+}
+
+static int marvell_nfc_hw_ecc_hmg_write_page(struct mtd_info *mtd,
+					     struct nand_chip *chip,
+					     const u8 *buf,
+					     int oob_required, int page)
+{
+	int ret;
+
+	marvell_nfc_enable_hw_ecc(chip);
+	ret = marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
+						   false, page);
+	marvell_nfc_disable_hw_ecc(chip);
+
+	return ret;
+}
+
+/*
+ * Spare area in Hamming layouts is not protected by the ECC engine (even if
+ * it appears before the ECC bytes when reading), the ->write_oob_raw() function
+ * also stands for ->write_oob().
+ */
+static int marvell_nfc_hw_ecc_hmg_write_oob_raw(struct mtd_info *mtd,
+						struct nand_chip *chip,
+						int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	memset(chip->data_buf, 0xFF, mtd->writesize);
+
+	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, chip->data_buf,
+						    chip->oob_poi, true, page);
+}
+
+/* BCH read helpers */
+static int marvell_nfc_hw_ecc_bch_read_page_raw(struct mtd_info *mtd,
+						struct nand_chip *chip, u8 *buf,
+						int oob_required, int page)
+{
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	u8 *oob = chip->oob_poi;
+	int chunk_size = lt->data_bytes + lt->spare_bytes + lt->ecc_bytes;
+	int ecc_offset = (lt->full_chunk_cnt * lt->spare_bytes) +
+		lt->last_spare_bytes;
+	int data_len = lt->data_bytes;
+	int spare_len = lt->spare_bytes;
+	int ecc_len = lt->ecc_bytes;
+	int chunk;
+
+	if (oob_required)
+		memset(chip->oob_poi, 0xFF, mtd->oobsize);
+
+	nand_read_page_op(chip, page, 0, NULL, 0);
+
+	for (chunk = 0; chunk < lt->nchunks; chunk++) {
+		/* Update last chunk length */
+		if (chunk >= lt->full_chunk_cnt) {
+			data_len = lt->last_data_bytes;
+			spare_len = lt->last_spare_bytes;
+			ecc_len = lt->last_ecc_bytes;
+		}
+
+		/* Read data bytes*/
+		nand_change_read_column_op(chip, chunk * chunk_size,
+					   buf + (lt->data_bytes * chunk),
+					   data_len, false);
+
+		/* Read spare bytes */
+		nand_read_data_op(chip, oob + (lt->spare_bytes * chunk),
+				  spare_len, false);
+
+		/* Read ECC bytes */
+		nand_read_data_op(chip, oob + ecc_offset +
+				  (ALIGN(lt->ecc_bytes, 32) * chunk),
+				  ecc_len, false);
+	}
+
+	return 0;
+}
+
+static void marvell_nfc_hw_ecc_bch_read_chunk(struct nand_chip *chip, int chunk,
+					      u8 *data, unsigned int data_len,
+					      u8 *spare, unsigned int spare_len,
+					      int page)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	int i, ret;
+	struct marvell_nfc_op nfc_op = {
+		.ndcb[0] = NDCB0_CMD_TYPE(TYPE_READ) |
+			   NDCB0_ADDR_CYC(marvell_nand->addr_cyc) |
+			   NDCB0_LEN_OVRD,
+		.ndcb[1] = NDCB1_ADDRS_PAGE(page),
+		.ndcb[2] = NDCB2_ADDR5_PAGE(page),
+		.ndcb[3] = data_len + spare_len,
+	};
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return;
+
+	if (chunk == 0)
+		nfc_op.ndcb[0] |= NDCB0_DBC |
+				  NDCB0_CMD1(NAND_CMD_READ0) |
+				  NDCB0_CMD2(NAND_CMD_READSTART);
+
+	/*
+	 * Trigger the naked read operation only on the last chunk.
+	 * Otherwise, use monolithic read.
+	 */
+	if (lt->nchunks == 1 || (chunk < lt->nchunks - 1))
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW);
+	else
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW);
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+
+	/*
+	 * According to the datasheet, when reading from NDDB
+	 * with BCH enabled, after each 32 bytes reads, we
+	 * have to make sure that the NDSR.RDDREQ bit is set.
+	 *
+	 * Drain the FIFO, 8 32-bit reads at a time, and skip
+	 * the polling on the last read.
+	 *
+	 * Length is a multiple of 32 bytes, hence it is a multiple of 8 too.
+	 */
+	for (i = 0; i < data_len; i += FIFO_DEPTH * BCH_SEQ_READS) {
+		marvell_nfc_end_cmd(chip, NDSR_RDDREQ,
+				    "RDDREQ while draining FIFO (data)");
+		marvell_nfc_xfer_data_in_pio(nfc, data,
+					     FIFO_DEPTH * BCH_SEQ_READS);
+		data += FIFO_DEPTH * BCH_SEQ_READS;
+	}
+
+	for (i = 0; i < spare_len; i += FIFO_DEPTH * BCH_SEQ_READS) {
+		marvell_nfc_end_cmd(chip, NDSR_RDDREQ,
+				    "RDDREQ while draining FIFO (OOB)");
+		marvell_nfc_xfer_data_in_pio(nfc, spare,
+					     FIFO_DEPTH * BCH_SEQ_READS);
+		spare += FIFO_DEPTH * BCH_SEQ_READS;
+	}
+}
+
+static int marvell_nfc_hw_ecc_bch_read_page(struct mtd_info *mtd,
+					    struct nand_chip *chip,
+					    u8 *buf, int oob_required,
+					    int page)
+{
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	int data_len = lt->data_bytes, spare_len = lt->spare_bytes, ecc_len;
+	u8 *data = buf, *spare = chip->oob_poi, *ecc;
+	int max_bitflips = 0;
+	u32 failure_mask = 0;
+	int chunk, ecc_offset_in_page, ret;
+
+	/*
+	 * With BCH, OOB is not fully used (and thus not read entirely), not
+	 * expected bytes could show up at the end of the OOB buffer if not
+	 * explicitly erased.
+	 */
+	if (oob_required)
+		memset(chip->oob_poi, 0xFF, mtd->oobsize);
+
+	marvell_nfc_enable_hw_ecc(chip);
+
+	for (chunk = 0; chunk < lt->nchunks; chunk++) {
+		/* Update length for the last chunk */
+		if (chunk >= lt->full_chunk_cnt) {
+			data_len = lt->last_data_bytes;
+			spare_len = lt->last_spare_bytes;
+		}
+
+		/* Read the chunk and detect number of bitflips */
+		marvell_nfc_hw_ecc_bch_read_chunk(chip, chunk, data, data_len,
+						  spare, spare_len, page);
+		ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips);
+		if (ret)
+			failure_mask |= BIT(chunk);
+
+		data += data_len;
+		spare += spare_len;
+	}
+
+	marvell_nfc_disable_hw_ecc(chip);
+
+	if (!failure_mask)
+		return max_bitflips;
+
+	/*
+	 * Please note that dumping the ECC bytes during a normal read with OOB
+	 * area would add a significant overhead as ECC bytes are "consumed" by
+	 * the controller in normal mode and must be re-read in raw mode. To
+	 * avoid dropping the performances, we prefer not to include them. The
+	 * user should re-read the page in raw mode if ECC bytes are required.
+	 *
+	 * However, for any subpage read error reported by ->correct(), the ECC
+	 * bytes must be read in raw mode and the full subpage must be checked
+	 * to see if it is entirely empty of if there was an actual error.
+	 */
+	for (chunk = 0; chunk < lt->nchunks; chunk++) {
+		/* No failure reported for this chunk, move to the next one */
+		if (!(failure_mask & BIT(chunk)))
+			continue;
+
+		/* Derive ECC bytes positions (in page/buffer) and length */
+		ecc = chip->oob_poi +
+			(lt->full_chunk_cnt * lt->spare_bytes) +
+			lt->last_spare_bytes +
+			(chunk * ALIGN(lt->ecc_bytes, 32));
+		ecc_offset_in_page =
+			(chunk * (lt->data_bytes + lt->spare_bytes +
+				  lt->ecc_bytes)) +
+			(chunk < lt->full_chunk_cnt ?
+			 lt->data_bytes + lt->spare_bytes :
+			 lt->last_data_bytes + lt->last_spare_bytes);
+		ecc_len = chunk < lt->full_chunk_cnt ?
+			lt->ecc_bytes : lt->last_ecc_bytes;
+
+		/* Do the actual raw read of the ECC bytes */
+		nand_change_read_column_op(chip, ecc_offset_in_page,
+					   ecc, ecc_len, false);
+
+		/* Derive data/spare bytes positions (in buffer) and length */
+		data = buf + (chunk * lt->data_bytes);
+		data_len = chunk < lt->full_chunk_cnt ?
+			lt->data_bytes : lt->last_data_bytes;
+		spare = chip->oob_poi + (chunk * (lt->spare_bytes +
+						  lt->ecc_bytes));
+		spare_len = chunk < lt->full_chunk_cnt ?
+			lt->spare_bytes : lt->last_spare_bytes;
+
+		/* Check the entire chunk (data + spare + ecc) for emptyness */
+		marvell_nfc_check_empty_chunk(chip, data, data_len, spare,
+					      spare_len, ecc, ecc_len,
+					      &max_bitflips);
+	}
+
+	return max_bitflips;
+}
+
+static int marvell_nfc_hw_ecc_bch_read_oob_raw(struct mtd_info *mtd,
+					       struct nand_chip *chip, int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	return chip->ecc.read_page_raw(mtd, chip, chip->data_buf, true, page);
+}
+
+static int marvell_nfc_hw_ecc_bch_read_oob(struct mtd_info *mtd,
+					   struct nand_chip *chip, int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	return chip->ecc.read_page(mtd, chip, chip->data_buf, true, page);
+}
+
+/* BCH write helpers */
+static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
+						 struct nand_chip *chip,
+						 const u8 *buf,
+						 int oob_required, int page)
+{
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	int full_chunk_size = lt->data_bytes + lt->spare_bytes + lt->ecc_bytes;
+	int data_len = lt->data_bytes;
+	int spare_len = lt->spare_bytes;
+	int ecc_len = lt->ecc_bytes;
+	int oob_len = spare_len + ecc_len;
+	int spare_offset = 0;
+	int ecc_offset = (lt->full_chunk_cnt * lt->spare_bytes) +
+		lt->last_spare_bytes;
+	int chunk;
+
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
+	for (chunk = 0; chunk < lt->nchunks; chunk++) {
+		if (chunk >= lt->full_chunk_cnt) {
+			data_len = lt->last_data_bytes;
+			spare_len = lt->last_spare_bytes;
+			ecc_len = lt->last_ecc_bytes;
+			oob_len = spare_len + ecc_len;
+		}
+
+		/* Point to the column of the next chunk */
+		nand_change_write_column_op(chip, chunk * full_chunk_size,
+					    NULL, 0, false);
+
+		/* Write the data */
+		nand_write_data_op(chip, buf + (chunk * lt->data_bytes),
+				   data_len, false);
+
+		if (!oob_required)
+			continue;
+
+		/* Write the spare bytes */
+		if (spare_len)
+			nand_write_data_op(chip, chip->oob_poi + spare_offset,
+					   spare_len, false);
+
+		/* Write the ECC bytes */
+		if (ecc_len)
+			nand_write_data_op(chip, chip->oob_poi + ecc_offset,
+					   ecc_len, false);
+
+		spare_offset += spare_len;
+		ecc_offset += ALIGN(ecc_len, 32);
+	}
+
+	return nand_prog_page_end_op(chip);
+}
+
+static int
+marvell_nfc_hw_ecc_bch_write_chunk(struct nand_chip *chip, int chunk,
+				   const u8 *data, unsigned int data_len,
+				   const u8 *spare, unsigned int spare_len,
+				   int page)
+{
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	int ret;
+	struct marvell_nfc_op nfc_op = {
+		.ndcb[0] = NDCB0_CMD_TYPE(TYPE_WRITE) | NDCB0_LEN_OVRD,
+		.ndcb[3] = data_len + spare_len,
+	};
+
+	/*
+	 * First operation dispatches the CMD_SEQIN command, issue the address
+	 * cycles and asks for the first chunk of data.
+	 * All operations in the middle (if any) will issue a naked write and
+	 * also ask for data.
+	 * Last operation (if any) asks for the last chunk of data through a
+	 * last naked write.
+	 */
+	if (chunk == 0) {
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_WRITE_DISPATCH) |
+				  NDCB0_ADDR_CYC(marvell_nand->addr_cyc) |
+				  NDCB0_CMD1(NAND_CMD_SEQIN);
+		nfc_op.ndcb[1] |= NDCB1_ADDRS_PAGE(page);
+		nfc_op.ndcb[2] |= NDCB2_ADDR5_PAGE(page);
+	} else if (chunk < lt->nchunks - 1) {
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_NAKED_RW);
+	} else {
+		nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW);
+	}
+
+	/* Always dispatch the PAGEPROG command on the last chunk */
+	if (chunk == lt->nchunks - 1)
+		nfc_op.ndcb[0] |= NDCB0_CMD2(NAND_CMD_PAGEPROG) | NDCB0_DBC;
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_WRDREQ,
+				  "WRDREQ while loading FIFO (data)");
+	if (ret)
+		return ret;
+
+	/* Transfer the contents */
+	iowrite32_rep(nfc->regs + NDDB, data, FIFO_REP(data_len));
+	iowrite32_rep(nfc->regs + NDDB, spare, FIFO_REP(spare_len));
+
+	return 0;
+}
+
+static int marvell_nfc_hw_ecc_bch_write_page(struct mtd_info *mtd,
+					     struct nand_chip *chip,
+					     const u8 *buf,
+					     int oob_required, int page)
+{
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+	const u8 *data = buf;
+	const u8 *spare = chip->oob_poi;
+	int data_len = lt->data_bytes;
+	int spare_len = lt->spare_bytes;
+	int chunk, ret;
+
+	/* Spare data will be written anyway, so clear it to avoid garbage */
+	if (!oob_required)
+		memset(chip->oob_poi, 0xFF, mtd->oobsize);
+
+	marvell_nfc_enable_hw_ecc(chip);
+
+	for (chunk = 0; chunk < lt->nchunks; chunk++) {
+		if (chunk >= lt->full_chunk_cnt) {
+			data_len = lt->last_data_bytes;
+			spare_len = lt->last_spare_bytes;
+		}
+
+		marvell_nfc_hw_ecc_bch_write_chunk(chip, chunk, data, data_len,
+						   spare, spare_len, page);
+		data += data_len;
+		spare += spare_len;
+
+		/*
+		 * Waiting only for CMDD or PAGED is not enough, ECC are
+		 * partially written. No flag is set once the operation is
+		 * really finished but the ND_RUN bit is cleared, so wait for it
+		 * before stepping into the next command.
+		 */
+		marvell_nfc_wait_ndrun(chip);
+	}
+
+	ret = marvell_nfc_wait_op(chip,
+				  chip->data_interface.timings.sdr.tPROG_max);
+
+	marvell_nfc_disable_hw_ecc(chip);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int marvell_nfc_hw_ecc_bch_write_oob_raw(struct mtd_info *mtd,
+						struct nand_chip *chip,
+						int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	memset(chip->data_buf, 0xFF, mtd->writesize);
+
+	return chip->ecc.write_page_raw(mtd, chip, chip->data_buf, true, page);
+}
+
+static int marvell_nfc_hw_ecc_bch_write_oob(struct mtd_info *mtd,
+					    struct nand_chip *chip, int page)
+{
+	/* Invalidate page cache */
+	chip->pagebuf = -1;
+
+	memset(chip->data_buf, 0xFF, mtd->writesize);
+
+	return chip->ecc.write_page(mtd, chip, chip->data_buf, true, page);
+}
+
+/* NAND framework ->exec_op() hooks and related helpers */
+static void marvell_nfc_parse_instructions(struct nand_chip *chip,
+					   const struct nand_subop *subop,
+					   struct marvell_nfc_op *nfc_op)
+{
+	const struct nand_op_instr *instr = NULL;
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	bool first_cmd = true;
+	unsigned int op_id;
+	int i;
+
+	/* Reset the input structure as most of its fields will be OR'ed */
+	memset(nfc_op, 0, sizeof(struct marvell_nfc_op));
+
+	for (op_id = 0; op_id < subop->ninstrs; op_id++) {
+		unsigned int offset, naddrs;
+		const u8 *addrs;
+		int len = nand_subop_get_data_len(subop, op_id);
+
+		instr = &subop->instrs[op_id];
+
+		switch (instr->type) {
+		case NAND_OP_CMD_INSTR:
+			if (first_cmd)
+				nfc_op->ndcb[0] |=
+					NDCB0_CMD1(instr->ctx.cmd.opcode);
+			else
+				nfc_op->ndcb[0] |=
+					NDCB0_CMD2(instr->ctx.cmd.opcode) |
+					NDCB0_DBC;
+
+			nfc_op->cle_ale_delay_ns = instr->delay_ns;
+			first_cmd = false;
+			break;
+
+		case NAND_OP_ADDR_INSTR:
+			offset = nand_subop_get_addr_start_off(subop, op_id);
+			naddrs = nand_subop_get_num_addr_cyc(subop, op_id);
+			addrs = &instr->ctx.addr.addrs[offset];
+
+			nfc_op->ndcb[0] |= NDCB0_ADDR_CYC(naddrs);
+
+			for (i = 0; i < min_t(unsigned int, 4, naddrs); i++)
+				nfc_op->ndcb[1] |= addrs[i] << (8 * i);
+
+			if (naddrs >= 5)
+				nfc_op->ndcb[2] |= NDCB2_ADDR5_CYC(addrs[4]);
+			if (naddrs >= 6)
+				nfc_op->ndcb[3] |= NDCB3_ADDR6_CYC(addrs[5]);
+			if (naddrs == 7)
+				nfc_op->ndcb[3] |= NDCB3_ADDR7_CYC(addrs[6]);
+
+			nfc_op->cle_ale_delay_ns = instr->delay_ns;
+			break;
+
+		case NAND_OP_DATA_IN_INSTR:
+			nfc_op->data_instr = instr;
+			nfc_op->data_instr_idx = op_id;
+			nfc_op->ndcb[0] |= NDCB0_CMD_TYPE(TYPE_READ);
+			if (nfc->caps->is_nfcv2) {
+				nfc_op->ndcb[0] |=
+					NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
+					NDCB0_LEN_OVRD;
+				nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
+			}
+			nfc_op->data_delay_ns = instr->delay_ns;
+			break;
+
+		case NAND_OP_DATA_OUT_INSTR:
+			nfc_op->data_instr = instr;
+			nfc_op->data_instr_idx = op_id;
+			nfc_op->ndcb[0] |= NDCB0_CMD_TYPE(TYPE_WRITE);
+			if (nfc->caps->is_nfcv2) {
+				nfc_op->ndcb[0] |=
+					NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
+					NDCB0_LEN_OVRD;
+				nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
+			}
+			nfc_op->data_delay_ns = instr->delay_ns;
+			break;
+
+		case NAND_OP_WAITRDY_INSTR:
+			nfc_op->rdy_timeout_ms = instr->ctx.waitrdy.timeout_ms;
+			nfc_op->rdy_delay_ns = instr->delay_ns;
+			break;
+		}
+	}
+}
+
+static int marvell_nfc_xfer_data_pio(struct nand_chip *chip,
+				     const struct nand_subop *subop,
+				     struct marvell_nfc_op *nfc_op)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct nand_op_instr *instr = nfc_op->data_instr;
+	unsigned int op_id = nfc_op->data_instr_idx;
+	unsigned int len = nand_subop_get_data_len(subop, op_id);
+	unsigned int offset = nand_subop_get_data_start_off(subop, op_id);
+	bool reading = (instr->type == NAND_OP_DATA_IN_INSTR);
+	int ret;
+
+	if (instr->ctx.data.force_8bit)
+		marvell_nfc_force_byte_access(chip, true);
+
+	if (reading) {
+		u8 *in = instr->ctx.data.buf.in + offset;
+
+		ret = marvell_nfc_xfer_data_in_pio(nfc, in, len);
+	} else {
+		const u8 *out = instr->ctx.data.buf.out + offset;
+
+		ret = marvell_nfc_xfer_data_out_pio(nfc, out, len);
+	}
+
+	if (instr->ctx.data.force_8bit)
+		marvell_nfc_force_byte_access(chip, false);
+
+	return ret;
+}
+
+static int marvell_nfc_monolithic_access_exec(struct nand_chip *chip,
+					      const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	bool reading;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+	reading = (nfc_op.data_instr->type == NAND_OP_DATA_IN_INSTR);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_RDDREQ | NDSR_WRDREQ,
+				  "RDDREQ/WRDREQ while draining raw data");
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.cle_ale_delay_ns);
+
+	if (reading) {
+		if (nfc_op.rdy_timeout_ms) {
+			ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+			if (ret)
+				return ret;
+		}
+
+		cond_delay(nfc_op.rdy_delay_ns);
+	}
+
+	marvell_nfc_xfer_data_pio(chip, subop, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.data_delay_ns);
+
+	if (!reading) {
+		if (nfc_op.rdy_timeout_ms) {
+			ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+			if (ret)
+				return ret;
+		}
+
+		cond_delay(nfc_op.rdy_delay_ns);
+	}
+
+	/*
+	 * NDCR ND_RUN bit should be cleared automatically at the end of each
+	 * operation but experience shows that the behavior is buggy when it
+	 * comes to writes (with LEN_OVRD). Clear it by hand in this case.
+	 */
+	if (!reading) {
+		struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+
+		writel_relaxed(readl(nfc->regs + NDCR) & ~NDCR_ND_RUN,
+			       nfc->regs + NDCR);
+	}
+
+	return 0;
+}
+
+static int marvell_nfc_naked_access_exec(struct nand_chip *chip,
+					 const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+
+	/*
+	 * Naked access are different in that they need to be flagged as naked
+	 * by the controller. Reset the controller registers fields that inform
+	 * on the type and refill them according to the ongoing operation.
+	 */
+	nfc_op.ndcb[0] &= ~(NDCB0_CMD_TYPE(TYPE_MASK) |
+			    NDCB0_CMD_XTYPE(XTYPE_MASK));
+	switch (subop->instrs[0].type) {
+	case NAND_OP_CMD_INSTR:
+		nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_NAKED_CMD);
+		break;
+	case NAND_OP_ADDR_INSTR:
+		nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_NAKED_ADDR);
+		break;
+	case NAND_OP_DATA_IN_INSTR:
+		nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_READ) |
+				  NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW);
+		break;
+	case NAND_OP_DATA_OUT_INSTR:
+		nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_WRITE) |
+				  NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW);
+		break;
+	default:
+		/* This should never happen */
+		break;
+	}
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+
+	if (!nfc_op.data_instr) {
+		ret = marvell_nfc_wait_cmdd(chip);
+		cond_delay(nfc_op.cle_ale_delay_ns);
+		return ret;
+	}
+
+	ret = marvell_nfc_end_cmd(chip, NDSR_RDDREQ | NDSR_WRDREQ,
+				  "RDDREQ/WRDREQ while draining raw data");
+	if (ret)
+		return ret;
+
+	marvell_nfc_xfer_data_pio(chip, subop, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	/*
+	 * NDCR ND_RUN bit should be cleared automatically at the end of each
+	 * operation but experience shows that the behavior is buggy when it
+	 * comes to writes (with LEN_OVRD). Clear it by hand in this case.
+	 */
+	if (subop->instrs[0].type == NAND_OP_DATA_OUT_INSTR) {
+		struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+
+		writel_relaxed(readl(nfc->regs + NDCR) & ~NDCR_ND_RUN,
+			       nfc->regs + NDCR);
+	}
+
+	return 0;
+}
+
+static int marvell_nfc_naked_waitrdy_exec(struct nand_chip *chip,
+					  const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+
+	ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+	cond_delay(nfc_op.rdy_delay_ns);
+
+	return ret;
+}
+
+static int marvell_nfc_read_id_type_exec(struct nand_chip *chip,
+					 const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+	nfc_op.ndcb[0] &= ~NDCB0_CMD_TYPE(TYPE_READ);
+	nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_READ_ID);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_RDDREQ,
+				  "RDDREQ while reading ID");
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.cle_ale_delay_ns);
+
+	if (nfc_op.rdy_timeout_ms) {
+		ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+		if (ret)
+			return ret;
+	}
+
+	cond_delay(nfc_op.rdy_delay_ns);
+
+	marvell_nfc_xfer_data_pio(chip, subop, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.data_delay_ns);
+
+	return 0;
+}
+
+static int marvell_nfc_read_status_exec(struct nand_chip *chip,
+					const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+	nfc_op.ndcb[0] &= ~NDCB0_CMD_TYPE(TYPE_READ);
+	nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_STATUS);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_end_cmd(chip, NDSR_RDDREQ,
+				  "RDDREQ while reading status");
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.cle_ale_delay_ns);
+
+	if (nfc_op.rdy_timeout_ms) {
+		ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+		if (ret)
+			return ret;
+	}
+
+	cond_delay(nfc_op.rdy_delay_ns);
+
+	marvell_nfc_xfer_data_pio(chip, subop, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.data_delay_ns);
+
+	return 0;
+}
+
+static int marvell_nfc_reset_cmd_type_exec(struct nand_chip *chip,
+					   const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+	nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_RESET);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.cle_ale_delay_ns);
+
+	ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.rdy_delay_ns);
+
+	return 0;
+}
+
+static int marvell_nfc_erase_cmd_type_exec(struct nand_chip *chip,
+					   const struct nand_subop *subop)
+{
+	struct marvell_nfc_op nfc_op;
+	int ret;
+
+	marvell_nfc_parse_instructions(chip, subop, &nfc_op);
+	nfc_op.ndcb[0] |= NDCB0_CMD_TYPE(TYPE_ERASE);
+
+	ret = marvell_nfc_prepare_cmd(chip);
+	if (ret)
+		return ret;
+
+	marvell_nfc_send_cmd(chip, &nfc_op);
+	ret = marvell_nfc_wait_cmdd(chip);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.cle_ale_delay_ns);
+
+	ret = marvell_nfc_wait_op(chip, nfc_op.rdy_timeout_ms);
+	if (ret)
+		return ret;
+
+	cond_delay(nfc_op.rdy_delay_ns);
+
+	return 0;
+}
+
+static const struct nand_op_parser marvell_nfcv2_op_parser = NAND_OP_PARSER(
+	/* Monolithic reads/writes */
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_monolithic_access_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC_NFCV2),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, MAX_CHUNK_SIZE)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_monolithic_access_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYC_NFCV2),
+		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, MAX_CHUNK_SIZE),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
+	/* Naked commands */
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_access_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_access_exec,
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYC_NFCV2)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_access_exec,
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, MAX_CHUNK_SIZE)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_access_exec,
+		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, MAX_CHUNK_SIZE)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_waitrdy_exec,
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+	);
+
+static const struct nand_op_parser marvell_nfcv1_op_parser = NAND_OP_PARSER(
+	/* Naked commands not supported, use a function for each pattern */
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_read_id_type_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYC_NFCV1),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 8)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_erase_cmd_type_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYC_NFCV1),
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_read_status_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 1)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_reset_cmd_type_exec,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+	NAND_OP_PARSER_PATTERN(
+		marvell_nfc_naked_waitrdy_exec,
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+	);
+
+static int marvell_nfc_exec_op(struct nand_chip *chip,
+			       const struct nand_operation *op,
+			       bool check_only)
+{
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+
+	if (nfc->caps->is_nfcv2)
+		return nand_op_parser_exec_op(chip, &marvell_nfcv2_op_parser,
+					      op, check_only);
+	else
+		return nand_op_parser_exec_op(chip, &marvell_nfcv1_op_parser,
+					      op, check_only);
+}
+
+/*
+ * Layouts were broken in old pxa3xx_nand driver, these are supposed to be
+ * usable.
+ */
+static int marvell_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
+				      struct mtd_oob_region *oobregion)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+
+	if (section >= lt->nchunks)
+		return -ERANGE;
+
+	oobregion->offset = (lt->full_chunk_cnt * lt->spare_bytes) +
+		section * lt->ecc_bytes;
+	oobregion->length = section < lt->full_chunk_cnt ?
+		lt->ecc_bytes : lt->last_ecc_bytes;
+
+	return 0;
+}
+
+static int marvell_nand_ooblayout_free(struct mtd_info *mtd, int section,
+				       struct mtd_oob_region *oobregion)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout;
+
+	if (section >= lt->nchunks)
+		return -ERANGE;
+
+	oobregion->offset = section * lt->spare_bytes;
+	oobregion->length = section < lt->full_chunk_cnt ?
+		lt->spare_bytes : lt->last_spare_bytes;
+
+	if (!section) {
+		/*
+		 * Bootrom looks in bytes 0 & 5 for bad blocks for the
+		 * 4KB page / 4bit BCH combination.
+		 */
+		if (mtd->writesize == SZ_4K && lt->data_bytes == SZ_2K) {
+			oobregion->offset += 6;
+			oobregion->length -= 6;
+		} else {
+			oobregion->offset += 2;
+			oobregion->length -= 2;
+		}
+	}
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops marvell_nand_ooblayout_ops = {
+	.ecc = marvell_nand_ooblayout_ecc,
+	.free = marvell_nand_ooblayout_free,
+};
+
+static int marvell_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
+					 struct nand_ecc_ctrl *ecc)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	const struct marvell_hw_ecc_layout *l;
+	int i;
+
+	if (!nfc->caps->is_nfcv2 &&
+	    (mtd->writesize + mtd->oobsize > MAX_CHUNK_SIZE)) {
+		dev_err(nfc->dev,
+			"NFCv1: writesize (%d) cannot be bigger than a chunk (%d)\n",
+			mtd->writesize, MAX_CHUNK_SIZE - mtd->oobsize);
+		return -ENOTSUPP;
+	}
+
+	to_marvell_nand(chip)->layout = NULL;
+	for (i = 0; i < ARRAY_SIZE(marvell_nfc_layouts); i++) {
+		l = &marvell_nfc_layouts[i];
+		if (mtd->writesize == l->writesize &&
+		    ecc->size == l->chunk && ecc->strength == l->strength) {
+			to_marvell_nand(chip)->layout = l;
+			break;
+		}
+	}
+
+	if (!to_marvell_nand(chip)->layout ||
+	    (!nfc->caps->is_nfcv2 && ecc->strength > 1)) {
+		dev_err(nfc->dev,
+			"ECC strength %d at page size %d is not supported\n",
+			ecc->strength, mtd->writesize);
+		return -ENOTSUPP;
+	}
+
+	mtd_set_ooblayout(mtd, &marvell_nand_ooblayout_ops);
+	ecc->steps = l->nchunks;
+	ecc->size = l->data_bytes;
+
+	if (ecc->strength == 1) {
+		chip->ecc.algo = NAND_ECC_HAMMING;
+		ecc->read_page_raw = marvell_nfc_hw_ecc_hmg_read_page_raw;
+		ecc->read_page = marvell_nfc_hw_ecc_hmg_read_page;
+		ecc->read_oob_raw = marvell_nfc_hw_ecc_hmg_read_oob_raw;
+		ecc->read_oob = ecc->read_oob_raw;
+		ecc->write_page_raw = marvell_nfc_hw_ecc_hmg_write_page_raw;
+		ecc->write_page = marvell_nfc_hw_ecc_hmg_write_page;
+		ecc->write_oob_raw = marvell_nfc_hw_ecc_hmg_write_oob_raw;
+		ecc->write_oob = ecc->write_oob_raw;
+	} else {
+		chip->ecc.algo = NAND_ECC_BCH;
+		ecc->strength = 16;
+		ecc->read_page_raw = marvell_nfc_hw_ecc_bch_read_page_raw;
+		ecc->read_page = marvell_nfc_hw_ecc_bch_read_page;
+		ecc->read_oob_raw = marvell_nfc_hw_ecc_bch_read_oob_raw;
+		ecc->read_oob = marvell_nfc_hw_ecc_bch_read_oob;
+		ecc->write_page_raw = marvell_nfc_hw_ecc_bch_write_page_raw;
+		ecc->write_page = marvell_nfc_hw_ecc_bch_write_page;
+		ecc->write_oob_raw = marvell_nfc_hw_ecc_bch_write_oob_raw;
+		ecc->write_oob = marvell_nfc_hw_ecc_bch_write_oob;
+	}
+
+	return 0;
+}
+
+static int marvell_nand_ecc_init(struct mtd_info *mtd,
+				 struct nand_ecc_ctrl *ecc)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	int ret;
+
+	if (ecc->mode != NAND_ECC_NONE && (!ecc->size || !ecc->strength)) {
+		if (chip->ecc_step_ds && chip->ecc_strength_ds) {
+			ecc->size = chip->ecc_step_ds;
+			ecc->strength = chip->ecc_strength_ds;
+		} else {
+			dev_info(nfc->dev,
+				 "No minimum ECC strength, using 1b/512B\n");
+			ecc->size = 512;
+			ecc->strength = 1;
+		}
+	}
+
+	switch (ecc->mode) {
+	case NAND_ECC_HW:
+		ret = marvell_nand_hw_ecc_ctrl_init(mtd, ecc);
+		if (ret)
+			return ret;
+		break;
+	case NAND_ECC_NONE:
+	case NAND_ECC_SOFT:
+		if (!nfc->caps->is_nfcv2 && mtd->writesize != SZ_512 &&
+		    mtd->writesize != SZ_2K) {
+			dev_err(nfc->dev, "NFCv1 cannot write %d bytes pages\n",
+				mtd->writesize);
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
+static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+		   NAND_BBT_2BIT | NAND_BBT_VERSION,
+	.offs =	8,
+	.len = 6,
+	.veroffs = 14,
+	.maxblocks = 8,	/* Last 8 blocks in each chip */
+	.pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+		   NAND_BBT_2BIT | NAND_BBT_VERSION,
+	.offs =	8,
+	.len = 6,
+	.veroffs = 14,
+	.maxblocks = 8,	/* Last 8 blocks in each chip */
+	.pattern = bbt_mirror_pattern
+};
+
+static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
+					    const struct nand_data_interface
+					    *conf)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
+	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
+	unsigned int period_ns = 1000000000 / clk_get_rate(nfc->ecc_clk) * 2;
+	const struct nand_sdr_timings *sdr;
+	struct marvell_nfc_timings nfc_tmg;
+	int read_delay;
+
+	sdr = nand_get_sdr_timings(conf);
+	if (IS_ERR(sdr))
+		return PTR_ERR(sdr);
+
+	/*
+	 * SDR timings are given in pico-seconds while NFC timings must be
+	 * expressed in NAND controller clock cycles, which is half of the
+	 * frequency of the accessible ECC clock retrieved by clk_get_rate().
+	 * This is not written anywhere in the datasheet but was observed
+	 * with an oscilloscope.
+	 *
+	 * NFC datasheet gives equations from which thoses calculations
+	 * are derived, they tend to be slightly more restrictives than the
+	 * given core timings and may improve the overall speed.
+	 */
+	nfc_tmg.tRP = TO_CYCLES(DIV_ROUND_UP(sdr->tRC_min, 2), period_ns) - 1;
+	nfc_tmg.tRH = nfc_tmg.tRP;
+	nfc_tmg.tWP = TO_CYCLES(DIV_ROUND_UP(sdr->tWC_min, 2), period_ns) - 1;
+	nfc_tmg.tWH = nfc_tmg.tWP;
+	nfc_tmg.tCS = TO_CYCLES(sdr->tCS_min, period_ns);
+	nfc_tmg.tCH = TO_CYCLES(sdr->tCH_min, period_ns) - 1;
+	nfc_tmg.tADL = TO_CYCLES(sdr->tADL_min, period_ns);
+	/*
+	 * Read delay is the time of propagation from SoC pins to NFC internal
+	 * logic. With non-EDO timings, this is MIN_RD_DEL_CNT clock cycles. In
+	 * EDO mode, an additional delay of tRH must be taken into account so
+	 * the data is sampled on the falling edge instead of the rising edge.
+	 */
+	read_delay = sdr->tRC_min >= 30000 ?
+		MIN_RD_DEL_CNT : MIN_RD_DEL_CNT + nfc_tmg.tRH;
+
+	nfc_tmg.tAR = TO_CYCLES(sdr->tAR_min, period_ns);
+	/*
+	 * tWHR and tRHW are supposed to be read to write delays (and vice
+	 * versa) but in some cases, ie. when doing a change column, they must
+	 * be greater than that to be sure tCCS delay is respected.
+	 */
+	nfc_tmg.tWHR = TO_CYCLES(max_t(int, sdr->tWHR_min, sdr->tCCS_min),
+				 period_ns) - 2,
+	nfc_tmg.tRHW = TO_CYCLES(max_t(int, sdr->tRHW_min, sdr->tCCS_min),
+				 period_ns);
+
+	/* Use WAIT_MODE (wait for RB line) instead of only relying on delays */
+	nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns);
+
+	if (chipnr < 0)
+		return 0;
+
+	marvell_nand->ndtr0 =
+		NDTR0_TRP(nfc_tmg.tRP) |
+		NDTR0_TRH(nfc_tmg.tRH) |
+		NDTR0_ETRP(nfc_tmg.tRP) |
+		NDTR0_TWP(nfc_tmg.tWP) |
+		NDTR0_TWH(nfc_tmg.tWH) |
+		NDTR0_TCS(nfc_tmg.tCS) |
+		NDTR0_TCH(nfc_tmg.tCH) |
+		NDTR0_RD_CNT_DEL(read_delay) |
+		NDTR0_SELCNTR |
+		NDTR0_TADL(nfc_tmg.tADL);
+
+	marvell_nand->ndtr1 =
+		NDTR1_TAR(nfc_tmg.tAR) |
+		NDTR1_TWHR(nfc_tmg.tWHR) |
+		NDTR1_TRHW(nfc_tmg.tRHW) |
+		NDTR1_WAIT_MODE |
+		NDTR1_TR(nfc_tmg.tR);
+
+	writel_relaxed(marvell_nand->ndtr0, nfc->regs + NDTR0);
+	writel_relaxed(marvell_nand->ndtr1, nfc->regs + NDTR1);
+
+	return 0;
+}
+
+static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
+				  struct device_node *np)
+{
+	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(dev);
+	struct marvell_nand_chip *marvell_nand;
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	int nsels, ret, i;
+	u32 cs, rb;
+
+	/*
+	 * The legacy "num-cs" property indicates the number of CS on the only
+	 * chip connected to the controller (legacy bindings does not support
+	 * more than one chip). CS are only incremented one by one while the RB
+	 * pin is always the #0.
+	 *
+	 * When not using legacy bindings, a couple of "reg" and "nand-rb"
+	 * properties must be filled. For each chip, expressed as a subnode,
+	 * "reg" points to the CS lines and "nand-rb" to the RB line.
+	 */
+	if (pdata) {
+		nsels = 1;
+	} else if (nfc->caps->legacy_of_bindings) {
+		if (!of_get_property(np, "num-cs", &nsels)) {
+			dev_err(dev, "missing num-cs property\n");
+			return -EINVAL;
+		}
+	} else {
+		if (!of_get_property(np, "reg", &nsels)) {
+			dev_err(dev, "missing reg property\n");
+			return -EINVAL;
+		}
+	}
+
+	if (!pdata)
+		nsels /= sizeof(u32);
+	if (!nsels) {
+		dev_err(dev, "invalid reg property size\n");
+		return -EINVAL;
+	}
+
+	/* Alloc the nand chip structure */
+	marvell_nand = devm_kzalloc(dev, sizeof(*marvell_nand) +
+				    (nsels *
+				     sizeof(struct marvell_nand_chip_sel)),
+				    GFP_KERNEL);
+	if (!marvell_nand) {
+		dev_err(dev, "could not allocate chip structure\n");
+		return -ENOMEM;
+	}
+
+	marvell_nand->nsels = nsels;
+	marvell_nand->selected_die = -1;
+
+	for (i = 0; i < nsels; i++) {
+		if (pdata || nfc->caps->legacy_of_bindings) {
+			/*
+			 * Legacy bindings use the CS lines in natural
+			 * order (0, 1, ...)
+			 */
+			cs = i;
+		} else {
+			/* Retrieve CS id */
+			ret = of_property_read_u32_index(np, "reg", i, &cs);
+			if (ret) {
+				dev_err(dev, "could not retrieve reg property: %d\n",
+					ret);
+				return ret;
+			}
+		}
+
+		if (cs >= nfc->caps->max_cs_nb) {
+			dev_err(dev, "invalid reg value: %u (max CS = %d)\n",
+				cs, nfc->caps->max_cs_nb);
+			return -EINVAL;
+		}
+
+		if (test_and_set_bit(cs, &nfc->assigned_cs)) {
+			dev_err(dev, "CS %d already assigned\n", cs);
+			return -EINVAL;
+		}
+
+		/*
+		 * The cs variable represents the chip select id, which must be
+		 * converted in bit fields for NDCB0 and NDCB2 to select the
+		 * right chip. Unfortunately, due to a lack of information on
+		 * the subject and incoherent documentation, the user should not
+		 * use CS1 and CS3 at all as asserting them is not supported in
+		 * a reliable way (due to multiplexing inside ADDR5 field).
+		 */
+		marvell_nand->sels[i].cs = cs;
+		switch (cs) {
+		case 0:
+		case 2:
+			marvell_nand->sels[i].ndcb0_csel = 0;
+			break;
+		case 1:
+		case 3:
+			marvell_nand->sels[i].ndcb0_csel = NDCB0_CSEL;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		/* Retrieve RB id */
+		if (pdata || nfc->caps->legacy_of_bindings) {
+			/* Legacy bindings always use RB #0 */
+			rb = 0;
+		} else {
+			ret = of_property_read_u32_index(np, "nand-rb", i,
+							 &rb);
+			if (ret) {
+				dev_err(dev,
+					"could not retrieve RB property: %d\n",
+					ret);
+				return ret;
+			}
+		}
+
+		if (rb >= nfc->caps->max_rb_nb) {
+			dev_err(dev, "invalid reg value: %u (max RB = %d)\n",
+				rb, nfc->caps->max_rb_nb);
+			return -EINVAL;
+		}
+
+		marvell_nand->sels[i].rb = rb;
+	}
+
+	chip = &marvell_nand->chip;
+	chip->controller = &nfc->controller;
+	nand_set_flash_node(chip, np);
+
+	chip->exec_op = marvell_nfc_exec_op;
+	chip->select_chip = marvell_nfc_select_chip;
+	if (nfc->caps->is_nfcv2 &&
+	    !of_property_read_bool(np, "marvell,nand-keep-config"))
+		chip->setup_data_interface = marvell_nfc_setup_data_interface;
+
+	mtd = nand_to_mtd(chip);
+	mtd->dev.parent = dev;
+
+	/*
+	 * Default to HW ECC engine mode. If the nand-ecc-mode property is given
+	 * in the DT node, this entry will be overwritten in nand_scan_ident().
+	 */
+	chip->ecc.mode = NAND_ECC_HW;
+
+	chip->options |= NAND_BUSWIDTH_AUTO;
+	ret = nand_scan_ident(mtd, marvell_nand->nsels, NULL);
+	if (ret) {
+		dev_err(dev, "could not identify the nand chip\n");
+		return ret;
+	}
+
+	if (pdata && pdata->flash_bbt)
+		chip->bbt_options |= NAND_BBT_USE_FLASH;
+
+	if (chip->bbt_options & NAND_BBT_USE_FLASH) {
+		/*
+		 * We'll use a bad block table stored in-flash and don't
+		 * allow writing the bad block marker to the flash.
+		 */
+		chip->bbt_options |= NAND_BBT_NO_OOB_BBM;
+		chip->bbt_td = &bbt_main_descr;
+		chip->bbt_md = &bbt_mirror_descr;
+	}
+
+	/*
+	 * With RA_START bit set in NDCR, columns takes two address cycles. This
+	 * means addressing a chip with more than 256 pages needs a fifth
+	 * address cycle. Addressing a chip using CS 2 or 3 should also needs
+	 * this additional cycle but due to inconsistance in the documentation
+	 * and lack of hardware to test this situation, this case has been
+	 * dropped and is not supported by this driver.
+	 */
+	marvell_nand->addr_cyc = 4;
+	if (chip->options & NAND_ROW_ADDR_3)
+		marvell_nand->addr_cyc = 5;
+
+	if (pdata) {
+		chip->ecc.size = pdata->ecc_step_size;
+		chip->ecc.strength = pdata->ecc_strength;
+	}
+
+	ret = marvell_nand_ecc_init(mtd, &chip->ecc);
+	if (ret) {
+		dev_err(dev, "ECC init failed: %d\n", ret);
+		return ret;
+	}
+
+	if (chip->ecc.mode == NAND_ECC_HW) {
+		/*
+		 * Subpage write not available with hardware ECC, prohibit also
+		 * subpage read as in userspace subpage access would still be
+		 * allowed and subpage write, if used, would lead to numerous
+		 * uncorrectable ECC errors.
+		 */
+		chip->options |= NAND_NO_SUBPAGE_WRITE;
+	}
+
+	if (pdata || nfc->caps->legacy_of_bindings) {
+		/*
+		 * We keep the MTD name unchanged to avoid breaking platforms
+		 * where the MTD cmdline parser is used and the bootloader
+		 * has not been updated to use the new naming scheme.
+		 */
+		mtd->name = "pxa3xx_nand-0";
+	} else if (!mtd->name) {
+		/*
+		 * If the new bindings are used and the bootloader has not been
+		 * updated to pass a new mtdparts parameter on the cmdline, you
+		 * should define the following property in your NAND node, ie:
+		 *
+		 *	label = "main-storage";
+		 *
+		 * This way, mtd->name will be set by the core when
+		 * nand_set_flash_node() is called.
+		 */
+		mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL,
+					   "%s:nand.%d", dev_name(nfc->dev),
+					   marvell_nand->sels[0].cs);
+		if (!mtd->name) {
+			dev_err(nfc->dev, "Failed to allocate mtd->name\n");
+			return -ENOMEM;
+		}
+	}
+
+	/*
+	 * Save a reference value of NDCR for each NAND chip switch, adapt page
+	 * size and bus width.
+	 */
+	marvell_nand->ndcr = readl_relaxed(nfc->regs + NDCR);
+	marvell_nand->ndcr &= ~(NDCR_ND_RUN | NDCR_DWIDTH_M | NDCR_DWIDTH_C |
+				NDCR_PAGE_SZ(2048));
+	marvell_nand->ndcr |= NDCR_PAGE_SZ(mtd->writesize);
+	if (chip->options & NAND_BUSWIDTH_16)
+		marvell_nand->ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
+
+	ret = nand_scan_tail(mtd);
+	if (ret) {
+		dev_err(dev, "nand_scan_tail failed: %d\n", ret);
+		return ret;
+	}
+
+	if (pdata)
+		/* Legacy bindings support only one chip */
+		ret = mtd_device_register(mtd, pdata->parts[0],
+					  pdata->nr_parts[0]);
+	else
+		ret = mtd_device_register(mtd, NULL, 0);
+	if (ret) {
+		dev_err(dev, "failed to register mtd device: %d\n", ret);
+		nand_release(mtd);
+		return ret;
+	}
+
+	list_add_tail(&marvell_nand->node, &nfc->chips);
+
+	return 0;
+}
+
+static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *nand_np;
+	int max_cs = nfc->caps->max_cs_nb;
+	int nchips;
+	int ret;
+
+	if (!np)
+		nchips = 1;
+	else
+		nchips = of_get_child_count(np);
+
+	if (nchips > max_cs) {
+		dev_err(dev, "too many NAND chips: %d (max = %d CS)\n", nchips,
+			max_cs);
+		return -EINVAL;
+	}
+
+	/*
+	 * Legacy bindings do not use child nodes to exhibit NAND chip
+	 * properties and layout. Instead, NAND properties are mixed with the
+	 * controller ones, and partitions are defined as direct subnodes of the
+	 * NAND controller node.
+	 */
+	if (nfc->caps->legacy_of_bindings) {
+		ret = marvell_nand_chip_init(dev, nfc, np);
+		return ret;
+	}
+
+	for_each_child_of_node(np, nand_np) {
+		ret = marvell_nand_chip_init(dev, nfc, nand_np);
+		if (ret) {
+			of_node_put(nand_np);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc)
+{
+	struct marvell_nand_chip *entry, *temp;
+
+	list_for_each_entry_safe(entry, temp, &nfc->chips, node) {
+		nand_release(nand_to_mtd(&entry->chip));
+		list_del(&entry->node);
+	}
+}
+
+static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
+{
+	struct platform_device *pdev = container_of(nfc->dev,
+						    struct platform_device,
+						    dev);
+	struct dma_slave_config config = {};
+	struct resource *r;
+	dma_cap_mask_t mask;
+	struct pxad_param param;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_PXA_DMA)) {
+		dev_warn(nfc->dev,
+			 "DMA not enabled in configuration\n");
+		return -ENOTSUPP;
+	}
+
+	ret = dma_set_mask_and_coherent(nfc->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!r) {
+		dev_err(nfc->dev, "No resource defined for data DMA\n");
+		return -ENXIO;
+	}
+
+	param.drcmr = r->start;
+	param.prio = PXAD_PRIO_LOWEST;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	nfc->dma_chan =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, nfc->dev,
+						 "data");
+	if (!nfc->dma_chan) {
+		dev_err(nfc->dev,
+			"Unable to request data DMA channel\n");
+		return -ENODEV;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENXIO;
+
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.src_addr = r->start + NDDB;
+	config.dst_addr = r->start + NDDB;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
+	ret = dmaengine_slave_config(nfc->dma_chan, &config);
+	if (ret < 0) {
+		dev_err(nfc->dev, "Failed to configure DMA channel\n");
+		return ret;
+	}
+
+	/*
+	 * DMA must act on length multiple of 32 and this length may be
+	 * bigger than the destination buffer. Use this buffer instead
+	 * for DMA transfers and then copy the desired amount of data to
+	 * the provided buffer.
+	 */
+	nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_DMA);
+	if (!nfc->dma_buf)
+		return -ENOMEM;
+
+	nfc->use_dma = true;
+
+	return 0;
+}
+
+static int marvell_nfc_init(struct marvell_nfc *nfc)
+{
+	struct device_node *np = nfc->dev->of_node;
+
+	/*
+	 * Some SoCs like A7k/A8k need to enable manually the NAND
+	 * controller, gated clocks and reset bits to avoid being bootloader
+	 * dependent. This is done through the use of the System Functions
+	 * registers.
+	 */
+	if (nfc->caps->need_system_controller) {
+		struct regmap *sysctrl_base =
+			syscon_regmap_lookup_by_phandle(np,
+							"marvell,system-controller");
+		u32 reg;
+
+		if (IS_ERR(sysctrl_base))
+			return PTR_ERR(sysctrl_base);
+
+		reg = GENCONF_SOC_DEVICE_MUX_NFC_EN |
+			GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST |
+			GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST |
+			GENCONF_SOC_DEVICE_MUX_NFC_INT_EN;
+		regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg);
+
+		regmap_read(sysctrl_base, GENCONF_CLK_GATING_CTRL, &reg);
+		reg |= GENCONF_CLK_GATING_CTRL_ND_GATE;
+		regmap_write(sysctrl_base, GENCONF_CLK_GATING_CTRL, reg);
+
+		regmap_read(sysctrl_base, GENCONF_ND_CLK_CTRL, &reg);
+		reg |= GENCONF_ND_CLK_CTRL_EN;
+		regmap_write(sysctrl_base, GENCONF_ND_CLK_CTRL, reg);
+	}
+
+	/* Configure the DMA if appropriate */
+	if (!nfc->caps->is_nfcv2)
+		marvell_nfc_init_dma(nfc);
+
+	/*
+	 * ECC operations and interruptions are only enabled when specifically
+	 * needed. ECC shall not be activated in the early stages (fails probe).
+	 * Arbiter flag, even if marked as "reserved", must be set (empirical).
+	 * SPARE_EN bit must always be set or ECC bytes will not be at the same
+	 * offset in the read page and this will fail the protection.
+	 */
+	writel_relaxed(NDCR_RA_START | NDCR_ALL_INT | NDCR_ND_ARB_EN |
+		       NDCR_SPARE_EN | (nfc->caps->is_nfcv2 ?
+					0 : NDCR_RD_ID_CNT(NFCV1_READID_LEN)),
+		       nfc->regs + NDCR);
+	writel_relaxed(0xFFFFFFFF, nfc->regs + NDSR);
+	writel_relaxed(0, nfc->regs + NDECCCTRL);
+
+	return 0;
+}
+
+static int marvell_nfc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	struct marvell_nfc *nfc;
+	int ret;
+	int irq;
+
+	nfc = devm_kzalloc(&pdev->dev, sizeof(struct marvell_nfc),
+			   GFP_KERNEL);
+	if (!nfc)
+		return -ENOMEM;
+
+	nfc->dev = dev;
+	nand_hw_control_init(&nfc->controller);
+	INIT_LIST_HEAD(&nfc->chips);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(dev, r);
+	if (IS_ERR(nfc->regs))
+		return PTR_ERR(nfc->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "failed to retrieve irq\n");
+		return irq;
+	}
+
+	nfc->ecc_clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(nfc->ecc_clk))
+		return PTR_ERR(nfc->ecc_clk);
+
+	ret = clk_prepare_enable(nfc->ecc_clk);
+	if (ret)
+		return ret;
+
+	marvell_nfc_disable_int(nfc, NDCR_ALL_INT);
+	marvell_nfc_clear_int(nfc, NDCR_ALL_INT);
+	ret = devm_request_irq(dev, irq, marvell_nfc_isr,
+			       0, "marvell-nfc", nfc);
+	if (ret)
+		goto unprepare_clk;
+
+	/* Get NAND controller capabilities */
+	if (pdev->id_entry)
+		nfc->caps = (void *)pdev->id_entry->driver_data;
+	else
+		nfc->caps = of_device_get_match_data(&pdev->dev);
+
+	if (!nfc->caps) {
+		dev_err(dev, "Could not retrieve NFC caps\n");
+		ret = -EINVAL;
+		goto unprepare_clk;
+	}
+
+	/* Init the controller and then probe the chips */
+	ret = marvell_nfc_init(nfc);
+	if (ret)
+		goto unprepare_clk;
+
+	platform_set_drvdata(pdev, nfc);
+
+	ret = marvell_nand_chips_init(dev, nfc);
+	if (ret)
+		goto unprepare_clk;
+
+	return 0;
+
+unprepare_clk:
+	clk_disable_unprepare(nfc->ecc_clk);
+
+	return ret;
+}
+
+static int marvell_nfc_remove(struct platform_device *pdev)
+{
+	struct marvell_nfc *nfc = platform_get_drvdata(pdev);
+
+	marvell_nand_chips_cleanup(nfc);
+
+	if (nfc->use_dma) {
+		dmaengine_terminate_all(nfc->dma_chan);
+		dma_release_channel(nfc->dma_chan);
+	}
+
+	clk_disable_unprepare(nfc->ecc_clk);
+
+	return 0;
+}
+
+static const struct marvell_nfc_caps marvell_armada_8k_nfc_caps = {
+	.max_cs_nb = 4,
+	.max_rb_nb = 2,
+	.need_system_controller = true,
+	.is_nfcv2 = true,
+};
+
+static const struct marvell_nfc_caps marvell_armada370_nfc_caps = {
+	.max_cs_nb = 4,
+	.max_rb_nb = 2,
+	.is_nfcv2 = true,
+};
+
+static const struct marvell_nfc_caps marvell_pxa3xx_nfc_caps = {
+	.max_cs_nb = 2,
+	.max_rb_nb = 1,
+	.use_dma = true,
+};
+
+static const struct marvell_nfc_caps marvell_armada_8k_nfc_legacy_caps = {
+	.max_cs_nb = 4,
+	.max_rb_nb = 2,
+	.need_system_controller = true,
+	.legacy_of_bindings = true,
+	.is_nfcv2 = true,
+};
+
+static const struct marvell_nfc_caps marvell_armada370_nfc_legacy_caps = {
+	.max_cs_nb = 4,
+	.max_rb_nb = 2,
+	.legacy_of_bindings = true,
+	.is_nfcv2 = true,
+};
+
+static const struct marvell_nfc_caps marvell_pxa3xx_nfc_legacy_caps = {
+	.max_cs_nb = 2,
+	.max_rb_nb = 1,
+	.legacy_of_bindings = true,
+	.use_dma = true,
+};
+
+static const struct platform_device_id marvell_nfc_platform_ids[] = {
+	{
+		.name = "pxa3xx-nand",
+		.driver_data = (kernel_ulong_t)&marvell_pxa3xx_nfc_legacy_caps,
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, marvell_nfc_platform_ids);
+
+static const struct of_device_id marvell_nfc_of_ids[] = {
+	{
+		.compatible = "marvell,armada-8k-nand-controller",
+		.data = &marvell_armada_8k_nfc_caps,
+	},
+	{
+		.compatible = "marvell,armada370-nand-controller",
+		.data = &marvell_armada370_nfc_caps,
+	},
+	{
+		.compatible = "marvell,pxa3xx-nand-controller",
+		.data = &marvell_pxa3xx_nfc_caps,
+	},
+	/* Support for old/deprecated bindings: */
+	{
+		.compatible = "marvell,armada-8k-nand",
+		.data = &marvell_armada_8k_nfc_legacy_caps,
+	},
+	{
+		.compatible = "marvell,armada370-nand",
+		.data = &marvell_armada370_nfc_legacy_caps,
+	},
+	{
+		.compatible = "marvell,pxa3xx-nand",
+		.data = &marvell_pxa3xx_nfc_legacy_caps,
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, marvell_nfc_of_ids);
+
+static struct platform_driver marvell_nfc_driver = {
+	.driver	= {
+		.name		= "marvell-nfc",
+		.of_match_table = marvell_nfc_of_ids,
+	},
+	.id_table = marvell_nfc_platform_ids,
+	.probe = marvell_nfc_probe,
+	.remove	= marvell_nfc_remove,
+};
+module_platform_driver(marvell_nfc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Marvell NAND controller driver");
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 02:36:35 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue,  9 Jan 2018 11:36:35 +0100
Subject: [PATCH v3 5/7] mtd: nand: use Marvell reworked NAND controller driver
 with all platforms
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180109103637.23798-6-miquel.raynal@free-electrons.com>

Actually remove pxa3xx_nand.c to let marvell_nand.c be compiled instead.
Also change the defconfig files using it as well as some board files
depending on CONFIG_MTD_NAND_PXA3xx.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 arch/arm/configs/cm_x300_defconfig  |    2 +-
 arch/arm/configs/pxa3xx_defconfig   |    3 +-
 arch/arm/configs/pxa_defconfig      |    2 +-
 arch/arm/configs/raumfeld_defconfig |    2 +-
 arch/arm/mach-mmp/ttc_dkb.c         |    4 +-
 arch/arm/mach-pxa/cm-x300.c         |    2 +-
 arch/arm/mach-pxa/colibri-pxa3xx.c  |    2 +-
 arch/arm/mach-pxa/colibri.h         |    2 +-
 arch/arm/mach-pxa/littleton.c       |    4 +-
 arch/arm/mach-pxa/mxm8x10.c         |    4 +-
 arch/arm/mach-pxa/zylonite.c        |    4 +-
 drivers/mtd/nand/Kconfig            |   11 -
 drivers/mtd/nand/Makefile           |    1 -
 drivers/mtd/nand/pxa3xx_nand.c      | 2104 -----------------------------------
 14 files changed, 15 insertions(+), 2132 deletions(-)
 delete mode 100644 drivers/mtd/nand/pxa3xx_nand.c

diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig
index c0418e03d180..5e349c625b71 100644
--- a/arch/arm/configs/cm_x300_defconfig
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -49,7 +49,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index bfea6874b0a1..3e0de035ab77 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -32,8 +32,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
-CONFIG_MTD_NAND_PXA3xx_BUILTIN=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=y
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index 830e817a028a..934af8601f7d 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -198,7 +198,7 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
 CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
 CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
 CONFIG_MTD_NAND_SHARPSL=m
-CONFIG_MTD_NAND_PXA3xx=m
+CONFIG_MTD_NAND_MARVELL=m
 CONFIG_MTD_NAND_CM_X270=m
 CONFIG_MTD_NAND_TMIO=m
 CONFIG_MTD_NAND_BRCMNAND=m
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
index 77a56c23c6ef..2dd56e9a484e 100644
--- a/arch/arm/configs/raumfeld_defconfig
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -33,7 +33,7 @@ CONFIG_NFTL=y
 CONFIG_NFTL_RW=y
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_ISL29003=y
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index d90c74fa614d..e0b6073c61a7 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -178,7 +178,7 @@ static struct mv_usb_platform_data ttc_usb_pdata = {
 #endif
 #endif
 
-#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct pxa3xx_nand_platform_data dkb_nand_info = {
 	.enable_arbiter = 1,
 	.num_cs = 1,
@@ -275,7 +275,7 @@ static void __init ttc_dkb_init(void)
 
 	/* on-chip devices */
 	pxa910_add_uart(1);
-#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 	pxa910_add_nand(&dkb_nand_info);
 #endif
 
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 868448d2cd82..fe1c76bca212 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -391,7 +391,7 @@ static void __init cm_x300_init_ac97(void)
 static inline void cm_x300_init_ac97(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition cm_x300_nand_partitions[] = {
 	[0] = {
 		.name        = "OBM",
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index b04431bb4ba7..3018eafd723e 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -110,7 +110,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
 }
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition colibri_nand_partitions[] = {
 	{
 		.name        = "bootloader",
diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h
index 673a131da875..85525d49e321 100644
--- a/arch/arm/mach-pxa/colibri.h
+++ b/arch/arm/mach-pxa/colibri.h
@@ -46,7 +46,7 @@ static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
 extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 extern void colibri_pxa3xx_init_nand(void);
 #else
 static inline void colibri_pxa3xx_init_nand(void) {}
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index fae38fdc8d8e..380b07a15ef9 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -290,7 +290,7 @@ static void __init littleton_init_mmc(void)
 static inline void littleton_init_mmc(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition littleton_nand_partitions[] = {
 	[0] = {
 		.name        = "Bootloader",
@@ -340,7 +340,7 @@ static void __init littleton_init_nand(void)
 }
 #else
 static inline void littleton_init_nand(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
 static struct led_info littleton_da9034_leds[] = {
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index 9a22ae0ad8c9..743d983fc222 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -359,7 +359,7 @@ void __init mxm_8x10_ac97_init(void)
 }
 
 /* NAND flash Support */
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 #define NAND_BLOCK_SIZE SZ_128K
 #define NB(x)           (NAND_BLOCK_SIZE * (x))
 static struct mtd_partition mxm_8x10_nand_partitions[] = {
@@ -402,7 +402,7 @@ static void __init mxm_8x10_nand_init(void)
 }
 #else
 static inline void mxm_8x10_nand_init(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 /* Ethernet support: Davicom DM9000 */
 static struct resource dm9k_resources[] = {
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 4268552d600d..3a99fc054e96 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -338,7 +338,7 @@ static void __init zylonite_init_keypad(void)
 static inline void zylonite_init_keypad(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition zylonite_nand_partitions[] = {
 	[0] = {
 		.name        = "Bootloader",
@@ -388,7 +388,7 @@ static void __init zylonite_init_nand(void)
 }
 #else
 static inline void zylonite_init_nand(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static struct pxaohci_platform_data zylonite_ohci_info = {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index e6b8c59f2c0d..2c6ecb7ae753 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -313,17 +313,6 @@ config MTD_NAND_ATMEL
 	  Enables support for NAND Flash / Smart Media Card interface
 	  on Atmel AT91 processors.
 
-config MTD_NAND_PXA3xx
-	tristate "NAND support on PXA3xx and Armada 370/XP"
-	depends on !MTD_NAND_MARVELL
-	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU
-	help
-
-	  This enables the driver for the NAND flash device found on
-	  PXA3xx processors (NFCv1) and also on 32-bit Armada
-	  platforms (XP, 370, 375, 38x, 39x) and 64-bit Armada
-	  platforms (7K, 8K) (NFCv2).
-
 config MTD_NAND_MARVELL
 	tristate "NAND controller support on Marvell boards"
 	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 921634ba400c..c882d5ef192a 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -31,7 +31,6 @@ omap2_nand-objs := omap2.o
 obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2_nand.o
 obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD)	+= omap_elm.o
 obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
-obj-$(CONFIG_MTD_NAND_PXA3xx)		+= pxa3xx_nand.o
 obj-$(CONFIG_MTD_NAND_MARVELL)		+= marvell_nand.o
 obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
 obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
deleted file mode 100644
index 021374fe59dc..000000000000
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ /dev/null
@@ -1,2104 +0,0 @@
-/*
- * drivers/mtd/nand/pxa3xx_nand.c
- *
- * Copyright ? 2005 Intel Corporation
- * Copyright ? 2006 Marvell International Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma/pxa-dma.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/rawnand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_data/mtd-nand-pxa3xx.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
-
-#define	CHIP_DELAY_TIMEOUT	msecs_to_jiffies(200)
-#define NAND_STOP_DELAY		msecs_to_jiffies(40)
-#define PAGE_CHUNK_SIZE		(2048)
-
-/*
- * Define a buffer size for the initial command that detects the flash device:
- * STATUS, READID and PARAM.
- * ONFI param page is 256 bytes, and there are three redundant copies
- * to be read. JEDEC param page is 512 bytes, and there are also three
- * redundant copies to be read.
- * Hence this buffer should be at least 512 x 3. Let's pick 2048.
- */
-#define INIT_BUFFER_SIZE	2048
-
-/* System control register and bit to enable NAND on some SoCs */
-#define GENCONF_SOC_DEVICE_MUX	0x208
-#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0)
-
-/* registers and bit definitions */
-#define NDCR		(0x00) /* Control register */
-#define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
-#define NDTR1CS0	(0x0C) /* Timing Parameter 1 for CS0 */
-#define NDSR		(0x14) /* Status Register */
-#define NDPCR		(0x18) /* Page Count Register */
-#define NDBDR0		(0x1C) /* Bad Block Register 0 */
-#define NDBDR1		(0x20) /* Bad Block Register 1 */
-#define NDECCCTRL	(0x28) /* ECC control */
-#define NDDB		(0x40) /* Data Buffer */
-#define NDCB0		(0x48) /* Command Buffer0 */
-#define NDCB1		(0x4C) /* Command Buffer1 */
-#define NDCB2		(0x50) /* Command Buffer2 */
-
-#define NDCR_SPARE_EN		(0x1 << 31)
-#define NDCR_ECC_EN		(0x1 << 30)
-#define NDCR_DMA_EN		(0x1 << 29)
-#define NDCR_ND_RUN		(0x1 << 28)
-#define NDCR_DWIDTH_C		(0x1 << 27)
-#define NDCR_DWIDTH_M		(0x1 << 26)
-#define NDCR_PAGE_SZ		(0x1 << 24)
-#define NDCR_NCSX		(0x1 << 23)
-#define NDCR_ND_MODE		(0x3 << 21)
-#define NDCR_NAND_MODE   	(0x0)
-#define NDCR_CLR_PG_CNT		(0x1 << 20)
-#define NFCV1_NDCR_ARB_CNTL	(0x1 << 19)
-#define NFCV2_NDCR_STOP_ON_UNCOR	(0x1 << 19)
-#define NDCR_RD_ID_CNT_MASK	(0x7 << 16)
-#define NDCR_RD_ID_CNT(x)	(((x) << 16) & NDCR_RD_ID_CNT_MASK)
-
-#define NDCR_RA_START		(0x1 << 15)
-#define NDCR_PG_PER_BLK		(0x1 << 14)
-#define NDCR_ND_ARB_EN		(0x1 << 12)
-#define NDCR_INT_MASK           (0xFFF)
-
-#define NDSR_MASK		(0xfff)
-#define NDSR_ERR_CNT_OFF	(16)
-#define NDSR_ERR_CNT_MASK       (0x1f)
-#define NDSR_ERR_CNT(sr)	((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
-#define NDSR_RDY                (0x1 << 12)
-#define NDSR_FLASH_RDY          (0x1 << 11)
-#define NDSR_CS0_PAGED		(0x1 << 10)
-#define NDSR_CS1_PAGED		(0x1 << 9)
-#define NDSR_CS0_CMDD		(0x1 << 8)
-#define NDSR_CS1_CMDD		(0x1 << 7)
-#define NDSR_CS0_BBD		(0x1 << 6)
-#define NDSR_CS1_BBD		(0x1 << 5)
-#define NDSR_UNCORERR		(0x1 << 4)
-#define NDSR_CORERR		(0x1 << 3)
-#define NDSR_WRDREQ		(0x1 << 2)
-#define NDSR_RDDREQ		(0x1 << 1)
-#define NDSR_WRCMDREQ		(0x1)
-
-#define NDCB0_LEN_OVRD		(0x1 << 28)
-#define NDCB0_ST_ROW_EN         (0x1 << 26)
-#define NDCB0_AUTO_RS		(0x1 << 25)
-#define NDCB0_CSEL		(0x1 << 24)
-#define NDCB0_EXT_CMD_TYPE_MASK	(0x7 << 29)
-#define NDCB0_EXT_CMD_TYPE(x)	(((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
-#define NDCB0_CMD_TYPE_MASK	(0x7 << 21)
-#define NDCB0_CMD_TYPE(x)	(((x) << 21) & NDCB0_CMD_TYPE_MASK)
-#define NDCB0_NC		(0x1 << 20)
-#define NDCB0_DBC		(0x1 << 19)
-#define NDCB0_ADDR_CYC_MASK	(0x7 << 16)
-#define NDCB0_ADDR_CYC(x)	(((x) << 16) & NDCB0_ADDR_CYC_MASK)
-#define NDCB0_CMD2_MASK		(0xff << 8)
-#define NDCB0_CMD1_MASK		(0xff)
-#define NDCB0_ADDR_CYC_SHIFT	(16)
-
-#define EXT_CMD_TYPE_DISPATCH	6 /* Command dispatch */
-#define EXT_CMD_TYPE_NAKED_RW	5 /* Naked read or Naked write */
-#define EXT_CMD_TYPE_READ	4 /* Read */
-#define EXT_CMD_TYPE_DISP_WR	4 /* Command dispatch with write */
-#define EXT_CMD_TYPE_FINAL	3 /* Final command */
-#define EXT_CMD_TYPE_LAST_RW	1 /* Last naked read/write */
-#define EXT_CMD_TYPE_MONO	0 /* Monolithic read/write */
-
-/*
- * This should be large enough to read 'ONFI' and 'JEDEC'.
- * Let's use 7 bytes, which is the maximum ID count supported
- * by the controller (see NDCR_RD_ID_CNT_MASK).
- */
-#define READ_ID_BYTES		7
-
-/* macros for registers read/write */
-#define nand_writel(info, off, val)					\
-	do {								\
-		dev_vdbg(&info->pdev->dev,				\
-			 "%s():%d nand_writel(0x%x, 0x%04x)\n",		\
-			 __func__, __LINE__, (val), (off));		\
-		writel_relaxed((val), (info)->mmio_base + (off));	\
-	} while (0)
-
-#define nand_readl(info, off)						\
-	({								\
-		unsigned int _v;					\
-		_v = readl_relaxed((info)->mmio_base + (off));		\
-		dev_vdbg(&info->pdev->dev,				\
-			 "%s():%d nand_readl(0x%04x) = 0x%x\n",		\
-			 __func__, __LINE__, (off), _v);		\
-		_v;							\
-	})
-
-/* error code and state */
-enum {
-	ERR_NONE	= 0,
-	ERR_DMABUSERR	= -1,
-	ERR_SENDCMD	= -2,
-	ERR_UNCORERR	= -3,
-	ERR_BBERR	= -4,
-	ERR_CORERR	= -5,
-};
-
-enum {
-	STATE_IDLE = 0,
-	STATE_PREPARED,
-	STATE_CMD_HANDLE,
-	STATE_DMA_READING,
-	STATE_DMA_WRITING,
-	STATE_DMA_DONE,
-	STATE_PIO_READING,
-	STATE_PIO_WRITING,
-	STATE_CMD_DONE,
-	STATE_READY,
-};
-
-enum pxa3xx_nand_variant {
-	PXA3XX_NAND_VARIANT_PXA,
-	PXA3XX_NAND_VARIANT_ARMADA370,
-	PXA3XX_NAND_VARIANT_ARMADA_8K,
-};
-
-struct pxa3xx_nand_host {
-	struct nand_chip	chip;
-	void			*info_data;
-
-	/* page size of attached chip */
-	int			use_ecc;
-	int			cs;
-
-	/* calculated from pxa3xx_nand_flash data */
-	unsigned int		col_addr_cycles;
-	unsigned int		row_addr_cycles;
-};
-
-struct pxa3xx_nand_info {
-	struct nand_hw_control	controller;
-	struct platform_device	 *pdev;
-
-	struct clk		*clk;
-	void __iomem		*mmio_base;
-	unsigned long		mmio_phys;
-	struct completion	cmd_complete, dev_ready;
-
-	unsigned int 		buf_start;
-	unsigned int		buf_count;
-	unsigned int		buf_size;
-	unsigned int		data_buff_pos;
-	unsigned int		oob_buff_pos;
-
-	/* DMA information */
-	struct scatterlist	sg;
-	enum dma_data_direction	dma_dir;
-	struct dma_chan		*dma_chan;
-	dma_cookie_t		dma_cookie;
-	int			drcmr_dat;
-
-	unsigned char		*data_buff;
-	unsigned char		*oob_buff;
-	dma_addr_t 		data_buff_phys;
-	int 			data_dma_ch;
-
-	struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
-	unsigned int		state;
-
-	/*
-	 * This driver supports NFCv1 (as found in PXA SoC)
-	 * and NFCv2 (as found in Armada 370/XP SoC).
-	 */
-	enum pxa3xx_nand_variant variant;
-
-	int			cs;
-	int			use_ecc;	/* use HW ECC ? */
-	int			ecc_bch;	/* using BCH ECC? */
-	int			use_dma;	/* use DMA ? */
-	int			use_spare;	/* use spare ? */
-	int			need_wait;
-
-	/* Amount of real data per full chunk */
-	unsigned int		chunk_size;
-
-	/* Amount of spare data per full chunk */
-	unsigned int		spare_size;
-
-	/* Number of full chunks (i.e chunk_size + spare_size) */
-	unsigned int            nfullchunks;
-
-	/*
-	 * Total number of chunks. If equal to nfullchunks, then there
-	 * are only full chunks. Otherwise, there is one last chunk of
-	 * size (last_chunk_size + last_spare_size)
-	 */
-	unsigned int            ntotalchunks;
-
-	/* Amount of real data in the last chunk */
-	unsigned int		last_chunk_size;
-
-	/* Amount of spare data in the last chunk */
-	unsigned int		last_spare_size;
-
-	unsigned int		ecc_size;
-	unsigned int		ecc_err_cnt;
-	unsigned int		max_bitflips;
-	int 			retcode;
-
-	/*
-	 * Variables only valid during command
-	 * execution. step_chunk_size and step_spare_size is the
-	 * amount of real data and spare data in the current
-	 * chunk. cur_chunk is the current chunk being
-	 * read/programmed.
-	 */
-	unsigned int		step_chunk_size;
-	unsigned int		step_spare_size;
-	unsigned int            cur_chunk;
-
-	/* cached register value */
-	uint32_t		reg_ndcr;
-	uint32_t		ndtr0cs0;
-	uint32_t		ndtr1cs0;
-
-	/* generated NDCBx register values */
-	uint32_t		ndcb0;
-	uint32_t		ndcb1;
-	uint32_t		ndcb2;
-	uint32_t		ndcb3;
-};
-
-static bool use_dma = 1;
-module_param(use_dma, bool, 0444);
-MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW");
-
-struct pxa3xx_nand_timing {
-	unsigned int	tCH;  /* Enable signal hold time */
-	unsigned int	tCS;  /* Enable signal setup time */
-	unsigned int	tWH;  /* ND_nWE high duration */
-	unsigned int	tWP;  /* ND_nWE pulse time */
-	unsigned int	tRH;  /* ND_nRE high duration */
-	unsigned int	tRP;  /* ND_nRE pulse width */
-	unsigned int	tR;   /* ND_nWE high to ND_nRE low for read */
-	unsigned int	tWHR; /* ND_nWE high to ND_nRE low for status read */
-	unsigned int	tAR;  /* ND_ALE low to ND_nRE low delay */
-};
-
-struct pxa3xx_nand_flash {
-	uint32_t	chip_id;
-	unsigned int	flash_width;	/* Width of Flash memory (DWIDTH_M) */
-	unsigned int	dfc_width;	/* Width of flash controller(DWIDTH_C) */
-	struct pxa3xx_nand_timing *timing;	/* NAND Flash timing */
-};
-
-static struct pxa3xx_nand_timing timing[] = {
-	{ 40, 80, 60, 100, 80, 100, 90000, 400, 40, },
-	{ 10,  0, 20,  40, 30,  40, 11123, 110, 10, },
-	{ 10, 25, 15,  25, 15,  30, 25000,  60, 10, },
-	{ 10, 35, 15,  25, 15,  25, 25000,  60, 10, },
-};
-
-static struct pxa3xx_nand_flash builtin_flash_types[] = {
-	{ 0x46ec, 16, 16, &timing[1] },
-	{ 0xdaec,  8,  8, &timing[1] },
-	{ 0xd7ec,  8,  8, &timing[1] },
-	{ 0xa12c,  8,  8, &timing[2] },
-	{ 0xb12c, 16, 16, &timing[2] },
-	{ 0xdc2c,  8,  8, &timing[2] },
-	{ 0xcc2c, 16, 16, &timing[2] },
-	{ 0xba20, 16, 16, &timing[3] },
-};
-
-static int pxa3xx_ooblayout_ecc(struct mtd_info *mtd, int section,
-				struct mtd_oob_region *oobregion)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int nchunks = mtd->writesize / info->chunk_size;
-
-	if (section >= nchunks)
-		return -ERANGE;
-
-	oobregion->offset = ((info->ecc_size + info->spare_size) * section) +
-			    info->spare_size;
-	oobregion->length = info->ecc_size;
-
-	return 0;
-}
-
-static int pxa3xx_ooblayout_free(struct mtd_info *mtd, int section,
-				 struct mtd_oob_region *oobregion)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int nchunks = mtd->writesize / info->chunk_size;
-
-	if (section >= nchunks)
-		return -ERANGE;
-
-	if (!info->spare_size)
-		return 0;
-
-	oobregion->offset = section * (info->ecc_size + info->spare_size);
-	oobregion->length = info->spare_size;
-	if (!section) {
-		/*
-		 * Bootrom looks in bytes 0 & 5 for bad blocks for the
-		 * 4KB page / 4bit BCH combination.
-		 */
-		if (mtd->writesize == 4096 && info->chunk_size == 2048) {
-			oobregion->offset += 6;
-			oobregion->length -= 6;
-		} else {
-			oobregion->offset += 2;
-			oobregion->length -= 2;
-		}
-	}
-
-	return 0;
-}
-
-static const struct mtd_ooblayout_ops pxa3xx_ooblayout_ops = {
-	.ecc = pxa3xx_ooblayout_ecc,
-	.free = pxa3xx_ooblayout_free,
-};
-
-static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
-static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-		| NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	8,
-	.len = 6,
-	.veroffs = 14,
-	.maxblocks = 8,		/* Last 8 blocks in each chip */
-	.pattern = bbt_pattern
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-		| NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	8,
-	.len = 6,
-	.veroffs = 14,
-	.maxblocks = 8,		/* Last 8 blocks in each chip */
-	.pattern = bbt_mirror_pattern
-};
-
-#define NDTR0_tCH(c)	(min((c), 7) << 19)
-#define NDTR0_tCS(c)	(min((c), 7) << 16)
-#define NDTR0_tWH(c)	(min((c), 7) << 11)
-#define NDTR0_tWP(c)	(min((c), 7) << 8)
-#define NDTR0_tRH(c)	(min((c), 7) << 3)
-#define NDTR0_tRP(c)	(min((c), 7) << 0)
-
-#define NDTR1_tR(c)	(min((c), 65535) << 16)
-#define NDTR1_tWHR(c)	(min((c), 15) << 4)
-#define NDTR1_tAR(c)	(min((c), 15) << 0)
-
-/* convert nano-seconds to nand flash controller clock cycles */
-#define ns2cycle(ns, clk)	(int)((ns) * (clk / 1000000) / 1000)
-
-static const struct of_device_id pxa3xx_nand_dt_ids[] = {
-	{
-		.compatible = "marvell,pxa3xx-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
-	},
-	{
-		.compatible = "marvell,armada370-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
-	},
-	{
-		.compatible = "marvell,armada-8k-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA_8K,
-	},
-	{}
-};
-MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
-
-static enum pxa3xx_nand_variant
-pxa3xx_nand_get_variant(struct platform_device *pdev)
-{
-	const struct of_device_id *of_id =
-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-	if (!of_id)
-		return PXA3XX_NAND_VARIANT_PXA;
-	return (enum pxa3xx_nand_variant)of_id->data;
-}
-
-static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
-				   const struct pxa3xx_nand_timing *t)
-{
-	struct pxa3xx_nand_info *info = host->info_data;
-	unsigned long nand_clk = clk_get_rate(info->clk);
-	uint32_t ndtr0, ndtr1;
-
-	ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) |
-		NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) |
-		NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) |
-		NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) |
-		NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) |
-		NDTR0_tRP(ns2cycle(t->tRP, nand_clk));
-
-	ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) |
-		NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
-		NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
-
-	info->ndtr0cs0 = ndtr0;
-	info->ndtr1cs0 = ndtr1;
-	nand_writel(info, NDTR0CS0, ndtr0);
-	nand_writel(info, NDTR1CS0, ndtr1);
-}
-
-static void pxa3xx_nand_set_sdr_timing(struct pxa3xx_nand_host *host,
-				       const struct nand_sdr_timings *t)
-{
-	struct pxa3xx_nand_info *info = host->info_data;
-	struct nand_chip *chip = &host->chip;
-	unsigned long nand_clk = clk_get_rate(info->clk);
-	uint32_t ndtr0, ndtr1;
-
-	u32 tCH_min = DIV_ROUND_UP(t->tCH_min, 1000);
-	u32 tCS_min = DIV_ROUND_UP(t->tCS_min, 1000);
-	u32 tWH_min = DIV_ROUND_UP(t->tWH_min, 1000);
-	u32 tWP_min = DIV_ROUND_UP(t->tWC_min - t->tWH_min, 1000);
-	u32 tREH_min = DIV_ROUND_UP(t->tREH_min, 1000);
-	u32 tRP_min = DIV_ROUND_UP(t->tRC_min - t->tREH_min, 1000);
-	u32 tR = chip->chip_delay * 1000;
-	u32 tWHR_min = DIV_ROUND_UP(t->tWHR_min, 1000);
-	u32 tAR_min = DIV_ROUND_UP(t->tAR_min, 1000);
-
-	/* fallback to a default value if tR = 0 */
-	if (!tR)
-		tR = 20000;
-
-	ndtr0 = NDTR0_tCH(ns2cycle(tCH_min, nand_clk)) |
-		NDTR0_tCS(ns2cycle(tCS_min, nand_clk)) |
-		NDTR0_tWH(ns2cycle(tWH_min, nand_clk)) |
-		NDTR0_tWP(ns2cycle(tWP_min, nand_clk)) |
-		NDTR0_tRH(ns2cycle(tREH_min, nand_clk)) |
-		NDTR0_tRP(ns2cycle(tRP_min, nand_clk));
-
-	ndtr1 = NDTR1_tR(ns2cycle(tR, nand_clk)) |
-		NDTR1_tWHR(ns2cycle(tWHR_min, nand_clk)) |
-		NDTR1_tAR(ns2cycle(tAR_min, nand_clk));
-
-	info->ndtr0cs0 = ndtr0;
-	info->ndtr1cs0 = ndtr1;
-	nand_writel(info, NDTR0CS0, ndtr0);
-	nand_writel(info, NDTR1CS0, ndtr1);
-}
-
-static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host,
-					   unsigned int *flash_width,
-					   unsigned int *dfc_width)
-{
-	struct nand_chip *chip = &host->chip;
-	struct pxa3xx_nand_info *info = host->info_data;
-	const struct pxa3xx_nand_flash *f = NULL;
-	int i, id, ntypes;
-	u8 idbuf[2];
-
-	ntypes = ARRAY_SIZE(builtin_flash_types);
-
-	nand_readid_op(chip, 0, idbuf, sizeof(idbuf));
-	id = idbuf[0] | (idbuf[1] << 8);
-
-	for (i = 0; i < ntypes; i++) {
-		f = &builtin_flash_types[i];
-
-		if (f->chip_id == id)
-			break;
-	}
-
-	if (i == ntypes) {
-		dev_err(&info->pdev->dev, "Error: timings not found\n");
-		return -EINVAL;
-	}
-
-	pxa3xx_nand_set_timing(host, f->timing);
-
-	*flash_width = f->flash_width;
-	*dfc_width = f->dfc_width;
-
-	return 0;
-}
-
-static int pxa3xx_nand_init_timings_onfi(struct pxa3xx_nand_host *host,
-					 int mode)
-{
-	const struct nand_sdr_timings *timings;
-
-	mode = fls(mode) - 1;
-	if (mode < 0)
-		mode = 0;
-
-	timings = onfi_async_timing_mode_to_sdr_timings(mode);
-	if (IS_ERR(timings))
-		return PTR_ERR(timings);
-
-	pxa3xx_nand_set_sdr_timing(host, timings);
-
-	return 0;
-}
-
-static int pxa3xx_nand_init(struct pxa3xx_nand_host *host)
-{
-	struct nand_chip *chip = &host->chip;
-	struct pxa3xx_nand_info *info = host->info_data;
-	unsigned int flash_width = 0, dfc_width = 0;
-	int mode, err;
-
-	mode = onfi_get_async_timing_mode(chip);
-	if (mode == ONFI_TIMING_MODE_UNKNOWN) {
-		err = pxa3xx_nand_init_timings_compat(host, &flash_width,
-						      &dfc_width);
-		if (err)
-			return err;
-
-		if (flash_width == 16) {
-			info->reg_ndcr |= NDCR_DWIDTH_M;
-			chip->options |= NAND_BUSWIDTH_16;
-		}
-
-		info->reg_ndcr |= (dfc_width == 16) ? NDCR_DWIDTH_C : 0;
-	} else {
-		err = pxa3xx_nand_init_timings_onfi(host, mode);
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
-/**
- * NOTE: it is a must to set ND_RUN firstly, then write
- * command buffer, otherwise, it does not work.
- * We enable all the interrupt at the same time, and
- * let pxa3xx_nand_irq to handle all logic.
- */
-static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
-{
-	uint32_t ndcr;
-
-	ndcr = info->reg_ndcr;
-
-	if (info->use_ecc) {
-		ndcr |= NDCR_ECC_EN;
-		if (info->ecc_bch)
-			nand_writel(info, NDECCCTRL, 0x1);
-	} else {
-		ndcr &= ~NDCR_ECC_EN;
-		if (info->ecc_bch)
-			nand_writel(info, NDECCCTRL, 0x0);
-	}
-
-	if (info->use_dma)
-		ndcr |= NDCR_DMA_EN;
-	else
-		ndcr &= ~NDCR_DMA_EN;
-
-	if (info->use_spare)
-		ndcr |= NDCR_SPARE_EN;
-	else
-		ndcr &= ~NDCR_SPARE_EN;
-
-	ndcr |= NDCR_ND_RUN;
-
-	/* clear status bits and run */
-	nand_writel(info, NDSR, NDSR_MASK);
-	nand_writel(info, NDCR, 0);
-	nand_writel(info, NDCR, ndcr);
-}
-
-static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info)
-{
-	uint32_t ndcr;
-	int timeout = NAND_STOP_DELAY;
-
-	/* wait RUN bit in NDCR become 0 */
-	ndcr = nand_readl(info, NDCR);
-	while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) {
-		ndcr = nand_readl(info, NDCR);
-		udelay(1);
-	}
-
-	if (timeout <= 0) {
-		ndcr &= ~NDCR_ND_RUN;
-		nand_writel(info, NDCR, ndcr);
-	}
-	if (info->dma_chan)
-		dmaengine_terminate_all(info->dma_chan);
-
-	/* clear status bits */
-	nand_writel(info, NDSR, NDSR_MASK);
-}
-
-static void __maybe_unused
-enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
-{
-	uint32_t ndcr;
-
-	ndcr = nand_readl(info, NDCR);
-	nand_writel(info, NDCR, ndcr & ~int_mask);
-}
-
-static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
-{
-	uint32_t ndcr;
-
-	ndcr = nand_readl(info, NDCR);
-	nand_writel(info, NDCR, ndcr | int_mask);
-}
-
-static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
-{
-	if (info->ecc_bch) {
-		u32 val;
-		int ret;
-
-		/*
-		 * According to the datasheet, when reading from NDDB
-		 * with BCH enabled, after each 32 bytes reads, we
-		 * have to make sure that the NDSR.RDDREQ bit is set.
-		 *
-		 * Drain the FIFO 8 32 bits reads at a time, and skip
-		 * the polling on the last read.
-		 */
-		while (len > 8) {
-			ioread32_rep(info->mmio_base + NDDB, data, 8);
-
-			ret = readl_relaxed_poll_timeout(info->mmio_base + NDSR, val,
-							 val & NDSR_RDDREQ, 1000, 5000);
-			if (ret) {
-				dev_err(&info->pdev->dev,
-					"Timeout on RDDREQ while draining the FIFO\n");
-				return;
-			}
-
-			data += 32;
-			len -= 8;
-		}
-	}
-
-	ioread32_rep(info->mmio_base + NDDB, data, len);
-}
-
-static void handle_data_pio(struct pxa3xx_nand_info *info)
-{
-	switch (info->state) {
-	case STATE_PIO_WRITING:
-		if (info->step_chunk_size)
-			writesl(info->mmio_base + NDDB,
-				info->data_buff + info->data_buff_pos,
-				DIV_ROUND_UP(info->step_chunk_size, 4));
-
-		if (info->step_spare_size)
-			writesl(info->mmio_base + NDDB,
-				info->oob_buff + info->oob_buff_pos,
-				DIV_ROUND_UP(info->step_spare_size, 4));
-		break;
-	case STATE_PIO_READING:
-		if (info->step_chunk_size)
-			drain_fifo(info,
-				   info->data_buff + info->data_buff_pos,
-				   DIV_ROUND_UP(info->step_chunk_size, 4));
-
-		if (info->step_spare_size)
-			drain_fifo(info,
-				   info->oob_buff + info->oob_buff_pos,
-				   DIV_ROUND_UP(info->step_spare_size, 4));
-		break;
-	default:
-		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
-				info->state);
-		BUG();
-	}
-
-	/* Update buffer pointers for multi-page read/write */
-	info->data_buff_pos += info->step_chunk_size;
-	info->oob_buff_pos += info->step_spare_size;
-}
-
-static void pxa3xx_nand_data_dma_irq(void *data)
-{
-	struct pxa3xx_nand_info *info = data;
-	struct dma_tx_state state;
-	enum dma_status status;
-
-	status = dmaengine_tx_status(info->dma_chan, info->dma_cookie, &state);
-	if (likely(status == DMA_COMPLETE)) {
-		info->state = STATE_DMA_DONE;
-	} else {
-		dev_err(&info->pdev->dev, "DMA error on data channel\n");
-		info->retcode = ERR_DMABUSERR;
-	}
-	dma_unmap_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir);
-
-	nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
-	enable_int(info, NDCR_INT_MASK);
-}
-
-static void start_data_dma(struct pxa3xx_nand_info *info)
-{
-	enum dma_transfer_direction direction;
-	struct dma_async_tx_descriptor *tx;
-
-	switch (info->state) {
-	case STATE_DMA_WRITING:
-		info->dma_dir = DMA_TO_DEVICE;
-		direction = DMA_MEM_TO_DEV;
-		break;
-	case STATE_DMA_READING:
-		info->dma_dir = DMA_FROM_DEVICE;
-		direction = DMA_DEV_TO_MEM;
-		break;
-	default:
-		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
-				info->state);
-		BUG();
-	}
-	info->sg.length = info->chunk_size;
-	if (info->use_spare)
-		info->sg.length += info->spare_size + info->ecc_size;
-	dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir);
-
-	tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction,
-				     DMA_PREP_INTERRUPT);
-	if (!tx) {
-		dev_err(&info->pdev->dev, "prep_slave_sg() failed\n");
-		return;
-	}
-	tx->callback = pxa3xx_nand_data_dma_irq;
-	tx->callback_param = info;
-	info->dma_cookie = dmaengine_submit(tx);
-	dma_async_issue_pending(info->dma_chan);
-	dev_dbg(&info->pdev->dev, "%s(dir=%d cookie=%x size=%u)\n",
-		__func__, direction, info->dma_cookie, info->sg.length);
-}
-
-static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data)
-{
-	struct pxa3xx_nand_info *info = data;
-
-	handle_data_pio(info);
-
-	info->state = STATE_CMD_DONE;
-	nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
-{
-	struct pxa3xx_nand_info *info = devid;
-	unsigned int status, is_completed = 0, is_ready = 0;
-	unsigned int ready, cmd_done;
-	irqreturn_t ret = IRQ_HANDLED;
-
-	if (info->cs == 0) {
-		ready           = NDSR_FLASH_RDY;
-		cmd_done        = NDSR_CS0_CMDD;
-	} else {
-		ready           = NDSR_RDY;
-		cmd_done        = NDSR_CS1_CMDD;
-	}
-
-	status = nand_readl(info, NDSR);
-
-	if (status & NDSR_UNCORERR)
-		info->retcode = ERR_UNCORERR;
-	if (status & NDSR_CORERR) {
-		info->retcode = ERR_CORERR;
-		if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		     info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) &&
-		    info->ecc_bch)
-			info->ecc_err_cnt = NDSR_ERR_CNT(status);
-		else
-			info->ecc_err_cnt = 1;
-
-		/*
-		 * Each chunk composing a page is corrected independently,
-		 * and we need to store maximum number of corrected bitflips
-		 * to return it to the MTD layer in ecc.read_page().
-		 */
-		info->max_bitflips = max_t(unsigned int,
-					   info->max_bitflips,
-					   info->ecc_err_cnt);
-	}
-	if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
-		/* whether use dma to transfer data */
-		if (info->use_dma) {
-			disable_int(info, NDCR_INT_MASK);
-			info->state = (status & NDSR_RDDREQ) ?
-				      STATE_DMA_READING : STATE_DMA_WRITING;
-			start_data_dma(info);
-			goto NORMAL_IRQ_EXIT;
-		} else {
-			info->state = (status & NDSR_RDDREQ) ?
-				      STATE_PIO_READING : STATE_PIO_WRITING;
-			ret = IRQ_WAKE_THREAD;
-			goto NORMAL_IRQ_EXIT;
-		}
-	}
-	if (status & cmd_done) {
-		info->state = STATE_CMD_DONE;
-		is_completed = 1;
-	}
-	if (status & ready) {
-		info->state = STATE_READY;
-		is_ready = 1;
-	}
-
-	/*
-	 * Clear all status bit before issuing the next command, which
-	 * can and will alter the status bits and will deserve a new
-	 * interrupt on its own. This lets the controller exit the IRQ
-	 */
-	nand_writel(info, NDSR, status);
-
-	if (status & NDSR_WRCMDREQ) {
-		status &= ~NDSR_WRCMDREQ;
-		info->state = STATE_CMD_HANDLE;
-
-		/*
-		 * Command buffer registers NDCB{0-2} (and optionally NDCB3)
-		 * must be loaded by writing directly either 12 or 16
-		 * bytes directly to NDCB0, four bytes at a time.
-		 *
-		 * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored
-		 * but each NDCBx register can be read.
-		 */
-		nand_writel(info, NDCB0, info->ndcb0);
-		nand_writel(info, NDCB0, info->ndcb1);
-		nand_writel(info, NDCB0, info->ndcb2);
-
-		/* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
-		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
-			nand_writel(info, NDCB0, info->ndcb3);
-	}
-
-	if (is_completed)
-		complete(&info->cmd_complete);
-	if (is_ready)
-		complete(&info->dev_ready);
-NORMAL_IRQ_EXIT:
-	return ret;
-}
-
-static inline int is_buf_blank(uint8_t *buf, size_t len)
-{
-	for (; len > 0; len--)
-		if (*buf++ != 0xff)
-			return 0;
-	return 1;
-}
-
-static void set_command_address(struct pxa3xx_nand_info *info,
-		unsigned int page_size, uint16_t column, int page_addr)
-{
-	/* small page addr setting */
-	if (page_size < PAGE_CHUNK_SIZE) {
-		info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
-				| (column & 0xFF);
-
-		info->ndcb2 = 0;
-	} else {
-		info->ndcb1 = ((page_addr & 0xFFFF) << 16)
-				| (column & 0xFFFF);
-
-		if (page_addr & 0xFF0000)
-			info->ndcb2 = (page_addr & 0xFF0000) >> 16;
-		else
-			info->ndcb2 = 0;
-	}
-}
-
-static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct mtd_info *mtd = nand_to_mtd(&host->chip);
-
-	/* reset data and oob column point to handle data */
-	info->buf_start		= 0;
-	info->buf_count		= 0;
-	info->data_buff_pos	= 0;
-	info->oob_buff_pos	= 0;
-	info->step_chunk_size   = 0;
-	info->step_spare_size   = 0;
-	info->cur_chunk         = 0;
-	info->use_ecc		= 0;
-	info->use_spare		= 1;
-	info->retcode		= ERR_NONE;
-	info->ecc_err_cnt	= 0;
-	info->ndcb3		= 0;
-	info->need_wait		= 0;
-
-	switch (command) {
-	case NAND_CMD_READ0:
-	case NAND_CMD_PAGEPROG:
-		info->use_ecc = 1;
-		break;
-	case NAND_CMD_PARAM:
-		info->use_spare = 0;
-		break;
-	default:
-		info->ndcb1 = 0;
-		info->ndcb2 = 0;
-		break;
-	}
-
-	/*
-	 * If we are about to issue a read command, or about to set
-	 * the write address, then clean the data buffer.
-	 */
-	if (command == NAND_CMD_READ0 ||
-	    command == NAND_CMD_READOOB ||
-	    command == NAND_CMD_SEQIN) {
-
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xFF, info->buf_count);
-	}
-
-}
-
-static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
-		int ext_cmd_type, uint16_t column, int page_addr)
-{
-	int addr_cycle, exec_cmd;
-	struct pxa3xx_nand_host *host;
-	struct mtd_info *mtd;
-
-	host = info->host[info->cs];
-	mtd = nand_to_mtd(&host->chip);
-	addr_cycle = 0;
-	exec_cmd = 1;
-
-	if (info->cs != 0)
-		info->ndcb0 = NDCB0_CSEL;
-	else
-		info->ndcb0 = 0;
-
-	if (command == NAND_CMD_SEQIN)
-		exec_cmd = 0;
-
-	addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
-				    + host->col_addr_cycles);
-
-	switch (command) {
-	case NAND_CMD_READOOB:
-	case NAND_CMD_READ0:
-		info->buf_start = column;
-		info->ndcb0 |= NDCB0_CMD_TYPE(0)
-				| addr_cycle
-				| NAND_CMD_READ0;
-
-		if (command == NAND_CMD_READOOB)
-			info->buf_start += mtd->writesize;
-
-		if (info->cur_chunk < info->nfullchunks) {
-			info->step_chunk_size = info->chunk_size;
-			info->step_spare_size = info->spare_size;
-		} else {
-			info->step_chunk_size = info->last_chunk_size;
-			info->step_spare_size = info->last_spare_size;
-		}
-
-		/*
-		 * Multiple page read needs an 'extended command type' field,
-		 * which is either naked-read or last-read according to the
-		 * state.
-		 */
-		if (mtd->writesize == PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
-		} else if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
-					| NDCB0_LEN_OVRD
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
-			info->ndcb3 = info->step_chunk_size +
-				info->step_spare_size;
-		}
-
-		set_command_address(info, mtd->writesize, column, page_addr);
-		break;
-
-	case NAND_CMD_SEQIN:
-
-		info->buf_start = column;
-		set_command_address(info, mtd->writesize, 0, page_addr);
-
-		/*
-		 * Multiple page programming needs to execute the initial
-		 * SEQIN command that sets the page address.
-		 */
-		if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-				| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
-				| addr_cycle
-				| command;
-			exec_cmd = 1;
-		}
-		break;
-
-	case NAND_CMD_PAGEPROG:
-		if (is_buf_blank(info->data_buff,
-					(mtd->writesize + mtd->oobsize))) {
-			exec_cmd = 0;
-			break;
-		}
-
-		if (info->cur_chunk < info->nfullchunks) {
-			info->step_chunk_size = info->chunk_size;
-			info->step_spare_size = info->spare_size;
-		} else {
-			info->step_chunk_size = info->last_chunk_size;
-			info->step_spare_size = info->last_spare_size;
-		}
-
-		/* Second command setting for large pages */
-		if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			/*
-			 * Multiple page write uses the 'extended command'
-			 * field. This can be used to issue a command dispatch
-			 * or a naked-write depending on the current stage.
-			 */
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-					| NDCB0_LEN_OVRD
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
-			info->ndcb3 = info->step_chunk_size +
-				      info->step_spare_size;
-
-			/*
-			 * This is the command dispatch that completes a chunked
-			 * page program operation.
-			 */
-			if (info->cur_chunk == info->ntotalchunks) {
-				info->ndcb0 = NDCB0_CMD_TYPE(0x1)
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
-					| command;
-				info->ndcb1 = 0;
-				info->ndcb2 = 0;
-				info->ndcb3 = 0;
-			}
-		} else {
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-					| NDCB0_AUTO_RS
-					| NDCB0_ST_ROW_EN
-					| NDCB0_DBC
-					| (NAND_CMD_PAGEPROG << 8)
-					| NAND_CMD_SEQIN
-					| addr_cycle;
-		}
-		break;
-
-	case NAND_CMD_PARAM:
-		info->buf_count = INIT_BUFFER_SIZE;
-		info->ndcb0 |= NDCB0_CMD_TYPE(0)
-				| NDCB0_ADDR_CYC(1)
-				| NDCB0_LEN_OVRD
-				| command;
-		info->ndcb1 = (column & 0xFF);
-		info->ndcb3 = INIT_BUFFER_SIZE;
-		info->step_chunk_size = INIT_BUFFER_SIZE;
-		break;
-
-	case NAND_CMD_READID:
-		info->buf_count = READ_ID_BYTES;
-		info->ndcb0 |= NDCB0_CMD_TYPE(3)
-				| NDCB0_ADDR_CYC(1)
-				| command;
-		info->ndcb1 = (column & 0xFF);
-
-		info->step_chunk_size = 8;
-		break;
-	case NAND_CMD_STATUS:
-		info->buf_count = 1;
-		info->ndcb0 |= NDCB0_CMD_TYPE(4)
-				| NDCB0_ADDR_CYC(1)
-				| command;
-
-		info->step_chunk_size = 8;
-		break;
-
-	case NAND_CMD_ERASE1:
-		info->ndcb0 |= NDCB0_CMD_TYPE(2)
-				| NDCB0_AUTO_RS
-				| NDCB0_ADDR_CYC(3)
-				| NDCB0_DBC
-				| (NAND_CMD_ERASE2 << 8)
-				| NAND_CMD_ERASE1;
-		info->ndcb1 = page_addr;
-		info->ndcb2 = 0;
-
-		break;
-	case NAND_CMD_RESET:
-		info->ndcb0 |= NDCB0_CMD_TYPE(5)
-				| command;
-
-		break;
-
-	case NAND_CMD_ERASE2:
-		exec_cmd = 0;
-		break;
-
-	default:
-		exec_cmd = 0;
-		dev_err(&info->pdev->dev, "non-supported command %x\n",
-				command);
-		break;
-	}
-
-	return exec_cmd;
-}
-
-static void nand_cmdfunc(struct mtd_info *mtd, unsigned command,
-			 int column, int page_addr)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int exec_cmd;
-
-	/*
-	 * if this is a x16 device ,then convert the input
-	 * "byte" address into a "word" address appropriate
-	 * for indexing a word-oriented device
-	 */
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		column /= 2;
-
-	/*
-	 * There may be different NAND chip hooked to
-	 * different chip select, so check whether
-	 * chip select has been changed, if yes, reset the timing
-	 */
-	if (info->cs != host->cs) {
-		info->cs = host->cs;
-		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-	}
-
-	prepare_start_command(info, command);
-
-	info->state = STATE_PREPARED;
-	exec_cmd = prepare_set_command(info, command, 0, column, page_addr);
-
-	if (exec_cmd) {
-		init_completion(&info->cmd_complete);
-		init_completion(&info->dev_ready);
-		info->need_wait = 1;
-		pxa3xx_nand_start(info);
-
-		if (!wait_for_completion_timeout(&info->cmd_complete,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Wait time out!!!\n");
-			/* Stop State Machine for next command cycle */
-			pxa3xx_nand_stop(info);
-		}
-	}
-	info->state = STATE_IDLE;
-}
-
-static void nand_cmdfunc_extended(struct mtd_info *mtd,
-				  const unsigned command,
-				  int column, int page_addr)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int exec_cmd, ext_cmd_type;
-
-	/*
-	 * if this is a x16 device then convert the input
-	 * "byte" address into a "word" address appropriate
-	 * for indexing a word-oriented device
-	 */
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		column /= 2;
-
-	/*
-	 * There may be different NAND chip hooked to
-	 * different chip select, so check whether
-	 * chip select has been changed, if yes, reset the timing
-	 */
-	if (info->cs != host->cs) {
-		info->cs = host->cs;
-		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-	}
-
-	/* Select the extended command for the first command */
-	switch (command) {
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-		ext_cmd_type = EXT_CMD_TYPE_MONO;
-		break;
-	case NAND_CMD_SEQIN:
-		ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
-		break;
-	case NAND_CMD_PAGEPROG:
-		ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
-		break;
-	default:
-		ext_cmd_type = 0;
-		break;
-	}
-
-	prepare_start_command(info, command);
-
-	/*
-	 * Prepare the "is ready" completion before starting a command
-	 * transaction sequence. If the command is not executed the
-	 * completion will be completed, see below.
-	 *
-	 * We can do that inside the loop because the command variable
-	 * is invariant and thus so is the exec_cmd.
-	 */
-	info->need_wait = 1;
-	init_completion(&info->dev_ready);
-	do {
-		info->state = STATE_PREPARED;
-
-		exec_cmd = prepare_set_command(info, command, ext_cmd_type,
-					       column, page_addr);
-		if (!exec_cmd) {
-			info->need_wait = 0;
-			complete(&info->dev_ready);
-			break;
-		}
-
-		init_completion(&info->cmd_complete);
-		pxa3xx_nand_start(info);
-
-		if (!wait_for_completion_timeout(&info->cmd_complete,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Wait time out!!!\n");
-			/* Stop State Machine for next command cycle */
-			pxa3xx_nand_stop(info);
-			break;
-		}
-
-		/* Only a few commands need several steps */
-		if (command != NAND_CMD_PAGEPROG &&
-		    command != NAND_CMD_READ0    &&
-		    command != NAND_CMD_READOOB)
-			break;
-
-		info->cur_chunk++;
-
-		/* Check if the sequence is complete */
-		if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG)
-			break;
-
-		/*
-		 * After a splitted program command sequence has issued
-		 * the command dispatch, the command sequence is complete.
-		 */
-		if (info->cur_chunk == (info->ntotalchunks + 1) &&
-		    command == NAND_CMD_PAGEPROG &&
-		    ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
-			break;
-
-		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
-			/* Last read: issue a 'last naked read' */
-			if (info->cur_chunk == info->ntotalchunks - 1)
-				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
-			else
-				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
-
-		/*
-		 * If a splitted program command has no more data to transfer,
-		 * the command dispatch must be issued to complete.
-		 */
-		} else if (command == NAND_CMD_PAGEPROG &&
-			   info->cur_chunk == info->ntotalchunks) {
-				ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
-		}
-	} while (1);
-
-	info->state = STATE_IDLE;
-}
-
-static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required,
-		int page)
-{
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	return nand_prog_page_end_op(chip);
-}
-
-static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, uint8_t *buf, int oob_required,
-		int page)
-{
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-
-	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	if (info->retcode == ERR_CORERR && info->use_ecc) {
-		mtd->ecc_stats.corrected += info->ecc_err_cnt;
-
-	} else if (info->retcode == ERR_UNCORERR) {
-		/*
-		 * for blank page (all 0xff), HW will calculate its ECC as
-		 * 0, which is different from the ECC information within
-		 * OOB, ignore such uncorrectable errors
-		 */
-		if (is_buf_blank(buf, mtd->writesize))
-			info->retcode = ERR_NONE;
-		else
-			mtd->ecc_stats.failed++;
-	}
-
-	return info->max_bitflips;
-}
-
-static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	char retval = 0xFF;
-
-	if (info->buf_start < info->buf_count)
-		/* Has just send a new command? */
-		retval = info->data_buff[info->buf_start++];
-
-	return retval;
-}
-
-static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	u16 retval = 0xFFFF;
-
-	if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) {
-		retval = *((u16 *)(info->data_buff+info->buf_start));
-		info->buf_start += 2;
-	}
-	return retval;
-}
-
-static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
-
-	memcpy(buf, info->data_buff + info->buf_start, real_len);
-	info->buf_start += real_len;
-}
-
-static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
-		const uint8_t *buf, int len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
-
-	memcpy(info->data_buff + info->buf_start, buf, real_len);
-	info->buf_start += real_len;
-}
-
-static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
-{
-	return;
-}
-
-static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-
-	if (info->need_wait) {
-		info->need_wait = 0;
-		if (!wait_for_completion_timeout(&info->dev_ready,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Ready time out!!!\n");
-			return NAND_STATUS_FAIL;
-		}
-	}
-
-	/* pxa3xx_nand_send_command has waited for command complete */
-	if (this->state == FL_WRITING || this->state == FL_ERASING) {
-		if (info->retcode == ERR_NONE)
-			return 0;
-		else
-			return NAND_STATUS_FAIL;
-	}
-
-	return NAND_STATUS_READY;
-}
-
-static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	const struct nand_sdr_timings *timings;
-
-	/* Configure default flash values */
-	info->chunk_size = PAGE_CHUNK_SIZE;
-	info->reg_ndcr = 0x0; /* enable all interrupts */
-	info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-	info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES);
-	info->reg_ndcr |= NDCR_SPARE_EN;
-
-	/* use the common timing to make a try */
-	timings = onfi_async_timing_mode_to_sdr_timings(0);
-	if (IS_ERR(timings))
-		return PTR_ERR(timings);
-
-	pxa3xx_nand_set_sdr_timing(host, timings);
-	return 0;
-}
-
-static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct nand_chip *chip = &host->chip;
-	struct mtd_info *mtd = nand_to_mtd(chip);
-
-	info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0;
-	info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0;
-	info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0;
-}
-
-static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
-{
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	uint32_t ndcr = nand_readl(info, NDCR);
-
-	/* Set an initial chunk size */
-	info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-	info->reg_ndcr = ndcr &
-		~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL);
-	info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
-	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
-}
-
-static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
-{
-	struct platform_device *pdev = info->pdev;
-	struct dma_slave_config	config;
-	dma_cap_mask_t mask;
-	struct pxad_param param;
-	int ret;
-
-	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
-	if (info->data_buff == NULL)
-		return -ENOMEM;
-	if (use_dma == 0)
-		return 0;
-
-	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
-	sg_init_one(&info->sg, info->data_buff, info->buf_size);
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE, mask);
-	param.prio = PXAD_PRIO_LOWEST;
-	param.drcmr = info->drcmr_dat;
-	info->dma_chan = dma_request_slave_channel_compat(mask, pxad_filter_fn,
-							  &param, &pdev->dev,
-							  "data");
-	if (!info->dma_chan) {
-		dev_err(&pdev->dev, "unable to request data dma channel\n");
-		return -ENODEV;
-	}
-
-	memset(&config, 0, sizeof(config));
-	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	config.src_addr = info->mmio_phys + NDDB;
-	config.dst_addr = info->mmio_phys + NDDB;
-	config.src_maxburst = 32;
-	config.dst_maxburst = 32;
-	ret = dmaengine_slave_config(info->dma_chan, &config);
-	if (ret < 0) {
-		dev_err(&info->pdev->dev,
-			"dma channel configuration failed: %d\n",
-			ret);
-		return ret;
-	}
-
-	/*
-	 * Now that DMA buffers are allocated we turn on
-	 * DMA proper for I/O operations.
-	 */
-	info->use_dma = 1;
-	return 0;
-}
-
-static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
-{
-	if (info->use_dma) {
-		dmaengine_terminate_all(info->dma_chan);
-		dma_release_channel(info->dma_chan);
-	}
-	kfree(info->data_buff);
-}
-
-static int pxa_ecc_init(struct pxa3xx_nand_info *info,
-			struct mtd_info *mtd,
-			int strength, int ecc_stepsize, int page_size)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-
-	if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 40;
-		info->ecc_size = 24;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
-
-	} else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 512;
-		info->spare_size = 8;
-		info->ecc_size = 8;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
-
-	/*
-	 * Required ECC: 4-bit correction per 512 bytes
-	 * Select: 16-bit correction per 2048 bytes
-	 */
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 2;
-		info->ntotalchunks = 2;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-
-	/*
-	 * Required ECC: 8-bit correction per 512 bytes
-	 * Select: 16-bit correction per 1024 bytes
-	 */
-	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 4;
-		info->ntotalchunks = 5;
-		info->chunk_size = 1024;
-		info->spare_size = 0;
-		info->last_chunk_size = 0;
-		info->last_spare_size = 64;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-	} else {
-		dev_err(&info->pdev->dev,
-			"ECC strength %d at page size %d is not supported\n",
-			strength, page_size);
-		return -ENODEV;
-	}
-
-	dev_info(&info->pdev->dev, "ECC strength %d, ECC step size %d\n",
-		 ecc->strength, ecc->size);
-	return 0;
-}
-
-static int pxa3xx_nand_scan(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	int ret;
-	uint16_t ecc_strength, ecc_step;
-
-	if (pdata->keep_config) {
-		pxa3xx_nand_detect_config(info);
-	} else {
-		ret = pxa3xx_nand_config_ident(info);
-		if (ret)
-			return ret;
-	}
-
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		chip->options |= NAND_BUSWIDTH_16;
-
-	/* Device detection must be done with ECC disabled */
-	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-	    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
-		nand_writel(info, NDECCCTRL, 0x0);
-
-	if (pdata->flash_bbt)
-		chip->bbt_options |= NAND_BBT_USE_FLASH;
-
-	chip->ecc.strength = pdata->ecc_strength;
-	chip->ecc.size = pdata->ecc_step_size;
-
-	ret = nand_scan_ident(mtd, 1, NULL);
-	if (ret)
-		return ret;
-
-	if (!pdata->keep_config) {
-		ret = pxa3xx_nand_init(host);
-		if (ret) {
-			dev_err(&info->pdev->dev, "Failed to init nand: %d\n",
-				ret);
-			return ret;
-		}
-	}
-
-	if (chip->bbt_options & NAND_BBT_USE_FLASH) {
-		/*
-		 * We'll use a bad block table stored in-flash and don't
-		 * allow writing the bad block marker to the flash.
-		 */
-		chip->bbt_options |= NAND_BBT_NO_OOB_BBM;
-		chip->bbt_td = &bbt_main_descr;
-		chip->bbt_md = &bbt_mirror_descr;
-	}
-
-	/*
-	 * If the page size is bigger than the FIFO size, let's check
-	 * we are given the right variant and then switch to the extended
-	 * (aka splitted) command handling,
-	 */
-	if (mtd->writesize > PAGE_CHUNK_SIZE) {
-		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) {
-			chip->cmdfunc = nand_cmdfunc_extended;
-		} else {
-			dev_err(&info->pdev->dev,
-				"unsupported page size on this variant\n");
-			return -ENODEV;
-		}
-	}
-
-	ecc_strength = chip->ecc.strength;
-	ecc_step = chip->ecc.size;
-	if (!ecc_strength || !ecc_step) {
-		ecc_strength = chip->ecc_strength_ds;
-		ecc_step = chip->ecc_step_ds;
-	}
-
-	/* Set default ECC strength requirements on non-ONFI devices */
-	if (ecc_strength < 1 && ecc_step < 1) {
-		ecc_strength = 1;
-		ecc_step = 512;
-	}
-
-	ret = pxa_ecc_init(info, mtd, ecc_strength,
-			   ecc_step, mtd->writesize);
-	if (ret)
-		return ret;
-
-	/* calculate addressing information */
-	if (mtd->writesize >= 2048)
-		host->col_addr_cycles = 2;
-	else
-		host->col_addr_cycles = 1;
-
-	/* release the initial buffer */
-	kfree(info->data_buff);
-
-	/* allocate the real data + oob buffer */
-	info->buf_size = mtd->writesize + mtd->oobsize;
-	ret = pxa3xx_nand_init_buff(info);
-	if (ret)
-		return ret;
-	info->oob_buff = info->data_buff + mtd->writesize;
-
-	if ((mtd->size >> chip->page_shift) > 65536)
-		host->row_addr_cycles = 3;
-	else
-		host->row_addr_cycles = 2;
-
-	if (!pdata->keep_config)
-		pxa3xx_nand_config_tail(info);
-
-	return nand_scan_tail(mtd);
-}
-
-static int alloc_nand_resource(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct pxa3xx_nand_platform_data *pdata;
-	struct pxa3xx_nand_info *info;
-	struct pxa3xx_nand_host *host;
-	struct nand_chip *chip = NULL;
-	struct mtd_info *mtd;
-	struct resource *r;
-	int ret, irq, cs;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata->num_cs <= 0) {
-		dev_err(&pdev->dev, "invalid number of chip selects\n");
-		return -ENODEV;
-	}
-
-	info = devm_kzalloc(&pdev->dev,
-			    sizeof(*info) + sizeof(*host) * pdata->num_cs,
-			    GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	info->pdev = pdev;
-	info->variant = pxa3xx_nand_get_variant(pdev);
-	for (cs = 0; cs < pdata->num_cs; cs++) {
-		host = (void *)&info[1] + sizeof(*host) * cs;
-		chip = &host->chip;
-		nand_set_controller_data(chip, host);
-		mtd = nand_to_mtd(chip);
-		info->host[cs] = host;
-		host->cs = cs;
-		host->info_data = info;
-		mtd->dev.parent = &pdev->dev;
-		/* FIXME: all chips use the same device tree partitions */
-		nand_set_flash_node(chip, np);
-
-		nand_set_controller_data(chip, host);
-		chip->ecc.read_page	= pxa3xx_nand_read_page_hwecc;
-		chip->ecc.write_page	= pxa3xx_nand_write_page_hwecc;
-		chip->controller        = &info->controller;
-		chip->waitfunc		= pxa3xx_nand_waitfunc;
-		chip->select_chip	= pxa3xx_nand_select_chip;
-		chip->read_word		= pxa3xx_nand_read_word;
-		chip->read_byte		= pxa3xx_nand_read_byte;
-		chip->read_buf		= pxa3xx_nand_read_buf;
-		chip->write_buf		= pxa3xx_nand_write_buf;
-		chip->options		|= NAND_NO_SUBPAGE_WRITE;
-		chip->cmdfunc		= nand_cmdfunc;
-		chip->onfi_set_features	= nand_onfi_get_set_features_notsupp;
-		chip->onfi_get_features	= nand_onfi_get_set_features_notsupp;
-	}
-
-	nand_hw_control_init(chip->controller);
-	info->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(info->clk)) {
-		ret = PTR_ERR(info->clk);
-		dev_err(&pdev->dev, "failed to get nand clock: %d\n", ret);
-		return ret;
-	}
-	ret = clk_prepare_enable(info->clk);
-	if (ret < 0)
-		return ret;
-
-	if (!np && use_dma) {
-		r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-		if (r == NULL) {
-			dev_err(&pdev->dev,
-				"no resource defined for data DMA\n");
-			ret = -ENXIO;
-			goto fail_disable_clk;
-		}
-		info->drcmr_dat = r->start;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "no IRQ resource defined\n");
-		ret = -ENXIO;
-		goto fail_disable_clk;
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-	if (IS_ERR(info->mmio_base)) {
-		ret = PTR_ERR(info->mmio_base);
-		dev_err(&pdev->dev, "failed to map register space: %d\n", ret);
-		goto fail_disable_clk;
-	}
-	info->mmio_phys = r->start;
-
-	/* Allocate a buffer to allow flash detection */
-	info->buf_size = INIT_BUFFER_SIZE;
-	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
-	if (info->data_buff == NULL) {
-		ret = -ENOMEM;
-		goto fail_disable_clk;
-	}
-
-	/* initialize all interrupts to be disabled */
-	disable_int(info, NDSR_MASK);
-
-	ret = request_threaded_irq(irq, pxa3xx_nand_irq,
-				   pxa3xx_nand_irq_thread, IRQF_ONESHOT,
-				   pdev->name, info);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret);
-		goto fail_free_buf;
-	}
-
-	platform_set_drvdata(pdev, info);
-
-	return 0;
-
-fail_free_buf:
-	free_irq(irq, info);
-	kfree(info->data_buff);
-fail_disable_clk:
-	clk_disable_unprepare(info->clk);
-	return ret;
-}
-
-static int pxa3xx_nand_remove(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-	struct pxa3xx_nand_platform_data *pdata;
-	int irq, cs;
-
-	if (!info)
-		return 0;
-
-	pdata = dev_get_platdata(&pdev->dev);
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq >= 0)
-		free_irq(irq, info);
-	pxa3xx_nand_free_buff(info);
-
-	/*
-	 * In the pxa3xx case, the DFI bus is shared between the SMC and NFC.
-	 * In order to prevent a lockup of the system bus, the DFI bus
-	 * arbitration is granted to SMC upon driver removal. This is done by
-	 * setting the x_ARB_CNTL bit, which also prevents the NAND to have
-	 * access to the bus anymore.
-	 */
-	nand_writel(info, NDCR,
-		    (nand_readl(info, NDCR) & ~NDCR_ND_ARB_EN) |
-		    NFCV1_NDCR_ARB_CNTL);
-	clk_disable_unprepare(info->clk);
-
-	for (cs = 0; cs < pdata->num_cs; cs++)
-		nand_release(nand_to_mtd(&info->host[cs]->chip));
-	return 0;
-}
-
-static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_platform_data *pdata;
-	struct device_node *np = pdev->dev.of_node;
-	const struct of_device_id *of_id =
-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-
-	if (!of_id)
-		return 0;
-
-	/*
-	 * Some SoCs like A7k/A8k need to enable manually the NAND
-	 * controller to avoid being bootloader dependent. This is done
-	 * through the use of a single bit in the System Functions registers.
-	 */
-	if (pxa3xx_nand_get_variant(pdev) == PXA3XX_NAND_VARIANT_ARMADA_8K) {
-		struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle(
-			pdev->dev.of_node, "marvell,system-controller");
-		u32 reg;
-
-		if (IS_ERR(sysctrl_base))
-			return PTR_ERR(sysctrl_base);
-
-		regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, &reg);
-		reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN;
-		regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg);
-	}
-
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		return -ENOMEM;
-
-	if (of_get_property(np, "marvell,nand-enable-arbiter", NULL))
-		pdata->enable_arbiter = 1;
-	if (of_get_property(np, "marvell,nand-keep-config", NULL))
-		pdata->keep_config = 1;
-	of_property_read_u32(np, "num-cs", &pdata->num_cs);
-
-	pdev->dev.platform_data = pdata;
-
-	return 0;
-}
-
-static int pxa3xx_nand_probe(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_platform_data *pdata;
-	struct pxa3xx_nand_info *info;
-	int ret, cs, probe_success, dma_available;
-
-	dma_available = IS_ENABLED(CONFIG_ARM) &&
-		(IS_ENABLED(CONFIG_ARCH_PXA) || IS_ENABLED(CONFIG_ARCH_MMP));
-	if (use_dma && !dma_available) {
-		use_dma = 0;
-		dev_warn(&pdev->dev,
-			 "This platform can't do DMA on this device\n");
-	}
-
-	ret = pxa3xx_nand_probe_dt(pdev);
-	if (ret)
-		return ret;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -ENODEV;
-	}
-
-	ret = alloc_nand_resource(pdev);
-	if (ret)
-		return ret;
-
-	info = platform_get_drvdata(pdev);
-	probe_success = 0;
-	for (cs = 0; cs < pdata->num_cs; cs++) {
-		struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip);
-
-		/*
-		 * The mtd name matches the one used in 'mtdparts' kernel
-		 * parameter. This name cannot be changed or otherwise
-		 * user's mtd partitions configuration would get broken.
-		 */
-		mtd->name = "pxa3xx_nand-0";
-		info->cs = cs;
-		ret = pxa3xx_nand_scan(mtd);
-		if (ret) {
-			dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
-				cs);
-			continue;
-		}
-
-		ret = mtd_device_register(mtd, pdata->parts[cs],
-					  pdata->nr_parts[cs]);
-		if (!ret)
-			probe_success = 1;
-	}
-
-	if (!probe_success) {
-		pxa3xx_nand_remove(pdev);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int pxa3xx_nand_suspend(struct device *dev)
-{
-	struct pxa3xx_nand_info *info = dev_get_drvdata(dev);
-
-	if (info->state) {
-		dev_err(dev, "driver busy, state = %d\n", info->state);
-		return -EAGAIN;
-	}
-
-	clk_disable(info->clk);
-	return 0;
-}
-
-static int pxa3xx_nand_resume(struct device *dev)
-{
-	struct pxa3xx_nand_info *info = dev_get_drvdata(dev);
-	int ret;
-
-	ret = clk_enable(info->clk);
-	if (ret < 0)
-		return ret;
-
-	/* We don't want to handle interrupt without calling mtd routine */
-	disable_int(info, NDCR_INT_MASK);
-
-	/*
-	 * Directly set the chip select to a invalid value,
-	 * then the driver would reset the timing according
-	 * to current chip select at the beginning of cmdfunc
-	 */
-	info->cs = 0xff;
-
-	/*
-	 * As the spec says, the NDSR would be updated to 0x1800 when
-	 * doing the nand_clk disable/enable.
-	 * To prevent it damaging state machine of the driver, clear
-	 * all status before resume
-	 */
-	nand_writel(info, NDSR, NDSR_MASK);
-
-	return 0;
-}
-#else
-#define pxa3xx_nand_suspend	NULL
-#define pxa3xx_nand_resume	NULL
-#endif
-
-static const struct dev_pm_ops pxa3xx_nand_pm_ops = {
-	.suspend	= pxa3xx_nand_suspend,
-	.resume		= pxa3xx_nand_resume,
-};
-
-static struct platform_driver pxa3xx_nand_driver = {
-	.driver = {
-		.name	= "pxa3xx-nand",
-		.of_match_table = pxa3xx_nand_dt_ids,
-		.pm	= &pxa3xx_nand_pm_ops,
-	},
-	.probe		= pxa3xx_nand_probe,
-	.remove		= pxa3xx_nand_remove,
-};
-
-module_platform_driver(pxa3xx_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("PXA3xx NAND controller driver");
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:42 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:42 +0100
Subject: [PATCH 2/8] mtd: nand: mxc: Add function to control hardware ECC
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-3-s.hauer@pengutronix.de>

For proper raw read/write support need to be able to control the
hardware ECC engine. Add a function to enable/disable it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 6741af990dc4..019c58579dbc 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -154,6 +154,7 @@ struct mxc_nand_devtype_data {
 			u_char *read_ecc, u_char *calc_ecc);
 	int (*setup_data_interface)(struct mtd_info *mtd, int csline,
 				    const struct nand_data_interface *conf);
+	void (*enable_hwecc)(struct nand_chip *chip, bool enable);
 
 	/*
 	 * On i.MX21 the CONFIG2:INT bit cannot be read if interrupts are masked
@@ -678,6 +679,42 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
 	return ret;
 }
 
+static void mxc_nand_enable_hwecc_v1_v2(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint16_t config1;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config1 = readw(NFC_V1_V2_CONFIG1);
+
+	if (enable)
+		config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+	else
+		config1 &= ~NFC_V1_V2_CONFIG1_ECC_EN;
+
+	writew(config1, NFC_V1_V2_CONFIG1);
+}
+
+static void mxc_nand_enable_hwecc_v3(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint32_t config2;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config2 = readl(NFC_V3_CONFIG2);
+
+	if (enable)
+		config2 |= NFC_V3_CONFIG2_ECC_EN;
+	else
+		config2 &= ~NFC_V3_CONFIG2_ECC_EN;
+
+	writel(config2, NFC_V3_CONFIG2);
+}
+
 /* This functions is used by upper layer to checks if device is ready */
 static int mxc_nand_dev_ready(struct mtd_info *mtd)
 {
@@ -1408,6 +1445,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 1,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1431,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1456,6 +1495,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.select_chip = mxc_nand_select_chip_v2,
 	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0x1e00,
@@ -1480,6 +1520,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
@@ -1505,6 +1546,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:47 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:47 +0100
Subject: [PATCH 7/8] mtd: nand: mxc: Drop now unnecessary functions
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-8-s.hauer@pengutronix.de>

Since we have our own read_page/write_page functions correct_data and
calculate are no longer needed. Remove them.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 36 ------------------------------------
 1 file changed, 36 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 6fbf98851a96..1d2c55e5ca89 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -152,8 +152,6 @@ struct mxc_nand_devtype_data {
 	u32 (*get_ecc_status)(struct mxc_nand_host *);
 	const struct mtd_ooblayout_ops *ooblayout;
 	void (*select_chip)(struct mtd_info *mtd, int chip);
-	int (*correct_data)(struct mtd_info *mtd, u_char *dat,
-			u_char *read_ecc, u_char *calc_ecc);
 	int (*setup_data_interface)(struct mtd_info *mtd, int csline,
 				    const struct nand_data_interface *conf);
 	void (*enable_hwecc)(struct nand_chip *chip, bool enable);
@@ -727,20 +725,6 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd)
 	return 1;
 }
 
-static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	/*
-	 * If HW ECC is enabled, we turn it on during init. There is
-	 * no need to enable again here.
-	 */
-}
-
-static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	return 0;
-}
-
 static int mxc_nand_read_page_v1(struct mtd_info *mtd, struct nand_chip *chip,
 				 void *buf, void *oob, bool ecc, int page)
 {
@@ -802,12 +786,6 @@ static int mxc_nand_read_page_v1(struct mtd_info *mtd, struct nand_chip *chip,
 	return max_bitflips;
 }
 
-static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	return 0;
-}
-
 static int mxc_nand_read_page_v2_v3(struct mtd_info *mtd, struct nand_chip *chip,
 				    void *buf, void *oob, bool ecc, int page)
 {
@@ -946,12 +924,6 @@ static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	return __mxc_nand_write_page(mtd, chip, host->data_buf, 1, page);
 }
 
-static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-				  u_char *ecc_code)
-{
-	return 0;
-}
-
 static u_char mxc_nand_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
@@ -1604,7 +1576,6 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 1,
 	.needs_ip = 0,
@@ -1629,7 +1600,6 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
@@ -1655,7 +1625,6 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v2,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v2,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
@@ -1682,7 +1651,6 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
@@ -1709,7 +1677,6 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
@@ -1963,9 +1930,6 @@ static int mxcnd_probe(struct platform_device *pdev)
 		this->ecc.write_page = mxc_nand_write_page;
 		this->ecc.write_page_raw = mxc_nand_write_page_raw;
 		this->ecc.write_oob = mxc_nand_write_oob;
-		this->ecc.calculate = mxc_nand_calculate_ecc;
-		this->ecc.hwctl = mxc_nand_enable_hwecc;
-		this->ecc.correct = host->devtype_data->correct_data;
 		break;
 
 	case NAND_ECC_SOFT:
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:46 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:46 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-7-s.hauer@pengutronix.de>

Now that we have our own read_page function add a write_page function
for consistency aswell. This can be a lot easier than the generic
function since we do not have to iterate over subpages but can write
the whole page at once. Also add write_page_raw and write_oob for
proper raw and oob write support.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 83bb01ab7079..6fbf98851a96 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -893,6 +893,59 @@ static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 					     page);
 }
 
+static int __mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+				 const uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	memcpy32_toio(host->main_area0, buf, mtd->writesize);
+	copy_spare(mtd, false, chip->oob_poi);
+
+	host->devtype_data->send_page(mtd, NFC_INPUT);
+	host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	return 0;
+}
+
+static int mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+			       const uint8_t *buf, int oob_required, int page)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	host->devtype_data->enable_hwecc(nand_chip, true);
+
+	return __mxc_nand_write_page(mtd, chip, buf, oob_required, page);
+}
+
+static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				   const uint8_t *buf, int oob_required, int page)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	host->devtype_data->enable_hwecc(nand_chip, false);
+
+	return __mxc_nand_write_page(mtd, chip, buf, oob_required, page);
+}
+
+static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	memset(host->data_buf, 0xff, mtd->writesize);
+
+	host->devtype_data->enable_hwecc(nand_chip, false);
+
+	return __mxc_nand_write_page(mtd, chip, host->data_buf, 1, page);
+}
+
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 				  u_char *ecc_code)
 {
@@ -1907,6 +1960,9 @@ static int mxcnd_probe(struct platform_device *pdev)
 		this->ecc.read_page = mxc_nand_read_page;
 		this->ecc.read_page_raw = mxc_nand_read_page_raw;
 		this->ecc.read_oob = mxc_nand_read_oob;
+		this->ecc.write_page = mxc_nand_write_page;
+		this->ecc.write_page_raw = mxc_nand_write_page_raw;
+		this->ecc.write_oob = mxc_nand_write_oob;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:48 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:48 +0100
Subject: [PATCH 8/8] mtd: nand: mxc: remove now unused code
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-9-s.hauer@pengutronix.de>

Since we now have our own read_page/write_page functions
mxc_nand_command() will no longer be called with NAND_CMD_READ0,
NAND_CMD_READOOB, NAND_CMD_SEQIN and NAND_CMD_PAGEPROG. Remove
the code handling these commands.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 51 ---------------------------------------------
 1 file changed, 51 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 1d2c55e5ca89..efe29a179c5c 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1403,57 +1403,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-		if (command == NAND_CMD_READ0)
-			host->buf_start = column;
-		else
-			host->buf_start = column + mtd->writesize;
-
-		command = NAND_CMD_READ0; /* only READ0 is valid */
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < 0,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-
-		if (mtd->writesize > 512)
-			host->devtype_data->send_cmd(host,
-					NAND_CMD_READSTART, true);
-
-		host->devtype_data->send_page(mtd, NFC_OUTPUT);
-
-		memcpy32_fromio(host->data_buf, host->main_area0,
-				mtd->writesize);
-		copy_spare(mtd, true, host->data_buf + mtd->writesize);
-		break;
-
-	case NAND_CMD_SEQIN:
-		if (column >= mtd->writesize)
-			/* call ourself to read a page */
-			mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr);
-
-		host->buf_start = column;
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-		break;
-
-	case NAND_CMD_PAGEPROG:
-		memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
-		copy_spare(mtd, false, host->data_buf + mtd->writesize);
-		host->devtype_data->send_page(mtd, NFC_INPUT);
-		host->devtype_data->send_cmd(host, command, true);
-		WARN_ONCE(column != -1 || page_addr != -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, column, page_addr);
-		break;
-
 	case NAND_CMD_READID:
 		host->devtype_data->send_cmd(host, command, true);
 		mxc_do_addr_cycle(mtd, column, page_addr);
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:43 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:43 +0100
Subject: [PATCH 3/8] mtd: nand: mxc: Add buffer argument to copy_spare
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-4-s.hauer@pengutronix.de>

With following patches we will have to copy the spare data to/from
other buffers, so add the buffer as argument to copy_spare().

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 019c58579dbc..ab9cd45237d3 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -262,14 +262,14 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size)
  * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
  * spare) and the NFC buffer.
  */
-static void copy_spare(struct mtd_info *mtd, bool bfrom)
+static void copy_spare(struct mtd_info *mtd, bool bfrom, void *buf)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
 	struct mxc_nand_host *host = nand_get_controller_data(this);
 	u16 i, oob_chunk_size;
 	u16 num_chunks = mtd->writesize / 512;
 
-	u8 *d = host->data_buf + mtd->writesize;
+	u8 *d = buf;
 	u8 __iomem *s = host->spare0;
 	u16 sparebuf_size = host->devtype_data->spare_len;
 
@@ -1295,7 +1295,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 		memcpy32_fromio(host->data_buf, host->main_area0,
 				mtd->writesize);
-		copy_spare(mtd, true);
+		copy_spare(mtd, true, host->data_buf + mtd->writesize);
 		break;
 
 	case NAND_CMD_SEQIN:
@@ -1314,7 +1314,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 	case NAND_CMD_PAGEPROG:
 		memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
-		copy_spare(mtd, false);
+		copy_spare(mtd, false, host->data_buf + mtd->writesize);
 		host->devtype_data->send_page(mtd, NFC_INPUT);
 		host->devtype_data->send_cmd(host, command, true);
 		WARN_ONCE(column != -1 || page_addr != -1,
-- 
2.11.0



From s.hauer at pengutronix.de  Tue Jan  9 02:11:44 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue,  9 Jan 2018 11:11:44 +0100
Subject: [PATCH 4/8] mtd: nand: mxc: Fix failed/corrected values for v2/v3
 controllers
In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
Message-ID: <20180109101148.13728-5-s.hauer@pengutronix.de>

Currently nand_read_page_hwecc() from nand_base calls
mxc_nand_correct_data_v2_v3() for each subpage, but in this function we
return the corrected/failed results for the whole page instead
of a single subpage. On a 2k page size Nand this leads to results which
are 4 times too high.
The whole ecc.calculate/ecc.correct mechanism used by
nand_read_page_hwecc() is not suitable for devices which correct the
data in hardware, so fix this by using a driver specific read_page
function which does the right thing. Also add read_page_raw and read_oob
For proper raw and oob read support.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 84 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 76 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index ab9cd45237d3..d698f7c6666c 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -140,6 +140,8 @@ struct mxc_nand_host;
 
 struct mxc_nand_devtype_data {
 	void (*preset)(struct mtd_info *);
+	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
+			void *buf, void *oob, bool ecc, int page);
 	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_page)(struct mtd_info *, unsigned int);
@@ -757,13 +759,35 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
+	return 0;
+}
+
+static int mxc_nand_read_page_v2_v3(struct mtd_info *mtd, struct nand_chip *chip,
+				    void *buf, void *oob, bool ecc, int page)
+{
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int max_bitflips = 0;
 	u32 ecc_stat, err;
-	int no_subpages = 1;
-	int ret = 0;
+	int no_subpages;
 	u8 ecc_bit_mask, err_limit;
 
+	host->devtype_data->enable_hwecc(nand_chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host,
+				NAND_CMD_READSTART, true);
+
+	host->devtype_data->send_page(mtd, NFC_OUTPUT);
+
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
 	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
 	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
 
@@ -774,17 +798,53 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 	do {
 		err = ecc_stat & ecc_bit_mask;
 		if (err > err_limit) {
-			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
-			return -EBADMSG;
+			mtd->ecc_stats.failed++;
 		} else {
-			ret += err;
+			mtd->ecc_stats.corrected += err;
+			max_bitflips = max_t(unsigned int, max_bitflips, err);
 		}
+
 		ecc_stat >>= 4;
 	} while (--no_subpages);
 
-	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
+	return max_bitflips;
+}
 
-	return ret;
+static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(mtd, chip, buf, oob_buf, 1, page);
+}
+
+static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				  uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(mtd, chip, buf, oob_buf, 0, page);
+}
+
+static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			     int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	return host->devtype_data->read_page(mtd, chip, NULL, chip->oob_poi, 0,
+					     page);
 }
 
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
@@ -1483,6 +1543,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 /* v21: i.MX25, i.MX35 */
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.preset = preset_v2,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v2,
@@ -1509,6 +1570,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 /* v3.2a: i.MX51 */
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1535,6 +1597,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 /* v3.2b: i.MX53 */
 static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1793,6 +1856,11 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
+		if (host->devtype_data->read_page) {
+			this->ecc.read_page = mxc_nand_read_page;
+			this->ecc.read_page_raw = mxc_nand_read_page_raw;
+			this->ecc.read_oob = mxc_nand_read_oob;
+		}
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From miquel.raynal at free-electrons.com  Tue Jan  9 03:06:09 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Tue, 9 Jan 2018 12:06:09 +0100
Subject: [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87zi5nbh14.fsf@belgarion.home>
References: <20171207201814.30411-1-miquel.raynal@free-electrons.com>
 <20171214070930.0b885f6d@bbrezillon>
 <877etkecig.fsf@belgarion.home> <20171218092535.2ca1fe13@xps13>
 <87y3lxccr7.fsf@belgarion.home>
 <20171220224121.2cb6f690@bbrezillon>
 <87lghucykr.fsf@belgarion.home>
 <20171222222441.0fd77df9@bbrezillon>
 <20171222233730.68d9cb9d@xps13> <87k1xdblxf.fsf@belgarion.home>
 <20171223155709.2ba16e95@xps13> <87fu81bc45.fsf@belgarion.home>
 <20180102120326.7a2cf1d1@xps13> <87d12scbiy.fsf@belgarion.home>
 <20180103084037.422b239a@xps13> <878tded89m.fsf@belgarion.home>
 <20180103211028.619cd16d@bbrezillon>
 <20180103215206.5d85b41b@bbrezillon>
 <87zi5nbh14.fsf@belgarion.home>
Message-ID: <20180109120609.153b6bde@xps13>

Hello Robert,

On Tue, 09 Jan 2018 08:57:59 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> Ok I recovered my NAND.
> 
> For the next try, I'd like you to provide another "temporary patch"
> to disable BBT actual writing, just to be sure. Once the driver is
> working properly, I'll make another try without the temporary patch.

The best way to do it is to avoid using the BBT at all, and while I was
looking for the right line to comment in the Zylonite's board file I
found out that the boolean flash_bbt is not actually set and then I
remembered an old mail from you, then you should:

----->8-----
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 0534949d63f6..d247ef01dc62 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -378,6 +378,8 @@ static struct mtd_partition
zylonite_nand_partitions[] = { static struct pxa3xx_nand_platform_data
zylonite_nand_info = { .parts		= zylonite_nand_partitions,
 	.nr_parts	= ARRAY_SIZE(zylonite_nand_partitions),
-	.flash_bbt	= 1,
	.keep_config	= 1,
 };
 
 static void __init zylonite_init_nand(void)
-----8<-----

Then, do not forget to resize the partition that stores the BBT to
remove the last 4 erase blocks from it to avoid UBI/UBIFS smashing it.

Then you should be fine.

You can test this branch (updated with last version I sent earlier):
https://github.com/miquelraynal/linux/tree/marvell/nand-next/nfc


Thanks,
Miqu?l


From ladis at linux-mips.org  Tue Jan  9 03:19:13 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 12:19:13 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109110630.24a26735@bbrezillon>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
 <20180109090845.GA22600@lenoch>
 <20180109102704.62ba7fc9@bbrezillon> <20180109095803.GA6798@lenoch>
 <20180109110630.24a26735@bbrezillon>
Message-ID: <20180109111913.GA25137@lenoch>

On Tue, Jan 09, 2018 at 11:06:30AM +0100, Boris Brezillon wrote:
> On Tue, 9 Jan 2018 10:58:03 +0100
> Ladislav Michl <ladis at linux-mips.org> wrote:
> 
> > On Tue, Jan 09, 2018 at 10:27:04AM +0100, Boris Brezillon wrote:
> > > On Tue, 9 Jan 2018 10:08:45 +0100
> > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > >   
> > > > On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:  
> > > > > On Tue, 9 Jan 2018 00:48:37 +0100
> > > > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > > > >     
> > > > > > Samsung E-die SLC NAND manufactured using 21nm process supports only    
> > > > > 
> > > > > I would add the chip name here (K9F1G08U0E).    
> > > > 
> > > > Ok.
> > > >   
> > > > > > 1 partial program cycle, so disable subpage writes for it.    
> > > > > 
> > > > > Which means it does not support partial page programming, so how about
> > > > > rewording it like that:
> > > > > 
> > > > > Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> > > > > does not support partial page programming, so disable subpage writes
> > > > > for it.    
> > > > 
> > > > Yes, will post v2 eventually, but see bellow.
> > > >   
> > > > > > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > > > > > 
> > > > > > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > > > > > ---
> > > > > >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> > > > > >        board with K9F1G08U0E.    
> > > > > 
> > > > > Just out of curiosity, what are the symptoms when you don't have this
> > > > > flag set?    
> > > > 
> > > > Device is identified as:
> > > > nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
> > > > nand: Samsung NAND 128MiB 3,3V 8-bit
> > > > nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > > 
> > > > Short test:
> > > > # flash_erase /dev/mtd4 0 0
> > > > Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
> > > > flash_erase: Skipping bad block at 07fa0000
> > > > flash_erase: Skipping bad block at 07fc0000
> > > > flash_erase: Skipping bad block at 07fe0000
> > > > Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
> > > > # ubiformat /dev/mtd4
> > > > ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
> > > > libscan: scanning eraseblock 1023 -- 100 % complete  
> > > > ubiformat: 1020 eraseblocks are supposedly empty
> > > > ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
> > > > ubiformat: formatting eraseblock 1023 -- 100 % complete  
> > > > # ubiattach -m 4
> > > > ubi0: default fastmap pool size: 50
> > > > ubi0: default fastmap WL pool size: 25
> > > > ubi0: attaching mtd4
> > > > ubi0: scanning is finished
> > > > ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
> > > > ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> > > > ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> > > > ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> > > > ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
> > > > ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
> > > > ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
> > > > ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
> > > > ubi0: background thread "ubi_bgt0d" started, PID 716
> > > > UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
> > > > # ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
> > > > Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
> > > > # ubiupdatevol /dev/ubi0_0 linuximage 
> > > > __nand_correct_data: uncorrectable ECC error
> > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > __nand_correct_data: uncorrectable ECC error
> > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > __nand_correct_data: uncorrectable ECC error
> > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > __nand_correct_data: uncorrectable ECC error
> > > > ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
> > > > CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
> > > > Hardware name: Atmel AT91SAM9
> > > > [<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
> > > > [<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
> > > > [<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
> > > > [<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
> > > > [<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
> > > > [<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
> > > > [<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
> > > > [<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
> > > > [<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
> > > > [<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
> > > > ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
> > > > ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted
> > > > 
> > > > There's another patchset to deal with this issue:
> > > > http://thread.gmane.org/gmane.linux.drivers.mtd/54167  
> > > 
> > > Are you sure it fixes your problem??? Did you try it?  
> > 
> > Just forward ported them to -next yesterday. Will give it a try for sure.

Assuming I forward ported patches correctly they does _not_ solve my problem,
as you expected :)

> > > > And it brings a problem to us as those patches are mutually exclusive.
> > > > Once no subpage write patch is applied UBI's VID header offset changes to 2048
> > > > from 512, so on flash filesystem is no longer readable if we wish to give
> > > > optimize subpage writes a chance later.  
> > > 
> > > If your NAND does not support subpage writes, you have to expose a
> > > min_io_size of a page not a subpage. AFAICT, the patchset you're
> > > referring to won't fix your problem.
> > >   
> > > > 
> > > > I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
> > > > patch worth considering again?  
> > > 
> > > Incompatibility with what? The datasheet clearly says that the chip
> > > does not support subpage writes.
> > >   
> > > >   
> > > > > >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> > > > > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > > > > > index f6b0a63a068c..9400b4a84243 100644
> > > > > > --- a/drivers/mtd/nand/nand_samsung.c
> > > > > > +++ b/drivers/mtd/nand/nand_samsung.c
> > > > > > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> > > > > >  	} else {
> > > > > >  		nand_decode_ext_id(chip);
> > > > > >  
> > > > > > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > > > > > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > > > > > -			chip->ecc_step_ds = 512;
> > > > > > -			chip->ecc_strength_ds = 1;
> > > > > > +		if (nand_is_slc(chip)) {
> > > > > > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > > > > > +			if (chip->id.data[1] == 0xDC) {
> > > > > > +				chip->ecc_step_ds = 512;
> > > > > > +				chip->ecc_strength_ds = 1;
> > > > > > +			}
> > > > > > +
> > > > > > +			/* 21nm chips do not support partial page write */
> > > > > > +			if (chip->id.len > 4 &&
> > > > > > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)    
> > > > > 
> > > > > NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> > > > > should be more restrictive here: replace "chip->id.len > 4" by
> > > > > "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.    
> > > > 
> > > > Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
> > > > seems to be a good idea.  
> > > 
> > > That's not what the datasheet says :-/. What's the value of
> > > chip->id.data[5]?  
> > 
> > The result of
> > printk("id_len %d, id_data4 %x, id_data5 %x\n",
> > 	chip->id.len, chip->id.data[4], chip->id.data[5]);
> > is
> > id_len 6, id_data4 41, id_data5 ec
> 
> So id.data[5] == id.data[0], can you print id.data[6] and id.data[7]?

The result of
printk("id_len %d, id_data4 %x, id_data5 %x, id_data6 %x, id_data7 %x\n",
        chip->id.len, chip->id.data[4], chip->id.data[5], chip->id.data[6], chip->id.data[7]);
is
id_len 6, id_data4 41, id_data5 ec, id_data6 ec, id_data7 f1

Based on previous comments patch so far looks like (and unless there are
objections, I'm temped to replace if (chip->id.data[1] == XX) with
switch statement):

diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
index f6b0a63a068c..67ca9978cf27 100644
--- a/drivers/mtd/nand/nand_samsung.c
+++ b/drivers/mtd/nand/nand_samsung.c
@@ -92,10 +92,18 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 	} else {
 		nand_decode_ext_id(chip);
 
-		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
-		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
-			chip->ecc_step_ds = 512;
-			chip->ecc_strength_ds = 1;
+		if (nand_is_slc(chip)) {
+			/* K9F4G08U0D-S[I|C]B0(T00) */
+			if (chip->id.data[1] == 0xDC) {
+				chip->ecc_step_ds = 512;
+				chip->ecc_strength_ds = 1;
+			}
+
+			/* 21nm chips do not support partial page write */
+			if (chip->id.data[1] == 0xF1 &&
+			    chip->id.len > 4 &&
+			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
+				chip->options |= NAND_NO_SUBPAGE_WRITE;
 		}
 	}
 }


From s.hauer at pengutronix.de  Tue Jan  9 03:08:29 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 9 Jan 2018 12:08:29 +0100
Subject: [PATCH v2] mtd: tests: nandbiterrs: Fix read_page return value
In-Reply-To: <20180109105108.4ece18cf@bbrezillon>
References: <20180109094702.21488-1-s.hauer@pengutronix.de>
 <20180109105108.4ece18cf@bbrezillon>
Message-ID: <20180109110829.tteckyyt2lzkz2t4@pengutronix.de>

On Tue, Jan 09, 2018 at 10:51:08AM +0100, Boris Brezillon wrote:
> On Tue,  9 Jan 2018 10:47:02 +0100
> Sascha Hauer <s.hauer at pengutronix.de> wrote:
> 
> > The number of corrected bitflips is not correctly reported by
> > the test until the bitflip threshold is reached.
> > 
> > read_page() shall return the number of corrected bitflips, but
> > mtd_read() returns 0 or a negative error, so we can't forward
> > its return value. In the absence of an error we always have
> > calculate the number of bitflips ourselves.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> 
> I'll apply this patch, but you should really start using the userspace
> tests provided by mtd-utils, because I still plan to remove the
> in-kernel test modules at some point ;-).

Please do so. When I cannot find the in-kernel tests anymore I'll recall
that there are tests in userspace ;)

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From boris.brezillon at free-electrons.com  Tue Jan  9 05:07:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 9 Jan 2018 14:07:17 +0100
Subject: [PATCH] mtd: nand: samsung: Disable subpage writes on E-die NAND
In-Reply-To: <20180109111913.GA25137@lenoch>
References: <20180108234837.GA15913@lenoch>
 <20180109094621.23a5e368@bbrezillon>
 <20180109090845.GA22600@lenoch>
 <20180109102704.62ba7fc9@bbrezillon> <20180109095803.GA6798@lenoch>
 <20180109110630.24a26735@bbrezillon>
 <20180109111913.GA25137@lenoch>
Message-ID: <20180109140717.03d13908@bbrezillon>

On Tue, 9 Jan 2018 12:19:13 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> On Tue, Jan 09, 2018 at 11:06:30AM +0100, Boris Brezillon wrote:
> > On Tue, 9 Jan 2018 10:58:03 +0100
> > Ladislav Michl <ladis at linux-mips.org> wrote:
> >   
> > > On Tue, Jan 09, 2018 at 10:27:04AM +0100, Boris Brezillon wrote:  
> > > > On Tue, 9 Jan 2018 10:08:45 +0100
> > > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > > >     
> > > > > On Tue, Jan 09, 2018 at 09:46:21AM +0100, Boris Brezillon wrote:    
> > > > > > On Tue, 9 Jan 2018 00:48:37 +0100
> > > > > > Ladislav Michl <ladis at linux-mips.org> wrote:
> > > > > >       
> > > > > > > Samsung E-die SLC NAND manufactured using 21nm process supports only      
> > > > > > 
> > > > > > I would add the chip name here (K9F1G08U0E).      
> > > > > 
> > > > > Ok.
> > > > >     
> > > > > > > 1 partial program cycle, so disable subpage writes for it.      
> > > > > > 
> > > > > > Which means it does not support partial page programming, so how about
> > > > > > rewording it like that:
> > > > > > 
> > > > > > Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> > > > > > does not support partial page programming, so disable subpage writes
> > > > > > for it.      
> > > > > 
> > > > > Yes, will post v2 eventually, but see bellow.
> > > > >     
> > > > > > > Manufacturing process is stored in lowest two bits of 5th ID byte.
> > > > > > > 
> > > > > > > Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> > > > > > > ---
> > > > > > >  Note: Patch generated and tested against next-20180108 on at91sam9g20
> > > > > > >        board with K9F1G08U0E.      
> > > > > > 
> > > > > > Just out of curiosity, what are the symptoms when you don't have this
> > > > > > flag set?      
> > > > > 
> > > > > Device is identified as:
> > > > > nand: device found, Manufacturer ID: 0xec, Chip ID: 0xf1
> > > > > nand: Samsung NAND 128MiB 3,3V 8-bit
> > > > > nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > > > 
> > > > > Short test:
> > > > > # flash_erase /dev/mtd4 0 0
> > > > > Erasing 128 Kibyte @ 7f60000 -- 99 % complete flash_erase: Skipping bad block at 07f80000
> > > > > flash_erase: Skipping bad block at 07fa0000
> > > > > flash_erase: Skipping bad block at 07fc0000
> > > > > flash_erase: Skipping bad block at 07fe0000
> > > > > Erasing 128 Kibyte @ 7fe0000 -- 100 % complete 
> > > > > # ubiformat /dev/mtd4
> > > > > ubiformat: mtd4 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
> > > > > libscan: scanning eraseblock 1023 -- 100 % complete  
> > > > > ubiformat: 1020 eraseblocks are supposedly empty
> > > > > ubiformat: 4 bad eraseblocks found, numbers: 1020, 1021, 1022, 1023
> > > > > ubiformat: formatting eraseblock 1023 -- 100 % complete  
> > > > > # ubiattach -m 4
> > > > > ubi0: default fastmap pool size: 50
> > > > > ubi0: default fastmap WL pool size: 25
> > > > > ubi0: attaching mtd4
> > > > > ubi0: scanning is finished
> > > > > ubi0: attached mtd4 (name "atmel_nand", size 128 MiB)
> > > > > ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> > > > > ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> > > > > ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> > > > > ubi0: good PEBs: 1020, bad PEBs: 4, corrupted PEBs: 0
> > > > > ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
> > > > > ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 1387212117
> > > > > ubi0: available PEBs: 998, total reserved PEBs: 22, PEBs reserved for bad PEB handling: 16
> > > > > ubi0: background thread "ubi_bgt0d" started, PID 716
> > > > > UBI device number 0, total 1020 LEBs (129515520 bytes, 123.5 MiB), available 998 LEBs (126722048 bytes, 120.9 MiB), LEB size 126976 bytes (124.0 KiB)
> > > > > # ubimkvol /dev/ubi0 -s 4MiB -N kernel -t static
> > > > > Volume ID 0, size 34 LEBs (4317184 bytes, 4.1 MiB), LEB size 126976 bytes (124.0 KiB), static, name "kernel", alignment 1
> > > > > # ubiupdatevol /dev/ubi0_0 linuximage 
> > > > > __nand_correct_data: uncorrectable ECC error
> > > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > > __nand_correct_data: uncorrectable ECC error
> > > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > > __nand_correct_data: uncorrectable ECC error
> > > > > ubi0 warning: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read only 64 bytes, retry
> > > > > __nand_correct_data: uncorrectable ECC error
> > > > > ubi0 error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 309:512, read 64 bytes
> > > > > CPU: 0 PID: 720 Comm: ubiupdatevol Not tainted 4.14.4 #7
> > > > > Hardware name: Atmel AT91SAM9
> > > > > [<c010796c>] (unwind_backtrace) from [<c01053e0>] (show_stack+0x10/0x14)
> > > > > [<c01053e0>] (show_stack) from [<c0337fac>] (ubi_io_read+0x1d8/0x2ac)
> > > > > [<c0337fac>] (ubi_io_read) from [<c03384c4>] (ubi_io_read_vid_hdr+0x70/0x214)
> > > > > [<c03384c4>] (ubi_io_read_vid_hdr) from [<c0335b44>] (ubi_eba_read_leb+0x154/0x414)
> > > > > [<c0335b44>] (ubi_eba_read_leb) from [<c033e5b8>] (ubi_check_volume+0x7c/0xb8)
> > > > > [<c033e5b8>] (ubi_check_volume) from [<c0334180>] (vol_cdev_write+0x254/0x364)
> > > > > [<c0334180>] (vol_cdev_write) from [<c01a617c>] (__vfs_write+0x20/0x128)
> > > > > [<c01a617c>] (__vfs_write) from [<c01a6420>] (vfs_write+0xb4/0x13c)
> > > > > [<c01a6420>] (vfs_write) from [<c01a65b8>] (SyS_write+0x40/0x74)
> > > > > [<c01a65b8>] (SyS_write) from [<c0102480>] (ret_fast_syscall+0x0/0x44)
> > > > > ubi0 warning: ubi_eba_read_leb: corrupted VID header at PEB 309, LEB 0:0
> > > > > ubi0 warning: vol_cdev_write: volume 0 on UBI device 0 is corrupted
> > > > > 
> > > > > There's another patchset to deal with this issue:
> > > > > http://thread.gmane.org/gmane.linux.drivers.mtd/54167    
> > > > 
> > > > Are you sure it fixes your problem??? Did you try it?    
> > > 
> > > Just forward ported them to -next yesterday. Will give it a try for sure.  
> 
> Assuming I forward ported patches correctly they does _not_ solve my problem,
> as you expected :)
> 
> > > > > And it brings a problem to us as those patches are mutually exclusive.
> > > > > Once no subpage write patch is applied UBI's VID header offset changes to 2048
> > > > > from 512, so on flash filesystem is no longer readable if we wish to give
> > > > > optimize subpage writes a chance later.    
> > > > 
> > > > If your NAND does not support subpage writes, you have to expose a
> > > > min_io_size of a page not a subpage. AFAICT, the patchset you're
> > > > referring to won't fix your problem.
> > > >     
> > > > > 
> > > > > I do want to introduce any hard to overcome incompatibility, so isn't Pekon's
> > > > > patch worth considering again?    
> > > > 
> > > > Incompatibility with what? The datasheet clearly says that the chip
> > > > does not support subpage writes.
> > > >     
> > > > >     
> > > > > > >  drivers/mtd/nand/nand_samsung.c | 15 +++++++++++----
> > > > > > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> > > > > > > index f6b0a63a068c..9400b4a84243 100644
> > > > > > > --- a/drivers/mtd/nand/nand_samsung.c
> > > > > > > +++ b/drivers/mtd/nand/nand_samsung.c
> > > > > > > @@ -92,10 +92,17 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
> > > > > > >  	} else {
> > > > > > >  		nand_decode_ext_id(chip);
> > > > > > >  
> > > > > > > -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> > > > > > > -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> > > > > > > -			chip->ecc_step_ds = 512;
> > > > > > > -			chip->ecc_strength_ds = 1;
> > > > > > > +		if (nand_is_slc(chip)) {
> > > > > > > +			/* K9F4G08U0D-S[I|C]B0(T00) */
> > > > > > > +			if (chip->id.data[1] == 0xDC) {
> > > > > > > +				chip->ecc_step_ds = 512;
> > > > > > > +				chip->ecc_strength_ds = 1;
> > > > > > > +			}
> > > > > > > +
> > > > > > > +			/* 21nm chips do not support partial page write */
> > > > > > > +			if (chip->id.len > 4 &&
> > > > > > > +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)      
> > > > > > 
> > > > > > NAND vendors tend to change their ID decoding scheme a lot, so maybe we
> > > > > > should be more restrictive here: replace "chip->id.len > 4" by
> > > > > > "chip->id.len == 5" and restrict it to chip->id.data[1] == 0xF1.      
> > > > > 
> > > > > Well, K9F1G08U0E returns chip->id.len = 6, but adding chip->id.data[1]
> > > > > seems to be a good idea.    
> > > > 
> > > > That's not what the datasheet says :-/. What's the value of
> > > > chip->id.data[5]?    
> > > 
> > > The result of
> > > printk("id_len %d, id_data4 %x, id_data5 %x\n",
> > > 	chip->id.len, chip->id.data[4], chip->id.data[5]);
> > > is
> > > id_len 6, id_data4 41, id_data5 ec  
> > 
> > So id.data[5] == id.data[0], can you print id.data[6] and id.data[7]?  
> 
> The result of
> printk("id_len %d, id_data4 %x, id_data5 %x, id_data6 %x, id_data7 %x\n",
>         chip->id.len, chip->id.data[4], chip->id.data[5], chip->id.data[6], chip->id.data[7]);
> is
> id_len 6, id_data4 41, id_data5 ec, id_data6 ec, id_data7 f1

Okay, this explains why we get a len of 6 instead of 5: the
manufacturer code is repeated twice (data[5] and data[6]).

> 
> Based on previous comments patch so far looks like (and unless there are
> objections, I'm temped to replace if (chip->id.data[1] == XX) with
> switch statement):

Yes, sounds good (one extra comment below)

> 
> diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> index f6b0a63a068c..67ca9978cf27 100644
> --- a/drivers/mtd/nand/nand_samsung.c
> +++ b/drivers/mtd/nand/nand_samsung.c
> @@ -92,10 +92,18 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
>  	} else {
>  		nand_decode_ext_id(chip);
>  
> -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> -			chip->ecc_step_ds = 512;
> -			chip->ecc_strength_ds = 1;
> +		if (nand_is_slc(chip)) {
> +			/* K9F4G08U0D-S[I|C]B0(T00) */
> +			if (chip->id.data[1] == 0xDC) {
> +				chip->ecc_step_ds = 512;
> +				chip->ecc_strength_ds = 1;
> +			}
> +
> +			/* 21nm chips do not support partial page write */

Please give the chip name in your comment (K9F1G08U0E).

> +			if (chip->id.data[1] == 0xF1 &&
> +			    chip->id.len > 4 &&
> +			    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
> +				chip->options |= NAND_NO_SUBPAGE_WRITE;
>  		}
>  	}
>  }



From ladis at linux-mips.org  Tue Jan  9 05:08:12 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 14:08:12 +0100
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
Message-ID: <20180109130812.GA338@lenoch>

Just a very gentle ping, more bellow...

On Fri, Dec 01, 2017 at 03:43:55PM +0200, Roger Quadros wrote:
> On 30/11/17 18:09, Tony Lindgren wrote:
> > * Boris Brezillon <boris.brezillon at free-electrons.com> [171130 10:21]:
> >> On Wed, 15 Nov 2017 17:23:06 +0100
> >> Ladislav Michl <ladis at linux-mips.org> wrote:
> >>
> >>> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> >>> it fully DT configurable, using libgpio and dmaengine apis - those are
> >>> optional, driver will work without them.
> >>>
> >>> Please note that unlike previous driver version, which basically ignored
> >>> DT specified timings, this one relies on it, so it is important to get
> >>> it right in your DT (dumping it from previous kernel version).
> >>>
> >>> In case synchronous timings is requested, it is okay to specify timings
> >>> for the slowest chip ever used for you board as it is evetually optimized
> >>> after chip probe.
> >>>
> >>> Original driver used DMA only if user specified INT gpio in platform
> >>> data, now DMA is used unconditionally and PIO mode is used as fallback.
> >>>
> >>> In case anyone wants to give it a try, few DT related changes are needed:
> >>> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
> >>>   done in patch 2)
> >>> - to use INT pin, int-gpios needs to be specified (for n900 and n8x0 this is
> >>>   done in patch 16, however patch lacks pinmux configuration.
> >>>
> >>> Most notable changes from v3:
> >>> - added dmaengine patches by Peter Ujfalusi
> >>> - added dt bindings documentation
> >>> - added cleanup patches
> >>> - DMA enabled by default
> >>>
> >>> Most notable changes from v4:
> >>> - collected tags
> >>> - used INT pin name properly
> >>> - hopefully all comments taken into account
> >>>
> >>> Also note that driver will fail probe OneNAND chip after patch 13 and start
> >>> working again after patch 14.
> >>
> >> Well, breaking bisectability is never a good thing, this being said, I
> >> won't complain if TI maintainers are okay with that.
> > 
> > There should not be any reason to break git bisect for booting at all,
> > what exactly is the issue here?
> > 
> >>> Testing and benchmarking very welcome.
> >>
> >> Let me know when you think this series is ready to be merged.
> > 
> > Well we need Aaro to test this on n8x0 as my n800 is currently not
> > booting at all.
> > 
> >>> Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> >>> https://patchwork.kernel.org/patch/10043259/
> >>
> >> Hm, I see this patch has been applied to the omap tree, so maybe it's
> >> simpler if everything goes through this tree. I don't plan to modify
> >> onenand related stuff in this release anyway.
> > 
> > Maybe Roger can provide you with an immutable commit with just that
> > patch?
> 
> Here you go

Thank you :)

Merge window is really close now and patches seems still to be untested on
n8x0. So unless someone is going to test it soon, I'll pick used N800 on
ebay :-/

I would also appreciate final statement which tree will used to merge this
patchset. So far everyone seems to agree this patchset will enter via single
tree, right? If that is the case I'm proposing to squash patches 13 and 14
into single patch, so we do not break bisecting.

> The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
> 
>   Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
> 
> are available in the git repository at:
> 
>   https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
> 
> for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:
> 
>   memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
> 
> ----------------------------------------------------------------
> Ladislav Michl (1):
>       memory: omap-gpmc: Make 'bank-width' property optional
> 
>  drivers/memory/omap-gpmc.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From ladis at linux-mips.org  Tue Jan  9 05:19:11 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Tue, 9 Jan 2018 14:19:11 +0100
Subject: [PATCH v2] mtd: nand: samsung: Disable subpage writes on E-die NAND
Message-ID: <20180109131911.GA3907@lenoch>

Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
does not support partial page programming, so disable subpage writes
for it. Manufacturing process is stored in lowest two bits of 5th ID
byte.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
---
 Changes:
 - v2: 
   * Reword commit log
   * Check also for device type
   * Reimplement if statements using switch

 drivers/mtd/nand/nand_samsung.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
index f6b0a63a068c..6971c35b78e9 100644
--- a/drivers/mtd/nand/nand_samsung.c
+++ b/drivers/mtd/nand/nand_samsung.c
@@ -92,10 +92,22 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 	} else {
 		nand_decode_ext_id(chip);
 
-		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
-		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
-			chip->ecc_step_ds = 512;
-			chip->ecc_strength_ds = 1;
+		if (nand_is_slc(chip)) {
+			switch (chip->id.data[1]) {
+			/* K9F4G08U0D-S[I|C]B0(T00) */
+			case 0xDC:
+				chip->ecc_step_ds = 512;
+				chip->ecc_strength_ds = 1;
+				break;
+			/* K9F1G08U0E 21nm chips do not support subpage write */
+			case 0xF1:
+				if (chip->id.len > 4 &&
+				    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
+					chip->options |= NAND_NO_SUBPAGE_WRITE;
+				break;
+			default:
+				break;
+			}
 		}
 	}
 }
-- 
2.15.1



From nicolas.ferre at microchip.com  Tue Jan  9 05:46:39 2018
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Tue, 9 Jan 2018 14:46:39 +0100
Subject: [PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and ISC
 entries
Message-ID: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>

These two image capture interface drivers are now handled
by Wenyou Yang.
I benefit from this change to update the two entries by correcting the
binding documentation link for ISC and moving the ISI to the new
MICROCHIP / ATMEL location.

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Hi,

Patch against next-20180109.
Note that I didn't find it useful to have several patches for these changes.
Tell me if you feel differently.

I would like to have the Ack from Ludovic and Wenyou obviously. I don't know if
Songjun can answer as he's not with Microchip anymore.

Best regards,
  Nicolas

 MAINTAINERS | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a7d10a2bb980..65c4b59b582f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2353,13 +2353,6 @@ L:	linux-i2c at vger.kernel.org
 S:	Supported
 F:	drivers/i2c/busses/i2c-at91.c
 
-ATMEL ISI DRIVER
-M:	Ludovic Desroches <ludovic.desroches at microchip.com>
-L:	linux-media at vger.kernel.org
-S:	Supported
-F:	drivers/media/platform/atmel/atmel-isi.c
-F:	include/media/atmel-isi.h
-
 ATMEL LCDFB DRIVER
 M:	Nicolas Ferre <nicolas.ferre at microchip.com>
 L:	linux-fbdev at vger.kernel.org
@@ -9102,12 +9095,20 @@ S:	Maintained
 F:	drivers/crypto/atmel-ecc.*
 
 MICROCHIP / ATMEL ISC DRIVER
-M:	Songjun Wu <songjun.wu at microchip.com>
+M:	Wenyou Yang <wenyou.yang at microchip.com>
 L:	linux-media at vger.kernel.org
 S:	Supported
 F:	drivers/media/platform/atmel/atmel-isc.c
 F:	drivers/media/platform/atmel/atmel-isc-regs.h
-F:	devicetree/bindings/media/atmel-isc.txt
+F:	Documentation/devicetree/bindings/media/atmel-isc.txt
+
+MICROCHIP / ATMEL ISI DRIVER
+M:	Wenyou Yang <wenyou.yang at microchip.com>
+L:	linux-media at vger.kernel.org
+S:	Supported
+F:	drivers/media/platform/atmel/atmel-isi.c
+F:	include/media/atmel-isi.h
+F:	Documentation/devicetree/bindings/media/atmel-isi.txt
 
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh at microchip.com>
-- 
2.9.0



From nicolas.ferre at microchip.com  Tue Jan  9 05:46:40 2018
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Tue, 9 Jan 2018 14:46:40 +0100
Subject: [PATCH 2/2] MAINTAINERS: mtd/nand: update Microchip nand entry
In-Reply-To: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
References: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
Message-ID: <d8a6b8a3fe05c57972de1c374fcdeb933717396b.1515503733.git.nicolas.ferre@microchip.com>

Update Wenyou Yang email address.
Take advantage of this update to move this entry to the MICROCHIP / ATMEL
location and add the DT binding documentation link.

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Hi,

Patch against next-20180109.
This patch is somehow dependent on the previous one in the series
("MAINTAINERS: linux-media: update Microchip ISI and ISC entries") but can be
rebased easily.

I don't know if it's better to have them added at the end of the development
cycle or just after rc1: let me know if you plan to take them or if I need to
rebase them for next cycle.

Best regards,
  Nicolas


 MAINTAINERS | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 65c4b59b582f..b48e217d41fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2373,13 +2373,6 @@ F:	Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F:	drivers/input/touchscreen/atmel_mxt_ts.c
 F:	include/linux/platform_data/atmel_mxt_ts.h
 
-ATMEL NAND DRIVER
-M:	Wenyou Yang <wenyou.yang at atmel.com>
-M:	Josh Wu <rainyfeeling at outlook.com>
-L:	linux-mtd at lists.infradead.org
-S:	Supported
-F:	drivers/mtd/nand/atmel/*
-
 ATMEL SAMA5D2 ADC DRIVER
 M:	Ludovic Desroches <ludovic.desroches at microchip.com>
 L:	linux-iio at vger.kernel.org
@@ -9110,6 +9103,14 @@ F:	drivers/media/platform/atmel/atmel-isi.c
 F:	include/media/atmel-isi.h
 F:	Documentation/devicetree/bindings/media/atmel-isi.txt
 
+MICROCHIP / ATMEL NAND DRIVER
+M:	Wenyou Yang <wenyou.yang at microchip.com>
+M:	Josh Wu <rainyfeeling at outlook.com>
+L:	linux-mtd at lists.infradead.org
+S:	Supported
+F:	drivers/mtd/nand/atmel/*
+F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh at microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver at microchip.com>
-- 
2.9.0



From rafal at milecki.pl  Tue Jan  9 05:47:41 2018
From: rafal at milecki.pl (=?UTF-8?Q?Rafa=C5=82_Mi=C5=82ecki?=)
Date: Tue, 09 Jan 2018 14:47:41 +0100
Subject: [PATCH V6 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180109104245.0f8cf097@bbrezillon>
References: <20180102130458.16226-1-zajec5@gmail.com>
 <20180103105543.17897-1-zajec5@gmail.com>
 <CAL_JsqLYjUsWGAYm978oPmMAue6YDRb=K00gReZTia6iaJ6xsA@mail.gmail.com>
 <9a799300a0730a0103fe744878fb1a9f@milecki.pl>
 <20180109104245.0f8cf097@bbrezillon>
Message-ID: <2043e7d0214dffd5b0515cfdea2ed1d6@milecki.pl>

On 2018-01-09 10:42, Boris Brezillon wrote:
> Rafal, I had a look at your v7 and it looks sane, so I'll queue it for
> 4.16 unless Rob has other concerns.
> 
> Thanks for your patience.

Sounds great, thanks!


From ludovic.desroches at microchip.com  Tue Jan  9 06:01:02 2018
From: ludovic.desroches at microchip.com (Ludovic Desroches)
Date: Tue, 9 Jan 2018 15:01:02 +0100
Subject: [PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and
 ISC entries
In-Reply-To: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
References: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
Message-ID: <20180109140102.GH2425@rfolt0960.corp.atmel.com>

On Tue, Jan 09, 2018 at 02:46:39PM +0100, Nicolas Ferre wrote:
> These two image capture interface drivers are now handled
> by Wenyou Yang.
> I benefit from this change to update the two entries by correcting the
> binding documentation link for ISC and moving the ISI to the new
> MICROCHIP / ATMEL location.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroches at microchip.com>

> ---
> Hi,
> 
> Patch against next-20180109.
> Note that I didn't find it useful to have several patches for these changes.
> Tell me if you feel differently.
> 
> I would like to have the Ack from Ludovic and Wenyou obviously. I don't know if
> Songjun can answer as he's not with Microchip anymore.
> 
> Best regards,
>   Nicolas
> 
>  MAINTAINERS | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a7d10a2bb980..65c4b59b582f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2353,13 +2353,6 @@ L:	linux-i2c at vger.kernel.org
>  S:	Supported
>  F:	drivers/i2c/busses/i2c-at91.c
>  
> -ATMEL ISI DRIVER
> -M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> -L:	linux-media at vger.kernel.org
> -S:	Supported
> -F:	drivers/media/platform/atmel/atmel-isi.c
> -F:	include/media/atmel-isi.h
> -
>  ATMEL LCDFB DRIVER
>  M:	Nicolas Ferre <nicolas.ferre at microchip.com>
>  L:	linux-fbdev at vger.kernel.org
> @@ -9102,12 +9095,20 @@ S:	Maintained
>  F:	drivers/crypto/atmel-ecc.*
>  
>  MICROCHIP / ATMEL ISC DRIVER
> -M:	Songjun Wu <songjun.wu at microchip.com>
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
>  L:	linux-media at vger.kernel.org
>  S:	Supported
>  F:	drivers/media/platform/atmel/atmel-isc.c
>  F:	drivers/media/platform/atmel/atmel-isc-regs.h
> -F:	devicetree/bindings/media/atmel-isc.txt
> +F:	Documentation/devicetree/bindings/media/atmel-isc.txt
> +
> +MICROCHIP / ATMEL ISI DRIVER
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
> +L:	linux-media at vger.kernel.org
> +S:	Supported
> +F:	drivers/media/platform/atmel/atmel-isi.c
> +F:	include/media/atmel-isi.h
> +F:	Documentation/devicetree/bindings/media/atmel-isi.txt
>  
>  MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
>  M:	Woojung Huh <Woojung.Huh at microchip.com>
> -- 
> 2.9.0
> 


From frieder.schrempf at exceet.de  Tue Jan  9 08:25:57 2018
From: frieder.schrempf at exceet.de (Frieder Schrempf)
Date: Tue, 9 Jan 2018 17:25:57 +0100
Subject: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic
 LUT entry
In-Reply-To: <1515493602-19626-2-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1515493602-19626-2-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <80885d95-a6d4-b3a6-4249-f87379e6dc45@exceet.de>

Hello Yogesh,

> Add support to create dynamic LUT entry.
> 
> Current approach of creating LUT entries for various cmds like read, write,
> erase, readid, readsr, we, wd etc is that when QSPI controller gets
> initialized at that time static LUT entries for these cmds get created.
> 
> Patch add support to create the LUT at run time based on the operation
> being performed.
> 
> Added API fsl_qspi_prepare_lut(), this API would going to be called from
> fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
> fsl_qspi_erase APIs.
> This API would fetch required info like opcode, protocol info, dummy info
> for creating LUT from instance of 'struct spi_nor' and then prepare LUT
> entry for the required command.

I'm just about to get started working on a similar topic, so I have some 
general (maybe stupid) questions concerning the dynamic LUT implementation:

Why do you actually need to be able to switch between different kind of 
commands for READ/WRITE/ERASE at time of execution?

Wouldn't it be better to init the LUT statically, after the chip was 
detected and at that time decide which READ/WRITE/ERASE command is best 
for the connected chip?

Have you tested what kind of impact the dynamic loading of a command 
sequence to the LUT registers before each operation has on the performance?

In the context of the upcoming SPI NAND framework, I am working on NAND 
support for the FSL QSPI controller.
I have a working driver at [1] derived from the NOR driver.
As discussed with Boris ([2]) the plan is to add NAND support to the NOR 
driver until a common spi-flash layer is available to hold code, that is 
used by both types of SPI flash, NOR and NAND.

To achieve this, some kind of dynamic LUT allocation is needed, too.
But at first glance it seems me, that it would be better to actually use 
the LUT entries as much as possible and create the entries at time of 
init depending on flash type (NOR/NAND) and flash capabilities 
(QUAD/DUAL/QIO READ/WRITE...).

In the exotic case of needing to switch between different command sets 
(for hybrid NOR/NAND devices, see [3]) one could reinit the LUT for the 
current target upon selecting it.

Or maybe it is even better to create a mechanism that fills the LUT with 
entries when they are first needed and be able to reuse them until the 
space in the LUT runs out and entries need to be overriden.

What do you think?

As I'm quite new to this, maybe someone can point to other 
implementations with similar approaches for reference, if there are any.

Thanks and regards,

Frieder

[1]: 
https://github.com/fschrempf/linux-0day/blob/spi-nand-exceet/drivers/mtd/nand/spi/controllers/fsl-quadspi-controller.c
[2]: http://lists.infradead.org/pipermail/linux-mtd/2018-January/078592.html
[3]: http://lists.infradead.org/pipermail/linux-mtd/2018-January/078488.html


From aaro.koskinen at iki.fi  Tue Jan  9 13:01:14 2018
From: aaro.koskinen at iki.fi (Aaro Koskinen)
Date: Tue, 9 Jan 2018 23:01:14 +0200
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180109130812.GA338@lenoch>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
Message-ID: <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>

Hi,

On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> Merge window is really close now and patches seems still to be untested on
> n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> ebay :-/

Today I tried to test them on Nokia N810, and I get:

[    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
[    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
[    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
[    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22

With plain v4.15-rc7+ it probes fine.

A.


From Wenyou.Yang at Microchip.com  Tue Jan  9 17:52:25 2018
From: Wenyou.Yang at Microchip.com (Yang, Wenyou)
Date: Wed, 10 Jan 2018 09:52:25 +0800
Subject: [PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and
 ISC entries
In-Reply-To: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
References: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
Message-ID: <066d1016-51f6-75d5-c68c-00029b49b9c9@Microchip.com>



On 2018/1/9 21:46, Nicolas Ferre wrote:
> These two image capture interface drivers are now handled
> by Wenyou Yang.
> I benefit from this change to update the two entries by correcting the
> binding documentation link for ISC and moving the ISI to the new
> MICROCHIP / ATMEL location.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Acked-by: Wenyou Yang <wenyou.yang at microchip.com>
> ---
> Hi,
>
> Patch against next-20180109.
> Note that I didn't find it useful to have several patches for these changes.
> Tell me if you feel differently.
>
> I would like to have the Ack from Ludovic and Wenyou obviously. I don't know if
> Songjun can answer as he's not with Microchip anymore.
>
> Best regards,
>    Nicolas
>
>   MAINTAINERS | 19 ++++++++++---------
>   1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a7d10a2bb980..65c4b59b582f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2353,13 +2353,6 @@ L:	linux-i2c at vger.kernel.org
>   S:	Supported
>   F:	drivers/i2c/busses/i2c-at91.c
>   
> -ATMEL ISI DRIVER
> -M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> -L:	linux-media at vger.kernel.org
> -S:	Supported
> -F:	drivers/media/platform/atmel/atmel-isi.c
> -F:	include/media/atmel-isi.h
> -
>   ATMEL LCDFB DRIVER
>   M:	Nicolas Ferre <nicolas.ferre at microchip.com>
>   L:	linux-fbdev at vger.kernel.org
> @@ -9102,12 +9095,20 @@ S:	Maintained
>   F:	drivers/crypto/atmel-ecc.*
>   
>   MICROCHIP / ATMEL ISC DRIVER
> -M:	Songjun Wu <songjun.wu at microchip.com>
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
>   L:	linux-media at vger.kernel.org
>   S:	Supported
>   F:	drivers/media/platform/atmel/atmel-isc.c
>   F:	drivers/media/platform/atmel/atmel-isc-regs.h
> -F:	devicetree/bindings/media/atmel-isc.txt
> +F:	Documentation/devicetree/bindings/media/atmel-isc.txt
> +
> +MICROCHIP / ATMEL ISI DRIVER
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
> +L:	linux-media at vger.kernel.org
> +S:	Supported
> +F:	drivers/media/platform/atmel/atmel-isi.c
> +F:	include/media/atmel-isi.h
> +F:	Documentation/devicetree/bindings/media/atmel-isi.txt
>   
>   MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
>   M:	Woojung Huh <Woojung.Huh at microchip.com>
Best Regards,
Wenyou Yang


From Wenyou.Yang at Microchip.com  Tue Jan  9 17:53:54 2018
From: Wenyou.Yang at Microchip.com (Yang, Wenyou)
Date: Wed, 10 Jan 2018 09:53:54 +0800
Subject: [PATCH 2/2] MAINTAINERS: mtd/nand: update Microchip nand entry
In-Reply-To: <d8a6b8a3fe05c57972de1c374fcdeb933717396b.1515503733.git.nicolas.ferre@microchip.com>
References: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
 <d8a6b8a3fe05c57972de1c374fcdeb933717396b.1515503733.git.nicolas.ferre@microchip.com>
Message-ID: <cf8d2448-f4ba-c6d3-2fe6-ded5d32151fc@Microchip.com>



On 2018/1/9 21:46, Nicolas Ferre wrote:
> Update Wenyou Yang email address.
> Take advantage of this update to move this entry to the MICROCHIP / ATMEL
> location and add the DT binding documentation link.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Acked-by: Wenyou Yang <wenyou.yang at microchip.com>
> ---
> Hi,
>
> Patch against next-20180109.
> This patch is somehow dependent on the previous one in the series
> ("MAINTAINERS: linux-media: update Microchip ISI and ISC entries") but can be
> rebased easily.
>
> I don't know if it's better to have them added at the end of the development
> cycle or just after rc1: let me know if you plan to take them or if I need to
> rebase them for next cycle.
>
> Best regards,
>    Nicolas
>
>
>   MAINTAINERS | 15 ++++++++-------
>   1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 65c4b59b582f..b48e217d41fb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2373,13 +2373,6 @@ F:	Documentation/devicetree/bindings/input/atmel,maxtouch.txt
>   F:	drivers/input/touchscreen/atmel_mxt_ts.c
>   F:	include/linux/platform_data/atmel_mxt_ts.h
>   
> -ATMEL NAND DRIVER
> -M:	Wenyou Yang <wenyou.yang at atmel.com>
> -M:	Josh Wu <rainyfeeling at outlook.com>
> -L:	linux-mtd at lists.infradead.org
> -S:	Supported
> -F:	drivers/mtd/nand/atmel/*
> -
>   ATMEL SAMA5D2 ADC DRIVER
>   M:	Ludovic Desroches <ludovic.desroches at microchip.com>
>   L:	linux-iio at vger.kernel.org
> @@ -9110,6 +9103,14 @@ F:	drivers/media/platform/atmel/atmel-isi.c
>   F:	include/media/atmel-isi.h
>   F:	Documentation/devicetree/bindings/media/atmel-isi.txt
>   
> +MICROCHIP / ATMEL NAND DRIVER
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
> +M:	Josh Wu <rainyfeeling at outlook.com>
> +L:	linux-mtd at lists.infradead.org
> +S:	Supported
> +F:	drivers/mtd/nand/atmel/*
> +F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
> +
>   MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
>   M:	Woojung Huh <Woojung.Huh at microchip.com>
>   M:	Microchip Linux Driver Support <UNGLinuxDriver at microchip.com>

Best Regards,
Wenyou Yang


From boris.brezillon at free-electrons.com  Wed Jan 10 00:46:24 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 09:46:24 +0100
Subject: [PATCH v2] mtd: tests: nandbiterrs: Fix read_page return value
In-Reply-To: <20180109094702.21488-1-s.hauer@pengutronix.de>
References: <20180109094702.21488-1-s.hauer@pengutronix.de>
Message-ID: <20180110094624.584e1918@bbrezillon>

On Tue,  9 Jan 2018 10:47:02 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> The number of corrected bitflips is not correctly reported by
> the test until the bitflip threshold is reached.
> 
> read_page() shall return the number of corrected bitflips, but
> mtd_read() returns 0 or a negative error, so we can't forward
> its return value. In the absence of an error we always have
> calculate the number of bitflips ourselves.
> 

Applied.

Thanks,

Boris

> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/tests/nandbiterrs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c
> index 5f03b8c885a9..cde19c99e77b 100644
> --- a/drivers/mtd/tests/nandbiterrs.c
> +++ b/drivers/mtd/tests/nandbiterrs.c
> @@ -151,7 +151,7 @@ static int read_page(int log)
>  	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
>  
>  	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
> -	if (err == -EUCLEAN)
> +	if (!err || err == -EUCLEAN)
>  		err = mtd->ecc_stats.corrected - oldstats.corrected;
>  
>  	if (err < 0 || read != mtd->writesize) {



From boris.brezillon at free-electrons.com  Wed Jan 10 00:46:49 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 09:46:49 +0100
Subject: [PATCH v2] mtd: nand: samsung: Disable subpage writes on E-die
 NAND
In-Reply-To: <20180109131911.GA3907@lenoch>
References: <20180109131911.GA3907@lenoch>
Message-ID: <20180110094649.37f828b0@bbrezillon>

On Tue, 9 Jan 2018 14:19:11 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> Samsung E-die SLC NAND manufactured using 21nm process (K9F1G08U0E)
> does not support partial page programming, so disable subpage writes
> for it. Manufacturing process is stored in lowest two bits of 5th ID
> byte.

Applied.

Thanks,

Boris

> 
> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> ---
>  Changes:
>  - v2: 
>    * Reword commit log
>    * Check also for device type
>    * Reimplement if statements using switch
> 
>  drivers/mtd/nand/nand_samsung.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c
> index f6b0a63a068c..6971c35b78e9 100644
> --- a/drivers/mtd/nand/nand_samsung.c
> +++ b/drivers/mtd/nand/nand_samsung.c
> @@ -92,10 +92,22 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
>  	} else {
>  		nand_decode_ext_id(chip);
>  
> -		/* Datasheet values for SLC Samsung K9F4G08U0D-S[I|C]B0(T00) */
> -		if (nand_is_slc(chip) && chip->id.data[1] == 0xDC) {
> -			chip->ecc_step_ds = 512;
> -			chip->ecc_strength_ds = 1;
> +		if (nand_is_slc(chip)) {
> +			switch (chip->id.data[1]) {
> +			/* K9F4G08U0D-S[I|C]B0(T00) */
> +			case 0xDC:
> +				chip->ecc_step_ds = 512;
> +				chip->ecc_strength_ds = 1;
> +				break;
> +			/* K9F1G08U0E 21nm chips do not support subpage write */
> +			case 0xF1:
> +				if (chip->id.len > 4 &&
> +				    (chip->id.data[4] & GENMASK(1,0)) == 0x1)
> +					chip->options |= NAND_NO_SUBPAGE_WRITE;
> +				break;
> +			default:
> +				break;
> +			}
>  		}
>  	}
>  }



From prabhakar.kushwaha at nxp.com  Wed Jan 10 00:47:27 2018
From: prabhakar.kushwaha at nxp.com (Prabhakar Kushwaha)
Date: Wed, 10 Jan 2018 08:47:27 +0000
Subject: [PATCH] Documentation: binding: Update endianness usage
In-Reply-To: <HE1PR04MB124148862807D5BD05E4E5AF970D0@HE1PR04MB1241.eurprd04.prod.outlook.com>
References: <1511954855-8593-1-git-send-email-prabhakar.kushwaha@nxp.com>
 <1512105209.10062.1.camel@buserror.net>
 <HE1PR04MB12414AFA5F8081730B89378497390@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <1512165311.10062.3.camel@buserror.net>
 <HE1PR04MB1241226CD3B7ABD6D5FA2D91973C0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <1512441957.10062.6.camel@buserror.net>
 <HE1PR04MB1241ADD02E472BA492AE1C8F973D0@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <1512504459.10062.9.camel@buserror.net>
 <HE1PR04MB1241F1A70CDBA5A94D4D2CE597320@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <HE1PR04MB124174461F845000614CDAA197320@HE1PR04MB1241.eurprd04.prod.outlook.com>
 <HE1PR04MB124148862807D5BD05E4E5AF970D0@HE1PR04MB1241.eurprd04.prod.outlook.com>
Message-ID: <HE1PR04MB124133C61732D0A903D5C54D97110@HE1PR04MB1241.eurprd04.prod.outlook.com>

Hi Scott,
> -----Original Message-----
> From: Prabhakar Kushwaha
> Sent: Thursday, December 21, 2017 10:50 AM
> To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Scott Wood
> <oss at buserror.net>; linux-mtd at lists.infradead.org; devicetree at vger.kernel.org
> Cc: dedekind1 at gmail.com; computersforpeace at gmail.com
> Subject: RE: [PATCH] Documentation: binding: Update endianness usage
> 
> Hi Scott,
> 
> 
> > -----Original Message-----
> > From: devicetree-owner at vger.kernel.org [mailto:devicetree-
> > owner at vger.kernel.org] On Behalf Of Prabhakar Kushwaha
> > Sent: Wednesday, December 06, 2017 4:29 PM
> > To: Scott Wood <oss at buserror.net>; linux-mtd at lists.infradead.org;
> > devicetree at vger.kernel.org
> > Cc: dedekind1 at gmail.com; computersforpeace at gmail.com
> > Subject: RE: [PATCH] Documentation: binding: Update endianness usage
> >
> >
> >
> > > -----Original Message-----
> > > From: Prabhakar Kushwaha
> > > Sent: Wednesday, December 06, 2017 4:05 PM
> > > To: 'Scott Wood' <oss at buserror.net>; linux-mtd at lists.infradead.org;
> > > devicetree at vger.kernel.org
> > > Cc: dedekind1 at gmail.com; computersforpeace at gmail.com
> > > Subject: RE: [PATCH] Documentation: binding: Update endianness usage
> > >
> > >
> > > > -----Original Message-----
> > > > From: Scott Wood [mailto:oss at buserror.net]
> > > > Sent: Wednesday, December 06, 2017 1:38 AM
> > > > To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; linux-
> > > > mtd at lists.infradead.org; devicetree at vger.kernel.org
> > > > Cc: dedekind1 at gmail.com; computersforpeace at gmail.com
> > > > Subject: Re: [PATCH] Documentation: binding: Update endianness usage
> > > >
> > > > On Tue, 2017-12-05 at 09:45 +0000, Prabhakar Kushwaha wrote:
> > > > > > -----Original Message-----
> > > > > > From: Scott Wood [mailto:oss at buserror.net]
> > > > > > Sent: Tuesday, December 05, 2017 8:16 AM
> > > > > > To: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; linux-
> > > > > > mtd at lists.infradead.org; devicetree at vger.kernel.org
> > > > > > Cc: dedekind1 at gmail.com; computersforpeace at gmail.com
> > > > > > Subject: Re: [PATCH] Documentation: binding: Update endianness usage
> > > > > >
> > > > > > I now see your patch to of_flash_probe... where is the non-IFC-specific
> > > > > > binding that says the *parent* of a CFI node should be looked at for
> this?
> > > > > > Where?in general are endian properties kept in the parent of the node
> > with
> > > > > > "reg"???The right answer is to add endianness to mtd-physmap.txt.
> > > > > >
> > > > >
> > > > > Flashes are always littler endian.
> > > >
> > > > We wouldn't be having this discussion if that were true...  This is about how
> > > > it presents to the CPU, not about how the actual pins on the chip are
> > > > numbered.
> > > >
> > >
> > > Got your point :)
> > >
> > > > > It is because of IFC controller behavior, endianness is required.
> > > > > So as per my understanding, this info should go in IFC binding.
> > > >
> > > > If the info should go in the IFC binding why is the code in a non-IFC-specific
> > > > place?
> > > >
> > >
> > > Now I understand your point.
> > > So I should be moving endianness property detail in mtd-physmap.txt.
> > >
> > > Is my understanding correct?
> > >
> >
> > A second thought,
> > IFC binding was updated because there is no IFC-NOR driver. It uses generic
> Flash
> > framework.
> >
> > I am just trying to get more understanding.
> >
> 
> Do you have any comment/concern on this patch.
> May I go ahead and request for the merger of updated patch i.e.
> https://patchwork.kernel.org/patch/10084331/
> 

Please let me know if you have any concern on this patch. 

--prabhakar


From ladis at linux-mips.org  Wed Jan 10 01:20:58 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 10 Jan 2018 10:20:58 +0100
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
Message-ID: <20180110092058.GA25351@lenoch>

Aaro,

On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> Hi,
> 
> On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > Merge window is really close now and patches seems still to be untested on
> > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > ebay :-/
> 
> Today I tried to test them on Nokia N810, and I get:
> 
> [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> 
> With plain v4.15-rc7+ it probes fine.

Thank you for testing. As stated in cover letter, you need also
https://patchwork.kernel.org/patch/10043259/
which can be also found in Roger's branch
https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
(see previous replies in this thread and also discussion about OneNAND
DT node)

Thank you,
	ladis


From rockdotlee at gmail.com  Wed Jan 10 02:05:41 2018
From: rockdotlee at gmail.com (rockdotlee at gmail.com)
Date: Wed, 10 Jan 2018 05:05:41 -0500
Subject: [PATCH] ubifs: Change log level in ubifs_xattr_get
Message-ID: <1515578741-6612-1-git-send-email-rockdotlee@gmail.com>

From: Rock Lee <rockdotlee at gmail.com>

Just print warning message when xattr value size is bigger than the
buffer size. There is a situation that other modules, like overlayfs,
try to get xattr value with a small buffer, if they get -ERANGE, they
will try again with the proper buffer size. No need to report a error
message, warning message is enough.

Signed-off-by: Rock Lee <rockdotlee at gmail.com>
---
 fs/ubifs/xattr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 5ddc89d..bc20530 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -381,7 +381,7 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
 	if (buf) {
 		/* If @buf is %NULL we are supposed to return the length */
 		if (ui->data_len > size) {
-			ubifs_err(c, "buffer size %zd, xattr len %d",
+			ubifs_warn(c, "buffer size %zd, xattr len %d",
 				  size, ui->data_len);
 			err = -ERANGE;
 			goto out_iput;
-- 
1.9.1



From s.hauer at pengutronix.de  Wed Jan 10 06:16:17 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 10 Jan 2018 15:16:17 +0100
Subject: [PATCH] UBI: fastmap: Erase outdated anchor PEBs during attach
In-Reply-To: <20171205150120.26045-1-s.hauer@pengutronix.de>
References: <20171205150120.26045-1-s.hauer@pengutronix.de>
Message-ID: <20180110141617.orepk3srb5e6fcbj@pengutronix.de>

+Cc Boris

Hi Boris and all,

I can't find this patch in any tree. Boris, will you take it?

Sascha

On Tue, Dec 05, 2017 at 04:01:20PM +0100, Sascha Hauer wrote:
> The fastmap update code might erase the current fastmap anchor PEB
> in case it doesn't find any new free PEB. When a power cut happens
> in this situation we must not have any outdated fastmap anchor PEB
> on the device, because that would be used to attach during next
> boot.
> The easiest way to make that sure is to erase all outdated fastmap
> anchor PEBs synchronously during attach.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/ubi/wl.c | 77 ++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 57 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
> index b5b8cd6f481c..668b46202507 100644
> --- a/drivers/mtd/ubi/wl.c
> +++ b/drivers/mtd/ubi/wl.c
> @@ -1529,6 +1529,46 @@ static void shutdown_work(struct ubi_device *ubi)
>  }
>  
>  /**
> + * erase_aeb - erase a PEB given in UBI attach info PEB
> + * @ubi: UBI device description object
> + * @aeb: UBI attach info PEB
> + * @sync: If true, erase synchronously. Otherwise schedule for erasure
> + */
> +static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync)
> +{
> +	struct ubi_wl_entry *e;
> +	int err;
> +
> +	e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> +	if (!e)
> +		return -ENOMEM;
> +
> +	e->pnum = aeb->pnum;
> +	e->ec = aeb->ec;
> +	ubi->lookuptbl[e->pnum] = e;
> +
> +	if (sync) {
> +		err = sync_erase(ubi, e, false);
> +		if (err)
> +			goto out_free;
> +
> +		wl_tree_add(e, &ubi->free);
> +		ubi->free_count++;
> +	} else {
> +		err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false);
> +		if (err)
> +			goto out_free;
> +	}
> +
> +	return 0;
> +
> +out_free:
> +	wl_entry_destroy(ubi, e);
> +
> +	return err;
> +}
> +
> +/**
>   * ubi_wl_init - initialize the WL sub-system using attaching information.
>   * @ubi: UBI device description object
>   * @ai: attaching information
> @@ -1566,18 +1606,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
>  	list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
>  		cond_resched();
>  
> -		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> -		if (!e)
> +		err = erase_aeb(ubi, aeb, false);
> +		if (err)
>  			goto out_free;
>  
> -		e->pnum = aeb->pnum;
> -		e->ec = aeb->ec;
> -		ubi->lookuptbl[e->pnum] = e;
> -		if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
> -			wl_entry_destroy(ubi, e);
> -			goto out_free;
> -		}
> -
>  		found_pebs++;
>  	}
>  
> @@ -1635,6 +1667,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
>  			ubi_assert(!ubi->lookuptbl[e->pnum]);
>  			ubi->lookuptbl[e->pnum] = e;
>  		} else {
> +			bool sync = false;
> +
>  			/*
>  			 * Usually old Fastmap PEBs are scheduled for erasure
>  			 * and we don't have to care about them but if we face
> @@ -1644,18 +1678,21 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
>  			if (ubi->lookuptbl[aeb->pnum])
>  				continue;
>  
> -			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> -			if (!e)
> -				goto out_free;
> +			/*
> +			 * The fastmap update code might not find a free PEB for
> +			 * writing the fastmap anchor to and then reuses the
> +			 * current fastmap anchor PEB. When this PEB gets erased
> +			 * and a power cut happens before it is written again we
> +			 * must make sure that the fastmap attach code doesn't
> +			 * find any outdated fastmap anchors, hence we erase the
> +			 * outdated fastmap anchor PEBs synchronously here.
> +			 */
> +			if (aeb->vol_id == UBI_FM_SB_VOLUME_ID)
> +				sync = true;
>  
> -			e->pnum = aeb->pnum;
> -			e->ec = aeb->ec;
> -			ubi_assert(!ubi->lookuptbl[e->pnum]);
> -			ubi->lookuptbl[e->pnum] = e;
> -			if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
> -				wl_entry_destroy(ubi, e);
> +			err = erase_aeb(ubi, aeb, sync);
> +			if (err)
>  				goto out_free;
> -			}
>  		}
>  
>  		found_pebs++;
> -- 
> 2.11.0
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From boris.brezillon at free-electrons.com  Wed Jan 10 06:21:08 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 15:21:08 +0100
Subject: [PATCH] UBI: fastmap: Erase outdated anchor PEBs during attach
In-Reply-To: <20180110141617.orepk3srb5e6fcbj@pengutronix.de>
References: <20171205150120.26045-1-s.hauer@pengutronix.de>
 <20180110141617.orepk3srb5e6fcbj@pengutronix.de>
Message-ID: <20180110152108.38678750@bbrezillon>

On Wed, 10 Jan 2018 15:16:17 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> +Cc Boris
> 
> Hi Boris and all,
> 
> I can't find this patch in any tree. Boris, will you take it?

Nope, UBI changes go through Richard's tree and then directly to Linus.

> 
> Sascha
> 
> On Tue, Dec 05, 2017 at 04:01:20PM +0100, Sascha Hauer wrote:
> > The fastmap update code might erase the current fastmap anchor PEB
> > in case it doesn't find any new free PEB. When a power cut happens
> > in this situation we must not have any outdated fastmap anchor PEB
> > on the device, because that would be used to attach during next
> > boot.
> > The easiest way to make that sure is to erase all outdated fastmap
> > anchor PEBs synchronously during attach.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/mtd/ubi/wl.c | 77 ++++++++++++++++++++++++++++++++++++++--------------
> >  1 file changed, 57 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
> > index b5b8cd6f481c..668b46202507 100644
> > --- a/drivers/mtd/ubi/wl.c
> > +++ b/drivers/mtd/ubi/wl.c
> > @@ -1529,6 +1529,46 @@ static void shutdown_work(struct ubi_device *ubi)
> >  }
> >  
> >  /**
> > + * erase_aeb - erase a PEB given in UBI attach info PEB
> > + * @ubi: UBI device description object
> > + * @aeb: UBI attach info PEB
> > + * @sync: If true, erase synchronously. Otherwise schedule for erasure
> > + */
> > +static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync)
> > +{
> > +	struct ubi_wl_entry *e;
> > +	int err;
> > +
> > +	e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > +	if (!e)
> > +		return -ENOMEM;
> > +
> > +	e->pnum = aeb->pnum;
> > +	e->ec = aeb->ec;
> > +	ubi->lookuptbl[e->pnum] = e;
> > +
> > +	if (sync) {
> > +		err = sync_erase(ubi, e, false);
> > +		if (err)
> > +			goto out_free;
> > +
> > +		wl_tree_add(e, &ubi->free);
> > +		ubi->free_count++;
> > +	} else {
> > +		err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false);
> > +		if (err)
> > +			goto out_free;
> > +	}
> > +
> > +	return 0;
> > +
> > +out_free:
> > +	wl_entry_destroy(ubi, e);
> > +
> > +	return err;
> > +}
> > +
> > +/**
> >   * ubi_wl_init - initialize the WL sub-system using attaching information.
> >   * @ubi: UBI device description object
> >   * @ai: attaching information
> > @@ -1566,18 +1606,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> >  	list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
> >  		cond_resched();
> >  
> > -		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > -		if (!e)
> > +		err = erase_aeb(ubi, aeb, false);
> > +		if (err)
> >  			goto out_free;
> >  
> > -		e->pnum = aeb->pnum;
> > -		e->ec = aeb->ec;
> > -		ubi->lookuptbl[e->pnum] = e;
> > -		if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
> > -			wl_entry_destroy(ubi, e);
> > -			goto out_free;
> > -		}
> > -
> >  		found_pebs++;
> >  	}
> >  
> > @@ -1635,6 +1667,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> >  			ubi_assert(!ubi->lookuptbl[e->pnum]);
> >  			ubi->lookuptbl[e->pnum] = e;
> >  		} else {
> > +			bool sync = false;
> > +
> >  			/*
> >  			 * Usually old Fastmap PEBs are scheduled for erasure
> >  			 * and we don't have to care about them but if we face
> > @@ -1644,18 +1678,21 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> >  			if (ubi->lookuptbl[aeb->pnum])
> >  				continue;
> >  
> > -			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > -			if (!e)
> > -				goto out_free;
> > +			/*
> > +			 * The fastmap update code might not find a free PEB for
> > +			 * writing the fastmap anchor to and then reuses the
> > +			 * current fastmap anchor PEB. When this PEB gets erased
> > +			 * and a power cut happens before it is written again we
> > +			 * must make sure that the fastmap attach code doesn't
> > +			 * find any outdated fastmap anchors, hence we erase the
> > +			 * outdated fastmap anchor PEBs synchronously here.
> > +			 */
> > +			if (aeb->vol_id == UBI_FM_SB_VOLUME_ID)
> > +				sync = true;
> >  
> > -			e->pnum = aeb->pnum;
> > -			e->ec = aeb->ec;
> > -			ubi_assert(!ubi->lookuptbl[e->pnum]);
> > -			ubi->lookuptbl[e->pnum] = e;
> > -			if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
> > -				wl_entry_destroy(ubi, e);
> > +			err = erase_aeb(ubi, aeb, sync);
> > +			if (err)
> >  				goto out_free;
> > -			}
> >  		}
> >  
> >  		found_pebs++;
> > -- 
> > 2.11.0
> > 
> >   
> 



From richard at nod.at  Wed Jan 10 06:25:49 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 10 Jan 2018 15:25:49 +0100
Subject: [PATCH] UBI: fastmap: Erase outdated anchor PEBs during attach
In-Reply-To: <20180110141617.orepk3srb5e6fcbj@pengutronix.de>
References: <20171205150120.26045-1-s.hauer@pengutronix.de>
 <20180110141617.orepk3srb5e6fcbj@pengutronix.de>
Message-ID: <3533566.0JTIOxrrxM@blindfold>

Am Mittwoch, 10. Januar 2018, 15:16:17 CET schrieb Sascha Hauer:
> +Cc Boris
> 
> Hi Boris and all,
> 
> I can't find this patch in any tree. Boris, will you take it?

It will be part of the next merge window and tagged for stable.

Thanks,
//richard


From richard at nod.at  Wed Jan 10 06:39:21 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 10 Jan 2018 15:39:21 +0100
Subject: [PATCH] ubifs: Change log level in ubifs_xattr_get
In-Reply-To: <1515578741-6612-1-git-send-email-rockdotlee@gmail.com>
References: <1515578741-6612-1-git-send-email-rockdotlee@gmail.com>
Message-ID: <3873582.N8pb6r5EOO@blindfold>

Rock Lee,

Am Mittwoch, 10. Januar 2018, 11:05:41 CET schrieb rockdotlee at gmail.com:
> From: Rock Lee <rockdotlee at gmail.com>
> 
> Just print warning message when xattr value size is bigger than the
> buffer size. There is a situation that other modules, like overlayfs,
> try to get xattr value with a small buffer, if they get -ERANGE, they
> will try again with the proper buffer size. No need to report a error
> message, warning message is enough.
> 
> Signed-off-by: Rock Lee <rockdotlee at gmail.com>
> ---
>  fs/ubifs/xattr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
> index 5ddc89d..bc20530 100644
> --- a/fs/ubifs/xattr.c
> +++ b/fs/ubifs/xattr.c
> @@ -381,7 +381,7 @@ ssize_t ubifs_xattr_get(struct inode *host, const char
> *name, void *buf, if (buf) {
>  		/* If @buf is %NULL we are supposed to return the length */
>  		if (ui->data_len > size) {
> -			ubifs_err(c, "buffer size %zd, xattr len %d",
> +			ubifs_warn(c, "buffer size %zd, xattr len %d",
>  				  size, ui->data_len);

Hmm, if this can be triggered that easy I suggest getting completely rid of 
this message.

Thanks,
//richard



From aaro.koskinen at iki.fi  Wed Jan 10 09:35:19 2018
From: aaro.koskinen at iki.fi (Aaro Koskinen)
Date: Wed, 10 Jan 2018 19:35:19 +0200
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180110092058.GA25351@lenoch>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
Message-ID: <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>

Hi,

On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
> On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> > On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > > Merge window is really close now and patches seems still to be untested on
> > > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > > ebay :-/
> > 
> > Today I tried to test them on Nokia N810, and I get:
> > 
> > [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> > [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > 
> > With plain v4.15-rc7+ it probes fine.
> 
> Thank you for testing. As stated in cover letter, you need also
> https://patchwork.kernel.org/patch/10043259/
> which can be also found in Roger's branch
> https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
> (see previous replies in this thread and also discussion about OneNAND
> DT node)

I applied it, and now get:

[    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
[    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
[    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
[    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22

A.


From robert.jarzmik at free.fr  Wed Jan 10 12:27:34 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 10 Jan 2018 21:27:34 +0100
Subject: [PATCH v4 1/3] mtd: mtdpart: Make ECC stat handling consistent
In-Reply-To: <20180108211542.11891-2-boris.brezillon@free-electrons.com>
 (Boris Brezillon's message of "Mon, 8 Jan 2018 22:15:40 +0100")
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-2-boris.brezillon@free-electrons.com>
Message-ID: <87r2qxbgsp.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> part_read() and part_read_oob() where counting ECC failures and
Typo: s/where/were.

> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..283e8526713b 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  		struct mtd_oob_ops *ops)
>  {
>  	struct mtd_part *part = mtd_to_part(mtd);
> +	struct mtd_ecc_stats stats;
>  	int res;
>  
>  	if (from >= mtd->size)
> @@ -127,12 +128,12 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  	}
>  
>  	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
> -	if (unlikely(res)) {
> -		if (mtd_is_bitflip(res))
> -			mtd->ecc_stats.corrected++;
> -		if (mtd_is_eccerr(res))
> -			mtd->ecc_stats.failed++;
> -	}
> +	if (unlikely(mtd_is_eccerr(res)))
> +		mtd->ecc_stats.failed +=
> +			part->parent->ecc_stats.failed - stats.failed;
stats is used uninitialized, but I suppose you've already caught that.

Cheers.

-- 
Robert


From boris.brezillon at free-electrons.com  Wed Jan 10 13:07:18 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 22:07:18 +0100
Subject: [PATCH v4 1/3] mtd: mtdpart: Make ECC stat handling consistent
In-Reply-To: <87r2qxbgsp.fsf@belgarion.home>
References: <20180108211542.11891-1-boris.brezillon@free-electrons.com>
 <20180108211542.11891-2-boris.brezillon@free-electrons.com>
 <87r2qxbgsp.fsf@belgarion.home>
Message-ID: <20180110220718.0892b0f7@bbrezillon>

On Wed, 10 Jan 2018 21:27:34 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > part_read() and part_read_oob() where counting ECC failures and  
> Typo: s/where/were.

I'll fix the typo.

> 
> > diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> > index be088bccd593..283e8526713b 100644
> > --- a/drivers/mtd/mtdpart.c
> > +++ b/drivers/mtd/mtdpart.c
> > @@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
> >  		struct mtd_oob_ops *ops)
> >  {
> >  	struct mtd_part *part = mtd_to_part(mtd);
> > +	struct mtd_ecc_stats stats;
> >  	int res;
> >  
> >  	if (from >= mtd->size)
> > @@ -127,12 +128,12 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
> >  	}
> >  
> >  	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
> > -	if (unlikely(res)) {
> > -		if (mtd_is_bitflip(res))
> > -			mtd->ecc_stats.corrected++;
> > -		if (mtd_is_eccerr(res))
> > -			mtd->ecc_stats.failed++;
> > -	}
> > +	if (unlikely(mtd_is_eccerr(res)))
> > +		mtd->ecc_stats.failed +=
> > +			part->parent->ecc_stats.failed - stats.failed;  
> stats is used uninitialized, but I suppose you've already caught that.

Yep, already fixed in v5.

Thanks,

Boris


From ladis at linux-mips.org  Wed Jan 10 13:13:25 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 10 Jan 2018 22:13:25 +0100
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
 <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
Message-ID: <20180110211325.GA1938@lenoch>

+Rob and the DT ML

On Wed, Jan 10, 2018 at 07:35:19PM +0200, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
> > On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> > > On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > > > Merge window is really close now and patches seems still to be untested on
> > > > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > > > ebay :-/
> > > 
> > > Today I tried to test them on Nokia N810, and I get:
> > > 
> > > [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > > [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > > [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> > > [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > > 
> > > With plain v4.15-rc7+ it probes fine.
> > 
> > Thank you for testing. As stated in cover letter, you need also
> > https://patchwork.kernel.org/patch/10043259/
> > which can be also found in Roger's branch
> > https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
> > (see previous replies in this thread and also discussion about OneNAND
> > DT node)
> 
> I applied it, and now get:
> 
> [    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> [    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> [    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
> [    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22

As expected without reading discussion about OneNAND DT node :)

In short, this version expects "ti,omap2-onenand" compatible.

In earlier version of this patchset there was fixup present, so driver
worked even without compatible. Later on (17 Oct 2017 11:46:51 +0300)
Roger objected (https://www.spinics.net/lists/linux-omap/msg139576.html):
"I don't want to fixup broken DTs like this as they will go silently without
being fixed. Let's instead just error out after the dev_warn(). This will
force us to fix all DT nodes."
So fixup was removed. I know N900 support is under heavy development
in mainline, but if n8x0 is considered finished and stable, we should
reintroduce fixup. Thoughts?

Thank you for your patience,
	ladis


From aaro.koskinen at iki.fi  Wed Jan 10 13:27:48 2018
From: aaro.koskinen at iki.fi (Aaro Koskinen)
Date: Wed, 10 Jan 2018 23:27:48 +0200
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
 <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
Message-ID: <20180110212748.lbwwnktftqv3awzi@darkstar.musicnaut.iki.fi>

Hi,

On Wed, Jan 10, 2018 at 07:35:19PM +0200, Aaro Koskinen wrote:
> On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
> > On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> > > On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > > > Merge window is really close now and patches seems still to be untested on
> > > > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > > > ebay :-/
> > > 
> > > Today I tried to test them on Nokia N810, and I get:
> > > 
> > > [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > > [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > > [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> > > [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > > 
> > > With plain v4.15-rc7+ it probes fine.
> > 
> > Thank you for testing. As stated in cover letter, you need also
> > https://patchwork.kernel.org/patch/10043259/
> > which can be also found in Roger's branch
> > https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
> > (see previous replies in this thread and also discussion about OneNAND
> > DT node)
> 
> I applied it, and now get:
> 
> [    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> [    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> [    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
> [    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22

Crap, I think something is wrong in my kexec. It seems to pass the DTB from an
old kernel, although the new kernel has a new appended DTB... Need to
investigate, sorry for noise.

A.


From han.xu at nxp.com  Wed Jan 10 13:50:41 2018
From: han.xu at nxp.com (Han Xu)
Date: Wed, 10 Jan 2018 21:50:41 +0000
Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure
In-Reply-To: <1514484420-19344-1-git-send-email-festevam@gmail.com>
References: <1514484420-19344-1-git-send-email-festevam@gmail.com>
Message-ID: <VI1PR0401MB2221AF8D517BDDC52F5B550497110@VI1PR0401MB2221.eurprd04.prod.outlook.com>


________________________________________
From: Fabio Estevam <festevam at gmail.com>
Sent: Thursday, December 28, 2017 12:07 PM
To: boris.brezillon at free-electrons.com
Cc: Han Xu; linux-mtd at lists.infradead.org; Fabio Estevam
Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure

From: Fabio Estevam <fabio.estevam at nxp.com>

release_dma_channels() should be called in the case of error in
gpmi_init() or bch_set_geometry(), because acquire_dma_channels() has
been called previously.

Handle the error cases correctly.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 2ef8979..acfa5f5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -2137,20 +2137,25 @@ static int gpmi_pm_resume(struct device *dev)
        ret = gpmi_init(this);
        if (ret) {
                dev_err(this->dev, "Error setting GPMI : %d\n", ret);
-               return ret;
+               goto release_dma_channels;
        }

        /* re-init the BCH registers */
        ret = bch_set_geometry(this);
        if (ret) {
                dev_err(this->dev, "Error setting BCH : %d\n", ret);
-               return ret;
+               goto release_dma_channels;
        }

        /* re-init others */
        gpmi_extra_init(this);

        return 0;
+
+release_dma_channels:
+       release_dma_channels(this);
+       return ret;
+
 }
 #endif /* CONFIG_PM_SLEEP */

Acked-by: Han Xu <han.xu at nxp.com>

--
2.7.4



From boris.brezillon at free-electrons.com  Wed Jan 10 14:04:26 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 23:04:26 +0100
Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure
In-Reply-To: <VI1PR0401MB2221AF8D517BDDC52F5B550497110@VI1PR0401MB2221.eurprd04.prod.outlook.com>
References: <1514484420-19344-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB2221AF8D517BDDC52F5B550497110@VI1PR0401MB2221.eurprd04.prod.outlook.com>
Message-ID: <20180110230426.59e9f001@bbrezillon>

Hi Han,

On Wed, 10 Jan 2018 21:50:41 +0000
Han Xu <han.xu at nxp.com> wrote:

> ________________________________________
> From: Fabio Estevam <festevam at gmail.com>
> Sent: Thursday, December 28, 2017 12:07 PM
> To: boris.brezillon at free-electrons.com
> Cc: Han Xu; linux-mtd at lists.infradead.org; Fabio Estevam
> Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure
> 
> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> release_dma_channels() should be called in the case of error in
> gpmi_init() or bch_set_geometry(), because acquire_dma_channels() has
> been called previously.
> 
> Handle the error cases correctly.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 2ef8979..acfa5f5 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -2137,20 +2137,25 @@ static int gpmi_pm_resume(struct device *dev)
>         ret = gpmi_init(this);
>         if (ret) {
>                 dev_err(this->dev, "Error setting GPMI : %d\n", ret);
> -               return ret;
> +               goto release_dma_channels;
>         }
> 
>         /* re-init the BCH registers */
>         ret = bch_set_geometry(this);
>         if (ret) {
>                 dev_err(this->dev, "Error setting BCH : %d\n", ret);
> -               return ret;
> +               goto release_dma_channels;
>         }
> 
>         /* re-init others */
>         gpmi_extra_init(this);
> 
>         return 0;
> +
> +release_dma_channels:
> +       release_dma_channels(this);
> +       return ret;
> +
>  }
>  #endif /* CONFIG_PM_SLEEP */
> 
> Acked-by: Han Xu <han.xu at nxp.com>

Did you read my comment on v2 of this patch?


From boris.brezillon at free-electrons.com  Wed Jan 10 14:17:19 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 23:17:19 +0100
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>
References: <1515181560-1410-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>
Message-ID: <20180110231719.72767797@bbrezillon>

On Mon, 8 Jan 2018 17:13:17 +0000
Han Xu <han.xu at nxp.com> wrote:

> ________________________________________
> From: Fabio Estevam <festevam at gmail.com>
> Sent: Friday, January 5, 2018 1:46 PM
> To: Han Xu
> Cc: cyrille.pitchen at wedev4u.fr; David Wolfe; Frank Li; linux-mtd at lists.infradead.org; Fabio Estevam
> Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
> 
> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> to QSPI2 the following output from /proc/mtd is seen:
> 
> # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi"
> mtd1: 01000000 00010000 "21e4000.qspi"
> 
> Attempts to partition them on the kernel command line result in both
> chips with identical (and identically named) partitions, which is
> an inconvenient behavior.
> 
> Assign a different mtd->name for each mtd device to avoid this problem.
> 
> After this change the output from /proc/mtd becomes:
> 
> # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "fsl-quadspi.0"
> mtd1: 01000000 00010000 "fsl-quadspi.1"

What happens if you end up having 2 qspi IPs in the same SoC? IMHO,
it's more future proof to have something like
"<reg-addr>.qspi:<chipidx>" or "<reg-addr>.qspi:<chipidx>".

> 
> Reported-by: David Wolfe <david.wolfe at nxp.com>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index f17d224..7712c63 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>         struct resource *res;
>         struct spi_nor *nor;
>         struct mtd_info *mtd;
> -       int ret, i = 0;
> +       int ret, i = 0, mtd_index = 0;

It's not the MTD index if you have other MTD devices. How about
spiflash_idx?

> 
>         q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
>         if (!q)
> @@ -1047,6 +1047,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>                 nor = &q->nor[i];
>                 mtd = &nor->mtd;
> 
> +               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "fsl-quadspi.%d",
> +                                          mtd_index);

With the alternative naming scheme suggested above, it gives:

		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s:%d"
					   dev_name(&pdev->dev),
					   mtd_index);

> +               if (!mtd->name) {
> +                       ret = -ENOMEM;
> +                       goto mutex_failed;
> +               }
> +
>                 nor->dev = dev;
>                 spi_nor_set_flash_node(nor, np);
>                 nor->priv = q;
> @@ -1098,6 +1105,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>                         nor->page_size = q->devtype_data->txfifo;
> 
>                 i++;
> +               mtd_index++;
>         }
> 
>         /* finish the rest init. */
> --
> 2.7.4
> 
> Acked-by: Han Xu <han.xu at nxp.com>
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From han.xu at nxp.com  Wed Jan 10 14:30:35 2018
From: han.xu at nxp.com (Han Xu)
Date: Wed, 10 Jan 2018 22:30:35 +0000
Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure
In-Reply-To: <20180110230426.59e9f001@bbrezillon>
References: <1514484420-19344-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB2221AF8D517BDDC52F5B550497110@VI1PR0401MB2221.eurprd04.prod.outlook.com>,
 <20180110230426.59e9f001@bbrezillon>
Message-ID: <VI1PR0401MB2221D5DA2D87FFF406CC4AD597110@VI1PR0401MB2221.eurprd04.prod.outlook.com>


________________________________________
From: Boris Brezillon <boris.brezillon at free-electrons.com>
Sent: Wednesday, January 10, 2018 4:04 PM
To: Han Xu
Cc: Fabio Estevam; Fabio Estevam; linux-mtd at lists.infradead.org
Subject: Re: [PATCH] mtd: nand: gpmi: Release DMA channels on failure

Hi Han,

On Wed, 10 Jan 2018 21:50:41 +0000
Han Xu <han.xu at nxp.com> wrote:

> ________________________________________
> From: Fabio Estevam <festevam at gmail.com>
> Sent: Thursday, December 28, 2017 12:07 PM
> To: boris.brezillon at free-electrons.com
> Cc: Han Xu; linux-mtd at lists.infradead.org; Fabio Estevam
> Subject: [PATCH] mtd: nand: gpmi: Release DMA channels on failure
>
> From: Fabio Estevam <fabio.estevam at nxp.com>
>
> release_dma_channels() should be called in the case of error in
> gpmi_init() or bch_set_geometry(), because acquire_dma_channels() has
> been called previously.
>
> Handle the error cases correctly.
>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 2ef8979..acfa5f5 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -2137,20 +2137,25 @@ static int gpmi_pm_resume(struct device *dev)
>         ret = gpmi_init(this);
>         if (ret) {
>                 dev_err(this->dev, "Error setting GPMI : %d\n", ret);
> -               return ret;
> +               goto release_dma_channels;
>         }
>
>         /* re-init the BCH registers */
>         ret = bch_set_geometry(this);
>         if (ret) {
>                 dev_err(this->dev, "Error setting BCH : %d\n", ret);
> -               return ret;
> +               goto release_dma_channels;
>         }
>
>         /* re-init others */
>         gpmi_extra_init(this);
>
>         return 0;
> +
> +release_dma_channels:
> +       release_dma_channels(this);
> +       return ret;
> +
>  }
>  #endif /* CONFIG_PM_SLEEP */
>
> Acked-by: Han Xu <han.xu at nxp.com>

Did you read my comment on v2 of this patch?

Sorry I missed the emails, I agree with you not to release the DMA even returning error.


From festevam at gmail.com  Wed Jan 10 14:39:02 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 10 Jan 2018 20:39:02 -0200
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180110231719.72767797@bbrezillon>
References: <1515181560-1410-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>
 <20180110231719.72767797@bbrezillon>
Message-ID: <CAOMZO5AzfWeg=98F5QJeMcN3UaFvmf2d+69wvCmomK9bHTMn6g@mail.gmail.com>

Hi Boris,

On Wed, Jan 10, 2018 at 8:17 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:

> With the alternative naming scheme suggested above, it gives:
>
>                 mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s:%d"
>                                            dev_name(&pdev->dev),
>                                            mtd_index);

Yes, this looks better.

I have made the suggested change. Will test it tomorrow on my board
and will send a v2.

Thanks!


From boris.brezillon at free-electrons.com  Wed Jan 10 14:42:27 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 23:42:27 +0100
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180110231719.72767797@bbrezillon>
References: <1515181560-1410-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>
 <20180110231719.72767797@bbrezillon>
Message-ID: <20180110234227.203674c7@bbrezillon>

On Wed, 10 Jan 2018 23:17:19 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Mon, 8 Jan 2018 17:13:17 +0000
> Han Xu <han.xu at nxp.com> wrote:
> 
> > ________________________________________
> > From: Fabio Estevam <festevam at gmail.com>
> > Sent: Friday, January 5, 2018 1:46 PM
> > To: Han Xu
> > Cc: cyrille.pitchen at wedev4u.fr; David Wolfe; Frank Li; linux-mtd at lists.infradead.org; Fabio Estevam
> > Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
> > 
> > From: Fabio Estevam <fabio.estevam at nxp.com>
> > 
> > Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> > to QSPI2 the following output from /proc/mtd is seen:
> > 
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi"
> > mtd1: 01000000 00010000 "21e4000.qspi"
> > 
> > Attempts to partition them on the kernel command line result in both
> > chips with identical (and identically named) partitions, which is
> > an inconvenient behavior.
> > 
> > Assign a different mtd->name for each mtd device to avoid this problem.
> > 
> > After this change the output from /proc/mtd becomes:
> > 
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "fsl-quadspi.0"
> > mtd1: 01000000 00010000 "fsl-quadspi.1"  
> 
> What happens if you end up having 2 qspi IPs in the same SoC? IMHO,
> it's more future proof to have something like
> "<reg-addr>.qspi:<chipidx>" or "<reg-addr>.qspi:<chipidx>".

Hm, ':' is not a good separator because it's already used by mtdparts,
so I suggest using '-' ("<reg-addr>.qspi-<chipid>").

> 
> > 
> > Reported-by: David Wolfe <david.wolfe at nxp.com>
> > Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> > ---
> >  drivers/mtd/spi-nor/fsl-quadspi.c | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> > index f17d224..7712c63 100644
> > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >         struct resource *res;
> >         struct spi_nor *nor;
> >         struct mtd_info *mtd;
> > -       int ret, i = 0;
> > +       int ret, i = 0, mtd_index = 0;  
> 
> It's not the MTD index if you have other MTD devices. How about
> spiflash_idx?
> 
> > 
> >         q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
> >         if (!q)
> > @@ -1047,6 +1047,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >                 nor = &q->nor[i];
> >                 mtd = &nor->mtd;
> > 
> > +               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "fsl-quadspi.%d",
> > +                                          mtd_index);  
> 
> With the alternative naming scheme suggested above, it gives:
> 
> 		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s:%d"
> 					   dev_name(&pdev->dev),
> 					   mtd_index);

I realize your index depends on the order the nodes have been defined
in the DT, which is fragile. You should find a better solution to
uniquely identify each device connected to the fsl-qspi controller
(<busid>.<devid>?) and then have a property describing that (reg?).

> 
> > +               if (!mtd->name) {
> > +                       ret = -ENOMEM;
> > +                       goto mutex_failed;
> > +               }
> > +
> >                 nor->dev = dev;
> >                 spi_nor_set_flash_node(nor, np);
> >                 nor->priv = q;
> > @@ -1098,6 +1105,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >                         nor->page_size = q->devtype_data->txfifo;
> > 
> >                 i++;
> > +               mtd_index++;
> >         }
> > 
> >         /* finish the rest init. */
> > --
> > 2.7.4
> > 
> > Acked-by: Han Xu <han.xu at nxp.com>
> > 
> > ______________________________________________________
> > Linux MTD discussion mailing list
> > http://lists.infradead.org/mailman/listinfo/linux-mtd/  
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From boris.brezillon at free-electrons.com  Wed Jan 10 14:54:01 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 10 Jan 2018 23:54:01 +0100
Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180110231719.72767797@bbrezillon>
References: <1515181560-1410-1-git-send-email-festevam@gmail.com>
 <VI1PR0401MB22213B0560C91999E6E22E7197130@VI1PR0401MB2221.eurprd04.prod.outlook.com>
 <20180110231719.72767797@bbrezillon>
Message-ID: <20180110235401.724d6665@bbrezillon>

On Wed, 10 Jan 2018 23:17:19 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Mon, 8 Jan 2018 17:13:17 +0000
> Han Xu <han.xu at nxp.com> wrote:
> 
> > ________________________________________
> > From: Fabio Estevam <festevam at gmail.com>
> > Sent: Friday, January 5, 2018 1:46 PM
> > To: Han Xu
> > Cc: cyrille.pitchen at wedev4u.fr; David Wolfe; Frank Li; linux-mtd at lists.infradead.org; Fabio Estevam
> > Subject: [PATCH] mtd: fsl-quadspi: Distinguish the mtd device names
> > 
> > From: Fabio Estevam <fabio.estevam at nxp.com>
> > 
> > Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> > to QSPI2 the following output from /proc/mtd is seen:
> > 
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi"
> > mtd1: 01000000 00010000 "21e4000.qspi"
> > 
> > Attempts to partition them on the kernel command line result in both
> > chips with identical (and identically named) partitions, which is
> > an inconvenient behavior.
> > 
> > Assign a different mtd->name for each mtd device to avoid this problem.
> > 
> > After this change the output from /proc/mtd becomes:
> > 
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "fsl-quadspi.0"
> > mtd1: 01000000 00010000 "fsl-quadspi.1"  
> 
> What happens if you end up having 2 qspi IPs in the same SoC? IMHO,
> it's more future proof to have something like
> "<reg-addr>.qspi:<chipidx>" or "<reg-addr>.qspi:<chipidx>".
> 
> > 
> > Reported-by: David Wolfe <david.wolfe at nxp.com>
> > Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> > ---
> >  drivers/mtd/spi-nor/fsl-quadspi.c | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> > index f17d224..7712c63 100644
> > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >         struct resource *res;
> >         struct spi_nor *nor;
> >         struct mtd_info *mtd;
> > -       int ret, i = 0;
> > +       int ret, i = 0, mtd_index = 0;  
> 
> It's not the MTD index if you have other MTD devices. How about
> spiflash_idx?
> 
> > 
> >         q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
> >         if (!q)
> > @@ -1047,6 +1047,13 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >                 nor = &q->nor[i];
> >                 mtd = &nor->mtd;
> > 
> > +               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "fsl-quadspi.%d",
> > +                                          mtd_index);  
> 
> With the alternative naming scheme suggested above, it gives:
> 
> 		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s:%d"
> 					   dev_name(&pdev->dev),
> 					   mtd_index);
> 
> > +               if (!mtd->name) {
> > +                       ret = -ENOMEM;
> > +                       goto mutex_failed;
> > +               }
> > +
> >                 nor->dev = dev;
> >                 spi_nor_set_flash_node(nor, np);


One, last thing: there's a generic mechanism using the value of the
'label' property for mtd->name, which is particularly useful if one
wants to assign user-friendly names to his flashes. This is done in
spi_nor_set_flash_node() (more precisely in mtd_set_of_node() which is
called by spi_nor_set_flash_node()), but it only works if mtd->name is
NULL. So I recommend move the mtd->name assignment here, and making it
conditional:

		if (!mtd->name) {
			mtd->name = devm_kasprintf(...);
			...
		}

> >                 nor->priv = q;
> > @@ -1098,6 +1105,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >                         nor->page_size = q->devtype_data->txfifo;
> > 
> >                 i++;
> > +               mtd_index++;
> >         }
> > 
> >         /* finish the rest init. */
> > --
> > 2.7.4
> > 
> > Acked-by: Han Xu <han.xu at nxp.com>
> > 
> > ______________________________________________________
> > Linux MTD discussion mailing list
> > http://lists.infradead.org/mailman/listinfo/linux-mtd/  
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From rockdotlee at gmail.com  Wed Jan 10 17:47:11 2018
From: rockdotlee at gmail.com (Rock Lee)
Date: Thu, 11 Jan 2018 09:47:11 +0800
Subject: [PATCH] ubifs: Change log level in ubifs_xattr_get
In-Reply-To: <3873582.N8pb6r5EOO@blindfold>
References: <1515578741-6612-1-git-send-email-rockdotlee@gmail.com>
 <3873582.N8pb6r5EOO@blindfold>
Message-ID: <CAL-1w2vN46pakvAA+mOj+YNiSnh1PWgwwrWSA305X3+SHNwnUQ@mail.gmail.com>

>> Just print warning message when xattr value size is bigger than the
>> buffer size. There is a situation that other modules, like overlayfs,
>> try to get xattr value with a small buffer, if they get -ERANGE, they
>> will try again with the proper buffer size. No need to report a error
>> message, warning message is enough.
>>
>> Signed-off-by: Rock Lee <rockdotlee at gmail.com>
>> ---
>>  fs/ubifs/xattr.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
>> index 5ddc89d..bc20530 100644
>> --- a/fs/ubifs/xattr.c
>> +++ b/fs/ubifs/xattr.c
>> @@ -381,7 +381,7 @@ ssize_t ubifs_xattr_get(struct inode *host, const char
>> *name, void *buf, if (buf) {
>>               /* If @buf is %NULL we are supposed to return the length */
>>               if (ui->data_len > size) {
>> -                     ubifs_err(c, "buffer size %zd, xattr len %d",
>> +                     ubifs_warn(c, "buffer size %zd, xattr len %d",
>>                                 size, ui->data_len);
>
> Hmm, if this can be triggered that easy I suggest getting completely rid of
> this message.
>

OK, forget about this one, I am going to send you another patch to get
rid of this message


-- 
Cheers,
Rock


From rockdotlee at gmail.com  Wed Jan 10 18:08:24 2018
From: rockdotlee at gmail.com (rockdotlee at gmail.com)
Date: Wed, 10 Jan 2018 21:08:24 -0500
Subject: [PATCH] ubifs: remove error message in ubifs_xattr_get
Message-ID: <1515636504-7660-1-git-send-email-rockdotlee@gmail.com>

From: Rock Lee <rli at sierrawireless.com>

There is a situation that other modules, like overlayfs, try to get
xattr value with a small buffer, if they get -ERANGE, they will try
again with the proper buffer size. No need to report an error.

Signed-off-by: Rock Lee <rli at sierrawireless.com>
---
 fs/ubifs/xattr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c13eae8..1615270 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -380,8 +380,6 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
 	if (buf) {
 		/* If @buf is %NULL we are supposed to return the length */
 		if (ui->data_len > size) {
-			ubifs_err(c, "buffer size %zd, xattr len %d",
-				  size, ui->data_len);
 			err = -ERANGE;
 			goto out_iput;
 		}
-- 
1.9.1



From rogerq at ti.com  Thu Jan 11 00:08:19 2018
From: rogerq at ti.com (Roger Quadros)
Date: Thu, 11 Jan 2018 10:08:19 +0200
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180110212748.lbwwnktftqv3awzi@darkstar.musicnaut.iki.fi>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon> <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com> <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
 <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
 <20180110212748.lbwwnktftqv3awzi@darkstar.musicnaut.iki.fi>
Message-ID: <5709e23c-a2f1-c890-cf8b-8f52f31d8b73@ti.com>



On 10/01/18 23:27, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Jan 10, 2018 at 07:35:19PM +0200, Aaro Koskinen wrote:
>> On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
>>> On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
>>>> On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
>>>>> Merge window is really close now and patches seems still to be untested on
>>>>> n8x0. So unless someone is going to test it soon, I'll pick used N800 on
>>>>> ebay :-/
>>>>
>>>> Today I tried to test them on Nokia N810, and I get:
>>>>
>>>> [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
>>>> [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
>>>> [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
>>>> [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
>>>>
>>>> With plain v4.15-rc7+ it probes fine.
>>>
>>> Thank you for testing. As stated in cover letter, you need also
>>> https://patchwork.kernel.org/patch/10043259/
>>> which can be also found in Roger's branch
>>> https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
>>> (see previous replies in this thread and also discussion about OneNAND
>>> DT node)
>>
>> I applied it, and now get:
>>
>> [    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
>> [    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
>> [    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
>> [    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> 
> Crap, I think something is wrong in my kexec. It seems to pass the DTB from an
> old kernel, although the new kernel has a new appended DTB... Need to
> investigate, sorry for noise.
> 
> A.
> 

Aaro,

You will still need to add "ti,omap2-onenand" compatible property to the n800/810 onenand node for it to work.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


From boris.brezillon at free-electrons.com  Thu Jan 11 01:04:38 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 10:04:38 +0100
Subject: [PATCH V7 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180104070534.16248-1-zajec5@gmail.com>
References: <20180103105543.17897-1-zajec5@gmail.com>
 <20180104070534.16248-1-zajec5@gmail.com>
Message-ID: <20180111100438.281db30a@bbrezillon>

On Thu,  4 Jan 2018 08:05:33 +0100
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> From: Brian Norris <computersforpeace at gmail.com>
> 
> Partition parsers can now provide an of_match_table to enable
> flash<-->parser matching via device tree as documented in the
> mtd/partition.txt.
> 
> It works by looking for a matching parser for every string in the
> "compatibility" property (starting with the most specific one).
> 
> This support is currently limited to built-in parsers as it uses
> request_module() and friends. This should be sufficient for most cases
> though as compiling parsers as modules isn't a common choice.
> 

Applied both patches.

Thanks,

Boris

> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> This is based on Brian's patches:
> [RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
> [RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
> 
> V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
>     Merge helpers into a single of_mtd_match_mtd_parser
> V3: Add a simple comment to note we will need the best match in the future
> V4: Rework new functions to pick parser with the best match
>     Move new code in parse_mtd_partitions up so it has precedence over flash
>     driver defaults and MTD defaults
> V5: Rework matching code to start checking with the most specific string in the
>     "compatibility" property.
> V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
> V7: Rename function "mtd_part_get_parser_by_cp" to use "_compatible_"
>     Rename "cp" variable to "compat"
>     Drop unneeded if (np) check from the parse_mtd_partitions
> ---
>  drivers/mtd/mtdpart.c          | 59 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/partitions.h |  1 +
>  2 files changed, 60 insertions(+)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..76e12fb81563 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -30,6 +30,7 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/err.h>
> +#include <linux/of.h>
>  
>  #include "mtdcore.h"
>  
> @@ -880,6 +881,45 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
>  }
>  
>  /**
> + * mtd_part_get_compatible_parser - find MTD parser by a compatible string
> + *
> + * @compat: compatible string describing partitions in a device tree
> + *
> + * MTD parsers can specify supported partitions by providing a table of
> + * compatibility strings. This function finds a parser that advertises support
> + * for a passed value of "compatible".
> + */
> +static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
> +{
> +	struct mtd_part_parser *p, *ret = NULL;
> +
> +	spin_lock(&part_parser_lock);
> +
> +	list_for_each_entry(p, &part_parsers, list) {
> +		const struct of_device_id *matches;
> +
> +		matches = p->of_match_table;
> +		if (!matches)
> +			continue;
> +
> +		for (; matches->compatible[0]; matches++) {
> +			if (!strcmp(matches->compatible, compat) &&
> +			    try_module_get(p->owner)) {
> +				ret = p;
> +				break;
> +			}
> +		}
> +
> +		if (ret)
> +			break;
> +	}
> +
> +	spin_unlock(&part_parser_lock);
> +
> +	return ret;
> +}
> +
> +/**
>   * parse_mtd_partitions - parse MTD partitions
>   * @master: the master partition (describes whole MTD device)
>   * @types: names of partition parsers to try or %NULL
> @@ -905,8 +945,27 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
>  			 struct mtd_part_parser_data *data)
>  {
>  	struct mtd_part_parser *parser;
> +	struct device_node *np;
> +	struct property *prop;
> +	const char *compat;
>  	int ret, err = 0;
>  
> +	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
> +	of_property_for_each_string(np, "compatible", prop, compat) {
> +		parser = mtd_part_get_compatible_parser(compat);
> +		if (!parser)
> +			continue;
> +		ret = mtd_part_do_parse(parser, master, pparts, data);
> +		if (ret > 0) {
> +			of_node_put(np);
> +			return 0;
> +		}
> +		mtd_part_parser_put(parser);
> +		if (ret < 0 && !err)
> +			err = ret;
> +	}
> +	of_node_put(np);
> +
>  	if (!types)
>  		types = default_mtd_part_types;
>  
> diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
> index c4beb70dacbd..11cb0c50cd84 100644
> --- a/include/linux/mtd/partitions.h
> +++ b/include/linux/mtd/partitions.h
> @@ -77,6 +77,7 @@ struct mtd_part_parser {
>  	struct list_head list;
>  	struct module *owner;
>  	const char *name;
> +	const struct of_device_id *of_match_table;
>  	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
>  			struct mtd_part_parser_data *);
>  	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);



From boris.brezillon at free-electrons.com  Thu Jan 11 01:06:36 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 10:06:36 +0100
Subject: [PATCH v5 1/3] mtd: mtdpart: Make ECC stat handling consistent
In-Reply-To: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
References: <20180109085035.12438-1-boris.brezillon@free-electrons.com>
Message-ID: <20180111100636.3abe1459@bbrezillon>

On Tue,  9 Jan 2018 09:50:33 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> part_read() and part_read_oob() where counting ECC failures and
> bitflips differently. Adjust part_read_oob() to mimic what is done in
> part_read(). This is in needed to use ->_read_oob() as a fallback when
> when ->_read() is not implemented.
> 
> Note that bitflips and ECC failure accounting on MTD partitions is
> broken by design, because nothing prevents concurrent accesses to the
> underlying master MTD device between the moment we save the stats in a
> local variable and the moment master->_read[_oob]() returns. It's not
> something that can easily be fixed, so leave it like that for now.

Applied the series (also fixed the typo reported by Robert).

> 
> Suggested-by: Brian Norris <computersforpeace at gmail.com>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Tested-by: Ladislav Michl <ladis at linux-mips.org>
> ---
> Changes in v5:
> - save master's ECC stats before calling ->_read_oob()
> 
> Changes in v4:
> - new patch
> ---
>  drivers/mtd/mtdpart.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index be088bccd593..79bf1f61c7a0 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  		struct mtd_oob_ops *ops)
>  {
>  	struct mtd_part *part = mtd_to_part(mtd);
> +	struct mtd_ecc_stats stats;
>  	int res;
>  
>  	if (from >= mtd->size)
> @@ -126,13 +127,14 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
>  			return -EINVAL;
>  	}
>  
> +	stats = part->parent->ecc_stats;
>  	res = part->parent->_read_oob(part->parent, from + part->offset, ops);
> -	if (unlikely(res)) {
> -		if (mtd_is_bitflip(res))
> -			mtd->ecc_stats.corrected++;
> -		if (mtd_is_eccerr(res))
> -			mtd->ecc_stats.failed++;
> -	}
> +	if (unlikely(mtd_is_eccerr(res)))
> +		mtd->ecc_stats.failed +=
> +			part->parent->ecc_stats.failed - stats.failed;
> +	else
> +		mtd->ecc_stats.corrected +=
> +			part->parent->ecc_stats.corrected - stats.corrected;
>  	return res;
>  }
>  



From boris.brezillon at free-electrons.com  Thu Jan 11 03:27:51 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 12:27:51 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180111122751.4bd74366@bbrezillon>

On Tue,  9 Jan 2018 11:36:30 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Hi,
> 
> After the addition of the NAND framework ->exec_op() interface (see [1]
> for the series preparing it and [2] for the last version of the
> core-side implementation of ->exec_op() itself), this series replaces
> the current Marvell NAND controller driver pxa3xx_nand.c with a rework
> called marvell_nand.c.
> 
> Aside the fact that it drops the big state machine, improves the overall
> speed and implements raw accesses, it is the first driver-side
> implementation of the ->exec_op() interface and may be used as reference
> for latter reworks of the same type.
> 
> One may find more detail about why a completely new driver is needed in
> the commit log of:
> 
>     "mtd: nand: add reworked Marvell NAND controller driver"
> 
> Device tree NAND node definition for all platforms referring to the
> Marvell driver using the new bindings have already been accepted by the
> MVEBU DT maintainers and will be merged after the driver. They are more
> hierarchical and fit the real organization of the hardware, by having
> NAND partitions that are part of NAND chip nodes, themselves part of the
> NAND controller node.
> 
> These changes have been tested on:
>    - PXA3xx platform with a CM-X300 board (2kiB page NAND, 1b/512B
>      strength, Hamming ECC engine) [32 bits]
>    - Armada 385 DB AP (4kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
>    - Armada 398 DB (4kiB page NAND, 8b/512B, BCH ECC engine using a layout
>      with a last chunk different than the others) [32 bits]
>    - Armada 7040 DB and Armada 8040 DB (4kiB page NAND, 4b/512B, BCH ECC
>      engine) [64 bits]
>    - Triax dvb-tc board (2kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
> 
> This version is known not to be stable yet with a Zylonite based setup but
> otherwise looks good for Marvell EBU platforms.

So, here is the plan: since the driver has been tested on various mvebu
platforms and is known to work fine on these platforms, I'd like to
queue the driver and the patch modifying mvebu defconfigs (patches 1 to
4) for 4.16.
I'll leave other patches for 4.17, which means I'd like remaining bugs
to be fixed during the 4.16 release cycle so that we can eventually get
rid of the old driver. That's really important to me that we don't keep
both drivers around for too long, because my previous experience showed
that, when you have 2 drivers for the same HW, people don't switch to
the new one until they're forced to do it.

Robert, are you fine with this approach? What about the tests you were
doing? Did you make any progress? Did you find other issues?

> 
> For people who would like to test it easily, a branch ready to be tested
> is available at [3]. It is based on nand/next and has all the changes
> brought by the previously mentionned series as well as this one.
> 
> Thank you,
> Miqu?l
> 
> 
> [1] https://www.spinics.net/lists/arm-kernel/msg619633.html
> [2] http://lists.infradead.org/pipermail/linux-mtd/2017-December/077965.html
> [3] https://github.com/miquelraynal/linux/tree/marvell/nand-next/nfc
> 
> 
> Changes since v2:
>   - Added a patch to create the nand-rb property in the Documentation
>   - Rewording in the Documentation according to Rob's comments
>   - Moved from marvell,rb to nand-rb property in the code
>   - Disociated using this driver with Marvell EBU platforms than using
>     it with PXA ones
>   - Fixed the handling of 16-bit buses
>   - Fixed SPDX comment style
>   - Reorganized registers offsets/bit fields definitions as requested
>   - Moved to Kernel doc
>   - Changed the logic in ->select_chip() to use a prepared value of NDCR
>     only instead of recalculating it
>   - Fixed the presence of the SPARE_EN bit, reworked a bit the
>     hmg_do_read/write() helpers
>   - Fixed the OOB layouts that were unusable (all spare data first, then
>     all ECC bytes)
>   - Additional check on mtd->writesize when using NFCv1 (all sizes not
>     supported)
>   - Various typos/rewording
> 
> Changes since v1:
>   - Rewording
>   - Fixed BCH ->read/write_page() hooks for 2kiB pages NAND chips
>   - Removed license text, used SPDX tag instead
>   - Removed read_page_data()
>   - Enhanced the DT bindings document with the label property and the
>     deprecated bindings.
>   - Simplified the read_chunk() helper (OOB always read).
>   - Simplified the ->bch_read_page() hook by removing the addition raw
>     read to get ECC bytes.
>   - Fixed the ->correct() function that did not check for bitflips in
>     ECC bytes in erased pages.
> 
> 
> Miquel Raynal (7):
>   dt-bindings: mtd: document new nand-rb property
>   dt-bindings: mtd: add Marvell NAND controller documentation
>   mtd: nand: add reworked Marvell NAND controller driver
>   mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
>   mtd: nand: use Marvell reworked NAND controller driver with all
>     platforms
>   dt-bindings: mtd: remove pxa3xx NAND controller documentation
>   mtd: nand: remove useless fields from pxa3xx NAND platform data
> 
>  .../devicetree/bindings/mtd/marvell-nand.txt       |  123 +
>  Documentation/devicetree/bindings/mtd/nand.txt     |    1 +
>  .../devicetree/bindings/mtd/pxa3xx-nand.txt        |   50 -
>  arch/arm/configs/cm_x300_defconfig                 |    2 +-
>  arch/arm/configs/mvebu_v7_defconfig                |    2 +-
>  arch/arm/configs/pxa3xx_defconfig                  |    3 +-
>  arch/arm/configs/pxa_defconfig                     |    2 +-
>  arch/arm/configs/raumfeld_defconfig                |    2 +-
>  arch/arm/mach-mmp/ttc_dkb.c                        |    4 +-
>  arch/arm/mach-pxa/cm-x300.c                        |    8 +-
>  arch/arm/mach-pxa/colibri-pxa3xx.c                 |    8 +-
>  arch/arm/mach-pxa/colibri.h                        |    2 +-
>  arch/arm/mach-pxa/littleton.c                      |   10 +-
>  arch/arm/mach-pxa/mxm8x10.c                        |   10 +-
>  arch/arm/mach-pxa/raumfeld.c                       |    6 +-
>  arch/arm/mach-pxa/zylonite.c                       |   10 +-
>  arch/arm64/configs/defconfig                       |    2 +-
>  drivers/mtd/nand/Kconfig                           |   18 +-
>  drivers/mtd/nand/Makefile                          |    2 +-
>  drivers/mtd/nand/marvell_nand.c                    | 2896 ++++++++++++++++++++
>  drivers/mtd/nand/pxa3xx_nand.c                     | 2104 --------------
>  include/linux/platform_data/mtd-nand-pxa3xx.h      |   43 +-
>  22 files changed, 3072 insertions(+), 2236 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
>  delete mode 100644 Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
>  create mode 100644 drivers/mtd/nand/marvell_nand.c
>  delete mode 100644 drivers/mtd/nand/pxa3xx_nand.c
> 



From fabio.estevam at nxp.com  Thu Jan 11 05:15:04 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Thu, 11 Jan 2018 11:15:04 -0200
Subject: [PATCH v2] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1515676504-11510-1-git-send-email-fabio.estevam@nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v1:
- Use 'spiflash_idx' for the variable name
- Use the mtd->name in the format 21e4000.qspi-0
- Do not assing the mtd name relying on the dts ordering and use the reg
property instead
- Call devm_kasprintf() after spi_nor_set_flash_node().

 drivers/mtd/spi-nor/fsl-quadspi.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..b28ad8b 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, spiflash_idx;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1051,6 +1051,22 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		ret = of_property_read_u32(np, "reg", &spiflash_idx);
+		if (ret) {
+			dev_err(dev, "could not get reg property: %d\n", ret);
+			ret = -EINVAL;
+			goto mutex_failed;
+		}
+
+		if (!mtd->name) {
+			mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%d",
+						   dev_name(dev), spiflash_idx);
+			if (!mtd->name) {
+				ret = -ENOMEM;
+				goto mutex_failed;
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From fabio.estevam at nxp.com  Thu Jan 11 05:23:13 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Thu, 11 Jan 2018 11:23:13 -0200
Subject: [PATCH v3] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1515676993-15561-1-git-send-email-fabio.estevam@nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v2:
- Remove unnecessary EINVAL assignment when of_property_read_u32() fails
Changes since v1:
- Use 'spiflash_idx' for the variable name
- Use the mtd->name in the format 21e4000.qspi-0
- Do not assing the mtd name relying on the dts ordering and use the reg
property instead
- Call devm_kasprintf() after spi_nor_set_flash_node().
 drivers/mtd/spi-nor/fsl-quadspi.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..c2572be 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, spiflash_idx;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1051,6 +1051,21 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		ret = of_property_read_u32(np, "reg", &spiflash_idx);
+		if (ret) {
+			dev_err(dev, "could not get reg property: %d\n", ret);
+			goto mutex_failed;
+		}
+
+		if (!mtd->name) {
+			mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%d",
+						   dev_name(dev), spiflash_idx);
+			if (!mtd->name) {
+				ret = -ENOMEM;
+				goto mutex_failed;
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From boris.brezillon at free-electrons.com  Thu Jan 11 05:25:06 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 14:25:06 +0100
Subject: [PATCH v2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1515676504-11510-1-git-send-email-fabio.estevam@nxp.com>
References: <1515676504-11510-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <20180111142506.13a05281@bbrezillon>

On Thu, 11 Jan 2018 11:15:04 -0200
Fabio Estevam <fabio.estevam at nxp.com> wrote:

> Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> to QSPI2 the following output from /proc/mtd is seen:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi"
> mtd1: 01000000 00010000 "21e4000.qspi"
> 
> Attempts to partition them on the kernel command line result in both
> chips with identical (and identically named) partitions, which is
> an inconvenient behavior.
> 
> Assign a different mtd->name for each mtd device to avoid this problem.
> 
> After this change the output from /proc/mtd becomes:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi-0"
> mtd1: 01000000 00010000 "21e4000.qspi-1"
> 
> Reported-by: David Wolfe <david.wolfe at nxp.com>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
> Changes since v1:
> - Use 'spiflash_idx' for the variable name
> - Use the mtd->name in the format 21e4000.qspi-0
> - Do not assing the mtd name relying on the dts ordering and use the reg
> property instead
> - Call devm_kasprintf() after spi_nor_set_flash_node().
> 
>  drivers/mtd/spi-nor/fsl-quadspi.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index 2901c7b..b28ad8b 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	struct spi_nor *nor;
>  	struct mtd_info *mtd;
> -	int ret, i = 0;
> +	int ret, i = 0, spiflash_idx;
>  
>  	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
>  	if (!q)
> @@ -1051,6 +1051,22 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  		spi_nor_set_flash_node(nor, np);
>  		nor->priv = q;
>  
> +		ret = of_property_read_u32(np, "reg", &spiflash_idx);
> +		if (ret) {
> +			dev_err(dev, "could not get reg property: %d\n", ret);
> +			ret = -EINVAL;
> +			goto mutex_failed;

Was reg already mandatory before this commit? If it's not the case,
you're breaking backward compat.

> +		}

You can move the above block

> +
> +		if (!mtd->name) {

here.

> +			mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%d",
> +						   dev_name(dev), spiflash_idx);

By changing the name you're breaking existing users that pass
mtdparts=21e4000.qspi:<parts> :-(.

There's no easy solution for the problem you're trying to solve, but
maybe you can make reg optional, and if it's not present set
mtd->name to dev_name(dev).
And, you should complain when you have more than one child node and reg
is missing.

> +			if (!mtd->name) {
> +				ret = -ENOMEM;
> +				goto mutex_failed;
> +			}
> +		}
> +
>  		/* fill the hooks */
>  		nor->read_reg = fsl_qspi_read_reg;
>  		nor->write_reg = fsl_qspi_write_reg;



From boris.brezillon at free-electrons.com  Thu Jan 11 05:26:24 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 14:26:24 +0100
Subject: [PATCH v2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180111142506.13a05281@bbrezillon>
References: <1515676504-11510-1-git-send-email-fabio.estevam@nxp.com>
 <20180111142506.13a05281@bbrezillon>
Message-ID: <20180111142624.0373d343@bbrezillon>

On Thu, 11 Jan 2018 14:25:06 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Thu, 11 Jan 2018 11:15:04 -0200
> Fabio Estevam <fabio.estevam at nxp.com> wrote:
> 
> > Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> > to QSPI2 the following output from /proc/mtd is seen:
> > 
> > # cat /proc/mtd 
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi"
> > mtd1: 01000000 00010000 "21e4000.qspi"
> > 
> > Attempts to partition them on the kernel command line result in both
> > chips with identical (and identically named) partitions, which is
> > an inconvenient behavior.
> > 
> > Assign a different mtd->name for each mtd device to avoid this problem.
> > 
> > After this change the output from /proc/mtd becomes:
> > 
> > # cat /proc/mtd 
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi-0"
> > mtd1: 01000000 00010000 "21e4000.qspi-1"
> > 
> > Reported-by: David Wolfe <david.wolfe at nxp.com>
> > Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> > ---
> > Changes since v1:
> > - Use 'spiflash_idx' for the variable name
> > - Use the mtd->name in the format 21e4000.qspi-0
> > - Do not assing the mtd name relying on the dts ordering and use the reg
> > property instead
> > - Call devm_kasprintf() after spi_nor_set_flash_node().
> > 
> >  drivers/mtd/spi-nor/fsl-quadspi.c | 18 +++++++++++++++++-
> >  1 file changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> > index 2901c7b..b28ad8b 100644
> > --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> > +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> > @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >  	struct resource *res;
> >  	struct spi_nor *nor;
> >  	struct mtd_info *mtd;
> > -	int ret, i = 0;
> > +	int ret, i = 0, spiflash_idx;
> >  
> >  	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
> >  	if (!q)
> > @@ -1051,6 +1051,22 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> >  		spi_nor_set_flash_node(nor, np);
> >  		nor->priv = q;
> >  
> > +		ret = of_property_read_u32(np, "reg", &spiflash_idx);

Forgot to mention that the DT bindings doc should be updated
accordingly.

> > +		if (ret) {
> > +			dev_err(dev, "could not get reg property: %d\n", ret);
> > +			ret = -EINVAL;
> > +			goto mutex_failed;
> 
> Was reg already mandatory before this commit? If it's not the case,
> you're breaking backward compat.
> 
> > +		}
> 
> You can move the above block
> 
> > +
> > +		if (!mtd->name) {
> 
> here.
> 
> > +			mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%d",
> > +						   dev_name(dev), spiflash_idx);
> 
> By changing the name you're breaking existing users that pass
> mtdparts=21e4000.qspi:<parts> :-(.
> 
> There's no easy solution for the problem you're trying to solve, but
> maybe you can make reg optional, and if it's not present set
> mtd->name to dev_name(dev).
> And, you should complain when you have more than one child node and reg
> is missing.
> 
> > +			if (!mtd->name) {
> > +				ret = -ENOMEM;
> > +				goto mutex_failed;
> > +			}
> > +		}
> > +
> >  		/* fill the hooks */
> >  		nor->read_reg = fsl_qspi_read_reg;
> >  		nor->write_reg = fsl_qspi_write_reg;
> 



From fabio.estevam at nxp.com  Thu Jan 11 07:44:38 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Thu, 11 Jan 2018 13:44:38 -0200
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v1:
- Do not fail probe when reg is not present

 drivers/mtd/spi-nor/fsl-quadspi.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..8020295 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, spiflash_idx;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		if (!mtd->name) {
+			ret = of_property_read_u32(np, "reg", &spiflash_idx);
+			if (!ret) {
+				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+							   "%s-%d",
+							   dev_name(dev),
+							   spiflash_idx);
+			} else {
+				mtd->name = dev_name(dev);
+				dev_warn(dev, "reg property is missing\n");
+			}
+
+			if (!mtd->name) {
+				ret = -ENOMEM;
+				goto mutex_failed;
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From boris.brezillon at free-electrons.com  Thu Jan 11 07:48:23 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 16:48:23 +0100
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <20180111164823.34b0b8fd@bbrezillon>

On Thu, 11 Jan 2018 13:44:38 -0200
Fabio Estevam <fabio.estevam at nxp.com> wrote:

> Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> to QSPI2 the following output from /proc/mtd is seen:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi"
> mtd1: 01000000 00010000 "21e4000.qspi"
> 
> Attempts to partition them on the kernel command line result in both
> chips with identical (and identically named) partitions, which is
> an inconvenient behavior.
> 
> Assign a different mtd->name for each mtd device to avoid this problem.
> 
> After this change the output from /proc/mtd becomes:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi-0"
> mtd1: 01000000 00010000 "21e4000.qspi-1"
> 
> Reported-by: David Wolfe <david.wolfe at nxp.com>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
> Changes since v1:
> - Do not fail probe when reg is not present
> 
>  drivers/mtd/spi-nor/fsl-quadspi.c | 20 +++++++++++++++++++-

Still missing the DT doc update. You can do it in a separate patch, but
please make it part of the same series.

>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index 2901c7b..8020295 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -967,7 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	struct spi_nor *nor;
>  	struct mtd_info *mtd;
> -	int ret, i = 0;
> +	int ret, i = 0, spiflash_idx;
>  
>  	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
>  	if (!q)
> @@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  		spi_nor_set_flash_node(nor, np);
>  		nor->priv = q;
>  
> +		if (!mtd->name) {

Move the spiflash_idx declaration here.

> +			ret = of_property_read_u32(np, "reg", &spiflash_idx);
> +			if (!ret) {
> +				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
> +							   "%s-%d",
> +							   dev_name(dev),
> +							   spiflash_idx);
> +			} else {
> +				mtd->name = dev_name(dev);
> +				dev_warn(dev, "reg property is missing\n");
> +			}
> +
> +			if (!mtd->name) {
> +				ret = -ENOMEM;
> +				goto mutex_failed;
> +			}
> +		}
> +
>  		/* fill the hooks */
>  		nor->read_reg = fsl_qspi_read_reg;
>  		nor->write_reg = fsl_qspi_write_reg;



From festevam at gmail.com  Thu Jan 11 07:59:44 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 11 Jan 2018 13:59:44 -0200
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180111164823.34b0b8fd@bbrezillon>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
 <20180111164823.34b0b8fd@bbrezillon>
Message-ID: <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>

Hi Boris,

On Thu, Jan 11, 2018 at 1:48 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:

> Still missing the DT doc update. You can do it in a separate patch, but
> please make it part of the same series.

The dt-binding update part is not very clear to me.

Currently on the imx6sx-sdb.dts we have:

&qspi2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_qspi2>;
    status = "okay";

    flash0: n25q256a at 0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "micron,n25q256a", "jedec,spi-nor";
        spi-max-frequency = <29000000>;
        reg = <0>;
    };

    flash1: n25q256a at 1 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "micron,n25q256a", "jedec,spi-nor";
        spi-max-frequency = <29000000>;
        reg = <1>;
    };
};


The reg requirement is already present as part of
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt.

Are you proposing that I add a comment to
Documentation/devicetree/bindings/mtd/fsl-quadspi.txt saying that the
Flash sub-nodes must contain a reg property?

Please clarify.

Thanks


From nicolas.ferre at microchip.com  Thu Jan 11 08:26:59 2018
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Thu, 11 Jan 2018 17:26:59 +0100
Subject: [PATCH v2] MAINTAINERS: mtd/nand: update Microchip nand entry
Message-ID: <20180111162659.740-1-nicolas.ferre@microchip.com>

Update Wenyou Yang email address.
Take advantage of this update to move this entry to the MICROCHIP / ATMEL
location and add the DT binding documentation link.

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Acked-by: Wenyou Yang <wenyou.yang at microchip.com>
---
v2: - patch agains 09ec417b0ea8 ("mtd: nand: samsung: Disable subpage
      writes on E-die NAND") of 
      http://git.infradead.org/linux-mtd.git/shortlog/refs/heads/nand/next
    - Ack by Wenyou added


Hi,

v1 patch was part of a series because it was conflicting with the previous one
named:
"[PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and ISC entries"
Boris asked me to rebase it so that they are independent.
So, if this first one goes upstream through another tree, conflicts will have
to be resolved at one point.

Best regards,
  Nicolas


 MAINTAINERS | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa71ab52fd76..37ee5ae4bae2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2382,13 +2382,6 @@ F:	Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F:	drivers/input/touchscreen/atmel_mxt_ts.c
 F:	include/linux/platform_data/atmel_mxt_ts.h
 
-ATMEL NAND DRIVER
-M:	Wenyou Yang <wenyou.yang at atmel.com>
-M:	Josh Wu <rainyfeeling at outlook.com>
-L:	linux-mtd at lists.infradead.org
-S:	Supported
-F:	drivers/mtd/nand/atmel/*
-
 ATMEL SAMA5D2 ADC DRIVER
 M:	Ludovic Desroches <ludovic.desroches at microchip.com>
 L:	linux-iio at vger.kernel.org
@@ -9045,6 +9038,14 @@ F:	drivers/media/platform/atmel/atmel-isc.c
 F:	drivers/media/platform/atmel/atmel-isc-regs.h
 F:	devicetree/bindings/media/atmel-isc.txt
 
+MICROCHIP / ATMEL NAND DRIVER
+M:	Wenyou Yang <wenyou.yang at microchip.com>
+M:	Josh Wu <rainyfeeling at outlook.com>
+L:	linux-mtd at lists.infradead.org
+S:	Supported
+F:	drivers/mtd/nand/atmel/*
+F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh at microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver at microchip.com>
-- 
2.9.0



From boris.brezillon at free-electrons.com  Thu Jan 11 08:40:12 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 17:40:12 +0100
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
 <20180111164823.34b0b8fd@bbrezillon>
 <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>
Message-ID: <20180111174012.67e2681a@bbrezillon>

On Thu, 11 Jan 2018 13:59:44 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> Hi Boris,
> 
> On Thu, Jan 11, 2018 at 1:48 PM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> 
> > Still missing the DT doc update. You can do it in a separate patch, but
> > please make it part of the same series.  
> 
> The dt-binding update part is not very clear to me.
> 
> Currently on the imx6sx-sdb.dts we have:
> 
> &qspi2 {
>     pinctrl-names = "default";
>     pinctrl-0 = <&pinctrl_qspi2>;
>     status = "okay";
> 
>     flash0: n25q256a at 0 {
>         #address-cells = <1>;
>         #size-cells = <1>;
>         compatible = "micron,n25q256a", "jedec,spi-nor";
>         spi-max-frequency = <29000000>;
>         reg = <0>;
>     };
> 
>     flash1: n25q256a at 1 {
>         #address-cells = <1>;
>         #size-cells = <1>;
>         compatible = "micron,n25q256a", "jedec,spi-nor";
>         spi-max-frequency = <29000000>;
>         reg = <1>;
>     };
> };
> 
> 
> The reg requirement is already present as part of
> Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt.
> 
> Are you proposing that I add a comment to
> Documentation/devicetree/bindings/mtd/fsl-quadspi.txt saying that the
> Flash sub-nodes must contain a reg property?

Nope, I wasn't sure whether reg was mandatory or not since it was not
used by the driver before your patch. This being said, that'd be good to
update the example you have in the bindings do to fully describe a
flash device.

Anyway, if all existing DTs have a reg defined, even those where only
one flash device is described, then your patch might break mtdparts
users. And if this is not the case, and the reg property is really
mandatory, then that means those dts are not compliant with the DT
bindings and have to be patched :-). So, the solution of testing the
presence of a reg property to choose the naming scheme is probably not
appropriate.


From festevam at gmail.com  Thu Jan 11 08:58:39 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 11 Jan 2018 14:58:39 -0200
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180111174012.67e2681a@bbrezillon>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
 <20180111164823.34b0b8fd@bbrezillon>
 <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>
 <20180111174012.67e2681a@bbrezillon>
Message-ID: <CAOMZO5Aerkb2r0y2aC8sZJcEgpJzoNgR5_MU=2t_uq7jTzNo9g@mail.gmail.com>

On Thu, Jan 11, 2018 at 2:40 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:

> Nope, I wasn't sure whether reg was mandatory or not since it was not
> used by the driver before your patch. This being said, that'd be good to
> update the example you have in the bindings do to fully describe a
> flash device.

Ok, I can update fsl-quadspi.txt to include an example for describing
the flash devices.

> Anyway, if all existing DTs have a reg defined, even those where only

As far as I can see all DTs that use fsl-quadspi have a reg property
in the SPI flash sub-nodes:

arch/arm/boot/dts/imx6ul-14x14-evk.dts
arch/arm/boot/dts/imx6sx-sdb.dts
arch/arm/boot/dts/ls1021a-moxa-uc-8410a.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts

> one flash device is described, then your patch might break mtdparts
> users. And if this is not the case, and the reg property is really
> mandatory, then that means those dts are not compliant with the DT
> bindings and have to be patched :-). So, the solution of testing the
> presence of a reg property to choose the naming scheme is probably not
> appropriate.

Any ideas on how we can properly solve this?


From robert.jarzmik at free.fr  Thu Jan 11 09:42:56 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 11 Jan 2018 18:42:56 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180111122751.4bd74366@bbrezillon> (Boris Brezillon's message
 of "Thu, 11 Jan 2018 12:27:51 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
Message-ID: <87efmwb8bj.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

Hi Boris and Miquel,

> So, here is the plan: since the driver has been tested on various mvebu
> platforms and is known to work fine on these platforms, I'd like to
> queue the driver and the patch modifying mvebu defconfigs (patches 1 to
> 4) for 4.16.
That's all right.

> I'll leave other patches for 4.17, which means I'd like remaining bugs
> to be fixed during the 4.16 release cycle so that we can eventually get
> rid of the old driver. That's really important to me that we don't keep
> both drivers around for too long, because my previous experience showed
> that, when you have 2 drivers for the same HW, people don't switch to
> the new one until they're forced to do it.
>
> Robert, are you fine with this approach? What about the tests you were
> doing? Did you make any progress? Did you find other issues?
So far, with the latest branch from Miquel of tip commit 12b9e62c851c ("ARM64:
dts: marvell: use reworked NAND controller driver on Armada 8K"), the bad blocks
issue is still there, ie :
 - the old pxa3xx driver doesn't see any bad block and mounts the ext2/ubifs
   correctly
 - barebox doesn't see any bad block
 - marvell_nand sees all (or most all) blocks as bad with "flash_bbt=0" in
   platform data, which is very surprising

I'm really surprised that in your tests on the cm_x300, in a platform_data setup
(ie. not device-tree setup), you're not seeing these errors ...

As if I'm fine with this approach, I agree with step 1 (patches 1-4). As for
step 2, I'll agree if the current situation is solved and my boards recognize
correctly my ext2 over ubifs on the NAND.

Cheers.

--
Robert

[1] The dmesg extract (here with flash_bbt = 0)
Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
arch_number: 1233
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.15.0-rc1-00044-g11cc68b (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #879 PREEMPT Thu Jan 11 09:16:09 CET 2018
[    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] Memory policy: Data cache writeback
[    0.000000] RO Mode clock: 0.00MHz
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] System bus clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] random: fast init done
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56856K/65536K available (4225K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc04289e8   (4227 kB)
[    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
[    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
[    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
[    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
[    0.000068] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
[    0.000267] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
[    0.002139] Console: colour dummy device 80x30
[    0.002298] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
[    0.081019] pid_max: default: 32768 minimum: 301
[    0.081858] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.081958] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.085170] CPU: Testing write buffer coherency: ok
[    0.088980] Setting up static identity map for 0x80008200 - 0x80008260
[    0.089936] Hierarchical SRCU implementation.
[    0.102958] devtmpfs: initialized
[    0.113835] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.113974] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.116311] NET: Registered protocol family 16
[    0.119126] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.385492] Advanced Linux Sound Architecture Driver Initialized.
[    0.398200] clocksource: Switched to clocksource oscr0
[    0.551166] NET: Registered protocol family 2
[    0.556911] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.557135] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.557316] TCP: Hash tables configured (established 1024 bind 1024)
[    0.557858] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.558038] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.559740] NET: Registered protocol family 1
[    0.561795] RPC: Registered named UNIX socket transport module.
[    0.561891] RPC: Registered udp transport module.
[    0.561946] RPC: Registered tcp transport module.
[    0.562003] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.497308] Initialise system trusted keyrings
[    2.499900] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    2.503798] NFS: Registering the id_resolver key type
[    2.504004] Key type id_resolver registered
[    2.504066] Key type id_legacy registered
[    2.510210] Key type asymmetric registered
[    2.510311] Asymmetric key parser 'x509' registered
[    2.510469] io scheduler noop registered
[    2.510534] io scheduler deadline registered
[    2.510928] io scheduler cfq registered (default)
[    2.510999] io scheduler mq-deadline registered
[    2.511060] io scheduler kyber registered
[    2.571677] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
[    2.575099] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
[    3.050644] console [ttyS0] enabled
[    3.056987] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
[    3.069918] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
[    3.085482] nand: executing subop:
[    3.091647] nand:     ->CMD      [0xff]
[    3.095546] nand:     ->WAITRDY  [max 250 ms]
[    3.100705] marvell-nfc pxa3xx-nand: 
[    3.100705] NDCR:  0x90079fff
[    3.100705] NDCB0: 0x00a000ff
[    3.100705] NDCB1: 0x00000000
[    3.100705] NDCB2: 0x00000000
[    3.100705] NDCB3: 0x00000000
[    3.119968] nand: executing subop:
[    3.123439] nand:     ->CMD      [0x90]
[    3.127315] nand:     ->ADDR     [1 cyc: 00]
[    3.131983] nand:     ->DATA_IN  [2 B, force 8-bit]
[    3.136985] marvell-nfc pxa3xx-nand: 
[    3.136985] NDCR:  0x90079fff
[    3.136985] NDCB0: 0x00610090
[    3.136985] NDCB1: 0x00000000
[    3.136985] NDCB2: 0x00000000
[    3.136985] NDCB3: 0x00000000
[    3.155819] nand: executing subop:
[    3.159462] nand:     ->CMD      [0x90]
[    3.163343] nand:     ->ADDR     [1 cyc: 00]
[    3.167635] nand:     ->DATA_IN  [8 B, force 8-bit]
[    3.172747] marvell-nfc pxa3xx-nand: 
[    3.172747] NDCR:  0x90079fff
[    3.172747] NDCB0: 0x00610090
[    3.172747] NDCB1: 0x00000000
[    3.172747] NDCB2: 0x00000000
[    3.172747] NDCB3: 0x00000000
[    3.191422] nand: executing subop:
[    3.194876] nand:     ->CMD      [0x90]
[    3.198897] nand:     ->ADDR     [1 cyc: 20]
[    3.203210] nand:     ->DATA_IN  [4 B, force 8-bit]
[    3.208314] marvell-nfc pxa3xx-nand: 
[    3.208314] NDCR:  0x90079fff
[    3.208314] NDCB0: 0x00610090
[    3.208314] NDCB1: 0x00000020
[    3.208314] NDCB2: 0x00000000
[    3.208314] NDCB3: 0x00000000
[    3.226920] nand: executing subop:
[    3.230511] nand:     ->CMD      [0x90]
[    3.234394] nand:     ->ADDR     [1 cyc: 40]
[    3.238830] nand:     ->DATA_IN  [5 B, force 8-bit]
[    3.243808] marvell-nfc pxa3xx-nand: 
[    3.243808] NDCR:  0x90079fff
[    3.243808] NDCB0: 0x00610090
[    3.243808] NDCB1: 0x00000040
[    3.243808] NDCB2: 0x00000000
[    3.243808] NDCB3: 0x00000000
[    3.262444] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
[    3.268947] nand: ST Micro NAND 256MiB 1,8V 16-bit
[    3.273791] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    3.281519] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
[    3.288669] Scanning device for bad blocks
[    3.292845] nand: nand_do_read_oob: from = 0x00000000, len = 64
[    3.299007] marvell-nfc pxa3xx-nand: 
[    3.299007] NDCR:  0x9d079fff
[    3.299007] NDCB0: 0x000d3000
[    3.299007] NDCB1: 0x00000000
[    3.299007] NDCB2: 0x00000000
[    3.299007] NDCB3: 0x00000000
[    3.318075] Bad eraseblock 0 at 0x000000000000
[    3.322773] nand: nand_do_read_oob: from = 0x00020000, len = 64
[    3.328941] marvell-nfc pxa3xx-nand: 
[    3.328941] NDCR:  0x9d079fff
[    3.328941] NDCB0: 0x000d3000
[    3.328941] NDCB1: 0x00400000
[    3.328941] NDCB2: 0x00000000
[    3.328941] NDCB3: 0x00000000
[    3.347848] nand: nand_do_read_oob: from = 0x00040000, len = 64
[    3.354049] marvell-nfc pxa3xx-nand: 
[    3.354049] NDCR:  0x9d079fff
[    3.354049] NDCB0: 0x000d3000
[    3.354049] NDCB1: 0x00800000
[    3.354049] NDCB2: 0x00000000
[    3.354049] NDCB3: 0x00000000
[    3.372925] Bad eraseblock 2 at 0x000000040000
[    3.377451] nand: nand_do_read_oob: from = 0x00060000, len = 64
[    3.383633] marvell-nfc pxa3xx-nand: 
[    3.383633] NDCR:  0x9d079fff
[    3.383633] NDCB0: 0x000d3000
[    3.383633] NDCB1: 0x00c00000
[    3.383633] NDCB2: 0x00000000
[    3.383633] NDCB3: 0x00000000
[    3.402509] Bad eraseblock 3 at 0x000000060000
... and so on ...
[   60.154031] marvell-nfc pxa3xx-nand: 
[   60.154031] NDCR:  0x9d079fff
[   60.154031] NDCB0: 0x000d3000
[   60.154031] NDCB1: 0x58410000
[   60.154031] NDCB2: 0x00000000
[   60.154031] NDCB3: 0x00000000
[   60.173335] ubi0: scanning is finished
[   60.177297] ubi0 error: ubi_read_volume_table: the layout volume was not found
[   60.184878] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd5, error -22
[   60.192397] UBI error: cannot attach mtd5
[   60.197652] pxa-rtc pxa-rtc: setting system clock to 2000-01-01 00:01:25 UTC (946684885)
[   60.282788] smc91x smc91x.0 eth0: link down
[   62.152546] smc91x smc91x.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
[   62.198419] IP-Config: Complete:
[   62.201766]      device=eth0, hwaddr=00:0e:0c:a7:26:f7, ipaddr=192.168.1.232, mask=255.255.255.0, gw=255.255.255.255
[   62.212438]      host=192.168.1.232, domain=, nis-domain=(none)
[   62.218511]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
[   62.226759] ALSA device list:
[   62.230209]   #0: Zylonite
[   62.255735] Freeing unused kernel memory: 2396K
[   62.260675] This architecture does not have kernel memory protection.
Starting logging: OK


From aaro.koskinen at iki.fi  Thu Jan 11 11:29:31 2018
From: aaro.koskinen at iki.fi (Aaro Koskinen)
Date: Thu, 11 Jan 2018 21:29:31 +0200
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180110211325.GA1938@lenoch>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
 <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
 <20180110211325.GA1938@lenoch>
Message-ID: <20180111192931.vwnpvj2wtgrvkhbe@darkstar.musicnaut.iki.fi>

Hi,

On Wed, Jan 10, 2018 at 10:13:25PM +0100, Ladislav Michl wrote:
> On Wed, Jan 10, 2018 at 07:35:19PM +0200, Aaro Koskinen wrote:
> > On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
> > > On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> > > > On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > > > > Merge window is really close now and patches seems still to be untested on
> > > > > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > > > > ebay :-/
> > > > 
> > > > Today I tried to test them on Nokia N810, and I get:
> > > > 
> > > > [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > > > [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > > > [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> > > > [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > > > 
> > > > With plain v4.15-rc7+ it probes fine.
> > > 
> > > Thank you for testing. As stated in cover letter, you need also
> > > https://patchwork.kernel.org/patch/10043259/
> > > which can be also found in Roger's branch
> > > https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
> > > (see previous replies in this thread and also discussion about OneNAND
> > > DT node)
> > 
> > I applied it, and now get:
> > 
> > [    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > [    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > [    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
> > [    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> 
> As expected without reading discussion about OneNAND DT node :)
> 
> In short, this version expects "ti,omap2-onenand" compatible.

Right. I didn't realize by bootloader was passing the DTB from an old
kernel.

So after fixing my boot I got the patches working N800 and N810: I was
able to read and write on old JFFS2 file systems without any issues. So
you can add for the series:

Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>

> In earlier version of this patchset there was fixup present, so driver
> worked even without compatible. Later on (17 Oct 2017 11:46:51 +0300)
> Roger objected (https://www.spinics.net/lists/linux-omap/msg139576.html):
> "I don't want to fixup broken DTs like this as they will go silently without
> being fixed. Let's instead just error out after the dev_warn(). This will
> force us to fix all DT nodes."
> So fixup was removed. I know N900 support is under heavy development
> in mainline, but if n8x0 is considered finished and stable, we should
> reintroduce fixup. Thoughts?

N8x0 support is also "under development", and we are fine with updating
and always using latest in-tree DTs.

A.


From ladis at linux-mips.org  Thu Jan 11 11:38:56 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Thu, 11 Jan 2018 20:38:56 +0100
Subject: [PATCH v5 00/16] OMAP2+ OneNAND driver update
In-Reply-To: <20180111192931.vwnpvj2wtgrvkhbe@darkstar.musicnaut.iki.fi>
References: <20171115162306.2o2w2yrf7wucroxd@lenoch>
 <20171130111840.41c92d34@bbrezillon>
 <20171130160936.GO28152@atomide.com>
 <434bd733-0ba2-6e75-9de5-017eef905fd2@ti.com>
 <20180109130812.GA338@lenoch>
 <20180109210114.s66rpdg2jjdps5bc@darkstar.musicnaut.iki.fi>
 <20180110092058.GA25351@lenoch>
 <20180110173519.xyug4egltni4f3qi@darkstar.musicnaut.iki.fi>
 <20180110211325.GA1938@lenoch>
 <20180111192931.vwnpvj2wtgrvkhbe@darkstar.musicnaut.iki.fi>
Message-ID: <20180111193856.GA32512@lenoch>

On Thu, Jan 11, 2018 at 09:29:31PM +0200, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Jan 10, 2018 at 10:13:25PM +0100, Ladislav Michl wrote:
> > On Wed, Jan 10, 2018 at 07:35:19PM +0200, Aaro Koskinen wrote:
> > > On Wed, Jan 10, 2018 at 10:20:58AM +0100, Ladislav Michl wrote:
> > > > On Tue, Jan 09, 2018 at 11:01:14PM +0200, Aaro Koskinen wrote:
> > > > > On Tue, Jan 09, 2018 at 02:08:12PM +0100, Ladislav Michl wrote:
> > > > > > Merge window is really close now and patches seems still to be untested on
> > > > > > n8x0. So unless someone is going to test it soon, I'll pick used N800 on
> > > > > > ebay :-/
> > > > > 
> > > > > Today I tried to test them on Nokia N810, and I get:
> > > > > 
> > > > > [    0.174804] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > > > > [    0.174865] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > > > > [    0.177459] omap-gpmc 6800a000.gpmc: /ocp/gpmc at 6800a000/onenand at 0,0 has no 'bank-width' property
> > > > > [    0.177612] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > > > > 
> > > > > With plain v4.15-rc7+ it probes fine.
> > > > 
> > > > Thank you for testing. As stated in cover letter, you need also
> > > > https://patchwork.kernel.org/patch/10043259/
> > > > which can be also found in Roger's branch
> > > > https://github.com/rogerq/linux/commits/for-v4.16/gpmc-omap-immutable
> > > > (see previous replies in this thread and also discussion about OneNAND
> > > > DT node)
> > > 
> > > I applied it, and now get:
> > > 
> > > [    0.174987] omap-gpmc 6800a000.gpmc: GPMC revision 2.0
> > > [    0.175048] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > > [    0.177703] omap-gpmc 6800a000.gpmc: Incompatible OneNAND node: missing compatible
> > > [    0.177764] omap-gpmc 6800a000.gpmc: failed to probe DT child 'onenand': -22
> > 
> > As expected without reading discussion about OneNAND DT node :)
> > 
> > In short, this version expects "ti,omap2-onenand" compatible.
> 
> Right. I didn't realize by bootloader was passing the DTB from an old
> kernel.
> 
> So after fixing my boot I got the patches working N800 and N810: I was
> able to read and write on old JFFS2 file systems without any issues. So
> you can add for the series:
> 
> Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>

Thank you!

> > In earlier version of this patchset there was fixup present, so driver
> > worked even without compatible. Later on (17 Oct 2017 11:46:51 +0300)
> > Roger objected (https://www.spinics.net/lists/linux-omap/msg139576.html):
> > "I don't want to fixup broken DTs like this as they will go silently without
> > being fixed. Let's instead just error out after the dev_warn(). This will
> > force us to fix all DT nodes."
> > So fixup was removed. I know N900 support is under heavy development
> > in mainline, but if n8x0 is considered finished and stable, we should
> > reintroduce fixup. Thoughts?
> 
> N8x0 support is also "under development", and we are fine with updating
> and always using latest in-tree DTs.

That makes things simpler :) I'll post v6 based on -next with patches 13 and
14 squashed.

Thanks to everyone involved for cooperation,
	ladis


From boris.brezillon at free-electrons.com  Thu Jan 11 12:15:43 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 11 Jan 2018 21:15:43 +0100
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <CAOMZO5Aerkb2r0y2aC8sZJcEgpJzoNgR5_MU=2t_uq7jTzNo9g@mail.gmail.com>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
 <20180111164823.34b0b8fd@bbrezillon>
 <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>
 <20180111174012.67e2681a@bbrezillon>
 <CAOMZO5Aerkb2r0y2aC8sZJcEgpJzoNgR5_MU=2t_uq7jTzNo9g@mail.gmail.com>
Message-ID: <20180111211543.561ea46d@bbrezillon>

On Thu, 11 Jan 2018 14:58:39 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> On Thu, Jan 11, 2018 at 2:40 PM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> 
> > Nope, I wasn't sure whether reg was mandatory or not since it was not
> > used by the driver before your patch. This being said, that'd be good to
> > update the example you have in the bindings do to fully describe a
> > flash device.  
> 
> Ok, I can update fsl-quadspi.txt to include an example for describing
> the flash devices.
> 
> > Anyway, if all existing DTs have a reg defined, even those where only  
> 
> As far as I can see all DTs that use fsl-quadspi have a reg property
> in the SPI flash sub-nodes:
> 
> arch/arm/boot/dts/imx6ul-14x14-evk.dts
> arch/arm/boot/dts/imx6sx-sdb.dts
> arch/arm/boot/dts/ls1021a-moxa-uc-8410a.dts
> arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
> 
> > one flash device is described, then your patch might break mtdparts
> > users. And if this is not the case, and the reg property is really
> > mandatory, then that means those dts are not compliant with the DT
> > bindings and have to be patched :-). So, the solution of testing the
> > presence of a reg property to choose the naming scheme is probably not
> > appropriate.  
> 
> Any ideas on how we can properly solve this?

Nothing that I really like, sorry. One solution would be to use
dev_name(&pdev->dev) when only one flash device is declared and use
dev_name(&pdev->dev)-reg_val otherwise. Or you could leave the logic
unchanged and force users to specify a label property when they have
more than one device. The last solution would be to actually break
mtdparts users so that you can start using a sane naming scheme.


From miquel.raynal at free-electrons.com  Thu Jan 11 12:39:20 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Thu, 11 Jan 2018 21:39:20 +0100
Subject: [PATCH] mtd: mtd_oobtest: Handle bitflips during reads
Message-ID: <20180111203920.8136-1-miquel.raynal@free-electrons.com>

Reads from NAND devices usually trigger bitflips, this is an expected
behavior. While bitflips are under a given threshold, the MTD core
returns 0. However, when the number of corrected bitflips is above this
same threshold, -EUCLEAN is returned to inform the upper layer that this
block is slightly dying and soon the ECC engine will be overtaken so
actions should be taken to move the data out of it.

This particular condition should not be treated like an error and the
test should continue.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/tests/oobtest.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c
index 1cb3f7758fb6..766b2c385682 100644
--- a/drivers/mtd/tests/oobtest.c
+++ b/drivers/mtd/tests/oobtest.c
@@ -193,6 +193,9 @@ static int verify_eraseblock(int ebnum)
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd_read_oob(mtd, addr, &ops);
+		if (mtd_is_bitflip(err))
+			err = 0;
+
 		if (err || ops.oobretlen != use_len) {
 			pr_err("error: readoob failed at %#llx\n",
 			       (long long)addr);
@@ -227,6 +230,9 @@ static int verify_eraseblock(int ebnum)
 			ops.datbuf    = NULL;
 			ops.oobbuf    = readbuf;
 			err = mtd_read_oob(mtd, addr, &ops);
+			if (mtd_is_bitflip(err))
+				err = 0;
+
 			if (err || ops.oobretlen != mtd->oobavail) {
 				pr_err("error: readoob failed at %#llx\n",
 						(long long)addr);
@@ -286,6 +292,9 @@ static int verify_eraseblock_in_one_go(int ebnum)
 
 	/* read entire block's OOB at one go */
 	err = mtd_read_oob(mtd, addr, &ops);
+	if (mtd_is_bitflip(err))
+		err = 0;
+
 	if (err || ops.oobretlen != len) {
 		pr_err("error: readoob failed at %#llx\n",
 		       (long long)addr);
@@ -527,6 +536,9 @@ static int __init mtd_oobtest_init(void)
 	pr_info("attempting to start read past end of OOB\n");
 	pr_info("an error is expected...\n");
 	err = mtd_read_oob(mtd, addr0, &ops);
+	if (mtd_is_bitflip(err))
+		err = 0;
+
 	if (err) {
 		pr_info("error occurred as expected\n");
 		err = 0;
@@ -571,6 +583,9 @@ static int __init mtd_oobtest_init(void)
 		pr_info("attempting to read past end of device\n");
 		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
+		if (mtd_is_bitflip(err))
+			err = 0;
+
 		if (err) {
 			pr_info("error occurred as expected\n");
 			err = 0;
@@ -615,6 +630,9 @@ static int __init mtd_oobtest_init(void)
 		pr_info("attempting to read past end of device\n");
 		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
+		if (mtd_is_bitflip(err))
+			err = 0;
+
 		if (err) {
 			pr_info("error occurred as expected\n");
 			err = 0;
@@ -684,6 +702,9 @@ static int __init mtd_oobtest_init(void)
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd_read_oob(mtd, addr, &ops);
+		if (mtd_is_bitflip(err))
+			err = 0;
+
 		if (err)
 			goto out;
 		if (memcmpshow(addr, readbuf, writebuf,
-- 
2.11.0



From miquel.raynal at free-electrons.com  Thu Jan 11 12:39:58 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Thu, 11 Jan 2018 21:39:58 +0100
Subject: [PATCH] mtd: nand: Fix nand_do_read_oob() return value
Message-ID: <20180111203958.8211-1-miquel.raynal@free-electrons.com>

Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
negative error, and the MTD layer expected it.

However, the trend for the NAND layer is now to return an error or a
positive number of bitflips. Deciding which status to return to the user
belongs to the MTD layer.

Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
brought this logic to the mtd_read_oob() function while the status
coming from nand_do_read_oob() (called by the ->ecc.read_oob() hook) was
left unchanged.

Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/nand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 469220065b8b..88256b656072 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3876,7 +3876,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	return max_bitflips;
 }
 
 /**
-- 
2.11.0



From miquel.raynal at free-electrons.com  Thu Jan 11 13:20:20 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Thu, 11 Jan 2018 22:20:20 +0100
Subject: [PATCH] mtd: nand: Fix nand_do_read_oob() return value
In-Reply-To: <20180111203958.8211-1-miquel.raynal@free-electrons.com>
References: <20180111203958.8211-1-miquel.raynal@free-electrons.com>
Message-ID: <20180111222020.208d2359@xps13>

On Thu, 11 Jan 2018 21:39:58 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
> OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
> negative error, and the MTD layer expected it.
> 
> However, the trend for the NAND layer is now to return an error or a
> positive number of bitflips. Deciding which status to return to the
> user belongs to the MTD layer.
> 
> Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> brought this logic to the mtd_read_oob() function while the status
> coming from nand_do_read_oob() (called by the ->ecc.read_oob() hook)
> was left unchanged.
> 
> Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> Cc: stable at vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---

Oops, patch untested, will send a v2, sorry for the noise.

Thanks,
Miqu?l


From miquel.raynal at free-electrons.com  Thu Jan 11 13:42:02 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Thu, 11 Jan 2018 22:42:02 +0100
Subject: [PATCH v2] mtd: nand: Fix nand_do_read_oob() return value
Message-ID: <20180111214202.24531-1-miquel.raynal@free-electrons.com>

Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
negative error, and the MTD layer expected it.

However, the trend for the NAND layer is now to return an error or a
positive number of bitflips. Deciding which status to return to the user
belongs to the MTD layer.

Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
brought this logic to the mtd_read_oob() function while the return value
coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
left unchanged.

Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---

Changes since v1:
  - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit message
  - Fixed the compilation issue

 drivers/mtd/nand/nand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 469220065b8b..440d9f5d5b17 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3876,7 +3876,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	return ret;
 }
 
 /**
-- 
2.11.0



From robh at kernel.org  Thu Jan 11 14:23:59 2018
From: robh at kernel.org (Rob Herring)
Date: Thu, 11 Jan 2018 16:23:59 -0600
Subject: [PATCH v3 1/7] dt-bindings: mtd: document new nand-rb property
In-Reply-To: <20180109103637.23798-2-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180109103637.23798-2-miquel.raynal@free-electrons.com>
Message-ID: <20180111222359.aj2yyhduniw4egik@rob-hp-laptop>

On Tue, Jan 09, 2018 at 11:36:31AM +0100, Miquel Raynal wrote:
> There are already an atmel,rb and an allwinner,rb properties, let's not
> make other ones and instead use a generic term: nand-rb to define NAND
> chips Ready/Busy lines.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  Documentation/devicetree/bindings/mtd/nand.txt | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Rob Herring <robh at kernel.org>


From miquel.raynal at free-electrons.com  Thu Jan 11 14:24:17 2018
From: miquel.raynal at free-electrons.com (Miquel RAYNAL)
Date: Thu, 11 Jan 2018 23:24:17 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87efmwb8bj.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home>
Message-ID: <20180111232417.4aa86075@xps13>

Hi Robert,

On Thu, 11 Jan 2018 18:42:56 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> Hi Boris and Miquel,
> 
> > So, here is the plan: since the driver has been tested on various
> > mvebu platforms and is known to work fine on these platforms, I'd
> > like to queue the driver and the patch modifying mvebu defconfigs
> > (patches 1 to 4) for 4.16.
> That's all right.
> 
> > I'll leave other patches for 4.17, which means I'd like remaining
> > bugs to be fixed during the 4.16 release cycle so that we can
> > eventually get rid of the old driver. That's really important to me
> > that we don't keep both drivers around for too long, because my
> > previous experience showed that, when you have 2 drivers for the
> > same HW, people don't switch to the new one until they're forced to
> > do it.
> >
> > Robert, are you fine with this approach? What about the tests you
> > were doing? Did you make any progress? Did you find other issues?
> So far, with the latest branch from Miquel of tip commit 12b9e62c851c
> ("ARM64: dts: marvell: use reworked NAND controller driver on Armada
> 8K"), the bad blocks issue is still there, ie :
>  - the old pxa3xx driver doesn't see any bad block and mounts the
> ext2/ubifs correctly
>  - barebox doesn't see any bad block
>  - marvell_nand sees all (or most all) blocks as bad with
> "flash_bbt=0" in platform data, which is very surprising
> 
> I'm really surprised that in your tests on the cm_x300, in a
> platform_data setup (ie. not device-tree setup), you're not seeing
> these errors ...

I have no problems with the cm_x300 board (using platform data) but
there is one big difference: the bootloader. You are using Barebox
while I am using U-Boot.

Please pull this branch which is for testing purpose [1].

There are two "HACK"s:
1/ Dump the timing registers: this is to see how Barebox does
initialize these registers. I will put these values back into my setup
and see how the board reacts.
2/ Dump the OOB area while reading. This is to see why the driver
declares all blocks as bad.

Can you please run this branch first?

Then, can you please:
- boot the old driver
- dump both NDTR[0|1] registers that should be well initialized
- boot the new driver with the values previously retrieved (you can
  assign these values where exactly HACK 1/ adds the printk's).


Thank you,
Miqu?l

[1]
https://github.com/miquelraynal/linux/commits/marvell/nand-next/nfc-pxa-bug



From robh at kernel.org  Thu Jan 11 14:25:50 2018
From: robh at kernel.org (Rob Herring)
Date: Thu, 11 Jan 2018 16:25:50 -0600
Subject: [PATCH v3 2/7] dt-bindings: mtd: add Marvell NAND controller
 documentation
In-Reply-To: <20180109103637.23798-3-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180109103637.23798-3-miquel.raynal@free-electrons.com>
Message-ID: <20180111222550.nxus25nqoyvhq22r@rob-hp-laptop>

On Tue, Jan 09, 2018 at 11:36:32AM +0100, Miquel Raynal wrote:
> Document the legacy and the new bindings for Marvell NAND controller.
> 
> The pxa3xx_nand.c driver does only support legacy bindings, which are
> incomplete and inaccurate. A rework of this controller (called
> marvell_nand.c) does support both.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  .../devicetree/bindings/mtd/marvell-nand.txt       | 123 +++++++++++++++++++++
>  1 file changed, 123 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt

Reviewed-by: Rob Herring <robh at kernel.org>



From w at 1wt.eu  Thu Jan 11 14:28:33 2018
From: w at 1wt.eu (Willy Tarreau)
Date: Thu, 11 Jan 2018 23:28:33 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180111222833.GA15584@1wt.eu>

Hi Miquel,

On Tue, Jan 09, 2018 at 11:36:30AM +0100, Miquel Raynal wrote:
> These changes have been tested on:
>    - PXA3xx platform with a CM-X300 board (2kiB page NAND, 1b/512B
>      strength, Hamming ECC engine) [32 bits]
>    - Armada 385 DB AP (4kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
>    - Armada 398 DB (4kiB page NAND, 8b/512B, BCH ECC engine using a layout
>      with a last chunk different than the others) [32 bits]
>    - Armada 7040 DB and Armada 8040 DB (4kiB page NAND, 4b/512B, BCH ECC
>      engine) [64 bits]
>    - Triax dvb-tc board (2kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]

If you're interested, I have a mirabox with an armada 370 which uses the
same driver. I've not powered it up for a while but if that can be useful
I can try to find some time for this.

Just let me know
Willy


From stefan at agner.ch  Thu Jan 11 15:50:37 2018
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 12 Jan 2018 00:50:37 +0100
Subject: [RFC PATCH 2/2] mtd: nand: always request data transfer for parameter
 page
In-Reply-To: <20180111235037.10912-1-stefan@agner.ch>
References: <20180111235037.10912-1-stefan@agner.ch>
Message-ID: <20180111235037.10912-2-stefan@agner.ch>

To make sure the controller actually transfers data add a
DATA_IN op even if len is 0.

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 drivers/mtd/nand/nand_base.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 96c97588e1ba..26bbf54e125b 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1510,10 +1510,6 @@ static int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
 		};
 		struct nand_operation op = NAND_OPERATION(instrs);
 
-		/* Drop the DATA_IN instruction if len is set to 0. */
-		if (!len)
-			op.ninstrs--;
-
 		return nand_exec_op(chip, &op);
 	}
 
-- 
2.15.1



From stefan at agner.ch  Thu Jan 11 15:50:36 2018
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 12 Jan 2018 00:50:36 +0100
Subject: [RFC PATCH 1/2] mtd: nand: vf610_nfc: make use of ->exec_op()
Message-ID: <20180111235037.10912-1-stefan@agner.ch>

This reworks the driver to make use of ->exec_op() callback. The
command sequencer of the VF610 NFC aligns well with the new ops
interface.

Currently we handle reset and read id pattern separately. The
read id pattern uses registers for the returned data, using a
dedicated function helps to special case the data in op.

The parameter page handling is rather ad-hoc currently: The
stack calls exec_op twice, once to read the paramter page and
a second time to tranfer data. The code/controller can not
handle this steps separately, hence just transfer data already
in the first call and just memcpy from the buffer in the second
call. This needs a small change in the nand_base.c file.

The current state seems to pass MTD tests on a Colibri VF61.

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
Hi Boris, Hi Miquel,

Thanks for your work on the new NAND interface. The VF610 NFC
definitly matches better the ->exec_op() interface.

This is still in early stage but seems to boot a Linux as rootfs
successfully. Before working on further simplification I wanted
to get some feedback on the general idea.

If needed, the data sheet of the controller can be optained
publicly (Vybrid Reference Manual, Chapter 10.3).

Some questions from my side:
- Parameter page: Why is exec_op called twice currently? This
  seems to be problematic for this controller. Are there plans
  to integrate the two calls in a single op sequence?
- Row/Column addresses: The controller seems to separate those
  two, hence the driver "guesses" which address bytes need to
  go where.. Maybe it would be better to separate that on ops
  level?
- Separation is often needed by command. One can make an educated
  guess what kind of command is going to be passed by filtering
  the appropriate ops. Maybe it would be good if the ops parser
  can filter by command?

--
Stefan

miquel.raynal at free-electrons.com

 drivers/mtd/nand/vf610_nfc.c | 543 +++++++++++++++++++++++++++----------------
 1 file changed, 349 insertions(+), 194 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 80d31a58e558..db69afb727ca 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -22,7 +22,6 @@
  * - HW ECC: Only 2K page with 64+ OOB.
  * - HW ECC: Only 24 and 32-bit error correction implemented.
  */
-
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/clk.h>
@@ -74,6 +73,20 @@
 #define RESET_CMD_CODE			0x4040
 #define STATUS_READ_CMD_CODE		0x4068
 
+#define COMMAND_CMD_BYTE1		BIT(14)
+#define COMMAND_CAR_BYTE1		BIT(13)
+#define COMMAND_CAR_BYTE2		BIT(12)
+#define COMMAND_RAR_BYTE1		BIT(11)
+#define COMMAND_RAR_BYTE2		BIT(10)
+#define COMMAND_RAR_BYTE3		BIT(9)
+#define COMMAND_WRITE_DATA		BIT(8)
+#define COMMAND_CMD_BYTE2		BIT(7)
+#define COMMAND_RB_HANDSHAKE		BIT(6)
+#define COMMAND_READ_DATA		BIT(5)
+#define COMMAND_CMD_BYTE3		BIT(4)
+#define COMMAND_READ_STATUS		BIT(3)
+#define COMMAND_READ_ID			BIT(2)
+
 /* NFC ECC mode define */
 #define ECC_BYPASS			0
 #define ECC_45_BYTE			6
@@ -97,10 +110,21 @@
 /* NFC_COL_ADDR Field */
 #define COL_ADDR_MASK				0x0000FFFF
 #define COL_ADDR_SHIFT				0
+#define COL_ADDR_BYTE1_SHIFT			0
+#define COL_ADDR_BYTE2_SHIFT			8
+#define COL_ADDR_BYTE1(x)			((x & 0xFF) << COL_ADDR_BYTE1_SHIFT)
+#define COL_ADDR_BYTE2(x)			((x & 0XFF) << COL_ADDR_BYTE2_SHIFT)
+
 
 /* NFC_ROW_ADDR Field */
 #define ROW_ADDR_MASK				0x00FFFFFF
 #define ROW_ADDR_SHIFT				0
+#define ROW_ADDR_BYTE1_SHIFT			0
+#define ROW_ADDR_BYTE2_SHIFT			8
+#define ROW_ADDR_BYTE3_SHIFT			16
+#define ROW_ADDR_BYTE1(x)			((x & 0xFF) << ROW_ADDR_BYTE1_SHIFT)
+#define ROW_ADDR_BYTE2(x)			((x & 0XFF) << ROW_ADDR_BYTE2_SHIFT)
+#define ROW_ADDR_BYTE3(x)			((x & 0XFF) << ROW_ADDR_BYTE3_SHIFT)
 #define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
 #define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
 #define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
@@ -142,13 +166,6 @@
 #define ECC_STATUS_MASK		0x80
 #define ECC_STATUS_ERR_COUNT	0x3F
 
-enum vf610_nfc_alt_buf {
-	ALT_BUF_DATA = 0,
-	ALT_BUF_ID = 1,
-	ALT_BUF_STAT = 2,
-	ALT_BUF_ONFI = 3,
-};
-
 enum vf610_nfc_variant {
 	NFC_VFC610 = 1,
 };
@@ -158,10 +175,7 @@ struct vf610_nfc {
 	struct device *dev;
 	void __iomem *regs;
 	struct completion cmd_done;
-	uint buf_offset;
-	int write_sz;
 	/* Status and ID are in alternate locations. */
-	enum vf610_nfc_alt_buf alt_buf;
 	enum vf610_nfc_variant variant;
 	struct clk *clk;
 	bool use_hw_ecc;
@@ -173,6 +187,11 @@ static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd)
 	return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
 }
 
+static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip)
+{
+	return container_of(chip, struct vf610_nfc, chip);
+}
+
 static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
 {
 	return readl(nfc->regs + reg);
@@ -263,31 +282,22 @@ static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
 	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
 }
 
-static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
-				   u32 cmd_code)
+static void vf610_nfc_send_code(struct vf610_nfc *nfc, u32 cmd_code)
 {
-	u32 tmp;
-
-	vf610_nfc_clear_status(nfc);
-
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
-	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
-	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
-	tmp |= cmd_code << CMD_CODE_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_CODE_MASK, CMD_CODE_SHIFT,
+			    cmd_code);
 }
 
-static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
-				    u32 cmd_byte2, u32 cmd_code)
+static void vf610_nfc_set_cmd1(struct vf610_nfc *nfc, u32 cmd_byte1)
 {
-	u32 tmp;
-
-	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_BYTE1_MASK,
+			    CMD_BYTE1_SHIFT, cmd_byte1);
+}
 
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
-	tmp &= ~CMD_BYTE2_MASK;
-	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
+static void vf610_nfc_set_cmd2(struct vf610_nfc *nfc, u32 cmd_byte2)
+{
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD1, CMD_BYTE2_MASK,
+			    CMD_BYTE2_SHIFT, cmd_byte2);
 }
 
 static irqreturn_t vf610_nfc_irq(int irq, void *data)
@@ -301,19 +311,6 @@ static irqreturn_t vf610_nfc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
-{
-	if (column != -1) {
-		if (nfc->chip.options & NAND_BUSWIDTH_16)
-			column = column / 2;
-		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
-				    COL_ADDR_SHIFT, column);
-	}
-	if (page != -1)
-		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
-				    ROW_ADDR_SHIFT, page);
-}
-
 static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
 {
 	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
@@ -326,169 +323,325 @@ static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
 	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
 }
 
-static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
-			      int column, int page)
+static inline const struct nand_op_instr *vf610_get_next_instr(
+	const struct nand_subop *subop, int *op_id)
 {
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
+	if (*op_id + 1 >= subop->ninstrs)
+		return NULL;
 
-	nfc->buf_offset = max(column, 0);
-	nfc->alt_buf = ALT_BUF_DATA;
+	return &subop->instrs[++(*op_id)];
+}
 
-	switch (command) {
-	case NAND_CMD_SEQIN:
-		/* Use valid column/page from preread... */
-		vf610_nfc_addr_cycle(nfc, column, page);
-		nfc->buf_offset = 0;
+static int vf610_nfc_reset(struct nand_chip *chip,
+				const struct nand_subop *subop)
+{
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	const struct nand_op_instr *instr;
+	int op_id = -1;
 
-		/*
-		 * SEQIN => data => PAGEPROG sequence is done by the controller
-		 * hence we do not need to issue the command here...
-		 */
-		return;
-	case NAND_CMD_PAGEPROG:
-		trfr_sz += nfc->write_sz;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
-					command, PROGRAM_PAGE_CMD_CODE);
-		if (nfc->use_hw_ecc)
-			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		else
-			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_RESET:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
-		break;
-
-	case NAND_CMD_READOOB:
-		trfr_sz += mtd->oobsize;
-		column = mtd->writesize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_READ0:
-		trfr_sz += mtd->writesize + mtd->oobsize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		break;
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr || instr->type != NAND_OP_CMD_INSTR)
+		return -EINVAL;
 
-	case NAND_CMD_PARAM:
-		nfc->alt_buf = ALT_BUF_ONFI;
-		trfr_sz = 3 * sizeof(struct nand_onfi_params);
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_ERASE1:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_commands(nfc, command,
-					NAND_CMD_ERASE2, ERASE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		break;
-
-	case NAND_CMD_READID:
-		nfc->alt_buf = ALT_BUF_ID;
-		nfc->buf_offset = 0;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		break;
-
-	case NAND_CMD_STATUS:
-		nfc->alt_buf = ALT_BUF_STAT;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
-		break;
-	default:
-		return;
-	}
+	/* Handle only reset */
+	if (instr->ctx.cmd.opcode != NAND_CMD_RESET)
+		return -EINVAL;
 
+	dev_dbg(nfc->dev, "OP_CMD: code 0x%02x\n", instr->ctx.cmd.opcode);
+	vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
+	vf610_nfc_transfer_size(nfc, 0);
+	vf610_nfc_send_code(nfc, RESET_CMD_CODE);
 	vf610_nfc_done(nfc);
 
-	nfc->use_hw_ecc = false;
-	nfc->write_sz = 0;
+	return 0;
 }
 
-static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+static void vf610_nfc_copyid(struct nand_chip *chip,
+			     const struct nand_subop *subop, int op_id)
 {
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	const struct nand_op_instr *instr = &subop->instrs[op_id];
+	unsigned int len = nand_subop_get_data_len(subop, op_id);
+	unsigned int offset = nand_subop_get_data_start_off(subop, op_id);
+	u8 *in = instr->ctx.data.buf.in + offset;
+	int i;
 
-	/* Alternate buffers are only supported through read_byte */
-	WARN_ON(nfc->alt_buf);
+	dev_dbg(nfc->dev, "copyid: len %d, offset %d\n", len, offset);
+	for (i = 0; i < len; i++) {
+		*in = vf610_nfc_get_id(nfc, i);
+		in++;
+	}
+}
+
+static int vf610_nfc_readid(struct nand_chip *chip,
+				const struct nand_subop *subop)
+{
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	const struct nand_op_instr *instr;
+	int op_id = -1, row;
+
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr || instr->type != NAND_OP_CMD_INSTR)
+		return -EINVAL;
+
+	/* Handle only read id */
+	if (instr->ctx.cmd.opcode != NAND_CMD_READID)
+		return -EINVAL;
 
-	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
+	dev_dbg(nfc->dev, "OP_CMD: code 0x%02x\n", instr->ctx.cmd.opcode);
+	vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
+	vf610_nfc_send_code(nfc, READ_ID_CMD_CODE);
+	vf610_nfc_transfer_size(nfc, 0);
 
-	nfc->buf_offset += len;
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr || instr->type != NAND_OP_ADDR_INSTR)
+		return -EINVAL;
+
+	if (instr->ctx.addr.naddrs > 1)
+		return -EINVAL;
+
+	row = ROW_ADDR_BYTE1(instr->ctx.addr.addrs[0]);
+	vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+		    ROW_ADDR_SHIFT, row);
+
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr && instr->type != NAND_OP_DATA_IN_INSTR)
+		return -EINVAL;
+
+	vf610_nfc_done(nfc);
+	vf610_nfc_copyid(chip, subop, op_id);
+
+	return 0;
 }
 
-static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
-				int len)
+static int vf610_nfc_read_status(struct nand_chip *chip,
+				 const struct nand_subop *subop)
 {
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
-	uint l;
+	const struct nand_op_instr *instr;
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	int op_id = 0;
+	u8 *in;
+
+	instr = &subop->instrs[op_id];
+	if (instr->type != NAND_OP_CMD_INSTR)
+		return -EINVAL;
+
+	vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
+
+	instr = &subop->instrs[++op_id];
+	if (instr->type != NAND_OP_DATA_IN_INSTR)
+		return -EINVAL;
 
-	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
-	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
+	dev_dbg(nfc->dev, "vf610_nfc_read_status\n");
+	vf610_nfc_send_code(nfc, STATUS_READ_CMD_CODE);
+	vf610_nfc_done(nfc);
+
+	in = instr->ctx.data.buf.in;
+	in[0] = vf610_nfc_get_status(nfc);
 
-	nfc->write_sz += l;
-	nfc->buf_offset += l;
+	return 0;
 }
 
-static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
+static int vf610_nfc_cmd(struct nand_chip *chip,
+				const struct nand_subop *subop)
 {
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	u8 tmp;
-	uint c = nfc->buf_offset;
-
-	switch (nfc->alt_buf) {
-	case ALT_BUF_ID:
-		tmp = vf610_nfc_get_id(nfc, c);
-		break;
-	case ALT_BUF_STAT:
-		tmp = vf610_nfc_get_status(nfc);
-		break;
-#ifdef __LITTLE_ENDIAN
-	case ALT_BUF_ONFI:
-		/* Reverse byte since the controller uses big endianness */
-		c = nfc->buf_offset ^ 0x3;
-		/* fall-through */
-#endif
-	default:
-		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
-		break;
+	const struct nand_op_instr *instr;
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int op_id = -1, addr = 0, trfr_sz = 0;
+	u32 col = 0, row, code;
+
+	/* Some ops are optional, but they need to be in order */
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr || instr->type != NAND_OP_CMD_INSTR)
+		return -EINVAL;
+
+	if (instr->ctx.cmd.opcode == NAND_CMD_PARAM)
+		trfr_sz = 3 * sizeof(struct nand_onfi_params);
+
+	dev_dbg(nfc->dev, "OP_CMD: code 0x%02x\n", instr->ctx.cmd.opcode);
+	vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
+	code = COMMAND_CMD_BYTE1;
+
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr || instr->type != NAND_OP_ADDR_INSTR)
+		return -EINVAL;
+
+	if (instr->ctx.addr.naddrs > 1) {
+		col = COL_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
+		code |= COMMAND_CAR_BYTE1;
+
+		if (mtd->writesize > 512) {
+			col |= COL_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
+			code |= COMMAND_CAR_BYTE2;
+		}
+	}
+
+	row = ROW_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
+	code |= COMMAND_RAR_BYTE1;
+	if (addr < instr->ctx.addr.naddrs) {
+		row |= ROW_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
+		code |= COMMAND_RAR_BYTE2;
+	}
+	if (addr < instr->ctx.addr.naddrs) {
+		row |= ROW_ADDR_BYTE3(instr->ctx.addr.addrs[addr++]);
+		code |= COMMAND_RAR_BYTE3;
+	}
+
+	dev_dbg(nfc->dev, "OP_ADDR: col %d, row %d\n", col, row);
+	vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
+		    COL_ADDR_SHIFT, col);
+
+	vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+		    ROW_ADDR_SHIFT, row);
+
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (instr && instr->type == NAND_OP_DATA_OUT_INSTR) {
+		int len = nand_subop_get_data_len(subop, op_id);
+		int offset = nand_subop_get_data_start_off(subop, op_id);
+
+		dev_dbg(nfc->dev, "OP_DATA_OUT: len %d, offset %d\n", len, offset);
+
+		vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + offset,
+				 instr->ctx.data.buf.in + offset,
+				 len);
+		code |= COMMAND_WRITE_DATA;
+		trfr_sz += len;
+
+		instr = vf610_get_next_instr(subop, &op_id);
 	}
-	nfc->buf_offset++;
-	return tmp;
+
+	if (instr && instr->type == NAND_OP_CMD_INSTR) {
+		vf610_nfc_set_cmd2(nfc, instr->ctx.cmd.opcode);
+		code |= COMMAND_CMD_BYTE2;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_WAITRDY_INSTR) {
+		//dev_dbg(nfc->dev, "WAITRDY [max %d ms]\n",
+		//		  instr->ctx.waitrdy.timeout_ms);
+		code |= COMMAND_RB_HANDSHAKE;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		int len = nand_subop_get_data_len(subop, op_id);
+		code |= COMMAND_READ_DATA;
+		trfr_sz += len;
+	}
+
+	if (nfc->use_hw_ecc) {
+		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+
+		/* Always transfer complete page with OOB when using HW ECC */
+		trfr_sz = mtd->writesize + mtd->oobsize;
+	} else {
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+	}
+	vf610_nfc_transfer_size(nfc, trfr_sz);
+	vf610_nfc_send_code(nfc, code);
+
+	dev_dbg(nfc->dev, "Start: code: 0x%04x, hw ecc: %d, trfr_sz %d\n",
+		code, nfc->use_hw_ecc, trfr_sz);
+	vf610_nfc_done(nfc);
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		int len = nand_subop_get_data_len(subop, op_id);
+		int offset = nand_subop_get_data_start_off(subop, op_id);
+
+		dev_dbg(nfc->dev, "OP_DATA_IN: len %d, offset %d\n", len, offset);
+
+		vf610_nfc_memcpy(instr->ctx.data.buf.in + offset,
+				 nfc->regs + NFC_MAIN_AREA(0) + offset,
+				 len);
+	}
+
+	return 0;
 }
 
-static u16 vf610_nfc_read_word(struct mtd_info *mtd)
+/* This seems to be called for parameter page only currenlty */
+static int vf610_nfc_read_data(struct nand_chip *chip,
+				const struct nand_subop *subop)
 {
-	u16 tmp;
+	const struct nand_op_instr *instr = &subop->instrs[0];
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	int len, offset;
+
+	if (instr->type != NAND_OP_DATA_IN_INSTR)
+		return -EINVAL;
+
+	len = nand_subop_get_data_len(subop, 0);
+	offset = nand_subop_get_data_start_off(subop, 0);
+
+	dev_dbg(nfc->dev, "R OP_DATA_IN: len %d, offset %d\n", len, offset);
+
+	/*
+	 * HACK: force_8bit indicates we read the parameter page. The
+	 * controllers seems to reverse byte order on little endian
+	 * machines, which is critical when reading parameter page.
+	 */
+	if (instr->ctx.data.force_8bit && IS_ENABLED(__LITTLE_ENDIAN)) {
+		u8 *buf = instr->ctx.data.buf.in;
+
+		while (len--) {
+			int c = offset ^ 0x3;
+
+			*buf = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+			buf++; offset++;
+		}
+	} else {
+		vf610_nfc_memcpy(instr->ctx.data.buf.in + offset,
+				 nfc->regs + NFC_MAIN_AREA(0) + offset,
+				 len);
+	}
 
-	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
-	return tmp;
+	return 0;
 }
 
-/* If not provided, upper layers apply a fixed delay. */
-static int vf610_nfc_dev_ready(struct mtd_info *mtd)
-{
-	/* NFC handles R/B internally; always ready.  */
-	return 1;
+static const struct nand_op_parser vf610_nfc_op_parser = NAND_OP_PARSER(
+	NAND_OP_PARSER_PATTERN(
+		vf610_nfc_reset,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+	NAND_OP_PARSER_PATTERN(
+		vf610_nfc_readid,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, 1),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 8)),
+	NAND_OP_PARSER_PATTERN(
+		vf610_nfc_read_status,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 1)),
+	NAND_OP_PARSER_PATTERN(
+		vf610_nfc_cmd,
+		NAND_OP_PARSER_PAT_CMD_ELEM(false),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(false, 5),
+		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, PAGE_2K + OOB_MAX),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, PAGE_2K + OOB_MAX)),
+	NAND_OP_PARSER_PATTERN(
+		vf610_nfc_read_data,
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, PAGE_2K + OOB_MAX)),
+	);
+
+static int vf610_nfc_exec_op(struct nand_chip *chip,
+			     const struct nand_operation *op,
+			     bool check_only)
+{
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+
+	/* TODO: Probably not needed, has been called before setting cmd */
+	vf610_nfc_clear_status(nfc);
+
+	dev_dbg(nfc->dev, "exec_op, opcode 0x%02x\n", op->instrs[0].ctx.cmd.opcode);
+
+	return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op, check_only);
 }
 
+
 /*
  * This function supports Vybrid only (MPC5125 would have full RB and four CS)
  */
@@ -542,8 +695,7 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
 		return ecc_count;
 
 	/* Read OOB without ECC unit enabled */
-	vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
-	vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
+	nand_read_page_op(&nfc->chip, page, mtd->writesize, oob, mtd->oobsize);
 
 	/*
 	 * On an erased page, bit count (including OOB) should be zero or
@@ -557,12 +709,17 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
 static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int oob_required, int page)
 {
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 	int eccsize = chip->ecc.size;
 	int stat;
 
+	nfc->use_hw_ecc = true;
 	nand_read_page_op(chip, page, 0, buf, eccsize);
 	if (oob_required)
-		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+		vf610_nfc_memcpy(chip->oob_poi,
+				 nfc->regs + NFC_MAIN_AREA(0) + mtd->writesize,
+				 mtd->oobsize);
+	nfc->use_hw_ecc = false;
 
 	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
 
@@ -579,16 +736,20 @@ static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required, int page)
 {
 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
 
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	if (oob_required)
-		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	/* Always write whole page including OOB due to HW ECC */
 	nfc->use_hw_ecc = true;
-	nfc->write_sz = mtd->writesize + mtd->oobsize;
+	ret = nand_prog_page_op(chip, page, 0, buf, mtd->writesize);
+	nfc->use_hw_ecc = false;
 
-	return nand_prog_page_end_op(chip);
+	return ret;
+}
+
+static int vf610_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf, int oob_required, int page)
+{
+	return nand_prog_page_op(chip, page, 0, buf,
+			mtd->writesize + oob_required ? mtd->oobsize : 0);
 }
 
 static const struct of_device_id vf610_nfc_dt_ids[] = {
@@ -695,15 +856,8 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	chip->dev_ready = vf610_nfc_dev_ready;
-	chip->cmdfunc = vf610_nfc_command;
-	chip->read_byte = vf610_nfc_read_byte;
-	chip->read_word = vf610_nfc_read_word;
-	chip->read_buf = vf610_nfc_read_buf;
-	chip->write_buf = vf610_nfc_write_buf;
+	chip->exec_op = vf610_nfc_exec_op;
 	chip->select_chip = vf610_nfc_select_chip;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
 
 	chip->options |= NAND_NO_SUBPAGE_WRITE;
 
@@ -770,6 +924,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 
 		chip->ecc.read_page = vf610_nfc_read_page;
 		chip->ecc.write_page = vf610_nfc_write_page;
+		chip->ecc.write_page_raw = vf610_nfc_write_page_raw;
 
 		chip->ecc.size = PAGE_2K;
 	}
-- 
2.15.1



From gudjon at gudjon.org  Thu Jan 11 16:29:55 2018
From: gudjon at gudjon.org (Gudjon I. Gudjonsson)
Date: Fri, 12 Jan 2018 01:29:55 +0100
Subject: ECC configuration of NAND from Linux  (MEMSETOOBSEL)
Message-ID: <2132429.fBNFCxDbQz@fessender>

Hi list

I am trying to upgrade a few embedded Linux systems remotely 
and increasing the number of ECC bits at the same time.

I read your FAQ and found the reference to ioctl (MEMSETOOBSEL) [1]
but it seems to be removed from the kernel.
/*
 * Note, the following ioctl existed in the past and was removed:
 * #define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
 * Try to avoid adding a new ioctl with the same ioctl number.
 */
I assume this is an error in the documentation but I wonder if you
know any solution to my problem?

Regards
Gudjon

[1] http://www.linux-mtd.infradead.org/faq/nand.html


From yogeshnarayan.gaur at nxp.com  Thu Jan 11 20:44:48 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Narayan Gaur)
Date: Fri, 12 Jan 2018 04:44:48 +0000
Subject: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic
 LUT entry
In-Reply-To: <80885d95-a6d4-b3a6-4249-f87379e6dc45@exceet.de>
References: <1515493602-19626-2-git-send-email-yogeshnarayan.gaur@nxp.com>
 <80885d95-a6d4-b3a6-4249-f87379e6dc45@exceet.de>
Message-ID: <DB6PR0402MB2838BA43DBDBD8AF3AEDA04D99170@DB6PR0402MB2838.eurprd04.prod.outlook.com>

Hello Frieder,

> -----Original Message-----
> From: Frieder Schrempf [mailto:frieder.schrempf at exceet.de]
> Sent: Tuesday, January 09, 2018 9:56 PM
> To: Yogesh Narayan Gaur <yogeshnarayan.gaur at nxp.com>
> Cc: linux-mtd at lists.infradead.org; Boris Brezillon <boris.brezillon at free-
> electrons.com>; cyrille.pitchen at wedev4u.fr; computersforpeace at gmail.com;
> Han Xu <han.xu at nxp.com>; festevam at gmail.com; Prabhakar Kushwaha
> <prabhakar.kushwaha at nxp.com>; Suresh Gupta <suresh.gupta at nxp.com>
> Subject: Re: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
> entry
> 
> Hello Yogesh,
> 
> > Add support to create dynamic LUT entry.
> >
> > Current approach of creating LUT entries for various cmds like read,
> > write, erase, readid, readsr, we, wd etc is that when QSPI controller
> > gets initialized at that time static LUT entries for these cmds get created.
> >
> > Patch add support to create the LUT at run time based on the operation
> > being performed.
> >
> > Added API fsl_qspi_prepare_lut(), this API would going to be called
> > from fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write,
> > fsl_qspi_read and fsl_qspi_erase APIs.
> > This API would fetch required info like opcode, protocol info, dummy
> > info for creating LUT from instance of 'struct spi_nor' and then
> > prepare LUT entry for the required command.
> 
> I'm just about to get started working on a similar topic, so I have some general
> (maybe stupid) questions concerning the dynamic LUT implementation:
> 
> Why do you actually need to be able to switch between different kind of
> commands for READ/WRITE/ERASE at time of execution?
Actually we want to handle different NOR flash devices on different chip select. 
QSPI controller has 4 chip select and one can use different flashes on all different chip select (that might not be the use case for today). We analyzed that the flash have different parameters for the same command and this is true for NAND devices.
Also reg_protocol information, required for read register, read any register commands, read SFDP register, not available at the time of nor scan.
This change was done after understanding the requirement for NAND and Hybrid flash also.
NXP is going to support hybrid flash which has NOR and NAND at one chip select. So, to handle these type of flashes dynamic LUT is the best approach, condition NAND framework also provide required information (datalines, dummy bytes, addrlen)as provided by NOR framework as of now.
To handle all chip select and hybrid complexities, this dynamic LUT need to be required as we can have maximum 16 static LUT entries.

> 
> Wouldn't it be better to init the LUT statically, after the chip was detected and at
> that time decide which READ/WRITE/ERASE command is best for the connected
> chip?
As explained above if we have different flashes on different chip select (even for 2 flash we can maximum provide 8 LUT entries for different flashes). 
It is tough to handle such scenario and lead to code complexity.

> 
> Have you tested what kind of impact the dynamic loading of a command
> sequence to the LUT registers before each operation has on the performance?
We are programming 4 LUT register for every command sent from MTD layer. Theoretically it is max 16bytes per command.
It looks to be trivial overhead. We are doing analysis of performance impact of dynamic LUT creation.

> 
> In the context of the upcoming SPI NAND framework, I am working on NAND
> support for the FSL QSPI controller.
Hope you will take care of having support of NAND on chip select 1 and 2.

> I have a working driver at [1] derived from the NOR driver.
> As discussed with Boris ([2]) the plan is to add NAND support to the NOR driver
> until a common spi-flash layer is available to hold code, that is used by both
> types of SPI flash, NOR and NAND.
> 
> To achieve this, some kind of dynamic LUT allocation is needed, too.
> But at first glance it seems me, that it would be better to actually use the LUT
> entries as much as possible and create the entries at time of init depending on
> flash type (NOR/NAND) and flash capabilities (QUAD/DUAL/QIO
> READ/WRITE...).
> 
> In the exotic case of needing to switch between different command sets (for
> hybrid NOR/NAND devices, see [3]) one could reinit the LUT for the current
> target upon selecting it.
> 
> Or maybe it is even better to create a mechanism that fills the LUT with entries
> when they are first needed and be able to reuse them until the space in the LUT
> runs out and entries need to be overriden.
> 
> What do you think?
Right, we also though of this approach but we think this would going to increase the code complexity so the simple and best possible approach we use is to create run-time LUT for every command when function ptr (read_reg, write_reg, read, write and erase) gets invoked.

Thanks
Yogesh Gaur
> 
> As I'm quite new to this, maybe someone can point to other implementations
> with similar approaches for reference, if there are any.
> 
> Thanks and regards,
> 
> Frieder
> 
> [1]:
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> com%2Ffschrempf%2Flinux-0day%2Fblob%2Fspi-nand-
> exceet%2Fdrivers%2Fmtd%2Fnand%2Fspi%2Fcontrollers%2Ffsl-quadspi-
> controller.c&data=02%7C01%7Cyogeshnarayan.gaur%40nxp.com%7C0a92ac7c
> f9194daaa1e408d5577dac6f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C636511119642760392&sdata=97LBSctrv6set73W%2FMio5H8Mxa8PUOn
> af1qnbJibycs%3D&reserved=0
> [2]:
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.infr
> adead.org%2Fpipermail%2Flinux-mtd%2F2018-
> January%2F078592.html&data=02%7C01%7Cyogeshnarayan.gaur%40nxp.com%
> 7C0a92ac7cf9194daaa1e408d5577dac6f%7C686ea1d3bc2b4c6fa92cd99c5c301
> 635%7C0%7C0%7C636511119642760392&sdata=ur%2F%2BfRg0TIfuthyA%2BliL
> qOc4T1mCU2exZd62YQCOk1Y%3D&reserved=0
> [3]:
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.infr
> adead.org%2Fpipermail%2Flinux-mtd%2F2018-
> January%2F078488.html&data=02%7C01%7Cyogeshnarayan.gaur%40nxp.com%
> 7C0a92ac7cf9194daaa1e408d5577dac6f%7C686ea1d3bc2b4c6fa92cd99c5c301
> 635%7C0%7C0%7C636511119642760392&sdata=8ItjA5b%2FRnvVmBl0YrUoHet
> 4chNzVJq5b0s6vsxY%2BD4%3D&reserved=0

From tytso at mit.edu  Thu Jan 11 20:33:38 2018
From: tytso at mit.edu (Theodore Ts'o)
Date: Thu, 11 Jan 2018 23:33:38 -0500
Subject: [PATCH v2 00/11] fscrypt: symlink helpers and fscrypt.h cleanup
In-Reply-To: <20180105184502.48473-1-ebiggers3@gmail.com>
References: <20180105184502.48473-1-ebiggers3@gmail.com>
Message-ID: <20180112043338.GA8249@thunk.org>

I've taken the v2 version of this series, plus the ext4-specific
patches to use the new symlink helpers (from the v1 patch series).
After testing and validating them, I included the patches to convert
f2fs and ubifs to use the symlink helpers, so I could also grab the
cleanup patches from the V1 series.

Jaeguk, Richard, please let me know if you are OK with my taking the
f2fs and ubifs changes in the fscrypt tree.  It seems like it would
keep things simpler if we did that.

Cheers,

						- Ted


From boris.brezillon at free-electrons.com  Thu Jan 11 23:52:25 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 08:52:25 +0100
Subject: [PATCH v2] mtd: nand: Fix nand_do_read_oob() return value
In-Reply-To: <20180111214202.24531-1-miquel.raynal@free-electrons.com>
References: <20180111214202.24531-1-miquel.raynal@free-electrons.com>
Message-ID: <20180112085225.52482fba@bbrezillon>

On Thu, 11 Jan 2018 22:42:02 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
> OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
> negative error, and the MTD layer expected it.
> 
> However, the trend for the NAND layer is now to return an error or a
> positive number of bitflips. Deciding which status to return to the user
> belongs to the MTD layer.
> 
> Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> brought this logic to the mtd_read_oob() function while the return value
> coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
> left unchanged.
> 
> Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> Cc: stable at vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
> 
> Changes since v1:
>   - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit message
>   - Fixed the compilation issue
> 
>  drivers/mtd/nand/nand_base.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 469220065b8b..440d9f5d5b17 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -3876,7 +3876,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  	if (mtd->ecc_stats.failed - stats.failed)
>  		return -EBADMSG;
>  
> -	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
> +	return ret;

This is wrong, you're only returning the max number of bitflips of the
last OOB read.

>  }
>  
>  /**



From miquel.raynal at free-electrons.com  Fri Jan 12 00:03:26 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 12 Jan 2018 09:03:26 +0100
Subject: [PATCH v2] mtd: nand: Fix nand_do_read_oob() return value
In-Reply-To: <20180112085225.52482fba@bbrezillon>
References: <20180111214202.24531-1-miquel.raynal@free-electrons.com>
 <20180112085225.52482fba@bbrezillon>
Message-ID: <20180112090326.72ba327b@xps13>

Hi Boris,

On Fri, 12 Jan 2018 08:52:25 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Thu, 11 Jan 2018 22:42:02 +0100
> Miquel Raynal <miquel.raynal at free-electrons.com> wrote:
> 
> > Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
> > OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
> > negative error, and the MTD layer expected it.
> > 
> > However, the trend for the NAND layer is now to return an error or a
> > positive number of bitflips. Deciding which status to return to the
> > user belongs to the MTD layer.
> > 
> > Commit e47f68587b82 ("mtd: check for max_bitflips in
> > mtd_read_oob()") brought this logic to the mtd_read_oob() function
> > while the return value coming from nand_do_read_oob() (called by
> > the ->_read_oob() hook) was left unchanged.
> > 
> > Fixes: e47f68587b82 ("mtd: check for max_bitflips in
> > mtd_read_oob()") Cc: stable at vger.kernel.org
> > Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> > ---
> > 
> > Changes since v1:
> >   - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit
> > message
> >   - Fixed the compilation issue
> > 
> >  drivers/mtd/nand/nand_base.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/nand_base.c
> > b/drivers/mtd/nand/nand_base.c index 469220065b8b..440d9f5d5b17
> > 100644 --- a/drivers/mtd/nand/nand_base.c
> > +++ b/drivers/mtd/nand/nand_base.c
> > @@ -3876,7 +3876,7 @@ static int nand_do_read_oob(struct mtd_info
> > *mtd, loff_t from, if (mtd->ecc_stats.failed - stats.failed)
> >  		return -EBADMSG;
> >  
> > -	return  mtd->ecc_stats.corrected - stats.corrected ?
> > -EUCLEAN : 0;
> > +	return ret;  
> 
> This is wrong, you're only returning the max number of bitflips of the
> last OOB read.

I forgot about the while loop, that's right.

There will be a v3 :)

Thanks,
Miqu?l


From robert.jarzmik at free.fr  Fri Jan 12 00:09:17 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 12 Jan 2018 09:09:17 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180111232417.4aa86075@xps13> (Miquel RAYNAL's message of "Thu, 
 11 Jan 2018 23:24:17 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13>
Message-ID: <87a7xjbis2.fsf@belgarion.home>

Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:

I begun all your test procedure (on my zylonite board).
The timing registers are the same in both pxa3xx_nand and marvell_nand, ie :
[    3.085539] Timing registers from Bootloader:
[    3.089971] -  NDTR0: 0x00161c1c
[    3.095979] -  NDTR1: 0x0f3c00a2

I can attach the dmesg of the first run (dump of OOB). Yet I think you're
missing the point as to where the bug lies.

In the zylonite setup, the BBT is _not_ in the OOB of each block. Instead, it
lies at the end of the NAND, in the last blocks (see struct
nand_bbt_descr). Reading each block and declaring it as bad as is done in
marvell_nand (at least that is my understanding of your traces), but it is not
what should be done if a match is found for the bbt_pattern. Instead, the BBT
should be loaded from the last 8 blocks of the NAND, ie. page 130944 and page
131008 in my setup.

Therefore, I would rather think that marvell-nand is not using the BBT at the
end of the nand rather than misconfiguring the timing registers.

Cheers.

--
Robert

PS: You really should expunge the mailing recipients a bit ...

[1] DMesg extract
netconsole: port not set
netconsole: registered as netconsole-1
smc91c111 smc91c1110: chip is revision= 9, version= 2
mdio_bus: miibus0: probed
eth0: got preset MAC address: 00:0e:0c:a7:26:f7
nand: NAND device: Manufacturer ID: 0x20, Chip ID: 0xba (ST Micro NAND 256MiB 1,8V 16-bit), 256MiB, page size: 2048, OOB size: 64
mrvl_nand mrvl_nand0: ECC strength 1, ECC step size 512
Bad block table found at page 131008, version 0x04
Bad block table found at page 130944, version 0x04
malloc space: 0x83700000 -> 0x83efffff (size 8 MiB)
running /env/bin/init...
magicvar: No such file or directory
magicvar: No such file or directory
magicvar: No such file or directory

Hit any key to stop autoboot:  3 2 1 0
booting net
netconsole: netconsole initialized with 255.255.255.255:6662
eth0: 100Mbps full duplex link detected
DHCP client bound to address 192.168.1.232
netconsole: netconsole initialized with 255.255.255.255:6662
could not open /mnt/tftp/none-linux-zylonite: No such file or directory
Booting net failed: No such file or directory
booting net failed: No such file or directory
boot: No such file or directory
.[1;32mbarebox at .[1;36mZylonite:/.[0m global linux.bootargs.debug=earlycon
.[1;32mbarebox at .[1;36mZylonite:/.[0m bootm /mnt/tftp/zImage_jenkins

Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
arch_number: 1233
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.15.0-rc1-00047-g3085f79 (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #889 PREEMPT Fri Jan 12 08:26:17 CET 2018
[    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] Memory policy: Data cache writeback
[    0.000000] RO Mode clock: 0.00MHz
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] System bus clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] random: fast init done
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56856K/65536K available (4226K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0428a48   (4227 kB)
[    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
[    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
[    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
[    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
[    0.000070] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
[    0.000266] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
[    0.002134] Console: colour dummy device 80x30
[    0.002294] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
[    0.081019] pid_max: default: 32768 minimum: 301
[    0.081862] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.081960] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.085156] CPU: Testing write buffer coherency: ok
[    0.088957] Setting up static identity map for 0x80008200 - 0x80008260
[    0.089916] Hierarchical SRCU implementation.
[    0.102924] devtmpfs: initialized
[    0.113807] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.113948] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.116278] NET: Registered protocol family 16
[    0.119090] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.389530] Advanced Linux Sound Architecture Driver Initialized.
[    0.400350] clocksource: Switched to clocksource oscr0
[    0.553012] NET: Registered protocol family 2
[    0.558410] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.558634] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.558815] TCP: Hash tables configured (established 1024 bind 1024)
[    0.559367] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.559547] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.561234] NET: Registered protocol family 1
[    0.563263] RPC: Registered named UNIX socket transport module.
[    0.563363] RPC: Registered udp transport module.
[    0.563418] RPC: Registered tcp transport module.
[    0.563475] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.498791] Initialise system trusted keyrings
[    2.501003] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    2.504911] NFS: Registering the id_resolver key type
[    2.505141] Key type id_resolver registered
[    2.505204] Key type id_legacy registered
[    2.511301] Key type asymmetric registered
[    2.511404] Asymmetric key parser 'x509' registered
[    2.511567] io scheduler noop registered
[    2.511632] io scheduler deadline registered
[    2.512023] io scheduler cfq registered (default)
[    2.512092] io scheduler mq-deadline registered
[    2.512155] io scheduler kyber registered
[    2.569944] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
[    2.575695] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
[    3.050762] console [ttyS0] enabled
[    3.057118] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
[    3.069632] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
[    3.085539] Timing registers from Bootloader:
[    3.089971] -  NDTR0: 0x00161c1c
[    3.095979] -  NDTR1: 0x0f3c00a2
[    3.099319] nand: executing subop:
[    3.103209] nand:     ->CMD      [0xff]
[    3.107105] nand:     ->WAITRDY  [max 250 ms]
[    3.111915] marvell-nfc pxa3xx-nand: 
[    3.111915] NDCR:  0x90071fff
[    3.111915] NDCB0: 0x00a000ff
[    3.111915] NDCB1: 0x00000000
[    3.111915] NDCB2: 0x00000000
[    3.111915] NDCB3: 0x00000000
[    3.131170] nand: executing subop:
[    3.134638] nand:     ->CMD      [0x90]
[    3.138513] nand:     ->ADDR     [1 cyc: 00]
[    3.143174] nand:     ->DATA_IN  [2 B, force 8-bit]
[    3.148182] marvell-nfc pxa3xx-nand: 
[    3.148182] NDCR:  0x90071fff
[    3.148182] NDCB0: 0x00610090
[    3.148182] NDCB1: 0x00000000
[    3.148182] NDCB2: 0x00000000
[    3.148182] NDCB3: 0x00000000
[    3.167016] nand: executing subop:
[    3.170656] nand:     ->CMD      [0x90]
[    3.174543] nand:     ->ADDR     [1 cyc: 00]
[    3.178842] nand:     ->DATA_IN  [8 B, force 8-bit]
[    3.183955] marvell-nfc pxa3xx-nand: 
[    3.183955] NDCR:  0x90071fff
[    3.183955] NDCB0: 0x00610090
[    3.183955] NDCB1: 0x00000000
[    3.183955] NDCB2: 0x00000000
[    3.183955] NDCB3: 0x00000000
[    3.202627] nand: executing subop:
[    3.206083] nand:     ->CMD      [0x90]
[    3.209958] nand:     ->ADDR     [1 cyc: 20]
[    3.214403] nand:     ->DATA_IN  [4 B, force 8-bit]
[    3.219383] marvell-nfc pxa3xx-nand: 
[    3.219383] NDCR:  0x90071fff
[    3.219383] NDCB0: 0x00610090
[    3.219383] NDCB1: 0x00000020
[    3.219383] NDCB2: 0x00000000
[    3.219383] NDCB3: 0x00000000
[    3.238001] nand: executing subop:
[    3.241598] nand:     ->CMD      [0x90]
[    3.245491] nand:     ->ADDR     [1 cyc: 40]
[    3.249790] nand:     ->DATA_IN  [5 B, force 8-bit]
[    3.254897] marvell-nfc pxa3xx-nand: 
[    3.254897] NDCR:  0x90071fff
[    3.254897] NDCB0: 0x00610090
[    3.254897] NDCB1: 0x00000040
[    3.254897] NDCB2: 0x00000000
[    3.254897] NDCB3: 0x00000000
[    3.273547] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
[    3.279923] nand: ST Micro NAND 256MiB 1,8V 16-bit
[    3.284893] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    3.292633] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
[    3.299666] Scanning device for bad blocks
[    3.303978] nand: nand_do_read_oob: from = 0x00000000, len = 64
[    3.310000] marvell-nfc pxa3xx-nand: 
[    3.310000] NDCR:  0x9d079fff
[    3.310000] NDCB0: 0x000d3000
[    3.310000] NDCB1: 0x00000000
[    3.310000] NDCB2: 0x00000000
[    3.310000] NDCB3: 0x00000000
[    3.329036] OOB from page 0:
[    3.332122] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[    3.342950] 01: 00 00 00 00 00 00 00 00 d4 eb 0b f5 fa 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[    3.353817] Bad eraseblock 0 at 0x000000000000
[    3.358338] nand: nand_do_read_oob: from = 0x00020000, len = 64
[    3.364494] marvell-nfc pxa3xx-nand: 
[    3.364494] NDCR:  0x9d079fff
[    3.364494] NDCB0: 0x000d3000
[    3.364494] NDCB1: 0x00400000
[    3.364494] NDCB2: 0x00000000
[    3.364494] NDCB3: 0x00000000
[    3.383344] OOB from page 64:
[    3.386353] 00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
[    3.397213] 01: ff ff ff ff ff ff ff ff dc 1e ef 48 38 04 e6 95 40 86 da 0f b6 fd 95 6d 7f 05 2d cf fd 61 d9 05 
[    3.408131] nand: nand_do_read_oob: from = 0x00040000, len = 64
[    3.414298] marvell-nfc pxa3xx-nand: 
[    3.414298] NDCR:  0x9d079fff
[    3.414298] NDCB0: 0x000d3000
[    3.414298] NDCB1: 0x00800000
[    3.414298] NDCB2: 0x00000000
[    3.414298] NDCB3: 0x00000000
[    3.433140] OOB from page 128:
[    3.436237] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[    3.447080] 01: 00 00 00 00 00 00 00 00 48 5b 01 d2 56 00 a2 ec 23 82 51 02 ef af 9d ae 3e 02 34 82 6c d8 75 0e 
[    3.457961] Bad eraseblock 2 at 0x000000040000
[    3.462604] nand: nand_do_read_oob: from = 0x00060000, len = 64
[    3.468627] marvell-nfc pxa3xx-nand: 
[    3.468627] NDCR:  0x9d079fff
[    3.468627] NDCB0: 0x000d3000
[    3.468627] NDCB1: 0x00c00000
[    3.468627] NDCB2: 0x00000000
[    3.468627] NDCB3: 0x00000000
[    3.487466] OOB from page 192:
[    3.490706] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[    3.501537] 01: 00 00 00 00 00 00 00 00 a7 23 9c bc 5d 02 5e 55 3b fd 7f 04 ed 35 c0 d1 a7 0a c3 94 09 cf 9a 0d 
[    3.512409] Bad eraseblock 3 at 0x000000060000


From boris.brezillon at free-electrons.com  Fri Jan 12 00:45:01 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 09:45:01 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87a7xjbis2.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
Message-ID: <20180112094501.27706bfc@bbrezillon>

On Fri, 12 Jan 2018 09:09:17 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> 
> I begun all your test procedure (on my zylonite board).
> The timing registers are the same in both pxa3xx_nand and marvell_nand, ie :
> [    3.085539] Timing registers from Bootloader:
> [    3.089971] -  NDTR0: 0x00161c1c
> [    3.095979] -  NDTR1: 0x0f3c00a2
> 
> I can attach the dmesg of the first run (dump of OOB). Yet I think you're
> missing the point as to where the bug lies.

We definitely don't know where the bug lies, otherwise we wouldn't do
the remote debug session we're doing here.

> 
> In the zylonite setup, the BBT is _not_ in the OOB of each block. Instead, it
> lies at the end of the NAND, in the last blocks (see struct
> nand_bbt_descr). Reading each block and declaring it as bad as is done in
> marvell_nand (at least that is my understanding of your traces), but it is not
> what should be done if a match is found for the bbt_pattern. Instead, the BBT
> should be loaded from the last 8 blocks of the NAND, ie. page 130944 and page
> 131008 in my setup.

The driver is not searching for a BBT because it's explicitly disabled
in your pdata (if it was enabled we would see something like "Bad block
table not found ..." or "Bad block table found ..." in the logs). And
that's anyway not the bug we're trying to fix here. In your setup (2k
pages with Hamming ECC), the bad block markers, i.e. the markers
present in each block and used to mark a block good or bad (0xffff =>
good, != 0xffff => bad), should be preserved. So, the symptoms we're
seeing here, where almost all blocks are reported as bad when scanning
BBMs, is not expected, and that's what we're trying to debug/fix.

> 
> Therefore, I would rather think that marvell-nand is not using the BBT at the
> end of the nand rather than misconfiguring the timing registers.

Timing mis-configuration was just a lead we had to follow. It seems
that it's not the problem here, but we had to test it. Now, the missing
BBT scan is clearly caused by an explicit config telling the driver to
ignore the BBT. You can try to enable it if you want to test BBT
handling (pdata->flash_bbt = 1), but even if that works, we'd like to
understand why the regular BBM scanning does not work.

Honestly, it's hard to be sure what you're testing, because we don't
know whether you're testing the branch Miquel provided or manually
apply some changes locally. Can you push your local changes somewhere
(if any)?

> 
> Cheers.
> 
> --
> Robert
> 
> PS: You really should expunge the mailing recipients a bit ...

Indeed!

> 
> [1] DMesg extract
> netconsole: port not set
> netconsole: registered as netconsole-1
> smc91c111 smc91c1110: chip is revision= 9, version= 2
> mdio_bus: miibus0: probed
> eth0: got preset MAC address: 00:0e:0c:a7:26:f7
> nand: NAND device: Manufacturer ID: 0x20, Chip ID: 0xba (ST Micro NAND 256MiB 1,8V 16-bit), 256MiB, page size: 2048, OOB size: 64
> mrvl_nand mrvl_nand0: ECC strength 1, ECC step size 512
> Bad block table found at page 131008, version 0x04
> Bad block table found at page 130944, version 0x04
> malloc space: 0x83700000 -> 0x83efffff (size 8 MiB)
> running /env/bin/init...
> magicvar: No such file or directory
> magicvar: No such file or directory
> magicvar: No such file or directory
> 
> Hit any key to stop autoboot:  3 2 1 0
> booting net
> netconsole: netconsole initialized with 255.255.255.255:6662
> eth0: 100Mbps full duplex link detected
> DHCP client bound to address 192.168.1.232
> netconsole: netconsole initialized with 255.255.255.255:6662
> could not open /mnt/tftp/none-linux-zylonite: No such file or directory
> Booting net failed: No such file or directory
> booting net failed: No such file or directory
> boot: No such file or directory
> .[1;32mbarebox at .[1;36mZylonite:/.[0m global linux.bootargs.debug=earlycon
> .[1;32mbarebox at .[1;36mZylonite:/.[0m bootm /mnt/tftp/zImage_jenkins
> 
> Loading ARM Linux zImage '/mnt/tftp/zImage_jenkins'
> commandline: ram=64M console=ttyS0,115200 ip=dhcp root=/dev/nfs nfsroot=/home/none/nfsroot/zylonite,v3,tcp earlycon mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
> arch_number: 1233
> Uncompressing Linux... done, booting the kernel.
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 4.15.0-rc1-00047-g3085f79 (jenkins at belgarath) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) #889 PREEMPT Fri Jan 12 08:26:17 CET 2018
> [    0.000000] CPU: XScale-V3 based processor [69056891] revision 1 (ARMv5TE), cr=0000397f
> [    0.000000] CPU: VIVT data cache, VIVT instruction cache
> [    0.000000] Machine: PXA3xx Platform Development Kit (aka Zylonite)
> [    0.000000] Ignoring tag cmdline (using the default kernel command line)
> [    0.000000] Memory policy: Data cache writeback
> [    0.000000] RO Mode clock: 0.00MHz
> [    0.000000] Run Mode clock: 0.00MHz
> [    0.000000] Turbo Mode clock: 0.00MHz
> [    0.000000] System bus clock: 0.00MHz
> [    0.000000] On node 0 totalpages: 16384
> [    0.000000]   Normal zone: 128 pages used for memmap
> [    0.000000]   Normal zone: 0 pages reserved
> [    0.000000]   Normal zone: 16384 pages, LIFO batch:3
> [    0.000000] random: fast init done
> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
> [    0.000000] pcpu-alloc: [0] 0 
> [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
> [    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.232:192.168.1.5::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root) ubi.mtd=5 earlycon=pxa,io,0xf6200000,115200n8 debug no_console_suspend
> [    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
> [    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
> [    0.000000] Memory: 56856K/65536K available (4226K kernel code, 202K rwdata, 972K rodata, 2396K init, 102K bss, 8680K reserved, 0K cma-reserved)
> [    0.000000] Virtual kernel memory layout:
> [    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
> [    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
> [    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
> [    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
> [    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
> [    0.000000]       .text : 0xc0008000 - 0xc0428a48   (4227 kB)
> [    0.000000]       .init : 0xc053f000 - 0xc0796000   (2396 kB)
> [    0.000000]       .data : 0xc0796000 - 0xc07c8bec   ( 203 kB)
> [    0.000000]        .bss : 0xc07c8bec - 0xc07e25fc   ( 103 kB)
> [    0.000000] Preemptible hierarchical RCU implementation.
> [    0.000000] 	Tasks RCU enabled.
> [    0.000000] NR_IRQS: 16, nr_irqs: 336, preallocated irqs: 336
> [    0.000000] RJK: parent_rate=13000000, xl=8, xn=1
> [    0.000070] sched_clock: 32 bits at 3250kHz, resolution 307ns, wraps every 660764198758ns
> [    0.000266] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 588080137591 ns
> [    0.002134] Console: colour dummy device 80x30
> [    0.002294] Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
> [    0.081019] pid_max: default: 32768 minimum: 301
> [    0.081862] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.081960] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.085156] CPU: Testing write buffer coherency: ok
> [    0.088957] Setting up static identity map for 0x80008200 - 0x80008260
> [    0.089916] Hierarchical SRCU implementation.
> [    0.102924] devtmpfs: initialized
> [    0.113807] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
> [    0.113948] futex hash table entries: 256 (order: -1, 3072 bytes)
> [    0.116278] NET: Registered protocol family 16
> [    0.119090] DMA: preallocated 256 KiB pool for atomic coherent allocations
> [    0.389530] Advanced Linux Sound Architecture Driver Initialized.
> [    0.400350] clocksource: Switched to clocksource oscr0
> [    0.553012] NET: Registered protocol family 2
> [    0.558410] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.558634] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.558815] TCP: Hash tables configured (established 1024 bind 1024)
> [    0.559367] UDP hash table entries: 256 (order: 0, 4096 bytes)
> [    0.559547] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
> [    0.561234] NET: Registered protocol family 1
> [    0.563263] RPC: Registered named UNIX socket transport module.
> [    0.563363] RPC: Registered udp transport module.
> [    0.563418] RPC: Registered tcp transport module.
> [    0.563475] RPC: Registered tcp NFSv4.1 backchannel transport module.
> [    2.498791] Initialise system trusted keyrings
> [    2.501003] workingset: timestamp_bits=30 max_order=14 bucket_order=0
> [    2.504911] NFS: Registering the id_resolver key type
> [    2.505141] Key type id_resolver registered
> [    2.505204] Key type id_legacy registered
> [    2.511301] Key type asymmetric registered
> [    2.511404] Asymmetric key parser 'x509' registered
> [    2.511567] io scheduler noop registered
> [    2.511632] io scheduler deadline registered
> [    2.512023] io scheduler cfq registered (default)
> [    2.512092] io scheduler mq-deadline registered
> [    2.512155] io scheduler kyber registered
> [    2.569944] pxa-dma pxa-dma.0: initialized 32 channels on 100 requestors
> [    2.575695] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 928571) is a UART1
> [    3.050762] console [ttyS0] enabled
> [    3.057118] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 928571) is a UART2
> [    3.069632] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 928571) is a UART3
> [    3.085539] Timing registers from Bootloader:
> [    3.089971] -  NDTR0: 0x00161c1c
> [    3.095979] -  NDTR1: 0x0f3c00a2
> [    3.099319] nand: executing subop:
> [    3.103209] nand:     ->CMD      [0xff]
> [    3.107105] nand:     ->WAITRDY  [max 250 ms]
> [    3.111915] marvell-nfc pxa3xx-nand: 
> [    3.111915] NDCR:  0x90071fff
> [    3.111915] NDCB0: 0x00a000ff
> [    3.111915] NDCB1: 0x00000000
> [    3.111915] NDCB2: 0x00000000
> [    3.111915] NDCB3: 0x00000000
> [    3.131170] nand: executing subop:
> [    3.134638] nand:     ->CMD      [0x90]
> [    3.138513] nand:     ->ADDR     [1 cyc: 00]
> [    3.143174] nand:     ->DATA_IN  [2 B, force 8-bit]
> [    3.148182] marvell-nfc pxa3xx-nand: 
> [    3.148182] NDCR:  0x90071fff
> [    3.148182] NDCB0: 0x00610090
> [    3.148182] NDCB1: 0x00000000
> [    3.148182] NDCB2: 0x00000000
> [    3.148182] NDCB3: 0x00000000
> [    3.167016] nand: executing subop:
> [    3.170656] nand:     ->CMD      [0x90]
> [    3.174543] nand:     ->ADDR     [1 cyc: 00]
> [    3.178842] nand:     ->DATA_IN  [8 B, force 8-bit]
> [    3.183955] marvell-nfc pxa3xx-nand: 
> [    3.183955] NDCR:  0x90071fff
> [    3.183955] NDCB0: 0x00610090
> [    3.183955] NDCB1: 0x00000000
> [    3.183955] NDCB2: 0x00000000
> [    3.183955] NDCB3: 0x00000000
> [    3.202627] nand: executing subop:
> [    3.206083] nand:     ->CMD      [0x90]
> [    3.209958] nand:     ->ADDR     [1 cyc: 20]
> [    3.214403] nand:     ->DATA_IN  [4 B, force 8-bit]
> [    3.219383] marvell-nfc pxa3xx-nand: 
> [    3.219383] NDCR:  0x90071fff
> [    3.219383] NDCB0: 0x00610090
> [    3.219383] NDCB1: 0x00000020
> [    3.219383] NDCB2: 0x00000000
> [    3.219383] NDCB3: 0x00000000
> [    3.238001] nand: executing subop:
> [    3.241598] nand:     ->CMD      [0x90]
> [    3.245491] nand:     ->ADDR     [1 cyc: 40]
> [    3.249790] nand:     ->DATA_IN  [5 B, force 8-bit]
> [    3.254897] marvell-nfc pxa3xx-nand: 
> [    3.254897] NDCR:  0x90071fff
> [    3.254897] NDCB0: 0x00610090
> [    3.254897] NDCB1: 0x00000040
> [    3.254897] NDCB2: 0x00000000
> [    3.254897] NDCB3: 0x00000000
> [    3.273547] nand: device found, Manufacturer ID: 0x20, Chip ID: 0xba
> [    3.279923] nand: ST Micro NAND 256MiB 1,8V 16-bit
> [    3.284893] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> [    3.292633] marvell-nfc pxa3xx-nand: No minimum ECC strength, using 1b/512B
> [    3.299666] Scanning device for bad blocks
> [    3.303978] nand: nand_do_read_oob: from = 0x00000000, len = 64
> [    3.310000] marvell-nfc pxa3xx-nand: 
> [    3.310000] NDCR:  0x9d079fff
> [    3.310000] NDCB0: 0x000d3000
> [    3.310000] NDCB1: 0x00000000
> [    3.310000] NDCB2: 0x00000000
> [    3.310000] NDCB3: 0x00000000
> [    3.329036] OOB from page 0:
> [    3.332122] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> [    3.342950] 01: 00 00 00 00 00 00 00 00 d4 eb 0b f5 fa 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    3.353817] Bad eraseblock 0 at 0x000000000000
> [    3.358338] nand: nand_do_read_oob: from = 0x00020000, len = 64
> [    3.364494] marvell-nfc pxa3xx-nand: 
> [    3.364494] NDCR:  0x9d079fff
> [    3.364494] NDCB0: 0x000d3000
> [    3.364494] NDCB1: 0x00400000
> [    3.364494] NDCB2: 0x00000000
> [    3.364494] NDCB3: 0x00000000
> [    3.383344] OOB from page 64:
> [    3.386353] 00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
> [    3.397213] 01: ff ff ff ff ff ff ff ff dc 1e ef 48 38 04 e6 95 40 86 da 0f b6 fd 95 6d 7f 05 2d cf fd 61 d9 05 
> [    3.408131] nand: nand_do_read_oob: from = 0x00040000, len = 64
> [    3.414298] marvell-nfc pxa3xx-nand: 
> [    3.414298] NDCR:  0x9d079fff
> [    3.414298] NDCB0: 0x000d3000
> [    3.414298] NDCB1: 0x00800000
> [    3.414298] NDCB2: 0x00000000
> [    3.414298] NDCB3: 0x00000000
> [    3.433140] OOB from page 128:
> [    3.436237] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> [    3.447080] 01: 00 00 00 00 00 00 00 00 48 5b 01 d2 56 00 a2 ec 23 82 51 02 ef af 9d ae 3e 02 34 82 6c d8 75 0e 

All bytes set to 0. Looks like someone explicitly wrote 0 in the OOB
area :-/. Do you know which component wrote this block (barebox or
Linux)?

> [    3.457961] Bad eraseblock 2 at 0x000000040000
> [    3.462604] nand: nand_do_read_oob: from = 0x00060000, len = 64
> [    3.468627] marvell-nfc pxa3xx-nand: 
> [    3.468627] NDCR:  0x9d079fff
> [    3.468627] NDCB0: 0x000d3000
> [    3.468627] NDCB1: 0x00c00000
> [    3.468627] NDCB2: 0x00000000
> [    3.468627] NDCB3: 0x00000000
> [    3.487466] OOB from page 192:
> [    3.490706] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> [    3.501537] 01: 00 00 00 00 00 00 00 00 a7 23 9c bc 5d 02 5e 55 3b fd 7f 04 ed 35 c0 d1 a7 0a c3 94 09 cf 9a 0d 
> [    3.512409] Bad eraseblock 3 at 0x000000060000



From miquel.raynal at free-electrons.com  Fri Jan 12 01:01:32 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 12 Jan 2018 10:01:32 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180112094501.27706bfc@bbrezillon>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
Message-ID: <20180112100132.2b8cd003@xps13>

Hi Robert,

On Fri, 12 Jan 2018 09:45:01 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Fri, 12 Jan 2018 09:09:17 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> 
> > Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> > 
> > I begun all your test procedure (on my zylonite board).
> > The timing registers are the same in both pxa3xx_nand and
> > marvell_nand, ie : [    3.085539] Timing registers from Bootloader:
> > [    3.089971] -  NDTR0: 0x00161c1c
> > [    3.095979] -  NDTR1: 0x0f3c00a2
> > 
> > I can attach the dmesg of the first run (dump of OOB). Yet I think
> > you're missing the point as to where the bug lies.  
> 
> We definitely don't know where the bug lies, otherwise we wouldn't do
> the remote debug session we're doing here.
> 
> > 
> > In the zylonite setup, the BBT is _not_ in the OOB of each block.
> > Instead, it lies at the end of the NAND, in the last blocks (see
> > struct nand_bbt_descr). Reading each block and declaring it as bad
> > as is done in marvell_nand (at least that is my understanding of
> > your traces), but it is not what should be done if a match is found
> > for the bbt_pattern. Instead, the BBT should be loaded from the
> > last 8 blocks of the NAND, ie. page 130944 and page 131008 in my
> > setup.  
> 
> The driver is not searching for a BBT because it's explicitly disabled
> in your pdata (if it was enabled we would see something like "Bad
> block table not found ..." or "Bad block table found ..." in the
> logs). And that's anyway not the bug we're trying to fix here. In
> your setup (2k pages with Hamming ECC), the bad block markers, i.e.
> the markers present in each block and used to mark a block good or
> bad (0xffff => good, != 0xffff => bad), should be preserved. So, the
> symptoms we're seeing here, where almost all blocks are reported as
> bad when scanning BBMs, is not expected, and that's what we're trying
> to debug/fix.

Also, the first blocks are (presumably) taken by the Bootloader, having
data there in the OOB is not impossible. Could you please show the same
dumps within the partition where you UBI/EXT setup relies?

> 
> > 
> > Therefore, I would rather think that marvell-nand is not using the
> > BBT at the end of the nand rather than misconfiguring the timing
> > registers.  
> 
> Timing mis-configuration was just a lead we had to follow. It seems
> that it's not the problem here, but we had to test it. Now, the
> missing BBT scan is clearly caused by an explicit config telling the
> driver to ignore the BBT. You can try to enable it if you want to
> test BBT handling (pdata->flash_bbt = 1), but even if that works,
> we'd like to understand why the regular BBM scanning does not work.
> 
> Honestly, it's hard to be sure what you're testing, because we don't
> know whether you're testing the branch Miquel provided or manually
> apply some changes locally. Can you push your local changes somewhere
> (if any)?

Yes, please, can you push a branch with your patches?


As far as I remember, you removed the flash_bbt from the pdata to avoid
smashing the BBT again. Can you test this works with the old driver ?

If the old driver fails without flash_bbt, then you should go back to
the original setup and test again the last modifications.

Thanks,
Miqu?l


From xieyisheng1 at huawei.com  Fri Jan 12 01:12:12 2018
From: xieyisheng1 at huawei.com (Yisheng Xie)
Date: Fri, 12 Jan 2018 17:12:12 +0800
Subject: [PATCH v3 00/27] kill devm_ioremap_nocache
In-Reply-To: <1eb206ed-95e9-5839-485d-0e549ff3f505@c-s.fr>
References: <1514026525-32538-1-git-send-email-xieyisheng1@huawei.com>
 <20171223134831.GB10103@kroah.com>
 <b8ff7f17-7f2c-f220-9833-7ae5bd7343d5@c-s.fr>
 <8dd19411-5b06-0aa4-fd0e-e5b112c25dcb@huawei.com>
 <1eb206ed-95e9-5839-485d-0e549ff3f505@c-s.fr>
Message-ID: <ff498c83-d1ee-7553-e20c-a07369f8dad6@huawei.com>

Hi Christophe ?

On 2018/1/4 16:05, Christophe LEROY wrote:
> 
> 
> Le 25/12/2017 ? 02:34, Yisheng Xie a ?crit :
>>
>>
>> On 2017/12/24 17:05, christophe leroy wrote:
>>>
>>>
>>> Le 23/12/2017 ? 14:48, Greg KH a ?crit :
>>>> On Sat, Dec 23, 2017 at 06:55:25PM +0800, Yisheng Xie wrote:
>>>>> Hi all,
>>>>>
>>>>> When I tried to use devm_ioremap function and review related code, I found
>>>>> devm_ioremap and devm_ioremap_nocache is almost the same with each other,
>>>>> except one use ioremap while the other use ioremap_nocache.
>>>>
>>>> For all arches?  Really?  Look at MIPS, and x86, they have different
>>>> functions.
>>>>
>>>>> While ioremap's
>>>>> default function is ioremap_nocache, so devm_ioremap_nocache also have the
>>>>> same function with devm_ioremap, which can just be killed to reduce the size
>>>>> of devres.o(from 20304 bytes to 18992 bytes in my compile environment).
>>>>>
>>>>> I have posted two versions, which use macro instead of function for
>>>>> devm_ioremap_nocache[1] or devm_ioremap[2]. And Greg suggest me to kill
>>>>> devm_ioremap_nocache for no need to keep a macro around for the duplicate
>>>>> thing. So here comes v3 and please help to review.
>>>>
>>>> I don't think this can be done, what am I missing?  These functions are
>>>> not identical, sorry for missing that before.
>>>
>>> devm_ioremap() and devm_ioremap_nocache() are quite similar, both use devm_ioremap_release() for the release, why not just defining:
>>>
>>> static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
>>>                 resource_size_t size, bool nocache)
>>> {
>>> [...]
>>>      if (nocache)
>>>          addr = ioremap_nocache(offset, size);
>>>      else
>>>          addr = ioremap(offset, size);
>>> [...]
>>> }
>>>
>>> then in include/linux/io.h
>>>
>>> static inline void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
>>>                 resource_size_t size)
>>> {return __devm_ioremap(dev, offset, size, false);}
>>>
>>> static inline void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
>>>                     resource_size_t size);
>>> {return __devm_ioremap(dev, offset, size, true);}
>>
>> Yeah, this seems good to me, right now we have devm_ioremap, devm_ioremap_wc, devm_ioremap_nocache
>> May be we can use an enum like:
>> typedef enum {
>>     DEVM_IOREMAP = 0,
>>     DEVM_IOREMAP_NOCACHE,
>>     DEVM_IOREMAP_WC,
>> } devm_ioremap_type;
>>
>> static inline void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
>>                  resource_size_t size)
>>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP);}
>>
>>   static inline void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
>>                      resource_size_t size);
>>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NOCACHE);}
>>
>>   static inline void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
>>                      resource_size_t size);
>>   {return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC);}
>>
>>   static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
>>                  resource_size_t size, devm_ioremap_type type)
>>   {
>>       void __iomem **ptr, *addr = NULL;
>>   [...]
>>       switch (type){
>>       case DEVM_IOREMAP:
>>           addr = ioremap(offset, size);
>>           break;
>>       case DEVM_IOREMAP_NOCACHE:
>>           addr = ioremap_nocache(offset, size);
>>           break;
>>       case DEVM_IOREMAP_WC:
>>           addr = ioremap_wc(offset, size);
>>           break;
>>       }
>>   [...]
>>   }
> 
> 
> That looks good to me, will you submit a v4 ?

Sorry for late response. And I will submit the v4 as your suggestion.

Thanks
Yisheng

> 
> Christophe
> 
>>



From miquel.raynal at free-electrons.com  Fri Jan 12 01:13:36 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 12 Jan 2018 10:13:36 +0100
Subject: [PATCH v3] mtd: nand: Fix nand_do_read_oob() return value
Message-ID: <20180112091336.10709-1-miquel.raynal@free-electrons.com>

Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
negative error, and the MTD layer expected it.

However, the trend for the NAND layer is now to return an error or a
positive number of bitflips. Deciding which status to return to the user
belongs to the MTD layer.

Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
brought this logic to the mtd_read_oob() function while the return value
coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
left unchanged.

Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---


Changes since v2:
  - Correctly return the maximum number of bitflips, not the number of
    bitflips of the last chunk only.

Changes since v1:
  - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit message
  - Fixed the compilation issue
  

drivers/mtd/nand/nand_base.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 469220065b8b..e4e39890a975 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3794,6 +3794,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome);
 static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
 {
+	unsigned int max_bitflips = 0;
 	int page, realpage, chipnr;
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct mtd_ecc_stats stats;
@@ -3855,6 +3856,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 		if (!readlen)
 			break;
 
+		max_bitflips = max_t(unsigned int, max_bitflips, ret);
+
 		/* Increment page address */
 		realpage++;
 
@@ -3876,7 +3879,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	return max_bitflips;
 }
 
 /**
-- 
2.11.0



From yuyufen at huawei.com  Fri Jan 12 01:24:21 2018
From: yuyufen at huawei.com (Yufen Yu)
Date: Fri, 12 Jan 2018 17:24:21 +0800
Subject: [RFC PATCH] ubifs: Add zstd support
Message-ID: <20180112092421.22095-1-yuyufen@huawei.com>

Add zstd compression and decompression support to ubifs. zstd at its
fastest level compresses almost as well as zlib, while offering much
faster compression and decompression, approaching lzo speeds.

This patch is based on the patch:
	https://patchwork.kernel.org/patch/9892631/

zstd source repository: https://github.com/facebook/zstd

Signed-off-by: Yufen Yu <yuyufen at huawei.com>
---
 fs/ubifs/Kconfig       | 10 ++++++++++
 fs/ubifs/compress.c    | 25 +++++++++++++++++++++++++
 fs/ubifs/ubifs-media.h |  2 ++
 3 files changed, 37 insertions(+)

diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 83a961b..056a81b 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -5,8 +5,10 @@ config UBIFS_FS
 	select CRYPTO if UBIFS_FS_ADVANCED_COMPR
 	select CRYPTO if UBIFS_FS_LZO
 	select CRYPTO if UBIFS_FS_ZLIB
+	select CRYPTO if UBIFS_FS_ZSTD
 	select CRYPTO_LZO if UBIFS_FS_LZO
 	select CRYPTO_DEFLATE if UBIFS_FS_ZLIB
+	select CRYPTO_ZSTD if UBIFS_FS_XZ
 	depends on MTD_UBI
 	help
 	  UBIFS is a file system for flash devices which works on top of UBI.
@@ -36,6 +38,14 @@ config UBIFS_FS_ZLIB
 	help
 	  Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.
 
+config UBIFS_FS_ZSTD
+	bool "ZSTD compression support" if UBIFS_FS_ADVANCED_COMPR
+	depends on UBIFS_FS
+	default y
+	help
+	  ZSTD compresses is a big win in speed over Zlib and
+	  in compression ratio over LZO. Say 'Y' if unsure.
+
 config UBIFS_ATIME_SUPPORT
 	bool "Access time support" if UBIFS_FS
 	depends on UBIFS_FS
diff --git a/fs/ubifs/compress.c b/fs/ubifs/compress.c
index 565cb56..b310d6f 100644
--- a/fs/ubifs/compress.c
+++ b/fs/ubifs/compress.c
@@ -71,6 +71,24 @@ static struct ubifs_compressor zlib_compr = {
 };
 #endif
 
+#ifdef CONFIG_UBIFS_FS_ZSTD
+static DEFINE_MUTEX(zstd_enc_mutex);
+static DEFINE_MUTEX(zstd_dec_mutex);
+
+static struct ubifs_compressor zstd_compr = {
+	.compr_type = UBIFS_COMPR_ZSTD,
+	.comp_mutex = &zstd_enc_mutex,
+	.decomp_mutex = &zstd_dec_mutex,
+	.name = "zstd",
+	.capi_name = "zstd",
+};
+#else
+static struct ubifs_compressor zstd_compr = {
+	.compr_type = UBIFS_COMPR_ZSTD,
+	.name = "zstd",
+};
+#endif
+
 /* All UBIFS compressors */
 struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
 
@@ -228,6 +246,10 @@ int __init ubifs_compressors_init(void)
 	if (err)
 		return err;
 
+	err = compr_init(&zstd_compr);
+	if (err)
+		goto out_zstd;
+
 	err = compr_init(&zlib_compr);
 	if (err)
 		goto out_lzo;
@@ -235,6 +257,8 @@ int __init ubifs_compressors_init(void)
 	ubifs_compressors[UBIFS_COMPR_NONE] = &none_compr;
 	return 0;
 
+out_zstd:
+	compr_exit(&zstd_compr);
 out_lzo:
 	compr_exit(&lzo_compr);
 	return err;
@@ -247,4 +271,5 @@ void ubifs_compressors_exit(void)
 {
 	compr_exit(&lzo_compr);
 	compr_exit(&zlib_compr);
+	compr_exit(&zstd_compr);
 }
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index e8c23c9..9f869c7 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -341,12 +341,14 @@ enum {
  * UBIFS_COMPR_NONE: no compression
  * UBIFS_COMPR_LZO: LZO compression
  * UBIFS_COMPR_ZLIB: ZLIB compression
+ * UBIFS_COMPR_ZSTD: ZSTD compression
  * UBIFS_COMPR_TYPES_CNT: count of supported compression types
  */
 enum {
 	UBIFS_COMPR_NONE,
 	UBIFS_COMPR_LZO,
 	UBIFS_COMPR_ZLIB,
+	UBIFS_COMPR_ZSTD,
 	UBIFS_COMPR_TYPES_CNT,
 };
 
-- 
2.9.5



From boris.brezillon at free-electrons.com  Fri Jan 12 01:30:03 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 10:30:03 +0100
Subject: [PATCH v3] mtd: nand: Fix nand_do_read_oob() return value
In-Reply-To: <20180112091336.10709-1-miquel.raynal@free-electrons.com>
References: <20180112091336.10709-1-miquel.raynal@free-electrons.com>
Message-ID: <20180112103003.722cd541@bbrezillon>

On Fri, 12 Jan 2018 10:13:36 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
> OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
> negative error, and the MTD layer expected it.
> 
> However, the trend for the NAND layer is now to return an error or a
> positive number of bitflips. Deciding which status to return to the user
> belongs to the MTD layer.
> 
> Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> brought this logic to the mtd_read_oob() function while the return value
> coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
> left unchanged.
> 
> Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> Cc: stable at vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
> 
> 
> Changes since v2:
>   - Correctly return the maximum number of bitflips, not the number of
>     bitflips of the last chunk only.
> 
> Changes since v1:
>   - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit message
>   - Fixed the compilation issue
>   
> 
> drivers/mtd/nand/nand_base.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 469220065b8b..e4e39890a975 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -3794,6 +3794,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome);
>  static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  			    struct mtd_oob_ops *ops)
>  {
> +	unsigned int max_bitflips = 0;
>  	int page, realpage, chipnr;
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct mtd_ecc_stats stats;
> @@ -3855,6 +3856,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  		if (!readlen)
>  			break;
>  
> +		max_bitflips = max_t(unsigned int, max_bitflips, ret);

Should be moved just before the if (!readlen) test, otherwise you don't
take the last the ->read_oob() into account.

No need to send a new version, I'll fix it when applying.

> +
>  		/* Increment page address */
>  		realpage++;
>  
> @@ -3876,7 +3879,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  	if (mtd->ecc_stats.failed - stats.failed)
>  		return -EBADMSG;
>  
> -	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
> +	return max_bitflips;
>  }
>  
>  /**



From zajec5 at gmail.com  Fri Jan 12 01:33:53 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 12 Jan 2018 10:33:53 +0100
Subject: [PATCH 1/2] dt-bindings: mtd: document Broadcom's BCM47xx partitions
Message-ID: <20180112093354.17593-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Broadcom based home router devices use partitions which have to be
discovered in a specific non-standard way. As there is no partition
table this commit adds and describes a new custom binding.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../devicetree/bindings/mtd/partition.txt          | 46 +++++++++++++++++++++-
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt
index 36f3b769a626..b201d497b618 100644
--- a/Documentation/devicetree/bindings/mtd/partition.txt
+++ b/Documentation/devicetree/bindings/mtd/partition.txt
@@ -14,8 +14,6 @@ method is used for a given flash device. To describe the method there should be
 a subnode of the flash device that is named 'partitions'. It must have a
 'compatible' property, which is used to identify the method to use.
 
-We currently only document a binding for fixed layouts.
-
 
 Fixed Partitions
 ================
@@ -109,3 +107,47 @@ flash at 2 {
 		};
 	};
 };
+
+
+Broadcom BCM47xx Partitions
+===========================
+
+Broadcom is one of hardware manufacturers providing SoCs (BCM47xx) used in
+home routers. Their BCM947xx boards using CFE bootloader have several partitions
+without any on-flash partition table. On some devices their sizes and/or
+meanings can also vary so fixed partitioning can't be used.
+
+Discovering partitions on these devices is possible thanks to having a special
+header and/or magic signature at the beginning of each of them. They are also
+block aligned which is important for determinig a size.
+
+Most of partitions use ASCII text based magic for determining a type. More
+complex partitions (like TRX with its HDR0 magic) may include extra header
+containing some details, including a length.
+
+A list of supported partitions includes:
+1) Bootloader with Broadcom's CFE (Common Firmware Environment)
+2) NVRAM with configuration/calibration data
+3) Device manufacturer's data with some default values (e.g. SSIDs)
+4) TRX firmware container which can hold up to 4 subpartitions
+5) Backup TRX firmware used after failed upgrade
+
+As mentioned earlier, role of some partitions may depend on extra configuration.
+For example both: main firmware and backup firmware use the same TRX format with
+the same header. To distinguish currently used firmware a CFE's environment
+variable "bootpartition" is used.
+
+
+Devices using Broadcom partitions described above should should have flash node
+with a subnode named "partitions" using following properties:
+
+Required properties:
+- compatible : (required) must be "brcm,bcm947xx-cfe-partitions"
+
+Example:
+
+flash at 0 {
+	partitions {
+		compatible = "brcm,bcm947xx-cfe-partitions";
+	};
+};
-- 
2.11.0



From zajec5 at gmail.com  Fri Jan 12 01:33:54 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 12 Jan 2018 10:33:54 +0100
Subject: [PATCH 2/2] mtd: bcm47xxpart: add of_match_table with a new DT binding
In-Reply-To: <20180112093354.17593-1-zajec5@gmail.com>
References: <20180112093354.17593-1-zajec5@gmail.com>
Message-ID: <20180112093354.17593-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using bcm47xxpart parser to support DT describing partitions
on a flash using "brcm,bcm947xx-cfe-partitions" compatible property. It
means this parser doesn't have to be explicitly selected by a flash
driver anymore. It can be used e.g. together with a generic m25p80 /
spi-nor if device is just properly described.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/mtd/bcm47xxpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index fe2581d9d882..4bc2ad842eee 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -290,9 +290,16 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 	return curr_part;
 };
 
+static const struct of_device_id bcm47xxpart_of_match_table[] = {
+	{ .compatible = "brcm,bcm947xx-cfe-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm47xxpart_of_match_table);
+
 static struct mtd_part_parser bcm47xxpart_mtd_parser = {
 	.parse_fn = bcm47xxpart_parse,
 	.name = "bcm47xxpart",
+	.of_match_table = bcm47xxpart_of_match_table,
 };
 module_mtd_part_parser(bcm47xxpart_mtd_parser);
 
-- 
2.11.0



From robert.jarzmik at free.fr  Fri Jan 12 01:34:13 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 12 Jan 2018 10:34:13 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180112094501.27706bfc@bbrezillon> (Boris Brezillon's message
 of "Fri, 12 Jan 2018 09:45:01 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
Message-ID: <876087beui.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> On Fri, 12 Jan 2018 09:09:17 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
>
>> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
>> 
>> I begun all your test procedure (on my zylonite board).
>> The timing registers are the same in both pxa3xx_nand and marvell_nand, ie :
>> [    3.085539] Timing registers from Bootloader:
>> [    3.089971] -  NDTR0: 0x00161c1c
>> [    3.095979] -  NDTR1: 0x0f3c00a2
>> 
>> I can attach the dmesg of the first run (dump of OOB). Yet I think you're
>> missing the point as to where the bug lies.
>
> We definitely don't know where the bug lies, otherwise we wouldn't do
> the remote debug session we're doing here.
Fair enough.
> The driver is not searching for a BBT because it's explicitly disabled
> in your pdata (if it was enabled we would see something like "Bad block
> table not found ..." or "Bad block table found ..." in the logs).
You're right, and that's because I was told to remove the "flash_bbt=1" from my
platform data by Miquel in order to not destroy it again.

> And that's anyway not the bug we're trying to fix here. In your setup (2k
> pages with Hamming ECC), the bad block markers, i.e. the markers present in
> each block and used to mark a block good or bad (0xffff => good, != 0xffff =>
> bad), should be preserved.
I think we're still not aligned here. There are _no_ bad block markers in the
OOB on my flash, because there is a BBT at the end.

> So, the symptoms we're seeing here, where almost all blocks are reported as
> bad when scanning BBMs, is not expected, and that's what we're trying to
> debug/fix.
Well, I still think this is not something to fix ... I still think that OOB data
is not relevant as to the state of bad blocks in my flash ...

> Timing mis-configuration was just a lead we had to follow. It seems
> that it's not the problem here, but we had to test it. Now, the missing
> BBT scan is clearly caused by an explicit config telling the driver to
> ignore the BBT.
We agree on that.

> You can try to enable it if you want to test BBT
> handling (pdata->flash_bbt = 1), but even if that works, we'd like to
> understand why the regular BBM scanning does not work.
As you wish. I can make other tests, as long as my BBT is not broken again. If I
re-enable "flash_bbt=1", I'd like another "hack" to prevent BBT breakage, as
disabling it was adviced by Miquel to protect my NAND.

> Honestly, it's hard to be sure what you're testing, because we don't
> know whether you're testing the branch Miquel provided or manually
> apply some changes locally. Can you push your local changes somewhere
> (if any)?
git fetch https://github.com/rjarzmik/linux marvell-nand-bug
make zylonite_defconfig

>> mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
>> [    3.414298] marvell-nfc pxa3xx-nand: 
>> [    3.414298] NDCR:  0x9d079fff
>> [    3.414298] NDCB0: 0x000d3000
>> [    3.414298] NDCB1: 0x00800000
>> [    3.414298] NDCB2: 0x00000000
>> [    3.414298] NDCB3: 0x00000000
>> [    3.433140] OOB from page 128:
>> [    3.436237] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
>> [    3.447080] 01: 00 00 00 00 00 00 00 00 48 5b 01 d2 56 00 a2 ec 23 82 51 02 ef af 9d ae 3e 02 34 82 6c d8 75 0e 
>
> All bytes set to 0. Looks like someone explicitly wrote 0 in the OOB
> area :-/. Do you know which component wrote this block (barebox or
> Linux)?
In this specific case, you're in "TIMH" partition, which a specific partition
for the IPL (ROM part of the PXA3xx reads and loads it), and follows other rules
AFAIK.

The really anoying and relevant part are the bad blocks at 13568 KBytes offset
(ie. root partition), which contains the ext2/ubifs.

Cheers.

--
Robert


From boris.brezillon at free-electrons.com  Fri Jan 12 01:52:28 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 10:52:28 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <876087beui.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
Message-ID: <20180112105228.176ab80f@bbrezillon>

On Fri, 12 Jan 2018 10:34:13 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > On Fri, 12 Jan 2018 09:09:17 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> >> 
> >> I begun all your test procedure (on my zylonite board).
> >> The timing registers are the same in both pxa3xx_nand and marvell_nand, ie :
> >> [    3.085539] Timing registers from Bootloader:
> >> [    3.089971] -  NDTR0: 0x00161c1c
> >> [    3.095979] -  NDTR1: 0x0f3c00a2
> >> 
> >> I can attach the dmesg of the first run (dump of OOB). Yet I think you're
> >> missing the point as to where the bug lies.  
> >
> > We definitely don't know where the bug lies, otherwise we wouldn't do
> > the remote debug session we're doing here.  
> Fair enough.
> > The driver is not searching for a BBT because it's explicitly disabled
> > in your pdata (if it was enabled we would see something like "Bad block
> > table not found ..." or "Bad block table found ..." in the logs).  
> You're right, and that's because I was told to remove the "flash_bbt=1" from my
> platform data by Miquel in order to not destroy it again.

Because we though scanning of BBMs was working with the old pxa driver
(which should be the case for your setup, BTW), and we thought the new
driver was introducing a regression here.

BTW, did you ever try with the old driver and ->flash_bbt = false? If
you did not, can you test?

> 
> > And that's anyway not the bug we're trying to fix here. In your setup (2k
> > pages with Hamming ECC), the bad block markers, i.e. the markers present in
> > each block and used to mark a block good or bad (0xffff => good, != 0xffff =>
> > bad), should be preserved.  
> I think we're still not aligned here. There are _no_ bad block markers in the
> OOB on my flash, because there is a BBT at the end.

That's not how it works. The BBT is a way to get information about bad
blocks within a single read access, but, if you can preserve BBMs and
keep them updated (which is the case here), you should do it, just in
case you lose the BBT.

> 
> > So, the symptoms we're seeing here, where almost all blocks are reported as
> > bad when scanning BBMs, is not expected, and that's what we're trying to
> > debug/fix.  
> Well, I still think this is not something to fix ... I still think that OOB data
> is not relevant as to the state of bad blocks in my flash ...

Hm, I disagree. What if, for any reason, the BBT is lost? Don't you
want the full scan to work?

> 
> > Timing mis-configuration was just a lead we had to follow. It seems
> > that it's not the problem here, but we had to test it. Now, the missing
> > BBT scan is clearly caused by an explicit config telling the driver to
> > ignore the BBT.  
> We agree on that.
> 
> > You can try to enable it if you want to test BBT
> > handling (pdata->flash_bbt = 1), but even if that works, we'd like to
> > understand why the regular BBM scanning does not work.  
> As you wish. I can make other tests, as long as my BBT is not broken again. If I
> re-enable "flash_bbt=1", I'd like another "hack" to prevent BBT breakage, as
> disabling it was adviced by Miquel to protect my NAND.

Okay, so I have another solution for that: drop the NAND_BBT_CREATE and
NAND_BBT_WRITE here [1] and here [2]. That should let you read the
existing BBT without updating it or creating a new one if it's not
detected.

> 
> > Honestly, it's hard to be sure what you're testing, because we don't
> > know whether you're testing the branch Miquel provided or manually
> > apply some changes locally. Can you push your local changes somewhere
> > (if any)?  
> git fetch https://github.com/rjarzmik/linux marvell-nand-bug
> make zylonite_defconfig

Thanks for sharing this branch.

> 
> >> mtdparts=pxa3xx_nand-0:128k at 0(TIMH)ro,128k at 128k(OBMI)ro,768k at 256k(barebox),256k at 1024k(barebox-env),12M at 1280k(kernel),38016k at 13568k(root)
> >> [    3.414298] marvell-nfc pxa3xx-nand: 
> >> [    3.414298] NDCR:  0x9d079fff
> >> [    3.414298] NDCB0: 0x000d3000
> >> [    3.414298] NDCB1: 0x00800000
> >> [    3.414298] NDCB2: 0x00000000
> >> [    3.414298] NDCB3: 0x00000000
> >> [    3.433140] OOB from page 128:
> >> [    3.436237] 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> >> [    3.447080] 01: 00 00 00 00 00 00 00 00 48 5b 01 d2 56 00 a2 ec 23 82 51 02 ef af 9d ae 3e 02 34 82 6c d8 75 0e   
> >
> > All bytes set to 0. Looks like someone explicitly wrote 0 in the OOB
> > area :-/. Do you know which component wrote this block (barebox or
> > Linux)?  
> In this specific case, you're in "TIMH" partition, which a specific partition
> for the IPL (ROM part of the PXA3xx reads and loads it), and follows other rules
> AFAIK.
> 
> The really anoying and relevant part are the bad blocks at 13568 KBytes offset
> (ie. root partition), which contains the ext2/ubifs.

Can you provide the OOB dump of this block?

Thanks,

Boris

[1]https://github.com/rjarzmik/linux/blob/marvell-nand-bug/drivers/mtd/nand/marvell_nand.c#L2181
[2]https://github.com/rjarzmik/linux/blob/marvell-nand-bug/drivers/mtd/nand/marvell_nand.c#L2191


From boris.brezillon at free-electrons.com  Fri Jan 12 02:21:08 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 11:21:08 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <876087beui.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
Message-ID: <20180112112108.2e20dc14@bbrezillon>

On Fri, 12 Jan 2018 10:34:13 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > On Fri, 12 Jan 2018 09:09:17 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Miquel RAYNAL <miquel.raynal at free-electrons.com> writes:
> >> 
> >> I begun all your test procedure (on my zylonite board).
> >> The timing registers are the same in both pxa3xx_nand and marvell_nand, ie :
> >> [    3.085539] Timing registers from Bootloader:
> >> [    3.089971] -  NDTR0: 0x00161c1c
> >> [    3.095979] -  NDTR1: 0x0f3c00a2
> >> 
> >> I can attach the dmesg of the first run (dump of OOB). Yet I think you're
> >> missing the point as to where the bug lies.  
> >
> > We definitely don't know where the bug lies, otherwise we wouldn't do
> > the remote debug session we're doing here.  
> Fair enough.
> > The driver is not searching for a BBT because it's explicitly disabled
> > in your pdata (if it was enabled we would see something like "Bad block
> > table not found ..." or "Bad block table found ..." in the logs).  
> You're right, and that's because I was told to remove the "flash_bbt=1" from my
> platform data by Miquel in order to not destroy it again.
> 
> > And that's anyway not the bug we're trying to fix here. In your setup (2k
> > pages with Hamming ECC), the bad block markers, i.e. the markers present in
> > each block and used to mark a block good or bad (0xffff => good, != 0xffff =>
> > bad), should be preserved.  
> I think we're still not aligned here. There are _no_ bad block markers in the
> OOB on my flash, because there is a BBT at the end.

I think I'm still missing something. If I look at the branch you just
pushed, I see that ->flash_bbt was not set to 1 before this commit [1],
which means the pxa3xx driver was no setting the NAND_BBT_USE_FLASH
flag, which in turn means you were not using the on-flash-bbt.
When you test the old (pxa3xx) driver, are you sure you're testing
things with a mainline kernel? If you have extra commits on top of
mainline, can you push them somewhere?

[1]https://github.com/rjarzmik/linux/commit/5d391176c89a777f1c7d082cd50c1dc87e54b355#diff-6e551812174323b126d3f20eff6eec83


From boris.brezillon at free-electrons.com  Fri Jan 12 02:42:31 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 11:42:31 +0100
Subject: [RFC PATCH 2/2] mtd: nand: always request data transfer for
 parameter page
In-Reply-To: <20180111235037.10912-2-stefan@agner.ch>
References: <20180111235037.10912-1-stefan@agner.ch>
 <20180111235037.10912-2-stefan@agner.ch>
Message-ID: <20180112114231.51960fd3@bbrezillon>

On Fri, 12 Jan 2018 00:50:37 +0100
Stefan Agner <stefan at agner.ch> wrote:

> To make sure the controller actually transfers data add a
> DATA_IN op even if len is 0.

Nope, this is wrong. You should patch the caller of
nand_read_param_page_op() to always pass a valid buffer and
len != 0 instead.

> 
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
>  drivers/mtd/nand/nand_base.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 96c97588e1ba..26bbf54e125b 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -1510,10 +1510,6 @@ static int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
>  		};
>  		struct nand_operation op = NAND_OPERATION(instrs);
>  
> -		/* Drop the DATA_IN instruction if len is set to 0. */
> -		if (!len)
> -			op.ninstrs--;
> -
>  		return nand_exec_op(chip, &op);
>  	}
>  



From richard at nod.at  Fri Jan 12 02:45:49 2018
From: richard at nod.at (Richard Weinberger)
Date: Fri, 12 Jan 2018 11:45:49 +0100
Subject: [RFC PATCH] ubifs: Add zstd support
In-Reply-To: <20180112092421.22095-1-yuyufen@huawei.com>
References: <20180112092421.22095-1-yuyufen@huawei.com>
Message-ID: <7790203.HFZG64yrZx@blindfold>

Yufen Yu,

Am Freitag, 12. Januar 2018, 10:24:21 CET schrieb Yufen Yu:
> Add zstd compression and decompression support to ubifs. zstd at its
> fastest level compresses almost as well as zlib, while offering much
> faster compression and decompression, approaching lzo speeds.
> 
> This patch is based on the patch:
> 	https://patchwork.kernel.org/patch/9892631/
> 
> zstd source repository: https://github.com/facebook/zstd

Do you have numbers on how much we gain for UBIFS on a typical embedded 
device?

Thanks,
//richard


From boris.brezillon at free-electrons.com  Fri Jan 12 02:59:25 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 11:59:25 +0100
Subject: [RFC PATCH 1/2] mtd: nand: vf610_nfc: make use of ->exec_op()
In-Reply-To: <20180111235037.10912-1-stefan@agner.ch>
References: <20180111235037.10912-1-stefan@agner.ch>
Message-ID: <20180112115925.3d7dbde5@bbrezillon>

Hi Stefan,

On Fri, 12 Jan 2018 00:50:36 +0100
Stefan Agner <stefan at agner.ch> wrote:

> This reworks the driver to make use of ->exec_op() callback. The
> command sequencer of the VF610 NFC aligns well with the new ops
> interface.

That's great news!

> 
> Currently we handle reset and read id pattern separately. The
> read id pattern uses registers for the returned data, using a
> dedicated function helps to special case the data in op.
> 
> The parameter page handling is rather ad-hoc currently: The
> stack calls exec_op twice, once to read the paramter page and
> a second time to tranfer data. The code/controller can not
> handle this steps separately, hence just transfer data already
> in the first call and just memcpy from the buffer in the second
> call. This needs a small change in the nand_base.c file.

Hm, I think it's using change_column after the read_param_page command,
so it's not exactly a 'data xfer' only step. Can't your controller send
only a command or address cycle without any associated data xfers on
the bus?

Anyway, if you really have to do the READ_PARAM_PAGE in a single step,
you'll have to patch the core to pass a valid buffer and len != 0 when
calling nand_read_param_page_op().

> 
> The current state seems to pass MTD tests on a Colibri VF61.
> 
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
> Hi Boris, Hi Miquel,
> 
> Thanks for your work on the new NAND interface. The VF610 NFC
> definitly matches better the ->exec_op() interface.

And thanks for transitioning to this new interface.

> 
> This is still in early stage but seems to boot a Linux as rootfs
> successfully. Before working on further simplification I wanted
> to get some feedback on the general idea.

Sure.

> 
> If needed, the data sheet of the controller can be optained
> publicly (Vybrid Reference Manual, Chapter 10.3).

I'll have a look, thanks for the pointer.

> 
> Some questions from my side:
> - Parameter page: Why is exec_op called twice currently? This
>   seems to be problematic for this controller. Are there plans
>   to integrate the two calls in a single op sequence?

I don't know, but nothing is set in stone.

> - Row/Column addresses: The controller seems to separate those
>   two, hence the driver "guesses" which address bytes need to
>   go where.. Maybe it would be better to separate that on ops
>   level?

Miquel had a similar need for the new marvell NAND driver, so maybe we
can store this information at the nand_chip level:

	unsigned int row_cycles;
	unsigned int column_cycles;

I still want to keep the address data in an array of bytes, but thanks
to the [row,column]_cycles information you'll be able to easily convert
this array of bytes into row and column addresses.

> - Separation is often needed by command. One can make an educated
>   guess what kind of command is going to be passed by filtering
>   the appropriate ops. Maybe it would be good if the ops parser
>   can filter by command?

I'll have to check the datasheet you pointed out. We're not closed to
the idea of filtering things by particular opcodes, but most of the time
the controller is not hardcoded this way, and what they refer as READID
or READSTATUS is not about sending a NAND_READ_ID or a NAND_READ_STATUS
opcode, but following the sequence imposed by these operations (READID
is CMD+ADDR+DATA_IN, READSTATUS is CMD+DATA_IN). Which means, if you
have another operation which uses the same sequence but a different
opcode, the controller is able to handle it.

> 
> --
> Stefan
> 
> miquel.raynal at free-electrons.com
> 
>  drivers/mtd/nand/vf610_nfc.c | 543 +++++++++++++++++++++++++++----------------
>  1 file changed, 349 insertions(+), 194 deletions(-)

I'll have a look at the code once I have a better understanding of how
the controller actually work.

Once again, thanks a lot for working on this topic.

Regards,

Boris


From stefan at agner.ch  Fri Jan 12 04:58:11 2018
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 12 Jan 2018 13:58:11 +0100
Subject: [RFC PATCH 1/2] mtd: nand: vf610_nfc: make use of ->exec_op()
In-Reply-To: <20180112115925.3d7dbde5@bbrezillon>
References: <20180111235037.10912-1-stefan@agner.ch>
 <20180112115925.3d7dbde5@bbrezillon>
Message-ID: <fd812a82bf4a5604ff153d1d5b4e85ba@agner.ch>

On 2018-01-12 11:59, Boris Brezillon wrote:
> Hi Stefan,
> 
> On Fri, 12 Jan 2018 00:50:36 +0100
> Stefan Agner <stefan at agner.ch> wrote:
> 
>> This reworks the driver to make use of ->exec_op() callback. The
>> command sequencer of the VF610 NFC aligns well with the new ops
>> interface.
> 
> That's great news!
> 
>>
>> Currently we handle reset and read id pattern separately. The
>> read id pattern uses registers for the returned data, using a
>> dedicated function helps to special case the data in op.
>>
>> The parameter page handling is rather ad-hoc currently: The
>> stack calls exec_op twice, once to read the paramter page and
>> a second time to tranfer data. The code/controller can not
>> handle this steps separately, hence just transfer data already
>> in the first call and just memcpy from the buffer in the second
>> call. This needs a small change in the nand_base.c file.
> 
> Hm, I think it's using change_column after the read_param_page command,
> so it's not exactly a 'data xfer' only step. Can't your controller send
> only a command or address cycle without any associated data xfers on
> the bus?

Hm, I was looking at ONFI, where it does not do the column change:
http://git.infradead.org/linux-mtd.git/blob/8878b126df769831cb2fa4088c3806538e8305f5:/drivers/mtd/nand/nand_base.c#l5110

I am pretty sure that the controller can handle command and address
separately, but not sure about the successive data transfer...

> 
> Anyway, if you really have to do the READ_PARAM_PAGE in a single step,
> you'll have to patch the core to pass a valid buffer and len != 0 when
> calling nand_read_param_page_op().

I see.

> 
>>
>> The current state seems to pass MTD tests on a Colibri VF61.
>>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
>> ---
>> Hi Boris, Hi Miquel,
>>
>> Thanks for your work on the new NAND interface. The VF610 NFC
>> definitly matches better the ->exec_op() interface.
> 
> And thanks for transitioning to this new interface.
> 
>>
>> This is still in early stage but seems to boot a Linux as rootfs
>> successfully. Before working on further simplification I wanted
>> to get some feedback on the general idea.
> 
> Sure.
> 
>>
>> If needed, the data sheet of the controller can be optained
>> publicly (Vybrid Reference Manual, Chapter 10.3).
> 
> I'll have a look, thanks for the pointer.
> 
>>
>> Some questions from my side:
>> - Parameter page: Why is exec_op called twice currently? This
>>   seems to be problematic for this controller. Are there plans
>>   to integrate the two calls in a single op sequence?
> 
> I don't know, but nothing is set in stone.
> 
>> - Row/Column addresses: The controller seems to separate those
>>   two, hence the driver "guesses" which address bytes need to
>>   go where.. Maybe it would be better to separate that on ops
>>   level?
> 
> Miquel had a similar need for the new marvell NAND driver, so maybe we
> can store this information at the nand_chip level:
> 
> 	unsigned int row_cycles;
> 	unsigned int column_cycles;
> 
> I still want to keep the address data in an array of bytes, but thanks
> to the [row,column]_cycles information you'll be able to easily convert
> this array of bytes into row and column addresses.

That sounds good enough for my case.

> 
>> - Separation is often needed by command. One can make an educated
>>   guess what kind of command is going to be passed by filtering
>>   the appropriate ops. Maybe it would be good if the ops parser
>>   can filter by command?
> 
> I'll have to check the datasheet you pointed out. We're not closed to
> the idea of filtering things by particular opcodes, but most of the time
> the controller is not hardcoded this way, and what they refer as READID
> or READSTATUS is not about sending a NAND_READ_ID or a NAND_READ_STATUS
> opcode, but following the sequence imposed by these operations (READID
> is CMD+ADDR+DATA_IN, READSTATUS is CMD+DATA_IN). Which means, if you
> have another operation which uses the same sequence but a different
> opcode, the controller is able to handle it.
> 

The chapter 10.3.4.7 Flash Command Code Description is probably most
interesting in that regard. With the old interface, I used predefined
command codes, with the new interface I can dynamically generate the
command code from the operations provided by the stack.

However, some seem to be handled specially: There is single bit for
"Read ID". And the bytes returned by the controller are stored in
register instead of the regular data area. These are the reasons I do
use special handling right now...

--
Stefan

>>
>> --
>> Stefan
>>
>> miquel.raynal at free-electrons.com
>>
>>  drivers/mtd/nand/vf610_nfc.c | 543 +++++++++++++++++++++++++++----------------
>>  1 file changed, 349 insertions(+), 194 deletions(-)
> 
> I'll have a look at the code once I have a better understanding of how
> the controller actually work.
> 
> Once again, thanks a lot for working on this topic.
> 
> Regards,
> 
> Boris


From ladis at linux-mips.org  Fri Jan 12 05:11:05 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:11:05 +0100
Subject: [PATCH v6 00/14] OMAP2+ OneNAND driver update
Message-ID: <20180112131105.GA13810@lenoch>

this patch serie updates OMAP2+ OneNAND driver to the present times, making
it fully DT configurable, using libgpio and dmaengine apis.

Please note that unlike previous driver version, which basically ignored
DT specified timings, this one relies on it, so it is important to get
it right in your DT (dumping it from previous kernel version).

In case synchronous timings is requested, it is okay to specify timings
for the slowest chip ever used for you board as it is evetually optimized
after chip probe.

Original driver used DMA only if user specified INT gpio in platform
data, now DMA is used unconditionally and PIO mode is used as fallback.

In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
  done in patch 2)
- to use INT pin, int-gpios needs to be specified.

Most notable changes from v3:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by default

Most notable changes from v4:
- collected tags
- used INT pin name properly
- hopefully all comments taken into account

Most notable changes from v5:
- as this serie is expected to be merged via single tree patches 13 and 14
  were squashed together not to break bisecting.
- patch 16 was dropped.

This patchset depends on an immutable commit:

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable

for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:

  memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)


Ladislav Michl (12):
  dt-bindings: mtd: gpmc-onenand: Update properties description
  ARM: dts: OMAP2+: Add compatible property to onenand node
  ARM: dts: omap3-igep: Update onenand node timings
  mtd: onenand: omap2: Remove regulator support
  mtd: onenand: omap2: Remove skip initial unlocking support
  mtd: onenand: omap2: Remove partitioning support from platform data
  mtd: onenand: omap2: Account waiting time as waiting on IO
  mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
  mtd: onenand: omap2: Configure driver from DT
  ARM: OMAP2+: Remove gpmc-onenand

Peter Ujfalusi (2):
  mtd: onenand: omap2: Simplify the DMA setup for various paths
  mtd: onenand: omap2: Convert to use dmaengine for memcpy

 .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   1 +
 arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
 arch/arm/boot/dts/omap3-n900.dts                   |   1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
 arch/arm/mach-omap2/Makefile                       |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
 drivers/memory/omap-gpmc.c                         | 158 ++++--
 drivers/mtd/onenand/Kconfig                        |   4 +-
 drivers/mtd/onenand/omap2.c                        | 576 ++++++++-------------
 include/linux/omap-gpmc.h                          |  28 +
 include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
 13 files changed, 386 insertions(+), 866 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h

-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:11:53 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:11:53 +0100
Subject: [PATCH v6 01/14] dt-bindings: mtd: gpmc-onenand: Update properties
 description
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131153.GB13810@lenoch>

Compatible property is required for OMAP2+ mtd driver. Also
add INT pin gpio description and delete unused dma-channel
property.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Acked-by: Roger Quadros <rogerq at ti.com>
---

Changes in v6: None
Changes in v5:
- renamed R/B pin to INT pin

Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
index b6e8bfd024f4..e9f01a963a0a 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
@@ -9,13 +9,14 @@ Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 
 Required properties:
 
+ - compatible:		"ti,omap2-onenand"
  - reg:			The CS line the peripheral is connected to
- - gpmc,device-width	Width of the ONENAND device connected to the GPMC
+ - gpmc,device-width:	Width of the ONENAND device connected to the GPMC
 			in bytes. Must be 1 or 2.
 
 Optional properties:
 
- - dma-channel:		DMA Channel index
+ - int-gpios:		GPIO specifier for the INT pin.
 
 For inline partition table parsing (optional):
 
@@ -35,6 +36,7 @@ Example for an OMAP3430 board:
 		#size-cells = <1>;
 
 		onenand at 0 {
+			compatible = "ti,omap2-onenand";
 			reg = <0 0 0>; /* CS0, offset 0 */
 			gpmc,device-width = <2>;
 
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:12:56 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:12:56 +0100
Subject: [PATCH v6 02/14] ARM: dts: OMAP2+: Add compatible property to
 onenand node
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131256.GC13810@lenoch>

OMAP onenand nodes are missing compatible property, add it.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Acked-by: Roger Quadros <rogerq at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 +
 arch/arm/boot/dts/omap3-n900.dts            | 1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi        | 1 +
 arch/arm/boot/dts/omap3430-sdp.dts          | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 1df3ace3af92..63b0b4921e4e 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -52,6 +52,7 @@
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index f5700ff231db..a1e6307ae21e 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -840,6 +840,7 @@
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 12fbb3da5fce..0d9b85317529 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -367,6 +367,7 @@
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index 908951eb5943..d652708f6bef 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -154,6 +154,7 @@
 		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
 
 		gpmc,device-width = <2>;
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:13:19 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:13:19 +0100
Subject: [PATCH v6 03/14] ARM: dts: omap3-igep: Update onenand node timings
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131319.GD13810@lenoch>

Update node timings to be compatible with actual chip used -
gpmc_cs_show_timings utilized to dump values.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Acked-by: Roger Quadros <rogerq at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index 4ad7d5565906..f33cc80c9dbc 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -147,32 +147,32 @@
 		gpmc,sync-read;
 		gpmc,sync-write;
 		gpmc,burst-length = <16>;
-		gpmc,burst-read;
 		gpmc,burst-wrap;
+		gpmc,burst-read;
 		gpmc,burst-write;
 		gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
 		gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
 		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <87>;
-		gpmc,cs-wr-off-ns = <87>;
+		gpmc,cs-rd-off-ns = <96>;
+		gpmc,cs-wr-off-ns = <96>;
 		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <10>;
-		gpmc,adv-wr-off-ns = <10>;
-		gpmc,oe-on-ns = <15>;
-		gpmc,oe-off-ns = <87>;
+		gpmc,adv-rd-off-ns = <12>;
+		gpmc,adv-wr-off-ns = <12>;
+		gpmc,oe-on-ns = <18>;
+		gpmc,oe-off-ns = <96>;
 		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <87>;
-		gpmc,rd-cycle-ns = <112>;
-		gpmc,wr-cycle-ns = <112>;
-		gpmc,access-ns = <81>;
-		gpmc,page-burst-access-ns = <15>;
+		gpmc,we-off-ns = <96>;
+		gpmc,rd-cycle-ns = <114>;
+		gpmc,wr-cycle-ns = <114>;
+		gpmc,access-ns = <90>;
+		gpmc,page-burst-access-ns = <12>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <5>;
+		gpmc,clk-activation-ns = <6>;
 		gpmc,wr-data-mux-bus-ns = <30>;
-		gpmc,wr-access-ns = <81>;
-		gpmc,sync-clk-ps = <15000>;
+		gpmc,wr-access-ns = <90>;
+		gpmc,sync-clk-ps = <12000>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:13:36 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:13:36 +0100
Subject: [PATCH v6 04/14] mtd: onenand: omap2: Remove regulator support
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131336.GE13810@lenoch>

As no platform data user sets regulator_can_sleep, regulator code is
no-op and can be deleted.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch

 drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
 1 file changed, 1 insertion(+), 41 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 24a1388d3031..a03e1fe4aa48 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -34,7 +34,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 
 #include <asm/mach/flash.h>
@@ -59,7 +58,6 @@ struct omap2_onenand {
 	int dma_channel;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	struct regulator *regulator;
 	u8 flags;
 };
 
@@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
 }
 
-static int omap2_onenand_enable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_enable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't enable regulator\n");
-
-	return ret;
-}
-
-static int omap2_onenand_disable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_disable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't disable regulator\n");
-
-	return ret;
-}
-
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
 	struct omap_onenand_platform_data *pdata;
@@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->regulator_can_sleep) {
-		c->regulator = regulator_get(&pdev->dev, "vonenand");
-		if (IS_ERR(c->regulator)) {
-			dev_err(&pdev->dev,  "Failed to get regulator\n");
-			r = PTR_ERR(c->regulator);
-			goto err_release_dma;
-		}
-		c->onenand.enable = omap2_onenand_enable;
-		c->onenand.disable = omap2_onenand_disable;
-	}
-
 	if (pdata->skip_initial_unlocking)
 		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-		goto err_release_regulator;
+		goto err_release_dma;
 
 	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
 				pdata ? pdata->nr_parts : 0);
@@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 err_release_onenand:
 	onenand_release(&c->mtd);
-err_release_regulator:
-	regulator_put(c->regulator);
 err_release_dma:
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
@@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	regulator_put(c->regulator);
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
 	omap2_onenand_shutdown(pdev);
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:13:56 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:13:56 +0100
Subject: [PATCH v6 05/14] mtd: onenand: omap2: Remove skip initial unlocking
 support
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131356.GF13810@lenoch>

No platform data user sets skip_initial_unlocking, so remove test
for this field.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch

 drivers/mtd/onenand/omap2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index a03e1fe4aa48..93bd94337b35 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->skip_initial_unlocking)
-		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
-
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:14:17 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:14:17 +0100
Subject: [PATCH v6 06/14] mtd: onenand: omap2: Remove partitioning support
 from platform data
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131417.GG13810@lenoch>

No platform data user setups partitioning information, so remove.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch

 drivers/mtd/onenand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 93bd94337b35..883993bbe40b 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
-				pdata ? pdata->nr_parts : 0);
+	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
 
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:14:54 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:14:54 +0100
Subject: [PATCH v6 07/14] mtd: onenand: omap2: Account waiting time as
 waiting on IO
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131454.GH13810@lenoch>

Use wait_for_completion_io_timeout, which has an impact on how the
task is accounted in scheduling stats.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 drivers/mtd/onenand/omap2.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 883993bbe40b..0e7772e16d75 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (result == 0) {
 			int retry_cnt = 0;
 retry:
-			result = wait_for_completion_timeout(&c->irq_done,
-						    msecs_to_jiffies(20));
-			if (result == 0) {
+			if (!wait_for_completion_io_timeout(&c->irq_done,
+						msecs_to_jiffies(20))) {
 				/* Timeout after 20ms */
 				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 				if (ctrl & ONENAND_CTRL_ONGO &&
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:15:25 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:15:25 +0100
Subject: [PATCH v6 08/14] mtd: onenand: omap2: Simplify the DMA setup for
 various paths
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131525.GI13810@lenoch>

From: Peter Ujfalusi <peter.ujfalusi at ti.com>

We have 4 functions containing almost identical DMA setup code. Create one
function which can set up the DMA for both read and write and use this in
place for the setup code in the driver.
The new function will use wait_for_completion_io_timeout() and it will
figure out the best data_type to be used for the transfer instead of
hardwiring 32 or 16 bit data.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 0e7772e16d75..d22163271dc9 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
 	return 0;
 }
 
+static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
+					     dma_addr_t src, dma_addr_t dst,
+					     size_t count)
+{
+	int data_type = __ffs((src | dst | count));
+
+	if (data_type > OMAP_DMA_DATA_TYPE_S32)
+		data_type = OMAP_DMA_DATA_TYPE_S32;
+
+	omap_set_dma_transfer_params(c->dma_channel, data_type,
+				     count / BIT(data_type), 1, 0, 0, 0);
+	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				src, 0, 0);
+	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				 dst, 0, 0);
+
+	reinit_completion(&c->dma_done);
+	omap_start_dma(c->dma_channel);
+	if (!wait_for_completion_io_timeout(&c->dma_done,
+					    msecs_to_jiffies(20))) {
+		omap_stop_dma(c->dma_channel);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
 
 static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
@@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
 	size_t xtra;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		goto out_copy;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count / 4, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
@@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
-				     count / 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 #else
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:15:45 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:15:45 +0100
Subject: [PATCH v6 09/14] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA
 implementation
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131545.GJ13810@lenoch>

Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add
OMAP2 / OMAP3 OneNAND driver") DMA is disabled for OMAP2. Later
fixes thus went only into OMAP3 specific DMA functions which
turned out not to be so OMAP3 specific, so merge those two
implementations.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- rebase on top of Peter's patch

Changes in v3:
- new patch

Changes in v2: None

 drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
 1 file changed, 4 insertions(+), 125 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d22163271dc9..36314124488d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 					unsigned char *buffer, int offset,
 					size_t count)
 {
@@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 					 const unsigned char *buffer,
 					 int offset, size_t count)
 {
@@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-#else
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy(buffer, (__force void *)(this->base + bram_offset),
-		       count);
-		return 0;
-	}
-
-	dma_src = c->phys_base + bram_offset;
-	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
-				 DMA_FROM_DEVICE);
-	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy((__force void *)(this->base + bram_offset), buffer,
-		       count);
-		return 0;
-	}
-
-	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
-				 DMA_TO_DEVICE);
-	dma_dst = c->phys_base + bram_offset;
-	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-#else
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
 static struct platform_driver omap2_onenand_driver;
 
 static void omap2_onenand_shutdown(struct platform_device *pdev)
@@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	this = &c->onenand;
 	if (c->dma_channel >= 0) {
 		this->wait = omap2_onenand_wait;
-		if (c->flags & ONENAND_IN_OMAP34XX) {
-			this->read_bufferram = omap3_onenand_read_bufferram;
-			this->write_bufferram = omap3_onenand_write_bufferram;
-		} else {
-			this->read_bufferram = omap2_onenand_read_bufferram;
-			this->write_bufferram = omap2_onenand_write_bufferram;
-		}
+		this->read_bufferram = omap2_onenand_read_bufferram;
+		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:16:08 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:16:08 +0100
Subject: [PATCH v6 10/14] mtd: onenand: omap2: Convert to use dmaengine for
 memcpy
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131608.GK13810@lenoch>

From: Peter Ujfalusi <peter.ujfalusi at ti.com>

Do not use the legacy and deprecated omap-dma interface for setting up the
memcpy.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 36314124488d..c9ff67100ef4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
@@ -39,8 +40,6 @@
 #include <asm/mach/flash.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 
-#include <linux/omap-dma.h>
-
 #define DRIVER_NAME "omap2-onenand"
 
 #define ONENAND_BUFRAM_SIZE	(1024 * 5)
@@ -55,17 +54,15 @@ struct omap2_onenand {
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
-	int dma_channel;
+	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
 	u8 flags;
 };
 
-static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
+static void omap2_onenand_dma_complete_func(void *completion)
 {
-	struct omap2_onenand *c = data;
-
-	complete(&c->dma_done);
+	complete(completion);
 }
 
 static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
@@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 					     dma_addr_t src, dma_addr_t dst,
 					     size_t count)
 {
-	int data_type = __ffs((src | dst | count));
+	struct dma_async_tx_descriptor *tx;
+	dma_cookie_t cookie;
 
-	if (data_type > OMAP_DMA_DATA_TYPE_S32)
-		data_type = OMAP_DMA_DATA_TYPE_S32;
-
-	omap_set_dma_transfer_params(c->dma_channel, data_type,
-				     count / BIT(data_type), 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dst, 0, 0);
+	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
+	if (!tx) {
+		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
+		return -EIO;
+	}
 
 	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
+
+	tx->callback = omap2_onenand_dma_complete_func;
+	tx->callback_param = &c->dma_done;
+
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
+		return -EIO;
+	}
+
+	dma_async_issue_pending(c->dma_chan);
+
 	if (!wait_for_completion_io_timeout(&c->dma_done,
 					    msecs_to_jiffies(20))) {
-		omap_stop_dma(c->dma_channel);
+		dmaengine_terminate_sync(c->dma_chan);
 		return -ETIMEDOUT;
 	}
 
@@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
-	c->dma_channel = pdata->dma_channel;
-	if (c->dma_channel < 0) {
+	if (pdata->dma_channel < 0) {
 		/* if -1, don't use DMA */
 		c->gpio_irq = 0;
 	}
@@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		goto err_release_gpio;
 	}
 
-	if (c->dma_channel >= 0) {
-		r = omap_request_dma(0, pdev->dev.driver->name,
-				     omap2_onenand_dma_cb, (void *) c,
-				     &c->dma_channel);
-		if (r == 0) {
-			omap_set_dma_write_mode(c->dma_channel,
-						OMAP_DMA_WRITE_NON_POSTED);
-			omap_set_dma_src_data_pack(c->dma_channel, 1);
-			omap_set_dma_src_burst_mode(c->dma_channel,
-						    OMAP_DMA_DATA_BURST_8);
-			omap_set_dma_dest_data_pack(c->dma_channel, 1);
-			omap_set_dma_dest_burst_mode(c->dma_channel,
-						     OMAP_DMA_DATA_BURST_8);
-		} else {
+	if (pdata->dma_channel >= 0) {
+		dma_cap_mask_t mask;
+
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_MEMCPY, mask);
+
+		c->dma_chan = dma_request_channel(mask, NULL, NULL);
+		if (!c->dma_chan)
 			dev_info(&pdev->dev,
 				 "failed to allocate DMA for OneNAND, "
 				 "using PIO instead\n");
-			c->dma_channel = -1;
-		}
 	}
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
@@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	mtd_set_of_node(&c->mtd, pdata->of_node);
 
 	this = &c->onenand;
-	if (c->dma_channel >= 0) {
+	if (c->dma_chan) {
 		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
@@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_onenand:
 	onenand_release(&c->mtd);
 err_release_dma:
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	if (c->gpio_irq)
 		free_irq(gpio_to_irq(c->gpio_irq), c);
 err_release_gpio:
@@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
 	if (c->gpio_irq) {
 		free_irq(gpio_to_irq(c->gpio_irq), c);
-- 
2.15.1



From boris.brezillon at free-electrons.com  Fri Jan 12 05:18:50 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 14:18:50 +0100
Subject: [RFC PATCH 1/2] mtd: nand: vf610_nfc: make use of ->exec_op()
In-Reply-To: <fd812a82bf4a5604ff153d1d5b4e85ba@agner.ch>
References: <20180111235037.10912-1-stefan@agner.ch>
 <20180112115925.3d7dbde5@bbrezillon>
 <fd812a82bf4a5604ff153d1d5b4e85ba@agner.ch>
Message-ID: <20180112141850.46f7f45f@bbrezillon>

On Fri, 12 Jan 2018 13:58:11 +0100
Stefan Agner <stefan at agner.ch> wrote:

> On 2018-01-12 11:59, Boris Brezillon wrote:
> > Hi Stefan,
> > 
> > On Fri, 12 Jan 2018 00:50:36 +0100
> > Stefan Agner <stefan at agner.ch> wrote:
> >   
> >> This reworks the driver to make use of ->exec_op() callback. The
> >> command sequencer of the VF610 NFC aligns well with the new ops
> >> interface.  
> > 
> > That's great news!
> >   
> >>
> >> Currently we handle reset and read id pattern separately. The
> >> read id pattern uses registers for the returned data, using a
> >> dedicated function helps to special case the data in op.
> >>
> >> The parameter page handling is rather ad-hoc currently: The
> >> stack calls exec_op twice, once to read the paramter page and
> >> a second time to tranfer data. The code/controller can not
> >> handle this steps separately, hence just transfer data already
> >> in the first call and just memcpy from the buffer in the second
> >> call. This needs a small change in the nand_base.c file.  
> > 
> > Hm, I think it's using change_column after the read_param_page command,
> > so it's not exactly a 'data xfer' only step. Can't your controller send
> > only a command or address cycle without any associated data xfers on
> > the bus?  
> 
> Hm, I was looking at ONFI, where it does not do the column change:
> http://git.infradead.org/linux-mtd.git/blob/8878b126df769831cb2fa4088c3806538e8305f5:/drivers/mtd/nand/nand_base.c#l5110
> 
> I am pretty sure that the controller can handle command and address
> separately, but not sure about the successive data transfer...
> 
> > 
> > Anyway, if you really have to do the READ_PARAM_PAGE in a single step,
> > you'll have to patch the core to pass a valid buffer and len != 0 when
> > calling nand_read_param_page_op().  
> 
> I see.
> 
> >   
> >>
> >> The current state seems to pass MTD tests on a Colibri VF61.
> >>
> >> Signed-off-by: Stefan Agner <stefan at agner.ch>
> >> ---
> >> Hi Boris, Hi Miquel,
> >>
> >> Thanks for your work on the new NAND interface. The VF610 NFC
> >> definitly matches better the ->exec_op() interface.  
> > 
> > And thanks for transitioning to this new interface.
> >   
> >>
> >> This is still in early stage but seems to boot a Linux as rootfs
> >> successfully. Before working on further simplification I wanted
> >> to get some feedback on the general idea.  
> > 
> > Sure.
> >   
> >>
> >> If needed, the data sheet of the controller can be optained
> >> publicly (Vybrid Reference Manual, Chapter 10.3).  
> > 
> > I'll have a look, thanks for the pointer.
> >   
> >>
> >> Some questions from my side:
> >> - Parameter page: Why is exec_op called twice currently? This
> >>   seems to be problematic for this controller. Are there plans
> >>   to integrate the two calls in a single op sequence?  
> > 
> > I don't know, but nothing is set in stone.
> >   
> >> - Row/Column addresses: The controller seems to separate those
> >>   two, hence the driver "guesses" which address bytes need to
> >>   go where.. Maybe it would be better to separate that on ops
> >>   level?  
> > 
> > Miquel had a similar need for the new marvell NAND driver, so maybe we
> > can store this information at the nand_chip level:
> > 
> > 	unsigned int row_cycles;
> > 	unsigned int column_cycles;
> > 
> > I still want to keep the address data in an array of bytes, but thanks
> > to the [row,column]_cycles information you'll be able to easily convert
> > this array of bytes into row and column addresses.  
> 
> That sounds good enough for my case.
> 
> >   
> >> - Separation is often needed by command. One can make an educated
> >>   guess what kind of command is going to be passed by filtering
> >>   the appropriate ops. Maybe it would be good if the ops parser
> >>   can filter by command?  
> > 
> > I'll have to check the datasheet you pointed out. We're not closed to
> > the idea of filtering things by particular opcodes, but most of the time
> > the controller is not hardcoded this way, and what they refer as READID
> > or READSTATUS is not about sending a NAND_READ_ID or a NAND_READ_STATUS
> > opcode, but following the sequence imposed by these operations (READID
> > is CMD+ADDR+DATA_IN, READSTATUS is CMD+DATA_IN). Which means, if you
> > have another operation which uses the same sequence but a different
> > opcode, the controller is able to handle it.
> >   
> 
> The chapter 10.3.4.7 Flash Command Code Description is probably most
> interesting in that regard. With the old interface, I used predefined
> command codes, with the new interface I can dynamically generate the
> command code from the operations provided by the stack.
> 
> However, some seem to be handled specially: There is single bit for
> "Read ID". And the bytes returned by the controller are stored in
> register instead of the regular data area. These are the reasons I do
> use special handling right now...

Just don't use those special handling if you can avoid it. I mean, a
READID is just a regular READ with only 1 address cycle and X bytes of
DATA:
	NFC_SECSZ = X (information passed by the core)
	NFC_CMD2.CODE = SEND_CMD1 | SEND_COL_ADDR1 | READ_DATA
	...

This way you should have the READID data in the same region you have
regular data.

Same goes for the READ_STATUS operation:
	NFC_SECSZ = 1 (or 0 if no DATA_OUT is requested)
	NFC_CMD2.CODE = SEND_CMD1 [| READ_DATA]

And AFAICT, you can do naked READ/WRITE operations as well:

	NFC_SECSZ = X (the size of the read/write op)
	NFC_CMD2.CODE = READ_DATA or WRITE_DATA


With this approach, the final implementation should be much simpler
than what we have today.



From ladis at linux-mips.org  Fri Jan 12 05:18:00 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:18:00 +0100
Subject: [PATCH v6 14/14] ARM: OMAP2+: Remove gpmc-onenand
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131800.GO13810@lenoch>

As OneNAND driver is now using devicetree gpmc-onenand and its
platform data is unused and can be removed.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Acked-by: Roger Quadros <rogerq at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 arch/arm/mach-omap2/Makefile                    |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c              | 409 ------------------------
 include/linux/platform_data/mtd-onenand-omap2.h |  34 --
 3 files changed, 446 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 2f722a805948..c15bbcad5f67 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -232,6 +232,3 @@ obj-y					+= $(omap-hsmmc-m) $(omap-hsmmc-y)
 obj-y					+= omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
-
-onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
-obj-y					+= $(onenand-m) $(onenand-y)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
deleted file mode 100644
index 2944af820558..000000000000
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/gpmc-onenand.c
- *
- * Copyright (C) 2006 - 2009 Nokia Corporation
- * Contacts:	Juha Yrjola
- *		Tony Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/onenand_regs.h>
-#include <linux/io.h>
-#include <linux/omap-gpmc.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-#include <linux/err.h>
-
-#include <asm/mach/flash.h>
-
-#include "soc.h"
-
-#define	ONENAND_IO_SIZE	SZ_128K
-
-#define	ONENAND_FLAG_SYNCREAD	(1 << 0)
-#define	ONENAND_FLAG_SYNCWRITE	(1 << 1)
-#define	ONENAND_FLAG_HF		(1 << 2)
-#define	ONENAND_FLAG_VHF	(1 << 3)
-
-static unsigned onenand_flags;
-static unsigned latency;
-
-static struct omap_onenand_platform_data *gpmc_onenand_data;
-
-static struct resource gpmc_onenand_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gpmc_onenand_device = {
-	.name		= "omap2-onenand",
-	.id		= -1,
-	.num_resources	= 1,
-	.resource	= &gpmc_onenand_resource,
-};
-
-static struct gpmc_settings onenand_async = {
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-};
-
-static struct gpmc_settings onenand_sync = {
-	.burst_read	= true,
-	.burst_wrap	= true,
-	.burst_len	= GPMC_BURST_16,
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-	.wait_pin	= 0,
-};
-
-static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer = 15;
-	const int t_avdp = 12;
-	const int t_aavdh = 7;
-	const int t_ce = 76;
-	const int t_aa = 76;
-	const int t_oe = 20;
-	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_wpl = 40;
-	const int t_wph = 30;
-
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
-	dev_t.t_avdp_w = dev_t.t_avdp_r;
-	dev_t.t_aavdh = t_aavdh * 1000;
-	dev_t.t_aa = t_aa * 1000;
-	dev_t.t_ce = t_ce * 1000;
-	dev_t.t_oe = t_oe * 1000;
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.t_wpl = t_wpl * 1000;
-	dev_t.t_wph = t_wph * 1000;
-
-	gpmc_calc_timings(t, &onenand_async, &dev_t);
-}
-
-static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
-{
-	u32 reg;
-
-	/* Ensure sync read and sync write are disabled */
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static void set_onenand_cfg(void __iomem *onenand_base)
-{
-	u32 reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
-
-	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
-		ONENAND_SYS_CFG1_BL_16;
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		reg |= ONENAND_SYS_CFG1_SYNC_READ;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
-		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	if (onenand_flags & ONENAND_FLAG_HF)
-		reg |= ONENAND_SYS_CFG1_HF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_HF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		reg |= ONENAND_SYS_CFG1_VHF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_VHF;
-
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
-				  void __iomem *onenand_base)
-{
-	u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-	int freq;
-
-	switch ((ver >> 4) & 0xf) {
-	case 0:
-		freq = 40;
-		break;
-	case 1:
-		freq = 54;
-		break;
-	case 2:
-		freq = 66;
-		break;
-	case 3:
-		freq = 83;
-		break;
-	case 4:
-		freq = 104;
-		break;
-	default:
-		pr_err("onenand rate not detected, bad GPMC async timings?\n");
-		freq = 0;
-	}
-
-	return freq;
-}
-
-static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
-					    unsigned int flags,
-					    int freq)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer  = 15;
-	const int t_avdp = 12;
-	const int t_cez  = 20; /* max of t_cez, t_oez */
-	const int t_wpl  = 40;
-	const int t_wph  = 30;
-	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, gpmc_clk_ns;
-
-	if (flags & ONENAND_SYNC_READ)
-		onenand_flags = ONENAND_FLAG_SYNCREAD;
-	else if (flags & ONENAND_SYNC_READWRITE)
-		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
-
-	switch (freq) {
-	case 104:
-		min_gpmc_clk_period = 9600; /* 104 MHz */
-		t_ces   = 3;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 3;
-		t_aavdh = 6;
-		t_rdyo  = 6;
-		break;
-	case 83:
-		min_gpmc_clk_period = 12000; /* 83 MHz */
-		t_ces   = 5;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 9;
-		break;
-	case 66:
-		min_gpmc_clk_period = 15000; /* 66 MHz */
-		t_ces   = 6;
-		t_avds  = 5;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 11;
-		break;
-	default:
-		min_gpmc_clk_period = 18500; /* 54 MHz */
-		t_ces   = 7;
-		t_avds  = 7;
-		t_avdh  = 7;
-		t_ach   = 9;
-		t_aavdh = 7;
-		t_rdyo  = 15;
-		onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
-		break;
-	}
-
-	div = gpmc_calc_divider(min_gpmc_clk_period);
-	gpmc_clk_ns = gpmc_ticks_to_ns(div);
-	if (gpmc_clk_ns < 15) /* >66MHz */
-		onenand_flags |= ONENAND_FLAG_HF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_HF;
-	if (gpmc_clk_ns < 12) /* >83MHz */
-		onenand_flags |= ONENAND_FLAG_VHF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_VHF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		latency = 8;
-	else if (onenand_flags & ONENAND_FLAG_HF)
-		latency = 6;
-	else if (gpmc_clk_ns >= 25) /* 40 MHz*/
-		latency = 3;
-	else
-		latency = 4;
-
-	/* Set synchronous read timings */
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		onenand_sync.sync_read = true;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		onenand_sync.sync_write = true;
-		onenand_sync.burst_write = true;
-	} else {
-		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
-		dev_t.t_wpl = t_wpl * 1000;
-		dev_t.t_wph = t_wph * 1000;
-		dev_t.t_aavdh = t_aavdh * 1000;
-	}
-	dev_t.ce_xdelay = true;
-	dev_t.avd_xdelay = true;
-	dev_t.oe_xdelay = true;
-	dev_t.we_xdelay = true;
-	dev_t.clk = min_gpmc_clk_period;
-	dev_t.t_bacc = dev_t.clk;
-	dev_t.t_ces = t_ces * 1000;
-	dev_t.t_avds = t_avds * 1000;
-	dev_t.t_avdh = t_avdh * 1000;
-	dev_t.t_ach = t_ach * 1000;
-	dev_t.cyc_iaa = (latency + 1);
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.cyc_aavdh_oe = 1;
-	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
-
-	gpmc_calc_timings(t, &onenand_sync, &dev_t);
-}
-
-static int omap2_onenand_setup_async(void __iomem *onenand_base)
-{
-	struct gpmc_timings t;
-	int ret;
-
-	/*
-	 * Note that we need to keep sync_write set for the call to
-	 * omap2_onenand_set_async_mode() to work to detect the onenand
-	 * supported clock rate for the sync timings.
-	 */
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_async);
-		if (onenand_async.sync_read || onenand_async.sync_write) {
-			if (onenand_async.sync_write)
-				gpmc_onenand_data->flags |=
-					ONENAND_SYNC_READWRITE;
-			else
-				gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-			onenand_async.sync_read = false;
-		}
-	}
-
-	onenand_async.sync_write = true;
-	omap2_onenand_calc_async_timings(&t);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	omap2_onenand_set_async_mode(onenand_base);
-
-	return 0;
-}
-
-static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
-{
-	int ret, freq = *freq_ptr;
-	struct gpmc_timings t;
-
-	if (!freq) {
-		/* Very first call freq is not known */
-		freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
-		if (!freq)
-			return -ENODEV;
-		set_onenand_cfg(onenand_base);
-	}
-
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_sync);
-	} else {
-		/*
-		 * FIXME: Appears to be legacy code from initial ONENAND commit.
-		 * Unclear what boards this is for and if this can be removed.
-		 */
-		if (!cpu_is_omap34xx())
-			onenand_sync.wait_on_read = true;
-	}
-
-	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	set_onenand_cfg(onenand_base);
-
-	*freq_ptr = freq;
-
-	return 0;
-}
-
-static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
-{
-	struct device *dev = &gpmc_onenand_device.dev;
-	unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
-	int ret;
-
-	ret = omap2_onenand_setup_async(onenand_base);
-	if (ret) {
-		dev_err(dev, "unable to set to async mode\n");
-		return ret;
-	}
-
-	if (!(gpmc_onenand_data->flags & l))
-		return 0;
-
-	ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
-	if (ret)
-		dev_err(dev, "unable to set to sync mode\n");
-	return ret;
-}
-
-int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
-{
-	int err;
-	struct device *dev = &gpmc_onenand_device.dev;
-
-	gpmc_onenand_data = _onenand_data;
-	gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
-	gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
-
-	if (cpu_is_omap24xx() &&
-			(gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
-		dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
-		gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
-		gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-	}
-
-	if (cpu_is_omap34xx())
-		gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
-	else
-		gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
-
-	err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
-				(unsigned long *)&gpmc_onenand_resource.start);
-	if (err < 0) {
-		dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
-			gpmc_onenand_data->cs, err);
-		return err;
-	}
-
-	gpmc_onenand_resource.end = gpmc_onenand_resource.start +
-							ONENAND_IO_SIZE - 1;
-
-	err = platform_device_register(&gpmc_onenand_device);
-	if (err) {
-		dev_err(dev, "Unable to register OneNAND device\n");
-		gpmc_cs_free(gpmc_onenand_data->cs);
-	}
-
-	return err;
-}
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
deleted file mode 100644
index 56ff0e6f5ad1..000000000000
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 Nokia Corporation
- * Author: Juha Yrjola
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef	__MTD_ONENAND_OMAP2_H
-#define	__MTD_ONENAND_OMAP2_H
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define ONENAND_SYNC_READ	(1 << 0)
-#define ONENAND_SYNC_READWRITE	(1 << 1)
-#define	ONENAND_IN_OMAP34XX	(1 << 2)
-
-struct omap_onenand_platform_data {
-	int			cs;
-	int			gpio_irq;
-	struct mtd_partition	*parts;
-	int			nr_parts;
-	int			(*onenand_setup)(void __iomem *, int *freq_ptr);
-	int			dma_channel;
-	u8			flags;
-	u8			regulator_can_sleep;
-	u8			skip_initial_unlocking;
-
-	/* for passing the partitions */
-	struct device_node	*of_node;
-};
-#endif
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:17:25 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:17:25 +0100
Subject: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131725.GN13810@lenoch>

Move away from platform data configuration and use pure DT approach.

Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_child function. Import sync mode timing calculation
function from mach-omap2/gpmc-onenand.c

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6:
- squashed with previous patch

Changes in v5:
- rename ready_gpiod to int_gpiod
- use int-gpios as property name
- use devm_ioremap_resource
- "onenand" is now requested irq name
- add Kconfig dependencies
- make gpmc_omap_onenand_set_timings decsription more descriptive

Changes in v4: None
Changes in v3:
- remove 'ti,omap3-onenand' compatible as it is not needed anymore

Changes in v2:
- move cleanups into separate patches
- simplify dma setup
- fix checkpatch error
- print info about otimized timings in sync mode only
- add gpmc_omap_onenand_set_timings description

 drivers/memory/omap-gpmc.c  | 158 ++++++++++++++++++++--------
 drivers/mtd/onenand/Kconfig |   4 +-
 drivers/mtd/onenand/omap2.c | 250 +++++++++++++++++++++++++++-----------------
 include/linux/omap-gpmc.h   |  28 +++++
 4 files changed, 301 insertions(+), 139 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 0e30ee1c8677..90a66b3f7ae1 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -32,7 +32,6 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #include <asm/mach-types.h>
 
@@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
 }
 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
+static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
+						struct gpmc_settings *s,
+						int freq, int latency)
+{
+	struct gpmc_device_timings dev_t;
+	const int t_cer  = 15;
+	const int t_avdp = 12;
+	const int t_cez  = 20; /* max of t_cez, t_oez */
+	const int t_wpl  = 40;
+	const int t_wph  = 30;
+	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+
+	switch (freq) {
+	case 104:
+		min_gpmc_clk_period = 9600; /* 104 MHz */
+		t_ces   = 3;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 3;
+		t_aavdh = 6;
+		t_rdyo  = 6;
+		break;
+	case 83:
+		min_gpmc_clk_period = 12000; /* 83 MHz */
+		t_ces   = 5;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 9;
+		break;
+	case 66:
+		min_gpmc_clk_period = 15000; /* 66 MHz */
+		t_ces   = 6;
+		t_avds  = 5;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 11;
+		break;
+	default:
+		min_gpmc_clk_period = 18500; /* 54 MHz */
+		t_ces   = 7;
+		t_avds  = 7;
+		t_avdh  = 7;
+		t_ach   = 9;
+		t_aavdh = 7;
+		t_rdyo  = 15;
+		break;
+	}
+
+	/* Set synchronous read timings */
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	if (!s->sync_write) {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
+	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = min_gpmc_clk_period;
+	dev_t.t_bacc = dev_t.clk;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.cyc_aavdh_oe = 1;
+	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+	gpmc_calc_timings(t, s, &dev_t);
+}
+
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	int ret;
+	struct gpmc_timings gpmc_t;
+	struct gpmc_settings gpmc_s;
+
+	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
+
+	info->sync_read = gpmc_s.sync_read;
+	info->sync_write = gpmc_s.sync_write;
+	info->burst_len = gpmc_s.burst_len;
+
+	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
+		return 0;
+
+	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
+
+	ret = gpmc_cs_program_settings(cs, &gpmc_s);
+	if (ret < 0)
+		return ret;
+
+	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	if (!gpmc_irq_domain) {
@@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 		of_property_read_bool(np, "gpmc,time-para-granularity");
 }
 
-#if IS_ENABLED(CONFIG_MTD_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	struct omap_onenand_platform_data *gpmc_onenand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
-			child);
-		return -ENODEV;
-	}
-
-	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
-					 GFP_KERNEL);
-	if (!gpmc_onenand_data)
-		return -ENOMEM;
-
-	gpmc_onenand_data->cs = val;
-	gpmc_onenand_data->of_node = child;
-	gpmc_onenand_data->dma_channel = -1;
-
-	if (!of_property_read_u32(child, "dma-channel", &val))
-		gpmc_onenand_data->dma_channel = val;
-
-	return gpmc_onenand_init(gpmc_onenand_data);
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				    struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 /**
  * gpmc_probe_generic_child - configures the gpmc for a child device
  * @pdev:	pointer to gpmc platform device
@@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
+	if (of_node_cmp(child->name, "onenand") == 0) {
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible OneNAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
 		/* NAND specific setup */
 		val = 8;
@@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "onenand") == 0)
-			ret = gpmc_probe_onenand_child(pdev, child);
-		else
-			ret = gpmc_probe_generic_child(pdev, child);
-
+		ret = gpmc_probe_generic_child(pdev, child);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
 				child->name, ret);
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index aaeb30458139..9dc15748947b 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -25,9 +25,11 @@ config MTD_ONENAND_GENERIC
 config MTD_ONENAND_OMAP2
 	tristate "OneNAND on OMAP2/OMAP3 support"
 	depends on ARCH_OMAP2 || ARCH_OMAP3
+	depends on OF || COMPILE_TEST
 	help
-	  Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
+	  Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC
 	  via the GPMC memory controller.
+	  Enable dmaengine and gpiolib for better performance.
 
 config MTD_ONENAND_SAMSUNG
         tristate "OneNAND on Samsung SOC controller support"
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 1cd78a076759..2ce73fb6da1c 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -28,6 +28,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/of_device.h>
+#include <linux/omap-gpmc.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -35,10 +37,9 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach/flash.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -48,15 +49,12 @@ struct omap2_onenand {
 	struct platform_device *pdev;
 	int gpmc_cs;
 	unsigned long phys_base;
-	unsigned int mem_size;
-	int gpio_irq;
+	struct gpio_desc *int_gpiod;
 	struct mtd_info mtd;
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
 	struct dma_chan *dma_chan;
-	int freq;
-	int (*setup)(void __iomem *base, int *freq_ptr);
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
 	writew(value, c->onenand.base + reg);
 }
 
+static int omap2_onenand_set_cfg(struct omap2_onenand *c,
+				 bool sr, bool sw,
+				 int latency, int burst_len)
+{
+	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
+
+	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
+
+	switch (burst_len) {
+	case 0:		/* continuous */
+		break;
+	case 4:
+		reg |= ONENAND_SYS_CFG1_BL_4;
+		break;
+	case 8:
+		reg |= ONENAND_SYS_CFG1_BL_8;
+		break;
+	case 16:
+		reg |= ONENAND_SYS_CFG1_BL_16;
+		break;
+	case 32:
+		reg |= ONENAND_SYS_CFG1_BL_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (latency > 5)
+		reg |= ONENAND_SYS_CFG1_HF;
+	if (latency > 7)
+		reg |= ONENAND_SYS_CFG1_VHF;
+	if (sr)
+		reg |= ONENAND_SYS_CFG1_SYNC_READ;
+	if (sw)
+		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+
+	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
+
+	return 0;
+}
+
+static int omap2_onenand_get_freq(int ver)
+{
+	switch ((ver >> 4) & 0xf) {
+	case 0:
+		return 40;
+	case 1:
+		return 54;
+	case 2:
+		return 66;
+	case 3:
+		return 83;
+	case 4:
+		return 104;
+	}
+
+	return -EINVAL;
+}
+
 static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
 {
 	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
@@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		result = gpio_get_value(c->gpio_irq);
+		result = gpiod_get_value(c->int_gpiod);
 		if (result < 0) {
 			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 			intr = read_reg(c, ONENAND_REG_INTERRUPT);
 			wait_err("gpio error", state, ctrl, intr);
-			return -EIO;
+			return result;
 		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
@@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static struct platform_driver omap2_onenand_driver;
-
 static void omap2_onenand_shutdown(struct platform_device *pdev)
 {
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
@@ -446,105 +501,117 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
+	u32 val;
 	dma_cap_mask_t mask;
-	struct omap_onenand_platform_data *pdata;
-	struct omap2_onenand *c;
-	struct onenand_chip *this;
-	int r;
+	int freq, latency, r;
 	struct resource *res;
+	struct omap2_onenand *c;
+	struct gpmc_onenand_info info;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "error getting memory resource\n");
+		return -EINVAL;
+	}
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data missing\n");
-		return -ENODEV;
+	r = of_property_read_u32(np, "reg", &val);
+	if (r) {
+		dev_err(dev, "reg not found in DT\n");
+		return r;
 	}
 
-	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
+	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
 	if (!c)
 		return -ENOMEM;
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->gpmc_cs = pdata->cs;
-	c->gpio_irq = pdata->gpio_irq;
-	if (pdata->dma_channel < 0) {
-		/* if -1, don't use DMA */
-		c->gpio_irq = 0;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		r = -EINVAL;
-		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto err_kfree;
-	}
-
+	c->gpmc_cs = val;
 	c->phys_base = res->start;
-	c->mem_size = resource_size(res);
-
-	if (request_mem_region(c->phys_base, c->mem_size,
-			       pdev->dev.driver->name) == NULL) {
-		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
-						c->phys_base, c->mem_size);
-		r = -EBUSY;
-		goto err_kfree;
-	}
-	c->onenand.base = ioremap(c->phys_base, c->mem_size);
-	if (c->onenand.base == NULL) {
-		r = -ENOMEM;
-		goto err_release_mem_region;
-	}
 
-	if (pdata->onenand_setup != NULL) {
-		r = pdata->onenand_setup(c->onenand.base, &c->freq);
-		if (r < 0) {
-			dev_err(&pdev->dev, "Onenand platform setup failed: "
-				"%d\n", r);
-			goto err_iounmap;
-		}
-		c->setup = pdata->onenand_setup;
+	c->onenand.base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(c->onenand.base)) {
+		dev_err(dev, "Cannot reserve memory region at 0x%08x, size: 0x%x\n",
+			res->start, resource_size(res));
+		return PTR_ERR(c->onenand.base);
 	}
 
-	if (c->gpio_irq) {
-		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
-			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
-				"OneNAND\n", c->gpio_irq);
-			goto err_iounmap;
-		}
-		gpio_direction_input(c->gpio_irq);
+	c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN);
+	if (IS_ERR(c->int_gpiod)) {
+		r = PTR_ERR(c->int_gpiod);
+		/* Just try again if this happens */
+		if (r != -EPROBE_DEFER)
+			dev_err(dev, "error getting gpio: %d\n", r);
+		return r;
+	}
 
-		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-				     pdev->dev.driver->name, c)) < 0)
-			goto err_release_gpio;
+	if (c->int_gpiod) {
+		r = devm_request_irq(dev, gpiod_to_irq(c->int_gpiod),
+				     omap2_onenand_interrupt,
+				     IRQF_TRIGGER_RISING, "onenand", c);
+		if (r)
+			return r;
 
-		this->wait = omap2_onenand_wait;
+		c->onenand.wait = omap2_onenand_wait;
 	}
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_MEMCPY, mask);
 
 	c->dma_chan = dma_request_channel(mask, NULL, NULL);
-
-	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
+	if (c->dma_chan) {
+		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
+		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
+	}
 
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
+	c->mtd.dev.parent = dev;
+	mtd_set_of_node(&c->mtd, dev->of_node);
 
-	c->mtd.dev.parent = &pdev->dev;
-	mtd_set_of_node(&c->mtd, pdata->of_node);
-
-	this = &c->onenand;
-	if (c->dma_chan) {
-		this->read_bufferram = omap2_onenand_read_bufferram;
-		this->write_bufferram = omap2_onenand_write_bufferram;
-	}
+	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
+		 c->gpmc_cs, c->phys_base, c->onenand.base,
+		 c->dma_chan ? "DMA" : "PIO");
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
+	freq = omap2_onenand_get_freq(c->onenand.version_id);
+	if (freq > 0) {
+		switch (freq) {
+		case 104:
+			latency = 7;
+			break;
+		case 83:
+			latency = 6;
+			break;
+		case 66:
+			latency = 5;
+			break;
+		case 56:
+			latency = 4;
+			break;
+		default:	/* 40 MHz or lower */
+			latency = 3;
+			break;
+		}
+
+		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
+						  freq, latency, &info);
+		if (r)
+			goto err_release_onenand;
+
+		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
+					  latency, info.burst_len);
+		if (r)
+			goto err_release_onenand;
+
+		if (info.sync_read || info.sync_write)
+			dev_info(dev, "optimized timings for %d MHz\n", freq);
+	}
+
 	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
@@ -558,17 +625,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_dma:
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
-	if (c->gpio_irq)
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-err_release_gpio:
-	if (c->gpio_irq)
-		gpio_free(c->gpio_irq);
-err_iounmap:
-	iounmap(c->onenand.base);
-err_release_mem_region:
-	release_mem_region(c->phys_base, c->mem_size);
-err_kfree:
-	kfree(c);
 
 	return r;
 }
@@ -581,23 +637,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
-	if (c->gpio_irq) {
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-		gpio_free(c->gpio_irq);
-	}
-	iounmap(c->onenand.base);
-	release_mem_region(c->phys_base, c->mem_size);
-	kfree(c);
 
 	return 0;
 }
 
+static const struct of_device_id omap2_onenand_id_table[] = {
+	{ .compatible = "ti,omap2-onenand", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
+
 static struct platform_driver omap2_onenand_driver = {
 	.probe		= omap2_onenand_probe,
 	.remove		= omap2_onenand_remove,
 	.shutdown	= omap2_onenand_shutdown,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = omap2_onenand_id_table,
 	},
 };
 
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index edfa280c3d56..053feb41510a 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -25,15 +25,43 @@ struct gpmc_nand_ops {
 
 struct gpmc_nand_regs;
 
+struct gpmc_onenand_info {
+	bool sync_read;
+	bool sync_write;
+	int burst_len;
+};
+
 #if IS_ENABLED(CONFIG_OMAP_GPMC)
 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 					     int cs);
+/**
+ * gpmc_omap_onenand_set_timings - set optimized sync timings.
+ * @cs:      Chip Select Region
+ * @freq:    Chip frequency
+ * @latency: Burst latency cycle count
+ * @info:    Structure describing parameters used
+ *
+ * Sets optimized timings for the @cs region based on @freq and @latency.
+ * Updates the @info structure based on the GPMC settings.
+ */
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info);
+
 #else
 static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 							   int cs)
 {
 	return NULL;
 }
+
+static inline
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_OMAP_GPMC */
 
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:16:57 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:16:57 +0100
Subject: [PATCH v6 12/14] mtd: onenand: omap2: Decouple DMA enabling from INT
 pin availability
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131657.GM13810@lenoch>

INT pin (gpio_irq) is not really needed for DMA but only for notification
when a command that needs wait has completed. DMA memcpy can be still used
even without gpio_irq available, so enable it unconditionally.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5:
- rename patch and fix commit message

Changes in v4:
- new patch

Changes in v3: None
Changes in v2: None

 drivers/mtd/onenand/omap2.c | 52 ++++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 31 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index e4857a41760d..1cd78a076759 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		if (c->gpio_irq) {
-			result = gpio_get_value(c->gpio_irq);
-			if (result == -1) {
-				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
-				intr = read_reg(c, ONENAND_REG_INTERRUPT);
-				wait_err("gpio error", state, ctrl, intr);
-				return -EIO;
-			}
-		} else
-			result = 0;
-		if (result == 0) {
+		result = gpio_get_value(c->gpio_irq);
+		if (result < 0) {
+			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+			intr = read_reg(c, ONENAND_REG_INTERRUPT);
+			wait_err("gpio error", state, ctrl, intr);
+			return -EIO;
+		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
 			if (!wait_for_completion_io_timeout(&c->irq_done,
@@ -450,6 +446,7 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
+	dma_cap_mask_t mask;
 	struct omap_onenand_platform_data *pdata;
 	struct omap2_onenand *c;
 	struct onenand_chip *this;
@@ -513,31 +510,25 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
 				"OneNAND\n", c->gpio_irq);
 			goto err_iounmap;
-	}
-	gpio_direction_input(c->gpio_irq);
+		}
+		gpio_direction_input(c->gpio_irq);
 
-	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-			     pdev->dev.driver->name, c)) < 0)
-		goto err_release_gpio;
-	}
+		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
+				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
+				     pdev->dev.driver->name, c)) < 0)
+			goto err_release_gpio;
 
-	if (pdata->dma_channel >= 0) {
-		dma_cap_mask_t mask;
+		this->wait = omap2_onenand_wait;
+	}
 
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_MEMCPY, mask);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
 
-		c->dma_chan = dma_request_channel(mask, NULL, NULL);
-		if (!c->dma_chan)
-			dev_info(&pdev->dev,
-				 "failed to allocate DMA for OneNAND, "
-				 "using PIO instead\n");
-	}
+	c->dma_chan = dma_request_channel(mask, NULL, NULL);
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq);
+		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
+		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
 
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
@@ -547,7 +538,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	this = &c->onenand;
 	if (c->dma_chan) {
-		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
-- 
2.15.1



From ladis at linux-mips.org  Fri Jan 12 05:16:28 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Fri, 12 Jan 2018 14:16:28 +0100
Subject: [PATCH v6 11/14] mtd: onenand: omap2: Do not make delay for GPIO
 OMAP3 specific
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112131628.GL13810@lenoch>

Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
add delay for GPIO") added quirk for waiting until GPIO line settle.
As DMA was disabled for OMAP2 boards, chances are this problem was
not OMAP3 specific and as it is just one register read, previous
test for SoC type is approximately as expensive as read itself.
Make delay unconditional, which allows removing SoC specific code
alltogether.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.co.uk>
Acked-by: Roger Quadros <rogerq at ti.com>
Tested-by: Tony Lindgren <tony at atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- new patch

Changes in v2: None

 drivers/mtd/onenand/omap2.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index c9ff67100ef4..e4857a41760d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -57,7 +57,6 @@ struct omap2_onenand {
 	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	u8 flags;
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
 			syscfg |= ONENAND_SYS_CFG1_IOBE;
 			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
-			if (c->flags & ONENAND_IN_OMAP34XX)
-				/* Add a delay to let GPIO settle */
-				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+			/* Add a delay to let GPIO settle */
+			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
 		}
 
 		reinit_completion(&c->irq_done);
@@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
 	if (pdata->dma_channel < 0) {
-- 
2.15.1



From rogerq at ti.com  Fri Jan 12 05:46:43 2018
From: rogerq at ti.com (Roger Quadros)
Date: Fri, 12 Jan 2018 15:46:43 +0200
Subject: [PATCH v6 12/14] mtd: onenand: omap2: Decouple DMA enabling from
 INT pin availability
In-Reply-To: <20180112131657.GM13810@lenoch>
References: <20180112131105.GA13810@lenoch> <20180112131657.GM13810@lenoch>
Message-ID: <7d2a452b-3f0e-0ffb-5636-a26d1a903e88@ti.com>

On 12/01/18 15:16, Ladislav Michl wrote:
> INT pin (gpio_irq) is not really needed for DMA but only for notification
> when a command that needs wait has completed. DMA memcpy can be still used
> even without gpio_irq available, so enable it unconditionally.
> 
> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
> Tested-by: Tony Lindgren <tony at atomide.com>
> Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>

Acked-by: Tony Lindgren <tony at atomide.com>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


From rogerq at ti.com  Fri Jan 12 05:47:44 2018
From: rogerq at ti.com (Roger Quadros)
Date: Fri, 12 Jan 2018 15:47:44 +0200
Subject: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
In-Reply-To: <20180112131725.GN13810@lenoch>
References: <20180112131105.GA13810@lenoch> <20180112131725.GN13810@lenoch>
Message-ID: <07fd84e9-9df9-bc6f-c8f1-201e088ce807@ti.com>

On 12/01/18 15:17, Ladislav Michl wrote:
> Move away from platform data configuration and use pure DT approach.
> 
> Use generic probe function to deal with OneNAND node and remove now useless
> gpmc_probe_onenand_child function. Import sync mode timing calculation
> function from mach-omap2/gpmc-onenand.c
> 
> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
> Tested-by: Tony Lindgren <tony at atomide.com>
> Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>

Acked-by: Roger Quadros <rogerq at ti.com>


-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


From rogerq at ti.com  Fri Jan 12 05:56:55 2018
From: rogerq at ti.com (Roger Quadros)
Date: Fri, 12 Jan 2018 15:56:55 +0200
Subject: [PATCH v6 12/14] mtd: onenand: omap2: Decouple DMA enabling from
 INT pin availability
In-Reply-To: <7d2a452b-3f0e-0ffb-5636-a26d1a903e88@ti.com>
References: <20180112131105.GA13810@lenoch> <20180112131657.GM13810@lenoch>
 <7d2a452b-3f0e-0ffb-5636-a26d1a903e88@ti.com>
Message-ID: <bed28644-2df3-26e4-2261-6aa96b7f2aa3@ti.com>



On 12/01/18 15:46, Roger Quadros wrote:
> On 12/01/18 15:16, Ladislav Michl wrote:
>> INT pin (gpio_irq) is not really needed for DMA but only for notification
>> when a command that needs wait has completed. DMA memcpy can be still used
>> even without gpio_irq available, so enable it unconditionally.
>>
>> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
>> Reviewed-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
>> Tested-by: Tony Lindgren <tony at atomide.com>
>> Tested-by: Aaro Koskinen <aaro.koskinen at iki.fi>
> 
> Acked-by: Tony Lindgren <tony at atomide.com>
> 

oops. sorry.

Acked-by: Roger Quadros <rogerq at ti.com>


-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


From boris.brezillon at free-electrons.com  Fri Jan 12 06:03:15 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 15:03:15 +0100
Subject: [PATCH v6 00/14] OMAP2+ OneNAND driver update
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180112150315.54214fab@bbrezillon>

On Fri, 12 Jan 2018 14:11:05 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified INT gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use INT pin, int-gpios needs to be specified.

Roger, Tony, are you happy with this version? If this is the case, I'll
queue all patches to my nand/next branch (after merging Roger's
immutable branch in).

> 
> Most notable changes from v3:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Most notable changes from v4:
> - collected tags
> - used INT pin name properly
> - hopefully all comments taken into account
> 
> Most notable changes from v5:
> - as this serie is expected to be merged via single tree patches 13 and 14
>   were squashed together not to break bisecting.
> - patch 16 was dropped.
> 
> This patchset depends on an immutable commit:
> 
> The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
> 
>   Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
> 
> are available in the git repository at:
> 
>   https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
> 
> for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:
> 
>   memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
> 
> 
> Ladislav Michl (12):
>   dt-bindings: mtd: gpmc-onenand: Update properties description
>   ARM: dts: OMAP2+: Add compatible property to onenand node
>   ARM: dts: omap3-igep: Update onenand node timings
>   mtd: onenand: omap2: Remove regulator support
>   mtd: onenand: omap2: Remove skip initial unlocking support
>   mtd: onenand: omap2: Remove partitioning support from platform data
>   mtd: onenand: omap2: Account waiting time as waiting on IO
>   mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
>   mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
>   mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
>   mtd: onenand: omap2: Configure driver from DT
>   ARM: OMAP2+: Remove gpmc-onenand
> 
> Peter Ujfalusi (2):
>   mtd: onenand: omap2: Simplify the DMA setup for various paths
>   mtd: onenand: omap2: Convert to use dmaengine for memcpy
> 
>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   1 +
>  arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
>  arch/arm/boot/dts/omap3-n900.dts                   |   1 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
>  arch/arm/mach-omap2/Makefile                       |   3 -
>  arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
>  drivers/memory/omap-gpmc.c                         | 158 ++++--
>  drivers/mtd/onenand/Kconfig                        |   4 +-
>  drivers/mtd/onenand/omap2.c                        | 576 ++++++++-------------
>  include/linux/omap-gpmc.h                          |  28 +
>  include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
>  13 files changed, 386 insertions(+), 866 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
>  delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
> 



From boris.brezillon at free-electrons.com  Fri Jan 12 06:05:13 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 15:05:13 +0100
Subject: [PATCH v3] mtd: nand: Fix nand_do_read_oob() return value
In-Reply-To: <20180112091336.10709-1-miquel.raynal@free-electrons.com>
References: <20180112091336.10709-1-miquel.raynal@free-electrons.com>
Message-ID: <20180112150513.588294c0@bbrezillon>

On Fri, 12 Jan 2018 10:13:36 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
> OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
> negative error, and the MTD layer expected it.
> 
> However, the trend for the NAND layer is now to return an error or a
> positive number of bitflips. Deciding which status to return to the user
> belongs to the MTD layer.
> 
> Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> brought this logic to the mtd_read_oob() function while the return value
> coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
> left unchanged.
> 
> Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
> Cc: stable at vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Applied after fixing the bug I mentioned earlier.

Thanks,

Boris

> ---
> 
> 
> Changes since v2:
>   - Correctly return the maximum number of bitflips, not the number of
>     bitflips of the last chunk only.
> 
> Changes since v1:
>   - s/->ecc.read_oob() hook/->_read_oob() hook/ in the commit message
>   - Fixed the compilation issue
>   
> 
> drivers/mtd/nand/nand_base.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 469220065b8b..e4e39890a975 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -3794,6 +3794,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome);
>  static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  			    struct mtd_oob_ops *ops)
>  {
> +	unsigned int max_bitflips = 0;
>  	int page, realpage, chipnr;
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct mtd_ecc_stats stats;
> @@ -3855,6 +3856,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  		if (!readlen)
>  			break;
>  
> +		max_bitflips = max_t(unsigned int, max_bitflips, ret);
> +
>  		/* Increment page address */
>  		realpage++;
>  
> @@ -3876,7 +3879,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
>  	if (mtd->ecc_stats.failed - stats.failed)
>  		return -EBADMSG;
>  
> -	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
> +	return max_bitflips;
>  }
>  
>  /**



From boris.brezillon at free-electrons.com  Fri Jan 12 06:08:22 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 15:08:22 +0100
Subject: [PATCH] mtd: mtd_oobtest: Handle bitflips during reads
In-Reply-To: <20180111203920.8136-1-miquel.raynal@free-electrons.com>
References: <20180111203920.8136-1-miquel.raynal@free-electrons.com>
Message-ID: <20180112150822.291162c8@bbrezillon>

+David

On Thu, 11 Jan 2018 21:39:20 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Reads from NAND devices usually trigger bitflips, this is an expected
> behavior. While bitflips are under a given threshold, the MTD core
> returns 0. However, when the number of corrected bitflips is above this
> same threshold, -EUCLEAN is returned to inform the upper layer that this
> block is slightly dying and soon the ECC engine will be overtaken so
> actions should be taken to move the data out of it.
> 
> This particular condition should not be treated like an error and the
> test should continue.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Applied.

BTW, any volunteer to port this test in mtd-utils, or is there anything
in this test preventing us implementing it in userspace?

> ---
>  drivers/mtd/tests/oobtest.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c
> index 1cb3f7758fb6..766b2c385682 100644
> --- a/drivers/mtd/tests/oobtest.c
> +++ b/drivers/mtd/tests/oobtest.c
> @@ -193,6 +193,9 @@ static int verify_eraseblock(int ebnum)
>  		ops.datbuf    = NULL;
>  		ops.oobbuf    = readbuf;
>  		err = mtd_read_oob(mtd, addr, &ops);
> +		if (mtd_is_bitflip(err))
> +			err = 0;
> +
>  		if (err || ops.oobretlen != use_len) {
>  			pr_err("error: readoob failed at %#llx\n",
>  			       (long long)addr);
> @@ -227,6 +230,9 @@ static int verify_eraseblock(int ebnum)
>  			ops.datbuf    = NULL;
>  			ops.oobbuf    = readbuf;
>  			err = mtd_read_oob(mtd, addr, &ops);
> +			if (mtd_is_bitflip(err))
> +				err = 0;
> +
>  			if (err || ops.oobretlen != mtd->oobavail) {
>  				pr_err("error: readoob failed at %#llx\n",
>  						(long long)addr);
> @@ -286,6 +292,9 @@ static int verify_eraseblock_in_one_go(int ebnum)
>  
>  	/* read entire block's OOB at one go */
>  	err = mtd_read_oob(mtd, addr, &ops);
> +	if (mtd_is_bitflip(err))
> +		err = 0;
> +
>  	if (err || ops.oobretlen != len) {
>  		pr_err("error: readoob failed at %#llx\n",
>  		       (long long)addr);
> @@ -527,6 +536,9 @@ static int __init mtd_oobtest_init(void)
>  	pr_info("attempting to start read past end of OOB\n");
>  	pr_info("an error is expected...\n");
>  	err = mtd_read_oob(mtd, addr0, &ops);
> +	if (mtd_is_bitflip(err))
> +		err = 0;
> +
>  	if (err) {
>  		pr_info("error occurred as expected\n");
>  		err = 0;
> @@ -571,6 +583,9 @@ static int __init mtd_oobtest_init(void)
>  		pr_info("attempting to read past end of device\n");
>  		pr_info("an error is expected...\n");
>  		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
> +		if (mtd_is_bitflip(err))
> +			err = 0;
> +
>  		if (err) {
>  			pr_info("error occurred as expected\n");
>  			err = 0;
> @@ -615,6 +630,9 @@ static int __init mtd_oobtest_init(void)
>  		pr_info("attempting to read past end of device\n");
>  		pr_info("an error is expected...\n");
>  		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
> +		if (mtd_is_bitflip(err))
> +			err = 0;
> +
>  		if (err) {
>  			pr_info("error occurred as expected\n");
>  			err = 0;
> @@ -684,6 +702,9 @@ static int __init mtd_oobtest_init(void)
>  		ops.datbuf    = NULL;
>  		ops.oobbuf    = readbuf;
>  		err = mtd_read_oob(mtd, addr, &ops);
> +		if (mtd_is_bitflip(err))
> +			err = 0;
> +
>  		if (err)
>  			goto out;
>  		if (memcmpshow(addr, readbuf, writebuf,



From boris.brezillon at free-electrons.com  Fri Jan 12 06:08:46 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 15:08:46 +0100
Subject: [PATCH v2] MAINTAINERS: mtd/nand: update Microchip nand entry
In-Reply-To: <20180111162659.740-1-nicolas.ferre@microchip.com>
References: <20180111162659.740-1-nicolas.ferre@microchip.com>
Message-ID: <20180112150846.3b74ad67@bbrezillon>

On Thu, 11 Jan 2018 17:26:59 +0100
Nicolas Ferre <nicolas.ferre at microchip.com> wrote:

> Update Wenyou Yang email address.
> Take advantage of this update to move this entry to the MICROCHIP / ATMEL
> location and add the DT binding documentation link.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> Acked-by: Wenyou Yang <wenyou.yang at microchip.com>

Applied.

Thanks,

Boris

> ---
> v2: - patch agains 09ec417b0ea8 ("mtd: nand: samsung: Disable subpage
>       writes on E-die NAND") of 
>       http://git.infradead.org/linux-mtd.git/shortlog/refs/heads/nand/next
>     - Ack by Wenyou added
> 
> 
> Hi,
> 
> v1 patch was part of a series because it was conflicting with the previous one
> named:
> "[PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and ISC entries"
> Boris asked me to rebase it so that they are independent.
> So, if this first one goes upstream through another tree, conflicts will have
> to be resolved at one point.
> 
> Best regards,
>   Nicolas
> 
> 
>  MAINTAINERS | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index aa71ab52fd76..37ee5ae4bae2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2382,13 +2382,6 @@ F:	Documentation/devicetree/bindings/input/atmel,maxtouch.txt
>  F:	drivers/input/touchscreen/atmel_mxt_ts.c
>  F:	include/linux/platform_data/atmel_mxt_ts.h
>  
> -ATMEL NAND DRIVER
> -M:	Wenyou Yang <wenyou.yang at atmel.com>
> -M:	Josh Wu <rainyfeeling at outlook.com>
> -L:	linux-mtd at lists.infradead.org
> -S:	Supported
> -F:	drivers/mtd/nand/atmel/*
> -
>  ATMEL SAMA5D2 ADC DRIVER
>  M:	Ludovic Desroches <ludovic.desroches at microchip.com>
>  L:	linux-iio at vger.kernel.org
> @@ -9045,6 +9038,14 @@ F:	drivers/media/platform/atmel/atmel-isc.c
>  F:	drivers/media/platform/atmel/atmel-isc-regs.h
>  F:	devicetree/bindings/media/atmel-isc.txt
>  
> +MICROCHIP / ATMEL NAND DRIVER
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
> +M:	Josh Wu <rainyfeeling at outlook.com>
> +L:	linux-mtd at lists.infradead.org
> +S:	Supported
> +F:	drivers/mtd/nand/atmel/*
> +F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
> +
>  MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
>  M:	Woojung Huh <Woojung.Huh at microchip.com>
>  M:	Microchip Linux Driver Support <UNGLinuxDriver at microchip.com>



From tony at atomide.com  Fri Jan 12 06:20:50 2018
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 12 Jan 2018 06:20:50 -0800
Subject: [PATCH v6 00/14] OMAP2+ OneNAND driver update
In-Reply-To: <20180112150315.54214fab@bbrezillon>
References: <20180112131105.GA13810@lenoch>
 <20180112150315.54214fab@bbrezillon>
Message-ID: <20180112142050.GC4821@atomide.com>

* Boris Brezillon <boris.brezillon at free-electrons.com> [180112 14:03]:
> On Fri, 12 Jan 2018 14:11:05 +0100
> Ladislav Michl <ladis at linux-mips.org> wrote:
> 
> > this patch serie updates OMAP2+ OneNAND driver to the present times, making
> > it fully DT configurable, using libgpio and dmaengine apis.
> > 
> > Please note that unlike previous driver version, which basically ignored
> > DT specified timings, this one relies on it, so it is important to get
> > it right in your DT (dumping it from previous kernel version).
> > 
> > In case synchronous timings is requested, it is okay to specify timings
> > for the slowest chip ever used for you board as it is evetually optimized
> > after chip probe.
> > 
> > Original driver used DMA only if user specified INT gpio in platform
> > data, now DMA is used unconditionally and PIO mode is used as fallback.
> > 
> > In case anyone wants to give it a try, few DT related changes are needed:
> > - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
> >   done in patch 2)
> > - to use INT pin, int-gpios needs to be specified.
> 
> Roger, Tony, are you happy with this version? If this is the case, I'll
> queue all patches to my nand/next branch (after merging Roger's
> immutable branch in).

Yes thanks Aaro for testing, sounds good to me.

Regards,

Tony


From zajec5 at gmail.com  Fri Jan 12 06:40:32 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 12 Jan 2018 15:40:32 +0100
Subject: [PATCH 0/2] mtd: simplify mtd_device_parse_register code
Message-ID: <20180112144034.6655-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Even though I have some experience with MTD subsystem every time I was
starting working on it I had to do some quick research on the code flow.
I think there is some place for cleanup and optimization that would
simplify overall code and allow new developers to start working on it
more easily.

In these patches I meant to slightly simplify mtd_device_parse_register
function. I think we could reduce amount of add/register/del functions
and this is the first step for that.

Ideally I think mtdcore.c shouldn't handle parsing but just use a single
function from mtdpart.c.

Patch 1/2 modifies code to make sure parsing code is not mixed with MTD
master code. This should allow moving parsing parts to the mtdpart.c in
the future.

Patch 2/2 simplifies code and makes sure parsing is handled at 1 place
only.

Even though this cleanup isn't complete I think it already has some
value and could be accepted (if there won't be objections) on its own.
It's also quite small which should allow reviewing it easily.

Rafa? Mi?ecki (2):
  mtd: move code adding master MTD out of mtd_add_device_partitions
  mtd: get rid of the mtd_add_device_partitions function

 drivers/mtd/mtdcore.c | 45 +++++++++++++++------------------------------
 1 file changed, 15 insertions(+), 30 deletions(-)

-- 
2.11.0



From zajec5 at gmail.com  Fri Jan 12 06:40:34 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 12 Jan 2018 15:40:34 +0100
Subject: [PATCH 2/2] mtd: get rid of the mtd_add_device_partitions function
In-Reply-To: <20180112144034.6655-1-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
Message-ID: <20180112144034.6655-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This simplifies code a bit by:
1) Avoiding an extra (tiny) function
2) Checking for amount of parsed (found) partitions just once
3) Avoiding clearing/filling struct mtd_partitions manually

With this commit a proper functions are called directly from the
mtd_device_parse_register. It doesn't need to use minor tricks like
memsetting struct to 0 to trigger an expected mtd_add_device_partitions
behavior.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/mtd/mtdcore.c | 29 +++++++----------------------
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index f6460862e2ad..0a414750bc8b 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -636,21 +636,6 @@ int del_mtd_device(struct mtd_info *mtd)
 	return ret;
 }
 
-static int mtd_add_device_partitions(struct mtd_info *mtd,
-				     struct mtd_partitions *parts)
-{
-	const struct mtd_partition *real_parts = parts->parts;
-	int nbparts = parts->nr_parts;
-
-	if (nbparts == 0 && !IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-		return add_mtd_device(mtd);
-
-	if (nbparts > 0)
-		return add_mtd_partitions(mtd, real_parts, nbparts);
-
-	return 0;
-}
-
 /*
  * Set a few defaults based on the parent devices, if not provided by the
  * driver
@@ -717,19 +702,19 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
 	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
 		/* Fall back to driver-provided partitions */
-		parsed = (struct mtd_partitions){
-			.parts		= parts,
-			.nr_parts	= nr_parts,
-		};
+		ret = add_mtd_partitions(mtd, parts, nr_parts);
 	} else if (ret < 0) {
 		/* Didn't come up with parsed OR fallback partitions */
 		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
 			ret);
 		/* Don't abort on errors; we can still use unpartitioned MTD */
-		memset(&parsed, 0, sizeof(parsed));
+		if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+			ret = add_mtd_device(mtd);
+		else
+			ret = 0;
+	} else {
+		ret = add_mtd_partitions(mtd, parsed.parts, parsed.nr_parts);
 	}
-
-	ret = mtd_add_device_partitions(mtd, &parsed);
 	if (ret)
 		goto out;
 
-- 
2.11.0



From zajec5 at gmail.com  Fri Jan 12 06:40:33 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 12 Jan 2018 15:40:33 +0100
Subject: [PATCH 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180112144034.6655-1-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
Message-ID: <20180112144034.6655-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This change is a small cleanup of mtd_device_parse_register. When using
MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
dealing with partitions. There are 2 advantages of this:
1) Not mixing code handling master MTD with code handling partitions
2) Possibility of reusing mtd_parse_part in the future to avoid some
   code duplication.

This commit doesn't change any behavior except from a slightly different
failure code path. The new code may need to call del_mtd_device when
something goes wrong.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/mtd/mtdcore.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index f80e911b8843..f6460862e2ad 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
 {
 	const struct mtd_partition *real_parts = parts->parts;
 	int nbparts = parts->nr_parts;
-	int ret;
 
-	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			return ret;
-	}
+	if (nbparts == 0 && !IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+		return add_mtd_device(mtd);
 
-	if (nbparts > 0) {
-		ret = add_mtd_partitions(mtd, real_parts, nbparts);
-		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-			del_mtd_device(mtd);
-		return ret;
-	}
+	if (nbparts > 0)
+		return add_mtd_partitions(mtd, real_parts, nbparts);
 
 	return 0;
 }
@@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 
 	mtd_set_dev_defaults(mtd);
 
+	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+		ret = add_mtd_device(mtd);
+		if (ret)
+			return ret;
+	}
+
 	memset(&parsed, 0, sizeof(parsed));
 
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
@@ -753,6 +751,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 out:
 	/* Cleanup any parsed partitions */
 	mtd_part_parser_cleanup(&parsed);
+	if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+		del_mtd_device(mtd);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(mtd_device_parse_register);
-- 
2.11.0



From boris.brezillon at free-electrons.com  Fri Jan 12 06:46:39 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 15:46:39 +0100
Subject: ECC configuration of NAND from Linux  (MEMSETOOBSEL)
In-Reply-To: <2132429.fBNFCxDbQz@fessender>
References: <2132429.fBNFCxDbQz@fessender>
Message-ID: <20180112154639.63a8d133@bbrezillon>

Hello Gudjon,

On Fri, 12 Jan 2018 01:29:55 +0100
"Gudjon I. Gudjonsson" <gudjon at gudjon.org> wrote:

> Hi list
> 
> I am trying to upgrade a few embedded Linux systems remotely 
> and increasing the number of ECC bits at the same time.
> 
> I read your FAQ and found the reference to ioctl (MEMSETOOBSEL) [1]
> but it seems to be removed from the kernel.
> /*
>  * Note, the following ioctl existed in the past and was removed:
>  * #define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
>  * Try to avoid adding a new ioctl with the same ioctl number.
>  */
> I assume this is an error in the documentation but I wonder if you
> know any solution to my problem?

It's not something you can change dynamically. When you change the ECC
config, it makes existing content unreadable. In order to change this
setting you'll have to erase the whole flash and then change the ECC
config in your DT or board file (note that not all drivers support
adjusting the ECC strength/step-size).

Regards,

Boris


From boris.brezillon at free-electrons.com  Fri Jan 12 07:01:27 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:01:27 +0100
Subject: [PATCH 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180112144034.6655-2-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180112144034.6655-2-zajec5@gmail.com>
Message-ID: <20180112160127.0bfc3c57@bbrezillon>

On Fri, 12 Jan 2018 15:40:33 +0100
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This change is a small cleanup of mtd_device_parse_register. When using
> MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
> dealing with partitions. There are 2 advantages of this:
> 1) Not mixing code handling master MTD with code handling partitions
> 2) Possibility of reusing mtd_parse_part in the future to avoid some
>    code duplication.
> 
> This commit doesn't change any behavior except from a slightly different
> failure code path. The new code may need to call del_mtd_device when
> something goes wrong.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  drivers/mtd/mtdcore.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index f80e911b8843..f6460862e2ad 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
>  {
>  	const struct mtd_partition *real_parts = parts->parts;
>  	int nbparts = parts->nr_parts;
> -	int ret;
>  
> -	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
> -		ret = add_mtd_device(mtd);
> -		if (ret)
> -			return ret;
> -	}
> +	if (nbparts == 0 && !IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> +		return add_mtd_device(mtd);

Why not moving this part in mtd_device_parse_register() as well.

And I'd prefer something like:

	if (!nbparts && !device_is_registered(&mtd->dev))
		...

>  
> -	if (nbparts > 0) {
> -		ret = add_mtd_partitions(mtd, real_parts, nbparts);
> -		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> -			del_mtd_device(mtd);
> -		return ret;
> -	}
> +	if (nbparts > 0)
> +		return add_mtd_partitions(mtd, real_parts, nbparts);
>  
>  	return 0;
>  }
> @@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>  
>  	mtd_set_dev_defaults(mtd);
>  
> +	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
> +		ret = add_mtd_device(mtd);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	memset(&parsed, 0, sizeof(parsed));
>  
>  	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
> @@ -753,6 +751,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>  out:
>  	/* Cleanup any parsed partitions */
>  	mtd_part_parser_cleanup(&parsed);
> +	if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))

	if (ret && device_is_registered(&mtd->dev))

> +		del_mtd_device(mtd);

Blank line here, please.

>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(mtd_device_parse_register);



From rogerq at ti.com  Fri Jan 12 07:03:16 2018
From: rogerq at ti.com (Roger Quadros)
Date: Fri, 12 Jan 2018 17:03:16 +0200
Subject: [PATCH v6 00/14] OMAP2+ OneNAND driver update
In-Reply-To: <20180112150315.54214fab@bbrezillon>
References: <20180112131105.GA13810@lenoch>
 <20180112150315.54214fab@bbrezillon>
Message-ID: <09dc40a1-f305-4bcc-e134-8c594f454d0c@ti.com>

On 12/01/18 16:03, Boris Brezillon wrote:
> On Fri, 12 Jan 2018 14:11:05 +0100
> Ladislav Michl <ladis at linux-mips.org> wrote:
> 
>> this patch serie updates OMAP2+ OneNAND driver to the present times, making
>> it fully DT configurable, using libgpio and dmaengine apis.
>>
>> Please note that unlike previous driver version, which basically ignored
>> DT specified timings, this one relies on it, so it is important to get
>> it right in your DT (dumping it from previous kernel version).
>>
>> In case synchronous timings is requested, it is okay to specify timings
>> for the slowest chip ever used for you board as it is evetually optimized
>> after chip probe.
>>
>> Original driver used DMA only if user specified INT gpio in platform
>> data, now DMA is used unconditionally and PIO mode is used as fallback.
>>
>> In case anyone wants to give it a try, few DT related changes are needed:
>> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>>   done in patch 2)
>> - to use INT pin, int-gpios needs to be specified.
> 
> Roger, Tony, are you happy with this version? If this is the case, I'll
> queue all patches to my nand/next branch (after merging Roger's
> immutable branch in).

Yes Boris. Series looks good to me. Thanks Ladislav. Great work :)

> 
>>
>> Most notable changes from v3:
>> - added dmaengine patches by Peter Ujfalusi
>> - added dt bindings documentation
>> - added cleanup patches
>> - DMA enabled by default
>>
>> Most notable changes from v4:
>> - collected tags
>> - used INT pin name properly
>> - hopefully all comments taken into account
>>
>> Most notable changes from v5:
>> - as this serie is expected to be merged via single tree patches 13 and 14
>>   were squashed together not to break bisecting.
>> - patch 16 was dropped.
>>
>> This patchset depends on an immutable commit:
>>
>> The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
>>
>>   Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
>>
>> are available in the git repository at:
>>
>>   https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
>>
>> for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:
>>
>>   memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
>>
>>
>> Ladislav Michl (12):
>>   dt-bindings: mtd: gpmc-onenand: Update properties description
>>   ARM: dts: OMAP2+: Add compatible property to onenand node
>>   ARM: dts: omap3-igep: Update onenand node timings
>>   mtd: onenand: omap2: Remove regulator support
>>   mtd: onenand: omap2: Remove skip initial unlocking support
>>   mtd: onenand: omap2: Remove partitioning support from platform data
>>   mtd: onenand: omap2: Account waiting time as waiting on IO
>>   mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
>>   mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
>>   mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
>>   mtd: onenand: omap2: Configure driver from DT
>>   ARM: OMAP2+: Remove gpmc-onenand
>>
>> Peter Ujfalusi (2):
>>   mtd: onenand: omap2: Simplify the DMA setup for various paths
>>   mtd: onenand: omap2: Convert to use dmaengine for memcpy
>>
>>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
>>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   1 +
>>  arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
>>  arch/arm/boot/dts/omap3-n900.dts                   |   1 +
>>  arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
>>  arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
>>  arch/arm/mach-omap2/Makefile                       |   3 -
>>  arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
>>  drivers/memory/omap-gpmc.c                         | 158 ++++--
>>  drivers/mtd/onenand/Kconfig                        |   4 +-
>>  drivers/mtd/onenand/omap2.c                        | 576 ++++++++-------------
>>  include/linux/omap-gpmc.h                          |  28 +
>>  include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
>>  13 files changed, 386 insertions(+), 866 deletions(-)
>>  delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
>>  delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
>>
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


From boris.brezillon at free-electrons.com  Fri Jan 12 07:11:31 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:11:31 +0100
Subject: [PATCH 2/2] mtd: get rid of the mtd_add_device_partitions function
In-Reply-To: <20180112144034.6655-3-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180112144034.6655-3-zajec5@gmail.com>
Message-ID: <20180112161131.3cae7841@bbrezillon>

On Fri, 12 Jan 2018 15:40:34 +0100
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This simplifies code a bit by:
> 1) Avoiding an extra (tiny) function
> 2) Checking for amount of parsed (found) partitions just once
> 3) Avoiding clearing/filling struct mtd_partitions manually
> 
> With this commit a proper functions are called directly from the
> mtd_device_parse_register. It doesn't need to use minor tricks like
> memsetting struct to 0 to trigger an expected mtd_add_device_partitions
> behavior.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  drivers/mtd/mtdcore.c | 29 +++++++----------------------
>  1 file changed, 7 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index f6460862e2ad..0a414750bc8b 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -636,21 +636,6 @@ int del_mtd_device(struct mtd_info *mtd)
>  	return ret;
>  }
>  
> -static int mtd_add_device_partitions(struct mtd_info *mtd,
> -				     struct mtd_partitions *parts)
> -{
> -	const struct mtd_partition *real_parts = parts->parts;
> -	int nbparts = parts->nr_parts;
> -
> -	if (nbparts == 0 && !IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> -		return add_mtd_device(mtd);
> -
> -	if (nbparts > 0)
> -		return add_mtd_partitions(mtd, real_parts, nbparts);
> -
> -	return 0;
> -}
> -
>  /*
>   * Set a few defaults based on the parent devices, if not provided by the
>   * driver
> @@ -717,19 +702,19 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>  	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
>  	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
>  		/* Fall back to driver-provided partitions */
> -		parsed = (struct mtd_partitions){
> -			.parts		= parts,
> -			.nr_parts	= nr_parts,
> -		};
> +		ret = add_mtd_partitions(mtd, parts, nr_parts);
>  	} else if (ret < 0) {
>  		/* Didn't come up with parsed OR fallback partitions */
>  		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
>  			ret);
>  		/* Don't abort on errors; we can still use unpartitioned MTD */
> -		memset(&parsed, 0, sizeof(parsed));
> +		if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> +			ret = add_mtd_device(mtd);
> +		else
> +			ret = 0;
> +	} else {
> +		ret = add_mtd_partitions(mtd, parsed.parts, parsed.nr_parts);
>  	}

How about:

	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
	if (!ret && parsed.nr_parts) {
		parts = parsed.parts;
		nr_parts = parsed.nr_parts;
	}

	if (nr_parts)
		ret = add_mtd_partitions(mtd, parts, nr_parts);
	else if (!device_is_registered(&mtd->dev))
		ret = add_mtd_device(mtd);
	else
		ret = 0;

	...
> -
> -	ret = mtd_add_device_partitions(mtd, &parsed);
>  	if (ret)
>  		goto out;
>  



From boris.brezillon at free-electrons.com  Fri Jan 12 07:28:50 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:28:50 +0100
Subject: [PATCH 5/8] mtd: nand: mxc: Fix failed/corrected values for v1
 controllers
In-Reply-To: <20180109101148.13728-6-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-6-s.hauer@pengutronix.de>
Message-ID: <20180112162850.1fc04792@bbrezillon>

On Tue,  9 Jan 2018 11:11:45 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> The v1 controller code has several flaws:
> - We do not forward the number of corrected bitflips to the upper layers
> - For 2k page NAND chips only the status results from the fourth subpage
>   read are evaluated, so ECC failures in the other subpages remain
>   uncovered
> - When there are uncorrectable errors we have to increase the statistics
>   counter, but still have to return successfully. Currently we return
>   an error
> 
> This patch fixes this by introducing a v1 specific read_page function.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 78 +++++++++++++++++++++++++++++++++++----------
>  1 file changed, 62 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index d698f7c6666c..83bb01ab7079 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -738,22 +738,68 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
>  static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
>  				 u_char *read_ecc, u_char *calc_ecc)
>  {
> +	return 0;
> +}
> +
> +static int mxc_nand_read_page_v1(struct mtd_info *mtd, struct nand_chip *chip,
> +				 void *buf, void *oob, bool ecc, int page)
> +{
>  	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> -	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +	unsigned int max_bitflips = 0;
> +	int no_subpages;
> +	int i;
>  
> -	/*
> -	 * 1-Bit errors are automatically corrected in HW.  No need for
> -	 * additional correction.  2-Bit errors cannot be corrected by
> -	 * HW ECC, so we need to return failure
> -	 */
> -	uint16_t ecc_status = get_ecc_status_v1(host);
> +	host->devtype_data->enable_hwecc(nand_chip, ecc);
> +
> +	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	if (mtd->writesize > 512)
> +		host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true);
>  
> -	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
> -		dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n");
> -		return -EBADMSG;
> +	no_subpages = mtd->writesize >> 9;
> +
> +	for (i = 0; i < no_subpages; i++) {
> +		int flips = 0;
> +		uint16_t ecc_stats;
> +
> +		/* NANDFC buffer 0 is used for page read/write */
> +		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
> +
> +		writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2);
> +
> +		/* Wait for operation to complete */
> +		wait_op_done(host, true);
> +
> +		ecc_stats = get_ecc_status_v1(host);
> +
> +		ecc_stats >>= 2;
> +
> +		if (buf && ecc) {
> +			switch (ecc_stats & 0x3) {
> +			case 0:
> +			default:
> +				break;
> +			case 1:
> +				mtd->ecc_stats.corrected++;
> +				flips++;

Since the engine is anyway able to correct a maximum of 1 bitflip you
can get rid of flips and do:

				max_bitflips = 1;


You could even rename max_bitflips into bitflips_corrected.

> +				break;
> +			case 2:
> +				mtd->ecc_stats.failed++;
> +				break;
> +			}
> +		}
> +
> +		max_bitflips = max_t(unsigned int, max_bitflips, flips);

If you get rid of flips, this is not needed.

>  	}
>  
> -	return 0;
> +	if (buf)
> +		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
> +	if (oob)
> +		copy_spare(mtd, true, oob);
> +
> +	return max_bitflips;
>  }
>  
>  static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
> @@ -1494,6 +1540,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
>  /* v1 + irqpending_quirk: i.MX21 */
>  static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
>  	.preset = preset_v1,
> +	.read_page = mxc_nand_read_page_v1,
>  	.send_cmd = send_cmd_v1_v2,
>  	.send_addr = send_addr_v1_v2,
>  	.send_page = send_page_v1,
> @@ -1518,6 +1565,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
>  /* v1 + !irqpending_quirk: i.MX27, i.MX31 */
>  static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
>  	.preset = preset_v1,
> +	.read_page = mxc_nand_read_page_v1,
>  	.send_cmd = send_cmd_v1_v2,
>  	.send_addr = send_addr_v1_v2,
>  	.send_page = send_page_v1,
> @@ -1856,11 +1904,9 @@ static int mxcnd_probe(struct platform_device *pdev)
>  
>  	switch (this->ecc.mode) {
>  	case NAND_ECC_HW:
> -		if (host->devtype_data->read_page) {
> -			this->ecc.read_page = mxc_nand_read_page;
> -			this->ecc.read_page_raw = mxc_nand_read_page_raw;
> -			this->ecc.read_oob = mxc_nand_read_oob;
> -		}
> +		this->ecc.read_page = mxc_nand_read_page;
> +		this->ecc.read_page_raw = mxc_nand_read_page_raw;
> +		this->ecc.read_oob = mxc_nand_read_oob;
>  		this->ecc.calculate = mxc_nand_calculate_ecc;
>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;



From boris.brezillon at free-electrons.com  Fri Jan 12 07:31:10 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:31:10 +0100
Subject: [PATCH 4/8] mtd: nand: mxc: Fix failed/corrected values for
 v2/v3 controllers
In-Reply-To: <20180109101148.13728-5-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-5-s.hauer@pengutronix.de>
Message-ID: <20180112163110.27a571b7@bbrezillon>

On Tue,  9 Jan 2018 11:11:44 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> Currently nand_read_page_hwecc() from nand_base calls
> mxc_nand_correct_data_v2_v3() for each subpage, but in this function we
> return the corrected/failed results for the whole page instead
> of a single subpage. On a 2k page size Nand this leads to results which
> are 4 times too high.
> The whole ecc.calculate/ecc.correct mechanism used by
> nand_read_page_hwecc() is not suitable for devices which correct the
> data in hardware, so fix this by using a driver specific read_page
> function which does the right thing. Also add read_page_raw and read_oob
> For proper raw and oob read support.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 84 ++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 76 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index ab9cd45237d3..d698f7c6666c 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -140,6 +140,8 @@ struct mxc_nand_host;
>  
>  struct mxc_nand_devtype_data {
>  	void (*preset)(struct mtd_info *);
> +	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,

You really don't have to pass both mtd and chip, since mtd can be
extraced from chip. Just pass chip and you should be good (the same
comment apply to other patches).

> +			void *buf, void *oob, bool ecc, int page);
>  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_page)(struct mtd_info *, unsigned int);
> @@ -757,13 +759,35 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
>  static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
>  				 u_char *read_ecc, u_char *calc_ecc)
>  {
> +	return 0;
> +}
> +
> +static int mxc_nand_read_page_v2_v3(struct mtd_info *mtd, struct nand_chip *chip,
> +				    void *buf, void *oob, bool ecc, int page)
> +{
>  	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> -	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +	unsigned int max_bitflips = 0;
>  	u32 ecc_stat, err;
> -	int no_subpages = 1;
> -	int ret = 0;
> +	int no_subpages;
>  	u8 ecc_bit_mask, err_limit;
>  
> +	host->devtype_data->enable_hwecc(nand_chip, ecc);
> +
> +	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	if (mtd->writesize > 512)
> +		host->devtype_data->send_cmd(host,
> +				NAND_CMD_READSTART, true);
> +
> +	host->devtype_data->send_page(mtd, NFC_OUTPUT);
> +
> +	if (buf)
> +		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
> +	if (oob)
> +		copy_spare(mtd, true, oob);
> +
>  	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
>  	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
>  
> @@ -774,17 +798,53 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
>  	do {
>  		err = ecc_stat & ecc_bit_mask;
>  		if (err > err_limit) {
> -			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
> -			return -EBADMSG;
> +			mtd->ecc_stats.failed++;
>  		} else {
> -			ret += err;
> +			mtd->ecc_stats.corrected += err;
> +			max_bitflips = max_t(unsigned int, max_bitflips, err);
>  		}
> +
>  		ecc_stat >>= 4;
>  	} while (--no_subpages);
>  
> -	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
> +	return max_bitflips;
> +}
>  
> -	return ret;
> +static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
> +			      uint8_t *buf, int oob_required, int page)
> +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +	void *oob_buf;
> +
> +	if (oob_required)
> +		oob_buf = chip->oob_poi;
> +	else
> +		oob_buf = NULL;
> +
> +	return host->devtype_data->read_page(mtd, chip, buf, oob_buf, 1, page);
> +}
> +
> +static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
> +				  uint8_t *buf, int oob_required, int page)
> +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +	void *oob_buf;
> +
> +	if (oob_required)
> +		oob_buf = chip->oob_poi;
> +	else
> +		oob_buf = NULL;
> +
> +	return host->devtype_data->read_page(mtd, chip, buf, oob_buf, 0, page);
> +}
> +
> +static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
> +			     int page)
> +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	return host->devtype_data->read_page(mtd, chip, NULL, chip->oob_poi, 0,
> +					     page);
>  }
>  
>  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
> @@ -1483,6 +1543,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
>  /* v21: i.MX25, i.MX35 */
>  static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  	.preset = preset_v2,
> +	.read_page = mxc_nand_read_page_v2_v3,
>  	.send_cmd = send_cmd_v1_v2,
>  	.send_addr = send_addr_v1_v2,
>  	.send_page = send_page_v2,
> @@ -1509,6 +1570,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  /* v3.2a: i.MX51 */
>  static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  	.preset = preset_v3,
> +	.read_page = mxc_nand_read_page_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1535,6 +1597,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  /* v3.2b: i.MX53 */
>  static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
>  	.preset = preset_v3,
> +	.read_page = mxc_nand_read_page_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1793,6 +1856,11 @@ static int mxcnd_probe(struct platform_device *pdev)
>  
>  	switch (this->ecc.mode) {
>  	case NAND_ECC_HW:
> +		if (host->devtype_data->read_page) {
> +			this->ecc.read_page = mxc_nand_read_page;
> +			this->ecc.read_page_raw = mxc_nand_read_page_raw;
> +			this->ecc.read_oob = mxc_nand_read_oob;
> +		}
>  		this->ecc.calculate = mxc_nand_calculate_ecc;
>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;



From boris.brezillon at free-electrons.com  Fri Jan 12 07:36:49 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:36:49 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180109101148.13728-7-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-7-s.hauer@pengutronix.de>
Message-ID: <20180112163649.3103cb82@bbrezillon>

On Tue,  9 Jan 2018 11:11:46 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> Now that we have our own read_page function add a write_page function
> for consistency aswell. This can be a lot easier than the generic
> function since we do not have to iterate over subpages but can write
> the whole page at once. Also add write_page_raw and write_oob for
> proper raw and oob write support.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 83bb01ab7079..6fbf98851a96 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -893,6 +893,59 @@ static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
>  					     page);
>  }
>  
> +static int __mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,

I'm not a big fan of those '__' prefixes. How about keeping
mxc_nand_write_page() for this one, renaming the other
mxc_nand_write_page() into mxc_nand_write_page_ecc() and keeping the
other ones unchanged.

> +				 const uint8_t *buf, int oob_required, int page)

Why don't you pass a 'bool enable_ecc' argument here so that you can
directly do

	host->devtype_data->enable_hwecc(nand_chip, enable_ecc);

from here instead of duplicating it in all wrappers?

> +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	memcpy32_toio(host->main_area0, buf, mtd->writesize);
> +	copy_spare(mtd, false, chip->oob_poi);
> +
> +	host->devtype_data->send_page(mtd, NFC_INPUT);
> +	host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	return 0;
> +}
> +
> +static int mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
> +			       const uint8_t *buf, int oob_required, int page)
> +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->enable_hwecc(nand_chip, true);
> +
> +	return __mxc_nand_write_page(mtd, chip, buf, oob_required, page);
> +}
> +
> +static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
> +				   const uint8_t *buf, int oob_required, int page)
> +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->enable_hwecc(nand_chip, false);
> +
> +	return __mxc_nand_write_page(mtd, chip, buf, oob_required, page);
> +}
> +
> +static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
> +			      int page)
> +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	memset(host->data_buf, 0xff, mtd->writesize);
> +
> +	host->devtype_data->enable_hwecc(nand_chip, false);
> +
> +	return __mxc_nand_write_page(mtd, chip, host->data_buf, 1, page);
> +}
> +
>  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
>  				  u_char *ecc_code)
>  {
> @@ -1907,6 +1960,9 @@ static int mxcnd_probe(struct platform_device *pdev)
>  		this->ecc.read_page = mxc_nand_read_page;
>  		this->ecc.read_page_raw = mxc_nand_read_page_raw;
>  		this->ecc.read_oob = mxc_nand_read_oob;
> +		this->ecc.write_page = mxc_nand_write_page;
> +		this->ecc.write_page_raw = mxc_nand_write_page_raw;
> +		this->ecc.write_oob = mxc_nand_write_oob;
>  		this->ecc.calculate = mxc_nand_calculate_ecc;
>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;



From harjoc at gmail.com  Fri Jan 12 07:48:46 2018
From: harjoc at gmail.com (Bogdan Harjoc)
Date: Fri, 12 Jan 2018 17:48:46 +0200
Subject: Handle eraseblocks containing the bad-block table in UBI
Message-ID: <CAF4+tmq0km-HXGkmWtHMA_rtzYYtok6W_suTVwgJnz5qPK6ZGw@mail.gmail.com>

With some Macronix NANDs that present the bad-blocks table at a fixed
eraseblock, UBI tries to use the PEB as data and this results in the
"Bad node, ff ff ff ..." symptoms.

Should UBI receive this special status of the bbt PEBs via the
mtd_isbad() result values (in the Macronix case, mtd_block_isbad()
returns false for the PEB containing the bbt), or are 'bbt PEBs' not
supported in UBI ?

Thanks,
Bogdan Harjoc


From boris.brezillon at free-electrons.com  Fri Jan 12 07:55:21 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 12 Jan 2018 16:55:21 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
Message-ID: <20180112165521.28d17a20@bbrezillon>

On Tue,  9 Jan 2018 11:36:30 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Hi,
> 
> After the addition of the NAND framework ->exec_op() interface (see [1]
> for the series preparing it and [2] for the last version of the
> core-side implementation of ->exec_op() itself), this series replaces
> the current Marvell NAND controller driver pxa3xx_nand.c with a rework
> called marvell_nand.c.
> 
> Aside the fact that it drops the big state machine, improves the overall
> speed and implements raw accesses, it is the first driver-side
> implementation of the ->exec_op() interface and may be used as reference
> for latter reworks of the same type.
> 
> One may find more detail about why a completely new driver is needed in
> the commit log of:
> 
>     "mtd: nand: add reworked Marvell NAND controller driver"
> 
> Device tree NAND node definition for all platforms referring to the
> Marvell driver using the new bindings have already been accepted by the
> MVEBU DT maintainers and will be merged after the driver. They are more
> hierarchical and fit the real organization of the hardware, by having
> NAND partitions that are part of NAND chip nodes, themselves part of the
> NAND controller node.
> 
> These changes have been tested on:
>    - PXA3xx platform with a CM-X300 board (2kiB page NAND, 1b/512B
>      strength, Hamming ECC engine) [32 bits]
>    - Armada 385 DB AP (4kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
>    - Armada 398 DB (4kiB page NAND, 8b/512B, BCH ECC engine using a layout
>      with a last chunk different than the others) [32 bits]
>    - Armada 7040 DB and Armada 8040 DB (4kiB page NAND, 4b/512B, BCH ECC
>      engine) [64 bits]
>    - Triax dvb-tc board (2kiB page NAND, 4b/512B, BCH ECC engine) [32 bits]
> 
> This version is known not to be stable yet with a Zylonite based setup but
> otherwise looks good for Marvell EBU platforms.
> 
> For people who would like to test it easily, a branch ready to be tested
> is available at [3]. It is based on nand/next and has all the changes
> brought by the previously mentionned series as well as this one.
> 
> Thank you,
> Miqu?l
> 
> 
> [1] https://www.spinics.net/lists/arm-kernel/msg619633.html
> [2] http://lists.infradead.org/pipermail/linux-mtd/2017-December/077965.html
> [3] https://github.com/miquelraynal/linux/tree/marvell/nand-next/nfc
> 
> 
> Changes since v2:
>   - Added a patch to create the nand-rb property in the Documentation
>   - Rewording in the Documentation according to Rob's comments
>   - Moved from marvell,rb to nand-rb property in the code
>   - Disociated using this driver with Marvell EBU platforms than using
>     it with PXA ones
>   - Fixed the handling of 16-bit buses
>   - Fixed SPDX comment style
>   - Reorganized registers offsets/bit fields definitions as requested
>   - Moved to Kernel doc
>   - Changed the logic in ->select_chip() to use a prepared value of NDCR
>     only instead of recalculating it
>   - Fixed the presence of the SPARE_EN bit, reworked a bit the
>     hmg_do_read/write() helpers
>   - Fixed the OOB layouts that were unusable (all spare data first, then
>     all ECC bytes)
>   - Additional check on mtd->writesize when using NFCv1 (all sizes not
>     supported)
>   - Various typos/rewording
> 
> Changes since v1:
>   - Rewording
>   - Fixed BCH ->read/write_page() hooks for 2kiB pages NAND chips
>   - Removed license text, used SPDX tag instead
>   - Removed read_page_data()
>   - Enhanced the DT bindings document with the label property and the
>     deprecated bindings.
>   - Simplified the read_chunk() helper (OOB always read).
>   - Simplified the ->bch_read_page() hook by removing the addition raw
>     read to get ECC bytes.
>   - Fixed the ->correct() function that did not check for bitflips in
>     ECC bytes in erased pages.
> 
> 
> Miquel Raynal (7):
>   dt-bindings: mtd: document new nand-rb property
>   dt-bindings: mtd: add Marvell NAND controller documentation
>   mtd: nand: add reworked Marvell NAND controller driver
>   mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs

Applied patches 1 to 4.

Can you please send a patch to add a new entry in MAINTAINERS for this
driver?

Thanks,

Boris

>   mtd: nand: use Marvell reworked NAND controller driver with all
>     platforms
>   dt-bindings: mtd: remove pxa3xx NAND controller documentation
>   mtd: nand: remove useless fields from pxa3xx NAND platform data
> 
>  .../devicetree/bindings/mtd/marvell-nand.txt       |  123 +
>  Documentation/devicetree/bindings/mtd/nand.txt     |    1 +
>  .../devicetree/bindings/mtd/pxa3xx-nand.txt        |   50 -
>  arch/arm/configs/cm_x300_defconfig                 |    2 +-
>  arch/arm/configs/mvebu_v7_defconfig                |    2 +-
>  arch/arm/configs/pxa3xx_defconfig                  |    3 +-
>  arch/arm/configs/pxa_defconfig                     |    2 +-
>  arch/arm/configs/raumfeld_defconfig                |    2 +-
>  arch/arm/mach-mmp/ttc_dkb.c                        |    4 +-
>  arch/arm/mach-pxa/cm-x300.c                        |    8 +-
>  arch/arm/mach-pxa/colibri-pxa3xx.c                 |    8 +-
>  arch/arm/mach-pxa/colibri.h                        |    2 +-
>  arch/arm/mach-pxa/littleton.c                      |   10 +-
>  arch/arm/mach-pxa/mxm8x10.c                        |   10 +-
>  arch/arm/mach-pxa/raumfeld.c                       |    6 +-
>  arch/arm/mach-pxa/zylonite.c                       |   10 +-
>  arch/arm64/configs/defconfig                       |    2 +-
>  drivers/mtd/nand/Kconfig                           |   18 +-
>  drivers/mtd/nand/Makefile                          |    2 +-
>  drivers/mtd/nand/marvell_nand.c                    | 2896 ++++++++++++++++++++
>  drivers/mtd/nand/pxa3xx_nand.c                     | 2104 --------------
>  include/linux/platform_data/mtd-nand-pxa3xx.h      |   43 +-
>  22 files changed, 3072 insertions(+), 2236 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
>  delete mode 100644 Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
>  create mode 100644 drivers/mtd/nand/marvell_nand.c
>  delete mode 100644 drivers/mtd/nand/pxa3xx_nand.c
> 



From nicolas.ferre at microchip.com  Fri Jan 12 08:35:32 2018
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Fri, 12 Jan 2018 17:35:32 +0100
Subject: [PATCH 1/2] MAINTAINERS: linux-media: update Microchip ISI and
 ISC entries
In-Reply-To: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
References: <eb6b3cbe8e48faee7e88eca0649e42cbde91ffa6.1515503733.git.nicolas.ferre@microchip.com>
Message-ID: <701274f4-8006-132b-37ee-22cb374c6f62@microchip.com>

On 09/01/2018 at 14:46, Nicolas Ferre wrote:
> These two image capture interface drivers are now handled
> by Wenyou Yang.
> I benefit from this change to update the two entries by correcting the
> binding documentation link for ISC and moving the ISI to the new
> MICROCHIP / ATMEL location.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> ---
> Hi,
> 
> Patch against next-20180109.
> Note that I didn't find it useful to have several patches for these changes.
> Tell me if you feel differently.
> 
> I would like to have the Ack from Ludovic and Wenyou obviously. I don't know if
> Songjun can answer as he's not with Microchip anymore.

Update on this patch:

Boris took the second patch of the series through NAND/MTD tree so this
one can go alone upstream through the linux-media tree.
I also have the 2 required Ack.

So, do you want me to re-send this one independently or should we wait
for 4.16-rc1?

Best regards,
  Nicolas

>  MAINTAINERS | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a7d10a2bb980..65c4b59b582f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2353,13 +2353,6 @@ L:	linux-i2c at vger.kernel.org
>  S:	Supported
>  F:	drivers/i2c/busses/i2c-at91.c
>  
> -ATMEL ISI DRIVER
> -M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> -L:	linux-media at vger.kernel.org
> -S:	Supported
> -F:	drivers/media/platform/atmel/atmel-isi.c
> -F:	include/media/atmel-isi.h
> -
>  ATMEL LCDFB DRIVER
>  M:	Nicolas Ferre <nicolas.ferre at microchip.com>
>  L:	linux-fbdev at vger.kernel.org
> @@ -9102,12 +9095,20 @@ S:	Maintained
>  F:	drivers/crypto/atmel-ecc.*
>  
>  MICROCHIP / ATMEL ISC DRIVER
> -M:	Songjun Wu <songjun.wu at microchip.com>
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
>  L:	linux-media at vger.kernel.org
>  S:	Supported
>  F:	drivers/media/platform/atmel/atmel-isc.c
>  F:	drivers/media/platform/atmel/atmel-isc-regs.h
> -F:	devicetree/bindings/media/atmel-isc.txt
> +F:	Documentation/devicetree/bindings/media/atmel-isc.txt
> +
> +MICROCHIP / ATMEL ISI DRIVER
> +M:	Wenyou Yang <wenyou.yang at microchip.com>
> +L:	linux-media at vger.kernel.org
> +S:	Supported
> +F:	drivers/media/platform/atmel/atmel-isi.c
> +F:	include/media/atmel-isi.h
> +F:	Documentation/devicetree/bindings/media/atmel-isi.txt
>  
>  MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
>  M:	Woojung Huh <Woojung.Huh at microchip.com>
> 


-- 
Nicolas Ferre


From robert.jarzmik at free.fr  Fri Jan 12 08:43:52 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 12 Jan 2018 17:43:52 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180112112108.2e20dc14@bbrezillon> (Boris Brezillon's message
 of "Fri, 12 Jan 2018 11:21:08 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon> <876087beui.fsf@belgarion.home>
 <20180112112108.2e20dc14@bbrezillon>
Message-ID: <871sivauyf.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> I think I'm still missing something. If I look at the branch you just
> pushed, I see that ->flash_bbt was not set to 1 before this commit [1],
> which means the pxa3xx driver was no setting the NAND_BBT_USE_FLASH
> flag, which in turn means you were not using the on-flash-bbt.
> When you test the old (pxa3xx) driver, are you sure you're testing
> things with a mainline kernel? If you have extra commits on top of
> mainline, can you push them somewhere?

Here is the branch I'm using with my pxa3xx driver :
git fetch https://github.com/rjarzmik/linux pxa3xx-test

Cheers.

-- 
Robert


From miquel.raynal at free-electrons.com  Fri Jan 12 10:21:42 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 12 Jan 2018 19:21:42 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180111222833.GA15584@1wt.eu>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111222833.GA15584@1wt.eu>
Message-ID: <20180112192142.6541edf4@xps13>

Hello Willy,

On Thu, 11 Jan 2018 23:28:33 +0100
Willy Tarreau <w at 1wt.eu> wrote:

> Hi Miquel,
> 
> On Tue, Jan 09, 2018 at 11:36:30AM +0100, Miquel Raynal wrote:
> > These changes have been tested on:
> >    - PXA3xx platform with a CM-X300 board (2kiB page NAND, 1b/512B
> >      strength, Hamming ECC engine) [32 bits]
> >    - Armada 385 DB AP (4kiB page NAND, 4b/512B, BCH ECC engine) [32
> > bits]
> >    - Armada 398 DB (4kiB page NAND, 8b/512B, BCH ECC engine using a
> > layout with a last chunk different than the others) [32 bits]
> >    - Armada 7040 DB and Armada 8040 DB (4kiB page NAND, 4b/512B,
> > BCH ECC engine) [64 bits]
> >    - Triax dvb-tc board (2kiB page NAND, 4b/512B, BCH ECC engine)
> > [32 bits]  
> 
> If you're interested, I have a mirabox with an armada 370 which uses
> the same driver. I've not powered it up for a while but if that can
> be useful I can try to find some time for this.

Thank you very much for the proposal!

For the moment I don't think there is a need as this type of platform
has already been tested, but I keep it in mind.

Thanks again!
Miqu?l


From gudjon at gudjon.org  Fri Jan 12 10:50:00 2018
From: gudjon at gudjon.org (Gudjon I. Gudjonsson)
Date: Fri, 12 Jan 2018 19:50:00 +0100
Subject: ECC configuration of NAND from Linux  (MEMSETOOBSEL)
In-Reply-To: <20180112154639.63a8d133@bbrezillon>
References: <2132429.fBNFCxDbQz@fessender> <20180112154639.63a8d133@bbrezillon>
Message-ID: <2581607.A7Zl2yeV5U@fessender>

Hi Boris

Thanks for the answer.
> > I read your FAQ and found the reference to ioctl (MEMSETOOBSEL) [1]
> > but it seems to be removed from the kernel.
> > /*
> >  * Note, the following ioctl existed in the past and was removed:
> >  * #define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
> >  * Try to avoid adding a new ioctl with the same ioctl number.
> >  */
> > I assume this is an error in the documentation but I wonder if you
> > know any solution to my problem?
> 
> It's not something you can change dynamically. When you change the ECC
> config, it makes existing content unreadable. In order to change this
> setting you'll have to erase the whole flash and then change the ECC
> config in your DT or board file (note that not all drivers support
> adjusting the ECC strength/step-size).
I will have to accept that but can you please tell me how to change the
ECC strength if my driver supports it? My plan is to use swupdate and
update the system using an SD-card that is already installed but I could
not find any reference to changing the ECC strength.
I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp 
NAND flash. 

Regards
Gudjon


From robert.jarzmik at free.fr  Fri Jan 12 12:44:27 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 12 Jan 2018 21:44:27 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180112105228.176ab80f@bbrezillon> (Boris Brezillon's message
 of "Fri, 12 Jan 2018 10:52:28 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon> <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon>
Message-ID: <87wp0majtg.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> On Fri, 12 Jan 2018 10:34:13 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
>
>> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> Because we though scanning of BBMs was working with the old pxa driver
> (which should be the case for your setup, BTW), and we thought the new
> driver was introducing a regression here.
That's what happens :
 - flash_bbt=1 with old driver => everything works fine
 - flash_bbt=1 with marvell_nand => BBT is damaged (or so I believe from
   Miquel's analysis)

> BTW, did you ever try with the old driver and ->flash_bbt = false? If
> you did not, can you test?
Sure, just did, same behavior as with marvell_nand :
 - bad erase blocks (almost) everywhere
 - ubifs error

>> I think we're still not aligned here. There are _no_ bad block markers in the
>> OOB on my flash, because there is a BBT at the end.
>
> That's not how it works. The BBT is a way to get information about bad
> blocks within a single read access, but, if you can preserve BBMs and
> keep them updated (which is the case here), you should do it, just in
> case you lose the BBT.
You're probably right today. But this assertion is probably wrong for system
created in early 2000s ... :)

>> > So, the symptoms we're seeing here, where almost all blocks are reported as
>> > bad when scanning BBMs, is not expected, and that's what we're trying to
>> > debug/fix.  
>> Well, I still think this is not something to fix ... I still think that OOB data
>> is not relevant as to the state of bad blocks in my flash ...
>
> Hm, I disagree. What if, for any reason, the BBT is lost? Don't you
> want the full scan to work?
If the BBT is lost, you have the mirror BBT, it's its purpose.

> Okay, so I have another solution for that: drop the NAND_BBT_CREATE and
> NAND_BBT_WRITE here [1] and here [2]. That should let you read the
> existing BBT without updating it or creating a new one if it's not
> detected.
Okay, let's try the marvell-nand-bug branch with this included.
It works :
[   18.302123] ubi0: attached mtd5 (name "root", size 37 MiB)
[   18.307691] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[   18.315003] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[   18.322155] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[   18.329167] ubi0: good PEBs: 297, bad PEBs: 0, corrupted PEBs: 0
[   18.335789] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[   18.343409] ubi0: max/mean erase counter: 6/4, WL threshold: 4096, image sequence number: 30621
[   18.352460] ubi0: available PEBs: 0, total reserved PEBs: 297, PEBs reserved for bad PEB handling: 40
[   18.361937] ubi0: background thread "ubi_bgt0d" started, PID 411

That means the BBT reading is the issue don't you think ?

Now if I keep NAND_BBT_CREATE but remove NAND_BBT_WRITE same thing, it works as
well. That leaves only the re-enabling of the BBT write, which I'll do as soon
as you tell me my NAND won't be damaged.

Cheers.

-- 
Robert


From richard.weinberger at gmail.com  Fri Jan 12 12:52:25 2018
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Fri, 12 Jan 2018 21:52:25 +0100
Subject: Handle eraseblocks containing the bad-block table in UBI
In-Reply-To: <CAF4+tmq0km-HXGkmWtHMA_rtzYYtok6W_suTVwgJnz5qPK6ZGw@mail.gmail.com>
References: <CAF4+tmq0km-HXGkmWtHMA_rtzYYtok6W_suTVwgJnz5qPK6ZGw@mail.gmail.com>
Message-ID: <CAFLxGvxnEszGhC96=MB+Xmvv02A0A0WLY45Mf_dmWUKg2iKgfA@mail.gmail.com>

Bogdan,

On Fri, Jan 12, 2018 at 4:48 PM, Bogdan Harjoc <harjoc at gmail.com> wrote:
> With some Macronix NANDs that present the bad-blocks table at a fixed
> eraseblock, UBI tries to use the PEB as data and this results in the
> "Bad node, ff ff ff ..." symptoms.
>
> Should UBI receive this special status of the bbt PEBs via the
> mtd_isbad() result values (in the Macronix case, mtd_block_isbad()
> returns false for the PEB containing the bbt), or are 'bbt PEBs' not
> supported in UBI ?

Usually blocks containing the BBT are also marked as bad to avoid the
problem you're facing.
So, yes UBI should not see these PEBs because they should look like bad blocks.

Is this a kernel with vendor hackery?

-- 
Thanks,
//richard


From derosier at gmail.com  Fri Jan 12 18:41:58 2018
From: derosier at gmail.com (Steve deRosier)
Date: Fri, 12 Jan 2018 18:41:58 -0800
Subject: ECC configuration of NAND from Linux (MEMSETOOBSEL)
In-Reply-To: <2581607.A7Zl2yeV5U@fessender>
References: <2132429.fBNFCxDbQz@fessender> <20180112154639.63a8d133@bbrezillon>
 <2581607.A7Zl2yeV5U@fessender>
Message-ID: <CALLGbRJ9SipkxtNiCigrPHQim5C38uq9EVsYK3WS_HN3aW-pqg@mail.gmail.com>

Hi Gudjon,

On Fri, Jan 12, 2018 at 10:50 AM, Gudjon I. Gudjonsson
<gudjon at gudjon.org> wrote:
> > setting you'll have to erase the whole flash and then change the ECC
> > config in your DT or board file (note that not all drivers support
> > adjusting the ECC strength/step-size).
> I will have to accept that but can you please tell me how to change the
> ECC strength if my driver supports it? My plan is to use swupdate and
> update the system using an SD-card that is already installed but I could
> not find any reference to changing the ECC strength.
> I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp
> NAND flash.
>

I might be wrong, but I don't think there's any mechanism to change
the ECC strength on the fly with that processor and flash combination.
In order to do it, you have to adjust it in your device-tree. I went
through this in an upgrade scenario on a similar system a few years
ago and came to the conclusion that it wasn't viable. As a matter of
background, we had two spots on flash for the kernel (kernel-a,
kernel-b), and two for a rootfs that was a UBIFS (rootfs-a, rootfs-b).
Our upgrade procedure was to run on -a, and flash -b.  Next time, run
on -b and flash on -a, etc... To do it, here's what would have had to
be done:

1. Change the ECC strength in the DT, which then gets appended to the
the kernel image. Which means when the new kernel boots the new ECC
takes effect and not before. Note that the kernel that is running is
using the whatever ECC it was set for.
2. Change our update script to _not_ write the ECC bits when it
flashes... this is critical.
3. Now, (assuming running on -a partitions), erase kernel-b, rootfs-b.
Then flash the new kernel and new rootfs to the -b partitions
_with_out_ ECC bits!
4. Reboot to -b partitions. Note that you're now running a kernel
supporting the new ECC layout, but without any ECC actually being
performed.
5. Now, erase and reflash -a with the same new kernel and rootfs
_with_ ECC bits.
6. Boot to -a. Now you're running with the new ECC layout and with ECC
actually being done.

I'm going from memory, so I might have missed a step or done something
out of order, but you get the point. Now, why all of the above?  The
problem is the number of ECC bits that gets flashed is dependent on
the kernel running flashing it. So, having a kernel running 4 bits
trying to flash 8, doesn't work.  The solution is by forcing all the
written ECC bits to 0xffs by turing off the ECC bits when flashing
with nandwrite. The kernel will read and ignore ECC, no matter the set
strength, if there's no ECC bits set.  So, essentially, you have to
write the new stuff with the enhanced bits with no bits actually
written, in order to boot into it and then write it correctly a second
time.

Additionally, you got to remember to include the boot-loaders, so
bootstrap+uboot also need to be changed, upgraded, etc.  And, if
you've got a mix of versions out there, managing them and freely
allowing upgrades and downgrades becomes a headache too.  It's easier
if you don't have to boot into the kernel+rootfs and choose an upgrade
process that leverages u-boot, but our system didn't work that way. I
also came up with a number of other options, but they're not worth
detailing here and they were also a pain and risky to implement.

Basically, it's a major pain and since we were already using the
recommended minimum for our MT29Fxxxxxx flash, we left it alone. And
honestly, we haven't had any significant problems with the flash that
could be attributed to ECC strength.

All that said - this was a few years ago, and on a 3.8 kernel, running
bootstrap and u-boot and running the rootfs directly out of flash on
UBIFS. And we were running our own software update program that wasn't
very sophisticated. So, your situation may be different and or there
might be more options available now on newer kernels.

Hopefully that story helps a bit.

- Steve

Steve deRosier
Cal-Sierra Consulting LLC
https://www.cal-sierra.com/


From boris.brezillon at free-electrons.com  Sat Jan 13 00:24:43 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 13 Jan 2018 09:24:43 +0100
Subject: ECC configuration of NAND from Linux (MEMSETOOBSEL)
In-Reply-To: <CALLGbRJ9SipkxtNiCigrPHQim5C38uq9EVsYK3WS_HN3aW-pqg@mail.gmail.com>
References: <2132429.fBNFCxDbQz@fessender> <20180112154639.63a8d133@bbrezillon>
 <2581607.A7Zl2yeV5U@fessender>
 <CALLGbRJ9SipkxtNiCigrPHQim5C38uq9EVsYK3WS_HN3aW-pqg@mail.gmail.com>
Message-ID: <20180113092443.6222f2bf@bbrezillon>

On Fri, 12 Jan 2018 18:41:58 -0800
Steve deRosier <derosier at gmail.com> wrote:

> Hi Gudjon,
> 
> On Fri, Jan 12, 2018 at 10:50 AM, Gudjon I. Gudjonsson
> <gudjon at gudjon.org> wrote:
> > > setting you'll have to erase the whole flash and then change the ECC
> > > config in your DT or board file (note that not all drivers support
> > > adjusting the ECC strength/step-size).  
> > I will have to accept that but can you please tell me how to change the
> > ECC strength if my driver supports it? My plan is to use swupdate and
> > update the system using an SD-card that is already installed but I could
> > not find any reference to changing the ECC strength.
> > I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp
> > NAND flash.
> >  
> 
> I might be wrong, but I don't think there's any mechanism to change
> the ECC strength on the fly with that processor and flash combination.
> In order to do it, you have to adjust it in your device-tree. I went
> through this in an upgrade scenario on a similar system a few years
> ago and came to the conclusion that it wasn't viable. As a matter of
> background, we had two spots on flash for the kernel (kernel-a,
> kernel-b), and two for a rootfs that was a UBIFS (rootfs-a, rootfs-b).
> Our upgrade procedure was to run on -a, and flash -b.  Next time, run
> on -b and flash on -a, etc... To do it, here's what would have had to
> be done:
> 
> 1. Change the ECC strength in the DT, which then gets appended to the
> the kernel image. Which means when the new kernel boots the new ECC
> takes effect and not before. Note that the kernel that is running is
> using the whatever ECC it was set for.
> 2. Change our update script to _not_ write the ECC bits when it
> flashes... this is critical.
> 3. Now, (assuming running on -a partitions), erase kernel-b, rootfs-b.
> Then flash the new kernel and new rootfs to the -b partitions
> _with_out_ ECC bits!
> 4. Reboot to -b partitions. Note that you're now running a kernel
> supporting the new ECC layout, but without any ECC actually being
> performed.
> 5. Now, erase and reflash -a with the same new kernel and rootfs
> _with_ ECC bits.
> 6. Boot to -a. Now you're running with the new ECC layout and with ECC
> actually being done.
> 
> I'm going from memory, so I might have missed a step or done something
> out of order, but you get the point. Now, why all of the above?  The
> problem is the number of ECC bits that gets flashed is dependent on
> the kernel running flashing it. So, having a kernel running 4 bits
> trying to flash 8, doesn't work.  The solution is by forcing all the
> written ECC bits to 0xffs by turing off the ECC bits when flashing
> with nandwrite. The kernel will read and ignore ECC, no matter the set
> strength, if there's no ECC bits set.

That's not true. If you have all ECC bytes set to 0xff it will simply
not boot (or at least it should not), because the ECC engine will report
errors everywhere.

> So, essentially, you have to
> write the new stuff with the enhanced bits with no bits actually
> written, in order to boot into it and then write it correctly a second
> time.

And this trick only works if your NAND supports subpage writes.

> 
> Additionally, you got to remember to include the boot-loaders, so
> bootstrap+uboot also need to be changed, upgraded, etc.  And, if
> you've got a mix of versions out there, managing them and freely
> allowing upgrades and downgrades becomes a headache too.  It's easier
> if you don't have to boot into the kernel+rootfs and choose an upgrade
> process that leverages u-boot, but our system didn't work that way. I
> also came up with a number of other options, but they're not worth
> detailing here and they were also a pain and risky to implement.
> 
> Basically, it's a major pain and since we were already using the
> recommended minimum for our MT29Fxxxxxx flash, we left it alone. And
> honestly, we haven't had any significant problems with the flash that
> could be attributed to ECC strength.

That is true. Once you have chosen a specific strength, it's not easy
to change it: you have to erase everything and write it again with a
different config.

> 
> All that said - this was a few years ago, and on a 3.8 kernel, running
> bootstrap and u-boot and running the rootfs directly out of flash on
> UBIFS. And we were running our own software update program that wasn't
> very sophisticated. So, your situation may be different and or there
> might be more options available now on newer kernels.
> 
> Hopefully that story helps a bit.
> 
> - Steve
> 
> Steve deRosier
> Cal-Sierra Consulting LLC
> https://www.cal-sierra.com/



From boris.brezillon at free-electrons.com  Sat Jan 13 00:38:07 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 13 Jan 2018 09:38:07 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87wp0majtg.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon>
 <87wp0majtg.fsf@belgarion.home>
Message-ID: <20180113093807.3984c184@bbrezillon>

Hello Robert,

On Fri, 12 Jan 2018 21:44:27 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > On Fri, 12 Jan 2018 10:34:13 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Boris Brezillon <boris.brezillon at free-electrons.com> writes:  
> > Because we though scanning of BBMs was working with the old pxa driver
> > (which should be the case for your setup, BTW), and we thought the new
> > driver was introducing a regression here.  
> That's what happens :
>  - flash_bbt=1 with old driver => everything works fine
>  - flash_bbt=1 with marvell_nand => BBT is damaged (or so I believe from
>    Miquel's analysis)

It shouldn't be damaged anymore. The bug has been fixed just before we
asked you to scrub the BBT area.

> 
> > BTW, did you ever try with the old driver and ->flash_bbt = false? If
> > you did not, can you test?  
> Sure, just did, same behavior as with marvell_nand :
>  - bad erase blocks (almost) everywhere
>  - ubifs error

That's a relief!

> 
> >> I think we're still not aligned here. There are _no_ bad block markers in the
> >> OOB on my flash, because there is a BBT at the end.  
> >
> > That's not how it works. The BBT is a way to get information about bad
> > blocks within a single read access, but, if you can preserve BBMs and
> > keep them updated (which is the case here), you should do it, just in
> > case you lose the BBT.  
> You're probably right today. But this assertion is probably wrong for system
> created in early 2000s ... :)

I can't say, but I recommend patching the component that screw up BBMs
in your setup anyway. It's probably not the kernel since Miquel tested
the transition from the old to the new driver without activating the
on-flash-bbt on his pxa boards, and all BBMs were preserved.

So, it's either barebox or another component you use to program things.

> 
> >> > So, the symptoms we're seeing here, where almost all blocks are reported as
> >> > bad when scanning BBMs, is not expected, and that's what we're trying to
> >> > debug/fix.    
> >> Well, I still think this is not something to fix ... I still think that OOB data
> >> is not relevant as to the state of bad blocks in my flash ...  
> >
> > Hm, I disagree. What if, for any reason, the BBT is lost? Don't you
> > want the full scan to work?  
> If the BBT is lost, you have the mirror BBT, it's its purpose.

If both are lost, you're screwed.

> 
> > Okay, so I have another solution for that: drop the NAND_BBT_CREATE and
> > NAND_BBT_WRITE here [1] and here [2]. That should let you read the
> > existing BBT without updating it or creating a new one if it's not
> > detected.  
> Okay, let's try the marvell-nand-bug branch with this included.
> It works :
> [   18.302123] ubi0: attached mtd5 (name "root", size 37 MiB)
> [   18.307691] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> [   18.315003] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> [   18.322155] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
> [   18.329167] ubi0: good PEBs: 297, bad PEBs: 0, corrupted PEBs: 0
> [   18.335789] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
> [   18.343409] ubi0: max/mean erase counter: 6/4, WL threshold: 4096, image sequence number: 30621
> [   18.352460] ubi0: available PEBs: 0, total reserved PEBs: 297, PEBs reserved for bad PEB handling: 40
> [   18.361937] ubi0: background thread "ubi_bgt0d" started, PID 411
> 
> That means the BBT reading is the issue don't you think ?

The BBT detection issue has already been fixed with Miquel's previous
version. So there shouldn't be any issue with that anymore, and your
results tend to confirm that.

> 
> Now if I keep NAND_BBT_CREATE but remove NAND_BBT_WRITE same thing, it works as
> well. That leaves only the re-enabling of the BBT write, which I'll do as soon
> as you tell me my NAND won't be damaged.

It won't, you can safely re-enable NAND_BBT_WRITE. The one that was
causing trouble previously was NAND_BBT_CREATE, because the BBT was not
found, and the NAND framework was creating a new one after scanning
BBMs, which led to the situation you reported: BBT reporting all blocks
as bad.

Thanks for helping us with this bug, I think we're close to a fully
working situation now.

Regards,

Boris


From boris.brezillon at free-electrons.com  Sat Jan 13 00:38:55 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 13 Jan 2018 09:38:55 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <871sivauyf.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112112108.2e20dc14@bbrezillon>
 <871sivauyf.fsf@belgarion.home>
Message-ID: <20180113093855.49231a43@bbrezillon>

On Fri, 12 Jan 2018 17:43:52 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > I think I'm still missing something. If I look at the branch you just
> > pushed, I see that ->flash_bbt was not set to 1 before this commit [1],
> > which means the pxa3xx driver was no setting the NAND_BBT_USE_FLASH
> > flag, which in turn means you were not using the on-flash-bbt.
> > When you test the old (pxa3xx) driver, are you sure you're testing
> > things with a mainline kernel? If you have extra commits on top of
> > mainline, can you push them somewhere?  
> 
> Here is the branch I'm using with my pxa3xx driver :
> git fetch https://github.com/rjarzmik/linux pxa3xx-test

May I ask why this is not in mainline?


From miquel.raynal at free-electrons.com  Sat Jan 13 02:54:10 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Sat, 13 Jan 2018 11:54:10 +0100
Subject: [PATCH] MAINTAINERS: Add entry for Marvell NAND controller driver
Message-ID: <20180113105410.2555-1-miquel.raynal@free-electrons.com>

Add entry for Marvell NAND controller driver and its bindings which will
soon replace the old driver pxa3xx_nand.c.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa71ab52fd76..ca8bb8077e70 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8409,6 +8409,13 @@ L:	linux-wireless at vger.kernel.org
 S:	Odd Fixes
 F:	drivers/net/wireless/marvell/mwl8k.c
 
+MARVELL NAND CONTROLLER DRIVER
+M:	Miquel Raynal <miquel.raynal at free-electrons.com>
+L:	linux-mtd at lists.infradead.org
+S:	Maintained
+F:	drivers/mtd/nand/marvell_nand.c
+F:	Documentation/devicetree/bindings/mtd/marvell-nand.txt
+
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
 M:	Nicolas Pitre <nico at fluxnic.net>
 S:	Odd Fixes
-- 
2.11.0



From miquel.raynal at free-electrons.com  Sat Jan 13 03:05:29 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Sat, 13 Jan 2018 12:05:29 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180113093807.3984c184@bbrezillon>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon>
 <87wp0majtg.fsf@belgarion.home>
 <20180113093807.3984c184@bbrezillon>
Message-ID: <20180113120529.2f00ea20@xps13>

Hello,

On Sat, 13 Jan 2018 09:38:07 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hello Robert,
> 
> On Fri, 12 Jan 2018 21:44:27 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> 
> > Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> >   
> > > On Fri, 12 Jan 2018 10:34:13 +0100
> > > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> > >    
> > >> Boris Brezillon <boris.brezillon at free-electrons.com> writes:    
> > > Because we though scanning of BBMs was working with the old pxa
> > > driver (which should be the case for your setup, BTW), and we
> > > thought the new driver was introducing a regression here.    
> > That's what happens :
> >  - flash_bbt=1 with old driver => everything works fine
> >  - flash_bbt=1 with marvell_nand => BBT is damaged (or so I believe
> > from Miquel's analysis)  
> 
> It shouldn't be damaged anymore. The bug has been fixed just before we
> asked you to scrub the BBT area.
> 
> >   
> > > BTW, did you ever try with the old driver and ->flash_bbt =
> > > false? If you did not, can you test?    
> > Sure, just did, same behavior as with marvell_nand :
> >  - bad erase blocks (almost) everywhere
> >  - ubifs error  
> 
> That's a relief!

Indeed, it is!

> 
> >   
> > >> I think we're still not aligned here. There are _no_ bad block
> > >> markers in the OOB on my flash, because there is a BBT at the
> > >> end.    
> > >
> > > That's not how it works. The BBT is a way to get information
> > > about bad blocks within a single read access, but, if you can
> > > preserve BBMs and keep them updated (which is the case here), you
> > > should do it, just in case you lose the BBT.    
> > You're probably right today. But this assertion is probably wrong
> > for system created in early 2000s ... :)  
> 
> I can't say, but I recommend patching the component that screw up BBMs
> in your setup anyway. It's probably not the kernel since Miquel tested
> the transition from the old to the new driver without activating the
> on-flash-bbt on his pxa boards, and all BBMs were preserved.
> 
> So, it's either barebox or another component you use to program
> things.
> 
> >   
> > >> > So, the symptoms we're seeing here, where almost all blocks
> > >> > are reported as bad when scanning BBMs, is not expected, and
> > >> > that's what we're trying to debug/fix.      
> > >> Well, I still think this is not something to fix ... I still
> > >> think that OOB data is not relevant as to the state of bad
> > >> blocks in my flash ...    
> > >
> > > Hm, I disagree. What if, for any reason, the BBT is lost? Don't
> > > you want the full scan to work?    
> > If the BBT is lost, you have the mirror BBT, it's its purpose.  
> 
> If both are lost, you're screwed.

And when you encounter a driver problem, it is very likely that both
will be smashed, as it happened this week. Now I better understand why
you feared loosing the BBT again: it forces you to recreate it by hand.

> 
> >   
> > > Okay, so I have another solution for that: drop the
> > > NAND_BBT_CREATE and NAND_BBT_WRITE here [1] and here [2]. That
> > > should let you read the existing BBT without updating it or
> > > creating a new one if it's not detected.    
> > Okay, let's try the marvell-nand-bug branch with this included.
> > It works :
> > [   18.302123] ubi0: attached mtd5 (name "root", size 37 MiB)
> > [   18.307691] ubi0: PEB size: 131072 bytes (128 KiB), LEB size:
> > 126976 bytes [   18.315003] ubi0: min./max. I/O unit sizes:
> > 2048/2048, sub-page size 2048 [   18.322155] ubi0: VID header
> > offset: 2048 (aligned 2048), data offset: 4096 [   18.329167] ubi0:
> > good PEBs: 297, bad PEBs: 0, corrupted PEBs: 0 [   18.335789] ubi0:
> > user volume: 1, internal volumes: 1, max. volumes count: 128
> > [   18.343409] ubi0: max/mean erase counter: 6/4, WL threshold:
> > 4096, image sequence number: 30621 [   18.352460] ubi0: available
> > PEBs: 0, total reserved PEBs: 297, PEBs reserved for bad PEB
> > handling: 40 [   18.361937] ubi0: background thread "ubi_bgt0d"
> > started, PID 411
> > 
> > That means the BBT reading is the issue don't you think ?  
> 
> The BBT detection issue has already been fixed with Miquel's previous
> version. So there shouldn't be any issue with that anymore, and your
> results tend to confirm that.
> 
> > 
> > Now if I keep NAND_BBT_CREATE but remove NAND_BBT_WRITE same thing,
> > it works as well. That leaves only the re-enabling of the BBT
> > write, which I'll do as soon as you tell me my NAND won't be
> > damaged.  
> 
> It won't, you can safely re-enable NAND_BBT_WRITE. The one that was
> causing trouble previously was NAND_BBT_CREATE, because the BBT was
> not found, and the NAND framework was creating a new one after
> scanning BBMs, which led to the situation you reported: BBT reporting
> all blocks as bad.
> 
> Thanks for helping us with this bug, I think we're close to a fully
> working situation now.

That is great, thank you both.
Miqu?l


From harjoc at gmail.com  Sat Jan 13 04:46:45 2018
From: harjoc at gmail.com (Bogdan Harjoc)
Date: Sat, 13 Jan 2018 14:46:45 +0200
Subject: Handle eraseblocks containing the bad-block table in UBI
In-Reply-To: <CAFLxGvxnEszGhC96=MB+Xmvv02A0A0WLY45Mf_dmWUKg2iKgfA@mail.gmail.com>
References: <CAF4+tmq0km-HXGkmWtHMA_rtzYYtok6W_suTVwgJnz5qPK6ZGw@mail.gmail.com>
 <CAFLxGvxnEszGhC96=MB+Xmvv02A0A0WLY45Mf_dmWUKg2iKgfA@mail.gmail.com>
Message-ID: <CAF4+tmrYWU-R4YpxHMfrLubNpbXozWqCsWGJeW6HwNZ2C9dffA@mail.gmail.com>

On Fri, Jan 12, 2018 at 10:52 PM, Richard Weinberger
<richard.weinberger at gmail.com> wrote:
> Usually blocks containing the BBT are also marked as bad to avoid the
> problem you're facing.
> So, yes UBI should not see these PEBs because they should look like bad blocks.
>
> Is this a kernel with vendor hackery?

It is, at least the nand probing code adds its own nand_bbt_descr
structs. Since the issue goes away by adding an

if (ec_hdr->magic == 'Bbt0' or '1bbT')
   treat_it_as_bad_block()

in ubi_io_read_ec_hdr(), I will see where the bad-block status for the
bbt PEBs gets lost.

Thank you,
Bogdan


From richard at sigma-star.at  Sat Jan 13 06:17:34 2018
From: richard at sigma-star.at (Richard Weinberger)
Date: Sat, 13 Jan 2018 15:17:34 +0100
Subject: Handle eraseblocks containing the bad-block table in UBI
In-Reply-To: <CAF4+tmpcv-zTJKj++AwRfU=vf3OjhK2_jDvJS-KyNX3mZW_uNg@mail.gmail.com>
References: <CAF4+tmq0km-HXGkmWtHMA_rtzYYtok6W_suTVwgJnz5qPK6ZGw@mail.gmail.com>
 <CAFLxGvxnEszGhC96=MB+Xmvv02A0A0WLY45Mf_dmWUKg2iKgfA@mail.gmail.com>
 <CAF4+tmpcv-zTJKj++AwRfU=vf3OjhK2_jDvJS-KyNX3mZW_uNg@mail.gmail.com>
Message-ID: <5069949.lP7kaqOdCT@blindfold>

Am Samstag, 13. Januar 2018, 13:44:54 CET schrieb Bogdan Harjoc:
> On Fri, Jan 12, 2018 at 10:52 PM, Richard Weinberger
> 
> <richard.weinberger at gmail.com> wrote:
> > Usually blocks containing the BBT are also marked as bad to avoid the
> > problem you're facing.
> > So, yes UBI should not see these PEBs because they should look like bad
> > blocks.
> > 
> > Is this a kernel with vendor hackery?
> 
> It is, at least the nand probing code adds its own nand_bbt_descr
> structs. Since the issue goes away by adding an
> 
> if (ec_hdr->magic == 'Bbt0' or '1bbT')
>    treat_it_as_bad_block()
> 
> in ubi_io_read_ec_hdr(), I will see where the bad-block status for the
> bbt PEBs gets lost.

UBI is the wrong layer to address this.
Please make sure that these blocks are handled in the NAND core.
BBT_BLOCK_RESERVED is the flag you need for them.

Thanks,
//richard

-- 
sigma star gmbh - Eduard-Bodem-Gasse 6 - 6020 Innsbruck - Austria
ATU66964118 - FN 374287y


From miquel.raynal at free-electrons.com  Sat Jan 13 08:25:51 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Sat, 13 Jan 2018 17:25:51 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180109101148.13728-7-s.hauer@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-7-s.hauer@pengutronix.de>
Message-ID: <20180113172551.5dab8a7c@xps13>

Hi Sascha,

On Tue,  9 Jan 2018 11:11:46 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> Now that we have our own read_page function add a write_page function
> for consistency aswell. This can be a lot easier than the generic
> function since we do not have to iterate over subpages but can write
> the whole page at once. Also add write_page_raw and write_oob for
> proper raw and oob write support.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 56
> +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56
> insertions(+)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 83bb01ab7079..6fbf98851a96 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -893,6 +893,59 @@ static int mxc_nand_read_oob(struct mtd_info
> *mtd, struct nand_chip *chip, page);
>  }
>  
> +static int __mxc_nand_write_page(struct mtd_info *mtd, struct
> nand_chip *chip,
> +				 const uint8_t *buf, int
> oob_required, int page) +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	memcpy32_toio(host->main_area0, buf, mtd->writesize);
> +	copy_spare(mtd, false, chip->oob_poi);

If I remember correctly, there was a "spare only" mechanism to avoid
doing full page read/write when unnecessary. What about using it here
when (buf == NULL && oob_required)?

> +
> +	host->devtype_data->send_page(mtd, NFC_INPUT);
> +	host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true);
> +	mxc_do_addr_cycle(mtd, 0, page);
> +
> +	return 0;
> +}
> +
> +static int mxc_nand_write_page(struct mtd_info *mtd, struct
> nand_chip *chip,
> +			       const uint8_t *buf, int oob_required,
> int page) +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->enable_hwecc(nand_chip, true);
> +
> +	return __mxc_nand_write_page(mtd, chip, buf, oob_required,
> page); +}
> +
> +static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct
> nand_chip *chip,
> +				   const uint8_t *buf, int
> oob_required, int page) +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	host->devtype_data->enable_hwecc(nand_chip, false);
> +
> +	return __mxc_nand_write_page(mtd, chip, buf, oob_required,
> page); +}
> +
> +static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip
> *chip,
> +			      int page)
> +{
> +	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +
> +	memset(host->data_buf, 0xff, mtd->writesize);

If the above solution works, this won't be needed anymore.

> +
> +	host->devtype_data->enable_hwecc(nand_chip, false);
> +
> +	return __mxc_nand_write_page(mtd, chip, host->data_buf, 1,
> page);

And this could be:
    return __mxc_nand_write_page(mtd, chip, NULL, 1, page);

> +}
> +
>  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char
> *dat, u_char *ecc_code)
>  {
> @@ -1907,6 +1960,9 @@ static int mxcnd_probe(struct platform_device
> *pdev) this->ecc.read_page = mxc_nand_read_page;
>  		this->ecc.read_page_raw = mxc_nand_read_page_raw;
>  		this->ecc.read_oob = mxc_nand_read_oob;
> +		this->ecc.write_page = mxc_nand_write_page;
> +		this->ecc.write_page_raw = mxc_nand_write_page_raw;
> +		this->ecc.write_oob = mxc_nand_write_oob;
>  		this->ecc.calculate = mxc_nand_calculate_ecc;
>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;


Thanks,
Miqu?l


From christophe.jaillet at wanadoo.fr  Sat Jan 13 08:56:16 2018
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 13 Jan 2018 17:56:16 +0100
Subject: [PATCH] mtd: onenand: samsung: remove incorrect __iomem annotation
Message-ID: <20180113165616.19992-1-christophe.jaillet@wanadoo.fr>

'page_buf' and 'oob_buf' are allocated with 'devm_kzalloc()' and should not
have __iommem decoration.

Remove these decorations and some useless casting.

Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/mtd/onenand/samsung.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index dfdfb478ba35..2e9d076e445a 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -129,8 +129,8 @@ struct s3c_onenand {
 	void __iomem	*base;
 	void __iomem	*ahb_addr;
 	int		bootram_command;
-	void __iomem	*page_buf;
-	void __iomem	*oob_buf;
+	void		*page_buf;
+	void		*oob_buf;
 	unsigned int	(*mem_addr)(int fba, int fpa, int fsa);
 	unsigned int	(*cmd_map)(unsigned int type, unsigned int val);
 	void __iomem	*dma_addr;
@@ -408,8 +408,8 @@ static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
 	/*
 	 * Emulate Two BufferRAMs and access with 4 bytes pointer
 	 */
-	m = (unsigned int *) onenand->page_buf;
-	s = (unsigned int *) onenand->oob_buf;
+	m = onenand->page_buf;
+	s = onenand->oob_buf;
 
 	if (index) {
 		m += (this->writesize >> 2);
@@ -481,11 +481,11 @@ static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
 	unsigned char *p;
 
 	if (area == ONENAND_DATARAM) {
-		p = (unsigned char *) onenand->page_buf;
+		p = onenand->page_buf;
 		if (index == 1)
 			p += this->writesize;
 	} else {
-		p = (unsigned char *) onenand->oob_buf;
+		p = onenand->oob_buf;
 		if (index == 1)
 			p += mtd->oobsize;
 	}
-- 
2.14.1



From boris.brezillon at free-electrons.com  Sat Jan 13 09:31:05 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 13 Jan 2018 18:31:05 +0100
Subject: [PATCH v6 00/14] OMAP2+ OneNAND driver update
In-Reply-To: <20180112131105.GA13810@lenoch>
References: <20180112131105.GA13810@lenoch>
Message-ID: <20180113183105.4c6cb7b4@bbrezillon>

On Fri, 12 Jan 2018 14:11:05 +0100
Ladislav Michl <ladis at linux-mips.org> wrote:

> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified INT gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use INT pin, int-gpios needs to be specified.
> 
> Most notable changes from v3:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Most notable changes from v4:
> - collected tags
> - used INT pin name properly
> - hopefully all comments taken into account
> 
> Most notable changes from v5:
> - as this serie is expected to be merged via single tree patches 13 and 14
>   were squashed together not to break bisecting.
> - patch 16 was dropped.
> 
> This patchset depends on an immutable commit:
> 
> The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
> 
>   Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
> 
> are available in the git repository at:
> 
>   https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
> 
> for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:
> 
>   memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
> 
> 
> Ladislav Michl (12):
>   dt-bindings: mtd: gpmc-onenand: Update properties description
>   ARM: dts: OMAP2+: Add compatible property to onenand node
>   ARM: dts: omap3-igep: Update onenand node timings
>   mtd: onenand: omap2: Remove regulator support
>   mtd: onenand: omap2: Remove skip initial unlocking support
>   mtd: onenand: omap2: Remove partitioning support from platform data
>   mtd: onenand: omap2: Account waiting time as waiting on IO
>   mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
>   mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
>   mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
>   mtd: onenand: omap2: Configure driver from DT
>   ARM: OMAP2+: Remove gpmc-onenand
> 
> Peter Ujfalusi (2):
>   mtd: onenand: omap2: Simplify the DMA setup for various paths
>   mtd: onenand: omap2: Convert to use dmaengine for memcpy

Applied the whole series.

Thanks,

Boris

> 
>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   1 +
>  arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
>  arch/arm/boot/dts/omap3-n900.dts                   |   1 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
>  arch/arm/mach-omap2/Makefile                       |   3 -
>  arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
>  drivers/memory/omap-gpmc.c                         | 158 ++++--
>  drivers/mtd/onenand/Kconfig                        |   4 +-
>  drivers/mtd/onenand/omap2.c                        | 576 ++++++++-------------
>  include/linux/omap-gpmc.h                          |  28 +
>  include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
>  13 files changed, 386 insertions(+), 866 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
>  delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
> 



From derosier at gmail.com  Sat Jan 13 09:34:52 2018
From: derosier at gmail.com (Steve deRosier)
Date: Sat, 13 Jan 2018 09:34:52 -0800
Subject: ECC configuration of NAND from Linux (MEMSETOOBSEL)
In-Reply-To: <20180113092443.6222f2bf@bbrezillon>
References: <2132429.fBNFCxDbQz@fessender> <20180112154639.63a8d133@bbrezillon>
 <2581607.A7Zl2yeV5U@fessender>
 <CALLGbRJ9SipkxtNiCigrPHQim5C38uq9EVsYK3WS_HN3aW-pqg@mail.gmail.com>
 <20180113092443.6222f2bf@bbrezillon>
Message-ID: <CALLGbRLXXO_ZyDahNyohh+Fs1adbYEcMoxA3+7FRWfUJpua5tg@mail.gmail.com>

Hi Boris,

On Sat, Jan 13, 2018 at 12:24 AM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Fri, 12 Jan 2018 18:41:58 -0800
> Steve deRosier <derosier at gmail.com> wrote:
>
>> Hi Gudjon,
>>
>> On Fri, Jan 12, 2018 at 10:50 AM, Gudjon I. Gudjonsson
>> <gudjon at gudjon.org> wrote:
>> > > setting you'll have to erase the whole flash and then change the ECC
>> > > config in your DT or board file (note that not all drivers support
>> > > adjusting the ECC strength/step-size).
>> > I will have to accept that but can you please tell me how to change the
>> > ECC strength if my driver supports it? My plan is to use swupdate and
>> > update the system using an SD-card that is already installed but I could
>> > not find any reference to changing the ECC strength.
>> > I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp
>> > NAND flash.
>> >
>>
>> I might be wrong, but I don't think there's any mechanism to change
>> the ECC strength on the fly with that processor and flash combination.
>> In order to do it, you have to adjust it in your device-tree. I went
>> through this in an upgrade scenario on a similar system a few years
>> ago and came to the conclusion that it wasn't viable. As a matter of
>> background, we had two spots on flash for the kernel (kernel-a,
>> kernel-b), and two for a rootfs that was a UBIFS (rootfs-a, rootfs-b).
>> Our upgrade procedure was to run on -a, and flash -b.  Next time, run
>> on -b and flash on -a, etc... To do it, here's what would have had to
>> be done:
>>
>> 1. Change the ECC strength in the DT, which then gets appended to the
>> the kernel image. Which means when the new kernel boots the new ECC
>> takes effect and not before. Note that the kernel that is running is
>> using the whatever ECC it was set for.
>> 2. Change our update script to _not_ write the ECC bits when it
>> flashes... this is critical.
>> 3. Now, (assuming running on -a partitions), erase kernel-b, rootfs-b.
>> Then flash the new kernel and new rootfs to the -b partitions
>> _with_out_ ECC bits!
>> 4. Reboot to -b partitions. Note that you're now running a kernel
>> supporting the new ECC layout, but without any ECC actually being
>> performed.
>> 5. Now, erase and reflash -a with the same new kernel and rootfs
>> _with_ ECC bits.
>> 6. Boot to -a. Now you're running with the new ECC layout and with ECC
>> actually being done.
>>
>> I'm going from memory, so I might have missed a step or done something
>> out of order, but you get the point. Now, why all of the above?  The
>> problem is the number of ECC bits that gets flashed is dependent on
>> the kernel running flashing it. So, having a kernel running 4 bits
>> trying to flash 8, doesn't work.  The solution is by forcing all the
>> written ECC bits to 0xffs by turing off the ECC bits when flashing
>> with nandwrite. The kernel will read and ignore ECC, no matter the set
>> strength, if there's no ECC bits set.
>
> That's not true. If you have all ECC bytes set to 0xff it will simply
> not boot (or at least it should not), because the ECC engine will report
> errors everywhere.
>

Well, I'm glad you say it shouldn't work that way, because I happen to
agree that it shouldn't. However, I can unequivocally confirm that on
at least one Atmel processor with one specific NAND with kernel
version 3.8, it does indeed work this way in practice. It's very clear
from the behavior that ECC-configured, but with the OOB area being
0xffs is being interpreted as "I have no ECC data, so don't bother
trying to do ECC". Now, obviously if there are bit-flips, what is read
is invalid and can cause random operations. Which, unfortunately, is
how I know what the behavior is.

I do not know if newer kernels behave this way on the platform in
question. I solved the configuration and process issues long ago and
so I never had to debug the problem on the newer 4.4 and 4.9 kernels
the product uses.

>> So, essentially, you have to
>> write the new stuff with the enhanced bits with no bits actually
>> written, in order to boot into it and then write it correctly a second
>> time.
>
> And this trick only works if your NAND supports subpage writes.

The layout of the SLC NAND doesn't allow for subpage writes. It has a
2k-byte + 64 byte OOB page, with a BS of 64 pages. Standard operation
is as expected: must erase in blocks, may program individual pages. It
is possible to choose to write the 2k byte page with or without ECC
and leave the erased 0xFFs in the OOB. This can be confirmed by
working directly with the NAND using u-boot's nand commands. The NAND
itself is non-ECC, and the PMECC controller on the processor only
handles the algorithms. So what to write, including the OOB is all
constructed in-software, written to the program page cache and then
the command to write is issued. So, even without subpage writes, it's
quite easy to write the data without writing the OOB.

And, remember - we're not writing the same page twice.  First write,
with the erased OOB, of the rootfs in this case is to mtd7, and the
second write, the one with the correct new ECC data to the OOB, is to
mtd6. Perhaps thats the misunderstanding here.

I'm not trying to be argumentative, I'm just saying what does indeed
happen on this specific platform I worked with. I shared the details
of my experience as the OP has a similar platform, but what I
experienced may or may not be applicable to his case. I wanted to
explain _why_ it is such a pain. And that changing the ECC strength
can not be undertaken lightly.

- Steve

Steve deRosier
Cal-Sierra Consulting LLC
https://www.cal-sierra.com/


From festevam at gmail.com  Sat Jan 13 11:40:51 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 13 Jan 2018 17:40:51 -0200
Subject: [PATCH v4] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180111211543.561ea46d@bbrezillon>
References: <1515685478-31457-1-git-send-email-fabio.estevam@nxp.com>
 <20180111164823.34b0b8fd@bbrezillon>
 <CAOMZO5AChZVrGMSdGFW5ZyKOOx23f_WJjchmdE=hUj0PmAMZgw@mail.gmail.com>
 <20180111174012.67e2681a@bbrezillon>
 <CAOMZO5Aerkb2r0y2aC8sZJcEgpJzoNgR5_MU=2t_uq7jTzNo9g@mail.gmail.com>
 <20180111211543.561ea46d@bbrezillon>
Message-ID: <CAOMZO5DCOz4zp57g-VWBOOOdL1J3-nrNYr6-mdbY+nefp0boFw@mail.gmail.com>

Hi Boris,

On Thu, Jan 11, 2018 at 6:15 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:

> Nothing that I really like, sorry. One solution would be to use
> dev_name(&pdev->dev) when only one flash device is declared and use
> dev_name(&pdev->dev)-reg_val otherwise. Or you could leave the logic

Ok, so I can do as you suggested above:

--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
                spi_nor_set_flash_node(nor, np);
                nor->priv = q;

+               if (q->nor_num > 1) {
+                       int spiflash_idx;
+
+                       ret = of_property_read_u32(np, "reg", &spiflash_idx);
+                       if (!ret) {
+                               mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+                                                          "%s-%d",
+                                                          dev_name(dev),
+                                                          spiflash_idx);
+                               if (!mtd->name) {
+                                       ret = -ENOMEM;
+                                       goto mutex_failed;
+                               }
+                       } else {
+                               dev_warn(dev, "reg property is missing\n");
+                       }
+               }
+
                /* fill the hooks */
                nor->read_reg = fsl_qspi_read_reg;
                nor->write_reg = fsl_qspi_write_reg;

And then I can do a separate patch adding the qspi flash examples into
Documentation/devicetree/bindings/mtd/fsl-quadspi.txt

Does this look good?


From robert.jarzmik at free.fr  Sun Jan 14 02:20:57 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sun, 14 Jan 2018 11:20:57 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180113093855.49231a43@bbrezillon> (Boris Brezillon's message
 of "Sat, 13 Jan 2018 09:38:55 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon> <876087beui.fsf@belgarion.home>
 <20180112112108.2e20dc14@bbrezillon> <871sivauyf.fsf@belgarion.home>
 <20180113093855.49231a43@bbrezillon>
Message-ID: <87shb8aghi.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> On Fri, 12 Jan 2018 17:43:52 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
>
>> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
>> 
>> > I think I'm still missing something. If I look at the branch you just
>> > pushed, I see that ->flash_bbt was not set to 1 before this commit [1],
>> > which means the pxa3xx driver was no setting the NAND_BBT_USE_FLASH
>> > flag, which in turn means you were not using the on-flash-bbt.
>> > When you test the old (pxa3xx) driver, are you sure you're testing
>> > things with a mainline kernel? If you have extra commits on top of
>> > mainline, can you push them somewhere?  
>> 
>> Here is the branch I'm using with my pxa3xx driver :
>> git fetch https://github.com/rjarzmik/linux pxa3xx-test
>
> May I ask why this is not in mainline?
Sure.

The pxa3xx comes into 3 flavors of SoCs :
 - pxa300
 - pxa310
 - pxa320

In these 3, only pxa310 has an internal PoP NAND, and requires the keep_config =
1 setting (where timings are set by the internal ROM code).

Yet zylonite_init_nand() is shared across all 3 platforms. In order to not break
other existing pxa3xx devices, I don't want to change this setting. Instead, my
plan is slowly convert pxaXXX to devicetree, and have this parameter set in
devicetree in a per board basis.

As to the .flash_bbt = 1 parameter, it's even worse. That's the decision made in
the initial flash formatting that counts. With the zylonite310 I have, the BBT
is at the end of the NAND. There might be other parts where it's only in the OOB
area. So it's difficult to change it without taking a risk of breaking others.

Cheers.

-- 
Robert


From robert.jarzmik at free.fr  Sun Jan 14 02:35:30 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sun, 14 Jan 2018 11:35:30 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180113120529.2f00ea20@xps13> (Miquel Raynal's message of "Sat, 
 13 Jan 2018 12:05:29 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon> <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon> <87wp0majtg.fsf@belgarion.home>
 <20180113093807.3984c184@bbrezillon> <20180113120529.2f00ea20@xps13>
Message-ID: <87o9lwaft9.fsf@belgarion.home>

Miquel Raynal <miquel.raynal at free-electrons.com> writes:

>> It shouldn't be damaged anymore. The bug has been fixed just before we
>> asked you to scrub the BBT area.
I confirm. The last marvell branch I have (2be03e113a5b ("HACK: Dump OOB data
while reading")) does work correctly on my zylonite.

I still have to make a test of a file write, and a devicetree based setup, but I
don't think anything wrong will happen now.

Cheers.

-- 
Robert


From boris.brezillon at free-electrons.com  Sun Jan 14 05:59:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 14 Jan 2018 14:59:17 +0100
Subject: [PATCH] MAINTAINERS: Add entry for Marvell NAND controller driver
In-Reply-To: <20180113105410.2555-1-miquel.raynal@free-electrons.com>
References: <20180113105410.2555-1-miquel.raynal@free-electrons.com>
Message-ID: <20180114145917.3d0304a5@bbrezillon>

On Sat, 13 Jan 2018 11:54:10 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Add entry for Marvell NAND controller driver and its bindings which will
> soon replace the old driver pxa3xx_nand.c.
> 

Applied.

Thanks,

Boris

> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  MAINTAINERS | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index aa71ab52fd76..ca8bb8077e70 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8409,6 +8409,13 @@ L:	linux-wireless at vger.kernel.org
>  S:	Odd Fixes
>  F:	drivers/net/wireless/marvell/mwl8k.c
>  
> +MARVELL NAND CONTROLLER DRIVER
> +M:	Miquel Raynal <miquel.raynal at free-electrons.com>
> +L:	linux-mtd at lists.infradead.org
> +S:	Maintained
> +F:	drivers/mtd/nand/marvell_nand.c
> +F:	Documentation/devicetree/bindings/mtd/marvell-nand.txt
> +
>  MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
>  M:	Nicolas Pitre <nico at fluxnic.net>
>  S:	Odd Fixes



From boris.brezillon at free-electrons.com  Sun Jan 14 06:04:35 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 14 Jan 2018 15:04:35 +0100
Subject: [PATCH] mtd: onenand: samsung: remove incorrect __iomem annotation
In-Reply-To: <20180113165616.19992-1-christophe.jaillet@wanadoo.fr>
References: <20180113165616.19992-1-christophe.jaillet@wanadoo.fr>
Message-ID: <20180114150435.2b575f7e@bbrezillon>

On Sat, 13 Jan 2018 17:56:16 +0100
Christophe JAILLET <christophe.jaillet at wanadoo.fr> wrote:

> 'page_buf' and 'oob_buf' are allocated with 'devm_kzalloc()' and should not
> have __iommem decoration.

	^ __iomem

No need to send a new version, I'll fix it when applying.

> 
> Remove these decorations and some useless casting.
> 
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
>  drivers/mtd/onenand/samsung.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
> index dfdfb478ba35..2e9d076e445a 100644
> --- a/drivers/mtd/onenand/samsung.c
> +++ b/drivers/mtd/onenand/samsung.c
> @@ -129,8 +129,8 @@ struct s3c_onenand {
>  	void __iomem	*base;
>  	void __iomem	*ahb_addr;
>  	int		bootram_command;
> -	void __iomem	*page_buf;
> -	void __iomem	*oob_buf;
> +	void		*page_buf;
> +	void		*oob_buf;
>  	unsigned int	(*mem_addr)(int fba, int fpa, int fsa);
>  	unsigned int	(*cmd_map)(unsigned int type, unsigned int val);
>  	void __iomem	*dma_addr;
> @@ -408,8 +408,8 @@ static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
>  	/*
>  	 * Emulate Two BufferRAMs and access with 4 bytes pointer
>  	 */
> -	m = (unsigned int *) onenand->page_buf;
> -	s = (unsigned int *) onenand->oob_buf;
> +	m = onenand->page_buf;
> +	s = onenand->oob_buf;
>  
>  	if (index) {
>  		m += (this->writesize >> 2);
> @@ -481,11 +481,11 @@ static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
>  	unsigned char *p;
>  
>  	if (area == ONENAND_DATARAM) {
> -		p = (unsigned char *) onenand->page_buf;
> +		p = onenand->page_buf;
>  		if (index == 1)
>  			p += this->writesize;
>  	} else {
> -		p = (unsigned char *) onenand->oob_buf;
> +		p = onenand->oob_buf;
>  		if (index == 1)
>  			p += mtd->oobsize;
>  	}



From boris.brezillon at free-electrons.com  Sun Jan 14 06:39:15 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 14 Jan 2018 15:39:15 +0100
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
Message-ID: <20180114153915.4c6141a4@bbrezillon>

+Ezequiel

Hi Bradley,

On Tue,  2 Jan 2018 21:26:09 -0500
Bradley Bolen <bradleybolen at gmail.com> wrote:

> This fixes a race condition where running ubiblock on multiple volumes
> simultaneously produces the following splat.
> 
> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
> (sysfs_create_group+0x20/0x24)
> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
> (blk_trace_init_sysfs+0x18/0x20)
> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
> (blk_register_queue+0x6c/0x154)
> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
> (device_add_disk+0x2c8/0x450)
> [<c02cd610>] (device_add_disk) from [<c0430fac>]
> (ubiblock_create+0x254/0x2e4)
> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
> (vol_cdev_ioctl+0x3e0/0x564)
> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)
> 

Missing Fixes and Cc-stable tags.

> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>


Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

BTW, just had a quick look at the code, and I think the locking can be
simplified a bit by keeping the devices_lock for the whole
ubiblock_create() operation instead of acquiring/releasing it several
times in the function (see [1]). It makes sense to do fine grained
locking when operations protected by the lock are time sensitive, but I
don't think this is the case here.

Regards,

Boris

[1]http://code.bulix.org/ox2562-258097

> ---
>  drivers/mtd/ubi/block.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
> index b210fdb..1c12370 100644
> --- a/drivers/mtd/ubi/block.c
> +++ b/drivers/mtd/ubi/block.c
> @@ -390,7 +390,9 @@ int ubiblock_create(struct ubi_volume_info *vi)
>  
>  	gd->fops = &ubiblock_ops;
>  	gd->major = ubiblock_major;
> +	mutex_lock(&devices_mutex);
>  	gd->first_minor = idr_alloc(&ubiblock_minor_idr, dev, 0, 0, GFP_KERNEL);
> +	mutex_unlock(&devices_mutex);
>  	if (gd->first_minor < 0) {
>  		dev_err(disk_to_dev(gd),
>  			"block: dynamic minor allocation failed");
> @@ -452,7 +454,9 @@ int ubiblock_create(struct ubi_volume_info *vi)
>  out_free_tags:
>  	blk_mq_free_tag_set(&dev->tag_set);
>  out_remove_minor:
> +	mutex_lock(&devices_mutex);
>  	idr_remove(&ubiblock_minor_idr, gd->first_minor);
> +	mutex_unlock(&devices_mutex);
>  out_put_disk:
>  	put_disk(dev->gd);
>  out_free_dev:
> @@ -471,7 +475,9 @@ static void ubiblock_cleanup(struct ubiblock *dev)
>  	blk_cleanup_queue(dev->rq);
>  	blk_mq_free_tag_set(&dev->tag_set);
>  	dev_info(disk_to_dev(dev->gd), "released");
> +	mutex_lock(&devices_mutex);
>  	idr_remove(&ubiblock_minor_idr, dev->gd->first_minor);
> +	mutex_unlock(&devices_mutex);
>  	put_disk(dev->gd);
>  }
>  



From boris.brezillon at free-electrons.com  Sun Jan 14 07:10:28 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 14 Jan 2018 16:10:28 +0100
Subject: ECC configuration of NAND from Linux (MEMSETOOBSEL)
In-Reply-To: <CALLGbRLXXO_ZyDahNyohh+Fs1adbYEcMoxA3+7FRWfUJpua5tg@mail.gmail.com>
References: <2132429.fBNFCxDbQz@fessender> <20180112154639.63a8d133@bbrezillon>
 <2581607.A7Zl2yeV5U@fessender>
 <CALLGbRJ9SipkxtNiCigrPHQim5C38uq9EVsYK3WS_HN3aW-pqg@mail.gmail.com>
 <20180113092443.6222f2bf@bbrezillon>
 <CALLGbRLXXO_ZyDahNyohh+Fs1adbYEcMoxA3+7FRWfUJpua5tg@mail.gmail.com>
Message-ID: <20180114161028.61f357d7@bbrezillon>

Hi Steve,

On Sat, 13 Jan 2018 09:34:52 -0800
Steve deRosier <derosier at gmail.com> wrote:

> Hi Boris,
> 
> On Sat, Jan 13, 2018 at 12:24 AM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Fri, 12 Jan 2018 18:41:58 -0800
> > Steve deRosier <derosier at gmail.com> wrote:
> >  
> >> Hi Gudjon,
> >>
> >> On Fri, Jan 12, 2018 at 10:50 AM, Gudjon I. Gudjonsson
> >> <gudjon at gudjon.org> wrote:  
> >> > > setting you'll have to erase the whole flash and then change the ECC
> >> > > config in your DT or board file (note that not all drivers support
> >> > > adjusting the ECC strength/step-size).  
> >> > I will have to accept that but can you please tell me how to change the
> >> > ECC strength if my driver supports it? My plan is to use swupdate and
> >> > update the system using an SD-card that is already installed but I could
> >> > not find any reference to changing the ECC strength.
> >> > I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp
> >> > NAND flash.
> >> >  
> >>
> >> I might be wrong, but I don't think there's any mechanism to change
> >> the ECC strength on the fly with that processor and flash combination.
> >> In order to do it, you have to adjust it in your device-tree. I went
> >> through this in an upgrade scenario on a similar system a few years
> >> ago and came to the conclusion that it wasn't viable. As a matter of
> >> background, we had two spots on flash for the kernel (kernel-a,
> >> kernel-b), and two for a rootfs that was a UBIFS (rootfs-a, rootfs-b).
> >> Our upgrade procedure was to run on -a, and flash -b.  Next time, run
> >> on -b and flash on -a, etc... To do it, here's what would have had to
> >> be done:
> >>
> >> 1. Change the ECC strength in the DT, which then gets appended to the
> >> the kernel image. Which means when the new kernel boots the new ECC
> >> takes effect and not before. Note that the kernel that is running is
> >> using the whatever ECC it was set for.
> >> 2. Change our update script to _not_ write the ECC bits when it
> >> flashes... this is critical.
> >> 3. Now, (assuming running on -a partitions), erase kernel-b, rootfs-b.
> >> Then flash the new kernel and new rootfs to the -b partitions
> >> _with_out_ ECC bits!
> >> 4. Reboot to -b partitions. Note that you're now running a kernel
> >> supporting the new ECC layout, but without any ECC actually being
> >> performed.
> >> 5. Now, erase and reflash -a with the same new kernel and rootfs
> >> _with_ ECC bits.
> >> 6. Boot to -a. Now you're running with the new ECC layout and with ECC
> >> actually being done.
> >>
> >> I'm going from memory, so I might have missed a step or done something
> >> out of order, but you get the point. Now, why all of the above?  The
> >> problem is the number of ECC bits that gets flashed is dependent on
> >> the kernel running flashing it. So, having a kernel running 4 bits
> >> trying to flash 8, doesn't work.  The solution is by forcing all the
> >> written ECC bits to 0xffs by turing off the ECC bits when flashing
> >> with nandwrite. The kernel will read and ignore ECC, no matter the set
> >> strength, if there's no ECC bits set.  
> >
> > That's not true. If you have all ECC bytes set to 0xff it will simply
> > not boot (or at least it should not), because the ECC engine will report
> > errors everywhere.
> >  
> 
> Well, I'm glad you say it shouldn't work that way, because I happen to
> agree that it shouldn't. However, I can unequivocally confirm that on
> at least one Atmel processor with one specific NAND with kernel
> version 3.8, it does indeed work this way in practice. It's very clear
> from the behavior that ECC-configured, but with the OOB area being
> 0xffs is being interpreted as "I have no ECC data, so don't bother
> trying to do ECC". Now, obviously if there are bit-flips, what is read
> is invalid and can cause random operations. Which, unfortunately, is
> how I know what the behavior is.

You're right, it seems that this test [1], which is meant detect erased
pages, has the side effect of completely disabling ECC correction when
ECC bytes are all set to 0xff, which is obviously wrong!

> 
> I do not know if newer kernels behave this way on the platform in
> question. I solved the configuration and process issues long ago and
> so I never had to debug the problem on the newer 4.4 and 4.9 kernels
> the product uses.

I confirm that this trick does not work in mainline :-).

> 
> >> So, essentially, you have to
> >> write the new stuff with the enhanced bits with no bits actually
> >> written, in order to boot into it and then write it correctly a second
> >> time.  
> >
> > And this trick only works if your NAND supports subpage writes.  
> 
> The layout of the SLC NAND doesn't allow for subpage writes. It has a
> 2k-byte + 64 byte OOB page, with a BS of 64 pages. Standard operation
> is as expected: must erase in blocks, may program individual pages. It
> is possible to choose to write the 2k byte page with or without ECC
> and leave the erased 0xFFs in the OOB. This can be confirmed by
> working directly with the NAND using u-boot's nand commands. The NAND
> itself is non-ECC, and the PMECC controller on the processor only
> handles the algorithms. So what to write, including the OOB is all
> constructed in-software, written to the program page cache and then
> the command to write is issued. So, even without subpage writes, it's
> quite easy to write the data without writing the OOB.
> 
> And, remember - we're not writing the same page twice.  First write,
> with the erased OOB, of the rootfs in this case is to mtd7, and the
> second write, the one with the correct new ECC data to the OOB, is to
> mtd6. Perhaps thats the misunderstanding here.

Indeed, I thought you were overwriting already programmed pages.

> 
> I'm not trying to be argumentative, I'm just saying what does indeed
> happen on this specific platform I worked with. I shared the details
> of my experience as the OP has a similar platform, but what I
> experienced may or may not be applicable to his case. I wanted to
> explain _why_ it is such a pain. And that changing the ECC strength
> can not be undertaken lightly.

It's clearly a pain to change the ECC config after the products have
been shipped.

Regards,

Boris


From cyrille.pitchen at wedev4u.fr  Sun Jan 14 07:23:49 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 14 Jan 2018 16:23:49 +0100
Subject: [PATCH] mtd: mtk-nor: modify functions' name more generally
In-Reply-To: <1513561655-10570-2-git-send-email-guochun.mao@mediatek.com>
References: <1513561655-10570-1-git-send-email-guochun.mao@mediatek.com>
 <1513561655-10570-2-git-send-email-guochun.mao@mediatek.com>
Message-ID: <5348c8dd-dc78-bdeb-f9d0-5ce20616d69b@wedev4u.fr>

Le 18/12/2017 ? 02:47, Guochun Mao a ?crit?:
> Since more and more Mediatek's SoC can use this driver to
> control spi-nor flash, functions' name with "mt8173_" is
> no longer properly. Replacing "mt8173_" with "mtk_" will
> be more accurate to describe these functions' usable scope.
> 
> Signed-off-by: Guochun Mao <guochun.mao at mediatek.com>

Applied to the spi-nor/next branch of linux-mtd

Thanks!

> ---
>  drivers/mtd/spi-nor/mtk-quadspi.c |  240 ++++++++++++++++++-------------------
>  1 file changed, 120 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
> index abe455c..5442993 100644
> --- a/drivers/mtd/spi-nor/mtk-quadspi.c
> +++ b/drivers/mtd/spi-nor/mtk-quadspi.c
> @@ -110,7 +110,7 @@
>  #define MTK_NOR_PRG_REG(n)		(MTK_NOR_PRGDATA0_REG + 4 * (n))
>  #define MTK_NOR_SHREG(n)		(MTK_NOR_SHREG0_REG + 4 * (n))
>  
> -struct mt8173_nor {
> +struct mtk_nor {
>  	struct spi_nor nor;
>  	struct device *dev;
>  	void __iomem *base;	/* nor flash base address */
> @@ -118,48 +118,48 @@ struct mt8173_nor {
>  	struct clk *nor_clk;
>  };
>  
> -static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor)
>  {
> -	struct spi_nor *nor = &mt8173_nor->nor;
> +	struct spi_nor *nor = &mtk_nor->nor;
>  
>  	switch (nor->read_proto) {
>  	case SNOR_PROTO_1_1_1:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA3_REG);
> -		writeb(MTK_NOR_FAST_READ, mt8173_nor->base +
> +		writeb(MTK_NOR_FAST_READ, mtk_nor->base +
>  		       MTK_NOR_CFG1_REG);
>  		break;
>  	case SNOR_PROTO_1_1_2:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA3_REG);
> -		writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base +
> +		writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	case SNOR_PROTO_1_1_4:
> -		writeb(nor->read_opcode, mt8173_nor->base +
> +		writeb(nor->read_opcode, mtk_nor->base +
>  		       MTK_NOR_PRGDATA4_REG);
> -		writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base +
> +		writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	default:
> -		writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base +
> +		writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base +
>  		       MTK_NOR_DUAL_REG);
>  		break;
>  	}
>  }
>  
> -static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval)
> +static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval)
>  {
>  	int reg;
>  	u8 val = cmdval & 0x1f;
>  
> -	writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG);
> -	return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg,
> +	writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG);
> +	return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg,
>  				  !(reg & val), 100, 10000);
>  }
>  
> -static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
> -			       u8 *tx, int txlen, u8 *rx, int rxlen)
> +static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op,
> +			    u8 *tx, int txlen, u8 *rx, int rxlen)
>  {
>  	int len = 1 + txlen + rxlen;
>  	int i, ret, idx;
> @@ -167,26 +167,26 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
>  	if (len > MTK_NOR_MAX_SHIFT)
>  		return -EINVAL;
>  
> -	writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG);
> +	writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG);
>  
>  	/* start at PRGDATA5, go down to PRGDATA0 */
>  	idx = MTK_NOR_MAX_RX_TX_SHIFT - 1;
>  
>  	/* opcode */
> -	writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +	writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  	idx--;
>  
>  	/* program TX data */
>  	for (i = 0; i < txlen; i++, idx--)
> -		writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +		writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  
>  	/* clear out rest of TX registers */
>  	while (idx >= 0) {
> -		writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
> +		writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx));
>  		idx--;
>  	}
>  
> -	ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD);
> +	ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD);
>  	if (ret)
>  		return ret;
>  
> @@ -195,20 +195,20 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
>  
>  	/* read out RX data */
>  	for (i = 0; i < rxlen; i++, idx--)
> -		rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx));
> +		rx[i] = readb(mtk_nor->base + MTK_NOR_SHREG(idx));
>  
>  	return 0;
>  }
>  
>  /* Do a WRSR (Write Status Register) command */
> -static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr)
> +static int mtk_nor_wr_sr(struct mtk_nor *mtk_nor, u8 sr)
>  {
> -	writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG);
> -	writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG);
> -	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD);
> +	writeb(sr, mtk_nor->base + MTK_NOR_PRGDATA5_REG);
> +	writeb(8, mtk_nor->base + MTK_NOR_CNT_REG);
> +	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WRSR_CMD);
>  }
>  
> -static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_write_buffer_enable(struct mtk_nor *mtk_nor)
>  {
>  	u8 reg;
>  
> @@ -216,27 +216,27 @@ static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
>  	 * 0: pre-fetch buffer use for read
>  	 * 1: pre-fetch buffer use for page program
>  	 */
> -	writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
> -	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
> +	writel(MTK_NOR_WR_BUF_ENABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
> +	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
>  				  0x01 == (reg & 0x01), 100, 10000);
>  }
>  
> -static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_write_buffer_disable(struct mtk_nor *mtk_nor)
>  {
>  	u8 reg;
>  
> -	writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
> -	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
> +	writel(MTK_NOR_WR_BUF_DISABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
> +	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
>  				  MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100,
>  				  10000);
>  }
>  
> -static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_set_addr_width(struct mtk_nor *mtk_nor)
>  {
>  	u8 val;
> -	struct spi_nor *nor = &mt8173_nor->nor;
> +	struct spi_nor *nor = &mtk_nor->nor;
>  
> -	val = readb(mt8173_nor->base + MTK_NOR_DUAL_REG);
> +	val = readb(mtk_nor->base + MTK_NOR_DUAL_REG);
>  
>  	switch (nor->addr_width) {
>  	case 3:
> @@ -246,115 +246,115 @@ static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
>  		val |= MTK_NOR_4B_ADDR_EN;
>  		break;
>  	default:
> -		dev_warn(mt8173_nor->dev, "Unexpected address width %u.\n",
> +		dev_warn(mtk_nor->dev, "Unexpected address width %u.\n",
>  			 nor->addr_width);
>  		break;
>  	}
>  
> -	writeb(val, mt8173_nor->base + MTK_NOR_DUAL_REG);
> +	writeb(val, mtk_nor->base + MTK_NOR_DUAL_REG);
>  }
>  
> -static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr)
> +static void mtk_nor_set_addr(struct mtk_nor *mtk_nor, u32 addr)
>  {
>  	int i;
>  
> -	mt8173_nor_set_addr_width(mt8173_nor);
> +	mtk_nor_set_addr_width(mtk_nor);
>  
>  	for (i = 0; i < 3; i++) {
> -		writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4);
> +		writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR0_REG + i * 4);
>  		addr >>= 8;
>  	}
>  	/* Last register is non-contiguous */
> -	writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG);
> +	writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR3_REG);
>  }
>  
> -static ssize_t mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length,
> -			       u_char *buffer)
> +static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
> +			    u_char *buffer)
>  {
>  	int i, ret;
>  	int addr = (int)from;
>  	u8 *buf = (u8 *)buffer;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	/* set mode for fast read mode ,dual mode or quad mode */
> -	mt8173_nor_set_read_mode(mt8173_nor);
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_read_mode(mtk_nor);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	for (i = 0; i < length; i++) {
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
>  		if (ret < 0)
>  			return ret;
> -		buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG);
> +		buf[i] = readb(mtk_nor->base + MTK_NOR_RDATA_REG);
>  	}
>  	return length;
>  }
>  
> -static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor,
> -					int addr, int length, u8 *data)
> +static int mtk_nor_write_single_byte(struct mtk_nor *mtk_nor,
> +				     int addr, int length, u8 *data)
>  {
>  	int i, ret;
>  
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	for (i = 0; i < length; i++) {
> -		writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG);
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD);
> +		writeb(*data++, mtk_nor->base + MTK_NOR_WDATA_REG);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_WR_CMD);
>  		if (ret < 0)
>  			return ret;
>  	}
>  	return 0;
>  }
>  
> -static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr,
> -				   const u8 *buf)
> +static int mtk_nor_write_buffer(struct mtk_nor *mtk_nor, int addr,
> +				const u8 *buf)
>  {
>  	int i, bufidx, data;
>  
> -	mt8173_nor_set_addr(mt8173_nor, addr);
> +	mtk_nor_set_addr(mtk_nor, addr);
>  
>  	bufidx = 0;
>  	for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) {
>  		data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 |
>  		       buf[bufidx + 1]<<8 | buf[bufidx];
>  		bufidx += 4;
> -		writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG);
> +		writel(data, mtk_nor->base + MTK_NOR_PP_DATA_REG);
>  	}
> -	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD);
> +	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WR_CMD);
>  }
>  
> -static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
> -				const u_char *buf)
> +static ssize_t mtk_nor_write(struct spi_nor *nor, loff_t to, size_t len,
> +			     const u_char *buf)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  	size_t i;
>  
> -	ret = mt8173_nor_write_buffer_enable(mt8173_nor);
> +	ret = mtk_nor_write_buffer_enable(mtk_nor);
>  	if (ret < 0) {
> -		dev_warn(mt8173_nor->dev, "write buffer enable failed!\n");
> +		dev_warn(mtk_nor->dev, "write buffer enable failed!\n");
>  		return ret;
>  	}
>  
>  	for (i = 0; i + SFLASH_WRBUF_SIZE <= len; i += SFLASH_WRBUF_SIZE) {
> -		ret = mt8173_nor_write_buffer(mt8173_nor, to, buf);
> +		ret = mtk_nor_write_buffer(mtk_nor, to, buf);
>  		if (ret < 0) {
> -			dev_err(mt8173_nor->dev, "write buffer failed!\n");
> +			dev_err(mtk_nor->dev, "write buffer failed!\n");
>  			return ret;
>  		}
>  		to += SFLASH_WRBUF_SIZE;
>  		buf += SFLASH_WRBUF_SIZE;
>  	}
> -	ret = mt8173_nor_write_buffer_disable(mt8173_nor);
> +	ret = mtk_nor_write_buffer_disable(mtk_nor);
>  	if (ret < 0) {
> -		dev_warn(mt8173_nor->dev, "write buffer disable failed!\n");
> +		dev_warn(mtk_nor->dev, "write buffer disable failed!\n");
>  		return ret;
>  	}
>  
>  	if (i < len) {
> -		ret = mt8173_nor_write_single_byte(mt8173_nor, to,
> -						   (int)(len - i), (u8 *)buf);
> +		ret = mtk_nor_write_single_byte(mtk_nor, to,
> +						(int)(len - i), (u8 *)buf);
>  		if (ret < 0) {
> -			dev_err(mt8173_nor->dev, "write single byte failed!\n");
> +			dev_err(mtk_nor->dev, "write single byte failed!\n");
>  			return ret;
>  		}
>  	}
> @@ -362,72 +362,72 @@ static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
>  	return len;
>  }
>  
> -static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
> +static int mtk_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	switch (opcode) {
>  	case SPINOR_OP_RDSR:
> -		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD);
> +		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_RDSR_CMD);
>  		if (ret < 0)
>  			return ret;
>  		if (len == 1)
> -			*buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG);
> +			*buf = readb(mtk_nor->base + MTK_NOR_RDSR_REG);
>  		else
> -			dev_err(mt8173_nor->dev, "len should be 1 for read status!\n");
> +			dev_err(mtk_nor->dev, "len should be 1 for read status!\n");
>  		break;
>  	default:
> -		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len);
> +		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, NULL, 0, buf, len);
>  		break;
>  	}
>  	return ret;
>  }
>  
> -static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
> -				int len)
> +static int mtk_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
> +			     int len)
>  {
>  	int ret;
> -	struct mt8173_nor *mt8173_nor = nor->priv;
> +	struct mtk_nor *mtk_nor = nor->priv;
>  
>  	switch (opcode) {
>  	case SPINOR_OP_WRSR:
>  		/* We only handle 1 byte */
> -		ret = mt8173_nor_wr_sr(mt8173_nor, *buf);
> +		ret = mtk_nor_wr_sr(mtk_nor, *buf);
>  		break;
>  	default:
> -		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0);
> +		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, buf, len, NULL, 0);
>  		if (ret)
> -			dev_warn(mt8173_nor->dev, "write reg failure!\n");
> +			dev_warn(mtk_nor->dev, "write reg failure!\n");
>  		break;
>  	}
>  	return ret;
>  }
>  
> -static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
> +static void mtk_nor_disable_clk(struct mtk_nor *mtk_nor)
>  {
> -	clk_disable_unprepare(mt8173_nor->spi_clk);
> -	clk_disable_unprepare(mt8173_nor->nor_clk);
> +	clk_disable_unprepare(mtk_nor->spi_clk);
> +	clk_disable_unprepare(mtk_nor->nor_clk);
>  }
>  
> -static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
> +static int mtk_nor_enable_clk(struct mtk_nor *mtk_nor)
>  {
>  	int ret;
>  
> -	ret = clk_prepare_enable(mt8173_nor->spi_clk);
> +	ret = clk_prepare_enable(mtk_nor->spi_clk);
>  	if (ret)
>  		return ret;
>  
> -	ret = clk_prepare_enable(mt8173_nor->nor_clk);
> +	ret = clk_prepare_enable(mtk_nor->nor_clk);
>  	if (ret) {
> -		clk_disable_unprepare(mt8173_nor->spi_clk);
> +		clk_disable_unprepare(mtk_nor->spi_clk);
>  		return ret;
>  	}
>  
>  	return 0;
>  }
>  
> -static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
> +static int mtk_nor_init(struct mtk_nor *mtk_nor,
>  			struct device_node *flash_node)
>  {
>  	const struct spi_nor_hwcaps hwcaps = {
> @@ -439,18 +439,18 @@ static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
>  	struct spi_nor *nor;
>  
>  	/* initialize controller to accept commands */
> -	writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG);
> +	writel(MTK_NOR_ENABLE_SF_CMD, mtk_nor->base + MTK_NOR_WRPROT_REG);
>  
> -	nor = &mt8173_nor->nor;
> -	nor->dev = mt8173_nor->dev;
> -	nor->priv = mt8173_nor;
> +	nor = &mtk_nor->nor;
> +	nor->dev = mtk_nor->dev;
> +	nor->priv = mtk_nor;
>  	spi_nor_set_flash_node(nor, flash_node);
>  
>  	/* fill the hooks to spi nor */
> -	nor->read = mt8173_nor_read;
> -	nor->read_reg = mt8173_nor_read_reg;
> -	nor->write = mt8173_nor_write;
> -	nor->write_reg = mt8173_nor_write_reg;
> +	nor->read = mtk_nor_read;
> +	nor->read_reg = mtk_nor_read_reg;
> +	nor->write = mtk_nor_write;
> +	nor->write_reg = mtk_nor_write_reg;
>  	nor->mtd.name = "mtk_nor";
>  	/* initialized with NULL */
>  	ret = spi_nor_scan(nor, NULL, &hwcaps);
> @@ -465,34 +465,34 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>  	struct device_node *flash_np;
>  	struct resource *res;
>  	int ret;
> -	struct mt8173_nor *mt8173_nor;
> +	struct mtk_nor *mtk_nor;
>  
>  	if (!pdev->dev.of_node) {
>  		dev_err(&pdev->dev, "No DT found\n");
>  		return -EINVAL;
>  	}
>  
> -	mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL);
> -	if (!mt8173_nor)
> +	mtk_nor = devm_kzalloc(&pdev->dev, sizeof(*mtk_nor), GFP_KERNEL);
> +	if (!mtk_nor)
>  		return -ENOMEM;
> -	platform_set_drvdata(pdev, mt8173_nor);
> +	platform_set_drvdata(pdev, mtk_nor);
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res);
> -	if (IS_ERR(mt8173_nor->base))
> -		return PTR_ERR(mt8173_nor->base);
> +	mtk_nor->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(mtk_nor->base))
> +		return PTR_ERR(mtk_nor->base);
>  
> -	mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
> -	if (IS_ERR(mt8173_nor->spi_clk))
> -		return PTR_ERR(mt8173_nor->spi_clk);
> +	mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
> +	if (IS_ERR(mtk_nor->spi_clk))
> +		return PTR_ERR(mtk_nor->spi_clk);
>  
> -	mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
> -	if (IS_ERR(mt8173_nor->nor_clk))
> -		return PTR_ERR(mt8173_nor->nor_clk);
> +	mtk_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
> +	if (IS_ERR(mtk_nor->nor_clk))
> +		return PTR_ERR(mtk_nor->nor_clk);
>  
> -	mt8173_nor->dev = &pdev->dev;
> +	mtk_nor->dev = &pdev->dev;
>  
> -	ret = mt8173_nor_enable_clk(mt8173_nor);
> +	ret = mtk_nor_enable_clk(mtk_nor);
>  	if (ret)
>  		return ret;
>  
> @@ -503,20 +503,20 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>  		ret = -ENODEV;
>  		goto nor_free;
>  	}
> -	ret = mtk_nor_init(mt8173_nor, flash_np);
> +	ret = mtk_nor_init(mtk_nor, flash_np);
>  
>  nor_free:
>  	if (ret)
> -		mt8173_nor_disable_clk(mt8173_nor);
> +		mtk_nor_disable_clk(mtk_nor);
>  
>  	return ret;
>  }
>  
>  static int mtk_nor_drv_remove(struct platform_device *pdev)
>  {
> -	struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
> +	struct mtk_nor *mtk_nor = platform_get_drvdata(pdev);
>  
> -	mt8173_nor_disable_clk(mt8173_nor);
> +	mtk_nor_disable_clk(mtk_nor);
>  
>  	return 0;
>  }
> @@ -524,18 +524,18 @@ static int mtk_nor_drv_remove(struct platform_device *pdev)
>  #ifdef CONFIG_PM_SLEEP
>  static int mtk_nor_suspend(struct device *dev)
>  {
> -	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
> +	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
>  
> -	mt8173_nor_disable_clk(mt8173_nor);
> +	mtk_nor_disable_clk(mtk_nor);
>  
>  	return 0;
>  }
>  
>  static int mtk_nor_resume(struct device *dev)
>  {
> -	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
> +	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
>  
> -	return mt8173_nor_enable_clk(mt8173_nor);
> +	return mtk_nor_enable_clk(mtk_nor);
>  }
>  
>  static const struct dev_pm_ops mtk_nor_dev_pm_ops = {
> 



From cyrille.pitchen at wedev4u.fr  Sun Jan 14 07:52:59 2018
From: cyrille.pitchen at wedev4u.fr (Cyrille Pitchen)
Date: Sun, 14 Jan 2018 16:52:59 +0100
Subject: [GIT PULL] mtd: spi-nor: Changes for 4.16
Message-ID: <13f60855-0108-3ecd-fabe-9e74e25f9150@wedev4u.fr>

Hi all,

this is the spi-nor pull request for 4.16.

Best regards,

Cyrille

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/spi-nor/for-4.16

for you to fetch changes up to 23bae78e8a57f0249ed9e3f9c3f40fc1499ce0d4:

  mtd: mtk-nor: modify functions' name more generally (2018-01-14 16:14:06 +0100)

----------------------------------------------------------------
This pull-request contains the following notable changes:

Core changes:
* Add support to new ISSI and Cypress/Spansion memory parts.
* Fix support of Micron memories by checking error bits in the FSR.
* Fix update of block-protection bits by reading back the SR.
* Restore the internal state of the SPI flash memory when removing the
  device.

Driver changes:
* Maintenance for Freescale, Intel and Metiatek drivers.
* Add support of the direct access mode for the Cadence QSPI controller.

----------------------------------------------------------------
Aaron Sierra (1):
      mtd: spi-nor: Check that BP bits are set properly

Angelo Dureghello (1):
      mtd: spi-nor: add support for ISSI is25lp128

Bean Huo (beanhuo) (1):
      mtd: spi-nor: check FSR error bits for Micron memories

Fabio Estevam (1):
      dt-bindings: mtd: fsl-quadspi: Pass the qspi clock names

Guochun Mao (1):
      mtd: mtk-nor: modify functions' name more generally

Hou Zhiqiang (2):
      mtd: spi-nor: add an API to restore the status of SPI flash chip
      mtd: m25p80: restore the status of SPI flash when exiting

Julia Lawall (1):
      mtd: fsl-quadspi: account for const type of of_device_id.data

Mika Westerberg (1):
      spi-nor: intel-spi: Remove unused preopcodes field

Rafael Gago (1):
      mtd: spi-nor: Add support for s25fl128l and s25fl256l

Romain Porte (1):
      mtd: spi-nor: Add ISSI is25lp080d support

Sean Nyekjaer (2):
      mtd: spi-nor: add support for is25lq040b
      mtd: spi-nor: indent issi section

Vignesh R (2):
      mtd: spi-nor: cadence-quadspi: Refactor indirect read/write sequence.
      mtd: spi-nor: cadence-quadspi: Add support for direct access mode

 Documentation/devicetree/bindings/mtd/fsl-quadspi.txt |   2 +-
 Documentation/mtd/spi-nor.txt                         |   3 ++
 drivers/mtd/devices/m25p80.c                          |   9 ++++++
 drivers/mtd/spi-nor/cadence-quadspi.c                 |  55 ++++++++++++++++++++++++----------
 drivers/mtd/spi-nor/fsl-quadspi.c                     |   8 ++---
 drivers/mtd/spi-nor/intel-spi.c                       |   6 ----
 drivers/mtd/spi-nor/mtk-quadspi.c                     | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------
 drivers/mtd/spi-nor/spi-nor.c                         |  75 +++++++++++++++++++++++++++++++++++++----------
 include/linux/mtd/spi-nor.h                           |  12 +++++++-
 9 files changed, 246 insertions(+), 164 deletions(-)
 


From stefan at agner.ch  Sun Jan 14 14:00:12 2018
From: stefan at agner.ch (Stefan Agner)
Date: Sun, 14 Jan 2018 23:00:12 +0100
Subject: [RFC PATCH v2] mtd: nand: vf610_nfc: make use of ->exec_op()
Message-ID: <20180114220012.30039-1-stefan@agner.ch>

This reworks the driver to make use of ->exec_op() callback. The
command sequencer of the VF610 NFC aligns well with the new ops
interface.

The ops are translated to a NFC command code while filling the
necessary registers. Instead of using the special status and
read id command codes (which require the status/id form special
registers) the driver now uses the main data buffer for all
commands. This simplifies the driver as no special casing is
needed.

For control data (status byte, id bytes and parameter page) the
driver needs to reverse byte order for little endian CPUs since
the controller seems to store the bytes in big endian order in
the data buffer.

The current state seems to pass MTD tests on a Colibri VF61.

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
Hi,

In this second version I was able to remove all special command
handling. As Boris suggested, the special READID/STATUS handling
is really not needed and all return values can be read from the
regular data buffer. This simplified code even more and allowed
to get rid of the hack in the MTD core. The driver is now able
to handle all commands in a single function. Therefor I also got
rid of the command parser, since everything is handled in a single
function anyway.

The only thing which is somewhat unfortunate is the byte ordering
which needs to be reversed for commands which read flash data (id,
status and parameter page). All those request 8-bit handling, so
I used this as an indicator to fix byte order.

I did meassured a slight performance drop (before vs. now):
- write speed is 4036 KiB/s vs 3495 KiB/s
- read speed is 13741 KiB/s vs 13490 KiB/s

--
Stefan

 drivers/mtd/nand/vf610_nfc.c | 444 +++++++++++++++++++------------------------
 1 file changed, 194 insertions(+), 250 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 80d31a58e558..fb428a94bbd4 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -59,20 +59,20 @@
 #define OOB_64				0x0040
 #define OOB_MAX				0x0100
 
-/*
- * NFC_CMD2[CODE] values. See section:
- *  - 31.4.7 Flash Command Code Description, Vybrid manual
- *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
- *
- * Briefly these are bitmasks of controller cycles.
- */
-#define READ_PAGE_CMD_CODE		0x7EE0
-#define READ_ONFI_PARAM_CMD_CODE	0x4860
-#define PROGRAM_PAGE_CMD_CODE		0x7FC0
-#define ERASE_CMD_CODE			0x4EC0
-#define READ_ID_CMD_CODE		0x4804
-#define RESET_CMD_CODE			0x4040
-#define STATUS_READ_CMD_CODE		0x4068
+/* NFC_CMD2[CODE] controller cycle bit masks */
+#define COMMAND_CMD_BYTE1		BIT(14)
+#define COMMAND_CAR_BYTE1		BIT(13)
+#define COMMAND_CAR_BYTE2		BIT(12)
+#define COMMAND_RAR_BYTE1		BIT(11)
+#define COMMAND_RAR_BYTE2		BIT(10)
+#define COMMAND_RAR_BYTE3		BIT(9)
+#define COMMAND_WRITE_DATA		BIT(8)
+#define COMMAND_CMD_BYTE2		BIT(7)
+#define COMMAND_RB_HANDSHAKE		BIT(6)
+#define COMMAND_READ_DATA		BIT(5)
+#define COMMAND_CMD_BYTE3		BIT(4)
+#define COMMAND_READ_STATUS		BIT(3)
+#define COMMAND_READ_ID			BIT(2)
 
 /* NFC ECC mode define */
 #define ECC_BYPASS			0
@@ -97,10 +97,21 @@
 /* NFC_COL_ADDR Field */
 #define COL_ADDR_MASK				0x0000FFFF
 #define COL_ADDR_SHIFT				0
+#define COL_ADDR_BYTE1_SHIFT			0
+#define COL_ADDR_BYTE2_SHIFT			8
+#define COL_ADDR_BYTE1(x)			((x & 0xFF) << COL_ADDR_BYTE1_SHIFT)
+#define COL_ADDR_BYTE2(x)			((x & 0XFF) << COL_ADDR_BYTE2_SHIFT)
+
 
 /* NFC_ROW_ADDR Field */
 #define ROW_ADDR_MASK				0x00FFFFFF
 #define ROW_ADDR_SHIFT				0
+#define ROW_ADDR_BYTE1_SHIFT			0
+#define ROW_ADDR_BYTE2_SHIFT			8
+#define ROW_ADDR_BYTE3_SHIFT			16
+#define ROW_ADDR_BYTE1(x)			((x & 0xFF) << ROW_ADDR_BYTE1_SHIFT)
+#define ROW_ADDR_BYTE2(x)			((x & 0XFF) << ROW_ADDR_BYTE2_SHIFT)
+#define ROW_ADDR_BYTE3(x)			((x & 0XFF) << ROW_ADDR_BYTE3_SHIFT)
 #define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
 #define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
 #define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
@@ -142,13 +153,6 @@
 #define ECC_STATUS_MASK		0x80
 #define ECC_STATUS_ERR_COUNT	0x3F
 
-enum vf610_nfc_alt_buf {
-	ALT_BUF_DATA = 0,
-	ALT_BUF_ID = 1,
-	ALT_BUF_STAT = 2,
-	ALT_BUF_ONFI = 3,
-};
-
 enum vf610_nfc_variant {
 	NFC_VFC610 = 1,
 };
@@ -158,10 +162,7 @@ struct vf610_nfc {
 	struct device *dev;
 	void __iomem *regs;
 	struct completion cmd_done;
-	uint buf_offset;
-	int write_sz;
 	/* Status and ID are in alternate locations. */
-	enum vf610_nfc_alt_buf alt_buf;
 	enum vf610_nfc_variant variant;
 	struct clk *clk;
 	bool use_hw_ecc;
@@ -173,6 +174,11 @@ static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd)
 	return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
 }
 
+static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip)
+{
+	return container_of(chip, struct vf610_nfc, chip);
+}
+
 static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
 {
 	return readl(nfc->regs + reg);
@@ -214,7 +220,6 @@ static inline void vf610_nfc_memcpy(void *dst, const void __iomem *src,
 	memcpy(dst, src, n);
 }
 
-/* Clear flags for upcoming command */
 static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
 {
 	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
@@ -243,51 +248,22 @@ static void vf610_nfc_done(struct vf610_nfc *nfc)
 	vf610_nfc_clear_status(nfc);
 }
 
-static u8 vf610_nfc_get_id(struct vf610_nfc *nfc, int col)
-{
-	u32 flash_id;
-
-	if (col < 4) {
-		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS1);
-		flash_id >>= (3 - col) * 8;
-	} else {
-		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS2);
-		flash_id >>= 24;
-	}
-
-	return flash_id & 0xff;
-}
-
-static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
+static void vf610_nfc_send_code(struct vf610_nfc *nfc, u32 cmd_code)
 {
-	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_CODE_MASK, CMD_CODE_SHIFT,
+			    cmd_code);
 }
 
-static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
-				   u32 cmd_code)
+static void vf610_nfc_set_cmd1(struct vf610_nfc *nfc, u32 cmd_byte1)
 {
-	u32 tmp;
-
-	vf610_nfc_clear_status(nfc);
-
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
-	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
-	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
-	tmp |= cmd_code << CMD_CODE_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_BYTE1_MASK,
+			    CMD_BYTE1_SHIFT, cmd_byte1);
 }
 
-static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
-				    u32 cmd_byte2, u32 cmd_code)
+static void vf610_nfc_set_cmd2(struct vf610_nfc *nfc, u32 cmd_byte2)
 {
-	u32 tmp;
-
-	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
-
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
-	tmp &= ~CMD_BYTE2_MASK;
-	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
+	vf610_nfc_set_field(nfc, NFC_FLASH_CMD1, CMD_BYTE2_MASK,
+			    CMD_BYTE2_SHIFT, cmd_byte2);
 }
 
 static irqreturn_t vf610_nfc_irq(int irq, void *data)
@@ -301,19 +277,6 @@ static irqreturn_t vf610_nfc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
-{
-	if (column != -1) {
-		if (nfc->chip.options & NAND_BUSWIDTH_16)
-			column = column / 2;
-		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
-				    COL_ADDR_SHIFT, column);
-	}
-	if (page != -1)
-		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
-				    ROW_ADDR_SHIFT, page);
-}
-
 static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
 {
 	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
@@ -326,167 +289,158 @@ static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
 	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
 }
 
-static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
-			      int column, int page)
+static inline const struct nand_op_instr *vf610_get_next_instr(
+	const struct nand_operation *op, int *op_id)
 {
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
+	if (*op_id + 1 >= op->ninstrs)
+		return NULL;
 
-	nfc->buf_offset = max(column, 0);
-	nfc->alt_buf = ALT_BUF_DATA;
+	return &op->instrs[++(*op_id)];
+}
 
-	switch (command) {
-	case NAND_CMD_SEQIN:
-		/* Use valid column/page from preread... */
-		vf610_nfc_addr_cycle(nfc, column, page);
-		nfc->buf_offset = 0;
+static int vf610_nfc_exec_op(struct nand_chip *chip,
+			     const struct nand_operation *op,
+			     bool check_only)
+{
+	const struct nand_op_instr *instr;
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int op_id = -1, trfr_sz = 0, code = 0;
 
-		/*
-		 * SEQIN => data => PAGEPROG sequence is done by the controller
-		 * hence we do not need to issue the command here...
-		 */
-		return;
-	case NAND_CMD_PAGEPROG:
-		trfr_sz += nfc->write_sz;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
-					command, PROGRAM_PAGE_CMD_CODE);
-		if (nfc->use_hw_ecc)
-			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		else
-			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_RESET:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
-		break;
-
-	case NAND_CMD_READOOB:
-		trfr_sz += mtd->oobsize;
-		column = mtd->writesize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_READ0:
-		trfr_sz += mtd->writesize + mtd->oobsize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		break;
-
-	case NAND_CMD_PARAM:
-		nfc->alt_buf = ALT_BUF_ONFI;
-		trfr_sz = 3 * sizeof(struct nand_onfi_params);
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_ERASE1:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_commands(nfc, command,
-					NAND_CMD_ERASE2, ERASE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		break;
-
-	case NAND_CMD_READID:
-		nfc->alt_buf = ALT_BUF_ID;
-		nfc->buf_offset = 0;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		break;
-
-	case NAND_CMD_STATUS:
-		nfc->alt_buf = ALT_BUF_STAT;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
-		break;
-	default:
-		return;
+
+	/* Some ops are optional, but they need to be in order */
+	instr = vf610_get_next_instr(op, &op_id);
+	if (!instr)
+		return -EINVAL;
+
+	if (instr && instr->type == NAND_OP_CMD_INSTR) {
+		dev_dbg(nfc->dev, "OP_CMD: code 0x%02x\n", instr->ctx.cmd.opcode);
+		vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
+		code |= COMMAND_CMD_BYTE1;
+
+		instr = vf610_get_next_instr(op, &op_id);
 	}
 
-	vf610_nfc_done(nfc);
+	if (instr && instr->type == NAND_OP_ADDR_INSTR) {
+		int addr = 0;
+		u32 col = 0, row;
 
-	nfc->use_hw_ecc = false;
-	nfc->write_sz = 0;
-}
+		if (instr->ctx.addr.naddrs > 1) {
+			col = COL_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
+			code |= COMMAND_CAR_BYTE1;
 
-static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
+			if (mtd->writesize > 512) {
+				col |= COL_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
+				code |= COMMAND_CAR_BYTE2;
+			}
+		}
 
-	/* Alternate buffers are only supported through read_byte */
-	WARN_ON(nfc->alt_buf);
+		row = ROW_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
+		code |= COMMAND_RAR_BYTE1;
+		if (addr < instr->ctx.addr.naddrs) {
+			row |= ROW_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
+			code |= COMMAND_RAR_BYTE2;
+		}
+		if (addr < instr->ctx.addr.naddrs) {
+			row |= ROW_ADDR_BYTE3(instr->ctx.addr.addrs[addr++]);
+			code |= COMMAND_RAR_BYTE3;
+		}
 
-	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
+		dev_dbg(nfc->dev, "OP_ADDR: col %d, row %d\n", col, row);
+		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
+			    COL_ADDR_SHIFT, col);
 
-	nfc->buf_offset += len;
-}
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+			    ROW_ADDR_SHIFT, row);
 
-static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
-				int len)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
-	uint l;
+		instr = vf610_get_next_instr(op, &op_id);
+	}
 
-	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
-	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
+	if (instr && instr->type == NAND_OP_DATA_OUT_INSTR) {
+		int len = instr->ctx.data.len;
+		int offset = 0;
 
-	nfc->write_sz += l;
-	nfc->buf_offset += l;
-}
+		dev_dbg(nfc->dev, "OP_DATA_OUT: len %d, offset %d\n", len, offset);
+
+		vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + offset,
+				 instr->ctx.data.buf.in + offset,
+				 len);
+		code |= COMMAND_WRITE_DATA;
+		trfr_sz += len;
+
+		instr = vf610_get_next_instr(op, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_CMD_INSTR) {
+		vf610_nfc_set_cmd2(nfc, instr->ctx.cmd.opcode);
+		code |= COMMAND_CMD_BYTE2;
+
+		instr = vf610_get_next_instr(op, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_WAITRDY_INSTR) {
+		//dev_dbg(nfc->dev, "WAITRDY [max %d ms]\n",
+		//		  instr->ctx.waitrdy.timeout_ms);
+		code |= COMMAND_RB_HANDSHAKE;
+
+		instr = vf610_get_next_instr(op, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		int len = instr->ctx.data.len;
+		code |= COMMAND_READ_DATA;
+		trfr_sz += len;
+	}
+
+	if (nfc->use_hw_ecc) {
+		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+
+		/* Always transfer complete page with OOB when using HW ECC */
+		trfr_sz = mtd->writesize + mtd->oobsize;
+	} else {
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+	}
+	vf610_nfc_transfer_size(nfc, trfr_sz);
+	vf610_nfc_send_code(nfc, code);
+
+	dev_dbg(nfc->dev, "Start: code: 0x%04x, hw ecc: %d, trfr_sz %d\n",
+		code, nfc->use_hw_ecc, trfr_sz);
+	vf610_nfc_done(nfc);
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		int len = instr->ctx.data.len;
+		int offset = 0;
+		bool fix_byte_order = false;
 
-static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	u8 tmp;
-	uint c = nfc->buf_offset;
-
-	switch (nfc->alt_buf) {
-	case ALT_BUF_ID:
-		tmp = vf610_nfc_get_id(nfc, c);
-		break;
-	case ALT_BUF_STAT:
-		tmp = vf610_nfc_get_status(nfc);
-		break;
 #ifdef __LITTLE_ENDIAN
-	case ALT_BUF_ONFI:
-		/* Reverse byte since the controller uses big endianness */
-		c = nfc->buf_offset ^ 0x3;
-		/* fall-through */
+		fix_byte_order = true;
 #endif
-	default:
-		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
-		break;
-	}
-	nfc->buf_offset++;
-	return tmp;
-}
+		dev_dbg(nfc->dev, "OP_DATA_IN: 8-bit: %d, len %d, offset %d\n",
+			instr->ctx.data.force_8bit , len, offset);
 
-static u16 vf610_nfc_read_word(struct mtd_info *mtd)
-{
-	u16 tmp;
+		/*
+		 * HACK: force_8bit indicates reading of the parameter, status
+		 * or id data. The controllers seems to store data in big endian
+		 * byte order to the buffers. Reverse on little endian machines.
+		 */
+		if (instr->ctx.data.force_8bit && fix_byte_order) {
+			u8 *buf = instr->ctx.data.buf.in;
 
-	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
-	return tmp;
-}
+			while (len--) {
+				int c = offset ^ 0x3;
 
-/* If not provided, upper layers apply a fixed delay. */
-static int vf610_nfc_dev_ready(struct mtd_info *mtd)
-{
-	/* NFC handles R/B internally; always ready.  */
-	return 1;
+				*buf = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+				//dev_info(nfc->dev, "[%d]: %02x\n", offset, *buf);
+				buf++; offset++;
+			}
+		} else {
+			vf610_nfc_memcpy(instr->ctx.data.buf.in + offset,
+					 nfc->regs + NFC_MAIN_AREA(0) + offset,
+					 len);
+		}
+	}
+
+	return 0;
 }
 
 /*
@@ -511,21 +465,6 @@ static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
 	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
 }
 
-/* Count the number of 0's in buff up to max_bits */
-static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
-{
-	uint32_t *buff32 = (uint32_t *)buff;
-	int k, written_bits = 0;
-
-	for (k = 0; k < (size / 4); k++) {
-		written_bits += hweight32(~buff32[k]);
-		if (unlikely(written_bits > max_bits))
-			break;
-	}
-
-	return written_bits;
-}
-
 static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
 					 uint8_t *oob, int page)
 {
@@ -542,8 +481,7 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
 		return ecc_count;
 
 	/* Read OOB without ECC unit enabled */
-	vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
-	vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
+	nand_read_page_op(&nfc->chip, page, mtd->writesize, oob, mtd->oobsize);
 
 	/*
 	 * On an erased page, bit count (including OOB) should be zero or
@@ -557,12 +495,17 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
 static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int oob_required, int page)
 {
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 	int eccsize = chip->ecc.size;
 	int stat;
 
+	nfc->use_hw_ecc = true;
 	nand_read_page_op(chip, page, 0, buf, eccsize);
 	if (oob_required)
-		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+		vf610_nfc_memcpy(chip->oob_poi,
+				 nfc->regs + NFC_MAIN_AREA(0) + mtd->writesize,
+				 mtd->oobsize);
+	nfc->use_hw_ecc = false;
 
 	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
 
@@ -579,16 +522,20 @@ static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required, int page)
 {
 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
 
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	if (oob_required)
-		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	/* Always write whole page including OOB due to HW ECC */
 	nfc->use_hw_ecc = true;
-	nfc->write_sz = mtd->writesize + mtd->oobsize;
+	ret = nand_prog_page_op(chip, page, 0, buf, mtd->writesize);
+	nfc->use_hw_ecc = false;
 
-	return nand_prog_page_end_op(chip);
+	return ret;
+}
+
+static int vf610_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf, int oob_required, int page)
+{
+	return nand_prog_page_op(chip, page, 0, buf,
+			mtd->writesize + oob_required ? mtd->oobsize : 0);
 }
 
 static const struct of_device_id vf610_nfc_dt_ids[] = {
@@ -606,6 +553,9 @@ static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
 	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
 	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
 
+	/* Make sure flags are cleared on startup */
+	vf610_nfc_clear_status(nfc);
+
 	/* Disable virtual pages, only one elementary transfer unit */
 	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
 			    CONFIG_PAGE_CNT_SHIFT, 1);
@@ -695,15 +645,8 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	chip->dev_ready = vf610_nfc_dev_ready;
-	chip->cmdfunc = vf610_nfc_command;
-	chip->read_byte = vf610_nfc_read_byte;
-	chip->read_word = vf610_nfc_read_word;
-	chip->read_buf = vf610_nfc_read_buf;
-	chip->write_buf = vf610_nfc_write_buf;
+	chip->exec_op = vf610_nfc_exec_op;
 	chip->select_chip = vf610_nfc_select_chip;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
 
 	chip->options |= NAND_NO_SUBPAGE_WRITE;
 
@@ -770,6 +713,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 
 		chip->ecc.read_page = vf610_nfc_read_page;
 		chip->ecc.write_page = vf610_nfc_write_page;
+		chip->ecc.write_page_raw = vf610_nfc_write_page_raw;
 
 		chip->ecc.size = PAGE_2K;
 	}
-- 
2.15.1



From ezequiel at vanguardiasur.com.ar  Sun Jan 14 14:20:52 2018
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 14 Jan 2018 19:20:52 -0300
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <20180114153915.4c6141a4@bbrezillon>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
 <20180114153915.4c6141a4@bbrezillon>
Message-ID: <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>

On 14 January 2018 at 11:39, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> +Ezequiel
>
> Hi Bradley,
>
> On Tue,  2 Jan 2018 21:26:09 -0500
> Bradley Bolen <bradleybolen at gmail.com> wrote:
>
>> This fixes a race condition where running ubiblock on multiple volumes
>> simultaneously produces the following splat.
>>
>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
>> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
>> (sysfs_create_group+0x20/0x24)
>> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
>> (blk_trace_init_sysfs+0x18/0x20)
>> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
>> (blk_register_queue+0x6c/0x154)
>> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
>> (device_add_disk+0x2c8/0x450)
>> [<c02cd610>] (device_add_disk) from [<c0430fac>]
>> (ubiblock_create+0x254/0x2e4)
>> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
>> (vol_cdev_ioctl+0x3e0/0x564)
>> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
>> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
>> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
>> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)
>>

I'm a little confused, how does this stack trace relates to idr?

>
> Missing Fixes and Cc-stable tags.
>
>> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
>
>
> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
>
> BTW, just had a quick look at the code, and I think the locking can be
> simplified a bit by keeping the devices_lock for the whole
> ubiblock_create() operation instead of acquiring/releasing it several
> times in the function (see [1]). It makes sense to do fine grained
> locking when operations protected by the lock are time sensitive, but I
> don't think this is the case here.
>

Agreed. Something like this perhaps http://ix.io/E8G ?
Notice that ubiblock_remove_all seemed to require locking as well.
-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From guochun.mao at mediatek.com  Sun Jan 14 17:58:34 2018
From: guochun.mao at mediatek.com (Guochun Mao)
Date: Mon, 15 Jan 2018 09:58:34 +0800
Subject: [PATCH] mtd: mtk-nor: modify functions' name more generally
In-Reply-To: <5348c8dd-dc78-bdeb-f9d0-5ce20616d69b@wedev4u.fr>
References: <1513561655-10570-1-git-send-email-guochun.mao@mediatek.com>
 <1513561655-10570-2-git-send-email-guochun.mao@mediatek.com>
 <5348c8dd-dc78-bdeb-f9d0-5ce20616d69b@wedev4u.fr>
Message-ID: <1515981514.8823.3.camel@mhfsdcap03>

Hi Cyrille,

Thank you very much.

BR,
Guochun Mao


On Sun, 2018-01-14 at 16:23 +0100, Cyrille Pitchen wrote:
> Le 18/12/2017 ? 02:47, Guochun Mao a ?crit :
> > Since more and more Mediatek's SoC can use this driver to
> > control spi-nor flash, functions' name with "mt8173_" is
> > no longer properly. Replacing "mt8173_" with "mtk_" will
> > be more accurate to describe these functions' usable scope.
> > 
> > Signed-off-by: Guochun Mao <guochun.mao at mediatek.com>
> 
> Applied to the spi-nor/next branch of linux-mtd
> 
> Thanks!
> 
> > ---
> >  drivers/mtd/spi-nor/mtk-quadspi.c |  240 ++++++++++++++++++-------------------
> >  1 file changed, 120 insertions(+), 120 deletions(-)
> > 





From boris.brezillon at free-electrons.com  Mon Jan 15 02:02:42 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 11:02:42 +0100
Subject: [PATCH] mtd: onenand: samsung: remove incorrect __iomem annotation
In-Reply-To: <20180113165616.19992-1-christophe.jaillet@wanadoo.fr>
References: <20180113165616.19992-1-christophe.jaillet@wanadoo.fr>
Message-ID: <20180115110242.60354eca@bbrezillon>

On Sat, 13 Jan 2018 17:56:16 +0100
Christophe JAILLET <christophe.jaillet at wanadoo.fr> wrote:

> 'page_buf' and 'oob_buf' are allocated with 'devm_kzalloc()' and should not
> have __iommem decoration.
> 
> Remove these decorations and some useless casting.
> 

Applied.

Thanks,

Boris

> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
>  drivers/mtd/onenand/samsung.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
> index dfdfb478ba35..2e9d076e445a 100644
> --- a/drivers/mtd/onenand/samsung.c
> +++ b/drivers/mtd/onenand/samsung.c
> @@ -129,8 +129,8 @@ struct s3c_onenand {
>  	void __iomem	*base;
>  	void __iomem	*ahb_addr;
>  	int		bootram_command;
> -	void __iomem	*page_buf;
> -	void __iomem	*oob_buf;
> +	void		*page_buf;
> +	void		*oob_buf;
>  	unsigned int	(*mem_addr)(int fba, int fpa, int fsa);
>  	unsigned int	(*cmd_map)(unsigned int type, unsigned int val);
>  	void __iomem	*dma_addr;
> @@ -408,8 +408,8 @@ static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
>  	/*
>  	 * Emulate Two BufferRAMs and access with 4 bytes pointer
>  	 */
> -	m = (unsigned int *) onenand->page_buf;
> -	s = (unsigned int *) onenand->oob_buf;
> +	m = onenand->page_buf;
> +	s = onenand->oob_buf;
>  
>  	if (index) {
>  		m += (this->writesize >> 2);
> @@ -481,11 +481,11 @@ static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
>  	unsigned char *p;
>  
>  	if (area == ONENAND_DATARAM) {
> -		p = (unsigned char *) onenand->page_buf;
> +		p = onenand->page_buf;
>  		if (index == 1)
>  			p += this->writesize;
>  	} else {
> -		p = (unsigned char *) onenand->oob_buf;
> +		p = onenand->oob_buf;
>  		if (index == 1)
>  			p += mtd->oobsize;
>  	}



From boris.brezillon at free-electrons.com  Mon Jan 15 02:06:26 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 11:06:26 +0100
Subject: [RFC PATCH v2] mtd: nand: vf610_nfc: make use of ->exec_op()
In-Reply-To: <20180114220012.30039-1-stefan@agner.ch>
References: <20180114220012.30039-1-stefan@agner.ch>
Message-ID: <20180115110626.512ade88@bbrezillon>

Hi Stefan,

On Sun, 14 Jan 2018 23:00:12 +0100
Stefan Agner <stefan at agner.ch> wrote:

> This reworks the driver to make use of ->exec_op() callback. The
> command sequencer of the VF610 NFC aligns well with the new ops
> interface.
> 
> The ops are translated to a NFC command code while filling the
> necessary registers. Instead of using the special status and
> read id command codes (which require the status/id form special
> registers) the driver now uses the main data buffer for all
> commands. This simplifies the driver as no special casing is
> needed.
> 
> For control data (status byte, id bytes and parameter page) the
> driver needs to reverse byte order for little endian CPUs since
> the controller seems to store the bytes in big endian order in
> the data buffer.
> 
> The current state seems to pass MTD tests on a Colibri VF61.
> 
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
> Hi,
> 
> In this second version I was able to remove all special command
> handling. As Boris suggested, the special READID/STATUS handling
> is really not needed and all return values can be read from the
> regular data buffer. This simplified code even more and allowed
> to get rid of the hack in the MTD core. The driver is now able
> to handle all commands in a single function. Therefor I also got
> rid of the command parser, since everything is handled in a single
> function anyway.

Hm, I'm not sure getting rid of the generic command parser is a good
move. AFAICT, your controller has constraints of the command order and
you'll have to add tests that are already handled by the generic parser
(example, CMD+ADDR+CMD+WAITRB+DATA_OUT is not supported).

Another reason is the internal buffer SIZE limitation (2k IIUC), which
means, if the core requests more than 2k in one go, you'll have to
split the request in several operations. The generic operation parser
can do that for you.

> 
> The only thing which is somewhat unfortunate is the byte ordering
> which needs to be reversed for commands which read flash data (id,
> status and parameter page). All those request 8-bit handling, so
> I used this as an indicator to fix byte order.

Actually, I think the faulty part is the write/read page handling which
is doing things in the wrong endianness, but that's not something you
can change. I have one solution for this problem: don't use the generic
helpers for the read/write page hooks, and always swap bytes in the
->exec_op() path.

Note that "8-bit vs non-8-bit" approach is not such a good idea,
because the core might want to read OTP area of the NAND (programmed by
the vendor) using non-8-bit mode.

> 
> I did meassured a slight performance drop (before vs. now):
> - write speed is 4036 KiB/s vs 3495 KiB/s
> - read speed is 13741 KiB/s vs 13490 KiB/s

I still need to take a closer look at the code, but it might be a good
idea to bypass the ->exec_op() logic in your
ecc->[read,write]_page[_raw] handlers and optimize this path.

I'll try to have a look at the diff, but it's a bit hard to review
because of the unrelated interleaved removed/added lines.

Thanks,

Boris


From yogeshnarayan.gaur at nxp.com  Mon Jan 15 02:14:46 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Mon, 15 Jan 2018 15:44:46 +0530
Subject: [PATCH v2 0/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
Message-ID: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has 4 chip select and one can use different flashes
on all different chip select.
We analyzed that the flashes have different parameters for the same command
and this is true for NAND devices.
Also reg_protocol information, required for read register, read any
register commands, read SFDP register, not available at the time of nor scan.
As FSL QUADSPI controller has limitation in number of LUT entries, max 16,
require to have dynamic LUT creation support.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also update read capabilities as 1-4-4.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: add support to create dynamic LUT entry
  mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4

 drivers/mtd/spi-nor/fsl-quadspi.c | 291 ++++++++++++++++++++------------------
 1 file changed, 150 insertions(+), 141 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Mon Jan 15 02:14:47 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Mon, 15 Jan 2018 15:44:47 +0530
Subject: [PATCH v2 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
In-Reply-To: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516011288-6936-2-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>

v1: Swap patch sequences in the series to solve git bissect issue.
v2: Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 290 ++++++++++++++++++++------------------
 1 file changed, 149 insertions(+), 141 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index c22e3eb..48d0639 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -193,21 +193,21 @@
 #define QUADSPI_LUT_NUM		64
 
 /* SEQID -- we can have 16 seqids at most. */
+/* LUT0 programmed by bootloader, for run-time create entry for LUT seqid 1 */
 #define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+#define SEQID_RUN_CMD		1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +368,140 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
+{
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
 {
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
-	int i;
-
-	struct spi_nor *nor = &q->nor[0];
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
 	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	u8 read_dm, opcode;
+	int stop_lut;
+
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
+
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
+
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
-		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
-
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
+	/* Dynamic LUT */
+	lut_base = SEQID_RUN_CMD * 4;
 
-	fsl_qspi_lock_lut(q);
-}
+	/* default, STOP instruction to be programmed in (lut_base + 1) reg */
+	stop_lut = 1;
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		if (ops == FSL_QSPI_OPS_READ) {
+			qspi_writel(q,
+				    LUT0(DUMMY, pad_count(dummy_pad), read_dm) |
+				    LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+				    base + QUADSPI_LUT(lut_base + 1));
+			stop_lut = 2;
+
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				SEQID_RUN_CMD << QUADSPI_BFGENCR_SEQID_SHIFT,
+				q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+			stop_lut = 2;
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	/* prepare LUT for STOP instruction. */
+	qspi_writel(q, 0, base +  QUADSPI_LUT(lut_base + stop_lut));
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +536,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +688,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +732,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -746,9 +749,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 		base + QUADSPI_MCR);
 	udelay(1);
 
-	/* Init the LUT table. */
-	fsl_qspi_init_lut(q);
-
 	/* Disable the module */
 	qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
 			base + QUADSPI_MCR);
@@ -794,9 +794,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	return 0;
 }
 
@@ -820,6 +817,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +832,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +842,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +860,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +877,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +927,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Mon Jan 15 02:14:48 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Mon, 15 Jan 2018 15:44:48 +0530
Subject: [PATCH v2 2/2] mtd: fsl-quadspi: update hwcaps read capabilities as
 READ_1_4_4
In-Reply-To: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516011288-6936-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Update Read capabilities as SNOR_HWCAPS_READ_1_4_4 i.e. Quad I/O cmd
protocol. Spansion flash, s25fl512s, supports Quad read with read
capabilities as 1-4-4.

Patch added support for SNOR_HWCAPS_READ_1_4_4 protocol.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>

V1: Swap patch sequences in the series to solve git bissect issue.
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 48d0639..bc72678 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -967,6 +967,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	const struct spi_nor_hwcaps hwcaps = {
 		.mask = SNOR_HWCAPS_READ_1_1_4 |
+			SNOR_HWCAPS_READ_1_4_4 |
 			SNOR_HWCAPS_PP,
 	};
 	struct device_node *np = pdev->dev.of_node;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Mon Jan 15 02:39:45 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Narayan Gaur)
Date: Mon, 15 Jan 2018 10:39:45 +0000
Subject: [PATCH v2 1/2] mtd: fsl-quadspi: add support to create dynamic
 LUT entry
In-Reply-To: <1516011288-6936-2-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516011288-6936-1-git-send-email-yogeshnarayan.gaur@nxp.com>
 <1516011288-6936-2-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <DB6PR0402MB2838F8D4EAE61DB0F05EFBB399EB0@DB6PR0402MB2838.eurprd04.prod.outlook.com>

Checked performance with this patch set for Read, Write and Erase operation started using mtd_debug utility.
	time mtd_debug <ops> /dev/mtd0 0xc00000 0x100000

For Read/Write perform operation with data size of 1MB and for erase perform erase of 4MB data size.

For write and erase performance degradation is in range of ~(1-2)% for above data size
For read performance degradation is in range of ~(0-1)% for above data size.

--
Regards
Yogesh Gaur.

> -----Original Message-----
> From: Yogesh Gaur [mailto:yogeshnarayan.gaur at nxp.com]
> Sent: Monday, January 15, 2018 3:45 PM
> To: linux-mtd at lists.infradead.org
> Cc: boris.brezillon at free-electrons.com; cyrille.pitchen at wedev4u.fr;
> computersforpeace at gmail.com; Han Xu <han.xu at nxp.com>;
> festevam at gmail.com; Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>;
> Suresh Gupta <suresh.gupta at nxp.com>; Yogesh Narayan Gaur
> <yogeshnarayan.gaur at nxp.com>
> Subject: [PATCH v2 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
> entry
> 
> Add support to create dynamic LUT entry.
> 
> Current approach of creating LUT entries for various cmds like read, write,
> erase, readid, readsr, we, wd etc is that when QSPI controller gets initialized at
> that time static LUT entries for these cmds get created.
> 
> Patch add support to create the LUT at run time based on the operation being
> performed.
> 
> Added API fsl_qspi_prepare_lut(), this API would going to be called from
> fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
> fsl_qspi_erase APIs.
> This API would fetch required info like opcode, protocol info, dummy info for
> creating LUT from instance of 'struct spi_nor' and then prepare LUT entry for the
> required command.
> 
> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
> 
> v1: Swap patch sequences in the series to solve git bissect issue.
> v2: Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c | 290 ++++++++++++++++++++------------------
>  1 file changed, 149 insertions(+), 141 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index c22e3eb..48d0639 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -183,7 +183,7 @@
> 
>  /* Macros for constructing the LUT register. */
>  #define LUT0(ins, pad, opr)						\
> -		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
> +		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
>  		((LUT_##ins) << INSTR0_SHIFT))
> 
>  #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
> @@ -193,21 +193,21 @@
>  #define QUADSPI_LUT_NUM		64
> 
>  /* SEQID -- we can have 16 seqids at most. */
> +/* LUT0 programmed by bootloader, for run-time create entry for LUT
> +seqid 1 */
>  #define SEQID_READ		0
> -#define SEQID_WREN		1
> -#define SEQID_WRDI		2
> -#define SEQID_RDSR		3
> -#define SEQID_SE		4
> -#define SEQID_CHIP_ERASE	5
> -#define SEQID_PP		6
> -#define SEQID_RDID		7
> -#define SEQID_WRSR		8
> -#define SEQID_RDCR		9
> -#define SEQID_EN4B		10
> -#define SEQID_BRWR		11
> +#define SEQID_RUN_CMD		1
> 
>  #define QUADSPI_MIN_IOMAP SZ_4M
> 
> +enum fsl_qspi_ops {
> +	FSL_QSPI_OPS_READ = 0,
> +	FSL_QSPI_OPS_WRITE,
> +	FSL_QSPI_OPS_ERASE,
> +	FSL_QSPI_OPS_READ_REG,
> +	FSL_QSPI_OPS_WRITE_REG,
> +	FSL_QSPI_OPS_WRITE_BUF_REG,
> +};
> +
>  enum fsl_qspi_devtype {
>  	FSL_QUADSPI_VYBRID,
>  	FSL_QUADSPI_IMX6SX,
> @@ -368,136 +368,140 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void
> *dev_id)
>  	return IRQ_HANDLED;
>  }
> 
> -static void fsl_qspi_init_lut(struct fsl_qspi *q)
> +static inline s8 pad_count(s8 pad_val)
> +{
> +	s8 count = -1;
> +
> +	if (!pad_val)
> +		return 0;
> +
> +	while (pad_val) {
> +		pad_val >>= 1;
> +		count++;
> +	}
> +	return count;
> +}
> +
> +/*
> + * Prepare LUT entry for the input cmd.
> + * Protocol info is present in instance of struct spi_nor, using which
> +fields
> + * like cmd, data, addrlen along with pad info etc can be parsed.
> + */
> +static void fsl_qspi_prepare_lut(struct spi_nor *nor,
> +				 enum fsl_qspi_ops ops, u8 cmd)
>  {
> +	struct fsl_qspi *q = nor->priv;
>  	void __iomem *base = q->iobase;
>  	int rxfifo = q->devtype_data->rxfifo;
> +	int txfifo = q->devtype_data->txfifo;
>  	u32 lut_base;
> -	int i;
> -
> -	struct spi_nor *nor = &q->nor[0];
> +	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
> +	enum spi_nor_protocol protocol = 0;
>  	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
> -	u8 read_op = nor->read_opcode;
> -	u8 read_dm = nor->read_dummy;
> +	u8 read_dm, opcode;
> +	int stop_lut;
> +
> +	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad =
> 0;
> +
> +	switch (ops) {
> +	case FSL_QSPI_OPS_READ_REG:
> +	case FSL_QSPI_OPS_WRITE_REG:
> +	case FSL_QSPI_OPS_WRITE_BUF_REG:
> +		opcode = cmd;
> +		protocol = nor->reg_proto;
> +		break;
> +	case FSL_QSPI_OPS_READ:
> +		opcode = cmd;
> +		read_dm = nor->read_dummy;
> +		protocol = nor->read_proto;
> +		break;
> +	case FSL_QSPI_OPS_WRITE:
> +		opcode = cmd;
> +		protocol = nor->write_proto;
> +		break;
> +	case FSL_QSPI_OPS_ERASE:
> +		opcode = cmd;
> +		break;
> +	default:
> +		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
> +		return;
> +	}
> +
> +	if (protocol) {
> +		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
> +		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
> +		data_pad = spi_nor_get_protocol_data_nbits(protocol);
> +	}
> +
> +	dummy_pad = data_pad;
> +
> +	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d,
> data:%d]\n",
> +			ops, opcode, cmd_pad, addr_pad, data_pad);
> 
>  	fsl_qspi_unlock_lut(q);
> 
> -	/* Clear all the LUT table */
> -	for (i = 0; i < QUADSPI_LUT_NUM; i++)
> -		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
> -
> -	/* Read */
> -	lut_base = SEQID_READ * 4;
> -
> -	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
> -			base + QUADSPI_LUT(lut_base));
> -	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
> -		    LUT1(FSL_READ, PAD4, rxfifo),
> -			base + QUADSPI_LUT(lut_base + 1));
> -
> -	/* Write enable */
> -	lut_base = SEQID_WREN * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Page Program */
> -	lut_base = SEQID_PP * 4;
> -
> -	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
> -		    LUT1(ADDR, PAD1, addrlen),
> -			base + QUADSPI_LUT(lut_base));
> -	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
> -			base + QUADSPI_LUT(lut_base + 1));
> -
> -	/* Read Status */
> -	lut_base = SEQID_RDSR * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
> -			LUT1(FSL_READ, PAD1, 0x1),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Erase a sector */
> -	lut_base = SEQID_SE * 4;
> -
> -	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
> -		    LUT1(ADDR, PAD1, addrlen),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Erase the whole chip */
> -	lut_base = SEQID_CHIP_ERASE * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* READ ID */
> -	lut_base = SEQID_RDID * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
> -			LUT1(FSL_READ, PAD1, 0x8),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Write Register */
> -	lut_base = SEQID_WRSR * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
> -			LUT1(FSL_WRITE, PAD1, 0x2),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Read Configuration Register */
> -	lut_base = SEQID_RDCR * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
> -			LUT1(FSL_READ, PAD1, 0x1),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Write disable */
> -	lut_base = SEQID_WRDI * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Enter 4 Byte Mode (Micron) */
> -	lut_base = SEQID_EN4B * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
> -			base + QUADSPI_LUT(lut_base));
> -
> -	/* Enter 4 Byte Mode (Spansion) */
> -	lut_base = SEQID_BRWR * 4;
> -	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
> -			base + QUADSPI_LUT(lut_base));
> +	/* Dynamic LUT */
> +	lut_base = SEQID_RUN_CMD * 4;
> 
> -	fsl_qspi_lock_lut(q);
> -}
> +	/* default, STOP instruction to be programmed in (lut_base + 1) reg */
> +	stop_lut = 1;
> +	switch (ops) {
> +	case FSL_QSPI_OPS_READ_REG:
> +		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
> +			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
> +			  base + QUADSPI_LUT(lut_base));
> +		break;
> +	case FSL_QSPI_OPS_WRITE_REG:
> +		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
> +			  base + QUADSPI_LUT(lut_base));
> +		break;
> +	case FSL_QSPI_OPS_WRITE_BUF_REG:
> +		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
> +			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
> +			  base + QUADSPI_LUT(lut_base));
> +		break;
> +	case FSL_QSPI_OPS_READ:
> +	case FSL_QSPI_OPS_WRITE:
> +	case FSL_QSPI_OPS_ERASE:
> +		/* Common for Read, Write and Erase ops. */
> +		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
> +				LUT1(ADDR, pad_count(addr_pad), addrlen),
> +				base + QUADSPI_LUT(lut_base));
> +		/*
> +		 * For Erase ops - Data and Dummy not required.
> +		 * For Write ops - Dummy not required.
> +		 */
> 
> -/* Get the SEQID for the command */
> -static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd) -{
> -	switch (cmd) {
> -	case SPINOR_OP_READ_1_1_4:
> -		return SEQID_READ;
> -	case SPINOR_OP_WREN:
> -		return SEQID_WREN;
> -	case SPINOR_OP_WRDI:
> -		return SEQID_WRDI;
> -	case SPINOR_OP_RDSR:
> -		return SEQID_RDSR;
> -	case SPINOR_OP_SE:
> -		return SEQID_SE;
> -	case SPINOR_OP_CHIP_ERASE:
> -		return SEQID_CHIP_ERASE;
> -	case SPINOR_OP_PP:
> -		return SEQID_PP;
> -	case SPINOR_OP_RDID:
> -		return SEQID_RDID;
> -	case SPINOR_OP_WRSR:
> -		return SEQID_WRSR;
> -	case SPINOR_OP_RDCR:
> -		return SEQID_RDCR;
> -	case SPINOR_OP_EN4B:
> -		return SEQID_EN4B;
> -	case SPINOR_OP_BRWR:
> -		return SEQID_BRWR;
> +		if (ops == FSL_QSPI_OPS_READ) {
> +			qspi_writel(q,
> +				    LUT0(DUMMY, pad_count(dummy_pad),
> read_dm) |
> +				    LUT1(FSL_READ, pad_count(data_pad),
> rxfifo),
> +				    base + QUADSPI_LUT(lut_base + 1));
> +			stop_lut = 2;
> +
> +			/* TODO Add condition to check if READ is IP/AHB. */
> +
> +			/* For AHB read, add seqid in BFGENCR register. */
> +			qspi_writel(q,
> +				SEQID_RUN_CMD <<
> QUADSPI_BFGENCR_SEQID_SHIFT,
> +				q->iobase + QUADSPI_BFGENCR);
> +		}
> +
> +		if (ops == FSL_QSPI_OPS_WRITE) {
> +			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad),
> 0),
> +					base + QUADSPI_LUT(lut_base + 1));
> +			stop_lut = 2;
> +		}
> +		break;
>  	default:
> -		if (cmd == q->nor[0].erase_opcode)
> -			return SEQID_SE;
> -		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
> +		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
>  		break;
>  	}
> -	return -EINVAL;
> +
> +	/* prepare LUT for STOP instruction. */
> +	qspi_writel(q, 0, base +  QUADSPI_LUT(lut_base + stop_lut));
> +
> +	fsl_qspi_lock_lut(q);
>  }
> 
>  static int
> @@ -532,7 +536,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
>  	} while (1);
> 
>  	/* trigger the LUT now */
> -	seqid = fsl_qspi_get_seqid(q, cmd);
> +	seqid = SEQID_RUN_CMD;
>  	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
>  			base + QUADSPI_IPCR);
> 
> @@ -684,8 +688,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
>  	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
>  	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
> 
> -	/* Set the default lut sequence for AHB Read. */
> -	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
> +	/* Set dynamic LUT entry as lut sequence for AHB Read . */
> +	seqid = SEQID_RUN_CMD;
>  	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
>  		q->iobase + QUADSPI_BFGENCR);
>  }
> @@ -728,7 +732,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
>  	void __iomem *base = q->iobase;
>  	u32 reg;
>  	int ret;
> -
>  	/* disable and unprepare clock to avoid glitch pass to controller */
>  	fsl_qspi_clk_disable_unprep(q);
> 
> @@ -746,9 +749,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
>  		base + QUADSPI_MCR);
>  	udelay(1);
> 
> -	/* Init the LUT table. */
> -	fsl_qspi_init_lut(q);
> -
>  	/* Disable the module */
>  	qspi_writel(q, QUADSPI_MCR_MDIS_MASK |
> QUADSPI_MCR_RESERVED_MASK,
>  			base + QUADSPI_MCR);
> @@ -794,9 +794,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
>  	if (ret)
>  		return ret;
> 
> -	/* Init the LUT table again. */
> -	fsl_qspi_init_lut(q);
> -
>  	return 0;
>  }
> 
> @@ -820,6 +817,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8
> opcode, u8 *buf, int len)
>  	int ret;
>  	struct fsl_qspi *q = nor->priv;
> 
> +	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
>  	ret = fsl_qspi_runcmd(q, opcode, 0, len);
>  	if (ret)
>  		return ret;
> @@ -834,6 +832,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8
> opcode, u8 *buf, int len)
>  	int ret;
> 
>  	if (!buf) {
> +		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
> +		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
>  		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
>  		if (ret)
>  			return ret;
> @@ -842,6 +842,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8
> opcode, u8 *buf, int len)
>  			fsl_qspi_invalid(q);
> 
>  	} else if (len > 0) {
> +		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL.
> */
> +		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG,
> opcode);
>  		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
>  					(u32 *)buf, len);
>  		if (ret > 0)
> @@ -858,8 +860,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t
> to,
>  			      size_t len, const u_char *buf)  {
>  	struct fsl_qspi *q = nor->priv;
> -	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
> -					 (u32 *)buf, len);
> +	ssize_t ret;
> +
> +	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor-
> >program_opcode);
> +	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
> +				 (u32 *)buf, len);
> 
>  	/* invalid the data in the AHB buffer. */
>  	fsl_qspi_invalid(q);
> @@ -872,6 +877,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t
> from,
>  	struct fsl_qspi *q = nor->priv;
>  	u8 cmd = nor->read_opcode;
> 
> +	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
> +
>  	/* if necessary,ioremap buffer before AHB read, */
>  	if (!q->ahb_addr) {
>  		q->memmap_offs = q->chip_base_addr + from; @@ -920,6
> +927,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
>  	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
>  		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
> 
> +	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
>  	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
>  	if (ret)
>  		return ret;
> --
> 1.9.1



From zajec5 at gmail.com  Mon Jan 15 02:58:18 2018
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Mon, 15 Jan 2018 11:58:18 +0100
Subject: [PATCH 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180112160127.0bfc3c57@bbrezillon>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180112144034.6655-2-zajec5@gmail.com>
 <20180112160127.0bfc3c57@bbrezillon>
Message-ID: <CACna6ryuzV9aqWt+rrYkcPbibArtvo0OED8Z8dUgv4Cx2+cUwg@mail.gmail.com>

On 12 January 2018 at 16:01, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
>> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
>> index f80e911b8843..f6460862e2ad 100644
>> --- a/drivers/mtd/mtdcore.c
>> +++ b/drivers/mtd/mtdcore.c
>> @@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
>>  {
>>       const struct mtd_partition *real_parts = parts->parts;
>>       int nbparts = parts->nr_parts;
>> -     int ret;
>>
>> -     if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
>> -             ret = add_mtd_device(mtd);
>> -             if (ret)
>> -                     return ret;
>> -     }
>> +     if (nbparts == 0 && !IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
>> +             return add_mtd_device(mtd);
>
> Why not moving this part in mtd_device_parse_register() as well.

I move that in 2/2. I prefer to handle these changes in 2 steps as it
should be quite easier to review it that way.


> And I'd prefer something like:
>
>         if (!nbparts && !device_is_registered(&mtd->dev))
>                 ...

Nice idea with that device_is_registered.


From boris.brezillon at free-electrons.com  Mon Jan 15 02:59:50 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 11:59:50 +0100
Subject: [GIT PULL] mtd: nand: Changes for 4.16
Message-ID: <20180115115950.05b03d2b@bbrezillon>

Hello,

Here is the NAND PR for 4.16. As can be seen in the diffstat, the NAND
subsystem has been quite active. That's mainly caused by the
introduction of the ->exec_op() hook and the rework of the Marvell
driver.

Regards,

Boris

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/nand/for-4.16

for you to fetch changes up to 6837befde3a6b42a36c894a4f86bafdc6db82534:

  mtd: onenand: samsung: remove incorrect __iomem annotation (2018-01-14 15:04:56 +0100)

----------------------------------------------------------------
Core changes:
* Fix NAND_CMD_NONE handling in nand_command[_lp]() hooks
* Introduce the ->exec_op() infrastructure
* Rework NAND buffers handling
* Fix ECC requirements for K9F4G08U0D
* Fix nand_do_read_oob() to return the number of bitflips
* Mark K9F1G08U0E as not supporting subpage writes

Driver changes:
* MTK: Rework the driver to support new IP versions
* OMAP OneNAND: Full rework to use new APIs (libgpio, dmaengine) and fix
  DT support
* Marvell: Add a new driver to replace the pxa3xx one

----------------------------------------------------------------
Boris Brezillon (6):
      mtd: nand: hynix: Don't wait after applying new read-retry params
      mtd: nand: provide several helpers to do common NAND operations
      mtd: nand: force drivers to explicitly send READ/PROG commands
      mtd: nand: denali: Avoid using ecc->code_buf as a temporary buffer
      mtd: nand: Only allocate ecc->{calc, code}_buf when actually needed
      Merge tag 'gpmc-omap-for-v4.16-immutable' of https://github.com/rogerq/linux into nand/next

Christophe JAILLET (5):
      mtd: onenand: samsung: use devm_ function to simplify code and fix some leaks
      mtd: onenand: samsung: return an error if 'mtd_device_parse_register()' fails
      mtd: onenand: samsung: Propagate the error returned by 'onenand_scan()'
      mtd: onenand: samsung: Remove a useless include
      mtd: onenand: samsung: remove incorrect __iomem annotation

Fabio Estevam (2):
      mtd: nand: brcmnand: Add a NULL check for devm_kasprintf()
      mtd: nand: qcom: Add a NULL check for devm_kasprintf()

Gustavo A. R. Silva (1):
      mtd: nand: gpmi: replace _manual_ swap with swap macro

Jagdish Gediya (1):
      mtd: nand: ifc: update bufnum mask for ver >= 2.0.0

Jesse Chan (1):
      mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE

Kamal Dasu (1):
      mtd: nand: brcmnand: Disable prefetch by default

Ladislav Michl (15):
      memory: omap-gpmc: Make 'bank-width' property optional
      mtd: onenand: Remove obsolete url from Kconfig help
      mtd: nand: samsung: Disable subpage writes on E-die NAND
      dt-bindings: mtd: gpmc-onenand: Update properties description
      ARM: dts: OMAP2+: Add compatible property to onenand node
      ARM: dts: omap3-igep: Update onenand node timings
      mtd: onenand: omap2: Remove regulator support
      mtd: onenand: omap2: Remove skip initial unlocking support
      mtd: onenand: omap2: Remove partitioning support from platform data
      mtd: onenand: omap2: Account waiting time as waiting on IO
      mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
      mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
      mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
      mtd: onenand: omap2: Configure driver from DT
      ARM: OMAP2+: Remove gpmc-onenand

Masahiro Yamada (6):
      mtd: nand: remove unnecessary extern from driver headers
      mtd: nand: denali: rename misleading dma_buf to tmp_buf
      mtd: nand: cafe: remove use of NAND_OWN_BUFFERS
      mtd: nand: remove unused NAND_OWN_BUFFERS flag
      mtd: nand: squash struct nand_buffers into struct nand_chip
      mtd: nand: cafe: clean up DMA address setup

Miquel Raynal (13):
      mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]()
      mtd: nand: use usual return values for the ->erase() hook
      mtd: nand: provide valid ->data_interface during NAND detection
      mtd: nand: samsung: add ECC requirements for K9F4G08U0D
      mtd: nand: add ->exec_op() implementation
      mtd: nand: Fix unfinished comment in nand_init_data_interface()
      mtd: mtd_oobtest: Handle bitflips during reads
      mtd: nand: Fix nand_do_read_oob() return value
      dt-bindings: mtd: document new nand-rb property
      dt-bindings: mtd: add Marvell NAND controller documentation
      mtd: nand: add reworked Marvell NAND controller driver
      mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
      MAINTAINERS: Add entry for Marvell NAND controller driver

Nicolas Ferre (1):
      MAINTAINERS: mtd/nand: update Microchip nand entry

Peter Ujfalusi (2):
      mtd: onenand: omap2: Simplify the DMA setup for various paths
      mtd: onenand: omap2: Convert to use dmaengine for memcpy

RogerCC Lin (3):
      mtd: nand: mtk: update DT bindings
      mtd: nand: mtk: Support different MTK NAND flash controller IP
      mtd: nand: mtk: Support MT7622 NAND flash controller.

Sascha Hauer (2):
      mtd: nand: gpmi-nand: Remove wrong Kconfig help text
      mtd: tests: nandbiterrs: Fix read_page return value

Xiaolei Li (1):
      mtd: nand: mtk: use nand_reset() to reset NAND devices in resume function

 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt |    6 +-
 Documentation/devicetree/bindings/mtd/marvell-nand.txt |  123 ++
 Documentation/devicetree/bindings/mtd/mtk-nand.txt     |   11 +-
 Documentation/devicetree/bindings/mtd/nand.txt         |    1 +
 MAINTAINERS                                            |   22 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi            |    1 +
 arch/arm/boot/dts/omap3-igep.dtsi                      |   30 +-
 arch/arm/boot/dts/omap3-n900.dts                       |    1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi                   |    1 +
 arch/arm/boot/dts/omap3430-sdp.dts                     |    1 +
 arch/arm/configs/mvebu_v7_defconfig                    |    2 +-
 arch/arm/mach-omap2/Makefile                           |    3 -
 arch/arm/mach-omap2/gpmc-onenand.c                     |  409 ------
 arch/arm64/configs/defconfig                           |    2 +-
 drivers/memory/omap-gpmc.c                             |  163 ++-
 drivers/mtd/nand/Kconfig                               |   17 +-
 drivers/mtd/nand/Makefile                              |    1 +
 drivers/mtd/nand/atmel/nand-controller.c               |    9 +-
 drivers/mtd/nand/bf5xx_nand.c                          |    6 +-
 drivers/mtd/nand/brcmnand/brcmnand.c                   |   38 +-
 drivers/mtd/nand/cafe_nand.c                           |   52 +-
 drivers/mtd/nand/denali.c                              |   84 +-
 drivers/mtd/nand/denali.h                              |    4 +-
 drivers/mtd/nand/denali_pci.c                          |    4 +
 drivers/mtd/nand/diskonchip.c                          |    4 +-
 drivers/mtd/nand/docg4.c                               |   21 +-
 drivers/mtd/nand/fsl_elbc_nand.c                       |   10 +-
 drivers/mtd/nand/fsl_ifc_nand.c                        |   13 +-
 drivers/mtd/nand/fsmc_nand.c                           |    9 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c                 |   97 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h                 |   46 +-
 drivers/mtd/nand/hisi504_nand.c                        |    9 +-
 drivers/mtd/nand/jz4740_nand.c                         |   16 +-
 drivers/mtd/nand/lpc32xx_mlc.c                         |    7 +-
 drivers/mtd/nand/lpc32xx_slc.c                         |   33 +-
 drivers/mtd/nand/marvell_nand.c                        | 2898 +++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/mtk_ecc.c                             |  126 +-
 drivers/mtd/nand/mtk_ecc.h                             |    3 +-
 drivers/mtd/nand/mtk_nand.c                            |   76 +-
 drivers/mtd/nand/nand_base.c                           | 2229 ++++++++++++++++++++++++++-----
 drivers/mtd/nand/nand_bbt.c                            |    2 +-
 drivers/mtd/nand/nand_hynix.c                          |  129 +-
 drivers/mtd/nand/nand_micron.c                         |   83 +-
 drivers/mtd/nand/nand_samsung.c                        |   19 +
 drivers/mtd/nand/nand_timings.c                        |   21 +-
 drivers/mtd/nand/omap2.c                               |   28 +-
 drivers/mtd/nand/pxa3xx_nand.c                         |   14 +-
 drivers/mtd/nand/qcom_nandc.c                          |   30 +-
 drivers/mtd/nand/r852.c                                |   11 +-
 drivers/mtd/nand/sh_flctl.c                            |    6 +-
 drivers/mtd/nand/sm_common.h                           |    2 +-
 drivers/mtd/nand/sunxi_nand.c                          |  103 +-
 drivers/mtd/nand/tango_nand.c                          |   27 +-
 drivers/mtd/nand/tmio_nand.c                           |    5 +-
 drivers/mtd/nand/vf610_nfc.c                           |    6 +-
 drivers/mtd/onenand/Kconfig                            |    7 +-
 drivers/mtd/onenand/omap2.c                            |  576 +++-----
 drivers/mtd/onenand/samsung.c                          |  185 +--
 drivers/mtd/tests/nandbiterrs.c                        |    2 +-
 drivers/mtd/tests/oobtest.c                            |   21 +
 drivers/staging/mt29f_spinand/mt29f_spinand.c          |    5 +-
 include/linux/mtd/rawnand.h                            |  443 ++++++-
 include/linux/omap-gpmc.h                              |   28 +
 include/linux/platform_data/mtd-onenand-omap2.h        |   34 -
 64 files changed, 6457 insertions(+), 1918 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 create mode 100644 drivers/mtd/nand/marvell_nand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h


From frieder.schrempf at exceet.de  Mon Jan 15 03:05:09 2018
From: frieder.schrempf at exceet.de (Frieder Schrempf)
Date: Mon, 15 Jan 2018 12:05:09 +0100
Subject: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic
 LUT entry
In-Reply-To: <DB6PR0402MB2838BA43DBDBD8AF3AEDA04D99170@DB6PR0402MB2838.eurprd04.prod.outlook.com>
References: <1515493602-19626-2-git-send-email-yogeshnarayan.gaur@nxp.com>
 <80885d95-a6d4-b3a6-4249-f87379e6dc45@exceet.de>
 <DB6PR0402MB2838BA43DBDBD8AF3AEDA04D99170@DB6PR0402MB2838.eurprd04.prod.outlook.com>
Message-ID: <466636da-a65c-0f19-2ca7-7126eaa90cb9@exceet.de>

Hello Yogesh,

On 12.01.2018 05:44, Yogesh Narayan Gaur wrote:
> Hello Frieder,
> 
>> -----Original Message-----
>> From: Frieder Schrempf [mailto:frieder.schrempf at exceet.de]
>> Sent: Tuesday, January 09, 2018 9:56 PM
>> To: Yogesh Narayan Gaur <yogeshnarayan.gaur at nxp.com>
>> Cc: linux-mtd at lists.infradead.org; Boris Brezillon <boris.brezillon at free-
>> electrons.com>; cyrille.pitchen at wedev4u.fr; computersforpeace at gmail.com;
>> Han Xu <han.xu at nxp.com>; festevam at gmail.com; Prabhakar Kushwaha
>> <prabhakar.kushwaha at nxp.com>; Suresh Gupta <suresh.gupta at nxp.com>
>> Subject: Re: [PATCH v1 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
>> entry
>>
>> Hello Yogesh,
>>
>>> Add support to create dynamic LUT entry.
>>>
>>> Current approach of creating LUT entries for various cmds like read,
>>> write, erase, readid, readsr, we, wd etc is that when QSPI controller
>>> gets initialized at that time static LUT entries for these cmds get created.
>>>
>>> Patch add support to create the LUT at run time based on the operation
>>> being performed.
>>>
>>> Added API fsl_qspi_prepare_lut(), this API would going to be called
>>> from fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write,
>>> fsl_qspi_read and fsl_qspi_erase APIs.
>>> This API would fetch required info like opcode, protocol info, dummy
>>> info for creating LUT from instance of 'struct spi_nor' and then
>>> prepare LUT entry for the required command.
>>
>> I'm just about to get started working on a similar topic, so I have some general
>> (maybe stupid) questions concerning the dynamic LUT implementation:
>>
>> Why do you actually need to be able to switch between different kind of
>> commands for READ/WRITE/ERASE at time of execution?
> Actually we want to handle different NOR flash devices on different chip select.
> QSPI controller has 4 chip select and one can use different flashes on all different chip select (that might not be the use case for today). We analyzed that the flash have different parameters for the same command and this is true for NAND devices.
> Also reg_protocol information, required for read register, read any register commands, read SFDP register, not available at the time of nor scan.
> This change was done after understanding the requirement for NAND and Hybrid flash also.
> NXP is going to support hybrid flash which has NOR and NAND at one chip select. So, to handle these type of flashes dynamic LUT is the best approach, condition NAND framework also provide required information (datalines, dummy bytes, addrlen)as provided by NOR framework as of now.
> To handle all chip select and hybrid complexities, this dynamic LUT need to be required as we can have maximum 16 static LUT entries.

Thank you for the explanation. I think you're right, it's too difficult 
to set up a static LUT for all the different kinds of flash commands 
within the limit of 16 LUT entries.

>>
>> Wouldn't it be better to init the LUT statically, after the chip was detected and at
>> that time decide which READ/WRITE/ERASE command is best for the connected
>> chip?
> As explained above if we have different flashes on different chip select (even for 2 flash we can maximum provide 8 LUT entries for different flashes).
> It is tough to handle such scenario and lead to code complexity.

I see.

>>
>> Have you tested what kind of impact the dynamic loading of a command
>> sequence to the LUT registers before each operation has on the performance?
> We are programming 4 LUT register for every command sent from MTD layer. Theoretically it is max 16bytes per command.
> It looks to be trivial overhead. We are doing analysis of performance impact of dynamic LUT creation.

Ok. I guess you're right. I made a single quick test with my FSL NAND 
driver, running mtd_speedtest with 20 MHz QSPI clock and I can see only 
minor differences between a static LUT and a dynamic LUT implementation.

>>
>> In the context of the upcoming SPI NAND framework, I am working on NAND
>> support for the FSL QSPI controller.
> Hope you will take care of having support of NAND on chip select 1 and 2.

My current driver doesn't handle multiple chips, but I hope at some 
point I can merge my driver with the existing NOR driver and also 
support multiple chips.

> 
>> I have a working driver at [1] derived from the NOR driver.
>> As discussed with Boris ([2]) the plan is to add NAND support to the NOR driver
>> until a common spi-flash layer is available to hold code, that is used by both
>> types of SPI flash, NOR and NAND.
>>
>> To achieve this, some kind of dynamic LUT allocation is needed, too.
>> But at first glance it seems me, that it would be better to actually use the LUT
>> entries as much as possible and create the entries at time of init depending on
>> flash type (NOR/NAND) and flash capabilities (QUAD/DUAL/QIO
>> READ/WRITE...).
>>
>> In the exotic case of needing to switch between different command sets (for
>> hybrid NOR/NAND devices, see [3]) one could reinit the LUT for the current
>> target upon selecting it.
>>
>> Or maybe it is even better to create a mechanism that fills the LUT with entries
>> when they are first needed and be able to reuse them until the space in the LUT
>> runs out and entries need to be overriden.
>>
>> What do you think?
> Right, we also though of this approach but we think this would going to increase the code complexity so the simple and best possible approach we use is to create run-time LUT for every command when function ptr (read_reg, write_reg, read, write and erase) gets invoked.

Ok.

Thanks,

Frieder


From zajec5 at gmail.com  Mon Jan 15 04:56:34 2018
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Mon, 15 Jan 2018 13:56:34 +0100
Subject: [PATCH 2/2] mtd: get rid of the mtd_add_device_partitions function
In-Reply-To: <20180112161131.3cae7841@bbrezillon>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180112144034.6655-3-zajec5@gmail.com>
 <20180112161131.3cae7841@bbrezillon>
Message-ID: <CACna6rxzvNyMrPb=OV1ius7wvZkQQM4N7ynFUkbiXvDJkQapjQ@mail.gmail.com>

On 12 January 2018 at 16:11, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
>> @@ -717,19 +702,19 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>>       ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
>>       if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
>>               /* Fall back to driver-provided partitions */
>> -             parsed = (struct mtd_partitions){
>> -                     .parts          = parts,
>> -                     .nr_parts       = nr_parts,
>> -             };
>> +             ret = add_mtd_partitions(mtd, parts, nr_parts);
>>       } else if (ret < 0) {
>>               /* Didn't come up with parsed OR fallback partitions */
>>               pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
>>                       ret);
>>               /* Don't abort on errors; we can still use unpartitioned MTD */
>> -             memset(&parsed, 0, sizeof(parsed));
>> +             if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
>> +                     ret = add_mtd_device(mtd);
>> +             else
>> +                     ret = 0;
>> +     } else {
>> +             ret = add_mtd_partitions(mtd, parsed.parts, parsed.nr_parts);
>>       }
>
> How about:
>
>         ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
>         if (!ret && parsed.nr_parts) {
>                 parts = parsed.parts;
>                 nr_parts = parsed.nr_parts;
>         }
>
>         if (nr_parts)
>                 ret = add_mtd_partitions(mtd, parts, nr_parts);
>         else if (!device_is_registered(&mtd->dev))
>                 ret = add_mtd_device(mtd);
>         else
>                 ret = 0;

I spent a moment writing possible cases on a paper and your solution
should keep the same logic. Looks good!


From boris.brezillon at free-electrons.com  Mon Jan 15 05:19:00 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 14:19:00 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <20180108140429.79f67a83@bbrezillon>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>
 <20180105164239.79d7980c@xps13>
 <20180108140429.79f67a83@bbrezillon>
Message-ID: <20180115141900.39661c4e@bbrezillon>

Hi Han,

On Mon, 8 Jan 2018 14:04:29 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Fri, 5 Jan 2018 16:42:39 +0100
> Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> 
> > Hello,
> >   
> > > Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
> > > is applied as soon the CS line is released after a
> > > SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
> > > guarantee that the CS will be kept low by the controller after    
> > > ->onfi_set_features() returns we must assume the new mode has been      
> > > applied and call ->setup_data_interface() to instruct the controller
> > > to apply new timings.
> > > 
> > > If you want to check if the mode has really been applied, you should
> > > release the CS (->select_chip(-1)), re-acquire it
> > > (->select_chip(X)), and call    
> > > ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears    
> > > that the mode has not been applied, you should restore timing mode 0
> > > and issue a RESET.    
> > 
> > Boris, thanks for the comment, I will fix that.
> > 
> > Han, could I have your input on this series? Aside Boris' comment of
> > course.  
> 
> Han, we really need your feedback on this series since you were the one
> complaining that ONFI mode should be checked back after applying a new
> mode. Miquel is reworking the framework to mimic what the GPMI driver,
> but we need to be sure that you'll accept to transition to the generic
> ->setup_data_interface() solution.

Gentle ping.


From zajec5 at gmail.com  Mon Jan 15 05:22:21 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 14:22:21 +0100
Subject: [PATCH V2 0/2] mtd: simplify mtd_device_parse_register code
In-Reply-To: <20180112144034.6655-1-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
Message-ID: <20180115132223.9974-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Even though I have some experience with MTD subsystem every time I was
starting working on it I had to do some quick research on the code flow.
I think there is some place for cleanup and optimization that would
simplify overall code and allow new developers to start working on it
more easily.

In these patches I meant to slightly simplify mtd_device_parse_register
function. I think we could reduce amount of add/register/del functions
and this is the first step for that.

Ideally I think mtdcore.c shouldn't handle parsing but just use a single
function from mtdpart.c.

Patch 1/2 modifies code to make sure parsing code is not mixed with MTD
master code. This should allow moving parsing parts to the mtdpart.c in
the future.

Patch 2/2 simplifies code and makes sure parsing is handled at 1 place
only.

Even though this cleanup isn't complete I think it already has some
value and could be accepted (if there won't be objections) on its own.
It's also quite small which should allow reviewing it easily.

Rafa? Mi?ecki (2):
  mtd: move code adding master MTD out of mtd_add_device_partitions
  mtd: get rid of the mtd_add_device_partitions function

 drivers/mtd/mtdcore.c | 56 +++++++++++++++++----------------------------------
 1 file changed, 19 insertions(+), 37 deletions(-)

-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 05:22:23 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 14:22:23 +0100
Subject: [PATCH V2 2/2] mtd: get rid of the mtd_add_device_partitions function
In-Reply-To: <20180115132223.9974-1-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180115132223.9974-1-zajec5@gmail.com>
Message-ID: <20180115132223.9974-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This simplifies code a bit by:
1) Avoiding an extra (tiny) function
2) Checking for amount of parsed (found) partitions just once
3) Avoiding clearing/filling struct mtd_partitions manually

With this commit a proper functions are called directly from the
mtd_device_parse_register. It doesn't need to use minor tricks like
memsetting struct to 0 to trigger an expected mtd_add_device_partitions
behavior.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Simplify conditions in the mtd_device_parse_register (thanks Boris)
---
 drivers/mtd/mtdcore.c | 41 +++++++++++------------------------------
 1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dd9ba5b7b68e..e8fa05941f64 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -636,21 +636,6 @@ int del_mtd_device(struct mtd_info *mtd)
 	return ret;
 }
 
-static int mtd_add_device_partitions(struct mtd_info *mtd,
-				     struct mtd_partitions *parts)
-{
-	const struct mtd_partition *real_parts = parts->parts;
-	int nbparts = parts->nr_parts;
-
-	if (!nbparts && !device_is_registered(&mtd->dev))
-		return add_mtd_device(mtd);
-
-	if (nbparts > 0)
-		return add_mtd_partitions(mtd, real_parts, nbparts);
-
-	return 0;
-}
-
 /*
  * Set a few defaults based on the parent devices, if not provided by the
  * driver
@@ -712,24 +697,20 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 			return ret;
 	}
 
-	memset(&parsed, 0, sizeof(parsed));
-
+	/* Prefer parsed partitions over driver-provided fallback */
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
-	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
-		/* Fall back to driver-provided partitions */
-		parsed = (struct mtd_partitions){
-			.parts		= parts,
-			.nr_parts	= nr_parts,
-		};
-	} else if (ret < 0) {
-		/* Didn't come up with parsed OR fallback partitions */
-		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
-			ret);
-		/* Don't abort on errors; we can still use unpartitioned MTD */
-		memset(&parsed, 0, sizeof(parsed));
+	if (!ret && parsed.nr_parts) {
+		parts = parsed.parts;
+		nr_parts = parsed.nr_parts;
 	}
 
-	ret = mtd_add_device_partitions(mtd, &parsed);
+	if (nr_parts)
+		ret = add_mtd_partitions(mtd, parts, nr_parts);
+	else if (!device_is_registered(&mtd->dev))
+		ret = add_mtd_device(mtd);
+	else
+		ret = 0;
+
 	if (ret)
 		goto out;
 
-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 05:22:22 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 14:22:22 +0100
Subject: [PATCH V2 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180115132223.9974-1-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180115132223.9974-1-zajec5@gmail.com>
Message-ID: <20180115132223.9974-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This change is a small cleanup of mtd_device_parse_register. When using
MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
dealing with partitions. There are 2 advantages of this:
1) Not mixing code handling master MTD with code handling partitions
2) Possibility of reusing mtd_parse_part in the future to avoid some
   code duplication.

This commit doesn't change any behavior except from a slightly different
failure code path. The new code may need to call del_mtd_device when
something goes wrong.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Use device_is_registered (thanks Boris)
    Add an empty line before "return ret;"
---
 drivers/mtd/mtdcore.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index f80e911b8843..dd9ba5b7b68e 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
 {
 	const struct mtd_partition *real_parts = parts->parts;
 	int nbparts = parts->nr_parts;
-	int ret;
 
-	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			return ret;
-	}
+	if (!nbparts && !device_is_registered(&mtd->dev))
+		return add_mtd_device(mtd);
 
-	if (nbparts > 0) {
-		ret = add_mtd_partitions(mtd, real_parts, nbparts);
-		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-			del_mtd_device(mtd);
-		return ret;
-	}
+	if (nbparts > 0)
+		return add_mtd_partitions(mtd, real_parts, nbparts);
 
 	return 0;
 }
@@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 
 	mtd_set_dev_defaults(mtd);
 
+	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+		ret = add_mtd_device(mtd);
+		if (ret)
+			return ret;
+	}
+
 	memset(&parsed, 0, sizeof(parsed));
 
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
@@ -753,6 +751,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 out:
 	/* Cleanup any parsed partitions */
 	mtd_part_parser_cleanup(&parsed);
+	if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+		del_mtd_device(mtd);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(mtd_device_parse_register);
-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan 15 05:36:15 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 14:36:15 +0100
Subject: [PATCH V2 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180115132223.9974-2-zajec5@gmail.com>
References: <20180112144034.6655-1-zajec5@gmail.com>
 <20180115132223.9974-1-zajec5@gmail.com>
 <20180115132223.9974-2-zajec5@gmail.com>
Message-ID: <20180115143615.4f4975ce@bbrezillon>

On Mon, 15 Jan 2018 14:22:22 +0100
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This change is a small cleanup of mtd_device_parse_register. When using
> MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
> dealing with partitions. There are 2 advantages of this:
> 1) Not mixing code handling master MTD with code handling partitions
> 2) Possibility of reusing mtd_parse_part in the future to avoid some
>    code duplication.
> 
> This commit doesn't change any behavior except from a slightly different
> failure code path. The new code may need to call del_mtd_device when
> something goes wrong.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> V2: Use device_is_registered (thanks Boris)
>     Add an empty line before "return ret;"
> ---
>  drivers/mtd/mtdcore.c | 25 +++++++++++++------------
>  1 file changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index f80e911b8843..dd9ba5b7b68e 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
>  {
>  	const struct mtd_partition *real_parts = parts->parts;
>  	int nbparts = parts->nr_parts;
> -	int ret;
>  
> -	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
> -		ret = add_mtd_device(mtd);
> -		if (ret)
> -			return ret;
> -	}
> +	if (!nbparts && !device_is_registered(&mtd->dev))
> +		return add_mtd_device(mtd);
>  
> -	if (nbparts > 0) {
> -		ret = add_mtd_partitions(mtd, real_parts, nbparts);
> -		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> -			del_mtd_device(mtd);
> -		return ret;
> -	}
> +	if (nbparts > 0)
> +		return add_mtd_partitions(mtd, real_parts, nbparts);
>  
>  	return 0;
>  }
> @@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>  
>  	mtd_set_dev_defaults(mtd);
>  
> +	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
> +		ret = add_mtd_device(mtd);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	memset(&parsed, 0, sizeof(parsed));
>  
>  	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
> @@ -753,6 +751,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
>  out:
>  	/* Cleanup any parsed partitions */
>  	mtd_part_parser_cleanup(&parsed);
> +	if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))

Why not using device_is_registered(&mtd->dev) here as well?

> +		del_mtd_device(mtd);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(mtd_device_parse_register);



From zajec5 at gmail.com  Mon Jan 15 06:35:17 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 15:35:17 +0100
Subject: [PATCH V3 0/2] mtd: simplify mtd_device_parse_register code
In-Reply-To: <20180115132223.9974-1-zajec5@gmail.com>
References: <20180115132223.9974-1-zajec5@gmail.com>
Message-ID: <20180115143519.9845-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Even though I have some experience with MTD subsystem every time I was
starting working on it I had to do some quick research on the code flow.
I think there is some place for cleanup and optimization that would
simplify overall code and allow new developers to start working on it
more easily.

In these patches I meant to slightly simplify mtd_device_parse_register
function. I think we could reduce amount of add/register/del functions
and this is the first step for that.

Ideally I think mtdcore.c shouldn't handle parsing but just use a single
function from mtdpart.c.

Patch 1/2 modifies code to make sure parsing code is not mixed with MTD
master code. This should allow moving parsing parts to the mtdpart.c in
the future.

Patch 2/2 simplifies code and makes sure parsing is handled at 1 place
only.

Even though this cleanup isn't complete I think it already has some
value and could be accepted (if there won't be objections) on its own.
It's also quite small which should allow reviewing it easily.

Rafa? Mi?ecki (2):
  mtd: move code adding master MTD out of mtd_add_device_partitions
  mtd: get rid of the mtd_add_device_partitions function

 drivers/mtd/mtdcore.c | 56 +++++++++++++++++----------------------------------
 1 file changed, 19 insertions(+), 37 deletions(-)

-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 06:35:19 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 15:35:19 +0100
Subject: [PATCH V3 2/2] mtd: get rid of the mtd_add_device_partitions function
In-Reply-To: <20180115143519.9845-1-zajec5@gmail.com>
References: <20180115132223.9974-1-zajec5@gmail.com>
 <20180115143519.9845-1-zajec5@gmail.com>
Message-ID: <20180115143519.9845-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This simplifies code a bit by:
1) Avoiding an extra (tiny) function
2) Checking for amount of parsed (found) partitions just once
3) Avoiding clearing/filling struct mtd_partitions manually

With this commit a proper functions are called directly from the
mtd_device_parse_register. It doesn't need to use minor tricks like
memsetting struct to 0 to trigger an expected mtd_add_device_partitions
behavior.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Simplify conditions in the mtd_device_parse_register (thanks Boris)
---
 drivers/mtd/mtdcore.c | 41 +++++++++++------------------------------
 1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 3304199cca07..9baf93219873 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -636,21 +636,6 @@ int del_mtd_device(struct mtd_info *mtd)
 	return ret;
 }
 
-static int mtd_add_device_partitions(struct mtd_info *mtd,
-				     struct mtd_partitions *parts)
-{
-	const struct mtd_partition *real_parts = parts->parts;
-	int nbparts = parts->nr_parts;
-
-	if (!nbparts && !device_is_registered(&mtd->dev))
-		return add_mtd_device(mtd);
-
-	if (nbparts > 0)
-		return add_mtd_partitions(mtd, real_parts, nbparts);
-
-	return 0;
-}
-
 /*
  * Set a few defaults based on the parent devices, if not provided by the
  * driver
@@ -712,24 +697,20 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 			return ret;
 	}
 
-	memset(&parsed, 0, sizeof(parsed));
-
+	/* Prefer parsed partitions over driver-provided fallback */
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
-	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
-		/* Fall back to driver-provided partitions */
-		parsed = (struct mtd_partitions){
-			.parts		= parts,
-			.nr_parts	= nr_parts,
-		};
-	} else if (ret < 0) {
-		/* Didn't come up with parsed OR fallback partitions */
-		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
-			ret);
-		/* Don't abort on errors; we can still use unpartitioned MTD */
-		memset(&parsed, 0, sizeof(parsed));
+	if (!ret && parsed.nr_parts) {
+		parts = parsed.parts;
+		nr_parts = parsed.nr_parts;
 	}
 
-	ret = mtd_add_device_partitions(mtd, &parsed);
+	if (nr_parts)
+		ret = add_mtd_partitions(mtd, parts, nr_parts);
+	else if (!device_is_registered(&mtd->dev))
+		ret = add_mtd_device(mtd);
+	else
+		ret = 0;
+
 	if (ret)
 		goto out;
 
-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 06:35:18 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 15:35:18 +0100
Subject: [PATCH V3 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180115143519.9845-1-zajec5@gmail.com>
References: <20180115132223.9974-1-zajec5@gmail.com>
 <20180115143519.9845-1-zajec5@gmail.com>
Message-ID: <20180115143519.9845-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This change is a small cleanup of mtd_device_parse_register. When using
MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
dealing with partitions. There are 2 advantages of this:
1) Not mixing code handling master MTD with code handling partitions
2) Possibility of reusing mtd_parse_part in the future to avoid some
   code duplication.

This commit doesn't change any behavior except from a slightly different
failure code path. The new code may need to call del_mtd_device when
something goes wrong.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Use device_is_registered (thanks Boris)
    Add an empty line before "return ret;"
V3: Use device_is_registered also in a out code path
---
 drivers/mtd/mtdcore.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index f80e911b8843..3304199cca07 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
 {
 	const struct mtd_partition *real_parts = parts->parts;
 	int nbparts = parts->nr_parts;
-	int ret;
 
-	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			return ret;
-	}
+	if (!nbparts && !device_is_registered(&mtd->dev))
+		return add_mtd_device(mtd);
 
-	if (nbparts > 0) {
-		ret = add_mtd_partitions(mtd, real_parts, nbparts);
-		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-			del_mtd_device(mtd);
-		return ret;
-	}
+	if (nbparts > 0)
+		return add_mtd_partitions(mtd, real_parts, nbparts);
 
 	return 0;
 }
@@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 
 	mtd_set_dev_defaults(mtd);
 
+	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+		ret = add_mtd_device(mtd);
+		if (ret)
+			return ret;
+	}
+
 	memset(&parsed, 0, sizeof(parsed));
 
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
@@ -753,6 +751,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 out:
 	/* Cleanup any parsed partitions */
 	mtd_part_parser_cleanup(&parsed);
+	if (ret && device_is_registered(&mtd->dev))
+		del_mtd_device(mtd);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(mtd_device_parse_register);
-- 
2.11.0



From han.xu at nxp.com  Mon Jan 15 09:57:08 2018
From: han.xu at nxp.com (Han Xu)
Date: Mon, 15 Jan 2018 17:57:08 +0000
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by the
 chip
In-Reply-To: <20180115141900.39661c4e@bbrezillon>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>	<20180105164239.79d7980c@xps13>
 <20180108140429.79f67a83@bbrezillon>,<20180115141900.39661c4e@bbrezillon>
Message-ID: <VI1PR0401MB2221E2E684A28F8016C4D19197EB0@VI1PR0401MB2221.eurprd04.prod.outlook.com>


________________________________________
From: Boris Brezillon <boris.brezillon at free-electrons.com>
Sent: Monday, January 15, 2018 7:19 AM
To: Han Xu
Cc: Miquel RAYNAL; Richard Weinberger; David Woodhouse; Brian Norris; Marek Vasut; Cyrille Pitchen; linux-mtd at lists.infradead.org
Subject: Re: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by the chip

Hi Han,

On Mon, 8 Jan 2018 14:04:29 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Fri, 5 Jan 2018 16:42:39 +0100
> Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
>
> > Hello,
> >
> > > Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
> > > is applied as soon the CS line is released after a
> > > SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
> > > guarantee that the CS will be kept low by the controller after
> > > ->onfi_set_features() returns we must assume the new mode has been
> > > applied and call ->setup_data_interface() to instruct the controller
> > > to apply new timings.
> > >
> > > If you want to check if the mode has really been applied, you should
> > > release the CS (->select_chip(-1)), re-acquire it
> > > (->select_chip(X)), and call
> > > ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears
> > > that the mode has not been applied, you should restore timing mode 0
> > > and issue a RESET.
> >
> > Boris, thanks for the comment, I will fix that.
> >
> > Han, could I have your input on this series? Aside Boris' comment of
> > course.
>
> Han, we really need your feedback on this series since you were the one
> complaining that ONFI mode should be checked back after applying a new
> mode. Miquel is reworking the framework to mimic what the GPMI driver,
> but we need to be sure that you'll accept to transition to the generic
> ->setup_data_interface() solution.

Thanks Miquel, I do accept to transit to setup_data_interface solution and actually
I am also working on the similar patches. I reviewed the patch set and don't have
more comments, this one improved more than mine.

Gentle ping.


From boris.brezillon at free-electrons.com  Mon Jan 15 10:41:08 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 19:41:08 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <VI1PR0401MB2221E2E684A28F8016C4D19197EB0@VI1PR0401MB2221.eurprd04.prod.outlook.com>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>
 <20180105164239.79d7980c@xps13>
 <20180108140429.79f67a83@bbrezillon>
 <20180115141900.39661c4e@bbrezillon>
 <VI1PR0401MB2221E2E684A28F8016C4D19197EB0@VI1PR0401MB2221.eurprd04.prod.outlook.com>
Message-ID: <20180115194108.318d57b8@bbrezillon>

On Mon, 15 Jan 2018 17:57:08 +0000
Han Xu <han.xu at nxp.com> wrote:

> ________________________________________
> From: Boris Brezillon <boris.brezillon at free-electrons.com>
> Sent: Monday, January 15, 2018 7:19 AM
> To: Han Xu
> Cc: Miquel RAYNAL; Richard Weinberger; David Woodhouse; Brian Norris; Marek Vasut; Cyrille Pitchen; linux-mtd at lists.infradead.org
> Subject: Re: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by the chip
> 
> Hi Han,
> 
> On Mon, 8 Jan 2018 14:04:29 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > On Fri, 5 Jan 2018 16:42:39 +0100
> > Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> >  
> > > Hello,
> > >  
> > > > Hm, I'm not sure this is safe. The spec says that new ONFI timing mode
> > > > is applied as soon the CS line is released after a
> > > > SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we have no
> > > > guarantee that the CS will be kept low by the controller after  
> > > > ->onfi_set_features() returns we must assume the new mode has been  
> > > > applied and call ->setup_data_interface() to instruct the controller
> > > > to apply new timings.
> > > >
> > > > If you want to check if the mode has really been applied, you should
> > > > release the CS (->select_chip(-1)), re-acquire it
> > > > (->select_chip(X)), and call  
> > > > ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it appears  
> > > > that the mode has not been applied, you should restore timing mode 0
> > > > and issue a RESET.  
> > >
> > > Boris, thanks for the comment, I will fix that.
> > >
> > > Han, could I have your input on this series? Aside Boris' comment of
> > > course.  
> >
> > Han, we really need your feedback on this series since you were the one
> > complaining that ONFI mode should be checked back after applying a new
> > mode. Miquel is reworking the framework to mimic what the GPMI driver,
> > but we need to be sure that you'll accept to transition to the generic  
> > ->setup_data_interface() solution.  
> 
> Thanks Miquel, I do accept to transit to setup_data_interface solution and actually
> I am also working on the similar patches. I reviewed the patch set and don't have
> more comments, this one improved more than mine.

Glad to hear you're not opposed to the idea.


From miquel.raynal at free-electrons.com  Mon Jan 15 12:05:03 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Mon, 15 Jan 2018 21:05:03 +0100
Subject: [PATCH 1/2] mtd: nand: Check ONFI timings have been acked by
 the chip
In-Reply-To: <20180115194108.318d57b8@bbrezillon>
References: <20171222172853.27710-1-miquel.raynal@free-electrons.com>
 <20171222172853.27710-2-miquel.raynal@free-electrons.com>
 <20180105161321.44218e4e@bbrezillon>
 <20180105164239.79d7980c@xps13>
 <20180108140429.79f67a83@bbrezillon>
 <20180115141900.39661c4e@bbrezillon>
 <VI1PR0401MB2221E2E684A28F8016C4D19197EB0@VI1PR0401MB2221.eurprd04.prod.outlook.com>
 <20180115194108.318d57b8@bbrezillon>
Message-ID: <20180115210503.21fc34df@xps13>

Hi Han,

On Mon, 15 Jan 2018 19:41:08 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Mon, 15 Jan 2018 17:57:08 +0000
> Han Xu <han.xu at nxp.com> wrote:
> 
> > ________________________________________
> > From: Boris Brezillon <boris.brezillon at free-electrons.com>
> > Sent: Monday, January 15, 2018 7:19 AM
> > To: Han Xu
> > Cc: Miquel RAYNAL; Richard Weinberger; David Woodhouse; Brian
> > Norris; Marek Vasut; Cyrille Pitchen; linux-mtd at lists.infradead.org
> > Subject: Re: [PATCH 1/2] mtd: nand: Check ONFI timings have been
> > acked by the chip
> > 
> > Hi Han,
> > 
> > On Mon, 8 Jan 2018 14:04:29 +0100
> > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> >   
> > > On Fri, 5 Jan 2018 16:42:39 +0100
> > > Miquel RAYNAL <miquel.raynal at free-electrons.com> wrote:
> > >    
> > > > Hello,
> > > >    
> > > > > Hm, I'm not sure this is safe. The spec says that new ONFI
> > > > > timing mode is applied as soon the CS line is released after a
> > > > > SET_FEATURES(ONFI_FEATURE_ADDR_TIMING_MODE), and since we
> > > > > have no guarantee that the CS will be kept low by the
> > > > > controller after ->onfi_set_features() returns we must assume
> > > > > the new mode has been applied and call
> > > > > ->setup_data_interface() to instruct the controller to apply
> > > > > new timings.
> > > > >
> > > > > If you want to check if the mode has really been applied, you
> > > > > should release the CS (->select_chip(-1)), re-acquire it
> > > > > (->select_chip(X)), and call    
> > > > > ->onfi_get_features(ONFI_FEATURE_ADDR_TIMING_MODE). If it
> > > > > appears that the mode has not been applied, you should
> > > > > restore timing mode 0 and issue a RESET.    
> > > >
> > > > Boris, thanks for the comment, I will fix that.
> > > >
> > > > Han, could I have your input on this series? Aside Boris'
> > > > comment of course.    
> > >
> > > Han, we really need your feedback on this series since you were
> > > the one complaining that ONFI mode should be checked back after
> > > applying a new mode. Miquel is reworking the framework to mimic
> > > what the GPMI driver, but we need to be sure that you'll accept
> > > to transition to the generic ->setup_data_interface()
> > > solution.    
> > 
> > Thanks Miquel, I do accept to transit to setup_data_interface
> > solution and actually I am also working on the similar patches. I
> > reviewed the patch set and don't have more comments, this one
> > improved more than mine.  
> 
> Glad to hear you're not opposed to the idea.

I'm happy to read this, I'll send a v2 tomorrow that addresses Boris'
comments.

Thanks,
Miqu?l



From boris.brezillon at free-electrons.com  Mon Jan 15 14:07:16 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 15 Jan 2018 23:07:16 +0100
Subject: [RFC PATCH v2] mtd: nand: vf610_nfc: make use of ->exec_op()
In-Reply-To: <20180114220012.30039-1-stefan@agner.ch>
References: <20180114220012.30039-1-stefan@agner.ch>
Message-ID: <20180115230716.5d20c9ef@bbrezillon>

On Sun, 14 Jan 2018 23:00:12 +0100
Stefan Agner <stefan at agner.ch> wrote:

> This reworks the driver to make use of ->exec_op() callback. The
> command sequencer of the VF610 NFC aligns well with the new ops
> interface.
> 
> The ops are translated to a NFC command code while filling the
> necessary registers. Instead of using the special status and
> read id command codes (which require the status/id form special
> registers) the driver now uses the main data buffer for all
> commands. This simplifies the driver as no special casing is
> needed.
> 
> For control data (status byte, id bytes and parameter page) the
> driver needs to reverse byte order for little endian CPUs since
> the controller seems to store the bytes in big endian order in
> the data buffer.
> 
> The current state seems to pass MTD tests on a Colibri VF61.
> 
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
> Hi,
> 
> In this second version I was able to remove all special command
> handling. As Boris suggested, the special READID/STATUS handling
> is really not needed and all return values can be read from the
> regular data buffer. This simplified code even more and allowed
> to get rid of the hack in the MTD core. The driver is now able
> to handle all commands in a single function. Therefor I also got
> rid of the command parser, since everything is handled in a single
> function anyway.
> 
> The only thing which is somewhat unfortunate is the byte ordering
> which needs to be reversed for commands which read flash data (id,
> status and parameter page). All those request 8-bit handling, so
> I used this as an indicator to fix byte order.
> 
> I did meassured a slight performance drop (before vs. now):
> - write speed is 4036 KiB/s vs 3495 KiB/s
> - read speed is 13741 KiB/s vs 13490 KiB/s
> 
> --
> Stefan
> 
>  drivers/mtd/nand/vf610_nfc.c | 444 +++++++++++++++++++------------------------
>  1 file changed, 194 insertions(+), 250 deletions(-)
> 
> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> index 80d31a58e558..fb428a94bbd4 100644
> --- a/drivers/mtd/nand/vf610_nfc.c
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -59,20 +59,20 @@
>  #define OOB_64				0x0040
>  #define OOB_MAX				0x0100
>  
> -/*
> - * NFC_CMD2[CODE] values. See section:
> - *  - 31.4.7 Flash Command Code Description, Vybrid manual
> - *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
> - *
> - * Briefly these are bitmasks of controller cycles.
> - */
> -#define READ_PAGE_CMD_CODE		0x7EE0
> -#define READ_ONFI_PARAM_CMD_CODE	0x4860
> -#define PROGRAM_PAGE_CMD_CODE		0x7FC0
> -#define ERASE_CMD_CODE			0x4EC0
> -#define READ_ID_CMD_CODE		0x4804
> -#define RESET_CMD_CODE			0x4040
> -#define STATUS_READ_CMD_CODE		0x4068
> +/* NFC_CMD2[CODE] controller cycle bit masks */
> +#define COMMAND_CMD_BYTE1		BIT(14)
> +#define COMMAND_CAR_BYTE1		BIT(13)
> +#define COMMAND_CAR_BYTE2		BIT(12)
> +#define COMMAND_RAR_BYTE1		BIT(11)
> +#define COMMAND_RAR_BYTE2		BIT(10)
> +#define COMMAND_RAR_BYTE3		BIT(9)

ADDRESS cycles will always be specified in little-endian (column
cycles first and then row cycles), so maybe you can do:

#define COMMAND_NADDR_CYCLES(x)		GENMASK(14, 14 - (x) - 1)

> +#define COMMAND_WRITE_DATA		BIT(8)
> +#define COMMAND_CMD_BYTE2		BIT(7)
> +#define COMMAND_RB_HANDSHAKE		BIT(6)
> +#define COMMAND_READ_DATA		BIT(5)
> +#define COMMAND_CMD_BYTE3		BIT(4)
> +#define COMMAND_READ_STATUS		BIT(3)
> +#define COMMAND_READ_ID			BIT(2)
>  
>  /* NFC ECC mode define */
>  #define ECC_BYPASS			0
> @@ -97,10 +97,21 @@
>  /* NFC_COL_ADDR Field */
>  #define COL_ADDR_MASK				0x0000FFFF
>  #define COL_ADDR_SHIFT				0
> +#define COL_ADDR_BYTE1_SHIFT			0
> +#define COL_ADDR_BYTE2_SHIFT			8
> +#define COL_ADDR_BYTE1(x)			((x & 0xFF) << COL_ADDR_BYTE1_SHIFT)
> +#define COL_ADDR_BYTE2(x)			((x & 0XFF) << COL_ADDR_BYTE2_SHIFT)

Or just

#define COL_ADDR(pos, val)		((val) << (8 * (pos))) 

> +
>  
>  /* NFC_ROW_ADDR Field */
>  #define ROW_ADDR_MASK				0x00FFFFFF
>  #define ROW_ADDR_SHIFT				0
> +#define ROW_ADDR_BYTE1_SHIFT			0
> +#define ROW_ADDR_BYTE2_SHIFT			8
> +#define ROW_ADDR_BYTE3_SHIFT			16
> +#define ROW_ADDR_BYTE1(x)			((x & 0xFF) << ROW_ADDR_BYTE1_SHIFT)
> +#define ROW_ADDR_BYTE2(x)			((x & 0XFF) << ROW_ADDR_BYTE2_SHIFT)
> +#define ROW_ADDR_BYTE3(x)			((x & 0XFF) << ROW_ADDR_BYTE3_SHIFT)

Same here:

#define ROW_ADDR(pos, val)		((val) << (8 * (pos)))

>  #define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
>  #define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
>  #define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
> @@ -142,13 +153,6 @@
>  #define ECC_STATUS_MASK		0x80
>  #define ECC_STATUS_ERR_COUNT	0x3F
>  
> -enum vf610_nfc_alt_buf {
> -	ALT_BUF_DATA = 0,
> -	ALT_BUF_ID = 1,
> -	ALT_BUF_STAT = 2,
> -	ALT_BUF_ONFI = 3,
> -};
> -
>  enum vf610_nfc_variant {
>  	NFC_VFC610 = 1,
>  };
> @@ -158,10 +162,7 @@ struct vf610_nfc {
>  	struct device *dev;
>  	void __iomem *regs;
>  	struct completion cmd_done;
> -	uint buf_offset;
> -	int write_sz;
>  	/* Status and ID are in alternate locations. */
> -	enum vf610_nfc_alt_buf alt_buf;
>  	enum vf610_nfc_variant variant;
>  	struct clk *clk;
>  	bool use_hw_ecc;
> @@ -173,6 +174,11 @@ static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd)
>  	return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
>  }
>  
> +static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip)
> +{
> +	return container_of(chip, struct vf610_nfc, chip);
> +}

Not related to this patch, but the chip and nfc objects should be
separated, and the NFC object should inherit from nand_hw_control.

> +
>  static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
>  {
>  	return readl(nfc->regs + reg);
> @@ -214,7 +220,6 @@ static inline void vf610_nfc_memcpy(void *dst, const void __iomem *src,
>  	memcpy(dst, src, n);
>  }
>  
> -/* Clear flags for upcoming command */
>  static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
>  {
>  	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
> @@ -243,51 +248,22 @@ static void vf610_nfc_done(struct vf610_nfc *nfc)
>  	vf610_nfc_clear_status(nfc);
>  }
>  
> -static u8 vf610_nfc_get_id(struct vf610_nfc *nfc, int col)
> -{
> -	u32 flash_id;
> -
> -	if (col < 4) {
> -		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS1);
> -		flash_id >>= (3 - col) * 8;
> -	} else {
> -		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS2);
> -		flash_id >>= 24;
> -	}
> -
> -	return flash_id & 0xff;
> -}
> -
> -static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
> +static void vf610_nfc_send_code(struct vf610_nfc *nfc, u32 cmd_code)
>  {
> -	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
> +	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_CODE_MASK, CMD_CODE_SHIFT,
> +			    cmd_code);
>  }
>  
> -static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
> -				   u32 cmd_code)
> +static void vf610_nfc_set_cmd1(struct vf610_nfc *nfc, u32 cmd_byte1)
>  {
> -	u32 tmp;
> -
> -	vf610_nfc_clear_status(nfc);
> -
> -	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
> -	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
> -	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
> -	tmp |= cmd_code << CMD_CODE_SHIFT;
> -	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
> +	vf610_nfc_set_field(nfc, NFC_FLASH_CMD2, CMD_BYTE1_MASK,
> +			    CMD_BYTE1_SHIFT, cmd_byte1);
>  }
>  
> -static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
> -				    u32 cmd_byte2, u32 cmd_code)
> +static void vf610_nfc_set_cmd2(struct vf610_nfc *nfc, u32 cmd_byte2)
>  {
> -	u32 tmp;
> -
> -	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
> -
> -	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
> -	tmp &= ~CMD_BYTE2_MASK;
> -	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
> -	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
> +	vf610_nfc_set_field(nfc, NFC_FLASH_CMD1, CMD_BYTE2_MASK,
> +			    CMD_BYTE2_SHIFT, cmd_byte2);

Hm, you should prepare all reg values in an intermediate object, and then
push everything to the regs once the whole operation is ready to be
submitted. This set_field() might be one the reason you get better perfs
before this rework.

>  }
>  
>  static irqreturn_t vf610_nfc_irq(int irq, void *data)
> @@ -301,19 +277,6 @@ static irqreturn_t vf610_nfc_irq(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> -static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
> -{
> -	if (column != -1) {
> -		if (nfc->chip.options & NAND_BUSWIDTH_16)
> -			column = column / 2;
> -		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
> -				    COL_ADDR_SHIFT, column);
> -	}
> -	if (page != -1)
> -		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
> -				    ROW_ADDR_SHIFT, page);
> -}
> -
>  static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
>  {
>  	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
> @@ -326,167 +289,158 @@ static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
>  	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
>  }
>  
> -static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
> -			      int column, int page)
> +static inline const struct nand_op_instr *vf610_get_next_instr(
> +	const struct nand_operation *op, int *op_id)
>  {
> -	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> -	int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
> +	if (*op_id + 1 >= op->ninstrs)
> +		return NULL;
>  
> -	nfc->buf_offset = max(column, 0);
> -	nfc->alt_buf = ALT_BUF_DATA;
> +	return &op->instrs[++(*op_id)];
> +}
>  
> -	switch (command) {
> -	case NAND_CMD_SEQIN:
> -		/* Use valid column/page from preread... */
> -		vf610_nfc_addr_cycle(nfc, column, page);
> -		nfc->buf_offset = 0;
> +static int vf610_nfc_exec_op(struct nand_chip *chip,
> +			     const struct nand_operation *op,
> +			     bool check_only)
> +{
> +	const struct nand_op_instr *instr;
> +	struct vf610_nfc *nfc = chip_to_nfc(chip);
> +	struct mtd_info *mtd = nand_to_mtd(chip);
> +	int op_id = -1, trfr_sz = 0, code = 0;
>  
> -		/*
> -		 * SEQIN => data => PAGEPROG sequence is done by the controller
> -		 * hence we do not need to issue the command here...
> -		 */
> -		return;
> -	case NAND_CMD_PAGEPROG:
> -		trfr_sz += nfc->write_sz;
> -		vf610_nfc_transfer_size(nfc, trfr_sz);
> -		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
> -					command, PROGRAM_PAGE_CMD_CODE);
> -		if (nfc->use_hw_ecc)
> -			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
> -		else
> -			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
> -		break;
> -
> -	case NAND_CMD_RESET:
> -		vf610_nfc_transfer_size(nfc, 0);
> -		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
> -		break;
> -
> -	case NAND_CMD_READOOB:
> -		trfr_sz += mtd->oobsize;
> -		column = mtd->writesize;
> -		vf610_nfc_transfer_size(nfc, trfr_sz);
> -		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
> -					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
> -		vf610_nfc_addr_cycle(nfc, column, page);
> -		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
> -		break;
> -
> -	case NAND_CMD_READ0:
> -		trfr_sz += mtd->writesize + mtd->oobsize;
> -		vf610_nfc_transfer_size(nfc, trfr_sz);
> -		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
> -					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
> -		vf610_nfc_addr_cycle(nfc, column, page);
> -		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
> -		break;
> -
> -	case NAND_CMD_PARAM:
> -		nfc->alt_buf = ALT_BUF_ONFI;
> -		trfr_sz = 3 * sizeof(struct nand_onfi_params);
> -		vf610_nfc_transfer_size(nfc, trfr_sz);
> -		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
> -		vf610_nfc_addr_cycle(nfc, -1, column);
> -		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
> -		break;
> -
> -	case NAND_CMD_ERASE1:
> -		vf610_nfc_transfer_size(nfc, 0);
> -		vf610_nfc_send_commands(nfc, command,
> -					NAND_CMD_ERASE2, ERASE_CMD_CODE);
> -		vf610_nfc_addr_cycle(nfc, column, page);
> -		break;
> -
> -	case NAND_CMD_READID:
> -		nfc->alt_buf = ALT_BUF_ID;
> -		nfc->buf_offset = 0;
> -		vf610_nfc_transfer_size(nfc, 0);
> -		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
> -		vf610_nfc_addr_cycle(nfc, -1, column);
> -		break;
> -
> -	case NAND_CMD_STATUS:
> -		nfc->alt_buf = ALT_BUF_STAT;
> -		vf610_nfc_transfer_size(nfc, 0);
> -		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
> -		break;
> -	default:
> -		return;
> +
> +	/* Some ops are optional, but they need to be in order */
> +	instr = vf610_get_next_instr(op, &op_id);
> +	if (!instr)
> +		return -EINVAL;
> +
> +	if (instr && instr->type == NAND_OP_CMD_INSTR) {
> +		dev_dbg(nfc->dev, "OP_CMD: code 0x%02x\n", instr->ctx.cmd.opcode);
> +		vf610_nfc_set_cmd1(nfc, instr->ctx.cmd.opcode);
> +		code |= COMMAND_CMD_BYTE1;
> +
> +		instr = vf610_get_next_instr(op, &op_id);
>  	}
>  
> -	vf610_nfc_done(nfc);
> +	if (instr && instr->type == NAND_OP_ADDR_INSTR) {
> +		int addr = 0;
> +		u32 col = 0, row;
>  
> -	nfc->use_hw_ecc = false;
> -	nfc->write_sz = 0;
> -}
> +		if (instr->ctx.addr.naddrs > 1) {
> +			col = COL_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
> +			code |= COMMAND_CAR_BYTE1;
>  
> -static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
> -{
> -	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> -	uint c = nfc->buf_offset;
> +			if (mtd->writesize > 512) {
> +				col |= COL_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
> +				code |= COMMAND_CAR_BYTE2;
> +			}
> +		}
>  
> -	/* Alternate buffers are only supported through read_byte */
> -	WARN_ON(nfc->alt_buf);
> +		row = ROW_ADDR_BYTE1(instr->ctx.addr.addrs[addr++]);
> +		code |= COMMAND_RAR_BYTE1;
> +		if (addr < instr->ctx.addr.naddrs) {
> +			row |= ROW_ADDR_BYTE2(instr->ctx.addr.addrs[addr++]);
> +			code |= COMMAND_RAR_BYTE2;
> +		}
> +		if (addr < instr->ctx.addr.naddrs) {
> +			row |= ROW_ADDR_BYTE3(instr->ctx.addr.addrs[addr++]);
> +			code |= COMMAND_RAR_BYTE3;
> +		}
>  
> -	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
> +		dev_dbg(nfc->dev, "OP_ADDR: col %d, row %d\n", col, row);
> +		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
> +			    COL_ADDR_SHIFT, col);
>  
> -	nfc->buf_offset += len;
> -}
> +		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
> +			    ROW_ADDR_SHIFT, row);
>  
> -static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
> -				int len)
> -{
> -	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> -	uint c = nfc->buf_offset;
> -	uint l;
> +		instr = vf610_get_next_instr(op, &op_id);
> +	}
>  
> -	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
> -	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
> +	if (instr && instr->type == NAND_OP_DATA_OUT_INSTR) {
> +		int len = instr->ctx.data.len;
> +		int offset = 0;
>  
> -	nfc->write_sz += l;
> -	nfc->buf_offset += l;
> -}
> +		dev_dbg(nfc->dev, "OP_DATA_OUT: len %d, offset %d\n", len, offset);
> +
> +		vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + offset,
> +				 instr->ctx.data.buf.in + offset,
> +				 len);
> +		code |= COMMAND_WRITE_DATA;
> +		trfr_sz += len;
> +
> +		instr = vf610_get_next_instr(op, &op_id);
> +	}
> +
> +	if (instr && instr->type == NAND_OP_CMD_INSTR) {
> +		vf610_nfc_set_cmd2(nfc, instr->ctx.cmd.opcode);
> +		code |= COMMAND_CMD_BYTE2;
> +
> +		instr = vf610_get_next_instr(op, &op_id);
> +	}
> +
> +	if (instr && instr->type == NAND_OP_WAITRDY_INSTR) {
> +		//dev_dbg(nfc->dev, "WAITRDY [max %d ms]\n",
> +		//		  instr->ctx.waitrdy.timeout_ms);
> +		code |= COMMAND_RB_HANDSHAKE;
> +
> +		instr = vf610_get_next_instr(op, &op_id);
> +	}
> +
> +	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
> +		int len = instr->ctx.data.len;
> +		code |= COMMAND_READ_DATA;
> +		trfr_sz += len;
> +	}
> +
> +	if (nfc->use_hw_ecc) {
> +		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
> +
> +		/* Always transfer complete page with OOB when using HW ECC */
> +		trfr_sz = mtd->writesize + mtd->oobsize;
> +	} else {
> +		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
> +	}
> +	vf610_nfc_transfer_size(nfc, trfr_sz);
> +	vf610_nfc_send_code(nfc, code);
> +
> +	dev_dbg(nfc->dev, "Start: code: 0x%04x, hw ecc: %d, trfr_sz %d\n",
> +		code, nfc->use_hw_ecc, trfr_sz);
> +	vf610_nfc_done(nfc);
> +
> +	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
> +		int len = instr->ctx.data.len;
> +		int offset = 0;
> +		bool fix_byte_order = false;
>  
> -static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
> -{
> -	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> -	u8 tmp;
> -	uint c = nfc->buf_offset;
> -
> -	switch (nfc->alt_buf) {
> -	case ALT_BUF_ID:
> -		tmp = vf610_nfc_get_id(nfc, c);
> -		break;
> -	case ALT_BUF_STAT:
> -		tmp = vf610_nfc_get_status(nfc);
> -		break;
>  #ifdef __LITTLE_ENDIAN
> -	case ALT_BUF_ONFI:
> -		/* Reverse byte since the controller uses big endianness */
> -		c = nfc->buf_offset ^ 0x3;
> -		/* fall-through */
> +		fix_byte_order = true;
>  #endif
> -	default:
> -		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
> -		break;
> -	}
> -	nfc->buf_offset++;
> -	return tmp;
> -}
> +		dev_dbg(nfc->dev, "OP_DATA_IN: 8-bit: %d, len %d, offset %d\n",
> +			instr->ctx.data.force_8bit , len, offset);
>  
> -static u16 vf610_nfc_read_word(struct mtd_info *mtd)
> -{
> -	u16 tmp;
> +		/*
> +		 * HACK: force_8bit indicates reading of the parameter, status
> +		 * or id data. The controllers seems to store data in big endian
> +		 * byte order to the buffers. Reverse on little endian machines.
> +		 */
> +		if (instr->ctx.data.force_8bit && fix_byte_order) {
> +			u8 *buf = instr->ctx.data.buf.in;
>  
> -	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
> -	return tmp;
> -}
> +			while (len--) {
> +				int c = offset ^ 0x3;
>  
> -/* If not provided, upper layers apply a fixed delay. */
> -static int vf610_nfc_dev_ready(struct mtd_info *mtd)
> -{
> -	/* NFC handles R/B internally; always ready.  */
> -	return 1;
> +				*buf = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
> +				//dev_info(nfc->dev, "[%d]: %02x\n", offset, *buf);
> +				buf++; offset++;
> +			}
> +		} else {
> +			vf610_nfc_memcpy(instr->ctx.data.buf.in + offset,
> +					 nfc->regs + NFC_MAIN_AREA(0) + offset,
> +					 len);
> +		}
> +	}
> +
> +	return 0;
>  }

Hm, it's really hard to review things with these interleaved
deletions/additions. For the next version I recommend that you split things
in 2 steps:
1/ add ->exec_op()
2/ remove old hooks

Anyway, I think you should use the generic parser in order to simplify the
vf610_nfc_exec_op() logic and make it more robust/future-proof.

Note that you can describe several patterns that all points to the same
subop handler. This way the generic parser can isolate the sub-patterns
and pass them to your subop handler which no longer has to validate
instruction order.

>  
>  /*
> @@ -511,21 +465,6 @@ static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
>  	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
>  }
>  
> -/* Count the number of 0's in buff up to max_bits */
> -static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
> -{
> -	uint32_t *buff32 = (uint32_t *)buff;
> -	int k, written_bits = 0;
> -
> -	for (k = 0; k < (size / 4); k++) {
> -		written_bits += hweight32(~buff32[k]);
> -		if (unlikely(written_bits > max_bits))
> -			break;
> -	}
> -
> -	return written_bits;
> -}
> -
>  static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
>  					 uint8_t *oob, int page)
>  {
> @@ -542,8 +481,7 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
>  		return ecc_count;
>  
>  	/* Read OOB without ECC unit enabled */
> -	vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
> -	vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
> +	nand_read_page_op(&nfc->chip, page, mtd->writesize, oob, mtd->oobsize);
>  
>  	/*
>  	 * On an erased page, bit count (including OOB) should be zero or
> @@ -557,12 +495,17 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
>  static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  				uint8_t *buf, int oob_required, int page)
>  {
> +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
>  	int eccsize = chip->ecc.size;
>  	int stat;
>  
> +	nfc->use_hw_ecc = true;

Why not writing to NFC_CFG here instead of doing it your ->exec_op()
implem? Remember that ->exec_op() should be as dumb as possible.

>  	nand_read_page_op(chip, page, 0, buf, eccsize);
>  	if (oob_required)
> -		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
> +		vf610_nfc_memcpy(chip->oob_poi,
> +				 nfc->regs + NFC_MAIN_AREA(0) + mtd->writesize,
> +				 mtd->oobsize);

Hm, it should be done with the generic nand_read_data_op() helper. If
you want to handle page read differently in order to optimize this path,
you shouldn't be using nand_read_page_op() in the first place.

Anyway, when you call nand_read_page_op(), all that should go on the
bus are the CMD+ADDR cycles + eccsize bytes of DATA_IN. Given that you
copy things from the internal SRAM to the ->oob_poi buffer, i suspect
you're breaking the first and most important rule behind ->exec_op() =>
"don't try to be smart, just do what you were asked to do, and if you
can't, return an error".

> +	nfc->use_hw_ecc = false;
>  
>  	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
>  
> @@ -579,16 +522,20 @@ static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
>  				const uint8_t *buf, int oob_required, int page)
>  {
>  	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> +	int ret;
>  
> -	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
> -	if (oob_required)
> -		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
> -
> -	/* Always write whole page including OOB due to HW ECC */
>  	nfc->use_hw_ecc = true;
> -	nfc->write_sz = mtd->writesize + mtd->oobsize;
> +	ret = nand_prog_page_op(chip, page, 0, buf, mtd->writesize);
> +	nfc->use_hw_ecc = false;

Same as above, looks like your ->exec_op() is too smart: it decides to
transfer OOB data even if it's not asked to.

I really think you want custom handling for page accessors, which is
perfectly fine, but then it shouldn't use the generic xxxx_op() helpers.

>  
> -	return nand_prog_page_end_op(chip);
> +	return ret;
> +}
> +
> +static int vf610_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
> +				const uint8_t *buf, int oob_required, int page)
> +{
> +	return nand_prog_page_op(chip, page, 0, buf,
> +			mtd->writesize + oob_required ? mtd->oobsize : 0);
>  }
>  
>  static const struct of_device_id vf610_nfc_dt_ids[] = {
> @@ -606,6 +553,9 @@ static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
>  	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
>  	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
>  
> +	/* Make sure flags are cleared on startup */
> +	vf610_nfc_clear_status(nfc);
> +
>  	/* Disable virtual pages, only one elementary transfer unit */
>  	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
>  			    CONFIG_PAGE_CNT_SHIFT, 1);
> @@ -695,15 +645,8 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  		goto err_clk;
>  	}
>  
> -	chip->dev_ready = vf610_nfc_dev_ready;
> -	chip->cmdfunc = vf610_nfc_command;
> -	chip->read_byte = vf610_nfc_read_byte;
> -	chip->read_word = vf610_nfc_read_word;
> -	chip->read_buf = vf610_nfc_read_buf;
> -	chip->write_buf = vf610_nfc_write_buf;
> +	chip->exec_op = vf610_nfc_exec_op;
>  	chip->select_chip = vf610_nfc_select_chip;
> -	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
> -	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
>  
>  	chip->options |= NAND_NO_SUBPAGE_WRITE;
>  
> @@ -770,6 +713,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  
>  		chip->ecc.read_page = vf610_nfc_read_page;
>  		chip->ecc.write_page = vf610_nfc_write_page;
> +		chip->ecc.write_page_raw = vf610_nfc_write_page_raw;
>  
>  		chip->ecc.size = PAGE_2K;
>  	}



From miquel.raynal at free-electrons.com  Mon Jan 15 14:32:54 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Mon, 15 Jan 2018 23:32:54 +0100
Subject: [PATCH] mtd: nand: add ->setup_data_interface() support for Marvell
 NFCv1
Message-ID: <20180115223254.9351-1-miquel.raynal@free-electrons.com>

First generation of Marvell NAND flash controllers (eg. embedded in PXA
boards) did not make use of the NAND core hook ->setup_data_interface()
to setup controller timings. Add support for it.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/marvell_nand.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
index 10f108cc08e2..7db870ae1b07 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -379,6 +379,8 @@ struct marvell_nfc_timings {
  * return the number of clock periods.
  */
 #define TO_CYCLES(ps, period_ns) (DIV_ROUND_UP(ps / 1000, period_ns))
+#define TO_CYCLES64(ps, period_ns) (DIV_ROUND_UP_ULL(div_u64(ps, 1000), \
+						     period_ns))
 
 /**
  * NAND driver structure filled during the parsing of the ->exec_op() subop
@@ -2239,31 +2241,47 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
 	nfc_tmg.tRHW = TO_CYCLES(max_t(int, sdr->tRHW_min, sdr->tCCS_min),
 				 period_ns);
 
-	/* Use WAIT_MODE (wait for RB line) instead of only relying on delays */
-	nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns);
+	/*
+	 * NFCv2: Use WAIT_MODE (wait for RB line), do not rely only on delays.
+	 * NFCv1: No WAIT_MODE, tR must be maximal.
+	 */
+	if (nfc->caps->is_nfcv2)
+		nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns);
+	else
+		nfc_tmg.tR = TO_CYCLES64(sdr->tR_max, period_ns) -
+			nfc_tmg.tCH - 3;
+
+	if (nfc_tmg.tR < 0)
+		return -EINVAL;
 
 	if (chipnr < 0)
 		return 0;
 
 	marvell_nand->ndtr0 =
 		NDTR0_TRP(nfc_tmg.tRP) |
-		NDTR0_TRH(nfc_tmg.tRH) |
 		NDTR0_ETRP(nfc_tmg.tRP) |
+		NDTR0_TRH(nfc_tmg.tRH) |
 		NDTR0_TWP(nfc_tmg.tWP) |
 		NDTR0_TWH(nfc_tmg.tWH) |
 		NDTR0_TCS(nfc_tmg.tCS) |
-		NDTR0_TCH(nfc_tmg.tCH) |
-		NDTR0_RD_CNT_DEL(read_delay) |
-		NDTR0_SELCNTR |
-		NDTR0_TADL(nfc_tmg.tADL);
+		NDTR0_TCH(nfc_tmg.tCH);
 
 	marvell_nand->ndtr1 =
 		NDTR1_TAR(nfc_tmg.tAR) |
 		NDTR1_TWHR(nfc_tmg.tWHR) |
-		NDTR1_TRHW(nfc_tmg.tRHW) |
-		NDTR1_WAIT_MODE |
 		NDTR1_TR(nfc_tmg.tR);
 
+	if (nfc->caps->is_nfcv2) {
+		marvell_nand->ndtr0 |=
+			NDTR0_RD_CNT_DEL(read_delay) |
+			NDTR0_SELCNTR |
+			NDTR0_TADL(nfc_tmg.tADL);
+
+		marvell_nand->ndtr1 |=
+			NDTR1_TRHW(nfc_tmg.tRHW) |
+			NDTR1_WAIT_MODE;
+	}
+
 	return 0;
 }
 
@@ -2398,8 +2416,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
 
 	chip->exec_op = marvell_nfc_exec_op;
 	chip->select_chip = marvell_nfc_select_chip;
-	if (nfc->caps->is_nfcv2 &&
-	    !of_property_read_bool(np, "marvell,nand-keep-config"))
+	if (!of_property_read_bool(np, "marvell,nand-keep-config"))
 		chip->setup_data_interface = marvell_nfc_setup_data_interface;
 
 	mtd = nand_to_mtd(chip);
-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 14:45:45 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 23:45:45 +0100
Subject: [PATCH V4 0/2] mtd: simplify mtd_device_parse_register code
In-Reply-To: <20180115143519.9845-1-zajec5@gmail.com>
References: <20180115143519.9845-1-zajec5@gmail.com>
Message-ID: <20180115224547.9265-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Even though I have some experience with MTD subsystem every time I was
starting working on it I had to do some quick research on the code flow.
I think there is some place for cleanup and optimization that would
simplify overall code and allow new developers to start working on it
more easily.

In these patches I meant to slightly simplify mtd_device_parse_register
function. I think we could reduce amount of add/register/del functions
and this is the first step for that.

Ideally I think mtdcore.c shouldn't handle parsing but just use a single
function from mtdpart.c.

Patch 1/2 modifies code to make sure parsing code is not mixed with MTD
master code. This should allow moving parsing parts to the mtdpart.c in
the future.

Patch 2/2 simplifies code and makes sure parsing is handled at 1 place
only.

Even though this cleanup isn't complete I think it already has some
value and could be accepted (if there won't be objections) on its own.
It's also quite small which should allow reviewing it easily.

Rafa? Mi?ecki (2):
  mtd: move code adding master MTD out of mtd_add_device_partitions
  mtd: get rid of the mtd_add_device_partitions function

 drivers/mtd/mtdcore.c | 58 ++++++++++++++++++---------------------------------
 1 file changed, 20 insertions(+), 38 deletions(-)

-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 14:45:46 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 23:45:46 +0100
Subject: [PATCH V4 1/2] mtd: move code adding master MTD out of
 mtd_add_device_partitions
In-Reply-To: <20180115224547.9265-1-zajec5@gmail.com>
References: <20180115143519.9845-1-zajec5@gmail.com>
 <20180115224547.9265-1-zajec5@gmail.com>
Message-ID: <20180115224547.9265-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This change is a small cleanup of mtd_device_parse_register. When using
MTD_PARTITIONED_MASTER it makes sure a master MTD is registered before
dealing with partitions. There are 2 advantages of this:
1) Not mixing code handling master MTD with code handling partitions
2) Possibility of reusing mtd_parse_part in the future to avoid some
   code duplication.

This commit doesn't change any behavior except from a slightly different
failure code path. The new code may need to call del_mtd_device when
something goes wrong.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Use device_is_registered (thanks Boris)
    Add an empty line before "return ret;"
V3: Use device_is_registered also in a out code path
---
 drivers/mtd/mtdcore.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index f80e911b8843..3304199cca07 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -641,20 +641,12 @@ static int mtd_add_device_partitions(struct mtd_info *mtd,
 {
 	const struct mtd_partition *real_parts = parts->parts;
 	int nbparts = parts->nr_parts;
-	int ret;
 
-	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			return ret;
-	}
+	if (!nbparts && !device_is_registered(&mtd->dev))
+		return add_mtd_device(mtd);
 
-	if (nbparts > 0) {
-		ret = add_mtd_partitions(mtd, real_parts, nbparts);
-		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-			del_mtd_device(mtd);
-		return ret;
-	}
+	if (nbparts > 0)
+		return add_mtd_partitions(mtd, real_parts, nbparts);
 
 	return 0;
 }
@@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 
 	mtd_set_dev_defaults(mtd);
 
+	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+		ret = add_mtd_device(mtd);
+		if (ret)
+			return ret;
+	}
+
 	memset(&parsed, 0, sizeof(parsed));
 
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
@@ -753,6 +751,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 out:
 	/* Cleanup any parsed partitions */
 	mtd_part_parser_cleanup(&parsed);
+	if (ret && device_is_registered(&mtd->dev))
+		del_mtd_device(mtd);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(mtd_device_parse_register);
-- 
2.11.0



From zajec5 at gmail.com  Mon Jan 15 14:45:47 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 15 Jan 2018 23:45:47 +0100
Subject: [PATCH V4 2/2] mtd: get rid of the mtd_add_device_partitions()
In-Reply-To: <20180115224547.9265-1-zajec5@gmail.com>
References: <20180115143519.9845-1-zajec5@gmail.com>
 <20180115224547.9265-1-zajec5@gmail.com>
Message-ID: <20180115224547.9265-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This simplifies code a bit by:
1) Avoiding an extra (tiny) function
2) Checking for amount of parsed (found) partitions just once
3) Avoiding clearing/filling struct mtd_partitions manually

With this commit proper functions are called directly from the
mtd_device_parse_register(). It doesn't need to use minor tricks like
memsetting struct to 0 to trigger an expected
mtd_add_device_partitions() behavior.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Simplify conditions in the mtd_device_parse_register (thanks Boris)
V4: Zero-initialize parsed variable. Some parsers return 0 without
    setting nr_parts.
    Update commit message: drop "a" from "a functions" & use ()
---
 drivers/mtd/mtdcore.c | 43 ++++++++++++-------------------------------
 1 file changed, 12 insertions(+), 31 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 3304199cca07..4eebbc1cc967 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -636,21 +636,6 @@ int del_mtd_device(struct mtd_info *mtd)
 	return ret;
 }
 
-static int mtd_add_device_partitions(struct mtd_info *mtd,
-				     struct mtd_partitions *parts)
-{
-	const struct mtd_partition *real_parts = parts->parts;
-	int nbparts = parts->nr_parts;
-
-	if (!nbparts && !device_is_registered(&mtd->dev))
-		return add_mtd_device(mtd);
-
-	if (nbparts > 0)
-		return add_mtd_partitions(mtd, real_parts, nbparts);
-
-	return 0;
-}
-
 /*
  * Set a few defaults based on the parent devices, if not provided by the
  * driver
@@ -701,7 +686,7 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 			      const struct mtd_partition *parts,
 			      int nr_parts)
 {
-	struct mtd_partitions parsed;
+	struct mtd_partitions parsed = { };
 	int ret;
 
 	mtd_set_dev_defaults(mtd);
@@ -712,24 +697,20 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 			return ret;
 	}
 
-	memset(&parsed, 0, sizeof(parsed));
-
+	/* Prefer parsed partitions over driver-provided fallback */
 	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
-	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
-		/* Fall back to driver-provided partitions */
-		parsed = (struct mtd_partitions){
-			.parts		= parts,
-			.nr_parts	= nr_parts,
-		};
-	} else if (ret < 0) {
-		/* Didn't come up with parsed OR fallback partitions */
-		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
-			ret);
-		/* Don't abort on errors; we can still use unpartitioned MTD */
-		memset(&parsed, 0, sizeof(parsed));
+	if (!ret && parsed.nr_parts) {
+		parts = parsed.parts;
+		nr_parts = parsed.nr_parts;
 	}
 
-	ret = mtd_add_device_partitions(mtd, &parsed);
+	if (nr_parts)
+		ret = add_mtd_partitions(mtd, parts, nr_parts);
+	else if (!device_is_registered(&mtd->dev))
+		ret = add_mtd_device(mtd);
+	else
+		ret = 0;
+
 	if (ret)
 		goto out;
 
-- 
2.11.0



From yuyufen at huawei.com  Mon Jan 15 22:16:44 2018
From: yuyufen at huawei.com (yuyufen)
Date: Tue, 16 Jan 2018 14:16:44 +0800
Subject: [RFC PATCH] ubifs: Add zstd support
In-Reply-To: <7790203.HFZG64yrZx@blindfold>
References: <20180112092421.22095-1-yuyufen@huawei.com>
 <7790203.HFZG64yrZx@blindfold>
Message-ID: <7c454b10-6bec-8123-e750-7e6e4772b76e@huawei.com>

On 2018/1/12 18:45, Richard Weinberger wrote:
> Yufen Yu,
>
> Am Freitag, 12. Januar 2018, 10:24:21 CET schrieb Yufen Yu:
>> Add zstd compression and decompression support to ubifs. zstd at its
>> fastest level compresses almost as well as zlib, while offering much
>> faster compression and decompression, approaching lzo speeds.
>>
>> This patch is based on the patch:
>> 	https://patchwork.kernel.org/patch/9892631/
>>
>> zstd source repository: https://github.com/facebook/zstd
> Do you have numbers on how much we gain for UBIFS on a typical embedded
> device?
>
> Thanks,
> //richard
>
> .
>

This is a RFC patch. I will post the test results after the full 
function completing.

Thanks a lot.

Yufen Yu



From arnd at arndb.de  Mon Jan 15 23:43:40 2018
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 16 Jan 2018 08:43:40 +0100
Subject: [PATCH] mtd: onenand: omap2: print resource using %pR format string
Message-ID: <20180116074359.2861596-1-arnd@arndb.de>

The omap2 onenand driver is now available for compile-testing, which
uncovers a warning in configurations that have a 64-bit resource_size_t:

drivers/mtd/onenand/omap2.c: In function 'omap2_onenand_probe':
drivers/mtd/onenand/omap2.c:536:54: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t {aka long long unsigned int}' [-Werror=format=]
   dev_err(dev, "Cannot reserve memory region at 0x%08x, size: 0x%x\n",
drivers/mtd/onenand/omap2.c:536:66: error: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t {aka long long unsigned int}' [-Werror=format=]

Changing the format string to the special %pR simplifies the code
and lets it do the right thing in that configuration, while avoiding
the warning.

Fixes: a758f50f10cf ("mtd: onenand: omap2: Configure driver from DT")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/mtd/onenand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 2ce73fb6da1c..a4a2159bcfb7 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -533,8 +533,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	c->onenand.base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(c->onenand.base)) {
-		dev_err(dev, "Cannot reserve memory region at 0x%08x, size: 0x%x\n",
-			res->start, resource_size(res));
+		dev_err(dev, "Cannot reserve memory region %pR\n", res);
 		return PTR_ERR(c->onenand.base);
 	}
 
-- 
2.9.0



From aye78a at gmail.com  Tue Jan 16 18:01:08 2018
From: aye78a at gmail.com (=?UTF-8?Q?Mrs=2E_Marie_Ang=C3=A8le_O?=)
Date: Wed, 17 Jan 2018 02:01:08 +0000
Subject: Ut
Message-ID: <CAPO_6J1vk0UN_YEG0=s9EiYM8Z3PvLfxF2=X5gSP3sVtF6x8_Q@mail.gmail.com>

-- 
My name is Mrs. Emile Kenold from London. Am suffering from lung
cancer which had damaged my liver and back bone, my health is no
longer responding to treatment.

I have made up my mind to give a charity donation of ?7 Million
British Pound Sterling to you and i hope you use my donation for
charity work according to my will as i need your urgent response so
that i will move this money to you due to my bad health condition.

Regards
Emile.


From zajec5 at gmail.com  Wed Jan 17 00:15:20 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 17 Jan 2018 09:15:20 +0100
Subject: [PATCH V8 1/2] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180104070534.16248-1-zajec5@gmail.com>
References: <20180104070534.16248-1-zajec5@gmail.com>
Message-ID: <20180117081521.2463-1-zajec5@gmail.com>

From: Brian Norris <computersforpeace at gmail.com>

Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.

It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
Please note that driver-specified parsers still take a precedence. It's
assumed that driver providing a parser type has a good reason for that
(e.g. having platform data with device-specific info). Also doing
otherwise could break existing setups. The same applies to using default
parsers (including "cmdlinepart") as some overwrite DT data with cmdline
argument.

This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching

V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
    Merge helpers into a single of_mtd_match_mtd_parser
V3: Add a simple comment to note we will need the best match in the future
V4: Rework new functions to pick parser with the best match
    Move new code in parse_mtd_partitions up so it has precedence over flash
    driver defaults and MTD defaults
V5: Rework matching code to start checking with the most specific string in the
    "compatibility" property.
V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
V7: Rename function "mtd_part_get_parser_by_cp" to use "_compatible_"
    Rename "cp" variable to "compat"
    Drop unneeded if (np) check from the parse_mtd_partitions
V8: Move new OF code in parse_mtd_partitions() lower so driver-specified parsers
    take a precedence. Update commit message to make that clear.
---
 drivers/mtd/mtdpart.c          | 60 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/partitions.h |  1 +
 2 files changed, 61 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 76cd21d1171b..e33bad0e46f5 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -861,6 +862,45 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 }
 
 /**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+	struct mtd_part_parser *p, *ret = NULL;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->compatible[0]; matches++) {
+			if (!strcmp(matches->compatible, compat) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
+/**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
  * @types: names of partition parsers to try or %NULL
@@ -886,6 +926,9 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 			 struct mtd_part_parser_data *data)
 {
 	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *compat;
 	int ret, err = 0;
 
 	if (!types)
@@ -912,6 +955,23 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 		if (ret < 0 && !err)
 			err = ret;
 	}
+
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	of_property_for_each_string(np, "compatible", prop, compat) {
+		parser = mtd_part_get_compatible_parser(compat);
+		if (!parser)
+			continue;
+		ret = mtd_part_do_parse(parser, master, pparts, data);
+		if (ret > 0) {
+			of_node_put(np);
+			return 0;
+		}
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+	of_node_put(np);
+
 	return err;
 }
 
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70dacbd..11cb0c50cd84 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-- 
2.11.0



From zajec5 at gmail.com  Wed Jan 17 00:15:21 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 17 Jan 2018 09:15:21 +0100
Subject: [PATCH V8 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
In-Reply-To: <20180117081521.2463-1-zajec5@gmail.com>
References: <20180104070534.16248-1-zajec5@gmail.com>
 <20180117081521.2463-1-zajec5@gmail.com>
Message-ID: <20180117081521.2463-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).

This matches existing bindings documentation.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/ofpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e525677..92fcbac046d9 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
 	.parse_fn = parse_ofpart_partitions,
 	.name = "ofpart",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
-- 
2.11.0



From rafal at milecki.pl  Wed Jan 17 00:20:11 2018
From: rafal at milecki.pl (=?UTF-8?Q?Rafa=C5=82_Mi=C5=82ecki?=)
Date: Wed, 17 Jan 2018 09:20:11 +0100
Subject: [REGRESSION] linux-next panics when trying to mount root
In-Reply-To: <20180116163032.54a392c7@bbrezillon>
References: <574b1571-1664-f09f-62bf-48f7f94a51cd@axentia.se>
 <20180116143651.04bca70f@bbrezillon>
 <b5af18eb-e54d-eeab-d03b-4c0edbe74fd6@axentia.se>
 <20180116152138.18a114d6@bbrezillon>
 <6a51ff05-89ed-cd57-6d90-3af51c7ce619@axentia.se>
 <20180116163032.54a392c7@bbrezillon>
Message-ID: <0d3201d921386c32d2b65b3b7d3e10e7@milecki.pl>

On 2018-01-16 16:30, Boris Brezillon wrote:
> On Tue, 16 Jan 2018 16:02:35 +0100
> Peter Rosin <peda at axentia.se> wrote:
> 
>> On 2018-01-16 15:21, Boris Brezillon wrote:
>> > On Tue, 16 Jan 2018 14:56:52 +0100
>> > Peter Rosin <peda at axentia.se> wrote:
>> >
>> >> Hmmm, I guess the question is if the command line should override the
>> >> device tree or not?
>> >
>> > Yep, that's the problem. Now the core parses the compatible to decides
>> > which part parser should be used. The thing is, the "cmdline" parser is
>> > not yet exposing a compatible id, and even if it was, this would
>> > require patching all DTs to add this new compatible.
>> >
>> > 	partitions {
>> > 		compatible = "cmdline", "fixed-partitions";
>> > 		...
>> > 	};
>> >
>> > Not really an option, so I'll drop the 2 patches for now until we find a
>> > better solution.
>> >
>> >> I'm going to send a patch for the above dts change either way...
>> >
>> > If you want, but that does not solve the problem: we should not break
>> > existing users.
>> 
>> Well, don't let these devices stop you, they will not get a new kernel
>> w/o also getting a new dtb, and I can handle this just fine. But maybe
>> I'm just the first reporter and you'd rather not risk anything? 
>> Anyway,
>> just wanted to let you know where I stand...
> 
> Unfortunately, at91 is not the only platform to have "fixed-partitions"
> defined in its DTs, and I guess users of other platforms also like to
> override the default MTD layout by their own using mtdparts.I'd like to
> find a solution that keeps everyone happy.

I absolutely agree with Boris, we can't risk such regressions. That had 
to
be dropped and I'm looking for a better solution.


From rafal at milecki.pl  Wed Jan 17 00:27:18 2018
From: rafal at milecki.pl (=?UTF-8?Q?Rafa=C5=82_Mi=C5=82ecki?=)
Date: Wed, 17 Jan 2018 09:27:18 +0100
Subject: [REGRESSION] linux-next panics when trying to mount root
In-Reply-To: <574b1571-1664-f09f-62bf-48f7f94a51cd@axentia.se>
References: <574b1571-1664-f09f-62bf-48f7f94a51cd@axentia.se>
Message-ID: <a1fa20bcb07cf6016f38e499ba434d97@milecki.pl>

On 2018-01-16 14:28, Peter Rosin wrote:
> When trying next-20180116 I get the following panic during boot:
> 
> Linux version 4.15.0-rc8-next-20180116 (peda at orc) (gcc version 4.9.2
> 20140811 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.08 - Linaro
> GCC 4.9-2014.08)) #208 Tue Jan 16 14:23:44 CET 2018
> CPU: ARMv7 Processor [410fc051] revision 1 (ARMv7), cr=10c53c7d
> CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction 
> cache
> OF: fdt: Machine model: Axentia Linea-Nattis v2 Natte v2
> Memory policy: Data cache writeback
> CPU: All CPU(s) started in SVC mode.
> random: fast init done
> Built 1 zonelists, mobility grouping on.  Total pages: 16256
> Kernel command line: console=ttyS0,115200 rw consoleblank=0 ip=none
> root=ubi0:rootfs ubi.mtd=6 rootfstype=ubifs noinitrd
> mtdparts=atmel_nand:256k(at91bootstrap),384k(barebox)ro,256k at 768k(bareboxenv),256k(bareboxenv2),128k at 1536k(oftree),5M at 2M(kernel),- at 8M(rootfs)
> Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
> Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
> Memory: 56244K/65536K available (5120K kernel code, 183K rwdata, 1064K
> rodata, 1024K init, 108K bss, 9292K reserved, 0K cma-reserved)
> Virtual kernel memory layout:
>     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
>     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
>     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
>     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
>       .text : 0x(ptrval) - 0x(ptrval)   (6112 kB)
>       .init : 0x(ptrval) - 0x(ptrval)   (1024 kB)
>       .data : 0x(ptrval) - 0x(ptrval)   ( 184 kB)
>        .bss : 0x(ptrval) - 0x(ptrval)   ( 109 kB)
> NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
> clocksource: pit: mask: 0xfffffff max_cycles: 0xfffffff, max_idle_ns:
> 14479245754 ns
> sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every
> 21474836475000000ns
> Console: colour dummy device 80x30
> Calibrating delay loop... 351.43 BogoMIPS (lpj=1757184)
> pid_max: default: 32768 minimum: 301
> Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
> Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
> CPU: Testing write buffer coherency: ok
> Setting up static identity map for 0x20100000 - 0x20100060
> devtmpfs: initialized
> VFP support v0.3: implementor 41 architecture 2 part 30 variant 5 rev 1
> clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff,
> max_idle_ns: 19112604462750000 ns
> futex hash table entries: 256 (order: -1, 3072 bytes)
> pinctrl core: initialized pinctrl subsystem
> NET: Registered protocol family 16
> DMA: preallocated 256 KiB pool for atomic coherent allocations
> AT91: PM: standby: standby, suspend: ulp0
> No ATAGs?
> gpio-at91 fffff200.gpio: at address 45a5b6d3
> gpio-at91 fffff400.gpio: at address d0c9dba6
> gpio-at91 fffff600.gpio: at address fb737fc9
> gpio-at91 fffff800.gpio: at address c5aa2ee6
> gpio-at91 fffffa00.gpio: at address 4663f5ca
> pinctrl-at91 ahb:apb:pinctrl at fffff200: initialized AT91 pinctrl driver
> clocksource: tcb_clksrc: mask: 0xffffffff max_cycles: 0xffffffff,
> max_idle_ns: 115833966437 ns
> at_hdmac ffffe600.dma-controller: Atmel AHB DMA Controller ( cpy set
> slave ), 8 channels
> at_hdmac ffffe800.dma-controller: Atmel AHB DMA Controller ( cpy set
> slave ), 8 channels
> AT91: Detected SoC family: sama5d3
> AT91: Detected SoC: sama5d31, revision 2
> usbcore: registered new interface driver usbfs
> usbcore: registered new interface driver hub
> usbcore: registered new device driver usb
> at91_i2c f0014000.i2c: using dma0chan0 (tx) and dma0chan1 (rx) for DMA 
> transfers
> at91_i2c f0014000.i2c: AT91 i2c bus driver (hw version: 0x402).
> clocksource: Switched to clocksource tcb_clksrc
> NET: Registered protocol family 2
> tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes)
> TCP established hash table entries: 1024 (order: 0, 4096 bytes)
> TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
> TCP: Hash tables configured (established 1024 bind 1024)
> UDP hash table entries: 256 (order: 0, 4096 bytes)
> UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
> NET: Registered protocol family 1
> Initialise system trusted keyrings
> workingset: timestamp_bits=30 max_order=14 bucket_order=0
> Key type asymmetric registered
> Asymmetric key parser 'x509' registered
> io scheduler noop registered (default)
> io scheduler mq-deadline registered
> io scheduler kyber registered
> f001c000.serial: ttyS1 at MMIO 0xf001c000 (irq = 22, base_baud =
> 4125000) is a ATMEL_SERIAL
> ffffee00.serial: ttyS0 at MMIO 0xffffee00 (irq = 30, base_baud =
> 8250000) is a ATMEL_SERIAL
> console [ttyS0] enabled
> loop: module loaded
> ssc f0008000.ssc: Atmel SSC device at 0x6a12493c (irq 19)
> ssc f0008000.ssc: failed to auto-setup ssc for audio
> at24 0-0051: 8192 byte 24c64 EEPROM, writable, 32 bytes/write
> at24 0-0050: 256 byte 24c02 EEPROM, writable, 16 bytes/write
> [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [drm] No driver support for vblank timestamp query.
> atmel-hlcdc-display-controller atmel-hlcdc-dc: failed to create HLCDC
> outputs: -517
> atmel-hlcdc-display-controller atmel-hlcdc-dc: failed to initialize 
> mode setting
> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> ehci-atmel: EHCI Atmel driver
> atmel_usba_udc 500000.gadget: MMIO registers at 0xf8030000 mapped at 
> ff1022ba
> atmel_usba_udc 500000.gadget: FIFO at 0x00500000 mapped at 3b2532b1
> g_serial gadget: Gadget Serial v2.4
> g_serial gadget: g_serial ready
> at91_rtc fffffeb0.rtc: registered as rtc0
> at91_rtc fffffeb0.rtc: AT91 Real Time Clock driver.
> i2c /dev entries driver
> AT91: Starting after wakeup
> atmel_mci f0000000.mmc: version: 0x505
> atmel_mci f0000000.mmc: using dma0chan2 for DMA transfers
> atmel_mci f0000000.mmc: Atmel MCI controller at 0xf0000000 irq 18, 1 
> slots
> atmel_aes f8038000.aes: version: 0x135
> atmel_aes f8038000.aes: Atmel AES - Using dma1chan0, dma1chan1 for DMA 
> transfers
> atmel_sha f8034000.sha: version: 0x410
> atmel_sha f8034000.sha: using dma1chan2 for DMA transfers
> atmel_sha f8034000.sha: Atmel SHA1/SHA256/SHA224/SHA384/SHA512
> atmel_tdes f803c000.tdes: version: 0x701
> atmel_tdes f803c000.tdes: using dma1chan3, dma1chan4 for DMA transfers
> atmel_tdes f803c000.tdes: Atmel DES/TDES
> usbcore: registered new interface driver usbhid
> usbhid: USB HID core driver
> nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xac
> nand: Micron MT29F4G08ABBDAHC
> nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> Bad block table found at page 262080, version 0x01
> Bad block table found at page 262016, version 0x01
> 6 ofpart partitions found on MTD device atmel_nand
> Creating 6 MTD partitions on "atmel_nand":
> 0x000000000000-0x000000040000 : "at91bootstrap"
> 0x000000040000-0x0000000c0000 : "bootloader"
> 0x0000000c0000-0x000000180000 : "bootloader env"
> 0x000000180000-0x000000200000 : "device tree"
> 0x000000200000-0x000000800000 : "kernel"
> 0x000000800000-0x000010000000 : "rootfs"
> NET: Registered protocol family 10
> Segment Routing with IPv6
> sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
> NET: Registered protocol family 17
> Loading compiled-in X.509 certificates
> [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [drm] No driver support for vblank timestamp query.
> atmel-hlcdc-display-controller atmel-hlcdc-dc: fb0:  frame buffer 
> device
> [drm] Initialized atmel-hlcdc 1.0.0 20141504 for atmel-hlcdc-dc on 
> minor 0
> UBI error: cannot open mtd 6, error -19
> input: gpio-keys as /devices/platform/gpio-keys/input/input0
> at91_rtc fffffeb0.rtc: setting system clock to 2007-01-01 00:00:08 UTC
> (1167609608)
> panel-VCC: disabling
> panel-VDD: disabling
> atmel_usart ffffee00.serial: using dma1chan5 for rx DMA transfers
> Kernel panic - not syncing: VFS: Unable to mount root fs on 
> unknown-block(0,0)
> CPU: 0 PID: 1 Comm: swapper Not tainted 4.15.0-rc8-next-20180116 #208
> Hardware name: Atmel SAMA5
> [<c010cc5c>] (unwind_backtrace) from [<c010b140>] 
> (show_stack+0x10/0x14)
> [<c010b140>] (show_stack) from [<c0115f20>] (panic+0xc8/0x254)
> [<c0115f20>] (panic) from [<c0801348>] (mount_block_root+0x23c/0x2f8)
> [<c0801348>] (mount_block_root) from [<c0801528>] 
> (prepare_namespace+0xa8/0x19c)
> [<c0801528>] (prepare_namespace) from [<c0800ff0>]
> (kernel_init_freeable+0x1bc/0x1cc)
> [<c0800ff0>] (kernel_init_freeable) from [<c051b958>] 
> (kernel_init+0x8/0x10c)
> [<c051b958>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
> Exception stack(0xc3821fb0 to 0xc3821ff8)
> 1fa0:                                     00000000 00000000 00000000 
> 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
> 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on
> unknown-block(0,0)
> 
> 
> I bisected it to:
> 
> 4ac9222778478a00c7fc9d347b7ed1e0e595120d is the first bad commit
> commit 4ac9222778478a00c7fc9d347b7ed1e0e595120d
> Author: Rafa? Mi?ecki <rafal at milecki.pl>
> Date:   Thu Jan 4 08:05:34 2018 +0100
> 
>     mtd: ofpart: add of_match_table with "fixed-partitions"
> 
>     This allows using this parser with any flash driver that takes care 
> of
>     setting of_node (using mtd_set_of_node helper) correctly. Up to now
>     support for "fixed-partitions" DT compatibility string was working 
> only
>     with flash drivers that were specifying "ofpart" (manually or by 
> letting
>     mtd use the default set of parsers).
> 
>     This matches existing bindings documentation.
> 
>     Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>     Reviewed-by: Brian Norris <computersforpeace at gmail.com>
>     Tested-by: Brian Norris <computersforpeace at gmail.com>
>     Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> 
> 
> Reverting that patch on top of next-20180116 fixes the problem.
> 
> I'm using the arch/arm/boot/dts/at91-nattis-2-natte-2.dts device tree 
> which for
> the record is kind of new in the upstream kernel, but I have been using 
> that dts
> for a while previously. However, I'd put my money on at91-tse850-3.dts 
> also
> being affected, and that one have been upstream for a while. Haven't 
> tested the
> tse850 device tree though...

Peter, above patch was dropped, together with the one adding support for
the "of_match_table".

I just sent V8 of my changes, hopefully they don't cause regression this
time.

Would you be able to test following two patches & verify that your 
device
still works, please?
[PATCH V8 1/2] mtd: partitions: add of_match_table parser matching
[PATCH V8 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
https://patchwork.ozlabs.org/patch/862075/
https://patchwork.ozlabs.org/patch/862076/


From peda at axentia.se  Wed Jan 17 01:27:36 2018
From: peda at axentia.se (Peter Rosin)
Date: Wed, 17 Jan 2018 10:27:36 +0100
Subject: [REGRESSION] linux-next panics when trying to mount root
In-Reply-To: <a1fa20bcb07cf6016f38e499ba434d97@milecki.pl>
References: <574b1571-1664-f09f-62bf-48f7f94a51cd@axentia.se>
 <a1fa20bcb07cf6016f38e499ba434d97@milecki.pl>
Message-ID: <c93e7433-35fa-decb-f44e-02fda1c3e18f@axentia.se>

On 2018-01-17 09:27, Rafa? Mi?ecki wrote:
> On 2018-01-16 14:28, Peter Rosin wrote:
>> When trying next-20180116 I get the following panic during boot:
>>
>> Linux version 4.15.0-rc8-next-20180116 (peda at orc) (gcc version 4.9.2
>> 20140811 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.08 - Linaro
>> GCC 4.9-2014.08)) #208 Tue Jan 16 14:23:44 CET 2018
>> CPU: ARMv7 Processor [410fc051] revision 1 (ARMv7), cr=10c53c7d
>> CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction 
>> cache
>> OF: fdt: Machine model: Axentia Linea-Nattis v2 Natte v2
>> Memory policy: Data cache writeback
>> CPU: All CPU(s) started in SVC mode.
>> random: fast init done
>> Built 1 zonelists, mobility grouping on.  Total pages: 16256
>> Kernel command line: console=ttyS0,115200 rw consoleblank=0 ip=none
>> root=ubi0:rootfs ubi.mtd=6 rootfstype=ubifs noinitrd
>> mtdparts=atmel_nand:256k(at91bootstrap),384k(barebox)ro,256k at 768k(bareboxenv),256k(bareboxenv2),128k at 1536k(oftree),5M at 2M(kernel),- at 8M(rootfs)
>> Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
>> Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
>> Memory: 56244K/65536K available (5120K kernel code, 183K rwdata, 1064K
>> rodata, 1024K init, 108K bss, 9292K reserved, 0K cma-reserved)
>> Virtual kernel memory layout:
>>     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
>>     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
>>     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
>>     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
>>       .text : 0x(ptrval) - 0x(ptrval)   (6112 kB)
>>       .init : 0x(ptrval) - 0x(ptrval)   (1024 kB)
>>       .data : 0x(ptrval) - 0x(ptrval)   ( 184 kB)
>>        .bss : 0x(ptrval) - 0x(ptrval)   ( 109 kB)
>> NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
>> clocksource: pit: mask: 0xfffffff max_cycles: 0xfffffff, max_idle_ns:
>> 14479245754 ns
>> sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every
>> 21474836475000000ns
>> Console: colour dummy device 80x30
>> Calibrating delay loop... 351.43 BogoMIPS (lpj=1757184)
>> pid_max: default: 32768 minimum: 301
>> Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
>> Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
>> CPU: Testing write buffer coherency: ok
>> Setting up static identity map for 0x20100000 - 0x20100060
>> devtmpfs: initialized
>> VFP support v0.3: implementor 41 architecture 2 part 30 variant 5 rev 1
>> clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff,
>> max_idle_ns: 19112604462750000 ns
>> futex hash table entries: 256 (order: -1, 3072 bytes)
>> pinctrl core: initialized pinctrl subsystem
>> NET: Registered protocol family 16
>> DMA: preallocated 256 KiB pool for atomic coherent allocations
>> AT91: PM: standby: standby, suspend: ulp0
>> No ATAGs?
>> gpio-at91 fffff200.gpio: at address 45a5b6d3
>> gpio-at91 fffff400.gpio: at address d0c9dba6
>> gpio-at91 fffff600.gpio: at address fb737fc9
>> gpio-at91 fffff800.gpio: at address c5aa2ee6
>> gpio-at91 fffffa00.gpio: at address 4663f5ca
>> pinctrl-at91 ahb:apb:pinctrl at fffff200: initialized AT91 pinctrl driver
>> clocksource: tcb_clksrc: mask: 0xffffffff max_cycles: 0xffffffff,
>> max_idle_ns: 115833966437 ns
>> at_hdmac ffffe600.dma-controller: Atmel AHB DMA Controller ( cpy set
>> slave ), 8 channels
>> at_hdmac ffffe800.dma-controller: Atmel AHB DMA Controller ( cpy set
>> slave ), 8 channels
>> AT91: Detected SoC family: sama5d3
>> AT91: Detected SoC: sama5d31, revision 2
>> usbcore: registered new interface driver usbfs
>> usbcore: registered new interface driver hub
>> usbcore: registered new device driver usb
>> at91_i2c f0014000.i2c: using dma0chan0 (tx) and dma0chan1 (rx) for DMA 
>> transfers
>> at91_i2c f0014000.i2c: AT91 i2c bus driver (hw version: 0x402).
>> clocksource: Switched to clocksource tcb_clksrc
>> NET: Registered protocol family 2
>> tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes)
>> TCP established hash table entries: 1024 (order: 0, 4096 bytes)
>> TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
>> TCP: Hash tables configured (established 1024 bind 1024)
>> UDP hash table entries: 256 (order: 0, 4096 bytes)
>> UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
>> NET: Registered protocol family 1
>> Initialise system trusted keyrings
>> workingset: timestamp_bits=30 max_order=14 bucket_order=0
>> Key type asymmetric registered
>> Asymmetric key parser 'x509' registered
>> io scheduler noop registered (default)
>> io scheduler mq-deadline registered
>> io scheduler kyber registered
>> f001c000.serial: ttyS1 at MMIO 0xf001c000 (irq = 22, base_baud =
>> 4125000) is a ATMEL_SERIAL
>> ffffee00.serial: ttyS0 at MMIO 0xffffee00 (irq = 30, base_baud =
>> 8250000) is a ATMEL_SERIAL
>> console [ttyS0] enabled
>> loop: module loaded
>> ssc f0008000.ssc: Atmel SSC device at 0x6a12493c (irq 19)
>> ssc f0008000.ssc: failed to auto-setup ssc for audio
>> at24 0-0051: 8192 byte 24c64 EEPROM, writable, 32 bytes/write
>> at24 0-0050: 256 byte 24c02 EEPROM, writable, 16 bytes/write
>> [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [drm] No driver support for vblank timestamp query.
>> atmel-hlcdc-display-controller atmel-hlcdc-dc: failed to create HLCDC
>> outputs: -517
>> atmel-hlcdc-display-controller atmel-hlcdc-dc: failed to initialize 
>> mode setting
>> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
>> ehci-atmel: EHCI Atmel driver
>> atmel_usba_udc 500000.gadget: MMIO registers at 0xf8030000 mapped at 
>> ff1022ba
>> atmel_usba_udc 500000.gadget: FIFO at 0x00500000 mapped at 3b2532b1
>> g_serial gadget: Gadget Serial v2.4
>> g_serial gadget: g_serial ready
>> at91_rtc fffffeb0.rtc: registered as rtc0
>> at91_rtc fffffeb0.rtc: AT91 Real Time Clock driver.
>> i2c /dev entries driver
>> AT91: Starting after wakeup
>> atmel_mci f0000000.mmc: version: 0x505
>> atmel_mci f0000000.mmc: using dma0chan2 for DMA transfers
>> atmel_mci f0000000.mmc: Atmel MCI controller at 0xf0000000 irq 18, 1 
>> slots
>> atmel_aes f8038000.aes: version: 0x135
>> atmel_aes f8038000.aes: Atmel AES - Using dma1chan0, dma1chan1 for DMA 
>> transfers
>> atmel_sha f8034000.sha: version: 0x410
>> atmel_sha f8034000.sha: using dma1chan2 for DMA transfers
>> atmel_sha f8034000.sha: Atmel SHA1/SHA256/SHA224/SHA384/SHA512
>> atmel_tdes f803c000.tdes: version: 0x701
>> atmel_tdes f803c000.tdes: using dma1chan3, dma1chan4 for DMA transfers
>> atmel_tdes f803c000.tdes: Atmel DES/TDES
>> usbcore: registered new interface driver usbhid
>> usbhid: USB HID core driver
>> nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xac
>> nand: Micron MT29F4G08ABBDAHC
>> nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>> Bad block table found at page 262080, version 0x01
>> Bad block table found at page 262016, version 0x01
>> 6 ofpart partitions found on MTD device atmel_nand
>> Creating 6 MTD partitions on "atmel_nand":
>> 0x000000000000-0x000000040000 : "at91bootstrap"
>> 0x000000040000-0x0000000c0000 : "bootloader"
>> 0x0000000c0000-0x000000180000 : "bootloader env"
>> 0x000000180000-0x000000200000 : "device tree"
>> 0x000000200000-0x000000800000 : "kernel"
>> 0x000000800000-0x000010000000 : "rootfs"
>> NET: Registered protocol family 10
>> Segment Routing with IPv6
>> sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
>> NET: Registered protocol family 17
>> Loading compiled-in X.509 certificates
>> [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [drm] No driver support for vblank timestamp query.
>> atmel-hlcdc-display-controller atmel-hlcdc-dc: fb0:  frame buffer 
>> device
>> [drm] Initialized atmel-hlcdc 1.0.0 20141504 for atmel-hlcdc-dc on 
>> minor 0
>> UBI error: cannot open mtd 6, error -19
>> input: gpio-keys as /devices/platform/gpio-keys/input/input0
>> at91_rtc fffffeb0.rtc: setting system clock to 2007-01-01 00:00:08 UTC
>> (1167609608)
>> panel-VCC: disabling
>> panel-VDD: disabling
>> atmel_usart ffffee00.serial: using dma1chan5 for rx DMA transfers
>> Kernel panic - not syncing: VFS: Unable to mount root fs on 
>> unknown-block(0,0)
>> CPU: 0 PID: 1 Comm: swapper Not tainted 4.15.0-rc8-next-20180116 #208
>> Hardware name: Atmel SAMA5
>> [<c010cc5c>] (unwind_backtrace) from [<c010b140>] 
>> (show_stack+0x10/0x14)
>> [<c010b140>] (show_stack) from [<c0115f20>] (panic+0xc8/0x254)
>> [<c0115f20>] (panic) from [<c0801348>] (mount_block_root+0x23c/0x2f8)
>> [<c0801348>] (mount_block_root) from [<c0801528>] 
>> (prepare_namespace+0xa8/0x19c)
>> [<c0801528>] (prepare_namespace) from [<c0800ff0>]
>> (kernel_init_freeable+0x1bc/0x1cc)
>> [<c0800ff0>] (kernel_init_freeable) from [<c051b958>] 
>> (kernel_init+0x8/0x10c)
>> [<c051b958>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
>> Exception stack(0xc3821fb0 to 0xc3821ff8)
>> 1fa0:                                     00000000 00000000 00000000 
>> 00000000
>> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
>> 00000000
>> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>> ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on
>> unknown-block(0,0)
>>
>>
>> I bisected it to:
>>
>> 4ac9222778478a00c7fc9d347b7ed1e0e595120d is the first bad commit
>> commit 4ac9222778478a00c7fc9d347b7ed1e0e595120d
>> Author: Rafa? Mi?ecki <rafal at milecki.pl>
>> Date:   Thu Jan 4 08:05:34 2018 +0100
>>
>>     mtd: ofpart: add of_match_table with "fixed-partitions"
>>
>>     This allows using this parser with any flash driver that takes care 
>> of
>>     setting of_node (using mtd_set_of_node helper) correctly. Up to now
>>     support for "fixed-partitions" DT compatibility string was working 
>> only
>>     with flash drivers that were specifying "ofpart" (manually or by 
>> letting
>>     mtd use the default set of parsers).
>>
>>     This matches existing bindings documentation.
>>
>>     Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>     Reviewed-by: Brian Norris <computersforpeace at gmail.com>
>>     Tested-by: Brian Norris <computersforpeace at gmail.com>
>>     Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
>>
>>
>> Reverting that patch on top of next-20180116 fixes the problem.
>>
>> I'm using the arch/arm/boot/dts/at91-nattis-2-natte-2.dts device tree 
>> which for
>> the record is kind of new in the upstream kernel, but I have been using 
>> that dts
>> for a while previously. However, I'd put my money on at91-tse850-3.dts 
>> also
>> being affected, and that one have been upstream for a while. Haven't 
>> tested the
>> tse850 device tree though...
> 
> Peter, above patch was dropped, together with the one adding support for
> the "of_match_table".
> 
> I just sent V8 of my changes, hopefully they don't cause regression this
> time.
> 
> Would you be able to test following two patches & verify that your 
> device
> still works, please?
> [PATCH V8 1/2] mtd: partitions: add of_match_table parser matching
> [PATCH V8 2/2] mtd: ofpart: add of_match_table with "fixed-partitions"
> https://patchwork.ozlabs.org/patch/862075/
> https://patchwork.ozlabs.org/patch/862076/
> 

Ok, so I started with next-20180116, and:

1. verified that it still panicked.
2. reverted
bb2192123ec7 "mtd: partitions: add of_match_table parser matching"
4ac922277847 "mtd: ofpart: add of_match_table with "fixed-partitions""
3. applied the V8-series.
4. verified that the device boots, so cmdline seems to be considered.

Yay!

Tested-by: Peter Rosin <peda at axentia.se>

Cheers,
Peter


From s.hauer at pengutronix.de  Wed Jan 17 02:40:09 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 11:40:09 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180113172551.5dab8a7c@xps13>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-7-s.hauer@pengutronix.de>
 <20180113172551.5dab8a7c@xps13>
Message-ID: <20180117104009.geal4fs6eykqai3a@pengutronix.de>

Hi Miquel,

On Sat, Jan 13, 2018 at 05:25:51PM +0100, Miquel Raynal wrote:
> Hi Sascha,
> 
> On Tue,  9 Jan 2018 11:11:46 +0100
> Sascha Hauer <s.hauer at pengutronix.de> wrote:
> 
> > Now that we have our own read_page function add a write_page function
> > for consistency aswell. This can be a lot easier than the generic
> > function since we do not have to iterate over subpages but can write
> > the whole page at once. Also add write_page_raw and write_oob for
> > proper raw and oob write support.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/mtd/nand/mxc_nand.c | 56
> > +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56
> > insertions(+)
> > 
> > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > index 83bb01ab7079..6fbf98851a96 100644
> > --- a/drivers/mtd/nand/mxc_nand.c
> > +++ b/drivers/mtd/nand/mxc_nand.c
> > @@ -893,6 +893,59 @@ static int mxc_nand_read_oob(struct mtd_info
> > *mtd, struct nand_chip *chip, page);
> >  }
> >  
> > +static int __mxc_nand_write_page(struct mtd_info *mtd, struct
> > nand_chip *chip,
> > +				 const uint8_t *buf, int
> > oob_required, int page) +{
> > +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> > +
> > +	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
> > +	mxc_do_addr_cycle(mtd, 0, page);
> > +
> > +	memcpy32_toio(host->main_area0, buf, mtd->writesize);
> > +	copy_spare(mtd, false, chip->oob_poi);
> 
> If I remember correctly, there was a "spare only" mechanism to avoid
> doing full page read/write when unnecessary. What about using it here
> when (buf == NULL && oob_required)?

You are probably referring to the SP_EN bit in the NAND_FLASH_CONFIG1
register right? This is described as:

> NAND Flash spare enable. This bit determines whether host reads/writes
> are to NAND Flash spare data only or NAND Flash main and spare data.
> This feature is supported only with memories with 1/2K page size.
> Note: There is no ECC in this mode of operation.
> 0 NAND Flash main and spare data is enabled
> 1 NAND Flash spare only data is enabled

At least the i.MX25 has the limitation of 1/2k page size for this
feature. It's not in the i.MX27 manual. I don't know if the i.MX27
documentation is inaccurate or if this limitation is there already.

Anyway, I don't think it's worth optimizing for this case given that
we still need to support a full page write for 2k pages (which should
be much more widespread nowadays than the 512b page size NANDs).

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From weiyongjun1 at huawei.com  Wed Jan 17 03:25:33 2018
From: weiyongjun1 at huawei.com (Wei Yongjun)
Date: Wed, 17 Jan 2018 11:25:33 +0000
Subject: [PATCH -next] mtd: onenand: omap2: Remove redundant dev_err call in
 omap2_onenand_probe()
Message-ID: <1516188333-144550-1-git-send-email-weiyongjun1@huawei.com>

There is a error message within devm_ioremap_resource
already, so remove the dev_err call to avoid redundant
error message.

Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
---
 drivers/mtd/onenand/omap2.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index a4a2159..87c34f6 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -532,10 +532,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	c->phys_base = res->start;
 
 	c->onenand.base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(c->onenand.base)) {
-		dev_err(dev, "Cannot reserve memory region %pR\n", res);
+	if (IS_ERR(c->onenand.base))
 		return PTR_ERR(c->onenand.base);
-	}
 
 	c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN);
 	if (IS_ERR(c->int_gpiod)) {





From s.hauer at pengutronix.de  Wed Jan 17 03:32:08 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:08 +0100
Subject: [PATCH 3/8] mtd: nand: mxc: Add buffer argument to copy_spare
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-4-s.hauer@pengutronix.de>

With following patches we will have to copy the spare data to/from
other buffers, so add the buffer as argument to copy_spare().

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 019c58579dbc..ab9cd45237d3 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -262,14 +262,14 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size)
  * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
  * spare) and the NFC buffer.
  */
-static void copy_spare(struct mtd_info *mtd, bool bfrom)
+static void copy_spare(struct mtd_info *mtd, bool bfrom, void *buf)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
 	struct mxc_nand_host *host = nand_get_controller_data(this);
 	u16 i, oob_chunk_size;
 	u16 num_chunks = mtd->writesize / 512;
 
-	u8 *d = host->data_buf + mtd->writesize;
+	u8 *d = buf;
 	u8 __iomem *s = host->spare0;
 	u16 sparebuf_size = host->devtype_data->spare_len;
 
@@ -1295,7 +1295,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 		memcpy32_fromio(host->data_buf, host->main_area0,
 				mtd->writesize);
-		copy_spare(mtd, true);
+		copy_spare(mtd, true, host->data_buf + mtd->writesize);
 		break;
 
 	case NAND_CMD_SEQIN:
@@ -1314,7 +1314,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 	case NAND_CMD_PAGEPROG:
 		memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
-		copy_spare(mtd, false);
+		copy_spare(mtd, false, host->data_buf + mtd->writesize);
 		host->devtype_data->send_page(mtd, NFC_INPUT);
 		host->devtype_data->send_cmd(host, command, true);
 		WARN_ONCE(column != -1 || page_addr != -1,
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:07 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:07 +0100
Subject: [PATCH 2/8] mtd: nand: mxc: Add function to control hardware ECC
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-3-s.hauer@pengutronix.de>

For proper raw read/write support need to be able to control the
hardware ECC engine. Add a function to enable/disable it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 6741af990dc4..019c58579dbc 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -154,6 +154,7 @@ struct mxc_nand_devtype_data {
 			u_char *read_ecc, u_char *calc_ecc);
 	int (*setup_data_interface)(struct mtd_info *mtd, int csline,
 				    const struct nand_data_interface *conf);
+	void (*enable_hwecc)(struct nand_chip *chip, bool enable);
 
 	/*
 	 * On i.MX21 the CONFIG2:INT bit cannot be read if interrupts are masked
@@ -678,6 +679,42 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
 	return ret;
 }
 
+static void mxc_nand_enable_hwecc_v1_v2(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint16_t config1;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config1 = readw(NFC_V1_V2_CONFIG1);
+
+	if (enable)
+		config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+	else
+		config1 &= ~NFC_V1_V2_CONFIG1_ECC_EN;
+
+	writew(config1, NFC_V1_V2_CONFIG1);
+}
+
+static void mxc_nand_enable_hwecc_v3(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint32_t config2;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config2 = readl(NFC_V3_CONFIG2);
+
+	if (enable)
+		config2 |= NFC_V3_CONFIG2_ECC_EN;
+	else
+		config2 &= ~NFC_V3_CONFIG2_ECC_EN;
+
+	writel(config2, NFC_V3_CONFIG2);
+}
+
 /* This functions is used by upper layer to checks if device is ready */
 static int mxc_nand_dev_ready(struct mtd_info *mtd)
 {
@@ -1408,6 +1445,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 1,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1431,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1456,6 +1495,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.select_chip = mxc_nand_select_chip_v2,
 	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0x1e00,
@@ -1480,6 +1520,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
@@ -1505,6 +1546,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
 	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:11 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:11 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-7-s.hauer@pengutronix.de>

Now that we have our own read_page function add a write_page function
for consistency aswell. This can be a lot easier than the generic
function since we do not have to iterate over subpages but can write
the whole page at once. Also add write_page_raw and write_oob for
proper raw and oob write support.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 47 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 49885afbcf43..2811102b0469 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -890,6 +890,50 @@ static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 					     page);
 }
 
+static int mxc_nand_write_page(struct nand_chip *chip, const uint8_t *buf,
+			       bool ecc, int page)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	host->devtype_data->enable_hwecc(chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	memcpy32_toio(host->main_area0, buf, mtd->writesize);
+	copy_spare(mtd, false, chip->oob_poi);
+
+	host->devtype_data->send_page(mtd, NFC_INPUT);
+	host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	return 0;
+}
+
+static int mxc_nand_write_page_ecc(struct mtd_info *mtd, struct nand_chip *chip,
+				   const uint8_t *buf, int oob_required,
+				   int page)
+{
+	return mxc_nand_write_page(chip, buf, true, page);
+}
+
+static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				   const uint8_t *buf, int oob_required, int page)
+{
+	return mxc_nand_write_page(chip, buf, false, page);
+}
+
+static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	memset(host->data_buf, 0xff, mtd->writesize);
+
+	return mxc_nand_write_page(chip, host->data_buf, false, page);
+}
+
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 				  u_char *ecc_code)
 {
@@ -1904,6 +1948,9 @@ static int mxcnd_probe(struct platform_device *pdev)
 		this->ecc.read_page = mxc_nand_read_page;
 		this->ecc.read_page_raw = mxc_nand_read_page_raw;
 		this->ecc.read_oob = mxc_nand_read_oob;
+		this->ecc.write_page = mxc_nand_write_page_ecc;
+		this->ecc.write_page_raw = mxc_nand_write_page_raw;
+		this->ecc.write_oob = mxc_nand_write_oob;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:12 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:12 +0100
Subject: [PATCH 7/8] mtd: nand: mxc: Drop now unnecessary functions
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-8-s.hauer@pengutronix.de>

Since we have our own read_page/write_page functions correct_data and
calculate are no longer needed. Remove them.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 36 ------------------------------------
 1 file changed, 36 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 2811102b0469..a7c4fdd1988e 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -152,8 +152,6 @@ struct mxc_nand_devtype_data {
 	u32 (*get_ecc_status)(struct mxc_nand_host *);
 	const struct mtd_ooblayout_ops *ooblayout;
 	void (*select_chip)(struct mtd_info *mtd, int chip);
-	int (*correct_data)(struct mtd_info *mtd, u_char *dat,
-			u_char *read_ecc, u_char *calc_ecc);
 	int (*setup_data_interface)(struct mtd_info *mtd, int csline,
 				    const struct nand_data_interface *conf);
 	void (*enable_hwecc)(struct nand_chip *chip, bool enable);
@@ -727,20 +725,6 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd)
 	return 1;
 }
 
-static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	/*
-	 * If HW ECC is enabled, we turn it on during init. There is
-	 * no need to enable again here.
-	 */
-}
-
-static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	return 0;
-}
-
 static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob,
 				 bool ecc, int page)
 {
@@ -799,12 +783,6 @@ static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob,
 	return bitflips_corrected;
 }
 
-static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	return 0;
-}
-
 static int mxc_nand_read_page_v2_v3(struct nand_chip *chip, void *buf,
 				    void *oob, bool ecc, int page)
 {
@@ -934,12 +912,6 @@ static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	return mxc_nand_write_page(chip, host->data_buf, false, page);
 }
 
-static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-				  u_char *ecc_code)
-{
-	return 0;
-}
-
 static u_char mxc_nand_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
@@ -1592,7 +1564,6 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 1,
 	.needs_ip = 0,
@@ -1617,7 +1588,6 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
@@ -1643,7 +1613,6 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v2,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v2,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
 	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
@@ -1670,7 +1639,6 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
@@ -1697,7 +1665,6 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
@@ -1951,9 +1918,6 @@ static int mxcnd_probe(struct platform_device *pdev)
 		this->ecc.write_page = mxc_nand_write_page_ecc;
 		this->ecc.write_page_raw = mxc_nand_write_page_raw;
 		this->ecc.write_oob = mxc_nand_write_oob;
-		this->ecc.calculate = mxc_nand_calculate_ecc;
-		this->ecc.hwctl = mxc_nand_enable_hwecc;
-		this->ecc.correct = host->devtype_data->correct_data;
 		break;
 
 	case NAND_ECC_SOFT:
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:05 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:05 +0100
Subject: [PATCH v2] mxc_nand controller fixes
Message-ID: <20180117113213.15455-1-s.hauer@pengutronix.de>

This series fixes several problems in the mxc_nand driver.

- Raw support does not work since hardware ECC is unconditionally
  enabled
- The v2/v3 controller code returns the number of corrected
  bitflips for the whole page for each subpage leading to
  results for times too high
- The v1 controller code returns the number of corrected bitflips
  only for the last subpage. On 2k page NANDs bitflips in the
  first three subpages remain uncovered

This series fixes these issues. Tested with the mtd test modules
mtd_nandbiterrs, mtd_oobtest, mtd_pagetest and mtd_readtest and the
corresponding userspace tests from mtd-utils on a i.MX27 board which
is a v1 controller and a i.MX25 board which is a v2 controller.

Based on nand/next.

Sascha

Changes since v1:
- drop mtd argument from read_page/write_page functions
- do not add function beginning with two underscores
- simplify bitflips counting for v1 controllers
- Add ecc argument to mxc_nand_write_page()
- drop unused oob_required argument from mxc_nand_write_page()



From s.hauer at pengutronix.de  Wed Jan 17 03:32:06 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:06 +0100
Subject: [PATCH 1/8] mtd: nand: mxc: reorder functions to avoid forward
 declarations
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-2-s.hauer@pengutronix.de>

We'll call copy_spare() and mxc_do_addr_cycle() from another place
during the next patches, so move functions up to avoid forward
declarations.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 206 ++++++++++++++++++++++----------------------
 1 file changed, 103 insertions(+), 103 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index f3be0b2a8869..6741af990dc4 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -252,6 +252,109 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size)
 		__raw_writew(*s++, t++);
 }
 
+/*
+ * The controller splits a page into data chunks of 512 bytes + partial oob.
+ * There are writesize / 512 such chunks, the size of the partial oob parts is
+ * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
+ * contains additionally the byte lost by rounding (if any).
+ * This function handles the needed shuffling between host->data_buf (which
+ * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
+ * spare) and the NFC buffer.
+ */
+static void copy_spare(struct mtd_info *mtd, bool bfrom)
+{
+	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(this);
+	u16 i, oob_chunk_size;
+	u16 num_chunks = mtd->writesize / 512;
+
+	u8 *d = host->data_buf + mtd->writesize;
+	u8 __iomem *s = host->spare0;
+	u16 sparebuf_size = host->devtype_data->spare_len;
+
+	/* size of oob chunk for all but possibly the last one */
+	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
+
+	if (bfrom) {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_fromio(d + i * oob_chunk_size,
+					s + i * sparebuf_size,
+					oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_fromio(d + i * oob_chunk_size,
+				s + i * sparebuf_size,
+				host->used_oobsize - i * oob_chunk_size);
+	} else {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_toio(&s[i * sparebuf_size],
+				      &d[i * oob_chunk_size],
+				      oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_toio(&s[i * sparebuf_size],
+			      &d[i * oob_chunk_size],
+			      host->used_oobsize - i * oob_chunk_size);
+	}
+}
+
+/*
+ * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
+ * the upper layers perform a read/write buf operation, the saved column address
+ * is used to index into the full page. So usually this function is called with
+ * column == 0 (unless no column cycle is needed indicated by column == -1)
+ */
+static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+
+	/* Write out column address, if necessary */
+	if (column != -1) {
+		host->devtype_data->send_addr(host, column & 0xff,
+					      page_addr == -1);
+		if (mtd->writesize > 512)
+			/* another col addr cycle for 2k page */
+			host->devtype_data->send_addr(host,
+						      (column >> 8) & 0xff,
+						      false);
+	}
+
+	/* Write out page address, if necessary */
+	if (page_addr != -1) {
+		/* paddr_0 - p_addr_7 */
+		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
+
+		if (mtd->writesize > 512) {
+			if (mtd->size >= 0x10000000) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		} else {
+			if (nand_chip->options & NAND_ROW_ADDR_3) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		}
+	}
+}
+
 static int check_int_v3(struct mxc_nand_host *host)
 {
 	uint32_t tmp;
@@ -772,109 +875,6 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip)
 	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 }
 
-/*
- * The controller splits a page into data chunks of 512 bytes + partial oob.
- * There are writesize / 512 such chunks, the size of the partial oob parts is
- * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
- * contains additionally the byte lost by rounding (if any).
- * This function handles the needed shuffling between host->data_buf (which
- * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
- * spare) and the NFC buffer.
- */
-static void copy_spare(struct mtd_info *mtd, bool bfrom)
-{
-	struct nand_chip *this = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(this);
-	u16 i, oob_chunk_size;
-	u16 num_chunks = mtd->writesize / 512;
-
-	u8 *d = host->data_buf + mtd->writesize;
-	u8 __iomem *s = host->spare0;
-	u16 sparebuf_size = host->devtype_data->spare_len;
-
-	/* size of oob chunk for all but possibly the last one */
-	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
-
-	if (bfrom) {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_fromio(d + i * oob_chunk_size,
-					s + i * sparebuf_size,
-					oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_fromio(d + i * oob_chunk_size,
-				s + i * sparebuf_size,
-				host->used_oobsize - i * oob_chunk_size);
-	} else {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_toio(&s[i * sparebuf_size],
-				      &d[i * oob_chunk_size],
-				      oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_toio(&s[i * sparebuf_size],
-			      &d[i * oob_chunk_size],
-			      host->used_oobsize - i * oob_chunk_size);
-	}
-}
-
-/*
- * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
- * the upper layers perform a read/write buf operation, the saved column address
- * is used to index into the full page. So usually this function is called with
- * column == 0 (unless no column cycle is needed indicated by column == -1)
- */
-static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
-{
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
-
-	/* Write out column address, if necessary */
-	if (column != -1) {
-		host->devtype_data->send_addr(host, column & 0xff,
-					      page_addr == -1);
-		if (mtd->writesize > 512)
-			/* another col addr cycle for 2k page */
-			host->devtype_data->send_addr(host,
-						      (column >> 8) & 0xff,
-						      false);
-	}
-
-	/* Write out page address, if necessary */
-	if (page_addr != -1) {
-		/* paddr_0 - p_addr_7 */
-		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
-
-		if (mtd->writesize > 512) {
-			if (mtd->size >= 0x10000000) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		} else {
-			if (nand_chip->options & NAND_ROW_ADDR_3) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		}
-	}
-}
-
 #define MXC_V1_ECCBYTES		5
 
 static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:13 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:13 +0100
Subject: [PATCH 8/8] mtd: nand: mxc: remove now unused code
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-9-s.hauer@pengutronix.de>

Since we now have our own read_page/write_page functions
mxc_nand_command() will no longer be called with NAND_CMD_READ0,
NAND_CMD_READOOB, NAND_CMD_SEQIN and NAND_CMD_PAGEPROG. Remove
the code handling these commands.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 51 ---------------------------------------------
 1 file changed, 51 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index a7c4fdd1988e..87b5ee66e501 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1391,57 +1391,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-		if (command == NAND_CMD_READ0)
-			host->buf_start = column;
-		else
-			host->buf_start = column + mtd->writesize;
-
-		command = NAND_CMD_READ0; /* only READ0 is valid */
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < 0,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-
-		if (mtd->writesize > 512)
-			host->devtype_data->send_cmd(host,
-					NAND_CMD_READSTART, true);
-
-		host->devtype_data->send_page(mtd, NFC_OUTPUT);
-
-		memcpy32_fromio(host->data_buf, host->main_area0,
-				mtd->writesize);
-		copy_spare(mtd, true, host->data_buf + mtd->writesize);
-		break;
-
-	case NAND_CMD_SEQIN:
-		if (column >= mtd->writesize)
-			/* call ourself to read a page */
-			mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr);
-
-		host->buf_start = column;
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-		break;
-
-	case NAND_CMD_PAGEPROG:
-		memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
-		copy_spare(mtd, false, host->data_buf + mtd->writesize);
-		host->devtype_data->send_page(mtd, NFC_INPUT);
-		host->devtype_data->send_cmd(host, command, true);
-		WARN_ONCE(column != -1 || page_addr != -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, column, page_addr);
-		break;
-
 	case NAND_CMD_READID:
 		host->devtype_data->send_cmd(host, command, true);
 		mxc_do_addr_cycle(mtd, column, page_addr);
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:10 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:10 +0100
Subject: [PATCH 5/8] mtd: nand: mxc: Fix failed/corrected values for v1
 controllers
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-6-s.hauer@pengutronix.de>

The v1 controller code has several flaws:
- We do not forward the number of corrected bitflips to the upper layers
- For 2k page NAND chips only the status results from the fourth subpage
  read are evaluated, so ECC failures in the other subpages remain
  uncovered
- When there are uncorrectable errors we have to increase the statistics
  counter, but still have to return successfully. Currently we return
  an error

This patch fixes this by introducing a v1 specific read_page function.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 77 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 48804320056f..49885afbcf43 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -738,22 +738,65 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	return 0;
+}
 
-	/*
-	 * 1-Bit errors are automatically corrected in HW.  No need for
-	 * additional correction.  2-Bit errors cannot be corrected by
-	 * HW ECC, so we need to return failure
-	 */
-	uint16_t ecc_status = get_ecc_status_v1(host);
+static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob,
+				 bool ecc, int page)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int bitflips_corrected = 0;
+	int no_subpages;
+	int i;
+
+	host->devtype_data->enable_hwecc(chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true);
+
+	no_subpages = mtd->writesize >> 9;
+
+	for (i = 0; i < no_subpages; i++) {
+		uint16_t ecc_stats;
 
-	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
-		dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n");
-		return -EBADMSG;
+		/* NANDFC buffer 0 is used for page read/write */
+		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
+
+		writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2);
+
+		/* Wait for operation to complete */
+		wait_op_done(host, true);
+
+		ecc_stats = get_ecc_status_v1(host);
+
+		ecc_stats >>= 2;
+
+		if (buf && ecc) {
+			switch (ecc_stats & 0x3) {
+			case 0:
+			default:
+				break;
+			case 1:
+				mtd->ecc_stats.corrected++;
+				bitflips_corrected = 1;
+				break;
+			case 2:
+				mtd->ecc_stats.failed++;
+				break;
+			}
+		}
 	}
 
-	return 0;
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
+	return bitflips_corrected;
 }
 
 static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
@@ -1494,6 +1537,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 /* v1 + irqpending_quirk: i.MX21 */
 static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1518,6 +1562,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 /* v1 + !irqpending_quirk: i.MX27, i.MX31 */
 static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1856,11 +1901,9 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
-		if (host->devtype_data->read_page) {
-			this->ecc.read_page = mxc_nand_read_page;
-			this->ecc.read_page_raw = mxc_nand_read_page_raw;
-			this->ecc.read_oob = mxc_nand_read_oob;
-		}
+		this->ecc.read_page = mxc_nand_read_page;
+		this->ecc.read_page_raw = mxc_nand_read_page_raw;
+		this->ecc.read_oob = mxc_nand_read_oob;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From s.hauer at pengutronix.de  Wed Jan 17 03:32:09 2018
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 17 Jan 2018 12:32:09 +0100
Subject: [PATCH 4/8] mtd: nand: mxc: Fix failed/corrected values for v2/v3
 controllers
In-Reply-To: <20180117113213.15455-1-s.hauer@pengutronix.de>
References: <20180117113213.15455-1-s.hauer@pengutronix.de>
Message-ID: <20180117113213.15455-5-s.hauer@pengutronix.de>

Currently nand_read_page_hwecc() from nand_base calls
mxc_nand_correct_data_v2_v3() for each subpage, but in this function we
return the corrected/failed results for the whole page instead
of a single subpage. On a 2k page size Nand this leads to results which
are 4 times too high.
The whole ecc.calculate/ecc.correct mechanism used by
nand_read_page_hwecc() is not suitable for devices which correct the
data in hardware, so fix this by using a driver specific read_page
function which does the right thing. Also add read_page_raw and read_oob
For proper raw and oob read support.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c | 86 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index ab9cd45237d3..48804320056f 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -140,6 +140,8 @@ struct mxc_nand_host;
 
 struct mxc_nand_devtype_data {
 	void (*preset)(struct mtd_info *);
+	int (*read_page)(struct nand_chip *chip, void *buf, void *oob, bool ecc,
+			 int page);
 	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_page)(struct mtd_info *, unsigned int);
@@ -757,13 +759,35 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	return 0;
+}
+
+static int mxc_nand_read_page_v2_v3(struct nand_chip *chip, void *buf,
+				    void *oob, bool ecc, int page)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int max_bitflips = 0;
 	u32 ecc_stat, err;
-	int no_subpages = 1;
-	int ret = 0;
+	int no_subpages;
 	u8 ecc_bit_mask, err_limit;
 
+	host->devtype_data->enable_hwecc(chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host,
+				NAND_CMD_READSTART, true);
+
+	host->devtype_data->send_page(mtd, NFC_OUTPUT);
+
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
 	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
 	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
 
@@ -774,17 +798,53 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 	do {
 		err = ecc_stat & ecc_bit_mask;
 		if (err > err_limit) {
-			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
-			return -EBADMSG;
+			mtd->ecc_stats.failed++;
 		} else {
-			ret += err;
+			mtd->ecc_stats.corrected += err;
+			max_bitflips = max_t(unsigned int, max_bitflips, err);
 		}
+
 		ecc_stat >>= 4;
 	} while (--no_subpages);
 
-	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
+	return max_bitflips;
+}
 
-	return ret;
+static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(chip, buf, oob_buf, 1, page);
+}
+
+static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				  uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(chip, buf, oob_buf, 0, page);
+}
+
+static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			     int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0,
+					     page);
 }
 
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
@@ -1483,6 +1543,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 /* v21: i.MX25, i.MX35 */
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.preset = preset_v2,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v2,
@@ -1509,6 +1570,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 /* v3.2a: i.MX51 */
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1535,6 +1597,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 /* v3.2b: i.MX53 */
 static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1793,6 +1856,11 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
+		if (host->devtype_data->read_page) {
+			this->ecc.read_page = mxc_nand_read_page;
+			this->ecc.read_page_raw = mxc_nand_read_page_raw;
+			this->ecc.read_oob = mxc_nand_read_oob;
+		}
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0



From lionel.debieve at st.com  Wed Jan 17 04:45:28 2018
From: lionel.debieve at st.com (Lionel DEBIEVE)
Date: Wed, 17 Jan 2018 12:45:28 +0000
Subject: mtd: ubi: Update license header for ubi-media.h file
Message-ID: <d2f6d53e-ab0f-32ae-27f9-09fc029cae6c@st.com>

Hi,

I'm currently working on a first stage bootloader using UBI support for 
NAND boot. My concern is about the ubi-media.h file. This header file 
contains UBI structures described in specification (ie 
http://www.linux-mtd.infradead.org/doc/ubi.html.) and only contains 
structures and some defines, there is no kernel API inside.

To develop UBI driver support for first stage bootloader such as Arm 
Trusted Firmware, it could be possible to use Thomas Gleixner existing 
development made in U-Boot (a lightweight driver for U-Boot SPL) that 
allows**with restricted functionality to boot from UBI. Thomas wrote the 
driver in dual license (GPLv2 and BSD3-Clause) but it includes the 
ubi-media.h file. So, I'm currently blocked because the file ubi-media.h 
is only GPLV2.

I'd like you to check if it could be possible to change license header 
(GPLV2) to dual license as Thomas's driver (GPLv2 and BSD3-Clause) to 
allow UBI?s developer using that common structure file in different 
primary bootloader, helping UBI to be the standard solution for raw NAND 
management at any boot stages.*
*
In that scope, I would also update header to the following SPDX license 
header:

/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/*
 ?* Copyright (C) International Business Machines Corp., 2006
 ?* Authors: Artem Bityutskiy (???????? ?????)
 ?*???? ?????Thomas Gleixner
 ?*????????? Frank Haverkamp
 ?*????????? Oliver Lohmann
 ?*????????? Andreas Arnez
*/

BR,
Lionel/
/

From david at sigma-star.at  Wed Jan 17 07:19:14 2018
From: david at sigma-star.at (David Gstir)
Date: Wed, 17 Jan 2018 16:19:14 +0100
Subject: [RFC] UBIFS authentication
Message-ID: <E6D3BD02-AF3A-4B75-92FD-A8A07B4C9C51@sigma-star.at>

Hi everybody!

Richard and I have been working on extending UBIFS' security features and came
up with the following concept to add full file contents and metadata authentication.

For block devices like eMMCs dm-crypt and dm-verity/dm-integrity can be used to
get full data confidentiality and authenticity, but for raw flash or more
specifically UBIFS, existing options are not ideal:

One option is to use eCryptfs with some out-of-tree patches that add AEAD cipher
(AES-GCM) support, but does not look like there was much progress recently [1].

Another option is to use IMA/EVM as described by Marc Kleine-Budde in his
ELCE 2016 talk [2], but this just protects the file payload and some attributes
and not the full filesystem data structures.

A short overview of existing options is also given here [3].

Due to the design of UBIFS it is actually a bit easier than on other filesystems
to authenticate its data structures and ensure consistency of on-flash data.

I've attached the whitepaper below and also published it here [4].

Comments are welcome. :)

Thanks,
david

[1] https://bugs.launchpad.net/ecryptfs/+bug/1176448
[2] https://elinux.org/images/f/f8/Verified_Boot.pdf
[3] https://www.timesys.com/security/secure-boot-encrypted-data-storage/
[4] https://github.com/sigma-star/ubifs-authentication



---------------

% UBIFS Authentication
% sigma star gmbh
% 2018

# Introduction

UBIFS utilizes the fscrypt framework to provide confidentiality for file
contents and file names. This prevents attacks where an attacker is able to
read contents of the filesystem on a single point in time. A classic example
is a lost smartphone where the attacker is unable to read personal data stored
on the device without the filesystem decryption key.

At the current state, UBIFS encryption however does not prevent attacks where
the attacker is able to modify the filesystem contents and the user uses the
device afterwards. In such a scenario an attacker can modify filesystem
contents arbitrarily without the user noticing. One example is to modify a
binary to perform a malicious action when executed [DMC-CBC-ATTACK]. Since
most of the filesystem metadata of UBIFS is stored in plain, this makes it
fairly easy to swap files and replace their contents.

Other full disk encryption systems like dm-crypt cover all filesystem metadata,
which makes such kinds of attacks more complicated, but not impossible.
Especially, if the attacker is given access to the device multiple points in
time. For dm-crypt and other filesystems that build upon the Linux block IO
layer, the dm-integrity or dm-verity subsystems [DM-INTEGRITY, DM-VERITY] 
can be used to get full data authentication at the block layer.
These can also be combined with dm-crypt [CRYPTSETUP2].

This document describes an approach to get file contents _and_ full metadata
authentication for UBIFS. Since UBIFS uses fscrypt for file contents and file
name encryption, the authentication system could be tied into fscrypt such that
existing features like key derivation can be utilized. It should however also
be possible to use UBIFS authentication without using encryption.


## MTD, UBI & UBIFS

On Linux, the MTD (Memory Technology Devices) subsystem provides a uniform
interface to access raw flash devices. One of the more prominent subsystems that
work on top of MTD is UBI (Unsorted Block Images). It provides volume management
for flash devices and is thus somewhat similar to LVM for block devices. In
addition, it deals with flash-specific wear-leveling and transparent I/O error
handling. UBI offers logical erase blocks (LEBs) to the layers on top of it
and maps them transparently to physical erase blocks (PEBs) on the flash.

UBIFS is a filesystem for raw flash which operates on top of UBI. Thus, wear
leveling and some flash specifics are left to UBI, while UBIFS focuses on
scalability, performance and recoverability.



	+------------+ +*******+ +-----------+ +-----+
	|            | * UBIFS * | UBI-BLOCK | | ... |
	| JFFS/JFFS2 | +*******+ +-----------+ +-----+
	|            | +-----------------------------+ +-----------+ +-----+
	|            | |              UBI            | | MTD-BLOCK | | ... |
	+------------+ +-----------------------------+ +-----------+ +-----+
	+------------------------------------------------------------------+
	|                  MEMORY TECHNOLOGY DEVICES (MTD)                 |
	+------------------------------------------------------------------+
	+-----------------------------+ +--------------------------+ +-----+
	|         NAND DRIVERS        | |        NOR DRIVERS       | | ... |
	+-----------------------------+ +--------------------------+ +-----+

            Figure 1: Linux kernel subsystems for dealing with raw flash



Internally, UBIFS maintains multiple data structures which are persisted on
the flash:

- *Index*: an on-flash B+ tree where the leaf nodes contain filesystem data
- *Journal*: an additional data structure to collect FS changes before updating
  the on-flash index and reduce flash wear.
- *Tree Node Cache (TNC)*: an in-memory B+ tree that reflects the current FS
  state to avoid frequent flash reads. It is basically the in-memory
  representation of the index, but contains additional attributes.
- *LEB property tree (LPT)*: an on-flash B+ tree for free space accounting per
  UBI LEB.

In the remainder of this section we will cover the on-flash UBIFS data
structures in more detail. The TNC is of less importance here since it is never
persisted onto the flash directly. More details on UBIFS can also be found in
[UBIFS-WP].


### UBIFS Index & Tree Node Cache

Basic on-flash UBIFS entities are called *nodes*. UBIFS knows different types
of nodes. Eg. data nodes (`struct ubifs_data_node`) which store chunks of file
contents or inode nodes (`struct ubifs_ino_node`) which represent VFS inodes.
Almost all types of nodes share a common header (`ubifs_ch`) containing basic
information like node type, node length, a sequence number, etc. (see
`fs/ubifs/ubifs-media.h`in kernel source). Exceptions are entries of the LPT
and some less important node types like padding nodes which are used to pad
unusable content at the end of LEBs.

To avoid re-writing the whole B+ tree on every single change, it is implemented
as *wandering tree*, where only the changed nodes are re-written and previous
versions of them are obsoleted without erasing them right away. As a result,
the index is not stored in a single place on the flash, but *wanders* around
and there are obsolete parts on the flash as long as the LEB containing them is
not reused by UBIFS. To find the most recent version of the index, UBIFS stores
a special node called *master node* into UBI LEB 1 which always points to the
most recent root node of the UBIFS index. For recoverability, the master node
is additionally duplicated to LEB 2. Mounting UBIFS is thus a simple read of
LEB 1 and 2 to get the current master node and from there get the location of
the most recent on-flash index.

The TNC is the in-memory representation of the on-flash index. It contains some
additional runtime attributes per node which are not persisted. One of these is
a dirty-flag which marks nodes that have to be persisted the next time the
index is written onto the flash. The TNC acts as a write-back cache and all
modifications of the on-flash index are done through the TNC. Like other caches,
the TNC does not have to mirror the full index into memory, but reads parts of
it from flash whenever needed. A *commit* is the UBIFS operation of updating the
on-flash filesystem structures like the index. On every commit, the TNC nodes
marked as dirty are written to the flash to update the persisted index.


### Journal

To avoid wearing out the flash, the index is only persisted (*commited*) when
certain conditions are met (eg. `fsync(2)`). The journal is used to record
any changes (in form of inode nodes, data nodes etc.) between commits
of the index. During mount, the journal is read from the flash and replayed
onto the TNC (which will be created on-demand from the on-flash index).

UBIFS reserves a bunch of LEBs just for the journal called *log area*. The
amount of log area LEBs is configured on filesystem creation (using
`mkfs.ubifs`) and stored in the superblock node. The log area contains only
two types of nodes: *reference nodes* and *commit start nodes*. A commit start
node is written whenever an index commit is performed. Reference nodes are
written on every journal update. Each reference node points to the position of
other nodes (inode nodes, data nodes etc.) on the flash that are part of this
journal entry. These nodes are called *buds* and describe the actual filesystem
changes including their data.

The log area is maintained as a ring. Whenever the journal is almost full,
a commit is initiated. This also writes a commit start node so that during
mount, UBIFS will seek for the most recent commit start node and just replay
every reference node after that. Every reference node before the commit start
node will be ignored as they are already part of the on-flash index.

When writing a journal entry, UBIFS first ensures that enough space is
available to write the reference node and buds part of this entry. Then, the
reference node is written and afterwards the buds describing the file changes.
On replay, UBIFS will record every reference node and inspect the location of
the referenced LEBs to discover the buds. If these are corrupt or missing,
UBIFS will attempt to recover them by re-reading the LEB. This is however only
done for the last referenced LEB of the journal. Only this can become corrupt
because of a power cut. If the recovery fails, UBIFS will not mount. An error
for every other LEB will directly cause UBIFS to fail the mount operation.


       | ----    LOG AREA     ---- | ----------    MAIN AREA    ------------ |

        -----+------+-----+--------+----   ------+-----+-----+---------------
        \    |      |     |        |   /  /      |     |     |               \
        / CS |  REF | REF |        |   \  \ DENT | INO | INO |               /
        \    |      |     |        |   /  /      |     |     |               \
         ----+------+-----+--------+---   -------+-----+-----+----------------
                 |     |                  ^            ^
                 |     |                  |            |
                 +------------------------+            |
                       |                               |
                       +-------------------------------+


                Figure 2: UBIFS flash layout of log area with commit start nodes
                          (CS) and reference nodes (REF) pointing to main area
                          containing their buds


### LEB Property Tree/Table

The LEB property tree is used to store per-LEB information. This includes the
LEB type and amount of free and *dirty* (old, obsolete content) space [1] on
the LEB. The type is important, because UBIFS never mixes index nodes with data
nodes on a single LEB and thus each LEB has a specific purpose. This again is
useful for free space calculations. See [UBIFS-WP] for more details.

The LEB property tree again is a B+ tree, but it is much smaller than the
index. Due to its smaller size it is always written as one chunk on every
commit. Thus, saving the LPT is an atomic operation.


[1] Since LEBs can only be appended and never overwritten, there is a
difference between free space ie. the remaining space left on the LEB to be
written to without erasing it and previously written content that is obsolete
but can't be overwritten without erasing the full LEB.


# UBIFS Authentication

This chapter introduces UBIFS authentication which enables UBIFS to verify
the authenticity and integrity of metadata and file contents stored on flash.


## Threat Model

UBIFS authentication enables detection of offline data modification. While it
does not prevent it, it enables (trusted) code to check the integrity and
authenticity of on-flash file contents and filesystem metadata. This covers
attacks where file contents are swapped.

UBIFS authentication will not protect against rollback of full flash contents.
Ie. an attacker can still dump the flash and restore it at a later time without
detection. It will also not protect against partial rollback of individual
index commits. That means that an attacker is able to partially undo changes.
This is possible because UBIFS does not immediately overwrites obsolete
versions of the index tree or the journal, but instead marks them as obsolete
and garbage collection erases them at a later time. An attacker can use this by
erasing parts of the current tree and restoring old versions that are still on
the flash and have not yet been erased. This is possible, because every commit
will always write a new version of the index root node and the master node
without overwriting the previous version. This is further helped by the
wear-leveling operations of UBI which copies contents from one physical
eraseblock to another and does not atomically erase the first eraseblock.

UBIFS authentication does not cover attacks where an attacker is able to
execute code on the device after the authentication key was provided.
Additional measures like secure boot and trusted boot have to be taken to
ensure that only trusted code is executed on a device.


## Authentication

To be able to fully trust data read from flash, all UBIFS data structures
stored on flash are authenticated. That is:

- The index which includes file contents, file metadata like extended
  attributes, file length etc.
- The journal which also contains file contents and metadata by recording changes
  to the filesystem
- The LPT which stores UBI LEB metadata which UBIFS uses for free space accounting


### Index Authentication

Through UBIFS' concept of a wandering tree, it already takes care of only
updating and persisting changed parts from leaf node up to the root node
of the full B+ tree. This enables us to augment the index nodes of the tree
with a hash over each node's child nodes. As a result, the index basically also
a Merkle tree. Since the leaf nodes of the index contain the actual filesystem
data, the hashes of their parent index nodes thus cover all the file contents
and file metadata. When a file changes, the UBIFS index is updated accordingly
from the leaf nodes up to the root node including the master node. This process
can be hooked to recompute the hash only for each changed node at the same time.
Whenever a file is read, UBIFS can verify the hashes from each leaf node up to
the root node to ensure the node's integrity.

To ensure the authenticity of the whole index, the UBIFS master node stores a
keyed hash (HMAC) over its own contents (which includes the location of the root
node) and the root node of the index tree. As mentioned above, the master node
is always written to the flash whenever the index is persisted (ie. on index
commit).

Using this approach only UBIFS index nodes and the master node are changed to
include a hash. All other types of nodes will remain unchanged. This reduces
the storage overhead which is precious for users of UBIFS (ie. embedded
devices).


                                            HMAC Master Node
                                                 |
                      ' ' ' ' ' ' ' ' ' ' ' ' ' '|' '
                      '     +---------------+    o  '
                      '     |  Master Node  |       '
                      '     +---------------+       '       Hash Index Node #1
                      '             |               '                |
       . . . . . . . .'. . . . . .  v . . . . . . . . . . . . . . . .|. . . . .
       .              '      +---------------+      '                o        .
       .              '      | Index Node #1 |      '                         .
       .              '      +---------------+      '                         .
       .              '        |    ...   |  (fanout: 8)                      .
       .              ' ' ' '  | ' ' ' '  | ' ' ' ' '                         .
       .               +-------+          +------+                            .
       .               |                         |                            .
       .     ' ' ' ' ' v ' ' ' ' '  ' ' ' ' ' '  v  ' ' ' ' ' ' ' ' ' ' '     .
       .     ' +---------------+ '  '     +---------------+             '     .
       .     ' | Index Node #2 | '  '     | Index Node #3 |             '     .
       .     ' +---------------+ '  '     +---------------+             '     .
       .     '   |   ...         '  '        |   ...   |                '     .
       . . . ' . v . . . . . . . '. ' . . .  v . . . . v . . . . . . . .' . . .
             ' +-----------+     '  '+----------+  +-----------+        '
             ' | Data Node |     '  '| INO Node |  | DENT Node |        '
             ' +-----------+     '  '+----------+  +-----------+        '
             '  o                '  '                                o  '
             ' '|' ' ' ' ' ' ' ' '  ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '|' '
                |                                                    |
          Hash Index Node #2                                Hash Index Node #3


           Figure 3: Coverage areas of index node hash and master node HMAC



The most important part for robustness and power-cut safety is to atomically
persist the hash and file contents. Here the existing UBIFS logic for how
changed nodes are persisted is already designed for this purpose such that
UBIFS can safely recover if a power-cut occurs while persisting. Adding
hashes to index nodes does not change this since each hash will be persisted
atomically together with its respective node.


### Journal Authentication

The journal is authenticated too. Here, a HMAC is added to every commit start
and reference node which covers the full node itself and the contents of the
referenced buds describing the actual filesystem changes. During mount, the
journal is replayed and every HMAC is verified.

Reference nodes and their buds are not written atomically. This means, that
UBIFS can encounter reference nodes where one or more of the buds were not
written in full and thus the HMAC is invalid. Since this can also happen
without the HMAC due to power cuts, UBIFS already has the required checks in
place to deal with that and will ultimately fail. Errors during reading commit
start nodes or reference nodes are treated similarly.

Since the HMAC of each reference and commit start node does not cover any
previously written nodes of the log area, an attacker can potentially reorder,
remove or insert nodes to change the filesystem contents after replay. This is
however already avoided by UBIFS' use of a sequence number contained within
each node. UBIFS maintains a global 64-bit counter that is never allowed to
overflow. This counter is incremented for every node written to flash and is
part of the node's common header. Overflow of this counter is theoretically
possible, but since the lifetime of a flash will by then be long over, UBIFS
simply falls permanently back to read-only mode whenever the counter is about
to overflow. For UBIFS authentication, this means that simply comparing the
sequence number counter of consecutive nodes in the log area suffices to
detect such attacks.

The location of the log area is stored in the master node. Since the master
node is authenticated with a HMAC as described above, it is not possible to
tamper with that without detection. The size of the log area is specified when
the filesystem is created using `mkfs.ubifs` and stored in the superblock node.
To avoid tampering with this and other values stored there, a HMAC is added to
the superblock struct. The superblock node is stored in LEB 0 and is only
modified on feature flag or similar changes, but never on file changes.


### LPT Authentication

The location of the LPT root node on the flash is stored in the UBIFS master
node. Since the LPT is written and read atomically on every commit, there is
no need to authenticate individual nodes of the tree. It suffices to
protect the integrity of the full LPT by a simple hash stored in the master
node. Since the master node itself is authenticated, the LPTs authenticity can
be verified by verifying the authenticity of the master node and comparing the
LTP hash stored there with the hash computed from the read on-flash LPT.


## Key Management

For simplicity, UBIFS authentication uses a single key to compute the HMACs
of superblock, master, commit start and reference nodes. This key has to be
available on creation of the filesystem (`mkfs.ubifs`) to authenticate the
superblock node. Further, it has to be available on mount of the filesystem
to verify authenticated nodes and generate new HMACs for changes.

UBIFS authentication is intended to operate side-by-side with UBIFS encryption
(fscrypt) to provide confidentiality and authenticity. Since UBIFS encryption
has a different approach of encryption policies per directory, there can be
multiple fscrypt master keys and there might be folders without encryption.
UBIFS authentication on the other hand has an all-or-nothing approach in the
sense that it either authenticates everything of the filesystem or nothing.
Because of this and because UBIFS authentication should also be usable without
encryption, it does not share the same master key with fscrypt, but manages
a dedicated authentication key.

The API for providing the authentication key has yet to be defined, but the
key can eg. be provided by userspace through a keyring similar to the way it
is currently done in fscrypt. It should however be noted that the current
fscrypt approach has shown its flaws and the userspace API will eventually
change [FSCRYPT-POLICY2].

Nevertheless, it will be possible for a user to provide a single passphrase
or key in userspace that covers UBIFS authentication and encryption. This can
be solved by the corresponding userspace tools which derive a second key for
authentication in addition to the derived fscrypt master key used for
encryption.

To be able to check if the proper key is available on mount, the UBIFS
superblock node will additionally store a hash of the authentication key. This
approach is similar to the approach proposed for fscrypt encryption policy v2
[FSCRYPT-POLICY2].


# Future Extensions

In certain cases where a vendor wants to provide an authenticated filesystem
image to customers, it should be possible to do so without sharing the secret
UBIFS authentication key. Instead, in addition the each HMAC a digital
signature could be stored where the vendor shares the public key alongside the
filesystem image. In case this filesystem has to be modified afterwards,
UBIFS can exchange all digital signatures with HMACs on first mount similar
to the way the IMA/EVM subsystem deals with such situations. The HMAC key
will then have to be provided beforehand in the normal way.


# References

[CRYPTSETUP2]        http://www.saout.de/pipermail/dm-crypt/2017-November/005745.html

[DMC-CBC-ATTACK]     http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/

[DM-INTEGRITY]       https://www.kernel.org/doc/Documentation/device-mapper/dm-integrity.txt

[DM-VERITY]          https://www.kernel.org/doc/Documentation/device-mapper/verity.txt

[FSCRYPT-POLICY2]    https://www.spinics.net/lists/linux-ext4/msg58710.html

[UBIFS-WP]           http://www.linux-mtd.infradead.org/doc/ubifs_whitepaper.pdf



From richard at sigma-star.at  Wed Jan 17 07:47:15 2018
From: richard at sigma-star.at (Richard Weinberger)
Date: Wed, 17 Jan 2018 16:47:15 +0100
Subject: [PATCH] ubi: Fix filesystem corruption on detach when fastmap
 enabled
In-Reply-To: <CABatt_y_6D+unmRT_L3nScxN=RnPuAxSiykSwPkwNp6298OakQ@mail.gmail.com>
References: <CABatt_wEa+jiSmutzZrjyRFXqypPTbfdo_Z8CVDhuuRMUXjA6w@mail.gmail.com>
 <8925017.tvIN1CM1GY@blindfold>
 <CABatt_y_6D+unmRT_L3nScxN=RnPuAxSiykSwPkwNp6298OakQ@mail.gmail.com>
Message-ID: <1612877.xbAM7MeHb7@blindfold>

Martin,

Am Dienstag, 16. Januar 2018, 15:13:04 CET schrieb Martin Townsend:
> > Martin, can you please explain what corruption you see?
> > From reading the code I'd assume that you miss volumes but a full scan
> > would recover everything.
> 
> I didn't do much analysis of the corruption I'm afraid.  When I tried
> to reattach the the c->empty flag was set to true and indeed all the
> EBA tables were reporting an empty filesystem even after a reboot.

Sounds like what I'd expect.

> Not sure if this was recoverable, how do you trigger a full scan?

Booting a kernel without Fastmap support. B-)

> > For Linux I suggest this fix:
> > 
> > From 48287459cf8717cffac5aed423937cd7ba4360ab Mon Sep 17 00:00:00 2001
> > From: Richard Weinberger <richard at nod.at>
> > Date: Tue, 16 Jan 2018 14:12:46 +0100
> > Subject: [PATCH] ubi: fastmap: Don't flush fastmap work on detach
> > 
> > At this point UBI volumes have already been free()'ed and fastmap can no
> > longer access these data structures.
> > 
> > Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL
> > sub- system")
> > Signed-off-by: Richard Weinberger <richard at nod.at>
> > Cc: stable at vger.kernel.org
> > ---
> > 
> >  drivers/mtd/ubi/fastmap-wl.c | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
> > index 4f0bd6b4422a..69dd21679a30 100644
> > --- a/drivers/mtd/ubi/fastmap-wl.c
> > +++ b/drivers/mtd/ubi/fastmap-wl.c
> > @@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
> > 
> >  {
> >  
> >         int i;
> > 
> > -       flush_work(&ubi->fm_work);
> > 
> >         return_unused_pool_pebs(ubi, &ubi->fm_pool);
> >         return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
> > 
> > --
> > 2.13.6
> > 
> > In U-Boot you can do the same.
>
> Richard: This will work but just want to check that ubi_wl_close is
> supposed to never write out to the filesystem or will never do so in
> future, if so maybe a something in the comments above ubi_wl_close to
> ensure this?

Hmm, not sure if I got this question.
The filesystem sits above UBI. If we reach ubi_wl_close() all users ontop of 
UBI are gone. There is no UBIFS mounted anymore.

Thanks,
//richard

-- 
sigma star gmbh - Eduard-Bodem-Gasse 6 - 6020 Innsbruck - Austria
ATU66964118 - FN 374287y


From fabio.estevam at nxp.com  Wed Jan 17 09:50:48 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Wed, 17 Jan 2018 15:50:48 -0200
Subject: [PATCH v5 2/2] dt-bindings: fsl-quadspi: Add the example of two SPI
 NOR
In-Reply-To: <1516211448-27594-1-git-send-email-fabio.estevam@nxp.com>
References: <1516211448-27594-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <1516211448-27594-2-git-send-email-fabio.estevam@nxp.com>

Improve the bindings example by adding an example of how to represent
two SPI NOR devices.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v4:
- Newly introduced

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..483e9cf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,27 @@ qspi0: quadspi at 40044000 {
 		....
 	};
 };
+
+Example showing the usage of two SPI NOR devices:
+
+&qspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi2>;
+	status = "okay";
+
+	flash0: n25q256a at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+
+	flash1: n25q256a at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <1>;
+	};
+};
-- 
2.7.4



From fabio.estevam at nxp.com  Wed Jan 17 09:50:47 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Wed, 17 Jan 2018 15:50:47 -0200
Subject: [PATCH v5 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1516211448-27594-1-git-send-email-fabio.estevam@nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

In order to keep mtdparts compatibility keep the mtd->name
unchanged when a single SPI NOR is present.

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v4:
- Only use the new name scheme when more than one SPI NOR is present (Boris)

 drivers/mtd/spi-nor/fsl-quadspi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..1038842 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		if (q->nor_num > 1) {
+			int spiflash_idx;
+
+			ret = of_property_read_u32(np, "reg", &spiflash_idx);
+			if (!ret) {
+				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+							   "%s-%d",
+							   dev_name(dev),
+							   spiflash_idx);
+				if (!mtd->name) {
+					ret = -ENOMEM;
+					goto mutex_failed;
+				}
+			} else {
+				dev_warn(dev, "reg property is missing\n");
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From richard at nod.at  Wed Jan 17 10:12:42 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 17 Jan 2018 19:12:42 +0100
Subject: [PATCH] ubifs: Check ubifs_wbuf_sync() return code
Message-ID: <20180117181242.26572-1-richard@nod.at>

If ubifs_wbuf_sync() fails we must not write a master node with the
dirty marker cleared.
Otherwise it is possible that in case of an IO error while syncing we
mark the filesystem as clean and UBIFS refuses to recover upon next
mount.

Cc: <stable at vger.kernel.org>
Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
Signed-off-by: Richard Weinberger <richard at nod.at>
---
 fs/ubifs/super.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 0beb285b143d..468bca452d0a 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1739,8 +1739,11 @@ static void ubifs_remount_ro(struct ubifs_info *c)
 
 	dbg_save_space_info(c);
 
-	for (i = 0; i < c->jhead_cnt; i++)
-		ubifs_wbuf_sync(&c->jheads[i].wbuf);
+	for (i = 0; i < c->jhead_cnt; i++) {
+		err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+		if (err)
+			ubifs_ro_mode(c, err);
+	}
 
 	c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
 	c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
@@ -1806,8 +1809,11 @@ static void ubifs_put_super(struct super_block *sb)
 			int err;
 
 			/* Synchronize write-buffers */
-			for (i = 0; i < c->jhead_cnt; i++)
-				ubifs_wbuf_sync(&c->jheads[i].wbuf);
+			for (i = 0; i < c->jhead_cnt; i++) {
+				err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+				if (err)
+					ubifs_ro_mode(c, err);
+			}
 
 			/*
 			 * We are being cleanly unmounted which means the
-- 
2.13.6



From bradleybolen at gmail.com  Wed Jan 17 11:46:51 2018
From: bradleybolen at gmail.com (Bradley Bolen)
Date: Wed, 17 Jan 2018 14:46:51 -0500
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
 <20180114153915.4c6141a4@bbrezillon>
 <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>
Message-ID: <5aaad0f3-2d7d-2c1f-3ad1-6049a5a0c088@gmail.com>



On 01/14/2018 05:20 PM, Ezequiel Garcia wrote:
> On 14 January 2018 at 11:39, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
>> +Ezequiel
>>
>> Hi Bradley,
>>
>> On Tue,  2 Jan 2018 21:26:09 -0500
>> Bradley Bolen <bradleybolen at gmail.com> wrote:
>>
>>> This fixes a race condition where running ubiblock on multiple volumes
>>> simultaneously produces the following splat.
>>>
>>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
>>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
>>> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
>>> (sysfs_create_group+0x20/0x24)
>>> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
>>> (blk_trace_init_sysfs+0x18/0x20)
>>> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
>>> (blk_register_queue+0x6c/0x154)
>>> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
>>> (device_add_disk+0x2c8/0x450)
>>> [<c02cd610>] (device_add_disk) from [<c0430fac>]
>>> (ubiblock_create+0x254/0x2e4)
>>> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
>>> (vol_cdev_ioctl+0x3e0/0x564)
>>> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
>>> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
>>> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
>>> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)
>>>
> 
> I'm a little confused, how does this stack trace relates to idr?
> 
I apologize.  The commit message was a little terse.  Here is the full
output of the issue I ran into.

------------[ cut here ]------------
block ubiblock0_3: created from ubi0:3(Partition3)
block ubiblock0_2: created from ubi0:2(Partition2)
block ubiblock0_4: created from ubi0:4(Partition4)
WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31 sysfs_warn_dup+0x68/0x88
sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'
Modules linked in: 
CPU: 1 PID: 179 Comm: ubiblock Tainted: P           O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
[<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
[<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
[<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
[<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
[<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>] (sysfs_warn_dup+0x68/0x88)
[<c01e2028>] (sysfs_warn_dup) from [<c01e2120>] (sysfs_create_dir_ns+0x84/0x94)
[<c01e2120>] (sysfs_create_dir_ns) from [<c02e44cc>] (kobject_add_internal+0x130/0x2f8)
[<c02e44cc>] (kobject_add_internal) from [<c02e4730>] (kobject_add+0x9c/0xb8)
[<c02e4730>] (kobject_add) from [<c03b2744>] (device_add+0xfc/0x56c)
[<c03b2744>] (device_add) from [<c03b2d38>] (device_create_groups_vargs+0x90/0xd0)
[<c03b2d38>] (device_create_groups_vargs) from [<c03b2dac>] (device_create_vargs+0x34/0x3c)
[<c03b2dac>] (device_create_vargs) from [<c01301e4>] (bdi_register+0x70/0x1cc)
[<c01301e4>] (bdi_register) from [<c01308f8>] (bdi_register_owner+0x3c/0x7c)
[<c01308f8>] (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
[<c02cec04>] (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
[<c0436ec8>] (ubiblock_create) from [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554)
[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
---[ end trace e541910253daa337 ]---
------------[ cut here ]------------
WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240 kobject_add_internal+0x1ec/0x2f8
kobject_add_internal failed for 252:2 with -EEXIST, don't try to register things with the same name in the same direc
tory.
Modules linked in: 
CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
[<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
[<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
[<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
[<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
[<c002aee0>] (warn_slowpath_fmt) from [<c02e4588>] (kobject_add_internal+0x1ec/0x2f8)
[<c02e4588>] (kobject_add_internal) from [<c02e4730>] (kobject_add+0x9c/0xb8)
[<c02e4730>] (kobject_add) from [<c03b2744>] (device_add+0xfc/0x56c)
[<c03b2744>] (device_add) from [<c03b2d38>] (device_create_groups_vargs+0x90/0xd0)
[<c03b2d38>] (device_create_groups_vargs) from [<c03b2dac>] (device_create_vargs+0x34/0x3c)
[<c03b2dac>] (device_create_vargs) from [<c01301e4>] (bdi_register+0x70/0x1cc)
[<c01301e4>] (bdi_register) from [<c01308f8>] (bdi_register_owner+0x3c/0x7c)
[<c01308f8>] (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
[<c02cec04>] (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
[<c0436ec8>] (ubiblock_create) from [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554)
[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
---[ end trace e541910253daa338 ]---
------------[ cut here ]------------
WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31 sysfs_warn_dup+0x68/0x88
sysfs: cannot create duplicate filename '/dev/block/252:2'
Modules linked in: 
CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
[<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
[<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
[<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
[<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
[<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>] (sysfs_warn_dup+0x68/0x88)
[<c01e2028>] (sysfs_warn_dup) from [<c01e23c8>] (sysfs_do_create_link_sd+0xa0/0xbc)
[<c01e23c8>] (sysfs_do_create_link_sd) from [<c01e2418>] (sysfs_create_link+0x34/0x44)
[<c01e2418>] (sysfs_create_link) from [<c03b2a74>] (device_add+0x42c/0x56c)
[<c03b2a74>] (device_add) from [<c02cec50>] (device_add_disk+0x160/0x44c)
[<c02cec50>] (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
[<c0436ec8>] (ubiblock_create) from [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554)
[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
---[ end trace e541910253daa339 ]---
ubiblock (179): undefined instruction: pc=c01e26cc
CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
task: c185d780 task.stack: d053a000
PC is at internal_create_group+0x3c/0x2a0
LR is at sysfs_create_group+0x20/0x24
pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
sp : d053bd38  ip : d053bd70  fp : d053bd6c
r10: c095fddc  r9 : 00000000  r8 : c1b59c00
r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5383d  Table: 104b6840  DAC: ffab73de
Code: e89da8f0 e1a0c00d e92ddff0 e24cb004 e24dd00c e52de004 e8bd4000 e2507000 e1a09001 e1a05002 0a000004 e3510000 e59
74018 1a000002 e3540000 1a000002 (e7f001f2) e3540000 0a00000f e595300c e5951000 e3530000 1a00000d e5953010 e3530000 1
a00000a e59f2220 e3510000 e5973000 e59f0218 01a01002 e59f2214 
------------[ cut here ]------------
kernel BUG at kernel-source/fs/sysfs/group.c:113!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
-----------[ user debug ]-----------
Current process: ubiblock   pid=179
Running on CPU1 (2 online)

current=c185d780   preempt_count=0x0
CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
task: c185d780 task.stack: d053a000
PC is at 0x4b767d8c
LR is at 0x10b78
pc : [<4b767d8c>]    lr : [<00010b78>]    psr: 60000010
sp : be73fc34  ip : 4b767d80  fp : 00000000
r10: 00000003  r9 : be73fdb4  r8 : 00000000
r7 : 00000036  r6 : 00000003  r5 : 000250a8  r4 : ffffffff
r3 : 00000001  r2 : 22eea600  r1 : 40804f07  r0 : 00000003
Flags: nZCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
Control: 30c5383d  Table: 104b6840  DAC: ffab73de

Memory Maps:
00010-
00015
 ubiblock

00024-
00026
 ubiblock

00026-
00047

4b660-
4b67f
 ld-2

4b68e-
4b690
 ld-2

4b6a0-
4b7da
 libc-2

4b7da-
4b7dc

b6bad-
b6baf

be71f-
be740

beb84-
---------[ end user debug ]---------
Modules linked in: 
CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O    4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1
Hardware name: (Device Tree)
task: c185d780 task.stack: d053a000
PC is at internal_create_group+0x3c/0x2a0
LR is at sysfs_create_group+0x20/0x24
pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
sp : d053bd38  ip : d053bd70  fp : d053bd6c
r10: c095fddc  r9 : 00000000  r8 : c1b59c00
r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5383d  Table: 104b6840  DAC: ffab73de
Process ubiblock (pid: 179, stack limit = 0xd053a210)
Stack: (0xd053bd38 to 0xd053c000)
bd20:                                                       d053bd5c d053bd48
bd40: c00731c8 d0bd9e00 c1b59800 c090f488 c1b59868 c1b59c00 c1b5980c c095fddc
bd60: d053bd7c d053bd70 c01e2950 c01e269c d053bd8c d053bd80 c00e3d38 c01e293c
bd80: d053bdbc d053bd90 c02bdfbc c00e3d2c 00040b0c c1b59800 c1b59868 c090f488
bda0: c1b59870 c1b59c00 c1b5980c c095fddc d053be14 d053bdc0 c02cec84 c02bdef0
bdc0: c02ce6cc c1b59800 d053bdfc d053bdd8 0fc00002 c0053478 00000000 1f518000
bde0: d053be1c 00040b0c 00000000 c1b11e40 00000000 c1b59800 c095fda4 d053be60
be00: c1b11e8c c095fddc d053be54 d053be18 c0436ec8 c02ceafc 00000000 c1b5980c
be20: c01e06f0 c1b5980c 00000000 22eea600 d04b6100 d0b7cc00 d1c20000 c090f488
be40: d053a000 c090f488 d053bedc d053be58 c0427bb8 c0436c50 00000001 00000000
be60: 00000000 0000000f 00000017 00000003 002c9000 00000000 00000001 00000003
be80: 00000000 00000000 00000001 0001f000 00000006 d0b7ce5c 0f700010 c005368c
bea0: 9a877d41 00000007 c1aab015 c0755170 00000261 00040b0c d053beec 22eea600
bec0: d0b96228 c1896300 00000003 22eea600 d053beec d053bee0 c0189110 c0427774
bee0: d053bf7c d053bef0 c01892e0 c01890ec d053bf34 c0185224 c01954e8 c05e9a14
bf00: c0185278 c1aab000 c090f488 c1896300 d0b96228 c1aab000 c1896308 00000020
bf20: d053bf44 d053bf30 c0185224 c0163200 00000003 c090f488 d053bf94 d053bf48
bf40: c0175504 c01851c4 00000000 00040b0c 00000002 00000003 c1896300 c1896300
bf60: 40804f07 22eea600 d053a000 00000000 d053bfa4 d053bf80 c0189a14 c018924c
bf80: ffffffff 000250a8 00000003 00000036 c00107e4 d053a000 00000000 d053bfa8
bfa0: c0010640 c01899dc ffffffff 000250a8 00000003 40804f07 22eea600 00000001
bfc0: ffffffff 000250a8 00000003 00000036 00000000 be73fdb4 00000003 00000000
bfe0: 4b767d80 be73fc34 00010b78 4b767d8c 60000010 00000003 e675ff3a 2a3139dd
[<c01e26cc>] (internal_create_group) from [<c01e2950>] (sysfs_create_group+0x20/0x24)
[<c01e2950>] (sysfs_create_group) from [<c00e3d38>] (blk_trace_init_sysfs+0x18/0x20)
[<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>] (blk_register_queue+0xd8/0x154)
[<c02bdfbc>] (blk_register_queue) from [<c02cec84>] (device_add_disk+0x194/0x44c)
[<c02cec84>] (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
[<c0436ec8>] (ubiblock_create) from [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554)
[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
Code: e89da8f0 e1a0c00d e92ddff0 e24cb004 e24dd00c e52de004 e8bd4000 e2507000 e1a09001 e1a05002 0a000004 e3510000 e59
74018 1a000002 e3540000 1a000002 (e7f001f2) e3540000 0a00000f e595300c e5951000 e3530000 1a00000d e5953010 e3530000 1
a00000a e59f2220 e3510000 e5973000 e59f0218 01a01002 e59f2214 
---[ end trace e541910253daa33a ]---

I was able to reproduce the problem with the following script with the
underlying volumes already created:

while true; do
    for part in 2 3 4 15 24 90 91; do
        ubiblock -c /dev/ubi0_$part &
    done
    sleep 2

    for part in 2 3 4 15 24 90 91; do
        ubiblock -r /dev/ubi0_$part &
    done
    sleep 2
done

There is a race with idr_alloc where gd->first_minor could be set to the
same value for two different calls to ubiblock_create.  Each instance
calls device_add_disk with the same first_minor.  device_add_disk calls
bdi_register_owner.  The bdi_register_owner call path produces the
initial WARNINGS about registering the same device.  However,
device_add_disk does not error out when bdi_register_owner returns an
error.  The control continues until it reaches blk_register_queue which
eventually BUGs.
>>
>> Missing Fixes and Cc-stable tags.
>>
>>> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
>>
>>
>> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
>>
>> BTW, just had a quick look at the code, and I think the locking can be
>> simplified a bit by keeping the devices_lock for the whole
>> ubiblock_create() operation instead of acquiring/releasing it several
>> times in the function (see [1]). It makes sense to do fine grained
>> locking when operations protected by the lock are time sensitive, but I
>> don't think this is the case here.
>>
> 
> Agreed. Something like this perhaps http://ix.io/E8G ?
> Notice that ubiblock_remove_all seemed to require locking as well.
> 
I tried out Ezequiel's patch and it fixes this issue as well.  Note,
that ret needs to be defined in ubiblock_remove.


From ezequiel at vanguardiasur.com.ar  Wed Jan 17 12:06:29 2018
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 17 Jan 2018 17:06:29 -0300
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <2145261.UlTadXsT1L@blindfold>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
 <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>
 <5aaad0f3-2d7d-2c1f-3ad1-6049a5a0c088@gmail.com>
 <2145261.UlTadXsT1L@blindfold>
Message-ID: <CAAEAJfBK-m4jJDuZeqKa_sVwYP_x1EtFDfSW_c5dAod2iMWWWA@mail.gmail.com>

On 17 January 2018 at 17:04, Richard Weinberger <richard at nod.at> wrote:
> Am Mittwoch, 17. Januar 2018, 20:46:51 CET schrieb Bradley Bolen:
>> On 01/14/2018 05:20 PM, Ezequiel Garcia wrote:
>> > On 14 January 2018 at 11:39, Boris Brezillon
>> >
>> > <boris.brezillon at free-electrons.com> wrote:
>> >> +Ezequiel
>> >>
>> >> Hi Bradley,
>> >>
>> >> On Tue,  2 Jan 2018 21:26:09 -0500
>> >>
>> >> Bradley Bolen <bradleybolen at gmail.com> wrote:
>> >>> This fixes a race condition where running ubiblock on multiple volumes
>> >>> simultaneously produces the following splat.
>> >>>
>> >>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
>> >>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
>> >>> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
>> >>> (sysfs_create_group+0x20/0x24)
>> >>> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
>> >>> (blk_trace_init_sysfs+0x18/0x20)
>> >>> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
>> >>> (blk_register_queue+0x6c/0x154)
>> >>> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
>> >>> (device_add_disk+0x2c8/0x450)
>> >>> [<c02cd610>] (device_add_disk) from [<c0430fac>]
>> >>> (ubiblock_create+0x254/0x2e4)
>> >>> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
>> >>> (vol_cdev_ioctl+0x3e0/0x564)
>> >>> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
>> >>> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
>> >>> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
>> >>> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)
>> >
>> > I'm a little confused, how does this stack trace relates to idr?
>>
>> I apologize.  The commit message was a little terse.  Here is the full
>> output of the issue I ran into.
>>
>> ------------[ cut here ]------------
>> block ubiblock0_3: created from ubi0:3(Partition3)
>> block ubiblock0_2: created from ubi0:2(Partition2)
>> block ubiblock0_4: created from ubi0:4(Partition4)
>> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
>> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
>> '/devices/virtual/bdi/252:2' Modules linked in:
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P           O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
>> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
>> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
>> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
>> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
>> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e2120>]
>> (sysfs_create_dir_ns+0x84/0x94) [<c01e2120>] (sysfs_create_dir_ns) from
>> [<c02e44cc>] (kobject_add_internal+0x130/0x2f8) [<c02e44cc>]
>> (kobject_add_internal) from [<c02e4730>] (kobject_add+0x9c/0xb8)
>> [<c02e4730>] (kobject_add) from [<c03b2744>] (device_add+0xfc/0x56c)
>> [<c03b2744>] (device_add) from [<c03b2d38>]
>> (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
>> (device_create_groups_vargs) from [<c03b2dac>]
>> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
>> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
>> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
>> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
>> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
>> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
>> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
>> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
>> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
>> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
>> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa337
>> ]---
>> ------------[ cut here ]------------
>> WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
>> kobject_add_internal+0x1ec/0x2f8 kobject_add_internal failed for 252:2 with
>> -EEXIST, don't try to register things with the same name in the same direc
>> tory.
>> Modules linked in:
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
>> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
>> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
>> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
>> [<c002aee0>] (warn_slowpath_fmt) from [<c02e4588>]
>> (kobject_add_internal+0x1ec/0x2f8) [<c02e4588>] (kobject_add_internal) from
>> [<c02e4730>] (kobject_add+0x9c/0xb8) [<c02e4730>] (kobject_add) from
>> [<c03b2744>] (device_add+0xfc/0x56c) [<c03b2744>] (device_add) from
>> [<c03b2d38>] (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
>> (device_create_groups_vargs) from [<c03b2dac>]
>> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
>> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
>> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
>> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
>> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
>> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
>> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
>> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
>> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
>> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
>> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa338
>> ]---
>> ------------[ cut here ]------------
>> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
>> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
>> '/dev/block/252:2'
>> Modules linked in:
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
>> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
>> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
>> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
>> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
>> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e23c8>]
>> (sysfs_do_create_link_sd+0xa0/0xbc) [<c01e23c8>] (sysfs_do_create_link_sd)
>> from [<c01e2418>] (sysfs_create_link+0x34/0x44) [<c01e2418>]
>> (sysfs_create_link) from [<c03b2a74>] (device_add+0x42c/0x56c) [<c03b2a74>]
>> (device_add) from [<c02cec50>] (device_add_disk+0x160/0x44c) [<c02cec50>]
>> (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
>> [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
>> (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl) from
>> [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
>> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
>> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
>> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa339
>> ]---
>> ubiblock (179): undefined instruction: pc=c01e26cc
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> task: c185d780 task.stack: d053a000
>> PC is at internal_create_group+0x3c/0x2a0
>> LR is at sysfs_create_group+0x20/0x24
>> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
>> sp : d053bd38  ip : d053bd70  fp : d053bd6c
>> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
>> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
>> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
>> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
>> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
>> Code: e89da8f0 e1a0c00d e92ddff0 e24cb004 e24dd00c e52de004 e8bd4000
>> e2507000 e1a09001 e1a05002 0a000004 e3510000 e59 74018 1a000002 e3540000
>> 1a000002 (e7f001f2) e3540000 0a00000f e595300c e5951000 e3530000 1a00000d
>> e5953010 e3530000 1 a00000a e59f2220 e3510000 e5973000 e59f0218 01a01002
>> e59f2214
>> ------------[ cut here ]------------
>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
>> -----------[ user debug ]-----------
>> Current process: ubiblock   pid=179
>> Running on CPU1 (2 online)
>>
>> current=c185d780   preempt_count=0x0
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> task: c185d780 task.stack: d053a000
>> PC is at 0x4b767d8c
>> LR is at 0x10b78
>> pc : [<4b767d8c>]    lr : [<00010b78>]    psr: 60000010
>> sp : be73fc34  ip : 4b767d80  fp : 00000000
>> r10: 00000003  r9 : be73fdb4  r8 : 00000000
>> r7 : 00000036  r6 : 00000003  r5 : 000250a8  r4 : ffffffff
>> r3 : 00000001  r2 : 22eea600  r1 : 40804f07  r0 : 00000003
>> Flags: nZCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
>> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
>>
>> Memory Maps:
>> 00010-
>> 00015
>>  ubiblock
>>
>> 00024-
>> 00026
>>  ubiblock
>>
>> 00026-
>> 00047
>>
>> 4b660-
>> 4b67f
>>  ld-2
>>
>> 4b68e-
>> 4b690
>>  ld-2
>>
>> 4b6a0-
>> 4b7da
>>  libc-2
>>
>> 4b7da-
>> 4b7dc
>>
>> b6bad-
>> b6baf
>>
>> be71f-
>> be740
>>
>> beb84-
>> ---------[ end user debug ]---------
>> Modules linked in:
>> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
>> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
>> (Device Tree)
>> task: c185d780 task.stack: d053a000
>> PC is at internal_create_group+0x3c/0x2a0
>> LR is at sysfs_create_group+0x20/0x24
>> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
>> sp : d053bd38  ip : d053bd70  fp : d053bd6c
>> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
>> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
>> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
>> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
>> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
>> Process ubiblock (pid: 179, stack limit = 0xd053a210)
>> Stack: (0xd053bd38 to 0xd053c000)
>> bd20:                                                       d053bd5c
>> d053bd48 bd40: c00731c8 d0bd9e00 c1b59800 c090f488 c1b59868 c1b59c00
>> c1b5980c c095fddc bd60: d053bd7c d053bd70 c01e2950 c01e269c d053bd8c
>> d053bd80 c00e3d38 c01e293c bd80: d053bdbc d053bd90 c02bdfbc c00e3d2c
>> 00040b0c c1b59800 c1b59868 c090f488 bda0: c1b59870 c1b59c00 c1b5980c
>> c095fddc d053be14 d053bdc0 c02cec84 c02bdef0 bdc0: c02ce6cc c1b59800
>> d053bdfc d053bdd8 0fc00002 c0053478 00000000 1f518000 bde0: d053be1c
>> 00040b0c 00000000 c1b11e40 00000000 c1b59800 c095fda4 d053be60 be00:
>> c1b11e8c c095fddc d053be54 d053be18 c0436ec8 c02ceafc 00000000 c1b5980c
>> be20: c01e06f0 c1b5980c 00000000 22eea600 d04b6100 d0b7cc00 d1c20000
>> c090f488 be40: d053a000 c090f488 d053bedc d053be58 c0427bb8 c0436c50
>> 00000001 00000000 be60: 00000000 0000000f 00000017 00000003 002c9000
>> 00000000 00000001 00000003 be80: 00000000 00000000 00000001 0001f000
>> 00000006 d0b7ce5c 0f700010 c005368c bea0: 9a877d41 00000007 c1aab015
>> c0755170 00000261 00040b0c d053beec 22eea600 bec0: d0b96228 c1896300
>> 00000003 22eea600 d053beec d053bee0 c0189110 c0427774 bee0: d053bf7c
>> d053bef0 c01892e0 c01890ec d053bf34 c0185224 c01954e8 c05e9a14 bf00:
>> c0185278 c1aab000 c090f488 c1896300 d0b96228 c1aab000 c1896308 00000020
>> bf20: d053bf44 d053bf30 c0185224 c0163200 00000003 c090f488 d053bf94
>> d053bf48 bf40: c0175504 c01851c4 00000000 00040b0c 00000002 00000003
>> c1896300 c1896300 bf60: 40804f07 22eea600 d053a000 00000000 d053bfa4
>> d053bf80 c0189a14 c018924c bf80: ffffffff 000250a8 00000003 00000036
>> c00107e4 d053a000 00000000 d053bfa8 bfa0: c0010640 c01899dc ffffffff
>> 000250a8 00000003 40804f07 22eea600 00000001 bfc0: ffffffff 000250a8
>> 00000003 00000036 00000000 be73fdb4 00000003 00000000 bfe0: 4b767d80
>> be73fc34 00010b78 4b767d8c 60000010 00000003 e675ff3a 2a3139dd [<c01e26cc>]
>> (internal_create_group) from [<c01e2950>] (sysfs_create_group+0x20/0x24)
>> [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
>> (blk_trace_init_sysfs+0x18/0x20) [<c00e3d38>] (blk_trace_init_sysfs) from
>> [<c02bdfbc>] (blk_register_queue+0xd8/0x154) [<c02bdfbc>]
>> (blk_register_queue) from [<c02cec84>] (device_add_disk+0x194/0x44c)
>> [<c02cec84>] (device_add_disk) from [<c0436ec8>]
>> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
>> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
>> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
>> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
>> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
>> [<c0010640>] (ret_fast_syscall+0x0/0x34) Code: e89da8f0 e1a0c00d e92ddff0
>> e24cb004 e24dd00c e52de004 e8bd4000 e2507000 e1a09001 e1a05002 0a000004
>> e3510000 e59 74018 1a000002 e3540000 1a000002 (e7f001f2) e3540000 0a00000f
>> e595300c e5951000 e3530000 1a00000d e5953010 e3530000 1 a00000a e59f2220
>> e3510000 e5973000 e59f0218 01a01002 e59f2214
>> ---[ end trace e541910253daa33a ]---
>>
>> I was able to reproduce the problem with the following script with the
>> underlying volumes already created:
>>
>> while true; do
>>     for part in 2 3 4 15 24 90 91; do
>>         ubiblock -c /dev/ubi0_$part &
>>     done
>>     sleep 2
>>
>>     for part in 2 3 4 15 24 90 91; do
>>         ubiblock -r /dev/ubi0_$part &
>>     done
>>     sleep 2
>> done
>>
>> There is a race with idr_alloc where gd->first_minor could be set to the
>> same value for two different calls to ubiblock_create.  Each instance
>> calls device_add_disk with the same first_minor.  device_add_disk calls
>> bdi_register_owner.  The bdi_register_owner call path produces the
>> initial WARNINGS about registering the same device.  However,
>> device_add_disk does not error out when bdi_register_owner returns an
>> error.  The control continues until it reaches blk_register_queue which
>> eventually BUGs.
>>
>> >> Missing Fixes and Cc-stable tags.
>> >>
>> >>> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
>> >>
>> >> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
>> >>
>> >> BTW, just had a quick look at the code, and I think the locking can be
>> >> simplified a bit by keeping the devices_lock for the whole
>> >> ubiblock_create() operation instead of acquiring/releasing it several
>> >> times in the function (see [1]). It makes sense to do fine grained
>> >> locking when operations protected by the lock are time sensitive, but I
>> >> don't think this is the case here.
>> >
>> > Agreed. Something like this perhaps http://ix.io/E8G ?
>> > Notice that ubiblock_remove_all seemed to require locking as well.
>>
>> I tried out Ezequiel's patch and it fixes this issue as well.  Note,
>> that ret needs to be defined in ubiblock_remove.
>
> Can you please have a proper patch such that I can take it? :-)
>

Bradley,

Feel free to submit a patch based on the (untested) diff I sent.
While there, you can improve the commit log with the details
you sent.
-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From boris.brezillon at free-electrons.com  Wed Jan 17 12:10:18 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 17 Jan 2018 21:10:18 +0100
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <CAAEAJfBK-m4jJDuZeqKa_sVwYP_x1EtFDfSW_c5dAod2iMWWWA@mail.gmail.com>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
 <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>
 <5aaad0f3-2d7d-2c1f-3ad1-6049a5a0c088@gmail.com>
 <2145261.UlTadXsT1L@blindfold>
 <CAAEAJfBK-m4jJDuZeqKa_sVwYP_x1EtFDfSW_c5dAod2iMWWWA@mail.gmail.com>
Message-ID: <20180117211018.4327c9d4@bbrezillon>

On Wed, 17 Jan 2018 17:06:29 -0300
Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:

> On 17 January 2018 at 17:04, Richard Weinberger <richard at nod.at> wrote:
> > Am Mittwoch, 17. Januar 2018, 20:46:51 CET schrieb Bradley Bolen:  
> >> On 01/14/2018 05:20 PM, Ezequiel Garcia wrote:  
> >> > On 14 January 2018 at 11:39, Boris Brezillon
> >> >
> >> > <boris.brezillon at free-electrons.com> wrote:  
> >> >> +Ezequiel
> >> >>
> >> >> Hi Bradley,
> >> >>
> >> >> On Tue,  2 Jan 2018 21:26:09 -0500
> >> >>
> >> >> Bradley Bolen <bradleybolen at gmail.com> wrote:  
> >> >>> This fixes a race condition where running ubiblock on multiple volumes
> >> >>> simultaneously produces the following splat.
> >> >>>
> >> >>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> >> >>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> >> >>> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
> >> >>> (sysfs_create_group+0x20/0x24)
> >> >>> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
> >> >>> (blk_trace_init_sysfs+0x18/0x20)
> >> >>> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
> >> >>> (blk_register_queue+0x6c/0x154)
> >> >>> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
> >> >>> (device_add_disk+0x2c8/0x450)
> >> >>> [<c02cd610>] (device_add_disk) from [<c0430fac>]
> >> >>> (ubiblock_create+0x254/0x2e4)
> >> >>> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
> >> >>> (vol_cdev_ioctl+0x3e0/0x564)
> >> >>> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
> >> >>> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
> >> >>> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
> >> >>> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)  
> >> >
> >> > I'm a little confused, how does this stack trace relates to idr?  
> >>
> >> I apologize.  The commit message was a little terse.  Here is the full
> >> output of the issue I ran into.
> >>
> >> ------------[ cut here ]------------
> >> block ubiblock0_3: created from ubi0:3(Partition3)
> >> block ubiblock0_2: created from ubi0:2(Partition2)
> >> block ubiblock0_4: created from ubi0:4(Partition4)
> >> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> >> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
> >> '/devices/virtual/bdi/252:2' Modules linked in:
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P           O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> >> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> >> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> >> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> >> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
> >> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e2120>]
> >> (sysfs_create_dir_ns+0x84/0x94) [<c01e2120>] (sysfs_create_dir_ns) from
> >> [<c02e44cc>] (kobject_add_internal+0x130/0x2f8) [<c02e44cc>]
> >> (kobject_add_internal) from [<c02e4730>] (kobject_add+0x9c/0xb8)
> >> [<c02e4730>] (kobject_add) from [<c03b2744>] (device_add+0xfc/0x56c)
> >> [<c03b2744>] (device_add) from [<c03b2d38>]
> >> (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
> >> (device_create_groups_vargs) from [<c03b2dac>]
> >> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
> >> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
> >> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
> >> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
> >> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
> >> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> >> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> >> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> >> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> >> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> >> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa337
> >> ]---
> >> ------------[ cut here ]------------
> >> WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
> >> kobject_add_internal+0x1ec/0x2f8 kobject_add_internal failed for 252:2 with
> >> -EEXIST, don't try to register things with the same name in the same direc
> >> tory.
> >> Modules linked in:
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> >> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> >> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> >> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> >> [<c002aee0>] (warn_slowpath_fmt) from [<c02e4588>]
> >> (kobject_add_internal+0x1ec/0x2f8) [<c02e4588>] (kobject_add_internal) from
> >> [<c02e4730>] (kobject_add+0x9c/0xb8) [<c02e4730>] (kobject_add) from
> >> [<c03b2744>] (device_add+0xfc/0x56c) [<c03b2744>] (device_add) from
> >> [<c03b2d38>] (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
> >> (device_create_groups_vargs) from [<c03b2dac>]
> >> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
> >> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
> >> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
> >> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
> >> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
> >> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> >> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> >> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> >> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> >> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> >> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa338
> >> ]---
> >> ------------[ cut here ]------------
> >> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> >> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
> >> '/dev/block/252:2'
> >> Modules linked in:
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> >> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> >> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> >> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> >> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
> >> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e23c8>]
> >> (sysfs_do_create_link_sd+0xa0/0xbc) [<c01e23c8>] (sysfs_do_create_link_sd)
> >> from [<c01e2418>] (sysfs_create_link+0x34/0x44) [<c01e2418>]
> >> (sysfs_create_link) from [<c03b2a74>] (device_add+0x42c/0x56c) [<c03b2a74>]
> >> (device_add) from [<c02cec50>] (device_add_disk+0x160/0x44c) [<c02cec50>]
> >> (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
> >> [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
> >> (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl) from
> >> [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> >> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> >> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> >> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa339
> >> ]---
> >> ubiblock (179): undefined instruction: pc=c01e26cc
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> task: c185d780 task.stack: d053a000
> >> PC is at internal_create_group+0x3c/0x2a0
> >> LR is at sysfs_create_group+0x20/0x24
> >> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
> >> sp : d053bd38  ip : d053bd70  fp : d053bd6c
> >> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
> >> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
> >> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
> >> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> >> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> >> Code: e89da8f0 e1a0c00d e92ddff0 e24cb004 e24dd00c e52de004 e8bd4000
> >> e2507000 e1a09001 e1a05002 0a000004 e3510000 e59 74018 1a000002 e3540000
> >> 1a000002 (e7f001f2) e3540000 0a00000f e595300c e5951000 e3530000 1a00000d
> >> e5953010 e3530000 1 a00000a e59f2220 e3510000 e5973000 e59f0218 01a01002
> >> e59f2214
> >> ------------[ cut here ]------------
> >> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> >> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> >> -----------[ user debug ]-----------
> >> Current process: ubiblock   pid=179
> >> Running on CPU1 (2 online)
> >>
> >> current=c185d780   preempt_count=0x0
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> task: c185d780 task.stack: d053a000
> >> PC is at 0x4b767d8c
> >> LR is at 0x10b78
> >> pc : [<4b767d8c>]    lr : [<00010b78>]    psr: 60000010
> >> sp : be73fc34  ip : 4b767d80  fp : 00000000
> >> r10: 00000003  r9 : be73fdb4  r8 : 00000000
> >> r7 : 00000036  r6 : 00000003  r5 : 000250a8  r4 : ffffffff
> >> r3 : 00000001  r2 : 22eea600  r1 : 40804f07  r0 : 00000003
> >> Flags: nZCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
> >> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> >>
> >> Memory Maps:
> >> 00010-
> >> 00015
> >>  ubiblock
> >>
> >> 00024-
> >> 00026
> >>  ubiblock
> >>
> >> 00026-
> >> 00047
> >>
> >> 4b660-
> >> 4b67f
> >>  ld-2
> >>
> >> 4b68e-
> >> 4b690
> >>  ld-2
> >>
> >> 4b6a0-
> >> 4b7da
> >>  libc-2
> >>
> >> 4b7da-
> >> 4b7dc
> >>
> >> b6bad-
> >> b6baf
> >>
> >> be71f-
> >> be740
> >>
> >> beb84-
> >> ---------[ end user debug ]---------
> >> Modules linked in:
> >> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O
> >> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> >> (Device Tree)
> >> task: c185d780 task.stack: d053a000
> >> PC is at internal_create_group+0x3c/0x2a0
> >> LR is at sysfs_create_group+0x20/0x24
> >> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
> >> sp : d053bd38  ip : d053bd70  fp : d053bd6c
> >> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
> >> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
> >> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
> >> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> >> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> >> Process ubiblock (pid: 179, stack limit = 0xd053a210)
> >> Stack: (0xd053bd38 to 0xd053c000)
> >> bd20:                                                       d053bd5c
> >> d053bd48 bd40: c00731c8 d0bd9e00 c1b59800 c090f488 c1b59868 c1b59c00
> >> c1b5980c c095fddc bd60: d053bd7c d053bd70 c01e2950 c01e269c d053bd8c
> >> d053bd80 c00e3d38 c01e293c bd80: d053bdbc d053bd90 c02bdfbc c00e3d2c
> >> 00040b0c c1b59800 c1b59868 c090f488 bda0: c1b59870 c1b59c00 c1b5980c
> >> c095fddc d053be14 d053bdc0 c02cec84 c02bdef0 bdc0: c02ce6cc c1b59800
> >> d053bdfc d053bdd8 0fc00002 c0053478 00000000 1f518000 bde0: d053be1c
> >> 00040b0c 00000000 c1b11e40 00000000 c1b59800 c095fda4 d053be60 be00:
> >> c1b11e8c c095fddc d053be54 d053be18 c0436ec8 c02ceafc 00000000 c1b5980c
> >> be20: c01e06f0 c1b5980c 00000000 22eea600 d04b6100 d0b7cc00 d1c20000
> >> c090f488 be40: d053a000 c090f488 d053bedc d053be58 c0427bb8 c0436c50
> >> 00000001 00000000 be60: 00000000 0000000f 00000017 00000003 002c9000
> >> 00000000 00000001 00000003 be80: 00000000 00000000 00000001 0001f000
> >> 00000006 d0b7ce5c 0f700010 c005368c bea0: 9a877d41 00000007 c1aab015
> >> c0755170 00000261 00040b0c d053beec 22eea600 bec0: d0b96228 c1896300
> >> 00000003 22eea600 d053beec d053bee0 c0189110 c0427774 bee0: d053bf7c
> >> d053bef0 c01892e0 c01890ec d053bf34 c0185224 c01954e8 c05e9a14 bf00:
> >> c0185278 c1aab000 c090f488 c1896300 d0b96228 c1aab000 c1896308 00000020
> >> bf20: d053bf44 d053bf30 c0185224 c0163200 00000003 c090f488 d053bf94
> >> d053bf48 bf40: c0175504 c01851c4 00000000 00040b0c 00000002 00000003
> >> c1896300 c1896300 bf60: 40804f07 22eea600 d053a000 00000000 d053bfa4
> >> d053bf80 c0189a14 c018924c bf80: ffffffff 000250a8 00000003 00000036
> >> c00107e4 d053a000 00000000 d053bfa8 bfa0: c0010640 c01899dc ffffffff
> >> 000250a8 00000003 40804f07 22eea600 00000001 bfc0: ffffffff 000250a8
> >> 00000003 00000036 00000000 be73fdb4 00000003 00000000 bfe0: 4b767d80
> >> be73fc34 00010b78 4b767d8c 60000010 00000003 e675ff3a 2a3139dd [<c01e26cc>]
> >> (internal_create_group) from [<c01e2950>] (sysfs_create_group+0x20/0x24)
> >> [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
> >> (blk_trace_init_sysfs+0x18/0x20) [<c00e3d38>] (blk_trace_init_sysfs) from
> >> [<c02bdfbc>] (blk_register_queue+0xd8/0x154) [<c02bdfbc>]
> >> (blk_register_queue) from [<c02cec84>] (device_add_disk+0x194/0x44c)
> >> [<c02cec84>] (device_add_disk) from [<c0436ec8>]
> >> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> >> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> >> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> >> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> >> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> >> [<c0010640>] (ret_fast_syscall+0x0/0x34) Code: e89da8f0 e1a0c00d e92ddff0
> >> e24cb004 e24dd00c e52de004 e8bd4000 e2507000 e1a09001 e1a05002 0a000004
> >> e3510000 e59 74018 1a000002 e3540000 1a000002 (e7f001f2) e3540000 0a00000f
> >> e595300c e5951000 e3530000 1a00000d e5953010 e3530000 1 a00000a e59f2220
> >> e3510000 e5973000 e59f0218 01a01002 e59f2214
> >> ---[ end trace e541910253daa33a ]---
> >>
> >> I was able to reproduce the problem with the following script with the
> >> underlying volumes already created:
> >>
> >> while true; do
> >>     for part in 2 3 4 15 24 90 91; do
> >>         ubiblock -c /dev/ubi0_$part &
> >>     done
> >>     sleep 2
> >>
> >>     for part in 2 3 4 15 24 90 91; do
> >>         ubiblock -r /dev/ubi0_$part &
> >>     done
> >>     sleep 2
> >> done
> >>
> >> There is a race with idr_alloc where gd->first_minor could be set to the
> >> same value for two different calls to ubiblock_create.  Each instance
> >> calls device_add_disk with the same first_minor.  device_add_disk calls
> >> bdi_register_owner.  The bdi_register_owner call path produces the
> >> initial WARNINGS about registering the same device.  However,
> >> device_add_disk does not error out when bdi_register_owner returns an
> >> error.  The control continues until it reaches blk_register_queue which
> >> eventually BUGs.
> >>  
> >> >> Missing Fixes and Cc-stable tags.
> >> >>  
> >> >>> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>  
> >> >>
> >> >> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> >> >>
> >> >> BTW, just had a quick look at the code, and I think the locking can be
> >> >> simplified a bit by keeping the devices_lock for the whole
> >> >> ubiblock_create() operation instead of acquiring/releasing it several
> >> >> times in the function (see [1]). It makes sense to do fine grained
> >> >> locking when operations protected by the lock are time sensitive, but I
> >> >> don't think this is the case here.  
> >> >
> >> > Agreed. Something like this perhaps http://ix.io/E8G ?
> >> > Notice that ubiblock_remove_all seemed to require locking as well.  
> >>
> >> I tried out Ezequiel's patch and it fixes this issue as well.  Note,
> >> that ret needs to be defined in ubiblock_remove.  
> >
> > Can you please have a proper patch such that I can take it? :-)
> >  
> 
> Bradley,
> 
> Feel free to submit a patch based on the (untested) diff I sent.
> While there, you can improve the commit log with the details
> you sent.

Can we fix the locking in ubiblock_remove_all() as well?


From richard at nod.at  Wed Jan 17 12:04:24 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 17 Jan 2018 21:04:24 +0100
Subject: [PATCH] UBI: block: Must use a mutex when using
 idr_alloc/idr_remove
In-Reply-To: <5aaad0f3-2d7d-2c1f-3ad1-6049a5a0c088@gmail.com>
References: <1514946369-3674-1-git-send-email-bradleybolen@gmail.com>
 <CAAEAJfDB59gnAJf+m7gPRhT-oknJ=bOEYdEvv=5snLW9G1yNqQ@mail.gmail.com>
 <5aaad0f3-2d7d-2c1f-3ad1-6049a5a0c088@gmail.com>
Message-ID: <2145261.UlTadXsT1L@blindfold>

Am Mittwoch, 17. Januar 2018, 20:46:51 CET schrieb Bradley Bolen:
> On 01/14/2018 05:20 PM, Ezequiel Garcia wrote:
> > On 14 January 2018 at 11:39, Boris Brezillon
> > 
> > <boris.brezillon at free-electrons.com> wrote:
> >> +Ezequiel
> >> 
> >> Hi Bradley,
> >> 
> >> On Tue,  2 Jan 2018 21:26:09 -0500
> >> 
> >> Bradley Bolen <bradleybolen at gmail.com> wrote:
> >>> This fixes a race condition where running ubiblock on multiple volumes
> >>> simultaneously produces the following splat.
> >>> 
> >>> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> >>> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> >>> [<c01e4160>] (internal_create_group) from [<c01e43fc>]
> >>> (sysfs_create_group+0x20/0x24)
> >>> [<c01e43fc>] (sysfs_create_group) from [<c00e4800>]
> >>> (blk_trace_init_sysfs+0x18/0x20)
> >>> [<c00e4800>] (blk_trace_init_sysfs) from [<c02bc734>]
> >>> (blk_register_queue+0x6c/0x154)
> >>> [<c02bc734>] (blk_register_queue) from [<c02cd610>]
> >>> (device_add_disk+0x2c8/0x450)
> >>> [<c02cd610>] (device_add_disk) from [<c0430fac>]
> >>> (ubiblock_create+0x254/0x2e4)
> >>> [<c0430fac>] (ubiblock_create) from [<c0421a3c>]
> >>> (vol_cdev_ioctl+0x3e0/0x564)
> >>> [<c0421a3c>] (vol_cdev_ioctl) from [<c018a55c>] (vfs_ioctl+0x30/0x44)
> >>> [<c018a55c>] (vfs_ioctl) from [<c018ad2c>] (do_vfs_ioctl+0x694/0x798)
> >>> [<c018ad2c>] (do_vfs_ioctl) from [<c018ae74>] (SyS_ioctl+0x44/0x6c)
> >>> [<c018ae74>] (SyS_ioctl) from [<c0010720>] (ret_fast_syscall+0x0/0x34)
> > 
> > I'm a little confused, how does this stack trace relates to idr?
> 
> I apologize.  The commit message was a little terse.  Here is the full
> output of the issue I ran into.
> 
> ------------[ cut here ]------------
> block ubiblock0_3: created from ubi0:3(Partition3)
> block ubiblock0_2: created from ubi0:2(Partition2)
> block ubiblock0_4: created from ubi0:4(Partition4)
> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
> '/devices/virtual/bdi/252:2' Modules linked in:
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P           O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e2120>]
> (sysfs_create_dir_ns+0x84/0x94) [<c01e2120>] (sysfs_create_dir_ns) from
> [<c02e44cc>] (kobject_add_internal+0x130/0x2f8) [<c02e44cc>]
> (kobject_add_internal) from [<c02e4730>] (kobject_add+0x9c/0xb8)
> [<c02e4730>] (kobject_add) from [<c03b2744>] (device_add+0xfc/0x56c)
> [<c03b2744>] (device_add) from [<c03b2d38>]
> (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
> (device_create_groups_vargs) from [<c03b2dac>]
> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa337
> ]---
> ------------[ cut here ]------------
> WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
> kobject_add_internal+0x1ec/0x2f8 kobject_add_internal failed for 252:2 with
> -EEXIST, don't try to register things with the same name in the same direc
> tory.
> Modules linked in:
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> [<c002aee0>] (warn_slowpath_fmt) from [<c02e4588>]
> (kobject_add_internal+0x1ec/0x2f8) [<c02e4588>] (kobject_add_internal) from
> [<c02e4730>] (kobject_add+0x9c/0xb8) [<c02e4730>] (kobject_add) from
> [<c03b2744>] (device_add+0xfc/0x56c) [<c03b2744>] (device_add) from
> [<c03b2d38>] (device_create_groups_vargs+0x90/0xd0) [<c03b2d38>]
> (device_create_groups_vargs) from [<c03b2dac>]
> (device_create_vargs+0x34/0x3c) [<c03b2dac>] (device_create_vargs) from
> [<c01301e4>] (bdi_register+0x70/0x1cc) [<c01301e4>] (bdi_register) from
> [<c01308f8>] (bdi_register_owner+0x3c/0x7c) [<c01308f8>]
> (bdi_register_owner) from [<c02cec04>] (device_add_disk+0x114/0x44c)
> [<c02cec04>] (device_add_disk) from [<c0436ec8>]
> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa338
> ]---
> ------------[ cut here ]------------
> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> sysfs_warn_dup+0x68/0x88 sysfs: cannot create duplicate filename
> '/dev/block/252:2'
> Modules linked in:
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> [<c0019e50>] (unwind_backtrace) from [<c0014b20>] (show_stack+0x20/0x24)
> [<c0014b20>] (show_stack) from [<c02e2618>] (dump_stack+0x78/0x94)
> [<c02e2618>] (dump_stack) from [<c002ae6c>] (__warn+0xf0/0x110)
> [<c002ae6c>] (__warn) from [<c002aee0>] (warn_slowpath_fmt+0x54/0x74)
> [<c002aee0>] (warn_slowpath_fmt) from [<c01e2028>]
> (sysfs_warn_dup+0x68/0x88) [<c01e2028>] (sysfs_warn_dup) from [<c01e23c8>]
> (sysfs_do_create_link_sd+0xa0/0xbc) [<c01e23c8>] (sysfs_do_create_link_sd)
> from [<c01e2418>] (sysfs_create_link+0x34/0x44) [<c01e2418>]
> (sysfs_create_link) from [<c03b2a74>] (device_add+0x42c/0x56c) [<c03b2a74>]
> (device_add) from [<c02cec50>] (device_add_disk+0x160/0x44c) [<c02cec50>]
> (device_add_disk) from [<c0436ec8>] (ubiblock_create+0x284/0x2e0)
> [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
> (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl) from
> [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> [<c0010640>] (ret_fast_syscall+0x0/0x34) ---[ end trace e541910253daa339
> ]---
> ubiblock (179): undefined instruction: pc=c01e26cc
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> task: c185d780 task.stack: d053a000
> PC is at internal_create_group+0x3c/0x2a0
> LR is at sysfs_create_group+0x20/0x24
> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
> sp : d053bd38  ip : d053bd70  fp : d053bd6c
> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> Code: e89da8f0 e1a0c00d e92ddff0 e24cb004 e24dd00c e52de004 e8bd4000
> e2507000 e1a09001 e1a05002 0a000004 e3510000 e59 74018 1a000002 e3540000
> 1a000002 (e7f001f2) e3540000 0a00000f e595300c e5951000 e3530000 1a00000d
> e5953010 e3530000 1 a00000a e59f2220 e3510000 e5973000 e59f0218 01a01002
> e59f2214
> ------------[ cut here ]------------
> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> -----------[ user debug ]-----------
> Current process: ubiblock   pid=179
> Running on CPU1 (2 online)
> 
> current=c185d780   preempt_count=0x0
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> task: c185d780 task.stack: d053a000
> PC is at 0x4b767d8c
> LR is at 0x10b78
> pc : [<4b767d8c>]    lr : [<00010b78>]    psr: 60000010
> sp : be73fc34  ip : 4b767d80  fp : 00000000
> r10: 00000003  r9 : be73fdb4  r8 : 00000000
> r7 : 00000036  r6 : 00000003  r5 : 000250a8  r4 : ffffffff
> r3 : 00000001  r2 : 22eea600  r1 : 40804f07  r0 : 00000003
> Flags: nZCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> 
> Memory Maps:
> 00010-
> 00015
>  ubiblock
> 
> 00024-
> 00026
>  ubiblock
> 
> 00026-
> 00047
> 
> 4b660-
> 4b67f
>  ld-2
> 
> 4b68e-
> 4b690
>  ld-2
> 
> 4b6a0-
> 4b7da
>  libc-2
> 
> 4b7da-
> 4b7dc
> 
> b6bad-
> b6baf
> 
> be71f-
> be740
> 
> beb84-
> ---------[ end user debug ]---------
> Modules linked in:
> CPU: 1 PID: 179 Comm: ubiblock Tainted: P        W  O   
> 4.11.12-yocto-standard-414e5550071e0ca8639b0d8fb84fed31 #1 Hardware name:
> (Device Tree)
> task: c185d780 task.stack: d053a000
> PC is at internal_create_group+0x3c/0x2a0
> LR is at sysfs_create_group+0x20/0x24
> pc : [<c01e26cc>]    lr : [<c01e2950>]    psr: 60000013
> sp : d053bd38  ip : d053bd70  fp : d053bd6c
> r10: c095fddc  r9 : 00000000  r8 : c1b59c00
> r7 : c1b59870  r6 : c090f488  r5 : c09276f8  r4 : 00000000
> r3 : 00000000  r2 : c09276f8  r1 : 00000000  r0 : c1b59870
> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> Control: 30c5383d  Table: 104b6840  DAC: ffab73de
> Process ubiblock (pid: 179, stack limit = 0xd053a210)
> Stack: (0xd053bd38 to 0xd053c000)
> bd20:                                                       d053bd5c
> d053bd48 bd40: c00731c8 d0bd9e00 c1b59800 c090f488 c1b59868 c1b59c00
> c1b5980c c095fddc bd60: d053bd7c d053bd70 c01e2950 c01e269c d053bd8c
> d053bd80 c00e3d38 c01e293c bd80: d053bdbc d053bd90 c02bdfbc c00e3d2c
> 00040b0c c1b59800 c1b59868 c090f488 bda0: c1b59870 c1b59c00 c1b5980c
> c095fddc d053be14 d053bdc0 c02cec84 c02bdef0 bdc0: c02ce6cc c1b59800
> d053bdfc d053bdd8 0fc00002 c0053478 00000000 1f518000 bde0: d053be1c
> 00040b0c 00000000 c1b11e40 00000000 c1b59800 c095fda4 d053be60 be00:
> c1b11e8c c095fddc d053be54 d053be18 c0436ec8 c02ceafc 00000000 c1b5980c
> be20: c01e06f0 c1b5980c 00000000 22eea600 d04b6100 d0b7cc00 d1c20000
> c090f488 be40: d053a000 c090f488 d053bedc d053be58 c0427bb8 c0436c50
> 00000001 00000000 be60: 00000000 0000000f 00000017 00000003 002c9000
> 00000000 00000001 00000003 be80: 00000000 00000000 00000001 0001f000
> 00000006 d0b7ce5c 0f700010 c005368c bea0: 9a877d41 00000007 c1aab015
> c0755170 00000261 00040b0c d053beec 22eea600 bec0: d0b96228 c1896300
> 00000003 22eea600 d053beec d053bee0 c0189110 c0427774 bee0: d053bf7c
> d053bef0 c01892e0 c01890ec d053bf34 c0185224 c01954e8 c05e9a14 bf00:
> c0185278 c1aab000 c090f488 c1896300 d0b96228 c1aab000 c1896308 00000020
> bf20: d053bf44 d053bf30 c0185224 c0163200 00000003 c090f488 d053bf94
> d053bf48 bf40: c0175504 c01851c4 00000000 00040b0c 00000002 00000003
> c1896300 c1896300 bf60: 40804f07 22eea600 d053a000 00000000 d053bfa4
> d053bf80 c0189a14 c018924c bf80: ffffffff 000250a8 00000003 00000036
> c00107e4 d053a000 00000000 d053bfa8 bfa0: c0010640 c01899dc ffffffff
> 000250a8 00000003 40804f07 22eea600 00000001 bfc0: ffffffff 000250a8
> 00000003 00000036 00000000 be73fdb4 00000003 00000000 bfe0: 4b767d80
> be73fc34 00010b78 4b767d8c 60000010 00000003 e675ff3a 2a3139dd [<c01e26cc>]
> (internal_create_group) from [<c01e2950>] (sysfs_create_group+0x20/0x24)
> [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
> (blk_trace_init_sysfs+0x18/0x20) [<c00e3d38>] (blk_trace_init_sysfs) from
> [<c02bdfbc>] (blk_register_queue+0xd8/0x154) [<c02bdfbc>]
> (blk_register_queue) from [<c02cec84>] (device_add_disk+0x194/0x44c)
> [<c02cec84>] (device_add_disk) from [<c0436ec8>]
> (ubiblock_create+0x284/0x2e0) [<c0436ec8>] (ubiblock_create) from
> [<c0427bb8>] (vol_cdev_ioctl+0x450/0x554) [<c0427bb8>] (vol_cdev_ioctl)
> from [<c0189110>] (vfs_ioctl+0x30/0x44) [<c0189110>] (vfs_ioctl) from
> [<c01892e0>] (do_vfs_ioctl+0xa0/0x790) [<c01892e0>] (do_vfs_ioctl) from
> [<c0189a14>] (SyS_ioctl+0x44/0x68) [<c0189a14>] (SyS_ioctl) from
> [<c0010640>] (ret_fast_syscall+0x0/0x34) Code: e89da8f0 e1a0c00d e92ddff0
> e24cb004 e24dd00c e52de004 e8bd4000 e2507000 e1a09001 e1a05002 0a000004
> e3510000 e59 74018 1a000002 e3540000 1a000002 (e7f001f2) e3540000 0a00000f
> e595300c e5951000 e3530000 1a00000d e5953010 e3530000 1 a00000a e59f2220
> e3510000 e5973000 e59f0218 01a01002 e59f2214
> ---[ end trace e541910253daa33a ]---
> 
> I was able to reproduce the problem with the following script with the
> underlying volumes already created:
> 
> while true; do
>     for part in 2 3 4 15 24 90 91; do
>         ubiblock -c /dev/ubi0_$part &
>     done
>     sleep 2
> 
>     for part in 2 3 4 15 24 90 91; do
>         ubiblock -r /dev/ubi0_$part &
>     done
>     sleep 2
> done
> 
> There is a race with idr_alloc where gd->first_minor could be set to the
> same value for two different calls to ubiblock_create.  Each instance
> calls device_add_disk with the same first_minor.  device_add_disk calls
> bdi_register_owner.  The bdi_register_owner call path produces the
> initial WARNINGS about registering the same device.  However,
> device_add_disk does not error out when bdi_register_owner returns an
> error.  The control continues until it reaches blk_register_queue which
> eventually BUGs.
> 
> >> Missing Fixes and Cc-stable tags.
> >> 
> >>> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
> >> 
> >> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> >> 
> >> BTW, just had a quick look at the code, and I think the locking can be
> >> simplified a bit by keeping the devices_lock for the whole
> >> ubiblock_create() operation instead of acquiring/releasing it several
> >> times in the function (see [1]). It makes sense to do fine grained
> >> locking when operations protected by the lock are time sensitive, but I
> >> don't think this is the case here.
> > 
> > Agreed. Something like this perhaps http://ix.io/E8G ?
> > Notice that ubiblock_remove_all seemed to require locking as well.
> 
> I tried out Ezequiel's patch and it fixes this issue as well.  Note,
> that ret needs to be defined in ubiblock_remove.

Can you please have a proper patch such that I can take it? :-)

Thanks,
//richard


From richard.weinberger at gmail.com  Wed Jan 17 13:12:27 2018
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Wed, 17 Jan 2018 22:12:27 +0100
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <2774377.VZm18AqBqi@blindfold>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
 <20180105183744.GA44929@gmail.com> <2774377.VZm18AqBqi@blindfold>
Message-ID: <CAFLxGvzGeMkm_1HhcFDe4twTGsVHaXvjoM6GezxtCNW+NZw84Q@mail.gmail.com>

On Fri, Jan 5, 2018 at 11:11 PM, Richard Weinberger <richard at nod.at> wrote:
> Eric,
>
> Am Freitag, 5. Januar 2018, 19:37:44 CET schrieb Eric Biggers:
>> On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
>> > From: Eric Biggers <ebiggers at google.com>
>> >
>> > This series switches ubifs to use the fscrypt helper functions for
>> > open/link/rename/lookup/setattr introduced in v4.15.
>> >
>> > These patches were originally sent in "[PATCH 00/25] fscrypt: add some
>> > higher-level helper functions".  I've rebased them onto v4.15-rc1.
>> >
>> > Eric Biggers (5):
>> >   ubifs: switch to fscrypt_file_open()
>> >   ubifs: switch to fscrypt_prepare_link()
>> >   ubifs: switch to fscrypt_prepare_rename()
>> >   ubifs: switch to fscrypt_prepare_lookup()
>> >   ubifs: switch to fscrypt_prepare_setattr()
>> >
>> >  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
>> >  fs/ubifs/file.c | 41 ++++-------------------------------------
>> >  2 files changed, 17 insertions(+), 67 deletions(-)
>>
>> Richard, can you take these for UBIFS for v4.16?
>
> Yes. Thanks a lot for cleaning this up.

FYI, this series has merge conflicts with other fscrypt related
changes that went via Ted into fs/ubifs.

-- 
Thanks,
//richard


From ebiggers3 at gmail.com  Wed Jan 17 13:23:54 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Wed, 17 Jan 2018 13:23:54 -0800
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <CAFLxGvzGeMkm_1HhcFDe4twTGsVHaXvjoM6GezxtCNW+NZw84Q@mail.gmail.com>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
 <20180105183744.GA44929@gmail.com> <2774377.VZm18AqBqi@blindfold>
 <CAFLxGvzGeMkm_1HhcFDe4twTGsVHaXvjoM6GezxtCNW+NZw84Q@mail.gmail.com>
Message-ID: <20180117212354.xrsog7pekzoomq7p@gmail.com>

On Wed, Jan 17, 2018 at 10:12:27PM +0100, Richard Weinberger wrote:
> On Fri, Jan 5, 2018 at 11:11 PM, Richard Weinberger <richard at nod.at> wrote:
> > Eric,
> >
> > Am Freitag, 5. Januar 2018, 19:37:44 CET schrieb Eric Biggers:
> >> On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
> >> > From: Eric Biggers <ebiggers at google.com>
> >> >
> >> > This series switches ubifs to use the fscrypt helper functions for
> >> > open/link/rename/lookup/setattr introduced in v4.15.
> >> >
> >> > These patches were originally sent in "[PATCH 00/25] fscrypt: add some
> >> > higher-level helper functions".  I've rebased them onto v4.15-rc1.
> >> >
> >> > Eric Biggers (5):
> >> >   ubifs: switch to fscrypt_file_open()
> >> >   ubifs: switch to fscrypt_prepare_link()
> >> >   ubifs: switch to fscrypt_prepare_rename()
> >> >   ubifs: switch to fscrypt_prepare_lookup()
> >> >   ubifs: switch to fscrypt_prepare_setattr()
> >> >
> >> >  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
> >> >  fs/ubifs/file.c | 41 ++++-------------------------------------
> >> >  2 files changed, 17 insertions(+), 67 deletions(-)
> >>
> >> Richard, can you take these for UBIFS for v4.16?
> >
> > Yes. Thanks a lot for cleaning this up.
> 
> FYI, this series has merge conflicts with other fscrypt related
> changes that went via Ted into fs/ubifs.
> 

How so?  These apply cleanly to both Linus' tree and to fscrypt/master
currently.


From richard at nod.at  Wed Jan 17 13:36:12 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 17 Jan 2018 22:36:12 +0100
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <20180117212354.xrsog7pekzoomq7p@gmail.com>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
 <CAFLxGvzGeMkm_1HhcFDe4twTGsVHaXvjoM6GezxtCNW+NZw84Q@mail.gmail.com>
 <20180117212354.xrsog7pekzoomq7p@gmail.com>
Message-ID: <6120539.HEfP5UEqVm@blindfold>

Am Mittwoch, 17. Januar 2018, 22:23:54 CET schrieb Eric Biggers:
> On Wed, Jan 17, 2018 at 10:12:27PM +0100, Richard Weinberger wrote:
> > On Fri, Jan 5, 2018 at 11:11 PM, Richard Weinberger <richard at nod.at> 
wrote:
> > > Eric,
> > > 
> > > Am Freitag, 5. Januar 2018, 19:37:44 CET schrieb Eric Biggers:
> > >> On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
> > >> > From: Eric Biggers <ebiggers at google.com>
> > >> > 
> > >> > This series switches ubifs to use the fscrypt helper functions for
> > >> > open/link/rename/lookup/setattr introduced in v4.15.
> > >> > 
> > >> > These patches were originally sent in "[PATCH 00/25] fscrypt: add
> > >> > some
> > >> > higher-level helper functions".  I've rebased them onto v4.15-rc1.
> > >> > 
> > >> > Eric Biggers (5):
> > >> >   ubifs: switch to fscrypt_file_open()
> > >> >   ubifs: switch to fscrypt_prepare_link()
> > >> >   ubifs: switch to fscrypt_prepare_rename()
> > >> >   ubifs: switch to fscrypt_prepare_lookup()
> > >> >   ubifs: switch to fscrypt_prepare_setattr()
> > >> >  
> > >> >  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
> > >> >  fs/ubifs/file.c | 41 ++++-------------------------------------
> > >> >  2 files changed, 17 insertions(+), 67 deletions(-)
> > >> 
> > >> Richard, can you take these for UBIFS for v4.16?
> > > 
> > > Yes. Thanks a lot for cleaning this up.
> > 
> > FYI, this series has merge conflicts with other fscrypt related
> > changes that went via Ted into fs/ubifs.
> 
> How so?  These apply cleanly to both Linus' tree and to fscrypt/master
> currently.

Just checked, the problem is this commit:

commit 9a2cebc6e2368072490a574eafe0f0747d330bbd
Author: Eric Biggers <ebiggers at google.com>
Date:   Fri Jan 5 11:30:03 2018 -0800

    ubifs: free the encrypted symlink target

It exists also in my tree. I'll drop it and force push.
Sorry for messing up, next time I try hard to be more responsive.

Thanks,
//richard



From mtownsend1973 at gmail.com  Wed Jan 17 14:02:24 2018
From: mtownsend1973 at gmail.com (Martin Townsend)
Date: Wed, 17 Jan 2018 22:02:24 +0000
Subject: [PATCH] ubi: Fix filesystem corruption on detach when fastmap
 enabled
In-Reply-To: <1612877.xbAM7MeHb7@blindfold>
References: <CABatt_wEa+jiSmutzZrjyRFXqypPTbfdo_Z8CVDhuuRMUXjA6w@mail.gmail.com>
 <8925017.tvIN1CM1GY@blindfold>
 <CABatt_y_6D+unmRT_L3nScxN=RnPuAxSiykSwPkwNp6298OakQ@mail.gmail.com>
 <1612877.xbAM7MeHb7@blindfold>
Message-ID: <CABatt_wsqSOAzHRz82TVj9W98b9kOA607p_QM3wnZC__T2OEcg@mail.gmail.com>

Hi,


On Wed, Jan 17, 2018 at 3:47 PM, Richard Weinberger
<richard at sigma-star.at> wrote:
> Martin,
>
> Am Dienstag, 16. Januar 2018, 15:13:04 CET schrieb Martin Townsend:
>> > Martin, can you please explain what corruption you see?
>> > From reading the code I'd assume that you miss volumes but a full scan
>> > would recover everything.
>>
>> I didn't do much analysis of the corruption I'm afraid.  When I tried
>> to reattach the the c->empty flag was set to true and indeed all the
>> EBA tables were reporting an empty filesystem even after a reboot.
>
> Sounds like what I'd expect.
>
>> Not sure if this was recoverable, how do you trigger a full scan?
>
> Booting a kernel without Fastmap support. B-)
>
>> > For Linux I suggest this fix:
>> >
>> > From 48287459cf8717cffac5aed423937cd7ba4360ab Mon Sep 17 00:00:00 2001
>> > From: Richard Weinberger <richard at nod.at>
>> > Date: Tue, 16 Jan 2018 14:12:46 +0100
>> > Subject: [PATCH] ubi: fastmap: Don't flush fastmap work on detach
>> >
>> > At this point UBI volumes have already been free()'ed and fastmap can no
>> > longer access these data structures.
>> >
>> > Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL
>> > sub- system")
>> > Signed-off-by: Richard Weinberger <richard at nod.at>
>> > Cc: stable at vger.kernel.org
>> > ---
>> >
>> >  drivers/mtd/ubi/fastmap-wl.c | 1 -
>> >  1 file changed, 1 deletion(-)
>> >
>> > diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
>> > index 4f0bd6b4422a..69dd21679a30 100644
>> > --- a/drivers/mtd/ubi/fastmap-wl.c
>> > +++ b/drivers/mtd/ubi/fastmap-wl.c
>> > @@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
>> >
>> >  {
>> >
>> >         int i;
>> >
>> > -       flush_work(&ubi->fm_work);
>> >
>> >         return_unused_pool_pebs(ubi, &ubi->fm_pool);
>> >         return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
>> >
>> > --
>> > 2.13.6
>> >
>> > In U-Boot you can do the same.
>>
>> Richard: This will work but just want to check that ubi_wl_close is
>> supposed to never write out to the filesystem or will never do so in
>> future, if so maybe a something in the comments above ubi_wl_close to
>> ensure this?
>
> Hmm, not sure if I got this question.
> The filesystem sits above UBI. If we reach ubi_wl_close() all users ontop of
> UBI are gone. There is no UBIFS mounted anymore.
>

Thanks for clarifying, I'll submit a version 2 patch that replicates
this for U-Boot.

> Thanks,
> //richard
>
> --
> sigma star gmbh - Eduard-Bodem-Gasse 6 - 6020 Innsbruck - Austria
> ATU66964118 - FN 374287y


From richard at nod.at  Wed Jan 17 14:15:57 2018
From: richard at nod.at (Richard Weinberger)
Date: Wed, 17 Jan 2018 23:15:57 +0100
Subject: [PATCH] ubi: fastmap: Don't flush fastmap work on detach
Message-ID: <20180117221557.16768-1-richard@nod.at>

At this point UBI volumes have already been free()'ed and fastmap can no
longer access these data structures.

Reported-by: Martin Townsend <mtownsend1973 at gmail.com>
Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL sub-system")
Cc: stable at vger.kernel.org
Signed-off-by: Richard Weinberger <richard at nod.at>
---
 drivers/mtd/ubi/fastmap-wl.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
index 4f0bd6b4422a..69dd21679a30 100644
--- a/drivers/mtd/ubi/fastmap-wl.c
+++ b/drivers/mtd/ubi/fastmap-wl.c
@@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi)
 {
 	int i;
 
-	flush_work(&ubi->fm_work);
 	return_unused_pool_pebs(ubi, &ubi->fm_pool);
 	return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
 
-- 
2.13.6



From ebiggers3 at gmail.com  Wed Jan 17 15:44:58 2018
From: ebiggers3 at gmail.com (Eric Biggers)
Date: Wed, 17 Jan 2018 15:44:58 -0800
Subject: [PATCH v2 0/5] ubifs: switch to new fscrypt helper functions
In-Reply-To: <6120539.HEfP5UEqVm@blindfold>
References: <20171129204317.91205-1-ebiggers3@gmail.com>
 <CAFLxGvzGeMkm_1HhcFDe4twTGsVHaXvjoM6GezxtCNW+NZw84Q@mail.gmail.com>
 <20180117212354.xrsog7pekzoomq7p@gmail.com>
 <6120539.HEfP5UEqVm@blindfold>
Message-ID: <20180117234458.iw37mht6jtp5gdwn@gmail.com>

On Wed, Jan 17, 2018 at 10:36:12PM +0100, Richard Weinberger wrote:
> Am Mittwoch, 17. Januar 2018, 22:23:54 CET schrieb Eric Biggers:
> > On Wed, Jan 17, 2018 at 10:12:27PM +0100, Richard Weinberger wrote:
> > > On Fri, Jan 5, 2018 at 11:11 PM, Richard Weinberger <richard at nod.at> 
> wrote:
> > > > Eric,
> > > > 
> > > > Am Freitag, 5. Januar 2018, 19:37:44 CET schrieb Eric Biggers:
> > > >> On Wed, Nov 29, 2017 at 12:43:12PM -0800, Eric Biggers wrote:
> > > >> > From: Eric Biggers <ebiggers at google.com>
> > > >> > 
> > > >> > This series switches ubifs to use the fscrypt helper functions for
> > > >> > open/link/rename/lookup/setattr introduced in v4.15.
> > > >> > 
> > > >> > These patches were originally sent in "[PATCH 00/25] fscrypt: add
> > > >> > some
> > > >> > higher-level helper functions".  I've rebased them onto v4.15-rc1.
> > > >> > 
> > > >> > Eric Biggers (5):
> > > >> >   ubifs: switch to fscrypt_file_open()
> > > >> >   ubifs: switch to fscrypt_prepare_link()
> > > >> >   ubifs: switch to fscrypt_prepare_rename()
> > > >> >   ubifs: switch to fscrypt_prepare_lookup()
> > > >> >   ubifs: switch to fscrypt_prepare_setattr()
> > > >> >  
> > > >> >  fs/ubifs/dir.c  | 43 +++++++++++++------------------------------
> > > >> >  fs/ubifs/file.c | 41 ++++-------------------------------------
> > > >> >  2 files changed, 17 insertions(+), 67 deletions(-)
> > > >> 
> > > >> Richard, can you take these for UBIFS for v4.16?
> > > > 
> > > > Yes. Thanks a lot for cleaning this up.
> > > 
> > > FYI, this series has merge conflicts with other fscrypt related
> > > changes that went via Ted into fs/ubifs.
> > 
> > How so?  These apply cleanly to both Linus' tree and to fscrypt/master
> > currently.
> 
> Just checked, the problem is this commit:
> 
> commit 9a2cebc6e2368072490a574eafe0f0747d330bbd
> Author: Eric Biggers <ebiggers at google.com>
> Date:   Fri Jan 5 11:30:03 2018 -0800
> 
>     ubifs: free the encrypted symlink target
> 
> It exists also in my tree. I'll drop it and force push.
> Sorry for messing up, next time I try hard to be more responsive.
> 
> Thanks,
> //richard
> 

Ah yes, sorry for the confusion.  The original plan was to just take the initial
patches in the "fscrypt: symlink helpers and fscrypt.h cleanup" series, but we
decided to take the fs-specific patches through the fscrypt tree too, since the
only merge conflict was a "trivial" one in f2fs_symlink(), and it otherwise
would have taken a long time to get all those patches as well as the follow-on
fscrypt patches applied.

Eric


From miquel.raynal at free-electrons.com  Wed Jan 17 23:16:10 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Thu, 18 Jan 2018 08:16:10 +0100
Subject: [PATCH 6/8] mtd: nand: mxc: Add own write_page
In-Reply-To: <20180117104009.geal4fs6eykqai3a@pengutronix.de>
References: <20180109101148.13728-1-s.hauer@pengutronix.de>
 <20180109101148.13728-7-s.hauer@pengutronix.de>
 <20180113172551.5dab8a7c@xps13>
 <20180117104009.geal4fs6eykqai3a@pengutronix.de>
Message-ID: <20180118081610.32937f54@xps13>

Hi Sascha,

On Wed, 17 Jan 2018 11:40:09 +0100
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> Hi Miquel,
> 
> On Sat, Jan 13, 2018 at 05:25:51PM +0100, Miquel Raynal wrote:
> > Hi Sascha,
> > 
> > On Tue,  9 Jan 2018 11:11:46 +0100
> > Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >   
> > > Now that we have our own read_page function add a write_page
> > > function for consistency aswell. This can be a lot easier than
> > > the generic function since we do not have to iterate over
> > > subpages but can write the whole page at once. Also add
> > > write_page_raw and write_oob for proper raw and oob write support.
> > > 
> > > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > > ---
> > >  drivers/mtd/nand/mxc_nand.c | 56
> > > +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56
> > > insertions(+)
> > > 
> > > diff --git a/drivers/mtd/nand/mxc_nand.c
> > > b/drivers/mtd/nand/mxc_nand.c index 83bb01ab7079..6fbf98851a96
> > > 100644 --- a/drivers/mtd/nand/mxc_nand.c
> > > +++ b/drivers/mtd/nand/mxc_nand.c
> > > @@ -893,6 +893,59 @@ static int mxc_nand_read_oob(struct mtd_info
> > > *mtd, struct nand_chip *chip, page);
> > >  }
> > >  
> > > +static int __mxc_nand_write_page(struct mtd_info *mtd, struct
> > > nand_chip *chip,
> > > +				 const uint8_t *buf, int
> > > oob_required, int page) +{
> > > +	struct mxc_nand_host *host =
> > > nand_get_controller_data(chip); +
> > > +	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN,
> > > false);
> > > +	mxc_do_addr_cycle(mtd, 0, page);
> > > +
> > > +	memcpy32_toio(host->main_area0, buf, mtd->writesize);
> > > +	copy_spare(mtd, false, chip->oob_poi);  
> > 
> > If I remember correctly, there was a "spare only" mechanism to avoid
> > doing full page read/write when unnecessary. What about using it
> > here when (buf == NULL && oob_required)?  
> 
> You are probably referring to the SP_EN bit in the NAND_FLASH_CONFIG1
> register right? This is described as:
> 
> > NAND Flash spare enable. This bit determines whether host
> > reads/writes are to NAND Flash spare data only or NAND Flash main
> > and spare data. This feature is supported only with memories with
> > 1/2K page size. Note: There is no ECC in this mode of operation.
> > 0 NAND Flash main and spare data is enabled
> > 1 NAND Flash spare only data is enabled  
> 
> At least the i.MX25 has the limitation of 1/2k page size for this
> feature. It's not in the i.MX27 manual. I don't know if the i.MX27
> documentation is inaccurate or if this limitation is there already.

Ok, I ignored this limitation on i.MX25. Better write generic code
then.

> 
> Anyway, I don't think it's worth optimizing for this case given that
> we still need to support a full page write for 2k pages (which should
> be much more widespread nowadays than the 512b page size NANDs).

Sure!

Thanks,
Miqu?l


From bradleybolen at gmail.com  Thu Jan 18 05:55:20 2018
From: bradleybolen at gmail.com (Bradley Bolen)
Date: Thu, 18 Jan 2018 08:55:20 -0500
Subject: [PATCH] UBI: block: Fix locking for idr_alloc/idr_remove
Message-ID: <1516283720-11277-1-git-send-email-bbolen@lexmark.com>

From: Bradley Bolen <bradleybolen at gmail.com>

This fixes a race with idr_alloc where gd->first_minor can be set to the
same value for two simultaneous calls to ubiblock_create.  Each instance
calls device_add_disk with the same first_minor.  device_add_disk calls
bdi_register_owner which generates several warnings.

WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
sysfs_warn_dup+0x68/0x88
sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'

WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
kobject_add_internal+0x1ec/0x2f8
kobject_add_internal failed for 252:2 with -EEXIST, don't try to
register things with the same name in the same directory

WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
sysfs_warn_dup+0x68/0x88
sysfs: cannot create duplicate filename '/dev/block/252:2'

However, device_add_disk does not error out when bdi_register_owner
returns an error.  Control continues until reaching blk_register_queue.
It then BUGs.

kernel BUG at kernel-source/fs/sysfs/group.c:113!
[<c01e26cc>] (internal_create_group) from [<c01e2950>]
(sysfs_create_group+0x20/0x24)
[<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
(blk_trace_init_sysfs+0x18/0x20)
[<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>]
(blk_register_queue+0xd8/0x154)
[<c02bdfbc>] (blk_register_queue) from [<c02cec84>]
(device_add_disk+0x194/0x44c)
[<c02cec84>] (device_add_disk) from [<c0436ec8>]
(ubiblock_create+0x284/0x2e0)
[<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
(vol_cdev_ioctl+0x450/0x554)
[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)

Locking idr_alloc/idr_remove removes the race and keeps gd->first_minor
unique.

Fixes: 2bf50d42f3a4 ("UBI: block: Dynamically allocate minor numbers")
Cc: stable at vger.kernel.org
Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
---
 drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index b210fdb..b1fc28f 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -99,6 +99,8 @@ struct ubiblock {
 
 /* Linked list of all ubiblock instances */
 static LIST_HEAD(ubiblock_devices);
+static DEFINE_IDR(ubiblock_minor_idr);
+/* Protects ubiblock_devices and ubiblock_minor_idr */
 static DEFINE_MUTEX(devices_mutex);
 static int ubiblock_major;
 
@@ -351,8 +353,6 @@ static int ubiblock_init_request(struct blk_mq_tag_set *set,
 	.init_request	= ubiblock_init_request,
 };
 
-static DEFINE_IDR(ubiblock_minor_idr);
-
 int ubiblock_create(struct ubi_volume_info *vi)
 {
 	struct ubiblock *dev;
@@ -365,14 +365,15 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	/* Check that the volume isn't already handled */
 	mutex_lock(&devices_mutex);
 	if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
-		mutex_unlock(&devices_mutex);
-		return -EEXIST;
+		ret = -EEXIST;
+		goto out_unlock;
 	}
-	mutex_unlock(&devices_mutex);
 
 	dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
+	if (!dev) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
 
 	mutex_init(&dev->dev_mutex);
 
@@ -437,14 +438,13 @@ int ubiblock_create(struct ubi_volume_info *vi)
 		goto out_free_queue;
 	}
 
-	mutex_lock(&devices_mutex);
 	list_add_tail(&dev->list, &ubiblock_devices);
-	mutex_unlock(&devices_mutex);
 
 	/* Must be the last step: anyone can call file ops from now on */
 	add_disk(dev->gd);
 	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
 		 dev->ubi_num, dev->vol_id, vi->name);
+	mutex_unlock(&devices_mutex);
 	return 0;
 
 out_free_queue:
@@ -457,6 +457,8 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	put_disk(dev->gd);
 out_free_dev:
 	kfree(dev);
+out_unlock:
+	mutex_unlock(&devices_mutex);
 
 	return ret;
 }
@@ -478,30 +480,36 @@ static void ubiblock_cleanup(struct ubiblock *dev)
 int ubiblock_remove(struct ubi_volume_info *vi)
 {
 	struct ubiblock *dev;
+	int ret;
 
 	mutex_lock(&devices_mutex);
 	dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
 	if (!dev) {
-		mutex_unlock(&devices_mutex);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out_unlock;
 	}
 
 	/* Found a device, let's lock it so we can check if it's busy */
 	mutex_lock(&dev->dev_mutex);
 	if (dev->refcnt > 0) {
-		mutex_unlock(&dev->dev_mutex);
-		mutex_unlock(&devices_mutex);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out_unlock_dev;
 	}
 
 	/* Remove from device list */
 	list_del(&dev->list);
-	mutex_unlock(&devices_mutex);
-
 	ubiblock_cleanup(dev);
 	mutex_unlock(&dev->dev_mutex);
+	mutex_unlock(&devices_mutex);
+
 	kfree(dev);
 	return 0;
+
+out_unlock_dev:
+	mutex_unlock(&dev->dev_mutex);
+out_unlock:
+	mutex_unlock(&devices_mutex);
+	return ret;
 }
 
 static int ubiblock_resize(struct ubi_volume_info *vi)
@@ -630,6 +638,7 @@ static void ubiblock_remove_all(void)
 	struct ubiblock *next;
 	struct ubiblock *dev;
 
+	mutex_lock(&devices_mutex);
 	list_for_each_entry_safe(dev, next, &ubiblock_devices, list) {
 		/* The module is being forcefully removed */
 		WARN_ON(dev->desc);
@@ -638,6 +647,7 @@ static void ubiblock_remove_all(void)
 		ubiblock_cleanup(dev);
 		kfree(dev);
 	}
+	mutex_unlock(&devices_mutex);
 }
 
 int __init ubiblock_init(void)
-- 
1.9.3



From weiyongjun1 at huawei.com  Thu Jan 18 06:05:05 2018
From: weiyongjun1 at huawei.com (Wei Yongjun)
Date: Thu, 18 Jan 2018 14:05:05 +0000
Subject: [PATCH -next] mtd: ubi: wl: Fix error return code in ubi_wl_init()
Message-ID: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>

Fix to return error code -ENOMEM from the kmem_cache_alloc() error
handling case instead of 0, as done elsewhere in this function.

Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
---
 drivers/mtd/ubi/wl.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 77ab49f..2052a64 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1617,8 +1617,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		cond_resched();
 
 		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
-		if (!e)
+		if (!e) {
+			err = -ENOMEM;
 			goto out_free;
+		}
 
 		e->pnum = aeb->pnum;
 		e->ec = aeb->ec;
@@ -1637,8 +1639,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 			cond_resched();
 
 			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
-			if (!e)
+			if (!e) {
+				err = -ENOMEM;
 				goto out_free;
+			}
 
 			e->pnum = aeb->pnum;
 			e->ec = aeb->ec;



From boris.brezillon at free-electrons.com  Thu Jan 18 06:08:01 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 18 Jan 2018 15:08:01 +0100
Subject: [PATCH -next] mtd: ubi: wl: Fix error return code in ubi_wl_init()
In-Reply-To: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>
References: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>
Message-ID: <20180118150801.714ecc34@bbrezillon>

On Thu, 18 Jan 2018 14:05:05 +0000
Wei Yongjun <weiyongjun1 at huawei.com> wrote:

> Fix to return error code -ENOMEM from the kmem_cache_alloc() error
> handling case instead of 0, as done elsewhere in this function.

I guess you've used a static analysis code to detect this problem, can
you name it in the commit message, and paste the error/warning message
it reported next time you submit this kind of patch.

> 
> Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>

NAck. I you read the code you'll see that err is initialized to -ENOMEM
here [1], so these changes are actually not needed.

> ---
>  drivers/mtd/ubi/wl.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
> index 77ab49f..2052a64 100644
> --- a/drivers/mtd/ubi/wl.c
> +++ b/drivers/mtd/ubi/wl.c
> @@ -1617,8 +1617,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
>  		cond_resched();
>  
>  		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> -		if (!e)
> +		if (!e) {
> +			err = -ENOMEM;
>  			goto out_free;
> +		}
>  
>  		e->pnum = aeb->pnum;
>  		e->ec = aeb->ec;
> @@ -1637,8 +1639,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
>  			cond_resched();
>  
>  			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> -			if (!e)
> +			if (!e) {
> +				err = -ENOMEM;
>  				goto out_free;
> +			}
>  
>  			e->pnum = aeb->pnum;
>  			e->ec = aeb->ec;
> 

[1]https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/mtd/ubi/wl.c?h=next-20180118#n1596


From boris.brezillon at free-electrons.com  Thu Jan 18 06:11:32 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 18 Jan 2018 15:11:32 +0100
Subject: [PATCH -next] mtd: ubi: wl: Fix error return code in ubi_wl_init()
In-Reply-To: <20180118150801.714ecc34@bbrezillon>
References: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>
 <20180118150801.714ecc34@bbrezillon>
Message-ID: <20180118151132.255e0173@bbrezillon>

On Thu, 18 Jan 2018 15:08:01 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Thu, 18 Jan 2018 14:05:05 +0000
> Wei Yongjun <weiyongjun1 at huawei.com> wrote:
> 
> > Fix to return error code -ENOMEM from the kmem_cache_alloc() error
> > handling case instead of 0, as done elsewhere in this function.  
> 
> I guess you've used a static analysis code to detect this problem, can
> you name it in the commit message, and paste the error/warning message
> it reported next time you submit this kind of patch.
> 
> > 
> > Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>  
> 
> NAck. I you read the code you'll see that err is initialized to -ENOMEM
> here [1], so these changes are actually not needed.

Sorry, just realized I was wrong. It seems that err can be overridden by
[2]. So this patch is indeed fixing a real problem.

Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

> 
> > ---
> >  drivers/mtd/ubi/wl.c | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
> > index 77ab49f..2052a64 100644
> > --- a/drivers/mtd/ubi/wl.c
> > +++ b/drivers/mtd/ubi/wl.c
> > @@ -1617,8 +1617,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> >  		cond_resched();
> >  
> >  		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > -		if (!e)
> > +		if (!e) {
> > +			err = -ENOMEM;
> >  			goto out_free;
> > +		}
> >  
> >  		e->pnum = aeb->pnum;
> >  		e->ec = aeb->ec;
> > @@ -1637,8 +1639,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> >  			cond_resched();
> >  
> >  			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > -			if (!e)
> > +			if (!e) {
> > +				err = -ENOMEM;
> >  				goto out_free;
> > +			}
> >  
> >  			e->pnum = aeb->pnum;
> >  			e->ec = aeb->ec;
> >   
> 
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/mtd/ubi/wl.c?h=next-20180118#n1596

[2]https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/mtd/ubi/wl.c?h=next-20180118#n1609


From boris.brezillon at free-electrons.com  Thu Jan 18 06:22:53 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 18 Jan 2018 15:22:53 +0100
Subject: [PATCH v5 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1516211448-27594-1-git-send-email-fabio.estevam@nxp.com>
References: <1516211448-27594-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <20180118152253.266c6b30@bbrezillon>

On Wed, 17 Jan 2018 15:50:47 -0200
Fabio Estevam <fabio.estevam at nxp.com> wrote:

> Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> to QSPI2 the following output from /proc/mtd is seen:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi"
> mtd1: 01000000 00010000 "21e4000.qspi"
> 
> Attempts to partition them on the kernel command line result in both
> chips with identical (and identically named) partitions, which is
> an inconvenient behavior.
> 
> Assign a different mtd->name for each mtd device to avoid this problem.
> 
> After this change the output from /proc/mtd becomes:
> 
> # cat /proc/mtd 
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi-0"
> mtd1: 01000000 00010000 "21e4000.qspi-1"
> 
> In order to keep mtdparts compatibility keep the mtd->name
> unchanged when a single SPI NOR is present.
> 
> Reported-by: David Wolfe <david.wolfe at nxp.com>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
> Changes since v4:
> - Only use the new name scheme when more than one SPI NOR is present (Boris)

Not a perfect solution, but at least we don't break existing setups.

> 
>  drivers/mtd/spi-nor/fsl-quadspi.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index 2901c7b..1038842 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
>  		spi_nor_set_flash_node(nor, np);
>  		nor->priv = q;
>  
> +		if (q->nor_num > 1) {

You need to preserve the label value, if any:

		if (q->nor_num > 1 && !mtd->name) {

With that fixed

Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

> +			int spiflash_idx;
> +
> +			ret = of_property_read_u32(np, "reg", &spiflash_idx);
> +			if (!ret) {
> +				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
> +							   "%s-%d",
> +							   dev_name(dev),
> +							   spiflash_idx);
> +				if (!mtd->name) {
> +					ret = -ENOMEM;
> +					goto mutex_failed;
> +				}
> +			} else {
> +				dev_warn(dev, "reg property is missing\n");
> +			}
> +		}
> +
>  		/* fill the hooks */
>  		nor->read_reg = fsl_qspi_read_reg;
>  		nor->write_reg = fsl_qspi_write_reg;



From fabio.estevam at nxp.com  Thu Jan 18 06:28:40 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Thu, 18 Jan 2018 12:28:40 -0200
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
Message-ID: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

In order to keep mtdparts compatibility keep the mtd->name
unchanged when a single SPI NOR is present.

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes since v5:
- Preserve the label value, if any. (Boris)

 drivers/mtd/spi-nor/fsl-quadspi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..1038842 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		if (q->nor_num > 1 && !mtd->name) {
+			int spiflash_idx;
+
+			ret = of_property_read_u32(np, "reg", &spiflash_idx);
+			if (!ret) {
+				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+							   "%s-%d",
+							   dev_name(dev),
+							   spiflash_idx);
+				if (!mtd->name) {
+					ret = -ENOMEM;
+					goto mutex_failed;
+				}
+			} else {
+				dev_warn(dev, "reg property is missing\n");
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From fabio.estevam at nxp.com  Thu Jan 18 06:28:41 2018
From: fabio.estevam at nxp.com (Fabio Estevam)
Date: Thu, 18 Jan 2018 12:28:41 -0200
Subject: [PATCH v6 2/2] dt-bindings: fsl-quadspi: Add the example of two SPI
 NOR
In-Reply-To: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <1516285721-32294-2-git-send-email-fabio.estevam@nxp.com>

Improve the bindings example by adding an example of how to represent
two SPI NOR devices.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v5:
- None

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..483e9cf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,27 @@ qspi0: quadspi at 40044000 {
 		....
 	};
 };
+
+Example showing the usage of two SPI NOR devices:
+
+&qspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi2>;
+	status = "okay";
+
+	flash0: n25q256a at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+
+	flash1: n25q256a at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <1>;
+	};
+};
-- 
2.7.4



From boris.brezillon at free-electrons.com  Thu Jan 18 07:13:10 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 18 Jan 2018 16:13:10 +0100
Subject: [PATCH] UBI: block: Fix locking for idr_alloc/idr_remove
In-Reply-To: <1516283720-11277-1-git-send-email-bbolen@lexmark.com>
References: <1516283720-11277-1-git-send-email-bbolen@lexmark.com>
Message-ID: <20180118161310.4c1a779a@bbrezillon>

On Thu, 18 Jan 2018 08:55:20 -0500
Bradley Bolen <bradleybolen at gmail.com> wrote:

> From: Bradley Bolen <bradleybolen at gmail.com>
> 
> This fixes a race with idr_alloc where gd->first_minor can be set to the
> same value for two simultaneous calls to ubiblock_create.  Each instance
> calls device_add_disk with the same first_minor.  device_add_disk calls
> bdi_register_owner which generates several warnings.
> 
> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> sysfs_warn_dup+0x68/0x88
> sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'
> 
> WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
> kobject_add_internal+0x1ec/0x2f8
> kobject_add_internal failed for 252:2 with -EEXIST, don't try to
> register things with the same name in the same directory
> 
> WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> sysfs_warn_dup+0x68/0x88
> sysfs: cannot create duplicate filename '/dev/block/252:2'
> 
> However, device_add_disk does not error out when bdi_register_owner
> returns an error.  Control continues until reaching blk_register_queue.
> It then BUGs.
> 
> kernel BUG at kernel-source/fs/sysfs/group.c:113!
> [<c01e26cc>] (internal_create_group) from [<c01e2950>]
> (sysfs_create_group+0x20/0x24)
> [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
> (blk_trace_init_sysfs+0x18/0x20)
> [<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>]
> (blk_register_queue+0xd8/0x154)
> [<c02bdfbc>] (blk_register_queue) from [<c02cec84>]
> (device_add_disk+0x194/0x44c)
> [<c02cec84>] (device_add_disk) from [<c0436ec8>]
> (ubiblock_create+0x284/0x2e0)
> [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
> (vol_cdev_ioctl+0x450/0x554)
> [<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
> [<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
> [<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
> [<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
> 
> Locking idr_alloc/idr_remove removes the race and keeps gd->first_minor
> unique.
> 
> Fixes: 2bf50d42f3a4 ("UBI: block: Dynamically allocate minor numbers")
> Cc: stable at vger.kernel.org
> Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>

Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

> ---
>  drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++----------------
>  1 file changed, 26 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
> index b210fdb..b1fc28f 100644
> --- a/drivers/mtd/ubi/block.c
> +++ b/drivers/mtd/ubi/block.c
> @@ -99,6 +99,8 @@ struct ubiblock {
>  
>  /* Linked list of all ubiblock instances */
>  static LIST_HEAD(ubiblock_devices);
> +static DEFINE_IDR(ubiblock_minor_idr);
> +/* Protects ubiblock_devices and ubiblock_minor_idr */
>  static DEFINE_MUTEX(devices_mutex);
>  static int ubiblock_major;
>  
> @@ -351,8 +353,6 @@ static int ubiblock_init_request(struct blk_mq_tag_set *set,
>  	.init_request	= ubiblock_init_request,
>  };
>  
> -static DEFINE_IDR(ubiblock_minor_idr);
> -
>  int ubiblock_create(struct ubi_volume_info *vi)
>  {
>  	struct ubiblock *dev;
> @@ -365,14 +365,15 @@ int ubiblock_create(struct ubi_volume_info *vi)
>  	/* Check that the volume isn't already handled */
>  	mutex_lock(&devices_mutex);
>  	if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
> -		mutex_unlock(&devices_mutex);
> -		return -EEXIST;
> +		ret = -EEXIST;
> +		goto out_unlock;
>  	}
> -	mutex_unlock(&devices_mutex);
>  
>  	dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL);
> -	if (!dev)
> -		return -ENOMEM;
> +	if (!dev) {
> +		ret = -ENOMEM;
> +		goto out_unlock;
> +	}
>  
>  	mutex_init(&dev->dev_mutex);
>  
> @@ -437,14 +438,13 @@ int ubiblock_create(struct ubi_volume_info *vi)
>  		goto out_free_queue;
>  	}
>  
> -	mutex_lock(&devices_mutex);
>  	list_add_tail(&dev->list, &ubiblock_devices);
> -	mutex_unlock(&devices_mutex);
>  
>  	/* Must be the last step: anyone can call file ops from now on */
>  	add_disk(dev->gd);
>  	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
>  		 dev->ubi_num, dev->vol_id, vi->name);
> +	mutex_unlock(&devices_mutex);
>  	return 0;
>  
>  out_free_queue:
> @@ -457,6 +457,8 @@ int ubiblock_create(struct ubi_volume_info *vi)
>  	put_disk(dev->gd);
>  out_free_dev:
>  	kfree(dev);
> +out_unlock:
> +	mutex_unlock(&devices_mutex);
>  
>  	return ret;
>  }
> @@ -478,30 +480,36 @@ static void ubiblock_cleanup(struct ubiblock *dev)
>  int ubiblock_remove(struct ubi_volume_info *vi)
>  {
>  	struct ubiblock *dev;
> +	int ret;
>  
>  	mutex_lock(&devices_mutex);
>  	dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
>  	if (!dev) {
> -		mutex_unlock(&devices_mutex);
> -		return -ENODEV;
> +		ret = -ENODEV;
> +		goto out_unlock;
>  	}
>  
>  	/* Found a device, let's lock it so we can check if it's busy */
>  	mutex_lock(&dev->dev_mutex);
>  	if (dev->refcnt > 0) {
> -		mutex_unlock(&dev->dev_mutex);
> -		mutex_unlock(&devices_mutex);
> -		return -EBUSY;
> +		ret = -EBUSY;
> +		goto out_unlock_dev;
>  	}
>  
>  	/* Remove from device list */
>  	list_del(&dev->list);
> -	mutex_unlock(&devices_mutex);
> -
>  	ubiblock_cleanup(dev);
>  	mutex_unlock(&dev->dev_mutex);
> +	mutex_unlock(&devices_mutex);
> +
>  	kfree(dev);
>  	return 0;
> +
> +out_unlock_dev:
> +	mutex_unlock(&dev->dev_mutex);
> +out_unlock:
> +	mutex_unlock(&devices_mutex);
> +	return ret;
>  }
>  
>  static int ubiblock_resize(struct ubi_volume_info *vi)
> @@ -630,6 +638,7 @@ static void ubiblock_remove_all(void)
>  	struct ubiblock *next;
>  	struct ubiblock *dev;
>  
> +	mutex_lock(&devices_mutex);
>  	list_for_each_entry_safe(dev, next, &ubiblock_devices, list) {
>  		/* The module is being forcefully removed */
>  		WARN_ON(dev->desc);
> @@ -638,6 +647,7 @@ static void ubiblock_remove_all(void)
>  		ubiblock_cleanup(dev);
>  		kfree(dev);
>  	}
> +	mutex_unlock(&devices_mutex);
>  }
>  
>  int __init ubiblock_init(void)



From boris.brezillon at free-electrons.com  Thu Jan 18 07:34:45 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 18 Jan 2018 16:34:45 +0100
Subject: [PATCH -next] mtd: ubi: wl: Fix error return code in ubi_wl_init()
In-Reply-To: <20180118151132.255e0173@bbrezillon>
References: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>
 <20180118150801.714ecc34@bbrezillon>
 <20180118151132.255e0173@bbrezillon>
Message-ID: <20180118163445.5e465f90@bbrezillon>

On Thu, 18 Jan 2018 15:11:32 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Thu, 18 Jan 2018 15:08:01 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > On Thu, 18 Jan 2018 14:05:05 +0000
> > Wei Yongjun <weiyongjun1 at huawei.com> wrote:
> >   
> > > Fix to return error code -ENOMEM from the kmem_cache_alloc() error
> > > handling case instead of 0, as done elsewhere in this function.    
> > 
> > I guess you've used a static analysis code to detect this problem, can
> > you name it in the commit message, and paste the error/warning message
> > it reported next time you submit this kind of patch.
> >   
> > > 
> > > Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>    
> > 
> > NAck. I you read the code you'll see that err is initialized to -ENOMEM
> > here [1], so these changes are actually not needed.  
> 
> Sorry, just realized I was wrong. It seems that err can be overridden by
> [2]. So this patch is indeed fixing a real problem.
> 
> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

Oh, and you can add:

Fixes: f78e5623f45b ("ubi: fastmap: Erase outdated anchor PEBs during attach")

> 
> >   
> > > ---
> > >  drivers/mtd/ubi/wl.c | 8 ++++++--
> > >  1 file changed, 6 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
> > > index 77ab49f..2052a64 100644
> > > --- a/drivers/mtd/ubi/wl.c
> > > +++ b/drivers/mtd/ubi/wl.c
> > > @@ -1617,8 +1617,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> > >  		cond_resched();
> > >  
> > >  		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > > -		if (!e)
> > > +		if (!e) {
> > > +			err = -ENOMEM;
> > >  			goto out_free;
> > > +		}
> > >  
> > >  		e->pnum = aeb->pnum;
> > >  		e->ec = aeb->ec;
> > > @@ -1637,8 +1639,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
> > >  			cond_resched();
> > >  
> > >  			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
> > > -			if (!e)
> > > +			if (!e) {
> > > +				err = -ENOMEM;
> > >  				goto out_free;
> > > +			}
> > >  
> > >  			e->pnum = aeb->pnum;
> > >  			e->ec = aeb->ec;
> > >     
> > 
> > [1]https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/mtd/ubi/wl.c?h=next-20180118#n1596  
> 
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/mtd/ubi/wl.c?h=next-20180118#n1609
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From richard at nod.at  Thu Jan 18 07:46:17 2018
From: richard at nod.at (Richard Weinberger)
Date: Thu, 18 Jan 2018 16:46:17 +0100
Subject: [PATCH -next] mtd: ubi: wl: Fix error return code in ubi_wl_init()
In-Reply-To: <20180118163445.5e465f90@bbrezillon>
References: <1516284305-82544-1-git-send-email-weiyongjun1@huawei.com>
 <20180118151132.255e0173@bbrezillon> <20180118163445.5e465f90@bbrezillon>
Message-ID: <1565095.G3YoHPv5dZ@blindfold>

Boris, Wei Yongjun,

Am Donnerstag, 18. Januar 2018, 16:34:45 CET schrieb Boris Brezillon:
> On Thu, 18 Jan 2018 15:11:32 +0100
> 
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> > On Thu, 18 Jan 2018 15:08:01 +0100
> > 
> > Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> > > On Thu, 18 Jan 2018 14:05:05 +0000
> > > 
> > > Wei Yongjun <weiyongjun1 at huawei.com> wrote:
> > > > Fix to return error code -ENOMEM from the kmem_cache_alloc() error
> > > > handling case instead of 0, as done elsewhere in this function.
> > > 
> > > I guess you've used a static analysis code to detect this problem, can
> > > you name it in the commit message, and paste the error/warning message
> > > it reported next time you submit this kind of patch.
> > > 
> > > > Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
> > > 
> > > NAck. I you read the code you'll see that err is initialized to -ENOMEM
> > > here [1], so these changes are actually not needed.
> > 
> > Sorry, just realized I was wrong. It seems that err can be overridden by
> > [2]. So this patch is indeed fixing a real problem.
> > 
> > Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> 
> Oh, and you can add:
> 
> Fixes: f78e5623f45b ("ubi: fastmap: Erase outdated anchor PEBs during
> attach")

Good catch!

Thanks,
//richard


From richard at nod.at  Thu Jan 18 07:49:30 2018
From: richard at nod.at (Richard Weinberger)
Date: Thu, 18 Jan 2018 16:49:30 +0100
Subject: [PATCH] UBI: block: Fix locking for idr_alloc/idr_remove
In-Reply-To: <20180118161310.4c1a779a@bbrezillon>
References: <1516283720-11277-1-git-send-email-bbolen@lexmark.com>
 <20180118161310.4c1a779a@bbrezillon>
Message-ID: <1860384.duseTMRpLy@blindfold>

Boris, Bradley,
Am Donnerstag, 18. Januar 2018, 16:13:10 CET schrieb Boris Brezillon:
> On Thu, 18 Jan 2018 08:55:20 -0500
> 
> Bradley Bolen <bradleybolen at gmail.com> wrote:
> > From: Bradley Bolen <bradleybolen at gmail.com>
> > 
> > This fixes a race with idr_alloc where gd->first_minor can be set to the
> > same value for two simultaneous calls to ubiblock_create.  Each instance
> > calls device_add_disk with the same first_minor.  device_add_disk calls
> > bdi_register_owner which generates several warnings.
> > 
> > WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> > sysfs_warn_dup+0x68/0x88
> > sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'
> > 
> > WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
> > kobject_add_internal+0x1ec/0x2f8
> > kobject_add_internal failed for 252:2 with -EEXIST, don't try to
> > register things with the same name in the same directory
> > 
> > WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
> > sysfs_warn_dup+0x68/0x88
> > sysfs: cannot create duplicate filename '/dev/block/252:2'
> > 
> > However, device_add_disk does not error out when bdi_register_owner
> > returns an error.  Control continues until reaching blk_register_queue.
> > It then BUGs.
> > 
> > kernel BUG at kernel-source/fs/sysfs/group.c:113!
> > [<c01e26cc>] (internal_create_group) from [<c01e2950>]
> > (sysfs_create_group+0x20/0x24)
> > [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
> > (blk_trace_init_sysfs+0x18/0x20)
> > [<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>]
> > (blk_register_queue+0xd8/0x154)
> > [<c02bdfbc>] (blk_register_queue) from [<c02cec84>]
> > (device_add_disk+0x194/0x44c)
> > [<c02cec84>] (device_add_disk) from [<c0436ec8>]
> > (ubiblock_create+0x284/0x2e0)
> > [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
> > (vol_cdev_ioctl+0x450/0x554)
> > [<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
> > [<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
> > [<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
> > [<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
> > 
> > Locking idr_alloc/idr_remove removes the race and keeps gd->first_minor
> > unique.
> > 
> > Fixes: 2bf50d42f3a4 ("UBI: block: Dynamically allocate minor numbers")
> > Cc: stable at vger.kernel.org
> > Signed-off-by: Bradley Bolen <bradleybolen at gmail.com>
> 
> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>

Thanks!

Thanks,
//richard


From xhnjupt at gmail.com  Thu Jan 18 09:21:32 2018
From: xhnjupt at gmail.com (Han Xu)
Date: Thu, 18 Jan 2018 11:21:32 -0600
Subject: [PATCH] mtd: fsl-quadspi: fix api naming typo _init_ahb_read
In-Reply-To: <1514889552-23603-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1514889552-23603-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <CA+EcR23+mHbYTmexixjrJVK_-Nm=D=0tKQgGW4Z_QojMkpfM7w@mail.gmail.com>

On Tue, Jan 2, 2018 at 4:39 AM, Yogesh Gaur <yogeshnarayan.gaur at nxp.com> wrote:
> Fix api naming typo _init_ahb_read
> fsl_qspi_init_abh_read --> fsl_qspi_init_ahb_read
>
> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
> ---
>  drivers/mtd/spi-nor/fsl-quadspi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index f17d224..943e9c4 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -661,7 +661,7 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
>   * causes the controller to clear the buffer, and use the sequence pointed
>   * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
>   */
> -static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
> +static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
>  {
>         void __iomem *base = q->iobase;
>         int seqid;
> @@ -795,7 +795,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
>         fsl_qspi_init_lut(q);
>
>         /* Init for AHB read */
> -       fsl_qspi_init_abh_read(q);
> +       fsl_qspi_init_ahb_read(q);
>
>         return 0;
>  }
> --
> 1.9.1
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/

Acked-by: Han Xu <han.xu at nxp.com>

-- 
Sincerely,

Han XU


From han.xu at nxp.com  Thu Jan 18 09:23:56 2018
From: han.xu at nxp.com (Han Xu)
Date: Thu, 18 Jan 2018 17:23:56 +0000
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <DB5PR0401MB2214FBCDA5FF1B0C2B3BC93697E80@DB5PR0401MB2214.eurprd04.prod.outlook.com>


________________________________________
From: Fabio Estevam <fabio.estevam at nxp.com>
Sent: Thursday, January 18, 2018 8:28 AM
To: boris.brezillon at free-electrons.com
Cc: linux-mtd at lists.infradead.org; Han Xu; David Wolfe; Fabio Estevam
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

In order to keep mtdparts compatibility keep the mtd->name
unchanged when a single SPI NOR is present.

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes since v5:
- Preserve the label value, if any. (Boris)

 drivers/mtd/spi-nor/fsl-quadspi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..1038842 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
                spi_nor_set_flash_node(nor, np);
                nor->priv = q;

+               if (q->nor_num > 1 && !mtd->name) {
+                       int spiflash_idx;
+
+                       ret = of_property_read_u32(np, "reg", &spiflash_idx);
+                       if (!ret) {
+                               mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+                                                          "%s-%d",
+                                                          dev_name(dev),
+                                                          spiflash_idx);
+                               if (!mtd->name) {
+                                       ret = -ENOMEM;
+                                       goto mutex_failed;
+                               }
+                       } else {
+                               dev_warn(dev, "reg property is missing\n");
+                       }
+               }
+
                /* fill the hooks */
                nor->read_reg = fsl_qspi_read_reg;
                nor->write_reg = fsl_qspi_write_reg;
--
2.7.4

Acked-by: Han Xu <han.xu at nxp.com>

From han.xu at nxp.com  Thu Jan 18 09:24:17 2018
From: han.xu at nxp.com (Han Xu)
Date: Thu, 18 Jan 2018 17:24:17 +0000
Subject: [PATCH v6 2/2] dt-bindings: fsl-quadspi: Add the example of two
 SPI NOR
In-Reply-To: <1516285721-32294-2-git-send-email-fabio.estevam@nxp.com>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>,
 <1516285721-32294-2-git-send-email-fabio.estevam@nxp.com>
Message-ID: <DB5PR0401MB221453634FBAA077E8CE759A97E80@DB5PR0401MB2214.eurprd04.prod.outlook.com>


________________________________________
From: Fabio Estevam <fabio.estevam at nxp.com>
Sent: Thursday, January 18, 2018 8:28 AM
To: boris.brezillon at free-electrons.com
Cc: linux-mtd at lists.infradead.org; Han Xu; David Wolfe; Fabio Estevam
Subject: [PATCH v6 2/2] dt-bindings: fsl-quadspi: Add the example of two SPI NOR

Improve the bindings example by adding an example of how to represent
two SPI NOR devices.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
---
Changes since v5:
- None

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..483e9cf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,27 @@ qspi0: quadspi at 40044000 {
                ....
        };
 };
+
+Example showing the usage of two SPI NOR devices:
+
+&qspi2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi2>;
+       status = "okay";
+
+       flash0: n25q256a at 0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "micron,n25q256a", "jedec,spi-nor";
+               spi-max-frequency = <29000000>;
+               reg = <0>;
+       };
+
+       flash1: n25q256a at 1 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "micron,n25q256a", "jedec,spi-nor";
+               spi-max-frequency = <29000000>;
+               reg = <1>;
+       };
+};
--
2.7.4

Acked-by: Han Xu <han.xu at nxp.com>



From pavel at ucw.cz  Thu Jan 18 11:30:15 2018
From: pavel at ucw.cz (Pavel Machek)
Date: Thu, 18 Jan 2018 20:30:15 +0100
Subject: ubifs: noatime support?
Message-ID: <20180118193015.GA24748@amd>

Hi!

Ubifs seems to have atime support these days:

          sb->s_flags |= SB_ACTIVE;
#ifndef CONFIG_UBIFS_ATIME_SUPPORT
          sb->s_flags |= SB_NOATIME;
#else
          ubifs_msg(c, "full atime support is enabled.");
#endif

Which can be configured at compile-time, but no option to disable it
at runtime. What is going on there?

UBIFS: parse noatime
UBIFS error (ubi1:0 pid 94): ubifs_parse_options.constprop.5:
unrecognized mount option "noatime" e
mount: mounting ubi1:log_volume on /mnt/log failed: Invalid argument

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20180118/09d450c2/attachment.sig>

From richard at nod.at  Thu Jan 18 12:44:33 2018
From: richard at nod.at (Richard Weinberger)
Date: Thu, 18 Jan 2018 21:44:33 +0100
Subject: ubifs: noatime support?
In-Reply-To: <20180118193015.GA24748@amd>
References: <20180118193015.GA24748@amd>
Message-ID: <1996634.ggXeMYieCh@blindfold>

Pavel,

Am Donnerstag, 18. Januar 2018, 20:30:15 CET schrieb Pavel Machek:
> Hi!
> 
> Ubifs seems to have atime support these days:
> 
>           sb->s_flags |= SB_ACTIVE;
> #ifndef CONFIG_UBIFS_ATIME_SUPPORT
>           sb->s_flags |= SB_NOATIME;
> #else
>           ubifs_msg(c, "full atime support is enabled.");
> #endif
> 
> Which can be configured at compile-time, but no option to disable it
> at runtime. What is going on there?
> 
> UBIFS: parse noatime
> UBIFS error (ubi1:0 pid 94): ubifs_parse_options.constprop.5:
> unrecognized mount option "noatime" e
> mount: mounting ubi1:log_volume on /mnt/log failed: Invalid argument

Filesystems don't parse the "noatime" string, it is job of the mount tool to 
translate it to the MS_NOATIME mount flag.

Thanks,
//richard


From pavel at ucw.cz  Thu Jan 18 13:23:23 2018
From: pavel at ucw.cz (Pavel Machek)
Date: Thu, 18 Jan 2018 22:23:23 +0100
Subject: ubifs: noatime support?
In-Reply-To: <1996634.ggXeMYieCh@blindfold>
References: <20180118193015.GA24748@amd>
 <1996634.ggXeMYieCh@blindfold>
Message-ID: <20180118212323.GA17412@amd>

On Thu 2018-01-18 21:44:33, Richard Weinberger wrote:
> Pavel,
> 
> Am Donnerstag, 18. Januar 2018, 20:30:15 CET schrieb Pavel Machek:
> > Hi!
> > 
> > Ubifs seems to have atime support these days:
> > 
> >           sb->s_flags |= SB_ACTIVE;
> > #ifndef CONFIG_UBIFS_ATIME_SUPPORT
> >           sb->s_flags |= SB_NOATIME;
> > #else
> >           ubifs_msg(c, "full atime support is enabled.");
> > #endif
> > 
> > Which can be configured at compile-time, but no option to disable it
> > at runtime. What is going on there?
> > 
> > UBIFS: parse noatime
> > UBIFS error (ubi1:0 pid 94): ubifs_parse_options.constprop.5:
> > unrecognized mount option "noatime" e
> > mount: mounting ubi1:log_volume on /mnt/log failed: Invalid argument
> 
> Filesystems don't parse the "noatime" string, it is job of the mount tool to 
> translate it to the MS_NOATIME mount flag.

Ahha. I was using busybox version of mount. I guess I should check its
config. Thanks!
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20180118/c413be1d/attachment.sig>

From akpm at linux-foundation.org  Thu Jan 18 16:30:18 2018
From: akpm at linux-foundation.org (akpm at linux-foundation.org)
Date: Thu, 18 Jan 2018 16:30:18 -0800
Subject: [patch 1/1] include/linux/mtd/rawnand.h: fix build with gcc-4.4.4
Message-ID: <5a613c1a.p+Q5+DVAaEi8ctNz%akpm@linux-foundation.org>

From: Andrew Morton <akpm at linux-foundation.org>
Subject: include/linux/mtd/rawnand.h: fix build with gcc-4.4.4

gcc-4.4.4 has issues with anon union initializers.  Work aound this.

drivers/mtd/nand/marvell_nand.c:1936: warning: missing braces around initializer
drivers/mtd/nand/marvell_nand.c:1936: warning: (near initialization for '(anonymous)[1].<anonymous>')
drivers/mtd/nand/marvell_nand.c:1936: error: unknown field 'data' specified in initializer
drivers/mtd/nand/marvell_nand.c:1936: error: unknown field 'addr' specified in initializer
drivers/mtd/nand/marvell_nand.c:1936: warning: missing braces around initializer
drivers/mtd/nand/marvell_nand.c:1936: warning: (near initialization for '(anonymous)[1].<anonymous>')
drivers/mtd/nand/marvell_nand.c:1936: error: unknown field 'data' specified in initializer
drivers/mtd/nand/marvell_nand.c:1936: error: unknown field 'addr' specified in i

Fixes: 02f26ecf8c77275 ("mtd: nand: add reworked Marvell NAND controller driver")
Cc: Miquel Raynal <miquel.raynal at free-electrons.com>
Cc: Sean Nyekjaer <sean.nyekjaer at prevas.dk>
Cc: Willy Tarreau <w at 1wt.eu>
Cc: Boris Brezillon <boris.brezillon at free-electrons.com>
Cc: Richard Weinberger <richard at nod.at>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 include/linux/mtd/rawnand.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff -puN include/linux/mtd/rawnand.h~include-linux-mtd-rawnandh-fix-build-with-gcc-444 include/linux/mtd/rawnand.h
--- a/include/linux/mtd/rawnand.h~include-linux-mtd-rawnandh-fix-build-with-gcc-444
+++ a/include/linux/mtd/rawnand.h
@@ -975,21 +975,21 @@ struct nand_op_parser_pattern_elem {
 	{							\
 		.type = NAND_OP_ADDR_INSTR,			\
 		.optional = _opt,				\
-		.addr.maxcycles = _maxcycles,			\
+		{ .addr = { .maxcycles = _maxcycles }, },	\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_IN_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_IN_INSTR,			\
 		.optional = _opt,				\
-		.data.maxlen = _maxlen,				\
+		{ .data = { .maxlen = _maxlen, }, },		\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_OUT_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_OUT_INSTR,			\
 		.optional = _opt,				\
-		.data.maxlen = _maxlen,				\
+		{ .data = { .maxlen = _maxlen, }, },		\
 	}
 
 #define NAND_OP_PARSER_PAT_WAITRDY_ELEM(_opt)			\
_


From miquel.raynal at free-electrons.com  Thu Jan 18 23:39:52 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 08:39:52 +0100
Subject: [PATCH][next] mtd: nand: fix spelling mistake: "suceed"->
 "succeed"
In-Reply-To: <5A5DDCA0.1000908@bfs.de>
References: <20180116102808.23232-1-colin.king@canonical.com>
 <5A5DDCA0.1000908@bfs.de>
Message-ID: <20180119083952.23c4baeb@xps13>

Hello,

Can you please change the prefix, it should be:

mtd: nand: marvell:

On Tue, 16 Jan
2018 12:06:08 +0100 walter harms <wharms at bfs.de> wrote:

> Am 16.01.2018 11:28, schrieb Colin King:
> > From: Colin Ian King <colin.king at canonical.com>
> > 
> > Trivial fix to spelling mistakes in dev_err error message text.
> > 
> > Signed-off-by: Colin Ian King <colin.king at canonical.com>
> > ---
> >  drivers/mtd/nand/marvell_nand.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/marvell_nand.c
> > b/drivers/mtd/nand/marvell_nand.c index b8fec6093b75..4bd53b360277
> > 100644 --- a/drivers/mtd/nand/marvell_nand.c
> > +++ b/drivers/mtd/nand/marvell_nand.c
> > @@ -517,7 +517,7 @@ static int marvell_nfc_prepare_cmd(struct
> > nand_chip *chip) /* Poll ND_RUN and clear NDSR before issuing any
> > command */ ret = marvell_nfc_wait_ndrun(chip);
> >  	if (ret) {
> > -		dev_err(nfc->dev, "Last operation did not
> > suceed\n");
> > +		dev_err(nfc->dev, "Last operation did not
> > succeed\n"); return ret;
> >  	}
> >    
> 
> not succeed == Failed ??

I personally do not have a preference, as long as there is a clear
error message in this case.

> someone who is debugging may also interessted to know what operation
> failed.

It is not as easy to do, but starting from enabling dynamic debug in
both the driver and the NAND core should give you enough traces to
locate the issue.

Thanks,
Miqu?l


From miquel.raynal at free-electrons.com  Thu Jan 18 23:41:18 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 08:41:18 +0100
Subject: [PATCH][next] mtd: nand: remove redundant variable 'oob_len'
In-Reply-To: <20180116125748.26042-1-colin.king@canonical.com>
References: <20180116125748.26042-1-colin.king@canonical.com>
Message-ID: <20180119084118.3450d47f@xps13>

Hello,

On Tue, 16 Jan 2018 12:57:48 +0000
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Variable oob_len is assigned and never read, hence it is redundant and
> can be removed.
> 
> Cleans up clang warnings:
> 
> drivers/mtd/nand/marvell_nand.c:1356:6: warning: Value stored to
> 'oob_len' during its initialization is never read
> drivers/mtd/nand/marvell_nand.c:1369:4: warning: Value stored to
> 'oob_len' is never read
> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---

Same as before, can you change the prefix to:

mtd: nand: marvell:

Thank you,
Miqu?l



From colin.king at canonical.com  Thu Jan 18 23:55:31 2018
From: colin.king at canonical.com (Colin King)
Date: Fri, 19 Jan 2018 07:55:31 +0000
Subject: [PATCH][V2] mtd: nand: marvell: fix spelling mistake: "suceed"->
 "succeed"
Message-ID: <20180119075531.14841-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Trivial fix to spelling mistakes in dev_err error message text.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/mtd/nand/marvell_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
index b8fec6093b75..4bd53b360277 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -517,7 +517,7 @@ static int marvell_nfc_prepare_cmd(struct nand_chip *chip)
 	/* Poll ND_RUN and clear NDSR before issuing any command */
 	ret = marvell_nfc_wait_ndrun(chip);
 	if (ret) {
-		dev_err(nfc->dev, "Last operation did not suceed\n");
+		dev_err(nfc->dev, "Last operation did not succeed\n");
 		return ret;
 	}
 
-- 
2.15.1



From colin.king at canonical.com  Thu Jan 18 23:59:54 2018
From: colin.king at canonical.com (Colin King)
Date: Fri, 19 Jan 2018 07:59:54 +0000
Subject: [PATCH][V2] mtd: nand: marvell: remove redundant variable 'oob_len'
Message-ID: <20180119075954.15009-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Variable oob_len is assigned and never read, hence it is redundant and
can be removed.

Cleans up clang warnings:

drivers/mtd/nand/marvell_nand.c:1356:6: warning: Value stored to 'oob_len'
during its initialization is never read
drivers/mtd/nand/marvell_nand.c:1369:4: warning: Value stored to 'oob_len'
is never read

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/mtd/nand/marvell_nand.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
index 4bd53b360277..f15ab37edf4e 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -1353,7 +1353,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
 	int data_len = lt->data_bytes;
 	int spare_len = lt->spare_bytes;
 	int ecc_len = lt->ecc_bytes;
-	int oob_len = spare_len + ecc_len;
 	int spare_offset = 0;
 	int ecc_offset = (lt->full_chunk_cnt * lt->spare_bytes) +
 		lt->last_spare_bytes;
@@ -1366,7 +1365,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
 			data_len = lt->last_data_bytes;
 			spare_len = lt->last_spare_bytes;
 			ecc_len = lt->last_ecc_bytes;
-			oob_len = spare_len + ecc_len;
 		}
 
 		/* Point to the column of the next chunk */
-- 
2.15.1



From miquel.raynal at free-electrons.com  Fri Jan 19 00:04:48 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 09:04:48 +0100
Subject: [PATCH][V2] mtd: nand: marvell: fix spelling mistake:
 "suceed"-> "succeed"
In-Reply-To: <20180119075531.14841-1-colin.king@canonical.com>
References: <20180119075531.14841-1-colin.king@canonical.com>
Message-ID: <20180119090448.07352020@xps13>

Hello,

On Fri, 19 Jan 2018 07:55:31 +0000
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Trivial fix to spelling mistakes in dev_err error message text.
> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  drivers/mtd/nand/marvell_nand.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
> index b8fec6093b75..4bd53b360277 100644
> --- a/drivers/mtd/nand/marvell_nand.c
> +++ b/drivers/mtd/nand/marvell_nand.c
> @@ -517,7 +517,7 @@ static int marvell_nfc_prepare_cmd(struct nand_chip *chip)
>  	/* Poll ND_RUN and clear NDSR before issuing any command */
>  	ret = marvell_nfc_wait_ndrun(chip);
>  	if (ret) {
> -		dev_err(nfc->dev, "Last operation did not suceed\n");
> +		dev_err(nfc->dev, "Last operation did not succeed\n");
>  		return ret;
>  	}
>  

Acked-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Thanks,
Miqu?l


From miquel.raynal at free-electrons.com  Fri Jan 19 00:05:18 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 09:05:18 +0100
Subject: [PATCH][V2] mtd: nand: marvell: remove redundant variable
 'oob_len'
In-Reply-To: <20180119075954.15009-1-colin.king@canonical.com>
References: <20180119075954.15009-1-colin.king@canonical.com>
Message-ID: <20180119090518.619e3d44@xps13>

Hello,

On Fri, 19 Jan 2018 07:59:54 +0000
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Variable oob_len is assigned and never read, hence it is redundant and
> can be removed.
> 
> Cleans up clang warnings:
> 
> drivers/mtd/nand/marvell_nand.c:1356:6: warning: Value stored to 'oob_len'
> during its initialization is never read
> drivers/mtd/nand/marvell_nand.c:1369:4: warning: Value stored to 'oob_len'
> is never read
> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  drivers/mtd/nand/marvell_nand.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
> index 4bd53b360277..f15ab37edf4e 100644
> --- a/drivers/mtd/nand/marvell_nand.c
> +++ b/drivers/mtd/nand/marvell_nand.c
> @@ -1353,7 +1353,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
>  	int data_len = lt->data_bytes;
>  	int spare_len = lt->spare_bytes;
>  	int ecc_len = lt->ecc_bytes;
> -	int oob_len = spare_len + ecc_len;
>  	int spare_offset = 0;
>  	int ecc_offset = (lt->full_chunk_cnt * lt->spare_bytes) +
>  		lt->last_spare_bytes;
> @@ -1366,7 +1365,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
>  			data_len = lt->last_data_bytes;
>  			spare_len = lt->last_spare_bytes;
>  			ecc_len = lt->last_ecc_bytes;
> -			oob_len = spare_len + ecc_len;
>  		}
>  
>  		/* Point to the column of the next chunk */


Acked-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Thanks,
Miqu?l


From yogeshnarayan.gaur at nxp.com  Fri Jan 19 00:50:42 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Fri, 19 Jan 2018 14:20:42 +0530
Subject: [PATCH v4 0/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
Message-ID: <1516351844-9497-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has 4 chip select and one can use different flashes
on all different chip select.
We analyzed that the flashes have different parameters for the same command
and this is true for NAND devices.
Also reg_protocol information, needed for read register, read any register
commands, read SFDP register, not available at time of spi_nor_scan.
As FSL QUADSPI controller has limitation in number of LUT entries, max 16,
thus require to have dynamic LUT creation support.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also fix initialize sequence of AHB read, move
fsl_qspi_init_ahb_read() in  fsl_qspi_nor_setup() function.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: add support to create dynamic LUT entry
  mtd: fsl-quadspi: fix init AHB read in  fsl_qspi_nor_setup()

Changes for v4:
- Drop patch
'mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4', it
would be taken care in next-series.
- Added patch for 'fix initialize sequence of AHB read'.

Changes for v3:
- Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
- Update information in cover letter.

Changes for v2:
- Swap patch sequences in the series to solve git bissect issue.

 drivers/mtd/spi-nor/fsl-quadspi.c | 299 ++++++++++++++++++++------------------
 1 file changed, 155 insertions(+), 144 deletions(-)

-- 
1.9.1



From miquel.raynal at free-electrons.com  Fri Jan 19 01:25:45 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 10:25:45 +0100
Subject: [PATCH v2 0/2] Migrate the GPMI driver to use NAND core timings
Message-ID: <20180119092547.26873-1-miquel.raynal@free-electrons.com>

Hello,

The GPMI NAND controller driver has its own timings logic while the core
also has its own that should be preferred to avoid code duplication.
This series migrates the driver to use the ->setup_data_interface()
hook, preferred way to handle timings negotiation between controllers
and NAND chips.

This driver has stronger requirements in terms of respect of the ONFI
specification than the core has, and last time I post changes to this
section this was raised to me. Hence, the first patch effectively
applies the same requirements to the core. Doing this can slow down
several chips that do not follow entirely the specifications, but
another series is coming to add the possibility for NAND vendors to
flag certain features as "unsupported". See

    "mtd: nand: Check ONFI timings have been acked by the chip"

commit log for more details.

Thank you,
Miqu?l


Changes since v1:
=================
  - Removed inline on non-static gpmi_enable/disable_clk() functions.
  - Rewording some lines of the patch.
  - Use tREA_max value provided by the core instead of a locally defined
    value.
  - Check ->conf in gpmi_setup_data_interface() instead of
    ->onfi_timing_mode_default (use tRC).
  - Removed useless copy of hw.timing_mode.
  - Moved gpmi_nfc_apply_timings() to ->select_chip().
  - Canceled the useless move of one structure.

One comment is not addressed here: using one register for TIMING0/1 and
CTRL1 that is only written in ->apply_timings(). This will be done in a
later patch that will update the way timings are derived.


Miquel Raynal (2):
  mtd: nand: Check ONFI timings have been acked by the chip
  mtd: nand: gpmi: Support ->setup_data_interface()

 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 275 +++++++++------------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  43 ++++--
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  82 +++++-----
 drivers/mtd/nand/nand_base.c           |  41 ++++-
 4 files changed, 183 insertions(+), 258 deletions(-)

-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 01:25:47 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 10:25:47 +0100
Subject: [PATCH v2 2/2] mtd: nand: gpmi: Support ->setup_data_interface()
In-Reply-To: <20180119092547.26873-1-miquel.raynal@free-electrons.com>
References: <20180119092547.26873-1-miquel.raynal@free-electrons.com>
Message-ID: <20180119092547.26873-3-miquel.raynal@free-electrons.com>

Until now the GPMI driver had its own timings logic while the core
already handles that and request the NAND controller drivers to support
the ->setup_data_interface() hook. Implement that hook by reusing the
already existing function. No real glue is necessary between core timing
delays and GPMI registers because the driver already translates the
ONFI timing modes into register values.

Make use of the core's tREA, tRLOH and tRHOH values that allow computing
more precise timings for mode [0-3] and get significantly better values
(+20% with an i.MX6 Sabre Auto board). Otherwise use the existing logic.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 275 +++++++++------------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  43 ++++--
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  82 +++++-----
 3 files changed, 149 insertions(+), 251 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 97787246af41..4c773bff6e71 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -151,8 +151,15 @@ static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
 	return ret;
 }
 
-#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
-#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
+int gpmi_enable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, true);
+}
+
+int gpmi_disable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, false);
+}
 
 int gpmi_init(struct gpmi_nand_data *this)
 {
@@ -326,14 +333,13 @@ static unsigned int ns_to_cycles(unsigned int time,
 #define DEF_MIN_PROP_DELAY	5
 #define DEF_MAX_PROP_DELAY	9
 /* Apply timing to current hardware conditions. */
-static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
-					struct gpmi_nfc_hardware_timing *hw)
+static void
+gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
 {
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	struct timing_threshold *nfc = &timing_default_threshold;
-	struct resources *r = &this->resources;
 	struct nand_chip *nand = &this->nand;
 	struct nand_timing target = this->timing;
-	bool improved_timing_is_available;
 	unsigned long clock_frequency_in_hz;
 	unsigned int clock_period_in_ns;
 	bool dll_use_half_periods;
@@ -349,6 +355,9 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY;
 	unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY;
 
+	/* Clock rate for non-EDO modes */
+	hw->clk_rate = 22000000;
+
 	/*
 	 * If there are multiple chips, we need to relax the timings to allow
 	 * for signal distortion due to higher capacitance.
@@ -363,14 +372,8 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 		target.address_setup_in_ns += 5;
 	}
 
-	/* Check if improved timing information is available. */
-	improved_timing_is_available =
-		(target.tREA_in_ns  >= 0) &&
-		(target.tRLOH_in_ns >= 0) &&
-		(target.tRHOH_in_ns >= 0);
-
 	/* Inspect the clock. */
-	nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
+	nfc->clock_frequency_in_hz = hw->clk_rate;
 	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
 	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
 
@@ -482,65 +485,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	}
 
 	/*
-	 * Check if improved timing information is available. If not, we have to
-	 * use a less-sophisticated algorithm.
-	 */
-	if (!improved_timing_is_available) {
-		/*
-		 * Fold the read setup time required by the NFC into the ideal
-		 * sample delay.
-		 */
-		ideal_sample_delay_in_ns = target.gpmi_sample_delay_in_ns +
-						nfc->internal_data_setup_in_ns;
-
-		/*
-		 * The ideal sample delay may be greater than the maximum
-		 * allowed by the NFC. If so, we can trade off sample delay time
-		 * for more data setup time.
-		 *
-		 * In each iteration of the following loop, we add a cycle to
-		 * the data setup time and subtract a corresponding amount from
-		 * the sample delay until we've satisified the constraints or
-		 * can't do any better.
-		 */
-		while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-
-			data_setup_in_cycles++;
-			ideal_sample_delay_in_ns -= clock_period_in_ns;
-
-			if (ideal_sample_delay_in_ns < 0)
-				ideal_sample_delay_in_ns = 0;
-
-		}
-
-		/*
-		 * Compute the sample delay factor that corresponds most closely
-		 * to the ideal sample delay. If the result is too large for the
-		 * NFC, use the maximum value.
-		 *
-		 * Notice that we use the ns_to_cycles function to compute the
-		 * sample delay factor. We do this because the form of the
-		 * computation is the same as that for calculating cycles.
-		 */
-		sample_delay_factor =
-			ns_to_cycles(
-				ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-		if (sample_delay_factor > nfc->max_sample_delay_factor)
-			sample_delay_factor = nfc->max_sample_delay_factor;
-
-		/* Skip to the part where we return our results. */
-		goto return_results;
-	}
-
-	/*
-	 * If control arrives here, we have more detailed timing information,
-	 * so we can use a better algorithm.
-	 */
-
-	/*
 	 * Fold the read setup time required by the NFC into the maximum
 	 * propagation delay.
 	 */
@@ -760,8 +704,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 			sample_delay_factor = nfc->max_sample_delay_factor;
 	}
 
-	/* Control arrives here when we're ready to return our results. */
-return_results:
 	hw->data_setup_in_cycles    = data_setup_in_cycles;
 	hw->data_hold_in_cycles     = data_hold_in_cycles;
 	hw->address_setup_in_cycles = address_setup_in_cycles;
@@ -769,9 +711,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	hw->sample_delay_factor     = sample_delay_factor;
 	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
 	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
-
-	/* Return success. */
-	return 0;
 }
 
 /*
@@ -857,19 +796,17 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
  *       So we only support the mode 4 and mode 5. It is no need to
  *       support other modes.
  */
-static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
-			struct gpmi_nfc_hardware_timing *hw)
+static void gpmi_nfc_compute_edo_timings(struct gpmi_nand_data *this,
+					 int mode)
 {
-	struct resources *r = &this->resources;
-	unsigned long rate = clk_get_rate(r->clock[0]);
-	int mode = this->timing_mode;
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	int dll_threshold = this->devdata->max_chain_delay;
 	unsigned long delay;
 	unsigned long clk_period;
-	int t_rea;
-	int c = 4;
-	int t_rp;
-	int rp;
+	int t_rp, t_rea, rp;
+
+	/* Set the main clock to: 100MHz (mode 5) or 80MHz (mode 4) */
+	hw->clk_rate = (mode == 5) ? 100000000 : 80000000;
 
 	/*
 	 * [1] for GPMI_HW_GPMI_TIMING0:
@@ -880,7 +817,7 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 */
 	hw->data_setup_in_cycles = 1;
 	hw->data_hold_in_cycles = 1;
-	hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
+	hw->address_setup_in_cycles = (mode == 5) ? 1 : 0;
 
 	/* [2] for GPMI_HW_GPMI_TIMING1 */
 	hw->device_busy_timeout = 0x9000;
@@ -892,11 +829,9 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 * Enlarge 10 times for the numerator and denominator in {3}.
 	 * This make us to get more accurate result.
 	 */
-	clk_period = NSEC_PER_SEC / (rate / 10);
+	clk_period = NSEC_PER_SEC / (hw->clk_rate / 10);
 	dll_threshold *= 10;
-	t_rea = ((mode == 5) ? 16 : 20) * 10;
-	c *= 10;
-
+	t_rea = this->timing.tREA_in_ns * 10;
 	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
 
 	if (clk_period > dll_threshold) {
@@ -911,129 +846,42 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 * Multiply the numerator with 10, we could do a round off:
 	 *      7.8 round up to 8; 7.4 round down to 7.
 	 */
-	delay  = (((t_rea + c - t_rp) * 8) * 10) / rp;
+	delay  = (((t_rea + 40 - t_rp) * 8) * 10) / rp;
 	delay = (delay + 5) / 10;
 
 	hw->sample_delay_factor = delay;
 }
 
-static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
-{
-	struct resources  *r = &this->resources;
-	struct nand_chip *nand = &this->nand;
-	struct mtd_info	 *mtd = nand_to_mtd(nand);
-	uint8_t *feature;
-	unsigned long rate;
-	int ret;
-
-	feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
-	if (!feature)
-		return -ENOMEM;
-
-	nand->select_chip(mtd, 0);
-
-	/* [1] send SET FEATURE command to NAND */
-	feature[0] = mode;
-	ret = nand->onfi_set_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret)
-		goto err_out;
-
-	/* [2] send GET FEATURE command to double-check the timing mode */
-	memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
-	ret = nand->onfi_get_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret || feature[0] != mode)
-		goto err_out;
-
-	nand->select_chip(mtd, -1);
-
-	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
-	rate = (mode == 5) ? 100000000 : 80000000;
-	clk_set_rate(r->clock[0], rate);
-
-	/* Let the gpmi_begin() re-compute the timing again. */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
-
-	this->flags |= GPMI_ASYNC_EDO_ENABLED;
-	this->timing_mode = mode;
-	kfree(feature);
-	dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
-	return 0;
-
-err_out:
-	nand->select_chip(mtd, -1);
-	kfree(feature);
-	dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
-	return -EINVAL;
-}
-
-int gpmi_extra_init(struct gpmi_nand_data *this)
-{
-	struct nand_chip *chip = &this->nand;
-
-	/* Enable the asynchronous EDO feature. */
-	if (GPMI_IS_MX6(this) && chip->onfi_version) {
-		int mode = onfi_get_async_timing_mode(chip);
-
-		/* We only support the timing mode 4 and mode 5. */
-		if (mode & ONFI_TIMING_MODE_5)
-			mode = 5;
-		else if (mode & ONFI_TIMING_MODE_4)
-			mode = 4;
-		else
-			return 0;
-
-		return enable_edo_mode(this, mode);
-	}
-	return 0;
-}
-
 /* Begin the I/O */
-void gpmi_begin(struct gpmi_nand_data *this)
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
 {
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	struct resources *r = &this->resources;
 	void __iomem *gpmi_regs = r->gpmi_regs;
 	unsigned int   clock_period_in_ns;
 	uint32_t       reg;
 	unsigned int   dll_wait_time_in_us;
-	struct gpmi_nfc_hardware_timing  hw;
-	int ret;
-
-	/* Enable the clock. */
-	ret = gpmi_enable_clk(this);
-	if (ret) {
-		dev_err(this->dev, "We failed in enable the clk\n");
-		goto err_out;
-	}
 
-	/* Only initialize the timing once */
-	if (this->flags & GPMI_TIMING_INIT_OK)
-		return;
-	this->flags |= GPMI_TIMING_INIT_OK;
-
-	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
-		gpmi_compute_edo_timing(this, &hw);
-	else
-		gpmi_nfc_compute_hardware_timing(this, &hw);
+	/* [0] Set the main clock rate */
+	clk_set_rate(r->clock[0], hw->clk_rate);
 
 	/* [1] Set HW_GPMI_TIMING0 */
-	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
-		BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
-		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
+	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw->address_setup_in_cycles) |
+		BF_GPMI_TIMING0_DATA_HOLD(hw->data_hold_in_cycles) |
+		BF_GPMI_TIMING0_DATA_SETUP(hw->data_setup_in_cycles);
 
 	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
 
 	/* [2] Set HW_GPMI_TIMING1 */
-	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
-		gpmi_regs + HW_GPMI_TIMING1);
+	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw->device_busy_timeout),
+	       gpmi_regs + HW_GPMI_TIMING1);
 
 	/* [3] The following code is to set the HW_GPMI_CTRL1. */
 
 	/* Set the WRN_DLY_SEL */
 	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
-	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
-					gpmi_regs + HW_GPMI_CTRL1_SET);
+	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw->wrn_dly_sel),
+	       gpmi_regs + HW_GPMI_CTRL1_SET);
 
 	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
 	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
@@ -1043,12 +891,12 @@ void gpmi_begin(struct gpmi_nand_data *this)
 	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
 
 	/* If no sample delay is called for, return immediately. */
-	if (!hw.sample_delay_factor)
+	if (!hw->sample_delay_factor)
 		return;
 
 	/* Set RDN_DELAY or HALF_PERIOD. */
-	reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
-		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
+	reg = ((hw->use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
+		| BF_GPMI_CTRL1_RDN_DELAY(hw->sample_delay_factor);
 
 	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
 
@@ -1060,7 +908,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
 	 * we can use the GPMI. Calculate the amount of time we need to wait,
 	 * in microseconds.
 	 */
-	clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
+	clock_period_in_ns = NSEC_PER_SEC / hw->clk_rate;
 	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
 
 	if (!dll_wait_time_in_us)
@@ -1068,14 +916,43 @@ void gpmi_begin(struct gpmi_nand_data *this)
 
 	/* Wait for the DLL to settle. */
 	udelay(dll_wait_time_in_us);
-
-err_out:
-	return;
 }
 
-void gpmi_end(struct gpmi_nand_data *this)
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf)
 {
-	gpmi_disable_clk(this);
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	const struct nand_sdr_timings *sdr;
+	bool edo_mode = false;
+
+	/* Retrieve required NAND timings */
+	sdr = nand_get_sdr_timings(conf);
+	if (IS_ERR(sdr))
+		return PTR_ERR(sdr);
+
+	if (sdr->tRC_min <= 25000)
+		edo_mode = true;
+
+	/* Only MX6 GPMI controller can reach EDO timings */
+	if (edo_mode && !GPMI_IS_MX6(this))
+		return -ENOTSUPP;
+
+	if (chipnr < 0)
+		return 0;
+
+	this->timing.tREA_in_ns = sdr->tREA_max / 1000;
+	this->timing.tRLOH_in_ns = sdr->tRLOH_min / 1000;
+	this->timing.tRHOH_in_ns = sdr->tRHOH_min / 1000;
+
+	/* Compute GPMI parameters depending on the mode */
+	if (edo_mode)
+		gpmi_nfc_compute_edo_timings(this,
+					     sdr->tRC_min > 20000 ? 4 : 5);
+	else
+		gpmi_nfc_compute_hardware_timings(this);
+
+	return 0;
 }
 
 /* Clears a BCH interrupt. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index b51db8c85405..a3db75c27348 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -938,11 +938,32 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	int ret;
 
-	if ((this->current_chip < 0) && (chipnr >= 0))
-		gpmi_begin(this);
-	else if ((this->current_chip >= 0) && (chipnr < 0))
-		gpmi_end(this);
+	/*
+	 * For power consumption matters, disable/enable the clock each time a
+	 * die is selected/unselected.
+	 */
+	if (this->current_chip < 0 && chipnr >= 0) {
+		ret = gpmi_enable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to enable the clock\n");
+	} else if (this->current_chip >= 0 && chipnr < 0) {
+		ret = gpmi_disable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to disable the clock\n");
+	}
+
+	/*
+	 * This driver currently supports only one NAND chip. Plus, dies share
+	 * the same configuration. So once timings have been applied on the
+	 * controller side, they will not change anymore. When the time will
+	 * come, the check on must_apply_timings will have to be dropped.
+	 */
+	if (chipnr > 0 && this->hw.must_apply_timings) {
+		this->hw.must_apply_timings = false;
+		gpmi_nfc_apply_timings(this);
+	}
 
 	this->current_chip = chipnr;
 }
@@ -1947,14 +1968,6 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
 		chip->options |= NAND_SUBPAGE_READ;
 	}
 
-	/*
-	 * Can we enable the extra features? such as EDO or Sync mode.
-	 *
-	 * We do not check the return value now. That's means if we fail in
-	 * enable the extra features, we still can run in the normal way.
-	 */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 
@@ -1975,6 +1988,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
 	nand_set_controller_data(chip, this);
 	nand_set_flash_node(chip, this->pdev->dev.of_node);
 	chip->select_chip	= gpmi_select_chip;
+	chip->setup_data_interface = gpmi_setup_data_interface;
 	chip->cmd_ctrl		= gpmi_cmd_ctrl;
 	chip->dev_ready		= gpmi_dev_ready;
 	chip->read_byte		= gpmi_read_byte;
@@ -2080,6 +2094,7 @@ static int gpmi_nand_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, this);
 	this->pdev  = pdev;
 	this->dev   = &pdev->dev;
+	this->hw.must_apply_timings = true;
 
 	ret = acquire_resources(this);
 	if (ret)
@@ -2133,7 +2148,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 
 	/* re-init the GPMI registers */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
 	ret = gpmi_init(this);
 	if (ret) {
 		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
@@ -2147,9 +2161,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 	}
 
-	/* re-init others */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 06c1f993912c..23f9030cf6d2 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -135,11 +135,47 @@ struct gpmi_devdata {
 	const int clks_count;
 };
 
+/**
+ * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
+ * @timing_mode:               The timing mode to comply with.
+ * @must_apply_timings:        Whether controller timings have already been
+ *                             applied or not (useful only while there is
+ *                             support for only one chip select)
+ * @clk_rate:                  The clock rate that must be used to derive the
+ *                             following parameters.
+ * @data_setup_in_cycles:      The data setup time, in cycles.
+ * @data_hold_in_cycles:       The data hold time, in cycles.
+ * @address_setup_in_cycles:   The address setup time, in cycles.
+ * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
+ *                             this value is the number of cycles multiplied
+ *                             by 4096.
+ * @use_half_periods:          Indicates the clock is running slowly, so the
+ *                             NFC DLL should use half-periods.
+ * @sample_delay_factor:       The sample delay factor.
+ * @wrn_dly_sel:               The delay on the GPMI write strobe.
+ */
+struct gpmi_nfc_hardware_timing {
+	unsigned int timing_mode;
+	bool must_apply_timings;
+	unsigned long int clk_rate;
+
+	/* for HW_GPMI_TIMING0 */
+	u8 data_setup_in_cycles;
+	u8 data_hold_in_cycles;
+	u8 address_setup_in_cycles;
+
+	/* for HW_GPMI_TIMING1 */
+	u16 device_busy_timeout;
+#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
+
+	/* for HW_GPMI_CTRL1 */
+	bool use_half_periods;
+	u8 sample_delay_factor;
+	u8 wrn_dly_sel;
+};
+
 struct gpmi_nand_data {
-	/* flags */
-#define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
-#define GPMI_TIMING_INIT_OK	(1 << 1)
-	int			flags;
+	/* Devdata */
 	const struct gpmi_devdata *devdata;
 
 	/* System Interface */
@@ -152,6 +188,7 @@ struct gpmi_nand_data {
 	/* Flash Hardware */
 	struct nand_timing	timing;
 	int			timing_mode;
+	struct gpmi_nfc_hardware_timing hw;
 
 	/* BCH */
 	struct bch_geometry	bch_geometry;
@@ -205,35 +242,6 @@ struct gpmi_nand_data {
 };
 
 /**
- * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
- * @data_setup_in_cycles:      The data setup time, in cycles.
- * @data_hold_in_cycles:       The data hold time, in cycles.
- * @address_setup_in_cycles:   The address setup time, in cycles.
- * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
- *                             this value is the number of cycles multiplied
- *                             by 4096.
- * @use_half_periods:          Indicates the clock is running slowly, so the
- *                             NFC DLL should use half-periods.
- * @sample_delay_factor:       The sample delay factor.
- * @wrn_dly_sel:               The delay on the GPMI write strobe.
- */
-struct gpmi_nfc_hardware_timing {
-	/* for HW_GPMI_TIMING0 */
-	uint8_t  data_setup_in_cycles;
-	uint8_t  data_hold_in_cycles;
-	uint8_t  address_setup_in_cycles;
-
-	/* for HW_GPMI_TIMING1 */
-	uint16_t device_busy_timeout;
-#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
-
-	/* for HW_GPMI_CTRL1 */
-	bool     use_half_periods;
-	uint8_t  sample_delay_factor;
-	uint8_t  wrn_dly_sel;
-};
-
-/**
  * struct timing_threshold - Timing threshold
  * @max_data_setup_cycles:       The maximum number of data setup cycles that
  *                               can be expressed in the hardware.
@@ -279,14 +287,16 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *,
 
 /* GPMI-NAND helper function library */
 int gpmi_init(struct gpmi_nand_data *);
-int gpmi_extra_init(struct gpmi_nand_data *);
 void gpmi_clear_bch(struct gpmi_nand_data *);
 void gpmi_dump_info(struct gpmi_nand_data *);
 int bch_set_geometry(struct gpmi_nand_data *);
 int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
 int gpmi_send_command(struct gpmi_nand_data *);
-void gpmi_begin(struct gpmi_nand_data *);
-void gpmi_end(struct gpmi_nand_data *);
+int gpmi_enable_clk(struct gpmi_nand_data *this);
+int gpmi_disable_clk(struct gpmi_nand_data *this);
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf);
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this);
 int gpmi_read_data(struct gpmi_nand_data *);
 int gpmi_send_data(struct gpmi_nand_data *);
 int gpmi_send_page(struct gpmi_nand_data *,
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 01:25:46 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 10:25:46 +0100
Subject: [PATCH v2 1/2] mtd: nand: Check ONFI timings have been acked by the
 chip
In-Reply-To: <20180119092547.26873-1-miquel.raynal@free-electrons.com>
References: <20180119092547.26873-1-miquel.raynal@free-electrons.com>
Message-ID: <20180119092547.26873-2-miquel.raynal@free-electrons.com>

Choosing ONFI timings when ->onfi_set/get_features() calls are supported
by the NAND chip is a matter of reading the chip's ONFI parameter page
and telling the chip the chosen mode (between all of the supported ones)
with ->onfi_set_feature().

Add a check on whether the chip "acked" the timing mode or not.

This can be a problem for NAND chips that do not follow entirely the
ONFI specification. These chips actually support other modes than
"mode 0", but do not update the parameter page once a timing mode has
been selected. This issue will be addressed in another patch that will
add the feature to overwrite NAND chips features within the parameter
page, from the NAND chip driver.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/nand_base.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 96c97588e1ba..e209a65a17e0 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1231,15 +1231,47 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
 			chip->onfi_timing_mode_default,
 		};
 
+		chip->select_chip(mtd, chipnr);
 		ret = chip->onfi_set_features(mtd, chip,
 				ONFI_FEATURE_ADDR_TIMING_MODE,
 				tmode_param);
+		chip->select_chip(mtd, -1);
 		if (ret)
-			goto err;
+			return ret;
 	}
 
 	ret = chip->setup_data_interface(mtd, chipnr, &chip->data_interface);
-err:
+	if (ret)
+		return ret;
+
+	if (chip->onfi_version &&
+	    (le16_to_cpu(chip->onfi_params.opt_cmd) &
+	     ONFI_OPT_CMD_SET_GET_FEATURES)) {
+		u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {};
+
+		chip->select_chip(mtd, chipnr);
+		ret = chip->onfi_get_features(mtd, chip,
+					      ONFI_FEATURE_ADDR_TIMING_MODE,
+					      tmode_param);
+		chip->select_chip(mtd, -1);
+		if (ret)
+			goto err_reset_chip;
+
+		if (tmode_param[0] != chip->onfi_timing_mode_default) {
+			pr_warn("timings mode %d not acknowledged by the NAND chip\n",
+				chip->onfi_timing_mode_default);
+			goto err_reset_chip;
+		}
+	}
+
+	return 0;
+
+err_reset_chip:
+	onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0);
+	chip->select_chip(mtd, chipnr);
+	nand_reset_op(chip);
+	chip->select_chip(mtd, -1);
+
 	return ret;
 }
 
@@ -2738,10 +2770,8 @@ int nand_reset(struct nand_chip *chip, int chipnr)
 	if (ret)
 		return ret;
 
-	chip->select_chip(mtd, chipnr);
 	chip->data_interface = saved_data_intf;
 	ret = nand_setup_data_interface(chip, chipnr);
-	chip->select_chip(mtd, -1);
 	if (ret)
 		return ret;
 
@@ -6571,10 +6601,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 	/* Enter fastest possible mode on all dies. */
 	for (i = 0; i < chip->numchips; i++) {
-		chip->select_chip(mtd, i);
 		ret = nand_setup_data_interface(chip, i);
-		chip->select_chip(mtd, -1);
-
 		if (ret)
 			goto err_nand_manuf_cleanup;
 	}
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 02:19:24 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 11:19:24 +0100
Subject: [PATCH v2 2/2] mtd: nand: gpmi: Support ->setup_data_interface()
In-Reply-To: <20180119092547.26873-3-miquel.raynal@free-electrons.com>
References: <20180119092547.26873-1-miquel.raynal@free-electrons.com>
 <20180119092547.26873-3-miquel.raynal@free-electrons.com>
Message-ID: <20180119111924.24b43b27@xps13>

Hello,

On Fri, 19 Jan 2018 10:25:47 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Until now the GPMI driver had its own timings logic while the core
> already handles that and request the NAND controller drivers to support
> the ->setup_data_interface() hook. Implement that hook by reusing the
> already existing function. No real glue is necessary between core timing
> delays and GPMI registers because the driver already translates the
> ONFI timing modes into register values.
> 
> Make use of the core's tREA, tRLOH and tRHOH values that allow computing
> more precise timings for mode [0-3] and get significantly better values
> (+20% with an i.MX6 Sabre Auto board). Otherwise use the existing logic.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 275 +++++++++------------------------
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  43 ++++--
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  82 +++++-----
>  3 files changed, 149 insertions(+), 251 deletions(-)
> 

[...]

> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index b51db8c85405..a3db75c27348 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -938,11 +938,32 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
>  {

[...]

> +	/*
> +	 * This driver currently supports only one NAND chip. Plus, dies share
> +	 * the same configuration. So once timings have been applied on the
> +	 * controller side, they will not change anymore. When the time will
> +	 * come, the check on must_apply_timings will have to be dropped.
> +	 */
> +	if (chipnr > 0 && this->hw.must_apply_timings) {

I realized after sending that performances were actually bad, it is
because this line is wrong twice: the chipnr may be 0, and
hw.must_apply_timings must be reset after a ->setup_data_interface().

> +		this->hw.must_apply_timings = false;
> +		gpmi_nfc_apply_timings(this);
> +	}

I will send a v3, sorry for the noise.

Regards,
Miqu?l


From miquel.raynal at free-electrons.com  Fri Jan 19 05:58:53 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 14:58:53 +0100
Subject: [PATCH v3 0/2] Migrate the GPMI driver to use NAND core timings
Message-ID: <20180119135855.10673-1-miquel.raynal@free-electrons.com>

Hello,

The GPMI NAND controller driver has its own timings logic while the core
also has its own that should be preferred to avoid code duplication.
This series migrates the driver to use the ->setup_data_interface()
hook, preferred way to handle timings negotiation between controllers
and NAND chips.

This driver has stronger requirements in terms of respect of the ONFI
specification than the core has, and last time I post changes to this
section this was raised to me. Hence, the first patch effectively
applies the same requirements to the core. Doing this can slow down
several chips that do not follow entirely the specifications, but
another series is coming to add the possibility for NAND vendors to
flag certain features as "unsupported". See

    "mtd: nand: Check ONFI timings have been acked by the chip"

commit log for more details.

Thank you,
Miqu?l


Changes since v2:
=================
  - Fix ->select_chip(): chipnr == 0 is valid.
  - Fix ->select_chip(): hw.must_apply_timings must be reset after a
    ->setup_data_interface().

Changes since v1:
=================
  - Removed inline on non-static gpmi_enable/disable_clk() functions.
  - Rewording some lines of the patch.
  - Use tREA_max value provided by the core instead of a locally defined
    value.
  - Check ->conf in gpmi_setup_data_interface() instead of
    ->onfi_timing_mode_default (use tRC).
  - Removed useless copy of hw.timing_mode.
  - Moved gpmi_nfc_apply_timings() to ->select_chip().
  - Canceled the useless move of one structure.

One comment is not addressed here: using one register for TIMING0/1 and
CTRL1 that is only written in ->apply_timings(). This will be done in a
later patch that will update the way timings are derived.


Miquel Raynal (2):
  mtd: nand: Check ONFI timings have been acked by the chip
  mtd: nand: gpmi: Support ->setup_data_interface()

 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 277 ++++++++++-----------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  42 +++--
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  82 +++++-----
 drivers/mtd/nand/nand_base.c           |  42 ++++-
 4 files changed, 185 insertions(+), 258 deletions(-)

-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 05:58:54 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 14:58:54 +0100
Subject: [PATCH v3 1/2] mtd: nand: Check ONFI timings have been acked by the
 chip
In-Reply-To: <20180119135855.10673-1-miquel.raynal@free-electrons.com>
References: <20180119135855.10673-1-miquel.raynal@free-electrons.com>
Message-ID: <20180119135855.10673-2-miquel.raynal@free-electrons.com>

Choosing ONFI timings when ->onfi_set/get_features() calls are supported
by the NAND chip is a matter of reading the chip's ONFI parameter page
and telling the chip the chosen mode (between all of the supported ones)
with ->onfi_set_feature().

Add a check on whether the chip "acked" the timing mode or not.

This can be a problem for NAND chips that do not follow entirely the
ONFI specification. These chips actually support other modes than
"mode 0", but do not update the parameter page once a timing mode has
been selected. This issue will be addressed in another patch that will
add the feature to overwrite NAND chips features within the parameter
page, from the NAND chip driver.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/nand_base.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 96c97588e1ba..e209a65a17e0 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1231,15 +1231,47 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
 			chip->onfi_timing_mode_default,
 		};
 
+		chip->select_chip(mtd, chipnr);
 		ret = chip->onfi_set_features(mtd, chip,
 				ONFI_FEATURE_ADDR_TIMING_MODE,
 				tmode_param);
+		chip->select_chip(mtd, -1);
 		if (ret)
-			goto err;
+			return ret;
 	}
 
 	ret = chip->setup_data_interface(mtd, chipnr, &chip->data_interface);
-err:
+	if (ret)
+		return ret;
+
+	if (chip->onfi_version &&
+	    (le16_to_cpu(chip->onfi_params.opt_cmd) &
+	     ONFI_OPT_CMD_SET_GET_FEATURES)) {
+		u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {};
+
+		chip->select_chip(mtd, chipnr);
+		ret = chip->onfi_get_features(mtd, chip,
+					      ONFI_FEATURE_ADDR_TIMING_MODE,
+					      tmode_param);
+		chip->select_chip(mtd, -1);
+		if (ret)
+			goto err_reset_chip;
+
+		if (tmode_param[0] != chip->onfi_timing_mode_default) {
+			pr_warn("timings mode %d not acknowledged by the NAND chip\n",
+				chip->onfi_timing_mode_default);
+			goto err_reset_chip;
+		}
+	}
+
+	return 0;
+
+err_reset_chip:
+	onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0);
+	chip->select_chip(mtd, chipnr);
+	nand_reset_op(chip);
+	chip->select_chip(mtd, -1);
+
 	return ret;
 }
 
@@ -2738,10 +2770,8 @@ int nand_reset(struct nand_chip *chip, int chipnr)
 	if (ret)
 		return ret;
 
-	chip->select_chip(mtd, chipnr);
 	chip->data_interface = saved_data_intf;
 	ret = nand_setup_data_interface(chip, chipnr);
-	chip->select_chip(mtd, -1);
 	if (ret)
 		return ret;
 
@@ -6571,10 +6601,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 	/* Enter fastest possible mode on all dies. */
 	for (i = 0; i < chip->numchips; i++) {
-		chip->select_chip(mtd, i);
 		ret = nand_setup_data_interface(chip, i);
-		chip->select_chip(mtd, -1);
-
 		if (ret)
 			goto err_nand_manuf_cleanup;
 	}
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 05:58:55 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 14:58:55 +0100
Subject: [PATCH v3 2/2] mtd: nand: gpmi: Support ->setup_data_interface()
In-Reply-To: <20180119135855.10673-1-miquel.raynal@free-electrons.com>
References: <20180119135855.10673-1-miquel.raynal@free-electrons.com>
Message-ID: <20180119135855.10673-3-miquel.raynal@free-electrons.com>

Until now the GPMI driver had its own timings logic while the core
already handles that and request the NAND controller drivers to support
the ->setup_data_interface() hook. Implement that hook by reusing the
already existing function. No real glue is necessary between core timing
delays and GPMI registers because the driver already translates the
ONFI timing modes into register values.

Make use of the core's tREA, tRLOH and tRHOH values that allow computing
more precise timings for mode [0-3] and get significantly better values
(+20% with an i.MX6 Sabre Auto board). Otherwise use the existing logic.

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 277 ++++++++++-----------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  42 +++--
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  82 +++++-----
 drivers/mtd/nand/nand_base.c           |   3 +-
 4 files changed, 152 insertions(+), 252 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 97787246af41..9a58661eb3b1 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -151,8 +151,15 @@ static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
 	return ret;
 }
 
-#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
-#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
+int gpmi_enable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, true);
+}
+
+int gpmi_disable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, false);
+}
 
 int gpmi_init(struct gpmi_nand_data *this)
 {
@@ -326,14 +333,13 @@ static unsigned int ns_to_cycles(unsigned int time,
 #define DEF_MIN_PROP_DELAY	5
 #define DEF_MAX_PROP_DELAY	9
 /* Apply timing to current hardware conditions. */
-static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
-					struct gpmi_nfc_hardware_timing *hw)
+static void
+gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
 {
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	struct timing_threshold *nfc = &timing_default_threshold;
-	struct resources *r = &this->resources;
 	struct nand_chip *nand = &this->nand;
 	struct nand_timing target = this->timing;
-	bool improved_timing_is_available;
 	unsigned long clock_frequency_in_hz;
 	unsigned int clock_period_in_ns;
 	bool dll_use_half_periods;
@@ -349,6 +355,9 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY;
 	unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY;
 
+	/* Clock rate for non-EDO modes */
+	hw->clk_rate = 22000000;
+
 	/*
 	 * If there are multiple chips, we need to relax the timings to allow
 	 * for signal distortion due to higher capacitance.
@@ -363,14 +372,8 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 		target.address_setup_in_ns += 5;
 	}
 
-	/* Check if improved timing information is available. */
-	improved_timing_is_available =
-		(target.tREA_in_ns  >= 0) &&
-		(target.tRLOH_in_ns >= 0) &&
-		(target.tRHOH_in_ns >= 0);
-
 	/* Inspect the clock. */
-	nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
+	nfc->clock_frequency_in_hz = hw->clk_rate;
 	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
 	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
 
@@ -482,65 +485,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	}
 
 	/*
-	 * Check if improved timing information is available. If not, we have to
-	 * use a less-sophisticated algorithm.
-	 */
-	if (!improved_timing_is_available) {
-		/*
-		 * Fold the read setup time required by the NFC into the ideal
-		 * sample delay.
-		 */
-		ideal_sample_delay_in_ns = target.gpmi_sample_delay_in_ns +
-						nfc->internal_data_setup_in_ns;
-
-		/*
-		 * The ideal sample delay may be greater than the maximum
-		 * allowed by the NFC. If so, we can trade off sample delay time
-		 * for more data setup time.
-		 *
-		 * In each iteration of the following loop, we add a cycle to
-		 * the data setup time and subtract a corresponding amount from
-		 * the sample delay until we've satisified the constraints or
-		 * can't do any better.
-		 */
-		while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-
-			data_setup_in_cycles++;
-			ideal_sample_delay_in_ns -= clock_period_in_ns;
-
-			if (ideal_sample_delay_in_ns < 0)
-				ideal_sample_delay_in_ns = 0;
-
-		}
-
-		/*
-		 * Compute the sample delay factor that corresponds most closely
-		 * to the ideal sample delay. If the result is too large for the
-		 * NFC, use the maximum value.
-		 *
-		 * Notice that we use the ns_to_cycles function to compute the
-		 * sample delay factor. We do this because the form of the
-		 * computation is the same as that for calculating cycles.
-		 */
-		sample_delay_factor =
-			ns_to_cycles(
-				ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-		if (sample_delay_factor > nfc->max_sample_delay_factor)
-			sample_delay_factor = nfc->max_sample_delay_factor;
-
-		/* Skip to the part where we return our results. */
-		goto return_results;
-	}
-
-	/*
-	 * If control arrives here, we have more detailed timing information,
-	 * so we can use a better algorithm.
-	 */
-
-	/*
 	 * Fold the read setup time required by the NFC into the maximum
 	 * propagation delay.
 	 */
@@ -760,8 +704,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 			sample_delay_factor = nfc->max_sample_delay_factor;
 	}
 
-	/* Control arrives here when we're ready to return our results. */
-return_results:
 	hw->data_setup_in_cycles    = data_setup_in_cycles;
 	hw->data_hold_in_cycles     = data_hold_in_cycles;
 	hw->address_setup_in_cycles = address_setup_in_cycles;
@@ -769,9 +711,6 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
 	hw->sample_delay_factor     = sample_delay_factor;
 	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
 	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
-
-	/* Return success. */
-	return 0;
 }
 
 /*
@@ -857,19 +796,17 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
  *       So we only support the mode 4 and mode 5. It is no need to
  *       support other modes.
  */
-static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
-			struct gpmi_nfc_hardware_timing *hw)
+static void gpmi_nfc_compute_edo_timings(struct gpmi_nand_data *this,
+					 int mode)
 {
-	struct resources *r = &this->resources;
-	unsigned long rate = clk_get_rate(r->clock[0]);
-	int mode = this->timing_mode;
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	int dll_threshold = this->devdata->max_chain_delay;
 	unsigned long delay;
 	unsigned long clk_period;
-	int t_rea;
-	int c = 4;
-	int t_rp;
-	int rp;
+	int t_rp, t_rea, rp;
+
+	/* Set the main clock to: 100MHz (mode 5) or 80MHz (mode 4) */
+	hw->clk_rate = (mode == 5) ? 100000000 : 80000000;
 
 	/*
 	 * [1] for GPMI_HW_GPMI_TIMING0:
@@ -880,7 +817,7 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 */
 	hw->data_setup_in_cycles = 1;
 	hw->data_hold_in_cycles = 1;
-	hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
+	hw->address_setup_in_cycles = (mode == 5) ? 1 : 0;
 
 	/* [2] for GPMI_HW_GPMI_TIMING1 */
 	hw->device_busy_timeout = 0x9000;
@@ -892,11 +829,9 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 * Enlarge 10 times for the numerator and denominator in {3}.
 	 * This make us to get more accurate result.
 	 */
-	clk_period = NSEC_PER_SEC / (rate / 10);
+	clk_period = NSEC_PER_SEC / (hw->clk_rate / 10);
 	dll_threshold *= 10;
-	t_rea = ((mode == 5) ? 16 : 20) * 10;
-	c *= 10;
-
+	t_rea = this->timing.tREA_in_ns * 10;
 	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
 
 	if (clk_period > dll_threshold) {
@@ -911,129 +846,42 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
 	 * Multiply the numerator with 10, we could do a round off:
 	 *      7.8 round up to 8; 7.4 round down to 7.
 	 */
-	delay  = (((t_rea + c - t_rp) * 8) * 10) / rp;
+	delay  = (((t_rea + 40 - t_rp) * 8) * 10) / rp;
 	delay = (delay + 5) / 10;
 
 	hw->sample_delay_factor = delay;
 }
 
-static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
-{
-	struct resources  *r = &this->resources;
-	struct nand_chip *nand = &this->nand;
-	struct mtd_info	 *mtd = nand_to_mtd(nand);
-	uint8_t *feature;
-	unsigned long rate;
-	int ret;
-
-	feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
-	if (!feature)
-		return -ENOMEM;
-
-	nand->select_chip(mtd, 0);
-
-	/* [1] send SET FEATURE command to NAND */
-	feature[0] = mode;
-	ret = nand->onfi_set_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret)
-		goto err_out;
-
-	/* [2] send GET FEATURE command to double-check the timing mode */
-	memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
-	ret = nand->onfi_get_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret || feature[0] != mode)
-		goto err_out;
-
-	nand->select_chip(mtd, -1);
-
-	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
-	rate = (mode == 5) ? 100000000 : 80000000;
-	clk_set_rate(r->clock[0], rate);
-
-	/* Let the gpmi_begin() re-compute the timing again. */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
-
-	this->flags |= GPMI_ASYNC_EDO_ENABLED;
-	this->timing_mode = mode;
-	kfree(feature);
-	dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
-	return 0;
-
-err_out:
-	nand->select_chip(mtd, -1);
-	kfree(feature);
-	dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
-	return -EINVAL;
-}
-
-int gpmi_extra_init(struct gpmi_nand_data *this)
-{
-	struct nand_chip *chip = &this->nand;
-
-	/* Enable the asynchronous EDO feature. */
-	if (GPMI_IS_MX6(this) && chip->onfi_version) {
-		int mode = onfi_get_async_timing_mode(chip);
-
-		/* We only support the timing mode 4 and mode 5. */
-		if (mode & ONFI_TIMING_MODE_5)
-			mode = 5;
-		else if (mode & ONFI_TIMING_MODE_4)
-			mode = 4;
-		else
-			return 0;
-
-		return enable_edo_mode(this, mode);
-	}
-	return 0;
-}
-
 /* Begin the I/O */
-void gpmi_begin(struct gpmi_nand_data *this)
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
 {
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	struct resources *r = &this->resources;
 	void __iomem *gpmi_regs = r->gpmi_regs;
 	unsigned int   clock_period_in_ns;
 	uint32_t       reg;
 	unsigned int   dll_wait_time_in_us;
-	struct gpmi_nfc_hardware_timing  hw;
-	int ret;
-
-	/* Enable the clock. */
-	ret = gpmi_enable_clk(this);
-	if (ret) {
-		dev_err(this->dev, "We failed in enable the clk\n");
-		goto err_out;
-	}
 
-	/* Only initialize the timing once */
-	if (this->flags & GPMI_TIMING_INIT_OK)
-		return;
-	this->flags |= GPMI_TIMING_INIT_OK;
-
-	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
-		gpmi_compute_edo_timing(this, &hw);
-	else
-		gpmi_nfc_compute_hardware_timing(this, &hw);
+	/* [0] Set the main clock rate */
+	clk_set_rate(r->clock[0], hw->clk_rate);
 
 	/* [1] Set HW_GPMI_TIMING0 */
-	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
-		BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
-		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
+	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw->address_setup_in_cycles) |
+		BF_GPMI_TIMING0_DATA_HOLD(hw->data_hold_in_cycles) |
+		BF_GPMI_TIMING0_DATA_SETUP(hw->data_setup_in_cycles);
 
 	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
 
 	/* [2] Set HW_GPMI_TIMING1 */
-	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
-		gpmi_regs + HW_GPMI_TIMING1);
+	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw->device_busy_timeout),
+	       gpmi_regs + HW_GPMI_TIMING1);
 
 	/* [3] The following code is to set the HW_GPMI_CTRL1. */
 
 	/* Set the WRN_DLY_SEL */
 	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
-	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
-					gpmi_regs + HW_GPMI_CTRL1_SET);
+	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw->wrn_dly_sel),
+	       gpmi_regs + HW_GPMI_CTRL1_SET);
 
 	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
 	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
@@ -1043,12 +891,12 @@ void gpmi_begin(struct gpmi_nand_data *this)
 	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
 
 	/* If no sample delay is called for, return immediately. */
-	if (!hw.sample_delay_factor)
+	if (!hw->sample_delay_factor)
 		return;
 
 	/* Set RDN_DELAY or HALF_PERIOD. */
-	reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
-		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
+	reg = ((hw->use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
+		| BF_GPMI_CTRL1_RDN_DELAY(hw->sample_delay_factor);
 
 	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
 
@@ -1060,7 +908,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
 	 * we can use the GPMI. Calculate the amount of time we need to wait,
 	 * in microseconds.
 	 */
-	clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
+	clock_period_in_ns = NSEC_PER_SEC / hw->clk_rate;
 	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
 
 	if (!dll_wait_time_in_us)
@@ -1068,14 +916,45 @@ void gpmi_begin(struct gpmi_nand_data *this)
 
 	/* Wait for the DLL to settle. */
 	udelay(dll_wait_time_in_us);
-
-err_out:
-	return;
 }
 
-void gpmi_end(struct gpmi_nand_data *this)
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf)
 {
-	gpmi_disable_clk(this);
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	const struct nand_sdr_timings *sdr;
+	bool edo_mode = false;
+
+	/* Retrieve required NAND timings */
+	sdr = nand_get_sdr_timings(conf);
+	if (IS_ERR(sdr))
+		return PTR_ERR(sdr);
+
+	if (sdr->tRC_min <= 25000)
+		edo_mode = true;
+
+	/* Only MX6 GPMI controller can reach EDO timings */
+	if (edo_mode && !GPMI_IS_MX6(this))
+		return -ENOTSUPP;
+
+	if (chipnr < 0)
+		return 0;
+
+	this->timing.tREA_in_ns = sdr->tREA_max / 1000;
+	this->timing.tRLOH_in_ns = sdr->tRLOH_min / 1000;
+	this->timing.tRHOH_in_ns = sdr->tRHOH_min / 1000;
+
+	/* Compute GPMI parameters depending on the mode */
+	if (edo_mode)
+		gpmi_nfc_compute_edo_timings(this,
+					     sdr->tRC_min > 20000 ? 4 : 5);
+	else
+		gpmi_nfc_compute_hardware_timings(this);
+
+	this->hw.must_apply_timings = true;
+
+	return 0;
 }
 
 /* Clears a BCH interrupt. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index b51db8c85405..459b7fb5e15b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -938,11 +938,32 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	int ret;
 
-	if ((this->current_chip < 0) && (chipnr >= 0))
-		gpmi_begin(this);
-	else if ((this->current_chip >= 0) && (chipnr < 0))
-		gpmi_end(this);
+	/*
+	 * For power consumption matters, disable/enable the clock each time a
+	 * die is selected/unselected.
+	 */
+	if (this->current_chip < 0 && chipnr >= 0) {
+		ret = gpmi_enable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to enable the clock\n");
+	} else if (this->current_chip >= 0 && chipnr < 0) {
+		ret = gpmi_disable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to disable the clock\n");
+	}
+
+	/*
+	 * This driver currently supports only one NAND chip. Plus, dies share
+	 * the same configuration. So once timings have been applied on the
+	 * controller side, they will not change anymore. When the time will
+	 * come, the check on must_apply_timings will have to be dropped.
+	 */
+	if (chipnr >= 0 && this->hw.must_apply_timings) {
+		this->hw.must_apply_timings = false;
+		gpmi_nfc_apply_timings(this);
+	}
 
 	this->current_chip = chipnr;
 }
@@ -1947,14 +1968,6 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
 		chip->options |= NAND_SUBPAGE_READ;
 	}
 
-	/*
-	 * Can we enable the extra features? such as EDO or Sync mode.
-	 *
-	 * We do not check the return value now. That's means if we fail in
-	 * enable the extra features, we still can run in the normal way.
-	 */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 
@@ -1975,6 +1988,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
 	nand_set_controller_data(chip, this);
 	nand_set_flash_node(chip, this->pdev->dev.of_node);
 	chip->select_chip	= gpmi_select_chip;
+	chip->setup_data_interface = gpmi_setup_data_interface;
 	chip->cmd_ctrl		= gpmi_cmd_ctrl;
 	chip->dev_ready		= gpmi_dev_ready;
 	chip->read_byte		= gpmi_read_byte;
@@ -2133,7 +2147,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 
 	/* re-init the GPMI registers */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
 	ret = gpmi_init(this);
 	if (ret) {
 		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
@@ -2147,9 +2160,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 	}
 
-	/* re-init others */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 06c1f993912c..23f9030cf6d2 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -135,11 +135,47 @@ struct gpmi_devdata {
 	const int clks_count;
 };
 
+/**
+ * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
+ * @timing_mode:               The timing mode to comply with.
+ * @must_apply_timings:        Whether controller timings have already been
+ *                             applied or not (useful only while there is
+ *                             support for only one chip select)
+ * @clk_rate:                  The clock rate that must be used to derive the
+ *                             following parameters.
+ * @data_setup_in_cycles:      The data setup time, in cycles.
+ * @data_hold_in_cycles:       The data hold time, in cycles.
+ * @address_setup_in_cycles:   The address setup time, in cycles.
+ * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
+ *                             this value is the number of cycles multiplied
+ *                             by 4096.
+ * @use_half_periods:          Indicates the clock is running slowly, so the
+ *                             NFC DLL should use half-periods.
+ * @sample_delay_factor:       The sample delay factor.
+ * @wrn_dly_sel:               The delay on the GPMI write strobe.
+ */
+struct gpmi_nfc_hardware_timing {
+	unsigned int timing_mode;
+	bool must_apply_timings;
+	unsigned long int clk_rate;
+
+	/* for HW_GPMI_TIMING0 */
+	u8 data_setup_in_cycles;
+	u8 data_hold_in_cycles;
+	u8 address_setup_in_cycles;
+
+	/* for HW_GPMI_TIMING1 */
+	u16 device_busy_timeout;
+#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
+
+	/* for HW_GPMI_CTRL1 */
+	bool use_half_periods;
+	u8 sample_delay_factor;
+	u8 wrn_dly_sel;
+};
+
 struct gpmi_nand_data {
-	/* flags */
-#define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
-#define GPMI_TIMING_INIT_OK	(1 << 1)
-	int			flags;
+	/* Devdata */
 	const struct gpmi_devdata *devdata;
 
 	/* System Interface */
@@ -152,6 +188,7 @@ struct gpmi_nand_data {
 	/* Flash Hardware */
 	struct nand_timing	timing;
 	int			timing_mode;
+	struct gpmi_nfc_hardware_timing hw;
 
 	/* BCH */
 	struct bch_geometry	bch_geometry;
@@ -205,35 +242,6 @@ struct gpmi_nand_data {
 };
 
 /**
- * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
- * @data_setup_in_cycles:      The data setup time, in cycles.
- * @data_hold_in_cycles:       The data hold time, in cycles.
- * @address_setup_in_cycles:   The address setup time, in cycles.
- * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
- *                             this value is the number of cycles multiplied
- *                             by 4096.
- * @use_half_periods:          Indicates the clock is running slowly, so the
- *                             NFC DLL should use half-periods.
- * @sample_delay_factor:       The sample delay factor.
- * @wrn_dly_sel:               The delay on the GPMI write strobe.
- */
-struct gpmi_nfc_hardware_timing {
-	/* for HW_GPMI_TIMING0 */
-	uint8_t  data_setup_in_cycles;
-	uint8_t  data_hold_in_cycles;
-	uint8_t  address_setup_in_cycles;
-
-	/* for HW_GPMI_TIMING1 */
-	uint16_t device_busy_timeout;
-#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
-
-	/* for HW_GPMI_CTRL1 */
-	bool     use_half_periods;
-	uint8_t  sample_delay_factor;
-	uint8_t  wrn_dly_sel;
-};
-
-/**
  * struct timing_threshold - Timing threshold
  * @max_data_setup_cycles:       The maximum number of data setup cycles that
  *                               can be expressed in the hardware.
@@ -279,14 +287,16 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *,
 
 /* GPMI-NAND helper function library */
 int gpmi_init(struct gpmi_nand_data *);
-int gpmi_extra_init(struct gpmi_nand_data *);
 void gpmi_clear_bch(struct gpmi_nand_data *);
 void gpmi_dump_info(struct gpmi_nand_data *);
 int bch_set_geometry(struct gpmi_nand_data *);
 int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
 int gpmi_send_command(struct gpmi_nand_data *);
-void gpmi_begin(struct gpmi_nand_data *);
-void gpmi_end(struct gpmi_nand_data *);
+int gpmi_enable_clk(struct gpmi_nand_data *this);
+int gpmi_disable_clk(struct gpmi_nand_data *this);
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf);
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this);
 int gpmi_read_data(struct gpmi_nand_data *);
 int gpmi_send_data(struct gpmi_nand_data *);
 int gpmi_send_page(struct gpmi_nand_data *,
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e209a65a17e0..9602d17845e2 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1267,7 +1267,8 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
 	return 0;
 
 err_reset_chip:
-	onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0);
+	/* Fallback to timing mode 0 */
+	nand_reset_data_interface(chip, chipnr);
 	chip->select_chip(mtd, chipnr);
 	nand_reset_op(chip);
 	chip->select_chip(mtd, -1);
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 06:11:06 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 15:11:06 +0100
Subject: [PATCH] mtd: nand: gpmi: Use core timings instead of an empirical
 derivation
Message-ID: <20180119141106.18067-1-miquel.raynal@free-electrons.com>

GPMI driver timings derivation looks very empirical and does not use
the known timings that the core wants to use with the NAND chip, by
using local defined constants that have no special meaning from the
outside world.

Simplify the way all of this is computed and use the NAND core's SDR
timings.

Integrity of the reads/writes has been checked with nandbiterrs, speed
improvements with flash_speed on a Freescale i.MX6 DualLite/Solo SABRE
Automotive Board. Measures are below, variations of less than 150kiB/s
between tests are common and then not significant. Speeds using mode 5
are the same, while speeds using mode 0 are quite improved (+40/50%
from non-optimal computation).

Forcing timings mode 0:
=======================

Before this patch:
------------------
eraseblock write speed is 2298 KiB/s
eraseblock read speed is 3636 KiB/s
page write speed is 2136 KiB/s
page read speed is 3316 KiB/s
2 page write speed is 2199 KiB/s
2 page read speed is 3468 KiB/s

After this patch:
-----------------
eraseblock write speed is 3232 KiB/s
eraseblock read speed is 5663 KiB/s
page write speed is 2915 KiB/s
page read speed is 4904 KiB/s
2 page write speed is 3084 KiB/s
2 page read speed is 5267 KiB/s

Forcing timings mode 5:
=======================

Before this patch:
------------------
eraseblock write speed is 4338 KiB/s
eraseblock read speed is 14883 KiB/s
page write speed is 3786 KiB/s
page read speed is 12800 KiB/s
2 page write speed is 4076 KiB/s
2 page read speed is 14065 KiB/s

After this patch:
-----------------
eraseblock write speed is 4309 KiB/s
eraseblock read speed is 14712 KiB/s
page write speed is 3764 KiB/s
page read speed is 12673 KiB/s
2 page write speed is 4076 KiB/s
2 page read speed is 14065 KiB/s

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---


Hello,

This patch applies after this series that adds support in the GPMI
driver for ->setup_data_interface() available at [1].

Thanks,
Miqu?l

[1] http://lists.infradead.org/pipermail/linux-mtd/2018-January/078924.html


 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  | 608 +++++----------------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  40 +--
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 103 +-----
 drivers/mtd/nand/gpmi-nand/gpmi-regs.h |   5 +
 4 files changed, 99 insertions(+), 657 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 9a58661eb3b1..d55e838f377d 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -26,15 +26,8 @@
 #include "gpmi-regs.h"
 #include "bch-regs.h"
 
-static struct timing_threshold timing_default_threshold = {
-	.max_data_setup_cycles       = (BM_GPMI_TIMING0_DATA_SETUP >>
-						BP_GPMI_TIMING0_DATA_SETUP),
-	.internal_data_setup_in_ns   = 0,
-	.max_sample_delay_factor     = (BM_GPMI_CTRL1_RDN_DELAY >>
-						BP_GPMI_CTRL1_RDN_DELAY),
-	.max_dll_clock_period_in_ns  = 32,
-	.max_dll_delay_in_ns         = 16,
-};
+/* Converts time to clock cycles */
+#define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period)
 
 #define MXS_SET_ADDR		0x4
 #define MXS_CLR_ADDR		0x8
@@ -181,7 +174,6 @@ int gpmi_init(struct gpmi_nand_data *this)
 	if (ret)
 		goto err_out;
 
-
 	/* Choose NAND mode. */
 	writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
 
@@ -320,399 +312,6 @@ int bch_set_geometry(struct gpmi_nand_data *this)
 	return ret;
 }
 
-/* Converts time in nanoseconds to cycles. */
-static unsigned int ns_to_cycles(unsigned int time,
-			unsigned int period, unsigned int min)
-{
-	unsigned int k;
-
-	k = (time + period - 1) / period;
-	return max(k, min);
-}
-
-#define DEF_MIN_PROP_DELAY	5
-#define DEF_MAX_PROP_DELAY	9
-/* Apply timing to current hardware conditions. */
-static void
-gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
-{
-	struct gpmi_nfc_hardware_timing *hw = &this->hw;
-	struct timing_threshold *nfc = &timing_default_threshold;
-	struct nand_chip *nand = &this->nand;
-	struct nand_timing target = this->timing;
-	unsigned long clock_frequency_in_hz;
-	unsigned int clock_period_in_ns;
-	bool dll_use_half_periods;
-	unsigned int dll_delay_shift;
-	unsigned int max_sample_delay_in_ns;
-	unsigned int address_setup_in_cycles;
-	unsigned int data_setup_in_ns;
-	unsigned int data_setup_in_cycles;
-	unsigned int data_hold_in_cycles;
-	int ideal_sample_delay_in_ns;
-	unsigned int sample_delay_factor;
-	int tEYE;
-	unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY;
-	unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY;
-
-	/* Clock rate for non-EDO modes */
-	hw->clk_rate = 22000000;
-
-	/*
-	 * If there are multiple chips, we need to relax the timings to allow
-	 * for signal distortion due to higher capacitance.
-	 */
-	if (nand->numchips > 2) {
-		target.data_setup_in_ns    += 10;
-		target.data_hold_in_ns     += 10;
-		target.address_setup_in_ns += 10;
-	} else if (nand->numchips > 1) {
-		target.data_setup_in_ns    += 5;
-		target.data_hold_in_ns     += 5;
-		target.address_setup_in_ns += 5;
-	}
-
-	/* Inspect the clock. */
-	nfc->clock_frequency_in_hz = hw->clk_rate;
-	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
-	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
-
-	/*
-	 * The NFC quantizes setup and hold parameters in terms of clock cycles.
-	 * Here, we quantize the setup and hold timing parameters to the
-	 * next-highest clock period to make sure we apply at least the
-	 * specified times.
-	 *
-	 * For data setup and data hold, the hardware interprets a value of zero
-	 * as the largest possible delay. This is not what's intended by a zero
-	 * in the input parameter, so we impose a minimum of one cycle.
-	 */
-	data_setup_in_cycles    = ns_to_cycles(target.data_setup_in_ns,
-							clock_period_in_ns, 1);
-	data_hold_in_cycles     = ns_to_cycles(target.data_hold_in_ns,
-							clock_period_in_ns, 1);
-	address_setup_in_cycles = ns_to_cycles(target.address_setup_in_ns,
-							clock_period_in_ns, 0);
-
-	/*
-	 * The clock's period affects the sample delay in a number of ways:
-	 *
-	 * (1) The NFC HAL tells us the maximum clock period the sample delay
-	 *     DLL can tolerate. If the clock period is greater than half that
-	 *     maximum, we must configure the DLL to be driven by half periods.
-	 *
-	 * (2) We need to convert from an ideal sample delay, in ns, to a
-	 *     "sample delay factor," which the NFC uses. This factor depends on
-	 *     whether we're driving the DLL with full or half periods.
-	 *     Paraphrasing the reference manual:
-	 *
-	 *         AD = SDF x 0.125 x RP
-	 *
-	 * where:
-	 *
-	 *     AD   is the applied delay, in ns.
-	 *     SDF  is the sample delay factor, which is dimensionless.
-	 *     RP   is the reference period, in ns, which is a full clock period
-	 *          if the DLL is being driven by full periods, or half that if
-	 *          the DLL is being driven by half periods.
-	 *
-	 * Let's re-arrange this in a way that's more useful to us:
-	 *
-	 *                        8
-	 *         SDF  =  AD x ----
-	 *                       RP
-	 *
-	 * The reference period is either the clock period or half that, so this
-	 * is:
-	 *
-	 *                        8       AD x DDF
-	 *         SDF  =  AD x -----  =  --------
-	 *                      f x P        P
-	 *
-	 * where:
-	 *
-	 *       f  is 1 or 1/2, depending on how we're driving the DLL.
-	 *       P  is the clock period.
-	 *     DDF  is the DLL Delay Factor, a dimensionless value that
-	 *          incorporates all the constants in the conversion.
-	 *
-	 * DDF will be either 8 or 16, both of which are powers of two. We can
-	 * reduce the cost of this conversion by using bit shifts instead of
-	 * multiplication or division. Thus:
-	 *
-	 *                 AD << DDS
-	 *         SDF  =  ---------
-	 *                     P
-	 *
-	 *     or
-	 *
-	 *         AD  =  (SDF >> DDS) x P
-	 *
-	 * where:
-	 *
-	 *     DDS  is the DLL Delay Shift, the logarithm to base 2 of the DDF.
-	 */
-	if (clock_period_in_ns > (nfc->max_dll_clock_period_in_ns >> 1)) {
-		dll_use_half_periods = true;
-		dll_delay_shift      = 3 + 1;
-	} else {
-		dll_use_half_periods = false;
-		dll_delay_shift      = 3;
-	}
-
-	/*
-	 * Compute the maximum sample delay the NFC allows, under current
-	 * conditions. If the clock is running too slowly, no sample delay is
-	 * possible.
-	 */
-	if (clock_period_in_ns > nfc->max_dll_clock_period_in_ns)
-		max_sample_delay_in_ns = 0;
-	else {
-		/*
-		 * Compute the delay implied by the largest sample delay factor
-		 * the NFC allows.
-		 */
-		max_sample_delay_in_ns =
-			(nfc->max_sample_delay_factor * clock_period_in_ns) >>
-								dll_delay_shift;
-
-		/*
-		 * Check if the implied sample delay larger than the NFC
-		 * actually allows.
-		 */
-		if (max_sample_delay_in_ns > nfc->max_dll_delay_in_ns)
-			max_sample_delay_in_ns = nfc->max_dll_delay_in_ns;
-	}
-
-	/*
-	 * Fold the read setup time required by the NFC into the maximum
-	 * propagation delay.
-	 */
-	max_prop_delay_in_ns += nfc->internal_data_setup_in_ns;
-
-	/*
-	 * Earlier, we computed the number of clock cycles required to satisfy
-	 * the data setup time. Now, we need to know the actual nanoseconds.
-	 */
-	data_setup_in_ns = clock_period_in_ns * data_setup_in_cycles;
-
-	/*
-	 * Compute tEYE, the width of the data eye when reading from the NAND
-	 * Flash. The eye width is fundamentally determined by the data setup
-	 * time, perturbed by propagation delays and some characteristics of the
-	 * NAND Flash device.
-	 *
-	 * start of the eye = max_prop_delay + tREA
-	 * end of the eye   = min_prop_delay + tRHOH + data_setup
-	 */
-	tEYE = (int)min_prop_delay_in_ns + (int)target.tRHOH_in_ns +
-							(int)data_setup_in_ns;
-
-	tEYE -= (int)max_prop_delay_in_ns + (int)target.tREA_in_ns;
-
-	/*
-	 * The eye must be open. If it's not, we can try to open it by
-	 * increasing its main forcer, the data setup time.
-	 *
-	 * In each iteration of the following loop, we increase the data setup
-	 * time by a single clock cycle. We do this until either the eye is
-	 * open or we run into NFC limits.
-	 */
-	while ((tEYE <= 0) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-	}
-
-	/*
-	 * When control arrives here, the eye is open. The ideal time to sample
-	 * the data is in the center of the eye:
-	 *
-	 *     end of the eye + start of the eye
-	 *     ---------------------------------  -  data_setup
-	 *                    2
-	 *
-	 * After some algebra, this simplifies to the code immediately below.
-	 */
-	ideal_sample_delay_in_ns =
-		((int)max_prop_delay_in_ns +
-			(int)target.tREA_in_ns +
-				(int)min_prop_delay_in_ns +
-					(int)target.tRHOH_in_ns -
-						(int)data_setup_in_ns) >> 1;
-
-	/*
-	 * The following figure illustrates some aspects of a NAND Flash read:
-	 *
-	 *
-	 *           __                   _____________________________________
-	 * RDN         \_________________/
-	 *
-	 *                                         <---- tEYE ----->
-	 *                                        /-----------------\
-	 * Read Data ----------------------------<                   >---------
-	 *                                        \-----------------/
-	 *             ^                 ^                 ^              ^
-	 *             |                 |                 |              |
-	 *             |<--Data Setup -->|<--Delay Time -->|              |
-	 *             |                 |                 |              |
-	 *             |                 |                                |
-	 *             |                 |<--   Quantized Delay Time   -->|
-	 *             |                 |                                |
-	 *
-	 *
-	 * We have some issues we must now address:
-	 *
-	 * (1) The *ideal* sample delay time must not be negative. If it is, we
-	 *     jam it to zero.
-	 *
-	 * (2) The *ideal* sample delay time must not be greater than that
-	 *     allowed by the NFC. If it is, we can increase the data setup
-	 *     time, which will reduce the delay between the end of the data
-	 *     setup and the center of the eye. It will also make the eye
-	 *     larger, which might help with the next issue...
-	 *
-	 * (3) The *quantized* sample delay time must not fall either before the
-	 *     eye opens or after it closes (the latter is the problem
-	 *     illustrated in the above figure).
-	 */
-
-	/* Jam a negative ideal sample delay to zero. */
-	if (ideal_sample_delay_in_ns < 0)
-		ideal_sample_delay_in_ns = 0;
-
-	/*
-	 * Extend the data setup as needed to reduce the ideal sample delay
-	 * below the maximum permitted by the NFC.
-	 */
-	while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-
-		/*
-		 * Decrease the ideal sample delay by one half cycle, to keep it
-		 * in the middle of the eye.
-		 */
-		ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
-
-		/* Jam a negative ideal sample delay to zero. */
-		if (ideal_sample_delay_in_ns < 0)
-			ideal_sample_delay_in_ns = 0;
-	}
-
-	/*
-	 * Compute the sample delay factor that corresponds to the ideal sample
-	 * delay. If the result is too large, then use the maximum allowed
-	 * value.
-	 *
-	 * Notice that we use the ns_to_cycles function to compute the sample
-	 * delay factor. We do this because the form of the computation is the
-	 * same as that for calculating cycles.
-	 */
-	sample_delay_factor =
-		ns_to_cycles(ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-	if (sample_delay_factor > nfc->max_sample_delay_factor)
-		sample_delay_factor = nfc->max_sample_delay_factor;
-
-	/*
-	 * These macros conveniently encapsulate a computation we'll use to
-	 * continuously evaluate whether or not the data sample delay is inside
-	 * the eye.
-	 */
-	#define IDEAL_DELAY  ((int) ideal_sample_delay_in_ns)
-
-	#define QUANTIZED_DELAY  \
-		((int) ((sample_delay_factor * clock_period_in_ns) >> \
-							dll_delay_shift))
-
-	#define DELAY_ERROR  (abs(QUANTIZED_DELAY - IDEAL_DELAY))
-
-	#define SAMPLE_IS_NOT_WITHIN_THE_EYE  (DELAY_ERROR > (tEYE >> 1))
-
-	/*
-	 * While the quantized sample time falls outside the eye, reduce the
-	 * sample delay or extend the data setup to move the sampling point back
-	 * toward the eye. Do not allow the number of data setup cycles to
-	 * exceed the maximum allowed by the NFC.
-	 */
-	while (SAMPLE_IS_NOT_WITHIN_THE_EYE &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-		/*
-		 * If control arrives here, the quantized sample delay falls
-		 * outside the eye. Check if it's before the eye opens, or after
-		 * the eye closes.
-		 */
-		if (QUANTIZED_DELAY > IDEAL_DELAY) {
-			/*
-			 * If control arrives here, the quantized sample delay
-			 * falls after the eye closes. Decrease the quantized
-			 * delay time and then go back to re-evaluate.
-			 */
-			if (sample_delay_factor != 0)
-				sample_delay_factor--;
-			continue;
-		}
-
-		/*
-		 * If control arrives here, the quantized sample delay falls
-		 * before the eye opens. Shift the sample point by increasing
-		 * data setup time. This will also make the eye larger.
-		 */
-
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-
-		/*
-		 * Decrease the ideal sample delay by one half cycle, to keep it
-		 * in the middle of the eye.
-		 */
-		ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
-
-		/* ...and one less period for the delay time. */
-		ideal_sample_delay_in_ns -= clock_period_in_ns;
-
-		/* Jam a negative ideal sample delay to zero. */
-		if (ideal_sample_delay_in_ns < 0)
-			ideal_sample_delay_in_ns = 0;
-
-		/*
-		 * We have a new ideal sample delay, so re-compute the quantized
-		 * delay.
-		 */
-		sample_delay_factor =
-			ns_to_cycles(
-				ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-		if (sample_delay_factor > nfc->max_sample_delay_factor)
-			sample_delay_factor = nfc->max_sample_delay_factor;
-	}
-
-	hw->data_setup_in_cycles    = data_setup_in_cycles;
-	hw->data_hold_in_cycles     = data_hold_in_cycles;
-	hw->address_setup_in_cycles = address_setup_in_cycles;
-	hw->use_half_periods        = dll_use_half_periods;
-	hw->sample_delay_factor     = sample_delay_factor;
-	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
-	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
-}
-
 /*
  * <1> Firstly, we should know what's the GPMI-clock means.
  *     The GPMI-clock is the internal clock in the gpmi nand controller.
@@ -763,13 +362,10 @@ gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
  *  4.1) From the aspect of the nand chip pins:
  *        Delay = (tREA + C - tRP)               {1}
  *
- *        tREA : the maximum read access time. From the ONFI nand standards,
- *               we know that tREA is 16ns in mode 5, tREA is 20ns is mode 4.
- *               Please check it in : www.onfi.org
- *        C    : a constant for adjust the delay. default is 4.
- *        tRP  : the read pulse width.
- *               Specified by the HW_GPMI_TIMING0:DATA_SETUP:
- *                    tRP = (GPMI-clock-period) * DATA_SETUP
+ *        tREA : the maximum read access time.
+ *        C    : a constant to adjust the delay. default is 4000ps.
+ *        tRP  : the read pulse width, which is exactly:
+ *                   tRP = (GPMI-clock-period) * DATA_SETUP
  *
  *  4.2) From the aspect of the GPMI nand controller:
  *         Delay = RDN_DELAY * 0.125 * RP        {2}
@@ -782,140 +378,109 @@ gpmi_nfc_compute_hardware_timings(struct gpmi_nand_data *this)
  *
  *            Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
  *            is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
- *            is 16ns, but in mx6q, we use 12ns.
+ *            is 16000ps, but in mx6q, we use 12000ps.
  *
  *  4.3) since {1} equals {2}, we get:
  *
- *                    (tREA + 4 - tRP) * 8
- *         RDN_DELAY = ---------------------     {3}
- *                           RP
- *
- *  4.4) We only support the fastest asynchronous mode of ONFI nand.
- *       For some ONFI nand, the mode 4 is the fastest mode;
- *       while for some ONFI nand, the mode 5 is the fastest mode.
- *       So we only support the mode 4 and mode 5. It is no need to
- *       support other modes.
+ *                     (tREA + 4000 - tRP) * 8
+ *         RDN_DELAY = -----------------------   {3}
+ *                                RP
  */
-static void gpmi_nfc_compute_edo_timings(struct gpmi_nand_data *this,
-					 int mode)
+static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
+				     const struct nand_sdr_timings *sdr)
 {
 	struct gpmi_nfc_hardware_timing *hw = &this->hw;
-	int dll_threshold = this->devdata->max_chain_delay;
-	unsigned long delay;
-	unsigned long clk_period;
-	int t_rp, t_rea, rp;
-
-	/* Set the main clock to: 100MHz (mode 5) or 80MHz (mode 4) */
-	hw->clk_rate = (mode == 5) ? 100000000 : 80000000;
+	unsigned int dll_threshold_ps = this->devdata->max_chain_delay;
+	unsigned int period_ps, reference_period_ps;
+	unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles;
+	unsigned int tRP_ps;
+	bool use_half_period;
+	int sample_delay_ps, sample_delay_factor;
+	u16 busy_timeout_cycles;
+	u8 wrn_dly_sel;
+
+	if (sdr->tRC_min >= 30000) {
+		/* ONFI non-EDO modes [0-3] */
+		hw->clk_rate = 22000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
+	} else if (sdr->tRC_min >= 25000) {
+		/* ONFI EDO mode 4 */
+		hw->clk_rate = 80000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+	} else {
+		/* ONFI EDO mode 5 */
+		hw->clk_rate = 100000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+	}
 
-	/*
-	 * [1] for GPMI_HW_GPMI_TIMING0:
-	 *     The async mode requires 40MHz for mode 4, 50MHz for mode 5.
-	 *     The GPMI can support 100MHz at most. So if we want to
-	 *     get the 40MHz or 50MHz, we have to set DS=1, DH=1.
-	 *     Set the ADDRESS_SETUP to 0 in mode 4.
-	 */
-	hw->data_setup_in_cycles = 1;
-	hw->data_hold_in_cycles = 1;
-	hw->address_setup_in_cycles = (mode == 5) ? 1 : 0;
+	/* SDR core timings are given in picoseconds */
+	period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate);
 
-	/* [2] for GPMI_HW_GPMI_TIMING1 */
-	hw->device_busy_timeout = 0x9000;
+	addr_setup_cycles = TO_CYCLES(sdr->tALS_min, period_ps);
+	data_setup_cycles = TO_CYCLES(sdr->tDS_min, period_ps);
+	data_hold_cycles = TO_CYCLES(sdr->tDH_min, period_ps);
+	busy_timeout_cycles = TO_CYCLES(sdr->tWB_max + sdr->tR_max, period_ps);
 
-	/* [3] for GPMI_HW_GPMI_CTRL1 */
-	hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+	hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) |
+		      BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) |
+		      BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles);
+	hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(busy_timeout_cycles * 4096);
 
 	/*
-	 * Enlarge 10 times for the numerator and denominator in {3}.
-	 * This make us to get more accurate result.
+	 * Derive NFC ideal delay from {3}:
+	 *
+	 *                     (tREA + 4000 - tRP) * 8
+	 *         RDN_DELAY = -----------------------
+	 *                                RP
 	 */
-	clk_period = NSEC_PER_SEC / (hw->clk_rate / 10);
-	dll_threshold *= 10;
-	t_rea = this->timing.tREA_in_ns * 10;
-	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
-
-	if (clk_period > dll_threshold) {
-		hw->use_half_periods = 1;
-		rp = clk_period / 2;
+	if (period_ps > dll_threshold_ps) {
+		use_half_period = true;
+		reference_period_ps = period_ps / 2;
 	} else {
-		hw->use_half_periods = 0;
-		rp = clk_period;
+		use_half_period = false;
+		reference_period_ps = period_ps;
 	}
 
-	/*
-	 * Multiply the numerator with 10, we could do a round off:
-	 *      7.8 round up to 8; 7.4 round down to 7.
-	 */
-	delay  = (((t_rea + 40 - t_rp) * 8) * 10) / rp;
-	delay = (delay + 5) / 10;
+	tRP_ps = data_setup_cycles * period_ps;
+	sample_delay_ps = (sdr->tREA_max + 4000 - tRP_ps) * 8;
+	if (sample_delay_ps > 0)
+		sample_delay_factor = sample_delay_ps / reference_period_ps;
+	else
+		sample_delay_factor = 0;
 
-	hw->sample_delay_factor = delay;
+	hw->ctrl1n = BF_GPMI_CTRL1_WRN_DLY_SEL(wrn_dly_sel);
+	if (sample_delay_factor)
+		hw->ctrl1n |= BF_GPMI_CTRL1_RDN_DELAY(sample_delay_factor) |
+			      BM_GPMI_CTRL1_DLL_ENABLE |
+			      (use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0);
 }
 
-/* Begin the I/O */
 void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
 {
 	struct gpmi_nfc_hardware_timing *hw = &this->hw;
 	struct resources *r = &this->resources;
 	void __iomem *gpmi_regs = r->gpmi_regs;
-	unsigned int   clock_period_in_ns;
-	uint32_t       reg;
-	unsigned int   dll_wait_time_in_us;
+	unsigned int dll_wait_time_us;
 
-	/* [0] Set the main clock rate */
 	clk_set_rate(r->clock[0], hw->clk_rate);
 
-	/* [1] Set HW_GPMI_TIMING0 */
-	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw->address_setup_in_cycles) |
-		BF_GPMI_TIMING0_DATA_HOLD(hw->data_hold_in_cycles) |
-		BF_GPMI_TIMING0_DATA_SETUP(hw->data_setup_in_cycles);
-
-	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
-
-	/* [2] Set HW_GPMI_TIMING1 */
-	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw->device_busy_timeout),
-	       gpmi_regs + HW_GPMI_TIMING1);
-
-	/* [3] The following code is to set the HW_GPMI_CTRL1. */
-
-	/* Set the WRN_DLY_SEL */
-	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
-	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw->wrn_dly_sel),
-	       gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
-	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
-
-	/* Clear out the DLL control fields. */
-	reg = BM_GPMI_CTRL1_RDN_DELAY | BM_GPMI_CTRL1_HALF_PERIOD;
-	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
-
-	/* If no sample delay is called for, return immediately. */
-	if (!hw->sample_delay_factor)
-		return;
-
-	/* Set RDN_DELAY or HALF_PERIOD. */
-	reg = ((hw->use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
-		| BF_GPMI_CTRL1_RDN_DELAY(hw->sample_delay_factor);
-
-	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* At last, we enable the DLL. */
-	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
+	writel(hw->timing0, gpmi_regs + HW_GPMI_TIMING0);
+	writel(hw->timing1, gpmi_regs + HW_GPMI_TIMING1);
 
 	/*
-	 * After we enable the GPMI DLL, we have to wait 64 clock cycles before
-	 * we can use the GPMI. Calculate the amount of time we need to wait,
-	 * in microseconds.
+	 * Clear several CTRL1 fields, DLL must be disabled when setting
+	 * RDN_DELAY or HALF_PERIOD.
 	 */
-	clock_period_in_ns = NSEC_PER_SEC / hw->clk_rate;
-	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
+	writel(BM_GPMI_CTRL1_CLEAR_MASK, gpmi_regs + HW_GPMI_CTRL1_CLR);
+	writel(hw->ctrl1n, gpmi_regs + HW_GPMI_CTRL1_SET);
 
-	if (!dll_wait_time_in_us)
-		dll_wait_time_in_us = 1;
+	/* Wait 64 clock cycles before using the GPMI after enabling the DLL */
+	dll_wait_time_us = USEC_PER_SEC / hw->clk_rate * 64;
+	if (!dll_wait_time_us)
+		dll_wait_time_us = 1;
 
 	/* Wait for the DLL to settle. */
-	udelay(dll_wait_time_in_us);
+	udelay(dll_wait_time_us);
 }
 
 int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
@@ -924,33 +489,22 @@ int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct gpmi_nand_data *this = nand_get_controller_data(chip);
 	const struct nand_sdr_timings *sdr;
-	bool edo_mode = false;
 
 	/* Retrieve required NAND timings */
 	sdr = nand_get_sdr_timings(conf);
 	if (IS_ERR(sdr))
 		return PTR_ERR(sdr);
 
-	if (sdr->tRC_min <= 25000)
-		edo_mode = true;
-
 	/* Only MX6 GPMI controller can reach EDO timings */
-	if (edo_mode && !GPMI_IS_MX6(this))
+	if (sdr->tRC_min <= 25000 && !GPMI_IS_MX6(this))
 		return -ENOTSUPP;
 
+	/* Stop here if this call was just a check */
 	if (chipnr < 0)
 		return 0;
 
-	this->timing.tREA_in_ns = sdr->tREA_max / 1000;
-	this->timing.tRLOH_in_ns = sdr->tRLOH_min / 1000;
-	this->timing.tRHOH_in_ns = sdr->tRHOH_min / 1000;
-
-	/* Compute GPMI parameters depending on the mode */
-	if (edo_mode)
-		gpmi_nfc_compute_edo_timings(this,
-					     sdr->tRC_min > 20000 ? 4 : 5);
-	else
-		gpmi_nfc_compute_hardware_timings(this);
+	/* Do the actual derivation of the controller timings */
+	gpmi_nfc_compute_timings(this, sdr);
 
 	this->hw.must_apply_timings = true;
 
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 459b7fb5e15b..553c6c1cb932 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -94,7 +94,7 @@ static const struct mtd_ooblayout_ops gpmi_ooblayout_ops = {
 static const struct gpmi_devdata gpmi_devdata_imx23 = {
 	.type = IS_MX23,
 	.bch_max_ecc_strength = 20,
-	.max_chain_delay = 16,
+	.max_chain_delay = 16000,
 	.clks = gpmi_clks_for_mx2x,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
 };
@@ -102,7 +102,7 @@ static const struct gpmi_devdata gpmi_devdata_imx23 = {
 static const struct gpmi_devdata gpmi_devdata_imx28 = {
 	.type = IS_MX28,
 	.bch_max_ecc_strength = 20,
-	.max_chain_delay = 16,
+	.max_chain_delay = 16000,
 	.clks = gpmi_clks_for_mx2x,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
 };
@@ -114,7 +114,7 @@ static const char * const gpmi_clks_for_mx6[] = {
 static const struct gpmi_devdata gpmi_devdata_imx6q = {
 	.type = IS_MX6Q,
 	.bch_max_ecc_strength = 40,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx6,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
@@ -122,7 +122,7 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
 static const struct gpmi_devdata gpmi_devdata_imx6sx = {
 	.type = IS_MX6SX,
 	.bch_max_ecc_strength = 62,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx6,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
@@ -134,7 +134,7 @@ static const char * const gpmi_clks_for_mx7d[] = {
 static const struct gpmi_devdata gpmi_devdata_imx7d = {
 	.type = IS_MX7D,
 	.bch_max_ecc_strength = 62,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx7d,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx7d),
 };
@@ -695,34 +695,6 @@ static void release_resources(struct gpmi_nand_data *this)
 	release_dma_channels(this);
 }
 
-static int init_hardware(struct gpmi_nand_data *this)
-{
-	int ret;
-
-	/*
-	 * This structure contains the "safe" GPMI timing that should succeed
-	 * with any NAND Flash device
-	 * (although, with less-than-optimal performance).
-	 */
-	struct nand_timing  safe_timing = {
-		.data_setup_in_ns        = 80,
-		.data_hold_in_ns         = 60,
-		.address_setup_in_ns     = 25,
-		.gpmi_sample_delay_in_ns =  6,
-		.tREA_in_ns              = -1,
-		.tRLOH_in_ns             = -1,
-		.tRHOH_in_ns             = -1,
-	};
-
-	/* Initialize the hardwares. */
-	ret = gpmi_init(this);
-	if (ret)
-		return ret;
-
-	this->timing = safe_timing;
-	return 0;
-}
-
 static int read_page_prepare(struct gpmi_nand_data *this,
 			void *destination, unsigned length,
 			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
@@ -2099,7 +2071,7 @@ static int gpmi_nand_probe(struct platform_device *pdev)
 	if (ret)
 		goto exit_acquire_resources;
 
-	ret = init_hardware(this);
+	ret = gpmi_init(this);
 	if (ret)
 		goto exit_nfc_init;
 
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 23f9030cf6d2..62fde59b995f 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -86,39 +86,6 @@ enum dma_ops_type {
 	DMA_FOR_WRITE_ECC_PAGE
 };
 
-/**
- * struct nand_timing - Fundamental timing attributes for NAND.
- * @data_setup_in_ns:         The data setup time, in nanoseconds. Usually the
- *                            maximum of tDS and tWP. A negative value
- *                            indicates this characteristic isn't known.
- * @data_hold_in_ns:          The data hold time, in nanoseconds. Usually the
- *                            maximum of tDH, tWH and tREH. A negative value
- *                            indicates this characteristic isn't known.
- * @address_setup_in_ns:      The address setup time, in nanoseconds. Usually
- *                            the maximum of tCLS, tCS and tALS. A negative
- *                            value indicates this characteristic isn't known.
- * @gpmi_sample_delay_in_ns:  A GPMI-specific timing parameter. A negative value
- *                            indicates this characteristic isn't known.
- * @tREA_in_ns:               tREA, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- * @tRLOH_in_ns:              tRLOH, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- * @tRHOH_in_ns:              tRHOH, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- */
-struct nand_timing {
-	int8_t  data_setup_in_ns;
-	int8_t  data_hold_in_ns;
-	int8_t  address_setup_in_ns;
-	int8_t  gpmi_sample_delay_in_ns;
-	int8_t  tREA_in_ns;
-	int8_t  tRLOH_in_ns;
-	int8_t  tRHOH_in_ns;
-};
-
 enum gpmi_type {
 	IS_MX23,
 	IS_MX28,
@@ -137,41 +104,21 @@ struct gpmi_devdata {
 
 /**
  * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
- * @timing_mode:               The timing mode to comply with.
  * @must_apply_timings:        Whether controller timings have already been
  *                             applied or not (useful only while there is
  *                             support for only one chip select)
  * @clk_rate:                  The clock rate that must be used to derive the
- *                             following parameters.
- * @data_setup_in_cycles:      The data setup time, in cycles.
- * @data_hold_in_cycles:       The data hold time, in cycles.
- * @address_setup_in_cycles:   The address setup time, in cycles.
- * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
- *                             this value is the number of cycles multiplied
- *                             by 4096.
- * @use_half_periods:          Indicates the clock is running slowly, so the
- *                             NFC DLL should use half-periods.
- * @sample_delay_factor:       The sample delay factor.
- * @wrn_dly_sel:               The delay on the GPMI write strobe.
+ *                             following parameters
+ * @timing0:                   HW_GPMI_TIMING0 register
+ * @timing1:                   HW_GPMI_TIMING1 register
+ * @ctrl1n:                    HW_GPMI_CTRL1n register
  */
 struct gpmi_nfc_hardware_timing {
-	unsigned int timing_mode;
 	bool must_apply_timings;
 	unsigned long int clk_rate;
-
-	/* for HW_GPMI_TIMING0 */
-	u8 data_setup_in_cycles;
-	u8 data_hold_in_cycles;
-	u8 address_setup_in_cycles;
-
-	/* for HW_GPMI_TIMING1 */
-	u16 device_busy_timeout;
-#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
-
-	/* for HW_GPMI_CTRL1 */
-	bool use_half_periods;
-	u8 sample_delay_factor;
-	u8 wrn_dly_sel;
+	u32 timing0;
+	u32 timing1;
+	u32 ctrl1n;
 };
 
 struct gpmi_nand_data {
@@ -186,8 +133,6 @@ struct gpmi_nand_data {
 	struct resources	resources;
 
 	/* Flash Hardware */
-	struct nand_timing	timing;
-	int			timing_mode;
 	struct gpmi_nfc_hardware_timing hw;
 
 	/* BCH */
@@ -241,40 +186,6 @@ struct gpmi_nand_data {
 	void			*private;
 };
 
-/**
- * struct timing_threshold - Timing threshold
- * @max_data_setup_cycles:       The maximum number of data setup cycles that
- *                               can be expressed in the hardware.
- * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
- *                               for data read internal setup. In the Reference
- *                               Manual, see the chapter "High-Speed NAND
- *                               Timing" for more details.
- * @max_sample_delay_factor:     The maximum sample delay factor that can be
- *                               expressed in the hardware.
- * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
- *                               sample delay DLL hardware can possibly work
- *                               with (the DLL is unusable with longer periods).
- *                               If the full-cycle period is greater than HALF
- *                               this value, the DLL must be configured to use
- *                               half-periods.
- * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
- *                               DLL can implement.
- * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
- *                               I/O transaction. If no I/O transaction is in
- *                               progress, this is the clock frequency during
- *                               the most recent I/O transaction.
- */
-struct timing_threshold {
-	const unsigned int      max_chip_count;
-	const unsigned int      max_data_setup_cycles;
-	const unsigned int      internal_data_setup_in_ns;
-	const unsigned int      max_sample_delay_factor;
-	const unsigned int      max_dll_clock_period_in_ns;
-	const unsigned int      max_dll_delay_in_ns;
-	unsigned long           clock_frequency_in_hz;
-
-};
-
 /* Common Services */
 int common_nfc_set_geometry(struct gpmi_nand_data *);
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
index 82114cdc8330..d92bf32221ca 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
@@ -147,6 +147,11 @@
 
 #define BM_GPMI_CTRL1_GPMI_MODE				(1 << 0)
 
+#define BM_GPMI_CTRL1_CLEAR_MASK (BM_GPMI_CTRL1_WRN_DLY_SEL | \
+				  BM_GPMI_CTRL1_DLL_ENABLE |  \
+				  BM_GPMI_CTRL1_RDN_DELAY |   \
+				  BM_GPMI_CTRL1_HALF_PERIOD)
+
 #define HW_GPMI_TIMING0					0x00000070
 
 #define BP_GPMI_TIMING0_ADDRESS_SETUP			16
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 09:39:01 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 18:39:01 +0100
Subject: [PATCH] mtd: nand: marvell: Fix missing memory allocation modifier
Message-ID: <20180119173901.30430-1-miquel.raynal@free-electrons.com>

The function marvell_nfc_init_dma() allocates a DMA buffer without the
GFP_KERNEL modifier, that triggers this warning:
"marvell_nfc_init_dma() error: no modifiers for allocation."

Fix this by using (GFP_KERNEL | GFP_DMA) instead of only GFP_DMA as the
probe happens in non-interrupt context.

Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/marvell_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
index 48d78ca0d71c..5f49c4e0e9e1 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/marvell_nand.c
@@ -2670,7 +2670,7 @@ static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
 	 * for DMA transfers and then copy the desired amount of data to
 	 * the provided buffer.
 	 */
-	nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_DMA);
+	nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_KERNEL | GFP_DMA);
 	if (!nfc->dma_buf)
 		return -ENOMEM;
 
-- 
2.11.0



From miquel.raynal at free-electrons.com  Fri Jan 19 10:11:27 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Fri, 19 Jan 2018 19:11:27 +0100
Subject: [PATCH] mtd: nand: Fix build issues due to an anonymous union
Message-ID: <20180119181127.10473-1-miquel.raynal@free-electrons.com>

GCC-4.4.4 raises errors when assigning a parameter in an anonymous
union, leading to this kind of failure:

drivers/mtd/nand/marvell_nand.c:1936:
    warning: missing braces around initializer
    warning: (near initialization for '(anonymous)[1].<anonymous>')
    error: unknown field 'data' specified in initializer
    error: unknown field 'addr' specified in initializer

Work around the situation by naming these unions.

Reported-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/nand_base.c | 13 +++++++------
 include/linux/mtd/rawnand.h  | 14 ++++++++++----
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e4e39890a975..a3260e6207b8 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2332,23 +2332,24 @@ nand_op_parser_must_split_instr(const struct nand_op_parser_pattern_elem *pat,
 {
 	switch (pat->type) {
 	case NAND_OP_ADDR_INSTR:
-		if (!pat->addr.maxcycles)
+		if (!pat->ctx.addr.maxcycles)
 			break;
 
 		if (instr->ctx.addr.naddrs - *start_offset >
-		    pat->addr.maxcycles) {
-			*start_offset += pat->addr.maxcycles;
+		    pat->ctx.addr.maxcycles) {
+			*start_offset += pat->ctx.addr.maxcycles;
 			return true;
 		}
 		break;
 
 	case NAND_OP_DATA_IN_INSTR:
 	case NAND_OP_DATA_OUT_INSTR:
-		if (!pat->data.maxlen)
+		if (!pat->ctx.data.maxlen)
 			break;
 
-		if (instr->ctx.data.len - *start_offset > pat->data.maxlen) {
-			*start_offset += pat->data.maxlen;
+		if (instr->ctx.data.len - *start_offset >
+		    pat->ctx.data.maxlen) {
+			*start_offset += pat->ctx.data.maxlen;
 			return true;
 		}
 		break;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 469dc724f5df..f89fd2331f4a 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -962,7 +962,7 @@ struct nand_op_parser_pattern_elem {
 	union {
 		struct nand_op_parser_addr_constraints addr;
 		struct nand_op_parser_data_constraints data;
-	};
+	} ctx;
 };
 
 #define NAND_OP_PARSER_PAT_CMD_ELEM(_opt)			\
@@ -975,21 +975,27 @@ struct nand_op_parser_pattern_elem {
 	{							\
 		.type = NAND_OP_ADDR_INSTR,			\
 		.optional = _opt,				\
-		.addr.maxcycles = _maxcycles,			\
+		.ctx.addr = {					\
+			.maxcycles = _maxcycles,		\
+		},						\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_IN_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_IN_INSTR,			\
 		.optional = _opt,				\
-		.data.maxlen = _maxlen,				\
+		.ctx.data = {					\
+			.maxlen = _maxlen,			\
+		},						\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_OUT_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_OUT_INSTR,			\
 		.optional = _opt,				\
-		.data.maxlen = _maxlen,				\
+		.ctx.data = {					\
+			.maxlen = _maxlen,			\
+		},						\
 	}
 
 #define NAND_OP_PARSER_PAT_WAITRDY_ELEM(_opt)			\
-- 
2.11.0



From boris.brezillon at free-electrons.com  Fri Jan 19 10:13:39 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 19 Jan 2018 19:13:39 +0100
Subject: [PATCH] mtd: nand: Fix build issues due to an anonymous union
In-Reply-To: <20180119181127.10473-1-miquel.raynal@free-electrons.com>
References: <20180119181127.10473-1-miquel.raynal@free-electrons.com>
Message-ID: <20180119191339.551eed6d@bbrezillon>

On Fri, 19 Jan 2018 19:11:27 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> GCC-4.4.4 raises errors when assigning a parameter in an anonymous
> union, leading to this kind of failure:
> 
> drivers/mtd/nand/marvell_nand.c:1936:
>     warning: missing braces around initializer
>     warning: (near initialization for '(anonymous)[1].<anonymous>')
>     error: unknown field 'data' specified in initializer
>     error: unknown field 'addr' specified in initializer
> 
> Work around the situation by naming these unions.
> 
> Reported-by: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/nand_base.c | 13 +++++++------
>  include/linux/mtd/rawnand.h  | 14 ++++++++++----
>  2 files changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index e4e39890a975..a3260e6207b8 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2332,23 +2332,24 @@ nand_op_parser_must_split_instr(const struct nand_op_parser_pattern_elem *pat,
>  {
>  	switch (pat->type) {
>  	case NAND_OP_ADDR_INSTR:
> -		if (!pat->addr.maxcycles)
> +		if (!pat->ctx.addr.maxcycles)
>  			break;
>  
>  		if (instr->ctx.addr.naddrs - *start_offset >
> -		    pat->addr.maxcycles) {
> -			*start_offset += pat->addr.maxcycles;
> +		    pat->ctx.addr.maxcycles) {
> +			*start_offset += pat->ctx.addr.maxcycles;
>  			return true;
>  		}
>  		break;
>  
>  	case NAND_OP_DATA_IN_INSTR:
>  	case NAND_OP_DATA_OUT_INSTR:
> -		if (!pat->data.maxlen)
> +		if (!pat->ctx.data.maxlen)
>  			break;
>  
> -		if (instr->ctx.data.len - *start_offset > pat->data.maxlen) {
> -			*start_offset += pat->data.maxlen;
> +		if (instr->ctx.data.len - *start_offset >
> +		    pat->ctx.data.maxlen) {
> +			*start_offset += pat->ctx.data.maxlen;
>  			return true;
>  		}
>  		break;
> diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> index 469dc724f5df..f89fd2331f4a 100644
> --- a/include/linux/mtd/rawnand.h
> +++ b/include/linux/mtd/rawnand.h
> @@ -962,7 +962,7 @@ struct nand_op_parser_pattern_elem {
>  	union {
>  		struct nand_op_parser_addr_constraints addr;
>  		struct nand_op_parser_data_constraints data;
> -	};
> +	} ctx;
>  };
>  
>  #define NAND_OP_PARSER_PAT_CMD_ELEM(_opt)			\
> @@ -975,21 +975,27 @@ struct nand_op_parser_pattern_elem {
>  	{							\
>  		.type = NAND_OP_ADDR_INSTR,			\
>  		.optional = _opt,				\
> -		.addr.maxcycles = _maxcycles,			\
> +		.ctx.addr = {					\
> +			.maxcycles = _maxcycles,		\
> +		},						\

Or just
		.ctx.addr.maxcycles = _maxcycles,

No need to send a new version, I'll fix it when applying.

>  	}
>  
>  #define NAND_OP_PARSER_PAT_DATA_IN_ELEM(_opt, _maxlen)		\
>  	{							\
>  		.type = NAND_OP_DATA_IN_INSTR,			\
>  		.optional = _opt,				\
> -		.data.maxlen = _maxlen,				\
> +		.ctx.data = {					\
> +			.maxlen = _maxlen,			\
> +		},						\
>  	}
>  
>  #define NAND_OP_PARSER_PAT_DATA_OUT_ELEM(_opt, _maxlen)		\
>  	{							\
>  		.type = NAND_OP_DATA_OUT_INSTR,			\
>  		.optional = _opt,				\
> -		.data.maxlen = _maxlen,				\
> +		.ctx.data = {					\
> +			.maxlen = _maxlen,			\
> +		},						\
>  	}
>  
>  #define NAND_OP_PARSER_PAT_WAITRDY_ELEM(_opt)			\



From akpm at linux-foundation.org  Fri Jan 19 11:33:59 2018
From: akpm at linux-foundation.org (Andrew Morton)
Date: Fri, 19 Jan 2018 11:33:59 -0800
Subject: [PATCH] mtd: nand: Fix build issues due to an anonymous union
In-Reply-To: <20180119191339.551eed6d@bbrezillon>
References: <20180119181127.10473-1-miquel.raynal@free-electrons.com>
 <20180119191339.551eed6d@bbrezillon>
Message-ID: <20180119113359.22dd2de344c41f8bbdba844e@linux-foundation.org>

On Fri, 19 Jan 2018 19:13:39 +0100 Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> On Fri, 19 Jan 2018 19:11:27 +0100
> Miquel Raynal <miquel.raynal at free-electrons.com> wrote:
> 
> > GCC-4.4.4 raises errors when assigning a parameter in an anonymous
> > union, leading to this kind of failure:
> > 
> > drivers/mtd/nand/marvell_nand.c:1936:
> >     warning: missing braces around initializer
> >     warning: (near initialization for '(anonymous)[1].<anonymous>')
> >     error: unknown field 'data' specified in initializer
> >     error: unknown field 'addr' specified in initializer
> > 
> > Work around the situation by naming these unions.
> > 
> > Reported-by: Andrew Morton <akpm at linux-foundation.org>
> > Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Tested-by: Andrew Morton <akpm at linux-foundation.org>

> > @@ -975,21 +975,27 @@ struct nand_op_parser_pattern_elem {
> >  	{							\
> >  		.type = NAND_OP_ADDR_INSTR,			\
> >  		.optional = _opt,				\
> > -		.addr.maxcycles = _maxcycles,			\
> > +		.ctx.addr = {					\
> > +			.maxcycles = _maxcycles,		\
> > +		},						\
> 
> Or just
> 		.ctx.addr.maxcycles = _maxcycles,
> 
> No need to send a new version, I'll fix it when applying.

Yes, this also works with gcc-4.4.4:

--- a/include/linux/mtd/rawnand.h~mtd-nand-fix-build-issues-due-to-an-anonymous-union-fix
+++ a/include/linux/mtd/rawnand.h
@@ -975,27 +975,21 @@ struct nand_op_parser_pattern_elem {
 	{							\
 		.type = NAND_OP_ADDR_INSTR,			\
 		.optional = _opt,				\
-		.ctx.addr = {					\
-			.maxcycles = _maxcycles,		\
-		},						\
+		.ctx.addr.maxcycles = _maxcycles,		\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_IN_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_IN_INSTR,			\
 		.optional = _opt,				\
-		.ctx.data = {					\
-			.maxlen = _maxlen,			\
-		},						\
+		.ctx.data.maxlen = _maxlen,			\
 	}
 
 #define NAND_OP_PARSER_PAT_DATA_OUT_ELEM(_opt, _maxlen)		\
 	{							\
 		.type = NAND_OP_DATA_OUT_INSTR,			\
 		.optional = _opt,				\
-		.ctx.data = {					\
-			.maxlen = _maxlen,			\
-		},						\
+		.ctx.data.maxlen = _maxlen,			\
 	}
 
 #define NAND_OP_PARSER_PAT_WAITRDY_ELEM(_opt)			\
_



From robh at kernel.org  Fri Jan 19 13:44:50 2018
From: robh at kernel.org (Rob Herring)
Date: Fri, 19 Jan 2018 15:44:50 -0600
Subject: [PATCH 1/2] dt-bindings: mtd: document Broadcom's BCM47xx
 partitions
In-Reply-To: <20180112093354.17593-1-zajec5@gmail.com>
References: <20180112093354.17593-1-zajec5@gmail.com>
Message-ID: <20180119214450.vhctphu5d4kagwkv@rob-hp-laptop>

On Fri, Jan 12, 2018 at 10:33:53AM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Broadcom based home router devices use partitions which have to be
> discovered in a specific non-standard way. As there is no partition
> table this commit adds and describes a new custom binding.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  .../devicetree/bindings/mtd/partition.txt          | 46 +++++++++++++++++++++-
>  1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt
> index 36f3b769a626..b201d497b618 100644
> --- a/Documentation/devicetree/bindings/mtd/partition.txt
> +++ b/Documentation/devicetree/bindings/mtd/partition.txt
> @@ -14,8 +14,6 @@ method is used for a given flash device. To describe the method there should be
>  a subnode of the flash device that is named 'partitions'. It must have a
>  'compatible' property, which is used to identify the method to use.
>  
> -We currently only document a binding for fixed layouts.
> -
>  
>  Fixed Partitions
>  ================
> @@ -109,3 +107,47 @@ flash at 2 {
>  		};
>  	};
>  };
> +
> +
> +Broadcom BCM47xx Partitions
> +===========================
> +
> +Broadcom is one of hardware manufacturers providing SoCs (BCM47xx) used in
> +home routers. Their BCM947xx boards using CFE bootloader have several partitions
> +without any on-flash partition table. On some devices their sizes and/or
> +meanings can also vary so fixed partitioning can't be used.
> +
> +Discovering partitions on these devices is possible thanks to having a special
> +header and/or magic signature at the beginning of each of them. They are also
> +block aligned which is important for determinig a size.
> +
> +Most of partitions use ASCII text based magic for determining a type. More
> +complex partitions (like TRX with its HDR0 magic) may include extra header
> +containing some details, including a length.
> +
> +A list of supported partitions includes:
> +1) Bootloader with Broadcom's CFE (Common Firmware Environment)
> +2) NVRAM with configuration/calibration data
> +3) Device manufacturer's data with some default values (e.g. SSIDs)
> +4) TRX firmware container which can hold up to 4 subpartitions
> +5) Backup TRX firmware used after failed upgrade
> +
> +As mentioned earlier, role of some partitions may depend on extra configuration.
> +For example both: main firmware and backup firmware use the same TRX format with
> +the same header. To distinguish currently used firmware a CFE's environment
> +variable "bootpartition" is used.
> +
> +
> +Devices using Broadcom partitions described above should should have flash node
> +with a subnode named "partitions" using following properties:
> +
> +Required properties:
> +- compatible : (required) must be "brcm,bcm947xx-cfe-partitions"

So you can't discover you have CFE partitions, but you can discover 
everything else like where partitions start? 

Why doesn't the kernel just probe for the partition table?

Rob


From boris.brezillon at free-electrons.com  Sat Jan 20 05:49:06 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 14:49:06 +0100
Subject: [PATCH -next] mtd: onenand: omap2: Remove redundant dev_err
 call in omap2_onenand_probe()
In-Reply-To: <1516188333-144550-1-git-send-email-weiyongjun1@huawei.com>
References: <1516188333-144550-1-git-send-email-weiyongjun1@huawei.com>
Message-ID: <20180120144906.3d22a204@bbrezillon>

On Wed, 17 Jan 2018 11:25:33 +0000
Wei Yongjun <weiyongjun1 at huawei.com> wrote:

> There is a error message within devm_ioremap_resource
> already, so remove the dev_err call to avoid redundant
> error message.

Applied.

Thanks,

Boris

> 
> Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
> ---
>  drivers/mtd/onenand/omap2.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index a4a2159..87c34f6 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -532,10 +532,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	c->phys_base = res->start;
>  
>  	c->onenand.base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(c->onenand.base)) {
> -		dev_err(dev, "Cannot reserve memory region %pR\n", res);
> +	if (IS_ERR(c->onenand.base))
>  		return PTR_ERR(c->onenand.base);
> -	}
>  
>  	c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN);
>  	if (IS_ERR(c->int_gpiod)) {
> 
> 
> 



From boris.brezillon at free-electrons.com  Sat Jan 20 05:49:35 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 14:49:35 +0100
Subject: [PATCH][V2] mtd: nand: marvell: fix spelling mistake:
 "suceed"-> "succeed"
In-Reply-To: <20180119075531.14841-1-colin.king@canonical.com>
References: <20180119075531.14841-1-colin.king@canonical.com>
Message-ID: <20180120144935.020fa2e9@bbrezillon>

On Fri, 19 Jan 2018 07:55:31 +0000
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Trivial fix to spelling mistakes in dev_err error message text.

Applied.

Thanks,

Boris

> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  drivers/mtd/nand/marvell_nand.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
> index b8fec6093b75..4bd53b360277 100644
> --- a/drivers/mtd/nand/marvell_nand.c
> +++ b/drivers/mtd/nand/marvell_nand.c
> @@ -517,7 +517,7 @@ static int marvell_nfc_prepare_cmd(struct nand_chip *chip)
>  	/* Poll ND_RUN and clear NDSR before issuing any command */
>  	ret = marvell_nfc_wait_ndrun(chip);
>  	if (ret) {
> -		dev_err(nfc->dev, "Last operation did not suceed\n");
> +		dev_err(nfc->dev, "Last operation did not succeed\n");
>  		return ret;
>  	}
>  



From boris.brezillon at free-electrons.com  Sat Jan 20 05:52:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 14:52:17 +0100
Subject: [PATCH][V2] mtd: nand: marvell: remove redundant variable
 'oob_len'
In-Reply-To: <20180119075954.15009-1-colin.king@canonical.com>
References: <20180119075954.15009-1-colin.king@canonical.com>
Message-ID: <20180120145217.368504bb@bbrezillon>

On Fri, 19 Jan 2018 07:59:54 +0000
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Variable oob_len is assigned and never read, hence it is redundant and
> can be removed.
> 
> Cleans up clang warnings:
> 
> drivers/mtd/nand/marvell_nand.c:1356:6: warning: Value stored to 'oob_len'
> during its initialization is never read
> drivers/mtd/nand/marvell_nand.c:1369:4: warning: Value stored to 'oob_len'
> is never read
> 

Applied.

Thanks,

Boris

> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  drivers/mtd/nand/marvell_nand.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
> index 4bd53b360277..f15ab37edf4e 100644
> --- a/drivers/mtd/nand/marvell_nand.c
> +++ b/drivers/mtd/nand/marvell_nand.c
> @@ -1353,7 +1353,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
>  	int data_len = lt->data_bytes;
>  	int spare_len = lt->spare_bytes;
>  	int ecc_len = lt->ecc_bytes;
> -	int oob_len = spare_len + ecc_len;
>  	int spare_offset = 0;
>  	int ecc_offset = (lt->full_chunk_cnt * lt->spare_bytes) +
>  		lt->last_spare_bytes;
> @@ -1366,7 +1365,6 @@ static int marvell_nfc_hw_ecc_bch_write_page_raw(struct mtd_info *mtd,
>  			data_len = lt->last_data_bytes;
>  			spare_len = lt->last_spare_bytes;
>  			ecc_len = lt->last_ecc_bytes;
> -			oob_len = spare_len + ecc_len;
>  		}
>  
>  		/* Point to the column of the next chunk */



From boris.brezillon at free-electrons.com  Sat Jan 20 05:52:56 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 14:52:56 +0100
Subject: [PATCH] mtd: nand: Fix build issues due to an anonymous union
In-Reply-To: <20180119181127.10473-1-miquel.raynal@free-electrons.com>
References: <20180119181127.10473-1-miquel.raynal@free-electrons.com>
Message-ID: <20180120145256.7f588751@bbrezillon>

On Fri, 19 Jan 2018 19:11:27 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> GCC-4.4.4 raises errors when assigning a parameter in an anonymous
> union, leading to this kind of failure:
> 
> drivers/mtd/nand/marvell_nand.c:1936:
>     warning: missing braces around initializer
>     warning: (near initialization for '(anonymous)[1].<anonymous>')
>     error: unknown field 'data' specified in initializer
>     error: unknown field 'addr' specified in initializer
> 
> Work around the situation by naming these unions.
> 
> Reported-by: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Applied.

Thanks,

Boris

> ---
>  drivers/mtd/nand/nand_base.c | 13 +++++++------
>  include/linux/mtd/rawnand.h  | 14 ++++++++++----
>  2 files changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index e4e39890a975..a3260e6207b8 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2332,23 +2332,24 @@ nand_op_parser_must_split_instr(const struct nand_op_parser_pattern_elem *pat,
>  {
>  	switch (pat->type) {
>  	case NAND_OP_ADDR_INSTR:
> -		if (!pat->addr.maxcycles)
> +		if (!pat->ctx.addr.maxcycles)
>  			break;
>  
>  		if (instr->ctx.addr.naddrs - *start_offset >
> -		    pat->addr.maxcycles) {
> -			*start_offset += pat->addr.maxcycles;
> +		    pat->ctx.addr.maxcycles) {
> +			*start_offset += pat->ctx.addr.maxcycles;
>  			return true;
>  		}
>  		break;
>  
>  	case NAND_OP_DATA_IN_INSTR:
>  	case NAND_OP_DATA_OUT_INSTR:
> -		if (!pat->data.maxlen)
> +		if (!pat->ctx.data.maxlen)
>  			break;
>  
> -		if (instr->ctx.data.len - *start_offset > pat->data.maxlen) {
> -			*start_offset += pat->data.maxlen;
> +		if (instr->ctx.data.len - *start_offset >
> +		    pat->ctx.data.maxlen) {
> +			*start_offset += pat->ctx.data.maxlen;
>  			return true;
>  		}
>  		break;
> diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> index 469dc724f5df..f89fd2331f4a 100644
> --- a/include/linux/mtd/rawnand.h
> +++ b/include/linux/mtd/rawnand.h
> @@ -962,7 +962,7 @@ struct nand_op_parser_pattern_elem {
>  	union {
>  		struct nand_op_parser_addr_constraints addr;
>  		struct nand_op_parser_data_constraints data;
> -	};
> +	} ctx;
>  };
>  
>  #define NAND_OP_PARSER_PAT_CMD_ELEM(_opt)			\
> @@ -975,21 +975,27 @@ struct nand_op_parser_pattern_elem {
>  	{							\
>  		.type = NAND_OP_ADDR_INSTR,			\
>  		.optional = _opt,				\
> -		.addr.maxcycles = _maxcycles,			\
> +		.ctx.addr = {					\
> +			.maxcycles = _maxcycles,		\
> +		},						\
>  	}
>  
>  #define NAND_OP_PARSER_PAT_DATA_IN_ELEM(_opt, _maxlen)		\
>  	{							\
>  		.type = NAND_OP_DATA_IN_INSTR,			\
>  		.optional = _opt,				\
> -		.data.maxlen = _maxlen,				\
> +		.ctx.data = {					\
> +			.maxlen = _maxlen,			\
> +		},						\
>  	}
>  
>  #define NAND_OP_PARSER_PAT_DATA_OUT_ELEM(_opt, _maxlen)		\
>  	{							\
>  		.type = NAND_OP_DATA_OUT_INSTR,			\
>  		.optional = _opt,				\
> -		.data.maxlen = _maxlen,				\
> +		.ctx.data = {					\
> +			.maxlen = _maxlen,			\
> +		},						\
>  	}
>  
>  #define NAND_OP_PARSER_PAT_WAITRDY_ELEM(_opt)			\



From boris.brezillon at free-electrons.com  Sat Jan 20 05:56:59 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 14:56:59 +0100
Subject: [PATCH] mtd: nand: marvell: Fix missing memory allocation modifier
In-Reply-To: <20180119173901.30430-1-miquel.raynal@free-electrons.com>
References: <20180119173901.30430-1-miquel.raynal@free-electrons.com>
Message-ID: <20180120145659.7761e4ef@bbrezillon>

On Fri, 19 Jan 2018 18:39:01 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> The function marvell_nfc_init_dma() allocates a DMA buffer without the
> GFP_KERNEL modifier, that triggers this warning:
> "marvell_nfc_init_dma() error: no modifiers for allocation."
> 
> Fix this by using (GFP_KERNEL | GFP_DMA) instead of only GFP_DMA as the
> probe happens in non-interrupt context.

Applied.

Thanks,

Boris

> 
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
> ---
>  drivers/mtd/nand/marvell_nand.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c
> index 48d78ca0d71c..5f49c4e0e9e1 100644
> --- a/drivers/mtd/nand/marvell_nand.c
> +++ b/drivers/mtd/nand/marvell_nand.c
> @@ -2670,7 +2670,7 @@ static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
>  	 * for DMA transfers and then copy the desired amount of data to
>  	 * the provided buffer.
>  	 */
> -	nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_DMA);
> +	nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_KERNEL | GFP_DMA);
>  	if (!nfc->dma_buf)
>  		return -ENOMEM;
>  



From boris.brezillon at free-electrons.com  Sat Jan 20 07:25:26 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sat, 20 Jan 2018 16:25:26 +0100
Subject: [GIT PULL v2] mtd: nand: Changes for 4.16
Message-ID: <20180120162526.4e2a675e@bbrezillon>

Hello,

Here is the NAND PR for 4.16. As can be seen in the diffstat, the NAND
subsystem has been quite active. That's mainly caused by the
introduction of the ->exec_op() hook and the rework of the Marvell
driver.

Regards,

Boris

Changes in v2:
- Add a few fixes for the omap OneNAND and marvell NAND drivers

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/nand/for-4.16

for you to fetch changes up to c1a72e2dbb4abb90bd408480d7c48ba40cb799ce:

  mtd: nand: Fix build issues due to an anonymous union (2018-01-20 10:39:02 +0100)

----------------------------------------------------------------
Core changes:
* Fix NAND_CMD_NONE handling in nand_command[_lp]() hooks
* Introduce the ->exec_op() infrastructure
* Rework NAND buffers handling
* Fix ECC requirements for K9F4G08U0D
* Fix nand_do_read_oob() to return the number of bitflips
* Mark K9F1G08U0E as not supporting subpage writes

Driver changes:
* MTK: Rework the driver to support new IP versions
* OMAP OneNAND: Full rework to use new APIs (libgpio, dmaengine) and fix
  DT support
* Marvell: Add a new driver to replace the pxa3xx one

----------------------------------------------------------------
Arnd Bergmann (1):
      mtd: onenand: omap2: print resource using %pR format string

Boris Brezillon (6):
      mtd: nand: hynix: Don't wait after applying new read-retry params
      mtd: nand: provide several helpers to do common NAND operations
      mtd: nand: force drivers to explicitly send READ/PROG commands
      mtd: nand: denali: Avoid using ecc->code_buf as a temporary buffer
      mtd: nand: Only allocate ecc->{calc, code}_buf when actually needed
      Merge tag 'gpmc-omap-for-v4.16-immutable' of https://github.com/rogerq/linux into nand/next

Christophe JAILLET (5):
      mtd: onenand: samsung: use devm_ function to simplify code and fix some leaks
      mtd: onenand: samsung: return an error if 'mtd_device_parse_register()' fails
      mtd: onenand: samsung: Propagate the error returned by 'onenand_scan()'
      mtd: onenand: samsung: Remove a useless include
      mtd: onenand: samsung: remove incorrect __iomem annotation

Colin Ian King (2):
      mtd: nand: marvell: fix spelling mistake: "suceed"-> "succeed"
      mtd: nand: marvell: remove redundant variable 'oob_len'

Fabio Estevam (2):
      mtd: nand: brcmnand: Add a NULL check for devm_kasprintf()
      mtd: nand: qcom: Add a NULL check for devm_kasprintf()

Gustavo A. R. Silva (1):
      mtd: nand: gpmi: replace _manual_ swap with swap macro

Jagdish Gediya (1):
      mtd: nand: ifc: update bufnum mask for ver >= 2.0.0

Jesse Chan (1):
      mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE

Kamal Dasu (1):
      mtd: nand: brcmnand: Disable prefetch by default

Ladislav Michl (15):
      memory: omap-gpmc: Make 'bank-width' property optional
      mtd: onenand: Remove obsolete url from Kconfig help
      mtd: nand: samsung: Disable subpage writes on E-die NAND
      dt-bindings: mtd: gpmc-onenand: Update properties description
      ARM: dts: OMAP2+: Add compatible property to onenand node
      ARM: dts: omap3-igep: Update onenand node timings
      mtd: onenand: omap2: Remove regulator support
      mtd: onenand: omap2: Remove skip initial unlocking support
      mtd: onenand: omap2: Remove partitioning support from platform data
      mtd: onenand: omap2: Account waiting time as waiting on IO
      mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
      mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
      mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
      mtd: onenand: omap2: Configure driver from DT
      ARM: OMAP2+: Remove gpmc-onenand

Masahiro Yamada (6):
      mtd: nand: remove unnecessary extern from driver headers
      mtd: nand: denali: rename misleading dma_buf to tmp_buf
      mtd: nand: cafe: remove use of NAND_OWN_BUFFERS
      mtd: nand: remove unused NAND_OWN_BUFFERS flag
      mtd: nand: squash struct nand_buffers into struct nand_chip
      mtd: nand: cafe: clean up DMA address setup

Miquel Raynal (15):
      mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]()
      mtd: nand: use usual return values for the ->erase() hook
      mtd: nand: provide valid ->data_interface during NAND detection
      mtd: nand: samsung: add ECC requirements for K9F4G08U0D
      mtd: nand: add ->exec_op() implementation
      mtd: nand: Fix unfinished comment in nand_init_data_interface()
      mtd: mtd_oobtest: Handle bitflips during reads
      mtd: nand: Fix nand_do_read_oob() return value
      dt-bindings: mtd: document new nand-rb property
      dt-bindings: mtd: add Marvell NAND controller documentation
      mtd: nand: add reworked Marvell NAND controller driver
      mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
      MAINTAINERS: Add entry for Marvell NAND controller driver
      mtd: nand: marvell: Fix missing memory allocation modifier
      mtd: nand: Fix build issues due to an anonymous union

Nicolas Ferre (1):
      MAINTAINERS: mtd/nand: update Microchip nand entry

Peter Ujfalusi (2):
      mtd: onenand: omap2: Simplify the DMA setup for various paths
      mtd: onenand: omap2: Convert to use dmaengine for memcpy

RogerCC Lin (3):
      mtd: nand: mtk: update DT bindings
      mtd: nand: mtk: Support different MTK NAND flash controller IP
      mtd: nand: mtk: Support MT7622 NAND flash controller.

Sascha Hauer (2):
      mtd: nand: gpmi-nand: Remove wrong Kconfig help text
      mtd: tests: nandbiterrs: Fix read_page return value

Wei Yongjun (1):
      mtd: onenand: omap2: Remove redundant dev_err call in omap2_onenand_probe()

Xiaolei Li (1):
      mtd: nand: mtk: use nand_reset() to reset NAND devices in resume function

 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt |    6 +-
 Documentation/devicetree/bindings/mtd/marvell-nand.txt |  123 ++
 Documentation/devicetree/bindings/mtd/mtk-nand.txt     |   11 +-
 Documentation/devicetree/bindings/mtd/nand.txt         |    1 +
 MAINTAINERS                                            |   22 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi            |    1 +
 arch/arm/boot/dts/omap3-igep.dtsi                      |   30 +-
 arch/arm/boot/dts/omap3-n900.dts                       |    1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi                   |    1 +
 arch/arm/boot/dts/omap3430-sdp.dts                     |    1 +
 arch/arm/configs/mvebu_v7_defconfig                    |    2 +-
 arch/arm/mach-omap2/Makefile                           |    3 -
 arch/arm/mach-omap2/gpmc-onenand.c                     |  409 ------
 arch/arm64/configs/defconfig                           |    2 +-
 drivers/memory/omap-gpmc.c                             |  163 ++-
 drivers/mtd/nand/Kconfig                               |   17 +-
 drivers/mtd/nand/Makefile                              |    1 +
 drivers/mtd/nand/atmel/nand-controller.c               |    9 +-
 drivers/mtd/nand/bf5xx_nand.c                          |    6 +-
 drivers/mtd/nand/brcmnand/brcmnand.c                   |   38 +-
 drivers/mtd/nand/cafe_nand.c                           |   52 +-
 drivers/mtd/nand/denali.c                              |   84 +-
 drivers/mtd/nand/denali.h                              |    4 +-
 drivers/mtd/nand/denali_pci.c                          |    4 +
 drivers/mtd/nand/diskonchip.c                          |    4 +-
 drivers/mtd/nand/docg4.c                               |   21 +-
 drivers/mtd/nand/fsl_elbc_nand.c                       |   10 +-
 drivers/mtd/nand/fsl_ifc_nand.c                        |   13 +-
 drivers/mtd/nand/fsmc_nand.c                           |    9 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c                 |   97 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h                 |   46 +-
 drivers/mtd/nand/hisi504_nand.c                        |    9 +-
 drivers/mtd/nand/jz4740_nand.c                         |   16 +-
 drivers/mtd/nand/lpc32xx_mlc.c                         |    7 +-
 drivers/mtd/nand/lpc32xx_slc.c                         |   33 +-
 drivers/mtd/nand/marvell_nand.c                        | 2896 +++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/mtk_ecc.c                             |  126 +-
 drivers/mtd/nand/mtk_ecc.h                             |    3 +-
 drivers/mtd/nand/mtk_nand.c                            |   76 +-
 drivers/mtd/nand/nand_base.c                           | 2230 ++++++++++++++++++++++++++-----
 drivers/mtd/nand/nand_bbt.c                            |    2 +-
 drivers/mtd/nand/nand_hynix.c                          |  129 +-
 drivers/mtd/nand/nand_micron.c                         |   83 +-
 drivers/mtd/nand/nand_samsung.c                        |   19 +
 drivers/mtd/nand/nand_timings.c                        |   21 +-
 drivers/mtd/nand/omap2.c                               |   28 +-
 drivers/mtd/nand/pxa3xx_nand.c                         |   14 +-
 drivers/mtd/nand/qcom_nandc.c                          |   30 +-
 drivers/mtd/nand/r852.c                                |   11 +-
 drivers/mtd/nand/sh_flctl.c                            |    6 +-
 drivers/mtd/nand/sm_common.h                           |    2 +-
 drivers/mtd/nand/sunxi_nand.c                          |  103 +-
 drivers/mtd/nand/tango_nand.c                          |   27 +-
 drivers/mtd/nand/tmio_nand.c                           |    5 +-
 drivers/mtd/nand/vf610_nfc.c                           |    6 +-
 drivers/mtd/onenand/Kconfig                            |    7 +-
 drivers/mtd/onenand/omap2.c                            |  577 +++-----
 drivers/mtd/onenand/samsung.c                          |  185 +--
 drivers/mtd/tests/nandbiterrs.c                        |    2 +-
 drivers/mtd/tests/oobtest.c                            |   21 +
 drivers/staging/mt29f_spinand/mt29f_spinand.c          |    5 +-
 include/linux/mtd/rawnand.h                            |  443 ++++++-
 include/linux/omap-gpmc.h                              |   28 +
 include/linux/platform_data/mtd-onenand-omap2.h        |   34 -
 64 files changed, 6455 insertions(+), 1920 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 create mode 100644 drivers/mtd/nand/marvell_nand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h


From colin.king at canonical.com  Sat Jan 20 14:09:34 2018
From: colin.king at canonical.com (Colin King)
Date: Sat, 20 Jan 2018 22:09:34 +0000
Subject: [PATCH] mtd: block2mtd: remove redundant initialization of 'bdev'
Message-ID: <20180120220934.21992-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Pointer bdev is being initialized however this value is never
read as bdev is assigned an updated value from the returned
call to blkdev_get_by_path.  Remove the redundant assignment.

Cleans up clang warning:
drivers/mtd/devices/block2mtd.c:228:23: warning: Value stored to
'bdev' during its initialization is never read

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/mtd/devices/block2mtd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 62fd6905c648..bb0734600a07 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -225,7 +225,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 	int i;
 #endif
 	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
-	struct block_device *bdev = ERR_PTR(-ENODEV);
+	struct block_device *bdev;
 	struct block2mtd_dev *dev;
 	char *name;
 
-- 
2.15.1



From f.fainelli at gmail.com  Sat Jan 20 15:13:35 2018
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sat, 20 Jan 2018 15:13:35 -0800
Subject: [PATCH v3] mtd: nand: brcmnand: Disable prefetch by default
In-Reply-To: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
References: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
Message-ID: <71de78c5-0081-a663-2383-638832766001@gmail.com>



On 01/08/2018 12:36 PM, Kamal Dasu wrote:
> Brcm nand controller prefetch feature needs to be disabled
> by default. Enabling affects performance on random reads as
> well as dma reads.
> 
> Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
> Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
> Cc: stable at vger.kernel.org

Boris, is there a reason this is not in your v4.16 pull request? If not,
could you take that fix?

Thank you
-- 
Florian


From boris.brezillon at free-electrons.com  Sat Jan 20 15:53:21 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Sun, 21 Jan 2018 00:53:21 +0100
Subject: [PATCH v3] mtd: nand: brcmnand: Disable prefetch by default
In-Reply-To: <71de78c5-0081-a663-2383-638832766001@gmail.com>
References: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
 <71de78c5-0081-a663-2383-638832766001@gmail.com>
Message-ID: <20180121005321.313ebc2c@bbrezillon>

On Sat, 20 Jan 2018 15:13:35 -0800
Florian Fainelli <f.fainelli at gmail.com> wrote:

> On 01/08/2018 12:36 PM, Kamal Dasu wrote:
> > Brcm nand controller prefetch feature needs to be disabled
> > by default. Enabling affects performance on random reads as
> > well as dma reads.
> > 
> > Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
> > Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
> > Cc: stable at vger.kernel.org  
> 
> Boris, is there a reason this is not in your v4.16 pull request?

Look carefully, it is there ;-).

"
Kamal Dasu (1):
      mtd: nand: brcmnand: Disable prefetch by default
"

> If not, could you take that fix?
> 
> Thank you



From f.fainelli at gmail.com  Sat Jan 20 16:03:41 2018
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sat, 20 Jan 2018 16:03:41 -0800
Subject: [PATCH v3] mtd: nand: brcmnand: Disable prefetch by default
In-Reply-To: <20180121005321.313ebc2c@bbrezillon>
References: <1515443808-31105-1-git-send-email-kdasu.kdev@gmail.com>
 <71de78c5-0081-a663-2383-638832766001@gmail.com>
 <20180121005321.313ebc2c@bbrezillon>
Message-ID: <8fad16e0-21a3-e1a9-ca7c-4f2a20be6c68@gmail.com>



On 01/20/2018 03:53 PM, Boris Brezillon wrote:
> On Sat, 20 Jan 2018 15:13:35 -0800
> Florian Fainelli <f.fainelli at gmail.com> wrote:
> 
>> On 01/08/2018 12:36 PM, Kamal Dasu wrote:
>>> Brcm nand controller prefetch feature needs to be disabled
>>> by default. Enabling affects performance on random reads as
>>> well as dma reads.
>>>
>>> Signed-off-by: Kamal Dasu <kdasu.kdev at gmail.com>
>>> Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
>>> Cc: stable at vger.kernel.org  
>>
>> Boris, is there a reason this is not in your v4.16 pull request?
> 
> Look carefully, it is there ;-).

Indeed, I can't read, my bad.
-- 
Florian


From boris.brezillon at free-electrons.com  Mon Jan 22 00:51:49 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 22 Jan 2018 09:51:49 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87o9lwaft9.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon>
 <87wp0majtg.fsf@belgarion.home>
 <20180113093807.3984c184@bbrezillon>
 <20180113120529.2f00ea20@xps13> <87o9lwaft9.fsf@belgarion.home>
Message-ID: <20180122095149.590612d9@bbrezillon>

Hi Robert,

On Sun, 14 Jan 2018 11:35:30 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Miquel Raynal <miquel.raynal at free-electrons.com> writes:
> 
> >> It shouldn't be damaged anymore. The bug has been fixed just before we
> >> asked you to scrub the BBT area.  
> I confirm. The last marvell branch I have (2be03e113a5b ("HACK: Dump OOB data
> while reading")) does work correctly on my zylonite.
> 
> I still have to make a test of a file write, and a devicetree based setup, but I
> don't think anything wrong will happen now.

Did you make any progress with that? Note that, no matter the outcome
of your tests, I don't plan to queue the remaining patches for this
release, so don't be afraid of putting your Tested-by/Acked-by on
patches 5-6 if it works on your platforms ;-).

Thanks,

Boris


From boris.brezillon at free-electrons.com  Mon Jan 22 00:54:38 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 22 Jan 2018 09:54:38 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87shb8aghi.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112112108.2e20dc14@bbrezillon>
 <871sivauyf.fsf@belgarion.home>
 <20180113093855.49231a43@bbrezillon>
 <87shb8aghi.fsf@belgarion.home>
Message-ID: <20180122095438.750d84ef@bbrezillon>

On Sun, 14 Jan 2018 11:20:57 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > On Fri, 12 Jan 2018 17:43:52 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> >>   
> >> > I think I'm still missing something. If I look at the branch you just
> >> > pushed, I see that ->flash_bbt was not set to 1 before this commit [1],
> >> > which means the pxa3xx driver was no setting the NAND_BBT_USE_FLASH
> >> > flag, which in turn means you were not using the on-flash-bbt.
> >> > When you test the old (pxa3xx) driver, are you sure you're testing
> >> > things with a mainline kernel? If you have extra commits on top of
> >> > mainline, can you push them somewhere?    
> >> 
> >> Here is the branch I'm using with my pxa3xx driver :
> >> git fetch https://github.com/rjarzmik/linux pxa3xx-test  
> >
> > May I ask why this is not in mainline?  
> Sure.
> 
> The pxa3xx comes into 3 flavors of SoCs :
>  - pxa300
>  - pxa310
>  - pxa320
> 
> In these 3, only pxa310 has an internal PoP NAND, and requires the keep_config =
> 1 setting (where timings are set by the internal ROM code).
> 
> Yet zylonite_init_nand() is shared across all 3 platforms. In order to not break
> other existing pxa3xx devices, I don't want to change this setting. Instead, my
> plan is slowly convert pxaXXX to devicetree, and have this parameter set in
> devicetree in a per board basis.
> 
> As to the .flash_bbt = 1 parameter, it's even worse. That's the decision made in
> the initial flash formatting that counts. With the zylonite310 I have, the BBT
> is at the end of the NAND. There might be other parts where it's only in the OOB
> area. So it's difficult to change it without taking a risk of breaking others.

Ok. It's clearer now. I wish we had this discussion earlier :-/.

Anyway, thanks for the clarification.

Boris


From boris.brezillon at free-electrons.com  Mon Jan 22 01:38:01 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 22 Jan 2018 10:38:01 +0100
Subject: [PATCH] mtd: Make sure the device supports erase operations in
 mtd_erase()
Message-ID: <20180122093801.19618-1-boris.brezillon@free-electrons.com>

Some devices do not implement ->_erase() or have an invalid ->erasesize
value. In this case, mtd_erase() should return -ENOTSUPP.

Note that the test is not done on the MTD_NO_ERASE flag because this
flag means 'erasing a block before writing to it is unnecessary',
not 'the erase operation is not supported'. Actually, some drivers are
setting the MTD_NO_ERASE flag but still implementing the ->_erase()
hook and setting a valid ->erasesize value.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 drivers/mtd/mtdcore.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index d7ab091b36b2..f24144cbc99c 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -971,10 +971,14 @@ EXPORT_SYMBOL_GPL(__put_mtd_device);
  */
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
+	if (!mtd->erasesize || !mtd->_erase)
+		return -ENOTSUPP;
+
 	if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
 		return -EINVAL;
 	if (!(mtd->flags & MTD_WRITEABLE))
 		return -EROFS;
+
 	instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
 	if (!instr->len) {
 		instr->state = MTD_ERASE_DONE;
-- 
2.11.0



From nagasure at xilinx.com  Mon Jan 22 04:29:51 2018
From: nagasure at xilinx.com (Naga Sureshkumar Relli)
Date: Mon, 22 Jan 2018 12:29:51 +0000
Subject: [PATCH v9 2/2] mtd: nand: Add support for Arasan NAND Flash
 Controller
In-Reply-To: <20171228215528.3ce15bd5@xps13>
References: <20171214134445.4985-1-nagasure@xilinx.com>
 <20171214134445.4985-3-nagasure@xilinx.com> <20171228215528.3ce15bd5@xps13>
Message-ID: <BY2PR02MB14112FAB777449F1B303D85AAFEC0@BY2PR02MB1411.namprd02.prod.outlook.com>

Hi Miquel,

Thanks for reviewing this patch series.

> -----Original Message-----
> From: Miquel RAYNAL [mailto:miquel.raynal at free-electrons.com]
> Sent: Friday, December 29, 2017 2:25 AM
> To: Naga Sureshkumar Relli <nagasure at xilinx.com>
> Cc: boris.brezillon at free-electrons.com; richard at nod.at;
> computersforpeace at gmail.com; marek.vasut at gmail.com;
> cyrille.pitchen at wedev4u.fr; Naga Sureshkumar Relli <nagasure at xilinx.com>;
> nagasuresh12 at gmail.com; linux-kernel at vger.kernel.org; linux-
> mtd at lists.infradead.org; Punnaiah Choudary Kalluri <punnaia at xilinx.com>;
> Michal Simek <michals at xilinx.com>; dwmw2 at infradead.org
> Subject: Re: [PATCH v9 2/2] mtd: nand: Add support for Arasan NAND Flash
> Controller
> 
> Hello,
> 
> Thanks for contributing this driver.
> 
> As you may know, the NAND framework is currently moving to an interface
> called ->exec_op(). Please look at the l2-mtd -or linux-next- tree to see what this
> is (drivers/mtd/nand/nand_base.c is quite well documented about this
> interface).
> 
> New drivers should drop their ->cmdfunc() / ->cmd_ctrl() /
> ->read/write_byte/word/buf() implementations and instead switch to
> ->exec_op(). I know this is a significant amount of work but do not
> hesitate to ask if you need some help.

Ok I will update the driver as per new exec_op() update.
Let me go through this interface.
> 
> You may take the Marvell NAND controller driver as example of how to
> implement it (rework also currently under review):
> https://www.spinics.net/lists/arm-kernel/msg624246.html
Ok, I will take a look into that driver.

> 
> Otherwise there are some comments below. I am really not a NAND god, so
> don't take them as pure truth :)
Thanks for reviewing this driver. 
> 
> Thank you,
> Miqu?l
> 
> On Thu, 14 Dec 2017 19:14:45 +0530
> Naga Sureshkumar Relli <naga.sureshkumar.relli at xilinx.com> wrote:
> 
> > Added the basic driver for Arasan NAND Flash Controller used in Zynq
> > UltraScale+ MPSoC. It supports only Hw ECC and upto 24bit correction.
> >
> > Signed-off-by: Naga Sureshkumar Relli <nagasure at xilinx.com>
> > Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
> > ---
> > Changes in v9:
> >  - Added the SPDX tags
> > Changes in v8:
> >  - Implemented setup_data_interface hook
> >  - fixed checkpatch --strict warnings
> >  - Added anfc_config_ecc in read_page_hwecc
> >  - Fixed returning status value by reading flash status in read_byte()
> >    instead of reading previous value.
> > Changes in v7:
> > - Implemented Marek suggestions and comments
> > - Corrected the acronyms those should be in caps
> > - Modified kconfig/Make file to keep arasan entry in sorted order
> > - Added is_vmlloc_addr check
> > - Used ioread/write32_rep variants to avoid compilation error for
> > intel platforms
> > - separated PIO and DMA mode read/write functions
> > - Minor cleanup
> > Chnages in v6:
> > - Addressed most of the Brian and Boris comments
> > - Separated the nandchip from the nand controller
> > - Removed the ecc lookup table from driver
> > - Now use framework nand waitfunction and readoob
> > - Fixed the compiler warning
> > - Adapted the new frameowrk changes related to ecc and ooblayout
> > - Disabled the clocks after the nand_reelase
> > - Now using only one completion object
> > - Boris suggessions like adapting cmd_ctrl and rework on read/write
> > byte are not implemented and i will patch them later
> > - Also check_erased_ecc_chunk for erase and check for is_vmalloc_addr
> > will implement later once the basic driver is mainlined.
> > Changes in v5:
> > - Renamed the driver filei as arasan_nand.c
> > - Fixed all comments relaqted coding style
> > - Fixed comments related to propagating the errors
> > - Modified the anfc_write_page_hwecc as per the write_page
> >   prototype
> > Changes in v4:
> > - Added support for onfi timing mode configuration
> > - Added clock supppport
> > - Added support for multiple chipselects Changes in v3:
> > - Removed unused variables
> > - Avoided busy loop and used jifies based implementation
> > - Fixed compiler warnings "right shift count >= width of type"
> > - Removed unneeded codei and improved error reporting
> > - Added onfi version check to ensure reading the valid address cycles
> > Changes in v2:
> > - Added missing of.h to avoid kbuild system report erro
> > ---
> >  drivers/mtd/nand/Kconfig       |    8 +
> >  drivers/mtd/nand/Makefile      |    1 +
> >  drivers/mtd/nand/arasan_nand.c | 1018
> > ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1027
> > insertions(+) create mode 100644 drivers/mtd/nand/arasan_nand.c
> >
> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index
> > 3f2036f31da4..bdc97510f758 100644
> > --- a/drivers/mtd/nand/Kconfig
> > +++ b/drivers/mtd/nand/Kconfig
> > @@ -40,6 +40,14 @@ config MTD_SM_COMMON
> >  	tristate
> >  	default n
> >
> > +config MTD_NAND_ARASAN
> > +	tristate "Support for Arasan Nand Flash controller"
> > +	depends on HAS_IOMEM
> > +	depends on HAS_DMA
> > +	help
> > +	  Enables the driver for the Arasan NAND Flash controller on
> > +	  Zynq UltraScale+ MPSoC.
> > +
> >  config MTD_NAND_DENALI
> >  	tristate
> >
> > diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> > index 6e2db700d923..b96965a95daf 100644
> > --- a/drivers/mtd/nand/Makefile
> > +++ b/drivers/mtd/nand/Makefile
> > @@ -8,6 +8,7 @@ obj-$(CONFIG_MTD_NAND_ECC)		+=
> > nand_ecc.o obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
> >  obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
> >
> > +obj-$(CONFIG_MTD_NAND_ARASAN)		+= arasan_nand.o
> >  obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o
> >  obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
> >  obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
> > diff --git a/drivers/mtd/nand/arasan_nand.c
> > b/drivers/mtd/nand/arasan_nand.c new file mode 100644 index
> > 000000000000..89c06b70b65d
> > --- /dev/null
> > +++ b/drivers/mtd/nand/arasan_nand.c
> > @@ -0,0 +1,1018 @@
> > +/*
> > + * Arasan NAND Flash Controller Driver
> > + *
> > + * Copyright (C) 2014 - 2017 Xilinx, Inc.
> > + * Author: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
> > + *
> > + * SPDX-License-Identifier: GPL-2.0
> > + */
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/module.h>
> > +#include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include
> > +<linux/mtd/partitions.h> #include <linux/of.h> #include
> > +<linux/platform_device.h>
> > +
> > +#define DRIVER_NAME			"arasan_nand"
> > +#define EVNT_TIMEOUT_MSEC		1000
> > +
> > +#define PKT_OFST			0x00
> > +#define MEM_ADDR1_OFST			0x04
> > +#define MEM_ADDR2_OFST			0x08
> > +#define CMD_OFST			0x0C
> > +#define PROG_OFST			0x10
> > +#define INTR_STS_EN_OFST		0x14
> > +#define INTR_SIG_EN_OFST		0x18
> > +#define INTR_STS_OFST			0x1C
> > +#define READY_STS_OFST			0x20
> > +#define DMA_ADDR1_OFST			0x24
> > +#define FLASH_STS_OFST			0x28
> > +#define DATA_PORT_OFST			0x30
> > +#define ECC_OFST			0x34
> > +#define ECC_ERR_CNT_OFST		0x38
> > +#define ECC_SPR_CMD_OFST		0x3C
> > +#define ECC_ERR_CNT_1BIT_OFST		0x40
> > +#define ECC_ERR_CNT_2BIT_OFST		0x44
> > +#define DMA_ADDR0_OFST			0x50
> > +#define DATA_INTERFACE_OFST		0x6C
> > +
> > +#define PKT_CNT_SHIFT			12
> > +
> > +#define ECC_ENABLE			BIT(31)
> > +#define DMA_EN_MASK			GENMASK(27, 26)
> > +#define DMA_ENABLE			0x2
> > +#define DMA_EN_SHIFT			26
> > +#define REG_PAGE_SIZE_SHIFT		23
> > +#define REG_PAGE_SIZE_512		0
> > +#define REG_PAGE_SIZE_1K		5
> > +#define REG_PAGE_SIZE_2K		1
> > +#define REG_PAGE_SIZE_4K		2
> > +#define REG_PAGE_SIZE_8K		3
> > +#define REG_PAGE_SIZE_16K		4
> > +#define CMD2_SHIFT			8
> > +#define ADDR_CYCLES_SHIFT		28
> > +
> > +#define XFER_COMPLETE			BIT(2)
> > +#define READ_READY			BIT(1)
> > +#define WRITE_READY			BIT(0)
> > +#define MBIT_ERROR			BIT(3)
> > +
> > +#define PROG_PGRD			BIT(0)
> > +#define PROG_ERASE			BIT(2)
> > +#define PROG_STATUS			BIT(3)
> > +#define PROG_PGPROG			BIT(4)
> > +#define PROG_RDID			BIT(6)
> > +#define PROG_RDPARAM			BIT(7)
> > +#define PROG_RST			BIT(8)
> > +#define PROG_GET_FEATURE		BIT(9)
> > +#define PROG_SET_FEATURE		BIT(10)
> > +
> > +#define PG_ADDR_SHIFT			16
> > +#define BCH_MODE_SHIFT			25
> > +#define BCH_EN_SHIFT			27
> > +#define ECC_SIZE_SHIFT			16
> > +
> > +#define MEM_ADDR_MASK			GENMASK(7, 0)
> > +#define BCH_MODE_MASK			GENMASK(27, 25)
> > +
> > +#define CS_MASK				GENMASK(31, 30)
> > +#define CS_SHIFT			30
> > +
> > +#define PAGE_ERR_CNT_MASK		GENMASK(16, 8)
> > +#define PKT_ERR_CNT_MASK		GENMASK(7, 0)
> > +
> > +#define NVDDR_MODE			BIT(9)
> > +#define NVDDR_TIMING_MODE_SHIFT		3
> > +
> > +#define ONFI_ID_LEN			8
> > +#define TEMP_BUF_SIZE			1024
> > +#define NVDDR_MODE_PACKET_SIZE		8
> > +#define SDR_MODE_PACKET_SIZE		4
> > +
> > +#define ONFI_DATA_INTERFACE_NVDDR      BIT(4)
> > +#define EVENT_MASK	(XFER_COMPLETE | READ_READY |
> WRITE_READY
> > | MBIT_ERROR) +
> > +#define SDR_MODE_DEFLT_FREQ		80000000
> > +
> > +/**
> > + * struct anfc_nand_chip - Defines the nand chip related information
> 
> I think you should s/nand/NAND/ when writing plain English?
Ok, I will update this in next patch.
> 
> > + * @node:		used to store NAND chips into a list.
> > + * @chip:		NAND chip information structure.
> > + * @bch:		Bch / Hamming mode enable/disable.
> > + * @bchmode:		Bch mode.
> > + * @eccval:		Ecc config value.
> > + * @raddr_cycles:	Row address cycle information.
> > + * @caddr_cycles:	Column address cycle information.
> > + * @pktsize:		Packet size for read / write operation.
> > + * @csnum:		chipselect number to be used.
> > + * @spktsize:		Packet size in ddr mode for status
> > operation.
> > + * @inftimeval:		Data interface and timing mode
> > information
> > + */
> > +struct anfc_nand_chip {
> > +	struct list_head node;
> > +	struct nand_chip chip;
> > +	bool bch;
> > +	u32 bchmode;
> > +	u32 eccval;
> > +	u16 raddr_cycles;
> > +	u16 caddr_cycles;
> > +	u32 pktsize;
> > +	int csnum;
> > +	u32 spktsize;
> > +	u32 inftimeval;
> > +};
> > +
> > +/**
> > + * struct anfc - Defines the Arasan NAND flash driver instance
> > + * @controller:		base controller structure.
> > + * @chips:		list of all nand chips attached to the
> > ctrler.
> > + * @dev:		Pointer to the device structure.
> > + * @base:		Virtual address of the NAND flash device.
> > + * @curr_cmd:		Current command issued.
> > + * @clk_sys:		Pointer to the system clock.
> > + * @clk_flash:		Pointer to the flash clock.
> > + * @dma:		Dma enable/disable.
> > + * @iswriteoob:		Identifies if oob write operation is
> > required.
> > + * @buf:		Buffer used for read/write byte operations.
> > + * @irq:		irq number
> > + * @bufshift:		Variable used for indexing buffer
> > operation
> > + * @csnum:		Chip select number currently inuse.
> > + * @event:		Completion event for nand status events.
> > + * @status:		Status of the flash device
> > + */
> > +struct anfc {
> > +	struct nand_hw_control controller;
> > +	struct list_head chips;
> > +	struct device *dev;
> > +	void __iomem *base;
> > +	int curr_cmd;
> > +	struct clk *clk_sys;
> > +	struct clk *clk_flash;
> > +	bool dma;
> > +	bool iswriteoob;
> > +	u8 buf[TEMP_BUF_SIZE];
> > +	int irq;
> > +	u32 bufshift;
> > +	int csnum;
> > +	struct completion event;
> > +	int status;
> > +};
> > +
> > +static int anfc_ooblayout_ecc(struct mtd_info *mtd, int section,
> > +			      struct mtd_oob_region *oobregion) {
> > +	struct nand_chip *nand = mtd_to_nand(mtd);
> > +
> > +	if (section)
> > +		return -ERANGE;
> > +
> > +	oobregion->length = nand->ecc.total;
> > +	oobregion->offset = mtd->oobsize - oobregion->length;
> > +
> > +	return 0;
> > +}
> > +
> > +static int anfc_ooblayout_free(struct mtd_info *mtd, int section,
> > +			       struct mtd_oob_region *oobregion) {
> > +	struct nand_chip *nand = mtd_to_nand(mtd);
> > +
> > +	if (section)
> > +		return -ERANGE;
> > +
> > +	oobregion->offset = 2;
> > +	oobregion->length = mtd->oobsize - nand->ecc.total - 2;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct mtd_ooblayout_ops anfc_ooblayout_ops = {
> > +	.ecc = anfc_ooblayout_ecc,
> > +	.free = anfc_ooblayout_free,
> > +};
> > +
> > +static inline struct anfc_nand_chip *to_anfc_nand(struct nand_chip
> > *nand) +{
> > +	return container_of(nand, struct anfc_nand_chip, chip); }
> > +
> > +static inline struct anfc *to_anfc(struct nand_hw_control *ctrl) {
> > +	return container_of(ctrl, struct anfc, controller); }
> > +
> > +static u8 anfc_page(u32 pagesize)
> > +{
> > +	switch (pagesize) {
> > +	case 512:
> > +		return REG_PAGE_SIZE_512;
> > +	case 1024:
> > +		return REG_PAGE_SIZE_1K;
> > +	case 2048:
> > +		return REG_PAGE_SIZE_2K;
> > +	case 4096:
> > +		return REG_PAGE_SIZE_4K;
> > +	case 8192:
> > +		return REG_PAGE_SIZE_8K;
> > +	case 16384:
> 
> Maybe you can use macros like SZ_512, SZ_1K, SZ_2K, etc, see
> include/linux/sizes.h
These are not really page size values.
In CMD_REG[25:23] we need to specify page size as below
000: 512-byte Page size.
001: 2KB Page size.
010: 4KB Page size.
011: 8KB Page size.
100: 16KB Page size, hence for naming conventions we used the above macros. 
Means, REG_PAGE_SIZE_512 = 0.
> 
> > +		return REG_PAGE_SIZE_16K;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static inline void anfc_enable_intrs(struct anfc *nfc, u32 val) {
> > +	writel(val, nfc->base + INTR_STS_EN_OFST);
> > +	writel(val, nfc->base + INTR_SIG_EN_OFST); }
> > +
> > +static inline void anfc_config_ecc(struct anfc *nfc, int on) {
> > +	u32 val;
> > +
> > +	val = readl(nfc->base + CMD_OFST);
> > +	if (on)
> > +		val |= ECC_ENABLE;
> > +	else
> > +		val &= ~ECC_ENABLE;
> > +	writel(val, nfc->base + CMD_OFST);
> > +}
> > +
> > +static inline void anfc_config_dma(struct anfc *nfc, int on) {
> > +	u32 val;
> > +
> > +	val = readl(nfc->base + CMD_OFST);
> > +	val &= ~DMA_EN_MASK;
> > +	if (on)
> > +		val |= DMA_ENABLE << DMA_EN_SHIFT;
> > +	writel(val, nfc->base + CMD_OFST);
> > +}
> 
> Nitpick: both anfc_config_ecc/dma() functions do similar actions but the syntax
> is different.
Yes, we can make it generic, But to identify whether we are configuring ecc or dma, these two functions are added.
> 
> > +
> > +static inline int anfc_wait_for_event(struct anfc *nfc) {
> > +	return wait_for_completion_timeout(&nfc->event,
> > +
> > msecs_to_jiffies(EVNT_TIMEOUT_MSEC)); +}
> > +
> > +static inline void anfc_setpktszcnt(struct anfc *nfc, u32 pktsize,
> > +				    u32 pktcount)
> > +{
> > +	writel(pktsize | (pktcount << PKT_CNT_SHIFT), nfc->base +
> > PKT_OFST); +}
> > +
> > +static inline void anfc_set_eccsparecmd(struct anfc *nfc,
> > +					struct anfc_nand_chip
> > *achip, u8 cmd1,
> > +					u8 cmd2)
> > +{
> > +	writel(cmd1 | (cmd2 << CMD2_SHIFT) |
> > +	       (achip->caddr_cycles << ADDR_CYCLES_SHIFT),
> > +	       nfc->base + ECC_SPR_CMD_OFST); }
> > +
> > +static void anfc_setpagecoladdr(struct anfc *nfc, u32 page, u16 col)
> > +{
> > +	u32 val;
> > +
> > +	writel(col | (page << PG_ADDR_SHIFT), nfc->base +
> > MEM_ADDR1_OFST); +
> > +	val = readl(nfc->base + MEM_ADDR2_OFST);
> > +	val = (val & ~MEM_ADDR_MASK) |
> > +	      ((page >> PG_ADDR_SHIFT) & MEM_ADDR_MASK);
> > +	writel(val, nfc->base + MEM_ADDR2_OFST); }
> > +
> > +static void anfc_prepare_cmd(struct anfc *nfc, u8 cmd1, u8 cmd2, u8
> > dmamode,
> > +			     u32 pagesize, u8 addrcycles)
> > +{
> > +	u32 regval;
> > +
> > +	regval = cmd1 | (cmd2 << CMD2_SHIFT);
> > +	if (dmamode && nfc->dma)
> > +		regval |= DMA_ENABLE << DMA_EN_SHIFT;
> > +	regval |= addrcycles << ADDR_CYCLES_SHIFT;
> > +	regval |= anfc_page(pagesize) << REG_PAGE_SIZE_SHIFT;
> > +	writel(regval, nfc->base + CMD_OFST); }
> > +
> > +static int anfc_write_oob(struct mtd_info *mtd, struct nand_chip
> > *chip,
> > +			  int page)
> > +{
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +
> > +	nfc->iswriteoob = true;
> > +	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
> > +	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> > +	nfc->iswriteoob = false;
> > +
> > +	return 0;
> > +}
> > +
> > +static void anfc_rw_buf_dma(struct mtd_info *mtd, uint8_t *buf, int
> > len,
> > +			    int operation, u32 prog)
> > +{
> > +	dma_addr_t paddr;
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	u32 eccintr = 0, dir;
> > +	u32 pktsize = len, pktcount = 1;
> > +
> > +	if (nfc->curr_cmd == NAND_CMD_READ0 ||
> > +	    (nfc->curr_cmd == NAND_CMD_SEQIN && !nfc->iswriteoob)) {
> > +		pktsize = achip->pktsize;
> > +		pktcount = DIV_ROUND_UP(mtd->writesize, pktsize);
> > +	}
> > +	anfc_setpktszcnt(nfc, pktsize, pktcount);
> > +
> > +	if (!achip->bch && nfc->curr_cmd == NAND_CMD_READ0)
> > +		eccintr = MBIT_ERROR;
> > +
> > +	if (operation)
> > +		dir = DMA_FROM_DEVICE;
> > +	else
> > +		dir = DMA_TO_DEVICE;
> > +
> > +	paddr = dma_map_single(nfc->dev, buf, len, dir);
> > +	if (dma_mapping_error(nfc->dev, paddr)) {
> > +		dev_err(nfc->dev, "Read buffer mapping error");
> > +		return;
> > +	}
> > +	writel(paddr, nfc->base + DMA_ADDR0_OFST);
> > +	writel((paddr >> 32), nfc->base + DMA_ADDR1_OFST);
> > +	anfc_enable_intrs(nfc, (XFER_COMPLETE | eccintr));
> > +	writel(prog, nfc->base + PROG_OFST);
> > +	anfc_wait_for_event(nfc);
> > +	dma_unmap_single(nfc->dev, paddr, len, dir); }
> > +
> > +static void anfc_rw_buf_pio(struct mtd_info *mtd, uint8_t *buf, int
> > len,
> > +			    int operation, int prog)
> > +{
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	u32 *bufptr = (u32 *)buf;
> > +	u32 cnt = 0, intr = 0;
> > +	u32 pktsize = len, pktcount = 1;
> > +
> > +	anfc_config_dma(nfc, 0);
> > +
> > +	if (nfc->curr_cmd == NAND_CMD_READ0 ||
> > +	    (nfc->curr_cmd == NAND_CMD_SEQIN && !nfc->iswriteoob)) {
> > +		pktsize = achip->pktsize;
> > +		pktcount = DIV_ROUND_UP(mtd->writesize, pktsize);
> > +	}
> > +	anfc_setpktszcnt(nfc, pktsize, pktcount);
> > +
> > +	if (!achip->bch && nfc->curr_cmd == NAND_CMD_READ0)
> > +		intr = MBIT_ERROR;
> > +
> > +	if (operation)
> > +		intr |= READ_READY;
> > +	else
> > +		intr |= WRITE_READY;
> > +
> > +	anfc_enable_intrs(nfc, intr);
> > +	writel(prog, nfc->base + PROG_OFST);
> > +
> > +	while (cnt < pktcount) {
> > +		anfc_wait_for_event(nfc);
> > +		cnt++;
> > +		if (cnt == pktcount)
> > +			anfc_enable_intrs(nfc, XFER_COMPLETE);
> > +		if (operation)
> > +			ioread32_rep(nfc->base + DATA_PORT_OFST,
> > bufptr,
> > +				     pktsize / 4);
> > +		else
> > +			iowrite32_rep(nfc->base + DATA_PORT_OFST,
> > bufptr,
> > +				      pktsize / 4);
> > +		bufptr += (pktsize / 4);
> > +		if (cnt < pktcount)
> > +			anfc_enable_intrs(nfc, intr);
> > +	}
> > +
> > +	anfc_wait_for_event(nfc);
> > +}
> > +
> > +static void anfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int
> > len) +{
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +
> > +	if (nfc->dma && !is_vmalloc_addr(buf))
> > +		anfc_rw_buf_dma(mtd, buf, len, 1, PROG_PGRD);
> > +	else
> > +		anfc_rw_buf_pio(mtd, buf, len, 1, PROG_PGRD);
> 
> You put 0 or 1 in the "operation" while this means "do a read" or "do a write",
> both anfc_rw_buf_dma/pio() functions would probably benefit to have this
> parameter renamed and turned into a boolean.

Ok, I will update it in next patch.
> 
> > +}
> > +
> > +static void anfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
> > int len) +{
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +
> > +	if (nfc->dma && !is_vmalloc_addr(buf))
> > +		anfc_rw_buf_dma(mtd, (char *)buf, len, 0,
> > PROG_PGPROG);
> > +	else
> > +		anfc_rw_buf_pio(mtd, (char *)buf, len, 0,
> > PROG_PGPROG);
> 
> I think both "(char *)" casts are abusive and the const qualifier should probably
> remain.
Ok, I will update it in next patch.
> 
> > +}
> > +
> > +static int anfc_read_page_hwecc(struct mtd_info *mtd,
> > +				struct nand_chip *chip, uint8_t *buf,
> > +				int oob_required, int page)
> > +{
> > +	u32 val;
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	u8 *ecc_code = chip->buffers->ecccode;
> > +	u8 *p = buf;
> > +	int eccsize = chip->ecc.size;
> > +	int eccbytes = chip->ecc.bytes;
> > +	int eccsteps = chip->ecc.steps;
> > +	int stat = 0, i;
> > +
> > +	anfc_set_eccsparecmd(nfc, achip, NAND_CMD_RNDOUT,
> > NAND_CMD_RNDOUTSTART);
> > +	anfc_config_ecc(nfc, 1);
> > +
> > +	chip->read_buf(mtd, buf, mtd->writesize);
> > +
> > +	val = readl(nfc->base + ECC_ERR_CNT_OFST);
> > +	val = ((val & PAGE_ERR_CNT_MASK) >> 8);
> 
> If I understand this correctly, there is no point doing the upper two lines out of
> the if statement?
Yes, I will move this to if statement.
> 
> > +	if (achip->bch) {
> > +		mtd->ecc_stats.corrected += val;
> 
> This is strange that there is no handling of a failing situation when using BCH
> algorithm. You should probably add some logic here that either increments
> ecc_stats.corrected or ecc_stats.failed like it is done below.
Yes, in case of BCH, upto 24 bit errors it will correct. After that it won't even detect the errors.
Hence when BCH we are not updating errors.

> 
> > +	} else {
> > +		val = readl(nfc->base + ECC_ERR_CNT_1BIT_OFST);
> > +		mtd->ecc_stats.corrected += val;
> > +		val = readl(nfc->base + ECC_ERR_CNT_2BIT_OFST);
> > +		mtd->ecc_stats.failed += val;
> > +		/* Clear ecc error count register 1Bit, 2Bit */
> > +		writel(0x0, nfc->base + ECC_ERR_CNT_1BIT_OFST);
> > +		writel(0x0, nfc->base + ECC_ERR_CNT_2BIT_OFST);
> > +	}
> > +
> > +	if (oob_required)
> > +		chip->ecc.read_oob(mtd, chip, page);
> > +
> > +	anfc_config_ecc(nfc, 0);
> > +
> 
> Some comments would be welcome from here to the end, that is not entirely
> clear to me what you try to achieve here.
> 
> > +	if (val) {
> 
> When using Hamming, val != 0 means there is an uncorrectable error, while
> when using BCH, it may just mean there was some corrected bitflips. I think you
> should enter this statement only if Hamming or BCH failed to recover bitflips?
Yes, I will update.
> 
> > +		chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
> > +		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
> 
> If OOB area was required, you are most likely overwriting OOB bytes that were
> maybe corrected by the ECC engine before it was turned off, by bytes retried
> with a raw read (potentially with bitflips).
This code is added to handle below case.
When a page was erased, ECC won't update for erased page.
And when we do an  empty page read, ECC will be updated and there is mismatch between ECC data 
At the time erasing and reading, causing ECC errors.
Hence we are reading entire OOB and updating the correct ECC value for all 0xff's case.
This we have seen when using UBIFS, sometimes read happens on erased page. 
> 
> > +		mtd_ooblayout_get_eccbytes(mtd, ecc_code,
> > chip->oob_poi, 0,
> > +					   chip->ecc.total);
> > +		for (i = 0 ; eccsteps; eccsteps--, i += eccbytes,
> > +		     p += eccsize) {
> > +			stat = nand_check_erased_ecc_chunk(p,
> > chip->ecc.size, &ecc_code[i], eccbytes, NULL, 0, chip->ecc.strength);
> 
> Do you actually check the entire OOB area here ?
> 
> Can't you just do the check on chip->oob_poi?

Above comments answers this.
> 
> > +		}
> > +		if (stat < 0)
> 
> Please check this, but I think you should increment ecc_stats.failed here.
Yes,  I will update.
> 
> > +			stat = 0;
> > +		else
> > +			mtd->ecc_stats.corrected += stat;
> > +		return stat;
> > +	}
> > +
> > +	return 0;
> > +}
> 
> Can you run nandbiterrs test (from mtd-utils) with both Hamming and BCH and
> check it fails after the right number of bitflips?
Ok, I will run.
> 
> > +
> > +static int anfc_write_page_hwecc(struct mtd_info *mtd,
> > +				 struct nand_chip *chip, const
> > uint8_t *buf,
> > +				 int oob_required, int page)
> > +{
> > +	int ret;
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	u8 *ecc_calc = chip->buffers->ecccalc;
> > +
> > +	anfc_set_eccsparecmd(nfc, achip, NAND_CMD_RNDIN, 0);
> > +	anfc_config_ecc(nfc, 1);
> > +
> > +	chip->write_buf(mtd, buf, mtd->writesize);
> > +
> > +	if (oob_required) {
> > +		chip->waitfunc(mtd, chip);
> > +		chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
> > +		chip->read_buf(mtd, ecc_calc, mtd->oobsize);
> > +		ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc,
> > chip->oob_poi,
> > +						 0, chip->ecc.total);
> > +		if (ret)
> > +			return ret;
> > +		chip->ecc.write_oob(mtd, chip, page);
> > +	}
> > +	anfc_config_ecc(nfc, 0);
> > +
> > +	return 0;
> > +}
> > +
> > +static u8 anfc_read_byte(struct mtd_info *mtd) {
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +
> > +	if (nfc->curr_cmd == NAND_CMD_STATUS)
> > +		return readl(nfc->base + FLASH_STS_OFST);
> > +	else
> > +		return nfc->buf[nfc->bufshift++];
> > +}
> > +
> > +static int anfc_extra_init(struct anfc *nfc, struct anfc_nand_chip
> > *achip) +{
> > +	int mode, err;
> > +	unsigned int feature[2];
> > +	u32 inftimeval;
> > +	struct nand_chip *chip = &achip->chip;
> > +	struct mtd_info *mtd = nand_to_mtd(chip);
> > +	bool change_sdr_clk = false;
> > +
> > +	if (!chip->onfi_version ||
> > +	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
> > +	    & ONFI_OPT_CMD_SET_GET_FEATURES))
> > +		return -EINVAL;
> 
> I think this check is already done by the core.
See my comments below.
> 
> > +
> > +	/*
> > +	 * If the controller is already in the same mode as flash
> > device
> > +	 * then no need to change the timing mode again.
> > +	 */
> > +	if (readl(nfc->base + DATA_INTERFACE_OFST) ==
> > achip->inftimeval)
> > +		return 0;
> > +
> > +	memset(feature, 0, NVDDR_MODE_PACKET_SIZE);
> > +	/* Get nvddr timing modes */
> > +	mode = onfi_get_sync_timing_mode(chip) & 0xff;
> > +	if (!mode) {
> > +		mode = fls(onfi_get_async_timing_mode(chip)) - 1;
> > +		inftimeval = mode;
> > +		if (mode >= 2 && mode <= 5)
> > +			change_sdr_clk = true;
> > +	} else {
> > +		mode = fls(mode) - 1;
> > +		inftimeval = NVDDR_MODE | (mode <<
> > NVDDR_TIMING_MODE_SHIFT);
> > +		mode |= ONFI_DATA_INTERFACE_NVDDR;
> > +	}
> > +	feature[0] = mode;
> > +	chip->select_chip(mtd, achip->csnum);
> > +	err = chip->onfi_set_features(mtd, chip,
> > ONFI_FEATURE_ADDR_TIMING_MODE,
> > +		(uint8_t *)feature);
> > +	chip->select_chip(mtd, -1);
> > +	if (err)
> > +		return err;
> 
> You should forget all the NAND chip related code here, the core already handles
> it, and then calls ->setup_data_interface() to tune timings on the controller side
> only.
Since core doesn't have support for NVDDR, 
enum nand_data_interface_type {
	NAND_SDR_IFACE,
};
we added this logic in setup_data_interface. To achieve the same
So what we are doing here is, 
When core calls setup_data_interface, the flash changes its operating mode to SDR.
And when flash supports NVDDR, we are changing the 
Flash operating mode to NVDDR.
Also the setup_data_interface call will happen during probe time, and at this time we don't have
Parameter page info, hence I added 
if (!chip->onfi_version ||
	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
	    & ONFI_OPT_CMD_SET_GET_FEATURES))
		return -EINVAL;
> 
> > +	/*
> > +	 * SDR timing modes 2-5 will not work for the arasan nand
> > when
> > +	 * freq > 90 MHz, so reduce the freq in SDR modes 2-5 to <
> > 90Mhz
> > +	 */
> > +	if (change_sdr_clk) {
> > +		clk_disable_unprepare(nfc->clk_sys);
> > +		err = clk_set_rate(nfc->clk_sys,
> > SDR_MODE_DEFLT_FREQ);
> > +		if (err) {
> > +			dev_err(nfc->dev, "Can't set the clock
> > rate\n");
> > +			return err;
> > +		}
> > +		err = clk_prepare_enable(nfc->clk_sys);
> > +		if (err) {
> > +			dev_err(nfc->dev, "Unable to enable sys
> > clock.\n");
> > +			clk_disable_unprepare(nfc->clk_sys);
> > +			return err;
> > +		}
> 
> You do this twice as it is already handled in ->setup_data_interface().
Yes, we added it twice, once when core sends SDR info
And the second, because there is a HW bug in controller, i.e SDR timing modes 2-5 will not work, when freq > 90MHz.
Hence when Flash operates at SDR modes 2-5, we are changing the clock rate to below 90MHz
> 
> > +	}
> > +	achip->inftimeval = inftimeval;
> > +	if (mode & ONFI_DATA_INTERFACE_NVDDR)
> > +		achip->spktsize = NVDDR_MODE_PACKET_SIZE;
> > +	return 0;
> > +}
> 
> I don't think this should be in a separate function and instead should be in -
> >setup_data_interface().
Yes, we can do it in single function, but as mentioned in comments, we added this extra_init().
> 
> > +
> > +static int anfc_ecc_init(struct mtd_info *mtd,
> > +			 struct nand_ecc_ctrl *ecc)
> > +{
> > +	u32 ecc_addr;
> > +	unsigned int bchmode, steps;
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +
> > +	ecc->mode = NAND_ECC_HW;
> > +	ecc->read_page = anfc_read_page_hwecc;
> > +	ecc->write_page = anfc_write_page_hwecc;
> > +	ecc->write_oob = anfc_write_oob;
> > +	mtd_set_ooblayout(mtd, &anfc_ooblayout_ops);
> > +
> > +	steps = mtd->writesize / chip->ecc_step_ds;
> > +
> > +	switch (chip->ecc_strength_ds) {
> > +	case 12:
> > +		bchmode = 0x1;
> > +		break;
> > +	case 8:
> > +		bchmode = 0x2;
> > +		break;
> > +	case 4:
> > +		bchmode = 0x3;
> > +		break;
> > +	case 24:
> > +		bchmode = 0x4;
> > +		break;
> > +	default:
> > +		bchmode = 0x0;
> > +	}
> > +
> > +	if (!bchmode)
> > +		ecc->total = 3 * steps;
> > +	else
> > +		ecc->total =
> > +		     DIV_ROUND_UP(fls(8 * chip->ecc_step_ds) *
> > +			 chip->ecc_strength_ds * steps, 8);
> > +
> > +	ecc->strength = chip->ecc_strength_ds;
> > +	ecc->size = chip->ecc_step_ds;
> > +	ecc->bytes = ecc->total / steps;
> > +	ecc->steps = steps;
> > +	achip->bchmode = bchmode;
> > +	achip->bch = achip->bchmode;
> > +	ecc_addr = mtd->writesize + (mtd->oobsize - ecc->total);
> > +
> > +	achip->eccval = ecc_addr | (ecc->total << ECC_SIZE_SHIFT) |
> > +			(achip->bch << BCH_EN_SHIFT);
> > +
> > +	if (chip->ecc_step_ds >= 1024)
> > +		achip->pktsize = 1024;
> > +	else
> > +		achip->pktsize = 512;
> > +
> > +	return 0;
> > +}
> > +
> > +static void anfc_cmd_function(struct mtd_info *mtd,
> > +			      unsigned int cmd, int column, int
> > page_addr) +{
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	bool wait = false;
> > +	u32 addrcycles, prog;
> > +
> > +	nfc->bufshift = 0;
> > +	nfc->curr_cmd = cmd;
> > +
> > +	if (page_addr == -1)
> > +		page_addr = 0;
> > +	if (column == -1)
> > +		column = 0;
> > +
> > +	switch (cmd) {
> > +	case NAND_CMD_RESET:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 0);
> > +		prog = PROG_RST;
> > +		wait = true;
> > +		break;
> > +	case NAND_CMD_SEQIN:
> > +		addrcycles = achip->raddr_cycles +
> > achip->caddr_cycles;
> > +		anfc_prepare_cmd(nfc, cmd, NAND_CMD_PAGEPROG, 1,
> > +				 mtd->writesize, addrcycles);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		break;
> > +	case NAND_CMD_READOOB:
> > +		column += mtd->writesize;
> > +	case NAND_CMD_READ0:
> > +	case NAND_CMD_READ1:
> > +		addrcycles = achip->raddr_cycles +
> > achip->caddr_cycles;
> > +		anfc_prepare_cmd(nfc, NAND_CMD_READ0,
> > NAND_CMD_READSTART, 1,
> > +				 mtd->writesize, addrcycles);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		break;
> > +	case NAND_CMD_RNDOUT:
> > +		anfc_prepare_cmd(nfc, cmd, NAND_CMD_RNDOUTSTART, 1,
> > +				 mtd->writesize, 2);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		break;
> > +	case NAND_CMD_PARAM:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 1);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		anfc_rw_buf_pio(mtd, nfc->buf,
> > +				(4 * sizeof(struct
> > nand_onfi_params)),
> > +				1, PROG_RDPARAM);
> > +		break;
> > +	case NAND_CMD_READID:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 1);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		anfc_rw_buf_pio(mtd, nfc->buf, ONFI_ID_LEN, 1,
> > PROG_RDID);
> > +		break;
> > +	case NAND_CMD_ERASE1:
> > +		addrcycles = achip->raddr_cycles;
> > +		prog = PROG_ERASE;
> > +		anfc_prepare_cmd(nfc, cmd, NAND_CMD_ERASE2, 0, 0,
> > addrcycles);
> > +		column = page_addr & 0xffff;
> > +		page_addr = (page_addr >> PG_ADDR_SHIFT) & 0xffff;
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		wait = true;
> > +		break;
> > +	case NAND_CMD_STATUS:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 0);
> > +		anfc_setpktszcnt(nfc, achip->spktsize / 4, 1);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		prog = PROG_STATUS;
> > +		wait = true;
> > +		break;
> > +	case NAND_CMD_GET_FEATURES:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 1);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		anfc_rw_buf_pio(mtd, nfc->buf, achip->spktsize, 1,
> > +				PROG_GET_FEATURE);
> > +		break;
> > +	case NAND_CMD_SET_FEATURES:
> > +		anfc_prepare_cmd(nfc, cmd, 0, 0, 0, 1);
> > +		anfc_setpagecoladdr(nfc, page_addr, column);
> > +		break;
> > +	default:
> > +		return;
> > +	}
> > +
> > +	if (wait) {
> > +		anfc_enable_intrs(nfc, XFER_COMPLETE);
> > +		writel(prog, nfc->base + PROG_OFST);
> > +		anfc_wait_for_event(nfc);
> > +	}
> > +	if (nfc->curr_cmd == NAND_CMD_STATUS)
> > +		nfc->status = readl(nfc->base + FLASH_STS_OFST); }
> > +
> > +static void anfc_select_chip(struct mtd_info *mtd, int num) {
> > +	u32 val;
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +
> > +	if (num == -1)
> > +		return;
> > +
> > +	val = readl(nfc->base + MEM_ADDR2_OFST);
> > +	val &= (val & ~(CS_MASK | BCH_MODE_MASK));
> > +	val |= (achip->csnum << CS_SHIFT) | (achip->bchmode <<
> > BCH_MODE_SHIFT);
> > +	writel(val, nfc->base + MEM_ADDR2_OFST);
> > +	nfc->csnum = achip->csnum;
> > +	writel(achip->eccval, nfc->base + ECC_OFST);
> > +	writel(achip->inftimeval, nfc->base + DATA_INTERFACE_OFST); }
> > +
> > +static irqreturn_t anfc_irq_handler(int irq, void *ptr) {
> > +	struct anfc *nfc = ptr;
> > +	u32 status;
> > +
> > +	status = readl(nfc->base + INTR_STS_OFST);
> > +	if (status & EVENT_MASK) {
> > +		complete(&nfc->event);
> > +		writel((status & EVENT_MASK), nfc->base +
> > INTR_STS_OFST);
> > +		writel(0, nfc->base + INTR_STS_EN_OFST);
> > +		writel(0, nfc->base + INTR_SIG_EN_OFST);
> > +		return IRQ_HANDLED;
> > +	}
> > +
> > +	return IRQ_NONE;
> > +}
> > +
> > +static int anfc_onfi_set_features(struct mtd_info *mtd, struct
> > nand_chip *chip,
> > +				  int addr, uint8_t
> > *subfeature_param) +{
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +	int status;
> > +
> > +	if (!chip->onfi_version)
> > +		return -EINVAL;
> > +
> > +	if (!(le16_to_cpu(chip->onfi_params.opt_cmd) &
> > +		ONFI_OPT_CMD_SET_GET_FEATURES))
> > +		return -EINVAL;
> > +
> > +	chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
> > +	anfc_rw_buf_pio(mtd, subfeature_param, achip->spktsize,
> > +			0, PROG_SET_FEATURE);
> > +	status = chip->waitfunc(mtd, chip);
> > +	if (status & NAND_STATUS_FAIL)
> > +		return -EIO;
> > +
> > +	return 0;
> > +}
> 
> Are you sure this function is needed? If yes can you add a comment to explain
> why? Otherwise I think the core already handles that kind of logic.
We added this to set/get features of on-die ECC. At the time of adding this, core doesn?t have support
For this. I will remove it now, since micron on-die ecc driver is there.
> 
> > +
> > +static int anfc_setup_data_interface(struct mtd_info *mtd, int
> > csline,
> > +				     const struct
> > nand_data_interface *conf) +{
> > +	struct nand_chip *chip = mtd_to_nand(mtd);
> > +	struct anfc *nfc = to_anfc(chip->controller);
> > +	int err;
> > +	struct anfc_nand_chip *achip = to_anfc_nand(chip);
> > +
> > +	if (csline == NAND_DATA_IFACE_CHECK_ONLY)
> > +		return 0;
> > +
> > +	clk_disable_unprepare(nfc->clk_sys);
> > +	err = clk_set_rate(nfc->clk_sys, SDR_MODE_DEFLT_FREQ);
> > +	if (err) {
> > +		dev_err(nfc->dev, "Can't set the clock rate\n");
> > +		return err;
> > +	}
> > +	err = clk_prepare_enable(nfc->clk_sys);
> > +	if (err) {
> > +		dev_err(nfc->dev, "Unable to enable sys clock.\n");
> > +		clk_disable_unprepare(nfc->clk_sys);
> > +		return err;
> > +	}
> > +	achip->inftimeval = 0;
> > +	anfc_extra_init(nfc, achip);
> > +
> > +	return 0;
> > +}
> > +
> > +static int anfc_nand_chip_init(struct anfc *nfc,
> > +			       struct anfc_nand_chip *anand_chip,
> > +			       struct device_node *np)
> > +{
> > +	struct nand_chip *chip = &anand_chip->chip;
> > +	struct mtd_info *mtd = nand_to_mtd(chip);
> > +	int ret;
> > +
> > +	ret = of_property_read_u32(np, "reg", &anand_chip->csnum);
> > +	if (ret) {
> > +		dev_err(nfc->dev, "can't get chip-select\n");
> > +		return -ENXIO;
> > +	}
> > +
> > +	mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL,
> > "arasan_nand.%d",
> > +				   anand_chip->csnum);
> > +	mtd->dev.parent = nfc->dev;
> > +
> > +	chip->cmdfunc = anfc_cmd_function;
> > +	chip->chip_delay = 30;
> > +	chip->controller = &nfc->controller;
> > +	chip->read_buf = anfc_read_buf;
> > +	chip->write_buf = anfc_write_buf;
> > +	chip->read_byte = anfc_read_byte;
> > +	chip->options = NAND_BUSWIDTH_AUTO |
> NAND_NO_SUBPAGE_WRITE;
> > +	chip->bbt_options = NAND_BBT_USE_FLASH;
> > +	chip->select_chip = anfc_select_chip;
> > +	chip->onfi_set_features = anfc_onfi_set_features;
> > +	chip->setup_data_interface = anfc_setup_data_interface;
> > +	nand_set_flash_node(chip, np);
> > +
> > +	anand_chip->spktsize = SDR_MODE_PACKET_SIZE;
> > +	ret = nand_scan_ident(mtd, 1, NULL);
> > +	if (ret) {
> > +		dev_err(nfc->dev, "nand_scan_ident for NAND
> > failed\n");
> > +		return ret;
> > +	}
> > +	if (chip->onfi_version) {
> > +		anand_chip->raddr_cycles =
> > chip->onfi_params.addr_cycles & 0xf;
> > +		anand_chip->caddr_cycles =
> > +				(chip->onfi_params.addr_cycles >> 4)
> > & 0xf;
> > +	} else {
> > +		/* For non-ONFI devices, configuring the address
> > cyles as 5 */
> > +		anand_chip->raddr_cycles = 3;
> > +		anand_chip->caddr_cycles = 2;
> > +	}
> 
> I think you should remove this block and instead decide how many cycles you
> will need depending on "chip->options & NAND_ROW_ADDR_3".
If chip supports ONFI, then we are reading addr cycles from parameter page, if not 
We are setting with default values.
I am not checking the sizes here, instead reading it from parameter page.
I didn't get your comment, can you please brief it?
I saw the patch https://patchwork.kernel.org/patch/9950377/.
These are based on sizes, and cycles are getting updated using " NAND_ROW_ADDR_3"
But the case here is I am setting some default values if not ONFI. 
> 
> > +
> > +	ret = anfc_ecc_init(mtd, &chip->ecc);
> > +	if (ret)
> > +		return ret;
> > +
> 
> Shouldn't the controller set mtd->name here if empty?
Yes, driver is not setting the name if empty.
I will add this in next version of patch.
> 
> > +	ret = nand_scan_tail(mtd);
> > +	if (ret) {
> > +		dev_err(nfc->dev, "nand_scan_tail for NAND
> > failed\n");
> > +		return ret;
> > +	}
> > +
> > +	return mtd_device_register(mtd, NULL, 0); }
> > +
> > +static int anfc_probe(struct platform_device *pdev) {
> > +	struct anfc *nfc;
> > +	struct anfc_nand_chip *anand_chip;
> > +	struct device_node *np = pdev->dev.of_node, *child;
> > +	struct resource *res;
> > +	int err;
> > +
> > +	nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
> > +	if (!nfc)
> > +		return -ENOMEM;
> > +
> > +	init_waitqueue_head(&nfc->controller.wq);
> > +	INIT_LIST_HEAD(&nfc->chips);
> > +	init_completion(&nfc->event);
> > +	nfc->dev = &pdev->dev;
> > +	platform_set_drvdata(pdev, nfc);
> > +	nfc->csnum = -1;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	nfc->base = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(nfc->base))
> > +		return PTR_ERR(nfc->base);
> > +	nfc->dma = of_property_read_bool(pdev->dev.of_node,
> > +					 "arasan,has-mdma");
> > +	nfc->irq = platform_get_irq(pdev, 0);
> > +	if (nfc->irq < 0) {
> > +		dev_err(&pdev->dev, "platform_get_irq failed\n");
> > +		return -ENXIO;
> > +	}
> > +	dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
> > +	err = devm_request_irq(&pdev->dev, nfc->irq,
> > anfc_irq_handler,
> > +			       0, "arasannfc", nfc);
> > +	if (err)
> > +		return err;
> > +	nfc->clk_sys = devm_clk_get(&pdev->dev, "sys");
> > +	if (IS_ERR(nfc->clk_sys)) {
> > +		dev_err(&pdev->dev, "sys clock not found.\n");
> > +		return PTR_ERR(nfc->clk_sys);
> > +	}
> > +
> > +	nfc->clk_flash = devm_clk_get(&pdev->dev, "flash");
> > +	if (IS_ERR(nfc->clk_flash)) {
> > +		dev_err(&pdev->dev, "flash clock not found.\n");
> > +		return PTR_ERR(nfc->clk_flash);
> > +	}
> > +
> > +	err = clk_prepare_enable(nfc->clk_sys);
> > +	if (err) {
> > +		dev_err(&pdev->dev, "Unable to enable sys clock.\n");
> > +		return err;
> > +	}
> > +
> > +	err = clk_prepare_enable(nfc->clk_flash);
> > +	if (err) {
> > +		dev_err(&pdev->dev, "Unable to enable flash
> > clock.\n");
> > +		goto clk_dis_sys;
> > +	}
> > +
> > +	for_each_available_child_of_node(np, child) {
> > +		anand_chip = devm_kzalloc(&pdev->dev,
> > sizeof(*anand_chip),
> > +					  GFP_KERNEL);
> > +		if (!anand_chip) {
> > +			of_node_put(child);
> > +			err = -ENOMEM;
> > +			goto nandchip_clean_up;
> > +		}
> > +
> > +		err = anfc_nand_chip_init(nfc, anand_chip, child);
> > +		if (err) {
> > +			devm_kfree(&pdev->dev, anand_chip);
> > +			continue;
> > +		}
> > +
> > +		list_add_tail(&anand_chip->node, &nfc->chips);
> > +	}
> > +
> > +	return 0;
> > +
> > +nandchip_clean_up:
> > +	list_for_each_entry(anand_chip, &nfc->chips, node)
> > +		nand_release(nand_to_mtd(&anand_chip->chip));
> > +	clk_disable_unprepare(nfc->clk_flash);
> > +clk_dis_sys:
> > +	clk_disable_unprepare(nfc->clk_sys);
> > +
> > +	return err;
> > +}
> > +
> > +static int anfc_remove(struct platform_device *pdev) {
> > +	struct anfc *nfc = platform_get_drvdata(pdev);
> > +	struct anfc_nand_chip *anand_chip;
> > +
> > +	list_for_each_entry(anand_chip, &nfc->chips, node)
> > +		nand_release(nand_to_mtd(&anand_chip->chip));
> > +
> > +	clk_disable_unprepare(nfc->clk_sys);
> > +	clk_disable_unprepare(nfc->clk_flash);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id anfc_ids[] = {
> > +	{ .compatible = "arasan,nfc-v3p10" },
> > +	{ .compatible = "xlnx,zynqmp-nand" },
> > +	{  }
> > +};
> > +MODULE_DEVICE_TABLE(of, anfc_ids);
> > +
> > +static struct platform_driver anfc_driver = {
> > +	.driver = {
> > +		.name = DRIVER_NAME,
> > +		.of_match_table = anfc_ids,
> > +	},
> > +	.probe = anfc_probe,
> > +	.remove = anfc_remove,
> > +};
> > +module_platform_driver(anfc_driver);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Xilinx, Inc");
> > +MODULE_DESCRIPTION("Arasan NAND Flash Controller Driver");
> 
> 
> 
> --
> Miquel Raynal, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

I will restructure the driver to sync with exec_op().
Thanks again for reviewing the driver.

Thanks,
Naga Sureshkumar Relli.

From richard at nod.at  Mon Jan 22 06:11:29 2018
From: richard at nod.at (Richard Weinberger)
Date: Mon, 22 Jan 2018 15:11:29 +0100
Subject: [GIT PULL] UBI/UBIFS changes for v4.16
Message-ID: <1676165.UvfiLElynS@blindfold>

Linus,

Sorry, I'm a week too early. Since I'm on vacation for the next two weeks
I'm sending the PR for UBI/UBIFS now and ask you to queue it until next
week (or as soon the merge window opens).

Thanks,
//richard

The following changes since commit a8750ddca918032d6349adbf9a4b6555e7db20da:

  Linux 4.15-rc8 (2018-01-14 15:32:30 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-ubifs.git tags/upstream-4.16-rc1

for you to fetch changes up to 7f29ae9f977bcdc3654e68bc36d170223c52fd48:

  ubi: block: Fix locking for idr_alloc/idr_remove (2018-01-18 16:48:31 +0100)

----------------------------------------------------------------
This pull request contains updates for both UBI and UBIFS:
- Usage of new fscrypt APIs
- A fix for a Fastmap issue
- Other minor bug fixes

----------------------------------------------------------------
Bradley Bolen (1):
      ubi: block: Fix locking for idr_alloc/idr_remove

Clay McClure (1):
      ubi: Fix race condition between ubi volume creation and udev

Colin Ian King (1):
      ubi: fastmap: Clean up the initialization of pointer p

Eric Biggers (5):
      ubifs: switch to fscrypt_file_open()
      ubifs: switch to fscrypt_prepare_link()
      ubifs: switch to fscrypt_prepare_rename()
      ubifs: switch to fscrypt_prepare_lookup()
      ubifs: switch to fscrypt_prepare_setattr()

Geert Uytterhoeven (1):
      ubifs: Fix uninitialized variable in search_dh_cookie()

Jeff Westfahl (1):
      mtd: ubi: Use 'max_bad_blocks' to compute bad_peb_limit if available

Pan Bian (1):
      ubi: fastmap: Use kmem_cache_free to deallocate memory

Rock Lee (1):
      ubifs: remove error message in ubifs_xattr_get

Sascha Hauer (3):
      ubi: fastmap: Erase outdated anchor PEBs during attach
      ubi: Fastmap: Fix typo
      ubi: Fix copy/paste error in function documentation

Wei Yongjun (1):
      mtd: ubi: wl: Fix error return code in ubi_wl_init()

 drivers/mtd/ubi/block.c      | 42 +++++++++++++--------
 drivers/mtd/ubi/build.c      | 13 ++++++-
 drivers/mtd/ubi/eba.c        |  2 +-
 drivers/mtd/ubi/fastmap-wl.c |  2 +-
 drivers/mtd/ubi/fastmap.c    |  5 +--
 drivers/mtd/ubi/vmt.c        | 15 +++++---
 drivers/mtd/ubi/wl.c         | 87 ++++++++++++++++++++++++++++++++------------
 drivers/mtd/ubi/wl.h         |  2 +-
 fs/ubifs/dir.c               | 43 +++++++---------------
 fs/ubifs/file.c              | 41 ++-------------------
 fs/ubifs/tnc.c               | 21 ++++-------
 fs/ubifs/xattr.c             |  2 -
 12 files changed, 140 insertions(+), 135 deletions(-)



From boris.brezillon at free-electrons.com  Mon Jan 22 13:51:48 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 22 Jan 2018 22:51:48 +0100
Subject: [PATCH] mtd: nand: gpmi: Add missing nand_read_page_op() in
 gpmi_ecc_read_subpage()
Message-ID: <20180122215148.4502-1-boris.brezillon@free-electrons.com>

When a subpage read request accesses the ECC block containing the BBM,
a full page read is required. Commit 25f815f66a14 ("mtd: nand: force
drivers to explicitly send READ/PROG commands") changed the default
behavior by forcing drivers to manually issue the READ0 command.
Unfortunately, the full page read case in gpmi_ecc_read_subpage() has
been omitted and the nand_read_page_op() call has been moved too far
in the function leading to a situation where gpmi_ecc_read_page() is
called without a READ0 command.

Fix that by adding a call to nand_read_page_op() just before calling
gpmi_ecc_read_page() in the "access ECC block containing the BBM" case.

Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index b51db8c85405..3198f5f79a82 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1215,6 +1215,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			dev_dbg(this->dev,
 				"page:%d, first:%d, last:%d, marker at:%d\n",
 				page, first, last, marker_pos);
+			nand_read_page_op(chip, page, 0, NULL, 0);
 			return gpmi_ecc_read_page(mtd, chip, buf, 0, page);
 		}
 	}
-- 
2.11.0



From boris.brezillon at free-electrons.com  Mon Jan 22 14:48:42 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 22 Jan 2018 23:48:42 +0100
Subject: [PATCH] mtd: nand: gpmi: Add missing nand_read_page_op() in
 gpmi_ecc_read_subpage()
In-Reply-To: <20180122215148.4502-1-boris.brezillon@free-electrons.com>
References: <20180122215148.4502-1-boris.brezillon@free-electrons.com>
Message-ID: <20180122234842.42949308@bbrezillon>

On Mon, 22 Jan 2018 22:51:48 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> When a subpage read request accesses the ECC block containing the BBM,
> a full page read is required. Commit 25f815f66a14 ("mtd: nand: force
> drivers to explicitly send READ/PROG commands") changed the default
> behavior by forcing drivers to manually issue the READ0 command.
> Unfortunately, the full page read case in gpmi_ecc_read_subpage() has
> been omitted and the nand_read_page_op() call has been moved too far
> in the function leading to a situation where gpmi_ecc_read_page() is
> called without a READ0 command.
> 
> Fix that by adding a call to nand_read_page_op() just before calling
> gpmi_ecc_read_page() in the "access ECC block containing the BBM" case.
> 
> Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index b51db8c85405..3198f5f79a82 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -1215,6 +1215,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
>  			dev_dbg(this->dev,
>  				"page:%d, first:%d, last:%d, marker at:%d\n",
>  				page, first, last, marker_pos);
> +			nand_read_page_op(chip, page, 0, NULL, 0);
>  			return gpmi_ecc_read_page(mtd, chip, buf, 0, page);

Please ignore this patch: nand_read_page_op() is already called from
gpmi_ecc_read_page().

>  		}
>  	}



From miquel.raynal at free-electrons.com  Tue Jan 23 00:00:46 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue, 23 Jan 2018 09:00:46 +0100
Subject: [PATCH] mtd: Make sure the device supports erase operations in
 mtd_erase()
In-Reply-To: <20180122093801.19618-1-boris.brezillon@free-electrons.com>
References: <20180122093801.19618-1-boris.brezillon@free-electrons.com>
Message-ID: <20180123090046.503b1129@xps13>

Hello Boris,

On Mon, 22 Jan 2018 10:38:01 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Some devices do not implement ->_erase() or have an invalid ->erasesize
> value. In this case, mtd_erase() should return -ENOTSUPP.
> 
> Note that the test is not done on the MTD_NO_ERASE flag because this
> flag means 'erasing a block before writing to it is unnecessary',
> not 'the erase operation is not supported'. Actually, some drivers are
> setting the MTD_NO_ERASE flag but still implementing the ->_erase()
> hook and setting a valid ->erasesize value.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
>  drivers/mtd/mtdcore.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index d7ab091b36b2..f24144cbc99c 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -971,10 +971,14 @@ EXPORT_SYMBOL_GPL(__put_mtd_device);
>   */
>  int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
>  {
> +	if (!mtd->erasesize || !mtd->_erase)
> +		return -ENOTSUPP;
> +
>  	if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
>  		return -EINVAL;
>  	if (!(mtd->flags & MTD_WRITEABLE))
>  		return -EROFS;

This remark is not inherent to this patch in particular but as we are
adding a new error path, I thought it might be interesting to also
patch:
- INFTL_formatblock() from inftlmount.c [1] (mtd_erase called twice)
- NFTL_formatblock() from nftlmount.c [2]

They both call mtd_erase() without checking the return code and then
error out only if instr->state == MTD_ERASE_FAILED, which has not been
set before quitting mtd_erase() in the conditions above. I guess the
right thing to do is to add another condition in both functions on the
return code of mtd_erase(). What do you think?

Otherwise:
Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Have a good day,
Miqu?l

[1]
http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/inftlmount.c#L396
[2]
http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nftlmount.c#L334


From boris.brezillon at free-electrons.com  Tue Jan 23 02:13:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 23 Jan 2018 11:13:17 +0100
Subject: [PATCH] mtd: nand: gpmi: Fix subpage reads
Message-ID: <20180123101317.15925-1-boris.brezillon@free-electrons.com>

Commit 25f815f66a14 ("mtd: nand: force drivers to explicitly send
READ/PROG commands") added a call to nand_read_page_op() in
gpmi_ecc_read_page(), which means this function now sends a READ0
command and place the data pointer at the beginning of the page. This
logic is breaking gpmi_ecc_read_subpage() which was calling
gpmi_ecc_read_page() and expected it to only retrieve the data without
sending the READ0 command.

Create a gpmi_ecc_read_page_data() helper which only does the data
retrieval and ECC correction steps and implement gpmi_ecc_read_page()
as a wrapper that calls nand_read_page_op()+gpmi_ecc_read_page_data().

This way, gpmi_ecc_read_subpage() can call gpmi_ecc_read_page_data()
which restores the logic we had before commit 25f815f66a14 ("mtd: nand:
force drivers to explicitly send READ/PROG commands").

Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 3198f5f79a82..93f212457d4d 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1029,11 +1029,13 @@ static void block_mark_swapping(struct gpmi_nand_data *this,
 	p[1] = (p[1] & mask) | (from_oob >> (8 - bit));
 }
 
-static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
-				uint8_t *buf, int oob_required, int page)
+static int gpmi_ecc_read_page_data(struct nand_chip *chip,
+				   uint8_t *buf, int oob_required,
+				   int page)
 {
 	struct gpmi_nand_data *this = nand_get_controller_data(chip);
 	struct bch_geometry *nfc_geo = &this->bch_geometry;
+	struct mtd_info *mtd = nand_to_mtd(chip);
 	void          *payload_virt;
 	dma_addr_t    payload_phys;
 	void          *auxiliary_virt;
@@ -1043,8 +1045,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	unsigned int  max_bitflips = 0;
 	int           ret;
 
-	nand_read_page_op(chip, page, 0, NULL, 0);
-
 	dev_dbg(this->dev, "page number is : %d\n", page);
 	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
 					this->payload_virt, this->payload_phys,
@@ -1178,6 +1178,14 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	return max_bitflips;
 }
 
+static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int oob_required, int page)
+{
+	nand_read_page_op(chip, page, 0, NULL, 0);
+
+	return gpmi_ecc_read_page_data(chip, buf, oob_required, page);
+}
+
 /* Fake a virtual small page for the subpage read */
 static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offs, uint32_t len, uint8_t *buf, int page)
@@ -1257,7 +1265,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 
 	/* Read the subpage now */
 	this->swap_block_mark = false;
-	max_bitflips = gpmi_ecc_read_page(mtd, chip, buf, 0, page);
+	max_bitflips = gpmi_ecc_read_page_data(chip, buf, 0, page);
 
 	/* Restore */
 	writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0);
-- 
2.11.0



From boris.brezillon at free-electrons.com  Tue Jan 23 02:24:24 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 23 Jan 2018 11:24:24 +0100
Subject: [PATCH] mtd: Make sure the device supports erase operations in
 mtd_erase()
In-Reply-To: <20180123090046.503b1129@xps13>
References: <20180122093801.19618-1-boris.brezillon@free-electrons.com>
 <20180123090046.503b1129@xps13>
Message-ID: <20180123112424.36e5e426@bbrezillon>

On Tue, 23 Jan 2018 09:00:46 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Hello Boris,
> 
> On Mon, 22 Jan 2018 10:38:01 +0100
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > Some devices do not implement ->_erase() or have an invalid ->erasesize
> > value. In this case, mtd_erase() should return -ENOTSUPP.
> > 
> > Note that the test is not done on the MTD_NO_ERASE flag because this
> > flag means 'erasing a block before writing to it is unnecessary',
> > not 'the erase operation is not supported'. Actually, some drivers are
> > setting the MTD_NO_ERASE flag but still implementing the ->_erase()
> > hook and setting a valid ->erasesize value.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> > ---
> >  drivers/mtd/mtdcore.c | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> > index d7ab091b36b2..f24144cbc99c 100644
> > --- a/drivers/mtd/mtdcore.c
> > +++ b/drivers/mtd/mtdcore.c
> > @@ -971,10 +971,14 @@ EXPORT_SYMBOL_GPL(__put_mtd_device);
> >   */
> >  int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
> >  {
> > +	if (!mtd->erasesize || !mtd->_erase)
> > +		return -ENOTSUPP;
> > +
> >  	if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
> >  		return -EINVAL;
> >  	if (!(mtd->flags & MTD_WRITEABLE))
> >  		return -EROFS;  
> 
> This remark is not inherent to this patch in particular but as we are
> adding a new error path, I thought it might be interesting to also
> patch:
> - INFTL_formatblock() from inftlmount.c [1] (mtd_erase called twice)
> - NFTL_formatblock() from nftlmount.c [2]
> 
> They both call mtd_erase() without checking the return code and then
> error out only if instr->state == MTD_ERASE_FAILED, which has not been
> set before quitting mtd_erase() in the conditions above. I guess the
> right thing to do is to add another condition in both functions on the
> return code of mtd_erase(). What do you think?

This sounds reasonable.

> 
> Otherwise:
> Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Thanks.

Boris

> 
> Have a good day,
> Miqu?l
> 
> [1]
> http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/inftlmount.c#L396
> [2]
> http://elixir.free-electrons.com/linux/latest/source/drivers/mtd/nftlmount.c#L334



From ladis at linux-mips.org  Wed Jan 24 02:06:04 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 24 Jan 2018 11:06:04 +0100
Subject: [PATCH v2 0/3] Add managed ioremap function for shared resources
Message-ID: <20180124100604.GA19593@lenoch>

Many drivers can simplified by using devm_ioremap_resource()
instead of open coding its functionality. However, as pointed
by Wei Yongjun, that function cannot be used when memory region
is already taken. See previous discussion here:
https://www.spinics.net/lists/linux-pci/msg68495.html

To ease job of driver developers, new function for that
purpose is implemented and its usage shown on davinci
mtd driver.

Changes from previous version:
- moved function prototype in headers other way around (PATCH 1/3),
  the rest of patches was dropped.

Ladislav Michl (3):
  devres: Move devm_ioremap_resource() out of device.h
  devres: Add devm_ioremap_shared_resource()
  mtd: nand: davinci: Use devm_ioremap_shared_resource()

 drivers/mtd/nand/davinci_nand.c | 24 +++++++-----------------
 include/linux/device.h          |  2 --
 include/linux/io.h              |  7 +++++++
 lib/devres.c                    | 22 ++++++++++++++--------
 4 files changed, 28 insertions(+), 27 deletions(-)

-- 
2.15.1



From ladis at linux-mips.org  Wed Jan 24 02:06:57 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 24 Jan 2018 11:06:57 +0100
Subject: [PATCH v2 1/3] devres: Move devm_ioremap_resource() out of device.h
In-Reply-To: <20180124100604.GA19593@lenoch>
References: <20180124100604.GA19593@lenoch>
Message-ID: <20180124100657.GB19593@lenoch>

Move devm_ioremap_resource() out of device.h into io.h to be
consistent with similar APIs.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
---
 Changes:
 - v2: new patch

 include/linux/device.h | 2 --
 include/linux/io.h     | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 4d88b6b9cda9..c9fcee2f5b91 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -683,8 +683,6 @@ extern unsigned long devm_get_free_pages(struct device *dev,
 					 gfp_t gfp_mask, unsigned int order);
 extern void devm_free_pages(struct device *dev, unsigned long addr);
 
-void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
-
 /* allows to add/remove a custom action to devres stack */
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
diff --git a/include/linux/io.h b/include/linux/io.h
index 32e30e8fb9db..2aea3363bfb2 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -79,6 +79,7 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
+void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 void devm_iounmap(struct device *dev, void __iomem *addr);
 int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
-- 
2.15.1



From ladis at linux-mips.org  Wed Jan 24 02:07:54 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 24 Jan 2018 11:07:54 +0100
Subject: [PATCH v2 2/3] devres: Add devm_ioremap_shared_resource()
In-Reply-To: <20180124100604.GA19593@lenoch>
References: <20180124100604.GA19593@lenoch>
Message-ID: <20180124100754.GC19593@lenoch>

Implement managed ioremap function for shared resources.

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
---
 Changes:
 - v2: Rebased on top of PATCH v2 1/3

 include/linux/io.h |  8 +++++++-
 lib/devres.c       | 22 ++++++++++++++--------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/include/linux/io.h b/include/linux/io.h
index 2aea3363bfb2..2b9eb48e0f49 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -79,10 +79,16 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
-void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
+#define devm_ioremap_resource(dev, res) \
+	__devm_ioremap_resource(dev, res, false)
+#define devm_ioremap_shared_resource(dev, res) \
+	__devm_ioremap_resource(dev, res, true)
+void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res,
+				      bool shared);
 void devm_iounmap(struct device *dev, void __iomem *addr);
 int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
+
 void devm_ioremap_release(struct device *dev, void *res);
 
 void *devm_memremap(struct device *dev, resource_size_t offset,
diff --git a/lib/devres.c b/lib/devres.c
index 5f2aedd58bc5..7711ff40a572 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -22,6 +22,9 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
  * @size: Size of map
  *
  * Managed ioremap().  Map is automatically unmapped on driver detach.
+ *
+ * When possible, use devm_ioremap_resource() or
+ * devm_ioremap_shared_resource() instead.
  */
 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 			   resource_size_t size)
@@ -116,13 +119,14 @@ void devm_iounmap(struct device *dev, void __iomem *addr)
 EXPORT_SYMBOL(devm_iounmap);
 
 /**
- * devm_ioremap_resource() - check, request region, and ioremap resource
+ * __devm_ioremap_resource() - check, request region, and ioremap resource
  * @dev: generic device to handle the resource for
  * @res: resource to be handled
+ * @shared: region is not requested when true
  *
- * Checks that a resource is a valid memory region, requests the memory
- * region and ioremaps it. All operations are managed and will be undone
- * on driver detach.
+ * Checks that a resource is a valid memory region, eventually requests the
+ * memory region and ioremaps it. All operations are managed and will be
+ * undone on driver detach.
  *
  * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
  * on failure. Usage example:
@@ -132,7 +136,8 @@ EXPORT_SYMBOL(devm_iounmap);
  *	if (IS_ERR(base))
  *		return PTR_ERR(base);
  */
-void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
+void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res,
+				      bool shared)
 {
 	resource_size_t size;
 	const char *name;
@@ -148,7 +153,7 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 	size = resource_size(res);
 	name = res->name ?: dev_name(dev);
 
-	if (!devm_request_mem_region(dev, res->start, size, name)) {
+	if (!shared && !devm_request_mem_region(dev, res->start, size, name)) {
 		dev_err(dev, "can't request region for resource %pR\n", res);
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
@@ -156,13 +161,14 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 	dest_ptr = devm_ioremap(dev, res->start, size);
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
-		devm_release_mem_region(dev, res->start, size);
+		if (!shared)
+			devm_release_mem_region(dev, res->start, size);
 		dest_ptr = IOMEM_ERR_PTR(-ENOMEM);
 	}
 
 	return dest_ptr;
 }
-EXPORT_SYMBOL(devm_ioremap_resource);
+EXPORT_SYMBOL(__devm_ioremap_resource);
 
 #ifdef CONFIG_HAS_IOPORT_MAP
 /*
-- 
2.15.1



From ladis at linux-mips.org  Wed Jan 24 02:08:28 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 24 Jan 2018 11:08:28 +0100
Subject: [PATCH v2 3/3] mtd: nand: davinci: Use devm_ioremap_shared_resource()
In-Reply-To: <20180124100604.GA19593@lenoch>
References: <20180124100604.GA19593@lenoch>
Message-ID: <20180124100828.GD19593@lenoch>

Simplify error handling by using devm_ioremap_shared_resource().

Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
---
 Changes:
 - v2: None

 drivers/mtd/nand/davinci_nand.c | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index ccc8c43abcff..9b6f06b177b9 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -612,10 +612,8 @@ static int nand_davinci_probe(struct platform_device *pdev)
 {
 	struct davinci_nand_pdata	*pdata;
 	struct davinci_nand_info	*info;
-	struct resource			*res1;
-	struct resource			*res2;
+	struct resource			*res;
 	void __iomem			*vaddr;
-	void __iomem			*base;
 	int				ret;
 	uint32_t			val;
 	struct mtd_info			*mtd;
@@ -638,14 +636,8 @@ static int nand_davinci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, info);
 
-	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res1 || !res2) {
-		dev_err(&pdev->dev, "resource missing\n");
-		return -EINVAL;
-	}
-
-	vaddr = devm_ioremap_resource(&pdev->dev, res1);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	vaddr = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(vaddr))
 		return PTR_ERR(vaddr);
 
@@ -655,14 +647,12 @@ static int nand_davinci_probe(struct platform_device *pdev)
 	 * by AEMIF, so we cannot request it twice, just ioremap.
 	 * The AEMIF and NAND drivers not use the same registers in this range.
 	 */
-	base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2));
-	if (!base) {
-		dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2);
-		return -EADDRNOTAVAIL;
-	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	info->base = devm_ioremap_shared_resource(&pdev->dev, res);
+	if (IS_ERR(info->base))
+		return PTR_ERR(info->base);
 
 	info->dev		= &pdev->dev;
-	info->base		= base;
 	info->vaddr		= vaddr;
 
 	mtd			= nand_to_mtd(&info->chip);
-- 
2.15.1



From miquel.raynal at free-electrons.com  Wed Jan 24 04:51:06 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Wed, 24 Jan 2018 13:51:06 +0100
Subject: [PATCH] mtd: nand: gpmi: Fix subpage reads
In-Reply-To: <20180123101317.15925-1-boris.brezillon@free-electrons.com>
References: <20180123101317.15925-1-boris.brezillon@free-electrons.com>
Message-ID: <20180124135106.2a145a11@xps13>

Hello Boris,

On Tue, 23 Jan 2018 11:13:17 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Commit 25f815f66a14 ("mtd: nand: force drivers to explicitly send
> READ/PROG commands") added a call to nand_read_page_op() in
> gpmi_ecc_read_page(), which means this function now sends a READ0
> command and place the data pointer at the beginning of the page. This
> logic is breaking gpmi_ecc_read_subpage() which was calling
> gpmi_ecc_read_page() and expected it to only retrieve the data without
> sending the READ0 command.
> 
> Create a gpmi_ecc_read_page_data() helper which only does the data
> retrieval and ECC correction steps and implement gpmi_ecc_read_page()
> as a wrapper that calls nand_read_page_op()+gpmi_ecc_read_page_data().
> 
> This way, gpmi_ecc_read_subpage() can call gpmi_ecc_read_page_data()
> which restores the logic we had before commit 25f815f66a14 ("mtd: nand:
> force drivers to explicitly send READ/PROG commands").
> 
> Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---

Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>

Thanks for fixing it,
Miqu?l


From andy.shevchenko at gmail.com  Wed Jan 24 08:21:38 2018
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Wed, 24 Jan 2018 18:21:38 +0200
Subject: [PATCH v2 2/3] devres: Add devm_ioremap_shared_resource()
In-Reply-To: <20180124100754.GC19593@lenoch>
References: <20180124100604.GA19593@lenoch> <20180124100754.GC19593@lenoch>
Message-ID: <CAHp75VeGpj28G60L86d4FDOL1YMAoM5kcdvSC5O6iH4Xi8zfHg@mail.gmail.com>

On Wed, Jan 24, 2018 at 12:07 PM, Ladislav Michl <ladis at linux-mips.org> wrote:
> Implement managed ioremap function for shared resources.

> +#define devm_ioremap_resource(dev, res) \
> +       __devm_ioremap_resource(dev, res, false)
> +#define devm_ioremap_shared_resource(dev, res) \
> +       __devm_ioremap_resource(dev, res, true)
> +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res,
> +                                     bool shared);

I would rather do the following:

_resource() ->  _resource_exclusive()

#define _resource()  _resource_exclusive()

Add _resource_shared()

And use long names below in this file whenever refer to exclusive or
shared variant.

>  void devm_iounmap(struct device *dev, void __iomem *addr);
>  int check_signature(const volatile void __iomem *io_addr,
>                         const unsigned char *signature, int length);
> +
>  void devm_ioremap_release(struct device *dev, void *res);

This part doesn't belong to the change.

> + * When possible, use devm_ioremap_resource() or
> + * devm_ioremap_shared_resource() instead.
> - * Checks that a resource is a valid memory region, requests the memory
> - * region and ioremaps it. All operations are managed and will be undone
> - * on driver detach.
> + * Checks that a resource is a valid memory region, eventually requests the
> + * memory region and ioremaps it. All operations are managed and will be
> + * undone on driver detach.

Wording is changed and no clue in commit message why.


-- 
With Best Regards,
Andy Shevchenko


From andy.shevchenko at gmail.com  Wed Jan 24 08:22:48 2018
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Wed, 24 Jan 2018 18:22:48 +0200
Subject: [PATCH v2 3/3] mtd: nand: davinci: Use
 devm_ioremap_shared_resource()
In-Reply-To: <20180124100828.GD19593@lenoch>
References: <20180124100604.GA19593@lenoch> <20180124100828.GD19593@lenoch>
Message-ID: <CAHp75Vf=5uCmJ4B2wDsbmxq4oJgt5+S2+n-mp1p6g4FLuwOeFw@mail.gmail.com>

On Wed, Jan 24, 2018 at 12:08 PM, Ladislav Michl <ladis at linux-mips.org> wrote:

> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       vaddr = devm_ioremap_resource(&pdev->dev, res);

_resource_exclusive()

> +       info->base = devm_ioremap_shared_resource(&pdev->dev, res);

_resource_shared()

-- 
With Best Regards,
Andy Shevchenko


From andy.shevchenko at gmail.com  Wed Jan 24 08:23:43 2018
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Wed, 24 Jan 2018 18:23:43 +0200
Subject: [PATCH v2 0/3] Add managed ioremap function for shared resources
In-Reply-To: <20180124100604.GA19593@lenoch>
References: <20180124100604.GA19593@lenoch>
Message-ID: <CAHp75VfW--mCEFEh7hFEtMKN0gz4xo2kcrN0y7yyK+QfuZ7NOQ@mail.gmail.com>

On Wed, Jan 24, 2018 at 12:06 PM, Ladislav Michl <ladis at linux-mips.org> wrote:
> Many drivers can simplified by using devm_ioremap_resource()
> instead of open coding its functionality. However, as pointed
> by Wei Yongjun, that function cannot be used when memory region
> is already taken. See previous discussion here:
> https://www.spinics.net/lists/linux-pci/msg68495.html
>
> To ease job of driver developers, new function for that
> purpose is implemented and its usage shown on davinci
> mtd driver.
>

Sometimes we also need that, so, after addressing my comments FWIW

Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>

> Changes from previous version:
> - moved function prototype in headers other way around (PATCH 1/3),
>   the rest of patches was dropped.
>
> Ladislav Michl (3):
>   devres: Move devm_ioremap_resource() out of device.h
>   devres: Add devm_ioremap_shared_resource()
>   mtd: nand: davinci: Use devm_ioremap_shared_resource()
>
>  drivers/mtd/nand/davinci_nand.c | 24 +++++++-----------------
>  include/linux/device.h          |  2 --
>  include/linux/io.h              |  7 +++++++
>  lib/devres.c                    | 22 ++++++++++++++--------
>  4 files changed, 28 insertions(+), 27 deletions(-)
>
> --
> 2.15.1
>



-- 
With Best Regards,
Andy Shevchenko


From ladis at linux-mips.org  Wed Jan 24 09:15:01 2018
From: ladis at linux-mips.org (Ladislav Michl)
Date: Wed, 24 Jan 2018 18:15:01 +0100
Subject: [PATCH v2 2/3] devres: Add devm_ioremap_shared_resource()
In-Reply-To: <CAHp75VeGpj28G60L86d4FDOL1YMAoM5kcdvSC5O6iH4Xi8zfHg@mail.gmail.com>
References: <20180124100604.GA19593@lenoch> <20180124100754.GC19593@lenoch>
 <CAHp75VeGpj28G60L86d4FDOL1YMAoM5kcdvSC5O6iH4Xi8zfHg@mail.gmail.com>
Message-ID: <20180124171501.GA1043@lenoch>

On Wed, Jan 24, 2018 at 06:21:38PM +0200, Andy Shevchenko wrote:
> On Wed, Jan 24, 2018 at 12:07 PM, Ladislav Michl <ladis at linux-mips.org> wrote:
> > Implement managed ioremap function for shared resources.
> 
> > +#define devm_ioremap_resource(dev, res) \
> > +       __devm_ioremap_resource(dev, res, false)
> > +#define devm_ioremap_shared_resource(dev, res) \
> > +       __devm_ioremap_resource(dev, res, true)
> > +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res,
> > +                                     bool shared);
> 
> I would rather do the following:
> 
> _resource() ->  _resource_exclusive()
> 
> #define _resource()  _resource_exclusive()
> 
> Add _resource_shared()
> 
> And use long names below in this file whenever refer to exclusive or
> shared variant.

Two separate functions were also considered, but I was unable to find small
common implementation. If code size does not matter or you can provide a hint
to make this solution small and nice, I'll go for it.

> >  void devm_iounmap(struct device *dev, void __iomem *addr);
> >  int check_signature(const volatile void __iomem *io_addr,
> >                         const unsigned char *signature, int length);
> > +
> >  void devm_ioremap_release(struct device *dev, void *res);
> 
> This part doesn't belong to the change.
> 
> > + * When possible, use devm_ioremap_resource() or
> > + * devm_ioremap_shared_resource() instead.
> > - * Checks that a resource is a valid memory region, requests the memory
> > - * region and ioremaps it. All operations are managed and will be undone
> > - * on driver detach.
> > + * Checks that a resource is a valid memory region, eventually requests the
> > + * memory region and ioremaps it. All operations are managed and will be
> > + * undone on driver detach.
> 
> Wording is changed and no clue in commit message why.

Above will be moved to separate patch.

	ladis


From miquel.raynal at free-electrons.com  Wed Jan 24 14:49:31 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Wed, 24 Jan 2018 23:49:31 +0100
Subject: [PATCH] mtd: nand: sunxi: Fix ECC strength choice
Message-ID: <20180124224931.14392-1-miquel.raynal@free-electrons.com>

When the requested ECC strength does not exactly match the strengths
supported by the ECC engine, the driver is selecting the closest
strength meeting the 'selected_strength > requested_strength'
constraint. Fix the fact that, in this particular case, ecc->strength
value was not updated to match the 'selected_strength'.

For instance, one can encounter this issue when no ECC requirement is
filled in the device tree while the NAND chip minimum requirement is not
a strength/step_size combo natively supported by the ECC engine.

Suggested-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/nand/sunxi_nand.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 82244be3e766..958974821582 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1853,8 +1853,14 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
 
 	/* Add ECC info retrieval from DT */
 	for (i = 0; i < ARRAY_SIZE(strengths); i++) {
-		if (ecc->strength <= strengths[i])
+		if (ecc->strength <= strengths[i]) {
+			/*
+			 * Update ecc->strength value with the actual strength
+			 * that will be used by the ECC engine.
+			 */
+			ecc->strength = strengths[i];
 			break;
+		}
 	}
 
 	if (i >= ARRAY_SIZE(strengths)) {
-- 
2.11.0



From miquel.raynal at free-electrons.com  Wed Jan 24 14:59:36 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Wed, 24 Jan 2018 23:59:36 +0100
Subject: [PATCH] mtd: nand: sunxi: Fix ECC strength choice
In-Reply-To: <20180124224931.14392-1-miquel.raynal@free-electrons.com>
References: <20180124224931.14392-1-miquel.raynal@free-electrons.com>
Message-ID: <20180124235936.4b49b094@xps13>

Hello,

On Wed, 24 Jan 2018 23:49:31 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> When the requested ECC strength does not exactly match the strengths
> supported by the ECC engine, the driver is selecting the closest
> strength meeting the 'selected_strength > requested_strength'
> constraint. Fix the fact that, in this particular case, ecc->strength
> value was not updated to match the 'selected_strength'.
> 
> For instance, one can encounter this issue when no ECC requirement is
> filled in the device tree while the NAND chip minimum requirement is not
> a strength/step_size combo natively supported by the ECC engine.
> 

I forgot to add the Fixes/CC tags, but it seems that this problem
has always been out there...

Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller
support")
CC: stable at vger.kernel.org

> Suggested-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>

I will wait a review before sending a v2.

Thanks,
Miqu?l


From miquel.raynal at free-electrons.com  Wed Jan 24 15:24:34 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Thu, 25 Jan 2018 00:24:34 +0100
Subject: [PATCH] mtd: nftl/inftl: check mtd_erase() return value
Message-ID: <20180124232434.32023-1-miquel.raynal@free-electrons.com>

Since the creation of mtd_erase(), the function can return a negative
error code without updating the instr->state flag. This happens for
instance when ->_erase() is not implemented or ->erasesize has an invalid
value. The calling function should error out in this case.

Functions in nftlmount/inftlmount call mtd_erase() without checking the
return code. The instr->state flag is checked but might not have been
updated depending on the error path.

Add checks on the returned value of mtd_erase().

Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>
---
 drivers/mtd/inftlmount.c | 7 +++++--
 drivers/mtd/nftlmount.c  | 3 ++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 8d6bb189ea8e..cab4a0b9f881 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -219,7 +219,9 @@ static int find_boot_record(struct INFTLrecord *inftl)
 				 */
 				instr->addr = ip->Reserved0 * inftl->EraseSize;
 				instr->len = inftl->EraseSize;
-				mtd_erase(mtd, instr);
+				ret = mtd_erase(mtd, instr);
+				if (ret < 0)
+					return ret;
 			}
 			if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
 				printk(KERN_WARNING "INFTL: Media Header "
@@ -393,7 +395,8 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
 	   mark only the failed block in the bbt. */
 	for (physblock = 0; physblock < inftl->EraseSize;
 	     physblock += instr->len, instr->addr += instr->len) {
-		mtd_erase(inftl->mbd.mtd, instr);
+		if (mtd_erase(inftl->mbd.mtd, instr < 0))
+			goto fail;
 
 		if (instr->state == MTD_ERASE_FAILED) {
 			printk(KERN_WARNING "INFTL: error while formatting block %d\n",
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 184c8fbfe465..8dbc40ab7d73 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -331,7 +331,8 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
 	instr->mtd = nftl->mbd.mtd;
 	instr->addr = block * nftl->EraseSize;
 	instr->len = nftl->EraseSize;
-	mtd_erase(mtd, instr);
+	if (mtd_erase(mtd, instr) < 0)
+		goto fail;
 
 	if (instr->state == MTD_ERASE_FAILED) {
 		printk("Error while formatting block %d\n", block);
-- 
2.11.0



From han.xu at nxp.com  Wed Jan 24 19:07:26 2018
From: han.xu at nxp.com (Han Xu)
Date: Thu, 25 Jan 2018 03:07:26 +0000
Subject: [PATCH] mtd: nand: gpmi: Fix subpage reads
In-Reply-To: <20180124135106.2a145a11@xps13>
References: <20180123101317.15925-1-boris.brezillon@free-electrons.com>,
 <20180124135106.2a145a11@xps13>
Message-ID: <VI1PR0401MB2221C5231ACDAB30A15E680497E10@VI1PR0401MB2221.eurprd04.prod.outlook.com>


________________________________________
From: Miquel Raynal <miquel.raynal at free-electrons.com>
Sent: Wednesday, January 24, 2018 6:51 AM
To: Boris Brezillon
Cc: Richard Weinberger; linux-mtd at lists.infradead.org; David Woodhouse; Brian Norris; Marek Vasut; Cyrille Pitchen; Han Xu
Subject: Re: [PATCH] mtd: nand: gpmi: Fix subpage reads

Hello Boris,

On Tue, 23 Jan 2018 11:13:17 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Commit 25f815f66a14 ("mtd: nand: force drivers to explicitly send
> READ/PROG commands") added a call to nand_read_page_op() in
> gpmi_ecc_read_page(), which means this function now sends a READ0
> command and place the data pointer at the beginning of the page. This
> logic is breaking gpmi_ecc_read_subpage() which was calling
> gpmi_ecc_read_page() and expected it to only retrieve the data without
> sending the READ0 command.
>
> Create a gpmi_ecc_read_page_data() helper which only does the data
> retrieval and ECC correction steps and implement gpmi_ecc_read_page()
> as a wrapper that calls nand_read_page_op()+gpmi_ecc_read_page_data().
>
> This way, gpmi_ecc_read_subpage() can call gpmi_ecc_read_page_data()
> which restores the logic we had before commit 25f815f66a14 ("mtd: nand:
> force drivers to explicitly send READ/PROG commands").
>
> Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---

Reviewed-by: Miquel Raynal <miquel.raynal at free-electrons.com>
Acked-by: Han Xu <han.xu at nxp.com>

Thanks for fixing it,
Miqu?l


From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:02:49 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:32:49 +0530
Subject: [PATCH v4 0/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
Message-ID: <1516863771-30974-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has 4 chip select and one can use different flashes
on all different chip select.
We analyzed that the flashes have different parameters for the same command
and this is true for NAND devices.
Also reg_protocol information, needed for read register, read any register
commands, read SFDP register, not available at time of spi_nor_scan.
As FSL QUADSPI controller has limitation in number of LUT entries, max 16,
thus require to have dynamic LUT creation support.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also fix initialize sequence of AHB read, move
fsl_qspi_init_ahb_read() in  fsl_qspi_nor_setup() function.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: add support to create dynamic LUT entry
  mtd: fsl-quadspi: fix init AHB read in  fsl_qspi_nor_setup()

Changes for v4:
- Drop patch
'mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4', it
would be taken care in next-series.
- Added patch for 'fix initialize sequence of AHB read'.

Changes for v3:
- Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
- Update information in cover letter.

Changes for v2:
- Swap patch sequences in the series to solve git bissect issue.

 drivers/mtd/spi-nor/fsl-quadspi.c | 299 ++++++++++++++++++++------------------
 1 file changed, 155 insertions(+), 144 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:02:50 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:32:50 +0530
Subject: [PATCH v4 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
In-Reply-To: <1516863771-30974-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516863771-30974-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516863771-30974-2-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>

---
Changes for v4:
- Correct version numbering.
Changes for v3:
- Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
Changes for v2:
- Swap patch sequences in the series to solve git bissect issue.

 drivers/mtd/spi-nor/fsl-quadspi.c | 293 ++++++++++++++++++++------------------
 1 file changed, 152 insertions(+), 141 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 943e9c4..94f9651 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -193,21 +193,21 @@
 #define QUADSPI_LUT_NUM		64
 
 /* SEQID -- we can have 16 seqids at most. */
+/* LUT0 programmed by bootloader, for run-time create entry for LUT seqid 1 */
 #define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+#define SEQID_RUN_CMD		1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +368,143 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
+{
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
 {
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
-	int i;
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
+	u8 addrlen = 0;
+	u8 read_dm, opcode;
+	int stop_lut;
+
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
 
-	struct spi_nor *nor = &q->nor[0];
-	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
+
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
-		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
-
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
+	/* Dynamic LUT */
+	lut_base = SEQID_RUN_CMD * 4;
 
-	fsl_qspi_lock_lut(q);
-}
+	/* default, STOP instruction to be programmed in (lut_base + 1) reg */
+	stop_lut = 1;
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
+
+		if (ops == FSL_QSPI_OPS_READ) {
+			qspi_writel(q,
+				    LUT0(DUMMY, pad_count(dummy_pad), read_dm) |
+				    LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+				    base + QUADSPI_LUT(lut_base + 1));
+			stop_lut = 2;
+
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				SEQID_RUN_CMD << QUADSPI_BFGENCR_SEQID_SHIFT,
+				q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+			stop_lut = 2;
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	/* prepare LUT for STOP instruction. */
+	qspi_writel(q, 0, base +  QUADSPI_LUT(lut_base + stop_lut));
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +539,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +691,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_RUN_CMD;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +735,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -746,9 +752,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 		base + QUADSPI_MCR);
 	udelay(1);
 
-	/* Init the LUT table. */
-	fsl_qspi_init_lut(q);
-
 	/* Disable the module */
 	qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
 			base + QUADSPI_MCR);
@@ -791,9 +794,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	/* Init for AHB read */
 	fsl_qspi_init_ahb_read(q);
 
@@ -820,6 +820,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +835,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +845,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +863,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +880,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +930,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:02:51 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:32:51 +0530
Subject: [PATCH v4 2/2] mtd: fsl-quadspi: fix init AHB read in
 fsl_qspi_nor_setup()
In-Reply-To: <1516863771-30974-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516863771-30974-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516863771-30974-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Move AHB read initialize in fsl_qspi_nor_setup().

In file spi-nor.c, func spi_nor_scan() calls nor->read() thru
spi_nor_read_sfdp() API.

Presently, fsl_qspi_init_ahb_read() called from fsl_qspi_nor_setup_last().
Func fsl_qspi_probe() calls spi_nor_scan() first and then calls
fsl_qspi_nor_setup_last().

When nor->read() being called from inside spi_nor_read_sfdp(), QSPI cntlr
AHB mode initialization is not yet done results in data read error.

Initialize AHB read inside fsl_qspi_nor_setup().

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Changes for v4:
- None
Changes for v3:
- None
Changes for v2:
- None

 drivers/mtd/spi-nor/fsl-quadspi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 94f9651..c5863cf 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -772,6 +772,9 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	/* enable the interrupt */
 	qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
 
+	/* Init for AHB read */
+	fsl_qspi_init_ahb_read(q);
+
 	return 0;
 }
 
@@ -794,9 +797,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init for AHB read */
-	fsl_qspi_init_ahb_read(q);
-
 	return 0;
 }
 
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:09:57 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:39:57 +0530
Subject: [PATCH] mtd: fsl-quadspi: add support for ls2080a/ls1080a
Message-ID: <1516864197-31484-1-git-send-email-yogeshnarayan.gaur@nxp.com>

LS2080a/LS1088a supports Freescale Quad SPI controller.
Add fsl-quadspi driver support for ls2080a and ls1088a chip.

Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=25286
 

 drivers/mtd/spi-nor/fsl-quadspi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index c5863cf..11389d8 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -214,6 +214,7 @@ enum fsl_qspi_devtype {
 	FSL_QUADSPI_IMX7D,
 	FSL_QUADSPI_IMX6UL,
 	FSL_QUADSPI_LS1021A,
+	FSL_QUADSPI_LS2080A,
 };
 
 struct fsl_qspi_devtype_data {
@@ -267,6 +268,15 @@ struct fsl_qspi_devtype_data {
 	.driver_data = 0,
 };
 
+static struct fsl_qspi_devtype_data ls2080a_data = {
+	.devtype = FSL_QUADSPI_LS2080A,
+	.rxfifo = 128,
+	.txfifo = 64,
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_TKT253890,
+};
+
+
 #define FSL_QSPI_MAX_CHIP	4
 struct fsl_qspi {
 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
@@ -806,6 +816,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
 	{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
 	{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
+	{ .compatible = "fsl,ls2080a-qspi", .data = (void *)&ls2080a_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:21:55 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:51:55 +0530
Subject: [PATCH 0/2] mtd: fsl-quadspi: Update hwcap based on mode provided in
 dtsi file
Message-ID: <1516864917-31969-1-git-send-email-yogeshnarayan.gaur@nxp.com>

This patch-set added support to update hwcap of FSL QUADSPI controller
by reading values from the device tree files.

Updated the fsl-quadspi binding by adding spi-tx-bus-width,
spi-rx-bus-width binding needed to define mode of operation.

Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=25286

Yogesh Gaur (2):
  Documentation: binding: Update fsl-quadspi binding
  mtd: fsl-quadspi: Update hwcap based on mode provided in dtsi file

 .../devicetree/bindings/mtd/fsl-quadspi.txt        |  4 ++
 drivers/mtd/spi-nor/fsl-quadspi.c                  | 46 ++++++++++++++++++++--
 2 files changed, 47 insertions(+), 3 deletions(-)

-- 
1.9.1


From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:21:56 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:51:56 +0530
Subject: [PATCH 1/2] Documentation: binding: Update fsl-quadspi binding
In-Reply-To: <1516864917-31969-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516864917-31969-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516864917-31969-2-git-send-email-yogeshnarayan.gaur@nxp.com>

QuadSPI controller supports Single, dual, quad modes of operation.
Mode is controlled via either RCW or the on-board connection to flash.

spi-tx-bus-width, spi-rx-bus-width binding added to define mode
of operation. Definition of these binding are standard as defined
in Documentation/devicetree/bindings/spi/spi-bus.txt.

Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 Documentation/devicetree/bindings/mtd/fsl-quadspi.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index c34aa6f..13a903e 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -23,6 +23,10 @@ Optional properties:
 			      bus, you should enable this property.
 			      (Please check the board's schematic.)
   - big-endian : That means the IP register is big endian
+  - spi-tx-bus-width - Definition as per
+                     Documentation/devicetree/bindings/spi/spi-bus.txt
+  - spi-rx-bus-width - Definition as per
+                     Documentation/devicetree/bindings/spi/spi-bus.txt
 
 Example:
 
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Wed Jan 24 23:21:57 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 12:51:57 +0530
Subject: [PATCH 2/2] mtd: fsl-quadspi: Update hwcap based on mode provided in
 dtsi file
In-Reply-To: <1516864917-31969-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1516864917-31969-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1516864917-31969-3-git-send-email-yogeshnarayan.gaur@nxp.com>

FSL QuadSPI controller supports Single, dual, quad modes of operation.
Mode information is available via "spi-tx-bus-width" and
"spi-rx-bus-width" nodes of device tree.

Update read hwcap capability by reading "spi-rx-bus-width".
Update write hwcap capability by reading "spi-tx-bus-width".

If value not provided in device tree file, then fallback to default
mode i.e. SNOR_HWCAPS_READ_1_1_4 and SNOR_HWCAPS_PP.

Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 46 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 11389d8..ff98e5a 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -979,8 +979,8 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
-	const struct spi_nor_hwcaps hwcaps = {
-		.mask = SNOR_HWCAPS_READ_1_1_4 |
+	struct spi_nor_hwcaps hwcaps = {
+		.mask = SNOR_HWCAPS_READ_FAST |
 			SNOR_HWCAPS_PP,
 	};
 	struct device_node *np = pdev->dev.of_node;
@@ -989,7 +989,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, value;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1037,6 +1037,46 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		goto clk_failed;
 	}
 
+	if (!of_property_read_u32(np, "spi-rx-bus-width", &value)) {
+		switch (value) {
+		case 1:
+			hwcaps.mask |= SNOR_HWCAPS_READ |
+				       SNOR_HWCAPS_READ_FAST;
+			break;
+		case 2:
+			hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2 |
+				       SNOR_HWCAPS_READ_1_2_2;
+			break;
+		case 4:
+			hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4 |
+				       SNOR_HWCAPS_READ_1_4_4;
+			break;
+		default:
+			dev_err(dev,
+				"spi-rx-bus-width %d not supported\n",
+				value);
+			break;
+		}
+	} else
+		hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
+
+	if (!of_property_read_u32(np, "spi-tx-bus-width", &value)) {
+		switch (value) {
+		case 1:
+			hwcaps.mask |= SNOR_HWCAPS_PP;
+			break;
+		case 4:
+			hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4 |
+				       SNOR_HWCAPS_PP_1_4_4;
+			break;
+		default:
+			dev_err(dev,
+				"spi-tx-bus-width %d not supported\n",
+				value);
+			break;
+		}
+	}
+
 	/* find the irq */
 	ret = platform_get_irq(pdev, 0);
 	if (ret < 0) {
-- 
1.9.1



From boris.brezillon at free-electrons.com  Thu Jan 25 00:13:26 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 25 Jan 2018 09:13:26 +0100
Subject: [PATCH] mtd: nand: gpmi: Fix subpage reads
In-Reply-To: <VI1PR0401MB2221C5231ACDAB30A15E680497E10@VI1PR0401MB2221.eurprd04.prod.outlook.com>
References: <20180123101317.15925-1-boris.brezillon@free-electrons.com>
 <20180124135106.2a145a11@xps13>
 <VI1PR0401MB2221C5231ACDAB30A15E680497E10@VI1PR0401MB2221.eurprd04.prod.outlook.com>
Message-ID: <20180125091326.414185e1@bbrezillon>

Hi Han,

On Thu, 25 Jan 2018 03:07:26 +0000
Han Xu <han.xu at nxp.com> wrote:

> Acked-by: Han Xu <han.xu at nxp.com>

Could you please fix you mailer (or use another one). Your emails are
systematically rejected by the ML, which means I don't have your Acks
in patchwork and have to add them back manually.

Thanks,

Boris


From yogeshnarayan.gaur at nxp.com  Thu Jan 25 00:26:57 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Thu, 25 Jan 2018 13:56:57 +0530
Subject: [PATCH] arm64: dts: ls1088a: Add qspi device node for ls1088a-rdb
Message-ID: <1516868817-2327-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Add nodes and properties for QSPI controller.
Add support for spansion flash, s25fs512s, as slave device for
QSPI controller.

Added entry of "fsl,ls1088a-qspi" in fsl-quadspi.txt binding file.

Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=25292

 .../devicetree/bindings/mtd/fsl-quadspi.txt         |  1 +
 arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts   | 21 +++++++++++++++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi      | 12 ++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 13a903e..927d65c 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -7,6 +7,7 @@ Required properties:
 		 or
 		 "fsl,ls2080a-qspi" followed by "fsl,ls1021a-qspi",
 		 "fsl,ls1043a-qspi" followed by "fsl,ls1021a-qspi"
+		 "fsl,ls2080a-qspi" followed by "fsl,ls1088a-qspi",
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
   - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
index 0f6fcda..3febb59 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
@@ -94,6 +94,27 @@
 	};
 };
 
+&qspi {
+	status = "okay";
+	fsl,qspi-has-second-chip;
+	spi-rx-bus-width = <4>;
+	spi-tx-bus-width = <4>;
+	qflash0: s25fs512s at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+	};
+
+	qflash1: s25fs512s at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <1>;
+	};
+
+};
+
 &ifc {
 	ranges = <0 0 0x5 0x30000000 0x00010000
 		  2 0 0x5 0x20000000 0x00010000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index bd80e9a..b45a522 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -394,6 +394,18 @@
 			status = "disabled";
 		};
 
+		qspi: quadspi at 20c0000 {
+			compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0 0x20c0000 0x0 0x10000>,
+				<0x0 0x20000000 0x0 0x10000000>;
+			reg-names = "QuadSPI", "QuadSPI-memory";
+			interrupts = <0 25 0x4>; /* Level high type */
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "qspi_en", "qspi";
+		};
+
 		sata: sata at 3200000 {
 			compatible = "fsl,ls1088a-ahci";
 			reg = <0x0 0x3200000 0x0 0x10000>,
-- 
1.9.1



From david at sigma-star.at  Thu Jan 25 00:49:32 2018
From: david at sigma-star.at (David Gstir)
Date: Thu, 25 Jan 2018 09:49:32 +0100
Subject: [RFC] UBIFS authentication
In-Reply-To: <E6D3BD02-AF3A-4B75-92FD-A8A07B4C9C51@sigma-star.at>
References: <E6D3BD02-AF3A-4B75-92FD-A8A07B4C9C51@sigma-star.at>
Message-ID: <AF303146-8E37-48B2-B9DF-8C3193138EFA@sigma-star.at>

Hi!

> On 17.01.2018, at 16:19, David Gstir <david at sigma-star.at> wrote:
> 
> Hi everybody!
> 
> Richard and I have been working on extending UBIFS' security features and came
> up with the following concept to add full file contents and metadata authentication.
> 
> For block devices like eMMCs dm-crypt and dm-verity/dm-integrity can be used to
> get full data confidentiality and authenticity, but for raw flash or more
> specifically UBIFS, existing options are not ideal:
> 
> One option is to use eCryptfs with some out-of-tree patches that add AEAD cipher
> (AES-GCM) support, but does not look like there was much progress recently [1].
> 
> Another option is to use IMA/EVM as described by Marc Kleine-Budde in his
> ELCE 2016 talk [2], but this just protects the file payload and some attributes
> and not the full filesystem data structures.
> 
> A short overview of existing options is also given here [3].
> 
> Due to the design of UBIFS it is actually a bit easier than on other filesystems
> to authenticate its data structures and ensure consistency of on-flash data.
> 
> I've attached the whitepaper below and also published it here [4].
> 
> Comments are welcome. :)

*ping*

Did anybody get a chance to look at this yet, or is everybody still busy with Meltdown and Spectre? ;D

Thanks,
David

From andrea.adami at gmail.com  Thu Jan 25 00:52:36 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Thu, 25 Jan 2018 09:52:36 +0100
Subject: [PATCH 0/2] mtd-utils: improve compatibility with klibc
Message-ID: <cover.1516868053.git.andrea.adami@gmail.com>

Klibc does not support floating point calculations.
Here some fixes needed to build the ubi-utils against klibc for aarch64,
without FPU.

These lines end up compiled with soft float for other arm targets w/out
FPU thus this was discovered only cross-building for qemuarm64 using the flag
 '-mgeneral-regs-only'.

Changes tested on armv5, same output is printed.

Andrea Adami (2):
  mtd-utils: common.c: convert to integer arithmetic
  ubi-utils: ubiformat.c: convert to integer arithmetic.

 lib/common.c          | 15 +++++++++------
 ubi-utils/ubiformat.c |  2 +-
 2 files changed, 10 insertions(+), 7 deletions(-)

-- 
2.7.4



From andrea.adami at gmail.com  Thu Jan 25 00:52:37 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Thu, 25 Jan 2018 09:52:37 +0100
Subject: [PATCH 1/2] mtd-utils: common.c: convert to integer arithmetic
In-Reply-To: <cover.1516868053.git.andrea.adami@gmail.com>
References: <cover.1516868053.git.andrea.adami@gmail.com>
Message-ID: <58232c8a9192b7fc279389099d2cd1ff7b5abcd3.1516868053.git.andrea.adami@gmail.com>

We use floating point just to print out KiB, MiB, GiB.
Avoid that to be klibc friendly.

Fixes compilation for aarch64 against klibc:

error: '-mgeneral-regs-only' is incompatible with floating-point argument
|    printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
etc.

Note:
* In the KiB case, we could apparently multiply by 100 before dividing
  without risking overflow. This code simply avoids multiplications.

Signed-off-by: Andrea Adami <andrea.adami at gmail.com>
---
 lib/common.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/lib/common.c b/lib/common.c
index 69b03b3..5e28853 100644
--- a/lib/common.c
+++ b/lib/common.c
@@ -107,6 +107,9 @@ long long util_get_bytes(const char *str)
 void util_print_bytes(long long bytes, int bracket)
 {
 	const char *p;
+	int GiB = 1024 * 1024 * 1024;
+	int MiB = 1024 * 1024;
+	int KiB = 1024;
 
 	if (bracket)
 		p = " (";
@@ -115,12 +118,12 @@ void util_print_bytes(long long bytes, int bracket)
 
 	printf("%lld bytes", bytes);
 
-	if (bytes > 1024 * 1024 * 1024)
-		printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
-	else if (bytes > 1024 * 1024)
-		printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024));
-	else if (bytes > 1024 && bytes != 0)
-		printf("%s%.1f KiB", p, (double)bytes / 1024);
+	if (bytes > GiB)
+		printf("%s%d.%d GiB", p, bytes / GiB, bytes % GiB / (GiB / 10));
+	else if (bytes > MiB)
+		printf("%s%d.%d MiB", p, bytes / MiB, bytes % MiB / (MiB / 10));
+	else if (bytes > KiB && bytes != 0)
+		printf("%s%d.%d KiB", p, bytes / KiB, bytes % KiB / (KiB / 10));
 	else
 		return;
 
-- 
2.7.4



From andrea.adami at gmail.com  Thu Jan 25 00:52:38 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Thu, 25 Jan 2018 09:52:38 +0100
Subject: [PATCH 2/2] ubi-utils: ubiformat.c: convert to integer arithmetic
In-Reply-To: <cover.1516868053.git.andrea.adami@gmail.com>
References: <cover.1516868053.git.andrea.adami@gmail.com>
Message-ID: <86bc7e1111a80d6938d623d29b926876b3563923.1516868053.git.andrea.adami@gmail.com>

Do not cast percent to double, it is just used as upper limit.
Avoid floating point to fix compilation for aarch64 against klibc:

error: '-mgeneral-regs-only' is incompatible with floating-point code
|    int percent = ((double)si->ok_cnt)/si->good_cnt * 100;
|        ^~~~~~~

Notes:
* The checks in the code above this line ensure that si->good_cnt is not 0.

* The code assumes  si->good_cnt * 100  will not overflow, then we can use
  (si->ok_cnt * 100) safely because the former is bigger.

* The truncated result does not affect the logic:
  i.e. a value of 49.9 is truncated to 49 and is still <50.

Signed-off-by: Andrea Adami <andrea.adami at gmail.com>
---
 ubi-utils/ubiformat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ubi-utils/ubiformat.c b/ubi-utils/ubiformat.c
index ef0378a..c38b9b4 100644
--- a/ubi-utils/ubiformat.c
+++ b/ubi-utils/ubiformat.c
@@ -844,7 +844,7 @@ int main(int argc, char * const argv[])
 	}
 
 	if (!args.override_ec && si->empty_cnt < si->good_cnt) {
-		int percent = ((double)si->ok_cnt)/si->good_cnt * 100;
+		int percent = (si->ok_cnt * 100) / si->good_cnt;
 
 		/*
 		 * Make sure the majority of eraseblocks have valid
-- 
2.7.4



From boris.brezillon at free-electrons.com  Thu Jan 25 02:05:01 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 25 Jan 2018 11:05:01 +0100
Subject: [PATCH] mtd: nand: gpmi: Fix subpage reads
In-Reply-To: <20180123101317.15925-1-boris.brezillon@free-electrons.com>
References: <20180123101317.15925-1-boris.brezillon@free-electrons.com>
Message-ID: <20180125110501.084c81dd@bbrezillon>

On Tue, 23 Jan 2018 11:13:17 +0100
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Commit 25f815f66a14 ("mtd: nand: force drivers to explicitly send
> READ/PROG commands") added a call to nand_read_page_op() in
> gpmi_ecc_read_page(), which means this function now sends a READ0
> command and place the data pointer at the beginning of the page. This
> logic is breaking gpmi_ecc_read_subpage() which was calling
> gpmi_ecc_read_page() and expected it to only retrieve the data without
> sending the READ0 command.
> 
> Create a gpmi_ecc_read_page_data() helper which only does the data
> retrieval and ECC correction steps and implement gpmi_ecc_read_page()
> as a wrapper that calls nand_read_page_op()+gpmi_ecc_read_page_data().
> 
> This way, gpmi_ecc_read_subpage() can call gpmi_ecc_read_page_data()
> which restores the logic we had before commit 25f815f66a14 ("mtd: nand:
> force drivers to explicitly send READ/PROG commands").
> 

Applied.

> Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands")
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 3198f5f79a82..93f212457d4d 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -1029,11 +1029,13 @@ static void block_mark_swapping(struct gpmi_nand_data *this,
>  	p[1] = (p[1] & mask) | (from_oob >> (8 - bit));
>  }
>  
> -static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
> -				uint8_t *buf, int oob_required, int page)
> +static int gpmi_ecc_read_page_data(struct nand_chip *chip,
> +				   uint8_t *buf, int oob_required,
> +				   int page)
>  {
>  	struct gpmi_nand_data *this = nand_get_controller_data(chip);
>  	struct bch_geometry *nfc_geo = &this->bch_geometry;
> +	struct mtd_info *mtd = nand_to_mtd(chip);
>  	void          *payload_virt;
>  	dma_addr_t    payload_phys;
>  	void          *auxiliary_virt;
> @@ -1043,8 +1045,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  	unsigned int  max_bitflips = 0;
>  	int           ret;
>  
> -	nand_read_page_op(chip, page, 0, NULL, 0);
> -
>  	dev_dbg(this->dev, "page number is : %d\n", page);
>  	ret = read_page_prepare(this, buf, nfc_geo->payload_size,
>  					this->payload_virt, this->payload_phys,
> @@ -1178,6 +1178,14 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  	return max_bitflips;
>  }
>  
> +static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
> +			      uint8_t *buf, int oob_required, int page)
> +{
> +	nand_read_page_op(chip, page, 0, NULL, 0);
> +
> +	return gpmi_ecc_read_page_data(chip, buf, oob_required, page);
> +}
> +
>  /* Fake a virtual small page for the subpage read */
>  static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
>  			uint32_t offs, uint32_t len, uint8_t *buf, int page)
> @@ -1257,7 +1265,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
>  
>  	/* Read the subpage now */
>  	this->swap_block_mark = false;
> -	max_bitflips = gpmi_ecc_read_page(mtd, chip, buf, 0, page);
> +	max_bitflips = gpmi_ecc_read_page_data(chip, buf, 0, page);
>  
>  	/* Restore */
>  	writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0);



From boris.brezillon at free-electrons.com  Thu Jan 25 02:05:54 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 25 Jan 2018 11:05:54 +0100
Subject: [PATCH] mtd: nand: sunxi: Fix ECC strength choice
In-Reply-To: <20180124235936.4b49b094@xps13>
References: <20180124224931.14392-1-miquel.raynal@free-electrons.com>
 <20180124235936.4b49b094@xps13>
Message-ID: <20180125110554.699b56e3@bbrezillon>

On Wed, 24 Jan 2018 23:59:36 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Hello,
> 
> On Wed, 24 Jan 2018 23:49:31 +0100
> Miquel Raynal <miquel.raynal at free-electrons.com> wrote:
> 
> > When the requested ECC strength does not exactly match the strengths
> > supported by the ECC engine, the driver is selecting the closest
> > strength meeting the 'selected_strength > requested_strength'
> > constraint. Fix the fact that, in this particular case, ecc->strength
> > value was not updated to match the 'selected_strength'.
> > 
> > For instance, one can encounter this issue when no ECC requirement is
> > filled in the device tree while the NAND chip minimum requirement is not
> > a strength/step_size combo natively supported by the ECC engine.
> >   
> 
> I forgot to add the Fixes/CC tags, but it seems that this problem
> has always been out there...
> 
> Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller
> support")
> CC: stable at vger.kernel.org

No need to send a new version. I added the Fixes+stable tags when
applying.

Thanks,

Boris

> 
> > Suggested-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> > Signed-off-by: Miquel Raynal <miquel.raynal at free-electrons.com>  
> 
> I will wait a review before sending a v2.
> 
> Thanks,
> Miqu?l



From boris.brezillon at free-electrons.com  Thu Jan 25 02:12:27 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 25 Jan 2018 11:12:27 +0100
Subject: [GIT PULL v3] mtd: nand: Changes for 4.16
Message-ID: <20180125111227.5d8c7084@bbrezillon>

Hello,

Here is the NAND PR for 4.16. As can be seen in the diffstat, the NAND
subsystem has been quite active. That's mainly caused by the
introduction of the ->exec_op() hook and the rework of the Marvell
driver.

v3 contains 2 late fixes, and one of them is fixing a bug introduced by
the exec_op() rework, hence the need for a v3. Hopefully, this will be
the last version.

Regards,

Boris

Changes in v3:
- Fix a bug introduced by the exec_op() rework in the GPMI driver
- Fix a long standing bug in the sunxi driver

Changes in v2:
- Add a few fixes for the omap OneNAND and marvell NAND drivers

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/nand/for-4.16

for you to fetch changes up to f4c6cd1a7f2275d5bc0e494b21fff26f8dde80f0:

  mtd: nand: sunxi: Fix ECC strength choice (2018-01-25 09:14:32 +0100)

----------------------------------------------------------------
Core changes:
* Fix NAND_CMD_NONE handling in nand_command[_lp]() hooks
* Introduce the ->exec_op() infrastructure
* Rework NAND buffers handling
* Fix ECC requirements for K9F4G08U0D
* Fix nand_do_read_oob() to return the number of bitflips
* Mark K9F1G08U0E as not supporting subpage writes

Driver changes:
* MTK: Rework the driver to support new IP versions
* OMAP OneNAND: Full rework to use new APIs (libgpio, dmaengine) and fix
  DT support
* Marvell: Add a new driver to replace the pxa3xx one

----------------------------------------------------------------
Arnd Bergmann (1):
      mtd: onenand: omap2: print resource using %pR format string

Boris Brezillon (7):
      mtd: nand: hynix: Don't wait after applying new read-retry params
      mtd: nand: provide several helpers to do common NAND operations
      mtd: nand: force drivers to explicitly send READ/PROG commands
      mtd: nand: denali: Avoid using ecc->code_buf as a temporary buffer
      mtd: nand: Only allocate ecc->{calc, code}_buf when actually needed
      Merge tag 'gpmc-omap-for-v4.16-immutable' of https://github.com/rogerq/linux into nand/next
      mtd: nand: gpmi: Fix subpage reads

Christophe JAILLET (5):
      mtd: onenand: samsung: use devm_ function to simplify code and fix some leaks
      mtd: onenand: samsung: return an error if 'mtd_device_parse_register()' fails
      mtd: onenand: samsung: Propagate the error returned by 'onenand_scan()'
      mtd: onenand: samsung: Remove a useless include
      mtd: onenand: samsung: remove incorrect __iomem annotation

Colin Ian King (2):
      mtd: nand: marvell: fix spelling mistake: "suceed"-> "succeed"
      mtd: nand: marvell: remove redundant variable 'oob_len'

Fabio Estevam (2):
      mtd: nand: brcmnand: Add a NULL check for devm_kasprintf()
      mtd: nand: qcom: Add a NULL check for devm_kasprintf()

Gustavo A. R. Silva (1):
      mtd: nand: gpmi: replace _manual_ swap with swap macro

Jagdish Gediya (1):
      mtd: nand: ifc: update bufnum mask for ver >= 2.0.0

Jesse Chan (1):
      mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE

Kamal Dasu (1):
      mtd: nand: brcmnand: Disable prefetch by default

Ladislav Michl (15):
      memory: omap-gpmc: Make 'bank-width' property optional
      mtd: onenand: Remove obsolete url from Kconfig help
      mtd: nand: samsung: Disable subpage writes on E-die NAND
      dt-bindings: mtd: gpmc-onenand: Update properties description
      ARM: dts: OMAP2+: Add compatible property to onenand node
      ARM: dts: omap3-igep: Update onenand node timings
      mtd: onenand: omap2: Remove regulator support
      mtd: onenand: omap2: Remove skip initial unlocking support
      mtd: onenand: omap2: Remove partitioning support from platform data
      mtd: onenand: omap2: Account waiting time as waiting on IO
      mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
      mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
      mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
      mtd: onenand: omap2: Configure driver from DT
      ARM: OMAP2+: Remove gpmc-onenand

Masahiro Yamada (6):
      mtd: nand: remove unnecessary extern from driver headers
      mtd: nand: denali: rename misleading dma_buf to tmp_buf
      mtd: nand: cafe: remove use of NAND_OWN_BUFFERS
      mtd: nand: remove unused NAND_OWN_BUFFERS flag
      mtd: nand: squash struct nand_buffers into struct nand_chip
      mtd: nand: cafe: clean up DMA address setup

Miquel Raynal (16):
      mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]()
      mtd: nand: use usual return values for the ->erase() hook
      mtd: nand: provide valid ->data_interface during NAND detection
      mtd: nand: samsung: add ECC requirements for K9F4G08U0D
      mtd: nand: add ->exec_op() implementation
      mtd: nand: Fix unfinished comment in nand_init_data_interface()
      mtd: mtd_oobtest: Handle bitflips during reads
      mtd: nand: Fix nand_do_read_oob() return value
      dt-bindings: mtd: document new nand-rb property
      dt-bindings: mtd: add Marvell NAND controller documentation
      mtd: nand: add reworked Marvell NAND controller driver
      mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
      MAINTAINERS: Add entry for Marvell NAND controller driver
      mtd: nand: marvell: Fix missing memory allocation modifier
      mtd: nand: Fix build issues due to an anonymous union
      mtd: nand: sunxi: Fix ECC strength choice

Nicolas Ferre (1):
      MAINTAINERS: mtd/nand: update Microchip nand entry

Peter Ujfalusi (2):
      mtd: onenand: omap2: Simplify the DMA setup for various paths
      mtd: onenand: omap2: Convert to use dmaengine for memcpy

RogerCC Lin (3):
      mtd: nand: mtk: update DT bindings
      mtd: nand: mtk: Support different MTK NAND flash controller IP
      mtd: nand: mtk: Support MT7622 NAND flash controller.

Sascha Hauer (2):
      mtd: nand: gpmi-nand: Remove wrong Kconfig help text
      mtd: tests: nandbiterrs: Fix read_page return value

Wei Yongjun (1):
      mtd: onenand: omap2: Remove redundant dev_err call in omap2_onenand_probe()

Xiaolei Li (1):
      mtd: nand: mtk: use nand_reset() to reset NAND devices in resume function

 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt |    6 +-
 Documentation/devicetree/bindings/mtd/marvell-nand.txt |  123 +++++++
 Documentation/devicetree/bindings/mtd/mtk-nand.txt     |   11 +-
 Documentation/devicetree/bindings/mtd/nand.txt         |    1 +
 MAINTAINERS                                            |   22 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi            |    1 +
 arch/arm/boot/dts/omap3-igep.dtsi                      |   30 +-
 arch/arm/boot/dts/omap3-n900.dts                       |    1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi                   |    1 +
 arch/arm/boot/dts/omap3430-sdp.dts                     |    1 +
 arch/arm/configs/mvebu_v7_defconfig                    |    2 +-
 arch/arm/mach-omap2/Makefile                           |    3 -
 arch/arm/mach-omap2/gpmc-onenand.c                     |  409 ---------------------
 arch/arm64/configs/defconfig                           |    2 +-
 drivers/memory/omap-gpmc.c                             |  163 ++++++---
 drivers/mtd/nand/Kconfig                               |   17 +-
 drivers/mtd/nand/Makefile                              |    1 +
 drivers/mtd/nand/atmel/nand-controller.c               |    9 +-
 drivers/mtd/nand/bf5xx_nand.c                          |    6 +-
 drivers/mtd/nand/brcmnand/brcmnand.c                   |   38 +-
 drivers/mtd/nand/cafe_nand.c                           |   52 +--
 drivers/mtd/nand/denali.c                              |   84 ++---
 drivers/mtd/nand/denali.h                              |    4 +-
 drivers/mtd/nand/denali_pci.c                          |    4 +
 drivers/mtd/nand/diskonchip.c                          |    4 +-
 drivers/mtd/nand/docg4.c                               |   21 +-
 drivers/mtd/nand/fsl_elbc_nand.c                       |   10 +-
 drivers/mtd/nand/fsl_ifc_nand.c                        |   13 +-
 drivers/mtd/nand/fsmc_nand.c                           |    9 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c                 |  111 +++---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h                 |   46 +--
 drivers/mtd/nand/hisi504_nand.c                        |    9 +-
 drivers/mtd/nand/jz4740_nand.c                         |   16 +-
 drivers/mtd/nand/lpc32xx_mlc.c                         |    7 +-
 drivers/mtd/nand/lpc32xx_slc.c                         |   33 +-
 drivers/mtd/nand/marvell_nand.c                        | 2896 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/mtk_ecc.c                             |  126 +++++--
 drivers/mtd/nand/mtk_ecc.h                             |    3 +-
 drivers/mtd/nand/mtk_nand.c                            |   76 ++--
 drivers/mtd/nand/nand_base.c                           | 2230 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 drivers/mtd/nand/nand_bbt.c                            |    2 +-
 drivers/mtd/nand/nand_hynix.c                          |  129 ++++---
 drivers/mtd/nand/nand_micron.c                         |   83 ++---
 drivers/mtd/nand/nand_samsung.c                        |   19 +
 drivers/mtd/nand/nand_timings.c                        |   21 +-
 drivers/mtd/nand/omap2.c                               |   28 +-
 drivers/mtd/nand/pxa3xx_nand.c                         |   14 +-
 drivers/mtd/nand/qcom_nandc.c                          |   30 +-
 drivers/mtd/nand/r852.c                                |   11 +-
 drivers/mtd/nand/sh_flctl.c                            |    6 +-
 drivers/mtd/nand/sm_common.h                           |    2 +-
 drivers/mtd/nand/sunxi_nand.c                          |  111 +++---
 drivers/mtd/nand/tango_nand.c                          |   27 +-
 drivers/mtd/nand/tmio_nand.c                           |    5 +-
 drivers/mtd/nand/vf610_nfc.c                           |    6 +-
 drivers/mtd/onenand/Kconfig                            |    7 +-
 drivers/mtd/onenand/omap2.c                            |  577 +++++++++++-------------------
 drivers/mtd/onenand/samsung.c                          |  185 +++-------
 drivers/mtd/tests/nandbiterrs.c                        |    2 +-
 drivers/mtd/tests/oobtest.c                            |   21 ++
 drivers/staging/mt29f_spinand/mt29f_spinand.c          |    5 +-
 include/linux/mtd/rawnand.h                            |  443 +++++++++++++++++++++--
 include/linux/omap-gpmc.h                              |   28 ++
 include/linux/platform_data/mtd-onenand-omap2.h        |   34 --
 64 files changed, 6473 insertions(+), 1924 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 create mode 100644 drivers/mtd/nand/marvell_nand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h


From festevam at gmail.com  Thu Jan 25 02:20:59 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 25 Jan 2018 08:20:59 -0200
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
Message-ID: <CAOMZO5Bo4Tbo+uQADrfo2O=LmHn4oFTqN7pWwqMrrtrhkemmEg@mail.gmail.com>

Hi Boris,

On Thu, Jan 18, 2018 at 12:28 PM, Fabio Estevam <fabio.estevam at nxp.com> wrote:
> Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> to QSPI2 the following output from /proc/mtd is seen:
>
> # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi"
> mtd1: 01000000 00010000 "21e4000.qspi"
>
> Attempts to partition them on the kernel command line result in both
> chips with identical (and identically named) partitions, which is
> an inconvenient behavior.
>
> Assign a different mtd->name for each mtd device to avoid this problem.
>
> After this change the output from /proc/mtd becomes:
>
> # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 01000000 00010000 "21e4000.qspi-0"
> mtd1: 01000000 00010000 "21e4000.qspi-1"
>
> In order to keep mtdparts compatibility keep the mtd->name
> unchanged when a single SPI NOR is present.
>
> Reported-by: David Wolfe <david.wolfe at nxp.com>
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> ---
> Changes since v5:
> - Preserve the label value, if any. (Boris)

Do you plan to apply this one for 4.17?

Thanks


From festevam at gmail.com  Thu Jan 25 02:40:37 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 25 Jan 2018 08:40:37 -0200
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <20180125113317.5e74d178@bbrezillon>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
 <CAOMZO5Bo4Tbo+uQADrfo2O=LmHn4oFTqN7pWwqMrrtrhkemmEg@mail.gmail.com>
 <20180125113317.5e74d178@bbrezillon>
Message-ID: <CAOMZO5D=5ostRrhunxvCxYENjJ=1ADAJ2puGDf0JgT2mWJFc5Q@mail.gmail.com>

Hi Boris,

On Thu, Jan 25, 2018 at 8:33 AM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:

> I'm not applying spi-nor patches, and Cyrille already sent me his PR
> for 4.16. So yes, I'd say it will be queued for 4.17. Is this a problem?

No problem. Thanks for the clarification.

Cyrille, I missed to add you on Cc on v6. Should I resend it with you on Cc?

Thanks


From boris.brezillon at free-electrons.com  Thu Jan 25 02:33:17 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 25 Jan 2018 11:33:17 +0100
Subject: [PATCH v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device names
In-Reply-To: <CAOMZO5Bo4Tbo+uQADrfo2O=LmHn4oFTqN7pWwqMrrtrhkemmEg@mail.gmail.com>
References: <1516285721-32294-1-git-send-email-fabio.estevam@nxp.com>
 <CAOMZO5Bo4Tbo+uQADrfo2O=LmHn4oFTqN7pWwqMrrtrhkemmEg@mail.gmail.com>
Message-ID: <20180125113317.5e74d178@bbrezillon>

On Thu, 25 Jan 2018 08:20:59 -0200
Fabio Estevam <festevam at gmail.com> wrote:

> Hi Boris,
> 
> On Thu, Jan 18, 2018 at 12:28 PM, Fabio Estevam <fabio.estevam at nxp.com> wrote:
> > Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
> > to QSPI2 the following output from /proc/mtd is seen:
> >
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi"
> > mtd1: 01000000 00010000 "21e4000.qspi"
> >
> > Attempts to partition them on the kernel command line result in both
> > chips with identical (and identically named) partitions, which is
> > an inconvenient behavior.
> >
> > Assign a different mtd->name for each mtd device to avoid this problem.
> >
> > After this change the output from /proc/mtd becomes:
> >
> > # cat /proc/mtd
> > dev:    size   erasesize  name
> > mtd0: 01000000 00010000 "21e4000.qspi-0"
> > mtd1: 01000000 00010000 "21e4000.qspi-1"
> >
> > In order to keep mtdparts compatibility keep the mtd->name
> > unchanged when a single SPI NOR is present.
> >
> > Reported-by: David Wolfe <david.wolfe at nxp.com>
> > Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> > Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> > ---
> > Changes since v5:
> > - Preserve the label value, if any. (Boris)  
> 
> Do you plan to apply this one for 4.17?

I'm not applying spi-nor patches, and Cyrille already sent me his PR
for 4.16. So yes, I'd say it will be queued for 4.17. Is this a problem?


From femi.ageuh at gmail.com  Thu Jan 25 23:22:47 2018
From: femi.ageuh at gmail.com (Peter Schuster)
Date: Fri, 26 Jan 2018 08:22:47 +0100
Subject: =?UTF-8?Q?Darlehen_Geld_f=C3=BCr_Einzelpersonen_und_Fachleute_in_w?=
 =?UTF-8?Q?eniger_als_72_Stunden?=
Message-ID: <CACKcKZ-YTVoO8xO=VcRR-F_91T=fQ=MZa2wBTk_EaRT7GRz52Q@mail.gmail.com>

Hallo,

Sind Sie in einer schwierigen Situation, f?r die Sie sich f?r ein
Darlehen suchen? Ben?tigen Sie eine Finanzierung, um eine Schuld zu
begleichen oder eine Aktivit?t zu finanzieren? Haben Sie einen
Verbraucherkredit, eine Hypothek, einen pers?nlichen Kredit, eine
Hypothek, Investition Darlehen, Schuldenkonsolidierung Darlehen oder
andere braucht?

Ich bin ein einzelner Investor. I zur Verf?gung stellen die Kredit
kurz-, mittel- und langfristige. Ihr Finanzierungsbedingungen sind
sehr einfach und meine Zinssatz betr?gt 3% pro Jahr.

F?r alle Anfragen, bleibe ich zur Verf?gung, um Ihre Fragen zu beantworten.

Danke, dass Sie mir per E-Mail an Sie von  :   klaus.peterschuster at outlook.de

Mit freundlichen Gr??en.

Peter Schuster

Financial Bank
https://firstfinancialsa.com/de


From lukma at denx.de  Fri Jan 26 01:24:13 2018
From: lukma at denx.de (Lukasz Majewski)
Date: Fri, 26 Jan 2018 10:24:13 +0100
Subject: reading ubi from a NAND for programming to other devices
In-Reply-To: <CAJ+vNU2YFMR5WkekSgHfRHo10PgqKBski0a47qEn2XKZ-zjE9Q@mail.gmail.com>
References: <CAJ+vNU2YFMR5WkekSgHfRHo10PgqKBski0a47qEn2XKZ-zjE9Q@mail.gmail.com>
Message-ID: <20180126102413.5faa4534@jawa>

Hi Tim,

> Greetings,
> 
> I'm looking to understand what methods are available for
> reading/writing ubi/ubifs from an existing NAND flash in order to
> duplicate the contents onto another device in U-Boot, Linux, and with
> JTAG flashing for production.

You may want to check if nanddump / nandwrite will work for you (but
those are Linux utils, not available in u-boot).

http://git.infradead.org/mtd-utils.git/tree/HEAD:/nand-utils

> 
> Typically I create ubi's using ubinize then I can use U-Boot 'nand
> erase' and 'nand write' or JTAG to write the ubi without issues.
> However if I use U-Boot 'nand read' to read a ubi then write it back
> using the same method I get 'ubi0 warning: ubi_io_read: error -74 (ECC
> error)' and 'ubi0 error: ubi_io_read: error -74 (ECC error)' messages
> from Linux when its mounted. I find I run into the same problem when
> JTAG programming ubi's: no issues when using a ubi created via ubinize
> but when flashing one that came from a U-Boot 'nand read' I see ubi
> errors when mounting it.
> 
> Some testing shows me that I can't use U-Boot nand read/erase/write
> once U-Boot has 'attached' the UBI (via the U-Boot 'ubi part' command)
> which scans and re-sizes the volume.
> 
> If I on the other hand take a ubi from U-Boot 'nand read' and use
> Linux ubiformat to flash that onto a new device I get no ubi
> warnings/errors when its mounted. My understanding is that ubiformat
> is simply preserving erase counters but there must be something else
> its doing.
> 
> What's going on here and what can I do in U-Boot/JTAG to properly
> write ubi that's been read from an existing system? I'm hoping there
> is a method that doesn't require iterating over the individual volumes
> within the ubi.
> 
> Best Regards,
> 
> Tim
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20180126/69c4d726/attachment.sig>

From andy.shevchenko at gmail.com  Fri Jan 26 10:52:18 2018
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 26 Jan 2018 20:52:18 +0200
Subject: [PATCH v2 2/3] devres: Add devm_ioremap_shared_resource()
In-Reply-To: <20180124171501.GA1043@lenoch>
References: <20180124100604.GA19593@lenoch> <20180124100754.GC19593@lenoch>
 <CAHp75VeGpj28G60L86d4FDOL1YMAoM5kcdvSC5O6iH4Xi8zfHg@mail.gmail.com>
 <20180124171501.GA1043@lenoch>
Message-ID: <CAHp75Vdi=EJoBPe8sS8U3h+QaKR2tqyv2KaF=ixsPoE1qpXOHQ@mail.gmail.com>

On Wed, Jan 24, 2018 at 7:15 PM, Ladislav Michl <ladis at linux-mips.org> wrote:
> On Wed, Jan 24, 2018 at 06:21:38PM +0200, Andy Shevchenko wrote:

>> > +#define devm_ioremap_resource(dev, res) \
>> > +       __devm_ioremap_resource(dev, res, false)
>> > +#define devm_ioremap_shared_resource(dev, res) \
>> > +       __devm_ioremap_resource(dev, res, true)
>> > +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res,
>> > +                                     bool shared);
>>
>> I would rather do the following:
>>
>> _resource() ->  _resource_exclusive()
>>
>> #define _resource()  _resource_exclusive()
>>
>> Add _resource_shared()
>>
>> And use long names below in this file whenever refer to exclusive or
>> shared variant.
>
> Two separate functions were also considered, but I was unable to find small
> common implementation.

Common part is still like you have done.

I'm talking about _naming_ scheme here.

> If code size does not matter or you can provide a hint
> to make this solution small and nice, I'll go for it.

It would be the same as in your initial proposal, since I'm not
talking about duplicating anything.

-- 
With Best Regards,
Andy Shevchenko


From festevam at gmail.com  Fri Jan 26 13:23:25 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 26 Jan 2018 19:23:25 -0200
Subject: [PATCH RESEND v6 2/2] dt-bindings: fsl-quadspi: Add the example of
 two SPI NOR
In-Reply-To: <1517001805-7646-1-git-send-email-festevam@gmail.com>
References: <1517001805-7646-1-git-send-email-festevam@gmail.com>
Message-ID: <1517001805-7646-2-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at nxp.com>

Improve the bindings example by adding an example of how to represent
two SPI NOR devices.

Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
Acked-by: Han Xu <han.xu at nxp.com>
---
Resending it as I missed to send it to Cyrille

Changes since v5:
- None

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..483e9cf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,27 @@ qspi0: quadspi at 40044000 {
 		....
 	};
 };
+
+Example showing the usage of two SPI NOR devices:
+
+&qspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi2>;
+	status = "okay";
+
+	flash0: n25q256a at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+
+	flash1: n25q256a at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <1>;
+	};
+};
-- 
2.7.4



From festevam at gmail.com  Fri Jan 26 13:23:24 2018
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 26 Jan 2018 19:23:24 -0200
Subject: [PATCH RESEND v6 1/2] mtd: fsl-quadspi: Distinguish the mtd device
 names
Message-ID: <1517001805-7646-1-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at nxp.com>

Currently on a imx6sx-sdb board, which has two SPI NOR chips connected
to QSPI2 the following output from /proc/mtd is seen:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi"
mtd1: 01000000 00010000 "21e4000.qspi"

Attempts to partition them on the kernel command line result in both
chips with identical (and identically named) partitions, which is
an inconvenient behavior.

Assign a different mtd->name for each mtd device to avoid this problem.

After this change the output from /proc/mtd becomes:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 01000000 00010000 "21e4000.qspi-0"
mtd1: 01000000 00010000 "21e4000.qspi-1"

In order to keep mtdparts compatibility keep the mtd->name
unchanged when a single SPI NOR is present.

Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Acked-by: Han Xu <han.xu at nxp.com>
---
Resending it as I missed to send it to Cyrille 

Changes since v5:
- Preserve the label value, if any. (Boris)

 drivers/mtd/spi-nor/fsl-quadspi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..1038842 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		if (q->nor_num > 1 && !mtd->name) {
+			int spiflash_idx;
+
+			ret = of_property_read_u32(np, "reg", &spiflash_idx);
+			if (!ret) {
+				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+							   "%s-%d",
+							   dev_name(dev),
+							   spiflash_idx);
+				if (!mtd->name) {
+					ret = -ENOMEM;
+					goto mutex_failed;
+				}
+			} else {
+				dev_warn(dev, "reg property is missing\n");
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
-- 
2.7.4



From khoroshilov at ispras.ru  Fri Jan 26 14:32:41 2018
From: khoroshilov at ispras.ru (Alexey Khoroshilov)
Date: Sat, 27 Jan 2018 01:32:41 +0300
Subject: [PATCH v3] mtd: nand: vf610: fix error handling in vf610_nfc_probe()
In-Reply-To: <20180106102541.75ff546d@bbrezillon>
Message-ID: <1517005961-7938-1-git-send-email-khoroshilov@ispras.ru>

vf610_nfc_probe() misses error handling of mtd_device_register()
and contains unneeded of_node_put() on error path.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
---
v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
v3: Rename error labels, remove of_node_put() per Boris Brezillon request.

 drivers/mtd/nand/vf610_nfc.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 8037d4b48a05..7cdc6eed305d 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 				dev_err(nfc->dev,
 					"Only one NAND chip supported!\n");
 				err = -EINVAL;
-				goto error;
+				goto err_disable_clk;
 			}
 
 			nand_set_flash_node(chip, child);
@@ -692,7 +692,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	if (!nand_get_flash_node(chip)) {
 		dev_err(nfc->dev, "NAND chip sub-node missing!\n");
 		err = -ENODEV;
-		goto err_clk;
+		goto err_disable_clk;
 	}
 
 	chip->dev_ready = vf610_nfc_dev_ready;
@@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
 	if (err) {
 		dev_err(nfc->dev, "Error requesting IRQ!\n");
-		goto error;
+		goto err_disable_clk;
 	}
 
 	vf610_nfc_preinit_controller(nfc);
@@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	/* first scan to find the device and get the page size */
 	err = nand_scan_ident(mtd, 1, NULL);
 	if (err)
-		goto error;
+		goto err_disable_clk;
 
 	vf610_nfc_init_controller(nfc);
 
@@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
 		dev_err(nfc->dev, "Unsupported flash page size\n");
 		err = -ENXIO;
-		goto error;
+		goto err_disable_clk;
 	}
 
 	if (chip->ecc.mode == NAND_ECC_HW) {
 		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
 			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
 			err = -ENXIO;
-			goto error;
+			goto err_disable_clk;
 		}
 
 		if (chip->ecc.size != mtd->writesize) {
 			dev_err(nfc->dev, "Step size needs to be page size\n");
 			err = -ENXIO;
-			goto error;
+			goto err_disable_clk;
 		}
 
 		/* Only 64 byte ECC layouts known */
@@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 		} else {
 			dev_err(nfc->dev, "Unsupported ECC strength\n");
 			err = -ENXIO;
-			goto error;
+			goto err_disable_clk;
 		}
 
 		chip->ecc.read_page = vf610_nfc_read_page;
@@ -777,16 +777,19 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	/* second phase scan */
 	err = nand_scan_tail(mtd);
 	if (err)
-		goto error;
+		goto err_disable_clk;
 
 	platform_set_drvdata(pdev, mtd);
 
 	/* Register device in MTD */
-	return mtd_device_register(mtd, NULL, 0);
+	err = mtd_device_register(mtd, NULL, 0);
+	if (err)
+		goto err_cleanup_nand;
+	return 0;
 
-error:
-	of_node_put(nand_get_flash_node(chip));
-err_clk:
+err_cleanup_nand:
+	nand_cleanup(chip);
+err_disable_clk:
 	clk_disable_unprepare(nfc->clk);
 	return err;
 }
-- 
2.7.4



From prasannatsmkumar at gmail.com  Fri Jan 26 23:42:47 2018
From: prasannatsmkumar at gmail.com (PrasannaKumar Muralidharan)
Date: Sat, 27 Jan 2018 13:12:47 +0530
Subject: [RFC] NAND: Optimize NAND_ECC_HW_OOB_FIRST read
In-Reply-To: <20171030093426.30827ef5@bbrezillon>
References: <20171028074351.13118-1-prasannatsmkumar@gmail.com>
 <20171030093426.30827ef5@bbrezillon>
Message-ID: <CANc+2y4=1GdfzzMeyO6=vrQDBQKca5NtrHbXtUH9f4yp5wJ-xg@mail.gmail.com>

Hi Boris,

On 30 October 2017 at 14:04, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> Hi PrasannaKumar,
>
> On Sat, 28 Oct 2017 13:13:51 +0530
> PrasannaKumar Muralidharan <prasannatsmkumar at gmail.com> wrote:
>
>> From: Lars-Peter Clausen <lars at metafoo.de>
>>
>> Avoid sending unnecessary READ commands to the chip.
>>
>> Signed-off-by: Lars-Peter Clausen <lars at metafoo.de>
>> Signed-off-by: PrasannaKumar Muralidharan <prasannatsmkumar at gmail.com>
>> ---
>> This patch is taken from git://projects.qi-hardware.com/qi-kernel.git
>> branch jz-3.16. From [1] and [2] it can be seen that the patch author
>> thinks this can be sent upstream but it never happened so far. This
>> patch is used in OpenWRT as seen from [3].
>
> Sounds reasonable, but it's likely to conflict with something I'd like
> to queue for 4.16 [1]. I'll rebase this patch on nand/next once the
> ->exec_op() series is merged. Don't hesitate to ping me if I forget.
>
> Regards,
>
> Boris
>
> [1]http://patchwork.ozlabs.org/project/linux-mtd/list/?series=8923
>
>>
>> I have only compile tested the patch.
>>
>> 1. https://www.mail-archive.com/discussion at lists.en.qi-hardware.com/msg04635.html
>> 2. https://www.mail-archive.com/discussion at lists.en.qi-hardware.com/msg04639.html
>> 3. https://git.lede-project.org/?p=source.git;a=blob;f=target/linux/xburst/patches-3.18/002-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch;h=046da51912de3cd4444779df5de13d2c1999719a;hb=c03d4317a6bc891cb4a5e89cbdd77f37c23aff86
>>
>>  drivers/mtd/nand/nand_base.c | 16 ++++++++++++----
>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
>> index 12edaae..4bf3bdb 100644
>> --- a/drivers/mtd/nand/nand_base.c
>> +++ b/drivers/mtd/nand/nand_base.c
>> @@ -1680,9 +1680,15 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
>>       unsigned int max_bitflips = 0;
>>
>>       /* Read the OOB area first */
>> -     chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
>> -     chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
>> -     chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
>> +     if (mtd->writesize > 512) {
>> +             chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
>> +             chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
>> +             chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0, -1);
>> +     } else {
>> +             chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
>> +             chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
>> +             chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
>> +     }
>>
>>       ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
>>                                        chip->ecc.total);
>> @@ -1902,8 +1908,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
>>                                                __func__, buf);
>>
>>  read_retry:
>> -                     if (nand_standard_page_accessors(&chip->ecc))
>> +                     if (nand_standard_page_accessors(&chip->ecc) &&
>> +                         chip->ecc.mode != NAND_ECC_HW_OOB_FIRST) {
>>                               chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
>> +                     }
>>
>>                       /*
>>                        * Now read the page into the buffer.  Absent an error,
>

Can you please revisit this?

Thanks,
PrasannaKumar


From robert.jarzmik at free.fr  Sat Jan 27 02:33:47 2018
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 27 Jan 2018 11:33:47 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <20180122095149.590612d9@bbrezillon> (Boris Brezillon's message
 of "Mon, 22 Jan 2018 09:51:49 +0100")
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon> <87efmwb8bj.fsf@belgarion.home>
 <20180111232417.4aa86075@xps13> <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon> <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon> <87wp0majtg.fsf@belgarion.home>
 <20180113093807.3984c184@bbrezillon> <20180113120529.2f00ea20@xps13>
 <87o9lwaft9.fsf@belgarion.home> <20180122095149.590612d9@bbrezillon>
Message-ID: <87y3kj8ub8.fsf@belgarion.home>

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> Hi Robert,
>
> On Sun, 14 Jan 2018 11:35:30 +0100
> Robert Jarzmik <robert.jarzmik at free.fr> wrote:
>
>> Miquel Raynal <miquel.raynal at free-electrons.com> writes:
>> 
>> >> It shouldn't be damaged anymore. The bug has been fixed just before we
>> >> asked you to scrub the BBT area.  
>> I confirm. The last marvell branch I have (2be03e113a5b ("HACK: Dump OOB data
>> while reading")) does work correctly on my zylonite.
>> 
>> I still have to make a test of a file write, and a devicetree based setup, but I
>> don't think anything wrong will happen now.
>
> Did you make any progress with that? Note that, no matter the outcome
> of your tests, I don't plan to queue the remaining patches for this
> release, so don't be afraid of putting your Tested-by/Acked-by on
> patches 5-6 if it works on your platforms ;-).

Hi Boris and Miquel,

I have done the write tests with my ubifs existing filesystem, it works.
Feel free to add to patches 5 and 6 my :

Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>

Cheers.

-- 
Robert


From andrea.adami at gmail.com  Sat Jan 27 16:37:00 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Sun, 28 Jan 2018 01:37:00 +0100
Subject: [PATCH 1/2] mtd-utils: common.c: convert to integer arithmetic
In-Reply-To: <58232c8a9192b7fc279389099d2cd1ff7b5abcd3.1516868053.git.andrea.adami@gmail.com>
References: <cover.1516868053.git.andrea.adami@gmail.com>
 <58232c8a9192b7fc279389099d2cd1ff7b5abcd3.1516868053.git.andrea.adami@gmail.com>
Message-ID: <CAAQYJAsSuvFZcb_aQ4F43PeaOQS2E5Jdq_F9ae=DexNvkmY3fw@mail.gmail.com>

On Thu, Jan 25, 2018 at 9:52 AM, Andrea Adami <andrea.adami at gmail.com> wrote:
> We use floating point just to print out KiB, MiB, GiB.
> Avoid that to be klibc friendly.
>
> Fixes compilation for aarch64 against klibc:
>
> error: '-mgeneral-regs-only' is incompatible with floating-point argument
> |    printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
> etc.
>
> Note:
> * In the KiB case, we could apparently multiply by 100 before dividing
>   without risking overflow. This code simply avoids multiplications.
>
> Signed-off-by: Andrea Adami <andrea.adami at gmail.com>
> ---
>  lib/common.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/lib/common.c b/lib/common.c
> index 69b03b3..5e28853 100644
> --- a/lib/common.c
> +++ b/lib/common.c
> @@ -107,6 +107,9 @@ long long util_get_bytes(const char *str)
>  void util_print_bytes(long long bytes, int bracket)
>  {
>         const char *p;
> +       int GiB = 1024 * 1024 * 1024;
> +       int MiB = 1024 * 1024;
> +       int KiB = 1024;
>
>         if (bracket)
>                 p = " (";
> @@ -115,12 +118,12 @@ void util_print_bytes(long long bytes, int bracket)
>
>         printf("%lld bytes", bytes);
>
> -       if (bytes > 1024 * 1024 * 1024)
> -               printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
> -       else if (bytes > 1024 * 1024)
> -               printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024));
> -       else if (bytes > 1024 && bytes != 0)
> -               printf("%s%.1f KiB", p, (double)bytes / 1024);
> +       if (bytes > GiB)
> +               printf("%s%d.%d GiB", p, bytes / GiB, bytes % GiB / (GiB / 10));
> +       else if (bytes > MiB)
> +               printf("%s%d.%d MiB", p, bytes / MiB, bytes % MiB / (MiB / 10));
> +       else if (bytes > KiB && bytes != 0)
> +               printf("%s%d.%d KiB", p, bytes / KiB, bytes % KiB / (KiB / 10));
>         else
>                 return;
>
> --
> 2.7.4
>

Missing cast to integer, the right specifier here would be %lld and not %d.
Building 1.5.2-klibc I had no warnings but now I see them with 2.0.1.
I'll send a v2.

Regards
Andrea


From boris.brezillon at free-electrons.com  Mon Jan 29 01:34:47 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 29 Jan 2018 10:34:47 +0100
Subject: [GIT PULL] mtd: Changes for 4.16
Message-ID: <20180129103447.2e786609@bbrezillon>

Hi Linus,

Here is the MTD PR for 4.16.

Regards,

Boris

The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:

  Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/mtd/for-4.16

for you to fetch changes up to 571cb17b23eccc22f18c4fc0a0fc34cf0abca7ef:

  Merge tag 'nand/for-4.16' of git://git.infradead.org/linux-mtd into mtd/next (2018-01-29 09:58:36 +0100)

----------------------------------------------------------------
MTD changes:
  Core changes:
  * Rework core functions to avoid duplicating generic checks in
    NAND/OneNAND sub-layers
  * Update the MAINTAINERS entry to reflect the fact that MTD
    maintainers now use a single git tree

  Driver changes:
  * CFI: use macros instead of inline functions to limit stack
    usage and make KASAN happy

NAND changes:
  Core changes:
  * Fix NAND_CMD_NONE handling in nand_command[_lp]() hooks
  * Introduce the ->exec_op() infrastructure
  * Rework NAND buffers handling
  * Fix ECC requirements for K9F4G08U0D
  * Fix nand_do_read_oob() to return the number of bitflips
  * Mark K9F1G08U0E as not supporting subpage writes

  Driver changes:
  * MTK: Rework the driver to support new IP versions
  * OMAP OneNAND: Full rework to use new APIs (libgpio, dmaengine) and fix
    DT support
  * Marvell: Add a new driver to replace the pxa3xx one

SPI NOR changes:
  Core changes:
  * Add support to new ISSI and Cypress/Spansion memory parts.
  * Fix support of Micron memories by checking error bits in the FSR.
  * Fix update of block-protection bits by reading back the SR.
  * Restore the internal state of the SPI flash memory when removing the
    device.

  Driver changes:
  * Maintenance for Freescale, Intel and Metiatek drivers.
  * Add support of the direct access mode for the Cadence QSPI controller.

----------------------------------------------------------------
Aaron Sierra (1):
      mtd: spi-nor: Check that BP bits are set properly

Angelo Dureghello (1):
      mtd: spi-nor: add support for ISSI is25lp128

Antonio Borneo (1):
      mtd: mchp23k256: propagate return value of spi_sync()

Arnd Bergmann (2):
      mtd: cfi: convert inline functions to macros
      mtd: onenand: omap2: print resource using %pR format string

Bean Huo (beanhuo) (1):
      mtd: spi-nor: check FSR error bits for Micron memories

Boris Brezillon (15):
      mtd: nand: hynix: Don't wait after applying new read-retry params
      mtd: nand: provide several helpers to do common NAND operations
      mtd: nand: force drivers to explicitly send READ/PROG commands
      mtd: nand: denali: Avoid using ecc->code_buf as a temporary buffer
      mtd: nand: Only allocate ecc->{calc, code}_buf when actually needed
      MAINTAINERS: Move all MTD related branches to a single repo
      mtd: Do not allow MTD devices with inconsistent erase properties
      mtd: Add an helper to make erase request aligned on ->erasesize
      Merge tag 'gpmc-omap-for-v4.16-immutable' of https://github.com/rogerq/linux into nand/next
      mtd: mtdpart: Make ECC stat handling consistent
      mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
      mtd: Remove duplicate checks on mtd_oob_ops parameter
      mtd: nand: gpmi: Fix subpage reads
      Merge tag 'spi-nor/for-4.16' of git://git.infradead.org/linux-mtd into mtd/next
      Merge tag 'nand/for-4.16' of git://git.infradead.org/linux-mtd into mtd/next

Christophe JAILLET (5):
      mtd: onenand: samsung: use devm_ function to simplify code and fix some leaks
      mtd: onenand: samsung: return an error if 'mtd_device_parse_register()' fails
      mtd: onenand: samsung: Propagate the error returned by 'onenand_scan()'
      mtd: onenand: samsung: Remove a useless include
      mtd: onenand: samsung: remove incorrect __iomem annotation

Colin Ian King (4):
      mtd: mtdswap: make array 'name' static const, shrinks object size
      mtd: sharpslpart: fix overflow on block_adr calculation
      mtd: nand: marvell: fix spelling mistake: "suceed"-> "succeed"
      mtd: nand: marvell: remove redundant variable 'oob_len'

Fabio Estevam (3):
      dt-bindings: mtd: fsl-quadspi: Pass the qspi clock names
      mtd: nand: brcmnand: Add a NULL check for devm_kasprintf()
      mtd: nand: qcom: Add a NULL check for devm_kasprintf()

Guochun Mao (1):
      mtd: mtk-nor: modify functions' name more generally

Gustavo A. R. Silva (1):
      mtd: nand: gpmi: replace _manual_ swap with swap macro

Hou Zhiqiang (2):
      mtd: spi-nor: add an API to restore the status of SPI flash chip
      mtd: m25p80: restore the status of SPI flash when exiting

Jagdish Gediya (1):
      mtd: nand: ifc: update bufnum mask for ver >= 2.0.0

Jesse Chan (1):
      mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE

Julia Lawall (1):
      mtd: fsl-quadspi: account for const type of of_device_id.data

Kamal Dasu (1):
      mtd: nand: brcmnand: Disable prefetch by default

Ladislav Michl (15):
      memory: omap-gpmc: Make 'bank-width' property optional
      mtd: onenand: Remove obsolete url from Kconfig help
      mtd: nand: samsung: Disable subpage writes on E-die NAND
      dt-bindings: mtd: gpmc-onenand: Update properties description
      ARM: dts: OMAP2+: Add compatible property to onenand node
      ARM: dts: omap3-igep: Update onenand node timings
      mtd: onenand: omap2: Remove regulator support
      mtd: onenand: omap2: Remove skip initial unlocking support
      mtd: onenand: omap2: Remove partitioning support from platform data
      mtd: onenand: omap2: Account waiting time as waiting on IO
      mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
      mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
      mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
      mtd: onenand: omap2: Configure driver from DT
      ARM: OMAP2+: Remove gpmc-onenand

Masahiro Yamada (6):
      mtd: nand: remove unnecessary extern from driver headers
      mtd: nand: denali: rename misleading dma_buf to tmp_buf
      mtd: nand: cafe: remove use of NAND_OWN_BUFFERS
      mtd: nand: remove unused NAND_OWN_BUFFERS flag
      mtd: nand: squash struct nand_buffers into struct nand_chip
      mtd: nand: cafe: clean up DMA address setup

Mika Westerberg (1):
      spi-nor: intel-spi: Remove unused preopcodes field

Miquel Raynal (16):
      mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]()
      mtd: nand: use usual return values for the ->erase() hook
      mtd: nand: provide valid ->data_interface during NAND detection
      mtd: nand: samsung: add ECC requirements for K9F4G08U0D
      mtd: nand: add ->exec_op() implementation
      mtd: nand: Fix unfinished comment in nand_init_data_interface()
      mtd: mtd_oobtest: Handle bitflips during reads
      mtd: nand: Fix nand_do_read_oob() return value
      dt-bindings: mtd: document new nand-rb property
      dt-bindings: mtd: add Marvell NAND controller documentation
      mtd: nand: add reworked Marvell NAND controller driver
      mtd: nand: use reworked NAND controller driver with Marvell EBU SoCs
      MAINTAINERS: Add entry for Marvell NAND controller driver
      mtd: nand: marvell: Fix missing memory allocation modifier
      mtd: nand: Fix build issues due to an anonymous union
      mtd: nand: sunxi: Fix ECC strength choice

Nicolas Ferre (1):
      MAINTAINERS: mtd/nand: update Microchip nand entry

Peter Ujfalusi (2):
      mtd: onenand: omap2: Simplify the DMA setup for various paths
      mtd: onenand: omap2: Convert to use dmaengine for memcpy

Rafael Gago (1):
      mtd: spi-nor: Add support for s25fl128l and s25fl256l

RogerCC Lin (3):
      mtd: nand: mtk: update DT bindings
      mtd: nand: mtk: Support different MTK NAND flash controller IP
      mtd: nand: mtk: Support MT7622 NAND flash controller.

Romain Porte (1):
      mtd: spi-nor: Add ISSI is25lp080d support

Sascha Hauer (2):
      mtd: nand: gpmi-nand: Remove wrong Kconfig help text
      mtd: tests: nandbiterrs: Fix read_page return value

Sean Nyekjaer (2):
      mtd: spi-nor: add support for is25lq040b
      mtd: spi-nor: indent issi section

Vignesh R (2):
      mtd: spi-nor: cadence-quadspi: Refactor indirect read/write sequence.
      mtd: spi-nor: cadence-quadspi: Add support for direct access mode

Wei Yongjun (2):
      mtd: sharpslpart: make local function sharpsl_nand_cleanup_ftl() static
      mtd: onenand: omap2: Remove redundant dev_err call in omap2_onenand_probe()

Xiaolei Li (1):
      mtd: nand: mtk: use nand_reset() to reset NAND devices in resume function

 Documentation/devicetree/bindings/mtd/fsl-quadspi.txt  |    2 +-
 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt |    6 +-
 Documentation/devicetree/bindings/mtd/marvell-nand.txt |  123 ++
 Documentation/devicetree/bindings/mtd/mtk-nand.txt     |   11 +-
 Documentation/devicetree/bindings/mtd/nand.txt         |    1 +
 Documentation/mtd/spi-nor.txt                          |    3 +
 MAINTAINERS                                            |   28 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi            |    1 +
 arch/arm/boot/dts/omap3-igep.dtsi                      |   30 +-
 arch/arm/boot/dts/omap3-n900.dts                       |    1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi                   |    1 +
 arch/arm/boot/dts/omap3430-sdp.dts                     |    1 +
 arch/arm/configs/mvebu_v7_defconfig                    |    2 +-
 arch/arm/mach-omap2/Makefile                           |    3 -
 arch/arm/mach-omap2/gpmc-onenand.c                     |  409 ------
 arch/arm64/configs/defconfig                           |    2 +-
 drivers/memory/omap-gpmc.c                             |  163 ++-
 drivers/mtd/devices/docg3.c                            |   70 -
 drivers/mtd/devices/m25p80.c                           |    9 +
 drivers/mtd/devices/mchp23k256.c                       |   18 +-
 drivers/mtd/mtdcore.c                                  |   36 +-
 drivers/mtd/mtdpart.c                                  |   43 +-
 drivers/mtd/mtdswap.c                                  |    5 +-
 drivers/mtd/nand/Kconfig                               |   17 +-
 drivers/mtd/nand/Makefile                              |    1 +
 drivers/mtd/nand/atmel/nand-controller.c               |    9 +-
 drivers/mtd/nand/bf5xx_nand.c                          |    6 +-
 drivers/mtd/nand/brcmnand/brcmnand.c                   |   38 +-
 drivers/mtd/nand/cafe_nand.c                           |   52 +-
 drivers/mtd/nand/denali.c                              |   84 +-
 drivers/mtd/nand/denali.h                              |    4 +-
 drivers/mtd/nand/denali_pci.c                          |    4 +
 drivers/mtd/nand/diskonchip.c                          |    4 +-
 drivers/mtd/nand/docg4.c                               |   21 +-
 drivers/mtd/nand/fsl_elbc_nand.c                       |   10 +-
 drivers/mtd/nand/fsl_ifc_nand.c                        |   13 +-
 drivers/mtd/nand/fsmc_nand.c                           |    9 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c                 |  111 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h                 |   46 +-
 drivers/mtd/nand/hisi504_nand.c                        |    9 +-
 drivers/mtd/nand/jz4740_nand.c                         |   16 +-
 drivers/mtd/nand/lpc32xx_mlc.c                         |    7 +-
 drivers/mtd/nand/lpc32xx_slc.c                         |   33 +-
 drivers/mtd/nand/marvell_nand.c                        | 2896 +++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/mtk_ecc.c                             |  126 +-
 drivers/mtd/nand/mtk_ecc.h                             |    3 +-
 drivers/mtd/nand/mtk_nand.c                            |   76 +-
 drivers/mtd/nand/nand_base.c                           | 2603 ++++++++++++++++++++++++++++--------
 drivers/mtd/nand/nand_bbt.c                            |    2 +-
 drivers/mtd/nand/nand_hynix.c                          |  129 +-
 drivers/mtd/nand/nand_micron.c                         |   83 +-
 drivers/mtd/nand/nand_samsung.c                        |   19 +
 drivers/mtd/nand/nand_timings.c                        |   21 +-
 drivers/mtd/nand/omap2.c                               |   28 +-
 drivers/mtd/nand/pxa3xx_nand.c                         |   14 +-
 drivers/mtd/nand/qcom_nandc.c                          |   30 +-
 drivers/mtd/nand/r852.c                                |   11 +-
 drivers/mtd/nand/sh_flctl.c                            |    6 +-
 drivers/mtd/nand/sm_common.h                           |    2 +-
 drivers/mtd/nand/sunxi_nand.c                          |  111 +-
 drivers/mtd/nand/tango_nand.c                          |   27 +-
 drivers/mtd/nand/tmio_nand.c                           |    5 +-
 drivers/mtd/nand/vf610_nfc.c                           |    6 +-
 drivers/mtd/onenand/Kconfig                            |    7 +-
 drivers/mtd/onenand/omap2.c                            |  577 +++-----
 drivers/mtd/onenand/onenand_base.c                     |   81 --
 drivers/mtd/onenand/samsung.c                          |  185 +--
 drivers/mtd/parsers/sharpslpart.c                      |    6 +-
 drivers/mtd/spi-nor/cadence-quadspi.c                  |   55 +-
 drivers/mtd/spi-nor/fsl-quadspi.c                      |    8 +-
 drivers/mtd/spi-nor/intel-spi.c                        |    6 -
 drivers/mtd/spi-nor/mtk-quadspi.c                      |  240 ++--
 drivers/mtd/spi-nor/spi-nor.c                          |   75 +-
 drivers/mtd/tests/nandbiterrs.c                        |    2 +-
 drivers/mtd/tests/oobtest.c                            |   21 +
 drivers/staging/mt29f_spinand/mt29f_spinand.c          |    5 +-
 include/linux/mtd/map.h                                |  130 +-
 include/linux/mtd/mtd.h                                |   28 +
 include/linux/mtd/rawnand.h                            |  443 ++++++-
 include/linux/mtd/spi-nor.h                            |   12 +-
 include/linux/omap-gpmc.h                              |   28 +
 include/linux/platform_data/mtd-onenand-omap2.h        |   34 -
 82 files changed, 7013 insertions(+), 2590 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/marvell-nand.txt
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 create mode 100644 drivers/mtd/nand/marvell_nand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h


From romain.izard.pro at gmail.com  Mon Jan 29 02:18:20 2018
From: romain.izard.pro at gmail.com (Romain Izard)
Date: Mon, 29 Jan 2018 11:18:20 +0100
Subject: [PATCH v1] mtd: ubi: block: Fix error for write access
Message-ID: <20180129101820.1692-1-romain.izard.pro@gmail.com>

When opening a device with write access, ubiblock_open returns an error
code. Currently, this error code is -EPERM, but this is not the right
value.

The open function for other block devices returns -EROFS when opening
read-only devices with FMODE_WRITE set. When used with dm-verity, the
veritysetup userspace tool is expecting EROFS, and refuses to use the
ubiblock device.

Use -EROFS for ubiblock as well. As a result, veritysetup accepts the
ubiblock device as valid.

Fixes: 9d54c8a33eec (UBI: R/O block driver on top of UBI volumes)
Signed-off-by: Romain Izard <romain.izard.pro at gmail.com>
---
 drivers/mtd/ubi/block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index b210fdb31c98..4533423cf2aa 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -242,7 +242,7 @@ static int ubiblock_open(struct block_device *bdev, fmode_t mode)
 	 * in any case.
 	 */
 	if (mode & FMODE_WRITE) {
-		ret = -EPERM;
+		ret = -EROFS;
 		goto out_unlock;
 	}
 
-- 
2.14.1



From boris.brezillon at free-electrons.com  Mon Jan 29 02:36:29 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 29 Jan 2018 11:36:29 +0100
Subject: [PATCH v3 0/7] Marvell NAND controller rework with ->exec_op()
In-Reply-To: <87y3kj8ub8.fsf@belgarion.home>
References: <20180109103637.23798-1-miquel.raynal@free-electrons.com>
 <20180111122751.4bd74366@bbrezillon>
 <87efmwb8bj.fsf@belgarion.home> <20180111232417.4aa86075@xps13>
 <87a7xjbis2.fsf@belgarion.home>
 <20180112094501.27706bfc@bbrezillon>
 <876087beui.fsf@belgarion.home>
 <20180112105228.176ab80f@bbrezillon>
 <87wp0majtg.fsf@belgarion.home>
 <20180113093807.3984c184@bbrezillon>
 <20180113120529.2f00ea20@xps13> <87o9lwaft9.fsf@belgarion.home>
 <20180122095149.590612d9@bbrezillon>
 <87y3kj8ub8.fsf@belgarion.home>
Message-ID: <20180129113629.681657df@bbrezillon>

On Sat, 27 Jan 2018 11:33:47 +0100
Robert Jarzmik <robert.jarzmik at free.fr> wrote:

> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > Hi Robert,
> >
> > On Sun, 14 Jan 2018 11:35:30 +0100
> > Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> >  
> >> Miquel Raynal <miquel.raynal at free-electrons.com> writes:
> >>   
> >> >> It shouldn't be damaged anymore. The bug has been fixed just before we
> >> >> asked you to scrub the BBT area.    
> >> I confirm. The last marvell branch I have (2be03e113a5b ("HACK: Dump OOB data
> >> while reading")) does work correctly on my zylonite.
> >> 
> >> I still have to make a test of a file write, and a devicetree based setup, but I
> >> don't think anything wrong will happen now.  
> >
> > Did you make any progress with that? Note that, no matter the outcome
> > of your tests, I don't plan to queue the remaining patches for this
> > release, so don't be afraid of putting your Tested-by/Acked-by on
> > patches 5-6 if it works on your platforms ;-).  
> 
> Hi Boris and Miquel,
> 
> I have done the write tests with my ubifs existing filesystem, it works.
> Feel free to add to patches 5 and 6 my :
> 
> Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>

Thanks a lot.

Would you mind reviewing/testing patch 7?

Thanks,

Boris


From stefan at agner.ch  Mon Jan 29 06:44:40 2018
From: stefan at agner.ch (Stefan Agner)
Date: Mon, 29 Jan 2018 15:44:40 +0100
Subject: [PATCH] mtd: nand: gpmi: fall back to legacy mode if no ECC
 information present
Message-ID: <20180129144440.13648-1-stefan@agner.ch>

In case fsl,use-minimum-ecc is set, the driver tries to determine
ECC layout by using the ECC information provided by the MTD stack.
However, in case the NAND chip does not provide any information,
the driver currently fails with:
  nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
  nand: Macronix NAND 128MiB 3,3V 8-bit
  nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
  gpmi-nand 1806000.gpmi-nand: Error setting BCH geometry : 1
  gpmi-nand: probe of 1806000.gpmi-nand failed with error 1

Fall back to implementation specific default mode if no ECC
information are provided by the NAND chip and fsl,use-minimum-ecc
is specified.

This is more in line with what the device tree binding documentation
promises:
  "However, note that if this strength is not
  discoverable or this property is not enabled,
  the software may chooses an implementation-defined
  ECC scheme."

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 50f8d4a1b983..7b8e8c629081 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -206,7 +206,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
 	unsigned int block_mark_bit_offset;
 
 	if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
-		return -EINVAL;
+		return -ENOTSUPP;
 
 	switch (chip->ecc_step_ds) {
 	case SZ_512:
@@ -423,11 +423,15 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
-	if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
-				|| legacy_set_geometry(this))
-		return set_geometry_by_ecc_info(this);
+	int ret = -ENOTSUPP;
 
-	return 0;
+	if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
+		ret = set_geometry_by_ecc_info(this);
+
+	if (ret == -ENOTSUPP)
+		return legacy_set_geometry(this);
+
+	return ret;
 }
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
-- 
2.16.1



From andrea.adami at gmail.com  Mon Jan 29 14:07:11 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Mon, 29 Jan 2018 23:07:11 +0100
Subject: [PATCH v2 1/2] mtd-utils: common.c: convert to integer arithmetic
In-Reply-To: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
References: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
Message-ID: <1517263632-11126-2-git-send-email-andrea.adami@gmail.com>

We use floating point just to print out KiB, MiB, GiB.
Avoid that to be klibc friendly.

Fixes compilation for aarch64 against klibc:

error: '-mgeneral-regs-only' is incompatible with floating-point argument
|    printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
etc.

Signed-off-by: Andrea Adami <andrea.adami at gmail.com>
---
v2 fixes -Wformat warnings for printf() using %d instead of %lld

 lib/common.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/lib/common.c b/lib/common.c
index 69b03b3..8041878 100644
--- a/lib/common.c
+++ b/lib/common.c
@@ -107,6 +107,9 @@ long long util_get_bytes(const char *str)
 void util_print_bytes(long long bytes, int bracket)
 {
 	const char *p;
+	int GiB = 1024 * 1024 * 1024;
+	int MiB = 1024 * 1024;
+	int KiB = 1024;
 
 	if (bracket)
 		p = " (";
@@ -115,12 +118,15 @@ void util_print_bytes(long long bytes, int bracket)
 
 	printf("%lld bytes", bytes);
 
-	if (bytes > 1024 * 1024 * 1024)
-		printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
-	else if (bytes > 1024 * 1024)
-		printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024));
-	else if (bytes > 1024 && bytes != 0)
-		printf("%s%.1f KiB", p, (double)bytes / 1024);
+	if (bytes > GiB)
+		printf("%s%lld.%lld GiB", p,
+		       bytes / GiB, bytes % GiB / (GiB / 10));
+	else if (bytes > MiB)
+		printf("%s%lld.%lld MiB", p,
+		        bytes / MiB, bytes % MiB / (MiB / 10));
+	else if (bytes > KiB && bytes != 0)
+		printf("%s%lld.%lld KiB", p,
+		        bytes / KiB, bytes % KiB / (KiB / 10));
 	else
 		return;
 
-- 
2.7.4



From andrea.adami at gmail.com  Mon Jan 29 14:07:10 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Mon, 29 Jan 2018 23:07:10 +0100
Subject: [PATCH v2 0/2] mtd-utils: improve compatibility with klibc
Message-ID: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>

Klibc does not support floating point calculations.
Here some fixes needed to build the ubi-utils against klibc for aarch64,
without FPU.

These lines end up compiled with soft float for other arm targets w/out
FPU thus this was discovered only cross-building for qemuarm64 using the flag
 '-mgeneral-regs-only'.

Changes tested on armv5, same output is printed.
v2 fixes compiler warnings (-Wformat) about printf().

Andrea Adami (2):
  mtd-utils: common.c: convert to integer arithmetic
  ubi-utils: ubiformat.c: convert to integer arithmetic

 lib/common.c          | 18 ++++++++++++------
 ubi-utils/ubiformat.c |  2 +-
 2 files changed, 13 insertions(+), 7 deletions(-)

-- 
2.7.4



From andrea.adami at gmail.com  Mon Jan 29 14:07:12 2018
From: andrea.adami at gmail.com (Andrea Adami)
Date: Mon, 29 Jan 2018 23:07:12 +0100
Subject: [PATCH v2 2/2] ubi-utils: ubiformat.c: convert to integer arithmetic
In-Reply-To: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
References: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
Message-ID: <1517263632-11126-3-git-send-email-andrea.adami@gmail.com>

Do not cast percent to double, it is just used as upper limit.
Avoid floating point to fix compilation for aarch64 against klibc:

error: '-mgeneral-regs-only' is incompatible with floating-point code
|    int percent = ((double)si->ok_cnt)/si->good_cnt * 100;
|        ^~~~~~~

Notes:
* The checks in the code above this line ensure that si->good_cnt is not 0.

* The code assumes  si->good_cnt * 100  will not overflow, then we can use
  (si->ok_cnt * 100) safely because the former is bigger.

* The truncated result does not affect the logic:
  i.e. a value of 49.9 is truncated to 49 and is still <50.

Signed-off-by: Andrea Adami <andrea.adami at gmail.com>
---
v2 no changes

 ubi-utils/ubiformat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ubi-utils/ubiformat.c b/ubi-utils/ubiformat.c
index ef0378a..c38b9b4 100644
--- a/ubi-utils/ubiformat.c
+++ b/ubi-utils/ubiformat.c
@@ -844,7 +844,7 @@ int main(int argc, char * const argv[])
 	}
 
 	if (!args.override_ec && si->empty_cnt < si->good_cnt) {
-		int percent = ((double)si->ok_cnt)/si->good_cnt * 100;
+		int percent = (si->ok_cnt * 100) / si->good_cnt;
 
 		/*
 		 * Make sure the majority of eraseblocks have valid
-- 
2.7.4



From yoshitake.kobayashi at toshiba.co.jp  Mon Jan 29 15:44:30 2018
From: yoshitake.kobayashi at toshiba.co.jp (KOBAYASHI Yoshitake)
Date: Tue, 30 Jan 2018 08:44:30 +0900
Subject: [PATCH -next v3 1/2] mtd: nand: toshiba: Retrieve ECC
 requirements from extended ID
In-Reply-To: <b9e62f60-770b-89c3-a2e2-c05767cfd16a@toshiba.co.jp>
References: <1512569098-30038-1-git-send-email-yoshitake.kobayashi@toshiba.co.jp>
 <1512569098-30038-2-git-send-email-yoshitake.kobayashi@toshiba.co.jp>
 <20171206160805.2435094b@bbrezillon>
 <3e11d966-0801-96f2-8417-194b36a0b775@toshiba.co.jp>
 <20171219125624.58e3e8f8@bbrezillon>
 <b9e62f60-770b-89c3-a2e2-c05767cfd16a@toshiba.co.jp>
Message-ID: <0cf2e0f7-e61b-2cae-f216-e616aecf3e76@toshiba.co.jp>

On 2017/12/27 15:06, KOBAYASHI Yoshitake wrote:
> On 2017/12/19 20:56, Boris Brezillon wrote:
>> On Tue, 19 Dec 2017 20:42:36 +0900
>> KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp> wrote:
>>
>>> On 2017/12/07 0:08, Boris Brezillon wrote:
>>>> On Wed,  6 Dec 2017 23:04:57 +0900
>>>> KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp> wrote:
>>>>   
>>>>> This patch enables support to read the ECC strength and size from the
>>>>> NAND flash using Toshiba Memory SLC NAND extended-ID. This patch is
>>>>> based on the information of the 6th ID byte of the Toshiba Memory SLC
>>>>> NAND.
>>>>>
>>>>> Signed-off-by: KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp>
>>>>> ---
>>>>>  drivers/mtd/nand/nand_toshiba.c | 28 ++++++++++++++++++++++++++++
>>>>>  1 file changed, 28 insertions(+)
>>>>>
>>>>> diff --git a/drivers/mtd/nand/nand_toshiba.c b/drivers/mtd/nand/nand_toshiba.c
>>>>> index 57df857..c2c141b 100644
>>>>> --- a/drivers/mtd/nand/nand_toshiba.c
>>>>> +++ b/drivers/mtd/nand/nand_toshiba.c
>>>>> @@ -35,6 +35,34 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
>>>>>  	    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
>>>>>  	    !(chip->id.data[4] & 0x80) /* !BENAND */)
>>>>>  		mtd->oobsize = 32 * mtd->writesize >> 9;
>>>>> +
>>>>> +	/*
>>>>> +	 * Extract ECC requirements from 6th id byte.
>>>>> +	 * For Toshiba SLC, ecc requrements are as follows:
>>>>> +	 *  - 43nm: 1 bit ECC for each 512Byte is required.
>>>>> +	 *  - 32nm: 4 bit ECC for each 512Byte is required.
>>>>> +	 *  - 24nm: 8 bit ECC for each 512Byte is required.
>>>>> +	 */
>>>>> +	if (chip->id.len >= 6 && nand_is_slc(chip)) {
>>>>> +		chip->ecc_step_ds = 512;
>>>>> +		switch (chip->id.data[5] & 0x7) {
>>>>> +		case 0x4:
>>>>> +			chip->ecc_strength_ds = 1;
>>>>> +			break;
>>>>> +		case 0x5:
>>>>> +			chip->ecc_strength_ds = 4;
>>>>> +			break;
>>>>> +		case 0x6:
>>>>> +			chip->ecc_strength_ds = 8;
>>>>> +			break;
>>>>> +		default:
>>>>> +			WARN(1, "Could not get ECC info");
>>>>> +			chip->ecc_step_ds = 0;
>>>>> +			break;
>>>>> +		}
>>>>> +	} else if (chip->id.len < 6 && nand_is_slc(chip)) {
>>>>> +		WARN(1, "Could not get ECC info, 6th nand id byte does not exist.");  
>>>>
>>>> I'm pretty sure you have old NAND chips that do not have 6bytes ids
>>>> (see the table here [1]), and printing a huge backtrace in this case is
>>>> probably not what you want.
>>>>
>>>> If you're okay with dropping this else block, I'll do the change when
>>>> applying, no need to send a new version.  
>>>
>>> Some controllers may have limitation in reading ids beyond 5 bytes, 
>>> considering such scenario we think it is better to keep this warning.
>>> However if you feel huge backtrace is an issue, how about we using pr_warn() instead?
>>>
>>
>> Toshiba NANDs with an id smaller than 6 bytes exist, so no, we should
>> not complain at all. If the controller is broken and can't read the 8 id
>> bytes the core is asking for, then it should be detected at the core
>> level not in the NAND manufacturer driver.
> 
> I understood your opinion. Please apply this patch with dropping the else block.

Should I repost patch with else block dropped? Please let me know if that is necessary.

-- Yoshi



From boris.brezillon at free-electrons.com  Tue Jan 30 00:04:46 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 30 Jan 2018 09:04:46 +0100
Subject: [PATCH -next v3 1/2] mtd: nand: toshiba: Retrieve ECC
 requirements from extended ID
In-Reply-To: <0cf2e0f7-e61b-2cae-f216-e616aecf3e76@toshiba.co.jp>
References: <1512569098-30038-1-git-send-email-yoshitake.kobayashi@toshiba.co.jp>
 <1512569098-30038-2-git-send-email-yoshitake.kobayashi@toshiba.co.jp>
 <20171206160805.2435094b@bbrezillon>
 <3e11d966-0801-96f2-8417-194b36a0b775@toshiba.co.jp>
 <20171219125624.58e3e8f8@bbrezillon>
 <b9e62f60-770b-89c3-a2e2-c05767cfd16a@toshiba.co.jp>
 <0cf2e0f7-e61b-2cae-f216-e616aecf3e76@toshiba.co.jp>
Message-ID: <20180130090446.1ace92b3@bbrezillon>

On Tue, 30 Jan 2018 08:44:30 +0900
KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp> wrote:

> On 2017/12/27 15:06, KOBAYASHI Yoshitake wrote:
> > On 2017/12/19 20:56, Boris Brezillon wrote:  
> >> On Tue, 19 Dec 2017 20:42:36 +0900
> >> KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp> wrote:
> >>  
> >>> On 2017/12/07 0:08, Boris Brezillon wrote:  
> >>>> On Wed,  6 Dec 2017 23:04:57 +0900
> >>>> KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp> wrote:
> >>>>     
> >>>>> This patch enables support to read the ECC strength and size from the
> >>>>> NAND flash using Toshiba Memory SLC NAND extended-ID. This patch is
> >>>>> based on the information of the 6th ID byte of the Toshiba Memory SLC
> >>>>> NAND.
> >>>>>
> >>>>> Signed-off-by: KOBAYASHI Yoshitake <yoshitake.kobayashi at toshiba.co.jp>
> >>>>> ---
> >>>>>  drivers/mtd/nand/nand_toshiba.c | 28 ++++++++++++++++++++++++++++
> >>>>>  1 file changed, 28 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/mtd/nand/nand_toshiba.c b/drivers/mtd/nand/nand_toshiba.c
> >>>>> index 57df857..c2c141b 100644
> >>>>> --- a/drivers/mtd/nand/nand_toshiba.c
> >>>>> +++ b/drivers/mtd/nand/nand_toshiba.c
> >>>>> @@ -35,6 +35,34 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
> >>>>>  	    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
> >>>>>  	    !(chip->id.data[4] & 0x80) /* !BENAND */)
> >>>>>  		mtd->oobsize = 32 * mtd->writesize >> 9;
> >>>>> +
> >>>>> +	/*
> >>>>> +	 * Extract ECC requirements from 6th id byte.
> >>>>> +	 * For Toshiba SLC, ecc requrements are as follows:
> >>>>> +	 *  - 43nm: 1 bit ECC for each 512Byte is required.
> >>>>> +	 *  - 32nm: 4 bit ECC for each 512Byte is required.
> >>>>> +	 *  - 24nm: 8 bit ECC for each 512Byte is required.
> >>>>> +	 */
> >>>>> +	if (chip->id.len >= 6 && nand_is_slc(chip)) {
> >>>>> +		chip->ecc_step_ds = 512;
> >>>>> +		switch (chip->id.data[5] & 0x7) {
> >>>>> +		case 0x4:
> >>>>> +			chip->ecc_strength_ds = 1;
> >>>>> +			break;
> >>>>> +		case 0x5:
> >>>>> +			chip->ecc_strength_ds = 4;
> >>>>> +			break;
> >>>>> +		case 0x6:
> >>>>> +			chip->ecc_strength_ds = 8;
> >>>>> +			break;
> >>>>> +		default:
> >>>>> +			WARN(1, "Could not get ECC info");
> >>>>> +			chip->ecc_step_ds = 0;
> >>>>> +			break;
> >>>>> +		}
> >>>>> +	} else if (chip->id.len < 6 && nand_is_slc(chip)) {
> >>>>> +		WARN(1, "Could not get ECC info, 6th nand id byte does not exist.");    
> >>>>
> >>>> I'm pretty sure you have old NAND chips that do not have 6bytes ids
> >>>> (see the table here [1]), and printing a huge backtrace in this case is
> >>>> probably not what you want.
> >>>>
> >>>> If you're okay with dropping this else block, I'll do the change when
> >>>> applying, no need to send a new version.    
> >>>
> >>> Some controllers may have limitation in reading ids beyond 5 bytes, 
> >>> considering such scenario we think it is better to keep this warning.
> >>> However if you feel huge backtrace is an issue, how about we using pr_warn() instead?
> >>>  
> >>
> >> Toshiba NANDs with an id smaller than 6 bytes exist, so no, we should
> >> not complain at all. If the controller is broken and can't read the 8 id
> >> bytes the core is asking for, then it should be detected at the core
> >> level not in the NAND manufacturer driver.  
> > 
> > I understood your opinion. Please apply this patch with dropping the else block.  
> 
> Should I repost patch with else block dropped? Please let me know if that is necessary.

I forgot to apply it :-/. Please, send a new version so I can track
it in patchwork.

Thanks,

Boris


From mika.westerberg at linux.intel.com  Tue Jan 30 02:50:13 2018
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Tue, 30 Jan 2018 12:50:13 +0200
Subject: [PATCH 1/3] spi-nor: intel-spi: Prefer WREN over other write
 enables
In-Reply-To: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
Message-ID: <20180130105013.GH27654@lahna.fi.intel.com>

On Thu, Jan 04, 2018 at 12:07:42PM +0300, Mika Westerberg wrote:
> On many older systems using SW sequencer the PREOP_OPTYPE register
> contains two preopcodes as following:
> 
>   PREOP_OPTYPE=0xf2785006
> 
> The last two bytes are the opcodes decoded to:
> 
>   0x50 - Write enable for volatile status register
>   0x06 - Write enable
> 
> The former is used to modify volatile bits in the status register. For
> non-volatile bits the latter is needed. Preopcodes are used in SW
> sequencer to send one command "atomically" without anything else
> interfering the transfer. The sequence that gets executed is:
> 
>   - Send preopcode (write enable) from PREOP_OPTYPE register
>   - Send the actual SPI command
>   - Poll busy bit in the status register (0x05, RDSR)
> 
> Commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
> programmed by BIOS") enabled atomic sequence handling but because both
> preopcodes are programmed, the following happens:
> 
>   if (preop >> 8)
>   	val |= SSFSTS_CTL_SPOP;
> 
> Since on these systems preop >> 8 == 0x50 we end up picking volatile
> write enable instead. Because of this the actual write command is pretty
> much NOP unless there is a WREN latched in the chip already.
> 
> Fix this by preferring WREN over other write enable preopcodes.
> 
> Fixes: 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> Cc: stable at vger.kernel.org

Hi,

Any change getting these merged for v4.16?


From boris.brezillon at free-electrons.com  Tue Jan 30 02:59:14 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 30 Jan 2018 11:59:14 +0100
Subject: [PATCH 1/3] spi-nor: intel-spi: Prefer WREN over other write
 enables
In-Reply-To: <20180130105013.GH27654@lahna.fi.intel.com>
References: <20180104090744.67654-1-mika.westerberg@linux.intel.com>
 <20180130105013.GH27654@lahna.fi.intel.com>
Message-ID: <20180130115914.6d75009a@bbrezillon>

On Tue, 30 Jan 2018 12:50:13 +0200
Mika Westerberg <mika.westerberg at linux.intel.com> wrote:

> On Thu, Jan 04, 2018 at 12:07:42PM +0300, Mika Westerberg wrote:
> > On many older systems using SW sequencer the PREOP_OPTYPE register
> > contains two preopcodes as following:
> > 
> >   PREOP_OPTYPE=0xf2785006
> > 
> > The last two bytes are the opcodes decoded to:
> > 
> >   0x50 - Write enable for volatile status register
> >   0x06 - Write enable
> > 
> > The former is used to modify volatile bits in the status register. For
> > non-volatile bits the latter is needed. Preopcodes are used in SW
> > sequencer to send one command "atomically" without anything else
> > interfering the transfer. The sequence that gets executed is:
> > 
> >   - Send preopcode (write enable) from PREOP_OPTYPE register
> >   - Send the actual SPI command
> >   - Poll busy bit in the status register (0x05, RDSR)
> > 
> > Commit 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
> > programmed by BIOS") enabled atomic sequence handling but because both
> > preopcodes are programmed, the following happens:
> > 
> >   if (preop >> 8)
> >   	val |= SSFSTS_CTL_SPOP;
> > 
> > Since on these systems preop >> 8 == 0x50 we end up picking volatile
> > write enable instead. Because of this the actual write command is pretty
> > much NOP unless there is a WREN latched in the chip already.
> > 
> > Fix this by preferring WREN over other write enable preopcodes.
> > 
> > Fixes: 8c473dd61bb5 ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
> > Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> > Cc: stable at vger.kernel.org  
> 
> Hi,
> 
> Any change getting these merged for v4.16?

It's a fix, so yes, I can queue it for -rc2. I just need Cyrille's ack.


From david.oberhollenzer at sigma-star.at  Tue Jan 30 04:08:51 2018
From: david.oberhollenzer at sigma-star.at (David Oberhollenzer)
Date: Tue, 30 Jan 2018 13:08:51 +0100
Subject: [PATCH v2 0/2] mtd-utils: improve compatibility with klibc
In-Reply-To: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
References: <1517263632-11126-1-git-send-email-andrea.adami@gmail.com>
Message-ID: <f835096b-3089-5fc5-baa7-76ff36106c26@sigma-star.at>

Applied to mtd-utils.git

Thanks,

David



From boris.brezillon at free-electrons.com  Tue Jan 30 05:11:41 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 30 Jan 2018 14:11:41 +0100
Subject: [PATCH v3] mtd: nand: vf610: fix error handling in
 vf610_nfc_probe()
In-Reply-To: <1517005961-7938-1-git-send-email-khoroshilov@ispras.ru>
References: <20180106102541.75ff546d@bbrezillon>
 <1517005961-7938-1-git-send-email-khoroshilov@ispras.ru>
Message-ID: <20180130141141.7f4fd15a@bbrezillon>

On Sat, 27 Jan 2018 01:32:41 +0300
Alexey Khoroshilov <khoroshilov at ispras.ru> wrote:

> vf610_nfc_probe() misses error handling of mtd_device_register()
> and contains unneeded of_node_put() on error path.
> 
> Found by Linux Driver Verification project (linuxtesting.org).
> 
> Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
> ---
> v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
> v3: Rename error labels, remove of_node_put() per Boris Brezillon request.

Should be separated in 3 patches IMO:
1/ remove the unnecessary of_node_put()
2/ rename error label into err_disable_clk
3/ check mtd_device_register() return code

> 
>  drivers/mtd/nand/vf610_nfc.c | 29 ++++++++++++++++-------------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> index 8037d4b48a05..7cdc6eed305d 100644
> --- a/drivers/mtd/nand/vf610_nfc.c
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  				dev_err(nfc->dev,
>  					"Only one NAND chip supported!\n");
>  				err = -EINVAL;
> -				goto error;
> +				goto err_disable_clk;
>  			}
>  
>  			nand_set_flash_node(chip, child);
> @@ -692,7 +692,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	if (!nand_get_flash_node(chip)) {
>  		dev_err(nfc->dev, "NAND chip sub-node missing!\n");
>  		err = -ENODEV;
> -		goto err_clk;
> +		goto err_disable_clk;
>  	}
>  
>  	chip->dev_ready = vf610_nfc_dev_ready;
> @@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
>  	if (err) {
>  		dev_err(nfc->dev, "Error requesting IRQ!\n");
> -		goto error;
> +		goto err_disable_clk;
>  	}
>  
>  	vf610_nfc_preinit_controller(nfc);
> @@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* first scan to find the device and get the page size */
>  	err = nand_scan_ident(mtd, 1, NULL);
>  	if (err)
> -		goto error;
> +		goto err_disable_clk;
>  
>  	vf610_nfc_init_controller(nfc);
>  
> @@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
>  		dev_err(nfc->dev, "Unsupported flash page size\n");
>  		err = -ENXIO;
> -		goto error;
> +		goto err_disable_clk;
>  	}
>  
>  	if (chip->ecc.mode == NAND_ECC_HW) {
>  		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
>  			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_disable_clk;
>  		}
>  
>  		if (chip->ecc.size != mtd->writesize) {
>  			dev_err(nfc->dev, "Step size needs to be page size\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_disable_clk;
>  		}
>  
>  		/* Only 64 byte ECC layouts known */
> @@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  		} else {
>  			dev_err(nfc->dev, "Unsupported ECC strength\n");
>  			err = -ENXIO;
> -			goto error;
> +			goto err_disable_clk;
>  		}
>  
>  		chip->ecc.read_page = vf610_nfc_read_page;
> @@ -777,16 +777,19 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	/* second phase scan */
>  	err = nand_scan_tail(mtd);
>  	if (err)
> -		goto error;
> +		goto err_disable_clk;
>  
>  	platform_set_drvdata(pdev, mtd);
>  
>  	/* Register device in MTD */
> -	return mtd_device_register(mtd, NULL, 0);
> +	err = mtd_device_register(mtd, NULL, 0);
> +	if (err)
> +		goto err_cleanup_nand;
> +	return 0;
>  
> -error:
> -	of_node_put(nand_get_flash_node(chip));
> -err_clk:
> +err_cleanup_nand:
> +	nand_cleanup(chip);
> +err_disable_clk:
>  	clk_disable_unprepare(nfc->clk);
>  	return err;
>  }



From geert at linux-m68k.org  Tue Jan 30 05:23:21 2018
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 30 Jan 2018 14:23:21 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
Message-ID: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>

If NO_DMA=y:

    ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!

Add a dependency on HAS_DMA to fix this.

Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
---
 drivers/mtd/nand/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index e6b8c59f2c0da7c0..736ac887303c88ba 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
 	tristate "NAND controller support on Marvell boards"
 	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
 		   COMPILE_TEST
-	depends on HAS_IOMEM
+	depends on HAS_IOMEM && HAS_DMA
 	help
 	  This enables the NAND flash controller driver for Marvell boards,
 	  including:
-- 
2.7.4



From boris.brezillon at free-electrons.com  Tue Jan 30 05:23:48 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 30 Jan 2018 14:23:48 +0100
Subject: [PATCH] mtd: nand: gpmi: fall back to legacy mode if no ECC
 information present
In-Reply-To: <20180129144440.13648-1-stefan@agner.ch>
References: <20180129144440.13648-1-stefan@agner.ch>
Message-ID: <20180130142348.35f1bce3@bbrezillon>

Hi Stefan,

On Mon, 29 Jan 2018 15:44:40 +0100
Stefan Agner <stefan at agner.ch> wrote:

> In case fsl,use-minimum-ecc is set, the driver tries to determine
> ECC layout by using the ECC information provided by the MTD stack.
> However, in case the NAND chip does not provide any information,
> the driver currently fails with:
>   nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
>   nand: Macronix NAND 128MiB 3,3V 8-bit
>   nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>   gpmi-nand 1806000.gpmi-nand: Error setting BCH geometry : 1
>   gpmi-nand: probe of 1806000.gpmi-nand failed with error 1
> 
> Fall back to implementation specific default mode if no ECC
> information are provided by the NAND chip and fsl,use-minimum-ecc
> is specified.

Hm, this sounds a bit fragile: if we ever fix the Macronix driver
(which should be done BTW) to set the appropriate ECC requirements, it
will break all platforms that were relying on this 'fall back to legacy
logic'.
So, if what you really want is legacy_set_geometry(), don't specify
"fsl,use-minimum-ecc" in your DT and you should be good. Otherwise, fix
the Macronix driver to initialize ->ecc_{strength,step_size}_ds
appropriately.

Regards,

Boris

> 
> This is more in line with what the device tree binding documentation
> promises:
>   "However, note that if this strength is not
>   discoverable or this property is not enabled,
>   the software may chooses an implementation-defined
>   ECC scheme."
> 
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 50f8d4a1b983..7b8e8c629081 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -206,7 +206,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
>  	unsigned int block_mark_bit_offset;
>  
>  	if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
> -		return -EINVAL;
> +		return -ENOTSUPP;
>  
>  	switch (chip->ecc_step_ds) {
>  	case SZ_512:
> @@ -423,11 +423,15 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> -	if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
> -				|| legacy_set_geometry(this))
> -		return set_geometry_by_ecc_info(this);
> +	int ret = -ENOTSUPP;
>  
> -	return 0;
> +	if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
> +		ret = set_geometry_by_ecc_info(this);
> +
> +	if (ret == -ENOTSUPP)
> +		return legacy_set_geometry(this);
> +
> +	return ret;
>  }
>  
>  struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)



From miquel.raynal at free-electrons.com  Tue Jan 30 05:46:47 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue, 30 Jan 2018 14:46:47 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
In-Reply-To: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
References: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
Message-ID: <20180130144647.73a44b8d@xps13>

Hi Geert,

On Tue, 30 Jan 2018 14:23:21 +0100
Geert Uytterhoeven <geert at linux-m68k.org> wrote:

> If NO_DMA=y:
> 
>     ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!
> 
> Add a dependency on HAS_DMA to fix this.
> 
> Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
> Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
> ---
>  drivers/mtd/nand/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index e6b8c59f2c0da7c0..736ac887303c88ba 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
>  	tristate "NAND controller support on Marvell boards"
>  	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
>  		   COMPILE_TEST
> -	depends on HAS_IOMEM
> +	depends on HAS_IOMEM && HAS_DMA

I think this is more a coding issue than a Kconfig issue. AFAIR, none
of the ARCH_MVEBU SoCs use DMA in conjunction with the NAND controller.
PXA SoCs may use DMA (NFCv1 only) but this is not a hard requirement and
the driver is supposed to support PIO mode in all situations.

Can you please share your setup, the SoC, the configuration,
maybe also the DT?


Thanks,
Miqu?l



From boris.brezillon at free-electrons.com  Tue Jan 30 05:56:26 2018
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 30 Jan 2018 14:56:26 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
In-Reply-To: <20180130144647.73a44b8d@xps13>
References: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
 <20180130144647.73a44b8d@xps13>
Message-ID: <20180130145626.7a108c64@bbrezillon>

On Tue, 30 Jan 2018 14:46:47 +0100
Miquel Raynal <miquel.raynal at free-electrons.com> wrote:

> Hi Geert,
> 
> On Tue, 30 Jan 2018 14:23:21 +0100
> Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> 
> > If NO_DMA=y:
> > 
> >     ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!
> > 
> > Add a dependency on HAS_DMA to fix this.
> > 
> > Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
> > Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
> > ---
> >  drivers/mtd/nand/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> > index e6b8c59f2c0da7c0..736ac887303c88ba 100644
> > --- a/drivers/mtd/nand/Kconfig
> > +++ b/drivers/mtd/nand/Kconfig
> > @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
> >  	tristate "NAND controller support on Marvell boards"
> >  	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
> >  		   COMPILE_TEST
> > -	depends on HAS_IOMEM
> > +	depends on HAS_IOMEM && HAS_DMA  
> 
> I think this is more a coding issue than a Kconfig issue. AFAIR, none
> of the ARCH_MVEBU SoCs use DMA in conjunction with the NAND controller.
> PXA SoCs may use DMA (NFCv1 only) but this is not a hard requirement and
> the driver is supposed to support PIO mode in all situations.
> 
> Can you please share your setup, the SoC, the configuration,
> maybe also the DT?

I don't think Geert is testing on a real board. He's just enabling
COMPILE_TEST and can then select your driver. Which means you really
need this depends on HAS_DMA.


From geert at linux-m68k.org  Tue Jan 30 05:59:37 2018
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 30 Jan 2018 14:59:37 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
In-Reply-To: <20180130145626.7a108c64@bbrezillon>
References: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
 <20180130144647.73a44b8d@xps13> <20180130145626.7a108c64@bbrezillon>
Message-ID: <CAMuHMdVZSBdGxRZfYRaNGH5Aygf3avuCu86dMJ0NsxxVp_yifg@mail.gmail.com>

On Tue, Jan 30, 2018 at 2:56 PM, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> On Tue, 30 Jan 2018 14:46:47 +0100
> Miquel Raynal <miquel.raynal at free-electrons.com> wrote:
>> On Tue, 30 Jan 2018 14:23:21 +0100
>> Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>>
>> > If NO_DMA=y:
>> >
>> >     ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!
>> >
>> > Add a dependency on HAS_DMA to fix this.
>> >
>> > Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
>> > Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
>> > ---
>> >  drivers/mtd/nand/Kconfig | 2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
>> > index e6b8c59f2c0da7c0..736ac887303c88ba 100644
>> > --- a/drivers/mtd/nand/Kconfig
>> > +++ b/drivers/mtd/nand/Kconfig
>> > @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
>> >     tristate "NAND controller support on Marvell boards"
>> >     depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
>> >                COMPILE_TEST
>> > -   depends on HAS_IOMEM
>> > +   depends on HAS_IOMEM && HAS_DMA
>>
>> I think this is more a coding issue than a Kconfig issue. AFAIR, none
>> of the ARCH_MVEBU SoCs use DMA in conjunction with the NAND controller.
>> PXA SoCs may use DMA (NFCv1 only) but this is not a hard requirement and
>> the driver is supposed to support PIO mode in all situations.
>>
>> Can you please share your setup, the SoC, the configuration,
>> maybe also the DT?
>
> I don't think Geert is testing on a real board. He's just enabling
> COMPILE_TEST and can then select your driver. Which means you really
> need this depends on HAS_DMA.

Correct.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From miquel.raynal at free-electrons.com  Tue Jan 30 06:05:14 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue, 30 Jan 2018 15:05:14 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
In-Reply-To: <CAMuHMdVZSBdGxRZfYRaNGH5Aygf3avuCu86dMJ0NsxxVp_yifg@mail.gmail.com>
References: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
 <20180130144647.73a44b8d@xps13>
 <20180130145626.7a108c64@bbrezillon>
 <CAMuHMdVZSBdGxRZfYRaNGH5Aygf3avuCu86dMJ0NsxxVp_yifg@mail.gmail.com>
Message-ID: <20180130150514.290bf0e9@xps13>

On Tue, 30 Jan 2018 14:59:37 +0100
Geert Uytterhoeven <geert at linux-m68k.org> wrote:

> On Tue, Jan 30, 2018 at 2:56 PM, Boris Brezillon
> <boris.brezillon at free-electrons.com> wrote:
> > On Tue, 30 Jan 2018 14:46:47 +0100
> > Miquel Raynal <miquel.raynal at free-electrons.com> wrote:  
> >> On Tue, 30 Jan 2018 14:23:21 +0100
> >> Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> >>  
> >> > If NO_DMA=y:
> >> >
> >> >     ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!
> >> >
> >> > Add a dependency on HAS_DMA to fix this.
> >> >
> >> > Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
> >> > Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
> >> > ---
> >> >  drivers/mtd/nand/Kconfig | 2 +-
> >> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >> >
> >> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> >> > index e6b8c59f2c0da7c0..736ac887303c88ba 100644
> >> > --- a/drivers/mtd/nand/Kconfig
> >> > +++ b/drivers/mtd/nand/Kconfig
> >> > @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
> >> >     tristate "NAND controller support on Marvell boards"
> >> >     depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
> >> >                COMPILE_TEST
> >> > -   depends on HAS_IOMEM
> >> > +   depends on HAS_IOMEM && HAS_DMA  
> >>
> >> I think this is more a coding issue than a Kconfig issue. AFAIR, none
> >> of the ARCH_MVEBU SoCs use DMA in conjunction with the NAND controller.
> >> PXA SoCs may use DMA (NFCv1 only) but this is not a hard requirement and
> >> the driver is supposed to support PIO mode in all situations.
> >>
> >> Can you please share your setup, the SoC, the configuration,
> >> maybe also the DT?  
> >
> > I don't think Geert is testing on a real board. He's just enabling
> > COMPILE_TEST and can then select your driver. Which means you really
> > need this depends on HAS_DMA.  
> 
> Correct.

My bad.

Ok then, it looks like this is the right fix.

Thanks Geert for reporting it.
Miqu?l

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
Miquel Raynal, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From miquel.raynal at free-electrons.com  Tue Jan 30 06:50:21 2018
From: miquel.raynal at free-electrons.com (Miquel Raynal)
Date: Tue, 30 Jan 2018 15:50:21 +0100
Subject: [PATCH] mtd: nand: MTD_NAND_MARVELL should depend on HAS_DMA
In-Reply-To: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
References: <1517318601-14793-1-git-send-email-geert@linux-m68k.org>
Message-ID: <20180130155021.69f05023@xps13>

On Tue, 30 Jan 2018 14:23:21 +0100
Geert Uytterhoeven <geert at linux-m68k.org> wrote:

> If NO_DMA=y:
> 
>     ERROR: "bad_dma_ops" [drivers/mtd/nand/marvell_nand.ko] undefined!
> 
> Add a dependency on HAS_DMA to fix this.
> 
> Fixes: 02f26ecf8c772751 ("mtd: nand: add reworked Marvell NAND controller driver")
> Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
> ---
>  drivers/mtd/nand/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index e6b8c59f2c0da7c0..736ac887303c88ba 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
>  	tristate "NAND controller support on Marvell boards"
>  	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
>  		   COMPILE_TEST
> -	depends on HAS_IOMEM
> +	depends on HAS_IOMEM && HAS_DMA
>  	help
>  	  This enables the NAND flash controller driver for Marvell boards,
>  	  including:

Acked-by: Miquel Raynal <miquel.raynal at free-electrons.com>


From yogeshnarayan.gaur at nxp.com  Tue Jan 30 08:49:28 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 22:19:28 +0530
Subject: [PATCH v5 0/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
Message-ID: <1517330970-15197-1-git-send-email-yogeshnarayan.gaur@nxp.com>

fsl-quadspi.c driver creates different LUT entries for various cmds like
read, write, erase, readid etc. These entries are created statically when
driver gets intiliazed.

To support various cmds e.g. different read cmds like SPINOR_OP_READ,
SPINOR_OP_READ_4B, SPINOR_OP_READ_FAST_4B, SPINOR_OP_READ_FAST,
SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_2_2 etc driver needs to
have different LUT entries for different cmds.

FSL QUADSPI controller has 4 chip select and one can use different flashes
on all different chip select.
We analyzed that the flashes have different parameters for the same command
and this is true for NAND devices.
Also reg_protocol information, needed for read register, read any register
commands, read SFDP register, not available at time of spi_nor_scan.
As FSL QUADSPI controller has limitation in number of LUT entries, max 16,
thus require to have dynamic LUT creation support.

Thus to have support for different flash devices, this patch-set adds
support to create LUT entry in run-time based on the exact cmnd requested.
Information like cmnd opcode, protocol info, dummy bit info etc required
for creating LUT entries parsed from instance of passed 'struct spi_nor'.

Also fix initialize sequence of AHB read, move
fsl_qspi_init_ahb_read() in  fsl_qspi_nor_setup() function.

Tested with "S25FS512S" flash and have checked read, write, erase
functionality using mtd_debug utility.
For read have checked hwcaps as SNOR_HWCAPS_READ_FAST,
SNOR_HWCAPS_READ_1_2_2 and SNOR_HWCAPS_READ_1_4_4
i.e. read cmds SPINOR_OP_READ_FAST_4B [0x0c],
SPINOR_OP_READ_1_2_2_4B [0xbc] and SPINOR_OP_READ_1_4_4_4B [0xec]

Yogesh Gaur (2):
  mtd: fsl-quadspi: add support to create dynamic LUT entry
  mtd: fsl-quadspi: fix init AHB read in fsl_qspi_nor_setup()

Changes for v5:
- Fix LUT preparation for SPINOR_OP_READ and SPINOR_OP_READ_4B cmds.

Changes for v4:
- Drop patch
'mtd: fsl-quadspi: update hwcaps read capabilities as READ_1_4_4', it
would be taken care in next-series.
- Added patch for 'fix initialize sequence of AHB read'.

Changes for v3:
- Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
- Update information in cover letter.

Changes for v2:
- Swap patch sequences in the series to solve git bissect issue.

 drivers/mtd/spi-nor/fsl-quadspi.c | 316 +++++++++++++++++++++-----------------
 1 file changed, 171 insertions(+), 145 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 08:49:29 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 22:19:29 +0530
Subject: [PATCH v5 1/2] mtd: fsl-quadspi: add support to create dynamic LUT
 entry
In-Reply-To: <1517330970-15197-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517330970-15197-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517330970-15197-2-git-send-email-yogeshnarayan.gaur@nxp.com>

Add support to create dynamic LUT entry.

Current approach of creating LUT entries for various cmds like read, write,
erase, readid, readsr, we, wd etc is that when QSPI controller gets
initialized at that time static LUT entries for these cmds get created.

Patch add support to create the LUT at run time based on the operation
being performed.

Added API fsl_qspi_prepare_lut(), this API would going to be called from
fsl_qspi_read_reg, fsl_qspi_write_reg, fsl_qspi_write, fsl_qspi_read and
fsl_qspi_erase APIs.
This API would fetch required info like opcode, protocol info, dummy info
for creating LUT from instance of 'struct spi_nor' and then prepare LUT
entry for the required command.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Changes for v5:
- Fix LUT preparation for SPINOR_OP_READ and SPINOR_OP_READ_4B cmds.
Changes for v4:
- Correct version numbering.
Changes for v3:
- Add STOP instruction for prepared LUT and remove memset of 4 LUT reg.
Changes for v2:
- Swap patch sequences in the series to solve git bissect issue.

 drivers/mtd/spi-nor/fsl-quadspi.c | 310 +++++++++++++++++++++-----------------
 1 file changed, 168 insertions(+), 142 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 89306cf..84c341b 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -183,7 +183,7 @@
 
 /* Macros for constructing the LUT register. */
 #define LUT0(ins, pad, opr)						\
-		(((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
+		(((opr) << OPRND0_SHIFT) | ((pad) << PAD0_SHIFT) | \
 		((LUT_##ins) << INSTR0_SHIFT))
 
 #define LUT1(ins, pad, opr)	(LUT0(ins, pad, opr) << OPRND1_SHIFT)
@@ -193,21 +193,21 @@
 #define QUADSPI_LUT_NUM		64
 
 /* SEQID -- we can have 16 seqids at most. */
-#define SEQID_READ		0
-#define SEQID_WREN		1
-#define SEQID_WRDI		2
-#define SEQID_RDSR		3
-#define SEQID_SE		4
-#define SEQID_CHIP_ERASE	5
-#define SEQID_PP		6
-#define SEQID_RDID		7
-#define SEQID_WRSR		8
-#define SEQID_RDCR		9
-#define SEQID_EN4B		10
-#define SEQID_BRWR		11
+/* LUT0 programmed by bootloader, for run-time create entry for LUT seqid 1 */
+#define SEQID_LUT0_BOOTLOADER	0
+#define SEQID_LUT1_RUNTIME	1
 
 #define QUADSPI_MIN_IOMAP SZ_4M
 
+enum fsl_qspi_ops {
+	FSL_QSPI_OPS_READ = 0,
+	FSL_QSPI_OPS_WRITE,
+	FSL_QSPI_OPS_ERASE,
+	FSL_QSPI_OPS_READ_REG,
+	FSL_QSPI_OPS_WRITE_REG,
+	FSL_QSPI_OPS_WRITE_BUF_REG,
+};
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -368,136 +368,158 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void fsl_qspi_init_lut(struct fsl_qspi *q)
+static inline s8 pad_count(s8 pad_val)
 {
+	s8 count = -1;
+
+	if (!pad_val)
+		return 0;
+
+	while (pad_val) {
+		pad_val >>= 1;
+		count++;
+	}
+	return count;
+}
+
+/*
+ * Prepare LUT entry for the input cmd.
+ * Protocol info is present in instance of struct spi_nor, using which fields
+ * like cmd, data, addrlen along with pad info etc can be parsed.
+ */
+static void fsl_qspi_prepare_lut(struct spi_nor *nor,
+				 enum fsl_qspi_ops ops, u8 cmd)
+{
+	struct fsl_qspi *q = nor->priv;
 	void __iomem *base = q->iobase;
 	int rxfifo = q->devtype_data->rxfifo;
+	int txfifo = q->devtype_data->txfifo;
 	u32 lut_base;
-	int i;
+	u8 cmd_pad, addr_pad, data_pad, dummy_pad;
+	enum spi_nor_protocol protocol = 0;
+	u8 addrlen = 0;
+	u8 read_dm, opcode;
+	int stop_lut;
+
+	read_dm = opcode = cmd_pad = addr_pad = data_pad = dummy_pad = 0;
+
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+	case FSL_QSPI_OPS_WRITE_REG:
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		opcode = cmd;
+		protocol = nor->reg_proto;
+		break;
+	case FSL_QSPI_OPS_READ:
+		opcode = cmd;
+		read_dm = nor->read_dummy;
+		protocol = nor->read_proto;
+		break;
+	case FSL_QSPI_OPS_WRITE:
+		opcode = cmd;
+		protocol = nor->write_proto;
+		break;
+	case FSL_QSPI_OPS_ERASE:
+		opcode = cmd;
+		break;
+	default:
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
+		return;
+	}
+
+	if (protocol) {
+		cmd_pad = spi_nor_get_protocol_inst_nbits(protocol);
+		addr_pad = spi_nor_get_protocol_addr_nbits(protocol);
+		data_pad = spi_nor_get_protocol_data_nbits(protocol);
+	}
 
-	struct spi_nor *nor = &q->nor[0];
-	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
-	u8 read_op = nor->read_opcode;
-	u8 read_dm = nor->read_dummy;
+	dummy_pad = data_pad;
+
+	dev_dbg(q->dev, "ops:%x opcode:%x pad[cmd:%d, addr:%d, data:%d]\n",
+			ops, opcode, cmd_pad, addr_pad, data_pad);
 
 	fsl_qspi_unlock_lut(q);
 
-	/* Clear all the LUT table */
-	for (i = 0; i < QUADSPI_LUT_NUM; i++)
-		qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
-
-	/* Read */
-	lut_base = SEQID_READ * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
-		    LUT1(FSL_READ, PAD4, rxfifo),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Write enable */
-	lut_base = SEQID_WREN * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Page Program */
-	lut_base = SEQID_PP * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-	qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
-			base + QUADSPI_LUT(lut_base + 1));
-
-	/* Read Status */
-	lut_base = SEQID_RDSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase a sector */
-	lut_base = SEQID_SE * 4;
-
-	qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
-		    LUT1(ADDR, PAD1, addrlen),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Erase the whole chip */
-	lut_base = SEQID_CHIP_ERASE * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-			base + QUADSPI_LUT(lut_base));
-
-	/* READ ID */
-	lut_base = SEQID_RDID * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
-			LUT1(FSL_READ, PAD1, 0x8),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write Register */
-	lut_base = SEQID_WRSR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
-			LUT1(FSL_WRITE, PAD1, 0x2),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Read Configuration Register */
-	lut_base = SEQID_RDCR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
-			LUT1(FSL_READ, PAD1, 0x1),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Write disable */
-	lut_base = SEQID_WRDI * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Micron) */
-	lut_base = SEQID_EN4B * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
-			base + QUADSPI_LUT(lut_base));
-
-	/* Enter 4 Byte Mode (Spansion) */
-	lut_base = SEQID_BRWR * 4;
-	qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
-			base + QUADSPI_LUT(lut_base));
+	/* Dynamic LUT */
+	lut_base = SEQID_LUT1_RUNTIME * 4;
 
-	fsl_qspi_lock_lut(q);
-}
+	/* default, STOP instruction to be programmed in (lut_base + 1) reg */
+	stop_lut = 1;
+	switch (ops) {
+	case FSL_QSPI_OPS_READ_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_READ, pad_count(data_pad), rxfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_WRITE_BUF_REG:
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+			  LUT1(FSL_WRITE, pad_count(data_pad), txfifo),
+			  base + QUADSPI_LUT(lut_base));
+		break;
+	case FSL_QSPI_OPS_READ:
+	case FSL_QSPI_OPS_WRITE:
+	case FSL_QSPI_OPS_ERASE:
+		/* Common for Read, Write and Erase ops. */
 
-/* Get the SEQID for the command */
-static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-{
-	switch (cmd) {
-	case SPINOR_OP_READ_1_1_4:
-		return SEQID_READ;
-	case SPINOR_OP_WREN:
-		return SEQID_WREN;
-	case SPINOR_OP_WRDI:
-		return SEQID_WRDI;
-	case SPINOR_OP_RDSR:
-		return SEQID_RDSR;
-	case SPINOR_OP_SE:
-		return SEQID_SE;
-	case SPINOR_OP_CHIP_ERASE:
-		return SEQID_CHIP_ERASE;
-	case SPINOR_OP_PP:
-		return SEQID_PP;
-	case SPINOR_OP_RDID:
-		return SEQID_RDID;
-	case SPINOR_OP_WRSR:
-		return SEQID_WRSR;
-	case SPINOR_OP_RDCR:
-		return SEQID_RDCR;
-	case SPINOR_OP_EN4B:
-		return SEQID_EN4B;
-	case SPINOR_OP_BRWR:
-		return SEQID_BRWR;
+		addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
+
+		qspi_writel(q, LUT0(CMD, pad_count(cmd_pad), opcode) |
+				LUT1(ADDR, pad_count(addr_pad), addrlen),
+				base + QUADSPI_LUT(lut_base));
+		/*
+		 * For Erase ops - Data and Dummy not required.
+		 * For Write ops - Dummy not required.
+		 */
+
+		if (ops == FSL_QSPI_OPS_READ) {
+
+			/*
+			 * For cmds SPINOR_OP_READ and SPINOR_OP_READ_4B value
+			 * of dummy cycles are 0.
+			 */
+			if (read_dm)
+				qspi_writel(q,
+					    LUT0(DUMMY, pad_count(dummy_pad),
+					    read_dm) |
+					    LUT1(FSL_READ, pad_count(data_pad),
+					    rxfifo),
+					    base + QUADSPI_LUT(lut_base + 1));
+			else
+				qspi_writel(q,
+					    LUT0(FSL_READ, pad_count(data_pad),
+					    rxfifo),
+					    base + QUADSPI_LUT(lut_base + 1));
+
+			stop_lut = 2;
+
+			/* TODO Add condition to check if READ is IP/AHB. */
+
+			/* For AHB read, add seqid in BFGENCR register. */
+			qspi_writel(q,
+				    SEQID_LUT1_RUNTIME <<
+				    QUADSPI_BFGENCR_SEQID_SHIFT,
+				    q->iobase + QUADSPI_BFGENCR);
+		}
+
+		if (ops == FSL_QSPI_OPS_WRITE) {
+			qspi_writel(q, LUT0(FSL_WRITE, pad_count(data_pad), 0),
+					base + QUADSPI_LUT(lut_base + 1));
+			stop_lut = 2;
+		}
+		break;
 	default:
-		if (cmd == q->nor[0].erase_opcode)
-			return SEQID_SE;
-		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
+		dev_err(q->dev, "Unsupported operation 0x%.2x\n", ops);
 		break;
 	}
-	return -EINVAL;
+
+	/* prepare LUT for STOP instruction. */
+	qspi_writel(q, 0, base +  QUADSPI_LUT(lut_base + stop_lut));
+
+	fsl_qspi_lock_lut(q);
 }
 
 static int
@@ -532,7 +554,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	} while (1);
 
 	/* trigger the LUT now */
-	seqid = fsl_qspi_get_seqid(q, cmd);
+	seqid = SEQID_LUT1_RUNTIME;
 	qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
 			base + QUADSPI_IPCR);
 
@@ -684,8 +706,8 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	/* Set the default lut sequence for AHB Read. */
-	seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+	/* Set dynamic LUT entry as lut sequence for AHB Read . */
+	seqid = SEQID_LUT1_RUNTIME;
 	qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
 		q->iobase + QUADSPI_BFGENCR);
 }
@@ -728,7 +750,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	void __iomem *base = q->iobase;
 	u32 reg;
 	int ret;
-
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	fsl_qspi_clk_disable_unprep(q);
 
@@ -746,9 +767,6 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 		base + QUADSPI_MCR);
 	udelay(1);
 
-	/* Init the LUT table. */
-	fsl_qspi_init_lut(q);
-
 	/* Disable the module */
 	qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
 			base + QUADSPI_MCR);
@@ -791,9 +809,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init the LUT table again. */
-	fsl_qspi_init_lut(q);
-
 	/* Init for AHB read */
 	fsl_qspi_init_ahb_read(q);
 
@@ -820,6 +835,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 	struct fsl_qspi *q = nor->priv;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ_REG, opcode);
 	ret = fsl_qspi_runcmd(q, opcode, 0, len);
 	if (ret)
 		return ret;
@@ -834,6 +850,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 	int ret;
 
 	if (!buf) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF as NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_REG, opcode);
 		ret = fsl_qspi_runcmd(q, opcode, 0, 1);
 		if (ret)
 			return ret;
@@ -842,6 +860,8 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
 			fsl_qspi_invalid(q);
 
 	} else if (len > 0) {
+		/* Prepare LUT for WRITE_REG cmd with input BUF non-NULL. */
+		fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE_BUF_REG, opcode);
 		ret = fsl_qspi_nor_write(q, nor, opcode, 0,
 					(u32 *)buf, len);
 		if (ret > 0)
@@ -858,8 +878,11 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
 			      size_t len, const u_char *buf)
 {
 	struct fsl_qspi *q = nor->priv;
-	ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-					 (u32 *)buf, len);
+	ssize_t ret;
+
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_WRITE, nor->program_opcode);
+	ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
+				 (u32 *)buf, len);
 
 	/* invalid the data in the AHB buffer. */
 	fsl_qspi_invalid(q);
@@ -872,6 +895,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_READ, nor->read_opcode);
+
 	/* if necessary,ioremap buffer before AHB read, */
 	if (!q->ahb_addr) {
 		q->memmap_offs = q->chip_base_addr + from;
@@ -920,6 +945,7 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
 	dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
 		nor->mtd.erasesize / 1024, q->chip_base_addr, (u32)offs);
 
+	fsl_qspi_prepare_lut(nor, FSL_QSPI_OPS_ERASE, nor->erase_opcode);
 	ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
 	if (ret)
 		return ret;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 08:49:30 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 22:19:30 +0530
Subject: [PATCH v5 2/2] mtd: fsl-quadspi: fix init AHB read in
 fsl_qspi_nor_setup()
In-Reply-To: <1517330970-15197-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517330970-15197-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517330970-15197-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Move AHB read initialize in fsl_qspi_nor_setup().

In file spi-nor.c, func spi_nor_scan() calls nor->read() thru
spi_nor_read_sfdp() API.

Presently, fsl_qspi_init_ahb_read() called from fsl_qspi_nor_setup_last().
Func fsl_qspi_probe() calls spi_nor_scan() first and then calls
fsl_qspi_nor_setup_last().

When nor->read() being called from inside spi_nor_read_sfdp(), QSPI cntlr
AHB mode initialization is not yet done results in data read error.

Initialize AHB read inside fsl_qspi_nor_setup().

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Changes for v5:
- None
Changes for v4:
- None
Changes for v3:
- None
Changes for v2:
- None

 drivers/mtd/spi-nor/fsl-quadspi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 84c341b..2b3b3eb 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -787,6 +787,9 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	/* enable the interrupt */
 	qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
 
+	/* Init for AHB read */
+	fsl_qspi_init_ahb_read(q);
+
 	return 0;
 }
 
@@ -809,9 +812,6 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
-	/* Init for AHB read */
-	fsl_qspi_init_ahb_read(q);
-
 	return 0;
 }
 
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:19:58 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 22:49:58 +0530
Subject: [PATCH v2] mtd: fsl-quadspi: add support for ls2080a/ls1080a
Message-ID: <1517332798-16644-1-git-send-email-yogeshnarayan.gaur@nxp.com>

LS2080a/LS1088a supports Freescale Quad SPI controller.
Add fsl-quadspi driver support for ls2080a and ls1088a chip.

Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=26084

Changes for v2:
- Remove void * cast of_device_id structure for ls2080a_data.
- Generate patch from spi-nor/next branch.

 drivers/mtd/spi-nor/fsl-quadspi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 035dacd..b9c5918 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -214,6 +214,7 @@ enum fsl_qspi_devtype {
 	FSL_QUADSPI_IMX7D,
 	FSL_QUADSPI_IMX6UL,
 	FSL_QUADSPI_LS1021A,
+	FSL_QUADSPI_LS2080A,
 };
 
 struct fsl_qspi_devtype_data {
@@ -267,6 +268,15 @@ struct fsl_qspi_devtype_data {
 	.driver_data = 0,
 };
 
+static const struct fsl_qspi_devtype_data ls2080a_data = {
+	.devtype = FSL_QUADSPI_LS2080A,
+	.rxfifo = 128,
+	.txfifo = 64,
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_TKT253890,
+};
+
+
 #define FSL_QSPI_MAX_CHIP	4
 struct fsl_qspi {
 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
@@ -821,6 +831,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	{ .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, },
 	{ .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, },
 	{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
+	{ .compatible = "fsl,ls2080a-qspi", .data = &ls2080a_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:31:06 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:01:06 +0530
Subject: [PATCH 0/2] mtd: fsl-quadspi: Update slave device hwcap based on mode
 provided in dtsi file
Message-ID: <1517333468-17153-1-git-send-email-yogeshnarayan.gaur@nxp.com>

This patch-set added support to update hwcap of slave device connected to
FSL QUADSPI controller by reading values from the device tree files.

Mode information is available via "spi-tx-bus-width" and
"spi-rx-bus-width" nodes of device tree for the connected slave device.

Update read and write hwcap capability for slave device by reading
"spi-rx-bus-width" and "spi-tx-bus-width" respectively.

Added usage example by adding support for spi-rx-bus-width
and spi-tx-bus-width binding.

Yogesh Gaur (2):
  mtd: fsl-quadspi: Update slave device hwcap based on mode provided in
    dtsi file
  dt-bindings: fsl-quadspi: spi-rx/tx-bus-width usage example

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 30 ++++++++++++
 drivers/mtd/spi-nor/fsl-quadspi.c                  | 56 ++++++++++++++++++++--
 2 files changed, 81 insertions(+), 5 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:31:07 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:01:07 +0530
Subject: [PATCH 1/2] mtd: fsl-quadspi: Update slave device hwcap based on mode
 provided in dtsi file
In-Reply-To: <1517333468-17153-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517333468-17153-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517333468-17153-2-git-send-email-yogeshnarayan.gaur@nxp.com>

FSL QuadSPI controller supports Single, dual, quad modes of operation.
Mode information is available via "spi-tx-bus-width" and
"spi-rx-bus-width" nodes of device tree for the connected slave device.

Update read and write hwcap capability for slave device by reading
"spi-rx-bus-width" and "spi-tx-bus-width" respectively.
Assign hwcaps mask to minimal caps for the slave node i.e.
	SNOR_HWCAPS_READ | SNOR_HWCAPS_PP

If value not provided in device tree file, then fallback to default
mode i.e. SNOR_HWCAPS_READ_1_1_4 and SNOR_HWCAPS_PP.

Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 56 +++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index b9c5918..1503e0c 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -994,17 +994,14 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
-	const struct spi_nor_hwcaps hwcaps = {
-		.mask = SNOR_HWCAPS_READ_1_1_4 |
-			SNOR_HWCAPS_PP,
-	};
+	struct spi_nor_hwcaps hwcaps;
 	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	struct fsl_qspi *q;
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, value;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1077,6 +1074,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 	/* iterate the subnodes. */
 	for_each_available_child_of_node(dev->of_node, np) {
+		/* Reset hwcaps mask to minimal caps for the slave node. */
+		hwcaps.mask = SNOR_HWCAPS_READ | SNOR_HWCAPS_PP;
+		value = 0;
+
 		/* skip the holes */
 		if (!q->has_second_chip)
 			i *= 2;
@@ -1106,6 +1107,51 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		/* set the chip address for READID */
 		fsl_qspi_set_base_addr(q, nor);
 
+		/*
+		 * If spi-rx-bus-width and spi-tx-bus-width not defined assign
+		 * default hardware capabilities SNOR_HWCAPS_READ_1_1_4 and
+		 * SNOR_HWCAPS_PP supported by the Quad-SPI controller.
+		 */
+		if (!of_property_read_u32(np, "spi-rx-bus-width", &value)) {
+			switch (value) {
+			case 1:
+				hwcaps.mask |= SNOR_HWCAPS_READ |
+					       SNOR_HWCAPS_READ_FAST;
+				break;
+			case 2:
+				hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2 |
+					       SNOR_HWCAPS_READ_1_2_2;
+				break;
+			case 4:
+				hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4 |
+					       SNOR_HWCAPS_READ_1_4_4;
+				break;
+			default:
+				dev_err(dev,
+					"spi-rx-bus-width %d not supported\n",
+					value);
+				break;
+			}
+		} else
+			hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
+
+		if (!of_property_read_u32(np, "spi-tx-bus-width", &value)) {
+			switch (value) {
+			case 1:
+				hwcaps.mask |= SNOR_HWCAPS_PP;
+				break;
+			case 4:
+				hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4 |
+					       SNOR_HWCAPS_PP_1_4_4;
+				break;
+			default:
+				dev_err(dev,
+					"spi-tx-bus-width %d not supported\n",
+					value);
+				break;
+			}
+		}
+
 		ret = spi_nor_scan(nor, NULL, &hwcaps);
 		if (ret)
 			goto mutex_failed;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:31:08 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:01:08 +0530
Subject: [PATCH 2/2] dt-bindings: fsl-quadspi: spi-rx/tx-bus-width usage
 example
In-Reply-To: <1517333468-17153-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517333468-17153-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517333468-17153-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Added usage example by adding support for spi-rx-bus-width
and spi-tx-bus-width binding.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..811da0e 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,33 @@ qspi0: quadspi at 40044000 {
 		....
 	};
 };
+
+qspi1: quadspi at 20c0000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x0 0x20c0000 0x0 0x10000>,
+		<0x0 0x20000000 0x0 0x10000000>;
+	reg-names = "QuadSPI", "QuadSPI-memory";
+	interrupts = <0 25 0x4>; /* Level high type */
+	clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+	clock-names = "qspi_en", "qspi";
+	status = "okay";
+
+	qflash0: s25fs512s at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+	qflash1: s25fs512s at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <1>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+};
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:33:55 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:03:55 +0530
Subject: [PATCH 0/2] mtd: fsl-quadspi: Update slave device hwcap based on mode
 provided in dtsi file
Message-ID: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>

This patch-set added support to update hwcap of slave device connected to
FSL QUADSPI controller by reading values from the device tree files.

Mode information is available via "spi-tx-bus-width" and
"spi-rx-bus-width" nodes of device tree for the connected slave device.

Update read and write hwcap capability for slave device by reading
"spi-rx-bus-width" and "spi-tx-bus-width" respectively.

Added usage example by adding support for spi-rx-bus-width
and spi-tx-bus-width binding.

Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=26084

Yogesh Gaur (2):
  mtd: fsl-quadspi: Update slave device hwcap based on mode provided in
    dtsi file
  dt-bindings: fsl-quadspi: spi-rx/tx-bus-width usage example

 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 30 ++++++++++++
 drivers/mtd/spi-nor/fsl-quadspi.c                  | 56 ++++++++++++++++++++--
 2 files changed, 81 insertions(+), 5 deletions(-)

-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:33:56 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:03:56 +0530
Subject: [PATCH 1/2] mtd: fsl-quadspi: Update slave device hwcap based on mode
 provided in dtsi file
In-Reply-To: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517333637-17331-2-git-send-email-yogeshnarayan.gaur@nxp.com>

FSL QuadSPI controller supports Single, dual, quad modes of operation.
Mode information is available via "spi-tx-bus-width" and
"spi-rx-bus-width" nodes of device tree for the connected slave device.

Update read and write hwcap capability for slave device by reading
"spi-rx-bus-width" and "spi-tx-bus-width" respectively.
Assign hwcaps mask to minimal caps for the slave node i.e.
	SNOR_HWCAPS_READ | SNOR_HWCAPS_PP

If value not provided in device tree file, then fallback to default
mode i.e. SNOR_HWCAPS_READ_1_1_4 and SNOR_HWCAPS_PP.

Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=26084

 drivers/mtd/spi-nor/fsl-quadspi.c | 56 +++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index b9c5918..1503e0c 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -994,17 +994,14 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
-	const struct spi_nor_hwcaps hwcaps = {
-		.mask = SNOR_HWCAPS_READ_1_1_4 |
-			SNOR_HWCAPS_PP,
-	};
+	struct spi_nor_hwcaps hwcaps;
 	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	struct fsl_qspi *q;
 	struct resource *res;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
-	int ret, i = 0;
+	int ret, i = 0, value;
 
 	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
 	if (!q)
@@ -1077,6 +1074,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 	/* iterate the subnodes. */
 	for_each_available_child_of_node(dev->of_node, np) {
+		/* Reset hwcaps mask to minimal caps for the slave node. */
+		hwcaps.mask = SNOR_HWCAPS_READ | SNOR_HWCAPS_PP;
+		value = 0;
+
 		/* skip the holes */
 		if (!q->has_second_chip)
 			i *= 2;
@@ -1106,6 +1107,51 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		/* set the chip address for READID */
 		fsl_qspi_set_base_addr(q, nor);
 
+		/*
+		 * If spi-rx-bus-width and spi-tx-bus-width not defined assign
+		 * default hardware capabilities SNOR_HWCAPS_READ_1_1_4 and
+		 * SNOR_HWCAPS_PP supported by the Quad-SPI controller.
+		 */
+		if (!of_property_read_u32(np, "spi-rx-bus-width", &value)) {
+			switch (value) {
+			case 1:
+				hwcaps.mask |= SNOR_HWCAPS_READ |
+					       SNOR_HWCAPS_READ_FAST;
+				break;
+			case 2:
+				hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2 |
+					       SNOR_HWCAPS_READ_1_2_2;
+				break;
+			case 4:
+				hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4 |
+					       SNOR_HWCAPS_READ_1_4_4;
+				break;
+			default:
+				dev_err(dev,
+					"spi-rx-bus-width %d not supported\n",
+					value);
+				break;
+			}
+		} else
+			hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
+
+		if (!of_property_read_u32(np, "spi-tx-bus-width", &value)) {
+			switch (value) {
+			case 1:
+				hwcaps.mask |= SNOR_HWCAPS_PP;
+				break;
+			case 4:
+				hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4 |
+					       SNOR_HWCAPS_PP_1_4_4;
+				break;
+			default:
+				dev_err(dev,
+					"spi-tx-bus-width %d not supported\n",
+					value);
+				break;
+			}
+		}
+
 		ret = spi_nor_scan(nor, NULL, &hwcaps);
 		if (ret)
 			goto mutex_failed;
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:33:57 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:03:57 +0530
Subject: [PATCH 2/2] dt-bindings: fsl-quadspi: spi-rx/tx-bus-width usage
 example
In-Reply-To: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <1517333637-17331-3-git-send-email-yogeshnarayan.gaur@nxp.com>

Added usage example by adding support for spi-rx-bus-width
and spi-tx-bus-width binding.

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
 .../devicetree/bindings/mtd/fsl-quadspi.txt        | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..811da0e 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,33 @@ qspi0: quadspi at 40044000 {
 		....
 	};
 };
+
+qspi1: quadspi at 20c0000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x0 0x20c0000 0x0 0x10000>,
+		<0x0 0x20000000 0x0 0x10000000>;
+	reg-names = "QuadSPI", "QuadSPI-memory";
+	interrupts = <0 25 0x4>; /* Level high type */
+	clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+	clock-names = "qspi_en", "qspi";
+	status = "okay";
+
+	qflash0: s25fs512s at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+	qflash1: s25fs512s at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <1>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+};
-- 
1.9.1



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 09:44:22 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Tue, 30 Jan 2018 23:14:22 +0530
Subject: [PATCH v2] arm64: dts: ls1088a: Add qspi device node for ls1088a-rdb
Message-ID: <1517334262-17969-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Add nodes and properties for QSPI controller.
Add support for spansion flash, s25fs512s, as slave device for
QSPI controller.

Added entry of "fsl,ls1088a-qspi" in fsl-quadspi.txt binding file.

Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=26084

Changes for v2:
- Move property spi-rx-bus-width and spi-tx-bus-width from controller
  to connected slave device node.

 .../devicetree/bindings/mtd/fsl-quadspi.txt        |  1 +
 arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts  | 23 ++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi     | 12 +++++++++++
 3 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 811da0e..956c23c 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -7,6 +7,7 @@ Required properties:
 		 or
 		 "fsl,ls2080a-qspi" followed by "fsl,ls1021a-qspi",
 		 "fsl,ls1043a-qspi" followed by "fsl,ls1021a-qspi"
+		 "fsl,ls2080a-qspi" followed by "fsl,ls1088a-qspi",
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
   - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
index 0f6fcda..8afe536 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
@@ -94,6 +94,29 @@
 	};
 };
 
+&qspi {
+	status = "okay";
+	fsl,qspi-has-second-chip;
+	qflash0: s25fs512s at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+	qflash1: s25fs512s at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <1>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+};
+
 &ifc {
 	ranges = <0 0 0x5 0x30000000 0x00010000
 		  2 0 0x5 0x20000000 0x00010000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index bd80e9a..b45a522 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -394,6 +394,18 @@
 			status = "disabled";
 		};
 
+		qspi: quadspi at 20c0000 {
+			compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0 0x20c0000 0x0 0x10000>,
+				<0x0 0x20000000 0x0 0x10000000>;
+			reg-names = "QuadSPI", "QuadSPI-memory";
+			interrupts = <0 25 0x4>; /* Level high type */
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "qspi_en", "qspi";
+		};
+
 		sata: sata at 3200000 {
 			compatible = "fsl,ls1088a-ahci";
 			reg = <0x0 0x3200000 0x0 0x10000>,
-- 
1.9.1



From robh at kernel.org  Tue Jan 30 10:53:33 2018
From: robh at kernel.org (Rob Herring)
Date: Tue, 30 Jan 2018 12:53:33 -0600
Subject: [PATCH 2/2] dt-bindings: fsl-quadspi: spi-rx/tx-bus-width usage
 example
In-Reply-To: <1517333637-17331-3-git-send-email-yogeshnarayan.gaur@nxp.com>
References: <1517333637-17331-1-git-send-email-yogeshnarayan.gaur@nxp.com>
 <1517333637-17331-3-git-send-email-yogeshnarayan.gaur@nxp.com>
Message-ID: <CAL_JsqLBUDNEWkcrNcrOmuYcR=Gbf2ALD=z4s9AP4poOcBxNRQ@mail.gmail.com>

On Tue, Jan 30, 2018 at 11:33 AM, Yogesh Gaur
<yogeshnarayan.gaur at nxp.com> wrote:
> Added usage example by adding support for spi-rx-bus-width
> and spi-tx-bus-width binding.

Why not just add to existing example? Is there something unclear about
adding these properties to warrant an example? We don't need every
possible option enumerated.

Rob


From zajec5 at gmail.com  Tue Jan 30 12:10:55 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 30 Jan 2018 21:10:55 +0100
Subject: [PATCH V9 0/4] mtd: read partitions compatible prop for "ofpart" type
Message-ID: <20180130201059.4424-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This patchset provides a proper support for flash device DT node with
"partitions" subnode using "compatible" property. It's already
documented in the: Documentation/devicetree/bindings/mtd/partition.txt

We believed a previous version 8 was ready to go, but soon after landing
in the linux-next we got a regression report from Peter.

This version takes a safe path by:
1) Respecting parsers order as specified in the default/driver-provided
   list.
2) Looking at "compatible" property only when "ofpart" type gets
   speciied.

I double-checked the code and cannot think of any regression this could
cause. I also hope this design (roughly discussed with Boris) can be
acceptable for the mtd subsystem.

This is of course 4.17 material at best.

Brian Norris (1):
  mtd: partitions: add of_match_table parser matching

Rafa? Mi?ecki (3):
  mtd: partitions: add special treating for the "ofpart" parser type
  mtd: rename "ofpart" parser to "fixed-partitions" as it fits it better
  mtd: ofpart: add of_match_table with "fixed-partitions"

 drivers/mtd/mtdpart.c          | 116 +++++++++++++++++++++++++++++++++++++----
 drivers/mtd/ofpart.c           |  18 +++++--
 include/linux/mtd/partitions.h |   1 +
 3 files changed, 121 insertions(+), 14 deletions(-)

-- 
2.11.0



From zajec5 at gmail.com  Tue Jan 30 12:10:59 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 30 Jan 2018 21:10:59 +0100
Subject: [PATCH V9 4/4] mtd: ofpart: add of_match_table with "fixed-partitions"
In-Reply-To: <20180130201059.4424-1-zajec5@gmail.com>
References: <20180130201059.4424-1-zajec5@gmail.com>
Message-ID: <20180130201059.4424-5-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).

This matches existing bindings documentation.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/ofpart.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 9f497315e65d..615f8c173162 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_fixed_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
 	.parse_fn = parse_fixed_partitions,
 	.name = "fixed-partitions",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
-- 
2.11.0



From zajec5 at gmail.com  Tue Jan 30 12:10:56 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 30 Jan 2018 21:10:56 +0100
Subject: [PATCH V9 1/4] mtd: partitions: add special treating for the "ofpart"
 parser type
In-Reply-To: <20180130201059.4424-1-zajec5@gmail.com>
References: <20180130201059.4424-1-zajec5@gmail.com>
Message-ID: <20180130201059.4424-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

In order to properly support compatibility strings as described in the
bindings/mtd/partition.txt "ofpart" type should be treated as an
indication for looking into OF. MTD should check "compatible" property
and search for a matching parser rather than blindly trying a one for
the "fixed-partitions".

This also means that existing parser should get renamed into a more
meaningful one.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V9: First appearance of this commit
---
 drivers/mtd/mtdpart.c | 61 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 76cd21d1171b..d40ec525ceff 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -860,6 +860,38 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 	return ret;
 }
 
+static int mtd_part_of_parse(struct mtd_info *master,
+			     struct mtd_partitions *pparts)
+{
+	struct mtd_part_parser *parser;
+	const char *fixed = "ofpart";
+	int ret, err = 0;
+
+	/*
+	 * TODO: Check "compatible" DT property and look for a matching parser.
+	 */
+
+	/*
+	 * For backward compatibility we have to try the "ofpart"
+	 * parser. It supports old DT format with partitions specified as a
+	 * direct subnodes of a flash device DT node without any compatibility
+	 * specified we could match.
+	 */
+	parser = mtd_part_parser_get(fixed);
+	if (!parser && !request_module("%s", fixed))
+		parser = mtd_part_parser_get(fixed);
+	if (parser) {
+		ret = mtd_part_do_parse(parser, master, pparts, NULL);
+		if (ret > 0)
+			return ret;
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+
+	return err;
+}
+
 /**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
@@ -892,19 +924,30 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 		types = default_mtd_part_types;
 
 	for ( ; *types; types++) {
-		pr_debug("%s: parsing partitions %s\n", master->name, *types);
-		parser = mtd_part_parser_get(*types);
-		if (!parser && !request_module("%s", *types))
+		/*
+		 * ofpart is a special type that means OF partitioning info
+		 * should be used. It requires a bit different logic so it is
+		 * handled in a separated function.
+		 */
+		if (!strcmp(*types, "ofpart")) {
+			ret = mtd_part_of_parse(master, pparts);
+		} else {
+			pr_debug("%s: parsing partitions %s\n", master->name,
+				 *types);
 			parser = mtd_part_parser_get(*types);
-		pr_debug("%s: got parser %s\n", master->name,
-			 parser ? parser->name : NULL);
-		if (!parser)
-			continue;
-		ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (!parser && !request_module("%s", *types))
+				parser = mtd_part_parser_get(*types);
+			pr_debug("%s: got parser %s\n", master->name,
+				parser ? parser->name : NULL);
+			if (!parser)
+				continue;
+			ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (ret <= 0)
+				mtd_part_parser_put(parser);
+		}
 		/* Found partitions! */
 		if (ret > 0)
 			return 0;
-		mtd_part_parser_put(parser);
 		/*
 		 * Stash the first error we see; only report it if no parser
 		 * succeeds
-- 
2.11.0



From zajec5 at gmail.com  Tue Jan 30 12:10:58 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 30 Jan 2018 21:10:58 +0100
Subject: [PATCH V9 3/4] mtd: partitions: add of_match_table parser matching
In-Reply-To: <20180130201059.4424-1-zajec5@gmail.com>
References: <20180130201059.4424-1-zajec5@gmail.com>
Message-ID: <20180130201059.4424-4-zajec5@gmail.com>

From: Brian Norris <computersforpeace at gmail.com>

Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.

It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
Please note that driver-specified parsers still take a precedence. It's
assumed that driver providing a parser type has a good reason for that
(e.g. having platform data with device-specific info). Also doing
otherwise could break existing setups. The same applies to using default
parsers (including "cmdlinepart") as some overwrite DT data with cmdline
argument.

This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching

V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
    Merge helpers into a single of_mtd_match_mtd_parser
V3: Add a simple comment to note we will need the best match in the future
V4: Rework new functions to pick parser with the best match
    Move new code in parse_mtd_partitions up so it has precedence over flash
    driver defaults and MTD defaults
V5: Rework matching code to start checking with the most specific string in the
    "compatibility" property.
V6: Initialize "ret" variable in mtd_part_get_parser_by_cp to NULL
V7: Rename function "mtd_part_get_parser_by_cp" to use "_compatible_"
    Rename "cp" variable to "compat"
    Drop unneeded if (np) check from the parse_mtd_partitions
V8: Move new OF code in parse_mtd_partitions() lower so driver-specified parsers
    take a precedence. Update commit message to make that clear.
V9: Update to modify mtd_part_of_parse() instead of parse_mtd_partitions()
---
 drivers/mtd/mtdpart.c          | 61 +++++++++++++++++++++++++++++++++++++++---
 include/linux/mtd/partitions.h |  1 +
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index a29bbcf79691..cdb1f496ab95 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -860,16 +861,70 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 	return ret;
 }
 
+/**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+	struct mtd_part_parser *p, *ret = NULL;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->compatible[0]; matches++) {
+			if (!strcmp(matches->compatible, compat) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
 static int mtd_part_of_parse(struct mtd_info *master,
 			     struct mtd_partitions *pparts)
 {
 	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *compat;
 	const char *fixed = "fixed-partitions";
 	int ret, err = 0;
 
-	/*
-	 * TODO: Check "compatible" DT property and look for a matching parser.
-	 */
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	of_property_for_each_string(np, "compatible", prop, compat) {
+		parser = mtd_part_get_compatible_parser(compat);
+		if (!parser)
+			continue;
+		ret = mtd_part_do_parse(parser, master, pparts, NULL);
+		if (ret > 0) {
+			of_node_put(np);
+			return ret;
+		}
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+	of_node_put(np);
 
 	/*
 	 * For backward compatibility we have to try the "fixed-partitions"
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70dacbd..11cb0c50cd84 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
-- 
2.11.0



From zajec5 at gmail.com  Tue Jan 30 12:10:57 2018
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 30 Jan 2018 21:10:57 +0100
Subject: [PATCH V9 2/4] mtd: rename "ofpart" parser to "fixed-partitions" as
 it fits it better
In-Reply-To: <20180130201059.4424-1-zajec5@gmail.com>
References: <20180130201059.4424-1-zajec5@gmail.com>
Message-ID: <20180130201059.4424-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Type "ofpart" means that OF should be used to get partitioning info and
this driver supports "fixed-partitions" binding only. Renaming it should
lead to less confusion especially when parsers for new compatibility
strings start to appear.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V9: First appearance of this commit
---
 drivers/mtd/mtdpart.c |  4 ++--
 drivers/mtd/ofpart.c  | 11 ++++++-----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index d40ec525ceff..a29bbcf79691 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -864,7 +864,7 @@ static int mtd_part_of_parse(struct mtd_info *master,
 			     struct mtd_partitions *pparts)
 {
 	struct mtd_part_parser *parser;
-	const char *fixed = "ofpart";
+	const char *fixed = "fixed-partitions";
 	int ret, err = 0;
 
 	/*
@@ -872,7 +872,7 @@ static int mtd_part_of_parse(struct mtd_info *master,
 	 */
 
 	/*
-	 * For backward compatibility we have to try the "ofpart"
+	 * For backward compatibility we have to try the "fixed-partitions"
 	 * parser. It supports old DT format with partitions specified as a
 	 * direct subnodes of a flash device DT node without any compatibility
 	 * specified we could match.
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e525677..9f497315e65d 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -25,9 +25,9 @@ static bool node_has_compatible(struct device_node *pp)
 	return of_get_property(pp, "compatible", NULL);
 }
 
-static int parse_ofpart_partitions(struct mtd_info *master,
-				   const struct mtd_partition **pparts,
-				   struct mtd_part_parser_data *data)
+static int parse_fixed_partitions(struct mtd_info *master,
+				  const struct mtd_partition **pparts,
+				  struct mtd_part_parser_data *data)
 {
 	struct mtd_partition *parts;
 	struct device_node *mtd_node;
@@ -141,8 +141,8 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 }
 
 static struct mtd_part_parser ofpart_parser = {
-	.parse_fn = parse_ofpart_partitions,
-	.name = "ofpart",
+	.parse_fn = parse_fixed_partitions,
+	.name = "fixed-partitions",
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
@@ -229,4 +229,5 @@ MODULE_AUTHOR("Vitaly Wool, David Gibson");
  * with the same name. Since we provide the ofoldpart parser, we should have
  * the corresponding alias.
  */
+MODULE_ALIAS("fixed-partitions");
 MODULE_ALIAS("ofoldpart");
-- 
2.11.0



From yogeshnarayan.gaur at nxp.com  Tue Jan 30 20:44:48 2018
From: yogeshnarayan.gaur at nxp.com (Yogesh Gaur)
Date: Wed, 31 Jan 2018 10:14:48 +0530
Subject: [PATCH v3] arm64: dts: ls1088a: Add qspi device node for ls1088a-rdb
Message-ID: <1517373888-4716-1-git-send-email-yogeshnarayan.gaur@nxp.com>

Add nodes and properties for QSPI controller.
Add support for spansion flash, s25fs512s, as slave device for
QSPI controller.

Added entry of "fsl,ls1088a-qspi" in fsl-quadspi.txt binding file.

Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur at nxp.com>
---
Depends on
 https://patchwork.ozlabs.org/project/linux-mtd/list/?series=26084

Changes for v3:
- Add compatible string for slave nodes.
Changes for v2:
- Move property spi-rx-bus-width and spi-tx-bus-width from controller
  to connected slave device node.

 .../devicetree/bindings/mtd/fsl-quadspi.txt        |  1 +
 arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts  | 25 ++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi     | 12 +++++++++++
 3 files changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 811da0e..956c23c 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -7,6 +7,7 @@ Required properties:
 		 or
 		 "fsl,ls2080a-qspi" followed by "fsl,ls1021a-qspi",
 		 "fsl,ls1043a-qspi" followed by "fsl,ls1021a-qspi"
+		 "fsl,ls2080a-qspi" followed by "fsl,ls1088a-qspi",
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
   - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
index 0f6fcda..99a514a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
@@ -94,6 +94,31 @@
 	};
 };
 
+&qspi {
+	status = "okay";
+	fsl,qspi-has-second-chip;
+	qflash0: s25fs512s at 0 {
+		compatible = "spansion,m25p80";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+	qflash1: s25fs512s at 1 {
+		compatible = "spansion,m25p80";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+		reg = <1>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+	};
+
+};
+
 &ifc {
 	ranges = <0 0 0x5 0x30000000 0x00010000
 		  2 0 0x5 0x20000000 0x00010000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index bd80e9a..b45a522 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -394,6 +394,18 @@
 			status = "disabled";
 		};
 
+		qspi: quadspi at 20c0000 {
+			compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0 0x20c0000 0x0 0x10000>,
+				<0x0 0x20000000 0x0 0x10000000>;
+			reg-names = "QuadSPI", "QuadSPI-memory";
+			interrupts = <0 25 0x4>; /* Level high type */
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "qspi_en", "qspi";
+		};
+
 		sata: sata at 3200000 {
 			compatible = "fsl,ls1088a-ahci";
 			reg = <0x0 0x3200000 0x0 0x10000>,
-- 
1.9.1



From stefan at agner.ch  Wed Jan 31 13:18:17 2018
From: stefan at agner.ch (stefan at agner.ch)
Date: Wed, 31 Jan 2018 22:18:17 +0100
Subject: [PATCH] mtd: nand: gpmi: fall back to legacy mode if no ECC
 information present
In-Reply-To: <20180131105705.17bbe858@bbrezillon>
References: <20180129144440.13648-1-stefan@agner.ch>
 <20180130142348.35f1bce3@bbrezillon>
 <d7a812de1b96be3460230efde4914ec1@agner.ch>
 <20180131105705.17bbe858@bbrezillon>
Message-ID: <33bcf28ff1c613886c950465160e5a97@agner.ch>

I accidentally removed ML/cc before, re-adding.

On 31.01.2018 10:57, Boris Brezillon wrote:
> On Wed, 31 Jan 2018 10:19:05 +0100
> stefan at agner.ch wrote:
> 
>> On 30.01.2018 14:23, Boris Brezillon wrote:
>> > Hi Stefan,
>> >
>> > On Mon, 29 Jan 2018 15:44:40 +0100
>> > Stefan Agner <stefan at agner.ch> wrote:
>> >
>> >> In case fsl,use-minimum-ecc is set, the driver tries to determine
>> >> ECC layout by using the ECC information provided by the MTD stack.
>> >> However, in case the NAND chip does not provide any information,
>> >> the driver currently fails with:
>> >>   nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
>> >>   nand: Macronix NAND 128MiB 3,3V 8-bit
>> >>   nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>> >>   gpmi-nand 1806000.gpmi-nand: Error setting BCH geometry : 1
>> >>   gpmi-nand: probe of 1806000.gpmi-nand failed with error 1
>> >>
>> >> Fall back to implementation specific default mode if no ECC
>> >> information are provided by the NAND chip and fsl,use-minimum-ecc
>> >> is specified.
>> >
>> > Hm, this sounds a bit fragile: if we ever fix the Macronix driver
>> > (which should be done BTW) to set the appropriate ECC requirements, it
>> > will break all platforms that were relying on this 'fall back to legacy
>> > logic'.
>>
>> I see. It is just that downstream behaves that way, hence we sell
>> modules which use minimal ECC on ONFI enabled chips and legacy (maximum
>> ECC which fits into OOB) on modules with non-ONFI chips.
> 
> And I guess you use the same DT for both variants of the board :-/
> 

Actually we only have two SKUs, and they differ also otherwise so I have
two DTs anyway.

>>
>> Currently we operate the above Macronix chip with 8-bit ECC since quite
>> a while.
> 
> Honestly, I don't see a good solution here except adding an extra DT or
> live-patching it from the bootloader, because, even if this hack works
> for you know, it might not in the future.

Extra DT is fine for Linux.

The problem is more with U-Boot, where I tried to add minimal ECC
support via Kconfig symbol and align with Linux behavior. For U-Boot I
would really prefer to have a single binary for all SKUs...

I already sent a first patchset
https://patchwork.ozlabs.org/patch/867180/

I guess it should be somehow possible to do a board specific selection
of ECC. But this is a discussion for another thread.

> 
> In the future, if you plan to have boards with different variants of
> NANDs, I recommend that you always maximize ECC, this way you won't
> have this kind of issues.

Makes sense. Unfortunately, for those products we already ship, changing
would be rather painful.

> 
>>
>> > So, if what you really want is legacy_set_geometry(), don't specify
>> > "fsl,use-minimum-ecc" in your DT and you should be good. Otherwise, fix
>> > the Macronix driver to initialize ->ecc_{strength,step_size}_ds
>> > appropriately.
>>
>> The datasheet says:
>> ? High Reliability
>> - Endurance: 100K cycles (with 1-bit ECC per 528-byte)
>>
>> So we would set ecc_strenght to 1?
> 
> If the datasheet says so, then yes, you should have
> ->ecc_strength_ds = 1 and ->ecc_step_size_ds = 512.
> 
>> But then there is almost no room for
>> wear leveling. I remember that I dumped the fixed bits once on such a
>> chip, and there were several blocks from factory which needed one bit
>> fixed...
> 
> Well, that's a different issue. You might want to maximize the ECC
> strength for your specific board. In this case, you should not specify
> "fsl,use-minimum-ecc" in your DT, or, if the driver supports it (but I
> doubt it does), you should add "nand-ecc-maximize". Alternatively, if
> you want to keep some of the OOB space, you can ask for a specific ECC
> config with the "nand-ecc-strength" and "nand-ecc-step-size" properties.

Different issue, but in the end all I care about: Does wear leveling
work properly.

The NAND chip documentation also mentions that typical access is per
page (2K), I guess if one uses a single ECC across the complete page
then 4-bits are available, which should allow a somewhat decent wear
leveling.

I guess we can go with nand-ecc-strength/nand-ecc-step-size for that
chip for now.

However, in Linux we should at least fix the device tree bindings
documentation for "fsl,use-minimum-ecc" then.

--
Stefan


From timo at exertus.fi  Wed Jan 31 22:44:26 2018
From: timo at exertus.fi (Timo Ketola)
Date: Thu, 1 Feb 2018 08:44:26 +0200
Subject: UBI assert failed in ubi_wl_init
Message-ID: <50443554-3f18-ce1b-70e7-a8092b39f5f5@exertus.fi>

Hi,

Could someone please give some ideas...

I'm trying to deploy UBI fastmap. Basically it seems to work but there
are some messages I'm not comfortable with.

I made UBI image with ubinize with fixed size empty volume (autoresize
seems not to work with fastmap at all). I flashed it with U-Boot 'nand
write.trimffs'. On first boot the fastmap complains about not to be able
to write fastmap:


> ubi1: default fastmap pool size: 256
> ubi1: default fastmap WL pool size: 128
> ubi1: attaching mtd1
> ubi1: scanning is finished
> ubi1: attached mtd1 (name "user", size 1984 MiB)
> ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096
> ubi1: good PEBs: 15864, bad PEBs: 8, corrupted PEBs: 0
> ubi1: user volume: 1, internal volumes: 1, max. volumes count: 128
> ubi1: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 18
> 6152832
> ubi1: available PEBs: 2331, total reserved PEBs: 13533, PEBs reserved for bad PE
> B handling: 312
> ubi1: background thread "ubi_bgt1d" started, PID 98
...
> ubi1 error: ubi_update_fastmap: could not get any free erase block
> ubi1 warning: ubi_update_fastmap: Unable to write new fastmap, err=-28
> UBIFS (ubi1:0): background thread "ubifs_bgt1_0" started, PID 105
> UBIFS (ubi1:0): UBIFS: mounted UBI device 1, volume 0, name "user"
> UBIFS (ubi1:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048
>  bytes/2048 bytes
> UBIFS (ubi1:0): FS size: 1675702272 bytes (1598 MiB, 13197 LEBs), journal size 9
> 023488 bytes (8 MiB, 72 LEBs)
> UBIFS (ubi1:0): reserved for root: 0 bytes (0 KiB)
> UBIFS (ubi1:0): media format: w4/r0 (latest is w5/r0), UUID C8D0E8D3-8394-445A-9
> 089-95BD864D5949, big LPT model


However, the image still mounts and works and on next boots also the
fastmap seems to be functional. Scanning is fast. But now UBI complains
about failing assert:


> ubi1: default fastmap pool size: 256
> ubi1: default fastmap WL pool size: 128
> ubi1: attaching mtd1
> ubi1: attached by fastmap
> ubi1: fastmap pool size: 256
> ubi1: fastmap WL pool size: 128
> UBI assert failed in ubi_wl_init at 1666 (pid 1)
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.1 #3
> Hardware name: Freescale i.MX6 SoloX (Device Tree)
> Backtrace: 
> [<c010a1b8>] (dump_backtrace) from [<c010a454>] (show_stack+0x18/0x1c)
>  r7:eee39b00 r6:c0912ac8 r5:60000013 r4:00000000
> [<c010a43c>] (show_stack) from [<c029edd0>] (dump_stack+0x80/0xa0)
> [<c029ed50>] (dump_stack) from [<c03d2394>] (ubi_wl_init+0x430/0x540)
>  r7:eee39b00 r6:eee39b04 r5:00003df7 r4:eee38040
> [<c03d1f64>] (ubi_wl_init) from [<c03d4c94>] (ubi_attach+0x28c/0x364)
>  r10:00000800 r9:eee37040 r8:00000040 r7:eee39c00 r6:eee39b00 r5:eee38040
>  r4:00000000
> [<c03d4a08>] (ubi_attach) from [<c03c9668>] (ubi_attach_mtd_dev+0x788/0xbc0)
>  r9:eee38080 r8:00000840 r7:ef349bc0 r6:00000001 r5:eee38040 r4:00000800
> [<c03c8ee0>] (ubi_attach_mtd_dev) from [<c0823d60>] (ubi_init+0x148/0x1e8)
>  r10:00000000 r9:c0933600 r8:00000000 r7:c0989024 r6:ef349bc0 r5:c0989074
>  r4:00000001
> [<c0823c18>] (ubi_init) from [<c0101780>] (do_one_initcall+0xb0/0x154)
>  r8:00000000 r7:c083edd0 r6:c0835838 r5:c0823c18 r4:00000007
> [<c01016d0>] (do_one_initcall) from [<c0800e30>] (kernel_init_freeable+0x130/0x1
> f8)
>  r8:c0933600 r7:c083edd0 r6:c0835838 r5:0000008d r4:00000007
> [<c0800d00>] (kernel_init_freeable) from [<c056ab6c>] (kernel_init+0x10/0x114)
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c056ab5c r4:00000000
> [<c056ab5c>] (kernel_init) from [<c01070c8>] (ret_from_fork+0x14/0x2c)
>  r5:c056ab5c r4:00000000
> ubi1: attached mtd1 (name "user", size 1984 MiB)
> ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
> ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
> ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096
> ubi1: good PEBs: 15864, bad PEBs: 8, corrupted PEBs: 0
> ubi1: user volume: 1, internal volumes: 1, max. volumes count: 128
> ubi1: max/mean erase counter: 2/0, WL threshold: 4096, image sequence number: 18
> 6152832
> ubi1: available PEBs: 2331, total reserved PEBs: 13533, PEBs reserved for bad PE
> B handling: 312
> ubi1: background thread "ubi_bgt1d" started, PID 98
...
> UBIFS (ubi1:0): background thread "ubifs_bgt1_0" started, PID 105
> UBIFS (ubi1:0): UBIFS: mounted UBI device 1, volume 0, name "user"
> UBIFS (ubi1:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048
>  bytes/2048 bytes
> UBIFS (ubi1:0): FS size: 1675702272 bytes (1598 MiB, 13197 LEBs), journal size 9
> 023488 bytes (8 MiB, 72 LEBs)
> UBIFS (ubi1:0): reserved for root: 0 bytes (0 KiB)
> UBIFS (ubi1:0): media format: w4/r0 (latest is w5/r0), UUID C8D0E8D3-8394-445A-9
> 089-95BD864D5949, big LPT model


The line 1666 reads:

> 	ubi_assert(ubi->good_peb_count == found_pebs);


Why the assert fails? Where should I look at to fix this? Is this
something to worry about?

I'm on mainline 4.12.1. ubinize version: 1.5.2

--

Timo


