Linux 通用 IRQ 處理¶
- 版權:
© 2005-2010: Thomas Gleixner
- 版權:
© 2005-2006: Ingo Molnar
引言¶
通用中斷處理層旨在為裝置驅動程式提供完整的中斷處理抽象。它能夠處理所有不同型別的中斷控制器硬體。裝置驅動程式使用通用 API 函式來請求、啟用、停用和釋放中斷。驅動程式無需瞭解任何中斷硬體細節,因此它們可以在不同平臺上使用而無需修改程式碼。
本文件提供給希望在其架構上實現基於通用 IRQ 處理層的中斷子系統的開發人員。
原理¶
Linux 中中斷處理的原始實現使用了 __do_IRQ() 超級處理程式,它能夠處理各種型別的中斷邏輯。
最初,Russell King 識別了不同型別的處理程式,為 Linux 2.5/2.6 中的 ARM 中斷處理程式實現構建了一個相當通用的集合。他區分了:
電平觸發型別
邊沿觸發型別
簡單型別
在實現過程中,我們識別了另一種型別:
快速 EOI 型別
在 __do_IRQ() 超級處理程式的 SMP 世界中,識別出另一種型別:
每 CPU 型別
這種高階 IRQ 處理程式的拆分實現允許我們最佳化每種特定中斷型別的處理流程。這減少了特定程式碼路徑中的複雜性,並允許對給定型別進行最佳化處理。
原始的通用 IRQ 實現使用 hw_interrupt_type 結構及其 ->ack、->end [等] 回撥函式來區分超級處理程式中的流程控制。這導致了流程邏輯和低階硬體邏輯的混淆,也導致了不必要的程式碼重複:例如,在 i386 中,有 ioapic_level_irq 和 ioapic_edge_irq 這兩種 IRQ 型別,它們共享許多低階細節但具有不同的流程處理。
更自然的抽象是“irq 流”和“晶片細節”的清晰分離。
分析一些架構的 IRQ 子系統實現表明,它們中的大多數可以使用一組通用的“irq 流”方法,只需要新增晶片級特定程式碼。這種分離對於需要在 IRQ 流本身而不是晶片細節中進行特定調整的(子)架構也很有價值——因此提供了更透明的 IRQ 子系統設計。
每個中斷描述符都分配有自己的高階流處理程式,通常是通用實現之一。(這種高階流處理程式實現還使得提供解複用處理程式變得簡單,這可以在各種架構上的嵌入式平臺中找到。)
這種分離使通用中斷處理層更加靈活和可擴充套件。例如,一個(子)架構可以為“電平觸發”中斷使用通用 IRQ 流實現,並新增一個(子)架構特定的“邊沿觸發”實現。
為了使向新模型的過渡更容易並防止現有實現的破壞,__do_IRQ() 超級處理程式仍然可用。這導致了暫時的一種二元性。隨著時間的推移,新模型應該在越來越多的架構中使用,因為它能夠實現更小、更乾淨的 IRQ 子系統。它現在已經被棄用三年了,即將被移除。
已知錯誤和假設¶
無(敲木頭)。
抽象層¶
中斷程式碼中有三個主要的抽象級別:
高階驅動程式 API
高階 IRQ 流處理程式
晶片級硬體封裝
中斷控制流¶
每個中斷都由一箇中斷描述符結構 irq_desc 描述。中斷透過一個“無符號整數”數值引用,該數值在描述符結構陣列中選擇相應的中斷描述結構。描述符結構包含狀態資訊以及指向分配給此中斷的中斷流方法和中斷晶片結構的指標。
每當中斷觸發時,低階架構程式碼透過呼叫 desc->handle_irq() 進入通用中斷程式碼。此高階 IRQ 處理函式僅使用由分配的晶片描述符結構引用的 desc->irq_data.chip 原語。
高階驅動程式 API¶
高階驅動程式 API 包含以下函式:
disable_irq_nosync()(僅限 SMP)synchronize_irq()(僅限 SMP)
詳情請參閱自動生成的函式文件。
高階 IRQ 流處理程式¶
通用層提供了一組預定義的中斷流方法:
handle_edge_eoi_irq()
中斷流處理程式(無論是預定義的還是特定於架構的)由架構在啟動期間或裝置初始化期間分配給特定的中斷。
預設流實現¶
輔助函式¶
輔助函式呼叫晶片原語,並由預設流實現使用。以下輔助函式已實現(簡化摘錄):
default_enable(struct irq_data *data)
{
desc->irq_data.chip->irq_unmask(data);
}
default_disable(struct irq_data *data)
{
if (!delay_disable(data))
desc->irq_data.chip->irq_mask(data);
}
default_ack(struct irq_data *data)
{
chip->irq_ack(data);
}
default_mask_ack(struct irq_data *data)
{
if (chip->irq_mask_ack) {
chip->irq_mask_ack(data);
} else {
chip->irq_mask(data);
chip->irq_ack(data);
}
}
noop(struct irq_data *data)
{
}
預設流處理程式實現¶
預設電平 IRQ 流處理程式¶
handle_level_irq 為電平觸發中斷提供通用實現。
實現以下控制流(簡化摘錄):
desc->irq_data.chip->irq_mask_ack();
handle_irq_event(desc->action);
desc->irq_data.chip->irq_unmask();
預設快速 EOI IRQ 流處理程式¶
handle_fasteoi_irq 為僅在處理程式結束時需要 EOI 的中斷提供通用實現。
實現以下控制流(簡化摘錄):
handle_irq_event(desc->action);
desc->irq_data.chip->irq_eoi();
預設邊沿 IRQ 流處理程式¶
handle_edge_irq 為邊沿觸發中斷提供通用實現。
實現以下控制流(簡化摘錄):
if (desc->status & running) {
desc->irq_data.chip->irq_mask_ack();
desc->status |= pending | masked;
return;
}
desc->irq_data.chip->irq_ack();
desc->status |= running;
do {
if (desc->status & masked)
desc->irq_data.chip->irq_unmask();
desc->status &= ~pending;
handle_irq_event(desc->action);
} while (desc->status & pending);
desc->status &= ~running;
預設簡單 IRQ 流處理程式¶
handle_simple_irq 為簡單中斷提供通用實現。
注意
簡單流處理程式不呼叫任何處理程式/晶片原語。
實現以下控制流(簡化摘錄):
handle_irq_event(desc->action);
預設每 CPU 流處理程式¶
handle_percpu_irq 為每 CPU 中斷提供通用實現。
每 CPU 中斷僅在 SMP 上可用,處理程式提供了一個沒有鎖定的簡化版本。
實現以下控制流(簡化摘錄):
if (desc->irq_data.chip->irq_ack)
desc->irq_data.chip->irq_ack();
handle_irq_event(desc->action);
if (desc->irq_data.chip->irq_eoi)
desc->irq_data.chip->irq_eoi();
EOI 邊沿 IRQ 流處理程式¶
handle_edge_eoi_irq 提供了一個邊沿處理程式的異常情況,它僅用於馴服 powerpc/cell 上一個嚴重損壞的 irq 控制器。
不良 IRQ 流處理程式¶
handle_bad_irq 用於沒有實際處理程式分配的偽中斷。
怪癖和最佳化¶
通用函式旨在用於“乾淨”的架構和晶片,這些架構和晶片沒有平臺特定的 IRQ 處理怪癖。如果架構需要在“流”級別實現怪癖,則可以透過覆蓋高階 irq 流處理程式來實現。
延遲中斷停用¶
此每中斷可選功能由 Russell King 在 ARM 中斷實現中引入,當呼叫 disable_irq() 時,它不會在硬體級別遮蔽中斷。中斷保持啟用狀態,並在發生中斷事件時在流處理程式中遮蔽。這可以防止在硬體級別停用中斷時,硬體不儲存邊沿中斷事件而丟失邊沿中斷。當 IRQ_DISABLED 標誌設定時中斷到來時,中斷在硬體級別被遮蔽,並且 IRQ_PENDING 位被設定。當透過 enable_irq() 重新啟用中斷時,會檢查 pending 位,如果設定,則透過硬體或軟體重發機制重新發送中斷。(如果您想使用延遲中斷停用功能並且您的硬體無法重新觸發中斷,則需要啟用 CONFIG_HARDIRQS_SW_RESEND。)延遲中斷停用不可配置。
晶片級硬體封裝¶
晶片級硬體描述符結構 irq_chip 包含所有直接與晶片相關的功能,這些功能可以被 irq 流實現使用。
irq_ackirq_mask_ack- 可選,建議用於效能irq_maskirq_unmaskirq_eoi- 可選,EOI 流處理程式必需irq_retrigger- 可選irq_set_type- 可選irq_set_wake- 可選
這些原語嚴格按照其字面意思:ack 表示 ACK,masking 表示遮蔽 IRQ 線等。流處理程式(或多個處理程式)負責使用這些低階功能的基本單元。
__do_IRQ 入口點¶
原始實現 __do_IRQ() 是所有型別中斷的替代入口點。它不再存在。
此處理程式被證明不適用於所有中斷硬體,因此已使用針對邊沿/電平/簡單/每CPU 中斷的拆分功能重新實現。這不僅是功能最佳化,還縮短了中斷的程式碼路徑。
SMP 上的鎖定¶
晶片暫存器的鎖定由定義晶片原語的架構負責。每個中斷結構透過 desc->lock 受通用層保護。
通用中斷晶片¶
為了避免重複的 IRQ 晶片實現,核心提供了可配置的通用中斷晶片實現。開發人員在自己以略微不同的方式實現相同功能之前,應仔細檢查通用晶片是否符合其需求。
引數
struct irq_data *dirq_data
引數
struct irq_data *dirq_data
描述
晶片有獨立的啟用/停用暫存器,而不是單個遮蔽暫存器。
引數
struct irq_data *dirq_data
描述
晶片有一個單一的遮蔽暫存器。該暫存器的值被快取並受 gc->lock 保護。
引數
struct irq_data *dirq_data
描述
晶片有一個單一的遮蔽暫存器。該暫存器的值被快取並受 gc->lock 保護。
引數
struct irq_data *dirq_data
描述
晶片有獨立的啟用/停用暫存器,而不是單個遮蔽暫存器。
引數
struct irq_data *dirq_data
引數
struct irq_data *dirq_data
描述
此 irq_mask_ack 方法的通用實現適用於具有獨立啟用/停用暫存器而非單個遮蔽暫存器的晶片,並且掛起中斷透過設定位來確認。
注意
這是目前唯一使用的排列組合。如果需要其他排列組合,應在此處新增類似的通用函式。
引數
struct irq_data *dirq_data
unsigned int on指示是否應設定或清除喚醒位
描述
對於喚醒掛起功能未在單獨暫存器中配置,且喚醒活動狀態僅儲存在位掩碼中的晶片。
-
struct irq_chip_generic *irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base, void __iomem *reg_base, irq_flow_handler_t handler)¶
分配通用晶片並初始化
引數
const char *nameirq 晶片的名稱
int num_ct與此相關的 irq_chip_type 例項數量
unsigned int irq_base此晶片的中斷基數
void __iomem *reg_base暫存器基地址(虛擬)
irq_flow_handler_t handler與此晶片關聯的預設流處理程式
描述
返回一個已初始化的 irq_chip_generic 結構。晶片預設為主要(索引 0)的 irq_chip_type 和 handler
-
int irq_domain_alloc_generic_chips(struct irq_domain *d, const struct irq_domain_chip_generic_info *info)¶
為 irq 域分配通用晶片
引數
struct irq_domain *d要分配晶片的 irq 域
const struct irq_domain_chip_generic_info *info通用晶片資訊
返回
成功返回 0,失敗返回負錯誤碼
-
void irq_domain_remove_generic_chips(struct irq_domain *d)¶
從 irq 域中移除通用晶片
引數
struct irq_domain *d要移除通用晶片的 irq 域
-
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, int num_ct, const char *name, irq_flow_handler_t handler, unsigned int clr, unsigned int set, enum irq_gc_flags gcflags)¶
為 irq 域分配通用晶片
引數
struct irq_domain *d要分配晶片的 irq 域
int irqs_per_chip每個晶片處理的中斷數量(最大 32)
int num_ct與此相關的 irq_chip_type 例項數量
const char *nameirq 晶片的名稱
irq_flow_handler_t handler與這些晶片關聯的預設流處理程式
unsigned int clr在對映函式中要清除的 IRQ_* 位
unsigned int set在對映函式中要設定的 IRQ_* 位
enum irq_gc_flags gcflags通用晶片特定設定標誌
-
struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq)¶
獲取 hw_irq 的通用晶片指標
引數
struct irq_domain *dirq 域指標
unsigned int hw_irq硬體中斷號,相對於中斷域本地
-
void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, enum irq_gc_flags flags, unsigned int clr, unsigned int set)¶
使用通用晶片設定一系列中斷
引數
struct irq_chip_generic *gc包含所有資料的通用 irq 晶片
u32 msk包含要初始化 irq 的位掩碼,相對於 gc->irq_base
enum irq_gc_flags flags初始化標誌
unsigned int clr要清除的 IRQ_* 位
unsigned int set要設定的 IRQ_* 位
描述
設定從 gc->irq_base 開始最多 32 箇中斷。注意,這將所有中斷初始化為主 irq_chip_type 及其關聯的處理程式。
引數
struct irq_data *d此中斷的 irq_data
unsigned int type要初始化的流型別
描述
只能從 chip->irq_set_type() 回撥中呼叫。
-
void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, unsigned int clr, unsigned int set)¶
移除晶片
引數
struct irq_chip_generic *gc包含所有資料的通用 irq 晶片
u32 msk包含要初始化 irq 的位掩碼,相對於 gc->irq_base
unsigned int clr要清除的 IRQ_* 位
unsigned int set要設定的 IRQ_* 位
描述
移除從 gc->irq_base 開始最多 32 箇中斷。
結構體¶
本章包含通用 IRQ 層中使用的結構的自動生成文件。
-
struct irq_common_data¶
所有 irqchip 共享的每個 irq 資料
定義:
struct irq_common_data {
unsigned int __private state_use_accessors;
#ifdef CONFIG_NUMA;
unsigned int node;
#endif;
void *handler_data;
struct msi_desc *msi_desc;
#ifdef CONFIG_SMP;
cpumask_var_t affinity;
#endif;
#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK;
cpumask_var_t effective_affinity;
#endif;
#ifdef CONFIG_GENERIC_IRQ_IPI;
unsigned int ipi_offset;
#endif;
};
成員
state_use_accessorsirq 晶片函式的狀態資訊。使用訪問器函式處理它
node用於平衡的節點索引
handler_data用於 irq_chip 方法的每個 IRQ 資料
msi_descMSI 描述符
affinitySMP 上的 IRQ 親和性。如果這是 IPI 相關 irq,則這是可以傳送 IPI 的 CPU 掩碼。
effective_affinitySMP 上的有效 IRQ 親和性,因為某些 irq 晶片不允許多 CPU 目標。是 affinity 的一個子集。
ipi_offsetaffinity 中第一個 IPI 目標 CPU 的偏移量。可選。
-
struct irq_data¶
傳遞給晶片函式的每個 irq 晶片資料
定義:
struct irq_data {
u32 mask;
unsigned int irq;
irq_hw_number_t hwirq;
struct irq_common_data *common;
struct irq_chip *chip;
struct irq_domain *domain;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY;
struct irq_data *parent_data;
#endif;
void *chip_data;
};
成員
mask用於訪問晶片暫存器的預計算位掩碼
irq中斷號
hwirq硬體中斷號,相對於中斷域本地
common指向所有 irqchip 共享的資料
chip低階中斷硬體訪問
domain中斷轉換域;負責硬體中斷號和 Linux 中斷號之間的對映。
parent_data指向父
struct irq_data的指標,以支援層次結構 irq_domainchip_data用於晶片方法的平臺特定每個晶片私有資料,以允許共享晶片實現
-
struct irq_chip¶
硬體中斷晶片描述符
定義:
struct irq_chip {
const char *name;
unsigned int (*irq_startup)(struct irq_data *data);
void (*irq_shutdown)(struct irq_data *data);
void (*irq_enable)(struct irq_data *data);
void (*irq_disable)(struct irq_data *data);
void (*irq_ack)(struct irq_data *data);
void (*irq_mask)(struct irq_data *data);
void (*irq_mask_ack)(struct irq_data *data);
void (*irq_unmask)(struct irq_data *data);
void (*irq_eoi)(struct irq_data *data);
int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force);
int (*irq_retrigger)(struct irq_data *data);
int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
int (*irq_set_wake)(struct irq_data *data, unsigned int on);
void (*irq_bus_lock)(struct irq_data *data);
void (*irq_bus_sync_unlock)(struct irq_data *data);
#ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE;
void (*irq_cpu_online)(struct irq_data *data);
void (*irq_cpu_offline)(struct irq_data *data);
#endif;
void (*irq_suspend)(struct irq_data *data);
void (*irq_resume)(struct irq_data *data);
void (*irq_pm_shutdown)(struct irq_data *data);
void (*irq_calc_mask)(struct irq_data *data);
void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
int (*irq_request_resources)(struct irq_data *data);
void (*irq_release_resources)(struct irq_data *data);
void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg);
int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state);
int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state);
int (*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info);
void (*ipi_send_single)(struct irq_data *data, unsigned int cpu);
void (*ipi_send_mask)(struct irq_data *data, const struct cpumask *dest);
int (*irq_nmi_setup)(struct irq_data *data);
void (*irq_nmi_teardown)(struct irq_data *data);
void (*irq_force_complete_move)(struct irq_data *data);
unsigned long flags;
};
成員
name用於 /proc/interrupts 的名稱
irq_startup啟動中斷(如果為 NULL,則預設為 ->enable)
irq_shutdown關閉中斷(如果為 NULL,則預設為 ->disable)
irq_enable啟用中斷(如果為 NULL,則預設為 chip->unmask)
irq_disable停用中斷
irq_ack新中斷的開始
irq_mask遮蔽中斷源
irq_mask_ack確認並遮蔽中斷源
irq_unmask解除中斷源的遮蔽
irq_eoi中斷結束
irq_set_affinity在 SMP 機器上設定 CPU 親和性。如果 force 引數為 true,則它告訴驅動程式無條件應用親和性設定。不需要對提供的親和性掩碼進行健全性檢查。這用於 CPU 熱插拔,其中目標 CPU 尚未在 cpu_online_mask 中設定。
irq_retrigger向 CPU 重新發送 IRQ
irq_set_type設定 IRQ 的流型別(IRQ_TYPE_LEVEL/等)
irq_set_wake啟用/停用 IRQ 的電源管理喚醒功能
irq_bus_lock鎖定對慢速匯流排(i2c)晶片訪問的函式
irq_bus_sync_unlock同步和解鎖慢速匯流排(i2c)晶片的函式
irq_cpu_online為輔助 CPU 配置中斷源
irq_cpu_offline取消配置輔助 CPU 的中斷源
irq_suspend當安裝了一個或多箇中斷時,從核心程式碼在掛起時為每個晶片呼叫一次的函式
irq_resume當安裝了一個或多箇中斷時,從核心程式碼在恢復時為每個晶片呼叫一次的函式
irq_pm_shutdown從核心程式碼在關閉時為每個晶片呼叫一次的函式
irq_calc_mask可選函式,用於為特殊情況設定 irq_data.mask
irq_print_chip可選,用於在 show_interrupts 中列印特殊的晶片資訊
irq_request_resources可選,用於在呼叫與此 irq 相關的任何其他回撥之前請求資源
irq_release_resources可選,用於釋放透過 irq_request_resources 獲取的資源
irq_compose_msi_msg可選,用於為 MSI 組合訊息內容
irq_write_msi_msg可選,用於為 MSI 寫入訊息內容
irq_get_irqchip_state返回中斷的內部狀態
irq_set_irqchip_state設定中斷的內部狀態
irq_set_vcpu_affinity可選,用於在虛擬機器中定位 vCPU
ipi_send_single向目標 CPU 傳送單個 IPI
ipi_send_mask向 cpumask 中的目標 CPU 傳送 IPI
irq_nmi_setup在啟用 NMI 之前從核心程式碼呼叫的函式
irq_nmi_teardown在停用 NMI 之後從核心程式碼呼叫的函式
irq_force_complete_move可選函式,用於強制完成掛起的中斷移動
flags晶片特定標誌
-
struct irq_chip_regs¶
結構體 irq_gci 的暫存器偏移
定義:
struct irq_chip_regs {
unsigned long enable;
unsigned long disable;
unsigned long mask;
unsigned long ack;
unsigned long eoi;
unsigned long type;
};
成員
enable相對於 reg_base 的啟用暫存器偏移
disable相對於 reg_base 的停用暫存器偏移
mask相對於 reg_base 的遮蔽暫存器偏移
ack相對於 reg_base 的確認暫存器偏移
eoi相對於 reg_base 的 Eoi 暫存器偏移
type相對於 reg_base 的型別配置暫存器偏移
-
struct irq_chip_type¶
流型別的通用中斷晶片例項
定義:
struct irq_chip_type {
struct irq_chip chip;
struct irq_chip_regs regs;
irq_flow_handler_t handler;
u32 type;
u32 mask_cache_priv;
u32 *mask_cache;
};
成員
chip提供回撥的實際中斷晶片
regs此晶片的暫存器偏移
handler與此晶片關聯的流處理程式
type晶片可以處理這些流型別
mask_cache_priv晶片型別私有的快取遮蔽暫存器
mask_cache指向快取遮蔽暫存器的指標
描述
當需要為不同的流型別實現不同的功能和暫存器偏移時,一個 irq_generic_chip 可以有多個 irq_chip_type 例項。
-
struct irq_chip_generic¶
通用 irq 晶片資料結構
定義:
struct irq_chip_generic {
raw_spinlock_t lock;
void __iomem *reg_base;
u32 (*reg_readl)(void __iomem *addr);
void (*reg_writel)(u32 val, void __iomem *addr);
void (*suspend)(struct irq_chip_generic *gc);
void (*resume)(struct irq_chip_generic *gc);
unsigned int irq_base;
unsigned int irq_cnt;
u32 mask_cache;
u32 wake_enabled;
u32 wake_active;
unsigned int num_ct;
void *private;
unsigned long installed;
unsigned long unused;
struct irq_domain *domain;
struct list_head list;
struct irq_chip_type chip_types[];
};
成員
lock保護暫存器和快取資料訪問的鎖
reg_base暫存器基地址(虛擬)
reg_readl備用 I/O 訪問器(如果為 NULL,則預設為 readl)
reg_writel備用 I/O 訪問器(如果為 NULL,則預設為 writel)
suspend當晶片未被使用時,從核心程式碼在掛起時為每個晶片呼叫一次的函式;可用於處理晶片細節,而無需 irq_chip::suspend
resume當晶片未被使用時,從核心程式碼在恢復時為每個晶片呼叫一次的函式;可用於處理晶片細節,而無需 irq_chip::suspend
irq_base此晶片的中斷基數
irq_cnt此晶片處理的中斷數量
mask_cache所有晶片型別之間共享的快取遮蔽暫存器
wake_enabled中斷可以從掛起狀態喚醒
wake_active中斷被標記為從掛起狀態喚醒的源
num_ct可用 irq_chip_type 例項的數量(通常為 1)
private用於非通用晶片回撥的私有資料
installed表示已安裝中斷的位域
unused表示未使用中斷的位域
domainirq 域指標
list例項跟蹤的列表頭
chip_types中斷 irq_chip_types 陣列
描述
請注意,irq_chip_generic 可以有多個 irq_chip_type 實現,這些實現可以關聯到 irq_chip_generic 例項的特定 irq 線。這允許在我們需要為 irq_chip_generic 例項實現不同的流機制(電平/邊沿)時,共享和保護狀態。
-
enum irq_gc_flags¶
通用 irq 晶片的初始化標誌
常量
IRQ_GC_INIT_MASK_CACHE透過讀取掩碼暫存器初始化 mask_cache
IRQ_GC_INIT_NESTED_LOCK為需要呼叫父 irq 上的 irq_set_wake() 的 irq 晶片設定鎖類別為巢狀。通常是 GPIO 實現
IRQ_GC_MASK_CACHE_PER_TYPE掩碼快取是晶片型別私有的
IRQ_GC_NO_MASK不計算 irq_data->mask
IRQ_GC_BE_IO使用大端暫存器訪問(預設:小端)
-
struct irq_domain_chip_generic_info¶
通用晶片資訊結構
定義:
struct irq_domain_chip_generic_info {
const char *name;
irq_flow_handler_t handler;
unsigned int irqs_per_chip;
unsigned int num_ct;
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
int (*init)(struct irq_chip_generic *gc);
void (*exit)(struct irq_chip_generic *gc);
};
成員
name通用中斷晶片的名稱
handler通用中斷晶片使用的中斷處理程式
irqs_per_chip每個晶片處理的中斷數量(最大 32)
num_ct與每個晶片關聯的 irq_chip_type 例項數量
irq_flags_to_clear在對映函式中要清除的 IRQ_* 位
irq_flags_to_set在對映函式中要設定的 IRQ_* 位
gc_flags通用晶片特定設定標誌
init在每個晶片建立時呼叫的函式。允許進行一些額外的晶片初始化。
exit在每個晶片銷燬時呼叫的函式。允許進行一些晶片清理操作。
-
struct irqaction¶
每個中斷動作描述符
定義:
struct irqaction {
irq_handler_t handler;
void *dev_id;
void __percpu *percpu_dev_id;
struct irqaction *next;
irq_handler_t thread_fn;
struct task_struct *thread;
struct irqaction *secondary;
unsigned int irq;
unsigned int flags;
unsigned long thread_flags;
unsigned long thread_mask;
const char *name;
struct proc_dir_entry *dir;
};
成員
handler中斷處理函式
dev_id用於識別裝置的 cookie
percpu_dev_id用於識別裝置的 cookie
next指向共享中斷的下一個 irqaction 的指標
thread_fn執行緒化中斷的中斷處理函式
thread執行緒化中斷的執行緒指標
secondary指向輔助 irqaction 的指標(強制執行緒化)
irq中斷號
flagsflags(參見上面的 IRQF_*)
thread_flags與 thread 相關的標誌
thread_mask用於跟蹤 thread 活動的位掩碼
name裝置名稱
dir指向 proc/irq/NN/name 條目的指標
-
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)¶
為中斷線新增處理程式
引數
unsigned int irq要分配的中斷線
irq_handler_t handler中斷髮生時要呼叫的函式。執行緒化中斷的主處理程式。如果為 NULL,則安裝預設的主處理程式。
unsigned long flags處理標誌
const char *name生成此中斷的裝置名稱
void *dev傳遞給處理函式的 cookie
描述
此呼叫分配中斷並建立處理程式;有關詳細資訊,請參閱 request_threaded_irq() 的文件。
-
struct irq_affinity_notify¶
IRQ 親和性更改通知的上下文
定義:
struct irq_affinity_notify {
unsigned int irq;
struct kref kref;
struct work_struct work;
void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
void (*release)(struct kref *ref);
};
成員
irq通知適用的中斷
kref引用計數,供內部使用
work工作項,供內部使用
notify更改時要呼叫的函式。這將在程序上下文中呼叫。
release釋放時要呼叫的函式。這將在程序上下文中呼叫。一旦註冊,結構只能在此函式被呼叫或之後才能釋放。
-
struct irq_affinity¶
自動 irq 親和性分配的描述
定義:
struct irq_affinity {
unsigned int pre_vectors;
unsigned int post_vectors;
unsigned int nr_sets;
unsigned int set_size[IRQ_AFFINITY_MAX_SETS];
void (*calc_sets)(struct irq_affinity *, unsigned int nvecs);
void *priv;
};
成員
pre_vectors不要將親和性應用於 MSI(-X) 向量空間開頭的 pre_vectors
post_vectors不要將親和性應用於 MSI(-X) 向量空間末尾的 post_vectors
nr_sets需要親和性擴散的中斷集數量
set_size儲存每個中斷集大小的陣列
calc_sets計算中斷集數量和大小的回撥函式
priv供 calc_sets 使用的私有資料,通常是指向驅動程式/裝置特定資料的指標。
-
struct irq_affinity_desc¶
中斷親和性描述符
定義:
struct irq_affinity_desc {
struct cpumask mask;
unsigned int is_managed : 1;
};
成員
mask用於儲存親和性分配的 cpumask
is_managed如果中斷由內部管理,則為 1
-
int irq_update_affinity_hint(unsigned int irq, const struct cpumask *m)¶
更新親和性提示
引數
unsigned int irq要更新的中斷
const struct cpumask *mcpumask 指標(NULL 表示清除提示)
描述
更新親和性提示,但不更改中斷的親和性。
-
int irq_set_affinity_and_hint(unsigned int irq, const struct cpumask *m)¶
更新親和性提示並將提供的 cpumask 應用於中斷
引數
unsigned int irq要更新的中斷
const struct cpumask *mcpumask 指標(NULL 表示清除提示)
描述
更新親和性提示,如果 m 不為 NULL,則將其應用於該中斷的親和性。
提供的公共函式¶
本章包含已匯出核心 API 函式的自動生成文件。
-
bool synchronize_hardirq(unsigned int irq)¶
等待掛起的硬 IRQ 處理程式(在其他 CPU 上)
引數
unsigned int irq要等待的中斷號
描述
此函式在返回之前等待此中斷的任何掛起硬 IRQ 處理程式完成。如果您在持有 IRQ 處理程式可能需要的資源時使用此函式,則會發生死鎖。它不考慮相關的執行緒化處理程式。
請勿在關閉場景中使用此功能,在這些場景中您必須確保所有部分(硬中斷和執行緒化處理程式)都已完成。
此函式可以——小心地——從 IRQ 上下文呼叫。
它不檢查中斷是否在硬體級別正在進行中但尚未服務,因為這可能會在停用中斷且中斷的目標 CPU 是當前 CPU 時導致死鎖。
返回
如果執行緒化處理程式處於活動狀態,則為 false。
-
void synchronize_irq(unsigned int irq)¶
等待掛起的 IRQ 處理程式(在其他 CPU 上)
引數
unsigned int irq要等待的中斷號
描述
此函式在返回之前等待此中斷的任何掛起 IRQ 處理程式完成。如果您在持有 IRQ 處理程式可能需要的資源時使用此函式,則會發生死鎖。
只能從可搶佔程式碼中呼叫,因為當中斷執行緒與 irq 關聯時,它可能會休眠。
它(當 irq 晶片支援該方法時)可選地確保中斷在任何 CPU 上都沒有掛起並等待服務。
-
int irq_can_set_affinity(unsigned int irq)¶
檢查給定 irq 的親和性是否可以設定
引數
unsigned int irq要檢查的中斷
-
bool irq_can_set_affinity_usr(unsigned int irq)¶
檢查是否可以從使用者空間設定 irq 的親和性
-
void irq_set_thread_affinity(struct irq_desc *desc)¶
通知 irq 執行緒調整親和性
引數
struct irq_desc *desc親和性已更改的 irq 描述符
描述
只需設定 IRQTF_AFFINITY 並將親和性設定委託給中斷執行緒本身。我們不能在此處呼叫 set_cpus_allowed_ptr(),因為我們持有 desc->lock,並且此程式碼可以從硬中斷上下文呼叫。
-
int irq_update_affinity_desc(unsigned int irq, struct irq_affinity_desc *affinity)¶
更新中斷的親和性管理
引數
unsigned int irq要更新的中斷號
struct irq_affinity_desc *affinity指向親和性描述符的指標
描述
此介面可用於配置已分配中斷的親和性管理。
在何時使用它存在某些限制——嘗試在核心配置為通用 IRQ 保留模式(在 config GENERIC_IRQ_RESERVATION_MODE 中)時使用它將失敗,因為它可能與託管/非託管中斷計數衝突。此外,嘗試在已啟動或已配置為託管的中斷上使用它也將失敗,因為這些意味著無效的初始狀態或重複初始化。
引數
unsigned int irq要設定親和性的中斷
const struct cpumask *cpumaskcpumask
描述
如果 cpumask 不包含線上 CPU,則失敗
引數
unsigned int irq要設定親和性的中斷
const struct cpumask *cpumaskcpumask
描述
與 irq_set_affinity 相同,但不檢查掩碼與線上 CPU 的匹配。
僅用於低階 CPU 熱插拔程式碼,我們需要在 CPU 上線之前使每個 CPU 中斷具有親和性。
-
int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)¶
控制 IRQ 親和性更改通知
引數
unsigned int irq要啟用/停用通知的中斷
struct irq_affinity_notify *notify通知上下文,或
NULL以停用通知。函式指標必須已初始化;其他欄位將由此函式初始化。
描述
必須在程序上下文中呼叫。通知只能在 IRQ 分配後啟用,並且必須在使用 free_irq() 釋放 IRQ 之前停用。
-
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)¶
設定中斷的 vcpu 親和性
引數
unsigned int irq要設定親和性的中斷號
void *vcpu_infovCPU 特定資料或指向 percpu_devid 中斷的 vCPU 特定資料每CPU 陣列的指標
描述
此函式使用 vCPU 特定資料來設定 irq 的 vCPU 親和性。vCPU 特定資料從外部傳遞,例如 KVM。一個示例程式碼路徑如下:KVM -> IOMMU -> irq_set_vcpu_affinity()。
-
void disable_irq_nosync(unsigned int irq)¶
停用 irq 而不等待
引數
unsigned int irq要停用的中斷
描述
停用選定的中斷線。停用和啟用是巢狀的。與 disable_irq() 不同,此函式在返回之前不確保 IRQ 處理程式的現有例項已完成。
此函式可以在 IRQ 上下文呼叫。
-
void disable_irq(unsigned int irq)¶
停用 irq 並等待完成
引數
unsigned int irq要停用的中斷
描述
停用選定的中斷線。啟用和停用是巢狀的。
此函式在返回之前等待此中斷的任何掛起 IRQ 處理程式完成。如果您在持有 IRQ 處理程式可能需要的資源時使用此函式,則會發生死鎖。
只能從可搶佔程式碼中呼叫,因為當中斷執行緒與 irq 關聯時,它可能會休眠。
-
bool disable_hardirq(unsigned int irq)¶
停用 irq 並等待硬中斷完成
引數
unsigned int irq要停用的中斷
描述
停用選定的中斷線。啟用和停用是巢狀的。
此函式在返回之前等待此中斷的任何掛起硬 IRQ 處理程式完成。如果您在持有硬 IRQ 處理程式可能需要的資源時使用此函式,則會發生死鎖。
當用於從原子上下文樂觀地停用中斷時,必須檢查返回值。
此函式可以——小心地——從 IRQ 上下文呼叫。
返回
如果執行緒化處理程式處於活動狀態,則為 false。
-
void disable_nmi_nosync(unsigned int irq)¶
停用 nmi 而不等待
引數
unsigned int irq要停用的中斷
描述
停用選定的中斷線。停用和啟用是巢狀的。
要停用的中斷必須透過 request_nmi 請求。與 disable_nmi() 不同,此函式在返回之前不確保 IRQ 處理程式的現有例項已完成。
-
void enable_irq(unsigned int irq)¶
啟用 irq 處理
引數
unsigned int irq要啟用的中斷
描述
撤銷一次 disable_irq() 呼叫的效果。如果這與最後一次停用匹配,則重新啟用此 IRQ 線上中斷的處理。
此函式僅當 desc->irq_data.chip->bus_lock 和 desc->chip->bus_sync_unlock 為 NULL 時才能從 IRQ 上下文呼叫!
-
void enable_nmi(unsigned int irq)¶
啟用 nmi 處理
引數
unsigned int irq要啟用的中斷
描述
要啟用的中斷必須透過 request_nmi 請求。撤銷一次 disable_nmi() 呼叫的效果。如果這與最後一次停用匹配,則重新啟用此 IRQ 線上中斷的處理。
-
int irq_set_irq_wake(unsigned int irq, unsigned int on)¶
控制 irq 電源管理喚醒
引數
unsigned int irq要控制的中斷
unsigned int on啟用/停用電源管理喚醒
描述
啟用/停用電源管理喚醒模式,該模式預設停用。啟用和停用必須匹配,就像它們與非喚醒模式支援匹配一樣。
喚醒模式允許此 IRQ 將系統從“掛起到 RAM”等睡眠狀態喚醒。
注意
irq 啟用/停用狀態與 irq 喚醒的啟用/停用狀態完全正交。一個 irq 可以透過 disable_irq() 停用,但只要 irq 啟用了喚醒功能,它仍然可以喚醒系統。如果這不成立,則需要調查底層 irq 晶片和相關驅動程式。
-
void irq_wake_thread(unsigned int irq, void *dev_id)¶
喚醒由 dev_id 標識的動作的 irq 執行緒
引數
unsigned int irq中斷線
void *dev_id應喚醒其執行緒的裝置標識
-
const void *free_irq(unsigned int irq, void *dev_id)¶
釋放用 request_irq 分配的中斷
引數
unsigned int irq要釋放的中斷線
void *dev_id要釋放的裝置標識
描述
移除中斷處理程式。處理程式被移除,如果中斷線不再被任何驅動程式使用,則將其停用。在共享 IRQ 上,呼叫者必須確保在呼叫此函式之前,它所驅動的卡上的中斷已停用。函式在針對此 IRQ 的任何正在執行的中斷完成之前不會返回。
此函式不得從中斷上下文呼叫。
返回傳遞給 request_irq 的 devname 引數。
-
int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long irqflags, const char *devname, void *dev_id)¶
分配中斷線
引數
unsigned int irq要分配的中斷線
irq_handler_t handler中斷髮生時要呼叫的函式。執行緒化中斷的主處理程式。如果
handler為 NULL 且thread_fn不為 NULL,則安裝預設的主處理程式。irq_handler_t thread_fn從 irq 處理程式執行緒呼叫的函式。如果為 NULL,則不建立 irq 執行緒。
unsigned long irqflags中斷型別標誌
const char *devname宣告此裝置的 ASCII 名稱
void *dev_id傳遞迴處理函式的一個 cookie
描述
此呼叫分配中斷資源並啟用中斷線和 IRQ 處理。從呼叫此函式的那一刻起,您的處理函式可能會被呼叫。由於您的處理函式必須清除板卡引發的任何中斷,因此您必須注意以正確的順序初始化硬體和設定中斷處理程式。
如果您想為您的裝置設定執行緒化 irq 處理程式,則需要提供 handler 和 thread_fn。handler 仍然在硬中斷上下文中呼叫,並且必須檢查中斷是否源自裝置。如果是,它需要停用裝置上的中斷並返回 IRQ_WAKE_THREAD,這將喚醒處理程式執行緒並執行 thread_fn。這種分離的處理程式設計對於支援共享中斷是必要的。
dev_id 必須全域性唯一。通常,裝置資料結構的地址用作 cookie。由於處理程式會收到此值,因此使用它是有意義的。
如果您的中斷是共享的,則必須傳遞一個非 NULL 的 dev_id,因為在釋放中斷時需要它。
標誌
IRQF_SHARED 中斷是共享的 IRQF_TRIGGER_* 指定活動邊沿或電平 IRQF_ONESHOT 在中斷線被遮蔽的情況下執行 thread_fn
-
int request_any_context_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev_id)¶
分配中斷線
引數
unsigned int irq要分配的中斷線
irq_handler_t handler當 IRQ 發生時呼叫的函式。用於執行緒化中斷的執行緒化處理程式。
unsigned long flags中斷型別標誌
const char *name宣告此裝置的 ASCII 名稱
void *dev_id傳遞迴處理函式的一個 cookie
描述
此呼叫分配中斷資源,並啟用中斷線和 IRQ 處理。它根據上下文選擇硬中斷(hardirq)或執行緒化處理方法。
返回
失敗時,返回負值。成功時,返回 IRQC_IS_HARDIRQ 或 IRQC_IS_NESTED。
-
int request_nmi(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *name, void *dev_id)¶
分配一條用於 NMI 遞送的中斷線
引數
unsigned int irq要分配的中斷線
irq_handler_t handler當 IRQ 發生時呼叫的函式。用於執行緒化中斷的執行緒化處理程式。
unsigned long irqflags中斷型別標誌
const char *name宣告此裝置的 ASCII 名稱
void *dev_id傳遞迴處理函式的一個 cookie
描述
此呼叫分配中斷資源,並啟用中斷線和 IRQ 處理。它將 IRQ 線設定為作為 NMI 處理。
遞送 NMI 的中斷線不能共享,且 IRQ 處理不能執行緒化。
請求用於 NMI 遞送的中斷線必須生成每個 CPU 的中斷,並且自動啟用設定必須被停用。
dev_id 必須全域性唯一。通常,裝置資料結構的地址用作 cookie。由於處理程式會收到此值,因此使用它是有意義的。
如果中斷線不能用於遞送 NMI,函式將失敗並返回負值。
-
bool irq_percpu_is_enabled(unsigned int irq)¶
檢查每個 CPU 中斷是否已啟用
引數
unsigned int irq要檢查的 Linux irq 號
描述
必須從不可遷移的上下文呼叫。返回當前 CPU 上每個 CPU 中斷的啟用狀態。
-
void free_percpu_irq(unsigned int irq, void __percpu *dev_id)¶
釋放用 request_percpu_irq 分配的中斷
引數
unsigned int irq要釋放的中斷線
void __percpu *dev_id要釋放的裝置標識
描述
移除一個每個 CPU 中斷處理程式。處理程式被移除,但中斷線並未停用。在呼叫此函式之前,必須在每個 CPU 上完成此操作。該函式只有在所有為此 IRQ 正在執行的中斷完成後才會返回。
此函式不得從中斷上下文呼叫。
引數
unsigned int irq要設定的中斷線
struct irqaction *act中斷的 irqaction
描述
用於在早期啟動過程中靜態設定每個 CPU 中斷。
-
int __request_percpu_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *devname, void __percpu *dev_id)¶
分配一個每個 CPU 中斷線
引數
unsigned int irq要分配的中斷線
irq_handler_t handler當 IRQ 發生時呼叫的函式。
unsigned long flags中斷型別標誌(僅 IRQF_TIMER)
const char *devname宣告此裝置的 ASCII 名稱
void __percpu *dev_id傳遞迴處理函式的每個 CPU cookie
描述
此呼叫分配中斷資源並在本地 CPU 上啟用中斷。如果中斷需要在其他 CPU 上啟用,則必須在每個 CPU 上使用 enable_percpu_irq() 完成此操作。
dev_id 必須全域性唯一。它是一個每個 CPU 變數,並且處理程式會使用被中斷 CPU 的該變數例項來呼叫。
-
int request_percpu_nmi(unsigned int irq, irq_handler_t handler, const char *name, void __percpu *dev_id)¶
分配一個用於 NMI 遞送的每個 CPU 中斷線
引數
unsigned int irq要分配的中斷線
irq_handler_t handler當 IRQ 發生時呼叫的函式。
const char *name宣告此裝置的 ASCII 名稱
void __percpu *dev_id傳遞迴處理函式的每個 CPU cookie
描述
此呼叫為每個 CPU NMI 分配中斷資源。每個 CPU NMI 必須在透過 enable_percpu_nmi() 在同一 CPU 上啟用之前,透過呼叫 prepare_percpu_nmi() 在每個 CPU 上進行設定。
dev_id 必須全域性唯一。它是一個每個 CPU 變數,並且處理程式會使用被中斷 CPU 的該變數例項來呼叫。
請求用於 NMI 遞送的中斷線應該停用自動啟用設定。
如果中斷線不能用於遞送 NMI,函式將失敗並返回負值。
-
int prepare_percpu_nmi(unsigned int irq)¶
執行 NMI 遞送的 CPU 本地設定
引數
unsigned int irq要準備用於 NMI 遞送的中斷線
描述
此呼叫準備一條中斷線,以便在當前 CPU 上遞送 NMI,在此中斷線透過 enable_percpu_nmi() 啟用之前。
作為 CPU 本地操作,應從不可搶佔的上下文呼叫此函式。
如果中斷線不能用於遞送 NMI,函式將失敗並返回負值。
-
void teardown_percpu_nmi(unsigned int irq)¶
撤銷 IRQ 線的 NMI 設定
引數
unsigned int irq應移除 CPU 本地 NMI 配置的中斷線
描述
此呼叫撤銷了由 prepare_percpu_nmi() 完成的設定。
IRQ 線不應為當前 CPU 啟用。作為 CPU 本地操作,應從不可搶佔的上下文呼叫此函式。
-
int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool *state)¶
返回中斷的 irqchip 狀態。
引數
unsigned int irq轉發到虛擬機器的中斷線
enum irqchip_irq_state which呼叫者想要了解的 IRQCHIP_STATE_* 之一
bool *state一個布林指標,用於儲存狀態
描述
此呼叫拍攝中斷的內部 irqchip 狀態快照,將與階段 which 對應的位返回到 state 中。
如果中斷控制器具有每個 CPU 暫存器,則應停用搶佔來呼叫此函式。
-
int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool val)¶
設定轉發中斷的狀態。
引數
unsigned int irq轉發到虛擬機器的中斷線
enum irqchip_irq_state which要恢復的狀態(IRQCHIP_STATE_* 之一)
bool val對應於 which 的值
描述
此呼叫根據 which 的值,設定中斷的內部 irqchip 狀態。
如果中斷控制器具有每個 CPU 暫存器,則應停用遷移來呼叫此函式。
-
bool irq_has_action(unsigned int irq)¶
檢查中斷是否已請求
引數
unsigned int irqLinux irq 號
返回
當前狀態的快照
-
bool irq_check_status_bit(unsigned int irq, unsigned int bitmask)¶
檢查 irq 描述符狀態中的位是否已設定
引數
unsigned int irqLinux irq 號
unsigned int bitmask要評估的位掩碼
返回
如果 bitmask 中的任一位被設定,則為 True
引數
unsigned int irqirq 號
const struct irq_chip *chip指向 irq 晶片描述結構的指標
-
int irq_set_irq_type(unsigned int irq, unsigned int type)¶
設定 irq 的 irq 觸發型別
引數
unsigned int irqirq 號
unsigned int typeIRQ_TYPE_{LEVEL,EDGE}_* 值 - 參見 include/linux/irq.h
-
int irq_set_handler_data(unsigned int irq, void *data)¶
設定 irq 的 irq 處理程式資料
引數
unsigned int irq中斷號
void *data指向中斷特定資料的指標
描述
設定 irq 的硬體 irq 控制器資料
-
int irq_set_chip_data(unsigned int irq, void *data)¶
設定 irq 的 irq 晶片資料
引數
unsigned int irq中斷號
void *data指向晶片特定資料的指標
描述
設定 irq 的硬體 irq 晶片資料
-
void handle_nested_irq(unsigned int irq)¶
從 irq 執行緒處理巢狀 irq
引數
unsigned int irq中斷號
描述
處理巢狀到執行緒化中斷處理程式中的中斷。處理函式在呼叫執行緒的上下文中被呼叫。
-
void handle_simple_irq(struct irq_desc *desc)¶
簡單和軟體解碼的 IRQ。
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
簡單中斷要麼從解複用中斷處理程式傳送,要麼來自硬體,其中不需要中斷硬體控制。
注意
如果需要,呼叫者應處理確認、清除、遮蔽和解除遮蔽問題。
-
void handle_untracked_irq(struct irq_desc *desc)¶
簡單和軟體解碼的 IRQ。
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
未跟蹤中斷從解複用中斷處理程式傳送,當解複用器不知道是其多路複用 irq 域中的哪個裝置生成了中斷時。透過此處處理的 IRQ 不受統計跟蹤、隨機性或虛假中斷檢測的影響。
注意
與 handle_simple_irq 類似,如果需要,呼叫者應處理確認、清除、遮蔽和解除遮蔽問題。
-
void handle_level_irq(struct irq_desc *desc)¶
電平觸發 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
電平觸發中斷在硬體線保持活動電平期間一直處於活動狀態。這可能需要遮蔽中斷,並在相關處理程式確認裝置後解除遮蔽,以便中斷線返回非活動狀態。
-
void handle_fasteoi_irq(struct irq_desc *desc)¶
透明控制器的 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
只會向晶片發出一個回撥:當中斷被服務後呼叫 ->eoi()。這支援現代形式的中斷處理程式,這些處理程式以透明方式在硬體中處理流詳細資訊。
-
void handle_fasteoi_nmi(struct irq_desc *desc)¶
NMI 中斷線的 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
一個簡單的 NMI 安全處理程式,考慮了 request_nmi 的限制。
只會向晶片發出一個回撥:當中斷被服務後呼叫 ->eoi()。這支援現代形式的中斷處理程式,這些處理程式以透明方式在硬體中處理流詳細資訊。
-
void handle_edge_irq(struct irq_desc *desc)¶
邊沿觸發 IRQ 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
中斷髮生在硬體訊號的下降沿和/或上升沿。發生的中斷被鎖存到 irq 控制器硬體中,並且必須透過確認才能重新啟用。確認後,即使在第一個中斷被相關事件處理程式處理之前,同一源上也可能發生另一箇中斷。如果發生這種情況,可能需要根據控制器硬體停用(遮蔽)中斷。這需要在一個迴圈中重新啟用中斷,該迴圈處理在處理程式執行時到達的中斷。如果所有待處理中斷都已處理,則退出迴圈。
-
void handle_fasteoi_ack_irq(struct irq_desc *desc)¶
堆疊在透明控制器上的邊沿層級 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
類似於 handle_fasteoi_irq(),但用於需要呼叫其 ->irq_ack() 函式的 irq_chip 的層級。
-
void handle_fasteoi_mask_irq(struct irq_desc *desc)¶
堆疊在透明控制器上的電平層級 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
類似於 handle_fasteoi_irq(),但用於需要呼叫其 ->irq_mask_ack() 函式的 irq_chip 的層級。
-
int irq_chip_set_parent_state(struct irq_data *data, enum irqchip_irq_state which, bool val)¶
設定父中斷的狀態。
引數
struct irq_data *data指向中斷特定資料的指標
enum irqchip_irq_state which要恢復的狀態(IRQCHIP_STATE_* 之一)
bool val對應於 which 的值
描述
如果底層 irqchip 未實現,則有條件成功。
-
int irq_chip_get_parent_state(struct irq_data *data, enum irqchip_irq_state which, bool *state)¶
獲取父中斷的狀態。
引數
struct irq_data *data指向中斷特定資料的指標
enum irqchip_irq_state which呼叫者想要了解的 IRQCHIP_STATE_* 之一
bool *state一個布林指標,用於儲存狀態
描述
如果底層 irqchip 未實現,則有條件成功。
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
-
int irq_chip_set_affinity_parent(struct irq_data *data, const struct cpumask *dest, bool force)¶
設定父中斷的親和性
引數
struct irq_data *data指向中斷特定資料的指標
const struct cpumask *dest要設定的親和性掩碼
bool force強制設定的標誌(停用線上檢查)
描述
有條件,因為底層父晶片可能未實現它。
引數
struct irq_data *data指向中斷特定資料的指標
unsigned int typeIRQ_TYPE_{LEVEL,EDGE}_* 值 - 參見 include/linux/irq.h
描述
有條件,因為底層父晶片可能未實現它。
引數
struct irq_data *data指向中斷特定資料的指標
描述
遍歷中斷的域層級,並檢查是否存在硬體重新觸發函式。如果存在,則呼叫它。
引數
struct irq_data *data指向中斷特定資料的指標
void *vcpu_infovcpu 親和性資訊
引數
struct irq_data *data指向中斷特定資料的指標
unsigned int on是否設定或重置此 irq 的喚醒功能
描述
有條件,因為底層父晶片可能未實現它。
引數
struct irq_data *data指向中斷特定資料的指標
引數
struct irq_data *data指向中斷特定資料的指標
提供的內部函式¶
本章包含內部函式的自動生成文件。
-
unsigned int irq_get_nr_irqs(void)¶
系統支援的中斷數量。
引數
void無引數
-
unsigned int irq_set_nr_irqs(unsigned int nr)¶
設定系統支援的中斷數量。
引數
unsigned int nr新的中斷數量。
返回
nr.
-
int generic_handle_irq(unsigned int irq)¶
為特定 irq 呼叫處理程式
引數
unsigned int irq要處理的 irq 號
返回
成功時為 0,如果轉換失敗則為 -EINVAL
此函式必須在 IRQ 上下文中呼叫,並初始化 irq 暫存器。
-
int generic_handle_irq_safe(unsigned int irq)¶
從任何上下文為特定 irq 呼叫處理程式。
引數
unsigned int irq要處理的 irq 號
返回
成功時為 0,錯誤時為負值。
描述
此函式可以從任何上下文(IRQ 或程序上下文)呼叫。如果未從 IRQ 上下文呼叫,並且 irq 已被標記為僅強制 IRQ 上下文,它將報告錯誤。
-
int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq)¶
為屬於某個域的硬體 irq 呼叫處理程式。
引數
struct irq_domain *domain執行查詢的域
unsigned int hwirq要轉換為邏輯值的硬體 irq 號
返回
成功時為 0,如果轉換失敗則為 -EINVAL
此函式必須在 IRQ 上下文中呼叫,並初始化 irq 暫存器。
-
int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq)¶
為屬於某個域的硬體 NMI 呼叫處理程式。
引數
struct irq_domain *domain執行查詢的域
unsigned int hwirq要轉換為邏輯值的硬體 irq 號
返回
成功時為 0,如果轉換失敗則為 -EINVAL
此函式必須在 NMI 上下文中呼叫,並初始化 irq 暫存器。
-
void irq_free_descs(unsigned int from, unsigned int cnt)¶
釋放 irq 描述符
引數
unsigned int from描述符範圍的起始
unsigned int cnt要釋放的連續 irq 數量
-
int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, struct module *owner, const struct irq_affinity_desc *affinity)¶
分配並初始化一個 irq 描述符範圍
引數
int irq如果 irq >= 0,則為特定 irq 號分配
unsigned int from從此 irq 號開始搜尋
unsigned int cnt要分配的連續 irq 數量。
int node優先分配 irq 描述符的節點
struct module *owner擁有模組(可為 NULL)
const struct irq_affinity_desc *affinity可選的指向大小為 cnt 的親和性掩碼陣列的指標,該陣列提示 irq 描述符應分配到何處以及使用哪些預設親和性
描述
返回第一個 irq 號或錯誤程式碼
-
unsigned int irq_get_next_irq(unsigned int offset)¶
獲取下一個已分配的 irq 號
引數
unsigned int offset從何處開始搜尋
描述
返回偏移量後的下一個 irq 號,如果未找到則返回 nr_irqs。
-
unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)¶
獲取 CPU 上中斷的統計資訊
引數
unsigned int irq中斷號
int cpuCPU 號
描述
返回自啟動以來 cpu 上 irq 的中斷計數總和。呼叫者必須確保中斷不會併發移除。
-
unsigned int kstat_irqs_usr(unsigned int irq)¶
從執行緒上下文獲取中斷的統計資訊
引數
unsigned int irq中斷號
描述
返回自啟動以來所有 CPU 上 irq 的中斷計數總和。
它使用 rcu 保護訪問,因為中斷描述符的併發移除在 delayed_free_desc()/irq_kobj_release() 之前會觀察到一個 rcu 寬限期。
-
void handle_bad_irq(struct irq_desc *desc)¶
處理虛假和未處理的 irq
引數
struct irq_desc *desc中斷的描述
描述
處理虛假和未處理的 IRQ。它還會列印一條除錯訊息。
-
void noinstr generic_handle_arch_irq(struct pt_regs *regs)¶
針對不自行進行入口計數的架構的根 irq 處理程式
引數
struct pt_regs *regs來自低階處理程式碼的暫存器檔案
-
int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset, struct msi_desc *entry)¶
在偏移量處為 irq 設定 MSI 描述符資料
引數
unsigned int irq_base中斷號基址
unsigned int irq_offset中斷號偏移量
struct msi_desc *entry指向 MSI 描述符資料的指標
描述
在偏移量處為 irq 設定 MSI 描述符條目
-
int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)¶
為 irq 設定 MSI 描述符資料
引數
unsigned int irq中斷號
struct msi_desc *entry指向 MSI 描述符資料的指標
描述
為 irq 設定 MSI 描述符條目
-
void irq_disable(struct irq_desc *desc)¶
將中斷標記為停用
引數
struct irq_desc *desc應該被停用的 irq 描述符
描述
如果晶片未實現 irq_disable 回撥,我們採用延遲停用方法。這意味著我們標記中斷為停用,但讓硬體保持未遮蔽狀態。這是一個最佳化,因為我們避免了在標記為停用後沒有中斷髮生的常見情況下的硬體訪問。如果發生中斷,則中斷流處理程式會在硬體級別遮蔽該線路並將其標記為待處理。
如果中斷晶片未實現 irq_disable 回撥,驅動程式可以透過呼叫“irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY)”來停用特定 irq 線的延遲方法。這可用於在某些情況下無法在裝置級別停用中斷,而必須使用 disable_irq[_nosync] 的裝置。
-
void handle_percpu_irq(struct irq_desc *desc)¶
每個 CPU 本地 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
SMP 機器上不需要鎖定要求的每個 CPU 中斷
-
void handle_percpu_devid_irq(struct irq_desc *desc)¶
帶有每個 CPU dev_id 的每個 CPU 本地 irq 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
SMP 機器上不需要鎖定要求的每個 CPU 中斷。與上面 handle_percpu_irq() 相同,但有以下額外功能
action->percpu_dev_id 是指向每個 CPU 變數的指標,這些變數包含呼叫此處理程式的 CPU 的實際裝置 ID
-
void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc)¶
帶有每個 CPU dev_id 的每個 CPU 本地 NMI 處理程式
引數
struct irq_desc *desc此 irq 的中斷描述結構
描述
類似於 handle_fasteoi_nmi,但將 dev_id cookie 作為每個 CPU 指標處理。
-
void irq_cpu_online(void)¶
呼叫所有 irq_cpu_online 函式。
-
void irq_cpu_offline(void)¶
呼叫所有 irq_cpu_offline 函式。
引數
struct irq_data *data指向中斷特定資料的指標
struct msi_msg *msg指向 MSI 訊息的指標
描述
對於分層域,我們找到層級中第一個實現 irq_compose_msi_msg 回撥的晶片。對於非分層域,我們使用頂層晶片。
引數
struct irq_data *data指向中斷特定資料的指標
描述
啟用中斷資料結構引用的 IRQ 晶片的電源。
引數
struct irq_data *data指向中斷特定資料的指標
描述
停用中斷資料結構引用的 IRQ 晶片的電源。請注意,只有在所有已呼叫 irq_chip_pm_get() 的 IRQ 都呼叫此函式後,電源才會被停用。
鳴謝¶
以下人員對本文件做出了貢獻
Thomas Gleixner tglx@linutronix.de
Ingo Molnar mingo@elte.hu