提交 23f73a5f 编写于 作者: M Milton Miller 提交者: Benjamin Herrenschmidt

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: NMilton Miller <miltonm@bga.com>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 67347eba
...@@ -240,12 +240,9 @@ static unsigned int pmac_pic_get_irq(void) ...@@ -240,12 +240,9 @@ static unsigned int pmac_pic_get_irq(void)
unsigned long flags; unsigned long flags;
#ifdef CONFIG_PPC_PMAC32_PSURGE #ifdef CONFIG_PPC_PMAC32_PSURGE
void psurge_smp_message_recv(void); /* IPI's are a hack on the powersurge -- Cort */
if (smp_processor_id() != 0) {
/* IPI's are a hack on the powersurge -- Cort */ return psurge_secondary_virq;
if ( smp_processor_id() != 0 ) {
psurge_smp_message_recv();
return NO_IRQ_IGNORE; /* ignore, already handled */
} }
#endif /* CONFIG_PPC_PMAC32_PSURGE */ #endif /* CONFIG_PPC_PMAC32_PSURGE */
raw_spin_lock_irqsave(&pmac_pic_lock, flags); raw_spin_lock_irqsave(&pmac_pic_lock, flags);
......
...@@ -33,6 +33,7 @@ extern void pmac_setup_pci_dma(void); ...@@ -33,6 +33,7 @@ extern void pmac_setup_pci_dma(void);
extern void pmac_check_ht_link(void); extern void pmac_check_ht_link(void);
extern void pmac_setup_smp(void); extern void pmac_setup_smp(void);
extern int psurge_secondary_virq;
extern void low_cpu_die(void) __attribute__((noreturn)); extern void low_cpu_die(void) __attribute__((noreturn));
extern int pmac_nvram_init(void); extern int pmac_nvram_init(void);
......
...@@ -124,6 +124,10 @@ static volatile u32 __iomem *psurge_start; ...@@ -124,6 +124,10 @@ static volatile u32 __iomem *psurge_start;
/* what sort of powersurge board we have */ /* what sort of powersurge board we have */
static int psurge_type = PSURGE_NONE; static int psurge_type = PSURGE_NONE;
/* irq for secondary cpus to report */
static struct irq_host *psurge_host;
int psurge_secondary_virq;
/* /*
* Set and clear IPIs for powersurge. * Set and clear IPIs for powersurge.
*/ */
...@@ -159,15 +163,11 @@ static inline void psurge_clr_ipi(int cpu) ...@@ -159,15 +163,11 @@ static inline void psurge_clr_ipi(int cpu)
* use the generic demux helpers * use the generic demux helpers
* -- paulus. * -- paulus.
*/ */
void psurge_smp_message_recv(void) static irqreturn_t psurge_ipi_intr(int irq, void *d)
{ {
psurge_clr_ipi(smp_processor_id()); psurge_clr_ipi(smp_processor_id());
smp_ipi_demux(); smp_ipi_demux();
}
irqreturn_t psurge_primary_intr(int irq, void *d)
{
psurge_smp_message_recv();
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -176,6 +176,38 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data) ...@@ -176,6 +176,38 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
psurge_set_ipi(cpu); psurge_set_ipi(cpu);
} }
static int psurge_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
return 0;
}
struct irq_host_ops psurge_host_ops = {
.map = psurge_host_map,
};
static int psurge_secondary_ipi_init(void)
{
int rc = -ENOMEM;
psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
&psurge_host_ops, 0);
if (psurge_host)
psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
if (psurge_secondary_virq)
rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
if (rc)
pr_err("Failed to setup secondary cpu IPI\n");
return rc;
}
/* /*
* Determine a quad card presence. We read the board ID register, we * Determine a quad card presence. We read the board ID register, we
* force the data bus to change to something else, and we read it again. * 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,6 +316,9 @@ static int __init smp_psurge_probe(void)
ncpus = 2; ncpus = 2;
} }
if (psurge_secondary_ipi_init())
return 1;
psurge_start = ioremap(PSURGE_START, 4); psurge_start = ioremap(PSURGE_START, 4);
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
...@@ -372,8 +407,8 @@ static int __init smp_psurge_kick_cpu(int nr) ...@@ -372,8 +407,8 @@ static int __init smp_psurge_kick_cpu(int nr)
} }
static struct irqaction psurge_irqaction = { static struct irqaction psurge_irqaction = {
.handler = psurge_primary_intr, .handler = psurge_ipi_intr,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED|IRQF_PERCPU,
.name = "primary IPI", .name = "primary IPI",
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册