ts-7000
[Top] [All Lists]

[ts-7000] query abt GPIO interrupts on ts- 7250

To:
Subject: [ts-7000] query abt GPIO interrupts on ts- 7250
From: "kernelnewbie" <>
Date: Sat, 31 Oct 2009 14:51:57 -0000
Hi ,
I am trying to get edge sensitive interrupt (from GPIO Port B bit 0), working 
on my Ts-7250 board.
I run kernel 2.6 through rootfs mounted through NFS.
Following is the part kernel module i had written for it . 

/*********************************************************************/

/*** Assume all the necessary hdr are present*/

/******************** GLOBALS *********************************/
static char *dev_name   = "My GPIOs";
static unsigned int bit = 0;
static int counter = 0;
static int irq_num = IRQ_EP93XX_GPIO_AB;

/******************** GLOBALS *********************************/




/****************** IRQ handler ***************/
static irqreturn_t irq_handler(int irq, void * dev_id)
{
        unsigned int unmasked;
        printk("IRQ %d handler called\n", irq);
        printk( "GPIO_B_INTENB = 0x%x\n ", 
                          __raw_readl(EP93XX_GPIO_B_INT_ENABLE) );
        printk( "GPIO_B_TYP1 = 0x%x\n ", 
                          __raw_readl(EP93XX_GPIO_B_INT_TYPE1)  );
        printk( "GPIO_B_TYP2 = 0x%x\n ", 
                           __raw_readl(EP93XX_GPIO_B_INT_TYPE2)  );
        printk( "GPIO_B_EOI = 0x%x\n ",
                           __raw_readl(EP93XX_GPIO_B_INT_ACK) );
        printk( "EP93XX_GPIO_B_INT_STATUS = 0x%x\n ",
                           __raw_readl(EP93XX_GPIO_B_INT_STATUS)); 

        return IRQ_HANDLED;
}



/***** INIT******/
int irqtest_init(void) 
{ 
int ret=0;
    struct task_struct* tid=NULL;   
    printk("Entering irqtest_init\n");    

    ret=request_irq (irq_num,
                     irq_handler, SA_INTERRUPT, DEVICE_NAME, NULL );
    if (ret)
    {
        printk(KERN_ERR MODULE_NAME " :Unable to get irq %d for "
                                       DEVICE_NAME " (err=%d)\n",
                                       bit,ret);
        return false;
     }
                        
     //Requesting gpio port B bit 0 of of                                       
                
     ret=request_irq (72,
                      irq_handler,SA_INTERRUPT,DEVICE_NAME, NULL );
     if (ret)
     {
        printk(KERN_ERR MODULE_NAME " :Unable to get irq %d for "
                                   DEVICE_NAME " (err=%d)\n", 72,ret);
        return false;
     }
        
    //Configure registers 
     config_intr();

return ret;

}


/************* Module EXIT ****************************/


void irqtest_exit(void) {

unsigned int unmasked = 0, mask ;

    printk("Entering irqtest_exit\n");
    printk( "GPIO_B_INTENB = 0x%x\n ",
               readl(EP93XX_GPIO_B_INT_ENABLE) );
    printk( "GPIO_B_TYP1 = 0x%x\n ", 
                 readl(EP93XX_GPIO_B_INT_TYPE1)  );
    printk( "GPIO_B_TYP2 = 0x%x\n ", 
                readl(EP93XX_GPIO_B_INT_TYPE2)  );
    printk( "GPIO_B_EOI = 0x%x\n ", 
                    readl(EP93XX_GPIO_B_INT_ACK) );
    printk( "EP93XX_GPIO_B_INT_STATUS = 0x%x\n ", 
                     __raw_readl(EP93XX_GPIO_B_INT_STATUS) );

    //Restore the pin to GPIO mode
    mask = (1 << bit);
    //Disable interrupt by writing to GPIO Interrupt Enable register.
        unmasked = __raw_readb(EP93XX_GPIO_B_INT_ENABLE);
        unmasked = unmasked & (~mask);
        __raw_writel( unmasked , EP93XX_GPIO_B_INT_ENABLE );

      printk(" EP93XX_GPIO_B_INT_ENABLE  = 0x%x \n", 
                    __raw_readl( EP93XX_GPIO_B_INT_ENABLE ) );


        //Clear the interrupt by writing to GPIO_B_EOI register
        unmasked = __raw_readb(EP93XX_GPIO_B_INT_ACK);
        unmasked = unmasked | mask;
        __raw_writel( unmasked, EP93XX_GPIO_B_INT_ACK );

        printk(" EP93XX_GPIO_B_INT_ACK = 0x%x \n", 
                        __raw_readl( EP93XX_GPIO_B_INT_ACK ) );

        free_irq( irq_num, NULL);
        free_irq( 72, NULL);

}


