
Device Tree에서 interrupts는 장치가 발생시키는 인터럽트 신호를 어떤 interrupt domain 기준으로 해석할지 적는 속성입니다. 단순히 IRQ 번호 하나를 적는 칸이 아니라, interrupt-parent, #interrupt-cells, interrupt controller binding이 함께 맞아야 의미가 정해집니다.
2026년 8월 11일 기준 Devicetree Specification과 Linux 커널 공식 문서를 보면, 검토 기준은 네 가지입니다. 인터럽트 부모를 어떻게 찾는지, specifier의 셀 개수를 누가 정하는지, interrupts와 interrupts-extended 중 무엇을 써야 하는지, 그리고 bus나 GPIO controller처럼 중간 domain이 있을 때 매핑이 어떻게 이어지는지입니다.
interrupts는 무엇을 표현하나
Device Tree에는 일반 노드 트리와 별개로 논리적인 interrupt tree가 있습니다. 장치 노드가 파일 구조상 어떤 부모 밑에 있더라도, 실제 인터럽트 신호는 다른 interrupt controller로 들어갈 수 있습니다. 이 실제 라우팅 관계를 나타내기 위해 interrupt-parent와 interrupts를 함께 봅니다.
명세에서 interrupts 값은 하나 이상의 interrupt specifier 목록입니다. 각 specifier의 형식은 장치가 연결된 interrupt domain의 root, 즉 interrupt controller나 interrupt nexus의 binding에 의해 정해집니다.

uart@1000 {
compatible = "ns16550";
reg = <0x1000 0x100>;
interrupt-parent = <&intc>;
interrupts = <5 4>;
};
intc: interrupt-controller@2000 {
compatible = "vendor,intc";
interrupt-controller;
#interrupt-cells = <2>;
};
이 예시에서 <5 4>가 정확히 무엇을 뜻하는지는 vendor,intc binding이 정합니다. 흔한 2셀 형식에서는 첫 번째 셀이 컨트롤러 안의 interrupt index, 두 번째 셀이 trigger나 level flag를 나타내지만, 모든 컨트롤러에 같은 의미를 강제로 적용하면 안 됩니다.
interrupt-parent는 어떻게 정해지나
interrupt-parent는 장치의 인터럽트가 라우팅되는 부모 interrupt controller 또는 interrupt nexus를 가리키는 phandle입니다. Devicetree Specification은 이 속성이 없으면 devicetree의 부모 노드를 interrupt parent로 가정한다고 설명합니다.
Linux 커널 binding 문서는 interrupt-parent가 상속될 수 있다고 설명합니다. 그래서 여러 장치가 같은 interrupt controller를 쓴다면 공통 부모 노드에 한 번 적고, child node에는 interrupts만 둘 수도 있습니다.
soc {
interrupt-parent = <&gic>;
serial@1000 {
interrupts = <33 4>;
};
i2c@2000 {
interrupts = <34 4>;
};
};
다만 상속은 편의일 뿐입니다. DTS를 읽는 사람 입장에서는 특정 장치의 IRQ가 어느 컨트롤러 기준인지 바로 보이지 않을 수 있습니다. 보드 파일을 검토할 때는 장치 노드부터 부모 방향으로 올라가며 실제 interrupt-parent가 어디서 정해졌는지 확인해야 합니다.
#interrupt-cells가 왜 중요한가
#interrupt-cells는 interrupt specifier 하나를 표현하는 데 필요한 u32 셀 개수를 정합니다. 이 속성은 인터럽트를 발생시키는 장치가 아니라 interrupt domain의 root 쪽에 있습니다.

| 항목 | 있는 위치 | 역할 |
|---|---|---|
interrupts |
interrupt client node | 장치가 발생시키는 인터럽트 specifier 목록을 적습니다. |
interrupt-parent |
client node 또는 상위 노드 | specifier를 어느 interrupt domain 기준으로 해석할지 정합니다. |
#interrupt-cells |
interrupt controller 또는 nexus | specifier 하나가 몇 개의 셀로 구성되는지 정합니다. |
interrupt-controller |
interrupt controller node | 해당 노드가 interrupt controller임을 나타내는 빈 boolean 속성입니다. |
따라서 interrupts = <5 4>만 보고 바로 “IRQ 5, active high”처럼 단정하면 위험합니다. 먼저 interrupt-parent를 찾고, 그 노드의 #interrupt-cells와 binding 문서가 어떤 셀 의미를 정의하는지 확인해야 합니다.
interrupts-extended는 언제 쓰나
interrupts는 기본적으로 하나의 interrupt parent 기준으로 specifier 목록을 해석합니다. 반면 interrupts-extended는 각 항목 안에 parent phandle과 specifier를 함께 넣습니다. 한 장치가 여러 interrupt controller에 연결되거나, 상속된 parent와 다른 parent를 항목별로 명확히 적어야 할 때 유용합니다.

