aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2011-05-10 15:30:22 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-19 01:31:51 -0400
commit23f73a5fb0dee5ab681bfeb8897bcfc57153ba9a (patch)
tree00d35813e753d704a26169b2d70390325548b444
parent67347eba156d64150be73c9f5797342a66b123d9 (diff)
powerpc/psurge: Create a irq_host for secondary cpus
Create a dummy irq_host using the generic dummy irq chip for the secondary cpus to use. Create a direct irq mapping for the ipi and register the ipi action handler against it. If for some unlikely reason part of this fails then don't detect the secondary cpus. This removes another instance of NO_IRQ_IGNORE, records the ipi stats for the secondary cpus, and runs the ipi on the interrupt stack. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/powermac/pic.c9
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h1
-rw-r--r--arch/powerpc/platforms/powermac/smp.c49
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);
33extern void pmac_check_ht_link(void); 33extern void pmac_check_ht_link(void);
34 34
35extern void pmac_setup_smp(void); 35extern void pmac_setup_smp(void);
36extern int psurge_secondary_virq;
36extern void low_cpu_die(void) __attribute__((noreturn)); 37extern void low_cpu_die(void) __attribute__((noreturn));
37 38
38extern int pmac_nvram_init(void); 39extern 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 */
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