diff mbox series

clk: socfpga: Don't have get_parent for single parent ops

Message ID 20181204193416.24661-1-sboyd@kernel.org (mailing list archive)
State Accepted, archived
Headers show
Series clk: socfpga: Don't have get_parent for single parent ops | expand

Commit Message

Stephen Boyd Dec. 4, 2018, 7:34 p.m. UTC
This driver creates a gate clk with the possibility to have multiple
parents. That can cause problems if the common clk framework tries to
call the get_parent() op and gets back a number that's larger than the
number of parents the clk says it supports in
clk_init_data::num_parents. Let's duplicate the clk_ops structure each
time this function is called and drop the get/set parent ops when there
is only one parent. This allows the framework to consider a number
larger than clk_init_data::num_parents as an error condition of the
get_parent() clk op, clearing the way for proper code.

Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/socfpga/clk-gate.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

Comments

Stephen Boyd Dec. 5, 2018, 7:17 a.m. UTC | #1
(Adding Dinh's korg email)

I also wonder if this driver is even used anymore or maybe we can delete
it?

Quoting Stephen Boyd (2018-12-04 11:34:16)
> This driver creates a gate clk with the possibility to have multiple
> parents. That can cause problems if the common clk framework tries to
> call the get_parent() op and gets back a number that's larger than the
> number of parents the clk says it supports in
> clk_init_data::num_parents. Let's duplicate the clk_ops structure each
> time this function is called and drop the get/set parent ops when there
> is only one parent. This allows the framework to consider a number
> larger than clk_init_data::num_parents as an error condition of the
> get_parent() clk op, clearing the way for proper code.
> 
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---
>  drivers/clk/socfpga/clk-gate.c | 22 +++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
> index aa7a6e6a15b6..73e03328d5c5 100644
> --- a/drivers/clk/socfpga/clk-gate.c
> +++ b/drivers/clk/socfpga/clk-gate.c
> @@ -176,8 +176,7 @@ static struct clk_ops gateclk_ops = {
>         .set_parent = socfpga_clk_set_parent,
>  };
>  
> -static void __init __socfpga_gate_init(struct device_node *node,
> -       const struct clk_ops *ops)
> +void __init socfpga_gate_init(struct device_node *node)
>  {
>         u32 clk_gate[2];
>         u32 div_reg[3];
> @@ -188,12 +187,17 @@ static void __init __socfpga_gate_init(struct device_node *node,
>         const char *clk_name = node->name;
>         const char *parent_name[SOCFPGA_MAX_PARENTS];
>         struct clk_init_data init;
> +       struct clk_ops *ops;
>         int rc;
>  
>         socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
>         if (WARN_ON(!socfpga_clk))
>                 return;
>  
> +       ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
> +       if (WARN_ON(!ops))
> +               return;
> +
>         rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
>         if (rc)
>                 clk_gate[0] = 0;
> @@ -202,8 +206,8 @@ static void __init __socfpga_gate_init(struct device_node *node,
>                 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
>                 socfpga_clk->hw.bit_idx = clk_gate[1];
>  
> -               gateclk_ops.enable = clk_gate_ops.enable;
> -               gateclk_ops.disable = clk_gate_ops.disable;
> +               ops->enable = clk_gate_ops.enable;
> +               ops->disable = clk_gate_ops.disable;
>         }
>  
>         rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
> @@ -234,6 +238,11 @@ static void __init __socfpga_gate_init(struct device_node *node,
>         init.flags = 0;
>  
>         init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
> +       if (init.num_parents < 2) {
> +               ops->get_parent = NULL;
> +               ops->set_parent = NULL;
> +       }
> +
>         init.parent_names = parent_name;
>         socfpga_clk->hw.hw.init = &init;
>  
> @@ -246,8 +255,3 @@ static void __init __socfpga_gate_init(struct device_node *node,
>         if (WARN_ON(rc))
>                 return;
>  }
> -
> -void __init socfpga_gate_init(struct device_node *node)
> -{
> -       __socfpga_gate_init(node, &gateclk_ops);
> -}
Dinh Nguyen Dec. 5, 2018, 3:17 p.m. UTC | #2
Hi Stephen,

On 12/5/18 1:17 AM, Stephen Boyd wrote:
> (Adding Dinh's korg email)
> 
> I also wonder if this driver is even used anymore or maybe we can delete
> it?
> 

The armv7 SoCFPGA platforms are using this driver.

Dinh
Stephen Boyd Dec. 5, 2018, 3:55 p.m. UTC | #3
Quoting Dinh Nguyen (2018-12-05 07:17:41)
> Hi Stephen,
> 
> On 12/5/18 1:17 AM, Stephen Boyd wrote:
> > (Adding Dinh's korg email)
> > 
> > I also wonder if this driver is even used anymore or maybe we can delete
> > it?
> > 
> 
> The armv7 SoCFPGA platforms are using this driver.
> 

Ok and those platforms are booting in kernelci.org as
https://kernelci.org/boot/socfpga_cyclone5_de0_sockit/ perhaps?
Dinh Nguyen Dec. 6, 2018, 3:16 p.m. UTC | #4
On 12/5/18 9:55 AM, Stephen Boyd wrote:
> Quoting Dinh Nguyen (2018-12-05 07:17:41)
>> Hi Stephen,
>>
>> On 12/5/18 1:17 AM, Stephen Boyd wrote:
>>> (Adding Dinh's korg email)
>>>
>>> I also wonder if this driver is even used anymore or maybe we can delete
>>> it?
>>>
>>
>> The armv7 SoCFPGA platforms are using this driver.
>>
> 
> Ok and those platforms are booting in kernelci.org as
> https://kernelci.org/boot/socfpga_cyclone5_de0_sockit/ perhaps?
> 

Yes that's right.

Dinh
Stephen Boyd Dec. 18, 2018, 1:54 a.m. UTC | #5
Quoting Dinh Nguyen (2018-12-06 07:16:47)
> 
> 
> On 12/5/18 9:55 AM, Stephen Boyd wrote:
> > Quoting Dinh Nguyen (2018-12-05 07:17:41)
> >> Hi Stephen,
> >>
> >> On 12/5/18 1:17 AM, Stephen Boyd wrote:
> >>> (Adding Dinh's korg email)
> >>>
> >>> I also wonder if this driver is even used anymore or maybe we can delete
> >>> it?
> >>>
> >>
> >> The armv7 SoCFPGA platforms are using this driver.
> >>
> > 
> > Ok and those platforms are booting in kernelci.org as
> > https://kernelci.org/boot/socfpga_cyclone5_de0_sockit/ perhaps?
> > 
> 
> Yes that's right.
> 

Ok. Dinh, can you review this patch? Or test it out? Or do I need to get
someone in kernelci to try it out?
Dinh Nguyen Dec. 18, 2018, 3:48 p.m. UTC | #6
On 12/17/18 7:54 PM, Stephen Boyd wrote:
> Quoting Dinh Nguyen (2018-12-06 07:16:47)
>>
>>
>> On 12/5/18 9:55 AM, Stephen Boyd wrote:
>>> Quoting Dinh Nguyen (2018-12-05 07:17:41)
>>>> Hi Stephen,
>>>>
>>>> On 12/5/18 1:17 AM, Stephen Boyd wrote:
>>>>> (Adding Dinh's korg email)
>>>>>
>>>>> I also wonder if this driver is even used anymore or maybe we can delete
>>>>> it?
>>>>>
>>>>
>>>> The armv7 SoCFPGA platforms are using this driver.
>>>>
>>>
>>> Ok and those platforms are booting in kernelci.org as
>>> https://kernelci.org/boot/socfpga_cyclone5_de0_sockit/ perhaps?
>>>
>>
>> Yes that's right.
>>
> 
> Ok. Dinh, can you review this patch? Or test it out? Or do I need to get
> someone in kernelci to try it out?
> 

Just tested on an Arria5 board, feel free to add:

Tested-by: Dinh Nguyen <dinguyen@kernel.org>

Thanks,
Dinh
diff mbox series

Patch

diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index aa7a6e6a15b6..73e03328d5c5 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -176,8 +176,7 @@  static struct clk_ops gateclk_ops = {
 	.set_parent = socfpga_clk_set_parent,
 };
 
-static void __init __socfpga_gate_init(struct device_node *node,
-	const struct clk_ops *ops)
+void __init socfpga_gate_init(struct device_node *node)
 {
 	u32 clk_gate[2];
 	u32 div_reg[3];
@@ -188,12 +187,17 @@  static void __init __socfpga_gate_init(struct device_node *node,
 	const char *clk_name = node->name;
 	const char *parent_name[SOCFPGA_MAX_PARENTS];
 	struct clk_init_data init;
+	struct clk_ops *ops;
 	int rc;
 
 	socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
 	if (WARN_ON(!socfpga_clk))
 		return;
 
+	ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
+	if (WARN_ON(!ops))
+		return;
+
 	rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
 	if (rc)
 		clk_gate[0] = 0;
@@ -202,8 +206,8 @@  static void __init __socfpga_gate_init(struct device_node *node,
 		socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
 		socfpga_clk->hw.bit_idx = clk_gate[1];
 
-		gateclk_ops.enable = clk_gate_ops.enable;
-		gateclk_ops.disable = clk_gate_ops.disable;
+		ops->enable = clk_gate_ops.enable;
+		ops->disable = clk_gate_ops.disable;
 	}
 
 	rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
@@ -234,6 +238,11 @@  static void __init __socfpga_gate_init(struct device_node *node,
 	init.flags = 0;
 
 	init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
+	if (init.num_parents < 2) {
+		ops->get_parent = NULL;
+		ops->set_parent = NULL;
+	}
+
 	init.parent_names = parent_name;
 	socfpga_clk->hw.hw.init = &init;
 
@@ -246,8 +255,3 @@  static void __init __socfpga_gate_init(struct device_node *node,
 	if (WARN_ON(rc))
 		return;
 }
-
-void __init socfpga_gate_init(struct device_node *node)
-{
-	__socfpga_gate_init(node, &gateclk_ops);
-}