AnsweredAssumed Answered

interrupt not cleared

Question asked by Ronen Aharoni on Oct 27, 2019
Latest reply on Oct 28, 2019 by Ronen Aharoni

I'm running on Imx6dq 

I'v wrote simple char device  and I configured gpio1_1 operate as an interrupt 

here is my code 

 

my issue is that the isr is been call more the 1 since it not ack 

what I'm doing wrong 

 

Thanks 

/*
//Taken from https://stackoverflow.com/questions/15215865/netlink-sockets-in-c-using-the-3-x-linux-kernel?lq=1

#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/time.h>
#include <stddef.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/irq.h>
#include <asm/irq.h>//#include <stdlib.h>
#include <asm/gpio.h>


#include <linux/module.h>
#include <linux/version.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
//#include <mach/hardware.h>
#include <asm/gpio.h>

#define __WORDSIZE 0

#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
# define __uint32_t_defined
#endif
/* Unsigned. */
typedef unsigned char uint_fast8_t;
#if __WORDSIZE == 64
typedef unsigned long int uint_fast16_t;
typedef unsigned long int uint_fast32_t;
typedef unsigned long int uint_fast64_t;
#else
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
__extension__
typedef unsigned long long int uint_fast64_t;
#endif

 

#define FUNC_GPIO 0x5
#define MAX_SIZE (PAGE_SIZE * 2) /* max size mmaped to userspace */

#define NETLINK_USER 31

static char *sh_mem = NULL;

struct sock *nl_sk = NULL;
struct timeval tvStart ;
struct timeval tvStop ;
//float f1 ;
unsigned int base_addr = 0x02000000;
unsigned int base_offs = 0x00000000;
void* gpioAddr = 0 ;
ssize_t page_size = (1024*1024);

enum function_t {
FUNCTION_UNKNOWN = 0,
FUNCTION_DIGITAL = 2,
FUNCTION_ANALOG = 4,
FUNCTION_I2C = 16,
FUNCTION_INTERRUPT = 32
};

enum pinmode_t {
PINMODE_NOT_SET = 0,
PINMODE_INPUT = 2,
PINMODE_OUTPUT = 4,
PINMODE_INTERRUPT = 8
};

enum isr_mode_t {
ISR_MODE_UNKNOWN = 0,
ISR_MODE_RISING = 2,
ISR_MODE_FALLING = 4,
ISR_MODE_BOTH = 8,
ISR_MODE_NONE = 16
};

enum isr_mode_t_driver
{
LOW_LEVEL = 0x00 , //LOW_LEVEL — Interrupt n is low-level sensitive.
HIGH_LEVEL = 0x01 , //HIGH_LEVEL — Interrupt n is high-level sensitive.
RISING_EDGE = 0x10 , //RISING_EDGE — Interrupt n is rising-edge sensitive.
FALLING_EDGE = 0x11 , //FALLING_EDGE — Interrupt n is falling-edge sensitive.
};

enum pud
{
// Pull up/down/none

PUD_OFF = 0 ,
PUD_DOWN = 1 ,
PUD_UP = 2

};
enum intMask
{
MASK = 0 ,
UNMASK = 1 ,
};

enum digital_value_t {
LOW,
HIGH
};

enum gpioRegOffset {
DR = 0x0 , // Data Register
GDIR = 0x4 , // Direction Register
PSR = 0x8 , // Status Register
ICR1 = 0xC , // Interrupt Configuration Register1
ICR2 = 0x10 , // Interrupt Configuration Register2
IMR = 0x14 , // Interrupt Mask Register
ISR = 0x18 , // Interrupt Status Register
EDGE_SEL = 0x1C , // Edge Select Register
};


void soc_writel(uintptr_t addr, uint32_t val)
{
writel(val, (volatile void *)addr );
}

uint32_t soc_readl(uintptr_t addr)
{
return readl((const volatile void *)addr);
}


#define RONENDEV_MAJOR 190
int irqNo = 0 ;

static int gpio_num;

DECLARE_COMPLETION(work);
int static counter = 0 ;

static irqreturn_t handler (int irq, void * dev)
{
void* addrDatISR = NULL ;//( gpioAddr + ISR );
void* addrDatStatus = NULL ;//( gpioAddr + PSR );
uint32_t valIMR = 0x2 ;
uint32_t valStatus = 0 ;

addrDatISR = (void*)( gpioAddr + 0x9C000 + ISR );//( gpioAddr + ISR ); valStatus = ioread32( addrDatStatus );
addrDatStatus = (void*)( gpioAddr + 0x9C000 + PSR );//( gpioAddr + PSR ); printk("Status 0x%08X Occurred aaa 0x%08lX\n" , valStatus, ( unsigned long ) addrDatISR );

valStatus = ioread32( addrDatStatus );

iowrite32( 0x02 , addrDatISR );

valStatus = ioread32( addrDatStatus );


complete_all(&work);
return IRQ_HANDLED;
}


static int __init hello_init(void)
{
int status;
printk("Entering: %s\n",__FUNCTION__);

 


gpioAddr = ioremap( 0x2000000 , page_size );
if( gpioAddr )
printk("success to virutal mem \n");


init_completion(&work);

gpio_num = 1;

status = gpio_request(gpio_num, "gpio_test\n");

if (status < 0)
{
printk("ERROR can not open GPIO %d\n", gpio_num);
return status;
}

gpio_direction_input(gpio_num);
gpio_export(gpio_num, true);

if(gpio_get_value(gpio_num) == 0)
printk("OFF. \n\tWaiting for the pin to be on..\n");
else
printk("ON. \n\tWaiting for the pin to be off..\n");

irqNo = gpio_to_irq(gpio_num);
printk("gpio %d has irq %d \n" , gpio_num , irqNo );

status = request_irq(irqNo, handler, 0, "gpio_test", NULL);
if(status < 0)
{
printk(KERN_ERR "error %d requesting GPIO IRQ %d\n", status, gpio_num);
return status;
}

irq_set_irq_type(irqNo, IRQ_TYPE_EDGE_RISING);

wait_for_completion_interruptible(&work);

printk(".. done counter %d \n");

 

return 0;
}

static void __exit hello_exit(void)
{

free_irq(gpio_to_irq(gpio_num), NULL);
gpio_free(gpio_num);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

Outcomes