By statically hardcoding at compile time the number of supplies ("#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)"), the driver assumed that every controller uses supplies and issued a warning if none were detected via the device tree [1], even though the vast majority of devices (with 1 exception from Samsung) don't need nor use them. So to return to normality and stop warning everyone unconditionally, detect if there are any supplies and no-op just like the dummy regulator which got loudly auto-asigned does. This issue has been previously discussed based on an alternative fix at [2] a year back but nothing came out of it then. [1] dwc2 3f980000.usb: 3f980000.usb supply vusb_d not found, using dummy regulator dwc2 3f980000.usb: 3f980000.usb supply vusb_a not found, using dummy regulator [2] https://www.spinics.net/lists/linux-usb/msg153010.html Signed-off-by: Ioan-Adrian Ratiu <adi@xxxxxxxxxx> --- drivers/usb/dwc2/core.h | 5 +++-- drivers/usb/dwc2/platform.c | 46 +++++++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index cd77af3b1565..c50b9fc4a162 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -128,7 +128,7 @@ static const char * const dwc2_hsotg_supply_names[] = { "vusb_a", /* analog USB supply, 1.1V */ }; -#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names) +#define DWC2_MAX_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names) /* * EP0_MPS_LIMIT @@ -921,7 +921,8 @@ struct dwc2_hsotg { struct phy *phy; struct usb_phy *uphy; struct dwc2_hsotg_plat *plat; - struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES]; + struct regulator_bulk_data supplies[DWC2_MAX_SUPPLIES]; + u8 num_supplies; u32 phyif; spinlock_t lock; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 4703478f702f..3acf658af4e9 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -126,10 +126,12 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev); int ret; - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - if (ret) - return ret; + if (hsotg->num_supplies) { + ret = regulator_bulk_enable(hsotg->num_supplies, + hsotg->supplies); + if (ret) + return ret; + } if (hsotg->clk) { ret = clk_prepare_enable(hsotg->clk); @@ -186,8 +188,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (hsotg->clk) clk_disable_unprepare(hsotg->clk); - ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); + if (hsotg->num_supplies) + ret = regulator_bulk_disable(hsotg->num_supplies, + hsotg->supplies); return ret; } @@ -210,6 +213,7 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { + struct regulator *reg; int i, ret; hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); @@ -290,16 +294,30 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "cannot get otg clock\n"); } - /* Regulators */ - for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) - hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; + /* Regulators, vast majority of dwc2 devices don't use them at all */ + for (i = 0; i < DWC2_MAX_SUPPLIES; i++) { + reg = regulator_get_optional(hsotg->dev, + dwc2_hsotg_supply_names[i]); + + /* All or nothing (bulk): regs either are or aren't present */ + if (IS_ERR(reg)) { + while (--i >= 0) { + regulator_put(hsotg->supplies[i].consumer); + hsotg->supplies[i].consumer = NULL; + hsotg->supplies[i].supply = NULL; + --hsotg->num_supplies; + } + break; + } - ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - if (ret) { - dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); - return ret; + hsotg->supplies[i].consumer = reg; + hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; + ++hsotg->num_supplies; } + + WARN_ON(hsotg->num_supplies && + hsotg->num_supplies != DWC2_MAX_SUPPLIES); + return 0; } -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html