Difference between r1.10 and the current
@@ -9,6 +9,7 @@
* [wiki:KernelApi4 Kernel API 4 - Porting(ARM)]
* [wiki:KernelApi5 Kernel API 5 - Linux Driver Model(ext)]
* [wiki:KernelApi6 Kernel API 6 - PM]
* [wiki:KernelApi7 Kernel API 7 - DEBUG]
[[TableOfContents]]
@@ -135,5 +136,4 @@
||IRQT_PROBE||||
리턴값은 성공시엔 0을 반환하고 그렇지 않은 경우엔 음수 값을 반환한다(-ENXIO, -ENODEV 등).
Kernel API 4 - Porting(ARM) #
--
김도집 2005-09-28 17:37:04
1.1.1 Instruction #
ARM은 Core 외에도 Co-processor로 그 기능을 확장 가능하도록 하고 있다. 일반적으로 알고 있는 MMU 및 Cache 관련 Co-processor의
?CP15가 바로 그것이다.
이러한 Co-processor를 위하여 ARM에서는 특별한 intstruction을 정의하고 있다. 그 포맷은 다음과 같다.
MCR/MRC{cond} P15, opcode_1, Rd, CRn, CRm, opcode_2
1.2.1 struct irqchip #
struct irq {
void (*ack)(unsigned int);
void (*mask)(unsigned int);
void (*unmask)(unsigned int);
int (*retrigger)(unsigned int);
int (*type)(unsigned int, unsigned int);
int (*wake)(unsigned int, unsigned int);
#ifdef CONFIG_SMP
void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu);
#endif
1.2.2 struct irqdesc #
struct irqdesc {
irq_handler_t handle;
struct irqchip *chip;
struct irqaction *action;
struct list_head pend;
void *chipdata;
void *data;
unsigned disable_depth;
unsigned int triggerd: 1;
unsigned int running: 1;
unsigned int pending: 1;
unsigned int probing: 1;
unsigned int probe_ok: 1;
unsigned int valid: 1;
unsigned int noautoenable: 1;
unsigned int unused: 25;
struct proc_dir_entry *procdir;
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
unsigned int lck_cnt;
unsigned int lck_pc;
unsigned int lck_jif;
};
하나의 irq는 하나의 irqdesc와 대응이 된다. 즉 irqdesc는 irq에 대한 기술자가 된다. 따라서 모든 irq에 대한 정보를 갖고 있는 테이블이 필요한데, 이에 대한 것은 전역으로 선언되어 있다.
extern struct irqdesc irq_desc[];
1.2.3 set_irq_chip #
함수 원형은 다음과 같다.
void set_irq_chip(unsigned int irq, struct irqchip *chip);
1.2.4 set_irq_handler #
함수 원형
void set_irq_handler(unsigned int irq, irq_handler_t handler);
irq_handler_t는 <asm/arch/irq.h>에 다음과 같이 선언되어 있다.
typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
유사 함수: set_irq_chained_handler
커널 소스내에서 본 함수는 __set_irq_handler(irq, handler, 0)을 호출한다.
1.2.5 set_irq_chained_handler #
일반적으로 하나의 인터럽트 번호에 대해 한들러를 등록할 때는 set_irq_handler를 이용한다. 그런데 물리적으로는 하나의 인터럽트 번호가 할당되어 있는데, 이를 demux하여 여러 개의 인터럽트 번호로 분배되고 각각에 인터럽트 핸들러가 등록되는 경우엔 최초 물리적인 인터럽트 번호에 대한 핸들러에 이 핸들러가 최종이 아니고 또 다른 핸들러가 있음을 알려야 한다. 이때 사용하는 것이 바로 set_irq_chained_handler 이다.
함수 원형은 다음과 같다.
void set_irq_chained_handler(unsigned int irq, irq_handler_t handler);
irq_handler_t는 <asm/arch/irq.h>에 다음과 같이 선언되어 있다.
typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
유사 함수: set_irq_handler
커널 소스 내에서 본 함수는 __set_irq_handler(irq, handler, 1)을 호출한다.
1.2.6 set_irq_flags #
함수 원형은 다음과 같다.
void set_irq_flags(unsigned int irq, unsigned int iflags);
1.2.7 set_irq_type #
어떤 방식의 인터럽트에 대해 감지할 것인지를 결정한다. 특히 하나의 인터럽트 번호를 공유하는 GPIO의 경우에는 인터럽트를 사용하기 위해서는 반드시 set_irq_type을 호출해야만 하는 경우도 있다.
함수는 <asm/irq.h>에 선언되어 있다.
함수 원형은 다음과 같다.
void set_irq_type (unsigned int irq, unsigned type);
인자 중 첫번째 irq는 인터럽트 번호이다. 두번째 인자인 type에서 사용할 수 있는 값은 다음과 같다.
type | 설명 |
IRQT_NOEDGE | |
IRQT_RISING | |
IRQT_FALLING | |
IRQT_BOTHEDGE | |
IRQT_LOW | |
IRQT_HIGH | |
IRQT_PROBE | |
리턴값은 성공시엔 0을 반환하고 그렇지 않은 경우엔 음수 값을 반환한다(-ENXIO, -ENODEV 등).