diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 49 |
3 files changed, 46 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index b706cb3ad99c..360260d1352d 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -240,12 +240,9 @@ static unsigned int pmac_pic_get_irq(void) | |||
240 | unsigned long flags; | 240 | unsigned long flags; |
241 | 241 | ||
242 | #ifdef CONFIG_PPC_PMAC32_PSURGE | 242 | #ifdef CONFIG_PPC_PMAC32_PSURGE |
243 | void psurge_smp_message_recv(void); | 243 | /* IPI's are a hack on the powersurge -- Cort */ |
244 | 244 | if (smp_processor_id() != 0) { | |
245 | /* IPI's are a hack on the powersurge -- Cort */ | 245 | return psurge_secondary_virq; |
246 | if ( smp_processor_id() != 0 ) { | ||
247 | psurge_smp_message_recv(); | ||
248 | return NO_IRQ_IGNORE; /* ignore, already handled */ | ||
249 | } | 246 | } |
250 | #endif /* CONFIG_PPC_PMAC32_PSURGE */ | 247 | #endif /* CONFIG_PPC_PMAC32_PSURGE */ |
251 | raw_spin_lock_irqsave(&pmac_pic_lock, flags); | 248 | raw_spin_lock_irqsave(&pmac_pic_lock, flags); |
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 20468f49aec0..8327cce2bdb0 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h | |||
@@ -33,6 +33,7 @@ extern void pmac_setup_pci_dma(void); | |||
33 | extern void pmac_check_ht_link(void); | 33 | extern void pmac_check_ht_link(void); |
34 | 34 | ||
35 | extern void pmac_setup_smp(void); | 35 | extern void pmac_setup_smp(void); |
36 | extern int psurge_secondary_virq; | ||
36 | extern void low_cpu_die(void) __attribute__((noreturn)); | 37 | extern void low_cpu_die(void) __attribute__((noreturn)); |
37 | 38 | ||
38 | extern int pmac_nvram_init(void); | 39 | extern int pmac_nvram_init(void); |
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 */ |
125 | static int psurge_type = PSURGE_NONE; | 125 | static int psurge_type = PSURGE_NONE; |
126 | 126 | ||
127 | /* irq for secondary cpus to report */ | ||
128 | static struct irq_host *psurge_host; | ||
129 | int 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 | */ |
162 | void psurge_smp_message_recv(void) | 166 | static 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 | ||
168 | irqreturn_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 | ||
179 | static 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 | |||
187 | struct irq_host_ops psurge_host_ops = { | ||
188 | .map = psurge_host_map, | ||
189 | }; | ||
190 | |||
191 | static 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 | ||
374 | static struct irqaction psurge_irqaction = { | 409 | static 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 | ||