]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mtd/nand/fsl_upm.c
Merge branches 'topic/fix/asoc', 'topic/fix/hda', 'topic/fix/misc' and 'topic/pci...
[linux-2.6-omap-h63xx.git] / drivers / mtd / nand / fsl_upm.c
index 1ebfd87f00b401de487f65836aac60e810bf5214..024e3fffd4bb49b6176af4701c07e344120a3fc2 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
@@ -36,8 +37,6 @@ struct fsl_upm_nand {
        uint8_t upm_cmd_offset;
        void __iomem *io_base;
        int rnb_gpio;
-       const uint32_t *wait_pattern;
-       const uint32_t *wait_write;
        int chip_delay;
 };
 
@@ -61,10 +60,11 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
        if (fun->rnb_gpio >= 0) {
                while (--cnt && !fun_chip_ready(&fun->mtd))
                        cpu_relax();
+               if (!cnt)
+                       dev_err(fun->dev, "tired waiting for RNB\n");
+       } else {
+               ndelay(100);
        }
-
-       if (!cnt)
-               dev_err(fun->dev, "tired waiting for RNB\n");
 }
 
 static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
@@ -89,8 +89,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 
        fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
 
-       if (fun->wait_pattern)
-               fun_wait_rnb(fun);
+       fun_wait_rnb(fun);
 }
 
 static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -116,14 +115,16 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
        for (i = 0; i < len; i++) {
                out_8(fun->chip.IO_ADDR_W, buf[i]);
-               if (fun->wait_write)
-                       fun_wait_rnb(fun);
+               fun_wait_rnb(fun);
        }
 }
 
-static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
+static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
+                                  const struct device_node *upm_np,
+                                  const struct resource *io_res)
 {
        int ret;
+       struct device_node *flash_np;
 #ifdef CONFIG_MTD_PARTITIONS
        static const char *part_types[] = { "cmdlinepart", NULL, };
 #endif
@@ -143,18 +144,37 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
        fun->mtd.priv = &fun->chip;
        fun->mtd.owner = THIS_MODULE;
 
+       flash_np = of_get_next_child(upm_np, NULL);
+       if (!flash_np)
+               return -ENODEV;
+
+       fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start,
+                                 flash_np->name);
+       if (!fun->mtd.name) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
        ret = nand_scan(&fun->mtd, 1);
        if (ret)
-               return ret;
-
-       fun->mtd.name = fun->dev->bus_id;
+               goto err;
 
 #ifdef CONFIG_MTD_PARTITIONS
        ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
+
+#ifdef CONFIG_MTD_OF_PARTS
+       if (ret == 0)
+               ret = of_mtd_parse_partitions(fun->dev, &fun->mtd,
+                                             flash_np, &fun->parts);
+#endif
        if (ret > 0)
-               return add_mtd_partitions(&fun->mtd, fun->parts, ret);
+               ret = add_mtd_partitions(&fun->mtd, fun->parts, ret);
+       else
 #endif
-       return add_mtd_device(&fun->mtd);
+               ret = add_mtd_device(&fun->mtd);
+err:
+       of_node_put(flash_np);
+       return ret;
 }
 
 static int __devinit fun_probe(struct of_device *ofdev,
@@ -211,6 +231,12 @@ static int __devinit fun_probe(struct of_device *ofdev,
                goto err2;
        }
 
+       prop = of_get_property(ofdev->node, "chip-delay", NULL);
+       if (prop)
+               fun->chip_delay = *prop;
+       else
+               fun->chip_delay = 50;
+
        fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
                                          io_res.end - io_res.start + 1);
        if (!fun->io_base) {
@@ -220,17 +246,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
 
        fun->dev = &ofdev->dev;
        fun->last_ctrl = NAND_CLE;
-       fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern",
-                                           NULL);
-       fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL);
-
-       prop = of_get_property(ofdev->node, "chip-delay", NULL);
-       if (prop)
-               fun->chip_delay = *prop;
-       else
-               fun->chip_delay = 50;
 
-       ret = fun_chip_init(fun);
+       ret = fun_chip_init(fun, ofdev->node, &io_res);
        if (ret)
                goto err2;
 
@@ -251,6 +268,7 @@ static int __devexit fun_remove(struct of_device *ofdev)
        struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
 
        nand_release(&fun->mtd);
+       kfree(fun->mtd.name);
 
        if (fun->rnb_gpio >= 0)
                gpio_free(fun->rnb_gpio);