device@3000 {
compatible = "vendor,device";
reg = <0x3000 0x100>;
interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
};
Devicetree Specification은 interrupts와 interrupts-extended가 모두 있으면 interrupts-extended가 우선한다고 설명합니다. 보통은 둘 중 하나만 쓰는 편이 명확합니다. 둘 다 있는 경우는 오래된 소프트웨어 호환성을 위해 interrupts를 남긴 상황인지 확인해야 합니다.
interrupt nexus와 interrupt-map
모든 장치가 최종 interrupt controller에 바로 연결되는 것은 아닙니다. PCI host bridge나 GPIO controller처럼 자신만의 interrupt domain을 만들고, 그 domain의 specifier를 상위 domain으로 변환하는 노드가 있을 수 있습니다. Devicetree Specification은 이런 노드를 interrupt nexus라고 설명합니다.
interrupt nexus는 interrupt-map으로 child domain의 unit address와 interrupt specifier를 parent domain의 specifier로 매핑합니다. 매핑 검색에는 interrupt-map-mask가 함께 쓰일 수 있습니다. 이 구조에서는 장치 노드의 interrupts 값이 최종 컨트롤러 번호를 직접 의미하지 않을 수 있습니다.
Linux 커널의 OF API 문서는 of_irq_parse_one()이 장치의 인터럽트를 해석할 때 interrupt tree를 걸으며 연결된 interrupt controller를 찾고, Linux IRQ 번호를 얻는 데 쓸 수 있는 interrupt specifier를 반환한다고 설명합니다. of_irq_parse_raw()은 interrupt-map을 찾고 specifier를 변환하며 interrupt tree를 걷는 저수준 함수로 설명됩니다.
검토할 때의 기준
- 장치 노드에
interrupts또는interrupts-extended가 있는지 확인합니다. interrupts를 쓴다면 실제interrupt-parent가 장치 노드에 있는지, 아니면 상위 노드에서 상속되는지 확인합니다.- 부모 interrupt controller 또는 nexus에
#interrupt-cells가 있고, 셀 개수가interrupts값의 길이와 맞는지 봅니다. - specifier 셀의 의미는 컨트롤러 binding 문서 기준으로 해석합니다.
- 여러 interrupt parent가 필요하면
interrupts-extended가 더 명확한지 검토합니다. - GPIO controller, PCI bridge처럼 중간 interrupt domain이 있으면
interrupt-map과interrupt-map-mask까지 확인합니다.
자주 틀리는 해석
| 오해 | 확인할 기준 |
|---|---|
interrupts의 첫 셀은 항상 Linux IRQ 번호다 |
아닙니다. 해당 interrupt domain binding의 specifier 값입니다. Linux IRQ 번호는 커널 매핑 이후의 값입니다. |
interrupt-parent가 없으면 오류다 |
항상 그렇지는 않습니다. 명세상 devicetree 부모가 기본 interrupt parent가 될 수 있고, Linux binding에서는 상위 노드 상속도 사용됩니다. |
#interrupt-cells = <2>이면 두 번째 셀 의미는 어디서나 같다 |
흔한 trigger flag 형식은 있지만, 최종 의미는 각 interrupt controller binding이 정의합니다. |
interrupts와 interrupts-extended를 같이 쓰면 둘 다 동등하다 |
공식 명세 기준으로 둘 다 있으면 interrupts-extended가 우선합니다. |
FAQ
interrupts = <5 4>에서 4는 무조건 active high인가
무조건 그렇지는 않습니다. Linux의 공통 interrupt controller binding 문서에는 2셀 형식에서 두 번째 셀의 하위 비트가 trigger type과 level flag를 나타내는 흔한 형식이 설명되어 있습니다. 하지만 실제 해석은 해당 interrupt controller의 binding을 기준으로 확인해야 합니다.
interrupt-parent를 매 장치마다 적는 것이 더 좋은가
공통 부모 노드에서 상속시키는 방식도 유효합니다. 다만 보드 검토나 디버깅에서는 IRQ 경로가 명확해야 하므로, 상속 위치가 너무 멀거나 여러 domain이 섞이면 장치 노드 근처에 명시하는 편이 읽기 쉬울 수 있습니다.
GPIO controller가 interrupt controller도 될 수 있나
될 수 있습니다. GPIO controller 노드가 interrupt-controller와 #interrupt-cells를 갖고 interrupt domain을 만들 수 있습니다. 이 경우 하위 장치는 GPIO controller를 interrupt-parent로 참조하고, GPIO controller 자체는 다시 상위 interrupt controller로 cascade될 수 있습니다.
참고 자료
'프로그래밍 > 리눅스 커널' 카테고리의 다른 글
| 리눅스 Device Tree reserved-memory 기준 정리 (0) | 2026.08.04 |
|---|---|
| 리눅스 Device Tree bootargs 기준 정리 (0) | 2026.07.30 |
| 리눅스 Device Tree dma-ranges 기준 정리 (0) | 2026.07.23 |
| 리눅스 Device Tree #address-cells와 #size-cells 기준 정리 (0) | 2026.07.18 |
| 리눅스 Device Tree stdout-path 기준 정리 (0) | 2026.07.13 |





