您的位置:首页 > 运维架构 > Linux

linux设备树之外部中断key

2017-04-28 20:38 381 查看

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>

//--------------------------------------------------------------------------------
// 查看 exynos4412-origen.dts
// --> #include "exynos4412.dtsi"
// 查看 exynos4412.dtsi
// --> #include "exynos4x12.dtsi"
// 查看 exynos4x12.dtsi
// -->#include "exynos4.dtsi"
//	  #include "exynos4x12-pinctrl.dtsi"
// 查看 exynos4x12-pinctrl.dtsi
/* -->  gpx1: gpx1 {
gpio-controller;
#gpio-cells = <2>;

interrupt-controller;
interrupt-parent = <&gic>;
interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
#interrupt-cells = <2>;
};
我们看到gpx1的中断控制父节点是gic(generic interrupt controller)
查看 exynos4.dtsi --> #include "skeleton.dtsi"
目标出现:------------------>
gic: interrupt-controller@10490000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x10490000 0x1000>, <0x10480000 0x100>;
};
查阅exynos4412手册-->
0x1048_0000 GIC_controller
0x1049_0000 GIC_distributor
--------------------------------------------------------------------------------
*/
// 26 58 – EINT[10] External Interrupt
// 25 57 – EINT[9]  External Interrupt
/*DTS
mykey{
compatible = "key2";
interrupt-parent = <&gpx1>; // 父节点gpx1
interrupts = <1 2>, <2 2>; // 锁定25, 26号中断<0 25 0>,<0 26 0>
};
*/
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("a simple driver example!");

int count;
long last;
struct resource *res2;
struct resource *res3;

struct timer_list key2_timer;
struct timer_list key3_timer;
void key2server_func(unsigned long arg)
{
printk("key2 pressed: %d!\n", count);
}
void key3server_func(unsigned long arg)
{
printk("key3 pressed: %d!\n", count);
}
irqreturn_t key2_int_handler(int n, void *dev)
{
// 定时器去抖
mod_timer(&key2_timer, jiffies+50);

return IRQ_HANDLED;
}

irqreturn_t key3_int_handler(int n, void *dev)
{
// 定时器去抖
mod_timer(&key3_timer, jiffies+50);

return IRQ_HANDLED;
}

int key_probe(struct platform_device *pdev)
{
int ret = 0;
printk("key probe !\n");

setup_timer(&key2_timer, key2server_func, 0);
setup_timer(&key3_timer, key3server_func, 0);

add_timer(&key2_timer);
add_timer(&key3_timer);
// 解析中断号
res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
printk("irqnum: %#x\n", res2->start);
res3 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
printk("irqnum: %#x\n", res3->start);
request_irq(res2->start, key2_int_handler, (res2->flags&IRQF_TRIGGER_MASK) | IRQF_DISABLED, "key2", NULL);
request_irq(res3->start, key3_int_handler, (res3->flags&IRQF_TRIGGER_MASK) | IRQF_DISABLED, "key3", NULL);

return ret;
}

int key_remove(struct platform_device *pdev)
{

printk("key module release\n");
free_irq(res2->start, NULL);
free_irq(res3->start, NULL);
return 0;
}

#ifdef CONFIG_OF

struct of_device_id key_table[] = {
{ .compatible = "key" },
{ }
};

#endif

struct platform_driver key_driver = {
.probe = key_probe,
.remove = key_remove,
.driver = {
.name = "key",
.of_match_table = of_match_ptr(key_table)
}
};

static int key_init(void)
{
printk("module install\n");

//add into platform bus
platform_driver_register(&key_driver);

return 0;
}

static void key_exit(void)
{
printk("module release\n");
//del from platform bus
platform_driver_unregister(&key_driver);
}

module_init(key_init);
module_exit(key_exit);

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息