]> Pileus Git - ~andy/linux/blobdiff - kernel/irq/chip.c
Merge branch 'at91-fixes' of git://github.com/at91linux/linux-at91 into fixes
[~andy/linux] / kernel / irq / chip.c
index dc5114b4c16cc6cd656290cdb03596a2ffd3f3b8..f7c543a801d97a67a2778e2685fa181739a803ac 100644 (file)
@@ -26,7 +26,7 @@
 int irq_set_chip(unsigned int irq, struct irq_chip *chip)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
 
        if (!desc)
                return -EINVAL;
@@ -54,7 +54,7 @@ EXPORT_SYMBOL(irq_set_chip);
 int irq_set_irq_type(unsigned int irq, unsigned int type)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
        int ret = 0;
 
        if (!desc)
@@ -78,7 +78,7 @@ EXPORT_SYMBOL(irq_set_irq_type);
 int irq_set_handler_data(unsigned int irq, void *data)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
 
        if (!desc)
                return -EINVAL;
@@ -98,7 +98,7 @@ EXPORT_SYMBOL(irq_set_handler_data);
 int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
 
        if (!desc)
                return -EINVAL;
@@ -119,7 +119,7 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
 int irq_set_chip_data(unsigned int irq, void *data)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
 
        if (!desc)
                return -EINVAL;
@@ -204,6 +204,24 @@ void irq_disable(struct irq_desc *desc)
        }
 }
 
+void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu)
+{
+       if (desc->irq_data.chip->irq_enable)
+               desc->irq_data.chip->irq_enable(&desc->irq_data);
+       else
+               desc->irq_data.chip->irq_unmask(&desc->irq_data);
+       cpumask_set_cpu(cpu, desc->percpu_enabled);
+}
+
+void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
+{
+       if (desc->irq_data.chip->irq_disable)
+               desc->irq_data.chip->irq_disable(&desc->irq_data);
+       else
+               desc->irq_data.chip->irq_mask(&desc->irq_data);
+       cpumask_clear_cpu(cpu, desc->percpu_enabled);
+}
+
 static inline void mask_ack_irq(struct irq_desc *desc)
 {
        if (desc->irq_data.chip->irq_mask_ack)
@@ -544,12 +562,44 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
                chip->irq_eoi(&desc->irq_data);
 }
 
+/**
+ * handle_percpu_devid_irq - Per CPU local irq handler with per cpu dev ids
+ * @irq:       the interrupt number
+ * @desc:      the interrupt description structure for this irq
+ *
+ * Per CPU interrupts on SMP machines without locking requirements. Same as
+ * handle_percpu_irq() above but with the following extras:
+ *
+ * action->percpu_dev_id is a pointer to percpu variables which
+ * contain the real device id for the cpu on which this handler is
+ * called
+ */
+void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct irqaction *action = desc->action;
+       void *dev_id = __this_cpu_ptr(action->percpu_dev_id);
+       irqreturn_t res;
+
+       kstat_incr_irqs_this_cpu(irq, desc);
+
+       if (chip->irq_ack)
+               chip->irq_ack(&desc->irq_data);
+
+       trace_irq_handler_entry(irq, action);
+       res = action->handler(irq, dev_id);
+       trace_irq_handler_exit(irq, action, res);
+
+       if (chip->irq_eoi)
+               chip->irq_eoi(&desc->irq_data);
+}
+
 void
 __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                  const char *name)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
 
        if (!desc)
                return;
@@ -593,7 +643,7 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
 void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 {
        unsigned long flags;
-       struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
 
        if (!desc)
                return;