2. デバイスツリー

2.1. 概要

DTSpec システムハードウェアを記述するための デバイスツリー と呼ばれる構造を指定します。 ブートプログラムは、デバイスツリーをクライアントプログラムのメモリにロードし、デバイスツリーへのポインタをクライアントに渡します。

この章では、デバイスツリーの論理構造について説明し、デバイスノードの説明に使用するプロパティの基本セットを指定します。 第 3 章 は、 DTSpec 準拠のデバイスツリーに必要な特定のデバイスノードを指定します。 第 4 章 は、 DTSpec で定義されたデバイスバインディング(特定のデバイスタイプまたはデバイスのクラスを表すための要件)について説明しています。 第 5 章 は、デバイスツリーのメモリ内エンコーディングについて説明しています。

デバイスツリーは、システム内のデバイスを記述するノードを持つツリーデータ構造です。 各ノードには、表現されているデバイスの特性を説明するプロパティと値のペアがあります。 親がないルートノードを除いて、各ノードには1つの親があります。

DTSpec 準拠のデバイスツリーは、クライアントプログラムによって必ずしも動的に検出されるとは限らないシステム内のデバイス情報を記述します。 たとえば、PCIのアーキテクチャにより、クライアントは接続されたデバイスを探索および検出できるため、PCIデバイスを記述するデバイスツリーノードは必要ない場合があります。 ただし、探索で検出できない場合は、システム内のPCIホストブリッジデバイスを記述するためにデバイスノードが必要です。

図 2.1 は、プラットフォームタイプ、CPU、メモリ、および一つのUARTが記述された、単純なオペレーティングシステムを起動するのにほぼ完全な単純なデバイスツリーの表現例を示しています。 デバイスノードは、各ノード内のプロパティと値とともに表示されます。

digraph tree { rankdir = LR; ranksep = equally; size = "6,8" node [ shape="Mrecord"; width="3.5"; fontname = Courier; ]; "/" [ label = "\N | model=\"fsl,mpc8572ds\"\l compatible=\"fsl,mpc8572ds\"\l #address-cells=\<1\>\l #size-cells=\<1\>\l"] "cpus" [ label="\N | #address-cells=\<1\>\l #size-cells=\<0\>\l"] "cpu@0" [ label="\N | device_type=\"cpu\"\l reg=\<0\>\l timebase-frequency=\<825000000\>\l clock-frequency=\<825000000\>\l"] "cpu@1" [ label="\N | device_type=\"cpu\"\l reg=\<1\>\l timebase-frequency=\<825000000\>\l clock-frequency=\<825000000\>\l"] "memory@0" [ label="\N | device_type=\"memory\"\l reg=\<0 0x20000000\>\l"] "uart@fe001000" [ label="\N | compatible=\"ns16550\"\l reg=\<0xfe001000 0x100\>\l"] "chosen" [ label="\N | bootargs=\"root=/dev/sda2\"\l"] "aliases" [ label="\N | serial0=\"/uart@fe001000\"\l"] "/":e -> "cpus":w "cpus":e -> "cpu@0":w "cpus":e -> "cpu@1":w "/":e -> "memory@0":w "/":e -> "uart@fe001000":w "/":e -> "chosen":w "/":e -> "aliases":w }

図 2.1 Devicetree Example

2.2. デバイスツリーの構造と規則

2.2.1. ノード名

2.2.1.1. ノード名の要件

デバイスツリーの各ノードには、次の規則に従って名前が付けられます。

node-name@unit-address

node-name コンポーネントは、ノードの名前を指定します。 長さは1〜31文字で、表 2.1 の文字セットの文字のみで構成されるものとします。

表 2.1 Valid characters for node names

Character

Description

0-9

digit

a-z

lowercase letter

A-Z

uppercase letter

,

comma

.

period

_

underscore

+

plus sign

-

dash

node-name は小文字または大文字で始まるものとし、デバイスの一般的なクラスを説明する必要があります。

名前の unit-address コンポーネントは、ノードが置かれているバスタイプに固有です。 これは、 表 2.1 の文字セットからの1つ以上のASCII文字で構成されます。 unit-address は、ノードの reg プロパティで指定された最初のアドレスと一致する必要があります。 ノードに reg プロパティがない場合は、 @unit-address を省略し、 node-name だけで、ツリー内の同じレベルにある他のノードとノードを区別します。 特定のバスのバインディングでは、reg の形式と unit-address に関する追加のより具体的な要件を指定できます。

@unit-address のない node-name の場合、 node-name は、ツリー内の同じレベルにあるすべてのプロパティ名から一意である必要があります。

ルートノードには、ノード名またはユニットアドレスがありません。スラッシュ(/)で識別されます。

digraph tree { rankdir = LR; ranksep = equally; size = "6,8" node [ shape="Mrecord"; width="2.5"; fontname = Courier; ]; "/":e -> "cpus":w "cpus":e -> "cpu@0":w "cpus":e -> "cpu@1":w "/":e -> "memory@0":w "/":e -> "uart@fe001000":w "/":e -> "ethernet@fe002000":w "/":e -> "ethernet@fe003000":w }

図 2.2 Examples of Node Names

In 図 2.2:

  • cpu という名前のノードは、0と1のユニットアドレス値によって区別されます。

  • ethernet という名前のノードは、ユニットアドレス値 fe002000 および fe003000 によって区別されます。

2.2.2. 一般名の推奨事項

