This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Handling interrupt on gpio in driver module?

Hello all,

I am using gpio2_7( pin46-header8, lcd_data1) as the interrupt pin with my beaglebone.

I have seen a lot of examples explaining the settings of gpio for interrupt in user space using sysfs/poll mechanism. But i am interested in code for kernel space to set the mux configuration, setting direction as IN, and edge as falling.

I want to do it through driver init code. 

Just to confirm, if i am doing correctly, there is the code snippet

=======

#define BEAGLEBONE_CONTROL_PADCONF_MUX_PBASE 0x44E10000LU
#define BEAGLEBONE_CONTROL_PADCONF_MUX_SIZE 0x0B38

static int setup_pin_mux_interrupt(void)
{
void* adress;
if (request_mem_region(BEAGLEBONE_CONTROL_PADCONF_MUX_PBASE, BEAGLEBONE_CONTROL_PADCONF_MUX_SIZE,"MuxMem") == NULL)
printk("Error requesting mem reqion MUX_PBASE\n");

adress = (void *)ioremap (BEAGLEBONE_CONTROL_PADCONF_MUX_PBASE,BEAGLEBONE_CONTROL_PADCONF_MUX_SIZE);
if (adress == NULL)
{
printk("Error ioremap: MUX_PBASE\n");
return -1;
}

iowrite16(7, (adress+0x8A4)); // mode7 for lcd_data1
iounmap(adress);
release_mem_region(BEAGLEBONE_CONTROL_PADCONF_MUX_PBASE,BEAGLEBONE_CONTROL_PADCONF_MUX_SIZE);

return 0;
}

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

//As per 25.3.3.1section of TI_3352 manual.

#define BEAGLEBONE_GPIO2_REG_BASE 0x481AC000LU
#define BEAGLEBONE_GPIO2_REG_SIZE 0x0200

#define GPIO_IRQ_STATUS_SET_0 0x34
#define GPIO_IRQ_STATUS_SET_1 0x38
#define GPIO_IRQ_FALLING_DETECT 0x14C

static int setup_bb_interrupt(void)
{
void* adress;
if (request_mem_region(BEAGLEBONE_GPIO2_REG_BASE, BEAGLEBONE_GPIO2_REG_SIZE,"GPIO2Mem") == NULL)
printk("Error requesting mem reqion GPIO2_PBASE\n");

adress = (void *)ioremap (BEAGLEBONE_GPIO2_REG_BASE,BEAGLEBONE_GPIO2_REG_SIZE);
if (adress == NULL)
{
printk("Error ioremap: GPIO2_PBASE\n");
return -1;
}

iowrite32(0x00000080, (adress+GPIO_IRQ_STATUS_SET_0));
iowrite32(0x00000080, (adress+GPIO_IRQ_STATUS_SET_1));
iowrite32(0x00000080, (adress+GPIO_IRQ_FALLING_DETECT));

iounmap(adress);
release_mem_region(BEAGLEBONE_GPIO2_REG_BASE,BEAGLEBONE_GPIO2_REG_SIZE);

return 0;
}

;;;;;;;;;;;;;;;;;;;;

and then in the file i am calling above methods, in below sequence.

setup_pin_mux_interrupt();

setup_bb_interrupt();
gpio_direction_input(71);
irq_number = gpio_to_irq(71); //gpio2_7
irq_set_irq_type(irq_number, IRQ_TYPE_EDGE_FALLING);

MSG("irq number = %d\n",irq_number);
//this interrupt line will be shared among different drivers

if (( rc = request_irq( irq_number,pico6_irq_handler, IRQF_SHARED,PICO6_FPGA_ISR_NAME, &pico6_irq_handler )) != 0 )//I IRQF_DISABLED
{
MSG("registering irq request failed!!!!!\n");
return rc;
}
else
{
MSG("registering irq request success\n");
return SUCCESS;
}

===========

So my questions are,

1. Is this all i need to do, to use the gpio2_7 as interrupt, with falling edge, or please suggest?

