irq_domain: Create common xlate functions that device drivers can use
Rather than having each interrupt controller driver creating its own barely unique .xlate function for irq_domain, create a library of translators which any driver can use directly. v5: - Remove irq_domain_xlate_pci(). It was incorrect. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Mark Salter <msalter@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Milton Miller <miltonm@bga.com> Tested-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
@@ -163,6 +163,18 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
|
|||||||
irq_hw_number_t hwirq);
|
irq_hw_number_t hwirq);
|
||||||
|
|
||||||
extern struct irq_domain_ops irq_domain_simple_ops;
|
extern struct irq_domain_ops irq_domain_simple_ops;
|
||||||
|
|
||||||
|
/* stock xlate functions */
|
||||||
|
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
||||||
|
int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
||||||
|
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)
|
#if defined(CONFIG_OF_IRQ)
|
||||||
extern void irq_domain_generate_simple(const struct of_device_id *match,
|
extern void irq_domain_generate_simple(const struct of_device_id *match,
|
||||||
u64 phys_base, unsigned int irq_start);
|
u64 phys_base, unsigned int irq_start);
|
||||||
|
@@ -699,25 +699,70 @@ int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int irq_domain_simple_xlate(struct irq_domain *d,
|
/**
|
||||||
struct device_node *controller,
|
* irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
|
||||||
const u32 *intspec, unsigned int intsize,
|
*
|
||||||
unsigned long *out_hwirq, unsigned int *out_type)
|
* Device Tree IRQ specifier translation function which works with one cell
|
||||||
|
* bindings where the cell value maps directly to the hwirq number.
|
||||||
|
*/
|
||||||
|
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
unsigned long *out_hwirq, unsigned int *out_type)
|
||||||
{
|
{
|
||||||
if (d->of_node != controller)
|
if (WARN_ON(intsize < 1))
|
||||||
return -EINVAL;
|
|
||||||
if (intsize < 1)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*out_hwirq = intspec[0];
|
*out_hwirq = intspec[0];
|
||||||
*out_type = IRQ_TYPE_NONE;
|
*out_type = IRQ_TYPE_NONE;
|
||||||
if (intsize > 1)
|
|
||||||
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings
|
||||||
|
*
|
||||||
|
* Device Tree IRQ specifier translation function which works with two cell
|
||||||
|
* bindings where the cell values map directly to the hwirq number
|
||||||
|
* and linux irq flags.
|
||||||
|
*/
|
||||||
|
int irq_domain_xlate_twocell(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 (WARN_ON(intsize < 2))
|
||||||
|
return -EINVAL;
|
||||||
|
*out_hwirq = intspec[0];
|
||||||
|
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
|
||||||
|
*
|
||||||
|
* Device Tree IRQ specifier translation function which works with either one
|
||||||
|
* or two cell bindings where the cell values map directly to the hwirq number
|
||||||
|
* and linux irq flags.
|
||||||
|
*
|
||||||
|
* Note: don't use this function unless your interrupt controller explicitly
|
||||||
|
* supports both one and two cell bindings. For the majority of controllers
|
||||||
|
* the _onecell() or _twocell() variants above should be used.
|
||||||
|
*/
|
||||||
|
int irq_domain_xlate_onetwocell(struct irq_domain *d,
|
||||||
|
struct device_node *ctrlr,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
unsigned long *out_hwirq, unsigned int *out_type)
|
||||||
|
{
|
||||||
|
if (WARN_ON(intsize < 1))
|
||||||
|
return -EINVAL;
|
||||||
|
*out_hwirq = intspec[0];
|
||||||
|
*out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);
|
||||||
|
|
||||||
struct irq_domain_ops irq_domain_simple_ops = {
|
struct irq_domain_ops irq_domain_simple_ops = {
|
||||||
.map = irq_domain_simple_map,
|
.map = irq_domain_simple_map,
|
||||||
.xlate = irq_domain_simple_xlate,
|
.xlate = irq_domain_xlate_onetwocell,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
|
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user