ppc32: PowerMac G5 interrupt management

The cascaded northbridge MPIC is currently dealt with a special
modified version of open_pic.c (open_pic2.c). A better mecanism
will have to be found for 2.7
parent e286560c
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/open_pic.h> #include <asm/open_pic.h>
#include <asm/xmon.h> #include <asm/xmon.h>
#include <asm/pmac_feature.h>
#include "pmac_pic.h" #include "pmac_pic.h"
...@@ -363,32 +364,76 @@ static int __init enable_second_ohare(void) ...@@ -363,32 +364,76 @@ static int __init enable_second_ohare(void)
return irqctrler->intrs[0].line; return irqctrler->intrs[0].line;
} }
void __init #ifdef CONFIG_POWER4
pmac_pic_init(void) static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs)
{
int irq;
irq = openpic2_get_irq(regs);
if (irq != -1)
ppc_irq_dispatch_handler(regs, irq);
return IRQ_HANDLED;
}
#endif /* CONFIG_POWER4 */
void __init pmac_pic_init(void)
{ {
int i; int i;
struct device_node *irqctrler; struct device_node *irqctrler = NULL;
struct device_node *irqctrler2 = NULL;
struct device_node *np;
unsigned long addr; unsigned long addr;
int irq_cascade = -1; int irq_cascade = -1;
/* We first try to detect Apple's new Core99 chipset, since mac-io /* We first try to detect Apple's new Core99 chipset, since mac-io
* is quite different on those machines and contains an IBM MPIC2. * is quite different on those machines and contains an IBM MPIC2.
*/ */
irqctrler = find_type_devices("open-pic"); np = find_type_devices("open-pic");
while(np) {
if (np->parent && !strcmp(np->parent->name, "u3"))
irqctrler2 = np;
else
irqctrler = np;
np = np->next;
}
if (irqctrler != NULL) if (irqctrler != NULL)
{ {
printk("PowerMac using OpenPIC irq controller\n");
if (irqctrler->n_addrs > 0) if (irqctrler->n_addrs > 0)
{ {
unsigned char senses[NR_IRQS]; unsigned char senses[128];
prom_get_irq_senses(senses, 0, NR_IRQS); printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
irqctrler->addrs[0].address);
prom_get_irq_senses(senses, 0, 128);
OpenPIC_InitSenses = senses; OpenPIC_InitSenses = senses;
OpenPIC_NumInitSenses = NR_IRQS; OpenPIC_NumInitSenses = 128;
ppc_md.get_irq = openpic_get_irq; ppc_md.get_irq = openpic_get_irq;
pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
irqctrler->addrs[0].size); irqctrler->addrs[0].size);
openpic_init(0); openpic_init(0);
#ifdef CONFIG_POWER4
if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
irqctrler2->n_addrs > 0) {
printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
irqctrler2->addrs[0].address,
irqctrler2->intrs[0].line);
pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address,
irqctrler2->addrs[0].size);
prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET,
PMAC_OPENPIC2_OFFSET+128);
OpenPIC_InitSenses = senses;
OpenPIC_NumInitSenses = 128;
openpic2_init(PMAC_OPENPIC2_OFFSET);
if (request_irq(irqctrler2->intrs[0].line, k2u3_action, 0,
"U3->K2 Cascade", NULL))
printk("Unable to get OpenPIC IRQ for cascade\n");
}
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_XMON #ifdef CONFIG_XMON
{ {
struct device_node* pswitch; struct device_node* pswitch;
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_PCI) += qspan_pci.o i8259.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
endif endif
obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o
obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o
obj-$(CONFIG_POWER4) += open_pic2.o
obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o
obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o
obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
......
...@@ -610,12 +610,15 @@ void openpic_request_IPIs(void) ...@@ -610,12 +610,15 @@ void openpic_request_IPIs(void)
void __devinit do_openpic_setup_cpu(void) void __devinit do_openpic_setup_cpu(void)
{ {
#ifdef CONFIG_IRQ_ALL_CPUS
int i; int i;
u32 msk = 1 << smp_hw_index[smp_processor_id()]; u32 msk;
#endif
spin_lock(&openpic_setup_lock); spin_lock(&openpic_setup_lock);
#ifdef CONFIG_IRQ_ALL_CPUS #ifdef CONFIG_IRQ_ALL_CPUS
msk = 1 << smp_hw_index[smp_processor_id()];
/* let the openpic know we want intrs. default affinity /* let the openpic know we want intrs. default affinity
* is 0xffffffff until changed via /proc * is 0xffffffff until changed via /proc
* That's how it's done on x86. If we want it differently, then * That's how it's done on x86. If we want it differently, then
...@@ -788,15 +791,25 @@ static void openpic_set_sense(u_int irq, int sense) ...@@ -788,15 +791,25 @@ static void openpic_set_sense(u_int irq, int sense)
*/ */
static void openpic_ack_irq(unsigned int irq_nr) static void openpic_ack_irq(unsigned int irq_nr)
{ {
#ifdef __SLOW_VERSION__
openpic_disable_irq(irq_nr); openpic_disable_irq(irq_nr);
openpic_eoi(); openpic_eoi();
#else
if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
openpic_eoi();
#endif
} }
static void openpic_end_irq(unsigned int irq_nr) static void openpic_end_irq(unsigned int irq_nr)
{ {
#ifdef __SLOW_VERSION__
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) && irq_desc[irq_nr].action)
openpic_enable_irq(irq_nr); openpic_enable_irq(irq_nr);
#else
if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
openpic_eoi();
#endif
} }
static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
......
This diff is collapsed.
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* Non-offset'ed vector numbers * Non-offset'ed vector numbers
*/ */
#define OPENPIC_VEC_TIMER 64 /* and up */ #define OPENPIC_VEC_TIMER 110 /* and up */
#define OPENPIC_VEC_IPI 72 /* and up */ #define OPENPIC_VEC_IPI 118 /* and up */
#define OPENPIC_VEC_SPURIOUS 127 #define OPENPIC_VEC_SPURIOUS 127
/* OpenPIC IRQ controller structure */ /* OpenPIC IRQ controller structure */
...@@ -51,6 +51,7 @@ extern void openpic_setup_ISU(int isu_num, unsigned long addr); ...@@ -51,6 +51,7 @@ extern void openpic_setup_ISU(int isu_num, unsigned long addr);
extern void openpic_cause_IPI(u_int ipi, u_int cpumask); extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
extern void smp_openpic_message_pass(int target, int msg, unsigned long data, extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
int wait); int wait);
extern void openpic_set_k2_cascade(int irq);
extern inline int openpic_to_irq(int irq) extern inline int openpic_to_irq(int irq)
{ {
...@@ -64,5 +65,25 @@ extern inline int openpic_to_irq(int irq) ...@@ -64,5 +65,25 @@ extern inline int openpic_to_irq(int irq)
return 0; return 0;
} }
} }
/*extern int open_pic_irq_offset;*/ /* Support for second openpic on G5 macs */
// FIXME: To be replaced by sane cascaded controller management */
#define PMAC_OPENPIC2_OFFSET 128
#define OPENPIC2_VEC_TIMER 110 /* and up */
#define OPENPIC2_VEC_IPI 118 /* and up */
#define OPENPIC2_VEC_SPURIOUS 127
extern void* OpenPIC2_Addr;
/* Exported functions */
extern void openpic2_set_sources(int first_irq, int num_irqs, void *isr);
extern void openpic2_init(int linux_irq_offset);
extern void openpic2_init_nmi_irq(u_int irq);
extern u_int openpic2_irq(void);
extern void openpic2_eoi(void);
extern int openpic2_get_irq(struct pt_regs *regs);
extern void openpic2_setup_ISU(int isu_num, unsigned long addr);
#endif /* _PPC_KERNEL_OPEN_PIC_H */ #endif /* _PPC_KERNEL_OPEN_PIC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment