aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/macintosh/smu.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 8ba49385c3ff..77ad192962c5 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -85,6 +85,7 @@ struct smu_device {
85 u32 cmd_buf_abs; /* command buffer absolute */ 85 u32 cmd_buf_abs; /* command buffer absolute */
86 struct list_head cmd_list; 86 struct list_head cmd_list;
87 struct smu_cmd *cmd_cur; /* pending command */ 87 struct smu_cmd *cmd_cur; /* pending command */
88 int broken_nap;
88 struct list_head cmd_i2c_list; 89 struct list_head cmd_i2c_list;
89 struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ 90 struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */
90 struct timer_list i2c_timer; 91 struct timer_list i2c_timer;
@@ -135,6 +136,19 @@ static void smu_start_cmd(void)
135 fend = faddr + smu->cmd_buf->length + 2; 136 fend = faddr + smu->cmd_buf->length + 2;
136 flush_inval_dcache_range(faddr, fend); 137 flush_inval_dcache_range(faddr, fend);
137 138
139
140 /* We also disable NAP mode for the duration of the command
141 * on U3 based machines.
142 * This is slightly racy as it can be written back to 1 by a sysctl
143 * but that never happens in practice. There seem to be an issue with
144 * U3 based machines such as the iMac G5 where napping for the
145 * whole duration of the command prevents the SMU from fetching it
146 * from memory. This might be related to the strange i2c based
147 * mechanism the SMU uses to access memory.
148 */
149 if (smu->broken_nap)
150 powersave_nap = 0;
151
138 /* This isn't exactly a DMA mapping here, I suspect 152 /* This isn't exactly a DMA mapping here, I suspect
139 * the SMU is actually communicating with us via i2c to the 153 * the SMU is actually communicating with us via i2c to the
140 * northbridge or the CPU to access RAM. 154 * northbridge or the CPU to access RAM.
@@ -211,6 +225,10 @@ static irqreturn_t smu_db_intr(int irq, void *arg)
211 misc = cmd->misc; 225 misc = cmd->misc;
212 mb(); 226 mb();
213 cmd->status = rc; 227 cmd->status = rc;
228
229 /* Re-enable NAP mode */
230 if (smu->broken_nap)
231 powersave_nap = 1;
214 bail: 232 bail:
215 /* Start next command if any */ 233 /* Start next command if any */
216 smu_start_cmd(); 234 smu_start_cmd();
@@ -461,7 +479,7 @@ int __init smu_init (void)
461 if (np == NULL) 479 if (np == NULL)
462 return -ENODEV; 480 return -ENODEV;
463 481
464 printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); 482 printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR);
465 483
466 if (smu_cmdbuf_abs == 0) { 484 if (smu_cmdbuf_abs == 0) {
467 printk(KERN_ERR "SMU: Command buffer not allocated !\n"); 485 printk(KERN_ERR "SMU: Command buffer not allocated !\n");
@@ -533,6 +551,11 @@ int __init smu_init (void)
533 goto fail; 551 goto fail;
534 } 552 }
535 553
554 /* U3 has an issue with NAP mode when issuing SMU commands */
555 smu->broken_nap = pmac_get_uninorth_variant() < 4;
556 if (smu->broken_nap)
557 printk(KERN_INFO "SMU: using NAP mode workaround\n");
558
536 sys_ctrler = SYS_CTRLER_SMU; 559 sys_ctrler = SYS_CTRLER_SMU;
537 return 0; 560 return 0;
538 561