From 760022a2091966deb588cf2fec65bcd73428bce3 Mon Sep 17 00:00:00 2001 From: Frank Wang Date: Thu, 5 Jan 2017 15:08:57 +0800 Subject: [PATCH] usb: dwc2: add bulk clock support Originally, dwc2 just handle one otg clock, however, it may have two or more clock need to manage for some vendor SoCs, so this reworks to use bulk clock APIs. Change-Id: I661297ef908d9eace2215205018fa94d12cea128 Signed-off-by: Frank Wang --- drivers/usb/dwc2/core.h | 3 ++- drivers/usb/dwc2/platform.c | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 7161344c6522..c619c3190b22 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1075,7 +1075,8 @@ struct dwc2_hsotg { spinlock_t lock; void *priv; int irq; - struct clk *clk; + struct clk_bulk_data *clks; + int num_clks; struct reset_control *reset; struct reset_control *reset_ecc; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5f18acac7406..8cac005b0737 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -143,11 +143,9 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) if (ret) return ret; - if (hsotg->clk) { - ret = clk_prepare_enable(hsotg->clk); - if (ret) - return ret; - } + ret = clk_bulk_prepare_enable(hsotg->num_clks, hsotg->clks); + if (ret) + return ret; if (hsotg->uphy) { ret = usb_phy_init(hsotg->uphy); @@ -195,8 +193,7 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (ret) return ret; - if (hsotg->clk) - clk_disable_unprepare(hsotg->clk); + clk_bulk_disable_unprepare(hsotg->num_clks, hsotg->clks); return 0; } @@ -281,10 +278,18 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) hsotg->plat = dev_get_platdata(hsotg->dev); /* Clock */ - hsotg->clk = devm_clk_get_optional(hsotg->dev, "otg"); - if (IS_ERR(hsotg->clk)) { - dev_err(hsotg->dev, "cannot get otg clock\n"); - return PTR_ERR(hsotg->clk); + if (hsotg->dev->of_node) { + ret = devm_clk_bulk_get_all(hsotg->dev, &hsotg->clks); + if (ret == -EPROBE_DEFER) + return ret; + /* + * Clocks are optional, but new DT platforms should support all + * clocks as required by the DT-binding. + */ + if (ret < 0) + hsotg->num_clks = 0; + else + hsotg->num_clks = ret; } /* Regulators */