]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/mtd/nand/fsmc_nand.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / mtd / nand / fsmc_nand.c
index 02edfba25b0cb6d5ce3e8a3c88c1a405629f5f50..205b10b9f9b9132dd136cc64459ec936665f16e5 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/mtd/fsmc.h>
+#include <linux/amba/bus.h>
 #include <mtd/mtd-abi.h>
 
 static struct nand_ecclayout fsmc_ecc1_layout = {
@@ -119,21 +120,36 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
        }
 };
 
-/*
- * Default partition tables to be used if the partition information not
- * provided through platform data
- */
-#define PARTITION(n, off, sz)  {.name = n, .offset = off, .size = sz}
 
+#ifdef CONFIG_MTD_PARTITIONS
 /*
+ * Default partition tables to be used if the partition information not
+ * provided through platform data.
+ *
  * Default partition layout for small page(= 512 bytes) devices
  * Size for "Root file system" is updated in driver based on actual device size
  */
 static struct mtd_partition partition_info_16KB_blk[] = {
-       PARTITION("X-loader", 0, 4 * 0x4000),
-       PARTITION("U-Boot", 0x10000, 20 * 0x4000),
-       PARTITION("Kernel", 0x60000, 256 * 0x4000),
-       PARTITION("Root File System", 0x460000, 0),
+       {
+               .name = "X-loader",
+               .offset = 0,
+               .size = 4*0x4000,
+       },
+       {
+               .name = "U-Boot",
+               .offset = 0x10000,
+               .size = 20*0x4000,
+       },
+       {
+               .name = "Kernel",
+               .offset = 0x60000,
+               .size = 256*0x4000,
+       },
+       {
+               .name = "Root File System",
+               .offset = 0x460000,
+               .size = 0,
+       },
 };
 
 /*
@@ -141,19 +157,37 @@ static struct mtd_partition partition_info_16KB_blk[] = {
  * Size for "Root file system" is updated in driver based on actual device size
  */
 static struct mtd_partition partition_info_128KB_blk[] = {
-       PARTITION("X-loader", 0, 4 * 0x20000),
-       PARTITION("U-Boot", 0x80000, 12 * 0x20000),
-       PARTITION("Kernel", 0x200000, 48 * 0x20000),
-       PARTITION("Root File System", 0x800000, 0),
+       {
+               .name = "X-loader",
+               .offset = 0,
+               .size = 4*0x20000,
+       },
+       {
+               .name = "U-Boot",
+               .offset = 0x80000,
+               .size = 12*0x20000,
+       },
+       {
+               .name = "Kernel",
+               .offset = 0x200000,
+               .size = 48*0x20000,
+       },
+       {
+               .name = "Root File System",
+               .offset = 0x800000,
+               .size = 0,
+       },
 };
 
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
+#endif
 
 /**
- * struct fsmc_nand_data - atructure for FSMC NAND device state
+ * struct fsmc_nand_data - structure for FSMC NAND device state
  *
+ * @pid:               Part ID on the AMBA PrimeCell format
  * @mtd:               MTD info for a NAND flash.
  * @nand:              Chip related info for a NAND flash.
  * @partitions:                Partition info for a NAND Flash.
@@ -169,6 +203,7 @@ const char *part_probes[] = { "cmdlinepart", NULL };
  * @regs_va:           FSMC regs base address.
  */
 struct fsmc_nand_data {
+       u32                     pid;
        struct mtd_info         mtd;
        struct nand_chip        nand;
        struct mtd_partition    *partitions;
@@ -508,7 +543,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
        struct nand_chip *nand;
        struct fsmc_regs *regs;
        struct resource *res;
-       int nr_parts, ret = 0;
+       int ret = 0;
+       u32 pid;
+       int i;
 
        if (!pdata) {
                dev_err(&pdev->dev, "platform data is NULL\n");
@@ -598,6 +635,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
        if (ret)
                goto err_probe1;
 
+       /*
+        * This device ID is actually a common AMBA ID as used on the
+        * AMBA PrimeCell bus. However it is not a PrimeCell.
+        */
+       for (pid = 0, i = 0; i < 4; i++)
+               pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
+       host->pid = pid;
+       dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, "
+                "revision %02x, config %02x\n",
+                AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
+                AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
+
        host->bank = pdata->bank;
        host->select_chip = pdata->select_bank;
        regs = host->regs_va;
@@ -625,7 +674,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 
        fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
 
-       if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+       if (AMBA_REV_BITS(host->pid) >= 8) {
                nand->ecc.read_page = fsmc_read_page_hwecc;
                nand->ecc.calculate = fsmc_read_hwecc_ecc4;
                nand->ecc.correct = fsmc_correct_data;
@@ -645,7 +694,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
                goto err_probe;
        }
 
-       if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+       if (AMBA_REV_BITS(host->pid) >= 8) {
                if (host->mtd.writesize == 512) {
                        nand->ecc.layout = &fsmc_ecc4_sp_layout;
                        host->ecc_place = &fsmc_ecc4_sp_place;
@@ -676,11 +725,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
         * Check if partition info passed via command line
         */
        host->mtd.name = "nand";
-       nr_parts = parse_mtd_partitions(&host->mtd, part_probes,
+       host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes,
                        &host->partitions, 0);
-       if (nr_parts > 0) {
-               host->nr_partitions = nr_parts;
-       } else {
+       if (host->nr_partitions <= 0) {
 #endif
                /*
                 * Check if partition info passed via command line