企业网站制作优化,wordpress媒体库在哪,wordpress文章404,个人网页设计思路怎么写irq自动探测机制
如果一个设备的驱动程序无法确定它说管理的设备的软件中断号irq#xff0c;此时设备驱动程序可以使用irq的自动探测机制来获取其正在使用的irq。
使用自动探测机制的条件
内核与驱动#xff0c;必须共同努力才能完成只限于非共享中断的情况
探测前#…irq自动探测机制
如果一个设备的驱动程序无法确定它说管理的设备的软件中断号irq此时设备驱动程序可以使用irq的自动探测机制来获取其正在使用的irq。
使用自动探测机制的条件
内核与驱动必须共同努力才能完成只限于非共享中断的情况
探测前驱动的设备关联到了某个irq但是因为设备驱动程序还不清楚是哪个irq因此无法调用request_irq来向该irq安装中断处理例程所以对应irq的action为空下面是一个设备驱动程序的使用示例 probe_irq_on和probe_irq_off是内核为驱动程序员设计的两个自动探测的接口函数
irq自动探测的原理描述 probe_irq_on /*** probe_irq_on - begin an interrupt autodetect** Commence probing for an interrupt. The interrupts are scanned* and a mask of potential interrupt lines is returned.** 开始探测中断扫描中断并返回潜在中断线的mask*/
unsigned long probe_irq_on(void)
{struct irq_desc *desc;unsigned long mask 0;int i;/** quiesce the kernel, or at least the asynchronous portion*/async_synchronize_full();mutex_lock(probing_active);/** something may have generated an irq long ago and we want to* flush such a longstanding irq before considering it as spurious.*/for_each_irq_desc_reverse(i, desc) {raw_spin_lock_irq(desc-lock);if (!desc-action irq_settings_can_probe(desc)) {/** Some chips need to know about probing in* progress:*/if (desc-irq_data.chip-irq_set_type)desc-irq_data.chip-irq_set_type(desc-irq_data,IRQ_TYPE_PROBE);irq_startup(desc);}raw_spin_unlock_irq(desc-lock);}/* Wait for longstanding interrupts to trigger. */msleep(20);/** enable any unassigned irqs* (we must startup again here because if a longstanding irq* happened in the previous stage, it may have masked itself)*/for_each_irq_desc_reverse(i, desc) {raw_spin_lock_irq(desc-lock);if (!desc-action irq_settings_can_probe(desc)) {desc-istate | IRQS_AUTODETECT | IRQS_WAITING;if (irq_startup(desc))desc-istate | IRQS_PENDING;}raw_spin_unlock_irq(desc-lock);}/** Wait for spurious interrupts to trigger*/msleep(100);/** Now filter out any obviously spurious interrupts*/for_each_irq_desc(i, desc) {raw_spin_lock_irq(desc-lock);if (desc-istate IRQS_AUTODETECT) {/* It triggered already - consider it spurious. */if (!(desc-istate IRQS_WAITING)) {desc-istate ~IRQS_AUTODETECT;irq_shutdown(desc);} elseif (i 32)mask | 1 i;}raw_spin_unlock_irq(desc-lock);}return mask;
}
EXPORT_SYMBOL(probe_irq_on);probe_irq_off
/*** probe_irq_off - end an interrupt autodetect* val: mask of potential interrupts (unused)** Scans the unused interrupt lines and returns the line which* appears to have triggered the interrupt. If no interrupt was* found then zero is returned. If more than one interrupt is* found then minus the first candidate is returned to indicate* their is doubt.** The interrupt probe logic state is returned to its previous* value.** BUGS: When used in a module (which arguably shouldnt happen)* nothing prevents two IRQ probe callers from overlapping. The* results of this are non-optimal.*/
int probe_irq_off(unsigned long val)
{int i, irq_found 0, nr_of_irqs 0;struct irq_desc *desc;for_each_irq_desc(i, desc) {raw_spin_lock_irq(desc-lock);if (desc-istate IRQS_AUTODETECT) {if (!(desc-istate IRQS_WAITING)) {if (!nr_of_irqs)irq_found i;nr_of_irqs;}desc-istate ~IRQS_AUTODETECT;irq_shutdown(desc);}raw_spin_unlock_irq(desc-lock);}mutex_unlock(probing_active);if (nr_of_irqs 1)irq_found -irq_found;return irq_found;
}
EXPORT_SYMBOL(probe_irq_off);