/**** config interrupt registers ******/

void config_intr()
{

unsigned int unmasked =0, mask =0;

/*   
In order to stop any spurious interrupts that may occur during the programming 
of the GPIOxINTTYPEx registers, the following sequence should be observed:
      1. Disable interrupt by writing to GPIO Interrupt Enable register.
      2. Set interrupt type by writing GPIOxINTTYPE1/2 register.
      3. Clear interrupt by writing to GPIOxEOI register.
      4. Enable interrupt by writing to GPIO Interrupt Enable register.
*/
        

        mask = (1 << bit);
        //Set interupt line as Input
        gpio_line_config ( EP93XX_GPIO_LINE_B(bit), GPIO_IN);   
        
        //Disable interrupt by writing to GPIO Interrupt Enable register.
        unmasked = __raw_readl(EP93XX_GPIO_B_INT_ENABLE);       
        unmasked = unmasked & (~mask);
        __raw_writel( unmasked ,EP93XX_GPIO_B_INT_ENABLE );

        
        
        //Set interrupt type ,as Edge Sensitive, by writing 1 to 
GPIO_B_INTTYPE1 register
        unmasked = __raw_readl(EP93XX_GPIO_B_INT_TYPE1);
        unmasked = unmasked | mask;
        __raw_writel( unmasked, EP93XX_GPIO_B_INT_TYPE1 );
        

        //Set Edge Sensitive interrupt type ,
        //as Rising Edge, by writing 1 to GPIO_B_INTTYPE2 register.
        unmasked = __raw_readl(EP93XX_GPIO_B_INT_TYPE2);
        unmasked = unmasked | mask;
        
        __raw_writel( unmasked, EP93XX_GPIO_B_INT_TYPE2 );
        
        //Clear  EOI by writing 1
        unmasked = __raw_readl(EP93XX_GPIO_B_INT_ACK );
        unmasked = unmasked | mask;
        __raw_writel( unmasked, EP93XX_GPIO_B_INT_ACK );

        //Enable interrupt by writing to GPIO Interrupt Enable register.
        unmasked = __raw_readl(EP93XX_GPIO_B_INT_ENABLE);
        unmasked = unmasked | mask;
        __raw_writel( unmasked ,EP93XX_GPIO_B_INT_ENABLE );     
}


I give pulses to the EGPIO8(Port B bit 0) on DIO pins of the board.

Following are my queries
1. My irq_handler does not get hit if I register to only IRQ_EP93XX_GPIO(  
EP93XX_GPIO_LINE_B(0) ) - 72 , (which correponds to port b bit 0 )
It gets hit only when I request_irq() for IRQ 72  and IRQ_EP93XX_GPIO_AB. Why 
is this so ?

2. I find after doing the above , the interrupt handler is invoked only for 
level sensitive interrupts- by having a logic0 on the pin EGPIO8.

This happens even after setting the necessary GPIO interrupt registers in 
config_intr() to respond to rising-edge pulses. 
I got to know that by printing the contents the registers

I need to know if this is the right way  and if, not what is right way to set 
the interrupt type. Is there any kernel function to do this?





------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

<Prev in Thread] Current Thread [Next in Thread>
  • [ts-7000] query abt GPIO interrupts on ts- 7250, kernelnewbie <=
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU