linux/arch/powerpc/kernel/idle_power4.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 *  This file contains the power_save function for 970-family CPUs.
   4 */
   5
   6#include <linux/threads.h>
   7#include <asm/processor.h>
   8#include <asm/page.h>
   9#include <asm/cputable.h>
  10#include <asm/thread_info.h>
  11#include <asm/ppc_asm.h>
  12#include <asm/asm-offsets.h>
  13#include <asm/irqflags.h>
  14#include <asm/hw_irq.h>
  15#include <asm/feature-fixups.h>
  16
  17#undef DEBUG
  18
  19        .text
  20
  21_GLOBAL(power4_idle)
  22BEGIN_FTR_SECTION
  23        blr
  24END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
  25        /* Now check if user or arch enabled NAP mode */
  26        LOAD_REG_ADDRBASE(r3,powersave_nap)
  27        lwz     r4,ADDROFF(powersave_nap)(r3)
  28        cmpwi   0,r4,0
  29        beqlr
  30
  31        /* This sequence is similar to prep_irq_for_idle() */
  32
  33        /* Hard disable interrupts */
  34        mfmsr   r7
  35        rldicl  r0,r7,48,1
  36        rotldi  r0,r0,16
  37        mtmsrd  r0,1
  38
  39        /* Check if something happened while soft-disabled */
  40        lbz     r0,PACAIRQHAPPENED(r13)
  41        cmpwi   cr0,r0,0
  42        bne-    2f
  43
  44        /*
  45         * Soft-enable interrupts. This will make power4_fixup_nap return
  46         * to our caller with interrupts enabled (soft and hard). The caller
  47         * can cope with either interrupts disabled or enabled upon return.
  48         */
  49#ifdef CONFIG_TRACE_IRQFLAGS
  50        /* Tell the tracer interrupts are on, because idle responds to them. */
  51        mflr    r0
  52        std     r0,16(r1)
  53        stdu    r1,-128(r1)
  54        bl      trace_hardirqs_on
  55        addi    r1,r1,128
  56        ld      r0,16(r1)
  57        mtlr    r0
  58        mfmsr   r7
  59#endif /* CONFIG_TRACE_IRQFLAGS */
  60
  61        li      r0,IRQS_ENABLED
  62        stb     r0,PACAIRQSOFTMASK(r13) /* we'll hard-enable shortly */
  63BEGIN_FTR_SECTION
  64        DSSALL
  65        sync
  66END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  67        ld      r9, PACA_THREAD_INFO(r13)
  68        ld      r8,TI_LOCAL_FLAGS(r9)   /* set napping bit */
  69        ori     r8,r8,_TLF_NAPPING      /* so when we take an exception */
  70        std     r8,TI_LOCAL_FLAGS(r9)   /* it will return to our caller */
  71        ori     r7,r7,MSR_EE
  72        oris    r7,r7,MSR_POW@h
  731:      sync
  74        isync
  75        mtmsrd  r7
  76        isync
  77        b       1b
  78
  792:      /* Return if an interrupt had happened while soft disabled */
  80        /* Set the HARD_DIS flag because interrupts are now hard disabled */
  81        ori     r0,r0,PACA_IRQ_HARD_DIS
  82        stb     r0,PACAIRQHAPPENED(r13)
  83        blr
  84