Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
usb: dwc3: imx8mp: fix software node kernel dump
Browse files Browse the repository at this point in the history
commit a4faee0 upstream.

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 torvalds#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: a9400f1 ("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>
  • Loading branch information
Xu Yang authored and gregkh committed Dec 17, 2024
1 parent bfe8dc6 commit bd79d9f
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions drivers/usb/dwc3/dwc3-imx8mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ static void dwc3_imx8mp_wakeup_disable(struct dwc3_imx8mp *dwc3_imx)
writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
}

static const struct property_entry dwc3_imx8mp_properties[] = {
PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk"),
PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk"),
{},
};

static const struct software_node dwc3_imx8mp_swnode = {
.properties = dwc3_imx8mp_properties,
};

static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
{
struct dwc3_imx8mp *dwc3_imx = _dwc3_imx;
Expand All @@ -148,17 +158,6 @@ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
return IRQ_HANDLED;
}

static int dwc3_imx8mp_set_software_node(struct device *dev)
{
struct property_entry props[3] = { 0 };
int prop_idx = 0;

props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk");
props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk");

return device_create_managed_software_node(dev, props, NULL);
}

static int dwc3_imx8mp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
Expand Down Expand Up @@ -221,17 +220,17 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
if (err < 0)
goto disable_rpm;

err = dwc3_imx8mp_set_software_node(dev);
err = device_add_software_node(dev, &dwc3_imx8mp_swnode);
if (err) {
err = -ENODEV;
dev_err(dev, "failed to create software node\n");
dev_err(dev, "failed to add software node\n");
goto disable_rpm;
}

err = of_platform_populate(node, NULL, NULL, dev);
if (err) {
dev_err(&pdev->dev, "failed to create dwc3 core\n");
goto disable_rpm;
goto remove_swnode;
}

dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np);
Expand All @@ -255,6 +254,8 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)

depopulate:
of_platform_depopulate(dev);
remove_swnode:
device_remove_software_node(dev);
disable_rpm:
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
Expand All @@ -268,6 +269,7 @@ static void dwc3_imx8mp_remove(struct platform_device *pdev)

pm_runtime_get_sync(dev);
of_platform_depopulate(dev);
device_remove_software_node(dev);

pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
Expand Down

0 comments on commit bd79d9f

Please sign in to comment.