This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM625:request_IRQ 返回-22

Guru**** 2540720 points
Other Parts Discussed in Thread: AM625, SK-AM62

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1262930/am625-request_irq-return--22

器件型号:AM625
主题中讨论的其他器件: SK-AM62

设备:AM625 GP

安装程序: ti-processor-sdk-linux-am62xx-evm-09.00.00.03-Linux-x86-Install.bin—6664936 K

SD 卡图像: tisdk-Debian-bookworm-am62xx-evm.wic.xz—1955030 K

我想驱动 HID I2C 触摸屏、使用 MAIN_i2c1、时钟频率为400kHz、使用 GPIO1_31作为 int 引脚。

Request_IRQ 返回-22、并且我看到以下错误消息:

[  3.930778] genirq: Setting trigger mode 8 for irq 384 failed (gpio_irq_type+0x0/0x54)

我想在 Request_IRQ 中使用 IRQF_TRIGGER_LOW。

(代码 URL: line971-IRQ_SET_TYPEline318-GPIO_IRQ_TYPE)

我发现 kernel/IRQ/manage.c 中的_IRQ_SET_TRIGGER 将调用 drivers/GPIO/davinca.c 中的 GPIO_IRQ_type、而 GPIO_IRQ_type 将返回-22。

我尝试注释掉以下代码行(kernel/irq/manage.c-line971):

ret = chip->irq_set_type(&desc->irq_data, flags);

触摸屏将成功探测、但中断无法正常工作。

INT 引脚在上电后为高电平、首次触摸触摸触摸触摸屏后将持续为低电平。

1.IRQ 384我多次触摸触摸触摸触摸触摸屏后、触发器的时间始终为0。

2.int 引脚注册为 GPIO-397

请帮我完成任务。

谢谢。

