From 3435f139fd0a497482959136f2103ddccdca5f96 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Sat, 2 Apr 2022 11:06:01 +0800 Subject: [PATCH] media: rockchip: vicap add shutdown function Signed-off-by: Zefa Chen Change-Id: I957415449aa3f6efc3832a10cee049135d4c76af --- drivers/media/platform/rockchip/cif/hw.c | 28 +++++++++++++++++++ .../media/platform/rockchip/cif/mipi-csi2.c | 13 +++++++++ .../media/platform/rockchip/cif/mipi-csi2.h | 6 ++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/hw.c b/drivers/media/platform/rockchip/cif/hw.c index e694e5e4ece7..81f80190922c 100644 --- a/drivers/media/platform/rockchip/cif/hw.c +++ b/drivers/media/platform/rockchip/cif/hw.c @@ -1270,6 +1270,33 @@ static int rkcif_plat_remove(struct platform_device *pdev) return 0; } +static void rkcif_hw_shutdown(struct platform_device *pdev) +{ + struct rkcif_hw *cif_hw = platform_get_drvdata(pdev); + struct rkcif_device *cif_dev = NULL; + int i = 0; + + if (cif_hw->chip_id == CHIP_RK3588_CIF || + cif_hw->chip_id == CHIP_RV1106_CIF) { + write_cif_reg(cif_hw->base_addr, 0, 0); + } else { + for (i = 0; i < cif_hw->dev_num; i++) { + cif_dev = cif_hw->cif_dev[i]; + if (atomic_read(&cif_dev->pipe.stream_cnt)) { + if (cif_dev->inf_id == RKCIF_MIPI_LVDS) + rkcif_write_register(cif_dev, + CIF_REG_MIPI_LVDS_CTRL, + 0); + else + rkcif_write_register(cif_dev, + CIF_REG_DVP_CTRL, + 0); + } + } + } + disable_irq(cif_hw->irq); +} + static int __maybe_unused rkcif_runtime_suspend(struct device *dev) { struct rkcif_hw *cif_hw = dev_get_drvdata(dev); @@ -1306,6 +1333,7 @@ static struct platform_driver rkcif_hw_plat_drv = { }, .probe = rkcif_plat_hw_probe, .remove = rkcif_plat_remove, + .shutdown = rkcif_hw_shutdown, }; static int __init rk_cif_plat_drv_init(void) diff --git a/drivers/media/platform/rockchip/cif/mipi-csi2.c b/drivers/media/platform/rockchip/cif/mipi-csi2.c index b0ee53be33fd..5660489df63e 100644 --- a/drivers/media/platform/rockchip/cif/mipi-csi2.c +++ b/drivers/media/platform/rockchip/cif/mipi-csi2.c @@ -880,6 +880,7 @@ static int csi2_probe(struct platform_device *pdev) if (ret < 0) v4l2_err(&csi2->sd, "request csi-intr1 irq failed: %d\n", ret); + csi2->irq1 = irq; } else { v4l2_err(&csi2->sd, "No found irq csi-intr1\n"); } @@ -893,6 +894,7 @@ static int csi2_probe(struct platform_device *pdev) if (ret < 0) v4l2_err(&csi2->sd, "request csi-intr2 failed: %d\n", ret); + csi2->irq2 = irq; } else { v4l2_err(&csi2->sd, "No found irq csi-intr2\n"); } @@ -917,6 +919,16 @@ rmmutex: return ret; } +static void csi2_shutdown(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct csi2_dev *csi2 = sd_to_dev(sd); + + csi2_disable(csi2); + disable_irq(csi2->irq1); + disable_irq(csi2->irq2); +} + static int csi2_remove(struct platform_device *pdev) { struct v4l2_subdev *sd = platform_get_drvdata(pdev); @@ -936,6 +948,7 @@ static struct platform_driver csi2_driver = { }, .probe = csi2_probe, .remove = csi2_remove, + .shutdown = csi2_shutdown, }; int __init rkcif_csi2_plat_drv_init(void) diff --git a/drivers/media/platform/rockchip/cif/mipi-csi2.h b/drivers/media/platform/rockchip/cif/mipi-csi2.h index 96f2ae71dea7..eb64659a7770 100644 --- a/drivers/media/platform/rockchip/cif/mipi-csi2.h +++ b/drivers/media/platform/rockchip/cif/mipi-csi2.h @@ -147,8 +147,10 @@ struct csi2_dev { const struct csi2_match_data *match_data; int num_sensors; atomic_t frm_sync_seq; - struct csi2_err_stats err_list[RK_CSI2_ERR_MAX]; - bool is_check_sot_sync; + struct csi2_err_stats err_list[RK_CSI2_ERR_MAX]; + int irq1; + int irq2; + bool is_check_sot_sync; }; u32 rkcif_csi2_get_sof(struct csi2_dev *csi2_dev);