From a911ba7a105e1317e8c5b349cab5e04ce9092e9f Mon Sep 17 00:00:00 2001 From: Zhou Peng Date: Mon, 30 Jul 2018 17:09:22 +0800 Subject: MLK-19005-2 - [i.MX8MM/Hantro]: Conformace test failed when decoder and encoder run simultaneously Disable irq during poweron stage to avoid unexpected irq triggered One mutex is added accordingly to handle the operation Signed-off-by: Zhou Peng --- drivers/mxc/hantro_845/hantrodec_845s.c | 34 +++++++++++++++++++++++++-------- drivers/mxc/hantro_845_h1/hx280enc.c | 30 ++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mxc/hantro_845/hantrodec_845s.c b/drivers/mxc/hantro_845/hantrodec_845s.c index 9b7410fb1c3c..6172030df983 100755 --- a/drivers/mxc/hantro_845/hantrodec_845s.c +++ b/drivers/mxc/hantro_845/hantrodec_845s.c @@ -185,6 +185,7 @@ typedef struct { atomic_t irq_rx; atomic_t irq_tx; struct device *dev; + struct mutex dev_mutex; } hantrodec_t; static hantrodec_t hantrodec_data[HXDEC_MAX_CORES]; /* dynamic allocation? */ @@ -298,6 +299,18 @@ static int hantro_ctrlblk_reset(hantrodec_t *dev) return 0; } +static int hantro_power_on_disirq(hantrodec_t *hantrodev) +{ + //spin_lock_irq(&owner_lock); + mutex_lock(&hantrodev->dev_mutex); + disable_irq(hantrodev->irq); + pm_runtime_get_sync(hantrodev->dev); + enable_irq(hantrodev->irq); + mutex_unlock(&hantrodev->dev_mutex); + //spin_unlock_irq(&owner_lock); + return 0; +} + #ifdef CONFIG_DEVICE_THERMAL_XXX static int hantro_thermal_check(struct device *dev) { @@ -1356,12 +1369,14 @@ static long hantrodec_ioctl32(struct file *filp, unsigned int cmd, unsigned long */ static int hantrodec_open(struct inode *inode, struct file *filp) { + int i; + PDEBUG("dev opened\n"); -#if 1 //1 FIXME - hantro_clk_enable(&hantrodec_data[0].clk); - hantro_clk_enable(&hantrodec_data[1].clk); - pm_runtime_get_sync(hantrodec_data[0].dev); - pm_runtime_get_sync(hantrodec_data[1].dev); +#if 1 // FIXME: need to identify core id + for (i = 0; i < 2; i++) { + hantro_clk_enable(&hantrodec_data[i].clk); + hantro_power_on_disirq(&hantrodec_data[i]); + } #endif return 0; } @@ -1379,7 +1394,7 @@ static int hantrodec_release(struct inode *inode, struct file *filp) //hantrodec_t *dev = &hantrodec_data; PDEBUG("closing ...\n"); -#if 1 //1 FIXME +#if 1 // FIXME: need to identify core id for (n = 0; n < cores; n++) { if (hantrodec_data[n].dec_owner == filp) { PDEBUG("releasing dec Core %i lock\n", n); @@ -1528,6 +1543,7 @@ static int hantrodec_init(struct platform_device *pdev, int id) hantrodec_data[id].irq_rx.counter = 0; hantrodec_data[id].irq_tx.counter = 0; + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); pr_info("hantrodec %d : module inserted. Major = %d\n", id, hantrodec_major); return 0; @@ -1843,6 +1859,8 @@ printk("power enable done\n"); hantro_dynamic_clock = 0; #endif hantrodec_data[id].timeout = 0; + mutex_init(&hantrodec_data[id].dev_mutex); + goto out; error: @@ -1861,7 +1879,7 @@ static int hantro_dev_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); hantrodec_cleanup(dev->core_id); -#if 1 //1 FIXME +#if 1 // FIXME: need to identify core id if (hantrodec_major > 0) { device_destroy(hantro_class, MKDEV(hantrodec_major, 0)); class_destroy(hantro_class); @@ -1890,7 +1908,7 @@ static int hantro_resume(struct device *dev) { hantrodec_t *hantrodev = dev_get_drvdata(dev); - pm_runtime_get_sync(dev); //power on + hantro_power_on_disirq(hantrodev); hantro_ctrlblk_reset(hantrodev); return 0; } diff --git a/drivers/mxc/hantro_845_h1/hx280enc.c b/drivers/mxc/hantro_845_h1/hx280enc.c index 6523d6cfac51..0ba6440212a8 100755 --- a/drivers/mxc/hantro_845_h1/hx280enc.c +++ b/drivers/mxc/hantro_845_h1/hx280enc.c @@ -52,7 +52,7 @@ #include #include - +#include #include /* our own stuff */ @@ -141,6 +141,8 @@ typedef struct { volatile u8 *hwregs; struct fasync_struct *async_queue; + struct device *dev; + struct mutex dev_mutex; } hx280enc_t; /* dynamic allocation? */ @@ -208,6 +210,18 @@ static int hantro_h1_ctrlblk_reset(struct device *dev) return 0; } +static int hantro_h1_power_on_disirq(hx280enc_t *hx280enc) +{ + //spin_lock_irq(&owner_lock); + mutex_lock(&hx280enc->dev_mutex); + disable_irq(hx280enc->irq); + pm_runtime_get_sync(hx280enc->dev); + enable_irq(hx280enc->irq); + mutex_unlock(&hx280enc->dev_mutex); + //spin_unlock_irq(&owner_lock); + return 0; +} + #endif /* the device's mmap method. The VFS has kindly prepared the process's @@ -391,8 +405,8 @@ static int hx280enc_open(struct inode *inode, struct file *filp) filp->private_data = (void *) dev; #ifndef VSI - hantro_h1_clk_enable(hantro_h1_dev); - pm_runtime_get_sync(hantro_h1_dev); + hantro_h1_clk_enable(dev->dev); + hantro_h1_power_on_disirq(dev); #endif PDEBUG("dev opened\n"); @@ -544,7 +558,8 @@ static int __init hx280enc_init(void) goto err; } } else - PDEBUG(KERN_INFO "hx280enc: IRQ not in use!\n"); + PDEBUG(KERN_INFO "hx280enc: IRQ not in use!\n"); + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); pr_info("hx280enc: module inserted. Major <%d>\n", hx280enc_major); return 0; @@ -762,6 +777,9 @@ static int hantro_h1_probe(struct platform_device *pdev) err = PTR_ERR(temp_class); goto err_out_class; } + hx280enc_data.dev = &pdev->dev; + platform_set_drvdata(pdev, &hx280enc_data); + mutex_init(&hx280enc_data.dev_mutex); goto out; @@ -801,7 +819,9 @@ static int hantro_h1_suspend(struct device *dev) } static int hantro_h1_resume(struct device *dev) { - pm_runtime_get_sync(dev); //power on + hx280enc_t *hx280enc = dev_get_drvdata(dev); + + hantro_h1_power_on_disirq(hx280enc); hantro_h1_ctrlblk_reset(dev); return 0; } -- cgit v1.2.3