irqdomain: Support three-cell scheme interrupts
Add new function *_twothreecell() to extend support to parse three-cell interrupts which encoded as <instance hwirq irqflag>, the translate function will retrieve irq number and flag from last two cells. This API will be used in gpio irq driver which need to work with two or three cells cases. Signed-off-by: Yixun Lan <dlan@gentoo.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20250326-04-gpio-irq-threecell-v3-1-aab006ab0e00@gentoo.orgpull/1250/head
parent
0af2f6be1b
commit
0a02e1f4a5
|
|
@ -571,16 +571,16 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
|
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
const u32 *intspec, unsigned int intsize,
|
const u32 *intspec, unsigned int intsize,
|
||||||
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
||||||
|
int irq_domain_xlate_twothreecell(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_translate_twocell(struct irq_domain *d,
|
int irq_domain_translate_onecell(struct irq_domain *d, struct irq_fwspec *fwspec,
|
||||||
struct irq_fwspec *fwspec,
|
unsigned long *out_hwirq, unsigned int *out_type);
|
||||||
unsigned long *out_hwirq,
|
int irq_domain_translate_twocell(struct irq_domain *d, struct irq_fwspec *fwspec,
|
||||||
unsigned int *out_type);
|
unsigned long *out_hwirq, unsigned int *out_type);
|
||||||
|
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec,
|
||||||
int irq_domain_translate_onecell(struct irq_domain *d,
|
unsigned long *out_hwirq, unsigned int *out_type);
|
||||||
struct irq_fwspec *fwspec,
|
|
||||||
unsigned long *out_hwirq,
|
|
||||||
unsigned int *out_type);
|
|
||||||
|
|
||||||
/* IPI functions */
|
/* IPI functions */
|
||||||
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
|
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
|
||||||
|
|
|
||||||
|
|
@ -1132,6 +1132,31 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_domain_xlate_twothreecell() - Generic xlate for direct two or three cell bindings
|
||||||
|
* @d: Interrupt domain involved in the translation
|
||||||
|
* @ctrlr: The device tree node for the device whose interrupt is translated
|
||||||
|
* @intspec: The interrupt specifier data from the device tree
|
||||||
|
* @intsize: The number of entries in @intspec
|
||||||
|
* @out_hwirq: Pointer to storage for the hardware interrupt number
|
||||||
|
* @out_type: Pointer to storage for the interrupt type
|
||||||
|
*
|
||||||
|
* Device Tree interrupt specifier translation function for two or three
|
||||||
|
* cell bindings, where the cell values map directly to the hardware
|
||||||
|
* interrupt number and the type specifier.
|
||||||
|
*/
|
||||||
|
int irq_domain_xlate_twothreecell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
irq_hw_number_t *out_hwirq, unsigned int *out_type)
|
||||||
|
{
|
||||||
|
struct irq_fwspec fwspec;
|
||||||
|
|
||||||
|
of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
|
||||||
|
|
||||||
|
return irq_domain_translate_twothreecell(d, &fwspec, out_hwirq, out_type);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_twothreecell);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
|
* irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
|
||||||
* @d: Interrupt domain involved in the translation
|
* @d: Interrupt domain involved in the translation
|
||||||
|
|
@ -1216,6 +1241,37 @@ int irq_domain_translate_twocell(struct irq_domain *d,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
|
EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_domain_translate_twothreecell() - Generic translate for direct two or three cell
|
||||||
|
* bindings
|
||||||
|
* @d: Interrupt domain involved in the translation
|
||||||
|
* @fwspec: The firmware interrupt specifier to translate
|
||||||
|
* @out_hwirq: Pointer to storage for the hardware interrupt number
|
||||||
|
* @out_type: Pointer to storage for the interrupt type
|
||||||
|
*
|
||||||
|
* Firmware interrupt specifier translation function for two or three cell
|
||||||
|
* specifications, where the parameter values map directly to the hardware
|
||||||
|
* interrupt number and the type specifier.
|
||||||
|
*/
|
||||||
|
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec,
|
||||||
|
unsigned long *out_hwirq, unsigned int *out_type)
|
||||||
|
{
|
||||||
|
if (fwspec->param_count == 2) {
|
||||||
|
*out_hwirq = fwspec->param[0];
|
||||||
|
*out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwspec->param_count == 3) {
|
||||||
|
*out_hwirq = fwspec->param[1];
|
||||||
|
*out_type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_translate_twothreecell);
|
||||||
|
|
||||||
int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
|
int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
|
||||||
int node, const struct irq_affinity_desc *affinity)
|
int node, const struct irq_affinity_desc *affinity)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue