aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 13:51:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 13:51:43 -0400
commite31a94ed371c70855eb30b77c490d6d85dd4da26 (patch)
tree58d9f1a75a22319f97731db8d9ac07b78a8d8aaf /arch/mips
parent9d9ad4b51d2b29b5bbeb4011f5e76f7538119cf9 (diff)
parentfcbd3b4b92efe29b59df16b910138cf43683be88 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (45 commits) [MIPS] Pb1200/DBAu1200: move platform code to its proper place [MIPS] Fix handling of trap and breakpoint instructions [MIPS] Pb1200: do register SMC 91C111 [MIPS] DBAu1200: fix bad SMC 91C111 resource size [NET] Kconfig: Rename MIKROTIK_RB500 -> MIKROTIK_RB532 [MIPS] IP27: Fix build bug due to missing include [MIPS] Fix some sparse warnings on traps.c and irq-msc01.c [MIPS] cevt-gt641xx: Kill unnecessary include [MIPS] DS1287: Add clockevent driver [MIPS] add DECstation I/O ASIC clocksource [MIPS] rbtx4938: minor cleanup [MIPS] Alchemy: kill unused PCI_IRQ_TABLE_LOOKUP macro [MIPS] rbtx4938: misc cleanups [MIPS] jmr3927: use generic txx9 gpio [MIPS] rbhma4500: use generic txx9 gpio [MIPS] generic txx9 gpio support [MIPS] make fallback gpio.h gpiolib-friendly [MIPS] unexport null_perf_irq() and make it static [MIPS] unexport rtc_mips_set_time() [MIPS] unexport copy_from_user_page() ...
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kconfig38
-rw-r--r--arch/mips/Kconfig.debug10
-rw-r--r--arch/mips/Makefile12
-rw-r--r--arch/mips/au1000/common/cputable.c5
-rw-r--r--arch/mips/au1000/common/dbdma.c6
-rw-r--r--arch/mips/au1000/common/dbg_io.c6
-rw-r--r--arch/mips/au1000/common/dma.c5
-rw-r--r--arch/mips/au1000/common/gpio.c5
-rw-r--r--arch/mips/au1000/common/irq.c8
-rw-r--r--arch/mips/au1000/common/pci.c2
-rw-r--r--arch/mips/au1000/common/platform.c117
-rw-r--r--arch/mips/au1000/common/power.c11
-rw-r--r--arch/mips/au1000/common/prom.c2
-rw-r--r--arch/mips/au1000/common/puts.c1
-rw-r--r--arch/mips/au1000/common/reset.c8
-rw-r--r--arch/mips/au1000/common/setup.c11
-rw-r--r--arch/mips/au1000/common/sleeper.S2
-rw-r--r--arch/mips/au1000/common/time.c35
-rw-r--r--arch/mips/au1000/db1x00/board_setup.c15
-rw-r--r--arch/mips/au1000/db1x00/init.c5
-rw-r--r--arch/mips/au1000/db1x00/irqmap.c19
-rw-r--r--arch/mips/au1000/mtx-1/board_setup.c12
-rw-r--r--arch/mips/au1000/mtx-1/init.c6
-rw-r--r--arch/mips/au1000/mtx-1/irqmap.c19
-rw-r--r--arch/mips/au1000/mtx-1/platform.c1
-rw-r--r--arch/mips/au1000/pb1000/board_setup.c11
-rw-r--r--arch/mips/au1000/pb1000/init.c6
-rw-r--r--arch/mips/au1000/pb1000/irqmap.c18
-rw-r--r--arch/mips/au1000/pb1100/board_setup.c11
-rw-r--r--arch/mips/au1000/pb1100/init.c6
-rw-r--r--arch/mips/au1000/pb1100/irqmap.c19
-rw-r--r--arch/mips/au1000/pb1200/Makefile1
-rw-r--r--arch/mips/au1000/pb1200/board_setup.c20
-rw-r--r--arch/mips/au1000/pb1200/init.c6
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c20
-rw-r--r--arch/mips/au1000/pb1200/platform.c84
-rw-r--r--arch/mips/au1000/pb1500/board_setup.c11
-rw-r--r--arch/mips/au1000/pb1500/init.c6
-rw-r--r--arch/mips/au1000/pb1500/irqmap.c19
-rw-r--r--arch/mips/au1000/pb1550/board_setup.c13
-rw-r--r--arch/mips/au1000/pb1550/init.c6
-rw-r--r--arch/mips/au1000/pb1550/irqmap.c19
-rw-r--r--arch/mips/au1000/xxs1500/board_setup.c11
-rw-r--r--arch/mips/au1000/xxs1500/init.c6
-rw-r--r--arch/mips/au1000/xxs1500/irqmap.c19
-rw-r--r--arch/mips/configs/mipssim_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig1
-rw-r--r--arch/mips/dec/time.c71
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c11
-rw-r--r--arch/mips/kernel/Makefile8
-rw-r--r--arch/mips/kernel/cevt-ds1287.c129
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c21
-rw-r--r--arch/mips/kernel/csrc-ioasic.c65
-rw-r--r--arch/mips/kernel/gpio_txx9.c87
-rw-r--r--arch/mips/kernel/irq-gic.c295
-rw-r--r--arch/mips/kernel/irq-msc01.c10
-rw-r--r--arch/mips/kernel/signal-common.h2
-rw-r--r--arch/mips/kernel/smp-cmp.c265
-rw-r--r--arch/mips/kernel/smp-mt.c143
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/kernel/smtc.c11
-rw-r--r--arch/mips/kernel/spram.c221
-rw-r--r--arch/mips/kernel/sync-r4k.c159
-rw-r--r--arch/mips/kernel/time.c5
-rw-r--r--arch/mips/kernel/traps.c213
-rw-r--r--arch/mips/math-emu/ieee754dp.h2
-rw-r--r--arch/mips/math-emu/ieee754sp.h2
-rw-r--r--arch/mips/mips-boards/generic/Makefile1
-rw-r--r--arch/mips/mips-boards/generic/amon.c80
-rw-r--r--arch/mips/mips-boards/generic/init.c23
-rw-r--r--arch/mips/mips-boards/generic/memory.c4
-rw-r--r--arch/mips/mips-boards/generic/time.c31
-rw-r--r--arch/mips/mips-boards/malta/Makefile1
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c354
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c10
-rw-r--r--arch/mips/mipssim/sim_setup.c6
-rw-r--r--arch/mips/mm/Makefile37
-rw-r--r--arch/mips/mm/c-r4k.c62
-rw-r--r--arch/mips/mm/cache.c31
-rw-r--r--arch/mips/mm/init.c11
-rw-r--r--arch/mips/mm/page.c684
-rw-r--r--arch/mips/mm/pg-r4k.c534
-rw-r--r--arch/mips/mm/pg-sb1.c302
-rw-r--r--arch/mips/mm/pgtable.c1
-rw-r--r--arch/mips/mm/tlb-r4k.c2
-rw-r--r--arch/mips/mm/uasm.c26
-rw-r--r--arch/mips/mm/uasm.h4
-rw-r--r--arch/mips/nxp/pnx8550/common/Makefile (renamed from arch/mips/philips/pnx8550/common/Makefile)0
-rw-r--r--arch/mips/nxp/pnx8550/common/gdb_hook.c (renamed from arch/mips/philips/pnx8550/common/gdb_hook.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/int.c (renamed from arch/mips/philips/pnx8550/common/int.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/pci.c (renamed from arch/mips/philips/pnx8550/common/pci.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/platform.c (renamed from arch/mips/philips/pnx8550/common/platform.c)2
-rw-r--r--arch/mips/nxp/pnx8550/common/proc.c (renamed from arch/mips/philips/pnx8550/common/proc.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/prom.c (renamed from arch/mips/philips/pnx8550/common/prom.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/reset.c (renamed from arch/mips/philips/pnx8550/common/reset.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/setup.c (renamed from arch/mips/philips/pnx8550/common/setup.c)0
-rw-r--r--arch/mips/nxp/pnx8550/common/time.c (renamed from arch/mips/philips/pnx8550/common/time.c)0
-rw-r--r--arch/mips/nxp/pnx8550/jbs/Makefile (renamed from arch/mips/philips/pnx8550/jbs/Makefile)2
-rw-r--r--arch/mips/nxp/pnx8550/jbs/board_setup.c (renamed from arch/mips/philips/pnx8550/jbs/board_setup.c)0
-rw-r--r--arch/mips/nxp/pnx8550/jbs/init.c (renamed from arch/mips/philips/pnx8550/jbs/init.c)2
-rw-r--r--arch/mips/nxp/pnx8550/jbs/irqmap.c (renamed from arch/mips/philips/pnx8550/jbs/irqmap.c)3
-rw-r--r--arch/mips/nxp/pnx8550/stb810/Makefile (renamed from arch/mips/philips/pnx8550/stb810/Makefile)2
-rw-r--r--arch/mips/nxp/pnx8550/stb810/board_setup.c (renamed from arch/mips/philips/pnx8550/stb810/board_setup.c)2
-rw-r--r--arch/mips/nxp/pnx8550/stb810/irqmap.c (renamed from arch/mips/philips/pnx8550/stb810/irqmap.c)3
-rw-r--r--arch/mips/nxp/pnx8550/stb810/prom_init.c (renamed from arch/mips/philips/pnx8550/stb810/prom_init.c)2
-rw-r--r--arch/mips/oprofile/common.c1
-rw-r--r--arch/mips/oprofile/op_impl.h1
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c39
-rw-r--r--arch/mips/pci/fixup-au1000.c5
-rw-r--r--arch/mips/pci/ops-pnx8550.c4
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c2
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c2
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c2
-rw-r--r--arch/mips/tx4938/common/dbgio.c4
-rw-r--r--arch/mips/tx4938/common/prom.c11
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c46
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c199
119 files changed, 3101 insertions, 1839 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8724ed3298d3..e5a7c5d96364 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -81,7 +81,9 @@ config MIPS_COBALT
81config MACH_DECSTATION 81config MACH_DECSTATION
82 bool "DECstations" 82 bool "DECstations"
83 select BOOT_ELF32 83 select BOOT_ELF32
84 select CEVT_DS1287
84 select CEVT_R4K 85 select CEVT_R4K
86 select CSRC_IOASIC
85 select CSRC_R4K 87 select CSRC_R4K
86 select CPU_DADDI_WORKAROUNDS if 64BIT 88 select CPU_DADDI_WORKAROUNDS if 64BIT
87 select CPU_R4000_WORKAROUNDS if 64BIT 89 select CPU_R4000_WORKAROUNDS if 64BIT
@@ -221,6 +223,7 @@ config MIPS_MALTA
221 select DMA_NONCOHERENT 223 select DMA_NONCOHERENT
222 select GENERIC_ISA_DMA 224 select GENERIC_ISA_DMA
223 select IRQ_CPU 225 select IRQ_CPU
226 select IRQ_GIC
224 select HW_HAS_PCI 227 select HW_HAS_PCI
225 select I8253 228 select I8253
226 select I8259 229 select I8259
@@ -309,12 +312,12 @@ config MACH_VR41XX
309 select GENERIC_HARDIRQS_NO__DO_IRQ 312 select GENERIC_HARDIRQS_NO__DO_IRQ
310 313
311config PNX8550_JBS 314config PNX8550_JBS
312 bool "Philips PNX8550 based JBS board" 315 bool "NXP PNX8550 based JBS board"
313 select PNX8550 316 select PNX8550
314 select SYS_SUPPORTS_LITTLE_ENDIAN 317 select SYS_SUPPORTS_LITTLE_ENDIAN
315 318
316config PNX8550_STB810 319config PNX8550_STB810
317 bool "Philips PNX8550 based STB810 board" 320 bool "NXP PNX8550 based STB810 board"
318 select PNX8550 321 select PNX8550
319 select SYS_SUPPORTS_LITTLE_ENDIAN 322 select SYS_SUPPORTS_LITTLE_ENDIAN
320 323
@@ -612,6 +615,7 @@ config TOSHIBA_JMR3927
612 select SYS_SUPPORTS_LITTLE_ENDIAN 615 select SYS_SUPPORTS_LITTLE_ENDIAN
613 select SYS_SUPPORTS_BIG_ENDIAN 616 select SYS_SUPPORTS_BIG_ENDIAN
614 select GENERIC_HARDIRQS_NO__DO_IRQ 617 select GENERIC_HARDIRQS_NO__DO_IRQ
618 select GPIO_TXX9
615 619
616config TOSHIBA_RBTX4927 620config TOSHIBA_RBTX4927
617 bool "Toshiba RBTX49[23]7 board" 621 bool "Toshiba RBTX49[23]7 board"
@@ -653,7 +657,7 @@ config TOSHIBA_RBTX4938
653 select SYS_SUPPORTS_BIG_ENDIAN 657 select SYS_SUPPORTS_BIG_ENDIAN
654 select SYS_SUPPORTS_KGDB 658 select SYS_SUPPORTS_KGDB
655 select GENERIC_HARDIRQS_NO__DO_IRQ 659 select GENERIC_HARDIRQS_NO__DO_IRQ
656 select GENERIC_GPIO 660 select GPIO_TXX9
657 help 661 help
658 This Toshiba board is based on the TX4938 processor. Say Y here to 662 This Toshiba board is based on the TX4938 processor. Say Y here to
659 support this machine type 663 support this machine type
@@ -767,6 +771,9 @@ config BOOT_RAW
767config CEVT_BCM1480 771config CEVT_BCM1480
768 bool 772 bool
769 773
774config CEVT_DS1287
775 bool
776
770config CEVT_GT641XX 777config CEVT_GT641XX
771 bool 778 bool
772 779
@@ -782,12 +789,20 @@ config CEVT_TXX9
782config CSRC_BCM1480 789config CSRC_BCM1480
783 bool 790 bool
784 791
792config CSRC_IOASIC
793 bool
794
785config CSRC_R4K 795config CSRC_R4K
786 bool 796 bool
787 797
788config CSRC_SB1250 798config CSRC_SB1250
789 bool 799 bool
790 800
801config GPIO_TXX9
802 select GENERIC_GPIO
803 select HAVE_GPIO_LIB
804 bool
805
791config CFE 806config CFE
792 bool 807 bool
793 808
@@ -840,6 +855,9 @@ config MIPS_NILE4
840config MIPS_DISABLE_OBSOLETE_IDE 855config MIPS_DISABLE_OBSOLETE_IDE
841 bool 856 bool
842 857
858config SYNC_R4K
859 bool
860
843config NO_IOPORT 861config NO_IOPORT
844 def_bool n 862 def_bool n
845 863
@@ -909,6 +927,9 @@ config IRQ_TXX9
909config IRQ_GT641XX 927config IRQ_GT641XX
910 bool 928 bool
911 929
930config IRQ_GIC
931 bool
932
912config MIPS_BOARDS_GEN 933config MIPS_BOARDS_GEN
913 bool 934 bool
914 935
@@ -1811,6 +1832,17 @@ config NR_CPUS
1811 performance should round up your number of processors to the next 1832 performance should round up your number of processors to the next
1812 power of two. 1833 power of two.
1813 1834
1835config MIPS_CMP
1836 bool "MIPS CMP framework support"
1837 depends on SMP
1838 select SYNC_R4K
1839 select SYS_SUPPORTS_SCHED_SMT
1840 select WEAK_ORDERING
1841 default n
1842 help
1843 This is a placeholder option for the GCMP work. It will need to
1844 be handled differently...
1845
1814source "kernel/time/Kconfig" 1846source "kernel/time/Kconfig"
1815 1847
1816# 1848#
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index fd7124c1b75a..f18cf92650e3 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -73,14 +73,4 @@ config RUNTIME_DEBUG
73 include/asm-mips/debug.h for debuging macros. 73 include/asm-mips/debug.h for debuging macros.
74 If unsure, say N. 74 If unsure, say N.
75 75
76config MIPS_UNCACHED
77 bool "Run uncached"
78 depends on DEBUG_KERNEL && !SMP && !SGI_IP27
79 help
80 If you say Y here there kernel will disable all CPU caches. This will
81 reduce the system's performance dramatically but can help finding
82 otherwise hard to track bugs. It can also useful if you're doing
83 hardware debugging with a logic analyzer and need to see all traffic
84 on the bus.
85
86endmenu 76endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 1c62381f5c23..69648d01acc0 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -410,21 +410,21 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
410load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000 410load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
411 411
412# 412#
413# Common Philips PNX8550 413# Common NXP PNX8550
414# 414#
415core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/ 415core-$(CONFIG_SOC_PNX8550) += arch/mips/nxp/pnx8550/common/
416cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550 416cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550
417 417
418# 418#
419# Philips PNX8550 JBS board 419# NXP PNX8550 JBS board
420# 420#
421libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/ 421libs-$(CONFIG_PNX8550_JBS) += arch/mips/nxp/pnx8550/jbs/
422#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550 422#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550
423load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000 423load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
424 424
425# Philips PNX8550 STB810 board 425# NXP PNX8550 STB810 board
426# 426#
427libs-$(CONFIG_PNX8550_STB810) += arch/mips/philips/pnx8550/stb810/ 427libs-$(CONFIG_PNX8550_STB810) += arch/mips/nxp/pnx8550/stb810/
428load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000 428load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000
429 429
430# NEC EMMA2RH boards 430# NEC EMMA2RH boards
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
index 5c0d35d6e22a..8c93a05d7382 100644
--- a/arch/mips/au1000/common/cputable.c
+++ b/arch/mips/au1000/common/cputable.c
@@ -11,10 +11,7 @@
11 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version. 12 * 2 of the License, or (at your option) any later version.
13 */ 13 */
14#include <linux/string.h> 14
15#include <linux/sched.h>
16#include <linux/threads.h>
17#include <linux/init.h>
18#include <asm/mach-au1x00/au1000.h> 15#include <asm/mach-au1x00/au1000.h>
19 16
20struct cpu_spec* cur_cpu_spec[NR_CPUS]; 17struct cpu_spec* cur_cpu_spec[NR_CPUS];
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index 57f17b41098d..53377dfc0640 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -31,18 +31,12 @@
31 */ 31 */
32 32
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/errno.h>
35#include <linux/sched.h>
36#include <linux/slab.h> 34#include <linux/slab.h>
37#include <linux/spinlock.h> 35#include <linux/spinlock.h>
38#include <linux/string.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h> 36#include <linux/interrupt.h>
41#include <linux/module.h> 37#include <linux/module.h>
42#include <asm/mach-au1x00/au1000.h> 38#include <asm/mach-au1x00/au1000.h>
43#include <asm/mach-au1x00/au1xxx_dbdma.h> 39#include <asm/mach-au1x00/au1xxx_dbdma.h>
44#include <asm/system.h>
45
46 40
47#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) 41#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
48 42
diff --git a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c
index 79e0b0a51ace..eae1bb2ca26e 100644
--- a/arch/mips/au1000/common/dbg_io.c
+++ b/arch/mips/au1000/common/dbg_io.c
@@ -1,5 +1,4 @@
1 1
2#include <asm/io.h>
3#include <asm/mach-au1x00/au1000.h> 2#include <asm/mach-au1x00/au1000.h>
4 3
5#ifdef CONFIG_KGDB 4#ifdef CONFIG_KGDB
@@ -55,8 +54,7 @@ typedef unsigned int uint32;
55#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) 54#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff)
56#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y)) 55#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
57 56
58extern unsigned long get_au1x00_uart_baud_base(void); 57extern unsigned long calc_clock(void);
59extern unsigned long cal_r4koff(void);
60 58
61void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) 59void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
62{ 60{
@@ -64,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
64 if (UART16550_READ(UART_MOD_CNTRL) != 0x3) { 62 if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
65 UART16550_WRITE(UART_MOD_CNTRL, 3); 63 UART16550_WRITE(UART_MOD_CNTRL, 3);
66 } 64 }
67 cal_r4koff(); 65 calc_clock();
68 66
69 /* disable interrupts */ 67 /* disable interrupts */
70 UART16550_WRITE(UART_IER, 0); 68 UART16550_WRITE(UART_IER, 0);
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
index c78260d4e837..95f69ea146e9 100644
--- a/arch/mips/au1000/common/dma.c
+++ b/arch/mips/au1000/common/dma.c
@@ -33,12 +33,9 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/errno.h> 35#include <linux/errno.h>
36#include <linux/sched.h>
37#include <linux/spinlock.h> 36#include <linux/spinlock.h>
38#include <linux/string.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h> 37#include <linux/interrupt.h>
41#include <asm/system.h> 38
42#include <asm/mach-au1x00/au1000.h> 39#include <asm/mach-au1x00/au1000.h>
43#include <asm/mach-au1x00/au1000_dma.h> 40#include <asm/mach-au1x00/au1000_dma.h>
44 41
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
index 0b658f1db4ce..525452589971 100644
--- a/arch/mips/au1000/common/gpio.c
+++ b/arch/mips/au1000/common/gpio.c
@@ -27,13 +27,8 @@
27 * others have a second one : GPIO2 27 * others have a second one : GPIO2
28 */ 28 */
29 29
30#include <linux/init.h>
31#include <linux/io.h>
32#include <linux/types.h>
33#include <linux/module.h> 30#include <linux/module.h>
34 31
35#include <asm/addrspace.h>
36
37#include <asm/mach-au1x00/au1000.h> 32#include <asm/mach-au1x00/au1000.h>
38#include <asm/gpio.h> 33#include <asm/gpio.h>
39 34
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index 3c7714f057ac..f0626992fd75 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -1,7 +1,6 @@
1/* 1/*
2 * Copyright 2001 MontaVista Software Inc. 2 * Copyright 2001, 2007-2008 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc. 3 * Author: MontaVista Software, Inc. <source@mvista.com>
4 * ppopov@mvista.com or source@mvista.com
5 * 4 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) 5 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 * 6 *
@@ -27,7 +26,6 @@
27 */ 26 */
28#include <linux/bitops.h> 27#include <linux/bitops.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/io.h>
31#include <linux/interrupt.h> 29#include <linux/interrupt.h>
32#include <linux/irq.h> 30#include <linux/irq.h>
33 31
@@ -591,7 +589,7 @@ void __init arch_init_irq(void)
591 imp++; 589 imp++;
592 } 590 }
593 591
594 set_c0_status(ALLINTS); 592 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
595 593
596 /* Board specific IRQ initialization. 594 /* Board specific IRQ initialization.
597 */ 595 */
diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c
index ce771487567d..7e966b31e3e1 100644
--- a/arch/mips/au1000/common/pci.c
+++ b/arch/mips/au1000/common/pci.c
@@ -30,7 +30,7 @@
30 * with this program; if not, write to the Free Software Foundation, Inc., 30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA. 31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */ 32 */
33#include <linux/types.h> 33
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/init.h> 36#include <linux/init.h>
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 39d681265297..31d2a2270878 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -3,18 +3,65 @@
3 * 3 *
4 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> 4 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
5 * 5 *
6 * (C) Copyright Embedded Alley Solutions, Inc 2005
7 * Author: Pantelis Antoniou <pantelis@embeddedalley.com>
8 *
6 * This file is licensed under the terms of the GNU General Public 9 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any 10 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied. 11 * warranty of any kind, whether express or implied.
9 */ 12 */
10#include <linux/device.h> 13
11#include <linux/platform_device.h> 14#include <linux/platform_device.h>
12#include <linux/kernel.h> 15#include <linux/serial_8250.h>
13#include <linux/init.h> 16#include <linux/init.h>
14#include <linux/resource.h>
15 17
16#include <asm/mach-au1x00/au1xxx.h> 18#include <asm/mach-au1x00/au1xxx.h>
17 19
20#define PORT(_base, _irq) \
21 { \
22 .iobase = _base, \
23 .membase = (void __iomem *)_base,\
24 .mapbase = CPHYSADDR(_base), \
25 .irq = _irq, \
26 .regshift = 2, \
27 .iotype = UPIO_AU, \
28 .flags = UPF_SKIP_TEST \
29 }
30
31static struct plat_serial8250_port au1x00_uart_data[] = {
32#if defined(CONFIG_SERIAL_8250_AU1X00)
33#if defined(CONFIG_SOC_AU1000)
34 PORT(UART0_ADDR, AU1000_UART0_INT),
35 PORT(UART1_ADDR, AU1000_UART1_INT),
36 PORT(UART2_ADDR, AU1000_UART2_INT),
37 PORT(UART3_ADDR, AU1000_UART3_INT),
38#elif defined(CONFIG_SOC_AU1500)
39 PORT(UART0_ADDR, AU1500_UART0_INT),
40 PORT(UART3_ADDR, AU1500_UART3_INT),
41#elif defined(CONFIG_SOC_AU1100)
42 PORT(UART0_ADDR, AU1100_UART0_INT),
43 PORT(UART1_ADDR, AU1100_UART1_INT),
44 PORT(UART3_ADDR, AU1100_UART3_INT),
45#elif defined(CONFIG_SOC_AU1550)
46 PORT(UART0_ADDR, AU1550_UART0_INT),
47 PORT(UART1_ADDR, AU1550_UART1_INT),
48 PORT(UART3_ADDR, AU1550_UART3_INT),
49#elif defined(CONFIG_SOC_AU1200)
50 PORT(UART0_ADDR, AU1200_UART0_INT),
51 PORT(UART1_ADDR, AU1200_UART1_INT),
52#endif
53#endif /* CONFIG_SERIAL_8250_AU1X00 */
54 { },
55};
56
57static struct platform_device au1xx0_uart_device = {
58 .name = "serial8250",
59 .id = PLAT8250_DEV_AU1X00,
60 .dev = {
61 .platform_data = au1x00_uart_data,
62 },
63};
64
18/* OHCI (USB full speed host controller) */ 65/* OHCI (USB full speed host controller) */
19static struct resource au1xxx_usb_ohci_resources[] = { 66static struct resource au1xxx_usb_ohci_resources[] = {
20 [0] = { 67 [0] = {
@@ -186,19 +233,6 @@ static struct resource au1200_lcd_resources[] = {
186 } 233 }
187}; 234};
188 235
189static struct resource au1200_ide0_resources[] = {
190 [0] = {
191 .start = AU1XXX_ATA_PHYS_ADDR,
192 .end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN - 1,
193 .flags = IORESOURCE_MEM,
194 },
195 [1] = {
196 .start = AU1XXX_ATA_INT,
197 .end = AU1XXX_ATA_INT,
198 .flags = IORESOURCE_IRQ,
199 }
200};
201
202static u64 au1200_lcd_dmamask = ~(u32)0; 236static u64 au1200_lcd_dmamask = ~(u32)0;
203 237
204static struct platform_device au1200_lcd_device = { 238static struct platform_device au1200_lcd_device = {
@@ -212,20 +246,6 @@ static struct platform_device au1200_lcd_device = {
212 .resource = au1200_lcd_resources, 246 .resource = au1200_lcd_resources,
213}; 247};
214 248
215
216static u64 ide0_dmamask = ~(u32)0;
217
218static struct platform_device au1200_ide0_device = {
219 .name = "au1200-ide",
220 .id = 0,
221 .dev = {
222 .dma_mask = &ide0_dmamask,
223 .coherent_dma_mask = 0xffffffff,
224 },
225 .num_resources = ARRAY_SIZE(au1200_ide0_resources),
226 .resource = au1200_ide0_resources,
227};
228
229static u64 au1xxx_mmc_dmamask = ~(u32)0; 249static u64 au1xxx_mmc_dmamask = ~(u32)0;
230 250
231static struct platform_device au1xxx_mmc_device = { 251static struct platform_device au1xxx_mmc_device = {
@@ -245,31 +265,6 @@ static struct platform_device au1x00_pcmcia_device = {
245 .id = 0, 265 .id = 0,
246}; 266};
247 267
248#ifdef CONFIG_MIPS_DB1200
249
250static struct resource smc91x_resources[] = {
251 [0] = {
252 .name = "smc91x-regs",
253 .start = AU1XXX_SMC91111_PHYS_ADDR,
254 .end = AU1XXX_SMC91111_PHYS_ADDR + 0xfffff,
255 .flags = IORESOURCE_MEM,
256 },
257 [1] = {
258 .start = AU1XXX_SMC91111_IRQ,
259 .end = AU1XXX_SMC91111_IRQ,
260 .flags = IORESOURCE_IRQ,
261 },
262};
263
264static struct platform_device smc91x_device = {
265 .name = "smc91x",
266 .id = -1,
267 .num_resources = ARRAY_SIZE(smc91x_resources),
268 .resource = smc91x_resources,
269};
270
271#endif
272
273/* All Alchemy demoboards with I2C have this #define in their headers */ 268/* All Alchemy demoboards with I2C have this #define in their headers */
274#ifdef SMBUS_PSC_BASE 269#ifdef SMBUS_PSC_BASE
275static struct resource pbdb_smbus_resources[] = { 270static struct resource pbdb_smbus_resources[] = {
@@ -289,6 +284,7 @@ static struct platform_device pbdb_smbus_device = {
289#endif 284#endif
290 285
291static struct platform_device *au1xxx_platform_devices[] __initdata = { 286static struct platform_device *au1xxx_platform_devices[] __initdata = {
287 &au1xx0_uart_device,
292 &au1xxx_usb_ohci_device, 288 &au1xxx_usb_ohci_device,
293 &au1x00_pcmcia_device, 289 &au1x00_pcmcia_device,
294#ifdef CONFIG_FB_AU1100 290#ifdef CONFIG_FB_AU1100
@@ -299,12 +295,8 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
299 &au1xxx_usb_gdt_device, 295 &au1xxx_usb_gdt_device,
300 &au1xxx_usb_otg_device, 296 &au1xxx_usb_otg_device,
301 &au1200_lcd_device, 297 &au1200_lcd_device,
302 &au1200_ide0_device,
303 &au1xxx_mmc_device, 298 &au1xxx_mmc_device,
304#endif 299#endif
305#ifdef CONFIG_MIPS_DB1200
306 &smc91x_device,
307#endif
308#ifdef SMBUS_PSC_BASE 300#ifdef SMBUS_PSC_BASE
309 &pbdb_smbus_device, 301 &pbdb_smbus_device,
310#endif 302#endif
@@ -312,6 +304,13 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
312 304
313int __init au1xxx_platform_init(void) 305int __init au1xxx_platform_init(void)
314{ 306{
307 unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
308 int i;
309
310 /* Fill up uartclk. */
311 for (i = 0; au1x00_uart_data[i].flags ; i++)
312 au1x00_uart_data[i].uartclk = uartclk;
313
315 return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices)); 314 return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
316} 315}
317 316
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index 54047d69b820..812a5f8b7d26 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -29,17 +29,14 @@
29 * with this program; if not, write to the Free Software Foundation, Inc., 29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA. 30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */ 31 */
32
32#include <linux/init.h> 33#include <linux/init.h>
33#include <linux/pm.h> 34#include <linux/pm.h>
34#include <linux/pm_legacy.h> 35#include <linux/pm_legacy.h>
35#include <linux/slab.h>
36#include <linux/sysctl.h> 36#include <linux/sysctl.h>
37#include <linux/jiffies.h> 37#include <linux/jiffies.h>
38 38
39#include <asm/string.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/cacheflush.h> 40#include <asm/cacheflush.h>
44#include <asm/mach-au1x00/au1000.h> 41#include <asm/mach-au1x00/au1000.h>
45 42
@@ -47,17 +44,13 @@
47 44
48#define DEBUG 1 45#define DEBUG 1
49#ifdef DEBUG 46#ifdef DEBUG
50# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) 47# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__, ## args)
51#else 48#else
52# define DPRINTK(fmt, args...) 49# define DPRINTK(fmt, args...)
53#endif 50#endif
54 51
55static void au1000_calibrate_delay(void); 52static void au1000_calibrate_delay(void);
56 53
57extern void set_au1x00_speed(unsigned int new_freq);
58extern unsigned int get_au1x00_speed(void);
59extern unsigned long get_au1x00_uart_baud_base(void);
60extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
61extern unsigned long save_local_and_disable(int controller); 54extern unsigned long save_local_and_disable(int controller);
62extern void restore_local_and_enable(int controller, unsigned long mask); 55extern void restore_local_and_enable(int controller, unsigned long mask);
63extern void local_enable_irq(unsigned int irq_nr); 56extern void local_enable_irq(unsigned int irq_nr);
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index 90d70695aa60..f10af829e4ec 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -33,8 +33,8 @@
33 * with this program; if not, write to the Free Software Foundation, Inc., 33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA. 34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */ 35 */
36
36#include <linux/module.h> 37#include <linux/module.h>
37#include <linux/kernel.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/string.h> 39#include <linux/string.h>
40 40
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
index 2705829cd466..e34c67e89293 100644
--- a/arch/mips/au1000/common/puts.c
+++ b/arch/mips/au1000/common/puts.c
@@ -28,7 +28,6 @@
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30 30
31#include <linux/types.h>
32#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
33 32
34#define SERIAL_BASE UART_BASE 33#define SERIAL_BASE UART_BASE
diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c
index b8638d293cf9..60cec537c745 100644
--- a/arch/mips/au1000/common/reset.c
+++ b/arch/mips/au1000/common/reset.c
@@ -27,13 +27,7 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30#include <linux/sched.h> 30
31#include <linux/mm.h>
32#include <asm/io.h>
33#include <asm/pgtable.h>
34#include <asm/processor.h>
35#include <asm/reboot.h>
36#include <asm/system.h>
37#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
38 32
39extern int au_sleep(void); 33extern int au_sleep(void);
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 9e4ab80caab6..0e86f7a6b4a7 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -25,21 +25,14 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/sched.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/mm.h>
32#include <linux/delay.h>
33#include <linux/interrupt.h>
34#include <linux/module.h> 31#include <linux/module.h>
35#include <linux/pm.h> 32#include <linux/pm.h>
36 33
37#include <asm/cpu.h>
38#include <asm/bootinfo.h>
39#include <asm/irq.h>
40#include <asm/mipsregs.h> 34#include <asm/mipsregs.h>
41#include <asm/reboot.h> 35#include <asm/reboot.h>
42#include <asm/pgtable.h>
43#include <asm/time.h> 36#include <asm/time.h>
44 37
45#include <au1000.h> 38#include <au1000.h>
@@ -49,8 +42,6 @@ extern void __init board_setup(void);
49extern void au1000_restart(char *); 42extern void au1000_restart(char *);
50extern void au1000_halt(void); 43extern void au1000_halt(void);
51extern void au1000_power_off(void); 44extern void au1000_power_off(void);
52extern void au1x_time_init(void);
53extern void au1x_timer_setup(struct irqaction *irq);
54extern void set_cpuspec(void); 45extern void set_cpuspec(void);
55 46
56void __init plat_mem_setup(void) 47void __init plat_mem_setup(void)
diff --git a/arch/mips/au1000/common/sleeper.S b/arch/mips/au1000/common/sleeper.S
index 683d9da84b66..4b3cf021a454 100644
--- a/arch/mips/au1000/common/sleeper.S
+++ b/arch/mips/au1000/common/sleeper.S
@@ -9,9 +9,9 @@
9 * Free Software Foundation; either version 2 of the License, or (at your 9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12
12#include <asm/asm.h> 13#include <asm/asm.h>
13#include <asm/mipsregs.h> 14#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h> 15#include <asm/regdef.h>
16#include <asm/stackframe.h> 16#include <asm/stackframe.h>
17 17
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index e122bbc6cd88..bdb6d73b26fb 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com 3 * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
4 * Copied and modified Carsten Langgaard's time.c 4 * Copied and modified Carsten Langgaard's time.c
5 * 5 *
6 * Carsten Langgaard, carstenl@mips.com 6 * Carsten Langgaard, carstenl@mips.com
@@ -34,23 +34,13 @@
34 34
35#include <linux/types.h> 35#include <linux/types.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/kernel_stat.h>
38#include <linux/sched.h>
39#include <linux/spinlock.h> 37#include <linux/spinlock.h>
40#include <linux/hardirq.h>
41 38
42#include <asm/compiler.h>
43#include <asm/mipsregs.h> 39#include <asm/mipsregs.h>
44#include <asm/time.h> 40#include <asm/time.h>
45#include <asm/div64.h>
46#include <asm/mach-au1x00/au1000.h> 41#include <asm/mach-au1x00/au1000.h>
47 42
48#include <linux/mc146818rtc.h> 43static int no_au1xxx_32khz;
49#include <linux/timex.h>
50
51static unsigned long r4k_offset; /* Amount to increment compare reg each time */
52static unsigned long r4k_cur; /* What counter should be at next timer irq */
53int no_au1xxx_32khz;
54extern int allow_au1k_wait; /* default off for CP0 Counter */ 44extern int allow_au1k_wait; /* default off for CP0 Counter */
55 45
56#ifdef CONFIG_PM 46#ifdef CONFIG_PM
@@ -184,7 +174,7 @@ wakeup_counter0_set(int ticks)
184 * "wait" is enabled, and we need to detect if the 32KHz isn't present 174 * "wait" is enabled, and we need to detect if the 32KHz isn't present
185 * but requested......got it? :-) -- Dan 175 * but requested......got it? :-) -- Dan
186 */ 176 */
187unsigned long cal_r4koff(void) 177unsigned long calc_clock(void)
188{ 178{
189 unsigned long cpu_speed; 179 unsigned long cpu_speed;
190 unsigned long flags; 180 unsigned long flags;
@@ -229,19 +219,13 @@ unsigned long cal_r4koff(void)
229 // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) 219 // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
230 set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); 220 set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
231 spin_unlock_irqrestore(&time_lock, flags); 221 spin_unlock_irqrestore(&time_lock, flags);
232 return (cpu_speed / HZ); 222 return cpu_speed;
233} 223}
234 224
235void __init plat_time_init(void) 225void __init plat_time_init(void)
236{ 226{
237 unsigned int est_freq; 227 unsigned int est_freq = calc_clock();
238
239 printk("calculating r4koff... ");
240 r4k_offset = cal_r4koff();
241 printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
242 228
243 //est_freq = 2*r4k_offset*HZ;
244 est_freq = r4k_offset*HZ;
245 est_freq += 5000; /* round */ 229 est_freq += 5000; /* round */
246 est_freq -= est_freq%10000; 230 est_freq -= est_freq%10000;
247 printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 231 printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
@@ -249,9 +233,6 @@ void __init plat_time_init(void)
249 set_au1x00_speed(est_freq); 233 set_au1x00_speed(est_freq);
250 set_au1x00_lcd_clock(); // program the LCD clock 234 set_au1x00_lcd_clock(); // program the LCD clock
251 235
252 r4k_cur = (read_c0_count() + r4k_offset);
253 write_c0_compare(r4k_cur);
254
255#ifdef CONFIG_PM 236#ifdef CONFIG_PM
256 /* 237 /*
257 * setup counter 0, since it keeps ticking after a 238 * setup counter 0, since it keeps ticking after a
@@ -265,12 +246,8 @@ void __init plat_time_init(void)
265 * Check to ensure we really have a 32KHz oscillator before 246 * Check to ensure we really have a 32KHz oscillator before
266 * we do this. 247 * we do this.
267 */ 248 */
268 if (no_au1xxx_32khz) { 249 if (no_au1xxx_32khz)
269 printk("WARNING: no 32KHz clock found.\n"); 250 printk("WARNING: no 32KHz clock found.\n");
270
271 /* Ensure we get CPO_COUNTER interrupts. */
272 set_c0_status(IE_IRQ5);
273 }
274 else { 251 else {
275 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); 252 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
276 au_writel(0, SYS_TOYWRITE); 253 au_writel(0, SYS_TOYWRITE);
diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c
index 99eafeada518..b7dcbad5c586 100644
--- a/arch/mips/au1000/db1x00/board_setup.c
+++ b/arch/mips/au1000/db1x00/board_setup.c
@@ -27,20 +27,9 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/sched.h> 32
32#include <linux/ioport.h>
33#include <linux/mm.h>
34#include <linux/console.h>
35#include <linux/mc146818rtc.h>
36#include <linux/delay.h>
37
38#include <asm/cpu.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/mipsregs.h>
42#include <asm/reboot.h>
43#include <asm/pgtable.h>
44#include <asm/mach-au1x00/au1000.h> 33#include <asm/mach-au1x00/au1000.h>
45#include <asm/mach-db1x00/db1x00.h> 34#include <asm/mach-db1x00/db1x00.h>
46 35
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index e822c123eab8..d3b967caf70c 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -28,13 +28,8 @@
28 */ 28 */
29 29
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33#include <linux/bootmem.h>
34#include <linux/string.h>
35#include <linux/kernel.h> 31#include <linux/kernel.h>
36 32
37#include <asm/addrspace.h>
38#include <asm/bootinfo.h> 33#include <asm/bootinfo.h>
39 34
40#include <prom.h> 35#include <prom.h>
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
index 09cea03411b0..eaa50c7b6341 100644
--- a/arch/mips/au1000/db1x00/irqmap.c
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50#ifdef CONFIG_MIPS_DB1500 33#ifdef CONFIG_MIPS_DB1500
diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c
index 310d5dff89fc..5736354829c6 100644
--- a/arch/mips/au1000/mtx-1/board_setup.c
+++ b/arch/mips/au1000/mtx-1/board_setup.c
@@ -28,19 +28,9 @@
28 * with this program; if not, write to the Free Software Foundation, Inc., 28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA. 29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */ 30 */
31
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/sched.h>
33#include <linux/ioport.h>
34#include <linux/mm.h>
35#include <linux/console.h>
36#include <linux/delay.h>
37 33
38#include <asm/cpu.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/mipsregs.h>
42#include <asm/reboot.h>
43#include <asm/pgtable.h>
44#include <asm/mach-au1x00/au1000.h> 34#include <asm/mach-au1x00/au1000.h>
45 35
46extern int (*board_pci_idsel)(unsigned int devsel, int assert); 36extern int (*board_pci_idsel)(unsigned int devsel, int assert);
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index e700fd312a24..c015cbce1cca 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -28,14 +28,10 @@
28 * with this program; if not, write to the Free Software Foundation, Inc., 28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA. 29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */ 30 */
31#include <linux/string.h> 31
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/init.h> 33#include <linux/init.h>
35#include <linux/mm.h>
36#include <linux/bootmem.h>
37 34
38#include <asm/addrspace.h>
39#include <asm/bootinfo.h> 35#include <asm/bootinfo.h>
40 36
41#include <prom.h> 37#include <prom.h>
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
index 49c612aeddcf..78d70c42c9db 100644
--- a/arch/mips/au1000/mtx-1/irqmap.c
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50char irq_tab_alchemy[][5] __initdata = { 33char irq_tab_alchemy[][5] __initdata = {
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
index ce8637b3afa9..a7edbf0829ac 100644
--- a/arch/mips/au1000/mtx-1/platform.c
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/types.h>
23#include <linux/platform_device.h> 22#include <linux/platform_device.h>
24#include <linux/leds.h> 23#include <linux/leds.h>
25#include <linux/gpio_keys.h> 24#include <linux/gpio_keys.h>
diff --git a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c
index 5198c4f98b43..33f15acc1b17 100644
--- a/arch/mips/au1000/pb1000/board_setup.c
+++ b/arch/mips/au1000/pb1000/board_setup.c
@@ -23,19 +23,10 @@
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/delay.h> 28#include <linux/delay.h>
32 29
33#include <asm/cpu.h>
34#include <asm/bootinfo.h>
35#include <asm/irq.h>
36#include <asm/mipsregs.h>
37#include <asm/reboot.h>
38#include <asm/pgtable.h>
39#include <asm/mach-au1x00/au1000.h> 30#include <asm/mach-au1x00/au1000.h>
40#include <asm/mach-pb1x00/pb1000.h> 31#include <asm/mach-pb1x00/pb1000.h>
41 32
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 2515b9fb24af..549447df71d6 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -26,14 +26,10 @@
26 * with this program; if not, write to the Free Software Foundation, Inc., 26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. 27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29
29#include <linux/init.h> 30#include <linux/init.h>
30#include <linux/mm.h>
31#include <linux/sched.h>
32#include <linux/bootmem.h>
33#include <linux/string.h>
34#include <linux/kernel.h> 31#include <linux/kernel.h>
35 32
36#include <asm/addrspace.h>
37#include <asm/bootinfo.h> 33#include <asm/bootinfo.h>
38 34
39#include <prom.h> 35#include <prom.h>
diff --git a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c
index 88e354508204..b3d56b0af321 100644
--- a/arch/mips/au1000/pb1000/irqmap.c
+++ b/arch/mips/au1000/pb1000/irqmap.c
@@ -25,26 +25,10 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h> 30#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 31
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 32#include <asm/mach-au1x00/au1000.h>
49 33
50struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { 34struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
diff --git a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c
index 42874a6b31d1..656164c8e9ca 100644
--- a/arch/mips/au1000/pb1100/board_setup.c
+++ b/arch/mips/au1000/pb1100/board_setup.c
@@ -23,19 +23,10 @@
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/delay.h> 28#include <linux/delay.h>
32 29
33#include <asm/cpu.h>
34#include <asm/bootinfo.h>
35#include <asm/irq.h>
36#include <asm/mipsregs.h>
37#include <asm/reboot.h>
38#include <asm/pgtable.h>
39#include <asm/mach-au1x00/au1000.h> 30#include <asm/mach-au1x00/au1000.h>
40#include <asm/mach-pb1x00/pb1100.h> 31#include <asm/mach-pb1x00/pb1100.h>
41 32
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index 490c3801c275..c91344648ed3 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -27,14 +27,10 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33#include <linux/bootmem.h>
34#include <linux/string.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36 33
37#include <asm/addrspace.h>
38#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
39 35
40#include <prom.h> 36#include <prom.h>
diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c
index 880456bf8c11..b5021e3d477f 100644
--- a/arch/mips/au1000/pb1100/irqmap.c
+++ b/arch/mips/au1000/pb1100/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { 33struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
index 970b1b1d5cda..4fe02ea65a60 100644
--- a/arch/mips/au1000/pb1200/Makefile
+++ b/arch/mips/au1000/pb1200/Makefile
@@ -3,5 +3,6 @@
3# 3#
4 4
5lib-y := init.o board_setup.o irqmap.o 5lib-y := init.o board_setup.o irqmap.o
6obj-y += platform.o
6 7
7EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
index b98bebfa87c6..4493a792cc4c 100644
--- a/arch/mips/au1000/pb1200/board_setup.c
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -23,27 +23,11 @@
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/sched.h> 28#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/mc146818rtc.h>
32#include <linux/delay.h>
33
34#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
35#include <linux/ide.h>
36#endif
37
38#include <asm/cpu.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/mipsregs.h>
42#include <asm/reboot.h>
43#include <asm/pgtable.h>
44 29
45#include <au1000.h> 30#include <au1000.h>
46#include <au1xxx_dbdma.h>
47#include <prom.h> 31#include <prom.h>
48 32
49#ifdef CONFIG_MIPS_PB1200 33#ifdef CONFIG_MIPS_PB1200
@@ -52,8 +36,6 @@
52 36
53#ifdef CONFIG_MIPS_DB1200 37#ifdef CONFIG_MIPS_DB1200
54#include <asm/mach-db1x00/db1200.h> 38#include <asm/mach-db1x00/db1200.h>
55#define PB1200_ETH_INT DB1200_ETH_INT
56#define PB1200_IDE_INT DB1200_IDE_INT
57#endif 39#endif
58 40
59extern void _board_init_irq(void); 41extern void _board_init_irq(void);
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index 069ed45f04f2..72af5500660b 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -27,14 +27,10 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33#include <linux/bootmem.h>
34#include <linux/string.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36 33
37#include <asm/addrspace.h>
38#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
39 35
40#include <prom.h> 36#include <prom.h>
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index 8fcd0df86f93..e61eb8e0b76b 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -22,26 +22,10 @@
22 * with this program; if not, write to the Free Software Foundation, Inc., 22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 */ 24 */
25#include <linux/errno.h> 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/irq.h>
28#include <linux/kernel_stat.h>
29#include <linux/module.h>
30#include <linux/signal.h>
31#include <linux/sched.h>
32#include <linux/types.h>
33#include <linux/interrupt.h> 27#include <linux/interrupt.h>
34#include <linux/ioport.h> 28
35#include <linux/timex.h>
36#include <linux/slab.h>
37#include <linux/random.h>
38#include <linux/delay.h>
39#include <linux/bitops.h>
40
41#include <asm/bootinfo.h>
42#include <asm/io.h>
43#include <asm/mipsregs.h>
44#include <asm/system.h>
45#include <asm/mach-au1x00/au1000.h> 29#include <asm/mach-au1x00/au1000.h>
46 30
47#ifdef CONFIG_MIPS_PB1200 31#ifdef CONFIG_MIPS_PB1200
diff --git a/arch/mips/au1000/pb1200/platform.c b/arch/mips/au1000/pb1200/platform.c
new file mode 100644
index 000000000000..5930110b9b6d
--- /dev/null
+++ b/arch/mips/au1000/pb1200/platform.c
@@ -0,0 +1,84 @@
1/*
2 * Pb1200/DBAu1200 board platform device registration
3 *
4 * Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <linux/init.h>
22#include <linux/platform_device.h>
23
24#include <asm/mach-au1x00/au1xxx.h>
25
26static struct resource ide_resources[] = {
27 [0] = {
28 .start = IDE_PHYS_ADDR,
29 .end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
30 .flags = IORESOURCE_MEM
31 },
32 [1] = {
33 .start = IDE_INT,
34 .end = IDE_INT,
35 .flags = IORESOURCE_IRQ
36 }
37};
38
39static u64 ide_dmamask = ~(u32)0;
40
41static struct platform_device ide_device = {
42 .name = "au1200-ide",
43 .id = 0,
44 .dev = {
45 .dma_mask = &ide_dmamask,
46 .coherent_dma_mask = 0xffffffff,
47 },
48 .num_resources = ARRAY_SIZE(ide_resources),
49 .resource = ide_resources
50};
51
52static struct resource smc91c111_resources[] = {
53 [0] = {
54 .name = "smc91x-regs",
55 .start = SMC91C111_PHYS_ADDR,
56 .end = SMC91C111_PHYS_ADDR + 0xf,
57 .flags = IORESOURCE_MEM
58 },
59 [1] = {
60 .start = SMC91C111_INT,
61 .end = SMC91C111_INT,
62 .flags = IORESOURCE_IRQ
63 },
64};
65
66static struct platform_device smc91c111_device = {
67 .name = "smc91x",
68 .id = -1,
69 .num_resources = ARRAY_SIZE(smc91c111_resources),
70 .resource = smc91c111_resources
71};
72
73static struct platform_device *board_platform_devices[] __initdata = {
74 &ide_device,
75 &smc91c111_device
76};
77
78static int __init board_register_devices(void)
79{
80 return platform_add_devices(board_platform_devices,
81 ARRAY_SIZE(board_platform_devices));
82}
83
84arch_initcall(board_register_devices);
diff --git a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c
index 5446836869d6..24c652e8ec4b 100644
--- a/arch/mips/au1000/pb1500/board_setup.c
+++ b/arch/mips/au1000/pb1500/board_setup.c
@@ -23,19 +23,10 @@
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/delay.h> 28#include <linux/delay.h>
32 29
33#include <asm/cpu.h>
34#include <asm/bootinfo.h>
35#include <asm/irq.h>
36#include <asm/mipsregs.h>
37#include <asm/reboot.h>
38#include <asm/pgtable.h>
39#include <asm/mach-au1x00/au1000.h> 30#include <asm/mach-au1x00/au1000.h>
40#include <asm/mach-pb1x00/pb1500.h> 31#include <asm/mach-pb1x00/pb1500.h>
41 32
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index db558c967048..488507c07db9 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -27,14 +27,10 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33#include <linux/bootmem.h>
34#include <linux/string.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36 33
37#include <asm/addrspace.h>
38#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
39 35
40#include <prom.h> 36#include <prom.h>
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
index 810f695e24bb..4817ab44d07f 100644
--- a/arch/mips/au1000/pb1500/irqmap.c
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50char irq_tab_alchemy[][5] __initdata = { 33char irq_tab_alchemy[][5] __initdata = {
diff --git a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c
index e3cfb0d73180..45d60872b565 100644
--- a/arch/mips/au1000/pb1550/board_setup.c
+++ b/arch/mips/au1000/pb1550/board_setup.c
@@ -27,20 +27,9 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/sched.h>
32#include <linux/ioport.h>
33#include <linux/mm.h>
34#include <linux/console.h>
35#include <linux/mc146818rtc.h>
36#include <linux/delay.h>
37 32
38#include <asm/cpu.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/mipsregs.h>
42#include <asm/reboot.h>
43#include <asm/pgtable.h>
44#include <asm/mach-au1x00/au1000.h> 33#include <asm/mach-au1x00/au1000.h>
45#include <asm/mach-pb1x00/pb1550.h> 34#include <asm/mach-pb1x00/pb1550.h>
46 35
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index b716363ea564..f6b2fc587980 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -27,14 +27,10 @@
27 * with this program; if not, write to the Free Software Foundation, Inc., 27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 29 */
30
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33#include <linux/bootmem.h>
34#include <linux/string.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36 33
37#include <asm/addrspace.h>
38#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
39 35
40#include <prom.h> 36#include <prom.h>
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
index 56becab28e5d..e1dac37af08a 100644
--- a/arch/mips/au1000/pb1550/irqmap.c
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50char irq_tab_alchemy[][5] __initdata = { 33char irq_tab_alchemy[][5] __initdata = {
diff --git a/arch/mips/au1000/xxs1500/board_setup.c b/arch/mips/au1000/xxs1500/board_setup.c
index b2e413e597a8..79d1798621bf 100644
--- a/arch/mips/au1000/xxs1500/board_setup.c
+++ b/arch/mips/au1000/xxs1500/board_setup.c
@@ -23,19 +23,10 @@
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/delay.h> 28#include <linux/delay.h>
32 29
33#include <asm/cpu.h>
34#include <asm/bootinfo.h>
35#include <asm/irq.h>
36#include <asm/mipsregs.h>
37#include <asm/reboot.h>
38#include <asm/pgtable.h>
39#include <asm/mach-au1x00/au1000.h> 30#include <asm/mach-au1x00/au1000.h>
40 31
41void board_reset(void) 32void board_reset(void)
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 7e6878c1b0a5..24fc6e132dc0 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -26,14 +26,10 @@
26 * with this program; if not, write to the Free Software Foundation, Inc., 26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. 27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29
29#include <linux/init.h> 30#include <linux/init.h>
30#include <linux/mm.h>
31#include <linux/sched.h>
32#include <linux/bootmem.h>
33#include <linux/string.h>
34#include <linux/kernel.h> 31#include <linux/kernel.h>
35 32
36#include <asm/addrspace.h>
37#include <asm/bootinfo.h> 33#include <asm/bootinfo.h>
38 34
39#include <prom.h> 35#include <prom.h>
diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c
index a343da134334..dd6e3d1eb4d4 100644
--- a/arch/mips/au1000/xxs1500/irqmap.c
+++ b/arch/mips/au1000/xxs1500/irqmap.c
@@ -25,26 +25,9 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h> 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h> 31#include <asm/mach-au1x00/au1000.h>
49 32
50struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { 33struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 6db0bdaefb27..4f6bce99d5cf 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -641,7 +641,6 @@ CONFIG_CROSSCOMPILE=y
641CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp" 641CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
642# CONFIG_DEBUG_STACK_USAGE is not set 642# CONFIG_DEBUG_STACK_USAGE is not set
643# CONFIG_RUNTIME_DEBUG is not set 643# CONFIG_RUNTIME_DEBUG is not set
644# CONFIG_MIPS_UNCACHED is not set
645 644
646# 645#
647# Security options 646# Security options
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 518a60892b78..780c7fc24b82 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -1223,7 +1223,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
1223# CONFIG_KGDB is not set 1223# CONFIG_KGDB is not set
1224CONFIG_SYS_SUPPORTS_KGDB=y 1224CONFIG_SYS_SUPPORTS_KGDB=y
1225# CONFIG_RUNTIME_DEBUG is not set 1225# CONFIG_RUNTIME_DEBUG is not set
1226# CONFIG_MIPS_UNCACHED is not set
1227 1226
1228# 1227#
1229# Security options 1228# Security options
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index 68351eb81bc8..267f21ed1d0f 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -1213,7 +1213,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
1213# CONFIG_KGDB is not set 1213# CONFIG_KGDB is not set
1214CONFIG_SYS_SUPPORTS_KGDB=y 1214CONFIG_SYS_SUPPORTS_KGDB=y
1215# CONFIG_RUNTIME_DEBUG is not set 1215# CONFIG_RUNTIME_DEBUG is not set
1216# CONFIG_MIPS_UNCACHED is not set
1217 1216
1218# 1217#
1219# Security options 1218# Security options
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 60349062595a..3965fda94a89 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -9,30 +9,15 @@
9 * 9 *
10 */ 10 */
11#include <linux/bcd.h> 11#include <linux/bcd.h>
12#include <linux/errno.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/kernel.h>
16#include <linux/mc146818rtc.h> 13#include <linux/mc146818rtc.h>
17#include <linux/mm.h>
18#include <linux/module.h>
19#include <linux/param.h> 14#include <linux/param.h>
20#include <linux/sched.h>
21#include <linux/string.h>
22#include <linux/time.h>
23#include <linux/types.h>
24
25#include <asm/bootinfo.h>
26#include <asm/cpu.h>
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mipsregs.h>
30#include <asm/sections.h>
31#include <asm/time.h>
32 15
16#include <asm/cpu-features.h>
17#include <asm/ds1287.h>
18#include <asm/time.h>
33#include <asm/dec/interrupts.h> 19#include <asm/dec/interrupts.h>
34#include <asm/dec/ioasic.h> 20#include <asm/dec/ioasic.h>
35#include <asm/dec/ioasic_addrs.h>
36#include <asm/dec/machtype.h> 21#include <asm/dec/machtype.h>
37 22
38unsigned long read_persistent_clock(void) 23unsigned long read_persistent_clock(void)
@@ -139,42 +124,32 @@ int rtc_mips_set_mmss(unsigned long nowtime)
139 return retval; 124 return retval;
140} 125}
141 126
142static int dec_timer_state(void) 127void __init plat_time_init(void)
143{ 128{
144 return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0; 129 u32 start, end;
145} 130 int i = HZ / 10;
146 131
147static void dec_timer_ack(void) 132 /* Set up the rate of periodic DS1287 interrupts. */
148{ 133 ds1287_set_base_clock(HZ);
149 CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */
150}
151
152static cycle_t dec_ioasic_hpt_read(void)
153{
154 /*
155 * The free-running counter is 32-bit which is good for about
156 * 2 minutes, 50 seconds at possible count rates of up to 25MHz.
157 */
158 return ioasic_read(IO_REG_FCTR);
159}
160 134
135 if (cpu_has_counter) {
136 while (!ds1287_timer_state())
137 ;
161 138
162void __init plat_time_init(void) 139 start = read_c0_count();
163{
164 mips_timer_ack = dec_timer_ack;
165 140
166 if (!cpu_has_counter && IOASIC) 141 while (i--)
167 /* For pre-R4k systems we use the I/O ASIC's counter. */ 142 while (!ds1287_timer_state())
168 clocksource_mips.read = dec_ioasic_hpt_read; 143 ;
169 144
170 /* Set up the rate of periodic DS1287 interrupts. */ 145 end = read_c0_count();
171 CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
172}
173 146
174void __init plat_timer_setup(struct irqaction *irq) 147 mips_hpt_frequency = (end - start) * 10;
175{ 148 printk(KERN_INFO "MIPS counter frequency %dHz\n",
176 setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); 149 mips_hpt_frequency);
150 } else if (IOASIC)
151 /* For pre-R4k systems we use the I/O ASIC's counter. */
152 dec_ioasic_clocksource_init();
177 153
178 /* Enable periodic DS1287 interrupts. */ 154 ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]);
179 CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
180} 155}
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index c886d804d303..f39c444e42d4 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -36,11 +36,13 @@
36#include <linux/pm.h> 36#include <linux/pm.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/clk.h> 38#include <linux/clk.h>
39#include <linux/gpio.h>
39#ifdef CONFIG_SERIAL_TXX9 40#ifdef CONFIG_SERIAL_TXX9
40#include <linux/serial_core.h> 41#include <linux/serial_core.h>
41#endif 42#endif
42 43
43#include <asm/txx9tmr.h> 44#include <asm/txx9tmr.h>
45#include <asm/txx9pio.h>
44#include <asm/reboot.h> 46#include <asm/reboot.h>
45#include <asm/jmr3927/jmr3927.h> 47#include <asm/jmr3927/jmr3927.h>
46#include <asm/mipsregs.h> 48#include <asm/mipsregs.h>
@@ -340,9 +342,12 @@ static void __init tx3927_setup(void)
340 342
341 /* PIO */ 343 /* PIO */
342 /* PIO[15:12] connected to LEDs */ 344 /* PIO[15:12] connected to LEDs */
343 tx3927_pioptr->dir = 0x0000f000; 345 __raw_writel(0x0000f000, &tx3927_pioptr->dir);
344 tx3927_pioptr->maskcpu = 0; 346 __raw_writel(0, &tx3927_pioptr->maskcpu);
345 tx3927_pioptr->maskext = 0; 347 __raw_writel(0, &tx3927_pioptr->maskext);
348 txx9_gpio_init(TX3927_PIO_REG, 0, 16);
349 gpio_request(11, "dipsw1");
350 gpio_request(10, "dipsw2");
346 { 351 {
347 unsigned int conf; 352 unsigned int conf;
348 353
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 6fcdb6fda2e2..45545be3eb86 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -10,12 +10,15 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
10 10
11obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 11obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
12obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 12obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
13obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
13obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 14obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
14obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o 15obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
15obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o 16obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
16obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o 17obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
18obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
17obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o 19obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
18obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o 20obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
21obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
19 22
20binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ 23binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
21 irix5sys.o sysirix.o 24 irix5sys.o sysirix.o
@@ -50,6 +53,8 @@ obj-$(CONFIG_MIPS_MT) += mips-mt.o
50obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o 53obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
51obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o 54obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
52obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o 55obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
56obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
57obj-$(CONFIG_CPU_MIPSR2) += spram.o
53 58
54obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o 59obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
55obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o 60obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
@@ -62,6 +67,7 @@ obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
62obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o 67obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
63obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o 68obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
64obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o 69obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o
70obj-$(CONFIG_IRQ_GIC) += irq-gic.o
65 71
66obj-$(CONFIG_32BIT) += scall32-o32.o 72obj-$(CONFIG_32BIT) += scall32-o32.o
67obj-$(CONFIG_64BIT) += scall64-64.o 73obj-$(CONFIG_64BIT) += scall64-64.o
@@ -77,6 +83,8 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o
77 83
78obj-$(CONFIG_I8253) += i8253.o 84obj-$(CONFIG_I8253) += i8253.o
79 85
86obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
87
80obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 88obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
81obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 89obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
82 90
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
new file mode 100644
index 000000000000..df4acb68bfb5
--- /dev/null
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -0,0 +1,129 @@
1/*
2 * DS1287 clockevent driver
3 *
4 * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/clockchips.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/mc146818rtc.h>
24
25#include <asm/time.h>
26
27int ds1287_timer_state(void)
28{
29 return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
30}
31
32int ds1287_set_base_clock(unsigned int hz)
33{
34 u8 rate;
35
36 switch (hz) {
37 case 128:
38 rate = 0x9;
39 break;
40 case 256:
41 rate = 0x8;
42 break;
43 case 1024:
44 rate = 0x6;
45 break;
46 default:
47 return -EINVAL;
48 }
49
50 CMOS_WRITE(RTC_REF_CLCK_32KHZ | rate, RTC_REG_A);
51
52 return 0;
53}
54
55static int ds1287_set_next_event(unsigned long delta,
56 struct clock_event_device *evt)
57{
58 return -EINVAL;
59}
60
61static void ds1287_set_mode(enum clock_event_mode mode,
62 struct clock_event_device *evt)
63{
64 u8 val;
65
66 spin_lock(&rtc_lock);
67
68 val = CMOS_READ(RTC_REG_B);
69
70 switch (mode) {
71 case CLOCK_EVT_MODE_PERIODIC:
72 val |= RTC_PIE;
73 break;
74 default:
75 val &= ~RTC_PIE;
76 break;
77 }
78
79 CMOS_WRITE(val, RTC_REG_B);
80
81 spin_unlock(&rtc_lock);
82}
83
84static void ds1287_event_handler(struct clock_event_device *dev)
85{
86}
87
88static struct clock_event_device ds1287_clockevent = {
89 .name = "ds1287",
90 .features = CLOCK_EVT_FEAT_PERIODIC,
91 .cpumask = CPU_MASK_CPU0,
92 .set_next_event = ds1287_set_next_event,
93 .set_mode = ds1287_set_mode,
94 .event_handler = ds1287_event_handler,
95};
96
97static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
98{
99 struct clock_event_device *cd = &ds1287_clockevent;
100
101 /* Ack the RTC interrupt. */
102 CMOS_READ(RTC_REG_C);
103
104 cd->event_handler(cd);
105
106 return IRQ_HANDLED;
107}
108
109static struct irqaction ds1287_irqaction = {
110 .handler = ds1287_interrupt,
111 .flags = IRQF_DISABLED | IRQF_PERCPU,
112 .name = "ds1287",
113};
114
115int __init ds1287_clockevent_init(int irq)
116{
117 struct clock_event_device *cd;
118
119 cd = &ds1287_clockevent;
120 cd->rating = 100;
121 cd->irq = irq;
122 clockevent_set_clock(cd, 32768);
123 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
124 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
125
126 clockevents_register_device(&ds1287_clockevent);
127
128 return setup_irq(irq, &ds1287_irqaction);
129}
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index c36772631fe0..6e2f58520afb 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -25,8 +25,6 @@
25#include <asm/gt64120.h> 25#include <asm/gt64120.h>
26#include <asm/time.h> 26#include <asm/time.h>
27 27
28#include <irq.h>
29
30static DEFINE_SPINLOCK(gt641xx_timer_lock); 28static DEFINE_SPINLOCK(gt641xx_timer_lock);
31static unsigned int gt641xx_base_clock; 29static unsigned int gt641xx_base_clock;
32 30
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 89c3304cb93c..335a6ae3d594 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -169,6 +169,7 @@ static inline void check_wait(void)
169 169
170 case CPU_24K: 170 case CPU_24K:
171 case CPU_34K: 171 case CPU_34K:
172 case CPU_1004K:
172 cpu_wait = r4k_wait; 173 cpu_wait = r4k_wait;
173 if (read_c0_config7() & MIPS_CONF7_WII) 174 if (read_c0_config7() & MIPS_CONF7_WII)
174 cpu_wait = r4k_wait_irqoff; 175 cpu_wait = r4k_wait_irqoff;
@@ -675,6 +676,12 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
675 return; 676 return;
676} 677}
677 678
679#ifdef CONFIG_CPU_MIPSR2
680extern void spram_config(void);
681#else
682static inline void spram_config(void) {}
683#endif
684
678static inline void cpu_probe_mips(struct cpuinfo_mips *c) 685static inline void cpu_probe_mips(struct cpuinfo_mips *c)
679{ 686{
680 decode_configs(c); 687 decode_configs(c);
@@ -711,7 +718,12 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
711 case PRID_IMP_74K: 718 case PRID_IMP_74K:
712 c->cputype = CPU_74K; 719 c->cputype = CPU_74K;
713 break; 720 break;
721 case PRID_IMP_1004K:
722 c->cputype = CPU_1004K;
723 break;
714 } 724 }
725
726 spram_config();
715} 727}
716 728
717static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) 729static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
@@ -778,7 +790,7 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
778 } 790 }
779} 791}
780 792
781static inline void cpu_probe_philips(struct cpuinfo_mips *c) 793static inline void cpu_probe_nxp(struct cpuinfo_mips *c)
782{ 794{
783 decode_configs(c); 795 decode_configs(c);
784 switch (c->processor_id & 0xff00) { 796 switch (c->processor_id & 0xff00) {
@@ -787,7 +799,7 @@ static inline void cpu_probe_philips(struct cpuinfo_mips *c)
787 c->isa_level = MIPS_CPU_ISA_M32R1; 799 c->isa_level = MIPS_CPU_ISA_M32R1;
788 break; 800 break;
789 default: 801 default:
790 panic("Unknown Philips Core!"); /* REVISIT: die? */ 802 panic("Unknown NXP Core!"); /* REVISIT: die? */
791 break; 803 break;
792 } 804 }
793} 805}
@@ -876,6 +888,7 @@ static __cpuinit const char *cpu_to_name(struct cpuinfo_mips *c)
876 case CPU_24K: name = "MIPS 24K"; break; 888 case CPU_24K: name = "MIPS 24K"; break;
877 case CPU_25KF: name = "MIPS 25Kf"; break; 889 case CPU_25KF: name = "MIPS 25Kf"; break;
878 case CPU_34K: name = "MIPS 34K"; break; 890 case CPU_34K: name = "MIPS 34K"; break;
891 case CPU_1004K: name = "MIPS 1004K"; break;
879 case CPU_74K: name = "MIPS 74K"; break; 892 case CPU_74K: name = "MIPS 74K"; break;
880 case CPU_VR4111: name = "NEC VR4111"; break; 893 case CPU_VR4111: name = "NEC VR4111"; break;
881 case CPU_VR4121: name = "NEC VR4121"; break; 894 case CPU_VR4121: name = "NEC VR4121"; break;
@@ -925,8 +938,8 @@ __cpuinit void cpu_probe(void)
925 case PRID_COMP_SANDCRAFT: 938 case PRID_COMP_SANDCRAFT:
926 cpu_probe_sandcraft(c); 939 cpu_probe_sandcraft(c);
927 break; 940 break;
928 case PRID_COMP_PHILIPS: 941 case PRID_COMP_NXP:
929 cpu_probe_philips(c); 942 cpu_probe_nxp(c);
930 break; 943 break;
931 default: 944 default:
932 c->cputype = CPU_UNKNOWN; 945 c->cputype = CPU_UNKNOWN;
diff --git a/arch/mips/kernel/csrc-ioasic.c b/arch/mips/kernel/csrc-ioasic.c
new file mode 100644
index 000000000000..1d5f63cf8997
--- /dev/null
+++ b/arch/mips/kernel/csrc-ioasic.c
@@ -0,0 +1,65 @@
1/*
2 * DEC I/O ASIC's counter clocksource
3 *
4 * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/clocksource.h>
21#include <linux/init.h>
22
23#include <asm/ds1287.h>
24#include <asm/time.h>
25#include <asm/dec/ioasic.h>
26#include <asm/dec/ioasic_addrs.h>
27
28static cycle_t dec_ioasic_hpt_read(void)
29{
30 return ioasic_read(IO_REG_FCTR);
31}
32
33static struct clocksource clocksource_dec = {
34 .name = "dec-ioasic",
35 .read = dec_ioasic_hpt_read,
36 .mask = CLOCKSOURCE_MASK(32),
37 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
38};
39
40void __init dec_ioasic_clocksource_init(void)
41{
42 unsigned int freq;
43 u32 start, end;
44 int i = HZ / 10;
45
46
47 while (!ds1287_timer_state())
48 ;
49
50 start = dec_ioasic_hpt_read();
51
52 while (i--)
53 while (!ds1287_timer_state())
54 ;
55
56 end = dec_ioasic_hpt_read();
57
58 freq = (end - start) * 10;
59 printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
60
61 clocksource_dec.rating = 200 + freq / 10000000;
62 clocksource_set_clock(&clocksource_dec, freq);
63
64 clocksource_register(&clocksource_dec);
65}
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c
new file mode 100644
index 000000000000..b1436a857998
--- /dev/null
+++ b/arch/mips/kernel/gpio_txx9.c
@@ -0,0 +1,87 @@
1/*
2 * A gpio chip driver for TXx9 SoCs
3 *
4 * Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/spinlock.h>
13#include <linux/gpio.h>
14#include <linux/errno.h>
15#include <linux/io.h>
16#include <asm/txx9pio.h>
17
18static DEFINE_SPINLOCK(txx9_gpio_lock);
19
20static struct txx9_pio_reg __iomem *txx9_pioptr;
21
22static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
23{
24 return __raw_readl(&txx9_pioptr->din) & (1 << offset);
25}
26
27static void txx9_gpio_set_raw(unsigned int offset, int value)
28{
29 u32 val;
30 val = __raw_readl(&txx9_pioptr->dout);
31 if (value)
32 val |= 1 << offset;
33 else
34 val &= ~(1 << offset);
35 __raw_writel(val, &txx9_pioptr->dout);
36}
37
38static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
39 int value)
40{
41 unsigned long flags;
42 spin_lock_irqsave(&txx9_gpio_lock, flags);
43 txx9_gpio_set_raw(offset, value);
44 mmiowb();
45 spin_unlock_irqrestore(&txx9_gpio_lock, flags);
46}
47
48static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
49{
50 spin_lock_irq(&txx9_gpio_lock);
51 __raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
52 &txx9_pioptr->dir);
53 mmiowb();
54 spin_unlock_irq(&txx9_gpio_lock);
55 return 0;
56}
57
58static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
59 int value)
60{
61 spin_lock_irq(&txx9_gpio_lock);
62 txx9_gpio_set_raw(offset, value);
63 __raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
64 &txx9_pioptr->dir);
65 mmiowb();
66 spin_unlock_irq(&txx9_gpio_lock);
67 return 0;
68}
69
70static struct gpio_chip txx9_gpio_chip = {
71 .get = txx9_gpio_get,
72 .set = txx9_gpio_set,
73 .direction_input = txx9_gpio_dir_in,
74 .direction_output = txx9_gpio_dir_out,
75 .label = "TXx9",
76};
77
78int __init txx9_gpio_init(unsigned long baseaddr,
79 unsigned int base, unsigned int num)
80{
81 txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
82 if (!txx9_pioptr)
83 return -ENODEV;
84 txx9_gpio_chip.base = base;
85 txx9_gpio_chip.ngpio = num;
86 return gpiochip_add(&txx9_gpio_chip);
87}
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
new file mode 100644
index 000000000000..f0a4bb19e096
--- /dev/null
+++ b/arch/mips/kernel/irq-gic.c
@@ -0,0 +1,295 @@
1#undef DEBUG
2
3#include <linux/bitmap.h>
4#include <linux/init.h>
5
6#include <asm/io.h>
7#include <asm/gic.h>
8#include <asm/gcmpregs.h>
9#include <asm/mips-boards/maltaint.h>
10#include <asm/irq.h>
11#include <linux/hardirq.h>
12#include <asm-generic/bitops/find.h>
13
14
15static unsigned long _gic_base;
16static unsigned int _irqbase, _mapsize, numvpes, numintrs;
17static struct gic_intr_map *_intrmap;
18
19static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
20static struct gic_pending_regs pending_regs[NR_CPUS];
21static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
22
23#define gic_wedgeb2bok 0 /*
24 * Can GIC handle b2b writes to wedge register?
25 */
26#if gic_wedgeb2bok == 0
27static DEFINE_SPINLOCK(gic_wedgeb2b_lock);
28#endif
29
30void gic_send_ipi(unsigned int intr)
31{
32#if gic_wedgeb2bok == 0
33 unsigned long flags;
34#endif
35 pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
36 read_c0_status());
37 if (!gic_wedgeb2bok)
38 spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
39 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
40 if (!gic_wedgeb2bok) {
41 (void) GIC_REG(SHARED, GIC_SH_CONFIG);
42 spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
43 }
44}
45
46/* This is Malta specific and needs to be exported */
47static void vpe_local_setup(unsigned int numvpes)
48{
49 int i;
50 unsigned long timer_interrupt = 5, perf_interrupt = 5;
51 unsigned int vpe_ctl;
52
53 /*
54 * Setup the default performance counter timer interrupts
55 * for all VPEs
56 */
57 for (i = 0; i < numvpes; i++) {
58 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
59
60 /* Are Interrupts locally routable? */
61 GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
62 if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
63 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
64 GIC_MAP_TO_PIN_MSK | timer_interrupt);
65
66 if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
67 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
68 GIC_MAP_TO_PIN_MSK | perf_interrupt);
69 }
70}
71
72unsigned int gic_get_int(void)
73{
74 unsigned int i;
75 unsigned long *pending, *intrmask, *pcpu_mask;
76 unsigned long *pending_abs, *intrmask_abs;
77
78 /* Get per-cpu bitmaps */
79 pending = pending_regs[smp_processor_id()].pending;
80 intrmask = intrmask_regs[smp_processor_id()].intrmask;
81 pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
82
83 pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
84 GIC_SH_PEND_31_0_OFS);
85 intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
86 GIC_SH_MASK_31_0_OFS);
87
88 for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) {
89 GICREAD(*pending_abs, pending[i]);
90 GICREAD(*intrmask_abs, intrmask[i]);
91 pending_abs++;
92 intrmask_abs++;
93 }
94
95 bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
96 bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
97
98 i = find_first_bit(pending, GIC_NUM_INTRS);
99
100 pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i);
101
102 return i;
103}
104
105static unsigned int gic_irq_startup(unsigned int irq)
106{
107 pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
108 irq -= _irqbase;
109 /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
110 GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
111 1 << (irq % 32));
112 return 0;
113}
114
115static void gic_irq_ack(unsigned int irq)
116{
117#if gic_wedgeb2bok == 0
118 unsigned long flags;
119#endif
120 pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
121 irq -= _irqbase;
122 GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
123 1 << (irq % 32));
124
125 if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) {
126 if (!gic_wedgeb2bok)
127 spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
128 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
129 if (!gic_wedgeb2bok) {
130 (void) GIC_REG(SHARED, GIC_SH_CONFIG);
131 spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
132 }
133 }
134}
135
136static void gic_mask_irq(unsigned int irq)
137{
138 pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
139 irq -= _irqbase;
140 /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
141 GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
142 1 << (irq % 32));
143}
144
145static void gic_unmask_irq(unsigned int irq)
146{
147 pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
148 irq -= _irqbase;
149 /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
150 GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
151 1 << (irq % 32));
152}
153
154#ifdef CONFIG_SMP
155
156static DEFINE_SPINLOCK(gic_lock);
157
158static void gic_set_affinity(unsigned int irq, cpumask_t cpumask)
159{
160 cpumask_t tmp = CPU_MASK_NONE;
161 unsigned long flags;
162 int i;
163
164 pr_debug(KERN_DEBUG "%s called\n", __func__);
165 irq -= _irqbase;
166
167 cpus_and(tmp, cpumask, cpu_online_map);
168 if (cpus_empty(tmp))
169 return;
170
171 /* Assumption : cpumask refers to a single CPU */
172 spin_lock_irqsave(&gic_lock, flags);
173 for (;;) {
174 /* Re-route this IRQ */
175 GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
176
177 /*
178 * FIXME: assumption that _intrmap is ordered and has no holes
179 */
180
181 /* Update the intr_map */
182 _intrmap[irq].cpunum = first_cpu(tmp);
183
184 /* Update the pcpu_masks */
185 for (i = 0; i < NR_CPUS; i++)
186 clear_bit(irq, pcpu_masks[i].pcpu_mask);
187 set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
188
189 }
190 irq_desc[irq].affinity = cpumask;
191 spin_unlock_irqrestore(&gic_lock, flags);
192
193}
194#endif
195
196static struct irq_chip gic_irq_controller = {
197 .name = "MIPS GIC",
198 .startup = gic_irq_startup,
199 .ack = gic_irq_ack,
200 .mask = gic_mask_irq,
201 .mask_ack = gic_mask_irq,
202 .unmask = gic_unmask_irq,
203 .eoi = gic_unmask_irq,
204#ifdef CONFIG_SMP
205 .set_affinity = gic_set_affinity,
206#endif
207};
208
209static void __init setup_intr(unsigned int intr, unsigned int cpu,
210 unsigned int pin, unsigned int polarity, unsigned int trigtype)
211{
212 /* Setup Intr to Pin mapping */
213 if (pin & GIC_MAP_TO_NMI_MSK) {
214 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
215 /* FIXME: hack to route NMI to all cpu's */
216 for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
217 GICWRITE(GIC_REG_ADDR(SHARED,
218 GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
219 0xffffffff);
220 }
221 } else {
222 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
223 GIC_MAP_TO_PIN_MSK | pin);
224 /* Setup Intr to CPU mapping */
225 GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
226 }
227
228 /* Setup Intr Polarity */
229 GIC_SET_POLARITY(intr, polarity);
230
231 /* Setup Intr Trigger Type */
232 GIC_SET_TRIGGER(intr, trigtype);
233
234 /* Init Intr Masks */
235 GIC_SET_INTR_MASK(intr, 0);
236}
237
238static void __init gic_basic_init(void)
239{
240 unsigned int i, cpu;
241
242 /* Setup defaults */
243 for (i = 0; i < GIC_NUM_INTRS; i++) {
244 GIC_SET_POLARITY(i, GIC_POL_POS);
245 GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
246 GIC_SET_INTR_MASK(i, 0);
247 }
248
249 /* Setup specifics */
250 for (i = 0; i < _mapsize; i++) {
251 cpu = _intrmap[i].cpunum;
252 if (cpu == X)
253 continue;
254
255 setup_intr(_intrmap[i].intrnum,
256 _intrmap[i].cpunum,
257 _intrmap[i].pin,
258 _intrmap[i].polarity,
259 _intrmap[i].trigtype);
260 /* Initialise per-cpu Interrupt software masks */
261 if (_intrmap[i].ipiflag)
262 set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask);
263 }
264
265 vpe_local_setup(numvpes);
266
267 for (i = _irqbase; i < (_irqbase + numintrs); i++)
268 set_irq_chip(i, &gic_irq_controller);
269}
270
271void __init gic_init(unsigned long gic_base_addr,
272 unsigned long gic_addrspace_size,
273 struct gic_intr_map *intr_map, unsigned int intr_map_size,
274 unsigned int irqbase)
275{
276 unsigned int gicconfig;
277
278 _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
279 gic_addrspace_size);
280 _irqbase = irqbase;
281 _intrmap = intr_map;
282 _mapsize = intr_map_size;
283
284 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
285 numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
286 GIC_SH_CONFIG_NUMINTRS_SHF;
287 numintrs = ((numintrs + 1) * 8);
288
289 numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
290 GIC_SH_CONFIG_NUMVPES_SHF;
291
292 pr_debug("%s called\n", __func__);
293
294 gic_basic_init();
295}
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 4edc7e451d91..963c16d266ab 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -17,6 +17,7 @@
17#include <asm/io.h> 17#include <asm/io.h>
18#include <asm/irq.h> 18#include <asm/irq.h>
19#include <asm/msc01_ic.h> 19#include <asm/msc01_ic.h>
20#include <asm/traps.h>
20 21
21static unsigned long _icctrl_msc; 22static unsigned long _icctrl_msc;
22#define MSC01_IC_REG_BASE _icctrl_msc 23#define MSC01_IC_REG_BASE _icctrl_msc
@@ -98,14 +99,13 @@ void ll_msc_irq(void)
98 } 99 }
99} 100}
100 101
101void 102static void msc_bind_eic_interrupt(int irq, int set)
102msc_bind_eic_interrupt(unsigned int irq, unsigned int set)
103{ 103{
104 MSCIC_WRITE(MSC01_IC_RAMW, 104 MSCIC_WRITE(MSC01_IC_RAMW,
105 (irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF)); 105 (irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF));
106} 106}
107 107
108struct irq_chip msc_levelirq_type = { 108static struct irq_chip msc_levelirq_type = {
109 .name = "SOC-it-Level", 109 .name = "SOC-it-Level",
110 .ack = level_mask_and_ack_msc_irq, 110 .ack = level_mask_and_ack_msc_irq,
111 .mask = mask_msc_irq, 111 .mask = mask_msc_irq,
@@ -115,7 +115,7 @@ struct irq_chip msc_levelirq_type = {
115 .end = end_msc_irq, 115 .end = end_msc_irq,
116}; 116};
117 117
118struct irq_chip msc_edgeirq_type = { 118static struct irq_chip msc_edgeirq_type = {
119 .name = "SOC-it-Edge", 119 .name = "SOC-it-Edge",
120 .ack = edge_mask_and_ack_msc_irq, 120 .ack = edge_mask_and_ack_msc_irq,
121 .mask = mask_msc_irq, 121 .mask = mask_msc_irq,
@@ -128,8 +128,6 @@ struct irq_chip msc_edgeirq_type = {
128 128
129void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq) 129void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq)
130{ 130{
131 extern void (*board_bind_eic_interrupt)(unsigned int irq, unsigned int regset);
132
133 _icctrl_msc = (unsigned long) ioremap(icubase, 0x40000); 131 _icctrl_msc = (unsigned long) ioremap(icubase, 0x40000);
134 132
135 /* Reset interrupt controller - initialises all registers to 0 */ 133 /* Reset interrupt controller - initialises all registers to 0 */
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index c0faabd52010..6c8e8c4246f7 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -14,7 +14,7 @@
14/* #define DEBUG_SIG */ 14/* #define DEBUG_SIG */
15 15
16#ifdef DEBUG_SIG 16#ifdef DEBUG_SIG
17# define DEBUGP(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args) 17# define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args)
18#else 18#else
19# define DEBUGP(fmt, args...) 19# define DEBUGP(fmt, args...)
20#endif 20#endif
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
new file mode 100644
index 000000000000..ca476c4f62a5
--- /dev/null
+++ b/arch/mips/kernel/smp-cmp.c
@@ -0,0 +1,265 @@
1/*
2 * This program is free software; you can distribute it and/or modify it
3 * under the terms of the GNU General Public License (Version 2) as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
14 *
15 * Copyright (C) 2007 MIPS Technologies, Inc.
16 * Chris Dearman (chris@mips.com)
17 */
18
19#undef DEBUG
20
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/cpumask.h>
24#include <linux/interrupt.h>
25#include <linux/compiler.h>
26
27#include <asm/atomic.h>
28#include <asm/cacheflush.h>
29#include <asm/cpu.h>
30#include <asm/processor.h>
31#include <asm/system.h>
32#include <asm/hardirq.h>
33#include <asm/mmu_context.h>
34#include <asm/smp.h>
35#include <asm/time.h>
36#include <asm/mipsregs.h>
37#include <asm/mipsmtregs.h>
38#include <asm/mips_mt.h>
39
40/*
41 * Crude manipulation of the CPU masks to control which
42 * which CPU's are brought online during initialisation
43 *
44 * Beware... this needs to be called after CPU discovery
45 * but before CPU bringup
46 */
47static int __init allowcpus(char *str)
48{
49 cpumask_t cpu_allow_map;
50 char buf[256];
51 int len;
52
53 cpus_clear(cpu_allow_map);
54 if (cpulist_parse(str, cpu_allow_map) == 0) {
55 cpu_set(0, cpu_allow_map);
56 cpus_and(cpu_possible_map, cpu_possible_map, cpu_allow_map);
57 len = cpulist_scnprintf(buf, sizeof(buf)-1, cpu_possible_map);
58 buf[len] = '\0';
59 pr_debug("Allowable CPUs: %s\n", buf);
60 return 1;
61 } else
62 return 0;
63}
64__setup("allowcpus=", allowcpus);
65
66static void ipi_call_function(unsigned int cpu)
67{
68 unsigned int action = 0;
69
70 pr_debug("CPU%d: %s cpu %d status %08x\n",
71 smp_processor_id(), __func__, cpu, read_c0_status());
72
73 switch (cpu) {
74 case 0:
75 action = GIC_IPI_EXT_INTR_CALLFNC_VPE0;
76 break;
77 case 1:
78 action = GIC_IPI_EXT_INTR_CALLFNC_VPE1;
79 break;
80 case 2:
81 action = GIC_IPI_EXT_INTR_CALLFNC_VPE2;
82 break;
83 case 3:
84 action = GIC_IPI_EXT_INTR_CALLFNC_VPE3;
85 break;
86 }
87 gic_send_ipi(action);
88}
89
90
91static void ipi_resched(unsigned int cpu)
92{
93 unsigned int action = 0;
94
95 pr_debug("CPU%d: %s cpu %d status %08x\n",
96 smp_processor_id(), __func__, cpu, read_c0_status());
97
98 switch (cpu) {
99 case 0:
100 action = GIC_IPI_EXT_INTR_RESCHED_VPE0;
101 break;
102 case 1:
103 action = GIC_IPI_EXT_INTR_RESCHED_VPE1;
104 break;
105 case 2:
106 action = GIC_IPI_EXT_INTR_RESCHED_VPE2;
107 break;
108 case 3:
109 action = GIC_IPI_EXT_INTR_RESCHED_VPE3;
110 break;
111 }
112 gic_send_ipi(action);
113}
114
115/*
116 * FIXME: This isn't restricted to CMP
117 * The SMVP kernel could use GIC interrupts if available
118 */
119void cmp_send_ipi_single(int cpu, unsigned int action)
120{
121 unsigned long flags;
122
123 local_irq_save(flags);
124
125 switch (action) {
126 case SMP_CALL_FUNCTION:
127 ipi_call_function(cpu);
128 break;
129
130 case SMP_RESCHEDULE_YOURSELF:
131 ipi_resched(cpu);
132 break;
133 }
134
135 local_irq_restore(flags);
136}
137
138static void cmp_send_ipi_mask(cpumask_t mask, unsigned int action)
139{
140 unsigned int i;
141
142 for_each_cpu_mask(i, mask)
143 cmp_send_ipi_single(i, action);
144}
145
146static void cmp_init_secondary(void)
147{
148 struct cpuinfo_mips *c = &current_cpu_data;
149
150 /* Assume GIC is present */
151 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP6 |
152 STATUSF_IP7);
153
154 /* Enable per-cpu interrupts: platform specific */
155
156 c->core = (read_c0_ebase() >> 1) & 0xff;
157#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
158 c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
159#endif
160#ifdef CONFIG_MIPS_MT_SMTC
161 c->tc_id = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
162#endif
163}
164
165static void cmp_smp_finish(void)
166{
167 pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
168
169 /* CDFIXME: remove this? */
170 write_c0_compare(read_c0_count() + (8 * mips_hpt_frequency / HZ));
171
172#ifdef CONFIG_MIPS_MT_FPAFF
173 /* If we have an FPU, enroll ourselves in the FPU-full mask */
174 if (cpu_has_fpu)
175 cpu_set(smp_processor_id(), mt_fpu_cpumask);
176#endif /* CONFIG_MIPS_MT_FPAFF */
177
178 local_irq_enable();
179}
180
181static void cmp_cpus_done(void)
182{
183 pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
184}
185
186/*
187 * Setup the PC, SP, and GP of a secondary processor and start it running
188 * smp_bootstrap is the place to resume from
189 * __KSTK_TOS(idle) is apparently the stack pointer
190 * (unsigned long)idle->thread_info the gp
191 */
192static void cmp_boot_secondary(int cpu, struct task_struct *idle)
193{
194 struct thread_info *gp = task_thread_info(idle);
195 unsigned long sp = __KSTK_TOS(idle);
196 unsigned long pc = (unsigned long)&smp_bootstrap;
197 unsigned long a0 = 0;
198
199 pr_debug("SMPCMP: CPU%d: %s cpu %d\n", smp_processor_id(),
200 __func__, cpu);
201
202#if 0
203 /* Needed? */
204 flush_icache_range((unsigned long)gp,
205 (unsigned long)(gp + sizeof(struct thread_info)));
206#endif
207
208 amon_cpu_start(cpu, pc, sp, gp, a0);
209}
210
211/*
212 * Common setup before any secondaries are started
213 */
214void __init cmp_smp_setup(void)
215{
216 int i;
217 int ncpu = 0;
218
219 pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
220
221#ifdef CONFIG_MIPS_MT_FPAFF
222 /* If we have an FPU, enroll ourselves in the FPU-full mask */
223 if (cpu_has_fpu)
224 cpu_set(0, mt_fpu_cpumask);
225#endif /* CONFIG_MIPS_MT_FPAFF */
226
227 for (i = 1; i < NR_CPUS; i++) {
228 if (amon_cpu_avail(i)) {
229 cpu_set(i, phys_cpu_present_map);
230 __cpu_number_map[i] = ++ncpu;
231 __cpu_logical_map[ncpu] = i;
232 }
233 }
234
235 if (cpu_has_mipsmt) {
236 unsigned int nvpe, mvpconf0 = read_c0_mvpconf0();
237
238 nvpe = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
239 smp_num_siblings = nvpe;
240 }
241 pr_info("Detected %i available secondary CPU(s)\n", ncpu);
242}
243
244void __init cmp_prepare_cpus(unsigned int max_cpus)
245{
246 pr_debug("SMPCMP: CPU%d: %s max_cpus=%d\n",
247 smp_processor_id(), __func__, max_cpus);
248
249 /*
250 * FIXME: some of these options are per-system, some per-core and
251 * some per-cpu
252 */
253 mips_mt_set_cpuoptions();
254}
255
256struct plat_smp_ops cmp_smp_ops = {
257 .send_ipi_single = cmp_send_ipi_single,
258 .send_ipi_mask = cmp_send_ipi_mask,
259 .init_secondary = cmp_init_secondary,
260 .smp_finish = cmp_smp_finish,
261 .cpus_done = cmp_cpus_done,
262 .boot_secondary = cmp_boot_secondary,
263 .smp_setup = cmp_smp_setup,
264 .prepare_cpus = cmp_prepare_cpus,
265};
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 89e6f6aa5166..87a1816c1f45 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -36,110 +36,7 @@
36#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
37#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
38 38
39#define MIPS_CPU_IPI_RESCHED_IRQ 0 39static void __init smvp_copy_vpe_config(void)
40#define MIPS_CPU_IPI_CALL_IRQ 1
41
42static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
43
44#if 0
45static void dump_mtregisters(int vpe, int tc)
46{
47 printk("vpe %d tc %d\n", vpe, tc);
48
49 settc(tc);
50
51 printk(" c0 status 0x%lx\n", read_vpe_c0_status());
52 printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
53 printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
54 printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
55 printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
56 printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
57 printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
58}
59#endif
60
61void __init sanitize_tlb_entries(void)
62{
63 int i, tlbsiz;
64 unsigned long mvpconf0, ncpu;
65
66 if (!cpu_has_mipsmt)
67 return;
68
69 /* Enable VPC */
70 set_c0_mvpcontrol(MVPCONTROL_VPC);
71
72 back_to_back_c0_hazard();
73
74 /* Disable TLB sharing */
75 clear_c0_mvpcontrol(MVPCONTROL_STLB);
76
77 mvpconf0 = read_c0_mvpconf0();
78
79 printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
80 (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
81 (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
82
83 tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
84 ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
85
86 printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
87
88 if (tlbsiz > 0) {
89 /* share them out across the vpe's */
90 tlbsiz /= ncpu;
91
92 printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
93
94 for (i = 0; i < ncpu; i++) {
95 settc(i);
96
97 if (i == 0)
98 write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
99 else
100 write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
101 (tlbsiz << 25));
102 }
103 }
104
105 clear_c0_mvpcontrol(MVPCONTROL_VPC);
106}
107
108static void ipi_resched_dispatch(void)
109{
110 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
111}
112
113static void ipi_call_dispatch(void)
114{
115 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
116}
117
118static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
119{
120 return IRQ_HANDLED;
121}
122
123static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
124{
125 smp_call_function_interrupt();
126
127 return IRQ_HANDLED;
128}
129
130static struct irqaction irq_resched = {
131 .handler = ipi_resched_interrupt,
132 .flags = IRQF_DISABLED|IRQF_PERCPU,
133 .name = "IPI_resched"
134};
135
136static struct irqaction irq_call = {
137 .handler = ipi_call_interrupt,
138 .flags = IRQF_DISABLED|IRQF_PERCPU,
139 .name = "IPI_call"
140};
141
142static void __init smp_copy_vpe_config(void)
143{ 40{
144 write_vpe_c0_status( 41 write_vpe_c0_status(
145 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 42 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
@@ -156,7 +53,7 @@ static void __init smp_copy_vpe_config(void)
156 write_vpe_c0_count(read_c0_count()); 53 write_vpe_c0_count(read_c0_count());
157} 54}
158 55
159static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, 56static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
160 unsigned int ncpu) 57 unsigned int ncpu)
161{ 58{
162 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) 59 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
@@ -182,12 +79,12 @@ static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
182 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); 79 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
183 80
184 if (tc != 0) 81 if (tc != 0)
185 smp_copy_vpe_config(); 82 smvp_copy_vpe_config();
186 83
187 return ncpu; 84 return ncpu;
188} 85}
189 86
190static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) 87static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
191{ 88{
192 unsigned long tmp; 89 unsigned long tmp;
193 90
@@ -254,15 +151,20 @@ static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
254 151
255static void __cpuinit vsmp_init_secondary(void) 152static void __cpuinit vsmp_init_secondary(void)
256{ 153{
257 /* Enable per-cpu interrupts */ 154 extern int gic_present;
258 155
259 /* This is Malta specific: IPI,performance and timer inetrrupts */ 156 /* This is Malta specific: IPI,performance and timer inetrrupts */
260 write_c0_status((read_c0_status() & ~ST0_IM ) | 157 if (gic_present)
261 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); 158 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
159 STATUSF_IP6 | STATUSF_IP7);
160 else
161 change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
162 STATUSF_IP6 | STATUSF_IP7);
262} 163}
263 164
264static void __cpuinit vsmp_smp_finish(void) 165static void __cpuinit vsmp_smp_finish(void)
265{ 166{
167 /* CDFIXME: remove this? */
266 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 168 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
267 169
268#ifdef CONFIG_MIPS_MT_FPAFF 170#ifdef CONFIG_MIPS_MT_FPAFF
@@ -323,7 +225,7 @@ static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
323/* 225/*
324 * Common setup before any secondaries are started 226 * Common setup before any secondaries are started
325 * Make sure all CPU's are in a sensible state before we boot any of the 227 * Make sure all CPU's are in a sensible state before we boot any of the
326 * secondarys 228 * secondaries
327 */ 229 */
328static void __init vsmp_smp_setup(void) 230static void __init vsmp_smp_setup(void)
329{ 231{
@@ -356,8 +258,8 @@ static void __init vsmp_smp_setup(void)
356 for (tc = 0; tc <= ntc; tc++) { 258 for (tc = 0; tc <= ntc; tc++) {
357 settc(tc); 259 settc(tc);
358 260
359 smp_tc_init(tc, mvpconf0); 261 smvp_tc_init(tc, mvpconf0);
360 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); 262 ncpu = smvp_vpe_init(tc, mvpconf0, ncpu);
361 } 263 }
362 264
363 /* Release config state */ 265 /* Release config state */
@@ -371,21 +273,6 @@ static void __init vsmp_smp_setup(void)
371static void __init vsmp_prepare_cpus(unsigned int max_cpus) 273static void __init vsmp_prepare_cpus(unsigned int max_cpus)
372{ 274{
373 mips_mt_set_cpuoptions(); 275 mips_mt_set_cpuoptions();
374
375 /* set up ipi interrupts */
376 if (cpu_has_vint) {
377 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
378 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
379 }
380
381 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
382 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
383
384 setup_irq(cpu_ipi_resched_irq, &irq_resched);
385 setup_irq(cpu_ipi_call_irq, &irq_call);
386
387 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
388 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
389} 276}
390 277
391struct plat_smp_ops vsmp_smp_ops = { 278struct plat_smp_ops vsmp_smp_ops = {
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 9d41dab90a80..33780cc61ce9 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -35,6 +35,7 @@
35#include <asm/atomic.h> 35#include <asm/atomic.h>
36#include <asm/cpu.h> 36#include <asm/cpu.h>
37#include <asm/processor.h> 37#include <asm/processor.h>
38#include <asm/r4k-timer.h>
38#include <asm/system.h> 39#include <asm/system.h>
39#include <asm/mmu_context.h> 40#include <asm/mmu_context.h>
40#include <asm/time.h> 41#include <asm/time.h>
@@ -125,6 +126,8 @@ asmlinkage __cpuinit void start_secondary(void)
125 126
126 cpu_set(cpu, cpu_callin_map); 127 cpu_set(cpu, cpu_callin_map);
127 128
129 synchronise_count_slave();
130
128 cpu_idle(); 131 cpu_idle();
129} 132}
130 133
@@ -287,6 +290,7 @@ void smp_send_stop(void)
287void __init smp_cpus_done(unsigned int max_cpus) 290void __init smp_cpus_done(unsigned int max_cpus)
288{ 291{
289 mp_ops->cpus_done(); 292 mp_ops->cpus_done();
293 synchronise_count_master();
290} 294}
291 295
292/* called from main before smp_init() */ 296/* called from main before smp_init() */
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index b42e71c71119..3e863186cd22 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -174,14 +174,6 @@ static int clock_hang_reported[NR_CPUS];
174 174
175#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ 175#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
176 176
177/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */
178
179void __init sanitize_tlb_entries(void)
180{
181 printk("Deprecated sanitize_tlb_entries() invoked\n");
182}
183
184
185/* 177/*
186 * Configure shared TLB - VPC configuration bit must be set by caller 178 * Configure shared TLB - VPC configuration bit must be set by caller
187 */ 179 */
@@ -339,7 +331,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
339 /* In general, all TCs should have the same cpu_data indications */ 331 /* In general, all TCs should have the same cpu_data indications */
340 memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); 332 memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
341 /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ 333 /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
342 if (cpu_data[0].cputype == CPU_34K) 334 if (cpu_data[0].cputype == CPU_34K ||
335 cpu_data[0].cputype == CPU_1004K)
343 cpu_data[cpu].options &= ~MIPS_CPU_FPU; 336 cpu_data[cpu].options &= ~MIPS_CPU_FPU;
344 cpu_data[cpu].vpe_id = vpe; 337 cpu_data[cpu].vpe_id = vpe;
345 cpu_data[cpu].tc_id = tc; 338 cpu_data[cpu].tc_id = tc;
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c
new file mode 100644
index 000000000000..6ddb507a87ef
--- /dev/null
+++ b/arch/mips/kernel/spram.c
@@ -0,0 +1,221 @@
1/*
2 * MIPS SPRAM support
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Copyright (C) 2007, 2008 MIPS Technologies, Inc.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/ptrace.h>
14#include <linux/stddef.h>
15
16#include <asm/cpu.h>
17#include <asm/fpu.h>
18#include <asm/mipsregs.h>
19#include <asm/system.h>
20#include <asm/r4kcache.h>
21#include <asm/hazards.h>
22
23/*
24 * These definitions are correct for the 24K/34K/74K SPRAM sample
25 * implementation. The 4KS interpreted the tags differently...
26 */
27#define SPRAM_TAG0_ENABLE 0x00000080
28#define SPRAM_TAG0_PA_MASK 0xfffff000
29#define SPRAM_TAG1_SIZE_MASK 0xfffff000
30
31#define SPRAM_TAG_STRIDE 8
32
33#define ERRCTL_SPRAM (1 << 28)
34
35/* errctl access */
36#define read_c0_errctl(x) read_c0_ecc(x)
37#define write_c0_errctl(x) write_c0_ecc(x)
38
39/*
40 * Different semantics to the set_c0_* function built by __BUILD_SET_C0
41 */
42static __cpuinit unsigned int bis_c0_errctl(unsigned int set)
43{
44 unsigned int res;
45 res = read_c0_errctl();
46 write_c0_errctl(res | set);
47 return res;
48}
49
50static __cpuinit void ispram_store_tag(unsigned int offset, unsigned int data)
51{
52 unsigned int errctl;
53
54 /* enable SPRAM tag access */
55 errctl = bis_c0_errctl(ERRCTL_SPRAM);
56 ehb();
57
58 write_c0_taglo(data);
59 ehb();
60
61 cache_op(Index_Store_Tag_I, CKSEG0|offset);
62 ehb();
63
64 write_c0_errctl(errctl);
65 ehb();
66}
67
68
69static __cpuinit unsigned int ispram_load_tag(unsigned int offset)
70{
71 unsigned int data;
72 unsigned int errctl;
73
74 /* enable SPRAM tag access */
75 errctl = bis_c0_errctl(ERRCTL_SPRAM);
76 ehb();
77 cache_op(Index_Load_Tag_I, CKSEG0 | offset);
78 ehb();
79 data = read_c0_taglo();
80 ehb();
81 write_c0_errctl(errctl);
82 ehb();
83
84 return data;
85}
86
87static __cpuinit void dspram_store_tag(unsigned int offset, unsigned int data)
88{
89 unsigned int errctl;
90
91 /* enable SPRAM tag access */
92 errctl = bis_c0_errctl(ERRCTL_SPRAM);
93 ehb();
94 write_c0_dtaglo(data);
95 ehb();
96 cache_op(Index_Store_Tag_D, CKSEG0 | offset);
97 ehb();
98 write_c0_errctl(errctl);
99 ehb();
100}
101
102
103static __cpuinit unsigned int dspram_load_tag(unsigned int offset)
104{
105 unsigned int data;
106 unsigned int errctl;
107
108 errctl = bis_c0_errctl(ERRCTL_SPRAM);
109 ehb();
110 cache_op(Index_Load_Tag_D, CKSEG0 | offset);
111 ehb();
112 data = read_c0_dtaglo();
113 ehb();
114 write_c0_errctl(errctl);
115 ehb();
116
117 return data;
118}
119
120static __cpuinit void probe_spram(char *type,
121 unsigned int base,
122 unsigned int (*read)(unsigned int),
123 void (*write)(unsigned int, unsigned int))
124{
125 unsigned int firstsize = 0, lastsize = 0;
126 unsigned int firstpa = 0, lastpa = 0, pa = 0;
127 unsigned int offset = 0;
128 unsigned int size, tag0, tag1;
129 unsigned int enabled;
130 int i;
131
132 /*
133 * The limit is arbitrary but avoids the loop running away if
134 * the SPRAM tags are implemented differently
135 */
136
137 for (i = 0; i < 8; i++) {
138 tag0 = read(offset);
139 tag1 = read(offset+SPRAM_TAG_STRIDE);
140 pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
141 type, i, tag0, tag1);
142
143 size = tag1 & SPRAM_TAG1_SIZE_MASK;
144
145 if (size == 0)
146 break;
147
148 if (i != 0) {
149 /* tags may repeat... */
150 if ((pa == firstpa && size == firstsize) ||
151 (pa == lastpa && size == lastsize))
152 break;
153 }
154
155 /* Align base with size */
156 base = (base + size - 1) & ~(size-1);
157
158 /* reprogram the base address base address and enable */
159 tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
160 write(offset, tag0);
161
162 base += size;
163
164 /* reread the tag */
165 tag0 = read(offset);
166 pa = tag0 & SPRAM_TAG0_PA_MASK;
167 enabled = tag0 & SPRAM_TAG0_ENABLE;
168
169 if (i == 0) {
170 firstpa = pa;
171 firstsize = size;
172 }
173
174 lastpa = pa;
175 lastsize = size;
176
177 if (strcmp(type, "DSPRAM") == 0) {
178 unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
179 unsigned int v;
180#define TDAT 0x5a5aa5a5
181 vp[0] = TDAT;
182 vp[1] = ~TDAT;
183
184 mb();
185
186 v = vp[0];
187 if (v != TDAT)
188 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
189 vp, TDAT, v);
190 v = vp[1];
191 if (v != ~TDAT)
192 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
193 vp+1, ~TDAT, v);
194 }
195
196 pr_info("%s%d: PA=%08x,Size=%08x%s\n",
197 type, i, pa, size, enabled ? ",enabled" : "");
198 offset += 2 * SPRAM_TAG_STRIDE;
199 }
200}
201
202__cpuinit void spram_config(void)
203{
204 struct cpuinfo_mips *c = &current_cpu_data;
205 unsigned int config0;
206
207 switch (c->cputype) {
208 case CPU_24K:
209 case CPU_34K:
210 case CPU_74K:
211 config0 = read_c0_config();
212 /* FIXME: addresses are Malta specific */
213 if (config0 & (1<<24)) {
214 probe_spram("ISPRAM", 0x1c000000,
215 &ispram_load_tag, &ispram_store_tag);
216 }
217 if (config0 & (1<<23))
218 probe_spram("DSPRAM", 0x1c100000,
219 &dspram_load_tag, &dspram_store_tag);
220 }
221}
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
new file mode 100644
index 000000000000..9021108eb9c1
--- /dev/null
+++ b/arch/mips/kernel/sync-r4k.c
@@ -0,0 +1,159 @@
1/*
2 * Count register synchronisation.
3 *
4 * All CPUs will have their count registers synchronised to the CPU0 expirelo
5 * value. This can cause a small timewarp for CPU0. All other CPU's should
6 * not have done anything significant (but they may have had interrupts
7 * enabled briefly - prom_smp_finish() should not be responsible for enabling
8 * interrupts...)
9 *
10 * FIXME: broken for SMTC
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/irqflags.h>
16#include <linux/r4k-timer.h>
17
18#include <asm/atomic.h>
19#include <asm/barrier.h>
20#include <asm/cpumask.h>
21#include <asm/mipsregs.h>
22
23static atomic_t __initdata count_start_flag = ATOMIC_INIT(0);
24static atomic_t __initdata count_count_start = ATOMIC_INIT(0);
25static atomic_t __initdata count_count_stop = ATOMIC_INIT(0);
26
27#define COUNTON 100
28#define NR_LOOPS 5
29
30void __init synchronise_count_master(void)
31{
32 int i;
33 unsigned long flags;
34 unsigned int initcount;
35 int nslaves;
36
37#ifdef CONFIG_MIPS_MT_SMTC
38 /*
39 * SMTC needs to synchronise per VPE, not per CPU
40 * ignore for now
41 */
42 return;
43#endif
44
45 pr_info("Checking COUNT synchronization across %u CPUs: ",
46 num_online_cpus());
47
48 local_irq_save(flags);
49
50 /*
51 * Notify the slaves that it's time to start
52 */
53 atomic_set(&count_start_flag, 1);
54 smp_wmb();
55
56 /* Count will be initialised to expirelo for all CPU's */
57 initcount = expirelo;
58
59 /*
60 * We loop a few times to get a primed instruction cache,
61 * then the last pass is more or less synchronised and
62 * the master and slaves each set their cycle counters to a known
63 * value all at once. This reduces the chance of having random offsets
64 * between the processors, and guarantees that the maximum
65 * delay between the cycle counters is never bigger than
66 * the latency of information-passing (cachelines) between
67 * two CPUs.
68 */
69
70 nslaves = num_online_cpus()-1;
71 for (i = 0; i < NR_LOOPS; i++) {
72 /* slaves loop on '!= ncpus' */
73 while (atomic_read(&count_count_start) != nslaves)
74 mb();
75 atomic_set(&count_count_stop, 0);
76 smp_wmb();
77
78 /* this lets the slaves write their count register */
79 atomic_inc(&count_count_start);
80
81 /*
82 * Everyone initialises count in the last loop:
83 */
84 if (i == NR_LOOPS-1)
85 write_c0_count(initcount);
86
87 /*
88 * Wait for all slaves to leave the synchronization point:
89 */
90 while (atomic_read(&count_count_stop) != nslaves)
91 mb();
92 atomic_set(&count_count_start, 0);
93 smp_wmb();
94 atomic_inc(&count_count_stop);
95 }
96 /* Arrange for an interrupt in a short while */
97 write_c0_compare(read_c0_count() + COUNTON);
98
99 local_irq_restore(flags);
100
101 /*
102 * i386 code reported the skew here, but the
103 * count registers were almost certainly out of sync
104 * so no point in alarming people
105 */
106 printk("done.\n");
107}
108
109void __init synchronise_count_slave(void)
110{
111 int i;
112 unsigned long flags;
113 unsigned int initcount;
114 int ncpus;
115
116#ifdef CONFIG_MIPS_MT_SMTC
117 /*
118 * SMTC needs to synchronise per VPE, not per CPU
119 * ignore for now
120 */
121 return;
122#endif
123
124 local_irq_save(flags);
125
126 /*
127 * Not every cpu is online at the time this gets called,
128 * so we first wait for the master to say everyone is ready
129 */
130
131 while (!atomic_read(&count_start_flag))
132 mb();
133
134 /* Count will be initialised to expirelo for all CPU's */
135 initcount = expirelo;
136
137 ncpus = num_online_cpus();
138 for (i = 0; i < NR_LOOPS; i++) {
139 atomic_inc(&count_count_start);
140 while (atomic_read(&count_count_start) != ncpus)
141 mb();
142
143 /*
144 * Everyone initialises count in the last loop:
145 */
146 if (i == NR_LOOPS-1)
147 write_c0_count(initcount);
148
149 atomic_inc(&count_count_stop);
150 while (atomic_read(&count_count_stop) != ncpus)
151 mb();
152 }
153 /* Arrange for an interrupt in a short while */
154 write_c0_compare(read_c0_count() + COUNTON);
155
156 local_irq_restore(flags);
157}
158#undef NR_LOOPS
159#endif
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index b45a7093ca2d..1f467d534642 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -38,7 +38,6 @@ int __weak rtc_mips_set_time(unsigned long sec)
38{ 38{
39 return 0; 39 return 0;
40} 40}
41EXPORT_SYMBOL(rtc_mips_set_time);
42 41
43int __weak rtc_mips_set_mmss(unsigned long nowtime) 42int __weak rtc_mips_set_mmss(unsigned long nowtime)
44{ 43{
@@ -50,13 +49,11 @@ int update_persistent_clock(struct timespec now)
50 return rtc_mips_set_mmss(now.tv_sec); 49 return rtc_mips_set_mmss(now.tv_sec);
51} 50}
52 51
53int null_perf_irq(void) 52static int null_perf_irq(void)
54{ 53{
55 return 0; 54 return 0;
56} 55}
57 56
58EXPORT_SYMBOL(null_perf_irq);
59
60int (*perf_irq)(void) = null_perf_irq; 57int (*perf_irq)(void) = null_perf_irq;
61 58
62EXPORT_SYMBOL(perf_irq); 59EXPORT_SYMBOL(perf_irq);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 984c0d0a7b4d..cb8b0e2c7954 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -22,6 +22,7 @@
22#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/ptrace.h>
25 26
26#include <asm/bootinfo.h> 27#include <asm/bootinfo.h>
27#include <asm/branch.h> 28#include <asm/branch.h>
@@ -80,19 +81,22 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
80 81
81static void show_raw_backtrace(unsigned long reg29) 82static void show_raw_backtrace(unsigned long reg29)
82{ 83{
83 unsigned long *sp = (unsigned long *)reg29; 84 unsigned long *sp = (unsigned long *)(reg29 & ~3);
84 unsigned long addr; 85 unsigned long addr;
85 86
86 printk("Call Trace:"); 87 printk("Call Trace:");
87#ifdef CONFIG_KALLSYMS 88#ifdef CONFIG_KALLSYMS
88 printk("\n"); 89 printk("\n");
89#endif 90#endif
90 while (!kstack_end(sp)) { 91#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
91 addr = *sp++; 92 if (IS_KVA01(sp)) {
92 if (__kernel_text_address(addr)) 93 while (!kstack_end(sp)) {
93 print_ip_sym(addr); 94 addr = *sp++;
95 if (__kernel_text_address(addr))
96 print_ip_sym(addr);
97 }
98 printk("\n");
94 } 99 }
95 printk("\n");
96} 100}
97 101
98#ifdef CONFIG_KALLSYMS 102#ifdef CONFIG_KALLSYMS
@@ -192,16 +196,19 @@ EXPORT_SYMBOL(dump_stack);
192static void show_code(unsigned int __user *pc) 196static void show_code(unsigned int __user *pc)
193{ 197{
194 long i; 198 long i;
199 unsigned short __user *pc16 = NULL;
195 200
196 printk("\nCode:"); 201 printk("\nCode:");
197 202
203 if ((unsigned long)pc & 1)
204 pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
198 for(i = -3 ; i < 6 ; i++) { 205 for(i = -3 ; i < 6 ; i++) {
199 unsigned int insn; 206 unsigned int insn;
200 if (__get_user(insn, pc + i)) { 207 if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
201 printk(" (Bad address in epc)\n"); 208 printk(" (Bad address in epc)\n");
202 break; 209 break;
203 } 210 }
204 printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>')); 211 printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
205 } 212 }
206} 213}
207 214
@@ -311,10 +318,21 @@ void show_regs(struct pt_regs *regs)
311 318
312void show_registers(const struct pt_regs *regs) 319void show_registers(const struct pt_regs *regs)
313{ 320{
321 const int field = 2 * sizeof(unsigned long);
322
314 __show_regs(regs); 323 __show_regs(regs);
315 print_modules(); 324 print_modules();
316 printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", 325 printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
317 current->comm, task_pid_nr(current), current_thread_info(), current); 326 current->comm, current->pid, current_thread_info(), current,
327 field, current_thread_info()->tp_value);
328 if (cpu_has_userlocal) {
329 unsigned long tls;
330
331 tls = read_c0_userlocal();
332 if (tls != current_thread_info()->tp_value)
333 printk("*HwTLS: %0*lx\n", field, tls);
334 }
335
318 show_stacktrace(current, regs); 336 show_stacktrace(current, regs);
319 show_code((unsigned int __user *) regs->cp0_epc); 337 show_code((unsigned int __user *) regs->cp0_epc);
320 printk("\n"); 338 printk("\n");
@@ -657,35 +675,24 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
657 force_sig_info(SIGFPE, &info, current); 675 force_sig_info(SIGFPE, &info, current);
658} 676}
659 677
660asmlinkage void do_bp(struct pt_regs *regs) 678static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
679 const char *str)
661{ 680{
662 unsigned int opcode, bcode;
663 siginfo_t info; 681 siginfo_t info;
664 682 char b[40];
665 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
666 goto out_sigsegv;
667
668 /*
669 * There is the ancient bug in the MIPS assemblers that the break
670 * code starts left to bit 16 instead to bit 6 in the opcode.
671 * Gas is bug-compatible, but not always, grrr...
672 * We handle both cases with a simple heuristics. --macro
673 */
674 bcode = ((opcode >> 6) & ((1 << 20) - 1));
675 if (bcode < (1 << 10))
676 bcode <<= 10;
677 683
678 /* 684 /*
679 * (A short test says that IRIX 5.3 sends SIGTRAP for all break 685 * A short test says that IRIX 5.3 sends SIGTRAP for all trap
680 * insns, even for break codes that indicate arithmetic failures. 686 * insns, even for trap and break codes that indicate arithmetic
681 * Weird ...) 687 * failures. Weird ...
682 * But should we continue the brokenness??? --macro 688 * But should we continue the brokenness??? --macro
683 */ 689 */
684 switch (bcode) { 690 switch (code) {
685 case BRK_OVERFLOW << 10: 691 case BRK_OVERFLOW:
686 case BRK_DIVZERO << 10: 692 case BRK_DIVZERO:
687 die_if_kernel("Break instruction in kernel code", regs); 693 scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
688 if (bcode == (BRK_DIVZERO << 10)) 694 die_if_kernel(b, regs);
695 if (code == BRK_DIVZERO)
689 info.si_code = FPE_INTDIV; 696 info.si_code = FPE_INTDIV;
690 else 697 else
691 info.si_code = FPE_INTOVF; 698 info.si_code = FPE_INTOVF;
@@ -695,12 +702,34 @@ asmlinkage void do_bp(struct pt_regs *regs)
695 force_sig_info(SIGFPE, &info, current); 702 force_sig_info(SIGFPE, &info, current);
696 break; 703 break;
697 case BRK_BUG: 704 case BRK_BUG:
698 die("Kernel bug detected", regs); 705 die_if_kernel("Kernel bug detected", regs);
706 force_sig(SIGTRAP, current);
699 break; 707 break;
700 default: 708 default:
701 die_if_kernel("Break instruction in kernel code", regs); 709 scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
710 die_if_kernel(b, regs);
702 force_sig(SIGTRAP, current); 711 force_sig(SIGTRAP, current);
703 } 712 }
713}
714
715asmlinkage void do_bp(struct pt_regs *regs)
716{
717 unsigned int opcode, bcode;
718
719 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
720 goto out_sigsegv;
721
722 /*
723 * There is the ancient bug in the MIPS assemblers that the break
724 * code starts left to bit 16 instead to bit 6 in the opcode.
725 * Gas is bug-compatible, but not always, grrr...
726 * We handle both cases with a simple heuristics. --macro
727 */
728 bcode = ((opcode >> 6) & ((1 << 20) - 1));
729 if (bcode >= (1 << 10))
730 bcode >>= 10;
731
732 do_trap_or_bp(regs, bcode, "Break");
704 return; 733 return;
705 734
706out_sigsegv: 735out_sigsegv:
@@ -710,7 +739,6 @@ out_sigsegv:
710asmlinkage void do_tr(struct pt_regs *regs) 739asmlinkage void do_tr(struct pt_regs *regs)
711{ 740{
712 unsigned int opcode, tcode = 0; 741 unsigned int opcode, tcode = 0;
713 siginfo_t info;
714 742
715 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) 743 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
716 goto out_sigsegv; 744 goto out_sigsegv;
@@ -719,32 +747,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
719 if (!(opcode & OPCODE)) 747 if (!(opcode & OPCODE))
720 tcode = ((opcode >> 6) & ((1 << 10) - 1)); 748 tcode = ((opcode >> 6) & ((1 << 10) - 1));
721 749
722 /* 750 do_trap_or_bp(regs, tcode, "Trap");
723 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
724 * insns, even for trap codes that indicate arithmetic failures.
725 * Weird ...)
726 * But should we continue the brokenness??? --macro
727 */
728 switch (tcode) {
729 case BRK_OVERFLOW:
730 case BRK_DIVZERO:
731 die_if_kernel("Trap instruction in kernel code", regs);
732 if (tcode == BRK_DIVZERO)
733 info.si_code = FPE_INTDIV;
734 else
735 info.si_code = FPE_INTOVF;
736 info.si_signo = SIGFPE;
737 info.si_errno = 0;
738 info.si_addr = (void __user *) regs->cp0_epc;
739 force_sig_info(SIGFPE, &info, current);
740 break;
741 case BRK_BUG:
742 die("Kernel bug detected", regs);
743 break;
744 default:
745 die_if_kernel("Trap instruction in kernel code", regs);
746 force_sig(SIGTRAP, current);
747 }
748 return; 751 return;
749 752
750out_sigsegv: 753out_sigsegv:
@@ -985,6 +988,21 @@ asmlinkage void do_reserved(struct pt_regs *regs)
985 (regs->cp0_cause & 0x7f) >> 2); 988 (regs->cp0_cause & 0x7f) >> 2);
986} 989}
987 990
991static int __initdata l1parity = 1;
992static int __init nol1parity(char *s)
993{
994 l1parity = 0;
995 return 1;
996}
997__setup("nol1par", nol1parity);
998static int __initdata l2parity = 1;
999static int __init nol2parity(char *s)
1000{
1001 l2parity = 0;
1002 return 1;
1003}
1004__setup("nol2par", nol2parity);
1005
988/* 1006/*
989 * Some MIPS CPUs can enable/disable for cache parity detection, but do 1007 * Some MIPS CPUs can enable/disable for cache parity detection, but do
990 * it different ways. 1008 * it different ways.
@@ -994,6 +1012,62 @@ static inline void parity_protection_init(void)
994 switch (current_cpu_type()) { 1012 switch (current_cpu_type()) {
995 case CPU_24K: 1013 case CPU_24K:
996 case CPU_34K: 1014 case CPU_34K:
1015 case CPU_74K:
1016 case CPU_1004K:
1017 {
1018#define ERRCTL_PE 0x80000000
1019#define ERRCTL_L2P 0x00800000
1020 unsigned long errctl;
1021 unsigned int l1parity_present, l2parity_present;
1022
1023 errctl = read_c0_ecc();
1024 errctl &= ~(ERRCTL_PE|ERRCTL_L2P);
1025
1026 /* probe L1 parity support */
1027 write_c0_ecc(errctl | ERRCTL_PE);
1028 back_to_back_c0_hazard();
1029 l1parity_present = (read_c0_ecc() & ERRCTL_PE);
1030
1031 /* probe L2 parity support */
1032 write_c0_ecc(errctl|ERRCTL_L2P);
1033 back_to_back_c0_hazard();
1034 l2parity_present = (read_c0_ecc() & ERRCTL_L2P);
1035
1036 if (l1parity_present && l2parity_present) {
1037 if (l1parity)
1038 errctl |= ERRCTL_PE;
1039 if (l1parity ^ l2parity)
1040 errctl |= ERRCTL_L2P;
1041 } else if (l1parity_present) {
1042 if (l1parity)
1043 errctl |= ERRCTL_PE;
1044 } else if (l2parity_present) {
1045 if (l2parity)
1046 errctl |= ERRCTL_L2P;
1047 } else {
1048 /* No parity available */
1049 }
1050
1051 printk(KERN_INFO "Writing ErrCtl register=%08lx\n", errctl);
1052
1053 write_c0_ecc(errctl);
1054 back_to_back_c0_hazard();
1055 errctl = read_c0_ecc();
1056 printk(KERN_INFO "Readback ErrCtl register=%08lx\n", errctl);
1057
1058 if (l1parity_present)
1059 printk(KERN_INFO "Cache parity protection %sabled\n",
1060 (errctl & ERRCTL_PE) ? "en" : "dis");
1061
1062 if (l2parity_present) {
1063 if (l1parity_present && l1parity)
1064 errctl ^= ERRCTL_L2P;
1065 printk(KERN_INFO "L2 cache parity protection %sabled\n",
1066 (errctl & ERRCTL_L2P) ? "en" : "dis");
1067 }
1068 }
1069 break;
1070
997 case CPU_5KC: 1071 case CPU_5KC:
998 write_c0_ecc(0x80000000); 1072 write_c0_ecc(0x80000000);
999 back_to_back_c0_hazard(); 1073 back_to_back_c0_hazard();
@@ -1306,6 +1380,17 @@ int cp0_compare_irq;
1306int cp0_perfcount_irq; 1380int cp0_perfcount_irq;
1307EXPORT_SYMBOL_GPL(cp0_perfcount_irq); 1381EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
1308 1382
1383static int __cpuinitdata noulri;
1384
1385static int __init ulri_disable(char *s)
1386{
1387 pr_info("Disabling ulri\n");
1388 noulri = 1;
1389
1390 return 1;
1391}
1392__setup("noulri", ulri_disable);
1393
1309void __cpuinit per_cpu_trap_init(void) 1394void __cpuinit per_cpu_trap_init(void)
1310{ 1395{
1311 unsigned int cpu = smp_processor_id(); 1396 unsigned int cpu = smp_processor_id();
@@ -1342,16 +1427,14 @@ void __cpuinit per_cpu_trap_init(void)
1342 change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, 1427 change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
1343 status_set); 1428 status_set);
1344 1429
1345#ifdef CONFIG_CPU_MIPSR2
1346 if (cpu_has_mips_r2) { 1430 if (cpu_has_mips_r2) {
1347 unsigned int enable = 0x0000000f; 1431 unsigned int enable = 0x0000000f;
1348 1432
1349 if (cpu_has_userlocal) 1433 if (!noulri && cpu_has_userlocal)
1350 enable |= (1 << 29); 1434 enable |= (1 << 29);
1351 1435
1352 write_c0_hwrena(enable); 1436 write_c0_hwrena(enable);
1353 } 1437 }
1354#endif
1355 1438
1356#ifdef CONFIG_MIPS_MT_SMTC 1439#ifdef CONFIG_MIPS_MT_SMTC
1357 if (!secondaryTC) { 1440 if (!secondaryTC) {
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
index 8977eb585a37..762786538449 100644
--- a/arch/mips/math-emu/ieee754dp.h
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -46,7 +46,7 @@
46#define DPDNORMX DPDNORMx(xm, xe) 46#define DPDNORMX DPDNORMx(xm, xe)
47#define DPDNORMY DPDNORMx(ym, ye) 47#define DPDNORMY DPDNORMx(ym, ye)
48 48
49static __inline ieee754dp builddp(int s, int bx, u64 m) 49static inline ieee754dp builddp(int s, int bx, u64 m)
50{ 50{
51 ieee754dp r; 51 ieee754dp r;
52 52
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
index 9917c1e4d947..d9e3586b5bce 100644
--- a/arch/mips/math-emu/ieee754sp.h
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -51,7 +51,7 @@
51#define SPDNORMX SPDNORMx(xm, xe) 51#define SPDNORMX SPDNORMx(xm, xe)
52#define SPDNORMY SPDNORMx(ym, ye) 52#define SPDNORMY SPDNORMx(ym, ye)
53 53
54static __inline ieee754sp buildsp(int s, int bx, unsigned m) 54static inline ieee754sp buildsp(int s, int bx, unsigned m)
55{ 55{
56 ieee754sp r; 56 ieee754sp r;
57 57
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
index b31d8dfed1be..f7f87fc09d1e 100644
--- a/arch/mips/mips-boards/generic/Makefile
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -20,6 +20,7 @@
20 20
21obj-y := reset.o display.o init.o memory.o \ 21obj-y := reset.o display.o init.o memory.o \
22 cmdline.o time.o 22 cmdline.o time.o
23obj-y += amon.o
23 24
24obj-$(CONFIG_EARLY_PRINTK) += console.o 25obj-$(CONFIG_EARLY_PRINTK) += console.o
25obj-$(CONFIG_PCI) += pci.o 26obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/mips-boards/generic/amon.c b/arch/mips/mips-boards/generic/amon.c
new file mode 100644
index 000000000000..b7633fda4180
--- /dev/null
+++ b/arch/mips/mips-boards/generic/amon.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2007 MIPS Technologies, Inc.
3 * All rights reserved.
4
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Arbitrary Monitor interface
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/smp.h>
24
25#include <asm-mips/addrspace.h>
26#include <asm-mips/mips-boards/launch.h>
27#include <asm-mips/mipsmtregs.h>
28
29int amon_cpu_avail(int cpu)
30{
31 struct cpulaunch *launch = (struct cpulaunch *)KSEG0ADDR(CPULAUNCH);
32
33 if (cpu < 0 || cpu >= NCPULAUNCH) {
34 pr_debug("avail: cpu%d is out of range\n", cpu);
35 return 0;
36 }
37
38 launch += cpu;
39 if (!(launch->flags & LAUNCH_FREADY)) {
40 pr_debug("avail: cpu%d is not ready\n", cpu);
41 return 0;
42 }
43 if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) {
44 pr_debug("avail: too late.. cpu%d is already gone\n", cpu);
45 return 0;
46 }
47
48 return 1;
49}
50
51void amon_cpu_start(int cpu,
52 unsigned long pc, unsigned long sp,
53 unsigned long gp, unsigned long a0)
54{
55 volatile struct cpulaunch *launch =
56 (struct cpulaunch *)KSEG0ADDR(CPULAUNCH);
57
58 if (!amon_cpu_avail(cpu))
59 return;
60 if (cpu == smp_processor_id()) {
61 pr_debug("launch: I am cpu%d!\n", cpu);
62 return;
63 }
64 launch += cpu;
65
66 pr_debug("launch: starting cpu%d\n", cpu);
67
68 launch->pc = pc;
69 launch->gp = gp;
70 launch->sp = sp;
71 launch->a0 = a0;
72
73 /* Make sure target sees parameters before the go bit */
74 smp_mb();
75
76 launch->flags |= LAUNCH_FGO;
77 while ((launch->flags & LAUNCH_FGONE) == 0)
78 ;
79 pr_debug("launch: cpu%d gone!\n", cpu);
80}
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 1695dca5506b..83b9dc739203 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -226,7 +226,7 @@ void __init kgdb_config(void)
226} 226}
227#endif 227#endif
228 228
229void __init mips_nmi_setup(void) 229static void __init mips_nmi_setup(void)
230{ 230{
231 void *base; 231 void *base;
232 extern char except_vec_nmi; 232 extern char except_vec_nmi;
@@ -238,7 +238,7 @@ void __init mips_nmi_setup(void)
238 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); 238 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
239} 239}
240 240
241void __init mips_ejtag_setup(void) 241static void __init mips_ejtag_setup(void)
242{ 242{
243 void *base; 243 void *base;
244 extern char except_vec_ejtag_debug; 244 extern char except_vec_ejtag_debug;
@@ -295,15 +295,21 @@ void __init prom_init(void)
295 break; 295 break;
296 case MIPS_REVISION_CORID_CORE_MSC: 296 case MIPS_REVISION_CORID_CORE_MSC:
297 case MIPS_REVISION_CORID_CORE_FPGA2: 297 case MIPS_REVISION_CORID_CORE_FPGA2:
298 case MIPS_REVISION_CORID_CORE_FPGA3:
299 case MIPS_REVISION_CORID_CORE_FPGA4:
300 case MIPS_REVISION_CORID_CORE_24K: 298 case MIPS_REVISION_CORID_CORE_24K:
301 case MIPS_REVISION_CORID_CORE_EMUL_MSC: 299 /*
300 * SOCit/ROCit support is essentially identical
301 * but make an attempt to distinguish them
302 */
302 mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; 303 mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
303 break; 304 break;
305 case MIPS_REVISION_CORID_CORE_FPGA3:
306 case MIPS_REVISION_CORID_CORE_FPGA4:
307 case MIPS_REVISION_CORID_CORE_FPGA5:
308 case MIPS_REVISION_CORID_CORE_EMUL_MSC:
304 default: 309 default:
305 mips_display_message("CC Error"); 310 /* See above */
306 while (1); /* We die here... */ 311 mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
312 break;
307 } 313 }
308 } 314 }
309 315
@@ -418,6 +424,9 @@ void __init prom_init(void)
418#ifdef CONFIG_SERIAL_8250_CONSOLE 424#ifdef CONFIG_SERIAL_8250_CONSOLE
419 console_config(); 425 console_config();
420#endif 426#endif
427#ifdef CONFIG_MIPS_CMP
428 register_smp_ops(&cmp_smp_ops);
429#endif
421#ifdef CONFIG_MIPS_MT_SMP 430#ifdef CONFIG_MIPS_MT_SMP
422 register_smp_ops(&vsmp_smp_ops); 431 register_smp_ops(&vsmp_smp_ops);
423#endif 432#endif
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index dc272c188233..5e443bba5662 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -37,7 +37,7 @@ enum yamon_memtypes {
37 yamon_prom, 37 yamon_prom,
38 yamon_free, 38 yamon_free,
39}; 39};
40struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; 40static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
41 41
42#ifdef DEBUG 42#ifdef DEBUG
43static char *mtypes[3] = { 43static char *mtypes[3] = {
@@ -50,7 +50,7 @@ static char *mtypes[3] = {
50/* determined physical memory size, not overridden by command line args */ 50/* determined physical memory size, not overridden by command line args */
51unsigned long physical_memsize = 0L; 51unsigned long physical_memsize = 0L;
52 52
53struct prom_pmemblock * __init prom_getmdesc(void) 53static struct prom_pmemblock * __init prom_getmdesc(void)
54{ 54{
55 char *memsize_str; 55 char *memsize_str;
56 unsigned int memsize; 56 unsigned int memsize;
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index b50e0fc406ac..008fd82b5840 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -55,16 +55,36 @@
55unsigned long cpu_khz; 55unsigned long cpu_khz;
56 56
57static int mips_cpu_timer_irq; 57static int mips_cpu_timer_irq;
58static int mips_cpu_perf_irq;
58extern int cp0_perfcount_irq; 59extern int cp0_perfcount_irq;
59 60
61DEFINE_PER_CPU(unsigned int, tickcount);
62#define tickcount_this_cpu __get_cpu_var(tickcount)
63static unsigned long ledbitmask;
64
60static void mips_timer_dispatch(void) 65static void mips_timer_dispatch(void)
61{ 66{
67#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_ATLAS)
68 /*
69 * Yes, this is very tacky, won't work as expected with SMTC and
70 * dyntick will break it,
71 * but it gives me a nice warm feeling during debug
72 */
73#define LEDBAR 0xbf000408
74 if (tickcount_this_cpu++ >= HZ) {
75 tickcount_this_cpu = 0;
76 change_bit(smp_processor_id(), &ledbitmask);
77 smp_wmb(); /* Make sure every one else sees the change */
78 /* This will pick up any recent changes made by other CPU's */
79 *(unsigned int *)LEDBAR = ledbitmask;
80 }
81#endif
62 do_IRQ(mips_cpu_timer_irq); 82 do_IRQ(mips_cpu_timer_irq);
63} 83}
64 84
65static void mips_perf_dispatch(void) 85static void mips_perf_dispatch(void)
66{ 86{
67 do_IRQ(cp0_perfcount_irq); 87 do_IRQ(mips_cpu_perf_irq);
68} 88}
69 89
70/* 90/*
@@ -127,21 +147,20 @@ unsigned long read_persistent_clock(void)
127 return mc146818_get_cmos_time(); 147 return mc146818_get_cmos_time();
128} 148}
129 149
130void __init plat_perf_setup(void) 150static void __init plat_perf_setup(void)
131{ 151{
132 cp0_perfcount_irq = -1;
133
134#ifdef MSC01E_INT_BASE 152#ifdef MSC01E_INT_BASE
135 if (cpu_has_veic) { 153 if (cpu_has_veic) {
136 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); 154 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
137 cp0_perfcount_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 155 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
138 } else 156 } else
139#endif 157#endif
140 if (cp0_perfcount_irq >= 0) { 158 if (cp0_perfcount_irq >= 0) {
141 if (cpu_has_vint) 159 if (cpu_has_vint)
142 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); 160 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
161 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
143#ifdef CONFIG_SMP 162#ifdef CONFIG_SMP
144 set_irq_handler(cp0_perfcount_irq, handle_percpu_irq); 163 set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq);
145#endif 164#endif
146 } 165 }
147} 166}
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile
index 931ca4600a63..8dc6e2ac4c03 100644
--- a/arch/mips/mips-boards/malta/Makefile
+++ b/arch/mips/mips-boards/malta/Makefile
@@ -22,6 +22,7 @@
22obj-y := malta_int.o malta_platform.o malta_setup.o 22obj-y := malta_int.o malta_platform.o malta_setup.o
23 23
24obj-$(CONFIG_MTD) += malta_mtd.o 24obj-$(CONFIG_MTD) += malta_mtd.o
25# FIXME FIXME FIXME
25obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o 26obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o
26 27
27EXTRA_CFLAGS += -Werror 28EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index dbe60eb55e29..8c495104b321 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/random.h> 32#include <linux/random.h>
33 33
34#include <asm/traps.h>
34#include <asm/i8259.h> 35#include <asm/i8259.h>
35#include <asm/irq_cpu.h> 36#include <asm/irq_cpu.h>
36#include <asm/irq_regs.h> 37#include <asm/irq_regs.h>
@@ -41,6 +42,14 @@
41#include <asm/mips-boards/generic.h> 42#include <asm/mips-boards/generic.h>
42#include <asm/mips-boards/msc01_pci.h> 43#include <asm/mips-boards/msc01_pci.h>
43#include <asm/msc01_ic.h> 44#include <asm/msc01_ic.h>
45#include <asm/gic.h>
46#include <asm/gcmpregs.h>
47
48int gcmp_present = -1;
49int gic_present;
50static unsigned long _msc01_biu_base;
51static unsigned long _gcmp_base;
52static unsigned int ipi_map[NR_CPUS];
44 53
45static DEFINE_SPINLOCK(mips_irq_lock); 54static DEFINE_SPINLOCK(mips_irq_lock);
46 55
@@ -121,6 +130,17 @@ static void malta_hw0_irqdispatch(void)
121 do_IRQ(MALTA_INT_BASE + irq); 130 do_IRQ(MALTA_INT_BASE + irq);
122} 131}
123 132
133static void malta_ipi_irqdispatch(void)
134{
135 int irq;
136
137 irq = gic_get_int();
138 if (irq < 0)
139 return; /* interrupt has already been cleared */
140
141 do_IRQ(MIPS_GIC_IRQ_BASE + irq);
142}
143
124static void corehi_irqdispatch(void) 144static void corehi_irqdispatch(void)
125{ 145{
126 unsigned int intedge, intsteer, pcicmd, pcibadaddr; 146 unsigned int intedge, intsteer, pcicmd, pcibadaddr;
@@ -257,12 +277,61 @@ asmlinkage void plat_irq_dispatch(void)
257 277
258 if (irq == MIPSCPU_INT_I8259A) 278 if (irq == MIPSCPU_INT_I8259A)
259 malta_hw0_irqdispatch(); 279 malta_hw0_irqdispatch();
280 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
281 malta_ipi_irqdispatch();
260 else if (irq >= 0) 282 else if (irq >= 0)
261 do_IRQ(MIPS_CPU_IRQ_BASE + irq); 283 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
262 else 284 else
263 spurious_interrupt(); 285 spurious_interrupt();
264} 286}
265 287
288#ifdef CONFIG_MIPS_MT_SMP
289
290
291#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3
292#define GIC_MIPS_CPU_IPI_CALL_IRQ 4
293
294#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */
295#define C_RESCHED C_SW0
296#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */
297#define C_CALL C_SW1
298static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
299
300static void ipi_resched_dispatch(void)
301{
302 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
303}
304
305static void ipi_call_dispatch(void)
306{
307 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
308}
309
310static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
311{
312 return IRQ_HANDLED;
313}
314
315static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
316{
317 smp_call_function_interrupt();
318
319 return IRQ_HANDLED;
320}
321
322static struct irqaction irq_resched = {
323 .handler = ipi_resched_interrupt,
324 .flags = IRQF_DISABLED|IRQF_PERCPU,
325 .name = "IPI_resched"
326};
327
328static struct irqaction irq_call = {
329 .handler = ipi_call_interrupt,
330 .flags = IRQF_DISABLED|IRQF_PERCPU,
331 .name = "IPI_call"
332};
333#endif /* CONFIG_MIPS_MT_SMP */
334
266static struct irqaction i8259irq = { 335static struct irqaction i8259irq = {
267 .handler = no_action, 336 .handler = no_action,
268 .name = "XT-PIC cascade" 337 .name = "XT-PIC cascade"
@@ -273,13 +342,13 @@ static struct irqaction corehi_irqaction = {
273 .name = "CoreHi" 342 .name = "CoreHi"
274}; 343};
275 344
276msc_irqmap_t __initdata msc_irqmap[] = { 345static msc_irqmap_t __initdata msc_irqmap[] = {
277 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, 346 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
278 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, 347 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
279}; 348};
280int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); 349static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap);
281 350
282msc_irqmap_t __initdata msc_eicirqmap[] = { 351static msc_irqmap_t __initdata msc_eicirqmap[] = {
283 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, 352 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
284 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, 353 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
285 {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, 354 {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0},
@@ -291,15 +360,90 @@ msc_irqmap_t __initdata msc_eicirqmap[] = {
291 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, 360 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
292 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} 361 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
293}; 362};
294int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); 363
364static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
365
366/*
367 * This GIC specific tabular array defines the association between External
368 * Interrupts and CPUs/Core Interrupts. The nature of the External
369 * Interrupts is also defined here - polarity/trigger.
370 */
371static struct gic_intr_map gic_intr_map[] = {
372 { GIC_EXT_INTR(0), X, X, X, X, 0 },
373 { GIC_EXT_INTR(1), X, X, X, X, 0 },
374 { GIC_EXT_INTR(2), X, X, X, X, 0 },
375 { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
376 { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
377 { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
378 { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
379 { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
380 { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
381 { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
382 { GIC_EXT_INTR(10), X, X, X, X, 0 },
383 { GIC_EXT_INTR(11), X, X, X, X, 0 },
384 { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
385 { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
386 { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
387 { GIC_EXT_INTR(15), X, X, X, X, 0 },
388 { GIC_EXT_INTR(16), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
389 { GIC_EXT_INTR(17), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
390 { GIC_EXT_INTR(18), 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
391 { GIC_EXT_INTR(19), 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
392 { GIC_EXT_INTR(20), 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
393 { GIC_EXT_INTR(21), 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
394 { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
395 { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 },
396};
397
398/*
399 * GCMP needs to be detected before any SMP initialisation
400 */
401int __init gcmp_probe(unsigned long addr, unsigned long size)
402{
403 if (gcmp_present >= 0)
404 return gcmp_present;
405
406 _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ);
407 _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ);
408 gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
409
410 if (gcmp_present)
411 printk(KERN_DEBUG "GCMP present\n");
412 return gcmp_present;
413}
414
415void __init fill_ipi_map(void)
416{
417 int i;
418
419 for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) {
420 if (gic_intr_map[i].ipiflag && (gic_intr_map[i].cpunum != X))
421 ipi_map[gic_intr_map[i].cpunum] |=
422 (1 << (gic_intr_map[i].pin + 2));
423 }
424}
295 425
296void __init arch_init_irq(void) 426void __init arch_init_irq(void)
297{ 427{
428 int gic_present, gcmp_present;
429
298 init_i8259_irqs(); 430 init_i8259_irqs();
299 431
300 if (!cpu_has_veic) 432 if (!cpu_has_veic)
301 mips_cpu_irq_init(); 433 mips_cpu_irq_init();
302 434
435 gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ);
436 if (gcmp_present) {
437 GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK;
438 gic_present = 1;
439 } else {
440 _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ);
441 gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
442 MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF;
443 }
444 if (gic_present)
445 printk(KERN_DEBUG "GIC present\n");
446
303 switch (mips_revision_sconid) { 447 switch (mips_revision_sconid) {
304 case MIPS_REVISION_SCON_SOCIT: 448 case MIPS_REVISION_SCON_SOCIT:
305 case MIPS_REVISION_SCON_ROCIT: 449 case MIPS_REVISION_SCON_ROCIT:
@@ -360,4 +504,206 @@ void __init arch_init_irq(void)
360 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 504 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
361 &corehi_irqaction); 505 &corehi_irqaction);
362 } 506 }
507
508#if defined(CONFIG_MIPS_MT_SMP)
509 if (gic_present) {
510 /* FIXME */
511 int i;
512 struct {
513 unsigned int resched;
514 unsigned int call;
515 } ipiirq[] = {
516 {
517 .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0,
518 .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0},
519 {
520 .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1,
521 .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1
522 }, {
523 .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2,
524 .call = GIC_IPI_EXT_INTR_CALLFNC_VPE2
525 }, {
526 .resched = GIC_IPI_EXT_INTR_RESCHED_VPE3,
527 .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3
528 }
529 };
530#define NIPI (sizeof(ipiirq)/sizeof(ipiirq[0]))
531 fill_ipi_map();
532 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
533 if (!gcmp_present) {
534 /* Enable the GIC */
535 i = REG(_msc01_biu_base, MSC01_SC_CFG);
536 REG(_msc01_biu_base, MSC01_SC_CFG) =
537 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
538 pr_debug("GIC Enabled\n");
539 }
540
541 /* set up ipi interrupts */
542 if (cpu_has_vint) {
543 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
544 set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch);
545 }
546 /* Argh.. this really needs sorting out.. */
547 printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status());
548 write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4);
549 printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status());
550 write_c0_status(0x1100dc00);
551 printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
552 for (i = 0; i < NIPI; i++) {
553 setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched);
554 setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call);
555
556 set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, handle_percpu_irq);
557 set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].call, handle_percpu_irq);
558 }
559 } else {
560 /* set up ipi interrupts */
561 if (cpu_has_veic) {
562 set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
563 set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch);
564 cpu_ipi_resched_irq = MSC01E_INT_SW0;
565 cpu_ipi_call_irq = MSC01E_INT_SW1;
566 } else {
567 if (cpu_has_vint) {
568 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
569 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
570 }
571 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
572 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
573 }
574
575 setup_irq(cpu_ipi_resched_irq, &irq_resched);
576 setup_irq(cpu_ipi_call_irq, &irq_call);
577
578 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
579 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
580 }
581#endif
582}
583
584void malta_be_init(void)
585{
586 if (gcmp_present) {
587 /* Could change CM error mask register */
588 }
589}
590
591
592static char *tr[8] = {
593 "mem", "gcr", "gic", "mmio",
594 "0x04", "0x05", "0x06", "0x07"
595};
596
597static char *mcmd[32] = {
598 [0x00] = "0x00",
599 [0x01] = "Legacy Write",
600 [0x02] = "Legacy Read",
601 [0x03] = "0x03",
602 [0x04] = "0x04",
603 [0x05] = "0x05",
604 [0x06] = "0x06",
605 [0x07] = "0x07",
606 [0x08] = "Coherent Read Own",
607 [0x09] = "Coherent Read Share",
608 [0x0a] = "Coherent Read Discard",
609 [0x0b] = "Coherent Ready Share Always",
610 [0x0c] = "Coherent Upgrade",
611 [0x0d] = "Coherent Writeback",
612 [0x0e] = "0x0e",
613 [0x0f] = "0x0f",
614 [0x10] = "Coherent Copyback",
615 [0x11] = "Coherent Copyback Invalidate",
616 [0x12] = "Coherent Invalidate",
617 [0x13] = "Coherent Write Invalidate",
618 [0x14] = "Coherent Completion Sync",
619 [0x15] = "0x15",
620 [0x16] = "0x16",
621 [0x17] = "0x17",
622 [0x18] = "0x18",
623 [0x19] = "0x19",
624 [0x1a] = "0x1a",
625 [0x1b] = "0x1b",
626 [0x1c] = "0x1c",
627 [0x1d] = "0x1d",
628 [0x1e] = "0x1e",
629 [0x1f] = "0x1f"
630};
631
632static char *core[8] = {
633 "Invalid/OK", "Invalid/Data",
634 "Shared/OK", "Shared/Data",
635 "Modified/OK", "Modified/Data",
636 "Exclusive/OK", "Exclusive/Data"
637};
638
639static char *causes[32] = {
640 "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR",
641 "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
642 "0x08", "0x09", "0x0a", "0x0b",
643 "0x0c", "0x0d", "0x0e", "0x0f",
644 "0x10", "0x11", "0x12", "0x13",
645 "0x14", "0x15", "0x16", "INTVN_WR_ERR",
646 "INTVN_RD_ERR", "0x19", "0x1a", "0x1b",
647 "0x1c", "0x1d", "0x1e", "0x1f"
648};
649
650int malta_be_handler(struct pt_regs *regs, int is_fixup)
651{
652 /* This duplicates the handling in do_be which seems wrong */
653 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
654
655 if (gcmp_present) {
656 unsigned long cm_error = GCMPGCB(GCMEC);
657 unsigned long cm_addr = GCMPGCB(GCMEA);
658 unsigned long cm_other = GCMPGCB(GCMEO);
659 unsigned long cause, ocause;
660 char buf[256];
661
662 cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK);
663 if (cause != 0) {
664 cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF;
665 if (cause < 16) {
666 unsigned long cca_bits = (cm_error >> 15) & 7;
667 unsigned long tr_bits = (cm_error >> 12) & 7;
668 unsigned long mcmd_bits = (cm_error >> 7) & 0x1f;
669 unsigned long stag_bits = (cm_error >> 3) & 15;
670 unsigned long sport_bits = (cm_error >> 0) & 7;
671
672 snprintf(buf, sizeof(buf),
673 "CCA=%lu TR=%s MCmd=%s STag=%lu "
674 "SPort=%lu\n",
675 cca_bits, tr[tr_bits], mcmd[mcmd_bits],
676 stag_bits, sport_bits);
677 } else {
678 /* glob state & sresp together */
679 unsigned long c3_bits = (cm_error >> 18) & 7;
680 unsigned long c2_bits = (cm_error >> 15) & 7;
681 unsigned long c1_bits = (cm_error >> 12) & 7;
682 unsigned long c0_bits = (cm_error >> 9) & 7;
683 unsigned long sc_bit = (cm_error >> 8) & 1;
684 unsigned long mcmd_bits = (cm_error >> 3) & 0x1f;
685 unsigned long sport_bits = (cm_error >> 0) & 7;
686 snprintf(buf, sizeof(buf),
687 "C3=%s C2=%s C1=%s C0=%s SC=%s "
688 "MCmd=%s SPort=%lu\n",
689 core[c3_bits], core[c2_bits],
690 core[c1_bits], core[c0_bits],
691 sc_bit ? "True" : "False",
692 mcmd[mcmd_bits], sport_bits);
693 }
694
695 ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >>
696 GCMP_GCB_GMEO_ERROR_2ND_SHF;
697
698 printk("CM_ERROR=%08lx %s <%s>\n", cm_error,
699 causes[cause], buf);
700 printk("CM_ADDR =%08lx\n", cm_addr);
701 printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]);
702
703 /* reprime cause register */
704 GCMPGCB(GCMEC) = 0;
705 }
706 }
707
708 return retval;
363} 709}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index 2cd8f5734b36..e7cad54936ca 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Carsten Langgaard, carstenl@mips.com 2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
4 * Copyright (C) Dmitri Vorobiev 4 * Copyright (C) 2008 Dmitri Vorobiev
5 * 5 *
6 * This program is free software; you can distribute it and/or modify it 6 * This program is free software; you can distribute it and/or modify it
7 * under the terms of the GNU General Public License (Version 2) as 7 * under the terms of the GNU General Public License (Version 2) as
@@ -36,7 +36,10 @@
36#include <linux/console.h> 36#include <linux/console.h>
37#endif 37#endif
38 38
39struct resource standard_io_resources[] = { 39extern void malta_be_init(void);
40extern int malta_be_handler(struct pt_regs *regs, int is_fixup);
41
42static struct resource standard_io_resources[] = {
40 { 43 {
41 .name = "dma1", 44 .name = "dma1",
42 .start = 0x00, 45 .start = 0x00,
@@ -220,4 +223,7 @@ void __init plat_mem_setup(void)
220 screen_info_setup(); 223 screen_info_setup();
221#endif 224#endif
222 mips_reboot_setup(); 225 mips_reboot_setup();
226
227 board_be_init = malta_be_init;
228 board_be_handler = malta_be_handler;
223} 229}
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index d49fe73426b7..7c7148ef2646 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -39,9 +39,6 @@
39static void __init serial_init(void); 39static void __init serial_init(void);
40unsigned int _isbonito = 0; 40unsigned int _isbonito = 0;
41 41
42extern void __init sanitize_tlb_entries(void);
43
44
45const char *get_system_type(void) 42const char *get_system_type(void)
46{ 43{
47 return "MIPSsim"; 44 return "MIPSsim";
@@ -55,9 +52,6 @@ void __init plat_mem_setup(void)
55 52
56 pr_info("Linux started...\n"); 53 pr_info("Linux started...\n");
57 54
58#ifdef CONFIG_MIPS_MT_SMP
59 sanitize_tlb_entries();
60#endif
61} 55}
62 56
63extern struct plat_smp_ops ssmtc_smp_ops; 57extern struct plat_smp_ops ssmtc_smp_ops;
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index c6f832e0f41c..48731020ca0e 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -4,30 +4,29 @@
4 4
5obj-y += cache.o dma-default.o extable.o fault.o \ 5obj-y += cache.o dma-default.o extable.o fault.o \
6 init.o pgtable.o tlbex.o tlbex-fault.o \ 6 init.o pgtable.o tlbex.o tlbex-fault.o \
7 uasm.o 7 uasm.o page.o
8 8
9obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o 9obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
10obj-$(CONFIG_64BIT) += pgtable-64.o 10obj-$(CONFIG_64BIT) += pgtable-64.o
11obj-$(CONFIG_HIGHMEM) += highmem.o 11obj-$(CONFIG_HIGHMEM) += highmem.o
12 12
13obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 13obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o tlb-r4k.o
14obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 14obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o tlb-r4k.o
15obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 15obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o tlb-r4k.o
16obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 16obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o tlb-r4k.o
17obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 17obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o tlb-r4k.o
18obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o 18obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
19obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 19obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o tlb-r4k.o
20obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 20obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o tlb-r4k.o
21obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 21obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o tlb-r4k.o
22obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 22obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o tlb-r4k.o
23obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o 23obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
24obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 24obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o tlb-r4k.o
25obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 25obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o tlb-r4k.o
26obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o pg-sb1.o \ 26obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
27 tlb-r4k.o 27obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
28obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o 28obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
29obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 29obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
30obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
31 30
32obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o 31obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
33obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o 32obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 77aefb4ebedd..643c8bcffff3 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -14,6 +14,7 @@
14#include <linux/linkage.h> 14#include <linux/linkage.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h>
17#include <linux/bitops.h> 18#include <linux/bitops.h>
18 19
19#include <asm/bcache.h> 20#include <asm/bcache.h>
@@ -53,6 +54,12 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
53 preempt_enable(); 54 preempt_enable();
54} 55}
55 56
57#if defined(CONFIG_MIPS_CMP)
58#define cpu_has_safe_index_cacheops 0
59#else
60#define cpu_has_safe_index_cacheops 1
61#endif
62
56/* 63/*
57 * Must die. 64 * Must die.
58 */ 65 */
@@ -481,6 +488,8 @@ static inline void local_r4k_flush_cache_page(void *args)
481 488
482 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 489 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
483 r4k_blast_dcache_page(addr); 490 r4k_blast_dcache_page(addr);
491 if (exec && !cpu_icache_snoops_remote_store)
492 r4k_blast_scache_page(addr);
484 } 493 }
485 if (exec) { 494 if (exec) {
486 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { 495 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
@@ -583,7 +592,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
583 * subset property so we have to flush the primary caches 592 * subset property so we have to flush the primary caches
584 * explicitly 593 * explicitly
585 */ 594 */
586 if (size >= dcache_size) { 595 if (cpu_has_safe_index_cacheops && size >= dcache_size) {
587 r4k_blast_dcache(); 596 r4k_blast_dcache();
588 } else { 597 } else {
589 R4600_HIT_CACHEOP_WAR_IMPL; 598 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -606,7 +615,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
606 return; 615 return;
607 } 616 }
608 617
609 if (size >= dcache_size) { 618 if (cpu_has_safe_index_cacheops && size >= dcache_size) {
610 r4k_blast_dcache(); 619 r4k_blast_dcache();
611 } else { 620 } else {
612 R4600_HIT_CACHEOP_WAR_IMPL; 621 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -968,6 +977,7 @@ static void __cpuinit probe_pcache(void)
968 case CPU_24K: 977 case CPU_24K:
969 case CPU_34K: 978 case CPU_34K:
970 case CPU_74K: 979 case CPU_74K:
980 case CPU_1004K:
971 if ((read_c0_config7() & (1 << 16))) { 981 if ((read_c0_config7() & (1 << 16))) {
972 /* effectively physically indexed dcache, 982 /* effectively physically indexed dcache,
973 thus no virtual aliases. */ 983 thus no virtual aliases. */
@@ -1216,9 +1226,25 @@ void au1x00_fixup_config_od(void)
1216 } 1226 }
1217} 1227}
1218 1228
1229static int __cpuinitdata cca = -1;
1230
1231static int __init cca_setup(char *str)
1232{
1233 get_option(&str, &cca);
1234
1235 return 1;
1236}
1237
1238__setup("cca=", cca_setup);
1239
1219static void __cpuinit coherency_setup(void) 1240static void __cpuinit coherency_setup(void)
1220{ 1241{
1221 change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); 1242 if (cca < 0 || cca > 7)
1243 cca = read_c0_config() & CONF_CM_CMASK;
1244 _page_cachable_default = cca << _CACHE_SHIFT;
1245
1246 pr_debug("Using cache attribute %d\n", cca);
1247 change_c0_config(CONF_CM_CMASK, cca);
1222 1248
1223 /* 1249 /*
1224 * c0_status.cu=0 specifies that updates by the sc instruction use 1250 * c0_status.cu=0 specifies that updates by the sc instruction use
@@ -1248,6 +1274,20 @@ static void __cpuinit coherency_setup(void)
1248 } 1274 }
1249} 1275}
1250 1276
1277#if defined(CONFIG_DMA_NONCOHERENT)
1278
1279static int __cpuinitdata coherentio;
1280
1281static int __init setcoherentio(char *str)
1282{
1283 coherentio = 1;
1284
1285 return 1;
1286}
1287
1288__setup("coherentio", setcoherentio);
1289#endif
1290
1251void __cpuinit r4k_cache_init(void) 1291void __cpuinit r4k_cache_init(void)
1252{ 1292{
1253 extern void build_clear_page(void); 1293 extern void build_clear_page(void);
@@ -1307,14 +1347,22 @@ void __cpuinit r4k_cache_init(void)
1307 flush_data_cache_page = r4k_flush_data_cache_page; 1347 flush_data_cache_page = r4k_flush_data_cache_page;
1308 flush_icache_range = r4k_flush_icache_range; 1348 flush_icache_range = r4k_flush_icache_range;
1309 1349
1310#ifdef CONFIG_DMA_NONCOHERENT 1350#if defined(CONFIG_DMA_NONCOHERENT)
1311 _dma_cache_wback_inv = r4k_dma_cache_wback_inv; 1351 if (coherentio) {
1312 _dma_cache_wback = r4k_dma_cache_wback_inv; 1352 _dma_cache_wback_inv = (void *)cache_noop;
1313 _dma_cache_inv = r4k_dma_cache_inv; 1353 _dma_cache_wback = (void *)cache_noop;
1354 _dma_cache_inv = (void *)cache_noop;
1355 } else {
1356 _dma_cache_wback_inv = r4k_dma_cache_wback_inv;
1357 _dma_cache_wback = r4k_dma_cache_wback_inv;
1358 _dma_cache_inv = r4k_dma_cache_inv;
1359 }
1314#endif 1360#endif
1315 1361
1316 build_clear_page(); 1362 build_clear_page();
1317 build_copy_page(); 1363 build_copy_page();
1364#if !defined(CONFIG_MIPS_CMP)
1318 local_r4k___flush_cache_all(NULL); 1365 local_r4k___flush_cache_all(NULL);
1366#endif
1319 coherency_setup(); 1367 coherency_setup();
1320} 1368}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index f5903679ee6a..034e8506f6ea 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -130,8 +130,28 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
130 } 130 }
131} 131}
132 132
133static char cache_panic[] __cpuinitdata = 133unsigned long _page_cachable_default;
134 "Yeee, unsupported cache architecture."; 134EXPORT_SYMBOL_GPL(_page_cachable_default);
135
136static inline void setup_protection_map(void)
137{
138 protection_map[0] = PAGE_NONE;
139 protection_map[1] = PAGE_READONLY;
140 protection_map[2] = PAGE_COPY;
141 protection_map[3] = PAGE_COPY;
142 protection_map[4] = PAGE_READONLY;
143 protection_map[5] = PAGE_READONLY;
144 protection_map[6] = PAGE_COPY;
145 protection_map[7] = PAGE_COPY;
146 protection_map[8] = PAGE_NONE;
147 protection_map[9] = PAGE_READONLY;
148 protection_map[10] = PAGE_SHARED;
149 protection_map[11] = PAGE_SHARED;
150 protection_map[12] = PAGE_READONLY;
151 protection_map[13] = PAGE_READONLY;
152 protection_map[14] = PAGE_SHARED;
153 protection_map[15] = PAGE_SHARED;
154}
135 155
136void __devinit cpu_cache_init(void) 156void __devinit cpu_cache_init(void)
137{ 157{
@@ -139,34 +159,29 @@ void __devinit cpu_cache_init(void)
139 extern void __weak r3k_cache_init(void); 159 extern void __weak r3k_cache_init(void);
140 160
141 r3k_cache_init(); 161 r3k_cache_init();
142 return;
143 } 162 }
144 if (cpu_has_6k_cache) { 163 if (cpu_has_6k_cache) {
145 extern void __weak r6k_cache_init(void); 164 extern void __weak r6k_cache_init(void);
146 165
147 r6k_cache_init(); 166 r6k_cache_init();
148 return;
149 } 167 }
150 if (cpu_has_4k_cache) { 168 if (cpu_has_4k_cache) {
151 extern void __weak r4k_cache_init(void); 169 extern void __weak r4k_cache_init(void);
152 170
153 r4k_cache_init(); 171 r4k_cache_init();
154 return;
155 } 172 }
156 if (cpu_has_8k_cache) { 173 if (cpu_has_8k_cache) {
157 extern void __weak r8k_cache_init(void); 174 extern void __weak r8k_cache_init(void);
158 175
159 r8k_cache_init(); 176 r8k_cache_init();
160 return;
161 } 177 }
162 if (cpu_has_tx39_cache) { 178 if (cpu_has_tx39_cache) {
163 extern void __weak tx39_cache_init(void); 179 extern void __weak tx39_cache_init(void);
164 180
165 tx39_cache_init(); 181 tx39_cache_init();
166 return;
167 } 182 }
168 183
169 panic(cache_panic); 184 setup_protection_map();
170} 185}
171 186
172int __weak __uncached_access(struct file *file, unsigned long addr) 187int __weak __uncached_access(struct file *file, unsigned long addr)
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index c7aed133d11d..ecd562d2c348 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -142,7 +142,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
142#endif 142#endif
143 vaddr = __fix_to_virt(FIX_CMAP_END - idx); 143 vaddr = __fix_to_virt(FIX_CMAP_END - idx);
144 pte = mk_pte(page, PAGE_KERNEL); 144 pte = mk_pte(page, PAGE_KERNEL);
145#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) 145#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
146 entrylo = pte.pte_high; 146 entrylo = pte.pte_high;
147#else 147#else
148 entrylo = pte_val(pte) >> 6; 148 entrylo = pte_val(pte) >> 6;
@@ -221,7 +221,7 @@ void copy_user_highpage(struct page *to, struct page *from,
221 copy_page(vto, vfrom); 221 copy_page(vto, vfrom);
222 kunmap_atomic(vfrom, KM_USER0); 222 kunmap_atomic(vfrom, KM_USER0);
223 } 223 }
224 if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) || 224 if ((!cpu_has_ic_fills_f_dc) ||
225 pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) 225 pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
226 flush_data_cache_page((unsigned long)vto); 226 flush_data_cache_page((unsigned long)vto);
227 kunmap_atomic(vto, KM_USER1); 227 kunmap_atomic(vto, KM_USER1);
@@ -229,8 +229,6 @@ void copy_user_highpage(struct page *to, struct page *from,
229 smp_wmb(); 229 smp_wmb();
230} 230}
231 231
232EXPORT_SYMBOL(copy_user_highpage);
233
234void copy_to_user_page(struct vm_area_struct *vma, 232void copy_to_user_page(struct vm_area_struct *vma,
235 struct page *page, unsigned long vaddr, void *dst, const void *src, 233 struct page *page, unsigned long vaddr, void *dst, const void *src,
236 unsigned long len) 234 unsigned long len)
@@ -249,8 +247,6 @@ void copy_to_user_page(struct vm_area_struct *vma,
249 flush_cache_page(vma, vaddr, page_to_pfn(page)); 247 flush_cache_page(vma, vaddr, page_to_pfn(page));
250} 248}
251 249
252EXPORT_SYMBOL(copy_to_user_page);
253
254void copy_from_user_page(struct vm_area_struct *vma, 250void copy_from_user_page(struct vm_area_struct *vma,
255 struct page *page, unsigned long vaddr, void *dst, const void *src, 251 struct page *page, unsigned long vaddr, void *dst, const void *src,
256 unsigned long len) 252 unsigned long len)
@@ -267,9 +263,6 @@ void copy_from_user_page(struct vm_area_struct *vma,
267 } 263 }
268} 264}
269 265
270EXPORT_SYMBOL(copy_from_user_page);
271
272
273#ifdef CONFIG_HIGHMEM 266#ifdef CONFIG_HIGHMEM
274unsigned long highstart_pfn, highend_pfn; 267unsigned long highstart_pfn, highend_pfn;
275 268
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
new file mode 100644
index 000000000000..d827d6144369
--- /dev/null
+++ b/arch/mips/mm/page.c
@@ -0,0 +1,684 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 Maciej W. Rozycki
8 * Copyright (C) 2008 Thiemo Seufer
9 */
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/module.h>
15#include <linux/proc_fs.h>
16
17#include <asm/bugs.h>
18#include <asm/cacheops.h>
19#include <asm/inst.h>
20#include <asm/io.h>
21#include <asm/page.h>
22#include <asm/pgtable.h>
23#include <asm/prefetch.h>
24#include <asm/system.h>
25#include <asm/bootinfo.h>
26#include <asm/mipsregs.h>
27#include <asm/mmu_context.h>
28#include <asm/cpu.h>
29#include <asm/war.h>
30
31#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
32#include <asm/sibyte/sb1250.h>
33#include <asm/sibyte/sb1250_regs.h>
34#include <asm/sibyte/sb1250_dma.h>
35#endif
36
37#include "uasm.h"
38
39/* Registers used in the assembled routines. */
40#define ZERO 0
41#define AT 2
42#define A0 4
43#define A1 5
44#define A2 6
45#define T0 8
46#define T1 9
47#define T2 10
48#define T3 11
49#define T9 25
50#define RA 31
51
52/* Handle labels (which must be positive integers). */
53enum label_id {
54 label_clear_nopref = 1,
55 label_clear_pref,
56 label_copy_nopref,
57 label_copy_pref_both,
58 label_copy_pref_store,
59};
60
61UASM_L_LA(_clear_nopref)
62UASM_L_LA(_clear_pref)
63UASM_L_LA(_copy_nopref)
64UASM_L_LA(_copy_pref_both)
65UASM_L_LA(_copy_pref_store)
66
67/* We need one branch and therefore one relocation per target label. */
68static struct uasm_label __cpuinitdata labels[5];
69static struct uasm_reloc __cpuinitdata relocs[5];
70
71#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
72#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
73
74/*
75 * Maximum sizes:
76 *
77 * R4000 128 bytes S-cache: 0x058 bytes
78 * R4600 v1.7: 0x05c bytes
79 * R4600 v2.0: 0x060 bytes
80 * With prefetching, 16 word strides 0x120 bytes
81 */
82
83static u32 clear_page_array[0x120 / 4];
84
85#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
86void clear_page_cpu(void *page) __attribute__((alias("clear_page_array")));
87#else
88void clear_page(void *page) __attribute__((alias("clear_page_array")));
89#endif
90
91EXPORT_SYMBOL(clear_page);
92
93/*
94 * Maximum sizes:
95 *
96 * R4000 128 bytes S-cache: 0x11c bytes
97 * R4600 v1.7: 0x080 bytes
98 * R4600 v2.0: 0x07c bytes
99 * With prefetching, 16 word strides 0x540 bytes
100 */
101static u32 copy_page_array[0x540 / 4];
102
103#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
104void
105copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array")));
106#else
107void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
108#endif
109
110EXPORT_SYMBOL(copy_page);
111
112
113static int pref_bias_clear_store __cpuinitdata;
114static int pref_bias_copy_load __cpuinitdata;
115static int pref_bias_copy_store __cpuinitdata;
116
117static u32 pref_src_mode __cpuinitdata;
118static u32 pref_dst_mode __cpuinitdata;
119
120static int clear_word_size __cpuinitdata;
121static int copy_word_size __cpuinitdata;
122
123static int half_clear_loop_size __cpuinitdata;
124static int half_copy_loop_size __cpuinitdata;
125
126static int cache_line_size __cpuinitdata;
127#define cache_line_mask() (cache_line_size - 1)
128
129static inline void __cpuinit
130pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
131{
132 if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
133 if (off > 0x7fff) {
134 uasm_i_lui(buf, T9, uasm_rel_hi(off));
135 uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
136 } else
137 uasm_i_addiu(buf, T9, ZERO, off);
138 uasm_i_daddu(buf, reg1, reg2, T9);
139 } else {
140 if (off > 0x7fff) {
141 uasm_i_lui(buf, T9, uasm_rel_hi(off));
142 uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
143 UASM_i_ADDU(buf, reg1, reg2, T9);
144 } else
145 UASM_i_ADDIU(buf, reg1, reg2, off);
146 }
147}
148
149static void __cpuinit set_prefetch_parameters(void)
150{
151 if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg)
152 clear_word_size = 8;
153 else
154 clear_word_size = 4;
155
156 if (cpu_has_64bit_gp_regs)
157 copy_word_size = 8;
158 else
159 copy_word_size = 4;
160
161 /*
162 * The pref's used here are using "streaming" hints, which cause the
163 * copied data to be kicked out of the cache sooner. A page copy often
164 * ends up copying a lot more data than is commonly used, so this seems
165 * to make sense in terms of reducing cache pollution, but I've no real
166 * performance data to back this up.
167 */
168 if (cpu_has_prefetch) {
169 /*
170 * XXX: Most prefetch bias values in here are based on
171 * guesswork.
172 */
173 cache_line_size = cpu_dcache_line_size();
174 switch (current_cpu_type()) {
175 case CPU_TX49XX:
176 /* TX49 supports only Pref_Load */
177 pref_bias_copy_load = 256;
178 break;
179
180 case CPU_RM9000:
181 /*
182 * As a workaround for erratum G105 which make the
183 * PrepareForStore hint unusable we fall back to
184 * StoreRetained on the RM9000. Once it is known which
185 * versions of the RM9000 we'll be able to condition-
186 * alize this.
187 */
188
189 case CPU_R10000:
190 case CPU_R12000:
191 case CPU_R14000:
192 /*
193 * Those values have been experimentally tuned for an
194 * Origin 200.
195 */
196 pref_bias_clear_store = 512;
197 pref_bias_copy_load = 256;
198 pref_bias_copy_store = 256;
199 pref_src_mode = Pref_LoadStreamed;
200 pref_dst_mode = Pref_StoreStreamed;
201 break;
202
203 case CPU_SB1:
204 case CPU_SB1A:
205 pref_bias_clear_store = 128;
206 pref_bias_copy_load = 128;
207 pref_bias_copy_store = 128;
208 /*
209 * SB1 pass1 Pref_LoadStreamed/Pref_StoreStreamed
210 * hints are broken.
211 */
212 if (current_cpu_type() == CPU_SB1 &&
213 (current_cpu_data.processor_id & 0xff) < 0x02) {
214 pref_src_mode = Pref_Load;
215 pref_dst_mode = Pref_Store;
216 } else {
217 pref_src_mode = Pref_LoadStreamed;
218 pref_dst_mode = Pref_StoreStreamed;
219 }
220 break;
221
222 default:
223 pref_bias_clear_store = 128;
224 pref_bias_copy_load = 256;
225 pref_bias_copy_store = 128;
226 pref_src_mode = Pref_LoadStreamed;
227 pref_dst_mode = Pref_PrepareForStore;
228 break;
229 }
230 } else {
231 if (cpu_has_cache_cdex_s)
232 cache_line_size = cpu_scache_line_size();
233 else if (cpu_has_cache_cdex_p)
234 cache_line_size = cpu_dcache_line_size();
235 }
236 /*
237 * Too much unrolling will overflow the available space in
238 * clear_space_array / copy_page_array. 8 words sounds generous,
239 * but a R4000 with 128 byte L2 line length can exceed even that.
240 */
241 half_clear_loop_size = min(8 * clear_word_size,
242 max(cache_line_size >> 1,
243 4 * clear_word_size));
244 half_copy_loop_size = min(8 * copy_word_size,
245 max(cache_line_size >> 1,
246 4 * copy_word_size));
247}
248
249static void __cpuinit build_clear_store(u32 **buf, int off)
250{
251 if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
252 uasm_i_sd(buf, ZERO, off, A0);
253 } else {
254 uasm_i_sw(buf, ZERO, off, A0);
255 }
256}
257
258static inline void __cpuinit build_clear_pref(u32 **buf, int off)
259{
260 if (off & cache_line_mask())
261 return;
262
263 if (pref_bias_clear_store) {
264 uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off,
265 A0);
266 } else if (cpu_has_cache_cdex_s) {
267 uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
268 } else if (cpu_has_cache_cdex_p) {
269 if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
270 uasm_i_nop(buf);
271 uasm_i_nop(buf);
272 uasm_i_nop(buf);
273 uasm_i_nop(buf);
274 }
275
276 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
277 uasm_i_lw(buf, ZERO, ZERO, AT);
278
279 uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
280 }
281}
282
283void __cpuinit build_clear_page(void)
284{
285 int off;
286 u32 *buf = (u32 *)&clear_page_array;
287 struct uasm_label *l = labels;
288 struct uasm_reloc *r = relocs;
289 int i;
290
291 memset(labels, 0, sizeof(labels));
292 memset(relocs, 0, sizeof(relocs));
293
294 set_prefetch_parameters();
295
296 /*
297 * This algorithm makes the following assumptions:
298 * - The prefetch bias is a multiple of 2 words.
299 * - The prefetch bias is less than one page.
300 */
301 BUG_ON(pref_bias_clear_store % (2 * clear_word_size));
302 BUG_ON(PAGE_SIZE < pref_bias_clear_store);
303
304 off = PAGE_SIZE - pref_bias_clear_store;
305 if (off > 0xffff || !pref_bias_clear_store)
306 pg_addiu(&buf, A2, A0, off);
307 else
308 uasm_i_ori(&buf, A2, A0, off);
309
310 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
311 uasm_i_lui(&buf, AT, 0xa000);
312
313 off = min(8, pref_bias_clear_store / cache_line_size) *
314 cache_line_size;
315 while (off) {
316 build_clear_pref(&buf, -off);
317 off -= cache_line_size;
318 }
319 uasm_l_clear_pref(&l, buf);
320 do {
321 build_clear_pref(&buf, off);
322 build_clear_store(&buf, off);
323 off += clear_word_size;
324 } while (off < half_clear_loop_size);
325 pg_addiu(&buf, A0, A0, 2 * off);
326 off = -off;
327 do {
328 build_clear_pref(&buf, off);
329 if (off == -clear_word_size)
330 uasm_il_bne(&buf, &r, A0, A2, label_clear_pref);
331 build_clear_store(&buf, off);
332 off += clear_word_size;
333 } while (off < 0);
334
335 if (pref_bias_clear_store) {
336 pg_addiu(&buf, A2, A0, pref_bias_clear_store);
337 uasm_l_clear_nopref(&l, buf);
338 off = 0;
339 do {
340 build_clear_store(&buf, off);
341 off += clear_word_size;
342 } while (off < half_clear_loop_size);
343 pg_addiu(&buf, A0, A0, 2 * off);
344 off = -off;
345 do {
346 if (off == -clear_word_size)
347 uasm_il_bne(&buf, &r, A0, A2,
348 label_clear_nopref);
349 build_clear_store(&buf, off);
350 off += clear_word_size;
351 } while (off < 0);
352 }
353
354 uasm_i_jr(&buf, RA);
355 uasm_i_nop(&buf);
356
357 BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array));
358
359 uasm_resolve_relocs(relocs, labels);
360
361 pr_debug("Synthesized clear page handler (%u instructions).\n",
362 (u32)(buf - clear_page_array));
363
364 pr_debug("\t.set push\n");
365 pr_debug("\t.set noreorder\n");
366 for (i = 0; i < (buf - clear_page_array); i++)
367 pr_debug("\t.word 0x%08x\n", clear_page_array[i]);
368 pr_debug("\t.set pop\n");
369}
370
371static void __cpuinit build_copy_load(u32 **buf, int reg, int off)
372{
373 if (cpu_has_64bit_gp_regs) {
374 uasm_i_ld(buf, reg, off, A1);
375 } else {
376 uasm_i_lw(buf, reg, off, A1);
377 }
378}
379
380static void __cpuinit build_copy_store(u32 **buf, int reg, int off)
381{
382 if (cpu_has_64bit_gp_regs) {
383 uasm_i_sd(buf, reg, off, A0);
384 } else {
385 uasm_i_sw(buf, reg, off, A0);
386 }
387}
388
389static inline void build_copy_load_pref(u32 **buf, int off)
390{
391 if (off & cache_line_mask())
392 return;
393
394 if (pref_bias_copy_load)
395 uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, A1);
396}
397
398static inline void build_copy_store_pref(u32 **buf, int off)
399{
400 if (off & cache_line_mask())
401 return;
402
403 if (pref_bias_copy_store) {
404 uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off,
405 A0);
406 } else if (cpu_has_cache_cdex_s) {
407 uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
408 } else if (cpu_has_cache_cdex_p) {
409 if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
410 uasm_i_nop(buf);
411 uasm_i_nop(buf);
412 uasm_i_nop(buf);
413 uasm_i_nop(buf);
414 }
415
416 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
417 uasm_i_lw(buf, ZERO, ZERO, AT);
418
419 uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
420 }
421}
422
423void __cpuinit build_copy_page(void)
424{
425 int off;
426 u32 *buf = (u32 *)&copy_page_array;
427 struct uasm_label *l = labels;
428 struct uasm_reloc *r = relocs;
429 int i;
430
431 memset(labels, 0, sizeof(labels));
432 memset(relocs, 0, sizeof(relocs));
433
434 set_prefetch_parameters();
435
436 /*
437 * This algorithm makes the following assumptions:
438 * - All prefetch biases are multiples of 8 words.
439 * - The prefetch biases are less than one page.
440 * - The store prefetch bias isn't greater than the load
441 * prefetch bias.
442 */
443 BUG_ON(pref_bias_copy_load % (8 * copy_word_size));
444 BUG_ON(pref_bias_copy_store % (8 * copy_word_size));
445 BUG_ON(PAGE_SIZE < pref_bias_copy_load);
446 BUG_ON(pref_bias_copy_store > pref_bias_copy_load);
447
448 off = PAGE_SIZE - pref_bias_copy_load;
449 if (off > 0xffff || !pref_bias_copy_load)
450 pg_addiu(&buf, A2, A0, off);
451 else
452 uasm_i_ori(&buf, A2, A0, off);
453
454 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
455 uasm_i_lui(&buf, AT, 0xa000);
456
457 off = min(8, pref_bias_copy_load / cache_line_size) * cache_line_size;
458 while (off) {
459 build_copy_load_pref(&buf, -off);
460 off -= cache_line_size;
461 }
462 off = min(8, pref_bias_copy_store / cache_line_size) * cache_line_size;
463 while (off) {
464 build_copy_store_pref(&buf, -off);
465 off -= cache_line_size;
466 }
467 uasm_l_copy_pref_both(&l, buf);
468 do {
469 build_copy_load_pref(&buf, off);
470 build_copy_load(&buf, T0, off);
471 build_copy_load_pref(&buf, off + copy_word_size);
472 build_copy_load(&buf, T1, off + copy_word_size);
473 build_copy_load_pref(&buf, off + 2 * copy_word_size);
474 build_copy_load(&buf, T2, off + 2 * copy_word_size);
475 build_copy_load_pref(&buf, off + 3 * copy_word_size);
476 build_copy_load(&buf, T3, off + 3 * copy_word_size);
477 build_copy_store_pref(&buf, off);
478 build_copy_store(&buf, T0, off);
479 build_copy_store_pref(&buf, off + copy_word_size);
480 build_copy_store(&buf, T1, off + copy_word_size);
481 build_copy_store_pref(&buf, off + 2 * copy_word_size);
482 build_copy_store(&buf, T2, off + 2 * copy_word_size);
483 build_copy_store_pref(&buf, off + 3 * copy_word_size);
484 build_copy_store(&buf, T3, off + 3 * copy_word_size);
485 off += 4 * copy_word_size;
486 } while (off < half_copy_loop_size);
487 pg_addiu(&buf, A1, A1, 2 * off);
488 pg_addiu(&buf, A0, A0, 2 * off);
489 off = -off;
490 do {
491 build_copy_load_pref(&buf, off);
492 build_copy_load(&buf, T0, off);
493 build_copy_load_pref(&buf, off + copy_word_size);
494 build_copy_load(&buf, T1, off + copy_word_size);
495 build_copy_load_pref(&buf, off + 2 * copy_word_size);
496 build_copy_load(&buf, T2, off + 2 * copy_word_size);
497 build_copy_load_pref(&buf, off + 3 * copy_word_size);
498 build_copy_load(&buf, T3, off + 3 * copy_word_size);
499 build_copy_store_pref(&buf, off);
500 build_copy_store(&buf, T0, off);
501 build_copy_store_pref(&buf, off + copy_word_size);
502 build_copy_store(&buf, T1, off + copy_word_size);
503 build_copy_store_pref(&buf, off + 2 * copy_word_size);
504 build_copy_store(&buf, T2, off + 2 * copy_word_size);
505 build_copy_store_pref(&buf, off + 3 * copy_word_size);
506 if (off == -(4 * copy_word_size))
507 uasm_il_bne(&buf, &r, A2, A0, label_copy_pref_both);
508 build_copy_store(&buf, T3, off + 3 * copy_word_size);
509 off += 4 * copy_word_size;
510 } while (off < 0);
511
512 if (pref_bias_copy_load - pref_bias_copy_store) {
513 pg_addiu(&buf, A2, A0,
514 pref_bias_copy_load - pref_bias_copy_store);
515 uasm_l_copy_pref_store(&l, buf);
516 off = 0;
517 do {
518 build_copy_load(&buf, T0, off);
519 build_copy_load(&buf, T1, off + copy_word_size);
520 build_copy_load(&buf, T2, off + 2 * copy_word_size);
521 build_copy_load(&buf, T3, off + 3 * copy_word_size);
522 build_copy_store_pref(&buf, off);
523 build_copy_store(&buf, T0, off);
524 build_copy_store_pref(&buf, off + copy_word_size);
525 build_copy_store(&buf, T1, off + copy_word_size);
526 build_copy_store_pref(&buf, off + 2 * copy_word_size);
527 build_copy_store(&buf, T2, off + 2 * copy_word_size);
528 build_copy_store_pref(&buf, off + 3 * copy_word_size);
529 build_copy_store(&buf, T3, off + 3 * copy_word_size);
530 off += 4 * copy_word_size;
531 } while (off < half_copy_loop_size);
532 pg_addiu(&buf, A1, A1, 2 * off);
533 pg_addiu(&buf, A0, A0, 2 * off);
534 off = -off;
535 do {
536 build_copy_load(&buf, T0, off);
537 build_copy_load(&buf, T1, off + copy_word_size);
538 build_copy_load(&buf, T2, off + 2 * copy_word_size);
539 build_copy_load(&buf, T3, off + 3 * copy_word_size);
540 build_copy_store_pref(&buf, off);
541 build_copy_store(&buf, T0, off);
542 build_copy_store_pref(&buf, off + copy_word_size);
543 build_copy_store(&buf, T1, off + copy_word_size);
544 build_copy_store_pref(&buf, off + 2 * copy_word_size);
545 build_copy_store(&buf, T2, off + 2 * copy_word_size);
546 build_copy_store_pref(&buf, off + 3 * copy_word_size);
547 if (off == -(4 * copy_word_size))
548 uasm_il_bne(&buf, &r, A2, A0,
549 label_copy_pref_store);
550 build_copy_store(&buf, T3, off + 3 * copy_word_size);
551 off += 4 * copy_word_size;
552 } while (off < 0);
553 }
554
555 if (pref_bias_copy_store) {
556 pg_addiu(&buf, A2, A0, pref_bias_copy_store);
557 uasm_l_copy_nopref(&l, buf);
558 off = 0;
559 do {
560 build_copy_load(&buf, T0, off);
561 build_copy_load(&buf, T1, off + copy_word_size);
562 build_copy_load(&buf, T2, off + 2 * copy_word_size);
563 build_copy_load(&buf, T3, off + 3 * copy_word_size);
564 build_copy_store(&buf, T0, off);
565 build_copy_store(&buf, T1, off + copy_word_size);
566 build_copy_store(&buf, T2, off + 2 * copy_word_size);
567 build_copy_store(&buf, T3, off + 3 * copy_word_size);
568 off += 4 * copy_word_size;
569 } while (off < half_copy_loop_size);
570 pg_addiu(&buf, A1, A1, 2 * off);
571 pg_addiu(&buf, A0, A0, 2 * off);
572 off = -off;
573 do {
574 build_copy_load(&buf, T0, off);
575 build_copy_load(&buf, T1, off + copy_word_size);
576 build_copy_load(&buf, T2, off + 2 * copy_word_size);
577 build_copy_load(&buf, T3, off + 3 * copy_word_size);
578 build_copy_store(&buf, T0, off);
579 build_copy_store(&buf, T1, off + copy_word_size);
580 build_copy_store(&buf, T2, off + 2 * copy_word_size);
581 if (off == -(4 * copy_word_size))
582 uasm_il_bne(&buf, &r, A2, A0,
583 label_copy_nopref);
584 build_copy_store(&buf, T3, off + 3 * copy_word_size);
585 off += 4 * copy_word_size;
586 } while (off < 0);
587 }
588
589 uasm_i_jr(&buf, RA);
590 uasm_i_nop(&buf);
591
592 BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array));
593
594 uasm_resolve_relocs(relocs, labels);
595
596 pr_debug("Synthesized copy page handler (%u instructions).\n",
597 (u32)(buf - copy_page_array));
598
599 pr_debug("\t.set push\n");
600 pr_debug("\t.set noreorder\n");
601 for (i = 0; i < (buf - copy_page_array); i++)
602 pr_debug("\t.word 0x%08x\n", copy_page_array[i]);
603 pr_debug("\t.set pop\n");
604}
605
606#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
607
608/*
609 * Pad descriptors to cacheline, since each is exclusively owned by a
610 * particular CPU.
611 */
612struct dmadscr {
613 u64 dscr_a;
614 u64 dscr_b;
615 u64 pad_a;
616 u64 pad_b;
617} ____cacheline_aligned_in_smp page_descr[DM_NUM_CHANNELS];
618
619void sb1_dma_init(void)
620{
621 int i;
622
623 for (i = 0; i < DM_NUM_CHANNELS; i++) {
624 const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
625 V_DM_DSCR_BASE_RINGSZ(1);
626 void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
627
628 __raw_writeq(base_val, base_reg);
629 __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
630 __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
631 }
632}
633
634void clear_page(void *page)
635{
636 u64 to_phys = CPHYSADDR((unsigned long)page);
637 unsigned int cpu = smp_processor_id();
638
639 /* if the page is not in KSEG0, use old way */
640 if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
641 return clear_page_cpu(page);
642
643 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
644 M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
645 page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
646 __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
647
648 /*
649 * Don't really want to do it this way, but there's no
650 * reliable way to delay completion detection.
651 */
652 while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
653 & M_DM_DSCR_BASE_INTERRUPT))
654 ;
655 __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
656}
657
658void copy_page(void *to, void *from)
659{
660 u64 from_phys = CPHYSADDR((unsigned long)from);
661 u64 to_phys = CPHYSADDR((unsigned long)to);
662 unsigned int cpu = smp_processor_id();
663
664 /* if any page is not in KSEG0, use old way */
665 if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
666 || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
667 return copy_page_cpu(to, from);
668
669 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
670 M_DM_DSCRA_INTERRUPT;
671 page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
672 __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
673
674 /*
675 * Don't really want to do it this way, but there's no
676 * reliable way to delay completion detection.
677 */
678 while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
679 & M_DM_DSCR_BASE_INTERRUPT))
680 ;
681 __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
682}
683
684#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
deleted file mode 100644
index 455dedb5b39e..000000000000
--- a/arch/mips/mm/pg-r4k.c
+++ /dev/null
@@ -1,534 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 Maciej W. Rozycki
8 */
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/module.h>
14#include <linux/proc_fs.h>
15
16#include <asm/bugs.h>
17#include <asm/cacheops.h>
18#include <asm/inst.h>
19#include <asm/io.h>
20#include <asm/page.h>
21#include <asm/pgtable.h>
22#include <asm/prefetch.h>
23#include <asm/system.h>
24#include <asm/bootinfo.h>
25#include <asm/mipsregs.h>
26#include <asm/mmu_context.h>
27#include <asm/cpu.h>
28#include <asm/war.h>
29
30#define half_scache_line_size() (cpu_scache_line_size() >> 1)
31#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
32#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
33
34
35/*
36 * Maximum sizes:
37 *
38 * R4000 128 bytes S-cache: 0x58 bytes
39 * R4600 v1.7: 0x5c bytes
40 * R4600 v2.0: 0x60 bytes
41 * With prefetching, 16 byte strides 0xa0 bytes
42 */
43
44static unsigned int clear_page_array[0x130 / 4];
45
46void clear_page(void * page) __attribute__((alias("clear_page_array")));
47
48EXPORT_SYMBOL(clear_page);
49
50/*
51 * Maximum sizes:
52 *
53 * R4000 128 bytes S-cache: 0x11c bytes
54 * R4600 v1.7: 0x080 bytes
55 * R4600 v2.0: 0x07c bytes
56 * With prefetching, 16 byte strides 0x0b8 bytes
57 */
58static unsigned int copy_page_array[0x148 / 4];
59
60void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
61
62EXPORT_SYMBOL(copy_page);
63
64/*
65 * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
66 * with 64-bit kernels. The prefetch offsets have been experimentally tuned
67 * an Origin 200.
68 */
69static int pref_offset_clear __cpuinitdata = 512;
70static int pref_offset_copy __cpuinitdata = 256;
71
72static unsigned int pref_src_mode __cpuinitdata;
73static unsigned int pref_dst_mode __cpuinitdata;
74
75static int load_offset __cpuinitdata;
76static int store_offset __cpuinitdata;
77
78static unsigned int __cpuinitdata *dest, *epc;
79
80static unsigned int instruction_pending;
81static union mips_instruction delayed_mi;
82
83static void __cpuinit emit_instruction(union mips_instruction mi)
84{
85 if (instruction_pending)
86 *epc++ = delayed_mi.word;
87
88 instruction_pending = 1;
89 delayed_mi = mi;
90}
91
92static inline void flush_delay_slot_or_nop(void)
93{
94 if (instruction_pending) {
95 *epc++ = delayed_mi.word;
96 instruction_pending = 0;
97 return;
98 }
99
100 *epc++ = 0;
101}
102
103static inline unsigned int *label(void)
104{
105 if (instruction_pending) {
106 *epc++ = delayed_mi.word;
107 instruction_pending = 0;
108 }
109
110 return epc;
111}
112
113static inline void build_insn_word(unsigned int word)
114{
115 union mips_instruction mi;
116
117 mi.word = word;
118
119 emit_instruction(mi);
120}
121
122static inline void build_nop(void)
123{
124 build_insn_word(0); /* nop */
125}
126
127static inline void build_src_pref(int advance)
128{
129 if (!(load_offset & (cpu_dcache_line_size() - 1)) && advance) {
130 union mips_instruction mi;
131
132 mi.i_format.opcode = pref_op;
133 mi.i_format.rs = 5; /* $a1 */
134 mi.i_format.rt = pref_src_mode;
135 mi.i_format.simmediate = load_offset + advance;
136
137 emit_instruction(mi);
138 }
139}
140
141static inline void __build_load_reg(int reg)
142{
143 union mips_instruction mi;
144 unsigned int width;
145
146 if (cpu_has_64bit_gp_regs) {
147 mi.i_format.opcode = ld_op;
148 width = 8;
149 } else {
150 mi.i_format.opcode = lw_op;
151 width = 4;
152 }
153 mi.i_format.rs = 5; /* $a1 */
154 mi.i_format.rt = reg; /* $reg */
155 mi.i_format.simmediate = load_offset;
156
157 load_offset += width;
158 emit_instruction(mi);
159}
160
161static inline void build_load_reg(int reg)
162{
163 if (cpu_has_prefetch)
164 build_src_pref(pref_offset_copy);
165
166 __build_load_reg(reg);
167}
168
169static inline void build_dst_pref(int advance)
170{
171 if (!(store_offset & (cpu_dcache_line_size() - 1)) && advance) {
172 union mips_instruction mi;
173
174 mi.i_format.opcode = pref_op;
175 mi.i_format.rs = 4; /* $a0 */
176 mi.i_format.rt = pref_dst_mode;
177 mi.i_format.simmediate = store_offset + advance;
178
179 emit_instruction(mi);
180 }
181}
182
183static inline void build_cdex_s(void)
184{
185 union mips_instruction mi;
186
187 if ((store_offset & (cpu_scache_line_size() - 1)))
188 return;
189
190 mi.c_format.opcode = cache_op;
191 mi.c_format.rs = 4; /* $a0 */
192 mi.c_format.c_op = 3; /* Create Dirty Exclusive */
193 mi.c_format.cache = 3; /* Secondary Data Cache */
194 mi.c_format.simmediate = store_offset;
195
196 emit_instruction(mi);
197}
198
199static inline void build_cdex_p(void)
200{
201 union mips_instruction mi;
202
203 if (store_offset & (cpu_dcache_line_size() - 1))
204 return;
205
206 if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
207 build_nop();
208 build_nop();
209 build_nop();
210 build_nop();
211 }
212
213 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
214 build_insn_word(0x8c200000); /* lw $zero, ($at) */
215
216 mi.c_format.opcode = cache_op;
217 mi.c_format.rs = 4; /* $a0 */
218 mi.c_format.c_op = 3; /* Create Dirty Exclusive */
219 mi.c_format.cache = 1; /* Data Cache */
220 mi.c_format.simmediate = store_offset;
221
222 emit_instruction(mi);
223}
224
225static void __cpuinit __build_store_reg(int reg)
226{
227 union mips_instruction mi;
228 unsigned int width;
229
230 if (cpu_has_64bit_gp_regs ||
231 (cpu_has_64bit_zero_reg && reg == 0)) {
232 mi.i_format.opcode = sd_op;
233 width = 8;
234 } else {
235 mi.i_format.opcode = sw_op;
236 width = 4;
237 }
238 mi.i_format.rs = 4; /* $a0 */
239 mi.i_format.rt = reg; /* $reg */
240 mi.i_format.simmediate = store_offset;
241
242 store_offset += width;
243 emit_instruction(mi);
244}
245
246static inline void build_store_reg(int reg)
247{
248 int pref_off = cpu_has_prefetch ?
249 (reg ? pref_offset_copy : pref_offset_clear) : 0;
250 if (pref_off)
251 build_dst_pref(pref_off);
252 else if (cpu_has_cache_cdex_s)
253 build_cdex_s();
254 else if (cpu_has_cache_cdex_p)
255 build_cdex_p();
256
257 __build_store_reg(reg);
258}
259
260static inline void build_addiu_rt_rs(unsigned int rt, unsigned int rs,
261 unsigned long offset)
262{
263 union mips_instruction mi;
264
265 BUG_ON(offset > 0x7fff);
266
267 if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
268 mi.i_format.opcode = addiu_op;
269 mi.i_format.rs = 0; /* $zero */
270 mi.i_format.rt = 25; /* $t9 */
271 mi.i_format.simmediate = offset;
272 emit_instruction(mi);
273
274 mi.r_format.opcode = spec_op;
275 mi.r_format.rs = rs;
276 mi.r_format.rt = 25; /* $t9 */
277 mi.r_format.rd = rt;
278 mi.r_format.re = 0;
279 mi.r_format.func = daddu_op;
280 } else {
281 mi.i_format.opcode = cpu_has_64bit_gp_regs ?
282 daddiu_op : addiu_op;
283 mi.i_format.rs = rs;
284 mi.i_format.rt = rt;
285 mi.i_format.simmediate = offset;
286 }
287 emit_instruction(mi);
288}
289
290static inline void build_addiu_a2_a0(unsigned long offset)
291{
292 build_addiu_rt_rs(6, 4, offset); /* $a2, $a0, offset */
293}
294
295static inline void build_addiu_a2(unsigned long offset)
296{
297 build_addiu_rt_rs(6, 6, offset); /* $a2, $a2, offset */
298}
299
300static inline void build_addiu_a1(unsigned long offset)
301{
302 build_addiu_rt_rs(5, 5, offset); /* $a1, $a1, offset */
303
304 load_offset -= offset;
305}
306
307static inline void build_addiu_a0(unsigned long offset)
308{
309 build_addiu_rt_rs(4, 4, offset); /* $a0, $a0, offset */
310
311 store_offset -= offset;
312}
313
314static inline void build_bne(unsigned int *dest)
315{
316 union mips_instruction mi;
317
318 mi.i_format.opcode = bne_op;
319 mi.i_format.rs = 6; /* $a2 */
320 mi.i_format.rt = 4; /* $a0 */
321 mi.i_format.simmediate = dest - epc - 1;
322
323 *epc++ = mi.word;
324 flush_delay_slot_or_nop();
325}
326
327static inline void build_jr_ra(void)
328{
329 union mips_instruction mi;
330
331 mi.r_format.opcode = spec_op;
332 mi.r_format.rs = 31;
333 mi.r_format.rt = 0;
334 mi.r_format.rd = 0;
335 mi.r_format.re = 0;
336 mi.r_format.func = jr_op;
337
338 *epc++ = mi.word;
339 flush_delay_slot_or_nop();
340}
341
342void __cpuinit build_clear_page(void)
343{
344 unsigned int loop_start;
345 unsigned long off;
346 int i;
347
348 epc = (unsigned int *) &clear_page_array;
349 instruction_pending = 0;
350 store_offset = 0;
351
352 if (cpu_has_prefetch) {
353 switch (current_cpu_type()) {
354 case CPU_TX49XX:
355 /* TX49 supports only Pref_Load */
356 pref_offset_clear = 0;
357 pref_offset_copy = 0;
358 break;
359
360 case CPU_RM9000:
361 /*
362 * As a workaround for erratum G105 which make the
363 * PrepareForStore hint unusable we fall back to
364 * StoreRetained on the RM9000. Once it is known which
365 * versions of the RM9000 we'll be able to condition-
366 * alize this.
367 */
368
369 case CPU_R10000:
370 case CPU_R12000:
371 case CPU_R14000:
372 pref_src_mode = Pref_LoadStreamed;
373 pref_dst_mode = Pref_StoreStreamed;
374 break;
375
376 default:
377 pref_src_mode = Pref_LoadStreamed;
378 pref_dst_mode = Pref_PrepareForStore;
379 break;
380 }
381 }
382
383 off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
384 if (off > 0x7fff) {
385 build_addiu_a2_a0(off >> 1);
386 build_addiu_a2(off >> 1);
387 } else
388 build_addiu_a2_a0(off);
389
390 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
391 build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
392
393dest = label();
394 do {
395 build_store_reg(0);
396 build_store_reg(0);
397 build_store_reg(0);
398 build_store_reg(0);
399 } while (store_offset < half_scache_line_size());
400 build_addiu_a0(2 * store_offset);
401 loop_start = store_offset;
402 do {
403 build_store_reg(0);
404 build_store_reg(0);
405 build_store_reg(0);
406 build_store_reg(0);
407 } while ((store_offset - loop_start) < half_scache_line_size());
408 build_bne(dest);
409
410 if (cpu_has_prefetch && pref_offset_clear) {
411 build_addiu_a2_a0(pref_offset_clear);
412 dest = label();
413 loop_start = store_offset;
414 do {
415 __build_store_reg(0);
416 __build_store_reg(0);
417 __build_store_reg(0);
418 __build_store_reg(0);
419 } while ((store_offset - loop_start) < half_scache_line_size());
420 build_addiu_a0(2 * store_offset);
421 loop_start = store_offset;
422 do {
423 __build_store_reg(0);
424 __build_store_reg(0);
425 __build_store_reg(0);
426 __build_store_reg(0);
427 } while ((store_offset - loop_start) < half_scache_line_size());
428 build_bne(dest);
429 }
430
431 build_jr_ra();
432
433 BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
434
435 pr_info("Synthesized clear page handler (%u instructions).\n",
436 (unsigned int)(epc - clear_page_array));
437
438 pr_debug("\t.set push\n");
439 pr_debug("\t.set noreorder\n");
440 for (i = 0; i < (epc - clear_page_array); i++)
441 pr_debug("\t.word 0x%08x\n", clear_page_array[i]);
442 pr_debug("\t.set pop\n");
443}
444
445void __cpuinit build_copy_page(void)
446{
447 unsigned int loop_start;
448 unsigned long off;
449 int i;
450
451 epc = (unsigned int *) &copy_page_array;
452 store_offset = load_offset = 0;
453 instruction_pending = 0;
454
455 off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
456 if (off > 0x7fff) {
457 build_addiu_a2_a0(off >> 1);
458 build_addiu_a2(off >> 1);
459 } else
460 build_addiu_a2_a0(off);
461
462 if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
463 build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
464
465dest = label();
466 loop_start = store_offset;
467 do {
468 build_load_reg( 8);
469 build_load_reg( 9);
470 build_load_reg(10);
471 build_load_reg(11);
472 build_store_reg( 8);
473 build_store_reg( 9);
474 build_store_reg(10);
475 build_store_reg(11);
476 } while ((store_offset - loop_start) < half_scache_line_size());
477 build_addiu_a0(2 * store_offset);
478 build_addiu_a1(2 * load_offset);
479 loop_start = store_offset;
480 do {
481 build_load_reg( 8);
482 build_load_reg( 9);
483 build_load_reg(10);
484 build_load_reg(11);
485 build_store_reg( 8);
486 build_store_reg( 9);
487 build_store_reg(10);
488 build_store_reg(11);
489 } while ((store_offset - loop_start) < half_scache_line_size());
490 build_bne(dest);
491
492 if (cpu_has_prefetch && pref_offset_copy) {
493 build_addiu_a2_a0(pref_offset_copy);
494 dest = label();
495 loop_start = store_offset;
496 do {
497 __build_load_reg( 8);
498 __build_load_reg( 9);
499 __build_load_reg(10);
500 __build_load_reg(11);
501 __build_store_reg( 8);
502 __build_store_reg( 9);
503 __build_store_reg(10);
504 __build_store_reg(11);
505 } while ((store_offset - loop_start) < half_scache_line_size());
506 build_addiu_a0(2 * store_offset);
507 build_addiu_a1(2 * load_offset);
508 loop_start = store_offset;
509 do {
510 __build_load_reg( 8);
511 __build_load_reg( 9);
512 __build_load_reg(10);
513 __build_load_reg(11);
514 __build_store_reg( 8);
515 __build_store_reg( 9);
516 __build_store_reg(10);
517 __build_store_reg(11);
518 } while ((store_offset - loop_start) < half_scache_line_size());
519 build_bne(dest);
520 }
521
522 build_jr_ra();
523
524 BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
525
526 pr_info("Synthesized copy page handler (%u instructions).\n",
527 (unsigned int)(epc - copy_page_array));
528
529 pr_debug("\t.set push\n");
530 pr_debug("\t.set noreorder\n");
531 for (i = 0; i < (epc - copy_page_array); i++)
532 pr_debug("\t.word 0x%08x\n", copy_page_array[i]);
533 pr_debug("\t.set pop\n");
534}
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
deleted file mode 100644
index 49e289d05414..000000000000
--- a/arch/mips/mm/pg-sb1.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
3 * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
4 * Copyright (C) 2000 SiByte, Inc.
5 * Copyright (C) 2005 Thiemo Seufer
6 *
7 * Written by Justin Carlson of SiByte, Inc.
8 * and Kip Walker of Broadcom Corp.
9 *
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25#include <linux/module.h>
26#include <linux/sched.h>
27#include <linux/smp.h>
28
29#include <asm/io.h>
30#include <asm/sibyte/sb1250.h>
31#include <asm/sibyte/sb1250_regs.h>
32#include <asm/sibyte/sb1250_dma.h>
33
34#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
35#define SB1_PREF_LOAD_STREAMED_HINT "0"
36#define SB1_PREF_STORE_STREAMED_HINT "1"
37#else
38#define SB1_PREF_LOAD_STREAMED_HINT "4"
39#define SB1_PREF_STORE_STREAMED_HINT "5"
40#endif
41
42static inline void clear_page_cpu(void *page)
43{
44 unsigned char *addr = (unsigned char *) page;
45 unsigned char *end = addr + PAGE_SIZE;
46
47 /*
48 * JDCXXX - This should be bottlenecked by the write buffer, but these
49 * things tend to be mildly unpredictable...should check this on the
50 * performance model
51 *
52 * We prefetch 4 lines ahead. We're also "cheating" slightly here...
53 * since we know we're on an SB1, we force the assembler to take
54 * 64-bit operands to speed things up
55 */
56 __asm__ __volatile__(
57 " .set push \n"
58 " .set mips4 \n"
59 " .set noreorder \n"
60#ifdef CONFIG_CPU_HAS_PREFETCH
61 " daddiu %0, %0, 128 \n"
62 " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n"
63 /* Prefetch the first 4 lines */
64 " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n"
65 " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n"
66 " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n"
67 "1: sd $0, -128(%0) \n" /* Throw out a cacheline of 0's */
68 " sd $0, -120(%0) \n"
69 " sd $0, -112(%0) \n"
70 " sd $0, -104(%0) \n"
71 " daddiu %0, %0, 32 \n"
72 " bnel %0, %1, 1b \n"
73 " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n"
74 " daddiu %0, %0, -128 \n"
75#endif
76 " sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */
77 "1: sd $0, 8(%0) \n"
78 " sd $0, 16(%0) \n"
79 " sd $0, 24(%0) \n"
80 " daddiu %0, %0, 32 \n"
81 " bnel %0, %1, 1b \n"
82 " sd $0, 0(%0) \n"
83 " .set pop \n"
84 : "+r" (addr)
85 : "r" (end)
86 : "memory");
87}
88
89static inline void copy_page_cpu(void *to, void *from)
90{
91 unsigned char *src = (unsigned char *)from;
92 unsigned char *dst = (unsigned char *)to;
93 unsigned char *end = src + PAGE_SIZE;
94
95 /*
96 * The pref's used here are using "streaming" hints, which cause the
97 * copied data to be kicked out of the cache sooner. A page copy often
98 * ends up copying a lot more data than is commonly used, so this seems
99 * to make sense in terms of reducing cache pollution, but I've no real
100 * performance data to back this up
101 */
102 __asm__ __volatile__(
103 " .set push \n"
104 " .set mips4 \n"
105 " .set noreorder \n"
106#ifdef CONFIG_CPU_HAS_PREFETCH
107 " daddiu %0, %0, 128 \n"
108 " daddiu %1, %1, 128 \n"
109 " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n"
110 /* Prefetch the first 4 lines */
111 " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
112 " pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n"
113 " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n"
114 " pref " SB1_PREF_LOAD_STREAMED_HINT ", -64(%0)\n"
115 " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%1)\n"
116 " pref " SB1_PREF_LOAD_STREAMED_HINT ", -32(%0)\n"
117 "1: pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%1)\n"
118# ifdef CONFIG_64BIT
119 " ld $8, -128(%0) \n" /* Block copy a cacheline */
120 " ld $9, -120(%0) \n"
121 " ld $10, -112(%0) \n"
122 " ld $11, -104(%0) \n"
123 " sd $8, -128(%1) \n"
124 " sd $9, -120(%1) \n"
125 " sd $10, -112(%1) \n"
126 " sd $11, -104(%1) \n"
127# else
128 " lw $2, -128(%0) \n" /* Block copy a cacheline */
129 " lw $3, -124(%0) \n"
130 " lw $6, -120(%0) \n"
131 " lw $7, -116(%0) \n"
132 " lw $8, -112(%0) \n"
133 " lw $9, -108(%0) \n"
134 " lw $10, -104(%0) \n"
135 " lw $11, -100(%0) \n"
136 " sw $2, -128(%1) \n"
137 " sw $3, -124(%1) \n"
138 " sw $6, -120(%1) \n"
139 " sw $7, -116(%1) \n"
140 " sw $8, -112(%1) \n"
141 " sw $9, -108(%1) \n"
142 " sw $10, -104(%1) \n"
143 " sw $11, -100(%1) \n"
144# endif
145 " daddiu %0, %0, 32 \n"
146 " daddiu %1, %1, 32 \n"
147 " bnel %0, %2, 1b \n"
148 " pref " SB1_PREF_LOAD_STREAMED_HINT ", -32(%0)\n"
149 " daddiu %0, %0, -128 \n"
150 " daddiu %1, %1, -128 \n"
151#endif
152#ifdef CONFIG_64BIT
153 " ld $8, 0(%0) \n" /* Block copy a cacheline */
154 "1: ld $9, 8(%0) \n"
155 " ld $10, 16(%0) \n"
156 " ld $11, 24(%0) \n"
157 " sd $8, 0(%1) \n"
158 " sd $9, 8(%1) \n"
159 " sd $10, 16(%1) \n"
160 " sd $11, 24(%1) \n"
161#else
162 " lw $2, 0(%0) \n" /* Block copy a cacheline */
163 "1: lw $3, 4(%0) \n"
164 " lw $6, 8(%0) \n"
165 " lw $7, 12(%0) \n"
166 " lw $8, 16(%0) \n"
167 " lw $9, 20(%0) \n"
168 " lw $10, 24(%0) \n"
169 " lw $11, 28(%0) \n"
170 " sw $2, 0(%1) \n"
171 " sw $3, 4(%1) \n"
172 " sw $6, 8(%1) \n"
173 " sw $7, 12(%1) \n"
174 " sw $8, 16(%1) \n"
175 " sw $9, 20(%1) \n"
176 " sw $10, 24(%1) \n"
177 " sw $11, 28(%1) \n"
178#endif
179 " daddiu %0, %0, 32 \n"
180 " daddiu %1, %1, 32 \n"
181 " bnel %0, %2, 1b \n"
182#ifdef CONFIG_64BIT
183 " ld $8, 0(%0) \n"
184#else
185 " lw $2, 0(%0) \n"
186#endif
187 " .set pop \n"
188 : "+r" (src), "+r" (dst)
189 : "r" (end)
190#ifdef CONFIG_64BIT
191 : "$8", "$9", "$10", "$11", "memory");
192#else
193 : "$2", "$3", "$6", "$7", "$8", "$9", "$10", "$11", "memory");
194#endif
195}
196
197
198#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
199
200/*
201 * Pad descriptors to cacheline, since each is exclusively owned by a
202 * particular CPU.
203 */
204typedef struct dmadscr_s {
205 u64 dscr_a;
206 u64 dscr_b;
207 u64 pad_a;
208 u64 pad_b;
209} dmadscr_t;
210
211static dmadscr_t page_descr[DM_NUM_CHANNELS]
212 __attribute__((aligned(SMP_CACHE_BYTES)));
213
214void sb1_dma_init(void)
215{
216 int i;
217
218 for (i = 0; i < DM_NUM_CHANNELS; i++) {
219 const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
220 V_DM_DSCR_BASE_RINGSZ(1);
221 void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
222
223 __raw_writeq(base_val, base_reg);
224 __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
225 __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
226 }
227}
228
229void clear_page(void *page)
230{
231 u64 to_phys = CPHYSADDR((unsigned long)page);
232 unsigned int cpu = smp_processor_id();
233
234 /* if the page is not in KSEG0, use old way */
235 if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
236 return clear_page_cpu(page);
237
238 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
239 M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
240 page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
241 __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
242
243 /*
244 * Don't really want to do it this way, but there's no
245 * reliable way to delay completion detection.
246 */
247 while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
248 & M_DM_DSCR_BASE_INTERRUPT))
249 ;
250 __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
251}
252
253void copy_page(void *to, void *from)
254{
255 u64 from_phys = CPHYSADDR((unsigned long)from);
256 u64 to_phys = CPHYSADDR((unsigned long)to);
257 unsigned int cpu = smp_processor_id();
258
259 /* if any page is not in KSEG0, use old way */
260 if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
261 || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
262 return copy_page_cpu(to, from);
263
264 page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
265 M_DM_DSCRA_INTERRUPT;
266 page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
267 __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
268
269 /*
270 * Don't really want to do it this way, but there's no
271 * reliable way to delay completion detection.
272 */
273 while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
274 & M_DM_DSCR_BASE_INTERRUPT))
275 ;
276 __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
277}
278
279#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
280
281void clear_page(void *page)
282{
283 return clear_page_cpu(page);
284}
285
286void copy_page(void *to, void *from)
287{
288 return copy_page_cpu(to, from);
289}
290
291#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */
292
293EXPORT_SYMBOL(clear_page);
294EXPORT_SYMBOL(copy_page);
295
296void __cpuinit build_clear_page(void)
297{
298}
299
300void __cpuinit build_copy_page(void)
301{
302}
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c
index 57df1c38e303..7dfa579ab24c 100644
--- a/arch/mips/mm/pgtable.c
+++ b/arch/mips/mm/pgtable.c
@@ -12,7 +12,6 @@ void show_mem(void)
12 12
13 printk("Mem-info:\n"); 13 printk("Mem-info:\n");
14 show_free_areas(); 14 show_free_areas();
15 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
16 pfn = max_mapnr; 15 pfn = max_mapnr;
17 while (pfn-- > 0) { 16 while (pfn-- > 0) {
18 if (!pfn_valid(pfn)) 17 if (!pfn_valid(pfn))
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 63065d6e8063..5ce2fa745626 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -299,7 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
299 idx = read_c0_index(); 299 idx = read_c0_index();
300 ptep = pte_offset_map(pmdp, address); 300 ptep = pte_offset_map(pmdp, address);
301 301
302#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) 302#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
303 write_c0_entrylo0(ptep->pte_high); 303 write_c0_entrylo0(ptep->pte_high);
304 ptep++; 304 ptep++;
305 write_c0_entrylo1(ptep->pte_high); 305 write_c0_entrylo1(ptep->pte_high);
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 1a6f7704cc89..1655aa69e133 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -58,13 +58,13 @@ enum opcode {
58 insn_invalid, 58 insn_invalid,
59 insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, 59 insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
60 insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, 60 insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
61 insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, 61 insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
62 insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, 62 insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
63 insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, 63 insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr,
64 insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, 64 insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
65 insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, 65 insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
66 insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi, 66 insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
67 insn_tlbwr, insn_xor, insn_xori 67 insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
68}; 68};
69 69
70struct insn { 70struct insn {
@@ -94,6 +94,7 @@ static struct insn insn_table[] __cpuinitdata = {
94 { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, 94 { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
95 { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, 95 { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
96 { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, 96 { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
97 { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
97 { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 98 { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
98 { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, 99 { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
99 { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, 100 { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
@@ -116,6 +117,7 @@ static struct insn insn_table[] __cpuinitdata = {
116 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, 117 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
117 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, 118 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
118 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, 119 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
120 { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
119 { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, 121 { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
120 { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 122 { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
121 { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 123 { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
@@ -337,6 +339,7 @@ I_u1s2(_bgezl)
337I_u1s2(_bltz) 339I_u1s2(_bltz)
338I_u1s2(_bltzl) 340I_u1s2(_bltzl)
339I_u1u2s3(_bne) 341I_u1u2s3(_bne)
342I_u2s3u1(_cache)
340I_u1u2u3(_dmfc0) 343I_u1u2u3(_dmfc0)
341I_u1u2u3(_dmtc0) 344I_u1u2u3(_dmtc0)
342I_u2u1s3(_daddiu) 345I_u2u1s3(_daddiu)
@@ -359,6 +362,7 @@ I_u2s3u1(_lw)
359I_u1u2u3(_mfc0) 362I_u1u2u3(_mfc0)
360I_u1u2u3(_mtc0) 363I_u1u2u3(_mtc0)
361I_u2u1u3(_ori) 364I_u2u1u3(_ori)
365I_u2s3u1(_pref)
362I_0(_rfe) 366I_0(_rfe)
363I_u2s3u1(_sc) 367I_u2s3u1(_sc)
364I_u2s3u1(_scd) 368I_u2s3u1(_scd)
@@ -555,6 +559,14 @@ uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
555} 559}
556 560
557void __cpuinit 561void __cpuinit
562uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
563 unsigned int reg2, int lid)
564{
565 uasm_r_mips_pc16(r, *p, lid);
566 uasm_i_bne(p, reg1, reg2, 0);
567}
568
569void __cpuinit
558uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) 570uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
559{ 571{
560 uasm_r_mips_pc16(r, *p, lid); 572 uasm_r_mips_pc16(r, *p, lid);
diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h
index fe0574f6e77d..0d6a66f32030 100644
--- a/arch/mips/mm/uasm.h
+++ b/arch/mips/mm/uasm.h
@@ -55,6 +55,7 @@ Ip_u1s2(_bgezl);
55Ip_u1s2(_bltz); 55Ip_u1s2(_bltz);
56Ip_u1s2(_bltzl); 56Ip_u1s2(_bltzl);
57Ip_u1u2s3(_bne); 57Ip_u1u2s3(_bne);
58Ip_u2s3u1(_cache);
58Ip_u1u2u3(_dmfc0); 59Ip_u1u2u3(_dmfc0);
59Ip_u1u2u3(_dmtc0); 60Ip_u1u2u3(_dmtc0);
60Ip_u2u1s3(_daddiu); 61Ip_u2u1s3(_daddiu);
@@ -77,6 +78,7 @@ Ip_u2s3u1(_lw);
77Ip_u1u2u3(_mfc0); 78Ip_u1u2u3(_mfc0);
78Ip_u1u2u3(_mtc0); 79Ip_u1u2u3(_mtc0);
79Ip_u2u1u3(_ori); 80Ip_u2u1u3(_ori);
81Ip_u2s3u1(_pref);
80Ip_0(_rfe); 82Ip_0(_rfe);
81Ip_u2s3u1(_sc); 83Ip_u2s3u1(_sc);
82Ip_u2s3u1(_scd); 84Ip_u2s3u1(_scd);
@@ -177,6 +179,8 @@ void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
177void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid); 179void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
178void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 180void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
179void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 181void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
182void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
183 unsigned int reg2, int lid);
180void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 184void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
181void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 185void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
182void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 186void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/nxp/pnx8550/common/Makefile
index 31cc1a5cec3b..31cc1a5cec3b 100644
--- a/arch/mips/philips/pnx8550/common/Makefile
+++ b/arch/mips/nxp/pnx8550/common/Makefile
diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/nxp/pnx8550/common/gdb_hook.c
index ad4624f6d9bc..ad4624f6d9bc 100644
--- a/arch/mips/philips/pnx8550/common/gdb_hook.c
+++ b/arch/mips/nxp/pnx8550/common/gdb_hook.c
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c
index aad03429a5e3..aad03429a5e3 100644
--- a/arch/mips/philips/pnx8550/common/int.c
+++ b/arch/mips/nxp/pnx8550/common/int.c
diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
index eee4f3dfc410..eee4f3dfc410 100644
--- a/arch/mips/philips/pnx8550/common/pci.c
+++ b/arch/mips/nxp/pnx8550/common/pci.c
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/nxp/pnx8550/common/platform.c
index c839436bd012..c7c763dbe588 100644
--- a/arch/mips/philips/pnx8550/common/platform.c
+++ b/arch/mips/nxp/pnx8550/common/platform.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Platform device support for Philips PNX8550 SoCs 2 * Platform device support for NXP PNX8550 SoCs
3 * 3 *
4 * Copyright 2005, Embedded Alley Solutions, Inc 4 * Copyright 2005, Embedded Alley Solutions, Inc
5 * 5 *
diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/nxp/pnx8550/common/proc.c
index 18b125e3b65d..18b125e3b65d 100644
--- a/arch/mips/philips/pnx8550/common/proc.c
+++ b/arch/mips/nxp/pnx8550/common/proc.c
diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/nxp/pnx8550/common/prom.c
index 2f567452e7ac..2f567452e7ac 100644
--- a/arch/mips/philips/pnx8550/common/prom.c
+++ b/arch/mips/nxp/pnx8550/common/prom.c
diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/nxp/pnx8550/common/reset.c
index 7b2cbc5b2c7c..7b2cbc5b2c7c 100644
--- a/arch/mips/philips/pnx8550/common/reset.c
+++ b/arch/mips/nxp/pnx8550/common/reset.c
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
index 92d764c97701..92d764c97701 100644
--- a/arch/mips/philips/pnx8550/common/setup.c
+++ b/arch/mips/nxp/pnx8550/common/setup.c
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/nxp/pnx8550/common/time.c
index 62f495b57f93..62f495b57f93 100644
--- a/arch/mips/philips/pnx8550/common/time.c
+++ b/arch/mips/nxp/pnx8550/common/time.c
diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/nxp/pnx8550/jbs/Makefile
index e8228dbca8f6..ad6a8ca7d8ce 100644
--- a/arch/mips/philips/pnx8550/jbs/Makefile
+++ b/arch/mips/nxp/pnx8550/jbs/Makefile
@@ -1,4 +1,4 @@
1 1
2# Makefile for the Philips JBS Board. 2# Makefile for the NXP JBS Board.
3 3
4lib-y := init.o board_setup.o irqmap.o 4lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/nxp/pnx8550/jbs/board_setup.c
index f92826e0096d..f92826e0096d 100644
--- a/arch/mips/philips/pnx8550/jbs/board_setup.c
+++ b/arch/mips/nxp/pnx8550/jbs/board_setup.c
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/nxp/pnx8550/jbs/init.c
index 90b4d35f3ece..d59b4a4e5e8b 100644
--- a/arch/mips/philips/pnx8550/jbs/init.c
+++ b/arch/mips/nxp/pnx8550/jbs/init.c
@@ -40,7 +40,7 @@ extern char *prom_getenv(char *envname);
40 40
41const char *get_system_type(void) 41const char *get_system_type(void)
42{ 42{
43 return "Philips PNX8550/JBS"; 43 return "NXP PNX8550/JBS";
44} 44}
45 45
46void __init prom_init(void) 46void __init prom_init(void)
diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/nxp/pnx8550/jbs/irqmap.c
index 98c3429e6e50..7fc89842002c 100644
--- a/arch/mips/philips/pnx8550/jbs/irqmap.c
+++ b/arch/mips/nxp/pnx8550/jbs/irqmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Philips JBS board irqmap. 2 * NXP JBS board irqmap.
3 * 3 *
4 * Copyright 2005 Embedded Alley Solutions, Inc 4 * Copyright 2005 Embedded Alley Solutions, Inc
5 * source@embeddealley.com 5 * source@embeddealley.com
@@ -33,4 +33,3 @@ char pnx8550_irq_tab[][5] __initdata = {
33 [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, 33 [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
34 [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, 34 [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
35}; 35};
36
diff --git a/arch/mips/philips/pnx8550/stb810/Makefile b/arch/mips/nxp/pnx8550/stb810/Makefile
index f14b592af398..ab91d72c5664 100644
--- a/arch/mips/philips/pnx8550/stb810/Makefile
+++ b/arch/mips/nxp/pnx8550/stb810/Makefile
@@ -1,4 +1,4 @@
1 1
2# Makefile for the Philips STB810 Board. 2# Makefile for the NXP STB810 Board.
3 3
4lib-y := prom_init.o board_setup.o irqmap.o 4lib-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/philips/pnx8550/stb810/board_setup.c b/arch/mips/nxp/pnx8550/stb810/board_setup.c
index 345d71e53cf2..1282c27cfcb7 100644
--- a/arch/mips/philips/pnx8550/stb810/board_setup.c
+++ b/arch/mips/nxp/pnx8550/stb810/board_setup.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * STB810 specific board startup routines. 2 * STB810 specific board startup routines.
3 * 3 *
4 * Based on the arch/mips/philips/pnx8550/jbs/board_setup.c 4 * Based on the arch/mips/nxp/pnx8550/jbs/board_setup.c
5 * 5 *
6 * Author: MontaVista Software, Inc. 6 * Author: MontaVista Software, Inc.
7 * source@mvista.com 7 * source@mvista.com
diff --git a/arch/mips/philips/pnx8550/stb810/irqmap.c b/arch/mips/nxp/pnx8550/stb810/irqmap.c
index 5ee11e19975e..8c034963ddcd 100644
--- a/arch/mips/philips/pnx8550/stb810/irqmap.c
+++ b/arch/mips/nxp/pnx8550/stb810/irqmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Philips STB810 board irqmap. 2 * NXP STB810 board irqmap.
3 * 3 *
4 * Author: MontaVista Software, Inc. 4 * Author: MontaVista Software, Inc.
5 * source@mvista.com 5 * source@mvista.com
@@ -20,4 +20,3 @@ char pnx8550_irq_tab[][5] __initdata = {
20 [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, 20 [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
21 [10] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, 21 [10] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
22}; 22};
23
diff --git a/arch/mips/philips/pnx8550/stb810/prom_init.c b/arch/mips/nxp/pnx8550/stb810/prom_init.c
index 832dd60b0a7a..ca7f4ada0640 100644
--- a/arch/mips/philips/pnx8550/stb810/prom_init.c
+++ b/arch/mips/nxp/pnx8550/stb810/prom_init.c
@@ -28,7 +28,7 @@ extern char *prom_getenv(char *envname);
28 28
29const char *get_system_type(void) 29const char *get_system_type(void)
30{ 30{
31 return "Philips PNX8550/STB810"; 31 return "NXP PNX8950/STB810";
32} 32}
33 33
34void __init prom_init(void) 34void __init prom_init(void)
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index aa52aa146cea..b5f6f71b27bc 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -80,6 +80,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
80 case CPU_24K: 80 case CPU_24K:
81 case CPU_25KF: 81 case CPU_25KF:
82 case CPU_34K: 82 case CPU_34K:
83 case CPU_1004K:
83 case CPU_74K: 84 case CPU_74K:
84 case CPU_SB1: 85 case CPU_SB1:
85 case CPU_SB1A: 86 case CPU_SB1A:
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
index fa6b4aae7523..2bfc17c30106 100644
--- a/arch/mips/oprofile/op_impl.h
+++ b/arch/mips/oprofile/op_impl.h
@@ -10,7 +10,6 @@
10#ifndef OP_IMPL_H 10#ifndef OP_IMPL_H
11#define OP_IMPL_H 1 11#define OP_IMPL_H 1
12 12
13extern int null_perf_irq(void);
14extern int (*perf_irq)(void); 13extern int (*perf_irq)(void);
15 14
16/* Per-counter configuration as set via oprofilefs. */ 15/* Per-counter configuration as set via oprofilefs. */
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index ccbea229a0e6..da8cbb6899dc 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,9 +31,14 @@
31 31
32#define M_COUNTER_OVERFLOW (1UL << 31) 32#define M_COUNTER_OVERFLOW (1UL << 31)
33 33
34static int (*save_perf_irq)(void);
35
34#ifdef CONFIG_MIPS_MT_SMP 36#ifdef CONFIG_MIPS_MT_SMP
35#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) 37static int cpu_has_mipsmt_pertccounters;
36#define vpe_id() smp_processor_id() 38#define WHAT (M_TC_EN_VPE | \
39 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
40#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
41 0 : cpu_data[smp_processor_id()].vpe_id)
37 42
38/* 43/*
39 * The number of bits to shift to convert between counters per core and 44 * The number of bits to shift to convert between counters per core and
@@ -243,11 +248,11 @@ static inline int __n_counters(void)
243{ 248{
244 if (!(read_c0_config1() & M_CONFIG1_PC)) 249 if (!(read_c0_config1() & M_CONFIG1_PC))
245 return 0; 250 return 0;
246 if (!(r_c0_perfctrl0() & M_PERFCTL_MORE)) 251 if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
247 return 1; 252 return 1;
248 if (!(r_c0_perfctrl1() & M_PERFCTL_MORE)) 253 if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
249 return 2; 254 return 2;
250 if (!(r_c0_perfctrl2() & M_PERFCTL_MORE)) 255 if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
251 return 3; 256 return 3;
252 257
253 return 4; 258 return 4;
@@ -274,8 +279,9 @@ static inline int n_counters(void)
274 return counters; 279 return counters;
275} 280}
276 281
277static inline void reset_counters(int counters) 282static void reset_counters(void *arg)
278{ 283{
284 int counters = (int)arg;
279 switch (counters) { 285 switch (counters) {
280 case 4: 286 case 4:
281 w_c0_perfctrl3(0); 287 w_c0_perfctrl3(0);
@@ -302,9 +308,12 @@ static int __init mipsxx_init(void)
302 return -ENODEV; 308 return -ENODEV;
303 } 309 }
304 310
305 reset_counters(counters); 311#ifdef CONFIG_MIPS_MT_SMP
306 312 cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
307 counters = counters_total_to_per_cpu(counters); 313 if (!cpu_has_mipsmt_pertccounters)
314 counters = counters_total_to_per_cpu(counters);
315#endif
316 on_each_cpu(reset_counters, (void *)counters, 0, 1);
308 317
309 op_model_mipsxx_ops.num_counters = counters; 318 op_model_mipsxx_ops.num_counters = counters;
310 switch (current_cpu_type()) { 319 switch (current_cpu_type()) {
@@ -320,6 +329,13 @@ static int __init mipsxx_init(void)
320 op_model_mipsxx_ops.cpu_type = "mips/25K"; 329 op_model_mipsxx_ops.cpu_type = "mips/25K";
321 break; 330 break;
322 331
332 case CPU_1004K:
333#if 0
334 /* FIXME: report as 34K for now */
335 op_model_mipsxx_ops.cpu_type = "mips/1004K";
336 break;
337#endif
338
323 case CPU_34K: 339 case CPU_34K:
324 op_model_mipsxx_ops.cpu_type = "mips/34K"; 340 op_model_mipsxx_ops.cpu_type = "mips/34K";
325 break; 341 break;
@@ -355,6 +371,7 @@ static int __init mipsxx_init(void)
355 return -ENODEV; 371 return -ENODEV;
356 } 372 }
357 373
374 save_perf_irq = perf_irq;
358 perf_irq = mipsxx_perfcount_handler; 375 perf_irq = mipsxx_perfcount_handler;
359 376
360 return 0; 377 return 0;
@@ -365,9 +382,9 @@ static void mipsxx_exit(void)
365 int counters = op_model_mipsxx_ops.num_counters; 382 int counters = op_model_mipsxx_ops.num_counters;
366 383
367 counters = counters_per_cpu_to_total(counters); 384 counters = counters_per_cpu_to_total(counters);
368 reset_counters(counters); 385 on_each_cpu(reset_counters, (void *)counters, 0, 1);
369 386
370 perf_irq = null_perf_irq; 387 perf_irq = save_perf_irq;
371} 388}
372 389
373struct op_mips_model op_model_mipsxx_ops = { 390struct op_mips_model op_model_mipsxx_ops = {
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index ca0276c8070a..00c36c9dbe0e 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -26,13 +26,10 @@
26 * with this program; if not, write to the Free Software Foundation, Inc., 26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. 27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29#include <linux/types.h> 29
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/kernel.h>
32#include <linux/init.h> 31#include <linux/init.h>
33 32
34#include <asm/mach-au1x00/au1000.h>
35
36extern char irq_tab_alchemy[][5]; 33extern char irq_tab_alchemy[][5];
37 34
38int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 35int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
index d61064652498..0e160d9f07c3 100644
--- a/arch/mips/pci/ops-pnx8550.c
+++ b/arch/mips/pci/ops-pnx8550.c
@@ -90,14 +90,14 @@ config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int
90 90
91 loops--; 91 loops--;
92 if (loops == 0) { 92 if (loops == 0) {
93 printk("%s : Arbiter Locked.\n", __FUNCTION__); 93 printk("%s : Arbiter Locked.\n", __func__);
94 } 94 }
95 } 95 }
96 96
97 clear_status(); 97 clear_status();
98 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) { 98 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
99 printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n", 99 printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
100 __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr, 100 __func__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
101 pci_cmd); 101 pci_cmd);
102 } 102 }
103 103
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 624bbdbff2a8..b6cab089561e 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -142,7 +142,7 @@ static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
142 reg_c = CMOS_READ(RTC_INTR_FLAGS); 142 reg_c = CMOS_READ(RTC_INTR_FLAGS);
143 if (!(reg_c & RTC_IRQF)) { 143 if (!(reg_c & RTC_IRQF)) {
144 printk(KERN_WARNING 144 printk(KERN_WARNING
145 "%s: RTC IRQ without RTC_IRQF\n", __FUNCTION__); 145 "%s: RTC IRQ without RTC_IRQF\n", __func__);
146 } 146 }
147 /* Wait until interrupt goes away */ 147 /* Wait until interrupt goes away */
148 disable_irq(MACEISA_RTC_IRQ); 148 disable_irq(MACEISA_RTC_IRQ);
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
index 3f808b629242..6d31f2a98abf 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
@@ -173,7 +173,7 @@ static const u32 toshiba_rbtx4927_irq_debug_flag =
173 { \ 173 { \
174 char tmp[100]; \ 174 char tmp[100]; \
175 sprintf( tmp, str ); \ 175 sprintf( tmp, str ); \
176 printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ 176 printk( "%s(%s:%u)::%s", __func__, __FILE__, __LINE__, tmp ); \
177 } 177 }
178#else 178#else
179#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag, str...) 179#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag, str...)
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index e466e5e711d8..2203c77b2ce2 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -93,7 +93,7 @@ static const u32 toshiba_rbtx4927_setup_debug_flag =
93 { \ 93 { \
94 char tmp[100]; \ 94 char tmp[100]; \
95 sprintf( tmp, str ); \ 95 sprintf( tmp, str ); \
96 printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ 96 printk( "%s(%s:%u)::%s", __func__, __FILE__, __LINE__, tmp ); \
97 } 97 }
98#else 98#else
99#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag, str...) 99#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag, str...)
diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
index bea59ff1842a..33b9c672a322 100644
--- a/arch/mips/tx4938/common/dbgio.c
+++ b/arch/mips/tx4938/common/dbgio.c
@@ -31,9 +31,7 @@
31 * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp> 31 * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
32 */ 32 */
33 33
34#include <asm/mipsregs.h> 34#include <linux/types>
35#include <asm/system.h>
36#include <asm/tx4938/tx4938_mips.h>
37 35
38extern u8 txx9_sio_kdbg_rd(void); 36extern u8 txx9_sio_kdbg_rd(void);
39extern int txx9_sio_kdbg_wr( u8 ch ); 37extern int txx9_sio_kdbg_wr( u8 ch );
diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
index 3189a65f7d7e..20baeaeba4cd 100644
--- a/arch/mips/tx4938/common/prom.c
+++ b/arch/mips/tx4938/common/prom.c
@@ -13,13 +13,8 @@
13 */ 13 */
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/mm.h> 16#include <linux/types.h>
17#include <linux/sched.h> 17#include <linux/io.h>
18#include <linux/bootmem.h>
19
20#include <asm/addrspace.h>
21#include <asm/bootinfo.h>
22#include <asm/tx4938/tx4938.h>
23 18
24static unsigned int __init 19static unsigned int __init
25tx4938_process_sdccr(u64 * addr) 20tx4938_process_sdccr(u64 * addr)
@@ -35,7 +30,7 @@ tx4938_process_sdccr(u64 * addr)
35 unsigned int bc = 4; 30 unsigned int bc = 4;
36 unsigned int msize = 0; 31 unsigned int msize = 0;
37 32
38 val = (*((vu64 *) (addr))); 33 val = ____raw_readq((void __iomem *)addr);
39 34
40 /* MVMCP -- need #defs for these bits masks */ 35 /* MVMCP -- need #defs for these bits masks */
41 sdccr_ce = ((val & (1 << 10)) >> 10); 36 sdccr_ce = ((val & (1 << 10)) >> 10);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index f00185017e80..4d6a8dc46c76 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -67,24 +67,7 @@ IRQ Device
6763 RBTX4938-IOC/07 SWINT 6763 RBTX4938-IOC/07 SWINT
68*/ 68*/
69#include <linux/init.h> 69#include <linux/init.h>
70#include <linux/kernel.h>
71#include <linux/types.h>
72#include <linux/mm.h>
73#include <linux/swap.h>
74#include <linux/ioport.h>
75#include <linux/sched.h>
76#include <linux/interrupt.h> 70#include <linux/interrupt.h>
77#include <linux/pci.h>
78#include <linux/timex.h>
79#include <asm/bootinfo.h>
80#include <asm/page.h>
81#include <asm/io.h>
82#include <asm/irq.h>
83#include <asm/processor.h>
84#include <asm/reboot.h>
85#include <asm/time.h>
86#include <asm/wbflush.h>
87#include <linux/bootmem.h>
88#include <asm/tx4938/rbtx4938.h> 71#include <asm/tx4938/rbtx4938.h>
89 72
90static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); 73static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
@@ -99,21 +82,16 @@ static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
99 .unmask = toshiba_rbtx4938_irq_ioc_enable, 82 .unmask = toshiba_rbtx4938_irq_ioc_enable,
100}; 83};
101 84
102#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
103#define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
104
105int 85int
106toshiba_rbtx4938_irq_nested(int sw_irq) 86toshiba_rbtx4938_irq_nested(int sw_irq)
107{ 87{
108 u8 level3; 88 u8 level3;
109 89
110 level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff; 90 level3 = readb(rbtx4938_imstat_addr);
111 if (level3) { 91 if (level3)
112 /* must use fls so onboard ATA has priority */ 92 /* must use fls so onboard ATA has priority */
113 sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1; 93 sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
114 }
115 94
116 wbflush();
117 return sw_irq; 95 return sw_irq;
118} 96}
119 97
@@ -144,25 +122,23 @@ toshiba_rbtx4938_irq_ioc_init(void)
144static void 122static void
145toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) 123toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
146{ 124{
147 volatile unsigned char v; 125 unsigned char v;
148 126
149 v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); 127 v = readb(rbtx4938_imask_addr);
150 v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); 128 v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
151 TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); 129 writeb(v, rbtx4938_imask_addr);
152 mmiowb(); 130 mmiowb();
153 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
154} 131}
155 132
156static void 133static void
157toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) 134toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
158{ 135{
159 volatile unsigned char v; 136 unsigned char v;
160 137
161 v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); 138 v = readb(rbtx4938_imask_addr);
162 v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); 139 v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
163 TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); 140 writeb(v, rbtx4938_imask_addr);
164 mmiowb(); 141 mmiowb();
165 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
166} 142}
167 143
168void __init arch_init_irq(void) 144void __init arch_init_irq(void)
@@ -174,14 +150,12 @@ void __init arch_init_irq(void)
174 /* all IRC interrupt mode are Low Active. */ 150 /* all IRC interrupt mode are Low Active. */
175 151
176 /* mask all IOC interrupts */ 152 /* mask all IOC interrupts */
177 *rbtx4938_imask_ptr = 0; 153 writeb(0, rbtx4938_imask_addr);
178 154
179 /* clear SoftInt interrupts */ 155 /* clear SoftInt interrupts */
180 *rbtx4938_softint_ptr = 0; 156 writeb(0, rbtx4938_softint_addr);
181 tx4938_irq_init(); 157 tx4938_irq_init();
182 toshiba_rbtx4938_irq_ioc_init(); 158 toshiba_rbtx4938_irq_ioc_init();
183 /* Onboard 10M Ether: High Active */ 159 /* Onboard 10M Ether: High Active */
184 set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); 160 set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
185
186 wbflush();
187} 161}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 61249f049cd6..3a3659e8633a 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -21,8 +21,8 @@
21#include <linux/pm.h> 21#include <linux/pm.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/gpio.h>
24 25
25#include <asm/wbflush.h>
26#include <asm/reboot.h> 26#include <asm/reboot.h>
27#include <asm/time.h> 27#include <asm/time.h>
28#include <asm/txx9tmr.h> 28#include <asm/txx9tmr.h>
@@ -34,7 +34,7 @@
34#endif 34#endif
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <asm/tx4938/spi.h> 36#include <asm/tx4938/spi.h>
37#include <asm/gpio.h> 37#include <asm/txx9pio.h>
38 38
39extern char * __init prom_getcmdline(void); 39extern char * __init prom_getcmdline(void);
40static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); 40static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
@@ -90,12 +90,11 @@ void rbtx4938_machine_restart(char *command)
90 local_irq_disable(); 90 local_irq_disable();
91 91
92 printk("Rebooting..."); 92 printk("Rebooting...");
93 *rbtx4938_softresetlock_ptr = 1; 93 writeb(1, rbtx4938_softresetlock_addr);
94 *rbtx4938_sfvol_ptr = 1; 94 writeb(1, rbtx4938_sfvol_addr);
95 *rbtx4938_softreset_ptr = 1; 95 writeb(1, rbtx4938_softreset_addr);
96 wbflush(); 96 while(1)
97 97 ;
98 while(1);
99} 98}
100 99
101void __init 100void __init
@@ -487,7 +486,7 @@ static int __init tx4938_pcibios_init(void)
487 } 486 }
488 487
489 /* Reset PCI Bus */ 488 /* Reset PCI Bus */
490 *rbtx4938_pcireset_ptr = 0; 489 writeb(0, rbtx4938_pcireset_addr);
491 /* Reset PCIC */ 490 /* Reset PCIC */
492 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; 491 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
493 if (txboard_pci66_mode > 0) 492 if (txboard_pci66_mode > 0)
@@ -495,8 +494,8 @@ static int __init tx4938_pcibios_init(void)
495 mdelay(10); 494 mdelay(10);
496 /* clear PCIC reset */ 495 /* clear PCIC reset */
497 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; 496 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
498 *rbtx4938_pcireset_ptr = 1; 497 writeb(1, rbtx4938_pcireset_addr);
499 wbflush(); 498 mmiowb();
500 tx4938_report_pcic_status1(tx4938_pcicptr); 499 tx4938_report_pcic_status1(tx4938_pcicptr);
501 500
502 tx4938_report_pciclk(); 501 tx4938_report_pciclk();
@@ -504,15 +503,15 @@ static int __init tx4938_pcibios_init(void)
504 if (txboard_pci66_mode == 0 && 503 if (txboard_pci66_mode == 0 &&
505 txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { 504 txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
506 /* Reset PCI Bus */ 505 /* Reset PCI Bus */
507 *rbtx4938_pcireset_ptr = 0; 506 writeb(0, rbtx4938_pcireset_addr);
508 /* Reset PCIC */ 507 /* Reset PCIC */
509 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; 508 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
510 tx4938_pciclk66_setup(); 509 tx4938_pciclk66_setup();
511 mdelay(10); 510 mdelay(10);
512 /* clear PCIC reset */ 511 /* clear PCIC reset */
513 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; 512 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
514 *rbtx4938_pcireset_ptr = 1; 513 writeb(1, rbtx4938_pcireset_addr);
515 wbflush(); 514 mmiowb();
516 /* Reinitialize PCIC */ 515 /* Reinitialize PCIC */
517 tx4938_report_pciclk(); 516 tx4938_report_pciclk();
518 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); 517 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
@@ -615,9 +614,6 @@ static void __init rbtx4938_spi_setup(void)
615{ 614{
616 /* set SPI_SEL */ 615 /* set SPI_SEL */
617 tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; 616 tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
618 /* chip selects for SPI devices */
619 tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
620 tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
621} 617}
622 618
623static struct resource rbtx4938_fpga_resource; 619static struct resource rbtx4938_fpga_resource;
@@ -776,12 +772,13 @@ void __init tx4938_board_setup(void)
776 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); 772 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
777 773
778 /* enable DMA */ 774 /* enable DMA */
779 TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN); 775 for (i = 0; i < 2; i++)
780 TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN); 776 ____raw_writeq(TX4938_DMA_MCR_MSTEN,
777 (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
781 778
782 /* PIO */ 779 /* PIO */
783 tx4938_pioptr->maskcpu = 0; 780 __raw_writel(0, &tx4938_pioptr->maskcpu);
784 tx4938_pioptr->maskext = 0; 781 __raw_writel(0, &tx4938_pioptr->maskext);
785 782
786 /* TX4938 internal registers */ 783 /* TX4938 internal registers */
787 if (request_resource(&iomem_resource, &tx4938_reg_resource)) 784 if (request_resource(&iomem_resource, &tx4938_reg_resource))
@@ -863,10 +860,6 @@ void __init plat_mem_setup(void)
863 if (txx9_master_clock == 0) 860 if (txx9_master_clock == 0)
864 txx9_master_clock = 25000000; /* 25MHz */ 861 txx9_master_clock = 25000000; /* 25MHz */
865 tx4938_board_setup(); 862 tx4938_board_setup();
866 /* setup serial stuff */
867 TX4938_WR(0xff1ff314, 0x00000000); /* h/w flow control off */
868 TX4938_WR(0xff1ff414, 0x00000000); /* h/w flow control off */
869
870#ifndef CONFIG_PCI 863#ifndef CONFIG_PCI
871 set_io_port_base(RBTX4938_ETHER_BASE); 864 set_io_port_base(RBTX4938_ETHER_BASE);
872#endif 865#endif
@@ -932,16 +925,16 @@ void __init plat_mem_setup(void)
932 pcfg = tx4938_ccfgptr->pcfg; /* updated */ 925 pcfg = tx4938_ccfgptr->pcfg; /* updated */
933 /* fixup piosel */ 926 /* fixup piosel */
934 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == 927 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
935 TX4938_PCFG_ATA_SEL) { 928 TX4938_PCFG_ATA_SEL)
936 *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04; 929 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
937 } 930 rbtx4938_piosel_addr);
938 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == 931 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
939 TX4938_PCFG_NDF_SEL) { 932 TX4938_PCFG_NDF_SEL)
940 *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08; 933 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
941 } 934 rbtx4938_piosel_addr);
942 else { 935 else
943 *rbtx4938_piosel_ptr &= ~(0x08 | 0x04); 936 writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
944 } 937 rbtx4938_piosel_addr);
945 938
946 rbtx4938_fpga_resource.name = "FPGA Registers"; 939 rbtx4938_fpga_resource.name = "FPGA Registers";
947 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); 940 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
@@ -950,17 +943,14 @@ void __init plat_mem_setup(void)
950 if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) 943 if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
951 printk("request resource for fpga failed\n"); 944 printk("request resource for fpga failed\n");
952 945
953 /* disable all OnBoard I/O interrupts */
954 *rbtx4938_imask_ptr = 0;
955
956 _machine_restart = rbtx4938_machine_restart; 946 _machine_restart = rbtx4938_machine_restart;
957 _machine_halt = rbtx4938_machine_halt; 947 _machine_halt = rbtx4938_machine_halt;
958 pm_power_off = rbtx4938_machine_power_off; 948 pm_power_off = rbtx4938_machine_power_off;
959 949
960 *rbtx4938_led_ptr = 0xff; 950 writeb(0xff, rbtx4938_led_addr);
961 printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr); 951 printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
962 printk(" DIPSW:%02x,%02x\n", 952 readb(rbtx4938_fpga_rev_addr),
963 *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); 953 readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
964} 954}
965 955
966static int __init rbtx4938_ne_init(void) 956static int __init rbtx4938_ne_init(void)
@@ -984,106 +974,48 @@ device_initcall(rbtx4938_ne_init);
984 974
985/* GPIO support */ 975/* GPIO support */
986 976
987static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); 977int gpio_to_irq(unsigned gpio)
988
989static void rbtx4938_spi_gpio_set(unsigned gpio, int value)
990{ 978{
991 u8 val; 979 return -EINVAL;
992 unsigned long flags;
993 gpio -= 16;
994 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
995 val = *rbtx4938_spics_ptr;
996 if (value)
997 val |= 1 << gpio;
998 else
999 val &= ~(1 << gpio);
1000 *rbtx4938_spics_ptr = val;
1001 mmiowb();
1002 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1003} 980}
1004 981
1005static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value) 982int irq_to_gpio(unsigned irq)
1006{ 983{
1007 rbtx4938_spi_gpio_set(gpio, value); 984 return -EINVAL;
1008 return 0;
1009} 985}
1010 986
1011static DEFINE_SPINLOCK(tx4938_gpio_lock); 987static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
1012
1013static int tx4938_gpio_get(unsigned gpio)
1014{
1015 return tx4938_pioptr->din & (1 << gpio);
1016}
1017 988
1018static void tx4938_gpio_set_raw(unsigned gpio, int value) 989static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
990 int value)
1019{ 991{
1020 u32 val; 992 u8 val;
1021 val = tx4938_pioptr->dout; 993 unsigned long flags;
994 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
995 val = readb(rbtx4938_spics_addr);
1022 if (value) 996 if (value)
1023 val |= 1 << gpio; 997 val |= 1 << offset;
1024 else 998 else
1025 val &= ~(1 << gpio); 999 val &= ~(1 << offset);
1026 tx4938_pioptr->dout = val; 1000 writeb(val, rbtx4938_spics_addr);
1027}
1028
1029static void tx4938_gpio_set(unsigned gpio, int value)
1030{
1031 unsigned long flags;
1032 spin_lock_irqsave(&tx4938_gpio_lock, flags);
1033 tx4938_gpio_set_raw(gpio, value);
1034 mmiowb();
1035 spin_unlock_irqrestore(&tx4938_gpio_lock, flags);
1036}
1037
1038static int tx4938_gpio_dir_in(unsigned gpio)
1039{
1040 spin_lock_irq(&tx4938_gpio_lock);
1041 tx4938_pioptr->dir &= ~(1 << gpio);
1042 mmiowb(); 1001 mmiowb();
1043 spin_unlock_irq(&tx4938_gpio_lock); 1002 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1044 return 0;
1045}
1046
1047static int tx4938_gpio_dir_out(unsigned int gpio, int value)
1048{
1049 spin_lock_irq(&tx4938_gpio_lock);
1050 tx4938_gpio_set_raw(gpio, value);
1051 tx4938_pioptr->dir |= 1 << gpio;
1052 mmiowb();
1053 spin_unlock_irq(&tx4938_gpio_lock);
1054 return 0;
1055}
1056
1057int gpio_direction_input(unsigned gpio)
1058{
1059 if (gpio < 16)
1060 return tx4938_gpio_dir_in(gpio);
1061 return -EINVAL;
1062}
1063
1064int gpio_direction_output(unsigned gpio, int value)
1065{
1066 if (gpio < 16)
1067 return tx4938_gpio_dir_out(gpio, value);
1068 if (gpio < 16 + 3)
1069 return rbtx4938_spi_gpio_dir_out(gpio, value);
1070 return -EINVAL;
1071} 1003}
1072 1004
1073int gpio_get_value(unsigned gpio) 1005static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
1006 unsigned int offset, int value)
1074{ 1007{
1075 if (gpio < 16) 1008 rbtx4938_spi_gpio_set(chip, offset, value);
1076 return tx4938_gpio_get(gpio);
1077 return 0; 1009 return 0;
1078} 1010}
1079 1011
1080void gpio_set_value(unsigned gpio, int value) 1012static struct gpio_chip rbtx4938_spi_gpio_chip = {
1081{ 1013 .set = rbtx4938_spi_gpio_set,
1082 if (gpio < 16) 1014 .direction_output = rbtx4938_spi_gpio_dir_out,
1083 tx4938_gpio_set(gpio, value); 1015 .label = "RBTX4938-SPICS",
1084 else 1016 .base = 16,
1085 rbtx4938_spi_gpio_set(gpio, value); 1017 .ngpio = 3,
1086} 1018};
1087 1019
1088/* SPI support */ 1020/* SPI support */
1089 1021
@@ -1094,7 +1026,6 @@ static void __init txx9_spi_init(unsigned long base, int irq)
1094 .start = base, 1026 .start = base,
1095 .end = base + 0x20 - 1, 1027 .end = base + 0x20 - 1,
1096 .flags = IORESOURCE_MEM, 1028 .flags = IORESOURCE_MEM,
1097 .parent = &tx4938_reg_resource,
1098 }, { 1029 }, {
1099 .start = irq, 1030 .start = irq,
1100 .flags = IORESOURCE_IRQ, 1031 .flags = IORESOURCE_IRQ,
@@ -1118,10 +1049,25 @@ static int __init rbtx4938_spi_init(void)
1118 spi_eeprom_register(SEEPROM1_CS); 1049 spi_eeprom_register(SEEPROM1_CS);
1119 spi_eeprom_register(16 + SEEPROM2_CS); 1050 spi_eeprom_register(16 + SEEPROM2_CS);
1120 spi_eeprom_register(16 + SEEPROM3_CS); 1051 spi_eeprom_register(16 + SEEPROM3_CS);
1052 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
1053 gpio_direction_output(16 + SRTC_CS, 0);
1054 gpio_request(SEEPROM1_CS, "seeprom1");
1055 gpio_direction_output(SEEPROM1_CS, 1);
1056 gpio_request(16 + SEEPROM2_CS, "seeprom2");
1057 gpio_direction_output(16 + SEEPROM2_CS, 1);
1058 gpio_request(16 + SEEPROM3_CS, "seeprom3");
1059 gpio_direction_output(16 + SEEPROM3_CS, 1);
1121 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); 1060 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
1122 return 0; 1061 return 0;
1123} 1062}
1124arch_initcall(rbtx4938_spi_init); 1063
1064static int __init rbtx4938_arch_init(void)
1065{
1066 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16);
1067 gpiochip_add(&rbtx4938_spi_gpio_chip);
1068 return rbtx4938_spi_init();
1069}
1070arch_initcall(rbtx4938_arch_init);
1125 1071
1126/* Watchdog support */ 1072/* Watchdog support */
1127 1073
@@ -1131,7 +1077,6 @@ static int __init txx9_wdt_init(unsigned long base)
1131 .start = base, 1077 .start = base,
1132 .end = base + 0x100 - 1, 1078 .end = base + 0x100 - 1,
1133 .flags = IORESOURCE_MEM, 1079 .flags = IORESOURCE_MEM,
1134 .parent = &tx4938_reg_resource,
1135 }; 1080 };
1136 struct platform_device *dev = 1081 struct platform_device *dev =
1137 platform_device_register_simple("txx9wdt", -1, &res, 1); 1082 platform_device_register_simple("txx9wdt", -1, &res, 1);