diff options
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 23 |
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 | ||
36 | static struct nand_ecclayout fsmc_ecc1_layout = { | 37 | static 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 | */ |
203 | struct fsmc_nand_data { | 205 | struct 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; |