* [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup
@ 2012-05-14 12:14 Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 1/8] mtd: sh_flctl: Add missing iounmap() Bastian Hecht
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
changelog v4:
- removed arch/arm related patches
- rebased on current l2-mtd.git
- fixed some compiler warnings
- patch 2: use "int irq" when removing irq binding in error case to fix smatch breakage
- patch 7 and 8: just directly use the void __iomem pointer instead of the unprecise void pointer to fix sparse breakage
changelog v3:
Just a rebase on current l2-mtd.git.
changelog v2:
- extract the iounmap calls from patch "Add support for error IRQ" into a new patch.
- swapped patches "Add support for error IRQ" and "Add error IRQ resource"
- corrected an indentation mistake
This series cleans up the flctl when run in hardware ecc mode. The first 2 patches make sure we catch all errors that result from hardware transmission. The other patches handle how the ecc is layed out, correct some code to write and read it and make sure we propagate the statistics about errors/repairs to the nand base.
Bastian Hecht (8):
mtd: sh_flctl: Add missing iounmap()
mtd: sh_flctl: Add support for error IRQ
mtd: sh_flctl: Use different OOB layout
mtd: sh_flctl: Fix hardware ECC behaviour
mtd: sh_flctl: Simplify the hardware ecc page read/write
mtd: sh_flctl: Group sector accesses into a single transfer
mtd: sh_flctl: Restructure the hardware ECC handling
mtd: sh_flctl: Use user oob data in hardware ECC mode
drivers/mtd/nand/sh_flctl.c | 299 ++++++++++++++++++++++++------------------
include/linux/mtd/sh_flctl.h | 23 +++-
2 files changed, 187 insertions(+), 135 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 1/8] mtd: sh_flctl: Add missing iounmap()
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ Bastian Hecht
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
Add the unmapping for the error case and for the driver removal.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/mtd/nand/sh_flctl.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index aa9b8a5..a5a60ca 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -918,6 +918,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
err_chip:
pm_runtime_disable(&pdev->dev);
+ iounmap(flctl->reg);
err_iomap:
kfree(flctl);
return ret;
@@ -929,6 +930,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
nand_release(&flctl->mtd);
pm_runtime_disable(&pdev->dev);
+ iounmap(flctl->reg);
kfree(flctl);
return 0;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 1/8] mtd: sh_flctl: Add missing iounmap() Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-07-06 15:51 ` David Woodhouse
2012-05-14 12:14 ` [PATCH v4 3/8] mtd: sh_flctl: Use different OOB layout Bastian Hecht
` (6 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
When the data transfer between the controller and the NAND chip fails,
we now get notified.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 34 +++++++++++++++++++++++++++++++---
include/linux/mtd/sh_flctl.h | 9 +++++++++
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index a5a60ca..fb22cc7 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -68,8 +69,8 @@ static struct nand_bbt_descr flctl_4secc_largepage = {
static void empty_fifo(struct sh_flctl *flctl)
{
- writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */
- writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */
+ writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl));
+ writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
}
static void start_translation(struct sh_flctl *flctl)
@@ -839,6 +840,16 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
return 0;
}
+static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
+{
+ struct sh_flctl *flctl = dev_id;
+
+ dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl)));
+ writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
+
+ return IRQ_HANDLED;
+}
+
static int __devinit flctl_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -847,6 +858,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
struct nand_chip *nand;
struct sh_flctl_platform_data *pdata;
int ret = -ENXIO;
+ int irq;
pdata = pdev->dev.platform_data;
if (pdata = NULL) {
@@ -872,14 +884,27 @@ static int __devinit flctl_probe(struct platform_device *pdev)
goto err_iomap;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get flste irq data\n");
+ goto err_flste;
+ }
+
+ ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
+ if (ret) {
+ dev_err(&pdev->dev, "request interrupt failed.\n");
+ goto err_flste;
+ }
+
platform_set_drvdata(pdev, flctl);
flctl_mtd = &flctl->mtd;
nand = &flctl->chip;
flctl_mtd->priv = nand;
flctl->pdev = pdev;
- flctl->flcmncr_base = pdata->flcmncr_val;
flctl->hwecc = pdata->has_hwecc;
flctl->holden = pdata->use_holden;
+ flctl->flcmncr_base = pdata->flcmncr_val;
+ flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE;
/* Set address of hardware control function */
/* 20 us command delay time */
@@ -918,6 +943,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
err_chip:
pm_runtime_disable(&pdev->dev);
+ free_irq(irq, flctl);
+err_flste:
iounmap(flctl->reg);
err_iomap:
kfree(flctl);
@@ -930,6 +957,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
nand_release(&flctl->mtd);
pm_runtime_disable(&pdev->dev);
+ free_irq(platform_get_irq(pdev, 0), flctl);
iounmap(flctl->reg);
kfree(flctl);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index a38e1fa..2daa43e 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -107,6 +107,14 @@
#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */
#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */
+/* FLINTDMACR control bits */
+#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */
+#define AC1CLR (0x1 << 19) /* ECC FIFO clear */
+#define AC0CLR (0x1 << 18) /* Data FIFO clear */
+#define ECERB (0x1 << 9) /* ECC error */
+#define STERB (0x1 << 8) /* Status error */
+#define STERINTE (0x1 << 4) /* Status error enable */
+
/* FLTRCR control bits */
#define TRSTRT (0x1 << 0) /* translation start */
#define TREND (0x1 << 1) /* translation end */
@@ -145,6 +153,7 @@ struct sh_flctl {
uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */
uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */
uint32_t flcmncr_base; /* base value of FLCMNCR */
+ uint32_t flintdmacr_base; /* irq enable bits */
int hwecc_cant_correct[4];
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 3/8] mtd: sh_flctl: Use different OOB layout
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 1/8] mtd: sh_flctl: Add missing iounmap() Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 4/8] mtd: sh_flctl: Fix hardware ECC behaviour Bastian Hecht
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
The flctl hardware has changed and a new OOB layout must be adapted for
2k page size NAND chips when using hardware ECC.
The related bit fields ECCPOS[0-2] are gone - the bits are marked as
reserved now in the datasheet. As there are no official users of the
hardware ECC so far, they are completely removed.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 18 ++++++++++++------
include/linux/mtd/sh_flctl.h | 4 ----
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index fb22cc7..4eaee54 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -44,11 +44,17 @@ static struct nand_ecclayout flctl_4secc_oob_16 = {
};
static struct nand_ecclayout flctl_4secc_oob_64 = {
- .eccbytes = 10,
- .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
+ .eccbytes = 4 * 10,
+ .eccpos = {
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
.oobfree = {
- {.offset = 60,
- . length = 4} },
+ {.offset = 2, .length = 4},
+ {.offset = 16, .length = 6},
+ {.offset = 32, .length = 6},
+ {.offset = 48, .length = 6} },
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -62,7 +68,7 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
static struct nand_bbt_descr flctl_4secc_largepage = {
.options = NAND_BBT_SCAN2NDPAGE,
- .offs = 58,
+ .offs = 0,
.len = 2,
.pattern = scan_ff_pattern,
};
@@ -832,7 +838,7 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
chip->ecc.mode = NAND_ECC_HW;
/* 4 symbols ECC enabled */
- flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02;
+ flctl->flcmncr_base |= _4ECCEN;
} else {
chip->ecc.mode = NAND_ECC_SOFT;
}
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 2daa43e..3feaae0 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -49,7 +49,6 @@
#define FLERRADR(f) (f->reg + 0x98)
/* FLCMNCR control bits */
-#define ECCPOS2 (0x1 << 25)
#define _4ECCCNTEN (0x1 << 24)
#define _4ECCEN (0x1 << 23)
#define _4ECCCORRECT (0x1 << 22)
@@ -59,9 +58,6 @@
#define QTSEL_E (0x1 << 17)
#define ENDIAN (0x1 << 16) /* 1 = little endian */
#define FCKSEL_E (0x1 << 15)
-#define ECCPOS_00 (0x00 << 12)
-#define ECCPOS_01 (0x01 << 12)
-#define ECCPOS_02 (0x02 << 12)
#define ACM_SACCES_MODE (0x01 << 10)
#define NANWF_E (0x1 << 9)
#define SE_D (0x1 << 8) /* Spare area disable */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 4/8] mtd: sh_flctl: Fix hardware ECC behaviour
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (2 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 3/8] mtd: sh_flctl: Use different OOB layout Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 5/8] mtd: sh_flctl: Simplify the hardware ecc page read/write Bastian Hecht
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
The flctl uses 10 bytes ECC data for every 512 bytes sector. This patch
makes the controller write all 40 bytes instead of 10 bytes only.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 30 +++++++-----------------------
1 files changed, 7 insertions(+), 23 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4eaee54..642986f 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -427,30 +427,20 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int page_sectors = flctl->page_size ? 4 : 1;
+ int i;
set_cmd_regs(mtd, NAND_CMD_READ0,
(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
empty_fifo(flctl);
- if (flctl->page_size) {
- int i;
- /* In case that the page size is 2k */
- for (i = 0; i < 16 * 3; i++)
- flctl->done_buff[i] = 0xFF;
-
- set_addr(mtd, 3 * 528 + 512, page_addr);
- writel(16, FLDTCNTR(flctl));
- start_translation(flctl);
- read_fiforeg(flctl, 16, 16 * 3);
- wait_completion(flctl);
- } else {
- /* In case that the page size is 512b */
- set_addr(mtd, 512, page_addr);
+ for (i = 0; i < page_sectors; i++) {
+ set_addr(mtd, (512 + 16) * i + 512 , page_addr);
writel(16, FLDTCNTR(flctl));
start_translation(flctl);
- read_fiforeg(flctl, 16, 0);
+ read_fiforeg(flctl, 16, 16 * i);
wait_completion(flctl);
}
}
@@ -495,18 +485,12 @@ static void execmd_write_oob(struct mtd_info *mtd)
int page_addr = flctl->seqin_page_addr;
int sector, page_sectors;
- if (flctl->page_size) {
- sector = 3;
- page_sectors = 4;
- } else {
- sector = 0;
- page_sectors = 1;
- }
+ page_sectors = flctl->page_size ? 4 : 1;
set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
- for (; sector < page_sectors; sector++) {
+ for (sector = 0; sector < page_sectors; sector++) {
empty_fifo(flctl);
set_addr(mtd, sector * 528 + 512, page_addr);
writel(16, FLDTCNTR(flctl)); /* set read size */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 5/8] mtd: sh_flctl: Simplify the hardware ecc page read/write
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (3 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 4/8] mtd: sh_flctl: Fix hardware ECC behaviour Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 6/8] mtd: sh_flctl: Group sector accesses into a single transfer Bastian Hecht
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
As the equation mtd->writesize = eccsteps * eccsize holds, we can
simplify the code. The second loop of the 1st hunk is never entered,
so we delete it.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 25 ++-----------------------
1 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 642986f..b28b53f 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -353,35 +353,14 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- struct sh_flctl *flctl = mtd_to_flctl(mtd);
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->read_buf(mtd, p, eccsize);
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- if (flctl->hwecc_cant_correct[i])
- mtd->ecc_stats.failed++;
- else
- mtd->ecc_stats.corrected += 0; /* FIXME */
- }
-
+ chip->read_buf(mtd, buf, mtd->writesize);
return 0;
}
static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- const uint8_t *p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->write_buf(mtd, p, eccsize);
+ chip->write_buf(mtd, buf, mtd->writesize);
}
static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 6/8] mtd: sh_flctl: Group sector accesses into a single transfer
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (4 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 5/8] mtd: sh_flctl: Simplify the hardware ecc page read/write Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 7/8] mtd: sh_flctl: Restructure the hardware ECC handling Bastian Hecht
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
When we use hardware ecc, the flctl is run in so-called "sector access
mode". We can bundle 4 sector accesses when using 2k page sizes to read
a whole page at once and speed up things.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 44 ++++++++++++++++++------------------------
1 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index b28b53f..9de4225 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -368,25 +368,21 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
struct sh_flctl *flctl = mtd_to_flctl(mtd);
int sector, page_sectors;
- if (flctl->page_size)
- page_sectors = 4;
- else
- page_sectors = 1;
+ page_sectors = flctl->page_size ? 4 : 1;
+
+ set_cmd_regs(mtd, NAND_CMD_READ0,
+ (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
FLCMNCR(flctl));
+ writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+ writel(page_addr << 2, FLADR(flctl));
- set_cmd_regs(mtd, NAND_CMD_READ0,
- (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
+ empty_fifo(flctl);
+ start_translation(flctl);
for (sector = 0; sector < page_sectors; sector++) {
int ret;
-
- empty_fifo(flctl);
- writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
- writel(page_addr << 2 | sector, FLADR(flctl));
-
- start_translation(flctl);
read_fiforeg(flctl, 512, 512 * sector);
ret = read_ecfiforeg(flctl,
@@ -397,8 +393,10 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
flctl->hwecc_cant_correct[sector] = 1;
writel(0x0, FL4ECCCR(flctl));
- wait_completion(flctl);
}
+
+ wait_completion(flctl);
+
writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
FLCMNCR(flctl));
}
@@ -430,31 +428,27 @@ static void execmd_write_page_sector(struct mtd_info *mtd)
int i, page_addr = flctl->seqin_page_addr;
int sector, page_sectors;
- if (flctl->page_size)
- page_sectors = 4;
- else
- page_sectors = 1;
-
- writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+ page_sectors = flctl->page_size ? 4 : 1;
set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
- for (sector = 0; sector < page_sectors; sector++) {
- empty_fifo(flctl);
- writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
- writel(page_addr << 2 | sector, FLADR(flctl));
+ empty_fifo(flctl);
+ writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+ writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+ writel(page_addr << 2, FLADR(flctl));
+ start_translation(flctl);
- start_translation(flctl);
+ for (sector = 0; sector < page_sectors; sector++) {
write_fiforeg(flctl, 512, 512 * sector);
for (i = 0; i < 4; i++) {
wait_wecfifo_ready(flctl); /* wait for write ready */
writel(0xFFFFFFFF, FLECFIFO(flctl));
}
- wait_completion(flctl);
}
+ wait_completion(flctl);
writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 7/8] mtd: sh_flctl: Restructure the hardware ECC handling
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (5 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 6/8] mtd: sh_flctl: Group sector accesses into a single transfer Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode Bastian Hecht
2012-05-15 10:47 ` [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Artem Bityutskiy
8 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
There are multiple reasons for a rewrite:
- a race exists: when _4ECCEND is set, _4ECCFA may become true too
meanwhile, which is lost and a non-correctable error is treated as
correctable.
- the ECC statistics don't get properly propagated to the base code.
- empty pages would get marked as corrupted
The rewrite resolves the issues and I hope it gives a more explicit
code flow structure.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 121 ++++++++++++++++++++++++++++--------------
include/linux/mtd/sh_flctl.h | 10 +++-
2 files changed, 88 insertions(+), 43 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 9de4225..631f7ed 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -165,27 +165,56 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
timeout_error(flctl, __func__);
}
-static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
+static enum flctl_ecc_res_t wait_recfifo_ready
+ (struct sh_flctl *flctl, int sector_number)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
- int checked[4];
void __iomem *ecc_reg[4];
int i;
+ int state = FL_SUCCESS;
uint32_t data, size;
- memset(checked, 0, sizeof(checked));
-
+ /*
+ * First this loops checks in FLDTCNTR if we are ready to read out the
+ * oob data. This is the case if either all went fine without errors or
+ * if the bottom part of the loop corrected the errors or marked them as
+ * uncorrectable and the controller is given time to push the data into
+ * the FIFO.
+ */
while (timeout--) {
+ /* check if all is ok and we can read out the OOB */
size = readl(FLDTCNTR(flctl)) >> 24;
- if (size & 0xFF)
- return 0; /* success */
+ if ((size & 0xFF) = 4)
+ return state;
+
+ /* check if a correction code has been calculated */
+ if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) {
+ /*
+ * either we wait for the fifo to be filled or a
+ * correction pattern is being generated
+ */
+ udelay(1);
+ continue;
+ }
- if (readl(FL4ECCCR(flctl)) & _4ECCFA)
- return 1; /* can't correct */
+ /* check for an uncorrectable error */
+ if (readl(FL4ECCCR(flctl)) & _4ECCFA) {
+ /* check if we face a non-empty page */
+ for (i = 0; i < 512; i++) {
+ if (flctl->done_buff[i] != 0xff) {
+ state = FL_ERROR; /* can't correct */
+ break;
+ }
+ }
- udelay(1);
- if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
+ if (state = FL_SUCCESS)
+ dev_dbg(&flctl->pdev->dev,
+ "reading empty sector %d, ecc error ignored\n",
+ sector_number);
+
+ writel(0, FL4ECCCR(flctl));
continue;
+ }
/* start error correction */
ecc_reg[0] = FL4ECCRESULT0(flctl);
@@ -194,28 +223,26 @@ static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
ecc_reg[3] = FL4ECCRESULT3(flctl);
for (i = 0; i < 3; i++) {
+ uint8_t org;
+ int index;
+
data = readl(ecc_reg[i]);
- if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
- uint8_t org;
- int index;
-
- if (flctl->page_size)
- index = (512 * sector_number) +
- (data >> 16);
- else
- index = data >> 16;
-
- org = flctl->done_buff[index];
- flctl->done_buff[index] = org ^ (data & 0xFF);
- checked[i] = 1;
- }
- }
+ if (flctl->page_size)
+ index = (512 * sector_number) +
+ (data >> 16);
+ else
+ index = data >> 16;
+
+ org = flctl->done_buff[index];
+ flctl->done_buff[index] = org ^ (data & 0xFF);
+ }
+ state = FL_REPAIRABLE;
writel(0, FL4ECCCR(flctl));
}
timeout_error(flctl, __func__);
- return 1; /* timeout */
+ return FL_TIMEOUT; /* timeout */
}
static void wait_wecfifo_ready(struct sh_flctl *flctl)
@@ -259,20 +286,23 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
+static enum flctl_ecc_res_t read_ecfiforeg
+ (struct sh_flctl *flctl, uint8_t *buff, int sector)
{
int i;
+ enum flctl_ecc_res_t res;
unsigned long *ecc_buf = (unsigned long *)buff;
- void *fifo_addr = (void *)FLECFIFO(flctl);
- for (i = 0; i < 4; i++) {
- if (wait_recfifo_ready(flctl , sector))
- return 1;
- ecc_buf[i] = readl(fifo_addr);
- ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+ res = wait_recfifo_ready(flctl , sector);
+
+ if (res != FL_ERROR) {
+ for (i = 0; i < 4; i++) {
+ ecc_buf[i] = readl(FLECFIFO(flctl));
+ ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+ }
}
- return 0;
+ return res;
}
static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
@@ -367,6 +397,7 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
int sector, page_sectors;
+ enum flctl_ecc_res_t ecc_result;
page_sectors = flctl->page_size ? 4 : 1;
@@ -382,17 +413,27 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
start_translation(flctl);
for (sector = 0; sector < page_sectors; sector++) {
- int ret;
read_fiforeg(flctl, 512, 512 * sector);
- ret = read_ecfiforeg(flctl,
+ ecc_result = read_ecfiforeg(flctl,
&flctl->done_buff[mtd->writesize + 16 * sector],
sector);
- if (ret)
- flctl->hwecc_cant_correct[sector] = 1;
-
- writel(0x0, FL4ECCCR(flctl));
+ switch (ecc_result) {
+ case FL_REPAIRABLE:
+ dev_info(&flctl->pdev->dev,
+ "applied ecc on page 0x%x", page_addr);
+ flctl->mtd.ecc_stats.corrected++;
+ break;
+ case FL_ERROR:
+ dev_warn(&flctl->pdev->dev,
+ "page 0x%x contains corrupted data\n",
+ page_addr);
+ flctl->mtd.ecc_stats.failed++;
+ break;
+ default:
+ ;
+ }
}
wait_completion(flctl);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 3feaae0..01e4b15 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -129,9 +129,15 @@
#define _4ECCEND (0x1 << 1) /* 4 symbols end */
#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */
-#define INIT_FL4ECCRESULT_VAL 0x03FF03FF
#define LOOP_TIMEOUT_MAX 0x00010000
+enum flctl_ecc_res_t {
+ FL_SUCCESS,
+ FL_REPAIRABLE,
+ FL_ERROR,
+ FL_TIMEOUT
+};
+
struct sh_flctl {
struct mtd_info mtd;
struct nand_chip chip;
@@ -151,8 +157,6 @@ struct sh_flctl {
uint32_t flcmncr_base; /* base value of FLCMNCR */
uint32_t flintdmacr_base; /* irq enable bits */
- int hwecc_cant_correct[4];
-
unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */
unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */
unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (6 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 7/8] mtd: sh_flctl: Restructure the hardware ECC handling Bastian Hecht
@ 2012-05-14 12:14 ` Bastian Hecht
2012-05-14 15:12 ` Brian Norris
2012-05-15 10:47 ` [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Artem Bityutskiy
8 siblings, 1 reply; 14+ messages in thread
From: Bastian Hecht @ 2012-05-14 12:14 UTC (permalink / raw)
To: linux-mtd; +Cc: Bastian Hecht, magnus.damm, laurent.pinchart, linux-sh
In hardware ecc mode, the flctl now writes and reads the oob data
provided by the user. Additionally the ECC is now returned in normal
page reads, not only when using the explicit NAND_CMD_READOOB command.
Signed-off-by: Bastian Hecht <hechtb@gmail.com>
Acked-by: Brian Norris <computersforpeace@gmail.com>
---
drivers/mtd/nand/sh_flctl.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 631f7ed..8a07212 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -275,13 +275,12 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
{
int i, len_4align;
unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
- void *fifo_addr = (void *)FLDTFIFO(flctl);
len_4align = (rlen + 3) / 4;
for (i = 0; i < len_4align; i++) {
wait_rfifo_ready(flctl);
- buf[i] = readl(fifo_addr);
+ buf[i] = readl(FLDTFIFO(flctl));
buf[i] = be32_to_cpu(buf[i]);
}
}
@@ -318,6 +317,18 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
+static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+{
+ int i, len_4align;
+ unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+
+ len_4align = (rlen + 3) / 4;
+ for (i = 0; i < len_4align; i++) {
+ wait_wecfifo_ready(flctl);
+ writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
+ }
+}
+
static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -384,6 +395,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
{
chip->read_buf(mtd, buf, mtd->writesize);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
return 0;
}
@@ -391,6 +403,7 @@ static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
chip->write_buf(mtd, buf, mtd->writesize);
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
}
static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
@@ -466,7 +479,7 @@ static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
static void execmd_write_page_sector(struct mtd_info *mtd)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
- int i, page_addr = flctl->seqin_page_addr;
+ int page_addr = flctl->seqin_page_addr;
int sector, page_sectors;
page_sectors = flctl->page_size ? 4 : 1;
@@ -482,11 +495,7 @@ static void execmd_write_page_sector(struct mtd_info *mtd)
for (sector = 0; sector < page_sectors; sector++) {
write_fiforeg(flctl, 512, 512 * sector);
-
- for (i = 0; i < 4; i++) {
- wait_wecfifo_ready(flctl); /* wait for write ready */
- writel(0xFFFFFFFF, FLECFIFO(flctl));
- }
+ write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector);
}
wait_completion(flctl);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode
2012-05-14 12:14 ` [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode Bastian Hecht
@ 2012-05-14 15:12 ` Brian Norris
2012-05-16 9:37 ` Bastian Hecht
0 siblings, 1 reply; 14+ messages in thread
From: Brian Norris @ 2012-05-14 15:12 UTC (permalink / raw)
To: Bastian Hecht
Cc: Artem Bityutskiy, linux-sh, magnus.damm, Bastian Hecht, linux-mtd,
laurent.pinchart
On Mon, May 14, 2012 at 5:14 AM, Bastian Hecht <hechtb@googlemail.com> wrote:
> diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
> index 631f7ed..8a07212 100644
> --- a/drivers/mtd/nand/sh_flctl.c
> +++ b/drivers/mtd/nand/sh_flctl.c
> @@ -384,6 +395,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
> uint8_t *buf, int oob_required, int page)
> {
> chip->read_buf(mtd, buf, mtd->writesize);
> + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
> return 0;
> }
Well, my 'oob_required' patches won the race for inclusion in
l2-mtd-2.6.git, so it's probably good to just use the 'oob_required'
parameter now. That is:
if (oob_required)
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
> @@ -391,6 +403,7 @@ static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
> const uint8_t *buf, int oob_required)
> {
> chip->write_buf(mtd, buf, mtd->writesize);
> + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> }
Similar here:
if (oob_required)
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
Brian
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
` (7 preceding siblings ...)
2012-05-14 12:14 ` [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode Bastian Hecht
@ 2012-05-15 10:47 ` Artem Bityutskiy
8 siblings, 0 replies; 14+ messages in thread
From: Artem Bityutskiy @ 2012-05-15 10:47 UTC (permalink / raw)
To: Bastian Hecht
Cc: Bastian Hecht, magnus.damm, linux-mtd, laurent.pinchart, linux-sh
[-- Attachment #1: Type: text/plain, Size: 673 bytes --]
On Mon, 2012-05-14 at 14:14 +0200, Bastian Hecht wrote:
> changelog v4:
>
> - removed arch/arm related patches
> - rebased on current l2-mtd.git
> - fixed some compiler warnings
> - patch 2: use "int irq" when removing irq binding in error case to fix smatch breakage
> - patch 7 and 8: just directly use the void __iomem pointer instead of the unprecise void pointer to fix sparse breakage
Pushed to l2-mtd.git. You can send a follow-up patch for using
"oob_required" parameter. Also, I CCed you to a thread which discusses
busy-loops I complained about - your driver also has a similar
busy-loop.
Thanks!
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode
2012-05-14 15:12 ` Brian Norris
@ 2012-05-16 9:37 ` Bastian Hecht
0 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-05-16 9:37 UTC (permalink / raw)
To: Brian Norris
Cc: Artem Bityutskiy, linux-sh, magnus.damm, Bastian Hecht, linux-mtd,
laurent.pinchart
Hello Brian,
Artem pushed the set and I'll supply a follow-up patch containing your
suggestion.
Thanks,
Bastian
2012/5/14 Brian Norris <computersforpeace@gmail.com>:
> On Mon, May 14, 2012 at 5:14 AM, Bastian Hecht <hechtb@googlemail.com> wrote:
>> diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
>> index 631f7ed..8a07212 100644
>> --- a/drivers/mtd/nand/sh_flctl.c
>> +++ b/drivers/mtd/nand/sh_flctl.c
>> @@ -384,6 +395,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
>> uint8_t *buf, int oob_required, int page)
>> {
>> chip->read_buf(mtd, buf, mtd->writesize);
>> + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
>> return 0;
>> }
>
> Well, my 'oob_required' patches won the race for inclusion in
> l2-mtd-2.6.git, so it's probably good to just use the 'oob_required'
> parameter now. That is:
>
> if (oob_required)
> chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
>
>> @@ -391,6 +403,7 @@ static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
>> const uint8_t *buf, int oob_required)
>> {
>> chip->write_buf(mtd, buf, mtd->writesize);
>> + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
>> }
>
> Similar here:
>
> if (oob_required)
> chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
>
> Brian
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ
2012-05-14 12:14 ` [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ Bastian Hecht
@ 2012-07-06 15:51 ` David Woodhouse
2012-07-06 16:39 ` Bastian Hecht
0 siblings, 1 reply; 14+ messages in thread
From: David Woodhouse @ 2012-07-06 15:51 UTC (permalink / raw)
To: Bastian Hecht
Cc: Bastian Hecht, magnus.damm, linux-mtd, laurent.pinchart, linux-sh
[-- Attachment #1: Type: text/plain, Size: 324 bytes --]
On Mon, 2012-05-14 at 14:14 +0200, Bastian Hecht wrote:
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
Is that correct? I know we have sometimes suffered from the insanity of
assuming that irq 0 is *invalid*, and you're treating it as valid here.
Did we recover from our insanity?
--
dwmw2
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ
2012-07-06 15:51 ` David Woodhouse
@ 2012-07-06 16:39 ` Bastian Hecht
0 siblings, 0 replies; 14+ messages in thread
From: Bastian Hecht @ 2012-07-06 16:39 UTC (permalink / raw)
To: David Woodhouse
Cc: Bastian Hecht, magnus.damm, linux-mtd, laurent.pinchart, linux-sh
2012/7/6 David Woodhouse <dwmw2@infradead.org>:
> On Mon, 2012-05-14 at 14:14 +0200, Bastian Hecht wrote:
>> + irq = platform_get_irq(pdev, 0);
>> + if (irq < 0) {
>
> Is that correct? I know we have sometimes suffered from the insanity of
> assuming that irq 0 is *invalid*, and you're treating it as valid here.
> Did we recover from our insanity?
This is pure ignorance from me - I have no idea what is right. Might
be the lucky shot that is superior to woman's/man's craft.
> --
> dwmw2
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-07-06 16:39 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-14 12:14 [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 1/8] mtd: sh_flctl: Add missing iounmap() Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 2/8] mtd: sh_flctl: Add support for error IRQ Bastian Hecht
2012-07-06 15:51 ` David Woodhouse
2012-07-06 16:39 ` Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 3/8] mtd: sh_flctl: Use different OOB layout Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 4/8] mtd: sh_flctl: Fix hardware ECC behaviour Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 5/8] mtd: sh_flctl: Simplify the hardware ecc page read/write Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 6/8] mtd: sh_flctl: Group sector accesses into a single transfer Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 7/8] mtd: sh_flctl: Restructure the hardware ECC handling Bastian Hecht
2012-05-14 12:14 ` [PATCH v4 8/8] mtd: sh_flctl: Use user oob data in hardware ECC mode Bastian Hecht
2012-05-14 15:12 ` Brian Norris
2012-05-16 9:37 ` Bastian Hecht
2012-05-15 10:47 ` [PATCH v4 0/8] sh_flctl hardware ECC mode cleanup Artem Bityutskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).