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.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 96226116a646..9ecd76849e35 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -94,6 +94,8 @@ struct smu_device {
94static struct smu_device *smu; 94static struct smu_device *smu;
95static DECLARE_MUTEX(smu_part_access); 95static DECLARE_MUTEX(smu_part_access);
96 96
97static 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,28 +575,41 @@ static int smu_late_init(void)
570 575
571 return 0; 576 return 0;
572} 577}
573arch_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 */
581core_initcall(smu_late_init);
574 582
575/* 583/*
576 * sysfs visibility 584 * sysfs visibility
577 */ 585 */
578 586
587static void smu_create_i2c(struct device_node *np)
588{
589 char name[32];
590 u32 *reg = (u32 *)get_property(np, "reg", NULL);
591
592 if (reg != NULL) {
593 sprintf(name, "smu-i2c-%02x", *reg);
594 of_platform_device_create(np, name, &smu->of_dev->dev);
595 }
596}
597
579static void smu_expose_childs(void *unused) 598static void smu_expose_childs(void *unused)
580{ 599{
581 struct device_node *np; 600 struct device_node *np, *gp;
582 601
583 for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { 602 for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) {
584 if (device_is_compatible(np, "smu-i2c")) { 603 if (device_is_compatible(np, "smu-i2c-control")) {
585 char name[32]; 604 gp = NULL;
586 u32 *reg = (u32 *)get_property(np, "reg", NULL); 605 while ((gp = of_get_next_child(np, gp)) != NULL)
587 606 if (device_is_compatible(gp, "i2c-bus"))
588 if (reg == NULL) 607 smu_create_i2c(gp);
589 continue; 608 } else if (device_is_compatible(np, "smu-i2c"))
590 sprintf(name, "smu-i2c-%02x", *reg); 609 smu_create_i2c(np);
591 of_platform_device_create(np, name, &smu->of_dev->dev);
592 }
593 if (device_is_compatible(np, "smu-sensors")) 610 if (device_is_compatible(np, "smu-sensors"))
594 of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev); 611 of_platform_device_create(np, "smu-sensors",
612 &smu->of_dev->dev);
595 } 613 }
596 614
597} 615}
@@ -712,13 +730,13 @@ static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail)
712 730
713static void smu_i2c_retry(unsigned long data) 731static void smu_i2c_retry(unsigned long data)
714{ 732{
715 struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data; 733 struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur;
716 734
717 DPRINTK("SMU: i2c failure, requeuing...\n"); 735 DPRINTK("SMU: i2c failure, requeuing...\n");
718 736
719 /* requeue command simply by resetting reply_len */ 737 /* requeue command simply by resetting reply_len */
720 cmd->pdata[0] = 0xff; 738 cmd->pdata[0] = 0xff;
721 cmd->scmd.reply_len = 0x10; 739 cmd->scmd.reply_len = sizeof(cmd->pdata);
722 smu_queue_cmd(&cmd->scmd); 740 smu_queue_cmd(&cmd->scmd);
723} 741}
724 742
@@ -747,10 +765,8 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
747 */ 765 */
748 if (fail && --cmd->retries > 0) { 766 if (fail && --cmd->retries > 0) {
749 DPRINTK("SMU: i2c failure, starting timer...\n"); 767 DPRINTK("SMU: i2c failure, starting timer...\n");
750 smu->i2c_timer.function = smu_i2c_retry; 768 BUG_ON(cmd != smu->cmd_i2c_cur);
751 smu->i2c_timer.data = (unsigned long)cmd; 769 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; 770 return;
755 } 771 }
756 772
@@ -764,7 +780,7 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
764 780
765 /* Ok, initial command complete, now poll status */ 781 /* Ok, initial command complete, now poll status */
766 scmd->reply_buf = cmd->pdata; 782 scmd->reply_buf = cmd->pdata;
767 scmd->reply_len = 0x10; 783 scmd->reply_len = sizeof(cmd->pdata);
768 scmd->data_buf = cmd->pdata; 784 scmd->data_buf = cmd->pdata;
769 scmd->data_len = 1; 785 scmd->data_len = 1;
770 cmd->pdata[0] = 0; 786 cmd->pdata[0] = 0;
@@ -786,7 +802,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd)
786 cmd->scmd.done = smu_i2c_low_completion; 802 cmd->scmd.done = smu_i2c_low_completion;
787 cmd->scmd.misc = cmd; 803 cmd->scmd.misc = cmd;
788 cmd->scmd.reply_buf = cmd->pdata; 804 cmd->scmd.reply_buf = cmd->pdata;
789 cmd->scmd.reply_len = 0x10; 805 cmd->scmd.reply_len = sizeof(cmd->pdata);
790 cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; 806 cmd->scmd.data_buf = (u8 *)(char *)&cmd->info;
791 cmd->scmd.status = 1; 807 cmd->scmd.status = 1;
792 cmd->stage = 0; 808 cmd->stage = 0;