Hi Ralf,
This patch has added common IRQ routines for GT64111/GT64120.
Yoichi
Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
diff -pruN -X mips/Documentation/dontdiff
mips-orig/arch/mips/gt64120/cobalt/irq.c mips/arch/mips/gt64120/cobalt/irq.c
--- mips-orig/arch/mips/gt64120/cobalt/irq.c 2006-08-18 22:16:52.068534750
+0900
+++ mips/arch/mips/gt64120/cobalt/irq.c 2006-08-17 22:59:36.226694250 +0900
@@ -7,11 +7,10 @@
*
* Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
*/
-#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
#include <asm/i8259.h>
#include <asm/irq_cpu.h>
@@ -37,37 +36,11 @@
* The VIA chip is a master/slave 8259 setup and has the following interrupts:
*
* 8 - RTC
- * 9 - PCI
+ * 9 - PCI slot
* 14 - IDE0
* 15 - IDE1
*/
-static inline void galileo_irq(struct pt_regs *regs)
-{
- unsigned int mask, pending, devfn;
-
- mask = GT_READ(GT_INTRMASK_OFS);
- pending = GT_READ(GT_INTRCAUSE_OFS) & mask;
-
- if (pending & GALILEO_INTR_T3EXP) {
-
- GT_WRITE(GT_INTRCAUSE_OFS, ~GALILEO_INTR_T3EXP);
- do_IRQ(COBALT_GALILEO_IRQ, regs);
-
- } else if (pending & GALILEO_INTR_RETRY_CTR) {
-
- devfn = GT_READ(GT_PCI0_CFGADDR_OFS) >> 8;
- GT_WRITE(GT_INTRCAUSE_OFS, ~GALILEO_INTR_RETRY_CTR);
- printk(KERN_WARNING "Galileo: PCI retry count exceeded
(%02x.%u)\n",
- PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- } else {
-
- GT_WRITE(GT_INTRMASK_OFS, mask & ~pending);
- printk(KERN_WARNING "Galileo: masking unexpected interrupt
%08x\n", pending);
- }
-}
-
static inline void via_pic_irq(struct pt_regs *regs)
{
int irq;
@@ -79,55 +52,38 @@ static inline void via_pic_irq(struct pt
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
- unsigned pending;
+ unsigned int pending;
- pending = read_c0_status() & read_c0_cause();
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ
(18) */
-
- galileo_irq(regs);
-
+ gt641xx_irq_dispatch(regs);
else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22)
*/
-
via_pic_irq(regs);
-
else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19)
*/
-
do_IRQ(COBALT_CPU_IRQ + 3, regs);
-
else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20)
*/
-
do_IRQ(COBALT_CPU_IRQ + 4, regs);
-
else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ
(21) */
-
do_IRQ(COBALT_CPU_IRQ + 5, regs);
-
else if (pending & CAUSEF_IP7) /* IRQ 23 */
-
do_IRQ(COBALT_CPU_IRQ + 7, regs);
+ else
+ spurious_interrupt(regs);
}
-static struct irqaction irq_via = {
- no_action, 0, { { 0, } }, "cascade", NULL, NULL
+static struct irqaction cascade_irqaction = {
+ .handler = no_action,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
};
void __init arch_init_irq(void)
{
- /*
- * Mask all Galileo interrupts. The Galileo
- * handler is set in cobalt_timer_setup()
- */
- GT_WRITE(GT_INTRMASK_OFS, 0);
-
init_i8259_irqs(); /* 0 ... 15 */
mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
+ gt641xx_irq_init(COBALT_GT64111_IRQ); /* 24 ... 55 */
- /*
- * Mask all cpu interrupts
- * (except IE4, we already masked those at VIA level)
- */
- change_c0_status(ST0_IM, IE_IRQ4);
-
- setup_irq(COBALT_VIA_IRQ, &irq_via);
+ setup_irq(COBALT_GALILEO_IRQ, &cascade_irqaction);
+ setup_irq(COBALT_VIA_IRQ, &cascade_irqaction);
}
diff -pruN -X mips/Documentation/dontdiff
mips-orig/arch/mips/gt64120/cobalt/setup.c mips/arch/mips/gt64120/cobalt/setup.c
--- mips-orig/arch/mips/gt64120/cobalt/setup.c 2006-08-18 22:16:52.068534750
+0900
+++ mips/arch/mips/gt64120/cobalt/setup.c 2006-08-17 22:59:36.246695500
+0900
@@ -52,7 +52,7 @@ const char *get_system_type(void)
void __init plat_timer_setup(struct irqaction *irq)
{
/* Register interrupt */
- setup_irq(COBALT_GALILEO_IRQ, irq);
+ setup_irq(COBALT_TIMER3_IRQ, irq);
}
extern struct pci_ops gt64120_pci_ops;
diff -pruN -X mips/Documentation/dontdiff
mips-orig/arch/mips/gt64120/common/Makefile
mips/arch/mips/gt64120/common/Makefile
--- mips-orig/arch/mips/gt64120/common/Makefile 2006-08-18 22:16:52.068534750
+0900
+++ mips/arch/mips/gt64120/common/Makefile 2006-08-17 22:59:36.246695500
+0900
@@ -2,4 +2,4 @@
# Makefile for common code of gt64120-based boards.
#
-obj-y += time.o
+obj-y += irq.o time.o
diff -pruN -X mips/Documentation/dontdiff
mips-orig/arch/mips/gt64120/common/irq.c mips/arch/mips/gt64120/common/irq.c
--- mips-orig/arch/mips/gt64120/common/irq.c 1970-01-01 09:00:00.000000000
+0900
+++ mips/arch/mips/gt64120/common/irq.c 2006-08-18 05:59:20.299939500 +0900
@@ -0,0 +1,125 @@
+/*
+ * Interrupt routines for Galileo GT64111/GT64120
+ *
+ * Copyright (C) 2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+ */
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/gt64120.h>
+
+static unsigned int gt641xx_irq_base;
+
+#define GT641XX_NR_IRQS 32
+#define GT641XX_IRQ_TO_BIT(irq) (1U << ((irq) - gt641xx_irq_base))
+
+static unsigned int gt641xx_irq_startup(unsigned int irq)
+{
+ uint32_t mask;
+
+ GT_WRITE(GT_INTRCAUSE_OFS, ~GT641XX_IRQ_TO_BIT(irq));
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask |= GT641XX_IRQ_TO_BIT(irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+
+ return 0;
+}
+
+static void gt641xx_irq_shutdown(unsigned int irq)
+{
+ uint32_t mask;
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask &= ~GT641XX_IRQ_TO_BIT(irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+}
+
+static void gt641xx_irq_enable(unsigned int irq)
+{
+ uint32_t mask;
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask |= GT641XX_IRQ_TO_BIT(irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+}
+
+#define gt641xx_irq_disable gt641xx_irq_shutdown
+
+static void gt641xx_irq_ack(unsigned int irq)
+{
+ uint32_t mask;
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask &= ~GT641XX_IRQ_TO_BIT(irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+ GT_WRITE(GT_INTRCAUSE_OFS, ~GT641XX_IRQ_TO_BIT(irq));
+}
+
+static void gt641xx_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ uint32_t mask;
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask |= GT641XX_IRQ_TO_BIT(irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+ }
+}
+
+static struct irq_chip gt641xx_irq_chip = {
+ .typename = "GT641xx",
+ .startup = gt641xx_irq_startup,
+ .shutdown = gt641xx_irq_shutdown,
+ .enable = gt641xx_irq_enable,
+ .disable = gt641xx_irq_disable,
+ .ack = gt641xx_irq_ack,
+ .end = gt641xx_irq_end,
+};
+
+void gt641xx_irq_dispatch(struct pt_regs *regs)
+{
+ uint32_t mask, pending;
+ int i;
+
+ mask = GT_READ(GT_INTRMASK_OFS);
+ pending = GT_READ(GT_INTRCAUSE_OFS);
+ pending &= mask;
+
+ for (i = 0; i < GT641XX_NR_IRQS; i++) {
+ if (pending & (1U << i)) {
+ do_IRQ(gt641xx_irq_base + i, regs);
+ break;
+ }
+ }
+}
+
+void __init gt641xx_irq_init(unsigned int irq_base)
+{
+ int i;
+
+ if (irq_base >= NR_IRQS)
+ return;
+
+ gt641xx_irq_base = irq_base;
+
+ GT_WRITE(GT_INTRMASK_OFS, 0);
+ GT_WRITE(GT_INTRCAUSE_OFS, 0);
+
+ for (i = irq_base; i < irq_base + GT641XX_NR_IRQS; i++)
+ irq_desc[i].chip = >641xx_irq_chip;
+}
diff -pruN -X mips/Documentation/dontdiff mips-orig/include/asm-mips/gt64120.h
mips/include/asm-mips/gt64120.h
--- mips-orig/include/asm-mips/gt64120.h 2006-08-18 22:16:52.068534750
+0900
+++ mips/include/asm-mips/gt64120.h 2006-08-17 22:59:36.246695500 +0900
@@ -573,6 +573,10 @@
#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs))
#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data))
+struct pt_regs;
+extern void gt641xx_irq_dispatch(struct pt_regs *regs);
+extern void gt641xx_irq_init(unsigned int irq_base);
+
extern void gt641xx_timer3_init(void);
extern void gt641xx_disable_alltimers(void);
diff -pruN -X mips/Documentation/dontdiff
mips-orig/include/asm-mips/mach-cobalt/cobalt.h
mips/include/asm-mips/mach-cobalt/cobalt.h
--- mips-orig/include/asm-mips/mach-cobalt/cobalt.h 2006-08-18
22:16:52.068534750 +0900
+++ mips/include/asm-mips/mach-cobalt/cobalt.h 2006-08-17 22:59:36.262696500
+0900
@@ -16,18 +16,18 @@
* i8259 legacy interrupts used on Cobalt:
*
* 8 - RTC
- * 9 - PCI
+ * 9 - PCI slot
* 14 - IDE0
* 15 - IDE1
*/
#define COBALT_QUBE_SLOT_IRQ 9
/*
- * CPU IRQs are 16 ... 23
+ * CPU IRQs are 16 ... 23
*/
#define COBALT_CPU_IRQ 16
-#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2)
+#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2) /* Chained to Galileo
GT64111 */
#define COBALT_SCC_IRQ (COBALT_CPU_IRQ + 3) /* pre-production has
85C30 */
#define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3)
#define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3)
@@ -38,6 +38,13 @@
#define COBALT_VIA_IRQ (COBALT_CPU_IRQ + 6) /* Chained to VIA ISA
bridge */
/*
+ * GT64111 IRQs are 24 ... 55
+ */
+#define COBALT_GT64111_IRQ 24
+
+#define COBALT_TIMER3_IRQ (COBALT_GT64111_IRQ + 11)
+
+/*
* PCI configuration space manifest constants. These are wired into
* the board layout according to the PCI spec to enable the software
* to probe the hardware configuration space in a well defined manner.
|