2008-03-21 06:23:27     gpio interrupt

Document created by Aaronwu Employee on Aug 5, 2013
Version 1Show Document
  • View in full screen mode

2008-03-21 06:23:27     gpio interrupt

Bastien Briec (FRANCE)

Message: 52882    hi all

i work on a cm-bf537e, and i would like to run an application when a button is pressed, i look at the interrupt wiki, so i wrote a driver :

 

    #include <linux/module.h>

    #include <linux/errno.h>

    #include <linux/interrupt.h>

    #include <asm/io.h>

    #include <asm/irq.h>

    #include <stdio.h>

 

    #define CONFIG_YOURDRIVERS_IRQ_PFX IRQ_PG10

    

 

    static irqreturn_t your_irq_handler (int irq, void *dev_id)

    {

      printk(KERN_INFO"your_irq_handler \n");

      return IRQ_HANDLED;

    }

    

    

    static int __init your_drivers_init_function(void)

    {

       if (request_irq(CONFIG_YOURDRIVERS_IRQ_PFX, your_irq_handler, IRQT_RISING, "PG10",NULL))

      {

    

              printk(KERN_WARNING "IRQ %d is not free.\n", CONFIG_YOURDRIVERS_IRQ_PFX);

              return -EBUSY;

       }

    

      disable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

    

      printf("driver test pg10");

    

      enable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

    

    }

    

    void __exit your_drivers_exit_function(void)

    {

      free_irq (CONFIG_YOURDRIVERS_IRQ_PFX, NULL);

    }

 

i add it like explained in the driver developpemnt but nothing when I push the pg10 button. can someone explain me how to do.

 

regards Bastien

TranslateQuoteReplyEditDelete

 

 

2008-03-21 07:07:58     Re: gpio interrupt

Jian Ju (HONG KONG)

Message: 52885    I'm unfamiliar with bf537 board, however, you need to setup the gpio (int mask, edge/level, polarity, etc) in the init function so that the interrupt can be generated as you expected.

TranslateQuoteReplyEditDelete

 

 

2008-03-21 08:53:40     Re: gpio interrupt

Mike Frysinger (UNITED STATES)

Message: 52888    all of those things are done for you with the GPIO framework ... you need need to mess with any masks

QuoteReplyEditDelete

 

 

2008-03-21 08:55:10     Re: gpio interrupt

Mike Frysinger (UNITED STATES)

Message: 52889    you called request_irq() with "IRQT_RISING" ... that is an invalid flag

 

please read the start of the wiki page where it lists valid flags

QuoteReplyEditDelete

 

 

2008-03-21 10:00:18     Re: gpio interrupt

Bastien Briec (FRANCE)

Message: 52891    I try to replace it by "IRQF_TRIGGER_LOW" but there is nothing when i push the button, what i would like to begin is just to display a message when the button is pressed.

 

regards Bastien

TranslateQuoteReplyEditDelete

 

 

2008-03-21 11:15:17     Re: gpio interrupt

Mike Frysinger (UNITED STATES)

Message: 52894    try using a rising or falling trigger ... otherwise, you'll have to verify with the hardware schematics what you're actually pushing

 

we've used the gpio keys driver on the BF537-STAMP just fine ... you could probably adapt it to the cm-bf537 pretty easily by just migrating over the board resources

QuoteReplyEditDelete

 

 

2008-03-25 05:32:31     Re: gpio interrupt

Bastien Briec (FRANCE)

Message: 53001    I try with a rising and a falling trigger but in all case i get nothing, i verify in the hardware schematics the button is pg14 and it works with the pflags_test program, is my driver correct or may be it's another problem?

 

    #include <linux/module.h>

    #include <linux/errno.h>

    #include <linux/interrupt.h>

    #include <asm/io.h>

    #include <asm/irq.h>

    #include <stdio.h>

 

    #define CONFIG_YOURDRIVERS_IRQ_PFX PG14

 

    static irqreturn_t your_irq_handler (int irq, void *dev_id)

    {

      printk(KERN_INFO"your_irq_handler \n");

      return IRQ_HANDLED;

    }

 

    static int __init your_drivers_init_function(void)

    {

       if (request_irq(CONFIG_YOURDRIVERS_IRQ_PFX, your_irq_handler, IRQF_RISING_RISING, "PG14",NULL))

       {

           printk(KERN_WARNING "IRQ %d is not free.\n", CONFIG_YOURDRIVERS_IRQ_PFX);

          return -EBUSY;

       }

     

       disable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

     

       printf("driver test pg14");

     

       enable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

    }

       

    void __exit your_drivers_exit_function(void)

    {

      free_irq (CONFIG_YOURDRIVERS_IRQ_PFX, NULL);

    }

 

    module_init(your_drivers_init_function)

    module_exit(your_drivers_exit_function);

 

TranslateQuoteReplyEditDelete

 

 

2008-03-25 08:19:02     Re: gpio interrupt

Mike Frysinger (UNITED STATES)

Message: 53013    your driver is incorrect ... you use IRQ_PG14, not PG14

QuoteReplyEditDelete

 

 

2008-03-25 08:51:00     Re: gpio interrupt

Bastien Briec (FRANCE)

