
From: Ralf Baechle <ralf@linux-mips.org>

SMP support for the PMC-Sierra Yosemite evaluation board.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/mips/Kconfig                                      |    1 
 25-akpm/arch/mips/configs/yosemite_defconfig                   |   49 ++++
 25-akpm/arch/mips/pci/ops-titan.c                              |   46 +---
 25-akpm/arch/mips/pci/pci-yosemite.c                           |    6 
 25-akpm/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h      |    2 
 25-akpm/arch/mips/pmc-sierra/yosemite/dbg_io.c                 |    4 
 25-akpm/arch/mips/pmc-sierra/yosemite/irq-handler.S            |   31 --
 25-akpm/arch/mips/pmc-sierra/yosemite/irq.c                    |   26 +-
 25-akpm/arch/mips/pmc-sierra/yosemite/prom.c                   |   10 
 25-akpm/arch/mips/pmc-sierra/yosemite/py-console.c             |   41 +--
 25-akpm/arch/mips/pmc-sierra/yosemite/setup.c                  |  108 ++++++----
 25-akpm/arch/mips/pmc-sierra/yosemite/setup.h                  |    9 
 25-akpm/arch/mips/pmc-sierra/yosemite/smp.c                    |   46 +++-
 25-akpm/include/asm-mips/mach-yosemite/cpu-feature-overrides.h |    1 
 14 files changed, 218 insertions(+), 162 deletions(-)

diff -puN arch/mips/configs/yosemite_defconfig~mips-pmc-sierra-updates arch/mips/configs/yosemite_defconfig
--- 25/arch/mips/configs/yosemite_defconfig~mips-pmc-sierra-updates	2005-01-29 11:26:14.120601264 -0800
+++ 25-akpm/arch/mips/configs/yosemite_defconfig	2005-01-29 11:26:14.143597768 -0800
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Fri Nov 26 00:00:39 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:13 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -80,14 +80,15 @@ CONFIG_PMC_YOSEMITE=y
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_IRQ_CPU=y
 CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_CPU_RM9K=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +135,19 @@ CONFIG_PCI_NAMES=y
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +163,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -172,10 +187,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -189,6 +206,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -401,7 +419,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
+CONFIG_GEN_RTC=y
+CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -409,7 +428,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -440,6 +458,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -454,11 +474,25 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -548,6 +582,7 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_HIGHMEM is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -567,6 +602,10 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_CRYPTO is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff -puN arch/mips/Kconfig~mips-pmc-sierra-updates arch/mips/Kconfig
--- 25/arch/mips/Kconfig~mips-pmc-sierra-updates	2005-01-29 11:26:14.121601112 -0800
+++ 25-akpm/arch/mips/Kconfig	2005-01-29 11:26:14.144597616 -0800
@@ -388,6 +388,7 @@ config PMC_YOSEMITE
 	select HW_HAS_PCI
 	select IRQ_CPU
 	select IRQ_CPU_RM7K
+	select IRQ_CPU_RM9K
 	select SWAP_IO_SPACE
 	help
 	  Yosemite is an evaluation board for the RM9000x2 processor
diff -puN arch/mips/pci/ops-titan.c~mips-pmc-sierra-updates arch/mips/pci/ops-titan.c
--- 25/arch/mips/pci/ops-titan.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.122600960 -0800
+++ 25-akpm/arch/mips/pci/ops-titan.c	2005-01-29 11:26:14.141598072 -0800
@@ -22,91 +22,69 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/version.h>
 
-#include <asm/pci.h>
-#include <asm/io.h>
 #include <asm/titan_dep.h>
 
