aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh/smu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh/smu.c')
-rw-r--r--drivers/macintosh/smu.c38
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: 563fail_msg_node:
564 if (smu->msg_node)
565 of_node_put(smu->msg_node);
566fail_db_node:
567 of_node_put(smu->db_node);
568fail_bootmem:
569 free_bootmem((unsigned long)smu, sizeof(struct smu_device));
563 smu = NULL; 570 smu = NULL;
564 return -ENXIO; 571fail_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}