Message: 53015    I also try to use IRQ_PG14 instead of PG14 but the driver does not seems to work

TranslateQuoteReplyEditDelete

 

 

2008-03-26 05:19:49     Re: gpio interrupt

roger froysaa (NORWAY)

Message: 53041   

 

Hi, here is an old test I did on the CM-BF537 to test IRQs. It worked for me when I was playing with it...

Please note that this was only a dumb test and is seriously crappy code

 

Ignore the SPI-related names, I was reusing test code from other stuff...

 

 

 

 

 

 

#include <linux/poll.h>

#include <linux/device.h>

#include <linux/cdev.h>

#include <asm-blackfin/mach-bf537/irq.h>

#include <linux/interrupt.h>

 

// GLOBAL SETTINGS AND INIT

int rf_major = 0;

int rf_minor = 0;

int rf_nr_devs = 1;

 

MODULE_LICENSE("GPL");

 

// Our local (internal) SPI device representation

struct rf_device_t

{

    int opened;

    struct cdev cdev;

};

 

struct rf_device_t rf_info; // One global instance - only one user at a time...

static DEFINE_SPINLOCK(rf_global_lock);

 

// =============================================================================

// Char device functions

// =============================================================================

 

static int rf_spi_open (struct inode * inode, struct file * filp)

{

    //printk(KERN_WARNING "rf: open() called\n");

    spin_lock(&rf_global_lock);

    if (rf_info.opened)

    {

        printk(KERN_WARNING "rf: Driver already opened - exiting.\n");

        spin_unlock(&rf_global_lock);

        return -EBUSY;

    }

    rf_info.opened++;   

    spin_unlock(&rf_global_lock);

    return 0;

}

 

static int rf_spi_release (struct inode * inode, struct file * filp)

{

    //printk(KERN_WARNING "rf: release() called on close\n");

    spin_lock(&rf_global_lock);

    rf_info.opened--;

    spin_unlock(&rf_global_lock);

    return 0;

}

 

// Character device specific function map.

struct file_operations rf_fops = {

    .owner   = THIS_MODULE,

    .open    = rf_spi_open,

    .release = rf_spi_release,

};

 

irqreturn_t rf_spi_irq (int irq, void *dev_id, struct pt_regs *regs)

{

    printk(KERN_WARNING "rf: IRQ handler: Button pressed!!!\n");

    return IRQ_HANDLED;

}

 

 

// =============================================================================

// MODULE RELATED STUFF

// =============================================================================

static int rf_spi_init (void)

{

    int result;

    dev_t devno = 0;

 

    // -------------------------------------------------------------------------

    // Allocate device number

    if (rf_major)

    {

        devno = MKDEV(rf_major, rf_minor);

        result = register_chrdev_region(devno, rf_nr_devs, "rf_spi");

    }

    else

    {

        // Normal case - have device nr given to us by kernel

        result = alloc_chrdev_region(&devno, rf_minor, rf_nr_devs, "rf_spi");

        rf_major = MAJOR(devno);

        printk(KERN_WARNING "rf: Device number allocated: major: %d, minor: %d\n", MAJOR(devno), MINOR(devno));

    }

 

    if (result < 0)

    {

        printk(KERN_WARNING "rf: can't get major %d\n", rf_major);

        return result;

    }

 

    // -------------------------------------------------------------------------

    // Char device registration

 

    // Initialize device...

    cdev_init(&rf_info.cdev, &rf_fops);

    rf_info.cdev.owner = THIS_MODULE;

    rf_info.cdev.ops = &rf_fops;

    result = cdev_add (&rf_info.cdev, devno, 1);

    if (result)

    {

        printk(KERN_NOTICE "Error %d adding rf_spi\n", result);

        goto cleanup_chrdev_region;

    }

 

    // -------------------------------------------------------------------------

    // Register GPIO IRQ

 

    result = request_irq (IRQ_PG14, rf_spi_irq, IRQF_TRIGGER_LOW, "rf_spi", NULL);

    if (result)

    {

        printk(KERN_NOTICE "Error %d requesting IRQ\n", result);

        goto cleanup_cdev;

    }

 

    // -------------------------------------------------------------------------

 

    printk(KERN_ALERT "rf loaded ok\n");

    return 0;

 

    // Error "catch" handlers

    cleanup_cdev:

    cdev_del(&rf_info.cdev);

 

    cleanup_chrdev_region:

    unregister_chrdev_region(devno, rf_nr_devs);

 

    return result;

}

 

static void rf_spi_cleanup (void)

{

    /* cleanup_module is never called if registering failed */

    dev_t devno = MKDEV(rf_major, rf_minor);

    free_irq (IRQ_PG14, NULL);

    cdev_del(&rf_info.cdev);   

    unregister_chrdev_region(devno, rf_nr_devs);   

    printk(KERN_ALERT "rf module cleanup done\n");

 

}

 

module_init(rf_spi_init);

module_exit(rf_spi_cleanup);

 

QuoteReplyEditDelete

 

 

2008-03-26 06:30:21     Re: gpio interrupt

Bastien Briec (FRANCE)

Message: 53046    Thanks Roger, it works, i'll try to understand all now.

Attachments

    Outcomes