From: Ashutosh A. <ash...@gm...> - 2005-09-30 08:58:41
|
Hi I am trying to build kernel module to handle the interrupt generated by nssp in the gumstix The process followed is as follows firstly created a kernel module registered it as the charter device( which can be seen by lsmod) registered a interrupt(number 9 i.e. the NSSP_IRQ value) handler which is viewable by 'cat /proc/interrupts' currently there in no hardware connected to nssp pins but using it in the loopback mode and trying to get interrupt by -->interrupt test register -->timeout register -->receive/transmit fifo service request but in all cases the system hang and is required to be restarted by switching off and then on the power supply also, i am using preloaded kernel my code snippet is int reg_init(struct ssp_state *dev) { dev->cr0=3D0; dev->cr0=3D SSCR0_DataSize(16) | SSCR0_TI | (7<<8) | SSCR0_EDSS; dev->cr1=3D0; dev->cr1=3DSSCR1_RIE | SSCR1_TIE | SSCR1_LBM | SSCR1_TxTresh(11) | SSCR1_RxTresh(11) | SSCR1_TINTE | SSCR1_TTE ; dev->to=3D46000; dev->itr=3D0; SSCR0_P2 =3D dev->cr0; SSCR1_P2 =3D dev->cr1; SSTO_P2 =3D dev->to; SSITR_P2=3Ddev->itr; return 0; } int nssp_set(void) { int ret, irq,i; down(&sem); printk(KERN_INFO " inside nssp_set"); irq =3D IRQ_NSSP; memset(®s,0,sizeof(struct ssp_state)); =09reg_init(®s); up(&sem); ret =3D request_irq(irq, &nssp_interrupt, 0, "NSSP",&nssp_int); if (ret) return -1; return 0; } int nssp_init(void) { int i,ret; printk(KERN_INFO "inside nssp_init()\n"); i=3Dnssp_set(); if(i!=3D0) return -3; =09Major =3D register_chrdev(0, DEVICE_NAME, &fops); =09if (Major < 0) { =09=09printk("Registering the character device(nsspdev) failed with %d\n", =09=09 Major); =09=09return -2; =09} =09printk("<1>I was assigned major number %d. \n", Major); =09 nssp_enable(); SSITR_P2 |=3D TRFS; for(i=3D0;i<1000;i++); SSITR_P2 &=3D ~TRFS; nssp_disable(); =09return 0; } void nssp_reset() { int irq; printk("nssp_reset: \n"); down(&sem); =09SSCR0_P2 &=3D ~SSCR0_SSE; irq =3D IRQ_NSSP; =09free_irq(irq, &nssp_int); =09 up(&sem); } void nssp_exit(void) { int ret; nssp_reset(); ret =3D unregister_chrdev(Major, DEVICE_NAME); =09if (ret < 0) =09=09printk("Error in unregister_chrdev: %d\n", ret); =09printk("nssp_exit \n");=09 } void nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { // struct ssp_dev *dev =3D (struct ssp_dev*) dev_id; unsigned int status =3D SSSR_P2; if (status & SSSR_BCE) { printk(KERN_WARNING "NSSP: bit count error\n");} =09if (status & SSSR_TUR) { printk(KERN_WARNING "NSSP: transmitter underrun\n");} =09 =09if(status & SSSR_TINT) =09{ printk(KERN_INFO "NSSP: timeout interrupt\n");} =09 if (status & SSSR_ROR) { printk(KERN_WARNING "NSSP: receiver overrun\n");} if(status & SSSR_RFS) { printk(KERN_INFO " NSSP: Rsv FIFO service request\n");} =09 if(status & SSSR_TFS) { printk(KERN_INFO " NSSP: Trns FIFO service request \n");} SSSR_P2 =3D status; /* clear status bits */ =09return ;//IRQ_HANDLED; } the nssp_init () module calls the nssp_set() which in turn calls reg_init() at the end of the nssp_init() function when the interrupt test register is set the system hangs Please help thanks in advance bye ashutosh |
From: Dave H. <dhy...@gm...> - 2005-09-30 15:04:00
|
Hi ashutosh, > I am trying to build kernel module to handle the interrupt generated > by nssp in the gumstix > The process followed is as follows > firstly created a kernel module registered it as the charter device( > which can be seen by lsmod) > registered a interrupt(number 9 i.e. the NSSP_IRQ value) handler which > is viewable by 'cat /proc/interrupts' > currently there in no hardware connected to nssp pins but using it in > the loopback mode > and trying to get interrupt by > -->interrupt test register > -->timeout register > -->receive/transmit fifo service request > but in all cases the system hang and is required to be restarted by > switching off and then on the power supply > also, i am using preloaded kernel It would be useful to see the entire c file (and any associated header files) as well as the console output. I'll throw out some comments based on what you did include: 1 - Your prototype for the interrupt routine is slightly wrong. I'm suprised you didn't get a warning on the call to request_irq. The correct prototype is: irqreturn_t nssp_interrupt( int irq, void *_dev, struct pt_regs *r) and you NEED to return something (like IRQ_HANDLED). Since your routine is declared void, you'll get some random return value. 2 - I don't see where sem is initialized. Calling down on an unintialized semaphore wouldn't be good. 3 - Your "delay" in the nssp_init routine using: for(i=3D0;i<1000;i++); will almost certainly be optimized away. You'd be better off you use ndelay or mdelay functions. 4 - Because I can't what regs is initialized to, I'm not sure if it's memory or pointing to the registers. If it's memory, then I don't see where you're enabling the interrupts. If it points to the hardware, then you're enabling the interrupts before you register an interrupt handler. 5 - When you built your module, are you sure that the kernel that's runnng on the gumstix matches the kernel in your buildroot? I always like to download my built root_fs_arm so that I can be sure everything matches. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Ashutosh A. <ash...@gm...> - 2005-09-30 16:28:46
|
hi Dave below is my code i have changed it a bit to make it more readable --the SSCR* are defined in the pxa-regs.h and also in the sample driver in the gumstix build root file ssp.c -- this code is tested and is hanging the gumstix -- in another driver if the various interrrupt situation(like txd\rxd service request, interrupt test reg or fifo over/under run are not enabled)are not enabled then the data can be transported and received form the FIFO --regs are initialised as follows SSCR0-- for 32 bit data transfer ,using TI ssp protocol SSCR1-- rxd/txd interrupt enabled,Loop backmode,transmission /receive fifo threshold,timeout interrupt, etc this code test for the interrupt when it is initialised. the gumstix system is not handling the interrupt it just hangup thanks in advance the code /* *nsspdrv.h */ #include <linux/fs.h> #include <asm/uaccess.h>=09/* for put_user */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/init.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/hardware.h> #include <asm/arch/pxa-regs.h> #define TRFS (1 << 6) #define SUCCESS 0 #define DEVICE_NAME "nsspdev"=09/* Dev name as it appears in /proc/devices = */ #define BUF_LEN 80=09=09/* Max length of the message from the device */ struct ssp_state { u32 cr0; u32 cr1; u32 to; u32 psp; u32 itr; }; static struct ssp_state regs; struct nssp_irq{ int a; int b; }; static struct nssp_irq nssp_int; static int Major;=09=09/* Major number assigned to our device driver */ static int Device_Open =3D 0;=09/* Is device open? =09=09=09=09 * Used to prevent multiple access to device */ static char msg[BUF_LEN];=09/* The msg the device will give when asked */ static char *msg_Ptr; int nssp_init(void); void nssp_exit(void); static int nssp_open(struct inode *, struct file *); static int nssp_release(struct inode *, struct file *); static ssize_t nssp_read(struct file *, char *, size_t, loff_t *); static ssize_t nssp_write(struct file *, const char *, size_t, loff_t *); void nssp_disable(void); void nssp_enable(void); int nssp_write_word(u32 ); int nssp_read_word(void); irqreturn_t nssp_interrupt(int , void *, struct pt_regs *); module_init(nssp_init); module_exit(nssp_exit); MODULE_DESCRIPTION("PXA NSSP driver"); MODULE_AUTHOR("ashutosh"); MODULE_LICENSE("GPL"); /* * nsspdrv.c */ #include"nsspdrv.h" //File_ops structture initialisation static struct file_operations fops =3D { =09.read =3D nssp_read, =09.write =3D nssp_write, =09.open =3D nssp_open, =09.release =3D nssp_release, =09 }; int nssp_write_word(u32 data) { while (!(SSSR_P2 & SSSR_TNF)); // cpu_relax(); SSDR_P2 =3D data; return 0; } int nssp_read_word() { while (!(SSSR_P2 & SSSR_RNE)); // cpu_relax(); return SSDR_P2; } void nssp_enable() { SSCR0_P2 |=3D SSCR0_SSE; } void nssp_disable() { SSCR0_P2 &=3D ~SSCR0_SSE; } int nssp_init(void) { int i,ret,irq; printk(KERN_INFO "inside nssp_init()\n"); irq =3D IRQ_NSSP; memset(®s,0,sizeof(struct ssp_state)); regs.cr0=3D SSCR0_DataSize(16) | SSCR0_TI | (7<<8) | SSCR0_EDSS; regs.cr1=3DSSCR1_RIE | SSCR1_TIE | SSCR1_LBM | SSCR1_TxTresh(11) | SSCR1_RxTresh(11) | SSCR1_TINTE | SSCR1_TTE ; regs.to=3D46000;//not used regs.itr=3D0;//not used SSCR0_P2 =3D regs.cr0; SSCR1_P2 =3D regs.cr1; ret =3D request_irq(irq, &nssp_interrupt, 0, "NSSP",&nssp_int); if (ret) return -3; Major =3D register_chrdev(0, DEVICE_NAME, &fops); =09if (Major < 0) { =09=09printk("Registering the character device(nsspdev) failed with %d\n", = Major); =09=09return -2; =09} =09printk("<1>I was assigned major number %d. To talk to\n", Major); =09printk("<1>the driver, create a dev file with\n"); =09printk("'mknod /dev/nssp c %d 0'.\n", Major); =09 nssp_enable(); //Testing the system for the interrupt SSITR_P2 |=3D TRFS; for(i=3D0;i<1000;i++);//just for testing the interrupt SSITR_P2 &=3D ~TRFS; nssp_disable(); =09return 0; } void nssp_exit(void) { int ret,irq; SSCR0_P2 &=3D ~SSCR0_SSE; irq =3D IRQ_NSSP; =09free_irq(irq, &nssp_int); =09ret =3D unregister_chrdev(Major, DEVICE_NAME); =09if (ret < 0) =09=09printk("Error in unregister_chrdev: %d\n", ret); =09printk("nssp_exit \n");=09 } static int nssp_open(struct inode *inode, struct file *file) { =09static int counter =3D 0; =09Device_Open++; =09printk("I already told you %d times Hello world!\n", Device_Open); =09msg_Ptr =3D msg; =09try_module_get(THIS_MODULE); return SUCCESS; } static int nssp_release(struct inode *inode, struct file *file) { =09Device_Open--; =09printk("the device no released : %i\n",Device_Open+1); =09module_put(THIS_MODULE); =09return 0; } irqreturn_t nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { // struct ssp_dev *dev =3D (struct ssp_dev*) dev_id; unsigned int status =3D SSSR_P2; SSSR_P2 =3D status; /* clear status bits */ if (status & SSSR_BCE) { printk(KERN_WARNING "NSSP: bit count error\n");} =09if (status & SSSR_TUR) { printk(KERN_WARNING "NSSP: transmitter underrun\n");} =09 =09if(status & SSSR_TINT) =09{ printk(KERN_INFO "NSSP: timeout interrupt\n");} =09 if (status & SSSR_ROR) { printk(KERN_WARNING "NSSP: receiver overrun\n");} if(status & SSSR_RFS) { printk(KERN_INFO " NSSP: Rsv FIFO service request\n");} =09 if(status & SSSR_TFS) { printk(KERN_INFO " NSSP: Trns FIFO service request \n");} =09return IRQ_HANDLED; } // the function accessed by read() system call static ssize_t nssp_read(struct file *filp, char *buffer,size_t length,loff_t * offset) { =09int ret, bytes_read =3D 1; int i=3D0; =09nssp_enable(); =09for(i=3D0;i<8;i++) { ret=3D1000+i; printk(" the word written is : %x \n",ret); nssp_write_word(ret); =09 printk(" reading : %x \n",nssp_read_word()); }=09 =09nssp_disable(); =09return bytes_read; } static ssize_t nssp_write(struct file *filp, const char *buff, size_t len, loff_t * off) { =09printk("<1>Sorry, this operation isn't supported.\n"); =09return -EINVAL; } bye ashutosh |
From: Craig H. <cr...@gu...> - 2005-10-02 20:54:37
|
On Sep 30, 2005, at 1:58 AM, Ashutosh Agarwal wrote: > void nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) > { > // struct ssp_dev *dev = (struct ssp_dev*) dev_id; > unsigned int status = SSSR_P2; > > if (status & SSSR_BCE) > { printk(KERN_WARNING "NSSP: bit count error\n");} > You can't do I/O inside an interrupt service routine. C |
From: Dave H. <dhy...@gm...> - 2005-10-03 03:56:02
|
Hi Craig, On 9/30/05, Craig Hughes <cr...@gu...> wrote: > On Sep 30, 2005, at 1:58 AM, Ashutosh Agarwal wrote: > > > void nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) > > { > > // struct ssp_dev *dev =3D (struct ssp_dev*) dev_id; > > unsigned int status =3D SSSR_P2; > > > > if (status & SSSR_BCE) > > { printk(KERN_WARNING "NSSP: bit count error\n");} > > > > You can't do I/O inside an interrupt service routine. Huh? Not sure what you're referring to as I/O. Calling printk from within an ISR is a perfectly valid and legal thing to do. It isn't wise from a performance perspective, but it's done all the time. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Ashutosh A. <ash...@gm...> - 2005-10-03 04:49:35
|
hi even the functions such as probe_irq_on() probe_irq_off() are also crashing the gumstix i have also tested it for the ssp but the same things happens my gumstix is connected through etherstix to a network and i am assessing it through ssh login thanks ashutosh On 10/3/05, Dave Hylands <dhy...@gm...> wrote: > Hi Craig, > > On 9/30/05, Craig Hughes <cr...@gu...> wrote: > > On Sep 30, 2005, at 1:58 AM, Ashutosh Agarwal wrote: > > > > > void nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) > > > { > > > // struct ssp_dev *dev =3D (struct ssp_dev*) dev_id; > > > unsigned int status =3D SSSR_P2; > > > > > > if (status & SSSR_BCE) > > > { printk(KERN_WARNING "NSSP: bit count error\n");} > > > > > > > You can't do I/O inside an interrupt service routine. > > Huh? Not sure what you're referring to as I/O. Calling printk from > within an ISR is a perfectly valid and legal thing to do. > > It isn't wise from a performance perspective, but it's done all the time. > > -- > Dave Hylands > Vancouver, BC, Canada > http://www.DaveHylands.com/ > > > ------------------------------------------------------- > This SF.Net email is sponsored by: > Power Architecture Resource Center: Free content, downloads, discussions, > and more. http://solutions.newsforge.com/ibmarch.tmpl > _______________________________________________ > gumstix-users mailing list > gum...@li... > https://lists.sourceforge.net/lists/listinfo/gumstix-users > |