aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh/smu.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-01-06 19:30:44 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:47:16 -0500
commit730745a5c45093982112ddc94cee6a9973455641 (patch)
tree1c36bd96c28d08e2b5d839ba3f4e37588aad2328 /drivers/macintosh/smu.c
parent002ec58eb57bac2380f0ed5a4e88121b4bdb32ec (diff)
[PATCH] 1/5 powerpc: Rework PowerMac i2c part 1
This is the first part of a rework of the PowerMac i2c code. It completely reworks the "low_i2c" layer. It is now more flexible, supports KeyWest, SMU and PMU i2c busses, and provides functions to match device nodes to i2c busses and adapters. This patch also extends & fix some bugs in the SMU driver related to i2c support and removes the clock spreading hacks from the pmac feature code rather than adapting them to the new API since they'll be replaced by the platform function code completely in patch 3/5 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
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;