mtd: plat_nand: request memory resource before doing ioremap
authorH Hartley Sweeten <hartleys@visionengravers.com>
Mon, 19 Oct 2009 23:45:29 +0000 (19:45 -0400)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Tue, 20 Oct 2009 00:09:59 +0000 (09:09 +0900)
Add a request_mem_region() before doing the ioremap().  Also, use the
resource_size macro instead of doing the end - start + 1 calc by hand.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/nand/plat_nand.c

index 4e16c6f5bdd5a7642b4fff683e2e05e2aadf7267..8d467315f02be00efd5b124f104feed37a8282b0 100644 (file)
@@ -34,7 +34,12 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
 {
        struct platform_nand_data *pdata = pdev->dev.platform_data;
        struct plat_nand_data *data;
-       int res = 0;
+       struct resource *res;
+       int err = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
 
        /* Allocate memory for the device structure (and zero it) */
        data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL);
@@ -43,12 +48,18 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       data->io_base = ioremap(pdev->resource[0].start,
-                               pdev->resource[0].end - pdev->resource[0].start + 1);
+       if (!request_mem_region(res->start, resource_size(res),
+                               dev_name(&pdev->dev))) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               err = -EBUSY;
+               goto out_free;
+       }
+
+       data->io_base = ioremap(res->start, resource_size(res));
        if (data->io_base == NULL) {
                dev_err(&pdev->dev, "ioremap failed\n");
-               kfree(data);
-               return -EIO;
+               err = -EIO;
+               goto out_release_io;
        }
 
        data->chip.priv = &data;
@@ -74,24 +85,24 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
 
        /* Handle any platform specific setup */
        if (pdata->ctrl.probe) {
-               res = pdata->ctrl.probe(pdev);
-               if (res)
+               err = pdata->ctrl.probe(pdev);
+               if (err)
                        goto out;
        }
 
        /* Scan to find existance of the device */
        if (nand_scan(&data->mtd, 1)) {
-               res = -ENXIO;
+               err = -ENXIO;
                goto out;
        }
 
 #ifdef CONFIG_MTD_PARTITIONS
        if (pdata->chip.part_probe_types) {
-               res = parse_mtd_partitions(&data->mtd,
+               err = parse_mtd_partitions(&data->mtd,
                                        pdata->chip.part_probe_types,
                                        &data->parts, 0);
-               if (res > 0) {
-                       add_mtd_partitions(&data->mtd, data->parts, res);
+               if (err > 0) {
+                       add_mtd_partitions(&data->mtd, data->parts, err);
                        return 0;
                }
        }
@@ -99,14 +110,14 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
                pdata->chip.set_parts(data->mtd.size, &pdata->chip);
        if (pdata->chip.partitions) {
                data->parts = pdata->chip.partitions;
-               res = add_mtd_partitions(&data->mtd, data->parts,
+               err = add_mtd_partitions(&data->mtd, data->parts,
                        pdata->chip.nr_partitions);
        } else
 #endif
-       res = add_mtd_device(&data->mtd);
+       err = add_mtd_device(&data->mtd);
 
-       if (!res)
-               return res;
+       if (!err)
+               return err;
 
        nand_release(&data->mtd);
 out:
@@ -114,8 +125,11 @@ out:
                pdata->ctrl.remove(pdev);
        platform_set_drvdata(pdev, NULL);
        iounmap(data->io_base);
+out_release_io:
+       release_mem_region(res->start, resource_size(res));
+out_free:
        kfree(data);
-       return res;
+       return err;
 }
 
 /*
@@ -125,6 +139,9 @@ static int __devexit plat_nand_remove(struct platform_device *pdev)
 {
        struct plat_nand_data *data = platform_get_drvdata(pdev);
        struct platform_nand_data *pdata = pdev->dev.platform_data;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        nand_release(&data->mtd);
 #ifdef CONFIG_MTD_PARTITIONS
@@ -134,6 +151,7 @@ static int __devexit plat_nand_remove(struct platform_device *pdev)
        if (pdata->ctrl.remove)
                pdata->ctrl.remove(pdev);
        iounmap(data->io_base);
+       release_mem_region(res->start, resource_size(res));
        kfree(data);
 
        return 0;