11 #include <linux/types.h>
12 #include <linux/kernel.h>
20 #include <linux/module.h>
26 #include <asm/errno.h>
51 static inline unsigned int icp_native_get_xirr(
void)
58 static inline void icp_native_set_xirr(
unsigned int value)
65 static inline void icp_native_set_cppr(
u8 value)
69 out_8(&icp_native_regs[cpu]->
xirr.bytes[0], value);
72 static inline void icp_native_set_qirr(
int n_cpu,
u8 value)
74 out_8(&icp_native_regs[n_cpu]->
qirr.bytes[0], value);
77 static void icp_native_set_cpu_priority(
unsigned char cppr)
79 xics_set_base_cppr(cppr);
80 icp_native_set_cppr(cppr);
84 static void icp_native_eoi(
struct irq_data *
d)
86 unsigned int hw_irq = (
unsigned int)irqd_to_hwirq(d);
89 icp_native_set_xirr((xics_pop_cppr() << 24) | hw_irq);
92 static void icp_native_teardown_cpu(
void)
97 icp_native_set_qirr(cpu, 0xff);
100 static void icp_native_flush_ipi(
void)
110 icp_native_set_xirr((0x00 << 24) |
XICS_IPI);
113 static unsigned int icp_native_get_irq(
void)
115 unsigned int xirr = icp_native_get_xirr();
116 unsigned int vec = xirr & 0x00ffffff;
132 icp_native_set_xirr(xirr);
139 static void icp_native_cause_ipi(
int cpu,
unsigned long data)
154 icp_native_set_qirr(cpu, 0xff);
156 return smp_ipi_demux();
161 static int __init icp_native_map_one_cpu(
int hw_id,
unsigned long addr,
173 if (hw_id == get_hard_smp_processor_id(i)) {
189 pr_warning(
"icp_native: Could not reserve ICP MMIO"
190 " for CPU %d, interrupt server #0x%x\n",
196 kvmppc_set_xics_phys(cpu, addr);
197 if (!icp_native_regs[cpu]) {
198 pr_warning(
"icp_native: Failed ioremap for CPU %d, "
199 "interrupt server #0x%x, addr %#lx\n",
229 *indx = of_read_number(ireg, 1);
230 if (ilen >= 2*
sizeof(
u32))
231 num_servers = of_read_number(ireg + 1, 1);
236 pr_err(
"icp_native: Can't find interrupt reg property");
241 if (((ilen % reg_tuple_size) != 0)
242 || (num_servers && (num_servers != (ilen / reg_tuple_size)))) {
243 pr_err(
"icp_native: ICP reg len (%d) != num servers (%d)",
244 ilen / reg_tuple_size, num_servers);
248 for (i = 0; i < (ilen / reg_tuple_size); i++) {
254 pr_err(
"icp_native: Could not translate ICP MMIO"
255 " for interrupt server 0x%x (%d)\n", *indx, err);
259 if (icp_native_map_one_cpu(*indx,
r.start, resource_size(&
r)))
267 static const struct icp_ops icp_native_ops = {
268 .get_irq = icp_native_get_irq,
269 .eoi = icp_native_eoi,
270 .set_priority = icp_native_set_cpu_priority,
271 .teardown_cpu = icp_native_teardown_cpu,
272 .flush_ipi = icp_native_flush_ipi,
274 .ipi_action = icp_native_ipi_action,
275 .cause_ipi = icp_native_cause_ipi,
285 for_each_compatible_node(np,
NULL,
"ibm,ppc-xicp")
286 if (icp_native_init_one_node(np, &indx) == 0)
289 for_each_node_by_type(np,
290 "PowerPC-External-Interrupt-Presentation") {
291 if (icp_native_init_one_node(np, &indx) == 0)