2. On the dmesg i see the backtrace,

316.409280] ------------[ cut here ]------------

[ 316.409318] WARNING: at drivers/gpio/gpiolib.c:101 gpio_ensure_requested+0x50/0xd4()
[ 316.409331] autorequest GPIO-71
[ 316.409339] Modules linked in: PICO6_driver(O+) snd_soc_tlv320aic3x spidev iptable_nat nf_nat nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 ip_tables x_tables rfcomm ircomm_tty ircomm irda crc_ccitt hidp bluetooth rfkill autofs4
[ 316.409412] Backtrace:
[ 316.409456] [<c0010a54>] (dump_backtrace+0x0/0x110) from [<c04f7fb4>] (dump_stack+0x18/0x1c)
[ 316.409472] r6:c0651373 r5:00000065 r4:cf83de38 r3:60000093
[ 316.409512] [<c04f7f9c>] (dump_stack+0x0/0x1c) from [<c003ac64>] (warn_slowpath_common+0x54/0x6c)
[ 316.409539] [<c003ac10>] (warn_slowpath_common+0x0/0x6c) from [<c003ad20>] (warn_slowpath_fmt+0x38/0x40)
[ 316.409554] r8:80000013 r7:00000007 r6:00000047 r5:cf80857c r4:c076db54
[ 316.409576] r3:00000009
[ 316.409596] [<c003ace8>] (warn_slowpath_fmt+0x0/0x40) from [<c02d3988>] (gpio_ensure_requested+0x50/0xd4)
[ 316.409611] r3:00000047 r2:c065138a
[ 316.409634] [<c02d3938>] (gpio_ensure_requested+0x0/0xd4) from [<c02d3c90>] (gpio_direction_input+0x74/0x134)
[ 316.409650] r6:00000047 r5:cf80857c r4:bf156fdc r3:00000020
[ 316.409784] [<c02d3c1c>] (gpio_direction_input+0x0/0x134) from [<bf13d944>] (isr_init+0x278/0x34c [PICO6_driver])
[ 316.409800] r8:00000000 r7:bf160000 r6:00000001 r5:bf156784 r4:bf156fdc
[ 316.409822] r3:80000000
[ 316.409904] [<bf13d6cc>] (isr_init+0x0/0x34c [PICO6_driver]) from [<bf160038>] (pico6_drv_init+0x38/0x68 [PICO6_driver])
[ 316.409921] r4:bf154a7c
[ 316.409972] [<bf160000>] (pico6_drv_init+0x0/0x68 [PICO6_driver]) from [<c0008770>] (do_one_initcall+0x9c/0x16c)
[ 316.409989] r4:bf15673c r3:cf83c000
[ 316.410018] [<c00086d4>] (do_one_initcall+0x0/0x16c) from [<c0068040>] (sys_init_module+0x166c/0x17e4)
[ 316.410033] r8:00000001 r7:cfb36940 r6:00000001 r5:bf156784 r4:bf15673c
[ 316.410068] [<c00669d4>] (sys_init_module+0x0/0x17e4) from [<c000d6c0>] (ret_fast_syscall+0x0/0x30)
[ 316.410084] ---[ end trace 304ad18b61a07fad ]---
[ 316.410118] pico6_driver:0163:isr_init:irq number = 231
[ 316.410246] pico6_driver:0173:isr_init:registering irq request success
[ 316.410300] pico6_driver:0114:pico6_drv_init:driver loaded successfully

What's going wrong?

3. Do i need to enable some global interrupt registers???..No idea..please suggest?

br

Vikas

  • Vikas,

    Don't write mux setting directly to the register like 

    iowrite16(7, (adress+0x8A4)); // mode7 for lcd_data1. Here you are not setting the pin as input.You should have written 0x27 instead of 0x7.

    Its better to use the standard macro where it will be defined properly/ 

    Next thing is: Before calling gpio_direction_input(71); you should have called gpio_request(). That's why the crash is happening.