Skip to content

Commit e304f2d

Browse files
romain-izard-proambarus
authored andcommitted
mtd: nand: atmel: Avoid ECC errors when leaving backup mode
During backup mode, the contents of all registers will be cleared as the SoC will be completely powered down. For a product that boots on NAND Flash memory, the bootloader will obviously use the related controller to read the Flash and correct any detected error in the memory, before handling back control to the kernel's resuming entry point. But it does not clean the NAND controller registers after use and on its side the kernel driver expects the error locator to be powered down and in a clean state. Add a resume hook for the PMECC error locator, and reset its registers. Signed-off-by: Romain Izard <romain.izard.pro@gmail.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> (cherry picked from commit 143b0ab)
1 parent 7aa921e commit e304f2d

3 files changed

Lines changed: 13 additions & 8 deletions

File tree

drivers/mtd/nand/atmel/nand-controller.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,6 +2529,9 @@ static __maybe_unused int atmel_nand_controller_resume(struct device *dev)
25292529
struct atmel_nand_controller *nc = dev_get_drvdata(dev);
25302530
struct atmel_nand *nand;
25312531

2532+
if (nc->pmecc)
2533+
atmel_pmecc_reset(nc->pmecc);
2534+
25322535
list_for_each_entry(nand, &nc->chips, node) {
25332536
int i;
25342537

drivers/mtd/nand/atmel/pmecc.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,13 @@ void atmel_pmecc_get_generated_eccbytes(struct atmel_pmecc_user *user,
765765
}
766766
EXPORT_SYMBOL_GPL(atmel_pmecc_get_generated_eccbytes);
767767

768+
void atmel_pmecc_reset(struct atmel_pmecc *pmecc)
769+
{
770+
writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
771+
writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
772+
}
773+
EXPORT_SYMBOL_GPL(atmel_pmecc_reset);
774+
768775
int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op)
769776
{
770777
struct atmel_pmecc *pmecc = user->pmecc;
@@ -797,10 +804,7 @@ EXPORT_SYMBOL_GPL(atmel_pmecc_enable);
797804

798805
void atmel_pmecc_disable(struct atmel_pmecc_user *user)
799806
{
800-
struct atmel_pmecc *pmecc = user->pmecc;
801-
802-
writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
803-
writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
807+
atmel_pmecc_reset(user->pmecc);
804808
mutex_unlock(&user->pmecc->lock);
805809
}
806810
EXPORT_SYMBOL_GPL(atmel_pmecc_disable);
@@ -855,10 +859,7 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
855859

856860
/* Disable all interrupts before registering the PMECC handler. */
857861
writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR);
858-
859-
/* Reset the ECC engine */
860-
writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
861-
writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
862+
atmel_pmecc_reset(pmecc);
862863

863864
return pmecc;
864865
}

drivers/mtd/nand/atmel/pmecc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
6161
struct atmel_pmecc_user_req *req);
6262
void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
6363

64+
void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
6465
int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
6566
void atmel_pmecc_disable(struct atmel_pmecc_user *user);
6667
int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user);

0 commit comments

Comments
 (0)