title: IRQ handler not getting registered
body: <p>I'm learning interrupt handling in linux kernel and tried below code snippet to register a dummy irq handler on IRQ2. But it seems it is not getting registered as I'm seeing a negative return value and a message in kernel as below , arising from cleanup function which is trying to do <code>free_irq()</code>:</p>
  
  <pre><code>[ 2203.989585] Trying to free already-free IRQ 2
  </code></pre>
  
  <p>below is the printk from kernel log which suggests that it hasn't got registered:</p>
  
  <pre><code>Here with registering IRQ handler on IRQ2 for flowTest...retval_irqreg= -22
  </code></pre>
  
  <p>Below is relevant part of my code which has four functions</p>
  
  <pre><code>1 the bottom half 
  2. handler 
  3. init function 
  4. cleanup function
  </code></pre>
  
  <p>I'm not scheduling the bottom half yet , though it is present below. I'm working on kernel 3.5.0-17.</p>
  
  <pre><code>//Bottom half for the irq handler
  static void bh_flowTest()
      {
          printk(KERN_INFO "Inside bottom half for flowTest.\n");
      }
  // IRQ handler function
  static irqreturn_t flow_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                  {
                  printk(KERN_INFO "This is flowTest IRQ handler.\n");
  
          //static struct tq_struct task = {NULL, 0, bh_flowTest, NULL};
                  /* Schedule bottom half to run */
          //queue_task(&amp;task, &amp;tq_immediate);
  
          // mark_bh(IMMEDIATE_BH);
      return IRQ_HANDLED;             
          }
  
  static int flow_init(void)
      {
      printk(KERN_ALERT "Here with flowTest module ... loading...\n");
   int result=0;
   dev_t dev=0;
  result = alloc_chrdev_region(&amp;dev, minor_num,
  num_devices,"mod_flowtest");                              // allocate major number dynamically.
  
  i=MAJOR(dev);
  printk(KERN_ALERT "Major allocated = %d",i);
  
  cdev_init(&amp;ms_flow_cd,&amp;flow_fops);
  cdev_add(&amp;ms_flow_cd,dev,1);
  
  //Registering interrupt handler on IRQ2 since IRQ2 is free as per /proc/interrupts
  int retval_irqreg;
  retval_irqreg=request_irq(2,(irq_handler_t)flow_irq_handler, /* our handler. It has been typecasted to remove warnings of incompatible pointer type , and enum irqreturn_t. Try removing the cast and see the warnings */
                IRQF_SHARED, 
                "test_flow_irq_handler", NULL);
  printk(KERN_ALERT "Here with registering IRQ handler on IRQ2 for flowTest...retval_irqreg= %d\n",retval_irqreg);
  
  return 0;
      }
  
  static void flow_terminate(void)
      {
      dev_t devno=MKDEV(i,0);         // wrap major/minor numbers in a dev_t structure , to pass for deassigning.
      printk(KERN_ALERT "Going out... exiting...\n");
      unregister_chrdev_region(devno,num_devices);        //remove entry from the /proc/devices
  
      free_irq(2, NULL);
      }
  </code></pre>
  
  <p>I feel there is some basic mistake ,but if someone could point me to that please..!</p>