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.

Sitara PSP interrupt problem

Other Parts Discussed in Thread: AM3358, TPS65217

Greetings!

I'm using BeagleBone Black (Sitara AM3358) with a LED connected to pin GPIO2_1 and a button with a 3k3 pull-up on GPIO0_7. I want the LED to reflect the state of the push button. I've written a simple device driver.

However I get no interrupt. I can see the correct value of the GPIO with:

cat /sys/kernel/debug/gpio

so it's not a hardware problem. If I do this:

cat /proc/interrupts

I see that my device driver gets no interrupt:

           CPU0       
  7:          1      INTC  tps65217
 12:       5293  INTC  edma
 14:          0     INTC  edma_error
 18:       3436  INTC  musb-hdrc.0.auto
....

135:          0    GPIO  gpio_test    <--- THIS IS FROM MY MODULE


Once I managed to get it working but I did not do anything special ... it just started by itself, randomly. Any help is appreciated!

#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>

static unsigned int irq_num;

void gpio_handler(void)
{
	if(gpio_get_value(7)){
		gpio_direction_output(65, 1);
	}else{
		gpio_direction_output(65, 0);
	}
}

static int __init thirddrv_init(void)
{
	printk("*******thirddrv init *******\n");

	gpio_request(7, "thirdingpio");
	gpio_direction_input(7);
	irq_num = gpio_to_irq(7);
	request_irq(irq_num, (irq_handler_t)gpio_handler, 0, "gpio_test", NULL);

	gpio_request(65, "thirdoutgpio");
	gpio_direction_output(65, 1);

	return 0;
}

static void __exit thirddrv_exit(void)
{
	printk("*******thirddrv exit*******\n");
	gpio_direction_output(65, 0);
	gpio_free(65);

	free_irq(irq_num, NULL);
	gpio_free(7);
}

module_init(thirddrv_init);
module_exit(thirddrv_exit);

