clear-pkgs-linux-iot-lts2018/1166-media-intel-ipu4-Add-c...

107 lines
2.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chen Meng J <meng.j.chen@intel.com>
Date: Tue, 4 Jun 2019 19:01:37 +0800
Subject: [PATCH] media: intel-ipu4: Add clkdev_drop to avoid memory leak
call clkdev_drop() to match clkdev_add().
dup clock mapping from pdata, keep the pdata no change for later
use if the module load again, and free duplicated mapping.
free dev_id from kstrdup.
Change-Id: I68484c9d8fae175acceec1d5e1d3aa54f772fab4
Tracked-On: PKT-2588
Tracked-On: #H1507238979
Signed-off-by: Chen Meng J <meng.j.chen@intel.com>
Signed-off-by: Meng Wei <wei.meng@intel.com>
---
drivers/media/pci/intel/ipu-buttress.c | 52 ++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/media/pci/intel/ipu-buttress.c b/drivers/media/pci/intel/ipu-buttress.c
index beff618b226c..947414be9fcd 100644
--- a/drivers/media/pci/intel/ipu-buttress.c
+++ b/drivers/media/pci/intel/ipu-buttress.c
@@ -1267,6 +1267,25 @@ static void ipu_buttress_read_psys_fused_freqs(struct ipu_device *isp)
}
#ifdef I2C_WA
+
+static struct ipu_isys_clk_mapping *clkmap_dynamic;
+
+static int ipu_clk_mapping_num(struct ipu_isys_clk_mapping *clkmap)
+{
+ int num = 0;
+
+ if (!clkmap)
+ return 0;
+
+ while (clkmap->clkdev_data.dev_id) {
+ num++;
+ clkmap++;
+ }
+
+ /* include the NULL terminated */
+ return num + 1;
+}
+
/*
* The dev_id was hard code in platform data, as i2c bus number
* may change dynamiclly, we need to update this bus id
@@ -1378,6 +1397,20 @@ static int ipu_buttress_clk_init(struct ipu_device *isp)
if (!clkmap)
return 0;
+#ifdef I2C_WA
+ clkmap_dynamic = devm_kzalloc(&isp->pdev->dev,
+ ipu_clk_mapping_num(clkmap) * sizeof(*clkmap_dynamic),
+ GFP_KERNEL);
+ if (!clkmap_dynamic) {
+ rval = -ENOMEM;
+ goto err;
+ }
+ memcpy(clkmap_dynamic, clkmap,
+ ipu_clk_mapping_num(clkmap) * sizeof(*clkmap_dynamic));
+
+ clkmap = clkmap_dynamic;
+#endif
+
while (clkmap->clkdev_data.dev_id) {
#ifdef I2C_WA
char *dev_id = kstrdup(clkmap->clkdev_data.dev_id, GFP_KERNEL);
@@ -1423,6 +1456,9 @@ static void ipu_buttress_clk_exit(struct ipu_device *isp)
{
struct ipu_buttress *b = &isp->buttress;
int i;
+#ifdef I2C_WA
+ struct ipu_isys_clk_mapping *clkmap;
+#endif
/* It is safe to call clk_unregister with null pointer */
for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++)
@@ -1430,6 +1466,22 @@ static void ipu_buttress_clk_exit(struct ipu_device *isp)
for (i = 0; i < ARRAY_SIZE(ipu_buttress_sensor_pll_data); i++)
clk_unregister(b->pll_sensor[i]);
+
+#ifdef I2C_WA
+ if (!clkmap_dynamic)
+ return;
+
+ clkmap = clkmap_dynamic;
+ while (clkmap->clkdev_data.dev_id) {
+ clkdev_drop(&clkmap->clkdev_data);
+ kfree(clkmap->clkdev_data.dev_id);
+ clkmap->clkdev_data.dev_id = NULL;
+ clkmap++;
+ }
+
+ devm_kfree(&isp->pdev->dev, clkmap_dynamic);
+ clkmap_dynamic = NULL;
+#endif
}
int ipu_buttress_tsc_read(struct ipu_device *isp, u64 *val)
--
https://clearlinux.org