I have written device driver to request an interrupt using GPIO pin. Once I gave the GPIO interrupt then the system is getting hanged. Only one time I am able to check the dmesg output in which the interrupt handler is continuosly running with printk() output. To stop the interrupt, i have used disable_irq() inside handler but still the system is hanging once raise the GPIO interrupt. Only Interrupt related program is pasted below and the driver code is not mentioned as it calls the interrupt function. I have commented tasklet_schedule() in the interrupt handler since interrupt itself is not running properly.
Also note that some of the code is written in actual driver and the gpio_pin_to_irq() is calling from driver init function.
Also note that some of the code is written in actual driver and the gpio_pin_to_irq() is calling from driver init function.
Code:
#ifndef__INTERRUPT_H__#define__INTERRUPT_H__#include <linux/gpio.h>#include <linux/interrupt.h>struct tasklet_struct *tasklet;// just tasklet variableunsigned long data = 10000;int gpio_irq_num;void gpio_pin_to_irq(void);static irqreturn_t handler(int irq, void *name);void tasklet_init(struct tasklet_struct *, void (*)(unsigned long), unsigned long);void tasklet_fun(unsigned long); // tasklet execution function//DECLARE_TASKLET(tasklet, tasklet_fun); // initializing taskletunsigned char lcd_text_3[] = "GPIO Int receiveed";unsigned int gpio_interrupt_pin[] = {/* Below pins are connected to 16x2 LCD pins except 0 and 1 */0, /* Du mmy val as pin GPIO0 is not to use */1, /* Dummy val as pin GPIO1 is not to use */2, /* RS pin */ /* R/W pin is directly grounded */3, /* Enable pin */4, /* Data d0 pin */5, /* Data d1 pin */6, /* Data d2 pin */7, /* Data d3 pin */8, /* Data d4 pin */9, /* Data d5 pin */10, /* Data d6 pin */11, /* Data d7 pin */12, /* LED test pin *//* Below pins are for testing gpio interrupt */13, /* Interrupt pin */14, /* LED for interrupt handler */15, /* LED for interrupt handler */};void tasklet_fun(unsigned long val){int i = 0;tasklet_disable(tasklet);printk(KERN_INFO "tasklet has been started\n");// writing data to lcd first linelcd_cmd(0x01);for(i = 0; lcd_text_3[i]; i++){lcd_data(lcd_text_3[i]);}// testing led at gpio14 & gpio15for(i = 0; i < 10; i++){GPIO_SET(1<<gpio_interrupt_pin[14]);GPIO_CLR(1<<gpio_interrupt_pin[15]);msleep(500);GPIO_SET(1<<gpio_interrupt_pin[15]);GPIO_CLR(1<<gpio_interrupt_pin[14]);msleep(500);}tasklet_enable(tasklet);}static irqreturn_t handler(int gpio_irq_num, void *name){disable_irq(gpio_irq_num);//int i = 0;printk(KERN_INFO "interrupt has raised\n");/*// writing data to lcd first linelcd_cmd(0x01);for(i = 0; lcd_text_3[i]; i++){lcd_data(lcd_text_3[i]);}// testing led at gpio14 & gpio15for(i = 0; i < 10; i++){GPIO_SET(1<<gpio_interrupt_pin[14]);GPIO_CLR(1<<gpio_interrupt_pin[15]);msleep(500);GPIO_SET(1<<gpio_interrupt_pin[15]);GPIO_CLR(1<<gpio_interrupt_pin[14]);msleep(500);}*/printk(KERN_INFO "interrupt work will be done in scheduled tasklet at later time in same CPU\n");//tasklet_schedule(tasklet);return IRQ_HANDLED;}void gpio_pin_to_irq(){int i = 0;/*if((i = gpio_request(gpio_interrupt_pin[13], "myInt")) < 0) {printk("GPIO request failure for %d th pin\n", gpio_interrupt_pin[13]);return;}*/u32 *gpio = ioremap(GPIO_BASE_ADDR, SZ_16K);#defineGPIO_IN_FUN(pin)*(gpio+((pin)/10)) &= ~(7<<(((pin)%10)*3))#defineGPIO_OUT_FUN(pin)*(gpio+((pin)/10)) |= ((GPIO_IN_FUN(pin)) | (1<<(((pin)%10)*3)))for(i = 13; i <= 13; i++) /* only chnaging gpio 13 for interrupt purpose */{GPIO_OUT_FUN(i);}printk(KERN_INFO "pins selected as output successfully\n");if((gpio_irq_num = gpio_to_irq(gpio_interrupt_pin[13])) < 0) {printk("GPIO to IRQ mapping failure %d th pin\n", gpio_interrupt_pin[13]);return;}printk(KERN_INFO "ret val of gpio_to_irq():%d\n", gpio_irq_num);if(request_irq(gpio_irq_num, handler, IRQF_TRIGGER_HIGH,\DEVICE_NAME, "myInt")) {printk("Irq Request failure for %d th pin\n", gpio_interrupt_pin[13]);return;}iounmap(gpio);#undefGPIO_IN_FUN#undefGPIO_OUT_FUNtasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);if(tasklet == NULL){printk(KERN_INFO "memory allocation failed for tasklet");}tasklet_init(tasklet, tasklet_fun, data);}#endif
Statistics: Posted by bhaskarauvsp — Wed Jan 17, 2024 4:39 pm — Replies 5 — Views 105