diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/macintosh/smu.c | 25 |
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 | ||