Actually, some of these things may be done in the release()
function, and some of these things must be done in the module_exit()
function. It all depends on what you do where.
First, some terminology: module_init()
is called when the module is loaded with insmod. The opposite function is module_exit()
which is called when the module is unloaded with rmmod. open()
is called when a user process tries to open a device file with the open()
system call, and the opposite function release()
is called when the process that opened the device file (as well as all processes that were branched from that original process) call the close()
system call on the file descriptor.
The module_exit() function is the opposite of the module_init() function. Assuming you are using the CDev API, in the module init function you must register a major / minor numbers (D) first with alloc_chrdev_region()
or register_chrdev_region()
before adding the cdev to the system with cdev_init()
and then cdev_add()
.
It stands to reason that when module_exit()
is called, you should undo what you did in the reverse order; i.e. remove the cdev first with cdev_del()
and then unregister the major/minor number with unregister_chrdev_region()
.
At some point in the module_init()
function you may request the GPIO resources with request_mem_region()
& ioremap()
, and then the IRQ resource with request_irq()
. On the other hand you may request the GPIO resources and the IRQ resource in the open()
function instead.
If you request these resources in the module_init()
function, then you should release these resources in the module_exit()
function. However, if you do it in open()
then you should keep track of how many processes have the device file open, and when all of them have released the device file, release the resources in the release()
function.
Again, whatever order you requested the resources in, in general you should release the resources in the opposite order. I will say however, that almost always it is incorrect to release the memory resources (in your case the GPIO resources) before releasing the IRQ resource, since the IRQ will most likely want to talk to the hardware, either in the top half or the bottom half handler.
In summary, the order depends on how you implemented the driver to request the resources in the first place, however, if you implement your drivers like I do, then in general, perform C then B in release()
, and perform A then D in module_exit()
.