From: Thierry Reding Date: Thu, 6 Aug 2020 15:36:50 +0000 (+0200) Subject: of: platform: Destroy child devices symmetrically X-Git-Tag: v5.15~2681^2~99 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70a29209f67cf7dfa7c04975b3261e127694a4e7;p=platform%2Fkernel%2Flinux-starfive.git of: platform: Destroy child devices symmetrically Iterate over child devices in reverse when unpopulating a platform device to make this step symmetrical with the population step. This fixes an issue in the Tegra DRM driver where upon module unload the DPAUX controller tries to unregister an I2C controller but will end up waiting indefinitely because one of the SOR devices is keeping a reference to it. Since the SOR devices are instantiated after the DPAUX devices, they would only be removed (and hence release their reference to the I2C controller) after the DPAUX devices have been removed. While destroying the child devices in reverse order helps in this situation, it isn't fully safe to do so either. An even better way would be for the child devices to be reordered to match the probe order, which would work irrespective of the instantiation order. However, reordering by probe order would be fairly complicated and doesn't fix any known issues, so we'll go with the simpler fix for now. Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20200806153650.3883530-1-thierry.reding@gmail.com Signed-off-by: Rob Herring --- diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 071f04d..b557a0fc 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(of_platform_device_destroy); void of_platform_depopulate(struct device *parent) { if (parent->of_node && of_node_check_flag(parent->of_node, OF_POPULATED_BUS)) { - device_for_each_child(parent, NULL, of_platform_device_destroy); + device_for_each_child_reverse(parent, NULL, of_platform_device_destroy); of_node_clear_flag(parent->of_node, OF_POPULATED_BUS); } }