Skip to content

Commit 54290bd

Browse files
andredvinodkoul
authored andcommitted
phy: exynos5-usbdrd: convert core clocks to clk_bulk
Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler. No need to check any flags whether or not certain clocks exist or not. Further, we can drop the various handles to the individual clocks in the driver data and instead simply treat them all as one thing. So far, this driver assumes that all platforms have a clock "ref". It also assumes that the clocks "phy_pipe", "phy_utmi", and "itp" exist if the platform data "has_common_clk_gate" is set to true. It then goes and individually tries to acquire and enable and disable all the individual clocks one by one. Rather than relying on these implicit clocks and open-coding the clock handling, we can just explicitly spell out the clock names in the different device data and use that information to populate clk_bulk_data, allowing us to use the clk_bulk APIs for managing the clocks. As a side-effect, this change highlighted the fact that exynos5_usbdrd_phy_power_on() forgot to check the result of the clock enable calls. Using the clk_bulk APIs, the compiler now warns when return values are not checked - therefore add the necessary check instead of silently ignoring failures and continuing as if all is OK when it isn't. For consistency, also change a related dev_err() to dev_err_probe() in exynos5_usbdrd_phy_clk_handle() to get consistent error message formatting. Finally, exynos5_usbdrd_phy_clk_handle() prints an error message in all cases as necessary (except for -ENOMEM). There is no need to print another message in its caller (the probe() function), and printing errors during OOM conditions is usually discouraged. Drop the duplicated message in exynos5_usbdrd_phy_probe(). Signed-off-by: André Draszik <[email protected]> Tested-by: Will McVicker <[email protected]> Reviewed-by: Peter Griffin <[email protected]> Tested-by: Peter Griffin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent bbb28a1 commit 54290bd

File tree

1 file changed

+61
-68
lines changed

1 file changed

+61
-68
lines changed

drivers/phy/samsung/phy-exynos5-usbdrd.c

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -185,37 +185,32 @@ struct exynos5_usbdrd_phy_config {
185185
struct exynos5_usbdrd_phy_drvdata {
186186
const struct exynos5_usbdrd_phy_config *phy_cfg;
187187
const struct phy_ops *phy_ops;
188+
const char * const *core_clk_names;
189+
int n_core_clks;
188190
u32 pmu_offset_usbdrd0_phy;
189191
u32 pmu_offset_usbdrd0_phy_ss;
190192
u32 pmu_offset_usbdrd1_phy;
191-
bool has_common_clk_gate;
192193
};
193194

194195
/**
195196
* struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY
196197
* @dev: pointer to device instance of this platform device
197198
* @reg_phy: usb phy controller register memory base
198199
* @clk: phy clock for register access
199-
* @pipeclk: clock for pipe3 phy
200-
* @utmiclk: clock for utmi+ phy
201-
* @itpclk: clock for ITP generation
200+
* @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
202201
* @drv_data: pointer to SoC level driver data structure
203202
* @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
204203
* instances each with its 'phy' and 'phy_cfg'.
205204
* @extrefclk: frequency select settings when using 'separate
206205
* reference clocks' for SS and HS operations
207-
* @ref_clk: reference clock to PHY block from which PHY's
208-
* operational clocks are derived
209206
* @vbus: VBUS regulator for phy
210207
* @vbus_boost: Boost regulator for VBUS present on few Exynos boards
211208
*/
212209
struct exynos5_usbdrd_phy {
213210
struct device *dev;
214211
void __iomem *reg_phy;
215212
struct clk *clk;
216-
struct clk *pipeclk;
217-
struct clk *utmiclk;
218-
struct clk *itpclk;
213+
struct clk_bulk_data *core_clks;
219214
const struct exynos5_usbdrd_phy_drvdata *drv_data;
220215
struct phy_usb_instance {
221216
struct phy *phy;
@@ -225,7 +220,6 @@ struct exynos5_usbdrd_phy {
225220
const struct exynos5_usbdrd_phy_config *phy_cfg;
226221
} phys[EXYNOS5_DRDPHYS_NUM];
227222
u32 extrefclk;
228-
struct clk *ref_clk;
229223
struct regulator *vbus;
230224
struct regulator *vbus_boost;
231225
};
@@ -505,12 +499,10 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy)
505499

506500
dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
507501

508-
clk_prepare_enable(phy_drd->ref_clk);
509-
if (!phy_drd->drv_data->has_common_clk_gate) {
510-
clk_prepare_enable(phy_drd->pipeclk);
511-
clk_prepare_enable(phy_drd->utmiclk);
512-
clk_prepare_enable(phy_drd->itpclk);
513-
}
502+
ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
503+
phy_drd->core_clks);
504+
if (ret)
505+
return ret;
514506

