3. Interrupt Controller Driver
In the Linux kernel, individual device drivers can simply invoke Request_irq (), ENABLE_IRQ (), DISABLE_IRQ (), local_irq_disable (), local_irq_enable () such as General API complete interrupt application, enable, prohibit and so on function. When porting Linux to a new SOC, the chip vendor needs to provide low-level support for that part of the API.
The implementation of Local_irq_disable (), Local_irq_enable () is independent of the specific interrupt controller, and for ARMV6 above architecture, it is directly called Cpsid/cpsie instruction, and for the previous architecture of ARMV6, It is through the Mrs, MSR instructions to read and set arm CPSR registers. This shows that local_irq_disable (), local_irq_enable () is not an external interrupt controller, but directly to the CPU itself does not respond to interrupt requests. Related implementations are located in Arch/arm/include/asm/irqflags.h:
11#if __linux_arm_arch__ >= 6
12
13static Inline unsigned long arch_local_irq_save (void)
14{
unsigned long flags;
16
Volatile ASM (
"Mrs%0, CPSR @ arch_local_irq_save\n"
"Cpsid i"
"=r" (Flags):: "Memory", "CC");
return to flags;
22}
23
24static inline void arch_local_irq_enable (void)
059
-ASM volatile (
"Cpsie I @ arch_local_irq_enable"
28:
29:
: "Memory", "CC");
31}
32
33static inline void arch_local_irq_disable (void)
34{
ASM volatile (
"Cpsid I @ arch_local_irq_disable"
37:
38:
: "Memory", "CC");
40}
44#else
45
46/*
Save the current interrupt enable state & Disable IRQs
48 */
49static Inline unsigned long arch_local_irq_save (void)
50{
Wuyi unsigned long flags, temp;
52
The ASM volatile (
"Mrs%0, CPSR @ arch_local_irq_save\n"
"Orr%1,%0, #128 \ n"
"MSR Cpsr_c,%1"
"=r" (Flags), "=r" (temp)
58:
: "Memory", "CC");
return to flags;
61}
62
63/*
* Enable IRQs
65 */
66static inline void arch_local_irq_enable (void)
67{
unsigned long temp;
Volatile ASM (
"Mrs%0, CPSR @ arch_local_irq_enable\n"
"Bic%0,%0, #128 \ n"
"MSR Cpsr_c,%0"
(temp): "=r"
74:
: "Memory", "CC");
76}
77
78/*
* Disable IRQs
80 */
81static inline void arch_local_irq_disable (void)
82{
unsigned long temp;
Volatile ASM (
"Mrs%0, CPSR @ arch_local_irq_disable\n"
"Orr%0,%0, #128 \ n"
"MSR Cpsr_c,%0"
A: "=r" (temp)
89:
: "Memory", "CC");
91}
#endif