Skip to content

Commit e33ebb1

Browse files
quic-bjorandegregkh
authored andcommitted
usb: dwc3: qcom: Use bulk clock API and devres
The Qualcomm DWC3 glue driver duplicates the logic of the bulk clock API to acquire, prepare, and unprepare the controller's clocks. It also manages the life cycle of these handled explicitly. Transition to the bulk clock API and manage the resources using devres, to clean up the code. The resource acquisition is moved above the initial reset pulse, to handle resource issues before the state is touched - other than this, this no functional change. Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20250508-dwc3-clk-bulk-v2-1-bad3427e88d4@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4f78a9c commit e33ebb1

1 file changed

Lines changed: 15 additions & 75 deletions

File tree

drivers/usb/dwc3/dwc3-qcom.c

Lines changed: 15 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct dwc3_qcom {
7373
struct device *dev;
7474
void __iomem *qscratch_base;
7575
struct dwc3 dwc;
76-
struct clk **clks;
76+
struct clk_bulk_data *clks;
7777
int num_clocks;
7878
struct reset_control *resets;
7979
struct dwc3_qcom_port ports[DWC3_QCOM_MAX_PORTS];
@@ -431,9 +431,7 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
431431
if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
432432
dev_err(qcom->dev, "port-%d HS-PHY not in L2\n", i + 1);
433433
}
434-
435-
for (i = qcom->num_clocks - 1; i >= 0; i--)
436-
clk_disable_unprepare(qcom->clks[i]);
434+
clk_bulk_disable_unprepare(qcom->num_clocks, qcom->clks);
437435

438436
ret = dwc3_qcom_interconnect_disable(qcom);
439437
if (ret)
@@ -465,14 +463,9 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup)
465463
if (dwc3_qcom_is_host(qcom) && wakeup)
466464
dwc3_qcom_disable_interrupts(qcom);
467465

468-
for (i = 0; i < qcom->num_clocks; i++) {
469-
ret = clk_prepare_enable(qcom->clks[i]);
470-
if (ret < 0) {
471-
while (--i >= 0)
472-
clk_disable_unprepare(qcom->clks[i]);
473-
return ret;
474-
}
475-
}
466+
ret = clk_bulk_prepare_enable(qcom->num_clocks, qcom->clks);
467+
if (ret < 0)
468+
return ret;
476469

477470
ret = dwc3_qcom_interconnect_enable(qcom);
478471
if (ret)
@@ -648,62 +641,14 @@ static int dwc3_qcom_setup_irq(struct dwc3_qcom *qcom, struct platform_device *p
648641
return 0;
649642
}
650643

651-
static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
652-
{
653-
struct device *dev = qcom->dev;
654-
struct device_node *np = dev->of_node;
655-
int i;
656-
657-
if (!np || !count)
658-
return 0;
659-
660-
if (count < 0)
661-
return count;
662-
663-
qcom->num_clocks = count;
664-
665-
qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
666-
sizeof(struct clk *), GFP_KERNEL);
667-
if (!qcom->clks)
668-
return -ENOMEM;
669-
670-
for (i = 0; i < qcom->num_clocks; i++) {
671-
struct clk *clk;
672-
int ret;
673-
674-
clk = of_clk_get(np, i);
675-
if (IS_ERR(clk)) {
676-
while (--i >= 0)
677-
clk_put(qcom->clks[i]);
678-
return PTR_ERR(clk);
679-
}
680-
681-
ret = clk_prepare_enable(clk);
682-
if (ret < 0) {
683-
while (--i >= 0) {
684-
clk_disable_unprepare(qcom->clks[i]);
685-
clk_put(qcom->clks[i]);
686-
}
687-
clk_put(clk);
688-
689-
return ret;
690-
}
691-
692-
qcom->clks[i] = clk;
693-
}
694-
695-
return 0;
696-
}
697-
698644
static int dwc3_qcom_probe(struct platform_device *pdev)
699645
{
700646
struct dwc3_probe_data probe_data = {};
701-
struct device_node *np = pdev->dev.of_node;
702647
struct device *dev = &pdev->dev;
703648
struct dwc3_qcom *qcom;
704649
struct resource res;
705650
struct resource *r;
706-
int ret, i;
651+
int ret;
707652
bool ignore_pipe_clk;
708653
bool wakeup_source;
709654

@@ -719,6 +664,11 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
719664
"failed to get resets\n");
720665
}
721666

667+
ret = devm_clk_bulk_get_all(&pdev->dev, &qcom->clks);
668+
if (ret < 0)
669+
return dev_err_probe(dev, ret, "failed to get clocks\n");
670+
qcom->num_clocks = ret;
671+
722672
ret = reset_control_assert(qcom->resets);
723673
if (ret) {
724674
dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
@@ -733,11 +683,9 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
733683
goto reset_assert;
734684
}
735685

736-
ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
737-
if (ret) {
738-
dev_err_probe(dev, ret, "failed to get clocks\n");
686+
ret = clk_bulk_prepare_enable(qcom->num_clocks, qcom->clks);
687+
if (ret < 0)
739688
goto reset_assert;
740-
}
741689

742690
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
743691
if (!r) {
@@ -806,10 +754,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
806754
remove_core:
807755
dwc3_core_remove(&qcom->dwc);
808756
clk_disable:
809-
for (i = qcom->num_clocks - 1; i >= 0; i--) {
810-
clk_disable_unprepare(qcom->clks[i]);
811-
clk_put(qcom->clks[i]);
812-
}
757+
clk_bulk_disable_unprepare(qcom->num_clocks, qcom->clks);
813758
reset_assert:
814759
reset_control_assert(qcom->resets);
815760

@@ -820,15 +765,10 @@ static void dwc3_qcom_remove(struct platform_device *pdev)
820765
{
821766
struct dwc3 *dwc = platform_get_drvdata(pdev);
822767
struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
823-
int i;
824768

825769
dwc3_core_remove(&qcom->dwc);
826770

827-
for (i = qcom->num_clocks - 1; i >= 0; i--) {
828-
clk_disable_unprepare(qcom->clks[i]);
829-
clk_put(qcom->clks[i]);
830-
}
831-
qcom->num_clocks = 0;
771+
clk_bulk_disable_unprepare(qcom->num_clocks, qcom->clks);
832772

833773
dwc3_qcom_interconnect_exit(qcom);
834774
reset_control_assert(qcom->resets);

0 commit comments

Comments
 (0)