Skip to content

Commit 3c7ea4e

Browse files
Bastian HechtDavid Woodhouse
authored andcommitted
mtd: sh_flctl: Add support for error IRQ
When the data transfer between the controller and the NAND chip fails, we now get notified. Signed-off-by: Bastian Hecht <hechtb@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
1 parent cb54751 commit 3c7ea4e

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

drivers/mtd/nand/sh_flctl.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/module.h>
2525
#include <linux/kernel.h>
2626
#include <linux/delay.h>
27+
#include <linux/interrupt.h>
2728
#include <linux/io.h>
2829
#include <linux/platform_device.h>
2930
#include <linux/pm_runtime.h>
@@ -68,8 +69,8 @@ static struct nand_bbt_descr flctl_4secc_largepage = {
6869

6970
static void empty_fifo(struct sh_flctl *flctl)
7071
{
71-
writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */
72-
writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */
72+
writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl));
73+
writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
7374
}
7475

7576
static void start_translation(struct sh_flctl *flctl)
@@ -839,6 +840,16 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
839840
return 0;
840841
}
841842

843+
static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
844+
{
845+
struct sh_flctl *flctl = dev_id;
846+
847+
dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl)));
848+
writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
849+
850+
return IRQ_HANDLED;
851+
}
852+
842853
static int __devinit flctl_probe(struct platform_device *pdev)
843854
{
844855
struct resource *res;
@@ -847,6 +858,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
847858
struct nand_chip *nand;
848859
struct sh_flctl_platform_data *pdata;
849860
int ret = -ENXIO;
861+
int irq;
850862

851863
pdata = pdev->dev.platform_data;
852864
if (pdata == NULL) {
@@ -872,14 +884,27 @@ static int __devinit flctl_probe(struct platform_device *pdev)
872884
goto err_iomap;
873885
}
874886

887+
irq = platform_get_irq(pdev, 0);
888+
if (irq < 0) {
889+
dev_err(&pdev->dev, "failed to get flste irq data\n");
890+
goto err_flste;
891+
}
892+
893+
ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
894+
if (ret) {
895+
dev_err(&pdev->dev, "request interrupt failed.\n");
896+
goto err_flste;
897+
}
898+
875899
platform_set_drvdata(pdev, flctl);
876900
flctl_mtd = &flctl->mtd;
877901
nand = &flctl->chip;
878902
flctl_mtd->priv = nand;
879903
flctl->pdev = pdev;
880-
flctl->flcmncr_base = pdata->flcmncr_val;
881904
flctl->hwecc = pdata->has_hwecc;
882905
flctl->holden = pdata->use_holden;
906+
flctl->flcmncr_base = pdata->flcmncr_val;
907+
flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE;
883908

884909
/* Set address of hardware control function */
885910
/* 20 us command delay time */
@@ -918,6 +943,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
918943

919944
err_chip:
920945
pm_runtime_disable(&pdev->dev);
946+
free_irq(irq, flctl);
947+
err_flste:
921948
iounmap(flctl->reg);
922949
err_iomap:
923950
kfree(flctl);
@@ -930,6 +957,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
930957

931958
nand_release(&flctl->mtd);
932959
pm_runtime_disable(&pdev->dev);
960+
free_irq(platform_get_irq(pdev, 0), flctl);
933961
iounmap(flctl->reg);
934962
kfree(flctl);
935963

include/linux/mtd/sh_flctl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@
107107
#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */
108108
#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */
109109

110+
/* FLINTDMACR control bits */
111+
#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */
112+
#define AC1CLR (0x1 << 19) /* ECC FIFO clear */
113+
#define AC0CLR (0x1 << 18) /* Data FIFO clear */
114+
#define ECERB (0x1 << 9) /* ECC error */
115+
#define STERB (0x1 << 8) /* Status error */
116+
#define STERINTE (0x1 << 4) /* Status error enable */
117+
110118
/* FLTRCR control bits */
111119
#define TRSTRT (0x1 << 0) /* translation start */
112120
#define TREND (0x1 << 1) /* translation end */
@@ -145,6 +153,7 @@ struct sh_flctl {
145153
uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */
146154
uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */
147155
uint32_t flcmncr_base; /* base value of FLCMNCR */
156+
uint32_t flintdmacr_base; /* irq enable bits */
148157

149158
int hwecc_cant_correct[4];
150159

0 commit comments

Comments
 (0)