git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
arch
/
ppc
/
syslib
/
open_pic.c
diff --git
a/arch/ppc/syslib/open_pic.c
b/arch/ppc/syslib/open_pic.c
index
a19f8c2
..
70456c8
100644
(file)
--- a/
arch/ppc/syslib/open_pic.c
+++ b/
arch/ppc/syslib/open_pic.c
@@
-1,6
+1,4
@@
/*
/*
- * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
- *
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
@@
-13,18
+11,17
@@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
+#include <linux/errno.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/prom.h>
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
-#include <asm/
hardirq
.h>
+#include <asm/
machdep
.h>
#include "open_pic_defs.h"
#include "open_pic_defs.h"
@@
-32,8
+29,8
@@
#define OPENPIC_BIG_ENDIAN
#endif
#define OPENPIC_BIG_ENDIAN
#endif
-void
*
OpenPIC_Addr;
-static volatile struct OpenPIC *OpenPIC = NULL;
+void
__iomem *
OpenPIC_Addr;
+static volatile struct OpenPIC
__iomem
*OpenPIC = NULL;
/*
* We define OpenPIC_InitSenses table thusly:
/*
* We define OpenPIC_InitSenses table thusly:
@@
-47,13
+44,12
@@
extern int use_of_interrupt_tree;
static u_int NumProcessors;
static u_int NumSources;
static int open_pic_irq_offset;
static u_int NumProcessors;
static u_int NumSources;
static int open_pic_irq_offset;
-static volatile OpenPIC_Source *ISR[NR_IRQS];
+static volatile OpenPIC_Source
__iomem
*ISR[NR_IRQS];
static int openpic_cascade_irq = -1;
static int (*openpic_cascade_fn)(struct pt_regs *);
/* Global Operations */
static void openpic_disable_8259_pass_through(void);
static int openpic_cascade_irq = -1;
static int (*openpic_cascade_fn)(struct pt_regs *);
/* Global Operations */
static void openpic_disable_8259_pass_through(void);
-static void openpic_set_priority(u_int pri);
static void openpic_set_spurious(u_int vector);
#ifdef CONFIG_SMP
static void openpic_set_spurious(u_int vector);
#ifdef CONFIG_SMP
@@
-79,7
+75,6
@@
static void openpic_mapirq(u_int irq, cpumask_t cpumask, cpumask_t keepmask);
*/
#ifdef notused
static void openpic_enable_8259_pass_through(void);
*/
#ifdef notused
static void openpic_enable_8259_pass_through(void);
-static u_int openpic_get_priority(void);
static u_int openpic_get_spurious(void);
static void openpic_set_sense(u_int irq, int sense);
#endif /* notused */
static u_int openpic_get_spurious(void);
static void openpic_set_sense(u_int irq, int sense);
#endif /* notused */
@@
-164,7
+159,7
@@
struct hw_interrupt_type open_pic_ipi = {
#define check_arg_cpu(cpu) do {} while (0)
#endif
#define check_arg_cpu(cpu) do {} while (0)
#endif
-u_int openpic_read(volatile u_int *addr)
+u_int openpic_read(volatile u_int
__iomem
*addr)
{
u_int val;
{
u_int val;
@@
-176,7
+171,7
@@
u_int openpic_read(volatile u_int *addr)
return val;
}
return val;
}
-static inline void openpic_write(volatile u_int *addr, u_int val)
+static inline void openpic_write(volatile u_int
__iomem
*addr, u_int val)
{
#ifdef OPENPIC_BIG_ENDIAN
out_be32(addr, val);
{
#ifdef OPENPIC_BIG_ENDIAN
out_be32(addr, val);
@@
-185,30
+180,30
@@
static inline void openpic_write(volatile u_int *addr, u_int val)
#endif
}
#endif
}
-static inline u_int openpic_readfield(volatile u_int *addr, u_int mask)
+static inline u_int openpic_readfield(volatile u_int
__iomem
*addr, u_int mask)
{
u_int val = openpic_read(addr);
return val & mask;
}
{
u_int val = openpic_read(addr);
return val & mask;
}
-inline void openpic_writefield(volatile u_int *addr, u_int mask,
+inline void openpic_writefield(volatile u_int
__iomem
*addr, u_int mask,
u_int field)
{
u_int val = openpic_read(addr);
openpic_write(addr, (val & ~mask) | (field & mask));
}
u_int field)
{
u_int val = openpic_read(addr);
openpic_write(addr, (val & ~mask) | (field & mask));
}
-static inline void openpic_clearfield(volatile u_int *addr, u_int mask)
+static inline void openpic_clearfield(volatile u_int
__iomem
*addr, u_int mask)
{
openpic_writefield(addr, mask, 0);
}
{
openpic_writefield(addr, mask, 0);
}
-static inline void openpic_setfield(volatile u_int *addr, u_int mask)
+static inline void openpic_setfield(volatile u_int
__iomem
*addr, u_int mask)
{
openpic_writefield(addr, mask, mask);
}
{
openpic_writefield(addr, mask, mask);
}
-static void openpic_safe_writefield(volatile u_int *addr, u_int mask,
+static void openpic_safe_writefield(volatile u_int
__iomem
*addr, u_int mask,
u_int field)
{
openpic_setfield(addr, OPENPIC_MASK);
u_int field)
{
openpic_setfield(addr, OPENPIC_MASK);
@@
-218,10
+213,10
@@
static void openpic_safe_writefield(volatile u_int *addr, u_int mask,
#ifdef CONFIG_SMP
/* yes this is right ... bug, feature, you decide! -- tgall */
#ifdef CONFIG_SMP
/* yes this is right ... bug, feature, you decide! -- tgall */
-u_int openpic_read_IPI(volatile u_int* addr)
+u_int openpic_read_IPI(volatile u_int
__iomem
* addr)
{
u_int val = 0;
{
u_int val = 0;
-#if defined(OPENPIC_BIG_ENDIAN)
|| defined(CONFIG_POWER3)
+#if defined(OPENPIC_BIG_ENDIAN)
val = in_be32(addr);
#else
val = in_le32(addr);
val = in_be32(addr);
#else
val = in_le32(addr);
@@
-230,23
+225,23
@@
u_int openpic_read_IPI(volatile u_int* addr)
}
/* because of the power3 be / le above, this is needed */
}
/* because of the power3 be / le above, this is needed */
-inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field)
+inline void openpic_writefield_IPI(volatile u_int
__iomem
* addr, u_int mask, u_int field)
{
u_int val = openpic_read_IPI(addr);
openpic_write(addr, (val & ~mask) | (field & mask));
}
{
u_int val = openpic_read_IPI(addr);
openpic_write(addr, (val & ~mask) | (field & mask));
}
-static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask)
+static inline void openpic_clearfield_IPI(volatile u_int
__iomem
*addr, u_int mask)
{
openpic_writefield_IPI(addr, mask, 0);
}
{
openpic_writefield_IPI(addr, mask, 0);
}
-static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask)
+static inline void openpic_setfield_IPI(volatile u_int
__iomem
*addr, u_int mask)
{
openpic_writefield_IPI(addr, mask, mask);
}
{
openpic_writefield_IPI(addr, mask, mask);
}
-static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field)
+static void openpic_safe_writefield_IPI(volatile u_int
__iomem
*addr, u_int mask, u_int field)
{
openpic_setfield_IPI(addr, OPENPIC_MASK);
{
openpic_setfield_IPI(addr, OPENPIC_MASK);
@@
-261,6
+256,9
@@
static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int
#endif /* CONFIG_SMP */
#ifdef CONFIG_EPIC_SERIAL_MODE
#endif /* CONFIG_SMP */
#ifdef CONFIG_EPIC_SERIAL_MODE
+/* On platforms that may use EPIC serial mode, the default is enabled. */
+int epic_serial_mode = 1;
+
static void __init openpic_eicr_set_clk(u_int clkval)
{
openpic_writefield(&OpenPIC->Global.Global_Configuration1,
static void __init openpic_eicr_set_clk(u_int clkval)
{
openpic_writefield(&OpenPIC->Global.Global_Configuration1,
@@
-274,7
+272,7
@@
static void __init openpic_enable_sie(void)
}
#endif
}
#endif
-#if defined(CONFIG_EPIC_SERIAL_MODE)
|| defined(CONFIG_PM)
+#if defined(CONFIG_EPIC_SERIAL_MODE)
static void openpic_reset(void)
{
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
static void openpic_reset(void)
{
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@
-285,16
+283,16
@@
static void openpic_reset(void)
}
#endif
}
#endif
-void __init openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
+void __init openpic_set_sources(int first_irq, int num_irqs, void
__iomem
*first_ISR)
{
{
- volatile OpenPIC_Source *src = first_ISR;
+ volatile OpenPIC_Source
__iomem
*src = first_ISR;
int i, last_irq;
last_irq = first_irq + num_irqs;
if (last_irq > NumSources)
NumSources = last_irq;
if (src == 0)
int i, last_irq;
last_irq = first_irq + num_irqs;
if (last_irq > NumSources)
NumSources = last_irq;
if (src == 0)
- src = &((struct OpenPIC *)OpenPIC_Addr)->Source[first_irq];
+ src = &((struct OpenPIC
__iomem
*)OpenPIC_Addr)->Source[first_irq];
for (i = first_irq; i < last_irq; ++i, ++src)
ISR[i] = src;
}
for (i = first_irq; i < last_irq; ++i, ++src)
ISR[i] = src;
}
@@
-316,7
+314,7
@@
void __init openpic_init(int offset)
printk("No OpenPIC found !\n");
return;
}
printk("No OpenPIC found !\n");
return;
}
- OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;
+ OpenPIC = (volatile struct OpenPIC
__iomem
*)OpenPIC_Addr;
#ifdef CONFIG_EPIC_SERIAL_MODE
/* Have to start from ground zero.
#ifdef CONFIG_EPIC_SERIAL_MODE
/* Have to start from ground zero.
@@
-370,8
+368,9
@@
void __init openpic_init(int offset)
/* Initialize IPI interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
for (i = 0; i < OPENPIC_NUM_IPI; i++) {
/* Initialize IPI interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
for (i = 0; i < OPENPIC_NUM_IPI; i++) {
- /* Disabled, Priority 10..13 */
- openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset);
+ /* Disabled, increased priorities 10..13 */
+ openpic_initipi(i, OPENPIC_PRIORITY_IPI_BASE+i,
+ OPENPIC_VEC_IPI+i+offset);
/* IPIs are per-CPU */
irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
/* IPIs are per-CPU */
irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
@@
-399,8
+398,9
@@
void __init openpic_init(int offset)
if (sense & IRQ_SENSE_MASK)
irq_desc[i+offset].status = IRQ_LEVEL;
if (sense & IRQ_SENSE_MASK)
irq_desc[i+offset].status = IRQ_LEVEL;
- /* Enabled, Priority 8 */
- openpic_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK),
+ /* Enabled, Default priority */
+ openpic_initirq(i, OPENPIC_PRIORITY_DEFAULT, i+offset,
+ (sense & IRQ_POLARITY_MASK),
(sense & IRQ_SENSE_MASK));
/* Processor 0 */
openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE);
(sense & IRQ_SENSE_MASK));
/* Processor 0 */
openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE);
@@
-412,11
+412,13
@@
void __init openpic_init(int offset)
/* Initialize the spurious interrupt */
if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
/* Initialize the spurious interrupt */
if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
- openpic_set_spurious(OPENPIC_VEC_SPURIOUS
+offset
);
+ openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
openpic_disable_8259_pass_through();
#ifdef CONFIG_EPIC_SERIAL_MODE
openpic_disable_8259_pass_through();
#ifdef CONFIG_EPIC_SERIAL_MODE
- openpic_eicr_set_clk(7); /* Slowest value until we know better */
- openpic_enable_sie();
+ if (epic_serial_mode) {
+ openpic_eicr_set_clk(7); /* Slowest value until we know better */
+ openpic_enable_sie();
+ }
#endif
openpic_set_priority(0);
#endif
openpic_set_priority(0);
@@
-461,8
+463,7
@@
void openpic_eoi(void)
(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
}
(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
}
-#ifdef notused
-static u_int openpic_get_priority(void)
+u_int openpic_get_priority(void)
{
DECL_THIS_CPU;
{
DECL_THIS_CPU;
@@
-470,9
+471,8
@@
static u_int openpic_get_priority(void)
return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
OPENPIC_CURRENT_TASK_PRIORITY_MASK);
}
return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
OPENPIC_CURRENT_TASK_PRIORITY_MASK);
}
-#endif /* notused */
-
static void __init
openpic_set_priority(u_int pri)
+
void
openpic_set_priority(u_int pri)
{
DECL_THIS_CPU;
{
DECL_THIS_CPU;
@@
-527,7
+527,7
@@
void openpic_reset_processor_phys(u_int mask)
}
#if defined(CONFIG_SMP) || defined(CONFIG_PM)
}
#if defined(CONFIG_SMP) || defined(CONFIG_PM)
-static
spinlock_t openpic_setup_lock = SPIN_LOCK_UNLOCKED
;
+static
DEFINE_SPINLOCK(openpic_setup_lock)
;
#endif
#ifdef CONFIG_SMP
#endif
#ifdef CONFIG_SMP
@@
-556,12
+556,10
@@
static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
*/
void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
{
*/
void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
{
- cpumask_t phys;
DECL_THIS_CPU;
CHECK_THIS_CPU;
check_arg_ipi(ipi);
DECL_THIS_CPU;
CHECK_THIS_CPU;
check_arg_ipi(ipi);
- phys = physmask(cpumask);
openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
cpus_addr(physmask(cpumask))[0]);
}
openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
cpus_addr(physmask(cpumask))[0]);
}
@@
-657,6
+655,18
@@
static void __init openpic_maptimer(u_int timer, cpumask_t cpumask)
cpus_addr(phys)[0]);
}
cpus_addr(phys)[0]);
}
+/*
+ * Change the priority of an interrupt
+ */
+void __init
+openpic_set_irq_priority(u_int irq, u_int pri)
+{
+ check_arg_irq(irq);
+ openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
+ OPENPIC_PRIORITY_MASK,
+ pri << OPENPIC_PRIORITY_SHIFT);
+}
+
/*
* Initalize the interrupt source which will generate an NMI.
* This raises the interrupt's priority from 8 to 9.
/*
* Initalize the interrupt source which will generate an NMI.
* This raises the interrupt's priority from 8 to 9.
@@
-667,9
+677,7
@@
void __init
openpic_init_nmi_irq(u_int irq)
{
check_arg_irq(irq);
openpic_init_nmi_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
- OPENPIC_PRIORITY_MASK,
- 9 << OPENPIC_PRIORITY_SHIFT);
+ openpic_set_irq_priority(irq, OPENPIC_PRIORITY_NMI);
}
/*
}
/*
@@
-681,13
+689,21
@@
openpic_init_nmi_irq(u_int irq)
/*
* Hookup a cascade to the OpenPIC.
*/
/*
* Hookup a cascade to the OpenPIC.
*/
+
+static struct irqaction openpic_cascade_irqaction = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .mask = CPU_MASK_NONE,
+};
+
void __init
openpic_hookup_cascade(u_int irq, char *name,
int (*cascade_fn)(struct pt_regs *))
{
openpic_cascade_irq = irq;
openpic_cascade_fn = cascade_fn;
void __init
openpic_hookup_cascade(u_int irq, char *name,
int (*cascade_fn)(struct pt_regs *))
{
openpic_cascade_irq = irq;
openpic_cascade_fn = cascade_fn;
- if (request_irq(irq, no_action, SA_INTERRUPT, name, NULL))
+
+ if (setup_irq(irq, &openpic_cascade_irqaction))
printk("Unable to get OpenPIC IRQ %d for cascade\n",
irq - open_pic_irq_offset);
}
printk("Unable to get OpenPIC IRQ %d for cascade\n",
irq - open_pic_irq_offset);
}
@@
-699,7
+715,7
@@
openpic_hookup_cascade(u_int irq, char *name,
*/
static void openpic_enable_irq(u_int irq)
{
*/
static void openpic_enable_irq(u_int irq)
{
- volatile u_int *vpp;
+ volatile u_int
__iomem
*vpp;
check_arg_irq(irq);
vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
check_arg_irq(irq);
vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
@@
-712,7
+728,7
@@
static void openpic_enable_irq(u_int irq)
static void openpic_disable_irq(u_int irq)
{
static void openpic_disable_irq(u_int irq)
{
- volatile u_int *vpp;
+ volatile u_int
__iomem
*vpp;
u32 vp;
check_arg_irq(irq);
u32 vp;
check_arg_irq(irq);
@@
-865,14
+881,14
@@
openpic_get_irq(struct pt_regs *regs)
irq = cirq;
openpic_eoi();
}
irq = cirq;
openpic_eoi();
}
-
} else if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset
)
+
} else if (irq == OPENPIC_VEC_SPURIOUS
)
irq = -1;
return irq;
}
#ifdef CONFIG_SMP
void
irq = -1;
return irq;
}
#ifdef CONFIG_SMP
void
-smp_openpic_message_pass(int target, int msg
, unsigned long data, int wait
)
+smp_openpic_message_pass(int target, int msg)
{
cpumask_t mask = CPU_MASK_ALL;
/* make sure we're sending something that translates to an IPI */
{
cpumask_t mask = CPU_MASK_ALL;
/* make sure we're sending something that translates to an IPI */
@@
-930,7
+946,7
@@
static void openpic_cached_disable_irq(u_int irq)
* we need something better to deal with that... Maybe switch to S1 for
* cpufreq changes
*/
* we need something better to deal with that... Maybe switch to S1 for
* cpufreq changes
*/
-int openpic_suspend(struct sys_device *sysdev,
u32
state)
+int openpic_suspend(struct sys_device *sysdev,
pm_message_t
state)
{
int i;
unsigned long flags;
{
int i;
unsigned long flags;
@@
-942,6
+958,8
@@
int openpic_suspend(struct sys_device *sysdev, u32 state)
return 0;
}
return 0;
}
+ openpic_set_priority(0xf);
+
open_pic.enable = openpic_cached_enable_irq;
open_pic.disable = openpic_cached_disable_irq;
open_pic.enable = openpic_cached_enable_irq;
open_pic.disable = openpic_cached_disable_irq;
@@
-984,13
+1002,11
@@
int openpic_resume(struct sys_device *sysdev)
return 0;
}
return 0;
}
- openpic_reset();
-
/* OpenPIC sometimes seem to need some time to be fully back up... */
do {
/* OpenPIC sometimes seem to need some time to be fully back up... */
do {
- openpic_set_spurious(OPENPIC_VEC_SPURIOUS
+open_pic_irq_offset
);
+ openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
} while(openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK)
} while(openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK)
- !=
(OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
);
+ !=
OPENPIC_VEC_SPURIOUS
);
openpic_disable_8259_pass_through();
openpic_disable_8259_pass_through();
@@
-1015,6
+1031,8
@@
int openpic_resume(struct sys_device *sysdev)
open_pic.enable = openpic_enable_irq;
open_pic.disable = openpic_disable_irq;
open_pic.enable = openpic_enable_irq;
open_pic.disable = openpic_disable_irq;
+ openpic_set_priority(0);
+
spin_unlock_irqrestore(&openpic_setup_lock, flags);
return 0;
spin_unlock_irqrestore(&openpic_setup_lock, flags);
return 0;