From 1ff184225b15930ea118ac2130f074c741d34f08 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:44:27 -0700 Subject: [MTD] [NAND] fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable MTD NAND platform drivers, to re-enable auto loading. NOTE: at91_nand for some reason disallows modular builds. I'm assuming that's just an oversight that will be fixed. [dbrownell@users.sourceforge.net: minor fix] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 9260ad947524..f3fa1be22ddf 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -927,3 +927,6 @@ module_exit(s3c2410_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks "); MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); +MODULE_ALIAS("platform:s3c2410-nand"); +MODULE_ALIAS("platform:s3c2412-nand"); +MODULE_ALIAS("platform:s3c2440-nand"); -- cgit v1.2.3 From 0916083210039bf3d186a87522cc806dc21b7097 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:18 +0100 Subject: [MTD] [NAND] S3C2410 Fix previous nFCE suspend save patch Commit 03680b1e00d146df718c8a4eac34438566b70c85 incorrectly was assuming S3C2410_NFCONF was being used to select the NAND chip. Fix this error by ising the sel_reg. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index f3fa1be22ddf..8557c68dbb42 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -119,8 +119,7 @@ struct s3c2410_nand_info { void __iomem *sel_reg; int sel_bit; int mtd_count; - - unsigned long save_nfconf; + unsigned long save_sel; enum s3c_cpu_type cpu_type; }; @@ -810,15 +809,14 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) struct s3c2410_nand_info *info = platform_get_drvdata(dev); if (info) { - info->save_nfconf = readl(info->regs + S3C2410_NFCONF); + info->save_sel = readl(info->sel_reg); /* For the moment, we must ensure nFCE is high during * the time we are suspended. This really should be * handled by suspending the MTDs we are using, but * that is currently not the case. */ - writel(info->save_nfconf | info->sel_bit, - info->regs + S3C2410_NFCONF); + writel(info->save_sel | info->sel_bit, info->sel_reg); if (!allow_clk_stop(info)) clk_disable(info->clk); @@ -830,7 +828,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) static int s3c24xx_nand_resume(struct platform_device *dev) { struct s3c2410_nand_info *info = platform_get_drvdata(dev); - unsigned long nfconf; + unsigned long sel; if (info) { clk_enable(info->clk); @@ -838,10 +836,10 @@ static int s3c24xx_nand_resume(struct platform_device *dev) /* Restore the state of the nFCE line. */ - nfconf = readl(info->regs + S3C2410_NFCONF); - nfconf &= ~info->sel_bit; - nfconf |= info->save_nfconf & info->sel_bit; - writel(nfconf, info->regs + S3C2410_NFCONF); + sel = readl(info->sel_reg); + sel &= ~info->sel_bit; + sel |= info->save_sel & info->sel_bit; + writel(sel, info->sel_reg); if (allow_clk_stop(info)) clk_disable(info->clk); -- cgit v1.2.3 From 71d54f3855b4ca98559e8782350336ec2433cc24 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:19 +0100 Subject: [MTD] [NAND] S3C2410 Large page NAND support This adds support for using large page NAND devices with the S3C24XX NAND controller. This also adds the file Documentation/arm/Samsung-S3C24XX/NAND.txt to describe the differences. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 8557c68dbb42..15397e0f3965 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -472,7 +472,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u ecc_code[1] = ecc >> 8; ecc_code[2] = ecc >> 16; - pr_debug("%s: returning ecc %06lx\n", __func__, ecc); + pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff); return 0; } @@ -643,9 +643,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.correct = s3c2410_nand_correct_data; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = 512; - chip->ecc.bytes = 3; - chip->ecc.layout = &nand_hw_eccoob; switch (info->cpu_type) { case TYPE_S3C2410: @@ -669,6 +666,34 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, } } +/* s3c2410_nand_update_chip + * + * post-probe chip update, to change any items, such as the + * layout for large page nand + */ + +static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, + struct s3c2410_nand_mtd *nmtd) +{ + struct nand_chip *chip = &nmtd->chip; + + printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift); + + if (hardware_ecc) { + /* change the behaviour depending on wether we are using + * the large or small page nand device */ + + if (chip->page_shift > 10) { + chip->ecc.size = 256; + chip->ecc.bytes = 3; + } else { + chip->ecc.size = 512; + chip->ecc.bytes = 3; + chip->ecc.layout = &nand_hw_eccoob; + } + } +} + /* s3c2410_nand_probe * * called by device layer when it finds a device matching @@ -775,9 +800,12 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, s3c2410_nand_init_chip(info, nmtd, sets); - nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1); + nmtd->scan_res = nand_scan_ident(&nmtd->mtd, + (sets) ? sets->nr_chips : 1); if (nmtd->scan_res == 0) { + s3c2410_nand_update_chip(info, nmtd); + nand_scan_tail(&nmtd->mtd); s3c2410_nand_add_partition(info, nmtd, sets); } -- cgit v1.2.3 From c45c6c68333c04de84c21a4b869f36a96f642779 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:20 +0100 Subject: [MTD] [NAND] S3C2410 Allow unset ecc to be ignored for ecc correction If a block's ecc field is all 0xff, then ignore the ECC correction. This is for systems where some of the blocks, such as the initial cramfs are written without ECC and need to be loaded on start. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 15397e0f3965..35401f7b9302 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -357,6 +357,14 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, if (diff0 == 0 && diff1 == 0 && diff2 == 0) return 0; /* ECC is ok */ + /* sometimes people do not think about using the ECC, so check + * to see if we have an 0xff,0xff,0xff read ECC and then ignore + * the error, on the assumption that this is an un-eccd page. + */ + if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff + && info->platform->ignore_unset_ecc) + return 0; + /* Can we correct this ECC (ie, one row and column change). * Note, this is similar to the 256 error code on smartmedia */ -- cgit v1.2.3 From 1c21ab67b7d3c9a1296019939e0efb69350487cf Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:21 +0100 Subject: [MTD] [NAND] S3C2410 Allow ECC layout to be passed through platform data Add support for the ECC layout to be passed via the platform data specified by the board. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 35401f7b9302..ccacc40e64ee 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -672,6 +672,9 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, } else { chip->ecc.mode = NAND_ECC_SOFT; } + + if (set->ecc_layout != NULL) + chip->ecc.layout = set->ecc_layout; } /* s3c2410_nand_update_chip -- cgit v1.2.3 From 37e5ffa3f15bd9a8b133ab13e9bef833b5eb33d4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:22 +0100 Subject: [MTD] [NAND] S3C2410 Allow ECC disable to be specified by the board Add support to disable ECC checking for a given chip when passed by the board via the platform data. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index ccacc40e64ee..b34a460ab679 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -675,6 +675,9 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, if (set->ecc_layout != NULL) chip->ecc.layout = set->ecc_layout; + + if (set->disable_ecc) + chip->ecc.mode = NAND_ECC_NONE; } /* s3c2410_nand_update_chip -- cgit v1.2.3