On Mon, 20 May 2013, Peter Chen wrote: > After checking the code more, the things should like below: > > At dwc3 core's removal: > 602 static int dwc3_remove(struct platform_device *pdev) > 603 { > 604 struct dwc3 *dwc = platform_get_drvdata(pdev); > 605 > 606 usb_phy_set_suspend(dwc->usb2_phy, 1); > 607 usb_phy_set_suspend(dwc->usb3_phy, 1); > 608 > 609 pm_runtime_put(&pdev->dev); > 610 pm_runtime_disable(&pdev->dev); > > At dwc3-pci's removal: > > 195 static void dwc3_pci_remove(struct pci_dev *pci) > 196 { > 197 struct dwc3_pci *glue = pci_get_drvdata(pci); > 198 > 199 platform_device_unregister(glue->usb2_phy); > 200 platform_device_unregister(glue->usb3_phy); > 201 platform_device_unregister(glue->dwc3); > 202 pci_set_drvdata(pci, NULL); > 203 pci_disable_device(pci); > 204 } > > I am afraid I did not mention "platform_device_unregister(glue->dwc3)" > will call dwc3 core's removal. > > If dwc3 core is removed first, then dwc3-pci. It is ok. > If dwc3-pci is removed first, the PHY's device will be removed, > when "platform_device_unregister(glue->dwc3) ->dwc3_remove > ->usb_phy_set_suspend", the oops will be occurred. > I think it was the problem Paul met. Yes, this sounds right. I had forgotten that dwc3 uses Felipe's "create an intermediate platform device" approach. This means that dwc3_pci_remove should first unregister all the core structures and then unregister the PCI or PHY structures. Alan Stern -- 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