Skip to content

Commit f491276

Browse files
aford173bebarino
authored andcommitted
clk: vc5: Allow Versaclock driver to support multiple instances
Currently, the Versaclock driver is only expecting one instance and uses hard-coded names for the various clock names. Unfortunately, this is a problem when there is more than one instance of the driver, because the subsequent instantiations of the driver use the identical name. Each clock after the fist fails to load, because the clock subsystem cannot handle two clocks with identical name. This patch removes the hard-coded name arrays and uses kasprintf to assign clock names based on names of their respective node and parent node which gives each clock a unique identifying name. For a verasaclock node with a name like: versaclock5: versaclock_som@6a The updated clock names would appear like: versaclock_som.mux versaclock_som.out0_sel_i2cb versaclock_som.pfd versaclock_som.pll versaclock_som.fod3 versaclock_som.out4 versaclock_som.fod2 versaclock_som.out3 versaclock_som.fod1 versaclock_som.out2 versaclock_som.fod0 versaclock_som.out1 Signed-off-by: Adam Ford <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent b3a9e3b commit f491276

File tree

1 file changed

+37
-47
lines changed

1 file changed

+37
-47
lines changed

drivers/clk/clk-versaclock5.c

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -161,30 +161,6 @@ struct vc5_driver_data {
161161
struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM];
162162
};
163163

