1. 程序说明
将GPIO口设为外部中断模式,当有外部中断触发时,进入中断处理函数中
中断处理函数中使用了工作队列
工作队列的处理函数中使用了wake_lock
2.
2.1工作队列的使用
struct work_struct wakeup_frome1408_wq
;
INIT_WORK(&wakeup_frome1408_wq,(void (*)(void*))wakeup_frome1408_wq_func);
//工作队列
schedule_work(&wakeup_frome1408_wq);
void wakeup_frome1408_wq_func(struct work_struct *work)
{
wake_lock_timeout(&wakeup6572_wlock, msecs_to_jiffies(10*1000));
}
工作队列的作用是延后处理中断
2.2 wake_lock
-
void wake_lock_init(struct wake_lock *lock, int type, const char *name);
-
void wake_lock_destroy(struct wake_lock *lock);
-
void wake_lock(struct wake_lock *lock);
-
void wake_lock_timeout(struct wake_lock *lock, long timeout); //在timeout时间内系统无法休眠
-
void wake_unlock(struct wake_lock *lock);
static struct wake_lock wakeup6572_wlock
;
wake_lock_init(&wakeup6572_wlock,WAKE_LOCK_SUSPEND,"wakeup6572_wlock
"); //wakelock
wake_lock_timeout(&wakeup6572_wlock, msecs_to_jiffies(10*1000));
wakelock在android的电源管理系统中扮演一个核心的角色,wakelock是一种锁的机制, 只要有task拿着这个锁, 系统就无法进入休眠
3.代码如下
-
#include <linux/init.h>
-
#include <linux/module.h>
-
#include <linux/device.h>
-
#include <linux/ioport.h>
-
#include <linux/errno.h>
-
#include <linux/spi/spi.h>
-
#include <linux/workqueue.h>
-
#include <linux/dma-mapping.h>
-
#include <linux/platform_device.h>
-
#include <linux/interrupt.h>
-
#include <linux/irqreturn.h>
-
#include <linux/types.h>
-
#include <linux/delay.h>
-
#include <linux/clk.h>
-
#include <linux/err.h>
-
#include <linux/io.h>
-
#include <linux/spinlock.h>
-
#include <linux/sched.h>
-
#include <linux/wakelock.h>
-
#include <mach/irqs.h>
-
#include <mach/mt_gpio.h>
-
#include <mach/eint.h>
-
-
-
#define GPIO_1408_WAKEUP_6572 GPIO145 //1408 pending interrupt
-
-
#define WAKEUP_FROM1408_NAME "wakeup_from1408"
-
-
#define WAKEUP_FROM1408_EINT_NUM 8
-
-
struct work_struct wakeup_frome1408_wq;
-
-
static struct wake_lock wakeup6572_wlock;
-
-
void wakeup_frome1408_wq_func(struct work_struct *work)
-
{
-
printk(KERN_NOTICE "cong: %s:%s[%d]: \n", __FILE__,__FUNCTION__, __LINE__);
-
wake_lock_timeout(&wakeup6572_wlock, msecs_to_jiffies(10*1000));
-
}
-
-
static void wakeup_from1408_irq_handler(void)
-
{
-
schedule_work(&wakeup_frome1408_wq);
-
return ;
-
}
-
-
static int __init mt6261_init(void)
-
{
-
int rc;
-
struct mt6261_data_t * pmt6261;
-
pmt6261 = devm_kzalloc(&pdev->dev, sizeof(*pmt6261), GFP_KERNEL); //初始化私有数据
-
if (!pmt6261) {
-
dev_err(&pdev->dev, "failed to allocate mt6261\n");
-
return -ENOMEM;
-
}
-
-
//1. 将GPIO145设为MOD3即INT8
-
mt_set_gpio_mode(GPIO_1408_WAKEUP_6572, GPIO_MODE_03); //MOD3
-
mt_set_gpio_dir(GPIO_1408_WAKEUP_6572, GPIO_DIR_IN); //输入状态
-
mt_set_gpio_pull_enable(GPIO_1408_WAKEUP_6572, GPIO_PULL_DISABLE); //禁止上拉,输入一般是需要上拉的,但这儿不需要
-
mt_eint_set_hw_debounce(WAKEUP_FROM1408_EINT_NUM, 1); //延时吧?
-
mt_eint_registration(WAKEUP_FROM1408_EINT_NUM, EINTF_TRIGGER_RISING, wakeup_from1408_irq_handler, true); //注册中断
-
mt_eint_unmask(WAKEUP_FROM1408_EINT_NUM);
-
-
INIT_WORK(&wakeup_frome1408_wq,(void (*)(void*))wakeup_frome1408_wq_func); //工作队列
-
-
wake_lock_init(&wakeup6572_wlock,WAKE_LOCK_SUSPEND,"wakeup6572_wlock"); //wakelock
-
-
platform_set_drvdata(pdev,pmt6261); //设置私有数据
-
-
return 0;
-
fail:
-
return rc;
-
}
-
-
static void __init mt6261_exit(void)
-
{
-
platform_driver_unregister(&mt6261_driver);
-
}
-
-
module_init(mt6261_init);
-
module_exit(mt6261_exit);
-
-
MODULE_DESCRIPTION("MT6261 Controller Driver");
-
MODULE_AUTHOR("wangcong");
-
MODULE_LICENSE("GPL");
阅读(2218) | 评论(0) | 转发(0) |