ノードの名前は、正確なプログラミングモデルではなく、デバイスの機能を反映して、ある程度一般的なものにする必要があります。 必要に応じて、名前は次のいずれかの選択肢になります。

  • adc

  • accelerometer

  • air-pollution-sensor

  • atm

  • audio-codec

  • audio-controller

  • backlight

  • bluetooth

  • bus

  • cache-controller

  • camera

  • can

  • charger

  • clock

  • clock-controller

  • co2-sensor

  • compact-flash

  • cpu

  • cpus

  • crypto

  • disk

  • display

  • dma-controller

  • dsi

  • dsp

  • eeprom

  • efuse

  • endpoint

  • ethernet

  • ethernet-phy

  • fdc

  • flash

  • gnss

  • gpio

  • gpu

  • gyrometer

  • hdmi

  • hwlock

  • i2c

  • i2c-mux

  • ide

  • interrupt-controller

  • iommu

  • isa

  • keyboard

  • key

  • keys

  • lcd-controller

  • led

  • leds

  • led-controller

  • light-sensor

  • lora

  • magnetometer

  • mailbox

  • mdio

  • memory

  • memory-controller

  • mmc

  • mmc-slot

  • mouse

  • nand-controller

  • nvram

  • oscillator

  • parallel

  • pc-card

  • pci

  • pcie

  • phy

  • pinctrl

  • pmic

  • pmu

  • port

  • ports

  • power-monitor

  • pwm

  • regulator

  • reset-controller

  • rng

  • rtc

  • sata

  • scsi

  • serial

  • sound

  • spi

  • spmi

  • sram-controller

  • ssi-controller

  • syscon

  • temperature-sensor

  • timer

  • touchscreen

  • tpm

  • usb

  • usb-hub

  • usb-phy

  • video-codec

  • vme

  • watchdog

  • wifi

2.2.3. パス名

デバイスツリー内のノードは、ルートノードからすべての子孫ノードを経由して目的のノードまでのフルパスを指定することで一意に識別できます。

デバイスパスを指定するための規則は次のとおりです。

/node-name-1/node-name-2/node-name-N

たとえば、 図 2.2 では、CPU#1 へのデバイスパスは次のようになります。

/cpus/cpu@1

ルートノードへのパスは/です。

ノードへのフルパスが明確な場合は、ユニットアドレスを省略できます。

クライアントプログラムがあいまいなパスに遭遇した場合、その動作は定義されていません。

2.2.4. プロパティ

デバイスツリーの各ノードには、ノードの特性を説明するプロパティがあります。 プロパティは、名前と値で構成されます。

2.2.4.1. プロパティ名

プロパティ名は、 表 2.2 に表示される文字の1〜31文字の文字列です。

表 2.2 Valid characters for property names

Character

Description

0-9

digit

a-z

lowercase letter

A-Z

uppercase letter

,

comma

.

period

_

underscore

+

plus sign

?

question mark

#

hash

-

dash

非標準のプロパティ名では、プロパティを定義した会社または組織の名前を識別する、株式相場記号などの一意の文字列プレフィックスを指定する必要があります。 例:

fsl,channel-fifo-len
ibm,ppc-interrupt-server#s
linux,network-index

2.2.4.2. プロパティ値

プロパティ値は、プロパティに関連付けられた情報を含む0バイト以上の配列です。

真偽の情報を伝達する場合、プロパティの値は空になる可能性があります。 この場合、プロパティの有無は十分に説明的です。

表 2.3 は、 DTSpec で定義された基本的な値型のセットを記述します。

表 2.3 プロパティ値

説明

<empty>

値は空です。 プロパティ自体の有無が十分に説明的である場合に、真偽の情報を伝達するために使用されます。

<u32>

ビッグエンディアン形式の32ビット整数。 例: 32ビット値0x11223344は、メモリ内で次のように表されます。

address    11
address+1  22
address+2  33
address+3  44

<u64>

ビッグエンディアン形式の64ビット整数を表します。 2つの <u32> 値で構成され、最初の値には整数の最上位ビットが含まれ、2番目の値には最下位ビットが含まれます。

例: 64ビット値0x1122334455667788は、2つのセルとして <0x11223344 0x55667788> として表されます。

値はメモリ内で次のように表されます。

  address  11
address+1  22
address+2  33
address+3  44
address+4  55
address+5  66
address+6  77
address+7  88

<string>

文字列はプリント可能で、null終端させます。 例: 文字列 "hello" は、メモリ内で次のように表されます。

  address  68  'h'
address+1  65  'e'
address+2  6C  'l'
address+3  6C  'l'
address+4  6F  'o'
address+5  00  '\0'

<prop-encoded-array>

形式はプロパティに固有です。 プロパティの定義を参照してください。

<phandle>

<u32> 値。 phandle 値は、デバイスツリー内の別のノードを参照する方法です。 参照できるノードはすべて、一意の <u32> 値を持つ phandle プロパティを定義します。 その番号は、phandle 値タイプのプロパティの値に使用されます。

<stringlist>

連結された <string> 値のリスト。

例: 文字列リスト "hello", "world" は、メモリ内で次のように表されます。

   address  68  'h'
 address+1  65  'e'
 address+2  6C  'l'
 address+3  6C  'l'
 address+4  6F  'o'
 address+5  00  '\0'
 address+6  77  'w'
 address+7  6f  'o'
 address+8  72  'r'
 address+9  6C  'l'
address+10  64  'd'
address+11  00  '\0'

2.3. 標準プロパティ

DTSpec はデバイスノードの標準プロパティのセットを指定します。 これらのプロパティについては、このセクションで詳しく説明します。 DTSpec で定義されたデバイスノード(第 3 章 を参照)は、標準プロパティの使用に関する追加の要件または制約を指定する場合があります。

第 4 章 は、特定のデバイスの表現を説明し、追加の要件を指定する場合もあります。

注釈

このドキュメントのデバイスツリーノードのすべての例では、ノードとプロパティを指定するために DTS 形式を使用しています。

2.3.1. compatible

プロパティ名: compatible

値のタイプ: <stringlist>

