From ac351a50510e7e8b667a3ec6029b3801c92067a2 Mon Sep 17 00:00:00 2001 From: Zhou Peng Date: Tue, 23 Apr 2019 13:32:35 +0800 Subject: [PATCH] [i.MX845/VPU]:MLK-21235: multi instance encode process fail to resume encoding during suspend resume test.100% Add mirror registers to store HW registers before power off Replace 'wait_event_interruptible' with 'wait_event_timeout' to avoid interrupted Signed-off-by: Zhou Peng (cherry picked from commit 789a419a5d4c0fed3eb0cbe83999bf8a65a980b4) --- drivers/mxc/hantro_845_h1/hx280enc.c | 44 ++++++++++++++++++++++------ drivers/mxc/hantro_845_h1/hx280enc.h | 3 ++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/mxc/hantro_845_h1/hx280enc.c b/drivers/mxc/hantro_845_h1/hx280enc.c index bdf23fd59d20..bc90b9236a6e 100755 --- a/drivers/mxc/hantro_845_h1/hx280enc.c +++ b/drivers/mxc/hantro_845_h1/hx280enc.c @@ -141,6 +141,7 @@ typedef struct { volatile u8 *hwregs; struct fasync_struct *async_queue; + unsigned int mirror_regs[512]; struct device *dev; struct mutex dev_mutex; } hx280enc_t; @@ -272,12 +273,26 @@ static int CheckEncIrq(hx280enc_t *dev) unsigned int WaitEncReady(hx280enc_t *dev) { - PDEBUG("WaitEncReady\n"); + u32 irq_status, is_write1_clr; + int i; + long ret; - if (wait_event_interruptible(enc_wait_queue, CheckEncIrq(dev))) { - PDEBUG("ENC wait_event_interruptible interrupted\n"); - return -ERESTARTSYS; - } + PDEBUG("%s\n", __func__); + ret = wait_event_timeout(enc_wait_queue, CheckEncIrq(dev), msecs_to_jiffies(200)); + if (ret == 0) + pr_err("ENC wait_event_timeout() timeout !\n"); + + /* read register to mirror */ + for (i = 0; i < dev->iosize; i += 4) + dev->mirror_regs[i/4] = readl(dev->hwregs + i); + + /* clear the status bits */ + is_write1_clr = (dev->mirror_regs[0x4a0/4] & 0x00800000); + irq_status = dev->mirror_regs[1]; + if (is_write1_clr) + writel(irq_status, dev->hwregs + 0x04); + else + writel(irq_status & (~0xf7d), dev->hwregs + 0x04); return 0; } @@ -338,7 +353,18 @@ void ReleaseEncoder(hx280enc_t *dev) spin_unlock_irqrestore(&owner_lock, flags); wake_up_interruptible_all(&enc_hw_queue); +} +static long EncRefreshRegs(hx280enc_t *dev, unsigned int *regs) +{ + long ret; + + ret = copy_to_user(regs, dev->mirror_regs, dev->iosize); + if (ret) { + PDEBUG("%s: copy_to_user failed, returned %li\n", __func__, ret); + return -EFAULT; + } + return 0; } @@ -388,10 +414,10 @@ static long hx280enc_ioctl(struct file *filp, unsigned int cmd, unsigned long ar ReleaseEncoder(&hx280enc_data); break; case _IOC_NR(HX280ENC_IOCG_CORE_WAIT): { - int ret; + unsigned int *regs = (unsigned int *)arg; - ret = WaitEncReady(&hx280enc_data); - return ret; + WaitEncReady(&hx280enc_data); + return EncRefreshRegs(&hx280enc_data, regs); } } return 0; @@ -677,7 +703,7 @@ irqreturn_t hx280enc_isr(int irq, void *dev_id) dev->irq_status = irq_status & (~0x01); spin_unlock_irqrestore(&owner_lock, flags); - wake_up_interruptible_all(&enc_wait_queue); + wake_up_all(&enc_wait_queue); PDEBUG("IRQ handled!\n"); return IRQ_HANDLED; diff --git a/drivers/mxc/hantro_845_h1/hx280enc.h b/drivers/mxc/hantro_845_h1/hx280enc.h index d465c25f9f66..d5b05607b1d4 100755 --- a/drivers/mxc/hantro_845_h1/hx280enc.h +++ b/drivers/mxc/hantro_845_h1/hx280enc.h @@ -46,6 +46,9 @@ /* * Ioctl definitions */ +struct mirror_regs { + unsigned int regs[512]; /* pointer to user registers */ +}; /* Use 'k' as magic number */ #define HX280ENC_IOC_MAGIC 'k' -- 2.17.1