515507
/* Enable VBUS supply */
516508
if (phy_drd->vbus_boost) {
@@ -540,12 +532,8 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy)
540532
regulator_disable(phy_drd->vbus_boost);
541533

542534
fail_vbus:
543-
clk_disable_unprepare(phy_drd->ref_clk);
544-
if (!phy_drd->drv_data->has_common_clk_gate) {
545-
clk_disable_unprepare(phy_drd->itpclk);
546-
clk_disable_unprepare(phy_drd->utmiclk);
547-
clk_disable_unprepare(phy_drd->pipeclk);
548-
}
535+
clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
536+
phy_drd->core_clks);
549537

550538
return ret;
551539
}
@@ -566,12 +554,8 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy)
566554
if (phy_drd->vbus_boost)
567555
regulator_disable(phy_drd->vbus_boost);
568556

569-
clk_disable_unprepare(phy_drd->ref_clk);
570-
if (!phy_drd->drv_data->has_common_clk_gate) {
571-
clk_disable_unprepare(phy_drd->itpclk);
572-
clk_disable_unprepare(phy_drd->pipeclk);
573-
clk_disable_unprepare(phy_drd->utmiclk);
574-
}
557+
clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
558+
phy_drd->core_clks);
575559

576560
return 0;
577561
}
@@ -885,51 +869,49 @@ static const struct phy_ops exynos850_usbdrd_phy_ops = {
885869

886870
static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
887871
{
888-
unsigned long ref_rate;
889872
int ret;
873+
struct clk *ref_clk;
874+
unsigned long ref_rate;
890875

891876
phy_drd->clk = devm_clk_get(phy_drd->dev, "phy");
892877
if (IS_ERR(phy_drd->clk)) {
893878
dev_err(phy_drd->dev, "Failed to get phy clock\n");
894879
return PTR_ERR(phy_drd->clk);
895880
}
896881

897-
phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref");
898-
if (IS_ERR(phy_drd->ref_clk)) {
899-
dev_err(phy_drd->dev, "Failed to get phy reference clock\n");
900-
return PTR_ERR(phy_drd->ref_clk);
901-
}
902-
ref_rate = clk_get_rate(phy_drd->ref_clk);
903-
904-
ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk);
905-
if (ret) {
906-
dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n",
907-
ref_rate);
908-
return ret;
909-
}
882+
phy_drd->core_clks = devm_kcalloc(phy_drd->dev,
883+
phy_drd->drv_data->n_core_clks,
884+
sizeof(*phy_drd->core_clks),
885+
GFP_KERNEL);
886+
if (!phy_drd->core_clks)
887+
return -ENOMEM;
910888

911-
if (!phy_drd->drv_data->has_common_clk_gate) {
912-
phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe");
913-
if (IS_ERR(phy_drd->pipeclk)) {
914-
dev_info(phy_drd->dev,
915-
"PIPE3 phy operational clock not specified\n");
916-
phy_drd->pipeclk = NULL;
917-
}
889+
for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i)
890+
phy_drd->core_clks[i].id = phy_drd->drv_data->core_clk_names[i];
918891

