[PATCH 4/8] atmel_nand: Clean up and fix probe() error path
Haavard Skinnemoen
haavard.skinnemoen at atmel.com
Fri Jun 6 12:04:54 EDT 2008
This fixes several bugs in the atmel_nand_probe() error path, including
at least one memory leak.
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
---
drivers/mtd/nand/atmel_nand.c | 41 ++++++++++++++++++++++-------------------
1 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 675a82c..325ce29 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -371,6 +371,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
int num_partitions = 0;
#endif
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
+ return -ENXIO;
+ }
+
/* Allocate memory for the device structure (and zero it) */
host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
if (!host) {
@@ -378,17 +384,11 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
return -ENOMEM;
}
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
- return -ENXIO;
- }
-
host->io_base = ioremap(mem->start, mem->end - mem->start + 1);
if (host->io_base == NULL) {
printk(KERN_ERR "atmel_nand: ioremap failed\n");
- kfree(host);
- return -EIO;
+ res = -EIO;
+ goto err_nand_ioremap;
}
mtd = &host->mtd;
@@ -446,14 +446,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
if (gpio_get_value(host->board->det_pin)) {
printk ("No SmartMedia card inserted.\n");
res = ENXIO;
- goto out;
+ goto err_no_card;
}
}
/* first scan to find the device and get the page size */
if (nand_scan_ident(mtd, 1)) {
res = -ENXIO;
- goto out;
+ goto err_scan_ident;
}
if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) {
@@ -498,7 +498,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
/* second phase scan */
if (nand_scan_tail(mtd)) {
res = -ENXIO;
- goto out;
+ goto err_scan_tail;
}
#ifdef CONFIG_MTD_PARTITIONS
@@ -514,7 +514,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
if ((!partitions) || (num_partitions == 0)) {
printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n");
res = ENXIO;
- goto release;
+ goto err_no_partitions;
}
res = add_mtd_partitions(mtd, partitions, num_partitions);
@@ -526,17 +526,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
return res;
#ifdef CONFIG_MTD_PARTITIONS
-release:
+err_no_partitions:
#endif
nand_release(mtd);
-
-out:
- iounmap(host->ecc);
-
-err_ecc_ioremap:
+err_scan_tail:
+err_scan_ident:
+err_no_card:
atmel_nand_disable(host);
platform_set_drvdata(pdev, NULL);
+ if (host->ecc)
+ iounmap(host->ecc);
+err_ecc_ioremap:
iounmap(host->io_base);
+err_nand_ioremap:
kfree(host);
return res;
}
@@ -553,8 +555,9 @@ static int __devexit atmel_nand_remove(struct platform_device *pdev)
atmel_nand_disable(host);
+ if (host->ecc)
+ iounmap(host->ecc);
iounmap(host->io_base);
- iounmap(host->ecc);
kfree(host);
return 0;
--
1.5.5.1
More information about the linux-mtd
mailing list