Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: chipidea: ci_hdrc_imx: add wakeup clock and keep it always on

Some platform using ChipIdea IP may keep 32KHz wakeup clock always
on without usb driver intervention. And some may need driver to handle
this clock. For now only i.MX93 needs this wakeup clock. This patch will
get wakeup clock and keep it always on to make controller work properly.

Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Tested-by: Stefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20231228110753.1755756-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Xu Yang and committed by
Greg Kroah-Hartman
5dbe9ac2 895ee5ae

+16 -1
+16 -1
drivers/usb/chipidea/ci_hdrc_imx.c
··· 96 96 struct usb_phy *phy; 97 97 struct platform_device *ci_pdev; 98 98 struct clk *clk; 99 + struct clk *clk_wakeup; 99 100 struct imx_usbmisc_data *usbmisc_data; 100 101 bool supports_runtime_pm; 101 102 bool override_phy_control; ··· 200 199 201 200 data->clk_ipg = devm_clk_get(dev, "ipg"); 202 201 if (IS_ERR(data->clk_ipg)) { 203 - /* If the platform only needs one clocks */ 202 + /* If the platform only needs one primary clock */ 204 203 data->clk = devm_clk_get(dev, NULL); 205 204 if (IS_ERR(data->clk)) { 206 205 ret = PTR_ERR(data->clk); ··· 209 208 PTR_ERR(data->clk), PTR_ERR(data->clk_ipg)); 210 209 return ret; 211 210 } 211 + /* Get wakeup clock. Not all of the platforms need to 212 + * handle this clock. So make it optional. 213 + */ 214 + data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup_clk"); 215 + if (IS_ERR(data->clk_wakeup)) 216 + ret = dev_err_probe(dev, PTR_ERR(data->clk_wakeup), 217 + "Failed to get wakeup clk\n"); 212 218 return ret; 213 219 } 214 220 ··· 431 423 if (ret) 432 424 goto disable_hsic_regulator; 433 425 426 + ret = clk_prepare_enable(data->clk_wakeup); 427 + if (ret) 428 + goto err_wakeup_clk; 429 + 434 430 data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0); 435 431 if (IS_ERR(data->phy)) { 436 432 ret = PTR_ERR(data->phy); ··· 516 504 disable_device: 517 505 ci_hdrc_remove_device(data->ci_pdev); 518 506 err_clk: 507 + clk_disable_unprepare(data->clk_wakeup); 508 + err_wakeup_clk: 519 509 imx_disable_unprepare_clks(dev); 520 510 disable_hsic_regulator: 521 511 if (data->hsic_pad_regulator) ··· 544 530 usb_phy_shutdown(data->phy); 545 531 if (data->ci_pdev) { 546 532 imx_disable_unprepare_clks(&pdev->dev); 533 + clk_disable_unprepare(data->clk_wakeup); 547 534 if (data->plat_data->flags & CI_HDRC_PMQOS) 548 535 cpu_latency_qos_remove_request(&data->pm_qos_req); 549 536 if (data->hsic_pad_regulator)