你好,
我们使用的芯片型号是:TDA4VL,对应的Linux版本是:PROCESSOR-SDK-LINUX-J721S2 08_00_04_05,对应的RTOS的版本是:PROCESSOR-SDK-RTOS-J721S2 08_00_04_04。
我们在A72上面运行Linux操作系统,我们想在Linux操作系统上实现GPIO外部中断功能。我使用的GPIO引脚是:GPIO0_5(AD25)。
对于GPIO中断,我们进行了验证,发现request_irq成功返回,我们尝试去触发中断(确保GPIO0_5(AD25)的电平发生了翻转),但是中断服务函数始终无法响应。我们的代码如下:
diff --git a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 35edbc1..9c75e3f 100755
--- a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -93,6 +93,13 @@
<3300000 0x1>;
};
+ gpio_test: gpio_test {
+ compatible = "ti,gpio_test";
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <5 IRQ_TYPE_EDGE_BOTH>;
+ };
+
+
transceiver1: can-phy1 {
compatible = "ti,tcan1043";
#phy-cells = <0>;
@@ -174,6 +181,12 @@
>;
};
+ test_key_pins_default: test-key-pins-default {
+ pinctrl-single,pins = <
+ J721S2_IOPAD(0x014, PIN_INPUT, 7) /* (AD25) MCAN14_TX.GPIO0_5 */
+ >;
+ };
+
main_uart8_pins_default: main-uart8-pins-default {
pinctrl-single,pins = <
J721S2_IOPAD(0x040, PIN_INPUT, 14) /* (AC28) MCASP0_AXR0.UART8_CTSn */
@@ -229,10 +242,11 @@
>;
};
+ /*更改I2C4 复用的引脚*/
main_i2c4_pins_default: main-i2c4-pins-default {
pinctrl-single,pins = <
- J721S2_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AD25) I2C4_SCL */
- J721S2_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AF28) I2C4_SDA */
+ J721S2_IOPAD(0x084, PIN_INPUT, 13) /* (AA28) MCASP0_AXR5.I2C4_SCL */
+ J721S2_IOPAD(0x010, PIN_INPUT, 8) /* (AF28) MCAN13_RX.I2C4_SDA */
>;
};
@@ -310,6 +324,12 @@
};
};
+&main_gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&test_key_pins_default>;
+};
+
+
&main_gpio2 {
status = "disabled";
};
diff --git a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
old mode 100644
new mode 100755
index 6f21385..d0d49d3
--- a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
+++ b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
@@ -25,6 +25,13 @@
#include <asm-generic/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+
+int gpio_test_init(void);
+
+
#define MAX_REGS_BANKS 5
#define MAX_INT_PER_BANK 32
@@ -64,6 +71,38 @@ struct davinci_gpio_controller {
int irqs[MAX_INT_PER_BANK];
};
+static irqreturn_t test_irq(int irq, void *data)
+{
+ pr_info("%s: irq %d, val=%d\n", __func__, irq,
+ gpio_get_value(432));
+ return IRQ_HANDLED;
+}
+
+int gpio_test_init(void)
+{
+ struct device_node *np;
+ int irq;
+ int ret = 0;
+
+ printk("%s %s %d.\n", __FILE__, __func__, __LINE__);
+
+ np = of_find_node_by_name(NULL, "gpio_test");
+
+ if (np) {
+ pr_info("Initializing gpio test\n");
+ irq = irq_of_parse_and_map(np, 0);
+ printk("irq number is %d\n", irq);
+ ret = request_irq(irq, test_irq, //IRQF_TRIGGER_RISING,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "key-gpio", NULL);
+ if (ret)
+ pr_err("request_irq returns %d\n", ret);
+ }
+
+ return ret;
+}
+
+
static inline u32 __gpio_mask(unsigned gpio)
{
return 1 << (gpio % 32);
@@ -273,6 +312,10 @@ static int davinci_gpio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (!strcmp("600000.gpio", pdev->name)) {
+ gpio_test_init();
+ }
+
return 0;
}
后面我们猜测会不会是MCU相关部分导致中断无法响应。我们采取了如下操作:
1、屏蔽了MCU相关代码对GPIO0_5(AD25)的使用。(中断函数还是无法响应)
2、我们在启动过程中,不加载任何MCU相关的固件。(中断函数还是无法响应)
注:我们在TDA4VM上面进行了同样的验证,同样的代码逻辑,发现在TDA4VM上面,GPIO中断可以正常响应。