]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/linux/irq.h
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.git] / include / linux / irq.h
index 94d1ad6ffdd4f08198f3787f02f9a843e4981ef5..00db35b61e9ec1e3dc850080681ed93dffa959ad 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/topology.h>
 #include <linux/wait.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -136,6 +137,9 @@ struct irq_domain;
  * @affinity:          IRQ affinity on SMP. If this is an IPI
  *                     related irq, then this is the mask of the
  *                     CPUs to which an IPI can be sent.
+ * @effective_affinity:        The effective IRQ affinity on SMP as some irq
+ *                     chips do not allow multi CPU destinations.
+ *                     A subset of @affinity.
  * @msi_desc:          MSI descriptor
  * @ipi_offset:                Offset of first IPI target cpu in @affinity. Optional.
  */
@@ -147,6 +151,9 @@ struct irq_common_data {
        void                    *handler_data;
        struct msi_desc         *msi_desc;
        cpumask_var_t           affinity;
+#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
+       cpumask_var_t           effective_affinity;
+#endif
 #ifdef CONFIG_GENERIC_IRQ_IPI
        unsigned int            ipi_offset;
 #endif
@@ -199,6 +206,10 @@ struct irq_data {
  * IRQD_WAKEUP_ARMED           - Wakeup mode armed
  * IRQD_FORWARDED_TO_VCPU      - The interrupt is forwarded to a VCPU
  * IRQD_AFFINITY_MANAGED       - Affinity is auto-managed by the kernel
+ * IRQD_IRQ_STARTED            - Startup state of the interrupt
+ * IRQD_MANAGED_SHUTDOWN       - Interrupt was shutdown due to empty affinity
+ *                               mask. Applies only to affinity managed irqs.
+ * IRQD_SINGLE_TARGET          - IRQ allows only a single affinity target
  */
 enum {
        IRQD_TRIGGER_MASK               = 0xf,
@@ -217,6 +228,8 @@ enum {
        IRQD_FORWARDED_TO_VCPU          = (1 << 20),
        IRQD_AFFINITY_MANAGED           = (1 << 21),
        IRQD_IRQ_STARTED                = (1 << 22),
+       IRQD_MANAGED_SHUTDOWN           = (1 << 23),
+       IRQD_SINGLE_TARGET              = (1 << 24),
 };
 
 #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
@@ -265,6 +278,20 @@ static inline bool irqd_is_level_type(struct irq_data *d)
        return __irqd_to_state(d) & IRQD_LEVEL;
 }
 
+/*
+ * Must only be called of irqchip.irq_set_affinity() or low level
+ * hieararchy domain allocation functions.
+ */
+static inline void irqd_set_single_target(struct irq_data *d)
+{
+       __irqd_to_state(d) |= IRQD_SINGLE_TARGET;
+}
+
+static inline bool irqd_is_single_target(struct irq_data *d)
+{
+       return __irqd_to_state(d) & IRQD_SINGLE_TARGET;
+}
+
 static inline bool irqd_is_wakeup_set(struct irq_data *d)
 {
        return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
@@ -335,6 +362,11 @@ static inline bool irqd_is_started(struct irq_data *d)
        return __irqd_to_state(d) & IRQD_IRQ_STARTED;
 }
 
+static inline bool irqd_is_managed_and_shutdown(struct irq_data *d)
+{
+       return __irqd_to_state(d) & IRQD_MANAGED_SHUTDOWN;
+}
+
 #undef __irqd_to_state
 
 static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -484,14 +516,21 @@ extern int irq_set_affinity_locked(struct irq_data *data,
                                   const struct cpumask *cpumask, bool force);
 extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
 
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_IRQ_MIGRATION)
 extern void irq_migrate_all_off_this_cpu(void);
+extern int irq_affinity_online_cpu(unsigned int cpu);
+#else
+# define irq_affinity_online_cpu       NULL
+#endif
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
 void irq_move_irq(struct irq_data *data);
 void irq_move_masked_irq(struct irq_data *data);
+void irq_force_complete_move(struct irq_desc *desc);
 #else
 static inline void irq_move_irq(struct irq_data *data) { }
 static inline void irq_move_masked_irq(struct irq_data *data) { }
+static inline void irq_force_complete_move(struct irq_desc *desc) { }
 #endif
 
 extern int no_irq_affinity;
@@ -733,6 +772,29 @@ static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
        return d->common->affinity;
 }
 
+#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
+static inline
+struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
+{
+       return d->common->effective_affinity;
+}
+static inline void irq_data_update_effective_affinity(struct irq_data *d,
+                                                     const struct cpumask *m)
+{
+       cpumask_copy(d->common->effective_affinity, m);
+}
+#else
+static inline void irq_data_update_effective_affinity(struct irq_data *d,
+                                                     const struct cpumask *m)
+{
+}
+static inline
+struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
+{
+       return d->common->affinity;
+}
+#endif
+
 unsigned int arch_dynirq_lower_bound(unsigned int from);
 
 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
@@ -957,6 +1019,14 @@ int irq_setup_alt_chip(struct irq_data *d, unsigned int type);
 void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
                             unsigned int clr, unsigned int set);
 
+struct irq_chip_generic *
+devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
+                           unsigned int irq_base, void __iomem *reg_base,
+                           irq_flow_handler_t handler);
+int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
+                               u32 msk, enum irq_gc_flags flags,
+                               unsigned int clr, unsigned int set);
+
 struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
 
 int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
@@ -973,6 +1043,19 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
                                         handler, clr, set, flags);     \
 })
 
+static inline void irq_free_generic_chip(struct irq_chip_generic *gc)
+{
+       kfree(gc);
+}
+
+static inline void irq_destroy_generic_chip(struct irq_chip_generic *gc,
+                                           u32 msk, unsigned int clr,
+                                           unsigned int set)
+{
+       irq_remove_generic_chip(gc, msk, clr, set);
+       irq_free_generic_chip(gc);
+}
+
 static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d)
 {
        return container_of(d->chip, struct irq_chip_type, chip);