아래의 소스는 인터럽트 테스트를 위해 만드 디바이스 드라이버 입니다.


gpio 10번 핀에 스위치를 연결하여 인터럽트가 발생하면 wait queue에 스케줄
하여 재 기동하려고 합니다.

스위치를 누르면 정상적으로 인터럽트 서비스루틴으로는 가는데...
그런데 아래부분에 표시해 놓은 부분에서 다시 깨어 나질 않습니다.
wakeupg함수에서 에러가 나는 것 같습니다.
이분에서 시스템(이지보드)가 다운 됩니다.

한가지더 테스트목적으로 간다한게 즉, 필요 없다구 생각되는 부분은 뺐습니
다. 근데 꼭들어가야 될 부분도 뺀것이 아니가 하는 생각이 듭니다.
혹시 그런 부분이 있다면 조언 부탁 드리겠습니다.

감사합니다.



extern void set_GPIO_IRQ_edge( int gpio_mask, int edge_mask );
static DECLARE_WAIT_QUEUE_HEAD(queue);

static int i;

void cleanup_module(void)
{
printk("GPIO RELEASE
");
free_irq(10,"NAME");
unregister_chrdev( 253, "GPIO2");

}

static int gpio_open(struct inode *inode, struct file *file)
{

GAFR = 0x00000000;
GPDR = 0xFF0;
GPSR = 0xFF0;
GPCR = 0x000;


printk("<1>GPIO OPEN
");

MOD_INC_USE_COUNT; // 사용수 증가.
return 0;
}

static int gpio_write(struct file *file, const char *data, size_t len,
loff_t *ppos)
{
static const char *gpiodata;
unsigned int c=0;
gpiodata = data;
get_user(c,gpiodata);
GPSR=0xFFF;

GPCR=0x0F0;
GPCR=(unsigned int )(GPCR|c);
printk("<1>level %x
",GPLR);
printk("<1>GPIO write
");
//GPCR=0x000;
return len;
}

static int gpio_read(struct file *file, char *data, size_t len, loff_t
*ppos)
{
DECLARE_WAITQUEUE(wait,current);
short temp[2];
temp[0]=i;

printk("<1>interrupt-1
");

add_wait_queue(&queue,&wait);
current->state = TASK_INTERRUPTIBLE;
printk("<1>interrupt-s
");

schedule();

printk("<1>interrupt-sn
");

current->state = TASK_RUNNING;
remove_wait_queue(&queue,&wait);
printk("<1>interrupt-e
");
return len;
//put_user(data,temp);
}

static int gpio_release(struct inode *inode, struct file *file)
{
printk("<1>GPIO close
");
MOD_DEC_USE_COUNT; // 모듈 사용횟수를 감소 시킨다.
return 0;
}

static struct file_operations gpio_fops =
{
open: gpio_open,
read: gpio_read,
release: gpio_release,
write: gpio_write,
};


static void hd_irq_call(int irq,void *dev_id, struct pt_regs *regs)
{
disable_irq(10);

printk("<1>interrupt-call-s
");

printk("<1>int %d
",i);

i++;

printk("<1>interrupt-call-m
");
/*********************에러 나는 부분 ***********************
wake_up_interruptible(&queue);
*****************************************************/


printk("<1>interrupt-call-e
");

enable_irq(10);
}


int init_module(void )
{
int result;
printk("


-- GPIO --
");
i=0;
result=register_chrdev( 253,"GPIO2", &gpio_fops);

if (result < 0)
{
printk(KERN_WARNING "GPIO: Can't get Major Number

");
return result;
}

request_irq
(10,hd_irq_call,SA_SHIRQ|SA_INTERRUPT,"NAME","NAME");
GPSR=~0xF0FF;
set_GPIO_IRQ_edge(1< enable_irq(10);
init_waitqueue_head(&queue);
return 0;

}