安德鲁

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Andrew、您好!

    触摸屏驱动程序是已在内核中、还是属于树外驱动程序?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bin Liu:

    感谢您的答复。

    下面是我使用的驱动程序.c 文件片段和 DTS 触摸屏节点。

    文件中的 probe 函数。

    (define:CONFIG_OF)
    未定义:CONFIG_HAS_EARLYSUSPEND、_FALLING_EDGE_IRQ、_Board_INFO_REG)

    static int __devinit egalax_i2c_probe(struct i2c_client *client, const struct i2c_device_id *idp)
    {
    	int ret;
    #ifdef CONFIG_OF	
    	struct device_node *devnode;
    #endif //#ifdef CONFIG_OF
    
    #ifdef _FALLING_EDGE_IRQ
    	u8 x_buf[MAX_I2C_LEN]={0};
    #endif
    
    	EGALAX_DBG(DBG_MODULE, " Start probe\n");
    
    	p_egalax_i2c_dev = (struct _egalax_i2c *)kzalloc(sizeof(struct _egalax_i2c), GFP_KERNEL);
    	if (!p_egalax_i2c_dev) 
    	{
    		EGALAX_DBG(DBG_MODULE, " Request memory failed\n");
    		ret = -ENOMEM;
    		goto fail1;
    	}
    
    #ifdef CONFIG_OF
    	devnode = client->dev.of_node;
    	if(devnode) //if use the device tree config
    	{
    		p_egalax_i2c_dev->interrupt_gpio = of_get_named_gpio(devnode, "int-gpios", 0);
    		client->irq = gpio_to_irq(p_egalax_i2c_dev->interrupt_gpio);
    	}
    #else
    	#ifdef _BOARD_INFO_REG
    	p_egalax_i2c_dev->interrupt_gpio = GPIO_INT;
    	client->irq = GPIO_IRQ;
    	#else
    	p_egalax_i2c_dev->interrupt_gpio = irq_to_gpio(client->irq);
    	#endif
    	
    #endif //#ifdef CONFIG_OF
    
    	if( !gpio_is_valid(p_egalax_i2c_dev->interrupt_gpio) )
    	{
    		ret = -ENODEV;
    		goto fail1;
    	}
    	ret = gpio_request(p_egalax_i2c_dev->interrupt_gpio, "Touch IRQ");
    	if(ret<0 && ret!=-EBUSY)
    	{
    		EGALAX_DBG(DBG_MODULE, " gpio_request[%d] failed: %d\n", p_egalax_i2c_dev->interrupt_gpio, ret);
    		goto fail1;
    	}
    	gpio_direction_input(p_egalax_i2c_dev->interrupt_gpio);
    
    	input_dev = allocate_Input_Dev();
    	if(input_dev==NULL)
    	{
    		EGALAX_DBG(DBG_MODULE, " allocate_Input_Dev failed\n");
    		ret = -EINVAL; 
    		goto fail2;
    	}
    	EGALAX_DBG(DBG_MODULE, " Register input device done\n");
    
    	input_dev_pen = allocate_Input_Dev_Pen();
    	if(input_dev_pen==NULL)
    	{
    		EGALAX_DBG(DBG_MODULE, " allocate_Input_Dev_Pen failed\n");
    		ret = -EINVAL;
    		goto fail3;
    	}
    	EGALAX_DBG(DBG_MODULE, " Register input device pen done\n");
    
    	p_egalax_i2c_dev->client = client;
    	mutex_init(&p_egalax_i2c_dev->mutex_wq);
    
    	p_egalax_i2c_dev->ktouch_wq = create_singlethread_workqueue("egalax_touch_wq");
    	INIT_WORK(&p_egalax_i2c_dev->work_irq, egalax_i2c_wq_irq);
    
    	i2c_set_clientdata(client, p_egalax_i2c_dev);
    
    	if( gpio_get_value(p_egalax_i2c_dev->interrupt_gpio) )
    		p_egalax_i2c_dev->skip_packet = 0;
    	else
    		p_egalax_i2c_dev->skip_packet = 1;
    
    	p_egalax_i2c_dev->work_state = MODE_WORKING;
    
    #ifdef _FALLING_EDGE_IRQ
    	ret = request_irq(client->irq, egalax_i2c_interrupt, IRQF_TRIGGER_FALLING, client->name, p_egalax_i2c_dev);
    #else
    	ret = request_irq(client->irq, egalax_i2c_interrupt, IRQF_TRIGGER_LOW, client->name, p_egalax_i2c_dev);
    #endif
    	if( ret ) 
    	{
    		EGALAX_DBG(DBG_MODULE, " Request irq(%d) failed\n", client->irq);
    		goto fail4;
    	}
    	EGALAX_DBG(DBG_MODULE, " Request irq(%d) gpio(%d) with result:%d\n", client->irq, p_egalax_i2c_dev->interrupt_gpio, ret);
    
    #ifdef _FALLING_EDGE_IRQ
    	queue_work(p_egalax_i2c_dev->ktouch_wq, &p_egalax_i2c_dev->work_irq);
    #endif
    
    #ifdef CONFIG_HAS_EARLYSUSPEND
    	egalax_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
    	egalax_early_suspend.suspend = egalax_i2c_early_suspend;
    	egalax_early_suspend.resume = egalax_i2c_early_resume;
    	register_early_suspend(&egalax_early_suspend);
    	EGALAX_DBG(DBG_MODULE, " Register early_suspend done\n");
    #endif
    
    	EGALAX_DBG(DBG_MODULE, " I2C probe done\n");
    	return 0;
    
    fail4:
    	i2c_set_clientdata(client, NULL);
    	destroy_workqueue(p_egalax_i2c_dev->ktouch_wq); 
    	free_irq(client->irq, p_egalax_i2c_dev);
    	input_unregister_device(input_dev_pen);
    	input_dev_pen = NULL;
    fail3:
    	input_unregister_device(input_dev);
    	input_dev = NULL;
    fail2:
    	gpio_free(p_egalax_i2c_dev->interrupt_gpio);
    fail1:
    	kfree(p_egalax_i2c_dev);
    	p_egalax_i2c_dev = NULL;
    
    	EGALAX_DBG(DBG_MODULE, " I2C probe failed\n");
    	return ret;
    }

    k3-am62x-sk-common.dtsi 中的触摸屏节点

    &main_i2c1 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_i2c1_pins_default>;
    // edit by AAEON Andrew start
    	clock-frequency = <400000>;
    
    	touchscreen1: egalax_i2c@2a {
    		compatible = "eeti,egalax_i2c";
    		reg = <0x2a>;
    		interrupt-parent = <&main_gpio1>;
    		interrupts = <31 8>;
    		int-gpios = <&main_gpio1 31 0>;
    		hid-descr-addr = <0x000f>;
    	};
    // edit by AAEON Andrew end
    };

    谢谢。

    安德鲁

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 TI:

    REt = request_IRQ (client->IRQ、egalax_i2c_interrupt、IRQF_TRIGGER_LOW、client->name、p_egalax_i2c_dev);  //ret = 0

    GPIO 1 31 :它是一个触摸中断引脚。  当 GPIO 1 31引脚为低时, 它不调用  egalax_i2c_interrupt 函数。  

    GPIO 1 31引脚对应于 GPIO 编号397。  我认为设备树设置正确。  我不知道为什么 在 GPIO 1 31引脚为低电平时不调用 IRQ 函数。

    您也可以在 AM625 GP 板上进行相同的实验。 请帮助解决此问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Albert:

    我 在内核源代码中没有找到 egalax_i2c_probe (),这似乎是来自一个脱机驱动程序。 请注意、 此论坛不支持定制的内核驱动程序。

    但我看到您的设备树使用 DT 属性名称"int-gpios"设置 GPIO、那么您的驱动程序应该使用内核 gpod 框架来管理此 GPIO 引脚、而不是直接使用内核 GPIO 函数。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 TI:

    我询问有关 IRQ 功能的问题。  这与触摸驱动器无关。  它不调用 IRQ 函数。  我想它取决于 GPIO 编号。

    (1) 如果我 在设备树中使用"int-gpios", 请告诉我如何设置。 (GPIO 1 31)。

    (2) 如果我在设备树中没有"int-gpios", 请告诉我如何设置。 (GPIO 1 31)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Andrew、您好!

    我正在做调试工作、将在几天后查看最新的帖子。 感谢您的耐心等待。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bin:

    我已经等了很长时间了。  有任何更新吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Albert:

    我需要回顾一下/proc/interrupts、但是将 R485接地将生成一个到主 GPIO1_23而不是到 I/O 扩展器的中断、pca953x_IRQ_handler ()将不会被调用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bin:

    我想解释一下这是一个例子。  我注册中断 IRQ 功能成功。
    当中断引脚为低电平时、它不会进入 IRQ 功能。
    您能解释一下为什么会这样吗?

    REt = devm_request_pthread_IRQ (&client->dev,client->IRQ,
    null、pca953x_irq_handler、
    IRQF_TRIGGER_LOW | IRQF_OneShot、
    dev_name (&client->dev)、chip);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Albert:

    中断引脚为低电平时,它不会输入 IRQ 功能。

    是不是让 R485接地? 这是为了向 AM625而不是 PCA953x 生成中断、因此不会调用 PCA953x 驱动程序中的中断处理程序。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bin:

    我想我应该和您一起讨论 devm_request_pthread_IRQ 函数。

    它是明确的定义.  当中断引脚为 低电平时,应调用 thread_fn (pca953x_IRQ_handler)。

    https://elixir.bootlin.com/linux/v6.1.33/source/kernel/irq/devres.c

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Albert:

    其定义明确。  当中断引脚为 低时,应调用 thread_fn (pca953x_IRQ_handler)。

    您能不能查看 PCA953x 数据表? 我认为它的中断引脚是 AM625的输出引脚。 将其驱动为低电平不会触发 pac953x_irq_handler ()函数。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bin:

    您可以参考我之前的说明。 触摸中断引脚为低电平但它没有调用 IRQ_Handle 函数。

    我的目的不是讨论 PCA953x 是否可以正常工作。 我使用 EETI 触控驱动程序,并使用中断引脚(低电平)
    以触发 IRQ 句柄。 TI AM62x 没有 EETI 源代码。
    如果我以本例(PCA953x)为例,您可以在 AM62x 板上重现此问题。

    如果你修复这个中断问题(PCA953x),我认为它也可以修复这个触摸驱动程序问题。
    请关注我的问题。 当 PCA953x 中断管脚为低电平时,为什么没有调用 pca953x_IRQ_handler 函数?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您需要查看 PCA953x 数据表- PCA953x 中断引脚是 AM62x 的输出引脚。 触摸其中断引脚将触发 AM62x GPIO 中断、但不会触发 PCA953x 的中断。 这是一个 PCA953x 输出引脚、其信号电平馈入 PCA953x 器件的可能性是多少???

    如果要实验 PCA953x 驱动程序中断处理程序、需要触碰它的任何输入 GPIO 引脚。 一个示例是使用其引脚21、该引脚连接到 SK-AM62上的跳线 J24。