Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detecting interrupt on a GPIO line in Embedded Linux?

There is an interrupt being generated at every 10ms on GPIO_39 in the pandaboard OMAP4. I have registered a handler for this in Linux driver code, but the handler is not being called since the interrupt is not being detected.

I made sure at the hardware level (by probing the gpio pin) that the interrupt is actually being generated. It's only that the software is not being able to detect it.

I've the following in my driver code.

#define GPIO_NO     39

  iowrite16(0x3, gpio_39_address + 2); /* Configured the pin 22 to be used as gpio. */

  ret = gpio_request(GPIO_NO, "Claiming GPIO");
  if(ret < 0)
  {
    printk(KERN_ALERT "%s: Claiming GPIO_%d failed\n", __func__, GPIO_NO);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Claiming GPIO_%d successful\n", __func__, GPIO_NO);
  }

  ret = gpio_direction_input(GPIO_NO);  
  if(ret < 0)
  {
    printk(KERN_INFO "%s: Setting GPIO direction to input failed\n", __func__);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Direction of GPIO_%d set to input\n", __func__, GPIO_NO);
  }

  GPIO_IRQ = gpio_to_irq(GPIO_NO);

  if(GPIO_IRQ < 0)
  {
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ failed\n", __func__, GPIO_NO);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ_%d successful\n", __func__, GPIO_NO, GPIO_IRQ);
  }

  if((request_irq(GPIO_IRQ, ten_ms_int, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL)))
  {
    printk(KERN_ALERT "%s: requeseting GPIO_IRQ %d failed\n", __func__, GPIO_IRQ);
    return -1;
  }
  else
  {
    printk(KERN_INFO "%s: requesting GPIO_IRQ %d successful\n", __func__, GPIO_IRQ);
  }

irqreturn_t ten_ms_int(int irq, void *dev_id)
{
  T_UINT32 l;
  /* Enable spi channel */
  l = ioread32(spi_base + SPI_CHCONF0);
  l |= SPI_CHCONF0_FORCE;
  iowrite32(l, (spi_base +  SPI_CHCONF0));

  l = ioread32(spi_base + SPI_CHCTRL0);
  l |= SPI_CHCTRL_EN;
  iowrite32(l, (spi_base + SPI_CHCTRL0));

  /* Enable dma channel 0 */
  l = ioread32(sdma_base + SDMA_CCR(CHANNEL0));
  l |= SDMA_CCR_ENABLE;
  iowrite32(l, sdma_base + SDMA_CCR(CHANNEL0));

  /* Enable dma channel 1 */
  l = ioread32(sdma_base + SDMA_CCR(CHANNEL1));
  l |= SDMA_CCR_ENABLE;
  iowrite32(l, sdma_base + SDMA_CCR(CHANNEL1));
  //printk(KERN_INFO "%s: 10ms interrupt detected %d\n", __func__, irq); /* I know that I've to remove this printk statement */
  return IRQ_HANDLED;
}

GPIO_39 belongs to the bank GPIO2 and the corresponding interrupt number is 32. But, the return value of gpio_to_irq() is 199. This is another cause of concern.

Please let me know if something is wrong in the code or if I have missed something.

like image 705
Sagar Jain Avatar asked Jul 07 '14 10:07

Sagar Jain


1 Answers

Make the GPIO pin explicitly to detect falling edge.

At the gpio module level it is necessary to enable FALLING_DETECT of gpio.

like image 164
Sagar Jain Avatar answered Oct 05 '22 11:10

Sagar Jain