diff options
Diffstat (limited to 'drivers/macintosh/smu.c')
-rw-r--r-- | drivers/macintosh/smu.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index e8378274d710..db2ae71d07ef 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #undef DEBUG_SMU | 53 | #undef DEBUG_SMU |
54 | 54 | ||
55 | #ifdef DEBUG_SMU | 55 | #ifdef DEBUG_SMU |
56 | #define DPRINTK(fmt, args...) do { udbg_printf(KERN_DEBUG fmt , ##args); } while (0) | 56 | #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) |
57 | #else | 57 | #else |
58 | #define DPRINTK(fmt, args...) do { } while (0) | 58 | #define DPRINTK(fmt, args...) do { } while (0) |
59 | #endif | 59 | #endif |
@@ -94,6 +94,8 @@ struct smu_device { | |||
94 | static struct smu_device *smu; | 94 | static struct smu_device *smu; |
95 | static DECLARE_MUTEX(smu_part_access); | 95 | static DECLARE_MUTEX(smu_part_access); |
96 | 96 | ||
97 | static void smu_i2c_retry(unsigned long data); | ||
98 | |||
97 | /* | 99 | /* |
98 | * SMU driver low level stuff | 100 | * SMU driver low level stuff |
99 | */ | 101 | */ |
@@ -469,7 +471,6 @@ int __init smu_init (void) | |||
469 | smu->of_node = np; | 471 | smu->of_node = np; |
470 | smu->db_irq = NO_IRQ; | 472 | smu->db_irq = NO_IRQ; |
471 | smu->msg_irq = NO_IRQ; | 473 | smu->msg_irq = NO_IRQ; |
472 | init_timer(&smu->i2c_timer); | ||
473 | 474 | ||
474 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a | 475 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a |
475 | * 32 bits value safely | 476 | * 32 bits value safely |
@@ -544,6 +545,10 @@ static int smu_late_init(void) | |||
544 | if (!smu) | 545 | if (!smu) |
545 | return 0; | 546 | return 0; |
546 | 547 | ||
548 | init_timer(&smu->i2c_timer); | ||
549 | smu->i2c_timer.function = smu_i2c_retry; | ||
550 | smu->i2c_timer.data = (unsigned long)smu; | ||
551 | |||
547 | /* | 552 | /* |
548 | * Try to request the interrupts | 553 | * Try to request the interrupts |
549 | */ | 554 | */ |
@@ -570,7 +575,10 @@ static int smu_late_init(void) | |||
570 | 575 | ||
571 | return 0; | 576 | return 0; |
572 | } | 577 | } |
573 | arch_initcall(smu_late_init); | 578 | /* This has to be before arch_initcall as the low i2c stuff relies on the |
579 | * above having been done before we reach arch_initcalls | ||
580 | */ | ||
581 | core_initcall(smu_late_init); | ||
574 | 582 | ||
575 | /* | 583 | /* |
576 | * sysfs visibility | 584 | * sysfs visibility |
@@ -580,20 +588,10 @@ static void smu_expose_childs(void *unused) | |||
580 | { | 588 | { |
581 | struct device_node *np; | 589 | struct device_node *np; |
582 | 590 | ||
583 | for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { | 591 | for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) |
584 | if (device_is_compatible(np, "smu-i2c")) { | ||
585 | char name[32]; | ||
586 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | ||
587 | |||
588 | if (reg == NULL) | ||
589 | continue; | ||
590 | sprintf(name, "smu-i2c-%02x", *reg); | ||
591 | of_platform_device_create(np, name, &smu->of_dev->dev); | ||
592 | } | ||
593 | if (device_is_compatible(np, "smu-sensors")) | 592 | if (device_is_compatible(np, "smu-sensors")) |
594 | of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev); | 593 | of_platform_device_create(np, "smu-sensors", |
595 | } | 594 | &smu->of_dev->dev); |
596 | |||
597 | } | 595 | } |
598 | 596 | ||
599 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); | 597 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); |
@@ -712,13 +710,13 @@ static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail) | |||
712 | 710 | ||
713 | static void smu_i2c_retry(unsigned long data) | 711 | static void smu_i2c_retry(unsigned long data) |
714 | { | 712 | { |
715 | struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data; | 713 | struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur; |
716 | 714 | ||
717 | DPRINTK("SMU: i2c failure, requeuing...\n"); | 715 | DPRINTK("SMU: i2c failure, requeuing...\n"); |
718 | 716 | ||
719 | /* requeue command simply by resetting reply_len */ | 717 | /* requeue command simply by resetting reply_len */ |
720 | cmd->pdata[0] = 0xff; | 718 | cmd->pdata[0] = 0xff; |
721 | cmd->scmd.reply_len = 0x10; | 719 | cmd->scmd.reply_len = sizeof(cmd->pdata); |
722 | smu_queue_cmd(&cmd->scmd); | 720 | smu_queue_cmd(&cmd->scmd); |
723 | } | 721 | } |
724 | 722 | ||
@@ -747,10 +745,8 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) | |||
747 | */ | 745 | */ |
748 | if (fail && --cmd->retries > 0) { | 746 | if (fail && --cmd->retries > 0) { |
749 | DPRINTK("SMU: i2c failure, starting timer...\n"); | 747 | DPRINTK("SMU: i2c failure, starting timer...\n"); |
750 | smu->i2c_timer.function = smu_i2c_retry; | 748 | BUG_ON(cmd != smu->cmd_i2c_cur); |
751 | smu->i2c_timer.data = (unsigned long)cmd; | 749 | mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5)); |
752 | smu->i2c_timer.expires = jiffies + msecs_to_jiffies(5); | ||
753 | add_timer(&smu->i2c_timer); | ||
754 | return; | 750 | return; |
755 | } | 751 | } |
756 | 752 | ||
@@ -764,7 +760,7 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) | |||
764 | 760 | ||
765 | /* Ok, initial command complete, now poll status */ | 761 | /* Ok, initial command complete, now poll status */ |
766 | scmd->reply_buf = cmd->pdata; | 762 | scmd->reply_buf = cmd->pdata; |
767 | scmd->reply_len = 0x10; | 763 | scmd->reply_len = sizeof(cmd->pdata); |
768 | scmd->data_buf = cmd->pdata; | 764 | scmd->data_buf = cmd->pdata; |
769 | scmd->data_len = 1; | 765 | scmd->data_len = 1; |
770 | cmd->pdata[0] = 0; | 766 | cmd->pdata[0] = 0; |
@@ -786,7 +782,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd) | |||
786 | cmd->scmd.done = smu_i2c_low_completion; | 782 | cmd->scmd.done = smu_i2c_low_completion; |
787 | cmd->scmd.misc = cmd; | 783 | cmd->scmd.misc = cmd; |
788 | cmd->scmd.reply_buf = cmd->pdata; | 784 | cmd->scmd.reply_buf = cmd->pdata; |
789 | cmd->scmd.reply_len = 0x10; | 785 | cmd->scmd.reply_len = sizeof(cmd->pdata); |
790 | cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; | 786 | cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; |
791 | cmd->scmd.status = 1; | 787 | cmd->scmd.status = 1; |
792 | cmd->stage = 0; | 788 | cmd->stage = 0; |
@@ -909,10 +905,13 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id) | |||
909 | struct property *prop; | 905 | struct property *prop; |
910 | 906 | ||
911 | /* First query the partition info */ | 907 | /* First query the partition info */ |
908 | DPRINTK("SMU: Query partition infos ... (irq=%d)\n", smu->db_irq); | ||
912 | smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, | 909 | smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, |
913 | smu_done_complete, &comp, | 910 | smu_done_complete, &comp, |
914 | SMU_CMD_PARTITION_LATEST, id); | 911 | SMU_CMD_PARTITION_LATEST, id); |
915 | wait_for_completion(&comp); | 912 | wait_for_completion(&comp); |
913 | DPRINTK("SMU: done, status: %d, reply_len: %d\n", | ||
914 | cmd.cmd.status, cmd.cmd.reply_len); | ||
916 | 915 | ||
917 | /* Partition doesn't exist (or other error) */ | 916 | /* Partition doesn't exist (or other error) */ |
918 | if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) | 917 | if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) |
@@ -975,6 +974,8 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, | |||
975 | 974 | ||
976 | sprintf(pname, "sdb-partition-%02x", id); | 975 | sprintf(pname, "sdb-partition-%02x", id); |
977 | 976 | ||
977 | DPRINTK("smu_get_sdb_partition(%02x)\n", id); | ||
978 | |||
978 | if (interruptible) { | 979 | if (interruptible) { |
979 | int rc; | 980 | int rc; |
980 | rc = down_interruptible(&smu_part_access); | 981 | rc = down_interruptible(&smu_part_access); |
@@ -986,6 +987,7 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, | |||
986 | part = (struct smu_sdbp_header *)get_property(smu->of_node, | 987 | part = (struct smu_sdbp_header *)get_property(smu->of_node, |
987 | pname, size); | 988 | pname, size); |
988 | if (part == NULL) { | 989 | if (part == NULL) { |
990 | DPRINTK("trying to extract from SMU ...\n"); | ||
989 | part = smu_create_sdb_partition(id); | 991 | part = smu_create_sdb_partition(id); |
990 | if (part != NULL && size) | 992 | if (part != NULL && size) |
991 | *size = part->len << 2; | 993 | *size = part->len << 2; |