Altera_Forum
Honored Contributor
14 years agohelp me about loadable module with calling to request_irq
help me about loadable module with calling to request_irq
With the help of alterawiki.com, I have successfully run uClinux on my epc235 board(kernel is 2.6.30), but have trouble in creating a loadable module driver for a GPIO interrupt. According to the alterawiki.com/wiki/ModuleProgramming, I write my daq_irq.c and then put it in nios2-linux/linux-2.6/drivers/misc/, and then modified drivers/misc/Kconfig, drivers/misc/Makefile ,then "make menuconfig" to enable my module. the result zImage can boot, but when I run "modprobe daq_irq", the uClinux will immediatly reboot. I think the problem is caused by the calling to request_irq( ) in module init part. If I don't call request_irq(), all things seems to be ok. otherwise, the printk(), the next line just after requrest_irq( ) is not run and the uClinux will rebooting from flash chip. the following is my daq_irq.c, please help me out!! # include <linux/init.h> # include <linux/types.h> # include <linux/fs.h> # include <linux/ioctl.h> # include <linux/wait.h> # include <linux/sched.h> # include <linux/errno.h> # include <linux/interrupt.h> # include <linux/module.h> # include <linux/version.h> # include <asm/io.h> // the writew(), writel() # include <asm/irq.h> # include "`/niosdev/niosdev/lvtong/hardware.h" MODULE_LICENSE("Dual BSD/GPL"); # define DAQ_IRQ_NAME "daq_irq" # define DAQ_IRQ_MAJOR 240 # define DAQ_IRQ_IRQ 6 static int daq_irq_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); static int daq_irq_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); static int daq_irq_ioctl(struct inode *inode, struct file *flip,unsigned int cmd, unsigned long arg); static int daq_irq_open(struct inode *inode, struct file *flip); static int daq_irq_release(struct inode *inode, struct file *flip); static irqreturn_t daq_irq_handle(int irq, void *dev_id); static void daq_irq_cleanup(void); struct file_operations daq_irq_fops = { read: daq_irq_read, write: daq_irq_write, ioctl: daq_irq_ioctl, open: daq_irq_open, release: daq_irq_release, }; /*********************the above is header******************/ static int daq_irq_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { return 0; } static int daq_irq_write(struct file *filp, char *buf, size_t count, loff_t *f_pos) { return 0; } static int daq_irq_ioctl(struct inode *inode, struct file *flip,unsigned int cmd, unsigned long arg) { // this function is cut for less pages ......... } static int daq_irq_open(struct inode *inode, struct file *flip) { printk("<0>somebody opens daq_irq\n"); return 0; } static int daq_irq_release(struct inode *inode, struct file *flip) { printk("<0>somebody closes daq_irq\n"); return 0; } static irqreturn_t daq_irq_handle(int irq, void *dev_id) { // the interrupt function here ...... return IRQ_HANDLED; } static int __init daq_irq_init(void) { int ret; ret = register_chrdev(DAQ_IRQ_MAJOR, "daq_irq", &daq_irq_fops); //register the device if(ret<0) { printk("failed to register daq_irq\n"); } else printk("ok to register daq_irq\n"); //CLEAR_PEND_INT(EXTINT_IRQ); writel(0,FSELECT_CAPTURE_BASE); //this will clear the irq source writel(0,FSELECT_INTMASK_BASE); //disable interrupt ret = request_irq(DAQ_IRQ_IRQ, daq_irq_handle, IRQF_TRIGGER_RISING, "daq_irq", NULL) ; /* i think problem is here. because if request_irq and free_irq (in daq_irq_cleanup() ) are cut off, the module can be insmod(modprobe) and rmmod, then insmod, rmmod ..., all things are OK. buf if i call request_irq here, my uClinux will be rebooting when "modprobe daq_irq" is run. */ if(ret){ printk("daq_irq: can NOT get assigned irq %i\n", DAQ_IRQ_IRQ); } else{ printk("daq_irq: got fselect interrupt %i\n",DAQ_IRQ_IRQ); writel(0,FSELECT_CAPTURE_BASE); //this will clear the irq source } return ret; } static void daq_irq_cleanup(void) { writel(0,FSELECT_CAPTURE_BASE); //this will clear the irq source writel(0,FSELECT_INTMASK_BASE); //disable interrupt free_irq(DAQ_IRQ_IRQ,0); unregister_chrdev(DAQ_IRQ_MAJOR,"daq_irq"); printk("remove the daq_irq driver!\n"); } module_init(daq_irq_init); module_exit(daq_irq_cleanup);