diff options
Diffstat (limited to 'drivers/macintosh/smu.c')
-rw-r--r-- | drivers/macintosh/smu.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 77ad192962c5..96faa799b82a 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * the userland interface | 19 | * the userland interface |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/smp_lock.h> | ||
22 | #include <linux/types.h> | 23 | #include <linux/types.h> |
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
24 | #include <linux/device.h> | 25 | #include <linux/device.h> |
@@ -35,6 +36,8 @@ | |||
35 | #include <linux/sysdev.h> | 36 | #include <linux/sysdev.h> |
36 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
37 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/of_device.h> | ||
40 | #include <linux/of_platform.h> | ||
38 | 41 | ||
39 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
40 | #include <asm/io.h> | 43 | #include <asm/io.h> |
@@ -45,8 +48,6 @@ | |||
45 | #include <asm/sections.h> | 48 | #include <asm/sections.h> |
46 | #include <asm/abs_addr.h> | 49 | #include <asm/abs_addr.h> |
47 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
48 | #include <asm/of_device.h> | ||
49 | #include <asm/of_platform.h> | ||
50 | 51 | ||
51 | #define VERSION "0.7" | 52 | #define VERSION "0.7" |
52 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." | 53 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." |
@@ -474,6 +475,7 @@ int __init smu_init (void) | |||
474 | { | 475 | { |
475 | struct device_node *np; | 476 | struct device_node *np; |
476 | const u32 *data; | 477 | const u32 *data; |
478 | int ret = 0; | ||
477 | 479 | ||
478 | np = of_find_node_by_type(NULL, "smu"); | 480 | np = of_find_node_by_type(NULL, "smu"); |
479 | if (np == NULL) | 481 | if (np == NULL) |
@@ -483,13 +485,11 @@ int __init smu_init (void) | |||
483 | 485 | ||
484 | if (smu_cmdbuf_abs == 0) { | 486 | if (smu_cmdbuf_abs == 0) { |
485 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); | 487 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
486 | return -EINVAL; | 488 | ret = -EINVAL; |
489 | goto fail_np; | ||
487 | } | 490 | } |
488 | 491 | ||
489 | smu = alloc_bootmem(sizeof(struct smu_device)); | 492 | smu = alloc_bootmem(sizeof(struct smu_device)); |
490 | if (smu == NULL) | ||
491 | return -ENOMEM; | ||
492 | memset(smu, 0, sizeof(*smu)); | ||
493 | 493 | ||
494 | spin_lock_init(&smu->lock); | 494 | spin_lock_init(&smu->lock); |
495 | INIT_LIST_HEAD(&smu->cmd_list); | 495 | INIT_LIST_HEAD(&smu->cmd_list); |
@@ -507,14 +507,14 @@ int __init smu_init (void) | |||
507 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); | 507 | smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); |
508 | if (smu->db_node == NULL) { | 508 | if (smu->db_node == NULL) { |
509 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); | 509 | printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); |
510 | goto fail; | 510 | ret = -ENXIO; |
511 | goto fail_bootmem; | ||
511 | } | 512 | } |
512 | data = of_get_property(smu->db_node, "reg", NULL); | 513 | data = of_get_property(smu->db_node, "reg", NULL); |
513 | if (data == NULL) { | 514 | if (data == NULL) { |
514 | of_node_put(smu->db_node); | ||
515 | smu->db_node = NULL; | ||
516 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); | 515 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); |
517 | goto fail; | 516 | ret = -ENXIO; |
517 | goto fail_db_node; | ||
518 | } | 518 | } |
519 | 519 | ||
520 | /* Current setup has one doorbell GPIO that does both doorbell | 520 | /* Current setup has one doorbell GPIO that does both doorbell |
@@ -548,7 +548,8 @@ int __init smu_init (void) | |||
548 | smu->db_buf = ioremap(0x8000860c, 0x1000); | 548 | smu->db_buf = ioremap(0x8000860c, 0x1000); |
549 | if (smu->db_buf == NULL) { | 549 | if (smu->db_buf == NULL) { |
550 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); | 550 | printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); |
551 | goto fail; | 551 | ret = -ENXIO; |
552 | goto fail_msg_node; | ||
552 | } | 553 | } |
553 | 554 | ||
554 | /* U3 has an issue with NAP mode when issuing SMU commands */ | 555 | /* U3 has an issue with NAP mode when issuing SMU commands */ |
@@ -559,10 +560,17 @@ int __init smu_init (void) | |||
559 | sys_ctrler = SYS_CTRLER_SMU; | 560 | sys_ctrler = SYS_CTRLER_SMU; |
560 | return 0; | 561 | return 0; |
561 | 562 | ||
562 | fail: | 563 | fail_msg_node: |
564 | if (smu->msg_node) | ||
565 | of_node_put(smu->msg_node); | ||
566 | fail_db_node: | ||
567 | of_node_put(smu->db_node); | ||
568 | fail_bootmem: | ||
569 | free_bootmem((unsigned long)smu, sizeof(struct smu_device)); | ||
563 | smu = NULL; | 570 | smu = NULL; |
564 | return -ENXIO; | 571 | fail_np: |
565 | 572 | of_node_put(np); | |
573 | return ret; | ||
566 | } | 574 | } |
567 | 575 | ||
568 | 576 | ||
@@ -1083,10 +1091,12 @@ static int smu_open(struct inode *inode, struct file *file) | |||
1083 | pp->mode = smu_file_commands; | 1091 | pp->mode = smu_file_commands; |
1084 | init_waitqueue_head(&pp->wait); | 1092 | init_waitqueue_head(&pp->wait); |
1085 | 1093 | ||
1094 | lock_kernel(); | ||
1086 | spin_lock_irqsave(&smu_clist_lock, flags); | 1095 | spin_lock_irqsave(&smu_clist_lock, flags); |
1087 | list_add(&pp->list, &smu_clist); | 1096 | list_add(&pp->list, &smu_clist); |
1088 | spin_unlock_irqrestore(&smu_clist_lock, flags); | 1097 | spin_unlock_irqrestore(&smu_clist_lock, flags); |
1089 | file->private_data = pp; | 1098 | file->private_data = pp; |
1099 | unlock_kernel(); | ||
1090 | 1100 | ||
1091 | return 0; | 1101 | return 0; |
1092 | } | 1102 | } |