/* Maximum number of Endpoints/HostChannels */
#define MAX_EPS_CHANNELS 16
+/* Maximum number of dwc2 clocks */
+#define DWC2_MAX_CLKS 3
+
/* dwc2-hsotg declarations */
static const char * const dwc2_hsotg_supply_names[] = {
"vusb_d", /* digital USB supply, 1.2V */
spinlock_t lock;
void *priv;
int irq;
- struct clk *clk;
+ struct clk *clks[DWC2_MAX_CLKS];
unsigned int queuing_high_bandwidth:1;
unsigned int srp_success:1;
static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
{
struct platform_device *pdev = to_platform_device(hsotg->dev);
- int ret;
+ int clk, ret;
ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
if (ret)
return ret;
- if (hsotg->clk) {
- ret = clk_prepare_enable(hsotg->clk);
- if (ret)
+ for (clk = 0; clk < DWC2_MAX_CLKS && hsotg->clks[clk]; clk++) {
+ ret = clk_prepare_enable(hsotg->clks[clk]);
+ if (ret) {
+ while (--clk >= 0)
+ clk_disable_unprepare(hsotg->clks[clk]);
return ret;
+ }
}
if (hsotg->uphy)
static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
{
struct platform_device *pdev = to_platform_device(hsotg->dev);
- int ret = 0;
+ int clk, ret = 0;
if (hsotg->uphy)
usb_phy_shutdown(hsotg->uphy);
if (ret)
return ret;
- if (hsotg->clk)
- clk_disable_unprepare(hsotg->clk);
+ for (clk = DWC2_MAX_CLKS - 1; clk >= 0; clk--)
+ if (hsotg->clks[clk])
+ clk_disable_unprepare(hsotg->clks[clk]);
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
{
- int i, ret;
+ int i, clk, ret;
/* Set default UTMI width */
hsotg->phyif = GUSBCFG_PHYIF16;
hsotg->phyif = GUSBCFG_PHYIF8;
}
- /* Clock */
- hsotg->clk = devm_clk_get(hsotg->dev, "otg");
- if (IS_ERR(hsotg->clk)) {
- hsotg->clk = NULL;
- dev_dbg(hsotg->dev, "cannot get otg clock\n");
+ for (clk = 0; clk < DWC2_MAX_CLKS; clk++) {
+ hsotg->clks[clk] = of_clk_get(hsotg->dev->of_node, clk);
+ if (IS_ERR(hsotg->clks[clk])) {
+ ret = PTR_ERR(hsotg->clks[clk]);
+ if (ret == -EPROBE_DEFER) {
+ while (--clk >= 0)
+ clk_put(hsotg->clks[clk]);
+ return ret;
+ }
+
+ hsotg->clks[clk] = NULL;
+ break;
+ }
}
/* Regulators */