【发布时间】:2021-09-14 13:32:46
【问题描述】:
上下文
我正在使用 i.MX6 (IMXYULL) 应用处理器,并且想通过软件了解何时按下了关机按钮:
幸运的是,IMX6ULL 参考手册解释说这应该是可能的:
第 10.5 节:ONOFF 按钮
该芯片支持使用按钮输入信号向 PMU 请求主 SoC 电源状态更改(即开启或关闭)。 SNVS_LP 内部的 ONOFF 逻辑允许直接连接到 PMIC 或其他稳压器设备。该逻辑采用按钮输入信号,然后输出
pmic_en_b和set_pwr_off_irq信号。 [...] 该逻辑有两种不同的操作模式(哑模式和智能模式)。 哑 PMIC 模式使用pmic_en_b发出一个电平信号,用于开启和关闭。哑 pmic 模式有许多不同的配置选项,包括(去抖动、关闭到开启时间和最大超时)。
(也可在第 18 页以精简形式 here 提供)
尝试
因此,我构建了一个非常简单的内核模块来尝试捕获这个中断:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/interrupt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Doe <j.doe@acme.inc>");
// Forward declaration
irqreturn_t irq_handler (int, void *);
// Number of interrupt to capture
#define INTERRUPT_NO 36
static int __init pwr_ctl_init (void)
{
pr_err("init()\n");
return request_irq(INTERRUPT_NO, irq_handler, IRQF_SHARED, "onoff-button",
(void *)irq_handler);
}
static void __exit pwr_ctl_exit (void)
{
pr_err("exit()\n");
free_irq(INTERRUPT_NO, NULL);
}
irqreturn_t irq_handler (int irq, void *dev_irq)
{
pr_err("interrupt!\n");
return IRQ_HANDLED;
}
module_init(pwr_ctl_init);
module_exit(pwr_ctl_exit);
问题
但是,我找不到有关中断编号的任何信息。在互联网上搜索时,我得到的只是一篇 NXP 论坛帖子:
提示应该是36。但是,我发现在我的平台上并非如此。当我检查/proc/interrupts 36 已经被20b4000.ethernet 占用。因为应用手册中也提到它是由SNVS低功耗系统生成的,所以我查看了device-tree,发现如下信息:
snvs_poweroff: snvs-poweroff {
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
value = <0x60>;
mask = <0x60>;
status = "disabled";
};
snvs_pwrkey: snvs-powerkey {
compatible = "fsl,sec-v4.0-pwrkey";
regmap = <&snvs>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
linux,keycode = <KEY_POWER>;
wakeup-source;
status = "disabled";
};
此信息似乎有助于了解 SNVS 是中断控制器,但不知道如何捕获此 set_pwr_off_irq 信号。
结论
- 如何捕获据称由 SNVS 生成的 ON/OFF 中断?
- 如何确定设备树中的中断编号(如果适用)
- 我是否对 ONOFF 功能的工作方式有误解?是否可以从内核模块中捕获它?
编辑
此编辑回答了一些用户问题,然后进入了关于我发现的问题的新信息:
用户问题
-
处理器:处理器是
NXP i.MX 6UltraLite / 6ULL / 6ULZARM Cortex A7。
新信息
-
SNVS 驱动程序:使用我的构建系统内核配置,我已经修改并验证了
snvs_pwrkey驱动程序(请参阅here)已启用。我的修改包括在中断例程中添加一个 singlekprint语句以查看按钮是否触发它。这不起作用 - 我已尝试将驱动程序更新到较新的版本,该版本声称支持较新的 i.MX6 处理器。这也不起作用
- 我已尝试将驱动程序加载为内核模块,以便于调试。这是不可能,因为内核配置需要启用它,我无法将其从静态构建到内核中删除。
【问题讨论】:
-
您是否检查过您的board dts 文件中是否启用了
snvs_pwrkey节点?snvs_pwrkey代码中显示的节点已禁用(尝试通过在 dts 中添加&snvs_pwrkey{ status = "okay"; };来启用它)。假设这是唯一的问题,一旦你正确设置它,你可以像 snvs_pwrkey.c 驱动程序一样捕获中断,如果你想在内核空间中执行它。如果您想从用户空间捕获它,snvs_pwrkey.c 已经通过在输入子系统中公开它来为您完成它,因此您可以像从 /dev/input/ 或任何映射到的任何输入一样访问它。跨度> -
@dhanushka 是的,它已启用。我觉得我已经检查了三次。默认是
disabled,没错。但我已经尝试设置status = "okay";并完全删除status行。没什么可悲的。快把我逼疯了!
标签: linux linux-kernel kernel-module device-tree imx6