-/*
- * Titan PCI Config Read Byte
- */
 static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
 	int size, u32 * val)
 {
+	uint32_t address, tmp;
 	int dev, busno, func;
-	uint32_t address_reg, data_reg;
-	uint32_t address;
 
 	busno = bus->number;
 	dev = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
 
-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
-	data_reg = TITAN_PCI_0_CONFIG_DATA;
-
 	address = (busno << 16) | (dev << 11) | (func << 8) |
 	          (reg & 0xfc) | 0x80000000;
 
+
 	/* start the configuration cycle */
-	TITAN_WRITE(address_reg, address);
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
+	tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
 
 	switch (size) {
 	case 1:
-		*val = TITAN_READ_8(data_reg + (~reg & 0x3));
-		break;
-
+		tmp &= 0xff;
 	case 2:
-		*val = TITAN_READ_16(data_reg + (~reg & 0x2));
-		break;
-
-	case 4:
-		*val = TITAN_READ(data_reg);
-		break;
+		tmp &= 0xffff;
 	}
+	*val = tmp;
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-/*
- * Titan PCI Config Byte Write
- */
 static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
 	int size, u32 val)
 {
-	uint32_t address_reg, data_reg, address;
+	uint32_t address;
 	int dev, busno, func;
 
 	busno = bus->number;
 	dev = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
 
-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
-	data_reg = TITAN_PCI_0_CONFIG_DATA;
-
 	address = (busno << 16) | (dev << 11) | (func << 8) |
 		(reg & 0xfc) | 0x80000000;
 
 	/* start the configuration cycle */
-	TITAN_WRITE(address_reg, address);
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
 
 	/* write the data */
 	switch (size) {
 	case 1:
-		TITAN_WRITE_8(data_reg + (~reg & 0x3), val);
+		TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val);
 		break;
 
 	case 2:
-		TITAN_WRITE_16(data_reg + (~reg & 0x2), val);
+		TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val);
 		break;
 
 	case 4:
-		TITAN_WRITE(data_reg, val);
+		TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val);
 		break;
 	}
 
diff -puN arch/mips/pci/pci-yosemite.c~mips-pmc-sierra-updates arch/mips/pci/pci-yosemite.c
--- 25/arch/mips/pci/pci-yosemite.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.124600656 -0800
+++ 25-akpm/arch/mips/pci/pci-yosemite.c	2005-01-29 11:26:14.142597920 -0800
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/gt64240.h>
+#include <asm/titan_dep.h>
 
 extern struct pci_ops titan_pci_ops;
 
@@ -23,6 +23,7 @@ static struct resource py_mem_resource =
  * anyway.  So we just claim 64kB here.
  */
 #define TITAN_IO_SIZE	0x0000ffffUL
