2011-7-31 12:59:42

来源:互联网 发布:tda100软件下载 编辑:程序博客网 时间:2024/05/17 02:26
 2011-7-31 12:59:42


int ipmc_init_sysop(void)
{
 int i, j, step;
 struct ipmc_ioctl_getfvopinfo get_fv_op_info;
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,21)
 struct pxa3xx_fv_info *fv_info;
#else
 struct mhn_fv_info *fv_info;
#endif
 int skip_cnt = 0;

 /* get operating points supported by kernel */
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,21)
 if (ioctl(ipmc_fd, IPMC_IOCTL_GET_FV_OP_COUNT, &pxa3xx_por_op_nr)){
#else
 if (ioctl(ipmc_fd, IPMC_IOCTL_GET_FV_OP_COUNT, &mhn_por_op_nr)){
#endif
  dbg("IPMC_IOCTL_GET_FV_OP_COUNT failed\n");
  return -EFAULT;
 }

 for (i = 0; i < MAX_OP_NR; i++) {
  op_tbl[i].op = 0;
  op_tbl[i].info = NULL;
 }
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,21)
 for(i = 0, j = 0; i < pxa3xx_por_op_nr; i++){
#else
 for(i = 0, j = 0; i < mhn_por_op_nr; i++){
#endif
  get_fv_op_info.op = i;
  if (ioctl(ipmc_fd, IPMC_IOCTL_GET_FV_OP_INFO, &get_fv_op_info)){
   dbg("IPMC_IOCTL_GET_FV_OP_INFO for OP%d failed\n", i);
   goto out;
  }
  /* skip 806MHz */
  if ((get_fv_op_info.info.xl == 31) && (get_fv_op_info.info.xn == 2)
   && (get_fv_op_info.info.d0cs == 0)) {
   skip_cnt++;
   continue;
  }

#ifdef VGA
  /* skip D0CS */
  if (get_fv_op_info.info.d0cs == 1) {
   skip_cnt++;
   continue;
  }
#endif
  /* skip duplicate operating point */
  for (step = 0; step < j; step++) {
   if ((get_fv_op_info.info.xl == op_tbl[step].info->xl)
    && (get_fv_op_info.info.xn
    == op_tbl[step].info->xn)) {
    break;
   }
  }
  if (step < j) {
   skip_cnt++;
   continue;
  }
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,21)
  fv_info = malloc(sizeof(struct pxa3xx_fv_info));
  memcpy(fv_info, &get_fv_op_info.info, sizeof(struct pxa3xx_fv_info));
#else
  fv_info = malloc(sizeof(struct mhn_fv_info));
  memcpy(fv_info, &get_fv_op_info.info, sizeof(struct mhn_fv_info));
#endif
  op_tbl[j].info = fv_info;
  op_tbl[j].op = get_fv_op_info.op;
  if (fv_info->d0cs) {
   op_tbl[j].freq = 60;
  }
  else {
   op_tbl[j].freq = fv_info->xl * fv_info->xn * 13;
  }
  j++;
 }
 /* skip some operatring point */
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,21)
 pxa3xx_por_op_nr = pxa3xx_por_op_nr - skip_cnt;
 dbg("max_op=%d\n", pxa3xx_por_op_nr);
#else
 mhn_por_op_nr = mhn_por_op_nr - skip_cnt;
 dbg("max_op=%d\n", mhn_por_op_nr);
#endif

 ipmc_dump_op();
 return 0;
 
out:
 for (i = 0; i < MAX_OP_NR; i++) {
  if (op_tbl[i].info != NULL) {
   op_tbl[i].op = 0;
   op_tbl[i].freq = 0;
   free(op_tbl[i].info);
  }
 }
 return -EFAULT;
}

首先获取所有的操作点

 ret = ioctl(ipmc_fd, IPMC_IOCTL_CLEAR_EVENTLIST, NULL);
 
清除事件列表


void build_fsm(void)
{
 int i = 0;

 build_smnode(SYS_RUN, IPM_EVENT_UITIMER, &status[i++], turnoff_bk);
 build_smnode(SYS_RUN, IPM_EVENT_PROFILER, &status[i++], sample_pmu);
 build_smnode(BKLIGHT_OFF, IPM_EVENT_PROFILER, &status[i++], sample_pmu);
 build_smnode(BKLIGHT_OFF, IPM_EVENT_UITIMER, &status[i++], useridle_bk);
 build_smnode(SYS_RUN, IPM_EVENT_UI, &status[i++], retain_run);
 build_smnode(BKLIGHT_OFF, IPM_EVENT_UI, &status[i++], turnon_bk);
 build_smnode(SYS_RUN, IPM_EVENT_STANDBY_WAKEUP, &status[i++], sample_pmu);
 build_smnode(BKLIGHT_OFF, IPM_EVENT_STANDBY_WAKEUP, &status[i++], sample_pmu);
 build_smnode(SYS_RUN, IPM_EVENT_DEVICE, &status[i++], out_freq);
 build_smnode(BKLIGHT_OFF, IPM_EVENT_DEVICE, &status[i++], out_freq);
 build_smnode(SYS_SUSPEND, IPM_EVENT_SUSPEND_WAKEUP, &status[i++], wakeup);

 /* check the memory boundary */
 if (i > STATUS_NUM) {
  dbg("FSM node has exceeded the limitation.\n");
  exit(1);
 }
}

建立了一个有穷状态机

 

static int init_fsm(void)
{
 int ret;

 build_fsm();
 fsm_state = SYS_RUN;
 reset_activity_count();
 sysop.set_speed(DEFAULT_FREQ);
 ret = start_pmu();
 if (ret < 0) {
  dbg("failed to start pmu\n");
 }
 return ret;
}


根据运行的程序类型来设置CPU的速度的

 

原创粉丝点击