18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * include/asm/irqflags.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * IRQ flags handling 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This file gets included from lowlevel asm headers too, to provide 88c2ecf20Sopenharmony_ci * wrapped versions of the local_irq_*() APIs, based on the 98c2ecf20Sopenharmony_ci * arch_local_irq_*() functions from the lowlevel headers. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#ifndef _ASM_IRQFLAGS_H 128c2ecf20Sopenharmony_ci#define _ASM_IRQFLAGS_H 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <asm/pil.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic inline notrace unsigned long arch_local_save_flags(void) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci unsigned long flags; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci __asm__ __volatile__( 238c2ecf20Sopenharmony_ci "rdpr %%pil, %0" 248c2ecf20Sopenharmony_ci : "=r" (flags) 258c2ecf20Sopenharmony_ci ); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci return flags; 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_restore(unsigned long flags) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci __asm__ __volatile__( 338c2ecf20Sopenharmony_ci "wrpr %0, %%pil" 348c2ecf20Sopenharmony_ci : /* no output */ 358c2ecf20Sopenharmony_ci : "r" (flags) 368c2ecf20Sopenharmony_ci : "memory" 378c2ecf20Sopenharmony_ci ); 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_disable(void) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci __asm__ __volatile__( 438c2ecf20Sopenharmony_ci "wrpr %0, %%pil" 448c2ecf20Sopenharmony_ci : /* no outputs */ 458c2ecf20Sopenharmony_ci : "i" (PIL_NORMAL_MAX) 468c2ecf20Sopenharmony_ci : "memory" 478c2ecf20Sopenharmony_ci ); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_enable(void) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci __asm__ __volatile__( 538c2ecf20Sopenharmony_ci "wrpr 0, %%pil" 548c2ecf20Sopenharmony_ci : /* no outputs */ 558c2ecf20Sopenharmony_ci : /* no inputs */ 568c2ecf20Sopenharmony_ci : "memory" 578c2ecf20Sopenharmony_ci ); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic inline notrace int arch_irqs_disabled_flags(unsigned long flags) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci return (flags > 0); 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic inline notrace int arch_irqs_disabled(void) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci return arch_irqs_disabled_flags(arch_local_save_flags()); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic inline notrace unsigned long arch_local_irq_save(void) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci unsigned long flags, tmp; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* Disable interrupts to PIL_NORMAL_MAX unless we already 758c2ecf20Sopenharmony_ci * are using PIL_NMI, in which case PIL_NMI is retained. 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * The only values we ever program into the %pil are 0, 788c2ecf20Sopenharmony_ci * PIL_NORMAL_MAX and PIL_NMI. 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci * Since PIL_NMI is the largest %pil value and all bits are 818c2ecf20Sopenharmony_ci * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX 828c2ecf20Sopenharmony_ci * actually is. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci __asm__ __volatile__( 858c2ecf20Sopenharmony_ci "rdpr %%pil, %0\n\t" 868c2ecf20Sopenharmony_ci "or %0, %2, %1\n\t" 878c2ecf20Sopenharmony_ci "wrpr %1, 0x0, %%pil" 888c2ecf20Sopenharmony_ci : "=r" (flags), "=r" (tmp) 898c2ecf20Sopenharmony_ci : "i" (PIL_NORMAL_MAX) 908c2ecf20Sopenharmony_ci : "memory" 918c2ecf20Sopenharmony_ci ); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci return flags; 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#endif /* (__ASSEMBLY__) */ 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#endif /* !(_ASM_IRQFLAGS_H) */ 99