This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

a strange kernel mode udelay or hrtimer usage problem in dm368 ipnc2.60

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;

}