[i.MX845/VPU]:MLK-21235: multi instance encode process fail to resume encoding during...
authorZhou Peng <eagle.zhou@nxp.com>
Tue, 23 Apr 2019 05:32:35 +0000 (13:32 +0800)
committerZhou Peng <eagle.zhou@nxp.com>
Wed, 24 Apr 2019 02:37:55 +0000 (10:37 +0800)
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 <eagle.zhou@nxp.com>
(cherry picked from commit 789a419a5d4c0fed3eb0cbe83999bf8a65a980b4)

drivers/mxc/hantro_845_h1/hx280enc.c
drivers/mxc/hantro_845_h1/hx280enc.h

index bdf23fd..bc90b92 100755 (executable)
@@ -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;
index d465c25..d5b0560 100755 (executable)
@@ -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'