各位大神好,最近在N32916上写了个简单的按键驱动,GPG14引脚为nIQR1,但是中断触发后就一直在中断函数内运行,一直唤不醒读程序。请各位指点
static int open_cnt = 0;
static int major;
#define bs83xx_irq W55FA95_IRQ(3)
#define HELLO_CNT 1
static struct cdev bs83xx_cdev; /* use 1 cdev for all pins */
static struct class *cls;
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
static int ev_press = 0;
static unsigned char key_val;
#define GPIO_GROUP_G 5
//#define GPIO_GROUP_H 6
/* GPIO register offset definition */
//static int __iomem * gpio_reg_dir[7] = { REG_GPIOA_OMD, REG_GPIOB_OMD, REG_GPIOC_OMD, REG_GPIOD_OMD, REG_GPIOE_OMD, REG_GPIOG_OMD, REG_GPIOH_OMD};
//static int __iomem * gpio_reg_out[7] = { REG_GPIOA_DOUT, REG_GPIOB_DOUT, REG_GPIOC_DOUT, REG_GPIOD_DOUT, REG_GPIOE_DOUT, REG_GPIOG_DOUT, REG_GPIOH_DOUT};
static int __iomem * gpio_reg_in[7] = { REG_GPIOA_PIN, REG_GPIOB_PIN, REG_GPIOC_PIN, REG_GPIOD_PIN, REG_GPIOE_PIN, REG_GPIOG_PIN, REG_GPIOH_PIN};
static inline int w55fa95_gpio_get(int group, int num)
{
return readl(gpio_reg_in[group]) & (1 << num) ? 1:0;
}
static irqreturn_t w55fa95_bs8xx_irq(int irq, void *dev_id)//一直执行这个程序
{
printk("w55fa95_bs8xx_irq\n");
int pinval;
pinval = w55fa95_gpio_get(GPIO_GROUP_G,14);
printk("pinval = %d\n",pinval);
if(pinval)
{
key_val = 0x01;
}
else
{
key_val =0x11;
}
ev_press = 1;
wake_up_interruptible(&button_waitq);
ev_press = 1;
// enable_irq(bs83xx_irq);
// writel(readl(REG_IRQTGSRC2) & 0x4000000, REG_IRQTGSRC2); // clear source
return IRQ_HANDLED;
}
static ssize_t bs83xx_read(struct file *file,char __user *buf, size_t count, loff_t *ppos)
{
// if (count != 1)
// return -EINVAL;
printk("read bs83xx_read\n");
printk(" ev_press = %d\n",ev_press);
wait_event_interruptible(button_waitq, ev_press);
printk(" ev_press = %d\n",ev_press);//
ev_press = 0;
copy_to_user(buf, &key_val, 1);
// enable_irq(bs83xx_irq);
return 1;
}
static int bs83xx_open(struct inode *inode, struct file *file){
printk("bs83xx_open\n");
if (open_cnt > 0) {
goto exit;
}
//disable_irq(bs83xx_irq);
//disable_irq_nosync(bs83xx_irq);
// w55fa95_gpio_configure(GPIO_GROUP_A, 1); // GPA1 as ScanGPIO Input
// w55fa95_gpio_set_input(GPIO_GROUP_A, 1);
// writel(readl(REG_GPIOA_PUEN) | (BIT1), REG_GPIOA_PUEN); // port GPA1 pull-up
// writel(readl(REG_IRQSRCGPA) & ~((0x3 << 2)), REG_IRQSRCGPA); // GPA[1] as nIRQ0 source
// writel((readl(REG_IRQENGPA)& ~(0x1 << 17)) | (0x1 << 1), REG_IRQENGPA); // falling edge trigger
//writel((readl(REG_AIC_SCR1)& ~(0x00C70000)) | 0x00470000, REG_AIC_SCR1);
// writel((1 << TS_IRQ_NUM), REG_AIC_SCCR); // force clear previous interrupt, if any.
writel(readl(REG_GPGFUN) & ~(MF_GPG14), REG_GPGFUN);
writel (readl(REG_SHRPIN_TOUCH) &~ TP_AEN, REG_SHRPIN_TOUCH);
writel (readl(REG_GPGFUN) &~ (0x3 << (14<<1)), REG_GPGFUN);//set share pin funcion
writel (readl(REG_GPIOG_OMD) | (1 << 14), REG_GPIOG_OMD);
writel(readl(REG_GPIOG_OMD) & ~(1 << 14), REG_GPIOG_OMD); // input
writel(readl(REG_GPIOG_PUEN) & ~(1 << 14), REG_GPIOG_PUEN); // pull-up
writel(readl(REG_IRQSRCGPG) & ~(0x20000000), REG_IRQSRCGPG); // GPG14 as nIRQ1 source
writel((readl(REG_IRQENGPG)& ~(0x40000000)) | 0x00004000, REG_IRQENGPG); //enable falling edge triggers
writel((readl(REG_IRQLHSEL)& ~(0x2)) | 0x2, REG_IRQLHSEL);
// writel((readl(REG_AIC_SCR1)& ~(0xC7000000)) | 0x47000000, REG_AIC_SCR1);
writel(readl(REG_DBNCECON) |0x71, REG_DBNCECON);
writel((1 << bs83xx_irq), REG_AIC_SCCR); // force clear previous interrupt, if any.
writel(readl(REG_IRQTGSRC2) & 0x4000000, REG_IRQTGSRC2); // clear source
if (request_irq(bs83xx_irq, w55fa95_bs8xx_irq,IRQF_DISABLED|IRQF_TRIGGER_FALLING, "bs8xx_key",NULL) != 0) {
printk("register the bs8xx_irq failed!\n");
return -1;
}
disable_irq_nosync(bs83xx_irq);
// Enable_IRQ(bs83xx_irq);
enable_irq(bs83xx_irq);
//enable falling edge triggers
// writel((readl(REG_IRQENGPG)& ~(0x40000000)) | 0x00004000, REG_IRQENGPG);
//enable_irq(bs83xx_irq);
exit:
open_cnt++;
return 0;
}
void bs83xx_close(struct inode *inode, struct file *file) {
open_cnt--;
if (open_cnt == 0) {
//disable falling edge triggers
writel((readl(REG_IRQENGPG)& ~(0x40004000)), REG_IRQENGPG);
free_irq(bs83xx_irq,NULL);
}
return;
}
static unsigned int bs83xx_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait);
if(ev_press)
{
mask |= POLLIN | POLLRDNORM;
}
return mask;
}
static struct file_operations bs83xx_fops = {
.owner =THIS_MODULE,
.open = bs83xx_open,
.read = bs83xx_read,
.release = bs83xx_close,
.poll = bs83xx_poll,
};
static int bs83xx_init(void)
{
dev_t devid;
if (major) {
devid = MKDEV(major, 0);
register_chrdev_region(devid, HELLO_CNT, "bs83xx");//(major,0-1)
} else
{
alloc_chrdev_region(&devid, 0, HELLO_CNT, "bs83xx");
major = MAJOR(devid);
}
cdev_init(&bs83xx_cdev, &bs83xx_fops);
cdev_add(&bs83xx_cdev, devid, HELLO_CNT);
cls = class_create(THIS_MODULE,"bs83xx");
device_create(cls,NULL,MKDEV(major,0),NULL,"bs83xx");
// device_create(cls,NULL,MKDEV(major,1),NULL,"hello1");
return 0;
}
static void bs83xx_exit(void)
{
device_destroy(cls,MKDEV(major,0));
class_destroy(cls);
unregister_chrdev_region(MKDEV(major, 0), HELLO_CNT);
cdev_del(&bs83xx_cdev);
}
module_init(bs83xx_init);
module_exit(bs83xx_exit);
MODULE_LICENSE("GPL"); |
|