Chenging 2 bits in MSR in ppc6xx_idle() with 1 command?

Guennadi Liakhovetski g.liakhovetski at gmx.de
Thu Dec 28 07:44:27 EST 2006


On Wed, 27 Dec 2006, Benjamin Herrenschmidt wrote:

> On Mon, 2006-12-25 at 21:07 +0100, Guennadi Liakhovetski wrote:
> > Hi
> > 
> > Here's a code fragment from ppc6xx_idle(), which should send the CPU into 
> > a powersaving mode (DOZE or NAP) and re-enable interrupts after a 
> > local_irq_disable():
> > 
> > 	mfmsr	r7
> > 	ori	r7,r7,MSR_EE
> > 	oris	r7,r7,MSR_POW at h
> > 1:	sync
> > 	mtmsr	r7
> > 	isync
> > 	b	1b
> > 
> > Whereas MPC8245's user manual says, that when setting the MSR_POW bit in 
> > the MSR one may not set any other bit in it with the same instruction. 
> > Does this mean that the above does not actually work on those (and 
> > similar) CPUs or does it work because of the loop?
> 
> That doc bit looks a bit strange. The kernel pretty much relies on
> setting MSR:EE and MSR:POW atomicaly.

Hm, wouldn't it just work? In ppc6xx_idle() the _TLF_NAPPING bit is set. 
If as a result of mtmsr only the EE bit is set and we get an interrupt, we 
end up in transfer_to_handler(), check the flag, it is set, so we branch 
to power_save_6xx_restore(). There we clear NAP/DOZE and just jump to 
transfer_to_handler_cont(). Why did you say we'd miss the check for 
need_resched (on IRC)? How is this case difference from if we really did 
go to NAP / DOZE?

Are there other places in the kernel where we rely on setting MSR:POW and 
some other bit atomically?

Thanks
Guennadi
---
Guennadi Liakhovetski



More information about the Linuxppc-dev mailing list