Commit fa2ae4a3 authored by Sven Schnelle's avatar Sven Schnelle Committed by Alexander Gordeev
Browse files

s390/idle: Rewrite psw_idle() in C



To ease maintenance and further enhancements, convert
the psw_idle() function to C.

Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 62b672c4
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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 */
+0 −6
Original line number Diff line number Diff line
@@ -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);
+0 −23
Original line number Diff line number Diff line
@@ -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
 */
+7 −3
Original line number Diff line number Diff line
@@ -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,