13915426184 发表于 2017-9-19 14:07:56

hi3516a 按键驱动注册中断失败

驱动代码如下

irqreturn_t key_intter(int irq, void *dev_id)
{
    //1. 检测是否发生了按键中断 这里可以暂时不做,因为这里没有使用共享中断
      
    //2. 清除已经发生的按键中断 这个是指硬件内部处理,按键CPU内部不需要做处理
         //比如如果是网卡驱动 就要处理
      
    //3. 打印按键值
      
    printk(KERN_WARNING"key down!\n");
      
    return 0;
}

void key_hw_init(void) //按键硬件初始化部分
{   
   int ret;
   writel(0x00000000, IO_ADDRESS(0x200f0104));//tobe gpio11_7

   ret=readl(IO_ADDRESS(0x201f0400)); //direction
   ret=ret&0x7f; //direction is in
   writel(ret, IO_ADDRESS(0x201f0400));

   ret=readl(IO_ADDRESS(0x201f0404)); //interrupt type level trigger
   ret=ret|0x80; //
   writel(ret, IO_ADDRESS(0x201f0404));

   ret=readl(IO_ADDRESS(0x201f040c)); //low level trigger
   ret=ret&0x7f; //
   writel(ret, IO_ADDRESS(0x201f040c));




   writel(0x80, IO_ADDRESS(0x201f041c)); //clean interrupt

   ret=readl(IO_ADDRESS(0x201f0410)); //interrupt mask
   ret=ret|0x80; //
   writel(ret, IO_ADDRESS(0x201f0410));
    printk(KERN_WARNING"init ...!\n");
    //第二步: 按键中断部分相应处理 注册中断 注销等等
}

int key_open(struct inode *node, struct file *filp)
{
    printk(KERN_WARNING"open ...!\n");
      
    return 0;
}

struct file_operations key_fops =   
{
    .open = key_open,
};

struct miscdevice* key=NULL;

static int key_init1(void)
{
   int err;

   
   

        key = kzalloc(sizeof(struct miscdevice), GFP_KERNEL);
        if (!key)
                return -ENOMEM;

        key->minor = MISC_DYNAMIC_MINOR;
        key->name= "key";
        key->fops= &key_fops;

        err = misc_register(key);
    //按键初始化 硬件初始化部分一般可一放在模块初始化部分或者open函数中 这里放在模块初始化部分
    key_hw_init();
      
    //由高电平变为低电平产生中断 IRQF_TRIGGER_FALLING
      
      printk("matt-2\n");
    //if( (err = request_irq(112,key_intter, IRQF_SHARED|IRQF_TRIGGER_LOW, "key", key)) < 0 )//注册中断处理程序 5个参数
   if( (err = request_irq(112,key_intter, IRQF_TRIGGER_LOW, "key", key)) < 0 )
    //if( (err = request_irq(112,key_intter, IRQF_SHARED, "key", key)) < 0 )
    {
         printk(KERN_WARNING"err = %d\n", err);
         goto irq_err;
    }
      
    return 0;
      
irq_err:
      misc_deregister(key);   
    return -1;
}

static void key_exit1(void)
{
    free_irq(112, 0);//注销中断 这里irqnumber参数暂时用一个变量来表示(中断号)
      
    misc_deregister(key);//注销一个混杂设备驱动
      
    printk(KERN_WARNING"key up!");
}


module_init(key_init1);
module_exit(key_exit1);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("key driver");


运行insmod以后报错:
/usr # insmod key.ko
init ...!
matt-2
err = -22
insmod: can't insert 'key.ko': Operation not permitted
/usr # cat /proc/interrupts
         CPU0
35:   434786       GICtimer
39:          0       GICRTC Alarm
40:       1525       GICuart-pl011
51:          0       GIChi_mci
52:          0       GIChi_mci
53:      478       GICehci_hcd:usb1
54:          1       GICohci_hcd:usb2
57:      166       GICgmac0
65:          0       GICVOU Interrupt
66:          0       GICmipi int
67:          0       GICISP, VIU
68:          0       GICVPSS0
69:          1       GICtde_osr_isr
70:          0       GICVGS0
71:          0       GICAIO Interrupt
72:          0       GICVEDU_0
73:          0       GICJPEGU_0
75:          0       GICHEVCU_0
76:          0       GICVDA
77:          0       GICIVE
88:          0       GICRTC Temperature
Err:          0
/usr # fbset -s
fbset: can't open '/dev/fb0': Operation not permitted
/usr # ifconfig eth0 192.168.1.133
/usr # ls
4g2wifi.sh      hi_gpio.ko      ntp_service.shsbin
bin             key.ko          ppp             start.sh
gpio.ko         lib             rtc_test      testgpio
/usr # rm -rf key.ko
/usr # ls
4g2wifi.sh      hi_gpio.ko      ntp_service.shsbin
bin             key.ko          ppp             start.sh
gpio.ko         lib             rtc_test      testgpio
/usr # chmod 777 key.ko
/usr # insmod key.ko
init ...!
matt-2
setting trigger mode 8 for irq 44 failed (gic_set_type+0x0/0xc8)
err = -22
insmod: can't insert 'key.ko': Operation not permitted
/usr # rm -rf key.ko
/usr # ls
4g2wifi.sh      hi_gpio.ko      ntp_service.shsbin
bin             key.ko          ppp             start.sh
gpio.ko         lib             rtc_test      testgpio
/usr # chmod 777 key.ko
/usr # insmod key.ko
init ...!
matt-2
err = -22
insmod: can't insert 'key.ko': Operation not permitted
/usr # rm -rf key.ko
/usr # chmod 777 key.ko
/usr # insmod key.ko
init ...!
matt-2
err = -22
insmod: can't insert 'key.ko': Operation not permitted
/usr # rm -rf key.ko
/usr # chmod 777 key.ko
/usr # insmod key.ko
init ...!
matt-2
err = -22
insmod: can't insert 'key.ko': Operation not permitted
查看中断也没有注册上,请问哪位大侠知道原因指点一二
/usr # cat /proc/interrupts
         CPU0
