unsigned int            buf_start;
        unsigned int            buf_count;
 
+       struct mtd_info         *mtd;
        /* DMA information */
        int                     drcmr_dat;
        int                     drcmr_cmd;
        this->chip_delay = 25;
 }
 
-static int pxa3xx_nand_probe(struct platform_device *pdev)
+static
+struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
 {
-       struct pxa3xx_nand_platform_data *pdata;
+       struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
        struct pxa3xx_nand_info *info;
-       struct nand_chip *this;
        struct mtd_info *mtd;
        struct resource *r;
-       int ret = 0, irq;
-
-       pdata = pdev->dev.platform_data;
-
-       if (!pdata) {
-               dev_err(&pdev->dev, "no platform data defined\n");
-               return -ENODEV;
-       }
+       int ret, irq;
 
        mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info),
                        GFP_KERNEL);
        if (!mtd) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
-               return -ENOMEM;
+               return NULL;
        }
 
        info = (struct pxa3xx_nand_info *)(&mtd[1]);
        info->pdev = pdev;
 
-       this = &info->nand_chip;
        mtd->priv = info;
+       info->mtd = mtd;
        mtd->owner = THIS_MODULE;
 
        info->clk = clk_get(&pdev->dev, NULL);
        }
 
        pxa3xx_nand_init_mtd(mtd, info);
+       platform_set_drvdata(pdev, info);
 
-       platform_set_drvdata(pdev, mtd);
-
-       if (nand_scan(mtd, 1)) {
-               dev_err(&pdev->dev, "failed to scan nand\n");
-               ret = -ENXIO;
-               goto fail_free_irq;
-       }
-
-#ifdef CONFIG_MTD_PARTITIONS
-       if (mtd_has_cmdlinepart()) {
-               static const char *probes[] = { "cmdlinepart", NULL };
-               struct mtd_partition *parts;
-               int nr_parts;
-
-               nr_parts = parse_mtd_partitions(mtd, probes, &parts, 0);
-
-               if (nr_parts)
-                       return add_mtd_partitions(mtd, parts, nr_parts);
-       }
-
-       return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
-#else
-       return 0;
-#endif
+       return info;
 
 fail_free_irq:
        free_irq(irq, info);
        clk_put(info->clk);
 fail_free_mtd:
        kfree(mtd);
-       return ret;
+       return NULL;
 }
 
 static int pxa3xx_nand_remove(struct platform_device *pdev)
 {
-       struct mtd_info *mtd = platform_get_drvdata(pdev);
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+       struct mtd_info *mtd = info->mtd;
        struct resource *r;
        int irq;
 
        return 0;
 }
 
+static int pxa3xx_nand_probe(struct platform_device *pdev)
+{
+       struct pxa3xx_nand_platform_data *pdata;
+       struct pxa3xx_nand_info *info;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
+               dev_err(&pdev->dev, "no platform data defined\n");
+               return -ENODEV;
+       }
+
+       info = alloc_nand_resource(pdev);
+       if (info == NULL)
+               return -ENOMEM;
+
+       if (nand_scan(info->mtd, 1)) {
+               dev_err(&pdev->dev, "failed to scan nand\n");
+               pxa3xx_nand_remove(pdev);
+               return -ENODEV;
+       }
+
+#ifdef CONFIG_MTD_PARTITIONS
+       if (mtd_has_cmdlinepart()) {
+               const char *probes[] = { "cmdlinepart", NULL };
+               struct mtd_partition *parts;
+               int nr_parts;
+
+               nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0);
+
+               if (nr_parts)
+                       return add_mtd_partitions(mtd, parts, nr_parts);
+       }
+
+       return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
+#else
+       return 0;
+#endif
+}
+
 #ifdef CONFIG_PM
 static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev);
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+       struct mtd_info *mtd = info->mtd;
 
        if (info->state != STATE_READY) {
                dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
 
 static int pxa3xx_nand_resume(struct platform_device *pdev)
 {
-       struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev);
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+       struct mtd_info *mtd = info->mtd;
 
        nand_writel(info, NDTR0CS0, info->ndtr0cs0);
        nand_writel(info, NDTR1CS0, info->ndtr1cs0);