Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

help 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);
No RepliesBe the first to reply