Qualcomm DTs are being updated to use a new format where the dwc3 glue node and controller are combined into a single DT node. Update the fixup code to handle this case.
Signed-off-by: Casey Connolly <[email protected]> --- arch/arm/mach-snapdragon/of_fixup.c | 40 +++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index eec2c0c757e0..5b6076ea8e57 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -31,31 +31,37 @@ * USB controllers. Rather than requiring source level DT changes, we fix up * DT here. This improves compatibility with upstream DT and simplifies the * porting process for new devices. */ -static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np) +static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np, bool flat) { struct device_node *dwc3; int ret, len, hsphy_idx = 1; const __be32 *phandles; const char *second_phy_name; debug("Fixing up %s\n", glue_np->name); + /* New DT flattens the glue and controller into a single node. */ + if (flat) { + dwc3 = glue_np; + debug("%s uses flat DT\n", glue_np->name); + } else { + /* Find the DWC3 node itself */ + dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3"); + if (!dwc3) { + log_err("Failed to find dwc3 node\n"); + return -ENOENT; + } + } + /* Tell the glue driver to configure the wrapper for high-speed only operation */ ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL); if (ret) { log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret); return ret; } - /* Find the DWC3 node itself */ - dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3"); - if (!dwc3) { - log_err("Failed to find dwc3 node\n"); - return -ENOENT; - } - phandles = of_get_property(dwc3, "phys", &len); len /= sizeof(*phandles); if (len == 1) { log_debug("Only one phy, not a superspeed controller\n"); @@ -103,15 +109,27 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np } static void fixup_usb_nodes(struct device_node *root) { - struct device_node *glue_np = root; + struct device_node *glue_np = root, *tmp; int ret; + bool flat; + + while (true) { + flat = false; + /* First check for the old DT format with glue node then the new flattened format */ + tmp = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"); + if (!tmp) { + tmp = of_find_compatible_node(glue_np, NULL, "qcom,snps-dwc3"); + flat = !!tmp; + } + if (!tmp) + break; + glue_np = tmp; - while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) { if (!of_device_is_available(glue_np)) continue; - ret = fixup_qcom_dwc3(root, glue_np); + ret = fixup_qcom_dwc3(root, glue_np, flat); if (ret) log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret); } } -- 2.51.0

