1. 程式人生 > 其它 >linux不用裝置樹寫中斷,linux-kernel – 將裝置樹中斷標誌對映到devm_request_irq

linux不用裝置樹寫中斷,linux-kernel – 將裝置樹中斷標誌對映到devm_request_irq

我目前正在為

Linux使用PowerPC編寫裝置驅動程式.

裝置樹條目如下:

// PPS Interrupt client

pps_hwirq {

compatible = "pps-hwirq";

interrupts = <17 0x02>; // IPIC 17 = IRQ1, 0x02 = 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, "No interrupt found in the device tree\n");

return -EINVAL;

}

但是如何將IRQ標誌從裝置樹對映到驅動程式?

/* ****TODO****: Get the interrupt flags from the device tree

* For now, hard code to suit my problem, but since this differs

* by GPS receiver, it should be configurable.

*/

flags = IRQF_TRIGGER_FALLING;

/* register IRQ interrupt handler */

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/picoxcell_crypto.c: if (devm_request_irq(&pdev->dev, irq->start, spacc_spacc_irq, 0,

或硬編碼硬體實際斷言的內容:

./drivers/crypto/tegra-aes.c: err = devm_request_irq(dev, dd->irq, aes_irq, IRQF_TRIGGER_HIGH |

那麼如何將這個屬性從裝置樹幹淨地關聯到實際的驅動程式呢?

此外,我將展示如何在一些常見情況下從裝置樹獲取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);

}

...

client->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_irq()時,它最終會在__setup_irq()中結束,然後執行下一步:

/*

* If the trigger type is not specified by the caller,

* then use the default for this interrupt.

*/

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());儲存的IRQ標誌將在devm_request_irq()中自動使用,如果您沒有向其傳遞IRQ觸發器型別(例如,您可以傳遞flags = 0)

> IRQ標誌可以在irq_get_trigger_type()獲得,但僅在執行irq_of_parse_and_map()之後

所以可能你只需要執行irq_of_parse_and_map()並讓devm_request_irq()為你處理標誌(只是確保你沒有向它傳遞觸發器標誌).

【轉】https://blog.csdn.net/weixin_28949355/article/details/116775031