Hi, everyone,
dm368-mt5 ipnc2.60, in kernel mode mt9p031 i2c driver file ipnc\av_capture\framework\drv\kermod\src\dev_i2c.c, add udelay or hrtimer cause corrupt,
soure code as below( green part is modification, red part would cause system corrupt, why?),
struct hrtimer shutter_close_timer;
struct timer_list shutter_reopen_timer_list;
void shutter_timer2(unsigned long arg);
enum hrtimer_restart shutter_close_timer_cb(struct hrtimer *timer)
{
/* gpo81, alarm out
gns:17, fbc67068
gnc:17, fbc6706c
*/
//*(unsigned int *)0xfbc67068 = (1 << 17);
return HRTIMER_NORESTART;
}
void shutter_timer2(unsigned long arg)
{
*(unsigned int *)0xfbc6706c = (1 << 17);
del_timer(&shutter_reopen_timer_list);
}
int I2C_devIoctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
I2C_Obj *pObj;
int status=0;
I2C_TransferPrm transferPrm;
static ktime_t delay;
pObj = (I2C_Obj *)filp->private_data;
#ifdef I2C_DEBUG
printk(KERN_INFO "I2C: I2C_devIoctl() \n");
#endif
if(!I2C_IOCTL_CMD_IS_VALID(cmd))
return -1;
cmd = I2C_IOCTL_CMD_GET(cmd);
down_interruptible(&gI2C_dev.semLock);
switch(cmd)
{
case I2C_CMD_SET_DEV_ADDR:
……………………
break;
case I2C_CMD_WRITE:
status = copy_from_user(&transferPrm, (void *)arg, sizeof(transferPrm));
if(status==0) {
status = copy_from_user(gI2C_dev.reg, transferPrm.reg, transferPrm.count);
status |= copy_from_user(gI2C_dev.buffer, transferPrm.value, transferPrm.count*transferPrm.dataSize);
if(status==0) {
if(gI2C_dev.reg[transferPrm.count - 1] == 0xFF)
{
memcpy(&oldShutterGain[0], gI2C_dev.buffer + (transferPrm.count - 3)* transferPrm.dataSize, 3 * transferPrm.dataSize);
status = I2C_write(pObj, gI2C_dev.reg, gI2C_dev.buffer, transferPrm.count - 3, transferPrm.dataSize);
atomic_set(&frameNum, 0);
atomic_inc(&SnapShotRequest);
#if 0
delay = ktime_set(0, 30 * 1000 * 1000);
hrtimer_start(&shutter_close_timer, delay, HRTIMER_MODE_REL);
#endif
#if 0
udelay(10);
#endif
shutter_reopen_timer_list.expires = jiffies + 4;
shutter_reopen_timer_list.function = shutter_timer2;
add_timer(&shutter_reopen_timer_list);
}
else
{
status = I2C_write(pObj, gI2C_dev.reg, gI2C_dev.buffer, transferPrm.count, transferPrm.dataSize);
}
}
}
break;
case I2C_CMD_READ:
………………….
break;
default:
status = -1;
break;
}
up(&gI2C_dev.semLock);
return status;
}
int I2C_devInit(void)
{
int result, i;
dev_t dev = 0;
#ifdef I2C_DEBUG
printk(KERN_INFO "I2C: I2C_devInit() \n");
#endif
…………………………………..
shutter_close_timer.function = shutter_close_timer_cb;
hrtimer_init(&shutter_close_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
init_timer(&shutter_reopen_timer_list);
return result;
}