e1000e: swap max hw supported frame size between 82574 and 82583
[safe/jmp/linux-2.6] / drivers / mfd / twl4030-irq.c
index fae868a..fb194fe 100644 (file)
@@ -180,9 +180,9 @@ static struct completion irq_event;
 static int twl4030_irq_thread(void *data)
 {
        long irq = (long)data;
-       irq_desc_t *desc = irq_desc + irq;
        static unsigned i2c_errors;
-       const static unsigned max_i2c_errors = 100;
+       static const unsigned max_i2c_errors = 100;
+
 
        current->flags |= PF_NOFREEZE;
 
@@ -215,7 +215,13 @@ static int twl4030_irq_thread(void *data)
                                pih_isr;
                                pih_isr >>= 1, module_irq++) {
                        if (pih_isr & 0x1) {
-                               irq_desc_t *d = irq_desc + module_irq;
+                               struct irq_desc *d = irq_to_desc(module_irq);
+
+                               if (!d) {
+                                       pr_err("twl4030: Invalid SIH IRQ: %d\n",
+                                              module_irq);
+                                       return -EINVAL;
+                               }
 
                                /* These can't be masked ... always warn
                                 * if we get any surprises.
@@ -229,7 +235,7 @@ static int twl4030_irq_thread(void *data)
                }
                local_irq_enable();
 
-               desc->chip->unmask(irq);
+               enable_irq(irq);
        }
 
        return 0;
@@ -244,25 +250,13 @@ static int twl4030_irq_thread(void *data)
  * thread.  All we do here is acknowledge and mask the interrupt and wakeup
  * the kernel thread.
  */
-static void handle_twl4030_pih(unsigned int irq, irq_desc_t *desc)
+static irqreturn_t handle_twl4030_pih(int irq, void *devid)
 {
        /* Acknowledge, clear *AND* mask the interrupt... */
-       desc->chip->ack(irq);
-       complete(&irq_event);
-}
-
-static struct task_struct *start_twl4030_irq_thread(long irq)
-{
-       struct task_struct *thread;
-
-       init_completion(&irq_event);
-       thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq");
-       if (!thread)
-               pr_err("twl4030: could not create irq %ld thread!\n", irq);
-
-       return thread;
+       disable_irq_nosync(irq);
+       complete(devid);
+       return IRQ_HANDLED;
 }
-
 /*----------------------------------------------------------------------*/
 
 /*
@@ -430,7 +424,7 @@ static void twl4030_sih_do_edge(struct work_struct *work)
        /* see what work we have */
        spin_lock_irq(&sih_agent_lock);
        edge_change = agent->edge_change;
-       agent->edge_change = 0;;
+       agent->edge_change = 0;
        sih = edge_change ? agent->sih : NULL;
        spin_unlock_irq(&sih_agent_lock);
        if (!sih)
@@ -452,10 +446,16 @@ static void twl4030_sih_do_edge(struct work_struct *work)
        /* Modify only the bits we know must change */
        while (edge_change) {
                int             i = fls(edge_change) - 1;
-               struct irq_desc *d = irq_desc + i + agent->irq_base;
+               struct irq_desc *d = irq_to_desc(i + agent->irq_base);
                int             byte = 1 + (i >> 2);
                int             off = (i & 0x3) * 2;
 
+               if (!d) {
+                       pr_err("twl4030: Invalid IRQ: %d\n",
+                              i + agent->irq_base);
+                       return;
+               }
+
                bytes[byte] &= ~(0x03 << off);
 
                spin_lock_irq(&d->lock);
@@ -512,9 +512,14 @@ static void twl4030_sih_unmask(unsigned irq)
 static int twl4030_sih_set_type(unsigned irq, unsigned trigger)
 {
        struct sih_agent *sih = get_irq_chip_data(irq);
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
+       if (!desc) {
+               pr_err("twl4030: Invalid IRQ: %d\n", irq);
+               return -EINVAL;
+       }
+
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
 
@@ -712,18 +717,28 @@ int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        }
 
        /* install an irq handler to demultiplex the TWL4030 interrupt */
-       task = start_twl4030_irq_thread(irq_num);
-       if (!task) {
-               pr_err("twl4030: irq thread FAIL\n");
-               status = -ESRCH;
-               goto fail;
-       }
 
-       set_irq_data(irq_num, task);
-       set_irq_chained_handler(irq_num, handle_twl4030_pih);
 
-       return status;
+       init_completion(&irq_event);
 
+       status = request_irq(irq_num, handle_twl4030_pih, IRQF_DISABLED,
+                               "TWL4030-PIH", &irq_event);
+       if (status < 0) {
+               pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
+               goto fail_rqirq;
+       }
+
+       task = kthread_run(twl4030_irq_thread, (void *)irq_num, "twl4030-irq");
+       if (IS_ERR(task)) {
+               pr_err("twl4030: could not create irq %d thread!\n", irq_num);
+               status = PTR_ERR(task);
+               goto fail_kthread;
+       }
+       return status;
+fail_kthread:
+       free_irq(irq_num, &irq_event);
+fail_rqirq:
+       /* clean up twl4030_sih_setup */
 fail:
        for (i = irq_base; i < irq_end; i++)
                set_irq_chip_and_handler(i, NULL, NULL);