Skip to content

Commit 7d34849

Browse files
legoatermpe
authored andcommitted
powerpc/xive: Introduce an IPI interrupt domain
The IPI interrupt is a special case of the XIVE IRQ domain. When mapping and unmapping the interrupts in the Linux interrupt number space, the HW interrupt number 0 (XIVE_IPI_HW_IRQ) is checked to distinguish the IPI interrupt from other interrupts of the system. Simplify the XIVE interrupt domain by introducing a specific domain for the IPI. Signed-off-by: Cédric Le Goater <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 078277a commit 7d34849

File tree

1 file changed

+46
-33
lines changed

1 file changed

+46
-33
lines changed

arch/powerpc/sysdev/xive/common.c

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,24 +1067,58 @@ static struct irq_chip xive_ipi_chip = {
10671067
.irq_unmask = xive_ipi_do_nothing,
10681068
};
10691069

1070-
static void __init xive_request_ipi(void)
1070+
/*
1071+
* IPIs are marked per-cpu. We use separate HW interrupts under the
1072+
* hood but associated with the same "linux" interrupt
1073+
*/
1074+
static int xive_ipi_irq_domain_map(struct irq_domain *h, unsigned int virq,
1075+
irq_hw_number_t hw)
10711076
{
1077+
irq_set_chip_and_handler(virq, &xive_ipi_chip, handle_percpu_irq);
1078+
return 0;
1079+
}
1080+
1081+
static const struct irq_domain_ops xive_ipi_irq_domain_ops = {
1082+
.map = xive_ipi_irq_domain_map,
1083+
};
1084+
1085+
static int __init xive_request_ipi(void)
1086+
{
1087+
struct fwnode_handle *fwnode;
1088+
struct irq_domain *ipi_domain;
10721089
unsigned int virq;
1090+
int ret = -ENOMEM;
10731091

1074-
/*
1075-
* Initialization failed, move on, we might manage to
1076-
* reach the point where we display our errors before
1077-
* the system falls appart
1078-
*/
1079-
if (!xive_irq_domain)
1080-
return;
1092+
fwnode = irq_domain_alloc_named_fwnode("XIVE-IPI");
1093+
if (!fwnode)
1094+
goto out;
1095+
1096+
ipi_domain = irq_domain_create_linear(fwnode, 1,
1097+
&xive_ipi_irq_domain_ops, NULL);
1098+
if (!ipi_domain)
1099+
goto out_free_fwnode;
10811100

10821101
/* Initialize it */
1083-
virq = irq_create_mapping(xive_irq_domain, XIVE_IPI_HW_IRQ);
1102+
virq = irq_create_mapping(ipi_domain, XIVE_IPI_HW_IRQ);
1103+
if (!virq) {
1104+
ret = -EINVAL;
1105+
goto out_free_domain;
1106+
}
1107+
10841108
xive_ipi_irq = virq;
10851109

1086-
WARN_ON(request_irq(virq, xive_muxed_ipi_action,
1087-
IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL));
1110+
ret = request_irq(virq, xive_muxed_ipi_action,
1111+
IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL);
1112+
1113+
WARN(ret < 0, "Failed to request IPI %d: %d\n", virq, ret);
1114+
return ret;
1115+
1116+
out_free_domain:
1117+
irq_domain_remove(ipi_domain);
1118+
out_free_fwnode:
1119+
irq_domain_free_fwnode(fwnode);
1120+
out:
1121+
return ret;
10881122
}
10891123

10901124
static int xive_setup_cpu_ipi(unsigned int cpu)
@@ -1178,19 +1212,6 @@ static int xive_irq_domain_map(struct irq_domain *h, unsigned int virq,
11781212
*/
11791213
irq_clear_status_flags(virq, IRQ_LEVEL);
11801214

1181-
#ifdef CONFIG_SMP
1182-
/* IPIs are special and come up with HW number 0 */
1183-
if (hw == XIVE_IPI_HW_IRQ) {
1184-
/*
1185-
* IPIs are marked per-cpu. We use separate HW interrupts under
1186-
* the hood but associated with the same "linux" interrupt
1187-
*/
1188-
irq_set_chip_and_handler(virq, &xive_ipi_chip,
1189-
handle_percpu_irq);
1190-
return 0;
1191-
}
1192-
#endif
1193-
11941215
rc = xive_irq_alloc_data(virq, hw);
11951216
if (rc)
11961217
return rc;
@@ -1202,15 +1223,7 @@ static int xive_irq_domain_map(struct irq_domain *h, unsigned int virq,
12021223

12031224
static void xive_irq_domain_unmap(struct irq_domain *d, unsigned int virq)
12041225
{
1205-
struct irq_data *data = irq_get_irq_data(virq);
1206-
unsigned int hw_irq;
1207-
1208-
/* XXX Assign BAD number */
1209-
if (!data)
1210-
return;
1211-
hw_irq = (unsigned int)irqd_to_hwirq(data);
1212-
if (hw_irq != XIVE_IPI_HW_IRQ)
1213-
xive_irq_free_data(virq);
1226+
xive_irq_free_data(virq);
12141227
}
12151228

12161229
static int xive_irq_domain_xlate(struct irq_domain *h, struct device_node *ct,

0 commit comments

Comments
 (0)