Device driver .shutdown() VS .remove()
Hello, despite having been searching for documentation I couldn't find out the exact and detailed difference between the .shutdown() and .remove() calls in struct device_driver. My best understanding follows. Any amendment or clarification would be appreciated, and why not it might end up in improving the docs. The different intent is kind of clear: remove() is called when the device is disconnected or otherwise removed from the system, and also when the driver is removed (which can only happen by unloading a kernel module, I think). shutdown() is called during reboot and shutdown. remove() is _not_ called during shutdown and reboot. shutdown() is not called on device or driver removal. Things get more blurred when trying to understand what each of the two should do. Definitely both must stop the device from producing any events to the rest of the system: stop DMAs, stop anything that would trigger interrupts etc. remove() should also "turn off" the device, but it's probably a good idea to do in shutdown() as well in order to not leave peripherals unnecessarily powered while rebooting. remove() must definitely free any allocated resources, which would be useless in shutdown().
From the above it looks like the shutdown() actions must be a subset of remove() actions.
How much of my understanding is correct? Thanks. -- Luca
On Thu, Apr 22, 2021 at 1:37 AM Luca Ceresoli <luca@lucaceresoli.net> wrote:
Hello,
despite having been searching for documentation I couldn't find out the exact and detailed difference between the .shutdown() and .remove() calls in struct device_driver.
so, I'll start by saying I know next to nothing, but most of what you said sounds good
From the above it looks like the shutdown() actions must be a subset of remove() actions.
but subset is a bit vague. theres 2 dimensions to think about. lifetime - shutdown/startup is surely the longer window, add/remove happen within that hierarchy - subsystems must be ready to handle add / remove fwiw, I 'grepped' (with ack), it shows a few drivers with both functions, many others with just remove you could see in detail what the difference is. $> ack '(\.remove|\.shutdown)\b' drivers/ drivers/rtc/rtc-twl.c 645: .remove = twl_rtc_remove, 646: .shutdown = twl_rtc_shutdown,
Hi Jim, thanks for the discussion. On 22/04/21 20:05, jim.cromie@gmail.com wrote:
On Thu, Apr 22, 2021 at 1:37 AM Luca Ceresoli <luca@lucaceresoli.net <mailto:luca@lucaceresoli.net>> wrote:
Hello,
despite having been searching for documentation I couldn't find out the exact and detailed difference between the .shutdown() and .remove() calls in struct device_driver.
so, I'll start by saying I know next to nothing, but most of what you said sounds good
Good to know.
From the above it looks like the shutdown() actions must be a subset of remove() actions.
but subset is a bit vague. theres 2 dimensions to think about. lifetime - shutdown/startup is surely the longer window, add/remove happen within that hierarchy - subsystems must be ready to handle add / remove
fwiw, I 'grepped' (with ack), it shows a few drivers with both functions, many others with just remove you could see in detail what the difference is.
$> ack '(\.remove|\.shutdown)\b' drivers/ drivers/rtc/rtc-twl.c 645: .remove = twl_rtc_remove, 646: .shutdown = twl_rtc_shutdown,
I've been looking at a few of the drivers that implement both calls, and they either look similar or they call the shutdown function within the remove function. This reinforces the idea that remove() should do the same things as shutdown() plus free all kernel resources. The only exception that I noticed happen for devices that don't have to be completely turned off during shutdown or reboot, such as RTCs. -- Luca
participants (2)
-
jim.cromie@gmail.com -
Luca Ceresoli