diff options
author | Julia Lawall <julia@diku.dk> | 2008-06-23 14:14:52 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-06-30 21:28:17 -0400 |
commit | 73f38fe1b563a9d23ffacbda7b51decf41b0c49c (patch) | |
tree | 37e228071b05696350bc015f26a5a9270dde927f /drivers | |
parent | 178f8d78fdeaace8b22a759a059b74f39caf23a4 (diff) |
drivers/macintosh/smu.c: Improve error handling
This makes two changes:
* As noted by Akinobu Mita in patch
b1fceac2b9e04d278316b2faddf276015fc06e3b, alloc_bootmem never returns NULL
and always returns a zeroed region of memory. Thus the error checking code
and memset after the call to alloc_bootmem are not necessary.
* The old error handling code consisted of setting a global variable to
NULL and returning an error code, which could cause previously allocated
resources never to be freed. The patch adds calls to appropriate resource
deallocation functions.
Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/macintosh/smu.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 1272184a3a6f..76dbf25cb70f 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -474,6 +474,7 @@ int __init smu_init (void) | |||
474 | { | 474 | { |
475 | struct device_node *np; | 475 | struct device_node *np; |
476 | const u32 *data; | 476 | const u32 *data; |
477 | int ret = 0; | ||
477 | 478 | ||
478 | np = of_find_node_by_type(NULL, "smu"); | 479 | np = of_find_node_by_type(NULL, "smu"); |
479 | if (np == NULL) | 480 | if (np == NULL) |
@@ -483,16 +484,11 @@ int __init smu_init (void) | |||
483 | 484 | ||
484 | if (smu_cmdbuf_abs == 0) { | 485 | if (smu_cmdbuf_abs == 0) { |
485 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); | 486 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
486 | of_node_put(np); | 487 | ret = -EINVAL; |
487 | return -EINVAL; | 488 | goto fail_np; |
488 | } | 489 | } |
489 | 490 | ||
490 | smu = alloc_bootmem(sizeof(struct smu_device)); | 491 | smu = alloc_bootmem(sizeof(struct smu_device)); |
491 | if (smu == NULL) { | ||
492 | of_node_put(np); | ||
493 | return -ENOMEM; | ||
494 | } | ||
495 | memset(smu, 0, sizeof(*smu)); | ||
496 | 492 | ||
497 | spin_lock_init(&smu->lock); | 493 | spin_lock_init(&smu->lock); |
498 | INIT_LIST_HEAD(&smu->cmd_list); | 494 | INIT_LIST_HEAD(&smu->cmd_list); |
@@ -510,14 +506,14 @@ int __init smu_init (void) | |||
510 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); | 506 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); |
511 | if (smu->db_node == NULL) { | 507 | if (smu->db_node == NULL) { |
512 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); | 508 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); |
513 | goto fail; | 509 | ret = -ENXIO; |
510 | goto fail_bootmem; | ||
514 | } | 511 | } |
515 | data = of_get_property(smu->db_node, "reg", NULL); | 512 | data = of_get_property(smu->db_node, "reg", NULL); |
516 | if (data == NULL) { | 513 | if (data == NULL) { |
517 | of_node_put(smu->db_node); | ||
518 | smu->db_node = NULL; | ||
519 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); | 514 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); |
520 | goto fail; | 515 | ret = -ENXIO; |
516 | goto fail_db_node; | ||
521 | } | 517 | } |
522 | 518 | ||
523 | /* Current setup has one doorbell GPIO that does both doorbell | 519 | /* Current setup has one doorbell GPIO that does both doorbell |
@@ -551,7 +547,8 @@ int __init smu_init (void) | |||
551 | smu->db_buf = ioremap(0x8000860c, 0x1000); | 547 | smu->db_buf = ioremap(0x8000860c, 0x1000); |
552 | if (smu->db_buf == NULL) { | 548 | if (smu->db_buf == NULL) { |
553 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); | 549 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); |
554 | goto fail; | 550 | ret = -ENXIO; |
551 | goto fail_msg_node; | ||
555 | } | 552 | } |
556 | 553 | ||
557 | /* U3 has an issue with NAP mode when issuing SMU commands */ | 554 | /* U3 has an issue with NAP mode when issuing SMU commands */ |
@@ -562,10 +559,17 @@ int __init smu_init (void) | |||
562 | sys_ctrler = SYS_CTRLER_SMU; | 559 | sys_ctrler = SYS_CTRLER_SMU; |
563 | return 0; | 560 | return 0; |
564 | 561 | ||
565 | fail: | 562 | fail_msg_node: |
563 | if (smu->msg_node) | ||
564 | of_node_put(smu->msg_node); | ||
565 | fail_db_node: | ||
566 | of_node_put(smu->db_node); | ||
567 | fail_bootmem: | ||
568 | free_bootmem((unsigned long)smu, sizeof(struct smu_device)); | ||
566 | smu = NULL; | 569 | smu = NULL; |
567 | return -ENXIO; | 570 | fail_np: |
568 | 571 | of_node_put(np); | |
572 | return ret; | ||
569 | } | 573 | } |
570 | 574 | ||
571 | 575 | ||