#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#define WORK_QUEUE "events"
//本代码是中断加work queue方式处理中断下文机制
struct work_struct work;
static void work_queue(struct work_struct* work)
{
printk("work_queue data:%ld\n",work->data);
return;
}
//中断处理函数,按下按钮直接执行这个函数,上半部函数
static irqreturn_t key_irq_handler(int irq, void *dev_id)
{
printk("key_irq_handler,irq:%d,dev_id:%p\n",irq,dev_id);
schedule_work(&work);
return IRQ_HANDLED;
}
static int key_probe(struct platform_device *pdev)
{
int err;
struct resource *res;
//获取中断资源
res = platform_get_resource(pdev, IORESOURCE_IRQ,0);
if(!res){
printk("fail to platform_get_resource\n");
return -ENODEV;
}
printk("IRQ :%d\n",res->start);
printk("Name :%s\n",res->name);
printk("Flags:%#x\n",(unsigned int)res->flags);//0x408,控制电平的只要8就行
//触发中断,动态初始化workqueue
INIT_WORK(&work, work_queue);
//请求中断,会自动释放资源
err = devm_request_irq(&pdev->dev,
res->start,
key_irq_handler,
res->flags & IRQF_TRIGGER_MASK,
res->name,
NULL);
if(err){
printk("fail to devm_request_irq\n");
return err;
}
return 0;
}
static int key_remove(struct platform_device *pdev)
{
return 0;
}
static const struct of_device_id key_of_match[] = {
{.compatible = "fs4412-key"},
{/*Sentinel*/}
};
static struct platform_driver key_driver = {
.probe = key_probe,
.remove = key_remove,
.driver = {
.name = "fs4412-key",
.owner = THIS_MODULE,
.of_match_table = key_of_match,
},
};
//注册driver以及模块初始化和退出都是用这个宏替代了
module_platform_driver(key_driver);
MODULE_LICENSE("GPL v2");
中断下文之work-queue机制
最新推荐文章于 2024-07-29 15:08:35 发布