return 0;
}
+/*
+ * default shutdown function
+ */
+static void default_shutdown(unsigned int irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+
+ desc->chip->mask(irq);
+ desc->status |= IRQ_MASKED;
+}
+
/*
* Fixup enable/disable function pointers
*/
chip->disable = default_disable;
if (!chip->startup)
chip->startup = default_startup;
+ /*
+ * We use chip->disable, when the user provided its own. When
+ * we have default_disable set for chip->disable, then we need
+ * to use default_shutdown, otherwise the irq line is not
+ * disabled on free_irq():
+ */
if (!chip->shutdown)
- chip->shutdown = chip->disable;
+ chip->shutdown = chip->disable != default_disable ?
+ chip->disable : default_shutdown;
if (!chip->name)
chip->name = chip->typename;
if (!chip->end)
* Note: The caller is expected to handle the ack, clear, mask and
* unmask issues if necessary.
*/
-void fastcall
+void
handle_simple_irq(unsigned int irq, struct irq_desc *desc)
{
struct irqaction *action;
if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
kstat_cpu(cpu).irqs[irq]++;
action = desc->action;
- if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
- if (desc->chip->mask)
- desc->chip->mask(irq);
- desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- desc->status |= IRQ_PENDING;
+ if (unlikely(!action || (desc->status & IRQ_DISABLED)))
goto out_unlock;
- }
- desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING);
desc->status |= IRQ_INPROGRESS;
spin_unlock(&desc->lock);
* it after the associated handler has acknowledged the device, so the
* interrupt line is back to inactive.
*/
-void fastcall
+void
handle_level_irq(unsigned int irq, struct irq_desc *desc)
{
unsigned int cpu = smp_processor_id();
* for modern forms of interrupt handlers, which handle the flow
* details in hardware, transparently.
*/
-void fastcall
+void
handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
{
unsigned int cpu = smp_processor_id();
* the handler was running. If all pending interrupts are handled, the
* loop is left.
*/
-void fastcall
+void
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
const unsigned int cpu = smp_processor_id();
spin_unlock(&desc->lock);
}
-#ifdef CONFIG_SMP
/**
* handle_percpu_IRQ - Per CPU local irq handler
* @irq: the interrupt number
*
* Per CPU interrupts on SMP machines without locking requirements
*/
-void fastcall
+void
handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
{
irqreturn_t action_ret;
desc->chip->eoi(irq);
}
-#endif /* CONFIG_SMP */
-
void
__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
set_irq_chip(irq, chip);
__set_irq_handler(irq, handle, 0, name);
}
+
+void __init set_irq_noprobe(unsigned int irq)
+{
+ struct irq_desc *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
+
+ return;
+ }
+
+ desc = irq_desc + irq;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->status |= IRQ_NOPROBE;
+ spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+void __init set_irq_probe(unsigned int irq)
+{
+ struct irq_desc *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
+
+ return;
+ }
+
+ desc = irq_desc + irq;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->status &= ~IRQ_NOPROBE;
+ spin_unlock_irqrestore(&desc->lock, flags);
+}