如何解决捕获 i.MX6ULLinux 内核的断电中断 用户问题新信息
上下文
我使用的是 i.MX6 (IMXULL) 应用处理器,想在软件中知道何时按下了关机按钮:
幸运的是,IMX6ULL 参考手册解释说这应该是可能的:
第 10.5 节:ONOFF 按钮
该芯片支持使用按钮输入信号从 PMU 请求主 SoC 电源状态更改(即打开或关闭)。 SNVS_LP 内部的 ONOFF 逻辑允许直接连接到 PMIC 或其他电压调节器设备。该逻辑采用按钮输入信号,然后输出 pmic_en_b
和 set_pwr_off_irq
信号。 [...] 该逻辑有两种不同的操作模式(哑模式和智能模式)。
Dumb 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);
问题
但是,我找不到有关中断编号是多少的任何信息。在互联网上搜索时,我得到的只是这个恩智浦论坛帖子:
提示应该是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
信号。
结论
编辑
此编辑回答了一些用户问题,然后介绍了有关我发现的问题的新信息:
用户问题
-
处理器:处理器是
NXP i.MX 6UltraLite / 6ULL / 6ULZ
ARM Cortex A7。
新信息
-
SNVS 驱动程序:使用我的构建系统内核配置,我修改并验证了
snvs_pwrkey
驱动程序(请参阅 here)已启用。我的修改包括向中断例程添加一个 singlekprint
语句以查看按钮是否触发它。这不起作用 - 我已尝试将驱动程序更新到较新版本,该版本声称支持较新的 i.MX6 处理器。这也不起作用
- 我尝试将驱动程序作为内核模块加载,以便于调试。这是不可能,因为内核配置要求启用此功能,我无法将其从静态内置到内核中删除。
解决方法
答案相当虎头蛇尾。简而言之,有一个设备树覆盖禁用我对 snvs_pwrkey
的更改,即使我已启用它。找到并移除覆盖层后,驱动程序 (snvs_pwrkey.c
) 会按预期工作。
至于 IRQ 编号,事实证明电源按钮的 IRQ 是 45
,通过 Linux 解释。中断未配置为共享,因此无法加载我的内核模块。
如果您想捕获电源按钮切换事件,我建议修改驱动程序以添加一些输出,然后可能添加一个 udev
规则来捕获按钮按下。我会尽快用一个例子更新我的答案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。