"The cardinal rule of interrupt handlers," in any operating system, is that an interrupt serves only to notify (the "first-level handler" layer of your code ...) that something has just happened that
might, or might not, be of interest to you.
You have to examine the status-flags presented by your device to see if it's the one that's ringing. If it
is your device, then you squash the interrupt ("whack the alarm clock so that it stops ringing ...") and
schedule what is supposed to happen next. Then, get out of there, letting the operating system know that the interrupt was "handled" by you.
But if it is
not your device, you simply exit and let the operating-system call the next first-level handler that it may have in its list for that IRQ.
The majority of the actual work of your driver happens at the
"second-level handler," which is what you scheduled. It is executed "promptly," but not immediately, by the dispatcher ... and at that point, interrupts are enabled again.
"Use the Source, Luke!" There are literally hundreds of device drivers out there, and one of them has
got to be "sufficiently close to whatever-it-is that you are trying to do here" that you can basically steal from it.
(Just be sure that the example that you're looking at is
recent, and that it corresponds to your particular kernel-version/distro, since the low-level "plumbing" at this level of Linux has evolved over these many years.)