aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/fsmc_nand.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 5af4b3c122f5..205b10b9f9b9 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -31,6 +31,7 @@
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/mtd/fsmc.h> 33#include <linux/mtd/fsmc.h>
34#include <linux/amba/bus.h>
34#include <mtd/mtd-abi.h> 35#include <mtd/mtd-abi.h>
35 36
36static struct nand_ecclayout fsmc_ecc1_layout = { 37static struct nand_ecclayout fsmc_ecc1_layout = {
@@ -184,8 +185,9 @@ const char *part_probes[] = { "cmdlinepart", NULL };
184#endif 185#endif
185 186
186/** 187/**
187 * struct fsmc_nand_data - atructure for FSMC NAND device state 188 * struct fsmc_nand_data - structure for FSMC NAND device state
188 * 189 *
190 * @pid: Part ID on the AMBA PrimeCell format
189 * @mtd: MTD info for a NAND flash. 191 * @mtd: MTD info for a NAND flash.
190 * @nand: Chip related info for a NAND flash. 192 * @nand: Chip related info for a NAND flash.
191 * @partitions: Partition info for a NAND Flash. 193 * @partitions: Partition info for a NAND Flash.
@@ -201,6 +203,7 @@ const char *part_probes[] = { "cmdlinepart", NULL };
201 * @regs_va: FSMC regs base address. 203 * @regs_va: FSMC regs base address.
202 */ 204 */
203struct fsmc_nand_data { 205struct fsmc_nand_data {
206 u32 pid;
204 struct mtd_info mtd; 207 struct mtd_info mtd;
205 struct nand_chip nand; 208 struct nand_chip nand;
206 struct mtd_partition *partitions; 209 struct mtd_partition *partitions;
@@ -541,6 +544,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
541 struct fsmc_regs *regs; 544 struct fsmc_regs *regs;
542 struct resource *res; 545 struct resource *res;
543 int ret = 0; 546 int ret = 0;
547 u32 pid;
548 int i;
544 549
545 if (!pdata) { 550 if (!pdata) {
546 dev_err(&pdev->dev, "platform data is NULL\n"); 551 dev_err(&pdev->dev, "platform data is NULL\n");
@@ -630,6 +635,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
630 if (ret) 635 if (ret)
631 goto err_probe1; 636 goto err_probe1;
632 637
638 /*
639 * This device ID is actually a common AMBA ID as used on the
640 * AMBA PrimeCell bus. However it is not a PrimeCell.
641 */
642 for (pid = 0, i = 0; i < 4; i++)
643 pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
644 host->pid = pid;
645 dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, "
646 "revision %02x, config %02x\n",
647 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
648 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
649
633 host->bank = pdata->bank; 650 host->bank = pdata->bank;
634 host->select_chip = pdata->select_bank; 651 host->select_chip = pdata->select_bank;
635 regs = host->regs_va; 652 regs = host->regs_va;
@@ -657,7 +674,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
657 674
658 fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16); 675 fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
659 676
660 if (get_fsmc_version(host->regs_va) == FSMC_VER8) { 677 if (AMBA_REV_BITS(host->pid) >= 8) {
661 nand->ecc.read_page = fsmc_read_page_hwecc; 678 nand->ecc.read_page = fsmc_read_page_hwecc;
662 nand->ecc.calculate = fsmc_read_hwecc_ecc4; 679 nand->ecc.calculate = fsmc_read_hwecc_ecc4;
663 nand->ecc.correct = fsmc_correct_data; 680 nand->ecc.correct = fsmc_correct_data;
@@ -677,7 +694,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
677 goto err_probe; 694 goto err_probe;
678 } 695 }
679 696
680 if (get_fsmc_version(host->regs_va) == FSMC_VER8) { 697 if (AMBA_REV_BITS(host->pid) >= 8) {
681 if (host->mtd.writesize == 512) { 698 if (host->mtd.writesize == 512) {
682 nand->ecc.layout = &fsmc_ecc4_sp_layout; 699 nand->ecc.layout = &fsmc_ecc4_sp_layout;
683 host->ecc_place = &fsmc_ecc4_sp_place; 700 host->ecc_place = &fsmc_ecc4_sp_place;