imx6系列--将一个gpio设置为可唤醒系统的外部中断流程

来源:互联网 发布:hub网络 编辑:程序博客网 时间:2024/06/04 23:43

http://blog.csdn.net/vertor11/article/details/67634666 

一:总体步骤 
涉及文件: 
a. 设备树文件:正确配置gpio复用及引脚属性。 
b. 驱动模块文件:设置gpio中断相关操作。

二:实际操作 
1.修改设备树 
参考方法: 
http://blog.csdn.net/vertor11/article/details/67633652 
例如:将imx6ul的下图两个gpio设置为外部中断 
这里写图片描述
设备树配置示例:

   fsl,pins = <                MX6UL_PAD_LCD_HSYNC__GPIO3_IO02            0x000010B0                MX6UL_PAD_LCD_VSYNC__GPIO3_IO03            0x000010B0            >;
  • 1
  • 2
  • 3
  • 4

2.驱动修改 
参考方法: 
http://blog.csdn.net/jiangbo_wei/article/details/9852659 
http://www.wowotech.net/linux_kenrel/request_threaded_irq.html 
http://blog.csdn.net/njuitjf/article/details/21475405 
示例代码:

#include <linux/delay.h>#include <linux/if_arp.h>#include <linux/if_ether.h>#include <linux/interrupt.h>#include <linux/io.h>#include <linux/kernel.h>#include <linux/list.h>#include <linux/module.h>#include <linux/of.h>#include <linux/of_device.h>#include <linux/platform_device.h>#include <linux/gpio.h>#include <linux/irq.h>#include <linux/miscdevice.h>#include <linux/suspend.h>#include <linux/poll.h>/*GPIO3_2: (3-1)*32 + 2*/#define MCU_WAKEUP_PIN  66static int wakeup_mcu_irq = 0;/*中断服务函数*/static irqreturn_t mcu_irq_handler(int irq, void *dev){    printk ("## mcu wake up! \n");    /*其他模块的导出符号*/    set_bit(8, &tbox_wakesoure);    return IRQ_HANDLED;}static int wakesource_open(struct inode *inode, struct file *file){    return 0;}static int wakesource_release(struct inode *inode, struct file *file){    /*note: releasing the wdt in NOWAYOUT-mode does not stop it */    return 0;}static int wakesource_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){    if (!buf || count < 1)        return 0;    if (count > 4)        count = 4;    if (copy_to_user(buf, (void*)&tbox_wakesoure, count)) {        printk(KERN_ERR"wakesource_read copy_to_user failed.");        return -EFAULT;    }    return count;}static int wakesource_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){    tbox_wakesoure = 0;    return count;}static const struct file_operations wakesource_fops = {    .owner = THIS_MODULE,       .open = wakesource_open,    .release = wakesource_release,    .read = wakesource_read,    .write = wakesource_write,};static struct miscdevice wakesource_device = {    .minor = MISC_DYNAMIC_MINOR,        .name = "wakesource",    .fops = &wakesource_fops,};static int __init gpio_init(void){    int ret;    /*注册misc设备驱动*/    ret = misc_register(&wakesource_device);    if (ret != 0) {        printk(KERN_ERR "register wakesource_device miscdevice ret");        return ret;    }    /*判断该gpio号码是否有效*/    if (0 == gpio_is_valid(MCU_WAKEUP_PIN)) {        printk(KERN_ERR "mcu  gpio is invalid!\n");        goto error;    }     /*请求申请单个GPIO,并且配置其输入,输出*/    ret = gpio_request_one(MCU_WAKEUP_PIN, GPIOF_IN, "mcupin");    if (ret < 0) {        printk(KERN_ERR "Failed to request GPIO %d, ret %d\n",            MCU_WAKEUP_PIN, ret);        goto error;    }    /*GPIO映射到中断*/    wakeup_mcu_irq = gpio_to_irq(MCU_WAKEUP_PIN);    if (wakeup_mcu_irq < 0) {        ret = wakeup_mcu_irq;        printk("Unable to get irq number for GPIO %d, ret %d\n", MCU_WAKEUP_PIN, ret);        goto error;    }    /*设置中断属性*/    ret = request_threaded_irq(wakeup_mcu_irq, mcu_irq_handler, NULL,                     IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING|IRQF_NO_SUSPEND | IRQF_ONESHOT,                     "mcu", NULL);    if (ret < 0) {        printk(KERN_ERR "failed to register mcu irq %d!\n", wakeup_mcu_irq);        goto freeirq;    }    /*将irq具有唤醒系统的功能*/    ret = enable_irq_wake(wakeup_mcu_irq);    if(ret) {        printk(KERN_ERR "failed to set mcu gpio irq %d wake up!\n",            wakeup_mcu_irq);        goto freeirq;    }    printk("4g  mcu wakeup driver probe sucsecc!\n");    return 0;freeirq:    free_irq(wakeup_mcu_irq, NULL);error:    misc_deregister(&wakesource_device);    return ret;}module_init(gpio_init);static void __exit gpio_exit(void){    disable_irq_wake(wakeup_mcu_irq);    free_irq(wakeup_mcu_irq, NULL);    if (gpio_is_valid(MCU_WAKEUP_PIN))        gpio_free(MCU_WAKEUP_PIN);    misc_deregister(&wakesource_device);}module_exit(gpio_exit);MODULE_AUTHOR("");MODULE_LICENSE("GPL v2");MODULE_DESCRIPTION("4g wakeup driver");