2020-05-02 04:39:00

by Amit Sunil Dhamne

[permalink] [raw]
Subject: [RESEND PATCH v2 0/4] drivers: clk: zynqmp: minor bux fixes for zynqmp clock driver

This patchset includes below fixes for clock driver
1> Fix Divider2 calculation
2> Memory leak in clock registration
3> Fix invalid name queries
4> Limit bestdiv with maxdiv

v2:
- Updated subject for cover letter and patches
to add prefix
resend-v2:
- -We have tried to ping Stephen several times over email. Link:
https://lkml.org/lkml/2020/4/9/754 and also we tried to pinged him
over IRC this week without no reaction that's why we are sending
patches again


Quanyang Wang (1):
drivers: clk: zynqmp: fix memory leak in zynqmp_register_clocks

Rajan Vaja (2):
drivers: clk: zynqmp: Limit bestdiv with maxdiv
drivers: clk: zynqmp: Fix invalid clock name queries

Tejas Patel (1):
drivers: clk: zynqmp: Fix divider2 calculation

drivers/clk/zynqmp/clkc.c | 20 ++++++++++++++------
drivers/clk/zynqmp/divider.c | 19 ++++++++++++++-----
2 files changed, 28 insertions(+), 11 deletions(-)

--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


2020-05-02 04:39:02

by Amit Sunil Dhamne

[permalink] [raw]
Subject: [RESEND PATCH v2 4/4] drivers: clk: zynqmp: fix memory leak in zynqmp_register_clocks

From: Quanyang Wang <[email protected]>

This is detected by kmemleak running on zcu102 board:

unreferenced object 0xffffffc877e48180 (size 128):
comm "swapper/0", pid 1, jiffies 4294892909 (age 315.436s)
hex dump (first 32 bytes):
64 70 5f 76 69 64 65 6f 5f 72 65 66 5f 64 69 76 dp_video_ref_div
31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1...............
backtrace:
[<00000000c9be883b>] __kmalloc_track_caller+0x200/0x380
[<00000000f02c3809>] kvasprintf+0x7c/0x100
[<00000000e51dde4d>] kasprintf+0x60/0x80
[<0000000092298b05>] zynqmp_register_clocks+0x29c/0x398
[<00000000faaff182>] zynqmp_clock_probe+0x3cc/0x4c0
[<000000005f5986f0>] platform_drv_probe+0x58/0xa8
[<00000000d5810136>] really_probe+0xd8/0x2a8
[<00000000f5b671be>] driver_probe_device+0x5c/0x100
[<0000000038f91fcf>] __device_attach_driver+0x98/0xb8
[<000000008a3f2ac2>] bus_for_each_drv+0x74/0xd8
[<000000001cb2783d>] __device_attach+0xe0/0x140
[<00000000c268031b>] device_initial_probe+0x24/0x30
[<000000006998de4b>] bus_probe_device+0x9c/0xa8
[<00000000647ae6ff>] device_add+0x3c0/0x610
[<0000000071c14bb8>] of_device_add+0x40/0x50
[<000000004bb5d132>] of_platform_device_create_pdata+0xbc/0x138

This is because that when num_nodes is larger than 1, clk_out is
allocated using kasprintf for these nodes but only the last node's
clk_out is freed.

Signed-off-by: Quanyang Wang <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
Signed-off-by: Tejas Patel <[email protected]>
Signed-off-by: Jolly Shah <[email protected]>
Signed-off-by: Amit Sunil Dhamne <[email protected]>
---
drivers/clk/zynqmp/clkc.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index 3e83c51..e8b2cf2 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -558,7 +558,7 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
{
int j;
u32 num_nodes, clk_dev_id;
- char *clk_out = NULL;
+ char *clk_out[MAX_NODES];
struct clock_topology *nodes;
struct clk_hw *hw = NULL;

@@ -572,16 +572,16 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
* Intermediate clock names are postfixed with type of clock.
*/
if (j != (num_nodes - 1)) {
- clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
+ clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name,
clk_type_postfix[nodes[j].type]);
} else {
- clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
+ clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name);
}

if (!clk_topology[nodes[j].type])
continue;

- hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
+ hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
parent_names,
num_parents,
&nodes[j]);
@@ -590,9 +590,12 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
__func__, clk_dev_id, clk_name,
PTR_ERR(hw));

- parent_names[0] = clk_out;
+ parent_names[0] = clk_out[j];
}
- kfree(clk_out);
+
+ for (j = 0; j < num_nodes; j++)
+ kfree(clk_out[j]);
+
return hw;
}

--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

2020-05-02 04:39:05

by Amit Sunil Dhamne

