10 #include <linux/types.h>
12 #include <linux/kernel.h>
21 #include <linux/slab.h>
27 #include <asm/machdep.h>
29 #include <asm/errno.h>
59 hcpuid = get_hard_smp_processor_id(
boot_cpuid);
70 i = ilen /
sizeof(
int);
77 for (j = 0; j <
i; j += 2) {
78 if (ireg[j] == hcpuid) {
83 pr_devel(
"xics: xics_default_distrib_server = 0x%x\n",
93 #ifdef CONFIG_PPC_RTAS
104 WARN(status < 0,
"set-indicator(%d, %d, %u) returned %d\n",
105 GLOBAL_INTERRUPT_QUEUE, index, join, status);
120 pr_err(
"Interrupt 0x%x (real) is invalid, disabling it.\n", vec);
129 static void xics_request_ipi(
void)
146 smp_ops->cause_ipi = icp_ops->cause_ipi;
151 return cpumask_weight(cpu_possible_mask);
184 #ifdef CONFIG_HOTPLUG_CPU
190 unsigned int irq, virq;
218 if (desc->
irq_data.domain != xics_host)
224 chip = irq_desc_get_chip(desc);
232 ics = irq_get_chip_data(virq);
245 if (server != hw_cpu)
250 pr_warning(
"IRQ %u affinity broken off cpu %u\n",
275 unsigned int strict_check)
278 if (!distribute_irqs)
281 if (!cpumask_subset(cpu_possible_mask, cpumask)) {
284 if (server < nr_cpu_ids)
285 return get_hard_smp_processor_id(server);
296 if (cpumask_equal(cpu_online_mask, cpu_present_mask))
316 static void xics_ipi_mask(
struct irq_data *
d) { }
318 static struct irq_chip xics_ipi_chip = {
321 .irq_mask = xics_ipi_mask,
322 .irq_unmask = xics_ipi_unmask,
325 static int xics_host_map(
struct irq_domain *h,
unsigned int virq,
330 pr_devel(
"xics: map virq %d, hwirq 0x%lx\n", virq, hw);
337 irq_set_chip_and_handler(virq, &xics_ipi_chip,
344 if (ics->
map(ics, virq) == 0)
351 const u32 *intspec,
unsigned int intsize,
359 *out_hwirq = intspec[0];
366 .match = xics_host_match,
367 .map = xics_host_map,
368 .xlate = xics_host_xlate,
371 static void __init xics_init_host(
void)
380 list_add(&ics->
link, &ics_list);
383 static void __init xics_get_server_size(
void)
406 if (firmware_has_feature(FW_FEATURE_LPAR))
411 pr_warning(
"XICS: Cannot find a Presentation Controller !\n");
426 pr_warning(
"XICS: Cannot find a Source Controller !\n");
429 xics_get_server_size();