aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powermac/smp.c')
-rw-r--r--arch/powerpc/platforms/powermac/smp.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 67b6e1432be2..db092d7c4c5b 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -124,6 +124,10 @@ static volatile u32 __iomem *psurge_start;
124/* what sort of powersurge board we have */ 124/* what sort of powersurge board we have */
125static int psurge_type = PSURGE_NONE; 125static int psurge_type = PSURGE_NONE;
126 126
127/* irq for secondary cpus to report */
128static struct irq_host *psurge_host;
129int psurge_secondary_virq;
130
127/* 131/*
128 * Set and clear IPIs for powersurge. 132 * Set and clear IPIs for powersurge.
129 */ 133 */
@@ -159,15 +163,11 @@ static inline void psurge_clr_ipi(int cpu)
159 * use the generic demux helpers 163 * use the generic demux helpers
160 * -- paulus. 164 * -- paulus.
161 */ 165 */
162void psurge_smp_message_recv(void) 166static irqreturn_t psurge_ipi_intr(int irq, void *d)
163{ 167{
164 psurge_clr_ipi(smp_processor_id()); 168 psurge_clr_ipi(smp_processor_id());
165 smp_ipi_demux(); 169 smp_ipi_demux();
166}
167 170
168irqreturn_t psurge_primary_intr(int irq, void *d)
169{
170 psurge_smp_message_recv();
171 return IRQ_HANDLED; 171 return IRQ_HANDLED;
172} 172}
173 173
@@ -176,6 +176,38 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
176 psurge_set_ipi(cpu); 176 psurge_set_ipi(cpu);
177} 177}
178 178
179static int psurge_host_map(struct irq_host *h, unsigned int virq,
180 irq_hw_number_t hw)
181{
182 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
183
184 return 0;
185}
186
187struct irq_host_ops psurge_host_ops = {
188 .map = psurge_host_map,
189};
190
191static int psurge_secondary_ipi_init(void)
192{
193 int rc = -ENOMEM;
194
195 psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
196 &psurge_host_ops, 0);
197
198 if (psurge_host)
199 psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
200
201 if (psurge_secondary_virq)
202 rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
203 IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
204
205 if (rc)
206 pr_err("Failed to setup secondary cpu IPI\n");
207
208 return rc;
209}
210
179/* 211/*
180 * Determine a quad card presence. We read the board ID register, we 212 * Determine a quad card presence. We read the board ID register, we
181 * force the data bus to change to something else, and we read it again. 213 * force the data bus to change to something else, and we read it again.
@@ -284,6 +316,9 @@ static int __init smp_psurge_probe(void)
284 ncpus = 2; 316 ncpus = 2;
285 } 317 }
286 318
319 if (psurge_secondary_ipi_init())
320 return 1;
321
287 psurge_start = ioremap(PSURGE_START, 4); 322 psurge_start = ioremap(PSURGE_START, 4);
288 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); 323 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
289 324
@@ -372,8 +407,8 @@ static int __init smp_psurge_kick_cpu(int nr)
372} 407}
373 408
374static struct irqaction psurge_irqaction = { 409static struct irqaction psurge_irqaction = {
375 .handler = psurge_primary_intr, 410 .handler = psurge_ipi_intr,
376 .flags = IRQF_DISABLED, 411 .flags = IRQF_DISABLED|IRQF_PERCPU,
377 .name = "primary IPI", 412 .name = "primary IPI",
378}; 413};
379 414