diff -drupN a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c --- a/arch/mips/kernel/idle.c 2017-10-21 18:09:07.000000000 +0300 +++ b/arch/mips/kernel/idle.c 2022-06-09 05:02:27.000000000 +0300 @@ -52,6 +52,30 @@ void r4k_wait(void) __r4k_wait(); } +#ifdef X2000_IDLE_PD +extern int x2000_pm_enter(void); +static void ingenic_wait_irqoff_pd(void) +{ + WARN_ON_ONCE(!irqs_disabled()); + x2000_pm_enter(PM_SUSPEND_STANDBY); + local_irq_enable(); +} +#else +void ingenic_wait_irqoff(void) +{ + local_irq_disable(); + if (!need_resched()) + __asm__( + " .set push \n" + " .set arch=r4000 \n" + " sync \n" + " wait \n" + " .set pop \n"); + local_irq_enable(); +} +#endif + + /* * This variant is preferable as it allows testing need_resched and going to * sleep depending on the outcome atomically. Unfortunately the "It is @@ -175,12 +199,19 @@ void __init check_wait(void) case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON3: - case CPU_JZRISC: case CPU_LOONGSON1: case CPU_XLR: case CPU_XLP: cpu_wait = r4k_wait; break; + case CPU_JZRISC: +#ifdef X2000_IDLE_PD + cpu_wait = ingenic_wait_irqoff_pd; +#else + cpu_wait = ingenic_wait_irqoff; +#endif + + break; case CPU_BMIPS5000: cpu_wait = r4k_wait_irqoff; break;