1 #include <linux/types.h>
2 #include <linux/kernel.h>
5 #include <linux/interrupt.h>
6 #include <linux/init.h>
9 #include <linux/spinlock.h>
10 #include <linux/msi.h>
14 #include <asm/machdep.h>
16 #include <asm/errno.h>
20 /* RTAS service tokens */
21 static int ibm_get_xive
;
22 static int ibm_set_xive
;
23 static int ibm_int_on
;
24 static int ibm_int_off
;
26 static int ics_rtas_map(struct ics
*ics
, unsigned int virq
);
27 static void ics_rtas_mask_unknown(struct ics
*ics
, unsigned long vec
);
28 static long ics_rtas_get_server(struct ics
*ics
, unsigned long vec
);
29 static int ics_rtas_host_match(struct ics
*ics
, struct device_node
*node
);
31 /* Only one global & state struct ics */
32 static struct ics ics_rtas
= {
34 .mask_unknown
= ics_rtas_mask_unknown
,
35 .get_server
= ics_rtas_get_server
,
36 .host_match
= ics_rtas_host_match
,
39 static void ics_rtas_unmask_irq(struct irq_data
*d
)
41 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
45 pr_devel("xics: unmask virq %d [hw 0x%x]\n", d
->irq
, hw_irq
);
47 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
50 server
= xics_get_irq_server(d
->irq
, d
->affinity
, 0);
52 call_status
= rtas_call(ibm_set_xive
, 3, 1, NULL
, hw_irq
, server
,
54 if (call_status
!= 0) {
56 "%s: ibm_set_xive irq %u server %x returned %d\n",
57 __func__
, hw_irq
, server
, call_status
);
61 /* Now unmask the interrupt (often a no-op) */
62 call_status
= rtas_call(ibm_int_on
, 1, 1, NULL
, hw_irq
);
63 if (call_status
!= 0) {
64 printk(KERN_ERR
"%s: ibm_int_on irq=%u returned %d\n",
65 __func__
, hw_irq
, call_status
);
70 static unsigned int ics_rtas_startup(struct irq_data
*d
)
74 * The generic MSI code returns with the interrupt disabled on the
75 * card, using the MSI mask bits. Firmware doesn't appear to unmask
76 * at that level, so we do it here by hand.
82 ics_rtas_unmask_irq(d
);
86 static void ics_rtas_mask_real_irq(unsigned int hw_irq
)
90 if (hw_irq
== XICS_IPI
)
93 call_status
= rtas_call(ibm_int_off
, 1, 1, NULL
, hw_irq
);
94 if (call_status
!= 0) {
95 printk(KERN_ERR
"%s: ibm_int_off irq=%u returned %d\n",
96 __func__
, hw_irq
, call_status
);
100 /* Have to set XIVE to 0xff to be able to remove a slot */
101 call_status
= rtas_call(ibm_set_xive
, 3, 1, NULL
, hw_irq
,
102 xics_default_server
, 0xff);
103 if (call_status
!= 0) {
104 printk(KERN_ERR
"%s: ibm_set_xive(0xff) irq=%u returned %d\n",
105 __func__
, hw_irq
, call_status
);
110 static void ics_rtas_mask_irq(struct irq_data
*d
)
112 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
114 pr_devel("xics: mask virq %d [hw 0x%x]\n", d
->irq
, hw_irq
);
116 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
118 ics_rtas_mask_real_irq(hw_irq
);
121 static int ics_rtas_set_affinity(struct irq_data
*d
,
122 const struct cpumask
*cpumask
,
125 unsigned int hw_irq
= (unsigned int)irqd_to_hwirq(d
);
130 if (hw_irq
== XICS_IPI
|| hw_irq
== XICS_IRQ_SPURIOUS
)
133 status
= rtas_call(ibm_get_xive
, 1, 3, xics_status
, hw_irq
);
136 printk(KERN_ERR
"%s: ibm,get-xive irq=%u returns %d\n",
137 __func__
, hw_irq
, status
);
141 irq_server
= xics_get_irq_server(d
->irq
, cpumask
, 1);
142 if (irq_server
== -1) {
144 cpumask_scnprintf(cpulist
, sizeof(cpulist
), cpumask
);
146 "%s: No online cpus in the mask %s for irq %d\n",
147 __func__
, cpulist
, d
->irq
);
151 status
= rtas_call(ibm_set_xive
, 3, 1, NULL
,
152 hw_irq
, irq_server
, xics_status
[1]);
155 printk(KERN_ERR
"%s: ibm,set-xive irq=%u returns %d\n",
156 __func__
, hw_irq
, status
);
160 return IRQ_SET_MASK_OK
;
163 static struct irq_chip ics_rtas_irq_chip
= {
165 .irq_startup
= ics_rtas_startup
,
166 .irq_mask
= ics_rtas_mask_irq
,
167 .irq_unmask
= ics_rtas_unmask_irq
,
168 .irq_eoi
= NULL
, /* Patched at init time */
169 .irq_set_affinity
= ics_rtas_set_affinity
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(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(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 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
);