18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_ARM_IRQFLAGS_H 38c2ecf20Sopenharmony_ci#define __ASM_ARM_IRQFLAGS_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* 108c2ecf20Sopenharmony_ci * CPU interrupt mask handling. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_V7M 138c2ecf20Sopenharmony_ci#define IRQMASK_REG_NAME_R "primask" 148c2ecf20Sopenharmony_ci#define IRQMASK_REG_NAME_W "primask" 158c2ecf20Sopenharmony_ci#define IRQMASK_I_BIT 1 168c2ecf20Sopenharmony_ci#else 178c2ecf20Sopenharmony_ci#define IRQMASK_REG_NAME_R "cpsr" 188c2ecf20Sopenharmony_ci#define IRQMASK_REG_NAME_W "cpsr_c" 198c2ecf20Sopenharmony_ci#define IRQMASK_I_BIT PSR_I_BIT 208c2ecf20Sopenharmony_ci#endif 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#if __LINUX_ARM_ARCH__ >= 6 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define arch_local_irq_save arch_local_irq_save 258c2ecf20Sopenharmony_cistatic inline unsigned long arch_local_irq_save(void) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci unsigned long flags; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci asm volatile( 308c2ecf20Sopenharmony_ci " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" 318c2ecf20Sopenharmony_ci " cpsid i" 328c2ecf20Sopenharmony_ci : "=r" (flags) : : "memory", "cc"); 338c2ecf20Sopenharmony_ci return flags; 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define arch_local_irq_enable arch_local_irq_enable 378c2ecf20Sopenharmony_cistatic inline void arch_local_irq_enable(void) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci asm volatile( 408c2ecf20Sopenharmony_ci " cpsie i @ arch_local_irq_enable" 418c2ecf20Sopenharmony_ci : 428c2ecf20Sopenharmony_ci : 438c2ecf20Sopenharmony_ci : "memory", "cc"); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define arch_local_irq_disable arch_local_irq_disable 478c2ecf20Sopenharmony_cistatic inline void arch_local_irq_disable(void) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci asm volatile( 508c2ecf20Sopenharmony_ci " cpsid i @ arch_local_irq_disable" 518c2ecf20Sopenharmony_ci : 528c2ecf20Sopenharmony_ci : 538c2ecf20Sopenharmony_ci : "memory", "cc"); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") 578c2ecf20Sopenharmony_ci#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#ifndef CONFIG_CPU_V7M 608c2ecf20Sopenharmony_ci#define local_abt_enable() __asm__("cpsie a @ __sta" : : : "memory", "cc") 618c2ecf20Sopenharmony_ci#define local_abt_disable() __asm__("cpsid a @ __cla" : : : "memory", "cc") 628c2ecf20Sopenharmony_ci#else 638c2ecf20Sopenharmony_ci#define local_abt_enable() do { } while (0) 648c2ecf20Sopenharmony_ci#define local_abt_disable() do { } while (0) 658c2ecf20Sopenharmony_ci#endif 668c2ecf20Sopenharmony_ci#else 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * Save the current interrupt enable state & disable IRQs 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_ci#define arch_local_irq_save arch_local_irq_save 728c2ecf20Sopenharmony_cistatic inline unsigned long arch_local_irq_save(void) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci unsigned long flags, temp; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci asm volatile( 778c2ecf20Sopenharmony_ci " mrs %0, cpsr @ arch_local_irq_save\n" 788c2ecf20Sopenharmony_ci " orr %1, %0, #128\n" 798c2ecf20Sopenharmony_ci " msr cpsr_c, %1" 808c2ecf20Sopenharmony_ci : "=r" (flags), "=r" (temp) 818c2ecf20Sopenharmony_ci : 828c2ecf20Sopenharmony_ci : "memory", "cc"); 838c2ecf20Sopenharmony_ci return flags; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* 878c2ecf20Sopenharmony_ci * Enable IRQs 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci#define arch_local_irq_enable arch_local_irq_enable 908c2ecf20Sopenharmony_cistatic inline void arch_local_irq_enable(void) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci unsigned long temp; 938c2ecf20Sopenharmony_ci asm volatile( 948c2ecf20Sopenharmony_ci " mrs %0, cpsr @ arch_local_irq_enable\n" 958c2ecf20Sopenharmony_ci " bic %0, %0, #128\n" 968c2ecf20Sopenharmony_ci " msr cpsr_c, %0" 978c2ecf20Sopenharmony_ci : "=r" (temp) 988c2ecf20Sopenharmony_ci : 998c2ecf20Sopenharmony_ci : "memory", "cc"); 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* 1038c2ecf20Sopenharmony_ci * Disable IRQs 1048c2ecf20Sopenharmony_ci */ 1058c2ecf20Sopenharmony_ci#define arch_local_irq_disable arch_local_irq_disable 1068c2ecf20Sopenharmony_cistatic inline void arch_local_irq_disable(void) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci unsigned long temp; 1098c2ecf20Sopenharmony_ci asm volatile( 1108c2ecf20Sopenharmony_ci " mrs %0, cpsr @ arch_local_irq_disable\n" 1118c2ecf20Sopenharmony_ci " orr %0, %0, #128\n" 1128c2ecf20Sopenharmony_ci " msr cpsr_c, %0" 1138c2ecf20Sopenharmony_ci : "=r" (temp) 1148c2ecf20Sopenharmony_ci : 1158c2ecf20Sopenharmony_ci : "memory", "cc"); 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* 1198c2ecf20Sopenharmony_ci * Enable FIQs 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_ci#define local_fiq_enable() \ 1228c2ecf20Sopenharmony_ci ({ \ 1238c2ecf20Sopenharmony_ci unsigned long temp; \ 1248c2ecf20Sopenharmony_ci __asm__ __volatile__( \ 1258c2ecf20Sopenharmony_ci "mrs %0, cpsr @ stf\n" \ 1268c2ecf20Sopenharmony_ci" bic %0, %0, #64\n" \ 1278c2ecf20Sopenharmony_ci" msr cpsr_c, %0" \ 1288c2ecf20Sopenharmony_ci : "=r" (temp) \ 1298c2ecf20Sopenharmony_ci : \ 1308c2ecf20Sopenharmony_ci : "memory", "cc"); \ 1318c2ecf20Sopenharmony_ci }) 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci/* 1348c2ecf20Sopenharmony_ci * Disable FIQs 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_ci#define local_fiq_disable() \ 1378c2ecf20Sopenharmony_ci ({ \ 1388c2ecf20Sopenharmony_ci unsigned long temp; \ 1398c2ecf20Sopenharmony_ci __asm__ __volatile__( \ 1408c2ecf20Sopenharmony_ci "mrs %0, cpsr @ clf\n" \ 1418c2ecf20Sopenharmony_ci" orr %0, %0, #64\n" \ 1428c2ecf20Sopenharmony_ci" msr cpsr_c, %0" \ 1438c2ecf20Sopenharmony_ci : "=r" (temp) \ 1448c2ecf20Sopenharmony_ci : \ 1458c2ecf20Sopenharmony_ci : "memory", "cc"); \ 1468c2ecf20Sopenharmony_ci }) 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#define local_abt_enable() do { } while (0) 1498c2ecf20Sopenharmony_ci#define local_abt_disable() do { } while (0) 1508c2ecf20Sopenharmony_ci#endif 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/* 1538c2ecf20Sopenharmony_ci * Save the current interrupt enable state. 1548c2ecf20Sopenharmony_ci */ 1558c2ecf20Sopenharmony_ci#define arch_local_save_flags arch_local_save_flags 1568c2ecf20Sopenharmony_cistatic inline unsigned long arch_local_save_flags(void) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci unsigned long flags; 1598c2ecf20Sopenharmony_ci asm volatile( 1608c2ecf20Sopenharmony_ci " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" 1618c2ecf20Sopenharmony_ci : "=r" (flags) : : "memory", "cc"); 1628c2ecf20Sopenharmony_ci return flags; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* 1668c2ecf20Sopenharmony_ci * restore saved IRQ & FIQ state 1678c2ecf20Sopenharmony_ci */ 1688c2ecf20Sopenharmony_ci#define arch_local_irq_restore arch_local_irq_restore 1698c2ecf20Sopenharmony_cistatic inline void arch_local_irq_restore(unsigned long flags) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci asm volatile( 1728c2ecf20Sopenharmony_ci " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" 1738c2ecf20Sopenharmony_ci : 1748c2ecf20Sopenharmony_ci : "r" (flags) 1758c2ecf20Sopenharmony_ci : "memory", "cc"); 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci#define arch_irqs_disabled_flags arch_irqs_disabled_flags 1798c2ecf20Sopenharmony_cistatic inline int arch_irqs_disabled_flags(unsigned long flags) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci return flags & IRQMASK_I_BIT; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#include <asm-generic/irqflags.h> 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci#endif /* ifdef __KERNEL__ */ 1878c2ecf20Sopenharmony_ci#endif /* ifndef __ASM_ARM_IRQFLAGS_H */ 188