aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/atmel_nand.c
diff options
context:
space:
mode:
authorHåvard Skinnemoen <haavard.skinnemoen@atmel.com>2008-06-06 12:04:54 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2008-06-07 03:43:11 -0400
commitcc0c72e173db70a3a864994b05ebbe59b79b888f (patch)
tree5d898582e8266251c135a786fcb59a1fe3048629 /drivers/mtd/nand/atmel_nand.c
parent3c3796cc32b6e53653a5eb868dc959b8c2779db9 (diff)
[MTD] [NAND] atmel_nand: Clean up and fix probe() error path
This fixes several bugs in the atmel_nand_probe() error path, including at least one memory leak. Signed-off-by: Håvard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/nand/atmel_nand.c')
-rw-r--r--drivers/mtd/nand/atmel_nand.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 675a82ca77f..325ce29f53f 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)
371 int num_partitions = 0; 371 int num_partitions = 0;
372#endif 372#endif
373 373
374 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
375 if (!mem) {
376 printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
377 return -ENXIO;
378 }
379
374 /* Allocate memory for the device structure (and zero it) */ 380 /* Allocate memory for the device structure (and zero it) */
375 host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL); 381 host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
376 if (!host) { 382 if (!host) {
@@ -378,17 +384,11 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
378 return -ENOMEM; 384 return -ENOMEM;
379 } 385 }
380 386
381 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
382 if (!mem) {
383 printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
384 return -ENXIO;
385 }
386
387 host->io_base = ioremap(mem->start, mem->end - mem->start + 1); 387 host->io_base = ioremap(mem->start, mem->end - mem->start + 1);
388 if (host->io_base == NULL) { 388 if (host->io_base == NULL) {
389 printk(KERN_ERR "atmel_nand: ioremap failed\n"); 389 printk(KERN_ERR "atmel_nand: ioremap failed\n");
390 kfree(host); 390 res = -EIO;
391 return -EIO; 391 goto err_nand_ioremap;
392 } 392 }
393 393
394 mtd = &host->mtd; 394 mtd = &host->mtd;
@@ -446,14 +446,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
446 if (gpio_get_value(host->board->det_pin)) { 446 if (gpio_get_value(host->board->det_pin)) {
447 printk ("No SmartMedia card inserted.\n"); 447 printk ("No SmartMedia card inserted.\n");
448 res = ENXIO; 448 res = ENXIO;
449 goto out; 449 goto err_no_card;
450 } 450 }
451 } 451 }
452 452
453 /* first scan to find the device and get the page size */ 453 /* first scan to find the device and get the page size */
454 if (nand_scan_ident(mtd, 1)) { 454 if (nand_scan_ident(mtd, 1)) {
455 res = -ENXIO; 455 res = -ENXIO;
456 goto out; 456 goto err_scan_ident;
457 } 457 }
458 458
459 if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { 459 if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) {
@@ -498,7 +498,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
498 /* second phase scan */ 498 /* second phase scan */
499 if (nand_scan_tail(mtd)) { 499 if (nand_scan_tail(mtd)) {
500 res = -ENXIO; 500 res = -ENXIO;
501 goto out; 501 goto err_scan_tail;
502 } 502 }
503 503
504#ifdef CONFIG_MTD_PARTITIONS 504#ifdef CONFIG_MTD_PARTITIONS
@@ -514,7 +514,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
514 if ((!partitions) || (num_partitions == 0)) { 514 if ((!partitions) || (num_partitions == 0)) {
515 printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); 515 printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n");
516 res = ENXIO; 516 res = ENXIO;
517 goto release; 517 goto err_no_partitions;
518 } 518 }
519 519
520 res = add_mtd_partitions(mtd, partitions, num_partitions); 520 res = add_mtd_partitions(mtd, partitions, num_partitions);
@@ -526,17 +526,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
526 return res; 526 return res;
527 527
528#ifdef CONFIG_MTD_PARTITIONS 528#ifdef CONFIG_MTD_PARTITIONS
529release: 529err_no_partitions:
530#endif 530#endif
531 nand_release(mtd); 531 nand_release(mtd);
532 532err_scan_tail:
533out: 533err_scan_ident:
534 iounmap(host->ecc); 534err_no_card:
535
536err_ecc_ioremap:
537 atmel_nand_disable(host); 535 atmel_nand_disable(host);
538 platform_set_drvdata(pdev, NULL); 536 platform_set_drvdata(pdev, NULL);
537 if (host->ecc)
538 iounmap(host->ecc);
539err_ecc_ioremap:
539 iounmap(host->io_base); 540 iounmap(host->io_base);
541err_nand_ioremap:
540 kfree(host); 542 kfree(host);
541 return res; 543 return res;
542} 544}
@@ -553,8 +555,9 @@ static int __devexit atmel_nand_remove(struct platform_device *pdev)
553 555
554 atmel_nand_disable(host); 556 atmel_nand_disable(host);
555 557
558 if (host->ecc)
559 iounmap(host->ecc);
556 iounmap(host->io_base); 560 iounmap(host->io_base);
557 iounmap(host->ecc);
558 kfree(host); 561 kfree(host);
559 562
560 return 0; 563 return 0;