GPIO IRQ for arm-linux

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/delay.h>
//#include <unistd.h>      
#define IRQ_GPIO            145    
#define IRQ_TEST        "IRQTEST"
#define DEVNAME        "GPIOIRQDEV"

#define CONFIG_DISABLE_IN_HANDLER

unsigned short int gpio_irq = 0;
//static unsigned long flags = 0;
unsigned long irqflags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
int irq_index = 0;
static struct task_struct *gpio_irq_kthread = NULL;

static irqreturn_t gpio_isr(int irq, void *data)
{
    unsigned long flags = 0;
    local_irq_save(flags);
    printk("gpio_isr triggered\n");
    irq_index = 1;
#ifdef CONFIG_DISABLE_IN_HANDLER
    disable_irq_nosync(gpio_irq);
#endif
    local_irq_restore(flags);
    return IRQ_HANDLED;
   
}
static int thread_gpio_irq_func(void *data)   
{
    while(!kthread_should_stop()) {
        if(irq_index == 1){
#ifdef CONFIG_DISABLE_IN_HANDLER
            printk("irq_index = %d enable_irq in kthread\n",irq_index);
            enable_irq(gpio_irq);
#else
            disable_irq_nosync(gpio_irq);
            printk("irq_index = %d disable_irq_nosync in kthread\n",irq_index);
#endif
            irq_index = 2;
        }else {
#ifdef CONFIG_DISABLE_IN_HANDLER
            printk("irq_index = %d irq already enabled\n",irq_index);
#else
            if(irq_index == 2){
                enable_irq(gpio_irq);
                irq_index = 0;
                printk("irq_index = %d enable_irq in kthread\n",irq_index);
            }
#endif
            msleep(300);
        }
    }
    return 0;
}

int __init gpio_irq_init(void)
{
    int ret;
    ret = gpio_request(IRQ_GPIO,IRQ_TEST);
    if (ret) {
        printk("IRQ_GPIO!\n");
        return ret;
    }
    ret = gpio_direction_input(IRQ_GPIO);
    if (ret) {
        printk("gpio_direction_input failed!\n");
        return ret;
    }
    gpio_irq = gpio_to_irq(IRQ_GPIO);
    if (gpio_irq < 0) {
        printk("gpio_to_irq FAILED!\n");
        return -1;
    }
    irqflags &= IRQF_TRIGGER_MASK;
    ret = request_irq(gpio_irq, gpio_isr, irqflags, IRQ_TEST, DEVNAME);
    if (ret < 0)
        return -1;
 
    ret = enable_irq_wake(gpio_irq);
    if (ret < 0){
        printk("enable_irq_wake failed\n");
        return -1;
    }
   gpio_irq_kthread = kthread_run(thread_gpio_irq_func,NULL,"thread-gpio-irq");
   if (!gpio_irq_kthread) {
    printk("kthread_run fail\n");
    return -ECHILD;
   }
    printk("Version 1.2\n");
    return ret;
}

void __exit gpio_irq_exit(void)
{
    if (gpio_irq_kthread) {
        printk("kthread_stop\n");
        kthread_stop(gpio_irq_kthread);
        gpio_irq_kthread = NULL;
    }
    disable_irq(gpio_irq);
    free_irq(gpio_irq, DEVNAME);
    gpio_free(IRQ_GPIO);
}

module_init(gpio_irq_init);
module_exit(gpio_irq_exit);

MODULE_LICENSE("GPL");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值