From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Yang Zhonghua Date: Tue, 27 Aug 2019 11:43:07 +0800 Subject: [PATCH] media: intel-ipu4: dynamic memory alloc for clkdev_add/clkdev_drop. Change-Id: If560bc7e241577ec3f1d4f872f655377625db75d Tracked-On: PKT-2588 Signed-off-by: Chen Meng J --- drivers/media/pci/intel/ipu-buttress.c | 92 ++++++++++++-------------- 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/drivers/media/pci/intel/ipu-buttress.c b/drivers/media/pci/intel/ipu-buttress.c index 757aa75a7108..9a1ade0f111d 100644 --- a/drivers/media/pci/intel/ipu-buttress.c +++ b/drivers/media/pci/intel/ipu-buttress.c @@ -1267,24 +1267,12 @@ static void ipu_buttress_read_psys_fused_freqs(struct ipu_device *isp) } #ifdef I2C_DYNAMIC +static LIST_HEAD(clkmap_dynamic); -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; -} +struct clk_dynamic { + struct list_head node; + struct clk_lookup *clk_data; +}; /* * The dev_id was hard code in platform data, as i2c bus number @@ -1397,20 +1385,6 @@ static int ipu_buttress_clk_init(struct ipu_device *isp) if (!clkmap) return 0; -#ifdef I2C_DYNAMIC - 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_DYNAMIC char *dev_id = kstrdup(clkmap->clkdev_data.dev_id, GFP_KERNEL); @@ -1428,11 +1402,32 @@ static int ipu_buttress_clk_init(struct ipu_device *isp) for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++) { if (!strcmp(clkmap->platform_clock_name, clk_data[i].name)) { - clkmap->clkdev_data.clk = b->clk_sensor[i]; #ifdef I2C_DYNAMIC - clkmap->clkdev_data.dev_id = dev_id; -#endif + struct clk_dynamic *clk = NULL; + struct clk_lookup *clk_data = NULL; + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { + rval = -ENOMEM; + goto err; + } + clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) { + kfree(clk); + rval = -ENOMEM; + goto err; + } + + clk_data->dev_id = dev_id; + clk_data->clk = b->clk_sensor[i]; + clk->clk_data = clk_data; + clkdev_add(clk_data); + + list_add_tail(&clk->node, &clkmap_dynamic); +#else + clkmap->clkdev_data.clk = b->clk_sensor[i]; clkdev_add(&clkmap->clkdev_data); +#endif break; } } @@ -1457,7 +1452,19 @@ static void ipu_buttress_clk_exit(struct ipu_device *isp) struct ipu_buttress *b = &isp->buttress; int i; #ifdef I2C_DYNAMIC - struct ipu_isys_clk_mapping *clkmap; + struct clk_dynamic *clk = NULL; + const char *dev_id = NULL; +#endif + +#ifdef I2C_DYNAMIC + while (!list_empty(&clkmap_dynamic)) { + clk = list_last_entry(&clkmap_dynamic, struct clk_dynamic, node); + dev_id = clk->clk_data->dev_id; + clkdev_drop(clk->clk_data); + kfree(dev_id); + list_del(&clk->node); + kfree(clk); + } #endif /* It is safe to call clk_unregister with null pointer */ @@ -1467,21 +1474,6 @@ 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_DYNAMIC - 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