107 lines
2.9 KiB
Diff
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
|
|
|