interrupt not cleared

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

interrupt not cleared

682 Views
ronen_aharoni
Contributor I

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");

Labels (1)
0 Kudos
2 Replies

575 Views
igorpadykov
NXP Employee
NXP Employee

Hi Ronen

for gpio interrupt one can look at touchscreen drivers examples, like

[v2,1/2] Input: egalax_ts: get gpio from devicetree node - Patchwork 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

575 Views
ronen_aharoni
Contributor I

Hello Igor

Thanks for the answer 

but I'm still dont understand how the interrupt cleared at the ISR .

My issue is that the ISR is been called many times 

0 Kudos