Pārlūkot izejas kodu

irq_domain: Standardise legacy/linear domain selection

A large proportion of interrupt controllers that support legacy mappings
do so because non-DT systems need to use fixed IRQ numbers when registering
devices via buses but can otherwise use a linear mapping. The interrupt
controller itself typically is not affected by the mapping used and best
practice is to use a linear mapping where possible so drivers frequently
select at runtime depending on if a legacy range has been allocated to
them.

Standardise this behaviour by providing irq_domain_register_simple() which
will allocate a linear mapping unless a positive first_irq is provided in
which case it will fall back to a legacy mapping. This helps make best
practice for irq_domain adoption clearer.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Mark Brown 13 gadi atpakaļ
vecāks
revīzija
781d0f46d8
3 mainītis faili ar 40 papildinājumiem un 0 dzēšanām
  1. 5 0
      Documentation/IRQ-domain.txt
  2. 5 0
      include/linux/irqdomain.h
  3. 30 0
      kernel/irq/irqdomain.c

+ 5 - 0
Documentation/IRQ-domain.txt

@@ -93,6 +93,7 @@ Linux IRQ number into the hardware.
 Most drivers cannot use this mapping.
 Most drivers cannot use this mapping.
 
 
 ==== Legacy ====
 ==== Legacy ====
+irq_domain_add_simple()
 irq_domain_add_legacy()
 irq_domain_add_legacy()
 irq_domain_add_legacy_isa()
 irq_domain_add_legacy_isa()
 
 
@@ -115,3 +116,7 @@ The legacy map should only be used if fixed IRQ mappings must be
 supported.  For example, ISA controllers would use the legacy map for
 supported.  For example, ISA controllers would use the legacy map for
 mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
 mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
 numbers.
 numbers.
+
+Most users of legacy mappings should use irq_domain_add_simple() which
+will use a legacy domain only if an IRQ range is supplied by the
+system and will otherwise use a linear domain mapping.

+ 5 - 0
include/linux/irqdomain.h

@@ -112,6 +112,11 @@ struct irq_domain {
 };
 };
 
 
 #ifdef CONFIG_IRQ_DOMAIN
 #ifdef CONFIG_IRQ_DOMAIN
+struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 const struct irq_domain_ops *ops,
+					 void *host_data);
 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 					 unsigned int size,
 					 unsigned int size,
 					 unsigned int first_irq,
 					 unsigned int first_irq,

+ 30 - 0
kernel/irq/irqdomain.c

@@ -139,6 +139,36 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
 	return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq;
 	return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq;
 }
 }
 
 
+/**
+ * irq_domain_add_simple() - Allocate and register a simple irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: total number of irqs in mapping
+ * @first_irq: first number of irq block assigned to the domain
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Allocates a legacy irq_domain if irq_base is positive or a linear
+ * domain otherwise.
+ *
+ * This is intended to implement the expected behaviour for most
+ * interrupt controllers which is that a linear mapping should
+ * normally be used unless the system requires a legacy mapping in
+ * order to support supplying interrupt numbers during non-DT
+ * registration of devices.
+ */
+struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 const struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	if (first_irq > 0)
+		return irq_domain_add_legacy(of_node, size, first_irq, 0,
+					     ops, host_data);
+	else
+		return irq_domain_add_linear(of_node, size, ops, host_data);
+}
+
 /**
 /**
  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
  * @of_node: pointer to interrupt controller's device tree node.
  * @of_node: pointer to interrupt controller's device tree node.