]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/irqdomain.h
Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux
[karo-tx-linux.git] / include / linux / irqdomain.h
index ba2c708adcff7da4b277ae9038c2779229831a8e..c983ed18c3326d8531a8acd01f1d83c65d9756e5 100644 (file)
@@ -73,57 +73,48 @@ struct irq_domain_chip_generic;
 /**
  * struct irq_domain - Hardware interrupt number translation object
  * @link: Element in global irq_domain list.
- * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This
- *               will be one of the IRQ_DOMAIN_MAP_* values.
- * @revmap_data: Revmap method specific data.
+ * @name: Name of interrupt domain
  * @ops: pointer to irq_domain methods
  * @host_data: private data pointer for use by owner.  Not touched by irq_domain
  *             core code.
- * @irq_base: Start of irq_desc range assigned to the irq_domain.  The creator
- *            of the irq_domain is responsible for allocating the array of
- *            irq_desc structures.
- * @nr_irq: Number of irqs managed by the irq domain
- * @hwirq_base: Starting number for hwirqs managed by the irq domain
- * @of_node: (optional) Pointer to device tree nodes associated with the
- *           irq_domain.  Used when decoding device tree interrupt specifiers.
+ *
+ * Optional elements
+ * @of_node: Pointer to device tree nodes associated with the irq_domain. Used
+ *           when decoding device tree interrupt specifiers.
+ * @gc: Pointer to a list of generic chips. There is a helper function for
+ *      setting up one or more generic chips for interrupt controllers
+ *      drivers using the generic chip library which uses this pointer.
+ *
+ * Revmap data, used internally by irq_domain
+ * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
+ *                         support direct mapping
+ * @revmap_size: Size of the linear map table @linear_revmap[]
+ * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
+ * @linear_revmap: Linear table of hwirq->virq reverse mappings
  */
 struct irq_domain {
        struct list_head link;
-
-       /* type of reverse mapping_technique */
-       unsigned int revmap_type;
-       union {
-               struct {
-                       unsigned int size;
-                       unsigned int first_irq;
-                       irq_hw_number_t first_hwirq;
-               } legacy;
-               struct {
-                       unsigned int size;
-                       unsigned int *revmap;
-               } linear;
-               struct {
-                       unsigned int max_irq;
-               } nomap;
-               struct radix_tree_root tree;
-       } revmap_data;
+       const char *name;
        const struct irq_domain_ops *ops;
        void *host_data;
-       irq_hw_number_t inval_irq;
 
-       /* Optional device node pointer */
+       /* Optional data */
        struct device_node *of_node;
-       /* Optional pointer to generic interrupt chips */
        struct irq_domain_chip_generic *gc;
-};
 
-#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
-                                * ie. legacy 8259, gets irqs 1..15 */
-#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
+       /* reverse map data. The linear map gets appended to the irq_domain */
+       irq_hw_number_t hwirq_max;
+       unsigned int revmap_direct_max_irq;
+       unsigned int revmap_size;
+       struct radix_tree_root revmap_tree;
+       unsigned int linear_revmap[];
+};
 
 #ifdef CONFIG_IRQ_DOMAIN
+struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
+                                   irq_hw_number_t hwirq_max, int direct_max,
+                                   const struct irq_domain_ops *ops,
+                                   void *host_data);
 struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
                                         unsigned int size,
                                         unsigned int first_irq,
@@ -135,21 +126,30 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
                                         irq_hw_number_t first_hwirq,
                                         const struct irq_domain_ops *ops,
                                         void *host_data);
-struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+
+/**
+ * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: Number of interrupts in the domain.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
                                         unsigned int size,
                                         const struct irq_domain_ops *ops,
-                                        void *host_data);
-struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        void *host_data)
+{
+       return __irq_domain_add(of_node, size, size, 0, ops, host_data);
+}
+static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
                                         unsigned int max_irq,
                                         const struct irq_domain_ops *ops,
-                                        void *host_data);
-struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
-                                        const struct irq_domain_ops *ops,
-                                        void *host_data);
-
-extern struct irq_domain *irq_find_host(struct device_node *node);
-extern void irq_set_default_host(struct irq_domain *host);
-
+                                        void *host_data)
+{
+       return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data);
+}
 static inline struct irq_domain *irq_domain_add_legacy_isa(
                                struct device_node *of_node,
                                const struct irq_domain_ops *ops,
@@ -158,21 +158,40 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
        return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
                                     host_data);
 }
+static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+                                        const struct irq_domain_ops *ops,
+                                        void *host_data)
+{
+       return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data);
+}
 
 extern void irq_domain_remove(struct irq_domain *host);
 
-extern int irq_domain_associate_many(struct irq_domain *domain,
-                                    unsigned int irq_base,
-                                    irq_hw_number_t hwirq_base, int count);
-static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
-                                       irq_hw_number_t hwirq)
-{
-       return irq_domain_associate_many(domain, irq, hwirq, 1);
-}
+extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
+                                       irq_hw_number_t hwirq);
+extern void irq_domain_associate_many(struct irq_domain *domain,
+                                     unsigned int irq_base,
+                                     irq_hw_number_t hwirq_base, int count);
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
                                       irq_hw_number_t hwirq);
 extern void irq_dispose_mapping(unsigned int virq);
+
+/**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is a fast path alternative to irq_find_mapping() that can be
+ * called directly by irq controller code to save a handful of
+ * instructions. It is always safe to call, but won't find irqs mapped
+ * using the radix tree.
+ */
+static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
+                                            irq_hw_number_t hwirq)
+{
+       return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0;
+}
 extern unsigned int irq_find_mapping(struct irq_domain *host,
                                     irq_hw_number_t hwirq);
 extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
@@ -186,9 +205,6 @@ static inline int irq_create_identity_mapping(struct irq_domain *host,
        return irq_create_strict_mappings(host, hwirq, hwirq, 1);
 }
 
-extern unsigned int irq_linear_revmap(struct irq_domain *host,
-                                     irq_hw_number_t hwirq);
-
 extern const struct irq_domain_ops irq_domain_simple_ops;
 
 /* stock xlate functions */
@@ -202,14 +218,6 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
                        const u32 *intspec, unsigned int intsize,
                        irq_hw_number_t *out_hwirq, unsigned int *out_type);
 
-#if defined(CONFIG_OF_IRQ)
-extern void irq_domain_generate_simple(const struct of_device_id *match,
-                                       u64 phys_base, unsigned int irq_start);
-#else /* CONFIG_OF_IRQ */
-static inline void irq_domain_generate_simple(const struct of_device_id *match,
-                                       u64 phys_base, unsigned int irq_start) { }
-#endif /* !CONFIG_OF_IRQ */
-
 #else /* CONFIG_IRQ_DOMAIN */
 static inline void irq_dispose_mapping(unsigned int virq) { }
 #endif /* !CONFIG_IRQ_DOMAIN */