共享中断还是有冲突

wangweicumt1 2009-12-30 02:47:00
加精
我用的华天正电子科技生产的RealARM开发板,移植他提供的linux系统(2.4.18)。里面带了触摸屏驱动,我想再加上ADC驱动。但是加了ADC驱动到内核后,触摸屏不能使用了,没有反应。今天我试了把触摸屏驱动里的中断和ADC驱动里的中断设置成共享中断。还是加了ADC到内核,触摸屏不能使用。这是为什么呢?
我现在把我的驱动贴出来:
ADC驱动:
/*
* s3c2410-adc.c
*
* S3C2410 ADC
* exclusive with s3c2410-ts.c
*
* Author: SeonKon Choi <bushi@mizi.com>
* Date : $Date: 2003/01/20 14:24:49 $
*
* $Revision: 1.1.2.6 $
*
2004-6-14 add a device by threewater<threewater@up-tech.com>

Fri Dec 03 2002 SeonKon Choi <bushi@mizi.com>
- initial

*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/delay.h>

#include <asm/hardware.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>

#include "s3c2410-adc.h"

#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__);printk(##x);}
#else
#define DPRINTK(x...) (void)(0)
#endif

#define DEVICE_NAME "s3c2410-adc"
#define ADCRAW_MINOR 1

static int adcMajor = 0;

typedef struct {
struct semaphore lock;
wait_queue_head_t wait;
int channel;
int prescale;
}ADC_DEV;

static ADC_DEV adcdev;

#define START_ADC_AIN(ch, prescale) \
do{ \
ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ; \
ADCCON |= ADC_START; \
}while(0)

static void adcdone_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{
if(strcmp(dev_id,DEVICE_NAME)!=0)
return -1;
wake_up(&adcdev.wait);
}

static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
{
int data;

if(count!=sizeof(data)){
//error input data size
DPRINTK("the size of input data must be %d\n", sizeof(data));
return 0;
}

copy_from_user(&data, buffer, count);
adcdev.channel=ADC_WRITE_GETCH(data);
adcdev.prescale=ADC_WRITE_GETPRE(data);

DPRINTK("set adc channel=%d, prescale=0x%x\n", adcdev.channel, adcdev.prescale);

return count;
}

static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
int ret = 0;

if (down_interruptible(&adcdev.lock))
return -ERESTARTSYS;

START_ADC_AIN(adcdev.channel, adcdev.prescale);
interruptible_sleep_on(&adcdev.wait);

ret = ADCDAT0;
ret &= 0x3ff;
DPRINTK("AIN[%d] = 0x%04x, %d\n", adcdev.channel, ret, ADCCON & 0x80 ? 1:0);

copy_to_user(buffer, (char *)&ret, sizeof(ret));

up(&adcdev.lock);

return sizeof(ret);
}

static int s3c2410_adc_open(struct inode *inode, struct file *filp)
{
init_MUTEX(&adcdev.lock);
init_waitqueue_head(&(adcdev.wait));

adcdev.channel=0;
adcdev.prescale=0xff;

MOD_INC_USE_COUNT;
DPRINTK( "adc opened\n");
return 0;
}

static int s3c2410_adc_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
DPRINTK( "adc closed\n");
return 0;
}


static struct file_operations s3c2410_fops = {
owner: THIS_MODULE,
open: s3c2410_adc_open,
read: s3c2410_adc_read,
write: s3c2410_adc_write,
release: s3c2410_adc_release,
};

#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_adc_dir, devfs_adcraw;
#endif

int __init s3c2410_adc_init(void)
{
int ret;

/* normal ADC */
ADCTSC = 0; //XP_PST(NOP_MODE);

ret = request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_SHIRQ, DEVICE_NAME, NULL);
if (ret) {
return ret;
}

ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);
if (ret < 0) {
printk(DEVICE_NAME " can't get major number\n");
return ret;
}
adcMajor=ret;

#ifdef CONFIG_DEVFS_FS
devfs_adc_dir = devfs_mk_dir(NULL, "adc", NULL);
devfs_adcraw = devfs_register(devfs_adc_dir, "0raw", DEVFS_FL_DEFAULT,
adcMajor, ADCRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_fops, NULL);
#endif
printk (DEVICE_NAME"\tinitialized\n");

return 0;
}

module_init(s3c2410_adc_init);

#ifdef MODULE
void __exit s3c2410_adc_exit(void)
{
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_adcraw);
devfs_unregister(devfs_adc_dir);
#endif
unregister_chrdev(adcMajor, DEVICE_NAME);

free_irq(IRQ_ADC_DONE, NULL);
}

module_exit(s3c2410_adc_exit);
MODULE_LICENSE("GPL");
#endif

...全文
815 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
良少 2011-02-12
  • 打赏
  • 举报
回复
ret = request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_SHIRQ, DEVICE_NAME, NULL);
---:--—------------------
共享中断时,最后一个参数不能是null,否则报错,中断处理函数注册失败!
随便填个数据进去吧。
y452181221 2010-10-27
  • 打赏
  • 举报
回复
不以逸待劳
y452181221 2010-10-27
  • 打赏
  • 举报
回复
i tdoedl
jayis520 2010-07-29
  • 打赏
  • 举报
回复
这不是还是没解决这个问题,到底dev_id是谁来赋值的,是内核还是写程序的人,然后赋的到底是什么值?
还有就是在中断处理函数中,怎么可以用if(strcmp(dev_id, DEVICE_NAME) !=0)
return -1
来判断到底是哪个中断???
如果是这样的话,就说了dev_id中的值是设备名咯?那楼主你什么时候将设备名写入到dev_id中,我怎么没看到???????
希望哪些高手看到我的留言能给我一个解答,谢谢啊!!!
勇往直前! 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 pottichu 的回复:]
ret = request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_SHIRQ, DEVICE_NAME, NULL);

汗, 实在是对不住楼主。 应该是最后一个参数必须唯一才行,之前没注意看到你的留言才发现。
关于你的问题, 你要查看一下硬件手册, ADC 和 触摸平 的中断方式是不是一样。
另外要检查一下 ADC 的驱动中,是否有对 62……
[/Quote]
UP
upc_zongchao 2010-01-31
  • 打赏
  • 举报
回复
好好学习下 一直没怎么搞明白呢 呜呜
austinT 2010-01-10
  • 打赏
  • 举报
回复
学习学习!!
hj26511314 2010-01-10
  • 打赏
  • 举报
回复
学习
ivfangwang_long 2010-01-10
  • 打赏
  • 举报
回复
帮顶~~~~~~~~~~~~~~~~~~~~~~~
jiang608 2010-01-10
  • 打赏
  • 举报
回复
来学习下
IThurricane 2010-01-10
  • 打赏
  • 举报
回复
学习一下
daxiao474 2010-01-10
  • 打赏
  • 举报
回复
了不起
「已注销」 2010-01-10
  • 打赏
  • 举报
回复
DDDDDDDDDDDDDDDDDDDDDDDD
viennaji 2010-01-09
  • 打赏
  • 举报
回复
我进来参观一下
jiejiejiej 2010-01-09
  • 打赏
  • 举报
回复
前排占座拜读楼主大作
ITCore168 2010-01-09
  • 打赏
  • 举报
回复
太多,看不懂!
cxj6789583 2010-01-09
  • 打赏
  • 举报
回复
不知道啊
llwapi 2010-01-08
  • 打赏
  • 举报
回复
ceilinglee 2010-01-08
  • 打赏
  • 举报
回复
學習
xuezhonghuo22 2010-01-08
  • 打赏
  • 举报
回复
学习~~
加载更多回复(52)

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