説明:

compatible プロパティ値は、デバイスの特定のプログラミングモデルを定義する1つ以上の文字列で構成されます。 この文字列のリストは、クライアントプログラムがデバイスドライバを選択するために使用する必要があります。 プロパティ値は、最も具体的なものから最も一般的なものまで、null終端文字列の連結リストで構成されます。 これらにより、デバイスは類似デバイスのファミリーとの互換性を表現できるため、単一のデバイスドライバーを複数のデバイスと照合できる可能性があります。

推奨される形式は "manufacturer,model" です。ここで、 manufacturer は製造元の名前(株式相場記号など)を説明する文字列であり、 model はモデル番号を指定します。

compatible の文字列は、小文字、数字、ダッシュのみで構成され、英文字で始まる必要があります。 単一のコンマは通常、ベンダープレフィックスの後にのみ使用されます。 下線は使用しないでください。

例:

compatible = "fsl,mpc8641", "ns16550";

この例では、オペレーティングシステムは、最初に fsl,mpc8641 をサポートするデバイスドライバーを見つけようとします。 ドライバーが見つからなかった場合は、より一般的な ns16550 デバイスタイプをサポートするドライバーを見つけようとします。

2.3.2. model

プロパティ名: model

値のタイプ: <string>

説明

モデルプロパティ値は、デバイスの製造元のモデル番号を指定する <string> です。

推奨される形式は "manufacturer,model" です。 ここで、 manufacturer は製造元の名前(株式相場記号など)を説明する文字列であり、modelはモデル番号を指定します。

Example:

model = "fsl,MPC8349EMITX";

2.3.3. phandle

プロパティ名: phandle

値のタイプ: <u32>

説明:

説明: phandle プロパティは、デバイスツリー内で一意のノードの数値識別子を指定します。 phandle プロパティ値は、プロパティに関連付けられたノードを参照する必要がある他のノードによって使用されます。

例:

次のデバイスツリーの抜粋を参照してください。


pic@10000000 {

phandle = <1>; interrupt-controller; reg = <0x10000000 0x100>;

};

phandle値に 1 が定義されています。 別のデバイスノードは、 phandle 値が1のpicノードを参照できます。

another-device-node {
interrupt-parent = <1>;
};

注釈

linux,phandle と呼ばれるこのプロパティの廃止された形式を含む古いバージョンのデバイス ツリーが検出される場合があります。 互換性のために、 phandle プロパティが存在しない場合、クライアント プログラムは linux,phandle をサポートする必要がある場合があります。 2 つのプロパティの意味と使用法は同じです。

注釈

Most devicetrees in DTS (see Appendix A) will not contain explicit phandle properties. The DTC tool automatically inserts the phandle properties when the DTS is compiled into the binary DTB format.

2.3.4. status

プロパティ名: status

値のタイプ: <string>

説明:

status プロパティは、デバイスの動作ステータスを示します。 status プロパティの欠如は、プロパティが "okay" の値で存在するかのように扱われる必要があります。 有効な値は、 表 2.4 にリストされて定義されています。

表 2.4 ステータスプロパティの値

説明

"okay"

デバイスが動作可能であることを示します。

"disabled"

デバイスが現在動作していないが、将来動作する可能性があることを示します(たとえば、何かが接続されていないか、スイッチがオフになっています)。 特定のデバイスの無効化の意味の詳細については、デバイスバインディングを参照してください。

"reserved"

デバイスが動作可能であることを示しますが、使用しないでください。 通常、これは、プラットフォームファームウェアなどの別のソフトウェアコンポーネントによって制御されるデバイスに使用されます。

"fail"

デバイスが動作していないことを示します。 デバイスで重大なエラーが検出されたため、修復せずに動作する可能性はほとんどありません。

"fail-sss"

デバイスが動作していないことを示します。 デバイスで重大なエラーが検出されたため、修復せずに動作する可能性はほとんどありません。 値の sss 部分はデバイスに固有であり、検出されたエラー状態を示します。

2.3.5. #address-cells と #size-cells

プロパティ名: #address-cells, #size-cells

値のタイプ: <u32>

説明:

#address-cells プロパティと #size-cells プロパティは、デバイスツリー階層に子があり、子デバイスノードのアドレス指定方法を説明する任意のデバイスノードで使用できます。 #address-cells プロパティは、子ノードの reg プロパティのアドレスフィールドをエンコードするために使用される <u32> セルの数を定義します。 #size-cells プロパティは、子ノードの reg プロパティのサイズフィールドをエンコードするために使用される <u32> セルの数を定義します。

#address-cells プロパティと #size-cells プロパティは、デバイスツリーの祖先から継承されません。 それらは明示的に定義されなければなりません。

DTSpec 準拠のブートプログラムは、子を持つすべてのノードに #address-cells#size-cells を提供する必要があります。

欠落している場合、クライアントプログラムはデフォルト値として #address-cells に値 2 を、#size-cells に値 1 を想定する必要があります。

例:

次のデバイスツリーの抜粋を参照してください。

soc {
   #address-cells = <1>;
   #size-cells = <1>;

   serial@4600 {
      compatible = "ns16550";
      reg = <0x4600 0x100>;
      clock-frequency = <0>;
      interrupts = <0xA 0x8>;
      interrupt-parent = <&ipic>;
   };
};

この例では、 soc ノードの #address-cells プロパティと #size-cells プロパティの両方が 1 に設定されています。 この設定は、このノードの子は、アドレスを表すために1つのセルが必要であり、ノードのサイズを表すために1つのセルが必要であることを指定します。

シリアルデバイスの reg プロパティは、親 (soc) ノードで設定されたこの仕様に従う必要があります。 アドレスは単一のセル (0x4600) で表され、サイズは単一のセル (0x100) で表されます。

