HI to all,
I am trying to enable GPIO interrupt on DM6446, i have written a code but getting error
i am using GPIO # 3,GPIOBANK 0,IRQ # 1
please guide me where i went wrong
following error is coming
Error requesting GPIO irq 56: returned -22
source code
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <asm/system.h>
#include <linux/kernel.h>
#include <linux/delay.h> // udelay()
#include <linux/fs.h> // everything...
#include <asm/uaccess.h> // copy_from/to_user
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/signal.h>
#include <linux/irq.h>
#include <linux/random.h>
// Definition for ASP Base Address and the local Power or Sleep Controller LPSoC
#include </root/Desktop/linux/kernel/git/khilman/linux-davinci.git/arch/arm/mach-davinci/include/mach/hardware.h>
#include </root/Desktop/linux/kernel/git/khilman/linux-davinci.git/arch/arm/mach-davinci/include/mach/clock.h>
#include </root/Desktop/linux/kernel/git/khilman/linux-davinci.git/include/linux/clk.h>
/***************************FUNCTION PROTOTYPE*************************/
int gpio_open(struct inode *inode, struct file *filp);
int gpio_release(struct inode *inode, struct file *filp);
ssize_t gpio_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t gpio_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
static void gpio_exit(void);
static int gpio_init(void);
void gpio_interrupt_handler(void);
/*************************************************************************/
#define GPIO_REG(reg) (*(int *__iomem) IO_ADDRESS(reg))
/********************************DEFINITION*******************************/
#define DM6446_GPIO_BASE 0x01C67000
#define BINTEN (DM6446_GPIO_BASE + 0x8) //GPIO Interrupt Per Bank Enable
#define DIR01 (DM6446_GPIO_BASE + 0x10) //GPIO Bank O & 1 Direction Register GPIO[0:31]
#define OUT_DATA01 (DM6446_GPIO_BASE + 0x14) //GPIO Bank O & 1 Data Register GPIO[0:31]
#define SET_DATA01 (DM6446_GPIO_BASE + 0x18) //GPIO Bank O & 1 Set Data Register GPIO[0:31]
#define CLR_DATA01 (DM6446_GPIO_BASE + 0x1C) //GPIO Bank O & 1 Clear Data for Bank 0 and 1
#define IN_DATA01 (DM6446_GPIO_BASE + 0x20) //GPIO Bank O & 1 Input Data Register
#define SET_RIS_TRIG01 (DM6446_GPIO_BASE + 0x24) //GPIO Bank O & 1 Set Rising Edge Interrupt Register
#define CLR_RIS_TRIG01 (DM6446_GPIO_BASE + 0x28) //GPIO Bank O & 1 Clear Rising Edge Interrupt Register
#define SET_FALL_TRIG01 (DM6446_GPIO_BASE + 0x2C) //GPIO Bank O & 1 Set Falling Edge Interrupt Register
#define CLR_FAL_TRIG01 (DM6446_GPIO_BASE + 0x30) //GPIO Bank O & 1 Clear Falling Edge Interrupt Register
#define INSTAT (DM6446_GPIO_BASE + 0x34) //Gpio Bank 0 & 1 Interrupt Status Register.
#define DM6446_DEV_BASE 0x01E02000
#define PCR (DM6446_DEV_BASE + 0x38)//Pin Control Register
#define PINMUX1 0x01c40004 // Definition for GPIO Pin Multiplexing
#define MDCTL17 0x01C41A44 // Module Control 17 Register (ASP)
#define PTCMD 0x01C41120 // Power Domain Transition Command Register
#define PTSTAT 0x01C41128 // Power Domain Transition Status Register
#define MAJOR_VERSION 58 // Version Number
#define MINOR_VERSION 01 // Version Number
#define IRQ1 0x01C4800C // Interrupt Request Status Register
#define EINT1 0x01C4801C // Interrupt Enable Register
#define INTPRI6 0x01C48048 // Interrupt Proirty
#define EABASE 0x01C48024 // Interrupt Entry Table Base Address
#define IRQENTRY 0x01C48047 // Entry Address for Valid IRQ
#define SA_INTERRUPT 0
//#define GpioIrq 1
/*************************************************************************/
/*************************Variable Declaration****************************/
unsigned int *binten;
unsigned int *dir01;
unsigned int *out_data01;
unsigned int *set_data01;
unsigned int *clr_data01;
unsigned int *in_data01;
unsigned int *set_ris_trig01;
unsigned int *set_fall_trig01;
unsigned int *clr_ris_trig01;
unsigned int *clr_fall_trig01;
unsigned int *instat;
unsigned int *pcr;
int GpioIrq;
int i;
GpioIrq = 56;
/*************************************************************************/
/*************************************************************************/
/**********************Structure for File Operation***********************/
static struct file_operations gpio_fops = {
read: gpio_read,
write: gpio_write,
open: gpio_open,
release: gpio_release
};
/*************************************************************************/
static int gpio_init(void)
{
int result;
int GpioIntRet;
result = register_chrdev(MAJOR_VERSION, "gpio", &gpio_fops); /* Registering device */
if (result < 0)
{
printk("<1>\nGPIO_INT: cannot obtain major number %d\n", MAJOR_VERSION);
return result;
}
/*
binten = (unsigned int *)ioremap(BINTEN,4);
dir01 = (unsigned int *)ioremap(DIR01,4);
out_data01 = (unsigned int *)ioremap(OUT_DATA01,4);
set_data01 = (unsigned int *)ioremap(SET_DATA01,4);
clr_data01 = (unsigned int *)ioremap(CLR_DATA01,4);
in_data01 = (unsigned int *)ioremap(IN_DATA01,4);
set_ris_trig01 = (unsigned int *)ioremap(SET_RIS_TRIG01,4);
clr_ris_trig01 = (unsigned int *)ioremap(CLR_RIS_TRIG01,4);
set_fall_trig01 = (unsigned int *)ioremap(SET_FALL_TRIG01,4);
clr_fall_trig01 = (unsigned int *)ioremap(CLR_FAL_TRIG01,4);
instat = (unsigned int *)ioremap(INSTAT,4);
pcr = (unsigned int *)ioremap(PCR,4);
*/
printk("<1>\nInserting GPIO module\n");
/**************************************************************/
GPIO_REG(IRQ1)=0x01000000; //GPIO0 INTERRUPT NUMBER = 48 BIT # 17
GPIO_REG(EINT1)=0x01000000; //INTERRUPT ENABLE
GPIO_REG(INTPRI6) = (GPIO_REG(INTPRI6) & 0xFFFFFFFF ) | ( 0x00000003 ); //INTERRUPT PIRIORITY
//ASP_REG(INTCTL);
GPIO_REG(DIR01)=0x00000008;
GPIO_REG(BINTEN)=0x00000001;
printk("<1>GPIO_SET_INT: %x\n", GPIO_REG(BINTEN));
GPIO_REG(SET_RIS_TRIG01)=0x00000008;
GPIO_REG(EABASE)=0x00000000;
GPIO_REG(IRQENTRY)=GPIO_REG(EABASE)+(GpioIrq+1)*4;
/********************GPIO NTERRRUPT*******************/
//GpioIntRet = request_irq(GpioIrq, gpio_interrupt_handler, SA_INTERRUPT, "gpio",NULL);
GpioIntRet = request_irq(GpioIrq, gpio_interrupt_handler, 0,"gpio",NULL);
if (GpioIntRet)
{
printk ("Error requesting GPIO irq 56: returned %d\n", GpioIntRet);
}
enable_irq(GpioIrq);
/**************************************************************/
return 0;
}
/****************************************INTERRUPT HANDLER*****************************************/
void gpio_interrupt_handler(void)
{
GPIO_REG(SET_DATA01)=0x00000040;
msleep(100);
//printk("\nGPIO INTERRUPT HANDLER");
}
/*********************************************Release Function*************************************/
int gpio_release(struct inode *inode, struct file *filp)
{
// Next State = Disable for the ASP Module
GPIO_REG(MDCTL17) = 0x00;
printk("<1>\nMDCTL17: %x\n", GPIO_REG(MDCTL17));
// Disable the ASP pins on the GPIO
//ASP_REG(PINMUX1) &= ~(0x00000000 | (0x1 << 10)); // ASP Multiplex
printk("<1>PINMUX1: %x\n", GPIO_REG(PINMUX1));
iounmap(binten);
iounmap(dir01);
iounmap(out_data01);
iounmap(in_data01);
iounmap(clr_data01);
iounmap(set_data01);
iounmap(set_ris_trig01);
iounmap(clr_ris_trig01);
iounmap(set_fall_trig01);
iounmap(clr_fall_trig01);
iounmap(instat);
return 0;
}
/**************************************************************************************************/
int gpio_open(struct inode *inode, struct file *filp)
{
/* Power Up the ASP Device*/
//unsigned int control=0;
/*Next State = Enable for the ASP Module*/
GPIO_REG(MDCTL17) = 0x03;
/* Enable State Transition*/
GPIO_REG(PTCMD) = 0x1; // Start power state transition for ALWAYSON
while((GPIO_REG(PTSTAT) & 0x1) != 0); /* Wait for power state transtion to finish */
printk("<1>\nPTSTAT: %x\n", GPIO_REG(PTSTAT));
GPIO_REG(PINMUX1) = 0x00000000;
mdelay(100);
printk("<1>BINTEN: %x\n", GPIO_REG(BINTEN));
printk("<1>SET_RIS_TRIG01: %x\n", GPIO_REG(SET_RIS_TRIG01));
printk("<1>XCR: %x\n", (unsigned int)ioread32((void *)binten));
printk("<1>SPCR: %x\n", (unsigned int)ioread32((void *)set_ris_trig01));
return 0;
}
/*********************************************Exit Function****************************************/
static void gpio_exit(void)
{
/* Freeing the major number */
unregister_chrdev(MAJOR_VERSION, "gpio");
gpio_release(0, 0);
disable_irq(GpioIrq);
free_irq(GpioIrq, gpio_interrupt_handler);
printk("<1>\nRemoving GPIO module\n");
}
/**************************************************************************************************/
/**************************************************************************************************/
/******************************************Read Function*******************************************/
ssize_t gpio_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
//short *data=0;
//unsigned char tmp[2];
//data = (unsigned int)ioread32((void *)drr);
// tmp[0] = data;
// tmp[1] = data>>8;
// do
// {
// spcrr = (unsigned int)ioread32((void *)spcr);
// }
// while((spcrr & RRDY) != RRDY); ////wait for recieve ready
// copy_to_user(buf,tmp,2);
return count;
}
/**************************************************************************************************/
/**************************************************************************************************/
ssize_t gpio_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
//unsigned int spcrr=0;
//unsigned char tmp[2];
//short *data;
//unsigned int XRDY = (0x00000000 | (0x1 << 17));
//copy_from_user(tmp,buf,2);/////copy the array from user
//data = (short *)tmp;//////type cast to the short value
//printk("%x\n",*data);
//printk("%x\n",tmp[1]);
//////////////////////////////////////////////////////////////////////////////////////////
//do
//{
// spcrr = (unsigned int)ioread32((void *)spcr);
//}
//////////////////////////////////////////////////////////////////////////////////////////
//while((spcrr & XRDY) != XRDY); // Wait for Transmitter ready
//iowrite32((unsigned int)(*data),(void *)dxr);//////transmit the value
return count;
}
MODULE_LICENSE("Dual BSD/GPL");
module_init(gpio_init);
module_exit(gpio_exit);