1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/types.h>
3 #include <linux/kernel.h>
6 #include <linux/interrupt.h>
7 #include <linux/init.h>
10 #include <linux/spinlock.h>
11 #include <linux/msi.h>
15 #include <asm/machdep.h>
17 #include <asm/errno.h>
21 /* RTAS service tokens */
22 static int ibm_get_xive
;
23 static int ibm_set_xive
;
24 static int ibm_int_on
;
25 static int ibm_int_off
;
27 static int ics_rtas_map(struct ics
*ics
, unsigned int virq
);
28 static void ics_rtas_mask_unknown(struct ics
*ics
, unsigned long vec
);
29 static long ics_rtas_get_server(struct ics
*ics
, unsigned long vec
);
30 static int ics_rtas_host_match(struct ics
*ics
, struct device_node
*node
);
32 /* Only one global & state struct ics */
33 static struct ics ics_rtas
= {
35 .mask_unknown
= ics_rtas_mask_unknown
,
36 .get_server
= ics_rtas_get_server
,
37 .host_match
= ics_rtas_host_match
,
40 static void ics_rtas_unmask_irq(struct irq_data
*d
)
42 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
46 pr_devel("xics: unmask virq %d [hw 0x%x]\n", d
->irq
, hw_irq
);
48 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
51 server
= xics_get_irq_server(d
->irq
, irq_data_get_affinity_mask(d
), 0);
53 call_status
= rtas_call_reentrant(ibm_set_xive
, 3, 1, NULL
, hw_irq
,
54 server
, DEFAULT_PRIORITY
);
55 if (call_status
!= 0) {
57 "%s: ibm_set_xive irq %u server %x returned %d\n",
58 __func__
, hw_irq
, server
, call_status
);
62 /* Now unmask the interrupt (often a no-op) */
63 call_status
= rtas_call_reentrant(ibm_int_on
, 1, 1, NULL
, hw_irq
);
64 if (call_status
!= 0) {
65 printk(KERN_ERR
"%s: ibm_int_on irq=%u returned %d\n",
66 __func__
, hw_irq
, call_status
);
71 static unsigned int ics_rtas_startup(struct irq_data
*d
)
75 * The generic MSI code returns with the interrupt disabled on the
76 * card, using the MSI mask bits. Firmware doesn't appear to unmask
77 * at that level, so we do it here by hand.
79 if (irq_data_get_msi_desc(d
))
80 pci_msi_unmask_irq(d
);
83 ics_rtas_unmask_irq(d
);
87 static void ics_rtas_mask_real_irq(unsigned int hw_irq
)
91 if (hw_irq
== XICS_IPI
)
94 call_status
= rtas_call_reentrant(ibm_int_off
, 1, 1, NULL
, hw_irq
);
95 if (call_status
!= 0) {
96 printk(KERN_ERR
"%s: ibm_int_off irq=%u returned %d\n",
97 __func__
, hw_irq
, call_status
);
101 /* Have to set XIVE to 0xff to be able to remove a slot */
102 call_status
= rtas_call_reentrant(ibm_set_xive
, 3, 1, NULL
, hw_irq
,
103 xics_default_server
, 0xff);
104 if (call_status
!= 0) {
105 printk(KERN_ERR
"%s: ibm_set_xive(0xff) irq=%u returned %d\n",
106 __func__
, hw_irq
, call_status
);
111 static void ics_rtas_mask_irq(struct irq_data
*d
)
113 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
115 pr_devel("xics: mask virq %d [hw 0x%x]\n", d
->irq
, hw_irq
);
117 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
119 ics_rtas_mask_real_irq(hw_irq
);
122 static int ics_rtas_set_affinity(struct irq_data
*d
,
123 const struct cpumask
*cpumask
,
126 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
131 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
134 status
= rtas_call_reentrant(ibm_get_xive
, 1, 3, xics_status
, hw_irq
);
137 printk(KERN_ERR
"%s: ibm,get-xive irq=%u returns %d\n",
138 __func__
, hw_irq
, status
);
142 irq_server
= xics_get_irq_server(d
->irq
, cpumask
, 1);
143 if (irq_server
== -1) {
144 pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
145 __func__
, cpumask_pr_args(cpumask
), d
->irq
);
149 status
= rtas_call_reentrant(ibm_set_xive
, 3, 1, NULL
,
150 hw_irq
, irq_server
, xics_status
[1]);
153 printk(KERN_ERR
"%s: ibm,set-xive irq=%u returns %d\n",
154 __func__
, hw_irq
, status
);
158 return IRQ_SET_MASK_OK
;
161 static struct irq_chip ics_rtas_irq_chip
= {
163 .irq_startup
= ics_rtas_startup
,
164 .irq_mask
= ics_rtas_mask_irq
,
165 .irq_unmask
= ics_rtas_unmask_irq
,
166 .irq_eoi
= NULL
, /* Patched at init time */
167 .irq_set_affinity
= ics_rtas_set_affinity
,
168 .irq_set_type
= xics_set_irq_type
,
169 .irq_retrigger
= xics_retrigger
,
172 static int ics_rtas_map(struct ics
*ics
, unsigned int virq
)
174 unsigned int hw_irq
= (unsigned int)virq_to_hw(virq
);
178 if (WARN_ON(hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
))
181 /* Check if RTAS knows about this interrupt */
182 rc
= rtas_call_reentrant(ibm_get_xive
, 1, 3, status
, hw_irq
);
186 irq_set_chip_and_handler(virq
, &ics_rtas_irq_chip
, handle_fasteoi_irq
);
187 irq_set_chip_data(virq
, &ics_rtas
);
192 static void ics_rtas_mask_unknown(struct ics
*ics
, unsigned long vec
)
194 ics_rtas_mask_real_irq(vec
);
197 static long ics_rtas_get_server(struct ics
*ics
, unsigned long vec
)
201 rc
= rtas_call_reentrant(ibm_get_xive
, 1, 3, status
, vec
);
207 static int ics_rtas_host_match(struct ics
*ics
, struct device_node
*node
)
209 /* IBM machines have interrupt parents of various funky types for things
210 * like vdevices, events, etc... The trick we use here is to match
211 * everything here except the legacy 8259 which is compatible "chrp,iic"
213 return !of_device_is_compatible(node
, "chrp,iic");
216 __init
int ics_rtas_init(void)
218 ibm_get_xive
= rtas_token("ibm,get-xive");
219 ibm_set_xive
= rtas_token("ibm,set-xive");
220 ibm_int_on
= rtas_token("ibm,int-on");
221 ibm_int_off
= rtas_token("ibm,int-off");
223 /* We enable the RTAS "ICS" if RTAS is present with the
226 if (ibm_get_xive
== RTAS_UNKNOWN_SERVICE
||
227 ibm_set_xive
== RTAS_UNKNOWN_SERVICE
)
230 /* We need to patch our irq chip's EOI to point to the
233 ics_rtas_irq_chip
.irq_eoi
= icp_ops
->eoi
;
235 /* Register ourselves */
236 xics_register_ics(&ics_rtas
);