919-
phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi");
920-
if (IS_ERR(phy_drd->utmiclk)) {
921-
dev_info(phy_drd->dev,
922-
"UTMI phy operational clock not specified\n");
923-
phy_drd->utmiclk = NULL;
924-
}
892+
ret = devm_clk_bulk_get(phy_drd->dev, phy_drd->drv_data->n_core_clks,
893+
phy_drd->core_clks);
894+
if (ret)
895+
return dev_err_probe(phy_drd->dev, ret,
896+
"failed to get phy core clock(s)\n");
925897

926-
phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp");
927-
if (IS_ERR(phy_drd->itpclk)) {
928-
dev_info(phy_drd->dev,
929-
"ITP clock from main OSC not specified\n");
930-
phy_drd->itpclk = NULL;
898+
ref_clk = NULL;
899+
for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) {
900+
if (!strcmp(phy_drd->core_clks[i].id, "ref")) {
901+
ref_clk = phy_drd->core_clks[i].clk;
902+
break;
931903
}
932904
}
905+
if (!ref_clk)
906+
return dev_err_probe(phy_drd->dev, -ENODEV,
907+
"failed to find phy reference clock\n");
908+
909+
ref_rate = clk_get_rate(ref_clk);
910+
ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk);
911+
if (ret)
912+
return dev_err_probe(phy_drd->dev, ret,
913+
"clock rate (%ld) not supported\n",
914+
ref_rate);
933915

934916
return 0;
935917
}
@@ -957,41 +939,54 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = {
957939
},
958940
};
959941

942+
static const char * const exynos5_core_clk_names[] = {
943+
"ref",
944+
};
945+
946+
static const char * const exynos5433_core_clk_names[] = {
947+
"ref", "phy_pipe", "phy_utmi", "itp",
948+
};
949+
960950
static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
961951
.phy_cfg = phy_cfg_exynos5,
962952
.phy_ops = &exynos5_usbdrd_phy_ops,
963953
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
964954
.pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL,
965-
.has_common_clk_gate = true,
955+
.core_clk_names = exynos5_core_clk_names,
956+
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
966957
};
967958

968959
static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = {
969960
.phy_cfg = phy_cfg_exynos5,
970961
.phy_ops = &exynos5_usbdrd_phy_ops,
971962
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
972-
.has_common_clk_gate = true,
963+
.core_clk_names = exynos5_core_clk_names,
964+
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
973965
};
974966

975967
static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = {
976968
.phy_cfg = phy_cfg_exynos5,
977969
.phy_ops = &exynos5_usbdrd_phy_ops,
978970
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
979971
.pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL,
980-
.has_common_clk_gate = false,
972+
.core_clk_names = exynos5433_core_clk_names,
973+
.n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names),
981974
};
982975

983976
static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = {
984977
.phy_cfg = phy_cfg_exynos5,
985978
.phy_ops = &exynos5_usbdrd_phy_ops,
986979
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
987-
.has_common_clk_gate = false,
980+
.core_clk_names = exynos5433_core_clk_names,
981+
.n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names),
988982
};
989983

990984
static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = {
991985
.phy_cfg = phy_cfg_exynos850,
992986
.phy_ops = &exynos850_usbdrd_phy_ops,
993987
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
994-
.has_common_clk_gate = true,
988+
.core_clk_names = exynos5_core_clk_names,
989+
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
995990
};
996991

997992
static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
@@ -1045,10 +1040,8 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
10451040
phy_drd->drv_data = drv_data;
10461041

10471042
ret = exynos5_usbdrd_phy_clk_handle(phy_drd);
1048-
if (ret) {
1049-
dev_err(dev, "Failed to initialize clocks\n");
1043+
if (ret)
10501044
return ret;
1051-
}
10521045

10531046
reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
10541047
"samsung,pmu-syscon");

0 commit comments

Comments
 (0)