s390/idle: Rewrite psw_idle() in C
To ease maintenance and further enhancements, convert the psw_idle() function to C. Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
parent
62b672c4ba
commit
fa2ae4a377
@ -40,6 +40,7 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/runtime_instr.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
typedef long (*sys_call_ptr_t)(struct pt_regs *regs);
|
||||
|
||||
@ -92,6 +93,14 @@ static inline void get_cpu_id(struct cpuid *ptr)
|
||||
asm volatile("stidp %0" : "=Q" (*ptr));
|
||||
}
|
||||
|
||||
static __always_inline unsigned long get_cpu_timer(void)
|
||||
{
|
||||
unsigned long timer;
|
||||
|
||||
asm volatile("stpt %[timer]" : [timer] "=Q" (timer));
|
||||
return timer;
|
||||
}
|
||||
|
||||
void s390_adjust_jiffies(void);
|
||||
void s390_update_cpu_mhz(void);
|
||||
void cpu_detect_mhz_feature(void);
|
||||
@ -394,6 +403,11 @@ static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
|
||||
return arch_irqs_disabled_flags(regs->psw.mask);
|
||||
}
|
||||
|
||||
static __always_inline void bpon(void)
|
||||
{
|
||||
asm volatile(ALTERNATIVE("nop", ".insn rrf,0xb2e80000,0,0,13,0", 82));
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_S390_PROCESSOR_H */
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <linux/purgatory.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm/idle.h>
|
||||
#include <asm/gmap.h>
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
@ -71,11 +70,6 @@ int main(void)
|
||||
OFFSET(__SFVDSO_RETURN_ADDRESS, stack_frame_vdso_wrapper, return_address);
|
||||
DEFINE(STACK_FRAME_VDSO_OVERHEAD, sizeof(struct stack_frame_vdso_wrapper));
|
||||
BLANK();
|
||||
/* idle data offsets */
|
||||
OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter);
|
||||
OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter);
|
||||
OFFSET(__MT_CYCLES_ENTER, s390_idle_data, mt_cycles_enter);
|
||||
BLANK();
|
||||
/* hardware defined lowcore locations 0x000 - 0x1ff */
|
||||
OFFSET(__LC_EXT_PARAMS, lowcore, ext_params);
|
||||
OFFSET(__LC_EXT_CPU_ADDR, lowcore, ext_cpu_addr);
|
||||
|
@ -440,29 +440,6 @@ SYM_CODE_END(\name)
|
||||
INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
|
||||
INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
|
||||
|
||||
/*
|
||||
* Load idle PSW.
|
||||
*/
|
||||
SYM_FUNC_START(psw_idle)
|
||||
stg %r14,(__SF_GPRS+8*8)(%r15)
|
||||
stg %r3,__SF_EMPTY(%r15)
|
||||
larl %r1,psw_idle_exit
|
||||
stg %r1,__SF_EMPTY+8(%r15)
|
||||
larl %r1,smp_cpu_mtid
|
||||
llgf %r1,0(%r1)
|
||||
ltgr %r1,%r1
|
||||
jz .Lpsw_idle_stcctm
|
||||
.insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
|
||||
.Lpsw_idle_stcctm:
|
||||
oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
|
||||
BPON
|
||||
stckf __CLOCK_IDLE_ENTER(%r2)
|
||||
stpt __TIMER_IDLE_ENTER(%r2)
|
||||
lpswe __SF_EMPTY(%r15)
|
||||
SYM_INNER_LABEL(psw_idle_exit, SYM_L_GLOBAL)
|
||||
BR_EX %r14
|
||||
SYM_FUNC_END(psw_idle)
|
||||
|
||||
/*
|
||||
* Machine check handler routines
|
||||
*/
|
||||
|
@ -57,9 +57,13 @@ void noinstr arch_cpu_idle(void)
|
||||
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT |
|
||||
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
|
||||
clear_cpu_flag(CIF_NOHZ_DELAY);
|
||||
|
||||
/* psw_idle() returns with interrupts disabled. */
|
||||
psw_idle(idle, psw_mask);
|
||||
set_cpu_flag(CIF_ENABLED_WAIT);
|
||||
if (smp_cpu_mtid)
|
||||
stcctm(MT_DIAG, smp_cpu_mtid, (u64 *)&idle->mt_cycles_enter);
|
||||
idle->clock_idle_enter = get_tod_clock_fast();
|
||||
idle->timer_idle_enter = get_cpu_timer();
|
||||
bpon();
|
||||
__load_psw_mask(psw_mask);
|
||||
}
|
||||
|
||||
static ssize_t show_idle_count(struct device *dev,
|
||||
|
Loading…
x
Reference in New Issue
Block a user