+#define TITAN_IO_BASE	0xe8000000UL
 
 static struct resource py_io_resource = {
 	"Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO,
@@ -42,11 +43,12 @@ static int __init pmc_yosemite_setup(voi
 {
 	unsigned long io_v_base;
 
-	io_v_base = (unsigned long) ioremap(0xe0000000UL,TITAN_IO_SIZE);
+	io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
 	if (!io_v_base)
 		panic(ioremap_failed);
 
 	set_io_port_base(io_v_base);
+	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
 
 	ioport_resource.end = TITAN_IO_SIZE - 1;
 
diff -puN arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
--- 25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h~mips-pmc-sierra-updates	2005-01-29 11:26:14.125600504 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2005-01-29 11:26:14.148597008 -0800
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2003 PMC-Sierra Inc.
  *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  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
@@ -29,7 +30,6 @@
  * Header file for atmel_read_eeprom.c 
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff -puN arch/mips/pmc-sierra/yosemite/dbg_io.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/dbg_io.c
--- 25/arch/mips/pmc-sierra/yosemite/dbg_io.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.126600352 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/dbg_io.c	2005-01-29 11:26:14.145597464 -0800
@@ -31,9 +31,6 @@
  * the interrupt came from channel A or B.
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_KGDB
 #include <asm/serial.h>
 
 /*
@@ -181,4 +178,3 @@ int putDebugChar(unsigned char byte)
 
 	return 1;
 }
-#endif
diff -puN arch/mips/pmc-sierra/yosemite/irq.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/irq.c
--- 25/arch/mips/pmc-sierra/yosemite/irq.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.128600048 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/irq.c	2005-01-29 11:26:14.150596704 -0800
@@ -24,7 +24,7 @@
  *
  * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
  */
-
+#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -58,7 +58,7 @@
 extern asmlinkage void titan_handle_int(void);
 extern void jaguar_mailbox_irq(struct pt_regs *);
 
-/* 
+/*
  * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
  * For interprocessor interrupts, the best thing to do is to use the INTMSG
  * register. We use the same external interrupt line, i.e. INTB3 and monitor
@@ -66,15 +66,15 @@ extern void jaguar_mailbox_irq(struct pt
  */
 asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
 {
-        u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
+	u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
 
 	/* Ack all the bits that correspond to the interrupt sources */
 	if (status != 0)
-	        OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
+		OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
 
 	status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
 	if (status != 0)
-                OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
+		OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
 
 #ifdef CONFIG_HT_LEVEL_TRIGGER
 	/*
@@ -110,6 +110,21 @@ asmlinkage void ll_ht_smp_irq_handler(in
 	do_IRQ(irq, regs);
 }
 
+asmlinkage void do_extended_irq(struct pt_regs *regs)
+{
+	unsigned int intcontrol = read_c0_intcontrol();
+	unsigned int cause = read_c0_cause();
+	unsigned int status = read_c0_status();
+	unsigned int pending_sr, pending_ic;
+
+	pending_sr = status & cause & 0xff00;
+	pending_ic = (cause >> 8) & intcontrol & 0xff00;
+
+	if (pending_ic & (1 << 13))
+		do_IRQ(13, regs);
+
+}
+
 #ifdef CONFIG_KGDB
 extern void init_second_port(void);
 #endif
@@ -124,6 +139,7 @@ void __init arch_init_irq(void)
 	set_except_vector(0, titan_handle_int);
 	mips_cpu_irq_init(0);
 	rm7k_cpu_irq_init(8);
+	rm9k_cpu_irq_init(12);
 
 #ifdef CONFIG_KGDB
 	/* At this point, initialize the second serial port */
diff -puN arch/mips/pmc-sierra/yosemite/irq-handler.S~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/irq-handler.S
--- 25/arch/mips/pmc-sierra/yosemite/irq-handler.S~mips-pmc-sierra-updates	2005-01-29 11:26:14.129599896 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/irq-handler.S	2005-01-29 11:26:14.149596856 -0800
@@ -34,37 +34,24 @@
 
 		and	t0, t2
 
+		andi	t2, t0, STATUSF_IP7	/* INTB5 hardware line */
+		bnez	t2, ll_timer_irq	/* Timer */
 		andi	t1, t0, STATUSF_IP2	/* INTB0 hardware line */
 		bnez	t1, ll_pcia_irq		/* 64-bit PCI */
-		andi	t1, t0, STATUSF_IP3	/* INTB1 hardware line */
-		bnez	t1, ll_pcib_irq		/* second 64-bit PCI slot */
+		andi	t2, t0, STATUSF_IP3	/* INTB1 hardware line */
+		bnez	t2, ll_pcib_irq		/* second 64-bit PCI slot */
 		andi	t1, t0, STATUSF_IP4	/* INTB2 hardware line */
 		bnez	t1, ll_duart_irq	/* UART	*/
-		andi    t1, t0, STATUSF_IP5	/* SMP inter-core interrupts */
-		bnez    t1, ll_smp_irq
+		andi    t2, t0, STATUSF_IP5	/* SMP inter-core interrupts */
+		bnez    t2, ll_smp_irq
 		andi	t1, t0, STATUSF_IP6
 		bnez	t1, ll_ht_irq		/* Hypertransport */
-		andi	t1, t0, STATUSF_IP7	/* INTB5 hardware line */
-		bnez	t1, ll_timer_irq	/* Timer */
 
-		nop
-		nop
-
-		/* Extended interrupts */
-                mfc0    t0, CP0_CAUSE
-                cfc0    t1, CP0_S1_INTCONTROL
-
-                sll     t2, t1, 8
-
-                and     t0, t2
-                srl     t0, t0, 16
-
-		.set	reorder
-
-		j	spurious_interrupt
-		nop
+		move	a0, sp
+		j	do_extended_irq
 		END(titan_handle_int)
 
+		.set	reorder
 		.align	5
 
 ll_pcia_irq:
diff -puN arch/mips/pmc-sierra/yosemite/prom.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/prom.c
--- 25/arch/mips/pmc-sierra/yosemite/prom.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.130599744 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/prom.c	2005-01-29 11:26:14.148597008 -0800
@@ -43,7 +43,7 @@ const char *get_system_type(void)
 
 static void prom_cpu0_exit(void *arg)
 {
-	void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR;
+	void *nvram = (void *) YOSEMITE_RTC_BASE;
 
 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
 	writeb(0x84, nvram + 0xff7);
@@ -94,8 +94,6 @@ void __init prom_init(void)
 	_machine_halt = prom_halt;
 	_machine_power_off = prom_halt;
 
-#ifdef CONFIG_MIPS32
-
 	debug_vectors = cv;
 	arcs_cmdline[0] = '\0';
 
@@ -109,6 +107,11 @@ void __init prom_init(void)
 		strcat(arcs_cmdline, " ");
 	}
 
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
+		strcat(arcs_cmdline, "console=ttyS0,115200");
+#endif
+
 	while (*env) {
 		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
 			yosemite_base =
@@ -122,7 +125,6 @@ void __init prom_init(void)
 
 		env++;
 	}
-#endif /* CONFIG_MIPS32 */
 
 	mips_machgroup = MACH_GROUP_TITAN;
 	mips_machtype = MACH_TITAN_YOSEMITE;
diff -puN arch/mips/pmc-sierra/yosemite/py-console.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/py-console.c
--- 25/arch/mips/pmc-sierra/yosemite/py-console.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.132599440 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/py-console.c	2005-01-29 11:26:14.149596856 -0800
@@ -48,9 +48,12 @@ struct yo_uartregs {
 #define iu_iir u3.iir
 #define iu_fcr u3.fcr
 
+#define ssnop()		__asm__ __volatile__("sll	$0, $0, 1\n");
+#define ssnop_4()	do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
+
 #define IO_BASE_64	0x9000000000000000ULL
 
-static unsigned char readb_outer_space(unsigned long phys)
+static unsigned char readb_outer_space(unsigned long long phys)
 {
 	unsigned long long vaddr = IO_BASE_64 | phys;
 	unsigned char res;
@@ -58,29 +61,23 @@ static unsigned char readb_outer_space(u
 
 	sr = read_c0_status();
 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	__asm__ __volatile__ (
 	"	.set	mips3		\n"
-	"	ld	%0, (%0)	\n"
+	"	ld	%0, %1		\n"
 	"	lbu	%0, (%0)	\n"
 	"	.set	mips0		\n"
 	: "=r" (res)
-	: "0" (&vaddr));
+	: "m" (vaddr));
 
 	write_c0_status(sr);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	return res;
 }
 
-static void writeb_outer_space(unsigned long phys, unsigned char c)
+static void writeb_outer_space(unsigned long long phys, unsigned char c)
 {
 	unsigned long long vaddr = IO_BASE_64 | phys;
 	unsigned long tmp;
@@ -88,30 +85,24 @@ static void writeb_outer_space(unsigned 
 
 	sr = read_c0_status();
 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	__asm__ __volatile__ (
 	"	.set	mips3		\n"
-	"	ld	%0, (%1)	\n"
+	"	ld	%0, %1		\n"
 	"	sb	%2, (%0)	\n"
 	"	.set	mips0		\n"
-	: "=r" (tmp)
-	: "r" (&vaddr), "r" (c));
+	: "=&r" (tmp)
+	: "m" (vaddr), "r" (c));
 
 	write_c0_status(sr);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 }
 
 void prom_putchar(char c)
 {
-	unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr);
-	unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr);
+	unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
+	unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
 
 	while ((readb_outer_space(lsr) & 0x20) == 0);
 	writeb_outer_space(thr, c);
diff -puN arch/mips/pmc-sierra/yosemite/setup.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/setup.c
--- 25/arch/mips/pmc-sierra/yosemite/setup.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.133599288 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/setup.c	2005-01-29 11:26:14.147597160 -0800
@@ -35,6 +35,10 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
 
 #include <asm/time.h>
 #include <asm/bootinfo.h>
@@ -45,84 +49,80 @@
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/serial.h>
-#include <linux/termios.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
 #include <asm/titan_dep.h>
+#include <asm/m48t37.h>
 
 #include "setup.h"
 
 unsigned char titan_ge_mac_addr_base[6] = {
-	0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+	// 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+	0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
 };
 
 unsigned long cpu_clock;
 unsigned long yosemite_base;
 
+static struct m48t37_rtc *m48t37_base;
+
 void __init bus_error_init(void)
 {
 	/* Do nothing */
 }
 
+
 unsigned long m48t37y_get_time(void)
 {
-	//unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
-	unsigned char *rtc_base = (unsigned char *) 0xfc000000UL;
 	unsigned int year, month, day, hour, min, sec;
-return;
 
 	/* Stop the update to the time */
-	rtc_base[0x7ff8] = 0x40;
+	m48t37_base->control = 0x40;
 
-	year = BCD2BIN(rtc_base[0x7fff]);
-	year += BCD2BIN(rtc_base[0x7fff1]) * 100;
+	year = BCD2BIN(m48t37_base->year);
+	year += BCD2BIN(m48t37_base->century) * 100;
 
-	month = BCD2BIN(rtc_base[0x7ffe]);
-	day = BCD2BIN(rtc_base[0x7ffd]);
-	hour = BCD2BIN(rtc_base[0x7ffb]);
-	min = BCD2BIN(rtc_base[0x7ffa]);
-	sec = BCD2BIN(rtc_base[0x7ff9]);
+	month = BCD2BIN(m48t37_base->month);
+	day = BCD2BIN(m48t37_base->date);
+	hour = BCD2BIN(m48t37_base->hour);
+	min = BCD2BIN(m48t37_base->min);
+	sec = BCD2BIN(m48t37_base->sec);
 
 	/* Start the update to the time again */
-	rtc_base[0x7ff8] = 0x00;
+	m48t37_base->control = 0x00;
 
 	return mktime(year, month, day, hour, min, sec);
 }
 
 int m48t37y_set_time(unsigned long sec)
 {
-	unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
 	struct rtc_time tm;
-return;
 
 	/* convert to a more useful format -- note months count from 0 */
 	to_tm(sec, &tm);
 	tm.tm_mon += 1;
 
 	/* enable writing */
-	rtc_base[0x7ff8] = 0x80;
+	m48t37_base->control = 0x80;
 
 	/* year */
-	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
-	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
+	m48t37_base->year = BIN2BCD(tm.tm_year % 100);
+	m48t37_base->century = BIN2BCD(tm.tm_year / 100);
 
 	/* month */
-	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
+	m48t37_base->month = BIN2BCD(tm.tm_mon);
 
 	/* day */
-	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
+	m48t37_base->date = BIN2BCD(tm.tm_mday);
 
 	/* hour/min/sec */
-	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
-	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
-	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
+	m48t37_base->hour = BIN2BCD(tm.tm_hour);
+	m48t37_base->min = BIN2BCD(tm.tm_min);
+	m48t37_base->sec = BIN2BCD(tm.tm_sec);
 
 	/* day of week -- not really used, but let's keep it up-to-date */
-	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
+	m48t37_base->day = BIN2BCD(tm.tm_wday + 1);
 
 	/* disable writing */
-	rtc_base[0x7ff8] = 0x00;
+	m48t37_base->control = 0x00;
 
 	return 0;
 }
@@ -136,13 +136,9 @@ void yosemite_time_init(void)
 {
 	board_timer_setup = yosemite_timer_setup;
 	mips_hpt_frequency = cpu_clock / 2;
-
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+mips_hpt_frequency = 33000000 * 3 * 5;
 }
 
-unsigned long uart_base = 0xfd000000L;
-
 /* No other usable initialization hook than this ...  */
 extern void (*late_time_init)(void);
 
@@ -161,16 +157,18 @@ EXPORT_SYMBOL(ocd_base);
 
 static void __init py_map_ocd(void)
 {
-        struct uart_port up;
-
-	/*
-	 * Not specifically interrupt stuff but in case of SMP core_send_ipi
-	 * needs this first so I'm mapping it here ...
-	 */
 	ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
 	if (!ocd_base)
 		panic("Mapping OCD failed - game over.  Your score is 0.");
 
+	/* Kludge for PMON bug ... */
+	OCD_WRITE(0x0710, 0x0ffff029);
+}
+
+static void __init py_uart_setup(void)
+{
+	struct uart_port up;
+
 	/*
 	 * Register to interrupt zero because we share the interrupt with
 	 * the serial driver which we don't properly support yet.
@@ -188,12 +186,36 @@ static void __init py_map_ocd(void)
 		printk(KERN_ERR "Early serial init of port 0 failed\n");
 }
 
-static int __init pmc_yosemite_setup(void)
+static void __init py_rtc_setup(void)
+{
+	m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
+	if (!m48t37_base)
+		printk(KERN_ERR "Mapping the RTC failed\n");
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+
+	write_seqlock(&xtime_lock);
+	xtime.tv_sec = m48t37y_get_time();
+	xtime.tv_nsec = 0;
+
+	set_normalized_timespec(&wall_to_monotonic,
+	                        -xtime.tv_sec, -xtime.tv_nsec);
+	write_sequnlock(&xtime_lock);
+}
+
+/* Not only time init but that's what the hook it's called through is named */
+static void __init py_late_time_init(void)
 {
-	extern void pmon_smp_bootstrap(void);
+	py_map_ocd();
+	py_uart_setup();
+	py_rtc_setup();
+}
 
+static int __init pmc_yosemite_setup(void)
+{
 	board_time_init = yosemite_time_init;
-	late_time_init = py_map_ocd;
+	late_time_init = py_late_time_init;
 
 	/* Add memory regions */
 	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
diff -puN arch/mips/pmc-sierra/yosemite/setup.h~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/setup.h
--- 25/arch/mips/pmc-sierra/yosemite/setup.h~mips-pmc-sierra-updates	2005-01-29 11:26:14.135598984 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/setup.h	2005-01-29 11:26:14.146597312 -0800
@@ -1,6 +1,7 @@
 /*
- * Copyright 2003 PMC-Sierra
+ * Copyright 2003, 04 PMC-Sierra
  * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
  *
  * Board specific definititions for the PMC-Sierra Yosemite
  *
@@ -12,9 +13,9 @@
 #ifndef __SETUP_H__
 #define __SETUP_H__
 
-/* NVRAM Base */
-#define	YOSEMITE_NVRAM_BASE_ADDR	0xbb000678	/* XXX Need change */
-#define	YOSEMITE_RTC_BASE		0xbb000679	/* XXX Need change */
+/* M48T37 RTC + NVRAM */
+#define	YOSEMITE_RTC_BASE		0xfc800000
+#define	YOSEMITE_RTC_SIZE		0x00800000
 
 #define HYPERTRANSPORT_BAR0_ADDR        0x00000006
 #define HYPERTRANSPORT_SIZE0            0x0fffffff
diff -puN arch/mips/pmc-sierra/yosemite/smp.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/smp.c
--- 25/arch/mips/pmc-sierra/yosemite/smp.c~mips-pmc-sierra-updates	2005-01-29 11:26:14.136598832 -0800
+++ 25-akpm/arch/mips/pmc-sierra/yosemite/smp.c	2005-01-29 11:26:14.145597464 -0800
@@ -4,6 +4,9 @@
 #include <asm/pmon.h>
 #include <asm/titan_dep.h>
 
+extern unsigned int (*mips_hpt_read)(void);
+extern void (*mips_hpt_init)(unsigned int);
+
 #define LAUNCHSTACK_SIZE 256
 
 static spinlock_t launch_lock __initdata;
@@ -37,8 +40,8 @@ void __init prom_grab_secondary(void)
 {
 	spin_lock(&launch_lock);
 
-	debug_vectors->cpustart(1, &prom_smp_bootstrap,
-	                        launchstack + LAUNCHSTACK_SIZE, 0);
+	pmon_cpustart(1, &prom_smp_bootstrap,
+	              launchstack + LAUNCHSTACK_SIZE, 0);
 }
 
 /*
@@ -47,23 +50,38 @@ void __init prom_grab_secondary(void)
  * We don't want to start the secondary CPU yet nor do we have a nice probing
  * feature in PMON so we just assume presence of the secondary core.
  */
-void prom_prepare_cpus(unsigned int max_cpus)
+static char maxcpus_string[] __initdata =
+	KERN_WARNING "max_cpus set to 0; using 1 instead\n";
+
+void __init prom_prepare_cpus(unsigned int max_cpus)
 {
+	int enabled = 0, i;
+
+	if (max_cpus == 0) {
+		printk(maxcpus_string);
+		max_cpus = 1;
+	}
+
 	cpus_clear(phys_cpu_present_map);
 
-	/*
-	 * The boot CPU
-	 */
-	cpu_set(0, phys_cpu_present_map);
-	__cpu_number_map[0]	= 0;
-	__cpu_logical_map[0]	= 0;
+	for (i = 0; i < 2; i++) {
+		if (i == max_cpus)
+			break;
+
+		/*
+		 * The boot CPU
+		 */
+		cpu_set(i, phys_cpu_present_map);
+		__cpu_number_map[i]	= i;
+		__cpu_logical_map[i]	= i;
+		enabled++;
+	}
 
 	/*
-	 * The secondary core
+	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
 	 */
-	cpu_set(1, phys_cpu_present_map);
-	__cpu_number_map[1]	= 1;
-	__cpu_logical_map[1]	= 1;
+	if (enabled > 1)
+		set_c0_status(STATUSF_IP5);
 }
 
 /*
@@ -95,6 +113,8 @@ void prom_cpus_done(void)
  */
 void prom_init_secondary(void)
 {
+	mips_hpt_init(mips_hpt_read());
+
 	set_c0_status(ST0_CO | ST0_IE | ST0_IM);
 }
 
diff -puN include/asm-mips/mach-yosemite/cpu-feature-overrides.h~mips-pmc-sierra-updates include/asm-mips/mach-yosemite/cpu-feature-overrides.h
--- 25/include/asm-mips/mach-yosemite/cpu-feature-overrides.h~mips-pmc-sierra-updates	2005-01-29 11:26:14.137598680 -0800
+++ 25-akpm/include/asm-mips/mach-yosemite/cpu-feature-overrides.h	2005-01-29 11:26:14.150596704 -0800
@@ -25,6 +25,7 @@
 #define cpu_has_vtag_icache	0
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
_