35:    1980675       GICtimer
39:          0       GICRTC Alarm
40:       2147       GICuart-pl011
51:          0       GIChi_mci
52:          0       GIChi_mci
53:       2178       GICehci_hcd:usb1
54:          1       GICohci_hcd:usb2
57:      670       GICgmac0
65:          0       GICVOU Interrupt
66:          0       GICmipi int
67:          0       GICISP, VIU
68:          0       GICVPSS0
69:          1       GICtde_osr_isr
70:          0       GICVGS0
71:          0       GICAIO Interrupt
72:          0       GICVEDU_0
73:          0       GICJPEGU_0
75:          0       GICHEVCU_0
76:          0       GICVDA
77:          0       GICIVE
88:          0       GICRTC Temperature

hero 发表于 2017-9-19 16:45:12

:):):):):)

_nucong 发表于 2017-9-19 17:04:49

驱动不挂在总线上去吗?不管是i2c还是虚拟platform, 可以参照switch_gpio.c的方式做吧!(软)

R4IN 发表于 2017-9-19 17:18:20

中断号不对

13915426184 发表于 2017-9-20 10:23:31

R4IN 发表于 2017-9-19 17:18
中断号不对

是的,我看了spec,gpio11的中断号是85,还是就是模式是share才行

13915426184 发表于 2017-9-20 10:24:23

结贴:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h> /* for struct miscdevice*/
#include <linux/interrupt.h>
#include <linux/fs.h> /* for iormap */
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/hidraw.h>
#include <linux/ioctl.h>
#include <linux/delay.h>

#include <linux/ioctl.h>
#define GPNCON 0x7F008830

irqreturn_t key_int(int irq, void *dev_id)
{
        //1. 检测是否发生了按键中断 这里可以暂时不做,因为这里没有使用共享中断

        //2. 清除已经发生的按键中断 这个是指硬件内部处理,按键CPU内部不需要做处理
        //比如如果是网卡驱动 就要处理

        //3. 打印按键值

        printk(KERN_WARNING"key down!\n");

        return 0;
}

void key_hw_init(void) //按键硬件初始化部分
{   
        int ret;
        writel(0x00000000, IO_ADDRESS(0x200f0104));//tobe gpio11_7

        ret=readl(IO_ADDRESS(0x201f0400)); //direction
        ret=ret&0x7f; //direction is in
        writel(ret, IO_ADDRESS(0x201f0400));

        ret=readl(IO_ADDRESS(0x201f0404)); //interrupt type level trigger
        ret=ret|0x80; //
        writel(ret, IO_ADDRESS(0x201f0404));

        ret=readl(IO_ADDRESS(0x201f040c)); //low level trigger
        ret=ret&0x7f; //
        writel(ret, IO_ADDRESS(0x201f040c));




        writel(0x80, IO_ADDRESS(0x201f041c)); //clean interrupt

        ret=readl(IO_ADDRESS(0x201f0410)); //interrupt mask
        ret=ret|0x80; //
        writel(ret, IO_ADDRESS(0x201f0410));
        printk(KERN_WARNING"init ...!\n");
        //第二步: 按键中断部分相应处理 注册中断 注销等等
}

int key_open(struct inode *node, struct file *filp)
{
        printk(KERN_WARNING"open ...!\n");

        return 0;
}

struct file_operations key_fops =   
{
        .open = key_open,
};

struct miscdevice* key=NULL;

static int key_init1(void)
{
        int err;

        key = kzalloc(sizeof(struct miscdevice), GFP_KERNEL);

        if (!key)
                return -ENOMEM;

        key->minor = MISC_DYNAMIC_MINOR;
        key->name= "key";
        key->fops= &key_fops;

        err = misc_register(key);
        //按键初始化 硬件初始化部分一般可一放在模块初始化部分或者open函数中 这里放在模块初始化部分
        key_hw_init();

        //由高电平变为低电平产生中断 IRQF_TRIGGER_FALLING
        printk("matt-2\n");

        //if( (err = request_irq(85,key_int, IRQF_SHARED|IRQF_TRIGGER_LOW, "key", key)) < 0 )//注册中断处理程序 5个参数
        //if( (err = request_irq(85,key_int, IRQF_TRIGGER_LOW, "key", key)) < 0 )
          if( (err = request_irq(85,key_int, IRQF_SHARED, "key", key)) < 0 )
        {
                printk(KERN_WARNING"err = %d\n", err);
                goto irq_err;
        }

        return 0;

irq_err:
        misc_deregister(key);   
        return -1;
}

static void key_exit1(void)
{
        free_irq(112, 0);//注销中断 这里irqnumber参数暂时用一个变量来表示(中断号)

        misc_deregister(key);//注销一个混杂设备驱动

        printk(KERN_WARNING"key up!");
}


module_init(key_init1);
module_exit(key_exit1);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("key driver");

dengqiao 发表于 2017-10-7 14:30:47

GPIO 11 是gpio组 某一个gpio的 irp如何获得
页: [1]
查看完整版本: hi3516a 按键驱动注册中断失败