struct list_head done; /* link to link_reg in struct vpu_reg */
struct list_head session; /* link to list_session in struct vpu_session */
atomic_t total_running;
- bool enabled;
+ atomic_t enabled;
+ atomic_t power_on_cnt;
+ atomic_t power_off_cnt;
vpu_reg *reg_codec;
vpu_reg *reg_pproc;
vpu_reg *reg_resev;
#if defined(CONFIG_VCODEC_MMU)
if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) {
set_bit(MMU_ACTIVATED, &data->state);
- BUG_ON(!pservice->enabled);
- if (pservice->enabled)
+ if (atomic_read(&pservice->enabled))
rockchip_iovmm_activate(data->dev);
+ else
+ BUG_ON(!atomic_read(&pservice->enabled));
}
#endif
return;
#if defined(CONFIG_VCODEC_MMU)
if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) {
set_bit(MMU_ACTIVATED, &data->state);
- BUG_ON(!pservice->enabled);
- if (pservice->enabled)
+ if (atomic_read(&pservice->enabled))
rockchip_iovmm_activate(data->dev);
+ else
+ BUG_ON(!atomic_read(&pservice->enabled));
}
#endif
pservice->prev_mode = pservice->curr_mode;
}
if (pservice->pd_video == NULL) {
pservice->pd_video = devm_clk_get(pservice->dev, "pd_video");
- if (IS_ERR(pservice->pd_video))
+ if (IS_ERR(pservice->pd_video)) {
pservice->pd_video = NULL;
+ dev_info(pservice->dev, "do not have pd_video\n");
+ }
}
break;
default:
#if defined(CONFIG_VCODEC_MMU)
if (data->mmu_dev && test_bit(MMU_ACTIVATED, &data->state)) {
clear_bit(MMU_ACTIVATED, &data->state);
- BUG_ON(!pservice->enabled);
- if (pservice->enabled)
+ if (atomic_read(&pservice->enabled))
rockchip_iovmm_deactivate(data->dev);
+ else
+ BUG_ON(!atomic_read(&pservice->enabled));
}
#endif
}
{
int total_running;
struct vpu_subdev_data *data = NULL, *n;
- if (!pservice->enabled)
+ int ret = atomic_add_unless(&pservice->enabled, -1, 0);
+ if (!ret)
return;
- pservice->enabled = false;
total_running = atomic_read(&pservice->total_running);
if (total_running) {
pr_alert("alert: power off when %d task running!!\n", total_running);
clk_disable_unprepare(pservice->clk_cabac);
#endif
+ atomic_add(1, &pservice->power_off_cnt);
wake_unlock(&pservice->wake_lock);
pr_info("done\n");
}
static void vpu_service_power_on(struct vpu_service_info *pservice)
{
+ int ret;
static ktime_t last;
ktime_t now = ktime_get();
if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) {
vpu_queue_power_off_work(pservice);
last = now;
}
- if (pservice->enabled)
+ ret = atomic_add_unless(&pservice->enabled, 1, 1);
+ if (!ret)
return ;
pr_info("%s: power on\n", dev_name(pservice->dev));
#endif
udelay(10);
- pservice->enabled = true;
+ atomic_add(1, &pservice->power_on_cnt);
wake_lock(&pservice->wake_lock);
}
pservice->reg_pproc = NULL;
atomic_set(&pservice->total_running, 0);
- pservice->enabled = false;
+ atomic_set(&pservice->enabled, 0);
+ atomic_set(&pservice->power_on_cnt, 0);
+ atomic_set(&pservice->power_off_cnt, 0);
INIT_DELAYED_WORK(&pservice->power_off_work, vpu_power_off_work);
seq_printf(s, "done register set\n");
}
}
+
+ seq_printf(s, "\npower counter: on %d off %d\n",
+ atomic_read(&pservice->power_on_cnt),
+ atomic_read(&pservice->power_off_cnt));
mutex_unlock(&pservice->lock);
+ vpu_service_power_off(pservice);
return 0;
}