{"id":4175,"date":"2022-12-20T17:39:37","date_gmt":"2022-12-20T20:39:37","guid":{"rendered":"http:\/\/lode.uno\/linux-man\/index.php\/2022\/12\/20\/request_irq-man9\/"},"modified":"2022-12-20T17:39:37","modified_gmt":"2022-12-20T20:39:37","slug":"request_irq-man9","status":"publish","type":"post","link":"https:\/\/lode.uno\/linux-man\/2022\/12\/20\/request_irq-man9\/","title":{"rendered":"REQUEST_IRQ (man9)"},"content":{"rendered":"<h1 align=\"center\">REQUEST_IRQ<\/h1>\n<p> <a href=\"#NAME\">NAME<\/a><br \/> <a href=\"#SYNOPSIS\">SYNOPSIS<\/a><br \/> <a href=\"#DESCRIPTION\">DESCRIPTION<\/a><br \/> <a href=\"#RETURN VALUE\">RETURN VALUE<\/a><br \/> <a href=\"#AVAILABILITY\">AVAILABILITY<\/a><br \/> <a href=\"#SEE ALSO\">SEE ALSO<\/a><br \/> <a href=\"#AUTHOR\">AUTHOR<\/a><br \/> <a href=\"#BUGS\">BUGS<\/a> <\/p>\n<hr>\n<h2>NAME <a name=\"NAME\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">request_irq, free_irq \u2212 register an interrupt handler<\/p>\n<h2>SYNOPSIS <a name=\"SYNOPSIS\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>#include <asm\/irq.h> <br \/> #include <linux\/signal.h> #include <linux\/sched.h> #include <linux\/interrupt.h><\/b><\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"89%\">\n<p style=\"margin-top: 1em\"><b>int request_irq(unsigned\u00a0int\u00a0<\/b><i>irq<\/i><b>, void\u00a0(*<\/b><i>handler<\/i><b>)(int,\u00a0void\u00a0*,\u00a0struct\u00a0pt_regs\u00a0*), unsigned\u00a0long<\/b> <i>irqflags<\/i><b>, const\u00a0char\u00a0*<\/b><i>devname<\/i><b>, void\u00a0*<\/b><i>dev_id<\/i><b>);<\/b><\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:11%;\"><b>void\u00a0free_irq(unsigned\u00a0int<\/b> <i>irq<\/i><b>, void\u00a0*<\/b><i>dev_id<\/i><b>);<\/b><\/p>\n<h2>DESCRIPTION <a name=\"DESCRIPTION\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>Usage<\/b> <br \/> The <b>request_irq()<\/b> function requests that a specified function (the handler) be called whenever the kernel receives a given interrupt. The handler may in turn register a bottom half, which is usually a slower part of the handler which does not need to be executed as soon as the interrupt is received. See <b>init_bh<\/b>(9) for more information on bottom halves.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The <i>irq<\/i> parameter is the interrupt number you want to handle. It must be less than <b>NR_IRQS<\/b> (16 on Intel systems), and there may be additional limitations on the value. See <i>arch\/*\/kernel\/irq.c<\/i> (<i>intr.c<\/i> on m68k machines) for more information.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><i>handler<\/i> is a pointer to the a pointer to the function that will handle the interrupt. The handler is passed the following parameters:<\/p>\n<p style=\"margin-left:22%;\"><b>int<\/b> <i>irq<\/i><\/p>\n<p style=\"margin-left:32%;\">The interrupt number. By testing the value of this parameter, it is possible for a single function to handle multiple IRQs.<\/p>\n<p style=\"margin-left:22%;\"><b>void *<\/b><i>dev_id<\/i><\/p>\n<p style=\"margin-left:32%;\">The device ID of this handler (see below).<\/p>\n<p style=\"margin-left:22%;\"><b>struct pt_regs *<\/b><i>regs<\/i><\/p>\n<p style=\"margin-left:32%;\">The registers stored on the stack of the process that was interrupted. Normally, one shouldn\u2019t mess with these, although they can be read to determine, for example, whether the interrupted process was in kernel or user mode.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><i>irqflags<\/i> is, as the name suggests, a bitmask of flags pertaining to this interrupt handler. Legal bits are:<\/p>\n<p style=\"margin-left:22%;\"><b>SA_INTERRUPT<\/b><\/p>\n<p style=\"margin-left:32%;\">This bit indicates that you are registering a fast interrupt handler. The semantics of this are discussed below.<\/p>\n<p style=\"margin-left:22%;\"><b>SA_SHIRQ<\/b><\/p>\n<p style=\"margin-left:32%;\">This bit indicates that your handler supports sharing an IRQ with other handlers (see also *<i>dev_id<\/i> below).<\/p>\n<p style=\"margin-left:22%;\"><b>SA_SAMPLE_RANDOM<\/b><\/p>\n<p style=\"margin-left:32%;\">This bit indicates that this IRQ may be used as an entropy source for <i>\/dev\/random<\/i> and <i>\/dev\/urandom<\/i> (see <i>drivers\/char\/random.c<\/i>).<\/p>\n<p style=\"margin-left:22%;\"><b>SA_PROBE<\/b><\/p>\n<p style=\"margin-left:32%;\">This bit indicates that the IRQ is being probed and that the handler being installed is not a real one. It was intended that this value be used internally by <b>probe_irq_on()<\/b> (q.v.), but it is no longer used in 2.1.x kernels. In fact, even with 2.0.x kernels, it is only used by the MIPS architecture. You should not be using this value unless you know what you are doing.<\/p>\n<p style=\"margin-left:22%;\"><b>SA_STATIC_ALLOC<\/b><\/p>\n<p style=\"margin-left:32%;\">(Sparc\/Sparc64 only) This bit requests that your <b>struct irqaction<\/b> (see below) be added to a statically allocated array of four handlers, rather than the normal <b>irq_action[]<\/b> table. This is used for IRQs that must be requested early in the boot process, before <b>kmalloc_init()<\/b> has been called.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The <i>devname<\/i> parameter is a short name for the device and is displayed in the <i>\/proc\/interrupts<\/i> list.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The <i>dev_id<\/i> parameter is the device ID. This parameter is usually set to NULL, but should be non-null if you wish to do IRQ sharing. This doesn\u2019t matter when hooking the interrupt, but is required so that, when <b>free_irq()<\/b> is called, the correct driver is unhooked. Since this is a <b>void *<\/b>, it can point to anything (such as a device-specific structure, or even empty space), but make sure you pass the same pointer to <b>free_irq()<\/b>.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The <b>free_irq()<\/b> function releases an interrupt handler from operation. It takes as parameters the IRQ to unregister, and the device ID of the handler to be unregistered. You should pass the same values here as you did to <b>request_irq()<\/b>. You probably shouldn\u2019t unregister other people\u2019s interrupt handlers unless you know what you are doing.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>Operation<\/b> <br \/> For most architectures, <b>request_irq()<\/b> operates by allocating memory for a <b>struct irqaction<\/b>, filling out the fields thereof, and adding it to the <b>irq_action[]<\/b> table. <b>enable_irq()<\/b> is then called, which simply tells the kernel to start delivering interrupts to the installed handler. This process is vastly different on m68k machines, where it varies depending on what type of machine (Amiga, Atari, etc.) one is using. <b>free_irq()<\/b> simply removes the entries that <b>request_irq()<\/b> added. Note that some of these names differ depending on the architecture (for example, <b>struct irqaction<\/b> is known as <b>struct irq_action<\/b> on the Power PC). If you need to know more about the internal workings of these functions, you are best off reading the source, as some of this information may have changed by the time you read this (if so, tell me, so I can try to update this page).<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>Fast Interrupt Handlers<\/b> <br \/> A \u2018fast\u2019 interrupt handler (one with <b>SA_INTERRUPT<\/b> set) has the following differences from normal \u2018slow\u2019 interrupt handlers:<\/p>\n<p style=\"margin-left:22%; margin-top: 1em\">On the ix86 and MIPS, the handler is called with interrupts disabled (they are enabled by default on these machines; on other machines, they are disabled by default).<\/p>\n<p style=\"margin-left:22%; margin-top: 1em\">On the MIPS, a faster return is used.<\/p>\n<p style=\"margin-left:22%; margin-top: 1em\">On the Alpha, MIPS, Sparc, and Sparc64, a fast and a slow handler may not share the same IRQ.<\/p>\n<p style=\"margin-left:22%; margin-top: 1em\">On all architectures except the m68k and the ix86, a \u2018+\u2019 is displayed between the interrupt count and the device name in <i>\/proc\/interrupts<\/i>.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The slow-versus-fast interrupt distinction is slowly being phased out. For example, under 2.0.x on the ix86, <b>SA_INTERRUPT<\/b> enabled a fast return as it still does on the MIPS; this distiction was removed in 2.1.x.<\/p>\n<h2>RETURN VALUE <a name=\"RETURN VALUE\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">On success, <b>request_irq()<\/b> returns 0 if everything goes as planned. Your interrupt handler will start receiving its interrupts immediately. On failure, <b>request_irq()<\/b> returns:<\/p>\n<p style=\"margin-left:22%;\"><b>-EINVAL<\/b><\/p>\n<p style=\"margin-left:32%;\">The IRQ number you requested was either invalid or reserved, or your passed a NULL pointer for the <i>handler()<\/i> parameter.<\/p>\n<p style=\"margin-left:22%;\"><b>-ENOMEM<\/b><\/p>\n<p style=\"margin-left:32%;\"><b>request_irq()<\/b> could not allocate enough memory for something (probably the <b>struct irqaction<\/b>).<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"22%\"><\/td>\n<td width=\"9%\">\n<p><b>-EBUSY<\/b><\/p>\n<\/td>\n<td width=\"1%\"><\/td>\n<td width=\"68%\">\n<p>The IRQ you requested is already being handled, and the IRQ cannot be shared. This can occur because either the handler being registered or the handler already present does not have <b>SA_SHIRQ<\/b> in its <i>irqflags<\/i> field. In addition, on most architectures, all handlers sharing a single IRQ must be of the same speed; i.e., either all or none of them may have the <b>SA_INTERRUPT<\/b> flag set. Finally, it is possible that your architecture may not support sharing of the IRQ you are attempting to use.<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"22%\"><\/td>\n<td width=\"9%\">\n<p><b>-ENXIO<\/b><\/p>\n<\/td>\n<td width=\"1%\"><\/td>\n<td width=\"68%\">\n<p>The m68k returns this value for an invalid IRQ number.<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>free_irq()<\/b> does not return a value.<\/p>\n<h2>AVAILABILITY <a name=\"AVAILABILITY\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Linux 2.1+. The information on this page should work for 2.0.x, but there may be subtle differences (for example, the semantics of <b>SA_INTERRUPT<\/b> on Intel-based machines). Versions earlier than 2.0 had these functions, but the <i>dev_id<\/i> parameter was missing. If you want your code to work with versions both earlier and later than 2.0, you should protect your code with preprocessor macros using <b>LINUX_VERSION_CODE<\/b>.<\/p>\n<h2>SEE ALSO <a name=\"SEE ALSO\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>init_bh<\/b>(9), <b>probe_irq_on<\/b>(9), <i>arch\/*\/kernel\/irq.c<\/i>, <i>arch\/*\/kernel\/entry.S<\/i>, <i>include\/linux\/interrupt.h<\/i>, <i>include\/asm*\/signal.h<\/i>.<\/p>\n<h2>AUTHOR <a name=\"AUTHOR\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Neil Moore <<i>amethyst@maxwell.ml.org<\/i>><\/p>\n<h2>BUGS <a name=\"BUGS\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">It\u2019s not exactly a bug, but <b>request_irq()<\/b> on the m68k is <i>very<\/i> strange compared to the same function on the other supported architectures. You should really read <i>arch\/m68k\/kernel\/ints.c<\/i>, <i>arch\/m68k\/atari\/ataints.c<\/i>, <i>arch\/m68k\/amiga\/amiints.c<\/i>, and <i>arch\/m68k\/amiga\/cia.c<\/i> if you plan on writing drivers for any of these systems.<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>  request_irq, free_irq \u2212 register an interrupt handler <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1222],"tags":[1226,1223,1225,1255],"class_list":["post-4175","post","type-post","status-publish","format-standard","hentry","category-9-rutinas-del-nucleo","tag-1226","tag-kernel","tag-man9","tag-request_irq"],"gutentor_comment":0,"_links":{"self":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/4175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/comments?post=4175"}],"version-history":[{"count":0,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/4175\/revisions"}],"wp:attachment":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/media?parent=4175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/categories?post=4175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/tags?post=4175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}