SPI作為共享中斷,直接使用request_irq等函式註冊中斷處理函式即可
對於SMP系統PPI中斷來說,就需要為每個core都註冊一箇中斷處理函式,相關處理函式如下:
int smp_call_function(void (*func)(void *info), void *info, int retry, int wait); // 引數說明 func 引數是指向要執行的函式的指標。 info 引數是一個可選的引數指標,可以傳遞給被呼叫的函式。 retry 引數指定了在發生錯誤時重試的次數。如果為 0,則不會重試。 wait 引數指示是否等待所有 CPU 完成函式的執行。如果為 0,則該函式立即返回,不等待所有 CPU 完成執行。如果為非零,則該函式會等待所有 CPU 完成執行。 int smp_call_function_single(int cpu, void (*func)(void *info), void *info, int retry, int wait); // 引數說明 cpu 引數是要執行函式的 CPU 核心編號。 func 引數是指向要執行的函式的指標。 info 引數是一個可選的引數指標,可以傳遞給被呼叫的函式。 retry 引數指定了在發生錯誤時重試的次數。如果為 0,則不會重試。 wait 引數指示是否等待指定 CPU 完成函式的執行。如果為 0,則該函式立即返回,不等待 CPU 完成執行。如果為非零,則該函式會等待指定 CPU 完成執行。 int request_percpu_irq(unsigned int irq, irq_handler_t handler, const char *devname, void *dev_id); // 引數說明 irq:要請求的中斷號。 handler:中斷處理函式,當中斷事件發生時被呼叫。 devname:與中斷相關聯的裝置的名稱,用於除錯和記錄目的。 dev_id:傳遞給中斷處理函式的裝置識別符號。
使用demo如下:
#include <linux/interrupt.h> #include <linux/smp.h> #define IRQ_NUM_BASE 10 // PPI中斷號,irq而非hwirq // 中斷處理函式 static irqreturn_t my_interrupt_handler(int irq, void *dev_id) { // 中斷事件發生時執行的處理程式碼 return IRQ_HANDLED; } // 在指定 CPU 上註冊基於 CPU 的中斷 static int register_percpu_irq_on_cpu(void *info) { int cpu = smp_processor_id(); int irq_num = IRQ_NUM_BASE + cpu; int ret; // 請求分配一個基於 CPU 的中斷 ret = request_percpu_irq(irq_num, my_interrupt_handler, "my_device", NULL); if (ret) { printk(KERN_ERR "Failed to request percpu IRQ %d on CPU %d: %d\n", irq_num, cpu, ret); return ret; } printk(KERN_INFO "Successfully requested percpu IRQ %d on CPU %d\n", irq_num, cpu); return 0; } // 初始化模組 int init_module(void) { int ret; // 在每個 CPU 核心上註冊基於 CPU 的中斷 ret = smp_call_function(register_percpu_irq_on_cpu, NULL, 1); if (ret) { printk(KERN_ERR "Failed to register percpu IRQ on all CPUs: %d\n", ret); return ret; } printk(KERN_INFO "Module initialized\n"); return 0; } // 清理模組 void cleanup_module(void) { int cpu; // 釋放在每個 CPU 核心上註冊的中斷資源 for_each_possible_cpu(cpu) { free_percpu_irq(IRQ_NUM_BASE + cpu, NULL); } printk(KERN_INFO "Module unloaded\n"); }