Linux芯片级移植与底层驱动(基于3.7.4内核) 中断控制器
副标题[/!--empirenews.page--]3.中断控制器驱动在Linux内核中,各个设备驱动可以简单地调用request_irq()、enable_irq()、disable_irq()、local_irq_disable()、local_irq_enable()等通用API完成中断申请、使能、禁止等功能。在将Linux移植到新的SoC时,芯片供应商需要提供该部分API的底层支持。 local_irq_disable()、local_irq_enable()的实现与具体中断控制器无关,对于ARMv6以上的体系架构而言,是直接调用CPSID/CPSIE指令进行,而对于ARMv6以前的体系结构,则是透过MRS、MSR指令来读取和设置ARM的CPSR寄存器。由此可见,local_irq_disable()、local_irq_enable()针对的并不是外部的中断控制器,而是直接让CPU本身不响应中断请求。相关的实现位于arch/arm/include/asm/irqflags.h: 11#if __LINUX_ARM_ARCH__ >= 6 12 13static inline unsigned long arch_local_irq_save(void) 14{ 15 unsigned long flags; 16 17 asm volatile( 18 " mrs %0, cpsr @ arch_local_irq_saven" 19 " cpsid i" 20 : "=r" (flags) : : "memory", "cc"); 21 return flags; 22} 23 24static inline void arch_local_irq_enable(void) 25{ 26 asm volatile( 27 " cpsie i @ arch_local_irq_enable" 28 : 29 : 30 : "memory", "cc"); 31} 32 33static inline void arch_local_irq_disable(void) 34{ 35 asm volatile( 36 " cpsid i @ arch_local_irq_disable" 37 : 38 : 39 : "memory", "cc"); 40} 44#else 45 46/* 47 * Save the current interrupt enable state & disable IRQs 48 */ 49static inline unsigned long arch_local_irq_save(void) 50{ 51 unsigned long flags, temp; 52 53 asm volatile( 54 " mrs %0, cpsr @ arch_local_irq_saven" 55 " orr %1, %0, #128n" 56 " msr cpsr_c, %1" 57 : "=r" (flags), "=r" (temp) 58 : 59 : "memory", "cc"); 60 return flags; 61} 62 63/* 64 * Enable IRQs 65 */ 66static inline void arch_local_irq_enable(void) 67{ 68 unsigned long temp; 69 asm volatile( 70 " mrs %0, cpsr @ arch_local_irq_enablen" 71 " bic %0, %0, #128n" 72 " msr cpsr_c, %0" 73 : "=r" (temp) 74 : 75 : "memory", "cc"); 76} 77 78/* 79 * Disable IRQs 80 */ 81static inline void arch_local_irq_disable(void) 82{ 83 unsigned long temp; 84 asm volatile( 85 " mrs %0, cpsr @ arch_local_irq_disablen" 86 " orr %0, %0, #128n" 87 " msr cpsr_c, %0" 88 : "=r" (temp) 89 : 90 : "memory", "cc"); 91} 92 #endif (编辑:佛山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

