irq_domain 中斷號對映庫¶
Linux 核心的當前設計使用一個大的編號空間,其中每個單獨的 IRQ 源都被分配一個唯一的編號。當只有一箇中斷控制器時,這很簡單。但在具有多箇中斷控制器的系統中,核心必須確保為每個中斷控制器分配不重疊的 Linux IRQ 編號。
註冊為唯一 irqchip 的中斷控制器數量呈上升趨勢。例如,諸如 GPIO 控制器之類的不同型別的子驅動程式透過將其中斷處理程式建模為 irqchip 來避免重新實現與 IRQ 核心系統相同的回撥機制。即,實際上是級聯中斷控制器。
因此,在過去,IRQ 編號可以選擇為與硬體 IRQ 線匹配到根中斷控制器(即,實際向 CPU 發出中斷線的元件)。如今,這個數字只是一個數字,並且該數字失去了與硬體中斷號的任何對應關係。
因此,我們需要一種機制來分離控制器本地中斷號(稱為硬體 IRQ)與 Linux IRQ 編號。
irq_alloc_desc*() 和 irq_free_desc*() API 提供 IRQ 編號的分配,但它們不提供對控制器本地 IRQ (hwirq) 編號到 Linux IRQ 編號空間的逆向對映的任何支援。
irq_domain 庫在 irq_alloc_desc*() API 之上添加了 hwirq 和 IRQ 編號之間的對映。優先使用 irq_domain 來管理對映,而不是中斷控制器驅動程式開放編碼其自己的反向對映方案。
irq_domain 還實現了從抽象 struct irq_fwspec 到 hwirq 編號的轉換(目前為止為裝置樹、非 DT 韌體節點、ACPI GSI 和軟體節點),並且可以輕鬆擴充套件以支援其他 IRQ 拓撲資料來源。該實現無需任何額外的平臺支援程式碼即可執行。
irq_domain 用法¶
struct irq_domain 可以定義為 irq 域控制器。也就是說,它處理給定中斷域的硬體和虛擬中斷號之間的對映。域結構通常由給定 PIC 例項的 PIC 程式碼建立(儘管域可以覆蓋多個 PIC,如果它們具有扁平編號模型)。域回撥負責在給定 irq_desc 上設定 irq_chip(在對映之後)。
主機程式碼和資料結構使用 fwnode_handle 指標來標識域。在某些情況下,為了保持原始碼相容性,此 fwnode 指標被“升級”為 DT device_node。對於那些不為中斷控制器提供唯一識別符號的韌體基礎設施,irq_domain 程式碼提供了一個 fwnode 分配器。
中斷控制器驅動程式透過呼叫 irq_domain_create_*() 函式之一(每種對映方法都有不同的分配器函式,稍後會詳細介紹)來建立和註冊 struct irq_domain。該函式將成功後返回指向 struct irq_domain 的指標。呼叫者必須為分配器函式提供一個 struct irq_domain_ops 指標。
在大多數情況下,irq_domain 將以空狀態開始,沒有任何 hwirq 和 IRQ 編號之間的對映。透過呼叫 irq_create_mapping() 將對映新增到 irq_domain,該函式接受 irq_domain 和 hwirq 編號作為引數。如果 hwirq 的對映尚不存在,irq_create_mapping() 將分配一個新的 Linux irq_desc,將其與 hwirq 關聯,並呼叫 irq_domain_ops.map() 回撥。在那裡,驅動程式可以執行任何所需的硬體設定。
一旦建立了對映,就可以透過多種方法檢索或使用它
irq_resolve_mapping()返回指向給定域和 hwirq 編號的 irq_desc 結構的指標,如果沒有對映,則返回 NULL。irq_find_mapping()返回給定域和 hwirq 編號的 Linux IRQ 編號,如果沒有對映,則返回 0generic_handle_domain_irq()處理由域和 hwirq 編號描述的中斷
請注意,irq 域查詢必須發生在與 RCU 讀取端關鍵部分相容的上下文中。
必須在任何呼叫 irq_find_mapping() 之前至少一次呼叫 irq_create_mapping() 函式,否則不會分配描述符。
如果驅動程式具有 Linux IRQ 編號或 irq_data 指標,並且需要知道關聯的 hwirq 編號(例如在 irq_chip 回撥中),則可以直接從 irq_data.hwirq 獲取。
irq_domain 對映型別¶
有幾種機制可用於從 hwirq 到 Linux irq 的反向對映,每種機制都使用不同的分配函式。應使用哪種反向對映型別取決於用例。以下描述了每種反向對映型別
線性¶
irq_domain_create_linear()
線性反向對映維護一個由 hwirq 編號索引的固定大小表。當對映 hwirq 時,將為 hwirq 分配一個 irq_desc,並將 IRQ 編號儲存在表中。
當 hwirq 的最大數量是固定的並且相對較小(~ < 256)時,線性對映是一個不錯的選擇。此對映的優點是 IRQ 編號的固定時間查詢,並且僅為使用中的 IRQ 分配 irq_desc。缺點是表必須與最大的 hwirq 編號一樣大。
大多數驅動程式應使用線性對映。
樹¶
irq_domain_create_tree()
irq_domain 維護從 hwirq 編號到 Linux IRQ 的基數樹對映。當對映 hwirq 時,將分配一個 irq_desc,並且 hwirq 用作基數樹的查詢鍵。
如果 hwirq 編號可能非常大,則樹對映是一個不錯的選擇,因為它不需要分配與最大 hwirq 編號一樣大的表。缺點是 hwirq 到 IRQ 編號的查詢取決於表中有多少個條目。
很少有驅動程式需要此對映。
無對映¶
irq_domain_create_nomap()
當可以在硬體中對 hwirq 編號進行程式設計時,應使用無對映。在這種情況下,最好將 Linux IRQ 編號程式設計到硬體本身中,這樣就不需要對映。呼叫 irq_create_direct_mapping() 將分配一個 Linux IRQ 編號並呼叫 .map() 回撥,以便驅動程式可以將 Linux IRQ 編號程式設計到硬體中。
大多數驅動程式無法使用此對映,並且它現在已在 CONFIG_IRQ_DOMAIN_NOMAP 選項上進行門控。請避免引入此 API 的新使用者。
舊版¶
irq_domain_create_simple()
irq_domain_create_legacy()
舊版對映是針對已經為 hwirq 分配了一系列 irq_desc 的驅動程式的特殊情況。當無法立即轉換驅動程式以使用線性對映時,將使用它。例如,許多嵌入式系統板支援檔案使用一組 #defines 作為傳遞給 struct device 註冊的 IRQ 編號。在這種情況下,無法動態分配 Linux IRQ 編號,應使用舊版對映。
顧名思義,*_legacy() 函式已被棄用,僅用於簡化對舊平臺的支援。不應新增新使用者。當 *_simple() 函式的使用導致舊版行為時,也是如此。
舊版對映假定已為控制器分配了連續的 IRQ 編號範圍,並且可以透過將固定偏移量新增到 hwirq 編號來計算 IRQ 編號,反之亦然。缺點是它要求中斷控制器管理 IRQ 分配,並且即使未使用,也需要為每個 hwirq 分配一個 irq_desc。
僅當必須支援固定 IRQ 對映時,才應使用舊版對映。例如,ISA 控制器將使用舊版對映來對映 Linux IRQ 0-15,以便現有 ISA 驅動程式獲得正確的 IRQ 編號。
舊版對映的大多數使用者應使用 irq_domain_create_simple(),如果系統提供了 IRQ 範圍,則該函式將僅使用舊版域,否則將使用線性域對映。此呼叫的語義是,如果指定了 IRQ 範圍,則將即時分配描述符,如果未指定範圍,則將回退到 irq_domain_create_linear(),這意味著不會分配 irq 描述符。
簡單域的典型用例是 irqchip 提供程式同時支援動態和靜態 IRQ 分配。
為了避免最終使用線性域並且沒有分配描述符的情況,非常重要的是,使用簡單域的驅動程式在任何 irq_find_mapping() 之前呼叫 irq_create_mapping(),因為後者實際上適用於靜態 IRQ 分配情況。
層次結構 IRQ 域¶
在某些體系結構上,可能涉及多箇中斷控制器,以便將中斷從裝置傳遞到目標 CPU。讓我們看一下 x86 平臺上的典型中斷傳遞路徑
Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
涉及三個中斷控制器
IOAPIC 控制器
中斷重對映控制器
本地 APIC 控制器
為了支援這樣的硬體拓撲並使軟體體系結構與硬體體系結構匹配,為每個中斷控制器構建了一個 irq_domain 資料結構,並將這些 irq_domain 組織成層次結構。構建 irq_domain 層次結構時,靠近裝置的 irq_domain 是子域,靠近 CPU 的 irq_domain 是父域。因此,將為上面的示例構建如下的層次結構
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
^
|
Interrupt Remapping irq_domain (manage irq_remapping entries)
^
|
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
有四個主要介面可用於層次結構 irq_domain
irq_domain_alloc_irqs():分配 IRQ 描述符和中斷控制器相關資源以傳遞這些中斷。irq_domain_free_irqs():釋放與這些中斷關聯的 IRQ 描述符和中斷控制器相關資源。irq_domain_activate_irq():啟用中斷控制器硬體以傳遞中斷。irq_domain_deactivate_irq():停用中斷控制器硬體以停止傳遞中斷。
支援層次結構 irq_domain 需要以下內容
struct irq_domain中的parent欄位用於維護 irq_domain 層次結構資訊。struct irq_data中的parent_data欄位用於構建層次結構 irq_data 以匹配層次結構 irq_domain。irq_data 用於儲存 irq_domain 指標和硬體 irq 編號。struct irq_domain_ops中的alloc()、free()和其他回撥用於支援層次結構 irq_domain 操作。
在支援層次結構 irq_domain 和層次結構 irq_data 準備就緒後,為每個中斷控制器構建一個 irq_domain 結構,併為與 IRQ 關聯的每個 irq_domain 分配一個 irq_data 結構。
為了使中斷控制器驅動程式支援層次結構 irq_domain,它需要
實現 irq_domain_ops.alloc() 和 irq_domain_ops.free()
可選地,實現 irq_domain_ops.activate() 和 irq_domain_ops.deactivate()。
可選地,實現 irq_chip 以管理中斷控制器硬體。
無需實現 irq_domain_ops.map() 和 irq_domain_ops.unmap()。它們與層次結構 irq_domain 不一起使用。
請注意,層次結構 irq_domain 絕不是 x86 特定的,並且被大量用於支援其他體系結構,例如 ARM、ARM64 等。
堆疊 irq_chip¶
現在,我們可以更進一步來支援堆疊(層次結構)irq_chip。也就是說,一個 irq_chip 與層次結構中的每個 irq_data 相關聯。子 irq_chip 可以透過自身或透過與其父 irq_chip 合作來實現所需的動作。
使用堆疊 irq_chip,中斷控制器驅動程式只需要處理自身管理的硬體,並且可以在需要時向其父 irq_chip 請求服務。因此,我們可以實現更清晰的軟體體系結構。
除錯¶
透過開啟 CONFIG_GENERIC_IRQ_DEBUGFS,IRQ 子系統的大部分內部結構都會在 debugfs 中公開。
提供的結構和公共函式¶
本章包含用於 IRQ 域的結構和匯出的核心 API 函式的自動生成文件。
-
struct irq_fwspec¶
通用 IRQ 說明符結構
定義:
struct irq_fwspec {
struct fwnode_handle *fwnode;
int param_count;
u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS];
};
成員
fwnode指向特定於韌體的描述符的指標
param_count特定於裝置的引數數量
param特定於裝置的引數
描述
此結構直接仿照 of_phandle_args,用於傳遞中斷的特定於裝置的描述。
-
struct irq_domain_ops¶
irq_domain 物件的方法
定義:
struct irq_domain_ops {
int (*match)(struct irq_domain *d, struct device_node *node, enum irq_domain_bus_token bus_token);
int (*select)(struct irq_domain *d, struct irq_fwspec *fwspec, enum irq_domain_bus_token bus_token);
int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
void (*unmap)(struct irq_domain *d, unsigned int virq);
int (*xlate)(struct irq_domain *d, struct device_node *node,const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY;
int (*alloc)(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs, void *arg);
void (*free)(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs);
int (*activate)(struct irq_domain *d, struct irq_data *irqd, bool reserve);
void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type);
#endif;
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS;
void (*debug_show)(struct seq_file *m, struct irq_domain *d, struct irq_data *irqd, int ind);
#endif;
};
成員
match將中斷控制器裝置節點與域匹配,匹配時返回 1
select匹配中斷控制器 fw 規範。它比 match 更通用,因為它接收完整的
struct irq_fwspec。因此,如果提供了 select,則首選它。匹配時返回 1。map建立或更新虛擬 irq 編號和 hw irq 編號之間的對映。對於給定的對映,這隻會被呼叫一次。
unmap處置此類對映
xlate給定裝置樹節點和中斷說明符,解碼硬體 irq 編號和 linux irq 型別值。
alloc從 virq 開始分配 nr_irqs 箇中斷。
free從 virq 開始釋放 nr_irqs 箇中斷。
activate在 HW 中啟用一箇中斷 (irqd)。如果設定了 reserve,則只保留向量。如果未設定,則分配向量(從
request_irq()呼叫)。deactivate解除一箇中斷 (irqd) 的武裝。
translate給定 fwspec,解碼硬體 irq 編號 (out_hwirq) 和 linux irq 型別值 (out_type)。這是廣義的 xlate(在
struct irq_fwspec上),如果提供了,則首選它。debug_show對於域,以在 debugfs 中顯示中斷的特定資料。
描述
以下函式由驅動程式提供,並在每次建立新對映或處置舊對映時呼叫。然後,驅動程式可以繼續進行所需的任何內部資料結構管理。它還需要在從 map() 返回時設定 irq_desc。
-
struct irq_domain¶
硬體中斷號轉換物件
定義:
struct irq_domain {
struct list_head link;
const char *name;
const struct irq_domain_ops *ops;
void *host_data;
unsigned int flags;
unsigned int mapcount;
struct mutex mutex;
struct irq_domain *root;
struct fwnode_handle *fwnode;
enum irq_domain_bus_token bus_token;
struct irq_domain_chip_generic *gc;
struct device *dev;
struct device *pm_dev;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY;
struct irq_domain *parent;
#endif;
#ifdef CONFIG_GENERIC_MSI_IRQ;
const struct msi_parent_ops *msi_parent_ops;
#endif;
void (*exit)(struct irq_domain *d);
irq_hw_number_t hwirq_max;
unsigned int revmap_size;
struct radix_tree_root revmap_tree;
struct irq_data __rcu *revmap[] ;
};
成員
link全域性 irq_domain 列表中的元素。
name中斷域的名稱
ops指向 irq_domain 方法的指標
host_data供所有者使用的私有資料指標。irq_domain 核心程式碼不接觸。
flags每個 irq_domain 的標誌
mapcount對映的中斷數
mutex域鎖,分層域使用根域的鎖
root指向根域的指標,如果是非分層結構,則指向包含結構
fwnode指向與 irq_domain 關聯的韌體節點的指標。很容易透過 irq_domain_get_of_node 訪問器將其交換為 of_node
bus_tokenfwnode 的 device_node 可能用於多個 irq 域。但是與 bus_token 結合使用時,該對在系統中應該是唯一的。
gc指向通用晶片列表的指標。有一個輔助函式可用於為使用使用此指標的通用晶片庫的中斷控制器驅動程式設定一個或多個通用晶片。
dev指向例項化 irqdomain 的裝置的指標。使用每個裝置 irq 域時,這不一定與 pm_dev 相同。
pm_dev指向可用於與 irq 域相關的電源管理目的的裝置的指標。
parent指向父 irq_domain 以支援層次結構 irq_domain
msi_parent_ops用於每個裝置域初始化的指向 MSI 父域方法的指標
exit銷燬域時呼叫的函式
hwirq_maxHW irq 編號的上限。特別是為了避免與保留的 HW irq 發生衝突/故障。可以是 ~0。
revmap_size線性對映表 revmap 的大小
revmap_tree用於不適合線性對映的 hwirq 的基數對映樹
revmapirq_data 指標的線性表
描述
可選元素:Revmap 資料,由 irq 域程式碼在內部使用
-
struct irq_domain_info¶
域資訊結構
定義:
struct irq_domain_info {
struct fwnode_handle *fwnode;
unsigned int domain_flags;
unsigned int size;
irq_hw_number_t hwirq_max;
int direct_max;
unsigned int hwirq_base;
unsigned int virq_base;
enum irq_domain_bus_token bus_token;
const char *name_suffix;
const struct irq_domain_ops *ops;
void *host_data;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY;
struct irq_domain *parent;
#endif;
struct irq_domain_chip_generic_info *dgc_info;
int (*init)(struct irq_domain *d);
void (*exit)(struct irq_domain *d);
};
成員
fwnode中斷控制器的韌體節點
domain_flags要新增到域標誌的其他標誌
size線性對映的大小;對於僅基數對映,為 0
hwirq_max控制器支援的最大中斷數
direct_max直接對映的最大值;對於無限制,請使用 ~0;對於無直接對映,請使用 0
hwirq_base第一個硬體中斷號(僅限舊版域)
virq_base舊版域的第一個 Linux 中斷號,用於在域建立後立即關聯中斷
bus_token域匯流排令牌
name_suffix可選名稱字尾,以避免使用相同 fwnode 新增多個域時發生衝突
ops域操作回撥
host_data控制器私有資料指標
parent指向層次結構域中使用的父 irq 域的指標
dgc_info如果不是 NULL,則用於為域建立通用晶片的 Geneneric 晶片資訊結構指標。
init建立域時呼叫的函式。允許進行一些額外的域初始化。
exit銷燬域時呼叫的函式。允許執行一些額外的清理操作。
-
struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode, unsigned int size, const struct irq_domain_ops *ops, void *host_data)¶
分配和註冊線性 revmap irq_domain。
引數
struct fwnode_handle *fwnode指向中斷控制器的 FW 節點的指標。
unsigned int size域中的中斷數。
const struct irq_domain_ops *opsmap/unmap 域回撥
void *host_data控制器私有資料指標
返回
新建立的 irq_domain
-
unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)¶
將硬體中斷對映到 linux irq 空間
引數
struct irq_domain *domain擁有此硬體中斷的域,如果為 NULL,則表示預設域
irq_hw_number_t hwirq該域空間中的硬體 irq 編號
描述
每個硬體中斷只允許一個對映。
如果要指定感應/觸發器,則應在從該呼叫返回的編號上呼叫 set_irq_type()。
返回
Linux irq 編號,如果出錯,則為 0
-
struct irq_desc *irq_resolve_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)¶
從 hw irq 編號查詢 linux irq。
引數
struct irq_domain *domain擁有此硬體中斷的域
irq_hw_number_t hwirq該域空間中的硬體 irq 編號
返回
中斷描述符
-
unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)¶
從 hw irq 編號查詢 linux irq。
引數
struct irq_domain *domain擁有此硬體中斷的域
irq_hw_number_t hwirq該域空間中的硬體 irq 編號
返回
Linux irq 編號,如果未找到,則為 0
-
struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent, unsigned int flags, unsigned int size, struct fwnode_handle *fwnode, const struct irq_domain_ops *ops, void *host_data)¶
將 irqdomain 新增到層次結構中
引數
struct irq_domain *parent要與新域關聯的父 irq 域
unsigned int flags與域關聯的 Irq 域標誌
unsigned int size域的大小。請參見下文
struct fwnode_handle *fwnode中斷控制器的可選 fwnode
const struct irq_domain_ops *ops指向中斷域回撥的指標
void *host_data控制器私有資料指標
描述
如果 size 為 0,則建立樹域,否則建立線性域。
如果成功,則將父級與新域關聯,並設定域標誌。
返回
指向 IRQ 域的指標,如果失敗,則為 NULL。
-
int irq_domain_alloc_irqs(struct irq_domain *domain, unsigned int nr_irqs, int node, void *arg)¶
從域分配 IRQ
引數
struct irq_domain *domain要從中分配的域
unsigned int nr_irqs要分配的 IRQ 數
int node用於記憶體分配的 NUMA 節點 ID
void *arg特定於域的引數
描述
請參見 __irq_domain_alloc_irqs() 的文件。
-
struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id, const char *name, phys_addr_t *pa)¶
分配適合於標識 irq 域的 fwnode_handle
引數
unsigned int typeirqchip_fwnode 的型別。請參見 linux/irqdomain.h
int id如果 name != NULL,則為可選的使用者提供的 id
const char *name可選的使用者提供的域名
phys_addr_t *pa可選的使用者提供的物理地址
描述
分配一個 struct irqchip_fwid,並返回指向嵌入的 fwnode_handle 的指標(如果失敗,則返回 NULL)。
注意
型別 IRQCHIP_FWNODE_NAMED 和 IRQCHIP_FWNODE_NAMED_ID 僅用於將名稱資訊傳輸到 irqdomain 建立程式碼。該節點未儲存。對於其他型別,指標儲存在 irq 域結構中。
-
void irq_domain_free_fwnode(struct fwnode_handle *fwnode)¶
釋放一個非OF支援的 fwnode_handle
引數
struct fwnode_handle *fwnode要釋放的 fwnode_handle
描述
釋放一個用 irq_domain_alloc_fwnode 分配的 fwnode_handle。
-
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)¶
例項化一個新的 irq 域資料結構
引數
const struct irq_domain_info *info指向此域資訊的域資訊指標
返回
指向例項化的 irq 域的指標,或一個 ERR_PTR 值。
-
void irq_domain_remove(struct irq_domain *domain)¶
移除一個 irq 域。
引數
struct irq_domain *domain要移除的域
描述
此例程用於移除一個 irq 域。呼叫者必須確保在使用之前,域中的所有對映都已根據 revmap 型別進行處理。
-
struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode, unsigned int size, unsigned int first_irq, const struct irq_domain_ops *ops, void *host_data)¶
註冊一個 irq_domain 並可選擇對映一個 irq 範圍
引數
struct fwnode_handle *fwnode中斷控制器的韌體節點
unsigned int size對映中的 irq 總數
unsigned int first_irq分配給域的 irq 塊的第一個數字,傳遞零以動態分配 irq。如果 first_irq 非零,則預先將域中的所有 irq 對映到從 first_irq 開始的 virq。
const struct irq_domain_ops *ops域回撥
void *host_data控制器私有資料指標
描述
分配一個 irq_domain,如果 first_irq 為正,則可選擇分配 irq_descs 並將所有 hwirq 對映到從 first_irq 開始的 virq。
此操作旨在實現大多數中斷控制器的預期行為。如果使用裝置樹,則 first_irq 將為 0,並且 irq 會動態地進行對映。但是,如果控制器需要靜態 virq 分配(非 DT 引導),則可以正確設定。
-
struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec, enum irq_domain_bus_token bus_token)¶
為給定的 fwspec 查詢域
引數
struct irq_fwspec *fwspec中斷的 FW 說明符
enum irq_domain_bus_token bus_token特定於域的資料
-
void irq_set_default_domain(struct irq_domain *domain)¶
設定一個“預設” irq 域
引數
struct irq_domain *domain預設域指標
描述
為了方便起見,可以設定一個“預設”域,每當將 NULL 傳遞給 irq_create_mapping() 時,都會使用它。這使得平臺更容易處理裝置樹中未正確表示的一些硬編碼中斷號。
-
struct irq_domain *irq_get_default_domain(void)¶
檢索“預設” irq 域
引數
void無引數
返回
預設域(如果有)。
描述
現代程式碼永遠不應使用此函式。此函式只應在無法實現 firmware->fwnode 對映的系統上使用(DT 和 ACPI 均提供)。
-
unsigned int irq_create_direct_mapping(struct irq_domain *domain)¶
為直接對映分配一個 irq
引數
struct irq_domain *domain為其分配 irq 的域,或 NULL 表示預設域
描述
此例程用於可以選擇其生成的硬體中斷號的 irq 控制器。在這種情況下,最簡單的方法是將 Linux irq 用作硬體中斷號。它仍然使用線性或基數樹來儲存對映,但 irq 控制器可以透過直接使用 hwirq 來最佳化 revmap 路徑。
-
unsigned int irq_create_mapping_affinity(struct irq_domain *domain, irq_hw_number_t hwirq, const struct irq_affinity_desc *affinity)¶
將硬體中斷對映到 linux irq 空間
引數
struct irq_domain *domain擁有此硬體中斷的域,如果為 NULL,則表示預設域
irq_hw_number_t hwirq該域空間中的硬體 irq 編號
const struct irq_affinity_desc *affinityirq 親和性
描述
每個硬體中斷只允許一個對映。返回一個 Linux irq 號碼。如果要指定感應/觸發器,則應在從該呼叫返回的號碼上呼叫 set_irq_type()。
-
void irq_dispose_mapping(unsigned int virq)¶
取消對映一箇中斷
引數
unsigned int virq要取消對映的中斷的 Linux irq 號碼
-
struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain, irq_hw_number_t hwirq, unsigned int *irq)¶
從 hw irq 編號查詢 linux irq。
引數
struct irq_domain *domain擁有此硬體中斷的域
irq_hw_number_t hwirq該域空間中的硬體 irq 編號
unsigned int *irq可選指標,用於在需要時返回 Linux irq
描述
返回中斷描述符。
-
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type)¶
用於直接單元格繫結的通用 xlate
引數
struct irq_domain *d參與轉換的中斷域
struct device_node *ctrlr裝置樹節點,用於轉換其中斷的裝置
const u32 *intspec來自裝置樹的中斷說明符資料
unsigned int intsizeintspec 中的條目數
unsigned long *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
裝置樹 IRQ 說明符轉換函式,適用於單元格值直接對映到 hwirq 號碼的一個單元格繫結。
-
int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_type)¶
用於直接雙單元格繫結的通用 xlate
引數
struct irq_domain *d參與轉換的中斷域
struct device_node *ctrlr裝置樹節點,用於轉換其中斷的裝置
const u32 *intspec來自裝置樹的中斷說明符資料
unsigned int intsizeintspec 中的條目數
irq_hw_number_t *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
裝置樹 IRQ 說明符轉換函式,適用於單元格值直接對映到 hwirq 號碼和 Linux irq 標誌的雙單元格繫結。
-
int irq_domain_xlate_twothreecell(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_type)¶
用於直接雙單元格或三單元格繫結的通用 xlate
引數
struct irq_domain *d參與轉換的中斷域
struct device_node *ctrlr裝置樹節點,用於轉換其中斷的裝置
const u32 *intspec來自裝置樹的中斷說明符資料
unsigned int intsizeintspec 中的條目數
irq_hw_number_t *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
用於雙單元格或三單元格繫結的裝置樹中斷說明符轉換函式,其中單元格值直接對映到硬體中斷號和型別說明符。
-
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type)¶
用於單單元格或雙單元格繫結的通用 xlate
引數
struct irq_domain *d參與轉換的中斷域
struct device_node *ctrlr裝置樹節點,用於轉換其中斷的裝置
const u32 *intspec來自裝置樹的中斷說明符資料
unsigned int intsizeintspec 中的條目數
unsigned long *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
裝置樹 IRQ 說明符轉換函式,適用於單元格值直接對映到 hwirq 號碼和 Linux irq 標誌的單單元格或雙單元格繫結。
注意
除非您的中斷控制器明確支援單單元格和雙單元格繫結,否則請勿使用此函式。對於大多數控制器,應使用上面的 _onecell() 或 _twocell() 變體。
-
int irq_domain_translate_onecell(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type)¶
用於直接單元格繫結的通用轉換
引數
struct irq_domain *d參與轉換的中斷域
struct irq_fwspec *fwspec要轉換的韌體中斷說明符
unsigned long *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
-
int irq_domain_translate_twocell(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type)¶
用於直接雙單元格繫結的通用轉換
引數
struct irq_domain *d參與轉換的中斷域
struct irq_fwspec *fwspec要轉換的韌體中斷說明符
unsigned long *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
裝置樹 IRQ 說明符轉換函式,適用於單元格值直接對映到 hwirq 號碼和 Linux irq 標誌的雙單元格繫結。
-
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type)¶
用於直接雙單元格或三單元格繫結的通用轉換
引數
struct irq_domain *d參與轉換的中斷域
struct irq_fwspec *fwspec要轉換的韌體中斷說明符
unsigned long *out_hwirq用於儲存硬體中斷號的指標
unsigned int *out_type用於儲存中斷型別的指標
描述
用於雙單元格或三單元格規範的韌體中斷說明符轉換函式,其中引數值直接對映到硬體中斷號和型別說明符。
引數
struct irq_data *irq_data指向 irq_data 的指標
-
int irq_domain_disconnect_hierarchy(struct irq_domain *domain, unsigned int virq)¶
標記層次結構的第一個未使用的級別
引數
struct irq_domain *domain要斷開層次結構的 IRQ 域
unsigned int virq要在其中修剪層次結構的 IRQ 號碼
描述
將屬於 domain 的 virq 級別標記為已斷開連線。如果 virq 沒有指向 domain 的有效 irq_data,則返回 -EINVAL。
它的唯一用途是能夠修剪此中斷沒有任何實際意義的層次結構級別,並且驅動程式從其 .alloc() 回撥中將其標記為這樣。
-
struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, unsigned int virq)¶
獲取與 virq 和 domain 關聯的 irq_data
引數
struct irq_domain *domain要匹配的域
unsigned int virq要獲取 irq_data 的 IRQ 號碼
-
int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq, const struct irq_chip *chip, void *chip_data)¶
在 domain 設定 virq 的 hwirq 和 irqchip
引數
struct irq_domain *domain要匹配的中斷域
unsigned int virqIRQ 號碼
irq_hw_number_t hwirqhwirq 號碼
const struct irq_chip *chip關聯的中斷晶片
void *chip_data關聯的晶片資料
-
void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq, const struct irq_chip *chip, void *chip_data, irq_flow_handler_t handler, void *handler_data, const char *handler_name)¶
在 domain 中設定 virq 的完整資料
引數
struct irq_domain *domain要匹配的中斷域
unsigned int virqIRQ 號碼
irq_hw_number_t hwirq硬體中斷號
const struct irq_chip *chip關聯的中斷晶片
void *chip_data關聯的中斷晶片資料
irq_flow_handler_t handler中斷流處理程式
void *handler_data中斷流處理程式資料
const char *handler_name中斷處理程式名稱
-
void irq_domain_free_irqs_common(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs)¶
清除 irq_data 並釋放父項
引數
struct irq_domain *domain要匹配的中斷域
unsigned int virq要從其開始的 IRQ 號碼
unsigned int nr_irqs要釋放的 irq 的數量
-
int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, bool realloc, const struct irq_affinity_desc *affinity)¶
從域分配 IRQ
引數
struct irq_domain *domain要從中分配的域
int irq_base如果 irq_base >= 0,則分配指定的 IRQ 號碼
unsigned int nr_irqs要分配的 IRQ 數
int node用於記憶體分配的 NUMA 節點 ID
void *arg特定於域的引數
bool realloc如果為 true,則已分配 IRQ 描述符
const struct irq_affinity_desc *affinity多佇列裝置的可選 irq 親和性掩碼
描述
分配 IRQ 號碼並初始化所有資料結構以支援層次結構 IRQ 域。引數 realloc 主要用於支援舊版 IRQ。返回錯誤程式碼或分配的 IRQ 號碼
設定 IRQ 的整個過程已分為兩個步驟。第一步,__irq_domain_alloc_irqs(),用於分配 IRQ 描述符和所需的硬體資源。第二步,irq_domain_activate_irq(),用於使用預分配的資源對硬體進行程式設計。這樣,當無法分配資源時,更容易回滾。
-
int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg)¶
將域推送到層次結構的頂部。
引數
struct irq_domain *domain要推送的域。
int virq要將域推送到的 Irq。
void *arg傳遞給 irq_domain_ops alloc() 函式。
描述
對於已存在的 irqdomain 層次結構(可能透過呼叫 pci_enable_msix() 獲得),將一個附加域新增到處理鏈的頭部。必須在呼叫 request_irq() 之前呼叫。
-
int irq_domain_pop_irq(struct irq_domain *domain, int virq)¶
從層次結構的頂部移除域。
引數
struct irq_domain *domain要移除的域。
int virq要從中移除域的 Irq。
描述
撤銷對 irq_domain_push_irq() 呼叫的影響。必須在 request_irq() 之前或 free_irq() 之後呼叫。
-
int irq_domain_alloc_irqs_parent(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs, void *arg)¶
從父域分配中斷
引數
struct irq_domain *domain必須分配中斷的域
unsigned int irq_base基本 IRQ 編號
unsigned int nr_irqs要分配的 IRQ 數量
void *arg分配資料(特定於 arch/domain)
-
void irq_domain_free_irqs_parent(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs)¶
從父域釋放中斷
引數
struct irq_domain *domain必須釋放中斷的域
unsigned int irq_base基本 IRQ 編號
unsigned int nr_irqs要釋放的 IRQ 數量
提供的內部函式¶
本章包含內部函式的自動生成文件。
-
void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs)¶
清除處理程式和處理程式資料,清除 irqdata 並釋放父級
引數
struct irq_domain *domain要匹配的中斷域
unsigned int virq要從其開始的 IRQ 號碼
unsigned int nr_irqs要釋放的 irq 的數量
-
void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)¶
釋放 IRQ 編號和關聯的資料結構
引數
unsigned int virq基本 IRQ 編號
unsigned int nr_irqs要釋放的 IRQ 數量
-
int irq_domain_activate_irq(struct irq_data *irq_data, bool reserve)¶
遞迴呼叫 domain_ops->activate 以啟用中斷
引數
struct irq_data *irq_data與中斷關聯的最外層 irq_data
bool reserve如果設定,則僅保留中斷向量而不是分配一個
描述
這是呼叫 domain_ops->activate 以程式設計中斷控制器的第二步,因此中斷實際上可以傳遞。
引數
struct irq_data *irq_data與中斷關聯的最外層 irq_data
描述
它呼叫 domain_ops->deactivate 以程式設計中斷控制器以停用中斷傳遞。