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

usb: dwc3: imx8mp: fix software node kernel dump

When unbind and bind the device again, kernel will dump below warning:

[ 173.972130] sysfs: cannot create duplicate filename '/devices/platform/soc/4c010010.usb/software_node'
[ 173.981564] CPU: 2 UID: 0 PID: 536 Comm: sh Not tainted 6.12.0-rc6-06344-g2aed7c4a5c56 #144
[ 173.989923] Hardware name: NXP i.MX95 15X15 board (DT)
[ 173.995062] Call trace:
[ 173.997509] dump_backtrace+0x90/0xe8
[ 174.001196] show_stack+0x18/0x24
[ 174.004524] dump_stack_lvl+0x74/0x8c
[ 174.008198] dump_stack+0x18/0x24
[ 174.011526] sysfs_warn_dup+0x64/0x80
[ 174.015201] sysfs_do_create_link_sd+0xf0/0xf8
[ 174.019656] sysfs_create_link+0x20/0x40
[ 174.023590] software_node_notify+0x90/0x100
[ 174.027872] device_create_managed_software_node+0xec/0x108
...

The '4c010010.usb' device is a platform device created during the initcall
and is never removed, which causes its associated software node to persist
indefinitely.

The existing device_create_managed_software_node() does not provide a
corresponding removal function.

Replace device_create_managed_software_node() with the
device_add_software_node() and device_remove_software_node() pair to ensure
proper addition and removal of software nodes, addressing this issue.

Fixes: a9400f1979a0 ("usb: dwc3: imx8mp: add 2 software managed quirk properties for host mode")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20241126032841.2458338-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
a4faee01 ef42b906

+16 -14
+16 -14
drivers/usb/dwc3/dwc3-imx8mp.c
··· 129 129 writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL); 130 130 } 131 131 132 + static const struct property_entry dwc3_imx8mp_properties[] = { 133 + PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk"), 134 + PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk"), 135 + {}, 136 + }; 137 + 138 + static const struct software_node dwc3_imx8mp_swnode = { 139 + .properties = dwc3_imx8mp_properties, 140 + }; 141 + 132 142 static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx) 133 143 { 134 144 struct dwc3_imx8mp *dwc3_imx = _dwc3_imx; ··· 156 146 pm_runtime_get(dwc->dev); 157 147 158 148 return IRQ_HANDLED; 159 - } 160 - 161 - static int dwc3_imx8mp_set_software_node(struct device *dev) 162 - { 163 - struct property_entry props[3] = { 0 }; 164 - int prop_idx = 0; 165 - 166 - props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk"); 167 - props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk"); 168 - 169 - return device_create_managed_software_node(dev, props, NULL); 170 149 } 171 150 172 151 static int dwc3_imx8mp_probe(struct platform_device *pdev) ··· 220 221 if (err < 0) 221 222 goto disable_rpm; 222 223 223 - err = dwc3_imx8mp_set_software_node(dev); 224 + err = device_add_software_node(dev, &dwc3_imx8mp_swnode); 224 225 if (err) { 225 226 err = -ENODEV; 226 - dev_err(dev, "failed to create software node\n"); 227 + dev_err(dev, "failed to add software node\n"); 227 228 goto disable_rpm; 228 229 } 229 230 230 231 err = of_platform_populate(node, NULL, NULL, dev); 231 232 if (err) { 232 233 dev_err(&pdev->dev, "failed to create dwc3 core\n"); 233 - goto disable_rpm; 234 + goto remove_swnode; 234 235 } 235 236 236 237 dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np); ··· 254 255 255 256 depopulate: 256 257 of_platform_depopulate(dev); 258 + remove_swnode: 259 + device_remove_software_node(dev); 257 260 disable_rpm: 258 261 pm_runtime_disable(dev); 259 262 pm_runtime_put_noidle(dev); ··· 269 268 270 269 pm_runtime_get_sync(dev); 271 270 of_platform_depopulate(dev); 271 + device_remove_software_node(dev); 272 272 273 273 pm_runtime_disable(dev); 274 274 pm_runtime_put_noidle(dev);