2.3.6. reg

プロパティ名: reg

プロパティ値: 任意の数の(アドレス長さ)のペアとしてエンコードされた <prop-encoded-array>

説明:

reg プロパティは、親バスによって定義されたアドレス空間内のデバイスのリソースのアドレスを記述します。 最も一般的には、これはメモリマップドIOレジスタブロックのオフセットと長さを意味しますが、一部のバスタイプでは異なる意味を持つ場合があります。 ルートノードによって定義されたアドレス空間のアドレスは、CPUの実アドレスです。

値は <prop-encoded-array> であり、アドレスと長さの任意の数のペア <address length> で構成されます。 アドレスと長さを指定するために必要な <u32> セルの数はバス固有であり、デバイスノードの親の #address-cells プロパティと #size-cells プロパティによって指定されます。 親ノードが #size-cells に値0を指定する場合、 reg の値の長さフィールドは省略されます。

例:

システムオンチップ内のデバイスに2つのレジスタブロックがあり、SOCのオフセット0x3000に32バイトのブロックがあり、オフセット0xFE00に256バイトのブロックがあるとします。 reg プロパティは次のようにエンコードされます(#address-cells#size-cells の値が 1 であると想定)。

reg = <0x3000 0x20 0xFE00 0x100>;

2.3.7. virtual-reg

プロパティ名: virtual-reg

値のタイプ: <u32>

説明:

virtual-reg プロパティは、デバイスノードの reg プロパティで指定された最初の物理アドレスにマップする実効アドレスを指定します。 このプロパティにより、ブートプログラムは、設定された仮想から物理へのマッピングをクライアントプログラムに提供できます。

2.3.8. ranges

プロパティ名: ranges

値のタイプ: <empty> または、任意の数の(子バスアドレス、親バスアドレス、長さ)のトリプレットとしてエンコードされた <prop-encoded-array>

説明:

ranges プロパティは、バスのアドレス空間(子アドレス空間)とバスノードの親のアドレス空間(親アドレス空間)の間のマッピングまたは変換を定義する手段を提供します。

ranges プロパティの値の形式は、任意の数の(子バスアドレス親バスアドレス長さ)のトリプレットです。

  • 子バスアドレス は、子バスのアドレス空間内の物理アドレスです。 アドレスを表すセルの数はバスに依存し、このノード(ranges プロパティが表示されるノード)の #address-cells から決定できます。

  • 親バスアドレス は、親バスのアドレス空間内の物理アドレスです。 親アドレスを表すセルの数はバスに依存し、親のアドレス空間を定義するノードの #address-cells プロパティから決定できます。

  • 長さ は、子のアドレス空間の範囲のサイズを指定します。 サイズを表すセルの数は、このノード(ranges プロパティが表示されるノード)の #size-cells から決定できます。

プロパティが <empty> 値で定義されている場合、親と子のアドレススペースが同一であり、アドレス変換は不要であることを指定します。

プロパティがバスノードに存在しない場合、ノードの子と親アドレス空間の間にマッピングが存在しないと見なされます。

アドレス変換の例:

soc {
   compatible = "simple-bus";
   #address-cells = <1>;
   #size-cells = <1>;
   ranges = <0x0 0xe0000000 0x00100000>;

   serial@4600 {
      device_type = "serial";
      compatible = "ns16550";
      reg = <0x4600 0x100>;
      clock-frequency = <0>;
      interrupts = <0xA 0x8>;
      interrupt-parent = <&ipic>;
   };
};

soc ノードは次の範囲プロパティを指定します。

<0x0 0xe0000000 0x00100000>;

このプロパティ値は、1024 KBの範囲のアドレス空間に対して、物理 0x0 でアドレス指定された子ノードが物理 0xe0000000 の親アドレスにマップされることを指定します。 このマッピングを使用すると、シリアルデバイスノードは、アドレス 0xe0004600 、オフセット 0x4600 (reg で指定)、および ranges で指定された 0xe0000000 マッピングでロードまたはストアによってアドレス指定できます。

2.3.9. dma-ranges

プロパティ名: dma-ranges

値のタイプ: <empty> または任意の数の (child-bus-address, parent-bus-address, length) トリプレットとしてエンコードされた <prop-encoded-array>

説明:

dma-ranges プロパティは、バスに由来するDMA操作からデバイスツリーの親にアクセスできるメモリマップドバスのダイレクトメモリアクセス (DMA) 構造を記述するために使用されます。 これは、バスの物理アドレス空間とバスの親の物理アドレス空間の間のマッピングまたは変換を定義する手段を提供します。

dma-ranges プロパティの値の形式は、 (child-bus-address, parent-bus-address, length) の任意の数のトリプレットです。 指定された各トリプレットは、連続する DMA アドレス範囲を表します。

  • child-bus-address は、子バスのアドレス空間内の物理アドレスです。 アドレスを表すセルの数はバスによって異なり、このノード (dma-ranges プロパティが表示されるノード) の #address-cells から決定できます。

  • parent-bus-address は、親バスのアドレス空間内の物理アドレスです。 親アドレスを表すセルの数はバスに依存し、親のアドレス空間を定義するノードの #address-cells プロパティから決定できます。

  • length は、子のアドレス空間の範囲のサイズを指定します。 サイズを表すセルの数は、このノード (dma-ranges プロパティが表示されるノード) の #size-cells から決定できます。

2.3.10. dma-coherent

プロパティ名: dma-coherent

値のタイプ: <empty>

説明:

デフォルトで I/O に対して非コヒーレントであるアーキテクチャの場合、 dma-coherent プロパティは、デバイスがコヒーレントDMA操作が可能であることを示すために使用されます。 一部のアーキテクチャにはデフォルトでコヒーレントDMAがあり、このプロパティは適用されません。

2.3.11. name (deprecated)

Property name: name

Value type: <string>

Description:

The name property is a string specifying the name of the node. This property is deprecated, and its use is not recommended. However, it might be used in older non-DTSpec-compliant devicetrees. Operating system should determine a node’s name based on the node-name component of the node name (see sect-node-names).

2.3.12. device_type (deprecated)

Property name: device_type

Value type: <string>

Description:

The device_type property was used in IEEE 1275 to describe the device’s FCode programming model. Because DTSpec does not have FCode, new use of the property is deprecated, and it should be included only on cpu and memory nodes for compatibility with IEEE 1275–derived devicetrees.

2.4. 割り込みと割り込みマッピング

DTSpec は Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 [b7] で指定された割り込みを表す割り込みツリーモデルを採用しています。 デバイスツリー内には、プラットフォームハードウェアの割り込みの階層とルーティングを表す論理割り込みツリーが存在します。 一般的に割り込みツリーと呼ばれますが、より技術的には有向非巡回グラフです。

割り込みソースから割り込みコントローラへの物理的な配線は、 interrupt-parent プロパティを持つデバイスツリーで表されます。 割り込み生成デバイスを表すノードには、デバイスの割り込みがルーティングされるデバイス(通常は割り込みコントローラー)を指す phandle 値を持つ interrupt-parent プロパティが含まれています。 割り込み生成デバイスに割り込み親プロパティがない場合、その割り込み親はデバイスツリーの親であると見なされます。

各割り込み生成デバイスには、そのデバイスの1つ以上の割り込みソースを説明する値を持つ interrupts プロパティが含まれています。 各ソースは、 interrupt specifier と呼ばれる情報で表されます。 interrupt specifier の形式と意味は、割り込みドメイン固有です。 つまり、割り込みドメインのルートにあるノードのプロパティに依存します。

#interrupt-cells プロパティは、割り込みドメインのルートによって使用され、割り込み指定子をエンコードするために必要な <u32> 値の数を定義します。 たとえば、Open PIC割り込みコントローラの場合、割り込み指示子は2つの32ビット値を取り、割り込み番号と割り込みのレベル/センス情報で構成されます。

割り込みドメインは、割り込み指定子が解釈されるコンテキストです。 ドメインのルートは、 (1) 割り込みコントローラーまたは (2) 割り込みネクサスのいずれかです。

  1. 割り込みコントローラー は物理デバイスであり、それを介してルーティングされる割り込みを処理するためのドライバーが必要になります。 また、別の割り込みドメインにカスケードされる場合もあります。 割り込みコントローラーは、デバイスツリー内のそのノードに interrupt-controller プロパティが存在することによって指定されます。

  1. 割り込みネクサス は、ある割り込みドメインと別の割り込みドメイン間の変換を定義します。 変換は、ドメイン固有の情報とバス固有の情報の両方に基づいています。 ドメイン間のこの変換は、 interrupt-map プロパティを使用して実行されます。 たとえば、PCIコントローラーデバイスノードは、PCI割り込みネームスペース (INTA、INTBなど) から割り込み要求 (IRQ) 番号を持つ割り込みコントローラーへの変換を定義する割り込みネクサスである可能性があります。

割り込みツリーのルートは、割り込みツリーのトラバースが interrupts プロパティなしで割り込みコントローラーノードに到達したときに決定されます。 したがって、明示的な割り込みの親はありません。

割り込みの親関係が示されているデバイスツリーのグラフィック表現の例については、図 2.3 を参照してください。 これは、デバイスツリーの自然な構造と、各ノードが論理割り込みツリーのどこにあるかを示しています。

digraph tree { rankdir = LR ranksep = "1.5" size = "6,8" edge [ dir="none" ] node [ shape="Mrecord" width="2.5" ] subgraph cluster_devices { label = "Devicetree" graph [ style = dotted ] "soc" [ ] "device1" [ label = "device1 | interrupt-parent=\<&open-pic\>" ] "device2" [ label = "device2 | interrupt-parent=\<&gpioctrl\>" ] "pci-host" [ label = "pci-host | interrupt-parent=\<&open-pic\>" ] "slot0" [ label = "slot0 | interrupt-parent=\<&pci-host\>" ] "slot1" [ label = "slot1 | interrupt-parent=\<&pci-host\>" ] "simple-bus" [ label = "simple-bus" ] "gpioctrl" [ label = "gpioctrl | interrupt-parent=\<&open-pic\>" ] "device3" [ label = "device3 | interrupt-parent=\<&gpioctrl\>" ] edge [dir=back color=blue] "soc":e -> "device1":w "soc":e -> "device2":w "soc":e -> "open-pic":w "soc":e -> "pci-host":w "soc":e -> "simple-bus":w "pci-host":e -> "slot0":w "pci-host":e -> "slot1":w "simple-bus":e -> "gpioctrl":w "simple-bus":e -> "device3":w } subgraph cluster_interrupts { label = "Interrupt tree" graph [ style = dotted ] "i-open-pic" [ label = "open-pic | Root of Interrupt tree" ] "i-pci-host" [ label = "pci-host | Nexus Node" ] "i-gpioctrl" [ label = "gpioctrl | Nexus Node" ] "i-device1" [ label = "device1" ] "i-device2" [ label = "device2" ] "i-device3" [ label = "device3" ] "i-slot0" [ label = "slot0" ] "i-slot1" [ label = "slot1" ] edge [dir=back color=green] "i-open-pic":e -> "i-device1":w "i-open-pic":e -> "i-pci-host":w "i-open-pic":e -> "i-gpioctrl":w "i-pci-host":e -> "i-slot0":w "i-pci-host":e -> "i-slot1":w "i-gpioctrl":e -> "i-device2":w "i-gpioctrl":e -> "i-device3":w } subgraph { edge [color=red, style=dotted, constraint=false] "open-pic" -> "i-open-pic" "gpioctrl":w -> "i-gpioctrl" "pci-host" -> "i-pci-host" "slot0":e -> "i-slot0":e "slot1":e -> "i-slot1":e "device2":e -> "i-device2":w "device3":e -> "i-device3":e } }

図 2.3 Example of the interrupt tree

In the example shown in 図 2.3:

  • The open-pic interrupt controller is the root of the interrupt tree.

  • The interrupt tree root has three children—devices that route their interrupts directly to the open-pic

    • device1

    • PCI host controller

    • GPIO Controller

  • Three interrupt domains exist; one rooted at the open-pic node, one at the PCI host bridge node, and one at the GPIO Controller node.

  • There are two nexus nodes; one at the PCI host bridge and one at the GPIO controller.

2.4.1. 割り込み生成デバイスのプロパティ

2.4.1.1. interrupts

プロパティ: interrupts

値のタイプ: 任意の数の割り込み指定子としてエンコードされた <prop-encoded-array>

説明:

デバイスノードの interrupts プロパティは、デバイスによって生成される1つまたは複数の割り込みを定義します。 interrupts プロパティの値は、任意の数の割り込み指定子で構成されます。 割り込み指定子の形式は、割り込みドメインルートのバインディングによって定義されます。

interruptsinterrupts-extended プロパティによってオーバーライドされ、通常はどちらか一方のみを使用する必要があります。

例:

オープンなPIC互換割り込みドメインでの割り込み指定子の一般的な定義は、割り込み番号とレベル/センス情報という2つのセルで構成されます。 次の例を参照してください。 この例では、割り込み番号が 0xA でレベル/センスエンコーディングが8の単一の割り込み指定子を定義しています。

interrupts = <0xA 8>;

2.4.1.2. interrupt-parent

プロパティ: interrupt-parent

値のタイプ: <phandle>

説明:

割り込みツリー内のノードの階層がデバイスツリーと一致しない可能性があるため、 interrupt-parent プロパティを使用して、割り込みの親の定義を明示的にすることができます。 値は、割り込みの親へのphandleです。このプロパティがデバイスにない場合、その割り込みの親はデバイスツリーの親であると見なされます。

2.4.1.3. interrupts-extended

プロパティ: interrupts-extended

値のタイプ: <phandle> <prop-encoded-array>

説明:

interrupts-extended プロパティは、デバイスによって生成された割り込みを一覧表示します。 割り込み-デバイスが複数の割り込みコントローラーに接続されている場合は、各割り込み指定子で親phandleをエンコードするため、interrupts の代わりに interrupts-extended を使用する必要があります。

例:

この例は、2つの割り込み出力が2つの別々の割り込みコントローラーに接続されているデバイスが、interrupts-extended プロパティを使用して接続を記述する方法を示しています。 pic#interrupt-cells 指定子が 2 の割り込みコントローラーであり、 gic#interrupts-cells 指定子が 1 の割り込みコントローラーです。

interrupts-extended = <&pic 0xA 8>, <&gic 0xda>;

interruptsinterrupts-extended プロパティは相互に排他的です。 デバイスノードはどちらか一方を使用する必要がありますが、両方を使用することはできません。 両方の使用は、 interrupts-extended を理解しないソフトウェアとの互換性のために必要な場合にのみ許可されます。 interrupts-extendedinterrupts の両方が存在する場合は、割り込み拡張が優先されます。

2.4.2. 割り込みコントローラのプロパティ

2.4.2.1. #interrupt-cells

Property: #interrupt-cells

Value type: <u32>

Description:

The #interrupt-cells property defines the number of cells required to encode an interrupt specifier for an interrupt domain.

2.4.2.2. interrupt-controller

Property: interrupt-controller

Value type: <empty>

Description:

The presence of an interrupt-controller property defines a node as an interrupt controller node.

2.4.3. Interrupt Nexus Properties

An interrupt nexus node shall have an #interrupt-cells property.

2.4.3.1. interrupt-map

Property: interrupt-map

Value type: <prop-encoded-array> encoded as an arbitrary number of interrupt mapping entries.

Description:

An interrupt-map is a property on a nexus node that bridges one interrupt domain with a set of parent interrupt domains and specifies how interrupt specifiers in the child domain are mapped to their respective parent domains.

The interrupt map is a table where each row is a mapping entry consisting of five components: child unit address, child interrupt specifier, interrupt-parent, parent unit address, parent interrupt specifier.

child unit address

The unit address of the child node being mapped. The number of 32-bit cells required to specify this is described by the #address-cells property of the bus node on which the child is located.

child interrupt specifier

The interrupt specifier of the child node being mapped. The number of 32-bit cells required to specify this component is described by the #interrupt-cells property of this node—the nexus node containing the interrupt-map property.

interrupt-parent

A single <phandle> value that points to the interrupt parent to which the child domain is being mapped.

parent unit address

The unit address in the domain of the interrupt parent. The number of 32-bit cells required to specify this address is described by the #address-cells property of the node pointed to by the interrupt-parent field.

parent interrupt specifier

The interrupt specifier in the parent domain. The number of 32-bit cells required to specify this component is described by the #interrupt-cells property of the node pointed to by the interrupt-parent field.

Lookups are performed on the interrupt mapping table by matching a unit-address/interrupt specifier pair against the child components in the interrupt-map. Because some fields in the unit interrupt specifier may not be relevant, a mask is applied before the lookup is done. This mask is defined in the interrupt-map-mask property (see 2.4.3.2 章).

注釈

Both the child node and the interrupt parent node are required to have #address-cells and #interrupt-cells properties defined. If a unit address component is not required, #address-cells shall be explicitly defined to be zero.

2.4.3.2. interrupt-map-mask

Property: interrupt-map-mask

Value type: <prop-encoded-array> encoded as a bit mask

Description:

An interrupt-map-mask property is specified for a nexus node in the interrupt tree. This property specifies a mask that is ANDed with the incoming unit interrupt specifier being looked up in the table specified in the interrupt-map property.

2.4.3.3. #interrupt-cells

Property: #interrupt-cells

Value type: <u32>

Description:

The #interrupt-cells property defines the number of cells required to encode an interrupt specifier for an interrupt domain.

2.4.4. Interrupt Mapping Example

The following shows the representation of a fragment of a devicetree with a PCI bus controller and a sample interrupt map for describing the interrupt routing for two PCI slots (IDSEL 0x11,0x12). The INTA, INTB, INTC, and INTD pins for slots 1 and 2 are wired to the Open PIC interrupt controller.

soc {
   compatible = "simple-bus";
   #address-cells = <1>;
   #size-cells = <1>;

   open-pic {
      clock-frequency = <0>;
      interrupt-controller;
      #address-cells = <0>;
      #interrupt-cells = <2>;
   };

   pci {
      #interrupt-cells = <1>;
      #size-cells = <2>;
      #address-cells = <3>;
      interrupt-map-mask = <0xf800 0 0 7>;
      interrupt-map = <
         /* IDSEL 0x11 - PCI slot 1 */
         0x8800 0 0 1 &open-pic 2 1 /* INTA */
         0x8800 0 0 2 &open-pic 3 1 /* INTB */
         0x8800 0 0 3 &open-pic 4 1 /* INTC */
         0x8800 0 0 4 &open-pic 1 1 /* INTD */
         /* IDSEL 0x12 - PCI slot 2 */
         0x9000 0 0 1 &open-pic 3 1 /* INTA */
         0x9000 0 0 2 &open-pic 4 1 /* INTB */
         0x9000 0 0 3 &open-pic 1 1 /* INTC */
         0x9000 0 0 4 &open-pic 2 1 /* INTD */
      >;
   };
};

One Open PIC interrupt controller is represented and is identified as an interrupt controller with an interrupt-controller property.

Each row in the interrupt-map table consists of five parts: a child unit address and interrupt specifier, which is mapped to an interrupt-parent node with a specified parent unit address and interrupt specifier.

  • For example, the first row of the interrupt-map table specifies the mapping for INTA of slot 1. The components of that row are shown here

    child unit address: 0x8800 0 0
    child interrupt specifier: 1
    interrupt parent: &open-pic
    parent unit address: (empty because #address-cells = <0> in the open-pic node)
    parent interrupt specifier: 2 1
    • The child unit address is <0x8800 0 0>. This value is encoded with three 32-bit cells, which is determined by the value of the #address-cells property (value of 3) of the PCI controller. The three cells represent the PCI address as described by the binding for the PCI bus.

      • The encoding includes the bus number (0x0 << 16), device number (0x11 << 11), and function number (0x0 << 8).

    • The child interrupt specifier is <1>, which specifies INTA as described by the PCI binding. This takes one 32-bit cell as specified by the #interrupt-cells property (value of 1) of the PCI controller, which is the child interrupt domain.

    • The interrupt parent is specified by a phandle which points to the interrupt parent of the slot, the Open PIC interrupt controller.

    • The parent has no unit address because the parent interrupt domain (the open-pic node) has an #address-cells value of <0>.

    • The parent interrupt specifier is <2 1>. The number of cells to represent the interrupt specifier (two cells) is determined by the #interrupt-cells property on the interrupt parent, the open-pic node.

      • The value <2 1> is a value specified by the device binding for the Open PIC interrupt controller (see 4.5 章). The value <2> specifies the physical interrupt source number on the interrupt controller to which INTA is wired. The value <1> specifies the level/sense encoding.

In this example, the interrupt-map-mask property has a value of <0xf800 0 0 7>. This mask is applied to a child unit interrupt specifier before performing a lookup in the interrupt-map table.

To perform a lookup of the open-pic interrupt source number for INTB for IDSEL 0x12 (slot 2), function 0x3, the following steps would be performed:

  • The child unit address and interrupt specifier form the value <0x9300 0 0 2>.

    • The encoding of the address includes the bus number (0x0 << 16), device number (0x12 << 11), and function number (0x3 << 8).

    • The interrupt specifier is 2, which is the encoding for INTB as per the PCI binding.

  • The interrupt-map-mask value <0xf800 0 0 7> is applied, giving a result of <0x9000 0 0 2>.

  • That result is looked up in the interrupt-map table, which maps to the parent interrupt specifier <4 1>.

2.5. Nexus Nodes and Specifier Mapping

2.5.1. Nexus Node Properties

A nexus node shall have a #<specifier>-cells property, where <specifier> is some specifier space such as 'gpio', 'clock', 'reset', etc.

2.5.1.1. <specifier>-map

Property: <specifier>-map

Value type: <prop-encoded-array> encoded as an arbitrary number of specifier mapping entries.

Description:

A <specifier>-map is a property in a nexus node that bridges one specifier domain with a set of parent specifier domains and describes how specifiers in the child domain are mapped to their respective parent domains.

The map is a table where each row is a mapping entry consisting of three components: child specifier, specifier parent, and parent specifier.

child specifier

The specifier of the child node being mapped. The number of 32-bit cells required to specify this component is described by the #<specifier>-cells property of this node—the nexus node containing the <specifier>-map property.

specifier parent

A single <phandle> value that points to the specifier parent to which the child domain is being mapped.

parent specifier

The specifier in the parent domain. The number of 32-bit cells required to specify this component is described by the #<specifier>-cells property of the specifier parent node.

Lookups are performed on the mapping table by matching a specifier against the child specifier in the map. Because some fields in the specifier may not be relevant or need to be modified, a mask is applied before the lookup is done. This mask is defined in the <specifier>-map-mask property (see 2.5.1.2 章).

Similarly, when the specifier is mapped, some fields in the unit specifier may need to be kept unmodified and passed through from the child node to the parent node. In this case, a <specifier>-map-pass-thru property (see 2.5.1.3 章) may be specified to apply a mask to the child specifier and copy any bits that match to the parent unit specifier.

2.5.1.2. <specifier>-map-mask

Property: <specifier>-map-mask

Value type: <prop-encoded-array> encoded as a bit mask

Description:

A <specifier>-map-mask property may be specified for a nexus node. This property specifies a mask that is ANDed with the child unit specifier being looked up in the table specified in the <specifier>-map property. If this property is not specified, the mask is assumed to be a mask with all bits set.

2.5.1.3. <specifier>-map-pass-thru

Property: <specifier>-map-pass-thru

Value type: <prop-encoded-array> encoded as a bit mask

Description:

A <specifier>-map-pass-thru property may be specified for a nexus node. This property specifies a mask that is applied to the child unit specifier being looked up in the table specified in the <specifier>-map property. Any matching bits in the child unit specifier are copied over to the parent specifier. If this property is not specified, the mask is assumed to be a mask with no bits set.

2.5.1.4. #<specifier>-cells

プロパティ: #<specifier>-cells

値のタイプ: <u32>

説明:

#<specifier>-cells プロパティは、ドメインの指定子をエンコードするために必要なセルの数を定義します。

2.5.2. 指定子マッピングの例

以下は、2つのGPIOコントローラーを備えたデバイスツリーのフラグメントの表現と、ボード上のコネクターを介してデバイスへの両方のコントローラー上のいくつかのgpiosのGPIOルーティングを記述するための指定子マップのサンプルを示しています。 拡張デバイスノードはコネクタノードの片側にあり、2つのGPIOコントローラを備えたSoCはコネクタの反対側にあります。

soc {
        soc_gpio1: gpio-controller1 {
                #gpio-cells = <2>;
        };

        soc_gpio2: gpio-controller2 {
                #gpio-cells = <2>;
        };
};

connector: connector {
        #gpio-cells = <2>;
        gpio-map = <0 0 &soc_gpio1 1 0>,
                   <1 0 &soc_gpio2 4 0>,
                   <2 0 &soc_gpio1 3 0>,
                   <3 0 &soc_gpio2 2 0>;
        gpio-map-mask = <0xf 0x0>;
        gpio-map-pass-thru = <0x0 0x1>;
};

expansion_device {
        reset-gpios = <&connector 2 GPIO_ACTIVE_LOW>;
};

gpio-map テーブルの各行は、3 つの部分で構成されています。 子ユニット指定子は、親指定子を使用して gpio-controller ノードにマップされます。

  • 例えば、specifier-mapテーブルの最初の行は、コネクタの GPIO 0 のマッピングを指定します。 その行のコンポーネントをここに示します

    子指定子: 0 0
    指定子の親: &soc_gpio1
    親指定子: 1 0
    • 子指定子は <0 0> であり、 flags フィールドが 0 のコネクタで GPIO 0 を指定します。 これは、子指定子ドメインであるコネクタノードの #gpio-cells プロパティで指定された2つの32ビットセルを取ります。

    • 指定子の親は、コネクタの指定子の親、つまりSoCの最初の GPIO コントローラーを指す phandle によって指定されます。

    • 親指定子は <1 0> です。 gpio 指定子(2つのセル)を表すセルの数は、指定子の親である soc_gpio1 ノードの #gpio-cells プロパティによって決定されます。

      • <1 0> は、GPIO コントローラーのデバイスバインディングによって指定された値です。

      <1> は、コネクタの GPIO 0 が配線されている GPIO コントローラの GPIO ピン番号を指定します。 値 <0> は、フラグ(アクティブロー、アクティブハイなど)を指定します。

この例では、gpio-map-mask プロパティの値は <0xf0> です。 このマスクは、 gpio-map テーブルでルックアップを実行する前に子ユニット指定子に適用されます。 同様に、 gpio-map-pass-thru プロパティの値は <0x0 0x1> です。 このマスクは、子ユニット指定子を親ユニット指定子にマッピングするときに適用されます。 このマスクに設定されたビットはすべて、親ユニット指定子からクリアされ、子ユニット指定子から親ユニット指定子にコピーされます。

拡張デバイスの reset-gpios プロパティから GPIO 2 のコネクタの指定元ソース番号のルックアップを実行するには、次の手順を実行します。

  • The child specifier forms the value <2 GPIO_ACTIVE_LOW>.

    • The specifier is encoding GPIO 2 with active low flags per the GPIO binding.

  • The gpio-map-mask value <0xf 0x0> is ANDed with the child specifier, giving a result of <0x2 0>.

  • The result is looked up in the gpio-map table, which maps to the parent specifier <3 0> and &soc_gpio1 phandle.

  • The gpio-map-pass-thru value <0x0 0x1> is inverted and ANDed with the parent specifier found in the gpio-map table, resulting in <3 0>. The child specifier is ANDed with the gpio-map-pass-thru mask, forming <0 GPIO_ACTIVE_LOW> which is then ORed with the cleared parent specifier <3 0> resulting in <3 GPIO_ACTIVE_LOW>.

  • The specifier <3 GPIO_ACTIVE_LOW> is appended to the mapped phandle &soc_gpio1 resulting in <&soc_gpio1 3 GPIO_ACTIVE_LOW>.