MLK-18517-1: ISI: fix system reboot stress test from nfs fail
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Thu, 28 Jun 2018 01:47:54 +0000 (09:47 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
1. System will dump painc message and hang when do system
reboot stress test. It caused by ISI HW reset function. When
user open the video device, it will get the device and driver
will turn on ISI power domain, but after that, ISI HW reset
will first turn off and then turn on it's power. During this
time, the process which open ISI channel 0 maybe sleep and
the other process which open other ISI channel will active but
the other channel power domain depend on channel 0. It leads to
system panic. So change msleep to udelay and move HW reset to
other place.

2. Refine ISI system and runtime suspend/resume.

Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
drivers/media/platform/imx8/mxc-isi-core.c

index e78fbac..3663223 100644 (file)
@@ -178,11 +178,10 @@ static int mxc_isi_probe(struct platform_device *pdev)
        }
 
        mxc_isi->flags = MXC_ISI_PM_POWERED;
+       mxc_isi_channel_set_chain_buf(mxc_isi);
+       clk_disable_unprepare(mxc_isi->clk);
 
-       pm_runtime_set_active(dev);
        pm_runtime_enable(dev);
-       pm_runtime_get_sync(dev);
-       pm_runtime_put_sync(dev);
 
        dev_dbg(dev, "mxc_isi.%d registered successfully\n", mxc_isi->id);
 
@@ -198,11 +197,7 @@ static int mxc_isi_remove(struct platform_device *pdev)
        struct mxc_isi_dev *mxc_isi = platform_get_drvdata(pdev);
        struct device *dev = &pdev->dev;
 
-       pm_runtime_get_sync(&pdev->dev);
        mxc_isi_unregister_capture_subdev(mxc_isi);
-
-       clk_disable_unprepare(mxc_isi->clk);
-       pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(dev);
 
        return 0;
@@ -211,42 +206,12 @@ static int mxc_isi_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int mxc_isi_pm_suspend(struct device *dev)
 {
-       struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
-
-       pm_runtime_get_sync(dev);
-
-       if ((mxc_isi->flags & MXC_ISI_PM_SUSPENDED) ||
-               (mxc_isi->flags & MXC_ISI_RUNTIME_SUSPEND))
-               return 0;
-
-       clk_disable_unprepare(mxc_isi->clk);
-       mxc_isi->flags |= MXC_ISI_PM_SUSPENDED;
-       mxc_isi->flags &= ~MXC_ISI_PM_POWERED;
-       pm_runtime_put_sync(dev);
-
-       return 0;
+       return pm_runtime_force_suspend(dev);
 }
 
 static int mxc_isi_pm_resume(struct device *dev)
 {
-       struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
-       int ret;
-
-       pm_runtime_get_sync(dev);
-       if (mxc_isi->flags & MXC_ISI_PM_POWERED)
-               return 0;
-
-       ret = clk_prepare_enable(mxc_isi->clk);
-       if (ret) {
-               pr_info("== %s ret=%d\n", __func__, ret);
-               return -EAGAIN;
-       }
-
-       mxc_isi->flags |= MXC_ISI_PM_POWERED;
-       mxc_isi->flags &= ~MXC_ISI_PM_SUSPENDED;
-       pm_runtime_put_sync(dev);
-
-       return 0;
+       return pm_runtime_force_resume(dev);
 }
 #endif
 
@@ -254,31 +219,20 @@ static int mxc_isi_runtime_suspend(struct device *dev)
 {
        struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
 
-       if (mxc_isi->flags & MXC_ISI_RUNTIME_SUSPEND)
-               return 0;
-
-       if (mxc_isi->flags & MXC_ISI_PM_POWERED) {
-               clk_disable_unprepare(mxc_isi->clk);
-               mxc_isi->flags |= MXC_ISI_RUNTIME_SUSPEND;
-               mxc_isi->flags &= ~MXC_ISI_PM_POWERED;
-       }
+       clk_disable_unprepare(mxc_isi->clk);
        return 0;
 }
 
 static int mxc_isi_runtime_resume(struct device *dev)
 {
        struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+       int ret;
 
-       if (mxc_isi->flags & MXC_ISI_PM_POWERED)
-               return 0;
-
-       if (mxc_isi->flags & MXC_ISI_RUNTIME_SUSPEND) {
-               clk_prepare_enable(mxc_isi->clk);
-               mxc_isi->flags |= MXC_ISI_PM_POWERED;
-               mxc_isi->flags &= ~MXC_ISI_RUNTIME_SUSPEND;
-       }
+       ret = clk_prepare_enable(mxc_isi->clk);
+       if (ret)
+               dev_err(dev, "%s clk enable fail\n", __func__);
 
-       return 0;
+       return (ret) ? ret : 0;
 }
 
 static const struct dev_pm_ops mxc_isi_pm_ops = {