MODULE_AUTHOR("L.B.");
MODULE_DESCRIPTION("BeagleBone Black toggle a 0.5 mA LED on GPIO2_1 when GPIO0_7 is pressed. Device driver.");
MODULE_LICENSE("GPL");

  • Hi Lubomir,

    Moved your post to correct forum.

    Use TI E2E Linux forum for general linux queries for all TI processors.

    http://e2e.ti.com/support/embedded/linux/f/354

    Use TI E2E Sitara E2E forum for sitara specfied problem.

    http://e2e.ti.com/support/arm/sitara_arm/f/
  • Have you done pinmux properly to access the GPIO 7 ?

    Put some printk & change the handler function like below.

    static irqreturn_t gpio_handler(int irq, void *dev_id, struct pt_regs *regs)
    
    {
    
    printk("Interrupt generated and IRQ is %d  \n",irq);
    
    /*
    
       if(gpio_get_value(7)){
    
           gpio_direction_output(65, 1);
    
       }else{
    
           gpio_direction_output(65, 0);
    
       }
    
    */
    
    return IRQ_HANDLED;
    
    }

    Try to probe GPIO 7 to check the transition while you press the switch which is connected to GPIO 7.

  • I did put a printk( ) in the handler - for the short time of its working life I was able to see the printk message. When it stopped working - I could not see the message anymore. I tried your code - I can't see the printk message either.

    About the pinmuxing - I thought gpio_request( ) and gpio_direction_input( ) did that?
    Still I did try the following:

    cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pins

    which yielded:

    pin 7 (44e1081c) 00000031 pinctrl-single
    pin 65 (44e10904) 00000030 pinctrl-single

    which is WRONG! The correct values are 0x37 (input) and 0x07 (output). As you guessed, I recompiled the DTB tree, rebooted and still the values are 0x31 and 0x30.

    I am completely confused now, cus I can see the correct logic value on GPIO2_1, meaning that the pinmuxing for this pin is correct.
  • Hi Lubomir,

    About the pinmuxing - I thought gpio_request( ) and gpio_direction_input( ) did that?

    No.

    Please make sure that you have done pinmuxing correctly.

    To avoid confusions, try to add pinmuxing stuff in driver itself.

    And also try to read the "0x44e1081c" address for GPIO pinmuxing through "devmem2" or "devmem" tool to cross verify the value.

    #include <linux/module.h>
    #include <linux/gpio.h>
    #include <linux/interrupt.h>
    #include <linux/irq.h>
    static unsigned int irq_num;
    void gpio_handler(void)
    {
    
    printk("Interrupt generated and IRQ is %d  \n",irq);
    
    
        if(gpio_get_value(7)){
            gpio_direction_output(65, 1);
        }else{
            gpio_direction_output(65, 0);
        }
    
    return IRQ_HANDLED;
    
    }
    static int __init thirddrv_init(void)
    {
        printk("*******thirddrv init *******\n");
    
    /* Newly added */
        volatile  unsigned int *PINMUX_GPIO = PINMUX_GPIO = ioremap(0x44e1081c,4); /* Doing pinmux for GPIO 7 */
        *PINMUX_GPIO = 0x37; /* To configure as a GPIO 7 */
    
    //TODO : Need to add the same for GPIO 65
    
    
        gpio_request(7, "thirdingpio");
        gpio_direction_input(7);
        irq_num = gpio_to_irq(7);
        request_irq(irq_num, (irq_handler_t)gpio_handler, 0, "gpio_test", NULL);
        gpio_request(65, "thirdoutgpio");
        gpio_direction_output(65, 1);
        return 0;
    }
    static void __exit thirddrv_exit(void)
    {
        printk("*******thirddrv exit*******\n");
        gpio_direction_output(65, 0);
        gpio_free(65);
        free_irq(irq_num, NULL);
        gpio_free(7);
    }
    module_init(thirddrv_init);
    module_exit(thirddrv_exit);
    MODULE_AUTHOR("L.B.");
    MODULE_DESCRIPTION("BeagleBone Black toggle a 0.5 mA LED on GPIO2_1 when GPIO0_7 is pressed. Device driver.");
    MODULE_LICENSE("GPL");
    

  • The suggested code does not work. The pinmuxing is successful this time with the ioremap( ) but no interrupt is generated. Furthermore - if I load this code I get trouble with the MMC memory - I get I/O errors which end up in a system crash!

    At first I thought that the pins are connected somewhere on the board - but this is not the case. The pins are free, I believe. I will continue to investigate the problem and if I come up with a solution I will post it!
  • OK, I got it working!

    You MUST specify the interrupt edge IRQF_TRIGGER_FALLING in:

    request_irq(irq_num, (irq_handler_t)gpio_handler, IRQF_TRIGGER_FALLING, "gpio_test", NULL);

    I had written 0 instead of it, which corresponded to IRQF_TRIGGER_NONE and meant that the default interrupt source would be used. But since this interrupt might not had been enabled previously, I was getting nothing at all.
    The Linux PSP GPIO Driver Guide suggests using set_irq_type( ); but I was not able to find it in my kernel and omitted this call. Well ... costed me two days for that! :-)

    I also had another mistake in the handler itself - the code does not toggle the LED, the code just turns it off the first time and is never turned on again. I've fixed this in my code below.

    Also - look ... I'm not pinmuxing ... I guess the default pinmux is GPIO.

    Thank you, once again, Titusrathinaraj for your time!

    #include <linux/module.h>
    #include <linux/gpio.h>
    #include <linux/interrupt.h>
    #include <linux/irq.h>

    static unsigned int irq_num;

    void gpio_handler(void)
    {
    static int flag = 0;
    if(flag){
    gpio_direction_output(65, 1);
    flag = 0;
    }else{
    gpio_direction_output(65, 0);
    flag = 1;
    }
    }

    static int __init thirddrv_init(void)
    {
    int err;
    printk("*******thirddrv init *******\n");

    gpio_request(7, "thirdingpio");
    gpio_direction_input(7);
    irq_num = gpio_to_irq(7);
    err = request_irq(irq_num, (irq_handler_t)gpio_handler, IRQF_TRIGGER_FALLING, "gpio_test", NULL);
    printk("request_irq( ) = %d\n", err);

    gpio_request(65, "thirdoutgpio");
    gpio_direction_output(65, 1);

    return 0;
    }

    static void __exit thirddrv_exit(void)
    {
    printk("*******thirddrv exit*******\n");
    gpio_direction_output(65, 0);
    gpio_free(65);

    free_irq(irq_num, NULL);
    gpio_free(7);
    }

    module_init(thirddrv_init);
    module_exit(thirddrv_exit);

    MODULE_AUTHOR("L.B.");
    MODULE_DESCRIPTION("BeagleBone Black toggle a 0.5 mA LED on GPIO2_1 when GPIO0_7 is pressed. Device driver.");
    MODULE_LICENSE("GPL");
  • I'm glad that you were able to solve the problem.
    Thanks for your update.