[permalink] [raw]
Subject: [RESEND PATCH v2 1/4] drivers: clk: zynqmp: Limit bestdiv with maxdiv

From: Rajan Vaja <[email protected]>

Clock divider value should not be greater than maximum divider value.
So use minimum of best divider or maximum divider value.

Signed-off-by: Rajan Vaja <[email protected]>
Signed-off-by: Jolly Shah <[email protected]>
Signed-off-by: Amit Sunil Dhamne <[email protected]>
---
drivers/clk/zynqmp/divider.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index 4be2cc7..5c41ddb 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -197,6 +197,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,

if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
bestdiv = rate % *prate ? 1 : bestdiv;
+
+ bestdiv = min_t(u32, bestdiv, divider->max_div);
*prate = rate * bestdiv;

return rate;
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

2020-05-02 04:41:13

by Amit Sunil Dhamne

[permalink] [raw]
Subject: [RESEND PATCH v2 2/4] drivers: clk: zynqmp: Fix divider2 calculation

From: Tejas Patel <[email protected]>

zynqmp_get_divider2_val() calculates, divider value of type DIV2 clock,
considering best possible combination of DIV1 and DIV2.

To find best possible values of DIV1 and DIV2, DIV1's parent rate
should be consider and not DIV2's parent rate since it would rate of
div1 clock. Consider a below topology,

out_clk->div2_clk->div1_clk->fixed_parent

where out_clk = (fixed_parent/div1_clk) / div2_clk, so parent clock
of div1_clk (i.e. out_clk) should be divided by div1_clk and div2_clk.

Existing code divides parent rate of div2_clk's clock instead of
div1_clk's parent rate, which is wrong.

Fix the same by considering div1's parent clock rate.

Fixes: 4ebd92d2e228 ("clk: zynqmp: Fix divider calculation")
Signed-off-by: Tejas Patel <[email protected]>
Signed-off-by: Jolly Shah <[email protected]>
Signed-off-by: Amit Sunil Dhamne <[email protected]>
---
drivers/clk/zynqmp/divider.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index 5c41ddb..f7b3545 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -111,23 +111,30 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,

static void zynqmp_get_divider2_val(struct clk_hw *hw,
unsigned long rate,
- unsigned long parent_rate,
struct zynqmp_clk_divider *divider,
int *bestdiv)
{
int div1;
int div2;
long error = LONG_MAX;
- struct clk_hw *parent_hw = clk_hw_get_parent(hw);
- struct zynqmp_clk_divider *pdivider = to_zynqmp_clk_divider(parent_hw);
+ unsigned long div1_prate;
+ struct clk_hw *div1_parent_hw;
+ struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
+ struct zynqmp_clk_divider *pdivider =
+ to_zynqmp_clk_divider(div2_parent_hw);

if (!pdivider)
return;

+ div1_parent_hw = clk_hw_get_parent(div2_parent_hw);
+ if (!div1_parent_hw)
+ return;
+
+ div1_prate = clk_hw_get_rate(div1_parent_hw);
*bestdiv = 1;
for (div1 = 1; div1 <= pdivider->max_div;) {
for (div2 = 1; div2 <= divider->max_div;) {
- long new_error = ((parent_rate / div1) / div2) - rate;
+ long new_error = ((div1_prate / div1) / div2) - rate;

if (abs(new_error) < abs(error)) {
*bestdiv = div2;
@@ -192,7 +199,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
*/
if (div_type == TYPE_DIV2 &&
(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
- zynqmp_get_divider2_val(hw, rate, *prate, divider, &bestdiv);
+ zynqmp_get_divider2_val(hw, rate, divider, &bestdiv);
}

if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

2020-05-02 04:41:44

by Amit Sunil Dhamne

[permalink] [raw]
Subject: [RESEND PATCH v2 3/4] drivers: clk: zynqmp: Fix invalid clock name queries

From: Rajan Vaja <[email protected]>

The clock driver makes EEMI call to get the name of invalid clk
when executing versal_get_clock_info() function. This results in
error messages.
Added check for validating clock before saving clock attribute and
calling zynqmp_pm_clock_get_name() in versal_get_clock_info() function.

Signed-off-by: Rajan Vaja <[email protected]>
Signed-off-by: Tejas Patel <[email protected]>
Signed-off-by: Jolly Shah <[email protected]>
Signed-off-by: Amit Sunil Dhamne <[email protected]>
---
drivers/clk/zynqmp/clkc.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index 10e89f2..3e83c51 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -663,6 +663,11 @@ static void zynqmp_get_clock_info(void)
continue;

clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
+ /* skip query for Invalid clock */
+ ret = zynqmp_is_valid_clock(i);
+ if (ret != CLK_ATTR_VALID)
+ continue;
+
clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;

--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.