ppc64: Add support for PowerMac G5 interrupts

parent 3f566849
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
void chrp_progress(char *, unsigned short); void chrp_progress(char *, unsigned short);
extern void openpic_init_IRQ(void); extern void pSeries_init_openpic(void);
extern void find_and_init_phbs(void); extern void find_and_init_phbs(void);
extern void pSeries_final_fixup(void); extern void pSeries_final_fixup(void);
...@@ -257,7 +257,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -257,7 +257,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_residual = NULL; ppc_md.setup_residual = NULL;
ppc_md.get_cpuinfo = chrp_get_cpuinfo; ppc_md.get_cpuinfo = chrp_get_cpuinfo;
if(naca->interrupt_controller == IC_OPEN_PIC) { if(naca->interrupt_controller == IC_OPEN_PIC) {
ppc_md.init_IRQ = openpic_init_IRQ; ppc_md.init_IRQ = pSeries_init_openpic;
ppc_md.get_irq = openpic_get_irq; ppc_md.get_irq = openpic_get_irq;
} else { } else {
ppc_md.init_IRQ = xics_init_IRQ; ppc_md.init_IRQ = xics_init_IRQ;
......
...@@ -34,7 +34,42 @@ static volatile struct OpenPIC *OpenPIC = NULL; ...@@ -34,7 +34,42 @@ static volatile struct OpenPIC *OpenPIC = NULL;
u_int OpenPIC_NumInitSenses __initdata = 0; u_int OpenPIC_NumInitSenses __initdata = 0;
u_char *OpenPIC_InitSenses __initdata = NULL; u_char *OpenPIC_InitSenses __initdata = NULL;
void find_ISUs(void); /*
* Local (static) OpenPIC Operations
*/
/* Global Operations */
static void openpic_reset(void);
static void openpic_enable_8259_pass_through(void);
static void openpic_disable_8259_pass_through(void);
static u_int openpic_irq(void);
static void openpic_eoi(void);
static u_int openpic_get_priority(void);
static void openpic_set_priority(u_int pri);
static u_int openpic_get_spurious(void);
static void openpic_set_spurious(u_int vector);
#ifdef CONFIG_SMP
/* Interprocessor Interrupts */
static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
static irqreturn_t openpic_ipi_action(int cpl, void *dev_id,
struct pt_regs *regs);
#endif
/* Timer Interrupts */
static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
static void openpic_maptimer(u_int timer, u_int cpumask);
/* Interrupt Sources */
static void openpic_enable_irq(u_int irq);
static void openpic_disable_irq(u_int irq);
static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
int is_level);
static void openpic_mapirq(u_int irq, u_int cpumask);
static void openpic_set_sense(u_int irq, int sense);
static void find_ISUs(void);
static u_int NumProcessors; static u_int NumProcessors;
static u_int NumSources; static u_int NumSources;
...@@ -130,7 +165,7 @@ unsigned int openpic_vec_spurious; ...@@ -130,7 +165,7 @@ unsigned int openpic_vec_spurious;
#define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf]
void __init openpic_init_IRQ(void) void __init pSeries_init_openpic(void)
{ {
struct device_node *np; struct device_node *np;
int i; int i;
...@@ -359,9 +394,12 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -359,9 +394,12 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
} }
/* Init all external sources */ /* Init all external sources */
for (i = 1; i < NumSources; i++) { for (i = 0; i < NumSources; i++) {
int pri, sense; int pri, sense;
/* skip cascade if any */
if (offset && i == 0)
continue;
/* the bootloader may have left it enabled (bad !) */ /* the bootloader may have left it enabled (bad !) */
openpic_disable_irq(i+offset); openpic_disable_irq(i+offset);
...@@ -396,6 +434,9 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -396,6 +434,9 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
*/ */
static int __init openpic_setup_i8259(void) static int __init openpic_setup_i8259(void)
{ {
if (systemcfg->platform == PLATFORM_POWERMAC)
return 0;
if (naca->interrupt_controller == IC_OPEN_PIC) { if (naca->interrupt_controller == IC_OPEN_PIC) {
/* Initialize the cascade */ /* Initialize the cascade */
if (request_irq(NUM_8259_INTERRUPTS, no_action, SA_INTERRUPT, if (request_irq(NUM_8259_INTERRUPTS, no_action, SA_INTERRUPT,
...@@ -419,6 +460,14 @@ void openpic_setup_ISU(int isu_num, unsigned long addr) ...@@ -419,6 +460,14 @@ void openpic_setup_ISU(int isu_num, unsigned long addr)
void find_ISUs(void) void find_ISUs(void)
{ {
/* For PowerMac, setup ISUs on base openpic */
if (systemcfg->platform == PLATFORM_POWERMAC) {
int i;
for (i=0; i<128; i+=0x10) {
ISU[i>>4] = &((struct OpenPIC *)OpenPIC_Addr)->Source[i];
NumISUs++;
}
}
/* Use /interrupt-controller/reg and /* Use /interrupt-controller/reg and
* /interrupt-controller/interrupt-ranges from OF device tree * /interrupt-controller/interrupt-ranges from OF device tree
* the ISU array is setup in chrp_pci.c in ibm_add_bridges * the ISU array is setup in chrp_pci.c in ibm_add_bridges
...@@ -429,11 +478,22 @@ void find_ISUs(void) ...@@ -429,11 +478,22 @@ void find_ISUs(void)
/* basically each ISU is a bus, and this assumes that /* basically each ISU is a bus, and this assumes that
* open_pic_isu_count interrupts per bus are possible * open_pic_isu_count interrupts per bus are possible
* ISU == Interrupt Source * ISU == Interrupt Source
*
* On G5, we keep the original NumSources provided by the controller,
* it's below 128, so we have room to stuff the IPIs and timers like darwin
* does. We put the spurrious vector up at 0xff though.
*/ */
if (systemcfg->platform == PLATFORM_POWERMAC) {
openpic_vec_ipi = NumSources;
openpic_vec_timer = openpic_vec_ipi + 4;
openpic_vec_spurious = 0xff;
} else {
NumSources = NumISUs * 0x10; NumSources = NumISUs * 0x10;
openpic_vec_ipi = NumSources + open_pic_irq_offset; openpic_vec_ipi = NumSources + open_pic_irq_offset;
openpic_vec_timer = openpic_vec_ipi + OPENPIC_NUM_IPI; openpic_vec_timer = openpic_vec_ipi + OPENPIC_NUM_IPI;
openpic_vec_spurious = openpic_vec_timer + OPENPIC_NUM_TIMERS; openpic_vec_spurious = openpic_vec_timer + OPENPIC_NUM_TIMERS;
}
} }
static inline void openpic_reset(void) static inline void openpic_reset(void)
...@@ -767,7 +827,6 @@ static inline void openpic_set_sense(u_int irq, int sense) ...@@ -767,7 +827,6 @@ static inline void openpic_set_sense(u_int irq, int sense)
static void openpic_end_irq(unsigned int irq_nr) static void openpic_end_irq(unsigned int irq_nr)
{ {
if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
openpic_eoi(); openpic_eoi();
} }
...@@ -807,9 +866,7 @@ int openpic_get_irq(struct pt_regs *regs) ...@@ -807,9 +866,7 @@ int openpic_get_irq(struct pt_regs *regs)
int irq = openpic_irq(); int irq = openpic_irq();
/* Management of the cascade should be moved out of here */ if (open_pic_irq_offset && irq == open_pic_irq_offset) {
if (open_pic_irq_offset && irq == open_pic_irq_offset)
{
/* /*
* This magic address generates a PCI IACK cycle. * This magic address generates a PCI IACK cycle.
*/ */
......
...@@ -40,6 +40,8 @@ extern void openpic_cause_IPI(u_int ipi, u_int cpumask); ...@@ -40,6 +40,8 @@ extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
extern inline int openpic_to_irq(int irq) extern inline int openpic_to_irq(int irq)
{ {
if (systemcfg->platform == PLATFORM_POWERMAC)
return irq;
return irq += NUM_8259_INTERRUPTS; return irq += NUM_8259_INTERRUPTS;
} }
/*extern int open_pic_irq_offset;*/ /*extern int open_pic_irq_offset;*/
......
...@@ -279,40 +279,6 @@ extern volatile struct OpenPIC *OpenPIC; ...@@ -279,40 +279,6 @@ extern volatile struct OpenPIC *OpenPIC;
#define Vector_Priority _Vector_Priority.Reg #define Vector_Priority _Vector_Priority.Reg
#define Destination _Destination.Reg #define Destination _Destination.Reg
/*
* Local (static) OpenPIC Operations
*/
/* Global Operations */
static void openpic_reset(void);
static void openpic_enable_8259_pass_through(void);
static void openpic_disable_8259_pass_through(void);
static u_int openpic_irq(void);
static void openpic_eoi(void);
static u_int openpic_get_priority(void);
static void openpic_set_priority(u_int pri);
static u_int openpic_get_spurious(void);
static void openpic_set_spurious(u_int vector);
#ifdef CONFIG_SMP
/* Interprocessor Interrupts */
static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
static irqreturn_t openpic_ipi_action(int cpl, void *dev_id,
struct pt_regs *regs);
#endif
/* Timer Interrupts */
static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
static void openpic_maptimer(u_int timer, u_int cpumask);
/* Interrupt Sources */
static void openpic_enable_irq(u_int irq);
static void openpic_disable_irq(u_int irq);
static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
int is_level);
static void openpic_mapirq(u_int irq, u_int cpumask);
static void openpic_set_sense(u_int irq, int sense);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
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