1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Multiplex several virtual IPIs over a single HW IPI.
5 * Copyright The Asahi Linux Contributors
6 * Copyright (c) 2022 Ventana Micro Systems Inc.
9 #define pr_fmt(fmt) "ipi-mux: " fmt
10 #include <linux/cpu.h>
11 #include <linux/init.h>
12 #include <linux/irq.h>
13 #include <linux/irqchip.h>
14 #include <linux/irqchip/chained_irq.h>
15 #include <linux/irqdomain.h>
16 #include <linux/jump_label.h>
17 #include <linux/percpu.h>
18 #include <linux/smp.h>
25 static struct ipi_mux_cpu __percpu
*ipi_mux_pcpu
;
26 static struct irq_domain
*ipi_mux_domain
;
27 static void (*ipi_mux_send
)(unsigned int cpu
);
29 static void ipi_mux_mask(struct irq_data
*d
)
31 struct ipi_mux_cpu
*icpu
= this_cpu_ptr(ipi_mux_pcpu
);
33 atomic_andnot(BIT(irqd_to_hwirq(d
)), &icpu
->enable
);
36 static void ipi_mux_unmask(struct irq_data
*d
)
38 struct ipi_mux_cpu
*icpu
= this_cpu_ptr(ipi_mux_pcpu
);
39 u32 ibit
= BIT(irqd_to_hwirq(d
));
41 atomic_or(ibit
, &icpu
->enable
);
44 * The atomic_or() above must complete before the atomic_read()
45 * below to avoid racing ipi_mux_send_mask().
47 smp_mb__after_atomic();
49 /* If a pending IPI was unmasked, raise a parent IPI immediately. */
50 if (atomic_read(&icpu
->bits
) & ibit
)
51 ipi_mux_send(smp_processor_id());
54 static void ipi_mux_send_mask(struct irq_data
*d
, const struct cpumask
*mask
)
56 struct ipi_mux_cpu
*icpu
= this_cpu_ptr(ipi_mux_pcpu
);
57 u32 ibit
= BIT(irqd_to_hwirq(d
));
58 unsigned long pending
;
61 for_each_cpu(cpu
, mask
) {
62 icpu
= per_cpu_ptr(ipi_mux_pcpu
, cpu
);
65 * This sequence is the mirror of the one in ipi_mux_unmask();
66 * see the comment there. Additionally, release semantics
67 * ensure that the vIPI flag set is ordered after any shared
68 * memory accesses that precede it. This therefore also pairs
69 * with the atomic_fetch_andnot in ipi_mux_process().
71 pending
= atomic_fetch_or_release(ibit
, &icpu
->bits
);
74 * The atomic_fetch_or_release() above must complete
75 * before the atomic_read() below to avoid racing with
78 smp_mb__after_atomic();
81 * The flag writes must complete before the physical IPI is
82 * issued to another CPU. This is implied by the control
83 * dependency on the result of atomic_read() below, which is
84 * itself already ordered after the vIPI flag write.
86 if (!(pending
& ibit
) && (atomic_read(&icpu
->enable
) & ibit
))
91 static const struct irq_chip ipi_mux_chip
= {
93 .irq_mask
= ipi_mux_mask
,
94 .irq_unmask
= ipi_mux_unmask
,
95 .ipi_send_mask
= ipi_mux_send_mask
,
98 static int ipi_mux_domain_alloc(struct irq_domain
*d
, unsigned int virq
,
99 unsigned int nr_irqs
, void *arg
)
103 for (i
= 0; i
< nr_irqs
; i
++) {
104 irq_set_percpu_devid(virq
+ i
);
105 irq_domain_set_info(d
, virq
+ i
, i
, &ipi_mux_chip
, NULL
,
106 handle_percpu_devid_irq
, NULL
, NULL
);
112 static const struct irq_domain_ops ipi_mux_domain_ops
= {
113 .alloc
= ipi_mux_domain_alloc
,
114 .free
= irq_domain_free_irqs_top
,
118 * ipi_mux_process - Process multiplexed virtual IPIs
120 void ipi_mux_process(void)
122 struct ipi_mux_cpu
*icpu
= this_cpu_ptr(ipi_mux_pcpu
);
123 irq_hw_number_t hwirq
;
128 * Reading enable mask does not need to be ordered as long as
129 * this function is called from interrupt handler because only
130 * the CPU itself can change it's own enable mask.
132 en
= atomic_read(&icpu
->enable
);
135 * Clear the IPIs we are about to handle. This pairs with the
136 * atomic_fetch_or_release() in ipi_mux_send_mask().
138 ipis
= atomic_fetch_andnot(en
, &icpu
->bits
) & en
;
140 for_each_set_bit(hwirq
, &ipis
, BITS_PER_TYPE(int))
141 generic_handle_domain_irq(ipi_mux_domain
, hwirq
);
145 * ipi_mux_create - Create virtual IPIs multiplexed on top of a single
147 * @nr_ipi: number of virtual IPIs to create. This should
148 * be <= BITS_PER_TYPE(int)
149 * @mux_send: callback to trigger parent IPI for a particular CPU
151 * Returns first virq of the newly created virtual IPIs upon success
152 * or <=0 upon failure
154 int ipi_mux_create(unsigned int nr_ipi
, void (*mux_send
)(unsigned int cpu
))
156 struct fwnode_handle
*fwnode
;
157 struct irq_domain
*domain
;
163 if (BITS_PER_TYPE(int) < nr_ipi
|| !mux_send
)
166 ipi_mux_pcpu
= alloc_percpu(typeof(*ipi_mux_pcpu
));
170 fwnode
= irq_domain_alloc_named_fwnode("IPI-Mux");
172 pr_err("unable to create IPI Mux fwnode\n");
177 domain
= irq_domain_create_linear(fwnode
, nr_ipi
,
178 &ipi_mux_domain_ops
, NULL
);
180 pr_err("unable to add IPI Mux domain\n");
182 goto fail_free_fwnode
;
185 domain
->flags
|= IRQ_DOMAIN_FLAG_IPI_SINGLE
;
186 irq_domain_update_bus_token(domain
, DOMAIN_BUS_IPI
);
188 rc
= irq_domain_alloc_irqs(domain
, nr_ipi
, NUMA_NO_NODE
, NULL
);
190 pr_err("unable to alloc IRQs from IPI Mux domain\n");
191 goto fail_free_domain
;
194 ipi_mux_domain
= domain
;
195 ipi_mux_send
= mux_send
;
200 irq_domain_remove(domain
);
202 irq_domain_free_fwnode(fwnode
);
204 free_percpu(ipi_mux_pcpu
);