aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/sgi-ip32
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sgi-ip32')
-rw-r--r--arch/mips/sgi-ip32/Makefile2
-rw-r--r--arch/mips/sgi-ip32/Platform11
-rw-r--r--arch/mips/sgi-ip32/crime.c6
-rw-r--r--arch/mips/sgi-ip32/ip32-berr.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c406
-rw-r--r--arch/mips/sgi-ip32/ip32-memory.c6
-rw-r--r--arch/mips/sgi-ip32/ip32-platform.c61
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c12
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c15
9 files changed, 278 insertions, 243 deletions
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 31c9aa1bcb4..60f0227425e 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -5,5 +5,3 @@
obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
crime.o ip32-memory.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip32/Platform b/arch/mips/sgi-ip32/Platform
new file mode 100644
index 00000000000..0fea556f364
--- /dev/null
+++ b/arch/mips/sgi-ip32/Platform
@@ -0,0 +1,11 @@
+#
+# SGI-IP32 (O2)
+#
+# Set the load address to >= 80069000 if you want to leave space for symmon,
+# 0xffffffff80004000 for production kernels. Note that the value must be aligned to
+# a multiple of the kernel stack size or the handling of the current variable
+# will break.
+#
+platform-$(CONFIG_SGI_IP32) += sgi-ip32/
+cflags-$(CONFIG_SGI_IP32) += -I$(srctree)/arch/mips/include/asm/mach-ip32
+load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
diff --git a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
index bff508704d0..563c614ad02 100644
--- a/arch/mips/sgi-ip32/crime.c
+++ b/arch/mips/sgi-ip32/crime.c
@@ -35,8 +35,8 @@ void __init crime_init(void)
id = crime->id;
rev = id & CRIME_ID_REV;
id = (id & CRIME_ID_IDBITS) >> 4;
- printk (KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
- id, rev, field, (unsigned long) CRIME_BASE);
+ printk(KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
+ id, rev, field, (unsigned long) CRIME_BASE);
}
irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id)
@@ -96,7 +96,7 @@ irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id)
unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK;
addr <<= 2;
- printk ("CRIME CPU error at 0x%09lx status 0x%08lx\n", addr, stat);
+ printk("CRIME CPU error at 0x%09lx status 0x%08lx\n", addr, stat);
crime->cpu_error_stat = 0;
return IRQ_HANDLED;
diff --git a/arch/mips/sgi-ip32/ip32-berr.c b/arch/mips/sgi-ip32/ip32-berr.c
index a278e918a01..afc1cadbba3 100644
--- a/arch/mips/sgi-ip32/ip32-berr.c
+++ b/arch/mips/sgi-ip32/ip32-berr.c
@@ -16,7 +16,7 @@
#include <asm/ptrace.h>
#include <asm/tlbdebug.h>
-int ip32_be_handler(struct pt_regs *regs, int is_fixup)
+static int ip32_be_handler(struct pt_regs *regs, int is_fixup)
{
int data = regs->cp0_cause & 4;
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index fb9da9acf53..e0c7d9e142f 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -15,14 +15,13 @@
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
+#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/signal.h>
-#include <asm/system.h>
#include <asm/time.h>
#include <asm/ip32/crime.h>
#include <asm/ip32/mace.h>
@@ -39,14 +38,8 @@ static void inline flush_mace_bus(void)
mace->perif.ctrl.misc;
}
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* O2 irq map
+/*
+ * O2 irq map
*
* IP0 -> software (ignored)
* IP1 -> software (ignored)
@@ -55,60 +48,60 @@ static void inline flush_mace_bus(void)
* IP4 -> (irq2) X unknown
* IP5 -> (irq3) X unknown
* IP6 -> (irq4) X unknown
- * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ * IP7 -> (irq5) 7 CPU count/compare timer (system timer)
*
* crime: (C)
*
* CRIME_INT_STAT 31:0:
*
- * 0 -> 1 Video in 1
- * 1 -> 2 Video in 2
- * 2 -> 3 Video out
- * 3 -> 4 Mace ethernet
+ * 0 -> 8 Video in 1
+ * 1 -> 9 Video in 2
+ * 2 -> 10 Video out
+ * 3 -> 11 Mace ethernet
* 4 -> S SuperIO sub-interrupt
* 5 -> M Miscellaneous sub-interrupt
* 6 -> A Audio sub-interrupt
- * 7 -> 8 PCI bridge errors
- * 8 -> 9 PCI SCSI aic7xxx 0
- * 9 -> 10 PCI SCSI aic7xxx 1
- * 10 -> 11 PCI slot 0
- * 11 -> 12 unused (PCI slot 1)
- * 12 -> 13 unused (PCI slot 2)
- * 13 -> 14 unused (PCI shared 0)
- * 14 -> 15 unused (PCI shared 1)
- * 15 -> 16 unused (PCI shared 2)
- * 16 -> 17 GBE0 (E)
- * 17 -> 18 GBE1 (E)
- * 18 -> 19 GBE2 (E)
- * 19 -> 20 GBE3 (E)
- * 20 -> 21 CPU errors
- * 21 -> 22 Memory errors
- * 22 -> 23 RE empty edge (E)
- * 23 -> 24 RE full edge (E)
- * 24 -> 25 RE idle edge (E)
- * 25 -> 26 RE empty level
- * 26 -> 27 RE full level
- * 27 -> 28 RE idle level
- * 28 -> 29 unused (software 0) (E)
- * 29 -> 30 unused (software 1) (E)
- * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E)
- * 31 -> 32 VICE
+ * 7 -> 15 PCI bridge errors
+ * 8 -> 16 PCI SCSI aic7xxx 0
+ * 9 -> 17 PCI SCSI aic7xxx 1
+ * 10 -> 18 PCI slot 0
+ * 11 -> 19 unused (PCI slot 1)
+ * 12 -> 20 unused (PCI slot 2)
+ * 13 -> 21 unused (PCI shared 0)
+ * 14 -> 22 unused (PCI shared 1)
+ * 15 -> 23 unused (PCI shared 2)
+ * 16 -> 24 GBE0 (E)
+ * 17 -> 25 GBE1 (E)
+ * 18 -> 26 GBE2 (E)
+ * 19 -> 27 GBE3 (E)
+ * 20 -> 28 CPU errors
+ * 21 -> 29 Memory errors
+ * 22 -> 30 RE empty edge (E)
+ * 23 -> 31 RE full edge (E)
+ * 24 -> 32 RE idle edge (E)
+ * 25 -> 33 RE empty level
+ * 26 -> 34 RE full level
+ * 27 -> 35 RE idle level
+ * 28 -> 36 unused (software 0) (E)
+ * 29 -> 37 unused (software 1) (E)
+ * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 39 VICE
*
* S, M, A: Use the MACE ISA interrupt register
* MACE_ISA_INT_STAT 31:0
*
- * 0-7 -> 33-40 Audio
- * 8 -> 41 RTC
- * 9 -> 42 Keyboard
+ * 0-7 -> 40-47 Audio
+ * 8 -> 48 RTC
+ * 9 -> 49 Keyboard
* 10 -> X Keyboard polled
- * 11 -> 44 Mouse
+ * 11 -> 51 Mouse
* 12 -> X Mouse polled
- * 13-15 -> 46-48 Count/compare timers
- * 16-19 -> 49-52 Parallel (16 E)
- * 20-25 -> 53-58 Serial 1 (22 E)
- * 26-31 -> 59-64 Serial 2 (28 E)
+ * 13-15 -> 53-55 Count/compare timers
+ * 16-19 -> 56-59 Parallel (16 E)
+ * 20-25 -> 60-62 Serial 1 (22 E)
+ * 26-31 -> 66-71 Serial 2 (28 E)
*
- * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a
+ * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a
* different IRQ map than IRIX uses, but that's OK as Linux irq handling
* is quite different anyway.
*/
@@ -117,39 +110,14 @@ static void inline flush_mace_bus(void)
extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
-struct irqaction memerr_irq = { crime_memerr_intr, IRQF_DISABLED,
- CPU_MASK_NONE, "CRIME memory error", NULL, NULL };
-struct irqaction cpuerr_irq = { crime_cpuerr_intr, IRQF_DISABLED,
- CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
-
-/*
- * For interrupts wired from a single device to the CPU. Only the clock
- * uses this it seems, which is IRQ 0 and IP7.
- */
-
-static void enable_cpu_irq(unsigned int irq)
-{
- set_c0_status(STATUSF_IP7);
-}
-
-static void disable_cpu_irq(unsigned int irq)
-{
- clear_c0_status(STATUSF_IP7);
-}
-
-static void end_cpu_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_cpu_irq (irq);
-}
+static struct irqaction memerr_irq = {
+ .handler = crime_memerr_intr,
+ .name = "CRIME memory error",
+};
-static struct irq_chip ip32_cpu_interrupt = {
- .name = "IP32 CPU",
- .ack = disable_cpu_irq,
- .mask = disable_cpu_irq,
- .mask_ack = disable_cpu_irq,
- .unmask = enable_cpu_irq,
- .end = end_cpu_irq,
+static struct irqaction cpuerr_irq = {
+ .handler = crime_cpuerr_intr,
+ .name = "CRIME CPU error",
};
/*
@@ -159,87 +127,80 @@ static struct irq_chip ip32_cpu_interrupt = {
static uint64_t crime_mask;
-static void enable_crime_irq(unsigned int irq)
+static inline void crime_enable_irq(struct irq_data *d)
{
- crime_mask |= 1 << (irq - 1);
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask |= 1 << bit;
crime->imask = crime_mask;
}
-static void disable_crime_irq(unsigned int irq)
+static inline void crime_disable_irq(struct irq_data *d)
{
- crime_mask &= ~(1 << (irq - 1));
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask &= ~(1 << bit);
crime->imask = crime_mask;
flush_crime_bus();
}
-static void mask_and_ack_crime_irq(unsigned int irq)
+static struct irq_chip crime_level_interrupt = {
+ .name = "IP32 CRIME",
+ .irq_mask = crime_disable_irq,
+ .irq_unmask = crime_enable_irq,
+};
+
+static void crime_edge_mask_and_ack_irq(struct irq_data *d)
{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+ uint64_t crime_int;
+
/* Edge triggered interrupts must be cleared. */
- if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
- || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ)
- || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
- uint64_t crime_int;
- crime_int = crime->hard_int;
- crime_int &= ~(1 << (irq - 1));
- crime->hard_int = crime_int;
- }
- disable_crime_irq(irq);
-}
+ crime_int = crime->hard_int;
+ crime_int &= ~(1 << bit);
+ crime->hard_int = crime_int;
-static void end_crime_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_crime_irq(irq);
+ crime_disable_irq(d);
}
-static struct irq_chip ip32_crime_interrupt = {
- .name = "IP32 CRIME",
- .ack = mask_and_ack_crime_irq,
- .mask = disable_crime_irq,
- .mask_ack = mask_and_ack_crime_irq,
- .unmask = enable_crime_irq,
- .end = end_crime_irq,
+static struct irq_chip crime_edge_interrupt = {
+ .name = "IP32 CRIME",
+ .irq_ack = crime_edge_mask_and_ack_irq,
+ .irq_mask = crime_disable_irq,
+ .irq_mask_ack = crime_edge_mask_and_ack_irq,
+ .irq_unmask = crime_enable_irq,
};
/*
* This is for MACE PCI interrupts. We can decrease bus traffic by masking
- * as close to the source as possible. This also means we can take the
+ * as close to the source as possible. This also means we can take the
* next chunk of the CRIME register in one piece.
*/
static unsigned long macepci_mask;
-static void enable_macepci_irq(unsigned int irq)
+static void enable_macepci_irq(struct irq_data *d)
{
- macepci_mask |= MACEPCI_CONTROL_INT(irq - 9);
+ macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
- crime_mask |= 1 << (irq - 1);
+ crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
crime->imask = crime_mask;
}
-static void disable_macepci_irq(unsigned int irq)
+static void disable_macepci_irq(struct irq_data *d)
{
- crime_mask &= ~(1 << (irq - 1));
+ crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
crime->imask = crime_mask;
flush_crime_bus();
- macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+ macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
flush_mace_bus();
}
-static void end_macepci_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_macepci_irq(irq);
-}
-
static struct irq_chip ip32_macepci_interrupt = {
.name = "IP32 MACE PCI",
- .ack = disable_macepci_irq,
- .mask = disable_macepci_irq,
- .mask_ack = disable_macepci_irq,
- .unmask = enable_macepci_irq,
- .end = end_macepci_irq,
+ .irq_mask = disable_macepci_irq,
+ .irq_unmask = enable_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
@@ -281,13 +242,13 @@ static struct irq_chip ip32_macepci_interrupt = {
static unsigned long maceisa_mask;
-static void enable_maceisa_irq (unsigned int irq)
+static void enable_maceisa_irq(struct irq_data *d)
{
unsigned int crime_int = 0;
- DBG ("maceisa enable: %u\n", irq);
+ pr_debug("maceisa enable: %u\n", d->irq);
- switch (irq) {
+ switch (d->irq) {
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
crime_int = MACE_AUDIO_INT;
break;
@@ -298,23 +259,23 @@ static void enable_maceisa_irq (unsigned int irq)
crime_int = MACE_SUPERIO_INT;
break;
}
- DBG ("crime_int %08x enabled\n", crime_int);
+ pr_debug("crime_int %08x enabled\n", crime_int);
crime_mask |= crime_int;
crime->imask = crime_mask;
- maceisa_mask |= 1 << (irq - 33);
+ maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
mace->perif.ctrl.imask = maceisa_mask;
}
-static void disable_maceisa_irq(unsigned int irq)
+static void disable_maceisa_irq(struct irq_data *d)
{
unsigned int crime_int = 0;
- maceisa_mask &= ~(1 << (irq - 33));
- if(!(maceisa_mask & MACEISA_AUDIO_INT))
+ maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
+ if (!(maceisa_mask & MACEISA_AUDIO_INT))
crime_int |= MACE_AUDIO_INT;
- if(!(maceisa_mask & MACEISA_MISC_INT))
+ if (!(maceisa_mask & MACEISA_MISC_INT))
crime_int |= MACE_MISC_INT;
- if(!(maceisa_mask & MACEISA_SUPERIO_INT))
+ if (!(maceisa_mask & MACEISA_SUPERIO_INT))
crime_int |= MACE_SUPERIO_INT;
crime_mask &= ~crime_int;
crime->imask = crime_mask;
@@ -323,81 +284,70 @@ static void disable_maceisa_irq(unsigned int irq)
flush_mace_bus();
}
-static void mask_and_ack_maceisa_irq(unsigned int irq)
+static void mask_and_ack_maceisa_irq(struct irq_data *d)
{
unsigned long mace_int;
- switch (irq) {
- case MACEISA_PARALLEL_IRQ:
- case MACEISA_SERIAL1_TDMAPR_IRQ:
- case MACEISA_SERIAL2_TDMAPR_IRQ:
- /* edge triggered */
- mace_int = mace->perif.ctrl.istat;
- mace_int &= ~(1 << (irq - 33));
- mace->perif.ctrl.istat = mace_int;
- break;
- }
- disable_maceisa_irq(irq);
-}
+ /* edge triggered */
+ mace_int = mace->perif.ctrl.istat;
+ mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
+ mace->perif.ctrl.istat = mace_int;
-static void end_maceisa_irq(unsigned irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_maceisa_irq(irq);
+ disable_maceisa_irq(d);
}
-static struct irq_chip ip32_maceisa_interrupt = {
- .name = "IP32 MACE ISA",
- .ack = mask_and_ack_maceisa_irq,
- .mask = disable_maceisa_irq,
- .mask_ack = mask_and_ack_maceisa_irq,
- .unmask = enable_maceisa_irq,
- .end = end_maceisa_irq,
+static struct irq_chip ip32_maceisa_level_interrupt = {
+ .name = "IP32 MACE ISA",
+ .irq_mask = disable_maceisa_irq,
+ .irq_unmask = enable_maceisa_irq,
+};
+
+static struct irq_chip ip32_maceisa_edge_interrupt = {
+ .name = "IP32 MACE ISA",
+ .irq_ack = mask_and_ack_maceisa_irq,
+ .irq_mask = disable_maceisa_irq,
+ .irq_mask_ack = mask_and_ack_maceisa_irq,
+ .irq_unmask = enable_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
* bits 0-3 and 7 in the CRIME register.
*/
-static void enable_mace_irq(unsigned int irq)
+static void enable_mace_irq(struct irq_data *d)
{
- crime_mask |= 1 << (irq - 1);
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask |= (1 << bit);
crime->imask = crime_mask;
}
-static void disable_mace_irq(unsigned int irq)
+static void disable_mace_irq(struct irq_data *d)
{
- crime_mask &= ~(1 << (irq - 1));
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask &= ~(1 << bit);
crime->imask = crime_mask;
flush_crime_bus();
}
-static void end_mace_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_mace_irq(irq);
-}
-
static struct irq_chip ip32_mace_interrupt = {
.name = "IP32 MACE",
- .ack = disable_mace_irq,
- .mask = disable_mace_irq,
- .mask_ack = disable_mace_irq,
- .unmask = enable_mace_irq,
- .end = end_mace_irq,
+ .irq_mask = disable_mace_irq,
+ .irq_unmask = enable_mace_irq,
};
static void ip32_unknown_interrupt(void)
{
- printk ("Unknown interrupt occurred!\n");
- printk ("cp0_status: %08x\n", read_c0_status());
- printk ("cp0_cause: %08x\n", read_c0_cause());
- printk ("CRIME intr mask: %016lx\n", crime->imask);
- printk ("CRIME intr status: %016lx\n", crime->istat);
- printk ("CRIME hardware intr register: %016lx\n", crime->hard_int);
- printk ("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
- printk ("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
- printk ("MACE PCI control register: %08x\n", mace->pci.control);
+ printk("Unknown interrupt occurred!\n");
+ printk("cp0_status: %08x\n", read_c0_status());
+ printk("cp0_cause: %08x\n", read_c0_cause());
+ printk("CRIME intr mask: %016lx\n", crime->imask);
+ printk("CRIME intr status: %016lx\n", crime->istat);
+ printk("CRIME hardware intr register: %016lx\n", crime->hard_int);
+ printk("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
+ printk("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
+ printk("MACE PCI control register: %08x\n", mace->pci.control);
printk("Register dump:\n");
show_regs(get_irq_regs());
@@ -414,16 +364,28 @@ static void ip32_irq0(void)
uint64_t crime_int;
int irq = 0;
+ /*
+ * Sanity check interrupt numbering enum.
+ * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy
+ * chained.
+ */
+ BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
+ BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
+
crime_int = crime->istat & crime_mask;
- irq = __ffs(crime_int);
- crime_int = 1 << irq;
+
+ /* crime sometime delivers spurious interrupts, ignore them */
+ if (unlikely(crime_int == 0))
+ return;
+
+ irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
if (crime_int & CRIME_MACEISA_INT_MASK) {
unsigned long mace_int = mace->perif.ctrl.istat;
- irq = __ffs(mace_int & maceisa_mask) + 32;
+ irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
}
- irq++;
- DBG("*irq %u*\n", irq);
+
+ pr_debug("*irq %u*\n", irq);
do_IRQ(irq);
}
@@ -449,7 +411,7 @@ static void ip32_irq4(void)
static void ip32_irq5(void)
{
- ll_timer_interrupt(IP32_R4K_TIMER_IRQ);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
}
asmlinkage void plat_irq_dispatch(void)
@@ -482,21 +444,57 @@ void __init arch_init_irq(void)
mace->perif.ctrl.istat = 0;
mace->perif.ctrl.imask = 0;
- for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
- struct irq_chip *controller;
-
- if (irq == IP32_R4K_TIMER_IRQ)
- controller = &ip32_cpu_interrupt;
- else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
- controller = &ip32_mace_interrupt;
- else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
- controller = &ip32_macepci_interrupt;
- else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
- controller = &ip32_crime_interrupt;
- else
- controller = &ip32_maceisa_interrupt;
-
- set_irq_chip(irq, controller);
+ mips_cpu_irq_init();
+ for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
+ switch (irq) {
+ case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_mace_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_macepci_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case CRIME_CPUERR_IRQ:
+ case CRIME_MEMERR_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &crime_level_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
+ case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
+ case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
+ case CRIME_VICE_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &crime_edge_interrupt,
+ handle_edge_irq,
+ "edge");
+ break;
+
+ case MACEISA_PARALLEL_IRQ:
+ case MACEISA_SERIAL1_TDMAPR_IRQ:
+ case MACEISA_SERIAL2_TDMAPR_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_edge_interrupt,
+ handle_edge_irq,
+ "edge");
+ break;
+
+ default:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_level_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+ }
}
setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
index 849d392a001..828ce131c22 100644
--- a/arch/mips/sgi-ip32/ip32-memory.c
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -19,7 +19,7 @@
extern void crime_init(void);
-void __init prom_meminit (void)
+void __init prom_meminit(void)
{
u64 base, size;
int bank;
@@ -36,9 +36,9 @@ void __init prom_meminit (void)
if (base + size > (256 << 20))
base += CRIME_HI_MEM_BASE;
- printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
+ printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n",
bank, base, size >> 20);
- add_memory_region (base, size, BOOT_MEM_RAM);
+ add_memory_region(base, size, BOOT_MEM_RAM);
}
}
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
index 7309e48d163..511e9ff2acf 100644
--- a/arch/mips/sgi-ip32/ip32-platform.c
+++ b/arch/mips/sgi-ip32/ip32-platform.c
@@ -13,21 +13,22 @@
#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
-/*
- * .iobase isn't a constant (in the sense of C) so we fill it in at runtime.
- */
-#define MACE_PORT(int) \
+#define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1)
+#define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2)
+
+#define MACE_PORT(offset,_irq) \
{ \
- .irq = int, \
+ .mapbase = MACE_BASE + offset, \
+ .irq = _irq, \
.uartclk = 1843200, \
.iotype = UPIO_MEM, \
- .flags = UPF_SKIP_TEST, \
+ .flags = UPF_SKIP_TEST|UPF_IOREMAP, \
.regshift = 8, \
}
static struct plat_serial8250_port uart8250_data[] = {
- MACE_PORT(MACEISA_SERIAL1_IRQ),
- MACE_PORT(MACEISA_SERIAL2_IRQ),
+ MACE_PORT(MACEISA_SERIAL1_OFFS, MACEISA_SERIAL1_IRQ),
+ MACE_PORT(MACEISA_SERIAL2_OFFS, MACEISA_SERIAL2_IRQ),
{ },
};
@@ -41,9 +42,6 @@ static struct platform_device uart8250_device = {
static int __init uart8250_init(void)
{
- uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1;
- uart8250_data[1].membase = (void __iomem *) &mace->isa.serial1;
-
return platform_device_register(&uart8250_device);
}
@@ -67,6 +65,47 @@ static __init int meth_devinit(void)
device_initcall(meth_devinit);
+static __init int sgio2audio_devinit(void)
+{
+ struct platform_device *pd;
+ int ret;
+
+ pd = platform_device_alloc("sgio2audio", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ platform_device_put(pd);
+
+ return ret;
+}
+
+device_initcall(sgio2audio_devinit);
+
+static __init int sgio2btns_devinit(void)
+{
+ return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0));
+}
+
+device_initcall(sgio2btns_devinit);
+
+static struct resource sgio2_cmos_rsrc[] = {
+ {
+ .start = 0x70,
+ .end = 0x71,
+ .flags = IORESOURCE_IO
+ }
+};
+
+static __init int sgio2_cmos_devinit(void)
+{
+ return IS_ERR(platform_device_register_simple("rtc_cmos", -1,
+ sgio2_cmos_rsrc, 1));
+}
+
+device_initcall(sgio2_cmos_devinit);
+
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 624bbdbff2a..1f823da4c77 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -20,7 +20,6 @@
#include <asm/addrspace.h>
#include <asm/irq.h>
#include <asm/reboot.h>
-#include <asm/system.h>
#include <asm/wbflush.h>
#include <asm/ip32/mace.h>
#include <asm/ip32/crime.h>
@@ -53,7 +52,7 @@ static inline void ip32_machine_halt(void)
static void ip32_machine_power_off(void)
{
- volatile unsigned char reg_a, xctrl_a, xctrl_b;
+ unsigned char reg_a, xctrl_a, xctrl_b;
disable_irq(MACEISA_RTC_IRQ);
reg_a = CMOS_READ(RTC_REG_A);
@@ -91,9 +90,10 @@ static void blink_timeout(unsigned long data)
static void debounce(unsigned long data)
{
- volatile unsigned char reg_a, reg_c, xctrl_a;
+ unsigned char reg_a, reg_c, xctrl_a;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
+ reg_a = CMOS_READ(RTC_REG_A);
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
@@ -137,15 +137,15 @@ static inline void ip32_power_button(void)
static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
{
- volatile unsigned char reg_c;
+ unsigned char reg_c;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
if (!(reg_c & RTC_IRQF)) {
printk(KERN_WARNING
- "%s: RTC IRQ without RTC_IRQF\n", __FUNCTION__);
+ "%s: RTC IRQ without RTC_IRQF\n", __func__);
}
/* Wait until interrupt goes away */
- disable_irq(MACEISA_RTC_IRQ);
+ disable_irq_nosync(MACEISA_RTC_IRQ);
init_timer(&debounce_timer);
debounce_timer.function = debounce;
debounce_timer.expires = jiffies + 50;
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index bbba066cb40..3abd1465ec0 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -65,7 +65,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
/* An arbitrary time; this can be decreased if reliability looks good */
#define WAIT_MS 10
-void __init ip32_time_init(void)
+void __init plat_time_init(void)
{
printk(KERN_INFO "Calibrating system timer... ");
write_c0_count(0);
@@ -75,21 +75,10 @@ void __init ip32_time_init(void)
printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- irq->handler = no_action;
- setup_irq(IP32_R4K_TIMER_IRQ, irq);
-}
-
void __init plat_mem_setup(void)
{
board_be_init = ip32_be_init;
- rtc_mips_get_time = mc146818_get_cmos_time;
- rtc_mips_set_mmss = mc146818_set_rtc_mmss;
-
- board_time_init = ip32_time_init;
-
#ifdef CONFIG_SGI_O2MACE_ETH
{
char *mac = ArcGetEnvironmentVariable("eaddr");
@@ -101,7 +90,7 @@ void __init plat_mem_setup(void)
{
char* con = ArcGetEnvironmentVariable("console");
if (con && *con == 'd') {
- static char options[8];
+ static char options[8] __initdata;
char *baud = ArcGetEnvironmentVariable("dbaud");
if (baud)
strcpy(options, baud);