作者:火鸟大叔 | 来源:互联网 | 2023-08-06 07:27
我现在
Linux使用PowerPC创建设备驱动程序。
设备树中的条目如下:
//PPS interrupt客户端
pps_hwirq {
compatible='pps-hwirq ';
interrupts=170x02; //ipic 17=IRQ 1,0 x02=falling edge
interrupt-parent=ipic;
(;
0x02标志非常重要。 PPS与下降沿一致,但这在GPS接收机中不是通用的,所以必须是可配置的。
驱动程序的probe ) )函数中,获取IRQ编号很简单。
hwirq=IRQ_of_parse_and_map(NP,0 );
if(hwirq==no_IRQ ) {
dev_err(pdev-dev,' nointerruptfoundinthedevicetree (n ) );
返回最大值;
}
但是,如何将IRQ标志从设备树映射到驱动程序?
/* * * todo * * * : gettheinterruptflagsfromthedevicetree
* For now,hard code to suit my problem,but since this differs
* by GPS receiver,it should be configurable。
*/
flags=IRQF_TRIGGER_FALLING;
/* registerirqinterrupthandler * /
ret=devm_request_IRQ(pdev-dev,data-irq,pps_hwint_irq_handler,
flags,data-info.name,data;
遗憾的是,很少有实例真正在树中执行了这项工作。 如果有,大多数情况下,此标志保持为0。 这是grep for devm_request_irq的结果片段。 请注意标志的值。
./drivers/crypto/mxs-DCP.c : ret=devm _ request _ IRQ (dev,dcp_vmi_irq,mxs_dcp_irq,0,
./drivers/crypto/mxs-DCP.c : ret=devm _ request _ IRQ (dev,dcp_irq,mxs_dcp_irq,0,
./drivers/crypto/omap-sham.c : err=devm _ request _ IRQ (dev,dd-irq,dd-pdata-intr_hdlr,
./drivers/crypto/omap-AES.c : err=devm _ request _ IRQ (dev,IRQ,omap_aes_irq,0,
./drivers/crypto/pico xcell _ crypto.c : if (devm _ request _ IRQ (pdev-dev、irq-start、spacc_spacc ) )
或硬编码硬件实际表明的内容:
./drivers/crypto/tegra-AES.c : err=devm _ request _ IRQ (dev、dd-irq、aes_irq、irqf _ triger _ hig
那么,如何将该属性从设备树干净地与实际驱动程序相关联呢?
还介绍了从设备树中检索IRQ编号和IRQ标志的常用方法。
在I2C驱动程序中
在平台驱动程序中
手动
在I2C驱动程序中
简而言之
如果正在创建I2C驱动程序,则不需要从DT中手动读取IRQ参数。 可以使用I2C内核输入IRQ参数。
probe (在函数中,client- irq包含IRQ编号
devm_request_irq ) )自动使用DT的IRQ标志。 但是,请不要将IRQ触发标志传递给此函数。
细微的地方
下面的i2c_device_probe (让我们看一下函数。 调用驱动程序probe )函数的位置。
static int I2C _ device _ probe (struct device * dev )
{
.
if(dev-of_node ) {
.
IRQ=of_IRQ_get(dev-of_node,0 );
}
.
客户端- IRQ=IRQ;
.
status=driver-probe(client,I2c_match_id ) driver-id_table,client );
}
因此,client- irq在驱动程序的探测函数中包含IRQ编号。
关于IRQ标志,在of_irq_get ()上的代码中,最终调用irqd_set_trigger_type ) ),从设备树读取的IRQ标志作为中断号码因此,当调用devm_request_时
/*
* ifthetriggertypeisnotspecifiedbythecaller,
* thenusethedefaultforthisinterrupt。
*/
if (! (new-flags IRQF_TRIGGER_MASK )
new-flags|=irqd _ get _ trigger _ type (desc-IRQ _ data );
在哪里:
new- flags包含为devm_request_irq )提供的标志
irqd_get_trigger_type ()返回从DT获取的标志
这意味着如果不将IRQ标志传递给devm_request_irq () (),例如,传递0,则将使用从设备树中检索到的IRQ标志。
有关详细信息,请参阅this question。
平台驱动程序
platform_get_irq ) )来获取IRQ号码。 此外,从DT获取的IRQ标志也存储在(内部)中,因此如果将flags=0传递给devm_request_irq ),则会使用来自DT的标志。
手动
如果驱动程序与内核框架无关,则必须手动获取IRQ值。
IRQ号码可通过irq_of_parse_and_map ()获得。 正如所说明的那样。 此函数不仅返回IRQ编号,还存储IRQ编号的IRQ标志。 最终,irqd_set_trigger_type () ); devm_request_irq ()会自动使用保存的IRQ标志。 如果不传递IRQ触发器类型,例如可以传递flags=0
IRQ标志可在irq_get_trigger_type ()中获得,但只有在执行了irq_of_parse_and_map )之后才能获得
因此,可能需要运行irq_of_parse_and_map ()并由devm_request_irq )处理该标志。 (只需确保没有传递触发标志。