Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4ed38a0 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

Resurrect Cobalt support for 2.6.

parent 049b13c3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -323,6 +323,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
# Cobalt Server
#
core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
cflags-$(CONFIG_MIPS_COBALT)	+= -Iinclude/asm-mips/cobalt
load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000

#
+1 −1
Original line number Diff line number Diff line
@@ -2,6 +2,6 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#

obj-y	 := irq.o int-handler.o reset.o setup.o promcon.o
obj-y	 := irq.o int-handler.o reset.o setup.o

EXTRA_AFLAGS := $(CFLAGS)
+2 −2
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@
		SAVE_ALL
		CLI

		la	ra, ret_from_irq
		move	a1, sp
		PTR_LA	ra, ret_from_irq
		move	a0, sp
		j	cobalt_irq

		END(cobalt_handle_int)
+73 −38
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/pci.h>

#include <asm/i8259.h>
#include <asm/irq_cpu.h>
@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void);
 * the CPU interrupt lines, and ones that come in on the via chip. The CPU
 * mappings are:
 *
 *    16,  - Software interrupt 0 (unused)	IE_SW0
 *    17   - Software interrupt 1 (unused)	IE_SW0
 *    16   - Software interrupt 0 (unused)	IE_SW0
 *    17   - Software interrupt 1 (unused)	IE_SW1
 *    18   - Galileo chip (timer)		IE_IRQ0
 *    19   - Tulip 0 + NCR SCSI			IE_IRQ1
 *    20   - Tulip 1				IE_IRQ2
@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void);
 *    15  - IDE1
 */

asmlinkage void cobalt_irq(struct pt_regs *regs)
static inline void galileo_irq(struct pt_regs *regs)
{
	unsigned int pending = read_c0_status() & read_c0_cause();
	unsigned int mask, pending, devfn;

	mask = GALILEO_INL(GT_INTRMASK_OFS);
	pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask;

	if (pending & GALILEO_INTR_T0EXP) {

		GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
		do_IRQ(COBALT_GALILEO_IRQ, regs);

	if (pending & CAUSEF_IP2) {			/* int 18 */
		unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
	} else if (pending & GALILEO_INTR_RETRY_CTR) {

		/* Check for timer irq ... */
		if (irq_src & GALILEO_T0EXP) {
			/* Clear the int line */
			GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
			do_IRQ(COBALT_TIMER_IRQ, regs);
		devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8;
		GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS);
		printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n",
			PCI_SLOT(devfn), PCI_FUNC(devfn));

	} else {

		GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS);
		printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending);
	}
		return;
}

	if (pending & CAUSEF_IP6) {			/* int 22 */
		int irq = i8259_irq();
static inline void via_pic_irq(struct pt_regs *regs)
{
	int irq;

	irq = i8259_irq();
	if (irq >= 0)
		do_IRQ(irq, regs);
		return;
}

	if (pending & CAUSEF_IP3) {			/* int 19 */
		do_IRQ(COBALT_ETH0_IRQ, regs);
		return;
	}
asmlinkage void cobalt_irq(struct pt_regs *regs)
{
	unsigned pending;

	if (pending & CAUSEF_IP4) {			/* int 20 */
		do_IRQ(COBALT_ETH1_IRQ, regs);
		return;
	}
	pending = read_c0_status() & read_c0_cause();

	if (pending & CAUSEF_IP5) {			/* int 21 */
		do_IRQ(COBALT_SERIAL_IRQ, regs);
		return;
	}
	if (pending & CAUSEF_IP2)			/* COBALT_GALILEO_IRQ (18) */

	if (pending & CAUSEF_IP7) {			/* int 23 */
		do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
		return;
	}
		galileo_irq(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);
}

static struct irqaction irq_via = {
	no_action, 0, { { 0, } }, "cascade", NULL, NULL
};

void __init arch_init_irq(void)
{
	/*
	 * Mask all Galileo interrupts. The Galileo
	 * handler is set in cobalt_timer_setup()
	 */
	GALILEO_OUTL(0, GT_INTRMASK_OFS);

	set_except_vector(0, cobalt_handle_int);

	init_i8259_irqs();				/*  0 ... 15 */
	mips_cpu_irq_init(16);				/* 16 ... 23 */
	mips_cpu_irq_init(COBALT_CPU_IRQ);		/* 16 ... 23 */

	/*
	 * 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);
}

arch/mips/cobalt/promcon.c

deleted100644 → 0
+0 −87
Original line number Diff line number Diff line
/*
 * PROM console for Cobalt Raq2
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
 * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
 *
 */

#include <linux/init.h>
#include <linux/console.h>
#include <linux/kdev_t.h>
#include <linux/serial_reg.h>

#include <asm/delay.h>
#include <asm/serial.h>
#include <asm/io.h>

static unsigned long port = 0xc800000;

static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
{
	char lsr;

	do {
		lsr = inb(ioaddr + UART_LSR);
	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
	outb(ch, ioaddr + UART_TX);
}

static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
{
	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
		udelay(1);
	return inb(ioaddr + UART_RX);
}

void ns16550_console_write(struct console *co, const char *s, unsigned count)
{
	char lsr, ier;
	unsigned i;

	ier = inb(port + UART_IER);
	outb(0x00, port + UART_IER);
	for (i=0; i < count; i++, s++) {

		if(*s == '\n')
			ns16550_cons_put_char('\r', port);
		ns16550_cons_put_char(*s, port);
	}

	do {
		lsr = inb(port + UART_LSR);
   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));

	outb(ier, port + UART_IER);
}

char getDebugChar(void)
{
	return ns16550_cons_get_char(port);
}

void putDebugChar(char kgdb_char)
{
	ns16550_cons_put_char(kgdb_char, port);
}

static struct console ns16550_console = {
    .name	= "prom",
    .setup	= NULL,
    .write	= ns16550_console_write,
    .flags	= CON_PRINTBUFFER,
    .index	= -1,
};

static int __init ns16550_setup_console(void)
{
	register_console(&ns16550_console);

	return 0;
}

console_initcall(ns16550_setup_console);
Loading