164-
static const char * const vc5_mux_names[] = {
165-
"mux"
166-
};
167-
168-
static const char * const vc5_dbl_names[] = {
169-
"dbl"
170-
};
171-
172-
static const char * const vc5_pfd_names[] = {
173-
"pfd"
174-
};
175-
176-
static const char * const vc5_pll_names[] = {
177-
"pll"
178-
};
179-
180-
static const char * const vc5_fod_names[] = {
181-
"fod0", "fod1", "fod2", "fod3",
182-
};
183-
184-
static const char * const vc5_clk_out_names[] = {
185-
"out0_sel_i2cb", "out1", "out2", "out3", "out4",
186-
};
187-
188164
/*
189165
* VersaClock5 i2c regmap
190166
*/
@@ -692,8 +668,7 @@ static int vc5_map_index_to_output(const enum vc5_model model,
692668

693669
static const struct of_device_id clk_vc5_of_match[];
694670

695-
static int vc5_probe(struct i2c_client *client,
696-
const struct i2c_device_id *id)
671+
static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
697672
{
698673
struct vc5_driver_data *vc5;
699674
struct clk_init_data init;
@@ -742,20 +717,21 @@ static int vc5_probe(struct i2c_client *client,
742717
if (!IS_ERR(vc5->pin_clkin)) {
743718
vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
744719
parent_names[init.num_parents++] =
745-
__clk_get_name(vc5->pin_clkin);
720+
__clk_get_name(vc5->pin_clkin);
746721
}
747722

748723
if (!init.num_parents) {
749724
dev_err(&client->dev, "no input clock specified!\n");
750725
return -EINVAL;
751726
}
752727

753-
init.name = vc5_mux_names[0];
728+
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
754729
init.ops = &vc5_mux_ops;
755730
init.flags = 0;
756731
init.parent_names = parent_names;
757732
vc5->clk_mux.init = &init;
758733
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
734+
kfree(init.name); /* clock framework made a copy of the name */
759735
if (ret) {
760736
dev_err(&client->dev, "unable to register %s\n", init.name);
761737
goto err_clk;
@@ -764,13 +740,16 @@ static int vc5_probe(struct i2c_client *client,
764740
if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
765741
/* Register frequency doubler */
766742
memset(&init, 0, sizeof(init));
767-
init.name = vc5_dbl_names[0];
743+
init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
744+
client->dev.of_node);
768745
init.ops = &vc5_dbl_ops;
769746
init.flags = CLK_SET_RATE_PARENT;
770-
init.parent_names = vc5_mux_names;
747+
init.parent_names = parent_names;
748+
parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
771749
init.num_parents = 1;
772750
vc5->clk_mul.init = &init;
773751
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
752+
kfree(init.name); /* clock framework made a copy of the name */
774753
if (ret) {
775754
dev_err(&client->dev, "unable to register %s\n",
776755
init.name);
@@ -780,32 +759,36 @@ static int vc5_probe(struct i2c_client *client,
780759

781760
/* Register PFD */
782761
memset(&init, 0, sizeof(init));
783-
init.name = vc5_pfd_names[0];
762+
init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
784763
init.ops = &vc5_pfd_ops;
785764
init.flags = CLK_SET_RATE_PARENT;
765+
init.parent_names = parent_names;
786766
if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
787-
init.parent_names = vc5_dbl_names;
767+
parent_names[0] = clk_hw_get_name(&vc5->clk_mul);
788768
else
789-
init.parent_names = vc5_mux_names;
769+
parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
790770
init.num_parents = 1;
791771
vc5->clk_pfd.init = &init;
792772
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
773+
kfree(init.name); /* clock framework made a copy of the name */
793774
if (ret) {
794775
dev_err(&client->dev, "unable to register %s\n", init.name);
795776
goto err_clk;
796777
}
797778

798779
/* Register PLL */
799780
memset(&init, 0, sizeof(init));
800-
init.name = vc5_pll_names[0];
781+
init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
801782
init.ops = &vc5_pll_ops;
802783
init.flags = CLK_SET_RATE_PARENT;
803-
init.parent_names = vc5_pfd_names;
784+
init.parent_names = parent_names;
785+
parent_names[0] = clk_hw_get_name(&vc5->clk_pfd);
804786
init.num_parents = 1;
805787
vc5->clk_pll.num = 0;
806788
vc5->clk_pll.vc5 = vc5;
807789
vc5->clk_pll.hw.init = &init;
808790
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
791+
kfree(init.name); /* clock framework made a copy of the name */
809792
if (ret) {
810793
dev_err(&client->dev, "unable to register %s\n", init.name);
811794
goto err_clk;
@@ -815,15 +798,18 @@ static int vc5_probe(struct i2c_client *client,
815798
for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
816799
idx = vc5_map_index_to_output(vc5->chip_info->model, n);
817800
memset(&init, 0, sizeof(init));
818-
init.name = vc5_fod_names[idx];
801+
init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
802+
client->dev.of_node, idx);
819803
init.ops = &vc5_fod_ops;
820804
init.flags = CLK_SET_RATE_PARENT;
821-
init.parent_names = vc5_pll_names;
805+
init.parent_names = parent_names;
806+
parent_names[0] = clk_hw_get_name(&vc5->clk_pll.hw);
822807
init.num_parents = 1;
823808
vc5->clk_fod[n].num = idx;
824809
vc5->clk_fod[n].vc5 = vc5;
825810
vc5->clk_fod[n].hw.init = &init;
826811
ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
812+
kfree(init.name); /* clock framework made a copy of the name */
827813
if (ret) {
828814
dev_err(&client->dev, "unable to register %s\n",
829815
init.name);
@@ -833,41 +819,45 @@ static int vc5_probe(struct i2c_client *client,
833819

834820
/* Register MUX-connected OUT0_I2C_SELB output */
835821
memset(&init, 0, sizeof(init));
836-
init.name = vc5_clk_out_names[0];
822+
init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
823+
client->dev.of_node);
837824
init.ops = &vc5_clk_out_ops;
838825
init.flags = CLK_SET_RATE_PARENT;
839-
init.parent_names = vc5_mux_names;
826+
init.parent_names = parent_names;
827+
parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
840828
init.num_parents = 1;
841829
vc5->clk_out[0].num = idx;
842830
vc5->clk_out[0].vc5 = vc5;
843831
vc5->clk_out[0].hw.init = &init;
844832
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
833+
kfree(init.name); /* clock framework made a copy of the name */
845834
if (ret) {
846-
dev_err(&client->dev, "unable to register %s\n",
847-
init.name);
835+
dev_err(&client->dev, "unable to register %s\n", init.name);
848836
goto err_clk;
849837
}
850838

851839
/* Register FOD-connected OUTx outputs */
852840
for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
853841
idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
854-
parent_names[0] = vc5_fod_names[idx];
842+
parent_names[0] = clk_hw_get_name(&vc5->clk_fod[idx].hw);
855843
if (n == 1)
856-
parent_names[1] = vc5_mux_names[0];
844+
parent_names[1] = clk_hw_get_name(&vc5->clk_mux);
857845
else
858-
parent_names[1] = vc5_clk_out_names[n - 1];
846+
parent_names[1] =
847+
clk_hw_get_name(&vc5->clk_out[n - 1].hw);
859848

860849
memset(&init, 0, sizeof(init));
861-
init.name = vc5_clk_out_names[idx + 1];
850+
init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
851+
client->dev.of_node, idx + 1);
862852
init.ops = &vc5_clk_out_ops;
863853
init.flags = CLK_SET_RATE_PARENT;
864854
init.parent_names = parent_names;
865855
init.num_parents = 2;
866856
vc5->clk_out[n].num = idx;
867857
vc5->clk_out[n].vc5 = vc5;
868858
vc5->clk_out[n].hw.init = &init;
869-
ret = devm_clk_hw_register(&client->dev,
870-
&vc5->clk_out[n].hw);
859+
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
860+
kfree(init.name); /* clock framework made a copy of the name */
871861
if (ret) {
872862
dev_err(&client->dev, "unable to register %s\n",
873863
init.name);

0 commit comments

Comments
 (0)