cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Visitor
Visitor
3,697 Views
Registered: ‎11-21-2011

Problem with external interrupt handler

Hello

I have a problem with writing drivers external interrupt handler in GNU / Linux (2.6.37).

Kernel downloaded from the repository site Xilinx.

Use Board Spartan3A1800DSP.

Used development environment Xilinx EDK 13.3

The essence of the problem:

Interrupt registers in the system normally, without errors, but on pressing the buttons does not respond.

 

Driver code:

 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
 
static int irq;
 
static irqreturn_t test_irq_handler(int irq, void *dev_id)
{
  printk(KERN_ALERT "all ok!\n");
  return IRQ_HANDLED;
}
 
static int __init kruger_driver_init(void)
{
  struct device_node *root_dn;
  struct device_node *kruger_gpio;
  struct resource resource;
  int result;
  unsigned int start_addr;
  unsigned long  *virt_addr;
 
  printk(KERN_ALERT "Kruger driver init\n");
  root_dn = of_find_node_by_path("/");
  kruger_gpio = of_find_node_by_name(root_dn, "gpiob");
  if (!kruger_gpio)
  {
    printk(KERN_ALERT "GPIO buttons not found in DTF\n");
    return -ENODEV;
  }
  result = of_address_to_resource(kruger_gpio, 0, &resource);
  if (result < 0)
  {
    printk(KERN_ALERT "GPIO buttons: error address to resource");
    return -ENODEV;
  }
  printk(KERN_ALERT "GPIO buttons: reg. size=%d Bytes\n", (u32)resource.end-(u32)resource.start);
  start_addr = (unsigned int)resource.start;
 
  irq = of_irq_to_resource(kruger_gpio, 0, &resource);
  if (irq == NO_IRQ)
  {
    printk(KERN_ALERT "GPIO buttons: of_irq_to_resource() failed\n");
    of_node_put(kruger_gpio);
    return -ENODEV;
  }
 
  printk(KERN_ALERT "GPIO buttons: irq=%d\n", irq);
  virt_addr = of_iomap(kruger_gpio, 0);
  printk(KERN_ALERT "GPIO buttons: at 0x%08X mapped to 0x%08X\n", start_addr, (u32)virt_addr);
  result = request_irq(irq, &test_irq_handler, IRQF_TRIGGER_MASK, "Gpio Buttons", NULL);
  if (result < 0)
  {
      printk(KERN_ALERT "GPIO buttons: error to request IRQ%d : %d\n", irq, result);
      of_node_put(kruger_gpio);
      return -ENODEV;
  }
  printk(KERN_ALERT "GPIO buttons module inserted successfully\n");
  return 0;
}
 
static void __exit kruger_driver_exit(void)
{
  printk(KERN_ALERT "Kruger driver exit\n");
}
 
module_init(kruger_driver_init);
module_exit(kruger_driver_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kruger");
MODULE_DESCRIPTION("Gpio example driver");

 

Part of the DTF file:

Push_Buttons: gpiob@81400000 {
			compatible = "xlnx,xps-gpio-2.00.a", "xlnx,xps-gpio-1.00.a";
			interrupt-parent = <&xps_intc_0>;
			interrupts = < 1 2 >;
			reg = < 0x81400000 0x10000 >;
			xlnx,all-inputs = <0x1>;
			xlnx,all-inputs-2 = <0x0>;
			xlnx,dout-default = <0x0>;
			xlnx,dout-default-2 = <0x0>;
			xlnx,family = "spartan3adsp";
			xlnx,gpio-width = <0x4>;
			xlnx,gpio2-width = <0x20>;
			xlnx,interrupt-present = <0x1>;
			xlnx,is-dual = <0x0>;
			xlnx,tri-default = <0xffffffff>;
			xlnx,tri-default-2 = <0xffffffff>;
		} ;

 

Part of the log during driver initialization:

[    7.635430] Kruger driver init
[    7.637493] GPIO buttons: reg. size=65535 Bytes
[    7.642095] GPIO buttons: irq=1
[    7.645278] GPIO buttons: at 0x81400000 mapped to 0xC80A0000
[    7.651114] GPIO buttons module inserted successfully

 

The output file /proc /interrupt

CPU0       
  1:          0     level Xilinx INTC  Gpio Buttons
  2:     546096      edge Xilinx INTC  timer
  4:       1193      edge Xilinx INTC  uartlite

 

In what may be the problem?

Thanks in advance for any help!

 

0 Kudos
Reply
2 Replies
Visitor
Visitor
3,634 Views
Registered: ‎08-03-2011

zavhoz,

 

Did you ever figure out how to get your interrupt to respond?  I am at the same stage as you - I am trying to capture interrupts from my GPIO LED's on a Xilinx ML510 development board, and I can register the IRQ, but cannot get any interrupts.  Any light you can shed on what the issue was for you would be appreciated.

0 Kudos
Reply
Visitor
Visitor
3,606 Views
Registered: ‎07-06-2011

I know it's a little bit late to be responding to this thread, but I just wanted to point out one thing to future readers.  It is NOT ok to call blocking functions from an ISR.  This of course includes printk()!  This may be one of the issues that you are having.  Instead of printing from within the ISR, the ISR should notify some other part of the code that the interrupt occured and then exit immediately.

 

For a good discussion on how to get external interrupts working in general, this thread helpped me out significantly:

 

problem to request an IRQ in custom linux device driver

 

 

0 Kudos
Reply