static void reg_deinit(vpu_reg *reg);
static void vpu_service_session_clear(vpu_session *session)
{
- unsigned long flag;
vpu_reg *reg, *n;
- spin_lock_irqsave(&service.lock, flag);
list_for_each_entry_safe(reg, n, &session->waiting, session_link) {
reg_deinit(reg);
}
list_for_each_entry_safe(reg, n, &session->done, session_link) {
reg_deinit(reg);
}
- spin_unlock_irqrestore(&service.lock, flag);
}
static void vpu_service_dump(void)
{
int running;
- unsigned long flag;
vpu_reg *reg, *reg_tmp;
vpu_session *session, *session_tmp;
- spin_lock_irqsave(&service.lock, flag);
running = atomic_read(&service.total_running);
printk("total_running %d\n", running);
printk("done register set 0x%.8x\n", (unsigned int)reg);
}
}
- spin_unlock_irqrestore(&service.lock, flag);
}
static void vpu_service_power_off(void)
}
}
atomic_sub(1, ®->session->task_running);
+ atomic_sub(1, &service.total_running);
wake_up_interruptible_sync(®->session->wait);
spin_unlock(&service.lock);
}
pr_err("pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));
ret = -ETIMEDOUT;
}
+ spin_lock_irqsave(&service.lock, flag);
if (ret < 0) {
int task_running = atomic_read(&session->task_running);
vpu_service_dump();
if (task_running) {
atomic_set(&session->task_running, 0);
+ atomic_sub(task_running, &service.total_running);
printk("%d task is running but not return, reset hardware...", task_running);
vpu_reset();
printk("done\n");
}
vpu_service_session_clear(session);
+ spin_unlock_irqrestore(&service.lock, flag);
return ret;
}
+ spin_unlock_irqrestore(&service.lock, flag);
}
spin_lock_irqsave(&service.lock, flag);
reg = list_entry(session->done.next, vpu_reg, session_link);
static int vpu_service_release(struct inode *inode, struct file *filp)
{
int task_running;
+ unsigned long flag;
vpu_session *session = (vpu_session *)filp->private_data;
if (NULL == session)
return -EINVAL;
}
wake_up_interruptible_sync(&session->wait);
+ spin_lock_irqsave(&service.lock, flag);
/* remove this filp from the asynchronusly notified filp's */
//vpu_service_fasync(-1, filp, 0);
list_del(&session->list_session);
vpu_service_session_clear(session);
kfree(session);
+ spin_unlock_irqrestore(&service.lock, flag);
pr_debug("dev closed\n");
return 0;
/* clear dec IRQ */
writel(irq_status_dec & (~DEC_INTERRUPT_BIT), dev->hwregs + DEC_INTERRUPT_REGISTER);
pr_debug("DEC IRQ received!\n");
- atomic_sub(1, &service.total_running);
if (NULL == service.reg_codec) {
pr_err("dec isr with no task waiting\n");
} else {
/* clear pp IRQ */
writel(irq_status_pp & (~DEC_INTERRUPT_BIT), dev->hwregs + PP_INTERRUPT_REGISTER);
pr_debug("PP IRQ received!\n");
- atomic_sub(1, &service.total_running);
if (NULL == service.reg_pproc) {
pr_err("pp isr with no task waiting\n");
} else {
/* clear enc IRQ */
writel(irq_status & (~ENC_INTERRUPT_BIT), dev->hwregs + ENC_INTERRUPT_REGISTER);
pr_debug("ENC IRQ received!\n");
- atomic_sub(1, &service.total_running);
if (NULL == service.reg_codec) {
pr_err("enc isr with no task waiting\n");
} else {