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:
Родитель
6b783f7c5d
Коммит
16b2e6e2f3
|
@ -163,6 +163,18 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
|
|||
irq_hw_number_t hwirq);
|
||||
|
||||
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)
|
||||
extern void irq_domain_generate_simple(const struct of_device_id *match,
|
||||
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;
|
||||
}
|
||||
|
||||
int irq_domain_simple_xlate(struct irq_domain *d,
|
||||
struct device_node *controller,
|
||||
/**
|
||||
* irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
|
||||
*
|
||||
* 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)
|
||||
return -EINVAL;
|
||||
if (intsize < 1)
|
||||
if (WARN_ON(intsize < 1))
|
||||
return -EINVAL;
|
||||
*out_hwirq = intspec[0];
|
||||
*out_type = IRQ_TYPE_NONE;
|
||||
if (intsize > 1)
|
||||
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 = {
|
||||
.map = irq_domain_simple_map,
|
||||
.xlate = irq_domain_simple_xlate,
|
||||
.xlate = irq_domain_xlate_onetwocell,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче