Skip to content

Commit 0a02e1f

Browse files
dlan17KAGA-KOKO
authored andcommitted
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.org
1 parent 0af2f6b commit 0a02e1f

2 files changed

Lines changed: 66 additions & 10 deletions

File tree

include/linux/irqdomain.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -571,16 +571,16 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
571571
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
572572
const u32 *intspec, unsigned int intsize,
573573
irq_hw_number_t *out_hwirq, unsigned int *out_type);
574-
575-
int irq_domain_translate_twocell(struct irq_domain *d,
576-
struct irq_fwspec *fwspec,
577-
unsigned long *out_hwirq,
578-
unsigned int *out_type);
579-
580-
int irq_domain_translate_onecell(struct irq_domain *d,
581-
struct irq_fwspec *fwspec,
582-
unsigned long *out_hwirq,
583-
unsigned int *out_type);
574+
int irq_domain_xlate_twothreecell(struct irq_domain *d, struct device_node *ctrlr,
575+
const u32 *intspec, unsigned int intsize,
576+
irq_hw_number_t *out_hwirq, unsigned int *out_type);
577+
578+
int irq_domain_translate_onecell(struct irq_domain *d, struct irq_fwspec *fwspec,
579+
unsigned long *out_hwirq, unsigned int *out_type);
580+
int irq_domain_translate_twocell(struct irq_domain *d, struct irq_fwspec *fwspec,
581+
unsigned long *out_hwirq, unsigned int *out_type);
582+
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec,
583+
unsigned long *out_hwirq, unsigned int *out_type);
584584

585585
/* IPI functions */
586586
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);

kernel/irq/irqdomain.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,31 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
11321132
}
11331133
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
11341134

1135+
/**
1136+
* irq_domain_xlate_twothreecell() - Generic xlate for direct two or three cell bindings
1137+
* @d: Interrupt domain involved in the translation
1138+
* @ctrlr: The device tree node for the device whose interrupt is translated
1139+
* @intspec: The interrupt specifier data from the device tree
1140+
* @intsize: The number of entries in @intspec
1141+
* @out_hwirq: Pointer to storage for the hardware interrupt number
1142+
* @out_type: Pointer to storage for the interrupt type
1143+
*
1144+
* Device Tree interrupt specifier translation function for two or three
1145+
* cell bindings, where the cell values map directly to the hardware
1146+
* interrupt number and the type specifier.
1147+
*/
1148+
int irq_domain_xlate_twothreecell(struct irq_domain *d, struct device_node *ctrlr,
1149+
const u32 *intspec, unsigned int intsize,
1150+
irq_hw_number_t *out_hwirq, unsigned int *out_type)
1151+
{
1152+
struct irq_fwspec fwspec;
1153+
1154+
of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
1155+
1156+
return irq_domain_translate_twothreecell(d, &fwspec, out_hwirq, out_type);
1157+
}
1158+
EXPORT_SYMBOL_GPL(irq_domain_xlate_twothreecell);
1159+
11351160
/**
11361161
* irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
11371162
* @d: Interrupt domain involved in the translation
@@ -1216,6 +1241,37 @@ int irq_domain_translate_twocell(struct irq_domain *d,
12161241
}
12171242
EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
12181243

1244+
/**
1245+
* irq_domain_translate_twothreecell() - Generic translate for direct two or three cell
1246+
* bindings
1247+
* @d: Interrupt domain involved in the translation
1248+
* @fwspec: The firmware interrupt specifier to translate
1249+
* @out_hwirq: Pointer to storage for the hardware interrupt number
1250+
* @out_type: Pointer to storage for the interrupt type
1251+
*
1252+
* Firmware interrupt specifier translation function for two or three cell
1253+
* specifications, where the parameter values map directly to the hardware
1254+
* interrupt number and the type specifier.
1255+
*/
1256+
int irq_domain_translate_twothreecell(struct irq_domain *d, struct irq_fwspec *fwspec,
1257+
unsigned long *out_hwirq, unsigned int *out_type)
1258+
{
1259+
if (fwspec->param_count == 2) {
1260+
*out_hwirq = fwspec->param[0];
1261+
*out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
1262+
return 0;
1263+
}
1264+
1265+
if (fwspec->param_count == 3) {
1266+
*out_hwirq = fwspec->param[1];
1267+
*out_type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
1268+
return 0;
1269+
}
1270+
1271+
return -EINVAL;
1272+
}
1273+
EXPORT_SYMBOL_GPL(irq_domain_translate_twothreecell);
1274+
12191275
int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
12201276
int node, const struct irq_affinity_desc *affinity)
12211277
{

0 commit comments

Comments
 (0)